Skip to main content

Quantum-Mechanics

Quantum gates, state representations, fidelity metrics, noise channels, and error-correcting codes for qubit-based computation.

Namespace: CSharpNumerics.Physics.Quantum

using CSharpNumerics.Physics.Quantum;
using CSharpNumerics.Physics.Quantum.NoiseModels;
using CSharpNumerics.Physics.Quantum.ErrorCorrection;

โš›๏ธ Quantum Gatesโ€‹

Namespace: CSharpNumerics.Physics.Quantum

Quantum gates are unitary operators acting on one or more qubits. Each gate is represented by a ComplexMatrix and knows how to apply itself to a ComplexVectorN state vector.

All gates extend the abstract QuantumGate base class:

ClassQubitsMatrixDescription
HadamardGate112(111โˆ’1)\frac{1}{\sqrt{2}}\begin{pmatrix}1&1\\1&-1\end{pmatrix}Creates equal superposition
PauliXGate1(0110)\begin{pmatrix}0&1\\1&0\end{pmatrix}Quantum NOT โ€” flips |0โŸฉ โ†” |1โŸฉ
PauliYGate1(0โˆ’ii0)\begin{pmatrix}0&-i\\i&0\end{pmatrix}Bit + phase flip, Y2=IY^2 = I
PauliZGate1(100โˆ’1)\begin{pmatrix}1&0\\0&-1\end{pmatrix}Phase flip โ€” |1โŸฉ โ†’ โˆ’|1โŸฉ
SGate1(100i)\begin{pmatrix}1&0\\0&i\end{pmatrix}Phase gate (ฯ€/2), S2=ZS^2 = Z
TGate1(100eiฯ€/4)\begin{pmatrix}1&0\\0&e^{i\pi/4}\end{pmatrix}ฯ€/8 gate, T2=ST^2 = S
PhaseGate(ฮธ)1(100eiฮธ)\begin{pmatrix}1&0\\0&e^{i\theta}\end{pmatrix}General phase gate, P(ฯ€)=ZP(\pi) = Z
RxGate(ฮธ)1(cosโกฮธ2โˆ’isinโกฮธ2โˆ’isinโกฮธ2cosโกฮธ2)\begin{pmatrix}\cos\frac{\theta}{2}&-i\sin\frac{\theta}{2}\\-i\sin\frac{\theta}{2}&\cos\frac{\theta}{2}\end{pmatrix}Rotation about X-axis
RyGate(ฮธ)1(cosโกฮธ2โˆ’sinโกฮธ2sinโกฮธ2cosโกฮธ2)\begin{pmatrix}\cos\frac{\theta}{2}&-\sin\frac{\theta}{2}\\\sin\frac{\theta}{2}&\cos\frac{\theta}{2}\end{pmatrix}Rotation about Y-axis
RzGate(ฮธ)1(eโˆ’iฮธ/200eiฮธ/2)\begin{pmatrix}e^{-i\theta/2}&0\\0&e^{i\theta/2}\end{pmatrix}Rotation about Z-axis
CNOTGate24ร—4 permutationFlips target qubit when control is |1โŸฉ
CZGate2diag(1,1,1,โˆ’1)\text{diag}(1,1,1,-1)Phase flip on |11โŸฉ
CPhaseGate(ฮธ)2diag(1,1,1,eiฮธ)\text{diag}(1,1,1,e^{i\theta})Controlled phase, CP(ฯ€)=CZCP(\pi) = CZ
SWAPGate24ร—4 permutationSwaps two qubit states
ToffoliGate38ร—8 permutationCCNOT โ€” flips target when both controls are |1โŸฉ
FredkinGate38ร—8 permutationCSWAP โ€” swaps targets when control is |1โŸฉ
PhaseOracle(n, states)n2โฟร—2โฟ diagonalFlips phase of marked basis states: |wโŸฉ โ†’ โˆ’|wโŸฉ
ControlledGate(U)n+12โฟโบยนร—2โฟโบยน blockApplies U when control qubit is |1โŸฉ
ModularMultiplyGate(a,N,n)n2โฟร—2โฟ permutation|yโŸฉ โ†’ |ay mod NโŸฉ, used in Shor's algorithm

