From 02ca9bfc498fc6592de4b4fae277a05febf7c13e Mon Sep 17 00:00:00 2001 From: KowerKoint Date: Fri, 24 Jan 2025 12:14:23 +0900 Subject: [PATCH] fix to compile gate/paramgate --- include/scaluq/gate/gate.hpp | 14 +- include/scaluq/gate/gate_pauli.hpp | 30 +-- include/scaluq/gate/gate_probablistic.hpp | 20 +- include/scaluq/gate/gate_standard.hpp | 210 +++++++++--------- include/scaluq/gate/param_gate.hpp | 158 ++++++------- include/scaluq/gate/param_gate_factory.hpp | 82 +++---- include/scaluq/gate/param_gate_pauli.hpp | 54 ++--- .../scaluq/gate/param_gate_probablistic.hpp | 51 ++--- include/scaluq/gate/param_gate_standard.hpp | 102 ++++----- src/CMakeLists.txt | 20 +- src/gate/gate_matrix.cpp | 4 +- src/gate/gate_pauli.cpp | 27 ++- src/gate/gate_standard.cpp | 7 +- src/gate/param_gate.cpp | 26 ++- src/gate/param_gate_pauli.cpp | 47 ++-- src/gate/param_gate_probablistic.cpp | 32 +-- src/gate/param_gate_standard.cpp | 112 +++++----- 17 files changed, 518 insertions(+), 478 deletions(-) diff --git a/include/scaluq/gate/gate.hpp b/include/scaluq/gate/gate.hpp index 006bd37e..18adcbd2 100644 --- a/include/scaluq/gate/gate.hpp +++ b/include/scaluq/gate/gate.hpp @@ -170,10 +170,10 @@ constexpr GateType get_gate_type() { namespace internal { // GateBase テンプレートクラス -template -class GateBase : public std::enable_shared_from_this> { +template +class GateBase : public std::enable_shared_from_this> { public: - constexpr static Precision Prec = Prec; + constexpr static Precision Prec = _Prec; using FloatType = Float; using ComplexType = Complex; @@ -205,7 +205,7 @@ class GateBase : public std::enable_shared_from_this> { } [[nodiscard]] virtual std::shared_ptr> get_inverse() const = 0; - [[nodiscard]] virtual internal::ComplexMatrix get_matrix() const = 0; + [[nodiscard]] virtual ComplexMatrix get_matrix() const = 0; virtual void update_quantum_state(StateVector& state_vector) const = 0; virtual void update_quantum_state(StateVectorBatched& states) const = 0; @@ -232,7 +232,7 @@ class GatePtr { GateType _gate_type; public: - constexpr Precision Prec = T::Prec; + constexpr static Precision Prec = T::Prec; using FloatType = Float; using ComplexType = Complex; GatePtr() : _gate_ptr(nullptr), _gate_type(get_gate_type()) {} @@ -241,7 +241,7 @@ class GatePtr { if constexpr (std::is_same_v) { _gate_type = get_gate_type(); _gate_ptr = gate_ptr; - } else if constexpr (std::is_same_v>) { + } else if constexpr (std::is_same_v>) { // upcast _gate_type = get_gate_type(); _gate_ptr = std::static_pointer_cast(gate_ptr); @@ -258,7 +258,7 @@ class GatePtr { if constexpr (std::is_same_v) { _gate_type = gate._gate_type; _gate_ptr = gate._gate_ptr; - } else if constexpr (std::is_same_v>) { + } else if constexpr (std::is_same_v>) { // upcast _gate_type = gate._gate_type; _gate_ptr = std::static_pointer_cast(gate._gate_ptr); diff --git a/include/scaluq/gate/gate_pauli.hpp b/include/scaluq/gate/gate_pauli.hpp index db359f45..625ad23f 100644 --- a/include/scaluq/gate/gate_pauli.hpp +++ b/include/scaluq/gate/gate_pauli.hpp @@ -24,7 +24,7 @@ class PauliGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return this->shared_from_this(); } - internal::ComplexMatrix get_matrix() const override { return this->_pauli.get_matrix(); } + ComplexMatrix get_matrix() const override { return this->_pauli.get_matrix(); } void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -59,7 +59,7 @@ class PauliRotationGateImpl : public GateBase { this->_control_mask, _pauli, -_angle); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -81,35 +81,35 @@ template using PauliRotationGate = internal::GatePtr>; namespace internal { -#define DECLARE_GET_FROM_JSON_PAULIGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_PAULIGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto controls = j.at("control").get>(); \ - auto pauli = j.at("pauli").get>(); \ - return std::make_shared>(vector_to_mask(controls), pauli); \ + auto pauli = j.at("pauli").get>(); \ + return std::make_shared>(vector_to_mask(controls), pauli); \ } \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto controls = j.at("control").get>(); \ - auto pauli = j.at("pauli").get>(); \ - auto angle = j.at("angle").get(); \ - return std::make_shared>( \ + auto pauli = j.at("pauli").get>(); \ + auto angle = j.at("angle").get(); \ + return std::make_shared>( \ vector_to_mask(controls), pauli, angle); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_PAULIGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_PAULIGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_PAULIGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_PAULIGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_PAULIGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_PAULIGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_PAULIGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_PAULIGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_PAULIGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_PAULIGATE_WITH_PRECISION } // namespace internal diff --git a/include/scaluq/gate/gate_probablistic.hpp b/include/scaluq/gate/gate_probablistic.hpp index c9d38186..80d2f807 100644 --- a/include/scaluq/gate/gate_probablistic.hpp +++ b/include/scaluq/gate/gate_probablistic.hpp @@ -52,7 +52,7 @@ class ProbablisticGateImpl : public GateBase { } std::shared_ptr> get_inverse() const override; - internal::ComplexMatrix get_matrix() const override { + ComplexMatrix get_matrix() const override { throw std::runtime_error( "ProbablisticGateImpl::get_matrix(): This function must not be used in " "ProbablisticGateImpl."); @@ -76,27 +76,27 @@ using ProbablisticGate = internal::GatePtr> namespace internal { -#define DECLARE_GET_FROM_JSON_PROBGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_PROBGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto distribution = j.at("distribution").get>(); \ - auto gate_list = j.at("gate_list").get>>(); \ - return std::make_shared>(distribution, gate_list); \ + auto gate_list = j.at("gate_list").get>>(); \ + return std::make_shared>(distribution, gate_list); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_PROBGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_PROBGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_PROBGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_PROBGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_PROBGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_PROBGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_PROBGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_PROBGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_PROBGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_PROBGATE_WITH_PRECISION } // namespace internal diff --git a/include/scaluq/gate/gate_standard.hpp b/include/scaluq/gate/gate_standard.hpp index 125564a5..2259592e 100644 --- a/include/scaluq/gate/gate_standard.hpp +++ b/include/scaluq/gate/gate_standard.hpp @@ -14,7 +14,7 @@ class IGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return this->shared_from_this(); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -33,12 +33,12 @@ class GlobalPhaseGateImpl : public GateBase { GlobalPhaseGateImpl(std::uint64_t control_mask, Float phase) : GateBase(0, control_mask), _phase(phase){}; - [[nodiscard]] Float phase() const { return _phase; } + [[nodiscard]] double phase() const { return _phase; } std::shared_ptr> get_inverse() const override { return std::make_shared>(this->_control_mask, -_phase); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -62,7 +62,7 @@ class RotationGateBase : public GateBase { RotationGateBase(std::uint64_t target_mask, std::uint64_t control_mask, Float angle) : GateBase(target_mask, control_mask), _angle(angle) {} - Float angle() const { return _angle; } + double angle() const { return _angle; } }; template @@ -73,7 +73,7 @@ class XGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return this->shared_from_this(); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -95,7 +95,7 @@ class YGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return this->shared_from_this(); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -117,7 +117,7 @@ class ZGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return this->shared_from_this(); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -139,7 +139,7 @@ class HGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return this->shared_from_this(); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -178,7 +178,7 @@ class SGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return std::make_shared>(this->_target_mask, this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -200,7 +200,7 @@ class SdagGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return std::make_shared>(this->_target_mask, this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -222,7 +222,7 @@ class TGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return std::make_shared>(this->_target_mask, this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -244,7 +244,7 @@ class TdagGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return std::make_shared>(this->_target_mask, this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -268,7 +268,7 @@ class SqrtXGateImpl : public GateBase { this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -290,7 +290,7 @@ class SqrtXdagGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return std::make_shared>(this->_target_mask, this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -314,7 +314,7 @@ class SqrtYGateImpl : public GateBase { this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -336,7 +336,7 @@ class SqrtYdagGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return std::make_shared>(this->_target_mask, this->_control_mask); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -358,7 +358,7 @@ class P0GateImpl : public GateBase { std::shared_ptr> get_inverse() const override { throw std::runtime_error("P0::get_inverse: Projection gate doesn't have inverse gate"); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -380,7 +380,7 @@ class P1GateImpl : public GateBase { std::shared_ptr> get_inverse() const override { throw std::runtime_error("P1::get_inverse: Projection gate doesn't have inverse gate"); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -403,7 +403,7 @@ class RXGateImpl : public RotationGateBase { return std::make_shared>( this->_target_mask, this->_control_mask, -this->_angle); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -427,7 +427,7 @@ class RYGateImpl : public RotationGateBase { return std::make_shared>( this->_target_mask, this->_control_mask, -this->_angle); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -451,7 +451,7 @@ class RZGateImpl : public RotationGateBase { return std::make_shared>( this->_target_mask, this->_control_mask, -this->_angle); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -480,7 +480,7 @@ class U1GateImpl : public GateBase { return std::make_shared>( this->_target_mask, this->_control_mask, -_lambda); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -515,7 +515,7 @@ class U2GateImpl : public GateBase { -_lambda - static_cast>(Kokkos::numbers::pi), -_phi + static_cast>(Kokkos::numbers::pi)); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -551,7 +551,7 @@ class U3GateImpl : public GateBase { return std::make_shared>( this->_target_mask, this->_control_mask, -_theta, -_lambda, -_phi); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -576,7 +576,7 @@ class SwapGateImpl : public GateBase { std::shared_ptr> get_inverse() const override { return this->shared_from_this(); } - internal::ComplexMatrix get_matrix() const override; + ComplexMatrix get_matrix() const override; void update_quantum_state(StateVector& state_vector) const override; void update_quantum_state(StateVectorBatched& states) const override; @@ -641,175 +641,175 @@ using SwapGate = internal::GatePtr>; namespace internal { -#define DECLARE_GET_FROM_JSON_IGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_IGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json&) { \ - return std::make_shared>(); \ + inline std::shared_ptr> get_from_json(const Json&) { \ + return std::make_shared>(); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_IGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_IGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_IGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_IGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_IGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_IGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_IGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_IGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_IGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_IGATE_WITH_PRECISION -#define DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto controls = j.at("control").get>(); \ - Type phase = j.at("phase").get(); \ - return std::make_shared>(vector_to_mask(controls), phase); \ + double phase = j.at("phase").get(); \ + return std::make_shared>(vector_to_mask(controls), phase); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_GLOBALPHASEGATE_WITH_PRECISION -#define DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(Impl, Type) \ +#define DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(Impl, Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto targets = j.at("target").get>(); \ auto controls = j.at("control").get>(); \ - return std::make_shared>(vector_to_mask(targets), \ + return std::make_shared>(vector_to_mask(targets), \ vector_to_mask(controls)); \ } -#define DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_TYPE(Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(XGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(YGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(ZGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(HGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(SGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(SdagGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(TGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(TdagGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(SqrtXGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(SqrtXdagGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(SqrtYGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(SqrtYdagGateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(P0GateImpl, Type) \ - DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE(P1GateImpl, Type) +#define DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_PRECISION(Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(XGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(YGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(ZGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(HGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(SGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(SdagGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(TGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(TdagGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(SqrtXGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(SqrtXdagGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(SqrtYGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(SqrtYdagGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(P0GateImpl, Prec) \ + DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION(P1GateImpl, Prec) #ifdef SCALUQ_FLOAT16 -DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_TYPE(F16) +DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_TYPE(F32) +DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_TYPE(F64) +DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_TYPE(BF16) +DECALRE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_TYPE -#undef DECLARE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_SINGLETARGETGATE_WITH_PRECISION +#undef DECLARE_GET_FROM_JSON_EACH_SINGLETARGETGATE_WITH_PRECISION -#define DECLARE_GET_FROM_JSON_RGATE_WITH_TYPE(Impl, Type) \ +#define DECLARE_GET_FROM_JSON_RGATE_WITH_PRECISION(Impl, Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto targets = j.at("target").get>(); \ auto controls = j.at("control").get>(); \ - Type angle = j.at("angle").get(); \ - return std::make_shared>( \ + double angle = j.at("angle").get(); \ + return std::make_shared>( \ vector_to_mask(targets), vector_to_mask(controls), angle); \ } -#define DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_TYPE(Type) \ - DECLARE_GET_FROM_JSON_RGATE_WITH_TYPE(RXGateImpl, Type) \ - DECLARE_GET_FROM_JSON_RGATE_WITH_TYPE(RYGateImpl, Type) \ - DECLARE_GET_FROM_JSON_RGATE_WITH_TYPE(RZGateImpl, Type) +#define DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_PRECISION(Prec) \ + DECLARE_GET_FROM_JSON_RGATE_WITH_PRECISION(RXGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_RGATE_WITH_PRECISION(RYGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_RGATE_WITH_PRECISION(RZGateImpl, Prec) #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_PRECISION(Precision::BF16) #endif #undef DECLARE_GET_FROM_JSON_RGATE -#undef DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_EACH_RGATE_WITH_PRECISION -#define DECLARE_GET_FROM_JSON_UGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_UGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto targets = j.at("target").get>(); \ auto controls = j.at("control").get>(); \ - Type theta = j.at("theta").get(); \ - return std::make_shared>( \ + double theta = j.at("theta").get(); \ + return std::make_shared>( \ vector_to_mask(targets), vector_to_mask(controls), theta); \ } \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto targets = j.at("target").get>(); \ auto controls = j.at("control").get>(); \ - Type theta = j.at("theta").get(); \ - Type phi = j.at("phi").get(); \ - return std::make_shared>( \ + double theta = j.at("theta").get(); \ + double phi = j.at("phi").get(); \ + return std::make_shared>( \ vector_to_mask(targets), vector_to_mask(controls), theta, phi); \ } \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto targets = j.at("target").get>(); \ auto controls = j.at("control").get>(); \ - Type theta = j.at("theta").get(); \ - Type phi = j.at("phi").get(); \ - Type lambda = j.at("lambda").get(); \ - return std::make_shared>( \ + double theta = j.at("theta").get(); \ + double phi = j.at("phi").get(); \ + double lambda = j.at("lambda").get(); \ + return std::make_shared>( \ vector_to_mask(targets), vector_to_mask(controls), theta, phi, lambda); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_UGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_UGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_UGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_UGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_UGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_UGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_UGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_UGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_UGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_UGATE_WITH_PRECISION -#define DECLARE_GET_FROM_JSON_SWAPGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_SWAPGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto targets = j.at("target").get>(); \ auto controls = j.at("control").get>(); \ - return std::make_shared>(vector_to_mask(targets), \ + return std::make_shared>(vector_to_mask(targets), \ vector_to_mask(controls)); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_SWAPGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_SWAPGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_SWAPGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_SWAPGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_SWAPGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_SWAPGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_SWAPGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_SWAPGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_SWAPGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_SWAPGATE_WITH_PRECISION } // namespace internal diff --git a/include/scaluq/gate/param_gate.hpp b/include/scaluq/gate/param_gate.hpp index ce7c2327..92820810 100644 --- a/include/scaluq/gate/param_gate.hpp +++ b/include/scaluq/gate/param_gate.hpp @@ -8,18 +8,18 @@ namespace scaluq { namespace internal { // forward declarations -template +template class ParamGateBase; -template +template class ParamRXGateImpl; -template +template class ParamRYGateImpl; -template +template class ParamRZGateImpl; -template +template class ParamPauliRotationGateImpl; -template +template class ParamProbablisticGateImpl; } // namespace internal @@ -34,44 +34,48 @@ enum class ParamGateType { Error }; -template +template constexpr ParamGateType get_param_gate_type() { using TWithoutConst = std::remove_cv_t; - if constexpr (std::is_same_v>) + if constexpr (std::is_same_v>) return ParamGateType::Unknown; - else if constexpr (std::is_same_v>) + else if constexpr (std::is_same_v>) return ParamGateType::ParamRX; - else if constexpr (std::is_same_v>) + else if constexpr (std::is_same_v>) return ParamGateType::ParamRY; - else if constexpr (std::is_same_v>) + else if constexpr (std::is_same_v>) return ParamGateType::ParamRZ; - else if constexpr (std::is_same_v>) + else if constexpr (std::is_same_v>) return ParamGateType::ParamPauliRotation; - else if constexpr (std::is_same_v>) + else if constexpr (std::is_same_v>) return ParamGateType::ParamProbablistic; else static_assert(internal::lazy_false_v, "unknown GateImpl"); } namespace internal { -template -class ParamGateBase { +template +class ParamGateBase : public std::enable_shared_from_this> { public: - using Fp = _FloatType; + constexpr static Precision Prec = _Prec; + using FloatType = Float; + using ComplexType = Complex; protected: std::uint64_t _target_mask, _control_mask; - Fp _pcoef; - void check_qubit_mask_within_bounds(const StateVector& state_vector) const; - void check_qubit_mask_within_bounds(const StateVectorBatched& states) const; + FloatType _pcoef; + void check_qubit_mask_within_bounds(const StateVector& state_vector) const; + void check_qubit_mask_within_bounds(const StateVectorBatched& states) const; std::string get_qubit_info_as_string(const std::string& indent) const; public: - ParamGateBase(std::uint64_t target_mask, std::uint64_t control_mask, Fp param_coef = 1); + ParamGateBase(std::uint64_t target_mask, + std::uint64_t control_mask, + Float param_coef = 1); virtual ~ParamGateBase() = default; - [[nodiscard]] Fp param_coef() const { return _pcoef; } + [[nodiscard]] double param_coef() const { return _pcoef; } [[nodiscard]] virtual std::vector target_qubit_list() const { return mask_to_vector(_target_mask); @@ -88,12 +92,12 @@ class ParamGateBase { return _target_mask | _control_mask; } - [[nodiscard]] virtual std::shared_ptr> get_inverse() const = 0; - [[nodiscard]] virtual internal::ComplexMatrix get_matrix(Fp param) const = 0; + [[nodiscard]] virtual std::shared_ptr> get_inverse() const = 0; + [[nodiscard]] virtual ComplexMatrix get_matrix(double param) const = 0; - virtual void update_quantum_state(StateVector& state_vector, Fp param) const = 0; - virtual void update_quantum_state(StateVectorBatched& states, - std::vector params) const = 0; + virtual void update_quantum_state(StateVector& state_vector, double param) const = 0; + virtual void update_quantum_state(StateVectorBatched& states, + std::vector params) const = 0; [[nodiscard]] virtual std::string to_string(const std::string& indent = "") const = 0; @@ -101,7 +105,7 @@ class ParamGateBase { }; template -concept ParamGateImpl = std::derived_from>; +concept ParamGateImpl = std::derived_from>; template inline std::shared_ptr get_from_json(const Json&); @@ -111,26 +115,28 @@ class ParamGatePtr { friend class ParamGateFactory; template friend class ParamGatePtr; - using Fp = typename T::Fp; + constexpr static Precision Prec = T::Prec; + using FloatType = Float; + using ComplexType = Complex; private: std::shared_ptr _param_gate_ptr; ParamGateType _param_gate_type; public: - ParamGatePtr() : _param_gate_ptr(nullptr), _param_gate_type(get_param_gate_type()) {} + ParamGatePtr() : _param_gate_ptr(nullptr), _param_gate_type(get_param_gate_type()) {} template ParamGatePtr(const std::shared_ptr& param_gate_ptr) { if constexpr (std::is_same_v) { - _param_gate_type = get_param_gate_type(); + _param_gate_type = get_param_gate_type(); _param_gate_ptr = param_gate_ptr; - } else if constexpr (std::is_same_v>) { + } else if constexpr (std::is_same_v>) { // upcast - _param_gate_type = get_param_gate_type(); + _param_gate_type = get_param_gate_type(); _param_gate_ptr = std::static_pointer_cast(param_gate_ptr); } else { // downcast - _param_gate_type = get_param_gate_type(); + _param_gate_type = get_param_gate_type(); if (!(_param_gate_ptr = std::dynamic_pointer_cast(param_gate_ptr))) { throw std::runtime_error("invalid gate cast"); } @@ -141,13 +147,13 @@ class ParamGatePtr { if constexpr (std::is_same_v) { _param_gate_type = param_gate._param_gate_type; _param_gate_ptr = param_gate._param_gate_ptr; - } else if constexpr (std::is_same_v>) { + } else if constexpr (std::is_same_v>) { // upcast _param_gate_type = param_gate._param_gate_type; _param_gate_ptr = std::static_pointer_cast(param_gate._param_gate_ptr); } else { // downcast - if (param_gate._param_gate_type != get_param_gate_type()) { + if (param_gate._param_gate_type != get_param_gate_type()) { throw std::runtime_error("invalid gate cast"); } _param_gate_type = param_gate._param_gate_type; @@ -175,109 +181,111 @@ class ParamGatePtr { std::string type = j.at("type"); // clang-format off - if (type == "ParamRX") gate = get_from_json>(j); - else if (type == "ParamRY") gate = get_from_json>(j); - else if (type == "ParamRZ") gate = get_from_json>(j); - else if (type == "ParamPauliRotation") gate = get_from_json>(j); - else if (type == "ParamProbablistic") gate = get_from_json>(j); + if (type == "ParamRX") gate = get_from_json>(j); + else if (type == "ParamRY") gate = get_from_json>(j); + else if (type == "ParamRZ") gate = get_from_json>(j); + else if (type == "ParamPauliRotation") gate = get_from_json>(j); + else if (type == "ParamProbablistic") gate = get_from_json>(j); // clang-format on } }; } // namespace internal -template -using ParamGate = internal::ParamGatePtr>; +template +using ParamGate = internal::ParamGatePtr>; #ifdef SCALUQ_USE_NANOBIND namespace internal { -#define DEF_PARAM_GATE_BASE(PARAM_GATE_TYPE, FLOAT, DESCRIPTION) \ - nb::class_>(m, #PARAM_GATE_TYPE, DESCRIPTION) \ +#define DEF_PARAM_GATE_BASE(PARAM_GATE_TYPE, PRECISION, DESCRIPTION) \ + nb::class_>(m, #PARAM_GATE_TYPE, DESCRIPTION) \ .def("param_gate_type", \ - &PARAM_GATE_TYPE::param_gate_type, \ + &PARAM_GATE_TYPE::param_gate_type, \ "Get parametric gate type as `ParamGateType` enum.") \ .def( \ "param_coef", \ - [](const PARAM_GATE_TYPE& gate) { return gate->param_coef(); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->param_coef(); }, \ "Get coefficient of parameter.") \ .def( \ "target_qubit_list", \ - [](const PARAM_GATE_TYPE& gate) { return gate->target_qubit_list(); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->target_qubit_list(); }, \ "Get target qubits as `list[int]`. **Control qubits is not included.**") \ .def( \ "control_qubit_list", \ - [](const PARAM_GATE_TYPE& gate) { return gate->control_qubit_list(); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->control_qubit_list(); }, \ "Get control qubits as `list[int]`.") \ .def( \ "operand_qubit_list", \ - [](const PARAM_GATE_TYPE& gate) { return gate->operand_qubit_list(); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->operand_qubit_list(); }, \ "Get target and control qubits as `list[int]`.") \ .def( \ "target_qubit_mask", \ - [](const PARAM_GATE_TYPE& gate) { return gate->target_qubit_mask(); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->target_qubit_mask(); }, \ "Get target qubits as mask. **Control qubits is not included.**") \ .def( \ "control_qubit_mask", \ - [](const PARAM_GATE_TYPE& gate) { return gate->control_qubit_mask(); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->control_qubit_mask(); }, \ "Get control qubits as mask.") \ .def( \ "operand_qubit_mask", \ - [](const PARAM_GATE_TYPE& gate) { return gate->operand_qubit_mask(); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->operand_qubit_mask(); }, \ "Get target and control qubits as mask.") \ .def( \ "get_inverse", \ - [](const PARAM_GATE_TYPE& param_gate) { return param_gate->get_inverse(); }, \ + [](const PARAM_GATE_TYPE& param_gate) { \ + return param_gate->get_inverse(); \ + }, \ "Generate inverse parametric-gate as `ParamGate` type. If not exists, return None.") \ .def( \ "update_quantum_state", \ - [](const PARAM_GATE_TYPE& param_gate, \ - StateVector& state_vector, \ - FLOAT param) { param_gate->update_quantum_state(state_vector, param); }, \ + [](const PARAM_GATE_TYPE& param_gate, \ + StateVector& state_vector, \ + double param) { param_gate->update_quantum_state(state_vector, param); }, \ "Apply gate to `state_vector` with holding the parameter. `state_vector` in args is " \ "directly updated.") \ .def( \ "update_quantum_state", \ - [](const PARAM_GATE_TYPE& param_gate, \ - StateVectorBatched& states, \ - std::vector params) { param_gate->update_quantum_state(states, params); }, \ + [](const PARAM_GATE_TYPE& param_gate, \ + StateVectorBatched& states, \ + std::vector params) { param_gate->update_quantum_state(states, params); }, \ "Apply gate to `states` with holding the parameter. `states` in args is directly " \ "updated.") \ .def( \ "get_matrix", \ - [](const PARAM_GATE_TYPE& gate, FLOAT param) { \ + [](const PARAM_GATE_TYPE& gate, double param) { \ return gate->get_matrix(param); \ }, \ "Get matrix representation of the gate with holding the parameter.") \ .def( \ "to_string", \ - [](const PARAM_GATE_TYPE& gate) { return gate->to_string(""); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->to_string(""); }, \ "Get string representation of the gate.") \ .def( \ "__str__", \ - [](const PARAM_GATE_TYPE& gate) { return gate->to_string(""); }, \ + [](const PARAM_GATE_TYPE& gate) { return gate->to_string(""); }, \ "Get string representation of the gate.") \ .def( \ "to_json", \ - [](const PARAM_GATE_TYPE& gate) { return Json(gate).dump(); }, \ + [](const PARAM_GATE_TYPE& gate) { return Json(gate).dump(); }, \ "Get JSON representation of the gate.") \ .def( \ "load_json", \ - [](PARAM_GATE_TYPE& gate, const std::string& str) { \ + [](PARAM_GATE_TYPE& gate, const std::string& str) { \ gate = nlohmann::json::parse(str); \ }, \ "Read an object from the JSON representation of the gate.") -template -nb::class_> param_gate_base_def; +template +nb::class_> param_gate_base_def; -#define DEF_PARAM_GATE(PARAM_GATE_TYPE, FLOAT, DESCRIPTION) \ - ::scaluq::internal::param_gate_base_def.def(nb::init>(), \ - "Upcast from `" #PARAM_GATE_TYPE "`."); \ +#define DEF_PARAM_GATE(PARAM_GATE_TYPE, PRECISION, DESCRIPTION) \ + ::scaluq::internal::param_gate_base_def.def(nb::init>(), \ + "Upcast from `" #PARAM_GATE_TYPE "`."); \ DEF_PARAM_GATE_BASE( \ PARAM_GATE_TYPE, \ - FLOAT, \ + PRECISION, \ DESCRIPTION \ "\n\n.. note:: Upcast is required to use gate-general functions (ex: add to Circuit).") \ - .def(nb::init>()) + .def(nb::init>()) void bind_gate_param_gate_hpp_without_precision(nb::module_& m) { nb::enum_(m, "ParamGateType", "Enum of ParamGate Type.") @@ -287,15 +295,15 @@ void bind_gate_param_gate_hpp_without_precision(nb::module_& m) { .value("ParamPauliRotation", ParamGateType::ParamPauliRotation); } -template +template void bind_gate_param_gate_hpp(nb::module_& m) { - param_gate_base_def = + param_gate_base_def = DEF_PARAM_GATE_BASE( ParamGate, - Fp, + Prec, "General class of parametric quantum gate.\n\n.. note:: Downcast to requred to use " "gate-specific functions.") - .def(nb::init>(), "Just copy shallowly."); + .def(nb::init>(), "Just copy shallowly."); } } // namespace internal diff --git a/include/scaluq/gate/param_gate_factory.hpp b/include/scaluq/gate/param_gate_factory.hpp index 49929323..2b17f92c 100644 --- a/include/scaluq/gate/param_gate_factory.hpp +++ b/include/scaluq/gate/param_gate_factory.hpp @@ -9,93 +9,99 @@ namespace internal { class ParamGateFactory { public: template - static ParamGate create_gate(Args... args) { + static ParamGate create_gate(Args... args) { return {std::make_shared(args...)}; } }; } // namespace internal namespace gate { -template -inline ParamGate ParamRX(std::uint64_t target, - Fp param_coef = 1., - const std::vector& controls = {}) { - return internal::ParamGateFactory::create_gate>( - internal::vector_to_mask({target}), internal::vector_to_mask(controls), param_coef); +template +inline ParamGate ParamRX(std::uint64_t target, + double param_coef = 1., + const std::vector& controls = {}) { + return internal::ParamGateFactory::create_gate>( + internal::vector_to_mask({target}), + internal::vector_to_mask(controls), + static_cast>(param_coef)); } -template -inline ParamGate ParamRY(std::uint64_t target, - Fp param_coef = 1., - const std::vector& controls = {}) { - return internal::ParamGateFactory::create_gate>( - internal::vector_to_mask({target}), internal::vector_to_mask(controls), param_coef); +template +inline ParamGate ParamRY(std::uint64_t target, + double param_coef = 1., + const std::vector& controls = {}) { + return internal::ParamGateFactory::create_gate>( + internal::vector_to_mask({target}), + internal::vector_to_mask(controls), + static_cast>(param_coef)); } -template -inline ParamGate ParamRZ(std::uint64_t target, - Fp param_coef = 1., - const std::vector& controls = {}) { - return internal::ParamGateFactory::create_gate>( - internal::vector_to_mask({target}), internal::vector_to_mask(controls), param_coef); +template +inline ParamGate ParamRZ(std::uint64_t target, + double param_coef = 1., + const std::vector& controls = {}) { + return internal::ParamGateFactory::create_gate>( + internal::vector_to_mask({target}), + internal::vector_to_mask(controls), + static_cast>(param_coef)); } -template -inline ParamGate ParamPauliRotation(const PauliOperator& pauli, - Fp param_coef = 1., - const std::vector& controls = {}) { - return internal::ParamGateFactory::create_gate>( - internal::vector_to_mask(controls), pauli, param_coef); +template +inline ParamGate ParamPauliRotation(const PauliOperator& pauli, + double param_coef = 1., + const std::vector& controls = {}) { + return internal::ParamGateFactory::create_gate>( + internal::vector_to_mask(controls), pauli, static_cast < internal::Float(param_coef)); } -template -inline ParamGate ParamProbablistic( +template +inline ParamGate ParamProbablistic( const std::vector& distribution, - const std::vector, ParamGate>>& gate_list) { - return internal::ParamGateFactory::create_gate>( + const std::vector, ParamGate>>& gate_list) { + return internal::ParamGateFactory::create_gate>( distribution, gate_list); } } // namespace gate #ifdef SCALUQ_USE_NANOBIND namespace internal { -template +template void bind_gate_param_gate_factory(nb::module_& mgate) { mgate.def("ParamRX", - &gate::ParamRX, + &gate::ParamRX, "Generate general ParamGate class instance of ParamRX.", "target"_a, "coef"_a = 1., "controls"_a = std::vector{}); mgate.def("ParamRY", - &gate::ParamRY, + &gate::ParamRY, "Generate general ParamGate class instance of ParamRY.", "target"_a, "coef"_a = 1., "controls"_a = std::vector{}); mgate.def("ParamRZ", - &gate::ParamRZ, + &gate::ParamRZ, "Generate general ParamGate class instance of ParamRZ.", "target"_a, "coef"_a = 1., "controls"_a = std::vector{}); mgate.def("ParamPauliRotation", - &gate::ParamPauliRotation, + &gate::ParamPauliRotation, "Generate general ParamGate class instance of ParamPauliRotation.", "pauli"_a, "coef"_a = 1., "controls"_a = std::vector{}); mgate.def("ParamProbablistic", - &gate::ParamProbablistic, + &gate::ParamProbablistic, "Generate general ParamGate class instance of ParamProbablistic."); mgate.def( "ParamProbablistic", - [](const std::vector, ParamGate>>>& + [](const std::vector, ParamGate>>>& prob_gate_list) { std::vector distribution; - std::vector, ParamGate>> gate_list; + std::vector, ParamGate>> gate_list; distribution.reserve(prob_gate_list.size()); gate_list.reserve(prob_gate_list.size()); for (const auto& [prob, gate] : prob_gate_list) { distribution.push_back(prob); gate_list.push_back(gate); } - return gate::ParamProbablistic(distribution, gate_list); + return gate::ParamProbablistic(distribution, gate_list); }, "Generate general ParamGate class instance of ParamProbablistic."); } diff --git a/include/scaluq/gate/param_gate_pauli.hpp b/include/scaluq/gate/param_gate_pauli.hpp index f2cb235a..49acd5b0 100644 --- a/include/scaluq/gate/param_gate_pauli.hpp +++ b/include/scaluq/gate/param_gate_pauli.hpp @@ -8,29 +8,29 @@ namespace scaluq { namespace internal { -template -class ParamPauliRotationGateImpl : public ParamGateBase { - const PauliOperator _pauli; +template +class ParamPauliRotationGateImpl : public ParamGateBase { + const PauliOperator _pauli; public: ParamPauliRotationGateImpl(std::uint64_t control_mask, - const PauliOperator& pauli, - Fp param_coef = 1.) - : ParamGateBase( + const PauliOperator& pauli, + Float param_coef = 1) + : ParamGateBase( vector_to_mask(pauli.target_qubit_list()), control_mask, param_coef), _pauli(pauli) {} - PauliOperator pauli() const { return _pauli; } + PauliOperator pauli() const { return _pauli; } std::vector pauli_id_list() const { return _pauli.pauli_id_list(); } - std::shared_ptr> get_inverse() const override { - return std::make_shared>( + std::shared_ptr> get_inverse() const override { + return std::make_shared>( this->_control_mask, _pauli, -this->_pcoef); } - internal::ComplexMatrix get_matrix(Fp param) const override; - void update_quantum_state(StateVector& state_vector, Fp param) const override; - void update_quantum_state(StateVectorBatched& states, - std::vector params) const override; + ComplexMatrix get_matrix(double param) const override; + void update_quantum_state(StateVector& state_vector, double param) const override; + void update_quantum_state(StateVectorBatched& states, + std::vector params) const override; std::string to_string(const std::string& indent) const override; void get_as_json(Json& j) const override { @@ -42,43 +42,43 @@ class ParamPauliRotationGateImpl : public ParamGateBase { }; } // namespace internal -template -using ParamPauliRotationGate = internal::ParamGatePtr>; +template +using ParamPauliRotationGate = internal::ParamGatePtr>; namespace internal { -#define DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto controls = j.at("control").get>(); \ - auto pauli = j.at("pauli").get>(); \ - auto param_coef = j.at("param_coef").get(); \ - return std::make_shared>( \ + auto pauli = j.at("pauli").get>(); \ + auto param_coef = j.at("param_coef").get(); \ + return std::make_shared>( \ vector_to_mask(controls), pauli, param_coef); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_PARAM_PAULIGATE_WITH_PRECISION } // namespace internal #ifdef SCALUQ_USE_NANOBIND namespace internal { -template +template void bind_gate_param_gate_pauli_hpp(nb::module_& m) { DEF_PARAM_GATE( ParamPauliRotationGate, - Fp, + Prec, "Specific class of parametric multi-qubit pauli-rotation gate, represented as " "$e^{-i\\frac{\\mathrm{angle}}{2}P}$. `angle` is given as `param * param_coef`."); } diff --git a/include/scaluq/gate/param_gate_probablistic.hpp b/include/scaluq/gate/param_gate_probablistic.hpp index e6ce1740..8717616a 100644 --- a/include/scaluq/gate/param_gate_probablistic.hpp +++ b/include/scaluq/gate/param_gate_probablistic.hpp @@ -9,16 +9,17 @@ namespace scaluq { namespace internal { -template -class ParamProbablisticGateImpl : public ParamGateBase { - using EitherGate = std::variant, ParamGate>; +template +class ParamProbablisticGateImpl : public ParamGateBase { + using EitherGate = std::variant, ParamGate>; std::vector _distribution; std::vector _cumulative_distribution; std::vector _gate_list; public: - ParamProbablisticGateImpl(const std::vector& distribution, - const std::vector, ParamGate>>& gate_list); + ParamProbablisticGateImpl( + const std::vector& distribution, + const std::vector, ParamGate>>& gate_list); const std::vector& gate_list() const { return _gate_list; } const std::vector& distribution() const { return _distribution; } @@ -53,16 +54,16 @@ class ParamProbablisticGateImpl : public ParamGateBase { "ParamProbablisticGateImpl."); } - std::shared_ptr> get_inverse() const override; - internal::ComplexMatrix get_matrix(Fp) const override { + std::shared_ptr> get_inverse() const override; + ComplexMatrix get_matrix(double) const override { throw std::runtime_error( "ParamProbablisticGateImpl::get_matrix(): This function must not be used in " "ParamProbablisticGateImpl."); } - void update_quantum_state(StateVector& state_vector, Fp param) const override; - void update_quantum_state(StateVectorBatched& states, - std::vector params) const override; + void update_quantum_state(StateVector& state_vector, double param) const override; + void update_quantum_state(StateVectorBatched& states, + std::vector params) const override; std::string to_string(const std::string& indent) const override; @@ -78,46 +79,46 @@ class ParamProbablisticGateImpl : public ParamGateBase { }; } // namespace internal -template -using ParamProbablisticGate = internal::ParamGatePtr>; +template +using ParamProbablisticGate = internal::ParamGatePtr>; namespace internal { -#define DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_TYPE(Type) \ +#define DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_PRECISION(Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto distribution = j.at("distribution").get>(); \ - std::vector, ParamGate>> gate_list; \ + std::vector, ParamGate>> gate_list; \ const Json& tmp_list = j.at("gate_list"); \ for (const Json& tmp_j : tmp_list) { \ if (tmp_j.at("type").get().starts_with("Param")) \ - gate_list.emplace_back(tmp_j.get>()); \ + gate_list.emplace_back(tmp_j.get>()); \ else \ - gate_list.emplace_back(tmp_j.get>()); \ + gate_list.emplace_back(tmp_j.get>()); \ } \ - return std::make_shared>(distribution, gate_list); \ + return std::make_shared>(distribution, gate_list); \ } #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_PARAMPROBABLISTICGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_PARAM_PROBABLISTICGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_PARAM_PROBABLISTICGATE_WITH_PRECISION } // namespace internal #ifdef SCALUQ_USE_NANOBIND namespace internal { -template +template void bind_gate_param_gate_probablistic_hpp(nb::module_& m) { DEF_PARAM_GATE( ParamProbablisticGate, - Fp, + Prec, "Specific class of parametric probablistic gate. The gate to apply is picked from a " "cirtain " "distribution.") diff --git a/include/scaluq/gate/param_gate_standard.hpp b/include/scaluq/gate/param_gate_standard.hpp index 56517d16..f0865c71 100644 --- a/include/scaluq/gate/param_gate_standard.hpp +++ b/include/scaluq/gate/param_gate_standard.hpp @@ -7,20 +7,20 @@ namespace scaluq { namespace internal { -template -class ParamRXGateImpl : public ParamGateBase { +template +class ParamRXGateImpl : public ParamGateBase { public: - using ParamGateBase::ParamGateBase; + using ParamGateBase::ParamGateBase; - std::shared_ptr> get_inverse() const override { - return std::make_shared>( + std::shared_ptr> get_inverse() const override { + return std::make_shared>( this->_target_mask, this->_control_mask, -this->_pcoef); } - internal::ComplexMatrix get_matrix(Fp param) const override; + ComplexMatrix get_matrix(double param) const override; - void update_quantum_state(StateVector& state_vector, Fp param) const override; - void update_quantum_state(StateVectorBatched& states, - std::vector params) const override; + void update_quantum_state(StateVector& state_vector, double param) const override; + void update_quantum_state(StateVectorBatched& states, + std::vector params) const override; std::string to_string(const std::string& indent) const override; @@ -32,20 +32,20 @@ class ParamRXGateImpl : public ParamGateBase { } }; -template -class ParamRYGateImpl : public ParamGateBase { +template +class ParamRYGateImpl : public ParamGateBase { public: - using ParamGateBase::ParamGateBase; + using ParamGateBase::ParamGateBase; - std::shared_ptr> get_inverse() const override { - return std::make_shared>( + std::shared_ptr> get_inverse() const override { + return std::make_shared>( this->_target_mask, this->_control_mask, -this->_pcoef); } - internal::ComplexMatrix get_matrix(Fp param) const override; + ComplexMatrix get_matrix(double param) const override; - void update_quantum_state(StateVector& state_vector, Fp param) const override; - void update_quantum_state(StateVectorBatched& states, - std::vector params) const override; + void update_quantum_state(StateVector& state_vector, double param) const override; + void update_quantum_state(StateVectorBatched& states, + std::vector params) const override; std::string to_string(const std::string& indent) const override; @@ -57,20 +57,20 @@ class ParamRYGateImpl : public ParamGateBase { } }; -template -class ParamRZGateImpl : public ParamGateBase { +template +class ParamRZGateImpl : public ParamGateBase { public: - using ParamGateBase::ParamGateBase; + using ParamGateBase::ParamGateBase; - std::shared_ptr> get_inverse() const override { - return std::make_shared>( + std::shared_ptr> get_inverse() const override { + return std::make_shared>( this->_target_mask, this->_control_mask, -this->_pcoef); } - internal::ComplexMatrix get_matrix(Fp param) const override; + ComplexMatrix get_matrix(double param) const override; - void update_quantum_state(StateVector& state_vector, Fp param) const override; - void update_quantum_state(StateVectorBatched& states, - std::vector params) const override; + void update_quantum_state(StateVector& state_vector, double param) const override; + void update_quantum_state(StateVectorBatched& states, + std::vector params) const override; std::string to_string(const std::string& indent) const override; @@ -84,64 +84,64 @@ class ParamRZGateImpl : public ParamGateBase { } // namespace internal -template -using ParamRXGate = internal::ParamGatePtr>; -template -using ParamRYGate = internal::ParamGatePtr>; -template -using ParamRZGate = internal::ParamGatePtr>; +template +using ParamRXGate = internal::ParamGatePtr>; +template +using ParamRYGate = internal::ParamGatePtr>; +template +using ParamRZGate = internal::ParamGatePtr>; namespace internal { -#define DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_TYPE(Impl, Type) \ +#define DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_PRECISION(Impl, Prec) \ template <> \ - inline std::shared_ptr> get_from_json(const Json& j) { \ + inline std::shared_ptr> get_from_json(const Json& j) { \ auto targets = j.at("target").get>(); \ auto controls = j.at("control").get>(); \ - auto param_coef = j.at("param_coef").get(); \ - return std::make_shared>( \ + auto param_coef = j.at("param_coef").get(); \ + return std::make_shared>( \ vector_to_mask(targets), vector_to_mask(controls), param_coef); \ } -#define DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_TYPE(Type) \ - DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_TYPE(ParamRXGateImpl, Type) \ - DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_TYPE(ParamRYGateImpl, Type) \ - DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_TYPE(ParamRZGateImpl, Type) +#define DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_PRECISION(Prec) \ + DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_PRECISION(ParamRXGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_PRECISION(ParamRYGateImpl, Prec) \ + DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_PRECISION(ParamRZGateImpl, Prec) #ifdef SCALUQ_FLOAT16 -DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_TYPE(F16) +DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_PRECISION(Precision::F16) #endif #ifdef SCALUQ_FLOAT32 -DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_TYPE(F32) +DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_PRECISION(Precision::F32) #endif #ifdef SCALUQ_FLOAT64 -DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_TYPE(F64) +DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_PRECISION(Precision::F64) #endif #ifdef SCALUQ_BFLOAT16 -DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_TYPE(BF16) +DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_PRECISION(Precision::BF16) #endif -#undef DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_TYPE -#undef DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_TYPE +#undef DECLARE_GET_FROM_JSON_PARAM_RGATE_WITH_PRECISION +#undef DECLARE_GET_FROM_JSON_EACH_PARAM_RGATE_WITH_PRECISION } // namespace internal #ifdef SCALUQ_USE_NANOBIND namespace internal { -template +template void bind_gate_param_gate_standard_hpp(nb::module_& m) { DEF_PARAM_GATE( ParamRXGate, - Fp, + Prec, "Specific class of parametric X rotation gate, represented as " "$e^{-i\\frac{\\mathrm{angle}}{2}X}$. `angle` is given as `param * param_coef`."); DEF_PARAM_GATE( ParamRYGate, - Fp, + Prec, "Specific class of parametric Y rotation gate, represented as " "$e^{-i\\frac{\\mathrm{angle}}{2}Y}$. `angle` is given as `param * param_coef`."); DEF_PARAM_GATE( ParamRZGate, - Fp, + Prec, "Specific class of parametric Z rotation gate, represented as " "$e^{-i\\frac{\\mathrm{angle}}{2}Z}$. `angle` is given as `param * param_coef`."); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 49951f52..81900fe2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,16 +3,16 @@ cmake_minimum_required(VERSION 3.21) target_sources(scaluq PRIVATE #circuit/circuit.cpp #gate/merge_gate.cpp - #gate/gate_matrix.cpp - #gate/gate_pauli.cpp - #gate/gate_probablistic.cpp - #gate/gate_standard.cpp - #gate/gate.cpp - #gate/param_gate.cpp - #gate/param_gate_pauli.cpp - #gate/param_gate_probablistic.cpp - #gate/param_gate_standard.cpp - #gate/param_gate.cpp + gate/gate_matrix.cpp + gate/gate_pauli.cpp + gate/gate_probablistic.cpp + gate/gate_standard.cpp + gate/gate.cpp + gate/param_gate.cpp + gate/param_gate_pauli.cpp + gate/param_gate_probablistic.cpp + gate/param_gate_standard.cpp + gate/param_gate.cpp gate/update_ops_dense_matrix.cpp gate/update_ops_sparse_matrix.cpp gate/update_ops_standard.cpp diff --git a/src/gate/gate_matrix.cpp b/src/gate/gate_matrix.cpp index c1e2bc6a..b678245c 100644 --- a/src/gate/gate_matrix.cpp +++ b/src/gate/gate_matrix.cpp @@ -10,7 +10,7 @@ DenseMatrixGateImpl::DenseMatrixGateImpl(std::uint64_t target_mask, const ComplexMatrix& mat, bool is_unitary) : GateBase(target_mask, control_mask), - _matrix(convert_external_matrix_to_internal_matrix(mat)), + _matrix(convert_external_matrix_to_internal_matrix(mat)), _is_unitary(is_unitary) {} template std::shared_ptr> DenseMatrixGateImpl::get_inverse() const { @@ -59,7 +59,7 @@ SparseMatrixGateImpl::SparseMatrixGateImpl(std::uint64_t target_mask, std::uint64_t control_mask, const SparseComplexMatrix& mat) : GateBase(target_mask, control_mask), - _matrix(SparseMatrix(mat)), + _matrix(SparseMatrix(mat)), num_nnz(mat.nonZeros()) {} template std::shared_ptr> SparseMatrixGateImpl::get_inverse() const { diff --git a/src/gate/gate_pauli.cpp b/src/gate/gate_pauli.cpp index 2007a953..299cb063 100644 --- a/src/gate/gate_pauli.cpp +++ b/src/gate/gate_pauli.cpp @@ -8,12 +8,17 @@ namespace scaluq::internal { template void PauliGateImpl::update_quantum_state(StateVector& state_vector) const { auto [bit_flip_mask, phase_flip_mask] = _pauli.get_XZ_mask_representation(); - apply_pauli(this->_control_mask, bit_flip_mask, phase_flip_mask, _pauli.coef(), state_vector); + apply_pauli(this->_control_mask, + bit_flip_mask, + phase_flip_mask, + Complex(_pauli.coef()), + state_vector); } template void PauliGateImpl::update_quantum_state(StateVectorBatched& states) const { auto [bit_flip_mask, phase_flip_mask] = _pauli.get_XZ_mask_representation(); - apply_pauli(this->_control_mask, bit_flip_mask, phase_flip_mask, _pauli.coef(), states); + apply_pauli( + this->_control_mask, bit_flip_mask, phase_flip_mask, Complex(_pauli.coef()), states); } template std::string PauliGateImpl::to_string(const std::string& indent) const { @@ -33,7 +38,7 @@ template ComplexMatrix PauliRotationGateImpl::get_matrix() const { ComplexMatrix mat = this->_pauli.get_matrix_ignoring_coef(); StdComplex true_angle = static_cast(_angle) * _pauli.coef(); - StdComplex half_angle = true_angle / 2; + StdComplex half_angle = true_angle / 2.; StdComplex imag_unit(0, 1); mat = std::cos(-half_angle) * ComplexMatrix::Identity(mat.rows(), mat.cols()) + imag_unit * std::sin(-half_angle) * mat; @@ -42,14 +47,22 @@ ComplexMatrix PauliRotationGateImpl::get_matrix() const { template void PauliRotationGateImpl::update_quantum_state(StateVector& state_vector) const { auto [bit_flip_mask, phase_flip_mask] = _pauli.get_XZ_mask_representation(); - apply_pauli_rotation( - this->_control_mask, bit_flip_mask, phase_flip_mask, _pauli.coef(), _angle, state_vector); + apply_pauli_rotation(this->_control_mask, + bit_flip_mask, + phase_flip_mask, + Complex(_pauli.coef()), + _angle, + state_vector); } template void PauliRotationGateImpl::update_quantum_state(StateVectorBatched& states) const { auto [bit_flip_mask, phase_flip_mask] = _pauli.get_XZ_mask_representation(); - apply_pauli_rotation( - this->_control_mask, bit_flip_mask, phase_flip_mask, _pauli.coef(), _angle, states); + apply_pauli_rotation(this->_control_mask, + bit_flip_mask, + phase_flip_mask, + Complex(_pauli.coef()), + _angle, + states); } template std::string PauliRotationGateImpl::to_string(const std::string& indent) const { diff --git a/src/gate/gate_standard.cpp b/src/gate/gate_standard.cpp index e867632b..a4139753 100644 --- a/src/gate/gate_standard.cpp +++ b/src/gate/gate_standard.cpp @@ -44,7 +44,7 @@ template std::string GlobalPhaseGateImpl::to_string(const std::string& indent) const { std::ostringstream ss; ss << indent << "Gate Type: GlobalPhase\n"; - ss << indent << " Phase: " << _phase << "\n"; + ss << indent << " Phase: " << static_cast(_phase) << "\n"; ss << this->get_qubit_info_as_string(indent); return ss.str(); } @@ -329,8 +329,7 @@ SCALUQ_DECLARE_CLASS_FOR_PRECISION(SqrtYGateImpl) template ComplexMatrix SqrtYdagGateImpl::get_matrix() const { ComplexMatrix mat(2, 2); - mat << StdComplex(half, -half), StdComplex(half, -half), StdComplex(-half, half), - StdComplex(half, -half); + mat << StdComplex(.5, -.5), StdComplex(.5, -.5), StdComplex(-.5, .5), StdComplex(.5, -.5); return mat; } template @@ -460,7 +459,7 @@ SCALUQ_DECLARE_CLASS_FOR_PRECISION(RYGateImpl) template ComplexMatrix RZGateImpl::get_matrix() const { ComplexMatrix mat(2, 2); - double half_angle = static_cast(this->_angle / 2); + double half_angle = static_cast(this->_angle) / 2; mat << std::exp(StdComplex(0, -half_angle)), 0, 0, std::exp(StdComplex(0, half_angle)); return mat; } diff --git a/src/gate/param_gate.cpp b/src/gate/param_gate.cpp index 5174e546..7c34a3e4 100644 --- a/src/gate/param_gate.cpp +++ b/src/gate/param_gate.cpp @@ -3,8 +3,9 @@ #include "../util/template.hpp" namespace scaluq::internal { -FLOAT(Fp) -void ParamGateBase::check_qubit_mask_within_bounds(const StateVector& state_vector) const { +template +void ParamGateBase::check_qubit_mask_within_bounds( + const StateVector& state_vector) const { std::uint64_t full_mask = (1ULL << state_vector.n_qubits()) - 1; if ((_target_mask | _control_mask) > full_mask) [[unlikely]] { throw std::runtime_error( @@ -12,8 +13,9 @@ void ParamGateBase::check_qubit_mask_within_bounds(const StateVector& st "Target/Control qubit exceeds the number of qubits in the system."); } } -FLOAT(Fp) -void ParamGateBase::check_qubit_mask_within_bounds(const StateVectorBatched& states) const { +template +void ParamGateBase::check_qubit_mask_within_bounds( + const StateVectorBatched& states) const { std::uint64_t full_mask = (1ULL << states.n_qubits()) - 1; if ((_target_mask | _control_mask) > full_mask) [[unlikely]] { throw std::runtime_error( @@ -21,12 +23,12 @@ void ParamGateBase::check_qubit_mask_within_bounds(const StateVectorBatched< "Target/Control qubit exceeds the number of qubits in the system."); } } -FLOAT(Fp) -std::string ParamGateBase::get_qubit_info_as_string(const std::string& indent) const { +template +std::string ParamGateBase::get_qubit_info_as_string(const std::string& indent) const { std::ostringstream ss; auto targets = target_qubit_list(); auto controls = control_qubit_list(); - ss << indent << " Parameter Coefficient: " << _pcoef << "\n"; + ss << indent << " Parameter Coefficient: " << static_cast(_pcoef) << "\n"; ss << indent << " Target Qubits: {"; for (std::uint32_t i = 0; i < targets.size(); ++i) ss << targets[i] << (i == targets.size() - 1 ? "" : ", "); @@ -37,10 +39,10 @@ std::string ParamGateBase::get_qubit_info_as_string(const std::string& inden ss << "}"; return ss.str(); } -FLOAT(Fp) -ParamGateBase::ParamGateBase(std::uint64_t target_mask, - std::uint64_t control_mask, - Fp param_coef) +template +ParamGateBase::ParamGateBase(std::uint64_t target_mask, + std::uint64_t control_mask, + Float param_coef) : _target_mask(target_mask), _control_mask(control_mask), _pcoef(param_coef) { if (_target_mask & _control_mask) [[unlikely]] { throw std::runtime_error( @@ -48,5 +50,5 @@ ParamGateBase::ParamGateBase(std::uint64_t target_mask, "control_mask) : Target and control qubits must not overlap."); } } -FLOAT_DECLARE_CLASS(ParamGateBase) +SCALUQ_DECLARE_CLASS_FOR_PRECISION(ParamGateBase) } // namespace scaluq::internal diff --git a/src/gate/param_gate_pauli.cpp b/src/gate/param_gate_pauli.cpp index 66e410e5..705b8a58 100644 --- a/src/gate/param_gate_pauli.cpp +++ b/src/gate/param_gate_pauli.cpp @@ -5,43 +5,44 @@ #include "../util/template.hpp" namespace scaluq::internal { -FLOAT(Fp) -ComplexMatrix ParamPauliRotationGateImpl::get_matrix(Fp param) const { - Fp angle = this->_pcoef * param; - Complex true_angle = angle * this->_pauli.coef(); - Complex half_angle = true_angle / Fp{2}; - internal::ComplexMatrix mat = this->_pauli.get_matrix_ignoring_coef(); - StdComplex imag_unit(0, 1); - mat = (StdComplex)internal::cos(-half_angle) * - internal::ComplexMatrix::Identity(mat.rows(), mat.cols()) + - imag_unit * (StdComplex)internal::sin(-half_angle) * mat; +template +ComplexMatrix ParamPauliRotationGateImpl::get_matrix(double param) const { + double angle = static_cast(this->_pcoef) * param; + StdComplex true_angle = angle * this->_pauli.coef(); + StdComplex half_angle = true_angle / 2.; + ComplexMatrix mat = this->_pauli.get_matrix_ignoring_coef(); + StdComplex imag_unit(0, 1); + mat = std::cos(-half_angle) * ComplexMatrix::Identity(mat.rows(), mat.cols()) + + imag_unit * std::sin(-half_angle) * mat; return mat; } -FLOAT(Fp) -void ParamPauliRotationGateImpl::update_quantum_state(StateVector& state_vector, - Fp param) const { +template +void ParamPauliRotationGateImpl::update_quantum_state(StateVector& state_vector, + double param) const { auto [bit_flip_mask, phase_flip_mask] = _pauli.get_XZ_mask_representation(); apply_pauli_rotation(this->_control_mask, bit_flip_mask, phase_flip_mask, - _pauli.coef(), - this->_pcoef * param, + Complex(_pauli.coef()), + this->_pcoef * Float{param}, state_vector); } -FLOAT(Fp) -void ParamPauliRotationGateImpl::update_quantum_state(StateVectorBatched& states, - std::vector params) const { +template +void ParamPauliRotationGateImpl::update_quantum_state(StateVectorBatched& states, + std::vector params) const { auto [bit_flip_mask, phase_flip_mask] = _pauli.get_XZ_mask_representation(); + std::vector> params_prec(params.size()); + std::ranges::transform(params, params_prec.begin(), [](double p) { return Float{p}; }); apply_pauli_rotation(this->_control_mask, bit_flip_mask, phase_flip_mask, - _pauli.coef(), + Complex(_pauli.coef()), this->_pcoef, - params, + params_prec, states); } -FLOAT(Fp) -std::string ParamPauliRotationGateImpl::to_string(const std::string& indent) const { +template +std::string ParamPauliRotationGateImpl::to_string(const std::string& indent) const { std::ostringstream ss; auto controls = this->control_qubit_list(); ss << indent << "Gate Type: ParamPauliRotation\n"; @@ -52,5 +53,5 @@ std::string ParamPauliRotationGateImpl::to_string(const std::string& indent) ss << indent << " Pauli Operator: \"" << _pauli.get_pauli_string() << "\""; return ss.str(); } -FLOAT_DECLARE_CLASS(ParamPauliRotationGateImpl) +SCALUQ_DECLARE_CLASS_FOR_PRECISION(ParamPauliRotationGateImpl) } // namespace scaluq::internal diff --git a/src/gate/param_gate_probablistic.cpp b/src/gate/param_gate_probablistic.cpp index db662c6a..d93395b8 100644 --- a/src/gate/param_gate_probablistic.cpp +++ b/src/gate/param_gate_probablistic.cpp @@ -3,11 +3,11 @@ #include "../util/template.hpp" namespace scaluq::internal { -FLOAT(Fp) -ParamProbablisticGateImpl::ParamProbablisticGateImpl( +template +ParamProbablisticGateImpl::ParamProbablisticGateImpl( const std::vector& distribution, - const std::vector, ParamGate>>& gate_list) - : ParamGateBase(0, 0), _distribution(distribution), _gate_list(gate_list) { + const std::vector, ParamGate>>& gate_list) + : ParamGateBase(0, 0), _distribution(distribution), _gate_list(gate_list) { std::uint64_t n = distribution.size(); if (n == 0) { throw std::runtime_error("At least one gate is required."); @@ -22,8 +22,8 @@ ParamProbablisticGateImpl::ParamProbablisticGateImpl( throw std::runtime_error("Sum of distribution must be equal to 1."); } } -FLOAT(Fp) -std::shared_ptr> ParamProbablisticGateImpl::get_inverse() const { +template +std::shared_ptr> ParamProbablisticGateImpl::get_inverse() const { std::vector inv_gate_list; inv_gate_list.reserve(_gate_list.size()); std::ranges::transform( @@ -32,9 +32,9 @@ std::shared_ptr> ParamProbablisticGateImpl::get_inve }); return std::make_shared(_distribution, inv_gate_list); } -FLOAT(Fp) -void ParamProbablisticGateImpl::update_quantum_state(StateVector& state_vector, - Fp param) const { +template +void ParamProbablisticGateImpl::update_quantum_state(StateVector& state_vector, + double param) const { Random random; double r = random.uniform(); std::uint64_t i = std::distance(_cumulative_distribution.begin(), @@ -48,9 +48,9 @@ void ParamProbablisticGateImpl::update_quantum_state(StateVector& state_ std::get<1>(gate)->update_quantum_state(state_vector, param); } } -FLOAT(Fp) -void ParamProbablisticGateImpl::update_quantum_state(StateVectorBatched& states, - std::vector params) const { +template +void ParamProbablisticGateImpl::update_quantum_state(StateVectorBatched& states, + std::vector params) const { Random random; std::vector r(states.batch_size()); std::ranges::generate(r, [&random]() { return random.uniform(); }); @@ -66,7 +66,7 @@ void ParamProbablisticGateImpl::update_quantum_state(StateVectorBatched& }); for (std::size_t i = 0; i < states.batch_size(); ++i) { const auto& gate = _gate_list[indicies[i]]; - auto state_vector = StateVector(Kokkos::subview(states._raw, i, Kokkos::ALL)); + auto state_vector = StateVector(Kokkos::subview(states._raw, i, Kokkos::ALL)); if (gate.index() == 0) { std::get<0>(gate)->update_quantum_state(state_vector); } else { @@ -74,8 +74,8 @@ void ParamProbablisticGateImpl::update_quantum_state(StateVectorBatched& } } } -FLOAT(Fp) -std::string ParamProbablisticGateImpl::to_string(const std::string& indent) const { +template +std::string ParamProbablisticGateImpl::to_string(const std::string& indent) const { std::ostringstream ss; const auto dist = distribution(); ss << indent << "Gate Type: Probablistic\n"; @@ -90,5 +90,5 @@ std::string ParamProbablisticGateImpl::to_string(const std::string& indent) } return ss.str(); } -FLOAT_DECLARE_CLASS(ParamProbablisticGateImpl) +SCALUQ_DECLARE_CLASS_FOR_PRECISION(ParamProbablisticGateImpl) } // namespace scaluq::internal diff --git a/src/gate/param_gate_standard.cpp b/src/gate/param_gate_standard.cpp index 7c8bd620..32934e7f 100644 --- a/src/gate/param_gate_standard.cpp +++ b/src/gate/param_gate_standard.cpp @@ -5,90 +5,100 @@ #include "update_ops.hpp" namespace scaluq::internal { -FLOAT(Fp) -ComplexMatrix ParamRXGateImpl::get_matrix(Fp param) const { - Fp angle = this->_pcoef * param; - Fp half_angle = angle / Fp{2}; - internal::ComplexMatrix mat(2, 2); - mat << internal::cos(half_angle), StdComplex(0, -internal::sin(half_angle)), - StdComplex(0, -internal::sin(half_angle)), internal::cos(half_angle); +template +ComplexMatrix ParamRXGateImpl::get_matrix(double param) const { + double angle = static_cast(this->_pcoef) * param; + double half_angle = angle / 2; + ComplexMatrix mat(2, 2); + mat << std::cos(half_angle), StdComplex(0, -std::sin(half_angle)), + StdComplex(0, -std::sin(half_angle)), std::cos(half_angle); return mat; } -FLOAT(Fp) -void ParamRXGateImpl::update_quantum_state(StateVector& state_vector, Fp param) const { +template +void ParamRXGateImpl::update_quantum_state(StateVector& state_vector, + double param) const { this->check_qubit_mask_within_bounds(state_vector); - rx_gate(this->_target_mask, this->_control_mask, this->_pcoef * param, state_vector); + rx_gate( + this->_target_mask, this->_control_mask, this->_pcoef * Float{param}, state_vector); } -FLOAT(Fp) -void ParamRXGateImpl::update_quantum_state(StateVectorBatched& states, - std::vector params) const { +template +void ParamRXGateImpl::update_quantum_state(StateVectorBatched& states, + std::vector params) const { this->check_qubit_mask_within_bounds(states); - rx_gate(this->_target_mask, this->_control_mask, this->_pcoef, params, states); + std::vector> params_prec(params.size()); + std::ranges::transform(params, params_prec.begin(), [](double p) { return Float{p}; }); + rx_gate(this->_target_mask, this->_control_mask, this->_pcoef, params_prec, states); } -FLOAT(Fp) -std::string ParamRXGateImpl::to_string(const std::string& indent) const { +template +std::string ParamRXGateImpl::to_string(const std::string& indent) const { std::ostringstream ss; ss << indent << "Gate Type: ParamRX\n"; ss << this->get_qubit_info_as_string(indent); return ss.str(); } -FLOAT_DECLARE_CLASS(ParamRXGateImpl) +SCALUQ_DECLARE_CLASS_FOR_PRECISION(ParamRXGateImpl) -FLOAT(Fp) -ComplexMatrix ParamRYGateImpl::get_matrix(Fp param) const { - Fp angle = this->_pcoef * param; - Fp half_angle = angle / Fp{2}; - internal::ComplexMatrix mat(2, 2); - mat << internal::cos(half_angle), -internal::sin(half_angle), internal::sin(half_angle), - internal::cos(half_angle); +template +ComplexMatrix ParamRYGateImpl::get_matrix(double param) const { + double angle = static_cast(this->_pcoef) * param; + double half_angle = angle / 2; + ComplexMatrix mat(2, 2); + mat << std::cos(half_angle), -std::sin(half_angle), std::sin(half_angle), std::cos(half_angle); return mat; } -FLOAT(Fp) -void ParamRYGateImpl::update_quantum_state(StateVector& state_vector, Fp param) const { +template +void ParamRYGateImpl::update_quantum_state(StateVector& state_vector, + double param) const { this->check_qubit_mask_within_bounds(state_vector); - ry_gate(this->_target_mask, this->_control_mask, this->_pcoef * param, state_vector); + ry_gate( + this->_target_mask, this->_control_mask, this->_pcoef * Float{param}, state_vector); } -FLOAT(Fp) -void ParamRYGateImpl::update_quantum_state(StateVectorBatched& states, - std::vector params) const { +template +void ParamRYGateImpl::update_quantum_state(StateVectorBatched& states, + std::vector params) const { this->check_qubit_mask_within_bounds(states); - ry_gate(this->_target_mask, this->_control_mask, this->_pcoef, params, states); + std::vector> params_prec(params.size()); + std::ranges::transform(params, params_prec.begin(), [](double p) { return Float{p}; }); + ry_gate(this->_target_mask, this->_control_mask, this->_pcoef, params_prec, states); } -FLOAT(Fp) -std::string ParamRYGateImpl::to_string(const std::string& indent) const { +template +std::string ParamRYGateImpl::to_string(const std::string& indent) const { std::ostringstream ss; ss << indent << "Gate Type: ParamRY\n"; ss << this->get_qubit_info_as_string(indent); return ss.str(); } -FLOAT_DECLARE_CLASS(ParamRYGateImpl) +SCALUQ_DECLARE_CLASS_FOR_PRECISION(ParamRYGateImpl) -FLOAT(Fp) -ComplexMatrix ParamRZGateImpl::get_matrix(Fp param) const { - Fp angle = this->_pcoef * param; - Fp half_angle = angle / Fp{2}; - internal::ComplexMatrix mat(2, 2); - mat << internal::exp(Complex(0, -half_angle)), 0, 0, - internal::exp(Complex(0, half_angle)); +template +ComplexMatrix ParamRZGateImpl::get_matrix(double param) const { + double angle = static_cast(this->_pcoef) * param; + double half_angle = angle / 2; + ComplexMatrix mat(2, 2); + mat << std::exp(StdComplex(0, -half_angle)), 0, 0, std::exp(StdComplex(0, half_angle)); return mat; } -FLOAT(Fp) -void ParamRZGateImpl::update_quantum_state(StateVector& state_vector, Fp param) const { +template +void ParamRZGateImpl::update_quantum_state(StateVector& state_vector, + double param) const { this->check_qubit_mask_within_bounds(state_vector); - rz_gate(this->_target_mask, this->_control_mask, this->_pcoef * param, state_vector); + rz_gate( + this->_target_mask, this->_control_mask, this->_pcoef * Float{param}, state_vector); } -FLOAT(Fp) -void ParamRZGateImpl::update_quantum_state(StateVectorBatched& states, - std::vector params) const { +template +void ParamRZGateImpl::update_quantum_state(StateVectorBatched& states, + std::vector params) const { this->check_qubit_mask_within_bounds(states); - rz_gate(this->_target_mask, this->_control_mask, this->_pcoef, params, states); + std::vector> params_prec(params.size()); + std::ranges::transform(params, params_prec.begin(), [](double p) { return Float{p}; }); + rz_gate(this->_target_mask, this->_control_mask, this->_pcoef, params_prec, states); } -FLOAT(Fp) -std::string ParamRZGateImpl::to_string(const std::string& indent) const { +template +std::string ParamRZGateImpl::to_string(const std::string& indent) const { std::ostringstream ss; ss << indent << "Gate Type: ParamRZ\n"; ss << this->get_qubit_info_as_string(indent); return ss.str(); } -FLOAT_DECLARE_CLASS(ParamRZGateImpl) +SCALUQ_DECLARE_CLASS_FOR_PRECISION(ParamRZGateImpl) } // namespace scaluq::internal