DensityMatrix encodes both pure and mixed quantum states as a matrix ρ satisfying Tr(ρ) = 1. It lives in the github.com/itsubaki/q/quantum/density package.
WeightedState
WeightedState pairs a qubit with a classical probability, forming one term in a mixed ensemble.
Classical probability of this state in the ensemble. Must be non-negative. The sum across all states in the ensemble must equal 1.0.
The quantum state associated with this weight. All qubits in an ensemble must have the same dimension.
Constructors
From
ρ = |ψ⟩⟨ψ| from a single qubit. Equivalent to calling FromStates with a single entry at probability 1.0.
FromStates
Normalize first if they do not already sum to 1.
Normalize
WeightedState with probabilities rescaled so they sum to 1. The original slice is not modified.
IsValid
WeightedState is suitable for constructing a density matrix. Returns false if any of the following hold:
- The slice is empty.
- Qubits have inconsistent dimensions.
- Any probability is negative.
- Probabilities do not sum to 1 (within optional tolerance
tol).
Properties
At
ρᵢⱼ at row i, column j (0-based).
Matrix
*matrix.Matrix. Useful when you need to pass the raw matrix to other parts of the library (e.g., gate.TensorProduct).
Dim
n-qubit system the matrix is 2ⁿ × 2ⁿ.
NumQubits
n such that Dim() == (2ⁿ, 2ⁿ).
Trace
Tr(ρ). For a valid density matrix this is always 1.0.
Purity
Tr(ρ²). A value of 1 indicates a pure state; values less than 1 indicate a mixed state. For an n-qubit maximally mixed state the purity equals 1 / 2ⁿ.
IsPure
Purity() ≈ 1 within optional tolerance tol.
IsMixed
IsPure() is false — i.e., whether the state is a non-trivial mixture.
IsHermitian
ρ = ρ† within optional tolerance tol. Every valid density matrix is Hermitian.
Probability
Tr(ρ |q⟩⟨q|) — the probability that a measurement in the computational basis yields the state q.
ExpectedValue
Tr(ρ U) — the expectation value of the observable U in state ρ.
Seq2
complex128 values.
Operations
Apply
ρ' = U ρ U†. Returns a new DensityMatrix; the receiver is not modified.
ApplyChannel
*Channel values sequentially. Each channel is expanded from its Kraus operators against the current number of qubits. Returns a new DensityMatrix.
ApplyChannelFunc
ChannelFunc values. Each function receives the qubit count n and returns a *Channel, which is then applied via ApplyChannel. This is the preferred high-level API for the built-in noise channels.
ApplyKraus
ρ' = Σᵢ Kᵢ ρ Kᵢ†. Returns a new DensityMatrix. Use this when you have hand-crafted operator matrices.
PartialTrace / TraceOut
TraceOut is an alias for PartialTrace.
The length of qb must be at most NumQubits() - 1; you cannot trace out all qubits.
Qubit indices are 0-based, ordered from most significant to least significant bit, matching the rest of the
itsubaki/q API.TensorProduct
ρ ⊗ σ — the tensor product of two density matrices, representing a composite system with no entanglement between the two subsystems.
Project
|q⟩. Returns:
p float64— the probability of obtaining outcomeq.*DensityMatrix— the post-measurement state(|q⟩⟨q| ρ |q⟩⟨q|) / p.
p is zero (within tol) the returned matrix is all-zeros.
Clone
Convenience channel methods
DensityMatrix exposes thin wrappers around ApplyChannelFunc for every built-in channel. Each returns a new *DensityMatrix; the receiver is not modified.
| Method | Delegates to |
|---|---|
BitFlip(p float64, qb int) | density.BitFlip |
PhaseFlip(p float64, qb int) | density.PhaseFlip |
BitPhaseFlip(p float64, qb int) | density.BitPhaseFlip |
Depolarizing(p float64, qb int) | density.Depolarizing |
AmplitudeDamping(gamma float64, qb int) | density.AmplitudeDamping |
PhaseDamping(gamma float64, qb int) | density.PhaseDamping |
Pauli(px, py, pz float64, qb int) | density.Pauli |
Flip(p float64, u *matrix.Matrix, qb int) | density.Flip |