QuantumGate (abstract)

public abstract class QuantumGate
{
public abstract int QubitCount { get; }
public abstract ComplexMatrix GetMatrix();
public ComplexVectorN Apply(ComplexVectorN amplitudes, int[] qubitIndices, int totalQubits);
}

Apply uses the gate's unitary matrix to transform the relevant amplitudes in-place (tensor-product expansion) โ€” works for arbitrary qubit counts and target indices.

Usage

Gates are consumed by QuantumInstruction and QuantumCircuit in the Engines Quantum section:

using CSharpNumerics.Physics.Quantum;
using CSharpNumerics.Engines.Quantum;

var circuit = new QuantumCircuit(2);
circuit.AddInstruction(new QuantumInstruction(new HadamardGate(), new List<int> { 0 }));
circuit.AddInstruction(new QuantumInstruction(new CNOTGate(), new List<int> { 0, 1 }));

var state = new QuantumSimulator().Run(circuit); // Bell state (|00โŸฉ + |11โŸฉ)/โˆš2

๐ŸŒ BlochVectorโ€‹

Represents a single-qubit pure state on the Bloch sphere. Given โˆฃฯˆโŸฉ=ฮฑโˆฃ0โŸฉ+ฮฒโˆฃ1โŸฉ|\psi\rangle = \alpha|0\rangle + \beta|1\rangle:

x=2โ€‰Re(ฮฑโˆ—ฮฒ),y=2โ€‰Im(ฮฑโˆ—ฮฒ),z=โˆฃฮฑโˆฃ2โˆ’โˆฃฮฒโˆฃ2x = 2\,\text{Re}(\alpha^*\beta), \quad y = 2\,\text{Im}(\alpha^*\beta), \quad z = |\alpha|^2 - |\beta|^2

using CSharpNumerics.Physics.Quantum;
using CSharpNumerics.Engines.Quantum;

// From a circuit result
var circuit = new QuantumCircuit(1);
circuit.AddInstruction(new QuantumInstruction(new HadamardGate(), new List<int> { 0 }));
var state = new QuantumSimulator().Run(circuit);

BlochVector bloch = state.GetBlochVector(); // (1, 0, 0) โ€” +X axis
double theta = bloch.Theta; // polar angle ฮธ
double phi = bloch.Phi; // azimuthal angle ฯ†
double r = bloch.Radius; // 1.0 for pure states
Vector v = bloch.ToVector(); // 3D Vector for rendering

// Directly from amplitudes
var b = BlochVector.FromAmplitudes(
new ComplexNumber(1, 0), new ComplexNumber(0, 0)); // |0โŸฉ โ†’ (0, 0, 1)
PropertyDescription
X, Y, ZCartesian Bloch coordinates
ThetaPolar angle ฮธโˆˆ[0,ฯ€]\theta \in [0, \pi] from +Z
PhiAzimuthal angle ฯ†โˆˆ(โˆ’ฯ€,ฯ€]\varphi \in (-\pi, \pi]
RadiusVector length (1 for pure states)
ToVector()Returns a 3D Vector for visualization

Canonical states on the sphere:

StateBloch
โˆฅ0โŸฉ\|0\rangle(0,0,1)(0, 0, 1) โ€” north pole
โˆฅ1โŸฉ\|1\rangle(0,0,โˆ’1)(0, 0, -1) โ€” south pole
(โˆฅ0โŸฉ+โˆฅ1โŸฉ)/2(\|0\rangle+\|1\rangle)/\sqrt{2}(1,0,0)(1, 0, 0) โ€” +X
(โˆฅ0โŸฉโˆ’โˆฅ1โŸฉ)/2(\|0\rangle-\|1\rangle)/\sqrt{2}(โˆ’1,0,0)(-1, 0, 0) โ€” โˆ’X
(โˆฅ0โŸฉ+iโˆฅ1โŸฉ)/2(\|0\rangle+i\|1\rangle)/\sqrt{2}(0,1,0)(0, 1, 0) โ€” +Y
(โˆฅ0โŸฉโˆ’iโˆฅ1โŸฉ)/2(\|0\rangle-i\|1\rangle)/\sqrt{2}(0,โˆ’1,0)(0, -1, 0) โ€” โˆ’Y

