numerics
Loading...
Searching...
No Matches
circuit.hpp
Go to the documentation of this file.
1/// @file quantum/circuit.hpp
2/// @brief Fluent quantum circuit builder and statevector simulator
3///
4/// Provides a chainable Circuit class that reads like a circuit diagram.
5/// Gates are recorded and replayed on a statevector on demand, so you can
6/// inspect intermediate states (step-through) or sample measurement outcomes.
7///
8/// ### Quick start
9/// @code
10/// #include "quantum/circuit.hpp"
11/// using num::Circuit;
12///
13/// // Bell state
14/// auto sv = Circuit(2).h(0).cx(0,1).statevector();
15///
16/// // Grover search (2 qubits, finds |11>)
17/// auto result = Circuit(2)
18/// .h(0).h(1)
19/// .cz(0,1) // oracle
20/// .h(0).h(1).x(0).x(1).cz(0,1).x(0).x(1).h(0).h(1) // diffusion
21/// .run(4096);
22/// result.print(); // |11>: 4096/4096
23///
24/// // QFT on 3 qubits
25/// Circuit qft(3);
26/// qft.x(0)
27/// .h(2).cp(M_PI/2, 1,2).cp(M_PI/4, 0,2)
28/// .h(1).cp(M_PI/2, 0,1)
29/// .h(0).swap(0,2);
30/// qft.print(); // ASCII diagram
31/// @endcode
32#pragma once
34#include <map>
35#include <string>
36#include <vector>
37
38namespace num {
39
40// -- Result -------------------------------------------------------------------
41
42/// @brief Measurement outcome from Circuit::run()
43struct Result {
44 std::map<std::string, int> counts; ///< basis label (e.g. "011") -> shot count
45 quantum::Statevector sv; ///< pre-measurement statevector
46 int shots = 0;
47
48 /// @brief Print counts sorted by count (descending)
49 void print() const;
50
51 /// @brief Basis label with the highest count
52 std::string most_likely() const;
53
54 /// @brief Empirical probability for a given label (e.g. "11")
55 real probability(const std::string& label) const;
56};
57
58// -- GateView -- for renderers --------------------------------------------------
59
60/// @brief Compact gate description used by visualisation code
61struct GateView {
62 std::string label; ///< e.g. "H", "CX", "RY(1.57)", "SWAP"
63 int q0 = -1; ///< primary qubit (target for 1Q; control for 2/3Q)
64 int q1 = -1; ///< secondary qubit (-1 if 1Q)
65 int q2 = -1; ///< tertiary qubit (-1 if not 3Q)
66 int col = 0; ///< time-slot column after layout pass
67 /// 0 = single-qubit, 1 = controlled (q0=ctrl, q1=tgt),
68 /// 2 = swap, 3 = Toffoli/Fredkin
69 int kind = 0;
70};
71
72// -- Circuit -------------------------------------------------------------------
73
74/// @brief Chainable quantum circuit builder
75///
76/// Gates are stored in order and applied to a fresh zero-state statevector
77/// when execution is requested. The circuit itself is immutable between calls.
78class Circuit {
79public:
80 explicit Circuit(int n_qubits);
81
82 // -- Single-qubit gates ----------------------------------------------------
83
84 Circuit& h (int q); ///< Hadamard
85 Circuit& x (int q); ///< Pauli-X (NOT)
86 Circuit& y (int q); ///< Pauli-Y
87 Circuit& z (int q); ///< Pauli-Z
88 Circuit& s (int q); ///< Phase S = sqrtZ
89 Circuit& sdg(int q); ///< S†
90 Circuit& t (int q); ///< T = sqrtS
91 Circuit& tdg(int q); ///< T†
92 Circuit& rx (real theta, int q); ///< R_x(theta) = e^{-ithetaX/2}
93 Circuit& ry (real theta, int q); ///< R_y(theta) = e^{-ithetaY/2}
94 Circuit& rz (real theta, int q); ///< R_z(theta) = e^{-ithetaZ/2}
95 Circuit& p (real lambda, int q); ///< Phase P(lambda)
96 Circuit& u (real theta, real phi, real lambda, int q); ///< General SU(2)
97
98 // -- Two-qubit gates -------------------------------------------------------
99
100 Circuit& cx (int ctrl, int tgt); ///< CNOT
101 Circuit& cy (int ctrl, int tgt); ///< Controlled-Y
102 Circuit& cz (int ctrl, int tgt); ///< Controlled-Z
103 Circuit& cp (real lambda, int ctrl, int tgt); ///< Controlled phase
104 Circuit& swap(int q0, int q1); ///< SWAP
105
106 // -- Three-qubit gates -----------------------------------------------------
107
108 Circuit& ccx (int c0, int c1, int tgt); ///< Toffoli (CCX)
109 Circuit& cswap(int ctrl, int q0, int q1); ///< Fredkin (CSWAP)
110
111 // -- Custom gates ----------------------------------------------------------
112
113 Circuit& gate(const quantum::Gate& G, int q, std::string label = "U");
114 Circuit& gate(const quantum::Gate2Q& G, int q0, int q1, std::string label = "U2");
115
116 // -- Execution -------------------------------------------------------------
117
118 /// @brief Run full circuit -> statevector (no measurement collapse)
120
121 /// @brief Apply first `n` gates only (0 = bare |0...0>).
122 /// Useful for stepping through the circuit in a visualiser.
124
125 /// @brief Sample `shots` measurements from the ideal distribution.
126 /// Uses pre-computed statevector probabilities -- O(2^n + shots).
127 Result run(int shots = 1024, unsigned seed = 42) const;
128
129 // -- Display ---------------------------------------------------------------
130
131 /// @brief ASCII wire diagram (Unicode box-drawing characters)
132 std::string diagram() const;
133
134 /// @brief Print diagram to stdout
135 void print() const;
136
137 // -- Inspection ------------------------------------------------------------
138
139 int n_qubits() const { return n_qubits_; }
140 int n_gates() const { return static_cast<int>(ops_.size()); }
141
142 /// @brief Gate descriptions with layout columns -- for renderers
143 std::vector<GateView> views() const;
144
145private:
146 struct Op {
147 enum Type {
148 H, X, Y, Z, S, Sdg, T, Tdg,
149 RX, RY, RZ, P, U,
150 CX, CY, CZ, CP, SWAP,
151 CCX, CSWAP,
152 Custom1Q, Custom2Q
153 } type;
154 int q0 = -1, q1 = -1, q2 = -1;
155 real theta = 0, phi = 0, lambda = 0;
156 quantum::Gate g1{};
157 quantum::Gate2Q g2{};
158 std::string label; // only for Custom gates
159 };
160
161 int n_qubits_;
162 std::vector<Op> ops_;
163
164 void apply_op(const Op& op, quantum::Statevector& sv) const;
165
166 // Returns (gate_col[i], total_cols)
167 std::pair<std::vector<int>, int> compute_layout() const;
168};
169
170// -- Convenience factory functions ---------------------------------------------
171
172/// @brief Bell state |Phi+> = (|00> + |11>)/sqrt2 on qubits q0, q1
173Circuit bell_pair(int q0 = 0, int q1 = 1);
174
175/// @brief n-qubit GHZ state (|00...0> + |11...1>)/sqrt2
176Circuit ghz_state(int n_qubits);
177
178/// @brief n-qubit Quantum Fourier Transform circuit
179/// Applied to |0...0> unless you prepend state-preparation gates.
180Circuit qft_circuit(int n_qubits);
181
182/// @brief Pretty-print a statevector, hiding amplitudes below threshold
183void print_state(const quantum::Statevector& sv, int n_qubits,
184 real threshold = 1e-6);
185
186} // namespace num
Dense vector with optional GPU storage, templated over scalar type T.
Definition vector.hpp:23
Chainable quantum circuit builder.
Definition circuit.hpp:78
std::vector< GateView > views() const
Gate descriptions with layout columns – for renderers.
Definition circuit.cpp:217
std::string diagram() const
ASCII wire diagram (Unicode box-drawing characters)
Definition circuit.cpp:266
Circuit & cx(int ctrl, int tgt)
CNOT.
Definition circuit.cpp:80
Circuit & swap(int q0, int q1)
SWAP.
Definition circuit.cpp:93
int n_qubits() const
Definition circuit.hpp:139
Circuit & cp(real lambda, int ctrl, int tgt)
Controlled phase.
Definition circuit.cpp:89
Circuit & h(int q)
Hadamard.
Definition circuit.cpp:52
Circuit & rz(real theta, int q)
R_z(theta) = e^{-ithetaZ/2}.
Definition circuit.cpp:67
Circuit & rx(real theta, int q)
R_x(theta) = e^{-ithetaX/2}.
Definition circuit.cpp:61
Circuit & s(int q)
Phase S = sqrtZ.
Definition circuit.cpp:56
Circuit & ry(real theta, int q)
R_y(theta) = e^{-ithetaY/2}.
Definition circuit.cpp:64
quantum::Statevector statevector() const
Run full circuit -> statevector (no measurement collapse)
Definition circuit.cpp:155
Circuit & sdg(int q)
S†
Definition circuit.cpp:57
Circuit & t(int q)
T = sqrtS.
Definition circuit.cpp:58
quantum::Statevector statevector_at(int n) const
Apply first n gates only (0 = bare |0...0>). Useful for stepping through the circuit in a visualiser.
Definition circuit.cpp:159
Circuit & z(int q)
Pauli-Z.
Definition circuit.cpp:55
Circuit & p(real lambda, int q)
Phase P(lambda)
Definition circuit.cpp:70
Circuit & x(int q)
Pauli-X (NOT)
Definition circuit.cpp:53
Circuit & u(real theta, real phi, real lambda, int q)
General SU(2)
Definition circuit.cpp:73
Circuit & cz(int ctrl, int tgt)
Controlled-Z.
Definition circuit.cpp:86
Circuit & ccx(int c0, int c1, int tgt)
Toffoli (CCX)
Definition circuit.cpp:99
void print() const
Print diagram to stdout.
Definition circuit.cpp:385
Result run(int shots=1024, unsigned seed=42) const
Sample shots measurements from the ideal distribution. Uses pre-computed statevector probabilities – ...
Definition circuit.cpp:167
Circuit & tdg(int q)
T†
Definition circuit.cpp:59
Circuit & cy(int ctrl, int tgt)
Controlled-Y.
Definition circuit.cpp:83
int n_gates() const
Definition circuit.hpp:140
Circuit & cswap(int ctrl, int q0, int q1)
Fredkin (CSWAP)
Definition circuit.cpp:102
Circuit & y(int q)
Pauli-Y.
Definition circuit.cpp:54
Circuit & gate(const quantum::Gate &G, int q, std::string label="U")
Definition circuit.cpp:108
std::array< cplx, 16 > Gate2Q
4x4 two-qubit gate stored row-major (16 entries)
std::array< cplx, 4 > Gate
2x2 single-qubit gate stored row-major: { G[0,0], G[0,1], G[1,0], G[1,1] }
num::CVector Statevector
Dense statevector: complex vector of length 2^n_qubits, backed by num::CVector.
double real
Definition types.hpp:10
constexpr real phi
Golden ratio.
Definition math.hpp:42
Circuit ghz_state(int n_qubits)
n-qubit GHZ state (|00...0> + |11...1>)/sqrt2
Definition circuit.cpp:395
constexpr T ipow(T x) noexcept
Compute x^N at compile time via repeated squaring.
constexpr real e
Definition math.hpp:41
Circuit qft_circuit(int n_qubits)
n-qubit Quantum Fourier Transform circuit Applied to |0...0> unless you prepend state-preparation gat...
Definition circuit.cpp:403
void print_state(const quantum::Statevector &sv, int n_qubits, real threshold=1e-6)
Pretty-print a statevector, hiding amplitudes below threshold.
Definition circuit.cpp:416
Circuit bell_pair(int q0=0, int q1=1)
Bell state |Phi+> = (|00> + |11>)/sqrt2 on qubits q0, q1.
Definition circuit.cpp:389
Statevector-based quantum circuit simulator.
Compact gate description used by visualisation code.
Definition circuit.hpp:61
int q1
secondary qubit (-1 if 1Q)
Definition circuit.hpp:64
int q2
tertiary qubit (-1 if not 3Q)
Definition circuit.hpp:65
std::string label
e.g. "H", "CX", "RY(1.57)", "SWAP"
Definition circuit.hpp:62
int q0
primary qubit (target for 1Q; control for 2/3Q)
Definition circuit.hpp:63
Measurement outcome from Circuit::run()
Definition circuit.hpp:43
void print() const
Print counts sorted by count (descending)
Definition circuit.cpp:14
std::string most_likely() const
Basis label with the highest count.
Definition circuit.cpp:32
quantum::Statevector sv
pre-measurement statevector
Definition circuit.hpp:45
real probability(const std::string &label) const
Empirical probability for a given label (e.g. "11")
Definition circuit.cpp:40
std::map< std::string, int > counts
basis label (e.g. "011") -> shot count
Definition circuit.hpp:44