diff --git a/include/scaluq/gate/gate_factory.hpp b/include/scaluq/gate/gate_factory.hpp index 5fb7904..aee21d0 100644 --- a/include/scaluq/gate/gate_factory.hpp +++ b/include/scaluq/gate/gate_factory.hpp @@ -238,179 +238,535 @@ inline Gate Probablistic(const std::vector& distribution, namespace internal { template void bind_gate_gate_factory_hpp(nb::module_& mgate) { - mgate.def("I", &gate::I, "Generate general Gate class instance of I."); - mgate.def("GlobalPhase", - &gate::GlobalPhase, - "Generate general Gate class instance of GlobalPhase.", - "phase"_a, - "controls"_a = std::vector{}); - mgate.def("X", - &gate::X, - "Generate general Gate class instance of X.", - "target"_a, - "controls"_a = std::vector{}); - mgate.def("Y", - &gate::Y, - "Generate general Gate class instance of Y.", - "taget"_a, - "controls"_a = std::vector{}); - mgate.def("Z", - &gate::Z, - "Generate general Gate class instance of Z.", - "target"_a, - "controls"_a = std::vector{}); - mgate.def("H", - &gate::H, - "Generate general Gate class instance of H.", - "target"_a, - "controls"_a = std::vector{}); - mgate.def("S", - &gate::S, - "Generate general Gate class instance of S.", - "target"_a, - "controls"_a = std::vector{}); + mgate.def("I", + &gate::I, + DocString() + .desc("Generate identity gate.") + .ret("Gate", "Identity gate instance") + .ex(DocString::Code({">>> gate = I()", ">>> print(gate)", "Identity Gate"})) + .build_as_google_style() + .c_str()); + mgate.def( + "GlobalPhase", + &gate::GlobalPhase, + "phase"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate global phase gate.") + .arg("phase", "float", "Global phase angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Global phase gate instance") + .ex(DocString::Code( + {">>> gate = GlobalPhase(math.pi/2)", ">>> print(gate)", "Global Phase Gate"})) + .build_as_google_style() + .c_str()); + mgate.def( + "X", + &gate::X, + "target"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate Pauli-X (NOT) gate.") + .desc("Performs bit flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Pauli-X gate instance") + .ex(DocString::Code({">>> gate = X(0) # X gate on qubit 0", + ">>> gate = X(1, [0]) # Controlled-X with control on qubit 0"})) + .build_as_google_style() + .c_str()); + mgate.def( + "Y", + &gate::Y, + "taget"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate Pauli-Y gate.") + .desc("Performs bit flip and phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Pauli-Y gate instance") + .ex(DocString::Code({">>> gate = Y(0) # Y gate on qubit 0", + ">>> gate = Y(1, [0]) # Controlled-Y with control on qubit 0"})) + .build_as_google_style() + .c_str()); + mgate.def( + "Z", + &gate::Z, + "target"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate Pauli-Z gate.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Pauli-Z gate instance") + .ex(DocString::Code({">>> gate = Z(0) # Z gate on qubit 0", + ">>> gate = Z(1, [0]) # Controlled-Z with control on qubit 0"})) + .build_as_google_style() + .c_str()); + mgate.def( + "H", + &gate::H, + "target"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate Hadamard gate.") + .desc("Performs superposition operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Hadamard gate instance") + .ex(DocString::Code({">>> gate = H(0) # H gate on qubit 0", + ">>> gate = H(1, [0]) # Controlled-H with control on qubit 0"})) + .build_as_google_style() + .c_str()); + mgate.def( + "S", + &gate::S, + "target"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of S.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "S gate instance") + .ex(DocString::Code({">>> gate = S(0) # S gate on qubit 0", + ">>> gate = S(1, [0]) # Controlled-S with control on qubit 0"})) + .build_as_google_style() + .c_str()); mgate.def("Sdag", &gate::Sdag, - "Generate general Gate class instance of Sdag.", - "target"_a, - "controls"_a = std::vector{}); - mgate.def("T", - &gate::T, - "Generate general Gate class instance of T.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of Sdag.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Sdag gate instance") + .ex(DocString::Code( + {">>> gate = Sdag(0) # Sdag gate on qubit 0", + ">>> gate = Sdag(1, [0]) # Controlled-Sdag with control on qubit 0"})) + .build_as_google_style() + .c_str()); + mgate.def( + "T", + &gate::T, + "target"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of T.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "T gate instance") + .ex(DocString::Code({">>> gate = T(0) # T gate on qubit 0", + ">>> gate = T(1, [0]) # Controlled-T with control on qubit 0"})) + .build_as_google_style() + .c_str()); mgate.def("Tdag", &gate::Tdag, - "Generate general Gate class instance of Tdag.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of Tdag.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Tdag gate instance") + .ex(DocString::Code( + {">>> gate = Tdag(0) # Tdag gate on qubit 0", + ">>> gate = Tdag(1, [0]) # Controlled-Tdag with control on qubit 0"})) + .build_as_google_style() + .c_str()); mgate.def("SqrtX", &gate::SqrtX, - "Generate general Gate class instance of SqrtX.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of SqrtX.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "SqrtX gate instance") + .ex(DocString::Code({">>> gate = SqrtX(0) # SqrtX gate on qubit 0", + ">>> gate = SqrtX(1, [0]) # Controlled-SqrtX"})) + .build_as_google_style() + .c_str()); mgate.def("SqrtXdag", &gate::SqrtXdag, - "Generate general Gate class instance of SqrtXdag.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of SqrtXdag.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "SqrtXdag gate instance") + .ex(DocString::Code({">>> gate = SqrtXdag(0) # SqrtXdag gate on qubit 0", + ">>> gate = SqrtXdag(1, [0]) # Controlled-SqrtXdag"})) + .build_as_google_style() + .c_str()); mgate.def("SqrtY", &gate::SqrtY, - "Generate general Gate class instance of SqrtY.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of SqrtY.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "SqrtY gate instance") + .ex(DocString::Code({">>> gate = SqrtY(0) # SqrtY gate on qubit 0", + ">>> gate = SqrtY(1, [0]) # Controlled-SqrtY"})) + .build_as_google_style() + .c_str()); mgate.def("SqrtYdag", &gate::SqrtYdag, - "Generate general Gate class instance of SqrtYdag.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of SqrtYdag.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "SqrtYdag gate instance") + .ex(DocString::Code({">>> gate = SqrtYdag(0) # SqrtYdag gate on qubit 0", + ">>> gate = SqrtYdag(1, [0]) # Controlled-SqrtYdag"})) + .build_as_google_style() + .c_str()); mgate.def("P0", &gate::P0, - "Generate general Gate class instance of P0.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of P0.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "P0 gate instance") + .ex(DocString::Code({">>> gate = P0(0) # P0 gate on qubit 0", + ">>> gate = P0(1, [0]) # Controlled-P0"})) + .build_as_google_style() + .c_str()); mgate.def("P1", &gate::P1, - "Generate general Gate class instance of P1.", "target"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of P1.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "P1 gate instance") + .ex(DocString::Code({">>> gate = P1(0) # P1 gate on qubit 0", + ">>> gate = P1(1, [0]) # Controlled-P1"})) + .build_as_google_style() + .c_str()); mgate.def("RX", &gate::RX, - "Generate general Gate class instance of RX.", "target"_a, "angle"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate rotation gate around X-axis.") + .desc("Rotation angle is specified in radians.") + .arg("target", "int", "Target qubit index") + .arg("angle", "float", "Rotation angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "RX gate instance") + .ex(DocString::Code({">>> gate = RX(0, math.pi/2) # π/2 rotation around X-axis", + ">>> gate = RX(1, math.pi, [0]) # Controlled-RX"})) + .build_as_google_style() + .c_str()); mgate.def("RY", &gate::RY, - "Generate general Gate class instance of RY.", "target"_a, "angle"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate rotation gate around Y-axis.") + .desc("Rotation angle is specified in radians.") + .arg("target", "int", "Target qubit index") + .arg("angle", "float", "Rotation angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "RY gate instance") + .ex(DocString::Code({">>> gate = RY(0, math.pi/2) # π/2 rotation around Y-axis", + ">>> gate = RY(1, math.pi, [0]) # Controlled-RY"})) + .build_as_google_style() + .c_str()); mgate.def("RZ", &gate::RZ, - "Generate general Gate class instance of RZ.", "target"_a, "angle"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate rotation gate around Z-axis.") + .desc("Rotation angle is specified in radians.") + .arg("target", "int", "Target qubit index") + .arg("angle", "float", "Rotation angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "RZ gate instance") + .ex(DocString::Code({">>> gate = RZ(0, math.pi/2) # π/2 rotation around Z-axis", + ">>> gate = RZ(1, math.pi, [0]) # Controlled-RZ"})) + .build_as_google_style() + .c_str()); mgate.def("U1", &gate::U1, - "Generate general Gate class instance of U1.", "target"_a, "lambda_"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of U1.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("lambda_", "float", "Rotation angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "U1 gate instance") + .ex(DocString::Code({">>> gate = U1(0, math.pi/2) # π/2 rotation around Z-axis", + ">>> gate = U1(1, math.pi, [0]) # Controlled-U1"})) + .build_as_google_style() + .c_str()); mgate.def("U2", &gate::U2, - "Generate general Gate class instance of U2.", - "target"_a, - "phi"_a, - "lambda_"_a, - "controls"_a = std::vector{}); - mgate.def("U3", - &gate::U3, - "Generate general Gate class instance of U3.", "target"_a, - "theta"_a, "phi"_a, "lambda_"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of U2.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("phi", "float", "Rotation angle in radians") + .arg("lambda_", "float", "Rotation angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "U2 gate instance") + .ex(DocString::Code( + {">>> gate = U2(0, math.pi/2, math.pi) # π/2 rotation around Z-axis", + ">>> gate = U2(1, math.pi, math.pi/2, [0]) # Controlled-U2"})) + .build_as_google_style() + .c_str()); + mgate.def( + "U3", + &gate::U3, + "target"_a, + "theta"_a, + "phi"_a, + "lambda_"_a, + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of U3.") + .desc("Performs phase flip operation.") + .arg("target", "int", "Target qubit index") + .arg("theta", "float", "Rotation angle in radians") + .arg("phi", "float", "Rotation angle in radians") + .arg("lambda_", "float", "Rotation angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "U3 gate instance") + .ex(DocString::Code( + {">>> gate = U3(0, math.pi/2, math.pi, math.pi) # π/2 rotation around Z-axis", + ">>> gate = U3(1, math.pi, math.pi/2, math.pi, [0]) # Controlled-U3"})) + .build_as_google_style() + .c_str()); mgate.def("Swap", &gate::Swap, - "Generate general Gate class instance of Swap.", "target1"_a, "target2"_a, - "controls"_a = std::vector{}); - mgate.def( - "CX", - &gate::CX, - "Generate general Gate class instance of CX.\n\n.. note:: CX is a specialization of X."); - mgate.def("CNot", + "controls"_a = std::vector{}, + DocString() + .desc("Generate SWAP gate.") + .desc("Swaps the states of two qubits.") + .arg("target1", "int", "First target qubit index") + .arg("target2", "int", "Second target qubit index") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "SWAP gate instance") + .ex(DocString::Code({">>> gate = Swap(0, 1) # Swap qubits 0 and 1", + ">>> gate = Swap(1, 2, [0]) # Controlled-SWAP"})) + .build_as_google_style() + .c_str()); + mgate.def("CX", &gate::CX, - "Generate general Gate class instance of CNot.\n\n.. note:: CNot is an alias of CX."); - mgate.def( - "CZ", - &gate::CZ, - "Generate general Gate class instance of CZ.\n\n.. note:: CZ is a specialization of Z."); + "control"_a, + "target"_a, + DocString() + .desc("Generate general Gate class instance of CX.") + .desc("Performs controlled-X operation.") + .arg("control", "int", "Control qubit index") + .arg("target", "int", "Target qubit index") + .ret("Gate", "CX gate instance") + .ex(DocString::Code({">>> gate = CX(0, 1) # CX gate with control on qubit 0", + ">>> gate = CX(1, 2) # CX gate with control on qubit 1"})) + .build_as_google_style() + .c_str()); mgate.def( - "CCX", - &gate::CCX, - "Generate general Gate class instance of CXX.\n\n.. note:: CX is a specialization of X."); + "CNot", + &gate::CX, + "control"_a, + "target"_a, + DocString() + .desc("Generate general Gate class instance of CNot.") + .desc("Performs controlled-X operation.") + .arg("control", "int", "Control qubit index") + .arg("target", "int", "Target qubit index") + .ret("Gate", "CNot gate instance") + .ex(DocString::Code({">>> gate = CNot(0, 1) # CNot gate with control on qubit 0", + ">>> gate = CNot(1, 2) # CNot gate with control on qubit 1"})) + .build_as_google_style() + .c_str()); + mgate.def("CZ", + &gate::CZ, + "control"_a, + "target"_a, + DocString() + .desc("Generate general Gate class instance of CZ.") + .desc("Performs controlled-Z operation.") + .arg("control", "int", "Control qubit index") + .arg("target", "int", "Target qubit index") + .ret("Gate", "CZ gate instance") + .ex(DocString::Code({">>> gate = CZ(0, 1) # CZ gate with control on qubit 0", + ">>> gate = CZ(1, 2) # CZ gate with control on qubit 1"})) + .build_as_google_style() + .c_str()); + mgate.def("CCX", + &gate::CCX, + "control1"_a, + "control2"_a, + "target"_a, + DocString() + .desc("Generate general Gate class instance of CCX.") + .desc("Performs controlled-controlled-X operation.") + .arg("control1", "int", "First control qubit index") + .arg("control2", "int", "Second control qubit index") + .arg("target", "int", "Target qubit index") + .ret("Gate", "CCX gate instance") + .ex(DocString::Code( + {">>> gate = CCX(0, 1, 2) # CCX gate with controls on qubits 0 and 1", + ">>> gate = CCX(1, 2, 3) # CCX gate with controls on qubits 1 and 2"})) + .build_as_google_style() + .c_str()); + mgate.def("CCNot", + &gate::CCX, + "control1"_a, + "control2"_a, + "target"_a, + DocString() + .desc("Generate general Gate class instance of CCNot.") + .desc("Performs controlled-controlled-X operation.") + .arg("control1", "int", "First control qubit index") + .arg("control2", "int", "Second control qubit index") + .arg("target", "int", "Target qubit index") + .ret("Gate", "CCNot gate instance") + .ex(DocString::Code( + {">>> gate = CCNot(0, 1, 2) # CCNot gate with controls on qubits 0 and 1", + ">>> gate = CCNot(1, 2, 3) # CCNot gate with controls on qubits 1 and 2"})) + .build_as_google_style() + .c_str()); mgate.def( - "CCNot", + "Toffoli", &gate::CCX, - "Generate general Gate class instance of CCNot.\n\n.. note:: CCNot is an alias of CCX."); - mgate.def("Toffoli", - &gate::CCX, - "Generate general Gate class instance of Toffoli.\n\n.. note:: Toffoli is an alias " - "of CCX."); + "control1"_a, + "control2"_a, + "target"_a, + DocString() + .desc("Toffoli is an alias of CCX.") + .desc("Generate general Gate class instance of Toffoli.") + .desc("Performs controlled-controlled-X operation.") + .arg("control1", "int", "First control qubit index") + .arg("control2", "int", "Second control qubit index") + .arg("target", "int", "Target qubit index") + .ret("Gate", "Toffoli gate instance") + .ex(DocString::Code( + {">>> gate = Toffoli(0, 1, 2) # Toffoli gate with controls on qubits 0 and 1", + ">>> gate = Toffoli(1, 2, 3) # Toffoli gate with controls on qubits 1 and 2"})) + .build_as_google_style() + .c_str()); mgate.def("DenseMatrix", &gate::DenseMatrix, - "Generate general Gate class instance of DenseMatrix.", "targets"_a, "matrix"_a, "controls"_a = std::vector{}, - "is_unitary"_a = false); + "is_unitary"_a = false, + DocString() + .desc("Generate general Gate class instance of DenseMatrix.") + .desc("Performs dense matrix operation.") + .arg("targets", "list[int]", "Target qubit indices") + .arg("matrix", "numpy.ndarray", "Matrix to be applied") + .arg("controls", "list[int]", true, "Control qubit indices") + .arg("is_unitary", "bool", true, "Whether the matrix is unitary") + .ret("Gate", "DenseMatrix gate instance") + .ex(DocString::Code( + {">>> matrix = np.array([[1, 0], [0, 1]])", + ">>> gate = DenseMatrix([0], matrix)", + ">>> gate = DenseMatrix([0], matrix, [1]) # Controlled-DenseMatrix"})) + .build_as_google_style() + .c_str()); mgate.def("SparseMatrix", &gate::SparseMatrix, - "Generate general Gate class instance of SparseMatrix.", "targets"_a, "matrix"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of SparseMatrix.") + .desc("Performs sparse matrix operation.") + .arg("targets", "list[int]", "Target qubit indices") + .arg("matrix", "scipy.sparse.csr_matrix", "Matrix to be applied") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "SparseMatrix gate instance") + .ex(DocString::Code( + {">>> matrix = scipy.sparse.csr_matrix([[1, 0], [0, 1]])", + ">>> gate = SparseMatrix([0], matrix)", + ">>> gate = SparseMatrix([0], matrix, [1]) # Controlled-SparseMatrix"})) + .build_as_google_style() + .c_str()); mgate.def("Pauli", &gate::Pauli, - "Generate general Gate class instance of Pauli.", "pauli"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of Pauli.") + .desc("Performs Pauli operation.") + .arg("pauli", "PauliOperator", "Pauli operator") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "Pauli gate instance") + .ex(DocString::Code({">>> pauli = PauliOperator('X', 0)", + ">>> gate = Pauli(pauli)", + ">>> gate = Pauli(pauli, [1]) # Controlled-Pauli"})) + .build_as_google_style() + .c_str()); mgate.def("PauliRotation", &gate::PauliRotation, - "Generate general Gate class instance of PauliRotation.", "pauli"_a, "angle"_a, - "controls"_a = std::vector{}); + "controls"_a = std::vector{}, + DocString() + .desc("Generate general Gate class instance of PauliRotation.") + .desc("Performs Pauli rotation operation.") + .arg("pauli", "PauliOperator", "Pauli operator") + .arg("angle", "float", "Rotation angle in radians") + .arg("controls", "list[int]", true, "Control qubit indices") + .ret("Gate", "PauliRotation gate instance") + .ex(DocString::Code( + {">>> pauli = PauliOperator('X', 0)", + ">>> gate = PauliRotation(pauli, math.pi/2)", + ">>> gate = PauliRotation(pauli, math.pi/2, [1]) # Controlled-Pauli"})) + .build_as_google_style() + .c_str()); mgate.def("Probablistic", &gate::Probablistic, - "Generate general Gate class instance of Probablistic.", "distribution"_a, - "gate_list"_a); + "gate_list"_a, + DocString() + .desc("Generate general Gate class instance of Probablistic.") + .desc("Performs probablistic operation.") + .arg("distribution", "list[float]", "Probablistic distribution") + .arg("gate_list", "list[Gate]", "List of gates") + .ret("Gate", "Probablistic gate instance") + .ex(DocString::Code({">>> distribution = [0.5, 0.5]", + ">>> gate_list = [X(0), Y(0)]", + ">>> gate = Probablistic(distribution, gate_list)"})) + .build_as_google_style() + .c_str()); } } // namespace internal #endif diff --git a/include/scaluq/state/state_vector_batched.hpp b/include/scaluq/state/state_vector_batched.hpp index d5a34b0..4c71b01 100644 --- a/include/scaluq/state/state_vector_batched.hpp +++ b/include/scaluq/state/state_vector_batched.hpp @@ -123,48 +123,132 @@ void bind_state_state_vector_batched_hpp(nb::module_& m) { nb::class_>( m, "StateVectorBatched", - "Batched vector representation of quantum state.\n\n.. note:: Qubit index is start from 0. " - "If the amplitudes of $\\ket{b_{n-1}\\dots b_0}$ is $b_i$, the state is $\\sum_i b_i " - "2^i$.") + DocString() + .desc("Batched vector representation of quantum state.") + .desc("Qubit index starts from 0. If the amplitudes of $\\ket{b_{n-1}\\dots b_0}$ " + "are $b_i$, the state is $\\sum_i b_i 2^i$.") + .build_as_google_style() + .c_str()) + // Constructor: batch size and number of qubits .def(nb::init(), - "Construct batched state vector with specified batch size and qubits.") + "batch_size"_a, + "n_qubits"_a, + DocString() + .desc("Construct batched state vector with specified batch size and qubits.") + .arg("batch_size", "int", "Number of batches.") + .arg("n_qubits", "int", "Number of qubits in each state vector.") + .ex(DocString::Code({">>> states = StateVectorBatched(3, 2)", + ">>> print(states)", + " *** Quantum States ***", + " * Qubit Count : 2", + " * Dimension : 4", + "--------------------", + " * Batch_id : 0", + " * State vector : ", + " 00 : (1,0)\n 01 : (0,0)\n 10 : (0,0)\n 11 : (0,0)", + "--------------------", + " * Batch_id : 1", + " * State vector : ", + " 00 : (1,0)\n 01 : (0,0)\n 10 : (0,0)\n 11 : (0,0)"})) + .build_as_google_style() + .c_str()) + // Constructor: Copy constructor .def(nb::init&>(), - "Constructing batched state vector by copying other batched state.") - .def("n_qubits", &StateVectorBatched::n_qubits, "Get num of qubits.") + "other"_a, + DocString() + .desc("Construct a batched state vector by copying another batched state.") + .arg("other", "StateVectorBatched", "The batched state vector to copy.") + .build_as_google_style() + .c_str()) + // Basic getters + .def("n_qubits", + &StateVectorBatched::n_qubits, + DocString() + .desc("Get the number of qubits in each state vector.") + .ret("int", "The number of qubits.") + .build_as_google_style() + .c_str()) .def("dim", &StateVectorBatched::dim, - "Get dimension of the vector ($=2^\\mathrm{n\\_qubits}$).") - .def("batch_size", &StateVectorBatched::batch_size, "Get batch size.") + DocString() + .desc("Get the dimension of each state vector (=$2^{\\mathrm{n\\_qubits}}$).") + .ret("int", "The dimension of the vector.") + .build_as_google_style() + .c_str()) + .def("batch_size", + &StateVectorBatched::batch_size, + DocString() + .desc("Get the batch size (number of state vectors).") + .ret("int", "The batch size.") + .build_as_google_style() + .c_str()) + // State manipulation methods .def("set_state_vector", - nb::overload_cast&>(&StateVectorBatched::set_state_vector), - "Set the state vector for all batches.") + &StateVectorBatched::set_state_vector, + "state"_a, + DocString() + .desc("Set all state vectors in the batch to the given state.") + .arg("state", "StateVector", "State to set for all batches.") + .build_as_google_style() + .c_str()) .def("set_state_vector_at", - nb::overload_cast&>( - &StateVectorBatched::set_state_vector_at), - "Set the state vector for a specific batch.") + &StateVectorBatched::set_state_vector_at, + "batch_id"_a, + "state"_a, + DocString() + .desc("Set the state vector at a specific batch index.") + .arg("batch_id", "int", "Index in batch to set.") + .arg("state", "StateVector", "State to set at the specified index.") + .build_as_google_style() + .c_str()) .def("get_state_vector_at", &StateVectorBatched::get_state_vector_at, - "Get the state vector for a specific batch.") + "batch_id"_a, + DocString() + .desc("Get the state vector at a specific batch index.") + .arg("batch_id", "int", "Index in batch to get.") + .ret("StateVector", "The state vector at the specified batch index.") + .build_as_google_style() + .c_str()) + // State initialization methods .def("set_zero_state", &StateVectorBatched::set_zero_state, - "Initialize all batches with computational basis $\\ket{00\\dots0}$.") - .def("set_zero_norm_state", - &StateVectorBatched::set_zero_norm_state, - "Initialize with 0 (null vector).") + DocString().desc("Initialize all states to |0...0⟩.").build_as_google_style().c_str()) .def("set_computational_basis", &StateVectorBatched::set_computational_basis, - "Initialize with computational basis \\ket{\\mathrm{basis}}.") + "basis"_a, + DocString() + .desc("Set all states to the specified computational basis state.") + .arg("basis", "int", "Index of the computational basis state.") + .build_as_google_style() + .c_str()) + .def("set_zero_norm_state", + &StateVectorBatched::set_zero_norm_state, + DocString().desc("Set all amplitudes to zero.").build_as_google_style().c_str()) + // Haar random state methods .def( - "sampling", - [](const StateVectorBatched& states, - std::uint64_t sampling_count, + "set_Haar_random_state", + [](StateVectorBatched& states, + std::uint64_t batch_size, + std::uint64_t n_qubits, + bool set_same_state, std::optional seed) { - return states.sampling(sampling_count, seed.value_or(std::random_device{}())); + states.set_Haar_random_state( + batch_size, n_qubits, set_same_state, seed.value_or(std::random_device()())); }, - "sampling_count"_a, + "batch_size"_a, + "n_qubits"_a, + "set_same_state"_a, "seed"_a = std::nullopt, - "Sampling specified times. Result is `list[list[int]]` with the `sampling_count` " - "length.") + DocString() + .desc("Initialize with Haar random states.") + .arg("batch_size", "int", "Number of states in batch.") + .arg("n_qubits", "int", "Number of qubits per state.") + .arg( + "set_same_state", "bool", "Whether to set all states to the same random state.") + .arg("seed", "int, optional", "Random seed (default: random).") + .build_as_google_style() + .c_str()) .def_static( "Haar_random_state", [](std::uint64_t batch_size, @@ -172,57 +256,152 @@ void bind_state_state_vector_batched_hpp(nb::module_& m) { bool set_same_state, std::optional seed) { return StateVectorBatched::Haar_random_state( - batch_size, n_qubits, set_same_state, seed.value_or(std::random_device{}())); + batch_size, n_qubits, set_same_state, seed.value_or(std::random_device()())); }, "batch_size"_a, "n_qubits"_a, "set_same_state"_a, "seed"_a = std::nullopt, - "Construct batched state vectors with Haar random states. If seed is not " - "specified, the value from random device is used.") - .def("get_amplitudes", - &StateVectorBatched::get_amplitudes, - "Get all amplitudes with as `list[list[complex]]`.") + DocString() + .desc("Construct :class:`StateVectorBatched` with Haar random state.") + .arg("batch_size", "int", "Number of states in batch.") + .arg("n_qubits", "int", "Number of qubits per state.") + .arg( + "set_same_state", "bool", "Whether to set all states to the same random state.") + .arg("seed", "int, optional", "Random seed (default: random).") + .ret("StateVectorBatched", "New batched state vector with random states.") + .build_as_google_style() + .c_str()) + // Measurement and probability methods .def("get_squared_norm", &StateVectorBatched::get_squared_norm, - "Get squared norm of each state in the batch. $\\braket{\\psi|\\psi}$.") + DocString() + .desc("Get squared norm for each state in the batch.") + .ret("list[float]", "List of squared norms.") + .build_as_google_style() + .c_str()) .def("normalize", &StateVectorBatched::normalize, - "Normalize each state in the batch (let $\\braket{\\psi|\\psi} = 1$ by " - "multiplying coef).") + DocString().desc("Normalize all states in the batch.").build_as_google_style().c_str()) .def("get_zero_probability", &StateVectorBatched::get_zero_probability, - "Get the probability to observe $\\ket{0}$ at specified index for each state in " - "the batch.") + "target_qubit_index"_a, + DocString() + .desc("Get probability of measuring |0⟩ on specified qubit for each state.") + .arg("target_qubit_index", "int", "Index of qubit to measure.") + .ret("list[float]", "Probabilities for each state in batch.") + .build_as_google_style() + .c_str()) .def("get_marginal_probability", &StateVectorBatched::get_marginal_probability, - "Get the marginal probability to observe as specified for each state in the batch. " - "Specify the result as n-length list. `0` and `1` represent the qubit is observed " - "and get the value. `2` represents the qubit is not observed.") + "measured_values"_a, + DocString() + .desc("Get marginal probabilities for specified measurement outcomes.") + .arg("measured_values", "list[int]", "Measurement configuration.") + .ret("list[float]", "Probabilities for each state in batch.") + .build_as_google_style() + .c_str()) + // Entropy and sampling methods .def("get_entropy", &StateVectorBatched::get_entropy, - "Get the entropy of each state in the batch.") + DocString() + .desc("Calculate von Neumann entropy for each state.") + .ret("list[float]", "Entropy values for each state.") + .build_as_google_style() + .c_str()) + .def( + "sampling", + [](const StateVectorBatched& states, + std::uint64_t sampling_count, + std::optional seed) { + return states.sampling(sampling_count, seed.value_or(std::random_device()())); + }, + "sampling_count"_a, + "seed"_a = std::nullopt, + DocString() + .desc("Sample from the probability distribution of each state.") + .arg("sampling_count", "int", "Number of samples to take.") + .arg("seed", "int, optional", "Random seed (default: random).") + .ret("list[list[int]]", "Samples for each state in batch.") + .build_as_google_style() + .c_str()) + // State manipulation methods .def("add_state_vector_with_coef", &StateVectorBatched::add_state_vector_with_coef, - "Add other batched state vectors with multiplying the coef and make superposition. " - "$\\ket{\\mathrm{this}}\\leftarrow\\ket{\\mathrm{this}}+\\mathrm{coef}" - "\\ket{\\mathrm{states}}$.") + "coef"_a, + "states"_a, + DocString() + .desc("Add another batched state vector multiplied by a coefficient.") + .arg("coef", "complex", "Coefficient to multiply with states.") + .arg("states", "StateVectorBatched", "States to add.") + .build_as_google_style() + .c_str()) + .def("multiply_coef", + &StateVectorBatched::multiply_coef, + "coef"_a, + DocString() + .desc("Multiply all states by a coefficient.") + .arg("coef", "complex", "Coefficient to multiply.") + .build_as_google_style() + .c_str()) + // Data access methods .def("load", &StateVectorBatched::load, - "Load batched amplitudes from `list[list[complex]]`.") - .def("copy", &StateVectorBatched::copy, "Create a copy of the batched state vector.") - .def("to_string", &StateVectorBatched::to_string, "Information as `str`.") - .def("__str__", &StateVectorBatched::to_string, "Information as `str`.") + "states"_a, + DocString() + .desc("Load amplitudes for all states in batch.") + .arg("states", "list[list[complex]]", "Amplitudes for each state.") + .build_as_google_style() + .c_str()) + .def("get_amplitudes", + &StateVectorBatched::get_amplitudes, + DocString() + .desc("Get amplitudes of all states in batch.") + .ret("list[list[complex]]", "Amplitudes for each state.") + .build_as_google_style() + .c_str()) + // Copy and string representation + .def("copy", + &StateVectorBatched::copy, + DocString() + .desc("Create a deep copy of this batched state vector.") + .ret("StateVectorBatched", "New copy of the states.") + .build_as_google_style() + .c_str()) + .def("to_string", + &StateVectorBatched::to_string, + DocString() + .desc("Get string representation of the batched states.") + .ret("str", "String representation of states.") + .build_as_google_style() + .c_str()) + .def("__str__", + &StateVectorBatched::to_string, + DocString() + .desc("Get string representation of the batched states.") + .ret("str", "String representation of states.") + .build_as_google_style() + .c_str()) + // JSON serialization .def( "to_json", [](const StateVectorBatched& states) { return Json(states).dump(); }, - "Get JSON representation of the states.") + DocString() + .desc("Convert states to JSON string.") + .ret("str", "JSON representation of states.") + .build_as_google_style() + .c_str()) .def( "load_json", [](StateVectorBatched& states, const std::string& str) { states = nlohmann::json::parse(str); }, - "Read an object from the JSON representation of the states."); + "json_str"_a, + DocString() + .desc("Load states from JSON string.") + .arg("json_str", "str", "JSON string to load from.") + .build_as_google_style() + .c_str()); } } // namespace internal #endif