๐Ÿ“ QuantumFidelityโ€‹

Static methods for computing the overlap between quantum states. Fidelity ranges from 0 (orthogonal) to 1 (identical).

State fidelity โ€” F=โˆฃโŸจฯˆโˆฃฯ•โŸฉโˆฃ2F = |\langle\psi|\phi\rangle|^2

using CSharpNumerics.Physics.Quantum;
using CSharpNumerics.Engines.Quantum;

var sim = new QuantumSimulator();
var s0 = sim.Run(QuantumCircuitBuilder.New(1).Build()); // |0โŸฉ
var sPlus = sim.Run(QuantumCircuitBuilder.New(1).H(0).Build()); // |+โŸฉ
var s1 = sim.Run(QuantumCircuitBuilder.New(1).X(0).Build()); // |1โŸฉ

double f1 = QuantumFidelity.Fidelity(s0, s0); // 1.0 โ€” identical
double f2 = QuantumFidelity.Fidelity(s0, sPlus); // 0.5 โ€” overlap
double f3 = QuantumFidelity.Fidelity(s0, s1); // 0.0 โ€” orthogonal

Vector fidelity โ€” works directly on ComplexVectorN

double f = QuantumFidelity.Fidelity(psi, phi);   // |โŸจฯˆ|ฯ†โŸฉ|ยฒ

Bloch fidelity โ€” geometric formula for single-qubit states: F=12(1+n^1โ‹…n^2)F = \frac{1}{2}(1 + \hat{n}_1 \cdot \hat{n}_2)

var b1 = s1State.GetBlochVector();
var b2 = s2State.GetBlochVector();
double f = QuantumFidelity.BlochFidelity(b1, b2);
// Matches state fidelity for pure single-qubit states

๐Ÿ”Š Noise Modelsโ€‹

The Physics.Quantum.NoiseModels namespace provides quantum noise channels using the Kraus operator formalism. Each channel implements INoiseChannel and satisfies the completeness relation โˆ‘Ekโ€ Ek=I\sum E_k^\dagger E_k = I.

ChannelParameterKraus OperatorsPhysical Model
DepolarizingNoise(p)pโˆˆ[0,1]p \in [0,1]E0=1โˆ’3p/4โ€‰IE_0 = \sqrt{1 - 3p/4}\,I, E1,2,3=p/4โ€‰{X,Y,Z}E_{1,2,3} = \sqrt{p/4}\,\{X, Y, Z\}Random Pauli error โ€” qubit replaced by maximally mixed state with probability pp
DephasingNoise(p)pโˆˆ[0,1]p \in [0,1]E0=1โˆ’pโ€‰IE_0 = \sqrt{1-p}\,I, E1=pโ€‰ZE_1 = \sqrt{p}\,ZPhase-flip error โ€” T2T_2 decoherence
AmplitudeDampingNoise(ฮณ)ฮณโˆˆ[0,1]\gamma \in [0,1]E0=[[1,0],[0,1โˆ’ฮณ]]E_0 = [[1,0],[0,\sqrt{1-\gamma}]], E1=[[0,ฮณ],[0,0]]E_1 = [[0,\sqrt{\gamma}],[0,0]]Energy dissipation โ€” โˆฅ1โŸฉโ†’โˆฅ0โŸฉ\|1\rangle \to \|0\rangle decay (T1T_1)

Usage with NoisyQuantumSimulator (from CSharpNumerics.Engines.Quantum):

using CSharpNumerics.Physics.Quantum.NoiseModels;
using CSharpNumerics.Engines.Quantum;

var circuit = QuantumCircuitBuilder.New(2).H(0).CNOT(0, 1).Build();

// Ideal simulation
var ideal = new QuantumSimulator().Run(circuit);

// Noisy simulation โ€” channels stacked, applied after each gate
var noisy = new NoisyQuantumSimulator(new Random(42))
.WithNoise(new DepolarizingNoise(0.01))
.WithNoise(new AmplitudeDampingNoise(0.005))
.Run(circuit);

