numerics
Loading...
Searching...
No Matches
statevector.hpp
Go to the documentation of this file.
1/// @file quantum/statevector.hpp
2/// @brief Statevector-based quantum circuit simulator
3///
4/// Simulates an n-qubit system as a dense complex statevector of length 2^n.
5/// Qubit indexing is little-endian: qubit 0 is the least-significant bit of
6/// the basis-state index.
7///
8/// @code
9/// using namespace num::quantum;
10/// auto sv = zero_state(2); // |00>
11/// apply_1q(sv, 2, gate_h(), 0); // H on qubit 0 -> (|00> + |10>) / sqrt2
12/// apply_cnot(sv, 2, 0, 1); // CNOT(ctrl=0, tgt=1) -> Bell state
13/// auto p = probabilities(sv); // {0.5, 0, 0, 0.5}
14/// @endcode
15#pragma once
16#include "core/types.hpp"
17#include "core/vector.hpp"
18#include <array>
19#include <functional>
20#include <vector>
21
22namespace num {
23namespace quantum {
24
25// -- Types --------------------------------------------------------------------
26
27/// @brief Dense statevector: complex vector of length 2^n_qubits, backed by num::CVector
29
30/// @brief 2x2 single-qubit gate stored row-major: { G[0,0], G[0,1], G[1,0], G[1,1] }
31using Gate = std::array<cplx, 4>;
32
33/// @brief 4x4 two-qubit gate stored row-major (16 entries)
34using Gate2Q = std::array<cplx, 16>;
35
36// -- State construction --------------------------------------------------------
37
38/// @brief Returns |0...0> computational basis state for n_qubits qubits
39Statevector zero_state(int n_qubits);
40
41/// @brief Returns the computational basis state |k> for an n_qubits system
42Statevector basis_state(int n_qubits, int k);
43
44// -- Single-qubit gates --------------------------------------------------------
45
46Gate gate_x(); ///< Pauli-X (NOT)
47Gate gate_y(); ///< Pauli-Y
48Gate gate_z(); ///< Pauli-Z
49Gate gate_h(); ///< Hadamard
50Gate gate_s(); ///< Phase gate S = diag(1, i)
51Gate gate_sdg(); ///< S† = diag(1, -i)
52Gate gate_t(); ///< T gate = diag(1, e^{ipi/4})
53Gate gate_tdg(); ///< T† gate
54Gate gate_rx(real theta); ///< Rotation about X: R_x(theta) = exp(-ithetaX/2)
55Gate gate_ry(real theta); ///< Rotation about Y: R_y(theta) = exp(-ithetaY/2)
56Gate gate_rz(real theta); ///< Rotation about Z: R_z(theta) = exp(-ithetaZ/2)
57Gate gate_p(real lambda); ///< Phase gate: diag(1, e^{ilambda})
58Gate gate_u(real theta, real phi, real lambda); ///< General SU(2) gate
59
60// -- Two-qubit gates -----------------------------------------------------------
61
62Gate2Q gate2q_cnot(); ///< CNOT (qubit 0 = control, qubit 1 = target in subspace)
63Gate2Q gate2q_cz(); ///< Controlled-Z
64Gate2Q gate2q_swap(); ///< SWAP
65
66// -- Gate application ---------------------------------------------------------
67
68/// @brief Apply a 2x2 gate to a single qubit in-place
69/// @param sv Statevector of length 2^n_qubits (modified in-place)
70/// @param n_qubits Total number of qubits
71/// @param G 2x2 gate (row-major)
72/// @param target Target qubit index (0 = LSB)
73void apply_1q(Statevector& sv, int n_qubits, const Gate& G, int target);
74
75/// @brief Apply a general 4x4 two-qubit gate to qubits q0, q1
76/// @param sv Statevector
77/// @param n_qubits Total number of qubits
78/// @param G 4x4 gate acting on (q0, q1) in little-endian order
79/// @param q0 First qubit (LSB of the 2-qubit subspace)
80/// @param q1 Second qubit (MSB of the 2-qubit subspace)
81void apply_2q(Statevector& sv, int n_qubits, const Gate2Q& G, int q0, int q1);
82
83/// @brief CNOT with explicit control and target qubits
84void apply_cnot(Statevector& sv, int n_qubits, int control, int target);
85
86/// @brief Controlled-Z
87void apply_cz(Statevector& sv, int n_qubits, int control, int target);
88
89/// @brief SWAP two qubits
90void apply_swap(Statevector& sv, int n_qubits, int q0, int q1);
91
92/// @brief Toffoli (CCX) gate
93void apply_toffoli(Statevector& sv, int n_qubits, int c0, int c1, int target);
94
95/// @brief Controlled-Y
96void apply_cy(Statevector& sv, int n_qubits, int control, int target);
97
98/// @brief Controlled phase: applies phase e^{ilambda} when both control=1 and target=1
99void apply_cp(Statevector& sv, int n_qubits, real lambda, int control, int target);
100
101/// @brief Fredkin (CSWAP): swaps q0 and q1 when ctrl=1
102void apply_cswap(Statevector& sv, int n_qubits, int ctrl, int q0, int q1);
103
104// -- Observables ---------------------------------------------------------------
105
106/// @brief L2 norm of the statevector (should be 1 for a valid quantum state)
107real norm(const Statevector& sv);
108
109/// @brief Normalize statevector in-place
110void normalize(Statevector& sv);
111
112/// @brief Measurement probability for each basis state: p_i = |a_i|^2
113std::vector<real> probabilities(const Statevector& sv);
114
115/// @brief Expectation value <psi|O|psi> for a Hermitian operator given as matrix-free matvec
117 std::function<void(const Statevector&, Statevector&)> op);
118
119/// @brief <Z_q> = P(q=0) - P(q=1) for qubit q
120real expectation_z(const Statevector& sv, int qubit);
121
122/// @brief <X_q> for qubit q
123real expectation_x(const Statevector& sv, int n_qubits, int qubit);
124
125/// @brief <Y_q> for qubit q
126real expectation_y(const Statevector& sv, int n_qubits, int qubit);
127
128/// @brief Reduced density matrix for a single qubit (2x2, returned row-major)
129std::array<std::complex<real>, 4> reduced_density_matrix(const Statevector& sv,
130 int n_qubits,
131 int qubit);
132
133/// @brief Von Neumann entropy of a single qubit's reduced density matrix
134real entanglement_entropy(const Statevector& sv, int n_qubits, int qubit);
135
136} // namespace quantum
137} // namespace num
Dense vector with optional GPU storage, templated over scalar type T.
Definition vector.hpp:23
Core type definitions.
Gate gate_ry(real theta)
Rotation about Y: R_y(theta) = exp(-ithetaY/2)
void apply_cy(Statevector &sv, int n_qubits, int control, int target)
Controlled-Y.
std::array< cplx, 16 > Gate2Q
4x4 two-qubit gate stored row-major (16 entries)
Gate gate_rx(real theta)
Rotation about X: R_x(theta) = exp(-ithetaX/2)
real norm(const Statevector &sv)
L2 norm of the statevector (should be 1 for a valid quantum state)
void apply_cp(Statevector &sv, int n_qubits, real lambda, int control, int target)
Controlled phase: applies phase e^{ilambda} when both control=1 and target=1.
Gate gate_x()
Pauli-X (NOT)
Gate gate_p(real lambda)
Phase gate: diag(1, e^{ilambda})
Gate gate_rz(real theta)
Rotation about Z: R_z(theta) = exp(-ithetaZ/2)
Gate2Q gate2q_cz()
Controlled-Z.
Gate gate_sdg()
S† = diag(1, -i)
void apply_2q(Statevector &sv, int n_qubits, const Gate2Q &G, int q0, int q1)
Apply a general 4x4 two-qubit gate to qubits q0, q1.
void apply_cnot(Statevector &sv, int n_qubits, int control, int target)
CNOT with explicit control and target qubits.
Gate2Q gate2q_cnot()
CNOT (qubit 0 = control, qubit 1 = target in subspace)
Gate gate_u(real theta, real phi, real lambda)
General SU(2) gate.
real expectation(const Statevector &sv, std::function< void(const Statevector &, Statevector &)> op)
Expectation value <psi|O|psi> for a Hermitian operator given as matrix-free matvec.
Gate gate_s()
Phase gate S = diag(1, i)
void apply_toffoli(Statevector &sv, int n_qubits, int c0, int c1, int target)
Toffoli (CCX) gate.
Statevector zero_state(int n_qubits)
Returns |0...0> computational basis state for n_qubits qubits.
Gate gate_tdg()
T† gate.
Gate gate_y()
Pauli-Y.
void apply_cz(Statevector &sv, int n_qubits, int control, int target)
Controlled-Z.
Gate2Q gate2q_swap()
SWAP.
Gate gate_h()
Hadamard.
real expectation_x(const Statevector &sv, int n_qubits, int qubit)
<X_q> for qubit q
void apply_cswap(Statevector &sv, int n_qubits, int ctrl, int q0, int q1)
Fredkin (CSWAP): swaps q0 and q1 when ctrl=1.
void normalize(Statevector &sv)
Normalize statevector in-place.
std::array< std::complex< real >, 4 > reduced_density_matrix(const Statevector &sv, int n_qubits, int qubit)
Reduced density matrix for a single qubit (2x2, returned row-major)
std::vector< real > probabilities(const Statevector &sv)
Measurement probability for each basis state: p_i = |a_i|^2.
real expectation_z(const Statevector &sv, int qubit)
<Z_q> = P(q=0) - P(q=1) for qubit q
void apply_swap(Statevector &sv, int n_qubits, int q0, int q1)
SWAP two qubits.
real entanglement_entropy(const Statevector &sv, int n_qubits, int qubit)
Von Neumann entropy of a single qubit's reduced density matrix.
void apply_1q(Statevector &sv, int n_qubits, const Gate &G, int target)
Apply a 2x2 gate to a single qubit in-place.
std::array< cplx, 4 > Gate
2x2 single-qubit gate stored row-major: { G[0,0], G[0,1], G[1,0], G[1,1] }
real expectation_y(const Statevector &sv, int n_qubits, int qubit)
<Y_q> for qubit q
Gate gate_z()
Pauli-Z.
Statevector basis_state(int n_qubits, int k)
Returns the computational basis state |k> for an n_qubits system.
Gate gate_t()
T gate = diag(1, e^{ipi/4})
double real
Definition types.hpp:10
constexpr real phi
Golden ratio.
Definition math.hpp:42
constexpr T ipow(T x) noexcept
Compute x^N at compile time via repeated squaring.
BasicVector< cplx > CVector
Complex-valued dense vector (sequential; no GPU)
Definition vector.hpp:125
Vector operations.