diff --git a/exe/main.cpp b/exe/main.cpp index 7354deb2..cb4a5f46 100644 --- a/exe/main.cpp +++ b/exe/main.cpp @@ -13,8 +13,18 @@ using namespace scaluq; using namespace std; void run() { - std::uint64_t n_qubits = 5; - auto state = StateVector::Haar_random_state(n_qubits); + auto x_gate = gate::X(2); + std::cout << x_gate << std::endl; + auto y_gate = gate::Y(2); + std::cout << y_gate << std::endl; + auto swap_gate = gate::Swap(2, 3, {4, 6}); + std::cout << swap_gate << "\n\n"; + + auto prob_gate = gate::Probablistic({0.1, 0.1, 0.8}, {x_gate, y_gate, swap_gate}); + std::cout << prob_gate << "\n\n"; + + auto prob_prob_gate = gate::Probablistic({0.5, 0.5}, {x_gate, prob_gate}); + std::cout << prob_prob_gate << "\n\n"; } int main() { diff --git a/scaluq/gate/gate.hpp b/scaluq/gate/gate.hpp index 527402df..64e77d7b 100644 --- a/scaluq/gate/gate.hpp +++ b/scaluq/gate/gate.hpp @@ -43,6 +43,7 @@ class SwapGateImpl; class TwoTargetMatrixGateImpl; class PauliGateImpl; class PauliRotationGateImpl; +class ProbablisticGateImpl; template class GatePtr; @@ -80,7 +81,8 @@ enum class GateType { Swap, TwoTargetMatrix, Pauli, - PauliRotation + PauliRotation, + Probablistic }; template @@ -119,6 +121,7 @@ constexpr GateType get_gate_type() { if constexpr (std::is_same_v) return GateType::Pauli; if constexpr (std::is_same_v) return GateType::PauliRotation; + if constexpr (std::is_same_v) return GateType::Probablistic; static_assert("unknown GateImpl"); return GateType::Unknown; } @@ -226,6 +229,8 @@ class GatePtr { } return _gate_ptr.get(); } + + // 依存関係により、operator<< の定義は gate_factory.hpp に定義 }; } // namespace internal diff --git a/scaluq/gate/gate_factory.hpp b/scaluq/gate/gate_factory.hpp index 6ed1580c..b6026b60 100644 --- a/scaluq/gate/gate_factory.hpp +++ b/scaluq/gate/gate_factory.hpp @@ -215,4 +215,135 @@ inline Gate Probablistic(const std::vector& distribution, gate_list); } } // namespace gate + +template +std::ostream& operator<<(std::ostream& os, const internal::GatePtr& obj) { + std::string indent = " "; + if (obj.gate_type() == GateType::Probablistic) { + const auto prob_gate = ProbablisticGate(obj); + const auto distribution = prob_gate->distribution(); + const auto gates = prob_gate->gate_list(); + os << "Gate Type: Probablistic\n"; + for (std::size_t i = 0; i < distribution.size(); ++i) { + std::ostringstream gate_ss; + gate_ss << gates[i]; + std::istringstream gate_is(gate_ss.str()); + std::string line; + // os << indent << "--------------------\n"; + os << indent << "Probability: " << distribution[i] << "\n"; + while (std::getline(gate_is, line)) { + os << indent << line << (gate_is.peek() == EOF ? "" : "\n"); + } + } + return os; + } + auto targets = internal::mask_to_vector(obj->target_qubit_mask()); + auto controls = internal::mask_to_vector(obj->control_qubit_mask()); + os << "Gate Type: "; + switch (obj.gate_type()) { + case GateType::I: + os << "I"; + break; + case GateType::GlobalPhase: + os << "GlobalPhase"; + break; + case GateType::X: + os << "X"; + break; + case GateType::Y: + os << "Y"; + break; + case GateType::Z: + os << "Z"; + break; + case GateType::H: + os << "H"; + break; + case GateType::S: + os << "S"; + break; + case GateType::Sdag: + os << "Sdag"; + break; + case GateType::T: + os << "T"; + break; + case GateType::Tdag: + os << "Tdag"; + break; + case GateType::SqrtX: + os << "SqrtX"; + break; + case GateType::SqrtXdag: + os << "SqrtXdag"; + break; + case GateType::SqrtY: + os << "SqrtY"; + break; + case GateType::SqrtYdag: + os << "SqrtYdag"; + break; + case GateType::P0: + os << "P0"; + break; + case GateType::P1: + os << "P1"; + break; + case GateType::RX: + os << "RX"; + break; + case GateType::RY: + os << "RY"; + break; + case GateType::RZ: + os << "RZ"; + break; + case GateType::U1: + os << "U1"; + break; + case GateType::U2: + os << "U2"; + break; + case GateType::U3: + os << "U3"; + break; + case GateType::OneTargetMatrix: + os << "OneTargetMatrix"; + break; + case GateType::CX: + os << "CX"; + break; + case GateType::CZ: + os << "CZ"; + break; + case GateType::CCX: + os << "CCX"; + break; + case GateType::Swap: + os << "Swap"; + break; + case GateType::TwoTargetMatrix: + os << "TwoTargetMatrix"; + break; + case GateType::Pauli: + os << "Pauli"; + break; + case GateType::PauliRotation: + os << "PauliRotation"; + break; + case GateType::Unknown: + default: + os << "Unknown"; + break; + } + os << "\n" << indent << "Target Qubits: {"; + for (std::uint32_t i = 0; i < targets.size(); ++i) + os << targets[i] << (i == targets.size() - 1 ? "" : ", "); + os << "}\n" << indent << "Control Qubits: {"; + for (std::uint32_t i = 0; i < controls.size(); ++i) + os << controls[i] << (i == controls.size() - 1 ? "" : ", "); + os << "}"; + return os; +} + } // namespace scaluq diff --git a/scaluq/gate/param_gate.hpp b/scaluq/gate/param_gate.hpp index edc159dd..e34c9e3a 100644 --- a/scaluq/gate/param_gate.hpp +++ b/scaluq/gate/param_gate.hpp @@ -142,6 +142,43 @@ class ParamGatePtr { } return _param_gate_ptr.get(); } + + friend std::ostream& operator<<(std::ostream& os, const ParamGatePtr& obj) { + if (!obj._param_gate_ptr) { + os << "Gate Type: Null"; + return os; + } + auto targets = internal::mask_to_vector(obj->target_qubit_mask()); + auto controls = internal::mask_to_vector(obj->control_qubit_mask()); + os << "Gate Type: "; + switch (obj.param_gate_type()) { + case ParamGateType::ParamRX: + os << "ParamRX"; + break; + case ParamGateType::ParamRY: + os << "ParamRY"; + break; + case ParamGateType::ParamRZ: + os << "ParamRZ"; + break; + case ParamGateType::ParamPauliRotation: + os << "ParamPauliRotation"; + break; + default: + os << "Undefined"; + break; + } + os << "\n" + "Target Qubits: {"; + for (std::uint32_t i = 0; i < targets.size(); ++i) + os << targets[i] << (i == targets.size() - 1 ? "" : ", "); + os << "}\n" + "Control Qubits: {"; + for (std::uint32_t i = 0; i < controls.size(); ++i) + os << controls[i] << (i == controls.size() - 1 ? "" : ", "); + os << "}"; + return os; + } }; } // namespace internal diff --git a/scaluq/state/state_vector.cpp b/scaluq/state/state_vector.cpp index 440c2419..2913ba21 100644 --- a/scaluq/state/state_vector.cpp +++ b/scaluq/state/state_vector.cpp @@ -233,7 +233,7 @@ std::string StateVector::to_string() const { } return tmp; }(i, _n_qubits) - << ": " << amp[i] << std::endl; + << ": " << amp[i] << (i < _dim - 1 ? "\n" : ""); } return os.str(); } diff --git a/scaluq/state/state_vector_batched.cpp b/scaluq/state/state_vector_batched.cpp index f56fc861..782a0fc9 100644 --- a/scaluq/state/state_vector_batched.cpp +++ b/scaluq/state/state_vector_batched.cpp @@ -367,7 +367,7 @@ std::string StateVectorBatched::to_string() const { for (std::uint64_t b = 0; b < _batch_size; ++b) { StateVector tmp(_n_qubits); os << "--------------------\n"; - os << " * Batch_id : " << b << '\n'; + os << " * Batch id : " << b << '\n'; os << " * State vector : \n"; for (std::uint64_t i = 0; i < _dim; ++i) { os << @@ -378,7 +378,7 @@ std::string StateVectorBatched::to_string() const { } return tmp; }(i, _n_qubits) - << ": " << states_h(b, i) << std::endl; + << ": " << states_h(b, i) << (b < _batch_size - 1 || i < _dim - 1 ? "\n" : ""); } } return os.str();