double fidelity = QuantumFidelity.Fidelity(ideal, noisy);

INoiseChannel interface

public interface INoiseChannel
{
int QubitCount { get; }
ComplexMatrix[] GetKrausOperators();
}

๐Ÿ›ก๏ธ Quantum Error Correction โ€” Code Definitionsโ€‹

Namespace: CSharpNumerics.Physics.Quantum.ErrorCorrection

The ErrorCorrection sub-namespace defines quantum error-correcting codes as mathematical objects โ€” stabilizers, correction maps, and logical operators. The simulation/orchestration layer lives in Engines.Quantum.ErrorCorrection.

IQuantumErrorCorrectionCodeโ€‹

Interface for any [[n, k, d]] stabilizer code:

Property / MethodDescription
PhysicalQubitsNumber of physical qubits (n)
LogicalQubitsNumber of logical qubits (k)
DistanceCode distance (d)
SyndromeQubitsNumber of ancilla qubits for syndrome extraction
GetStabilizers()Returns stabilizer generators as (qubit, Pauli) lists
GetCorrectionMap()Syndrome integer โ†’ corrective (qubit, Pauli) operations
GetLogicalX(i)Logical Xฬ„ operator for logical qubit i
GetLogicalZ(i)Logical Zฬ„ operator for logical qubit i

BitFlipCode3 โ€” [[3,1,1]]โ€‹

Encodes โˆฃฯˆโŸฉ=ฮฑโˆฃ0โŸฉ+ฮฒโˆฃ1โŸฉ|\psi\rangle = \alpha|0\rangle + \beta|1\rangle into ฮฑโˆฃ000โŸฉ+ฮฒโˆฃ111โŸฉ\alpha|000\rangle + \beta|111\rangle. Corrects any single-qubit X (bit-flip) error.

Stabilizers: Z0Z1Z_0 Z_1, Z1Z2Z_1 Z_2

SyndromeErrorCorrection
00Noneโ€”
01X0X_0Apply X to qubit 0
10X2X_2Apply X to qubit 2
11X1X_1Apply X to qubit 1

Logical operators: Xห‰=X0X1X2\bar{X} = X_0 X_1 X_2, Zห‰=Z0\bar{Z} = Z_0

PhaseFlipCode3 โ€” [[3,1,1]]โ€‹

Encodes โˆฃฯˆโŸฉ|\psi\rangle into ฮฑโˆฃ+++โŸฉ+ฮฒโˆฃโˆ’โˆ’โˆ’โŸฉ\alpha|{+}{+}{+}\rangle + \beta|{-}{-}{-}\rangle. Corrects any single-qubit Z (phase-flip) error.

Stabilizers: X0X1X_0 X_1, X1X2X_1 X_2

SyndromeErrorCorrection
00Noneโ€”
01Z0Z_0Apply Z to qubit 0
10Z2Z_2Apply Z to qubit 2
11Z1Z_1Apply Z to qubit 1

Logical operators: Xห‰=X0\bar{X} = X_0, Zห‰=Z0Z1Z2\bar{Z} = Z_0 Z_1 Z_2

using CSharpNumerics.Physics.Quantum.ErrorCorrection;

var code = new BitFlipCode3();
var stabs = code.GetStabilizers(); // [{(0,'Z'),(1,'Z')}, {(1,'Z'),(2,'Z')}]
var map = code.GetCorrectionMap(); // 0โ†’[], 1โ†’[(0,'X')], 2โ†’[(2,'X')], 3โ†’[(1,'X')]
var logX = code.GetLogicalX(); // [(0,'X'),(1,'X'),(2,'X')]

ShorCode9 โ€” [[9,1,3]]โ€‹

Shor's 9-qubit code โ€” the first code to correct any single-qubit error (X, Z, or Y). Uses three blocks of three qubits: inner bit-flip repetition within blocks, outer phase-flip repetition across blocks.

โˆฃ0โŸฉL=(โˆฃ000โŸฉ+โˆฃ111โŸฉ)(โˆฃ000โŸฉ+โˆฃ111โŸฉ)(โˆฃ000โŸฉ+โˆฃ111โŸฉ)22|0\rangle_L = \frac{(|000\rangle+|111\rangle)(|000\rangle+|111\rangle)(|000\rangle+|111\rangle)}{2\sqrt{2}} โˆฃ1โŸฉL=(โˆฃ000โŸฉโˆ’โˆฃ111โŸฉ)(โˆฃ000โŸฉโˆ’โˆฃ111โŸฉ)(โˆฃ000โŸฉโˆ’โˆฃ111โŸฉ)22|1\rangle_L = \frac{(|000\rangle-|111\rangle)(|000\rangle-|111\rangle)(|000\rangle-|111\rangle)}{2\sqrt{2}}

8 stabilizer generators:

GeneratorOperatorType
g1โ€ฆg6g_1 \ldots g_6ZiZi+1Z_i Z_{i+1} within each blockBit-flip detection
g7g_7X0X1X2X3X4X5X_0 X_1 X_2 X_3 X_4 X_5Phase-flip detection (blocks 0โ€“1)
g8g_8X3X4X5X6X7X8X_3 X_4 X_5 X_6 X_7 X_8Phase-flip detection (blocks 1โ€“2)

Correction: The 8-bit syndrome (256 values) maps to at most one X correction + one Z correction. Each block's 2-bit sub-syndrome identifies bit-flip errors exactly as in BitFlipCode3. The 2-bit phase-flip sub-syndrome identifies which block suffered a Z error.

Logical operators: Xห‰=X0X1โ€ฆX8\bar{X} = X_0 X_1 \ldots X_8, Zห‰=Z0Z3Z6\bar{Z} = Z_0 Z_3 Z_6

var shor = new ShorCode9();
var stabs = shor.GetStabilizers(); // 8 generators
var map = shor.GetCorrectionMap(); // 256 syndrome entries

SteaneCode7 โ€” [[7,1,3]]โ€‹

The Steane code โ€” the smallest CSS (Calderbank-Shor-Steane) code, correcting any single-qubit error using only 7 physical qubits. Built from the classical [7,4,3] Hamming code and its dual [7,3,4] code.

โˆฃ0โŸฉL=18โˆ‘xโˆˆC2โˆฃxโŸฉโˆฃ1โŸฉL=18โˆ‘xโˆˆC2+vโˆฃxโŸฉ|0\rangle_L = \frac{1}{\sqrt{8}} \sum_{x \in C_2} |x\rangle \qquad |1\rangle_L = \frac{1}{\sqrt{8}} \sum_{x \in C_2 + v} |x\rangle

where C2C_2 is the [7,3,4] dual Hamming code and v=(1110000)v = (1110000).

6 stabilizer generators:

GeneratorOperatorType
g1g_1Z3Z4Z5Z6Z_3 Z_4 Z_5 Z_6X-error detection
g2g_2Z1Z2Z5Z6Z_1 Z_2 Z_5 Z_6X-error detection
g3g_3Z0Z2Z4Z6Z_0 Z_2 Z_4 Z_6X-error detection
g4g_4X3X4X5X6X_3 X_4 X_5 X_6Z-error detection
g5g_5X1X2X5X6X_1 X_2 X_5 X_6Z-error detection
g6g_6X0X2X4X6X_0 X_2 X_4 X_6Z-error detection

Correction: The 6-bit syndrome has two independent 3-bit halves โ€” Z-stabilizer syndrome (bits 0โ€“2) identifies X errors, X-stabilizer syndrome (bits 3โ€“5) identifies Z errors, using the Hamming decoding map: syndrome sโ†’s \to qubit jj where column jj of the parity-check matrix equals the binary expansion of ss.

Logical operators: Xห‰=X0X1โ€ฆX6\bar{X} = X_0 X_1 \ldots X_6, Zห‰=Z0Z1โ€ฆZ6\bar{Z} = Z_0 Z_1 \ldots Z_6

var steane = new SteaneCode7();
var stabs = steane.GetStabilizers(); // 6 generators (3 Z-type + 3 X-type)
var map = steane.GetCorrectionMap(); // 64 syndrome entries