Linear algebra#
Linear-algebra building blocks of quantum-like models.
States are unit vectors (real or complex) or density matrices. A “yes” answer to a question is an orthogonal projector \(P\), and answering applies the Lüders rule
Nothing here assumes a particular domain: the model families, the robotics layer and the circuit builders are all written on top of these functions.
Functions
Scale a vector to unit length. |
|
Orthogonal projector onto the span of a set of vectors. |
|
Projector onto the orthogonal complement, \(I - P\). |
|
Apply the Lüders rule for one projective measurement outcome. |
|
Probabilities of every yes/no answer sequence to a sequence of questions. |
|
Unit vector from hyperspherical angles. |
|
Orthonormal frame built from Givens rotations. |
|
Density matrix of a pure state. |
|
Partial dephasing channel. |
|
Lindblad generator as a matrix acting on the row-stacked density matrix. |
|
Evolve a density matrix under a Lindblad generator. |
|
Time-evolution operator \(e^{-iHt}\). |
|
Test whether a matrix is an orthogonal projector. |
- normalize(v)[source]#
Scale a vector to unit length.
- Parameters:
v (
array_like) – Real or complex vector.- Returns:
numpy.ndarray–v / ||v||, real ifvis real and complex otherwise.- Raises:
ValueError – If
vis the zero vector.
- projector(basis)[source]#
Orthogonal projector onto the span of a set of vectors.
The vectors are orthonormalised first (QR decomposition), so any spanning set may be passed.
- Parameters:
basis (
array_like) – A single vector, or a 2D array whose rows span the subspace.- Returns:
numpy.ndarray– Hermitian, idempotent matrix \(QQ^\dagger\) of shape(d, d).
Examples
>>> from quantum_mind.core import projector >>> projector([1, 1]).round(2) array([[0.5, 0.5], [0.5, 0.5]])
- complement(P)[source]#
Projector onto the orthogonal complement, \(I - P\).
- Parameters:
P (
numpy.ndarray) – Orthogonal projector of shape(d, d).- Returns:
numpy.ndarray– The “no” projector belonging to the “yes” projectorP.
- luders(psi, P)[source]#
Apply the Lüders rule for one projective measurement outcome.
- Parameters:
psi (
numpy.ndarray) – Normalised state vector.P (
numpy.ndarray) – Projector of the outcome.
- Returns:
probability (
float) – \(\lVert P\psi \rVert^2\).state (
numpy.ndarray) – Post-measurement state \(P\psi / \lVert P\psi \rVert\); the unnormalised vector is returned when the probability is numerically zero.
- sequence_probabilities(psi, projectors, order)[source]#
Probabilities of every yes/no answer sequence to a sequence of questions.
Each question is answered in turn with the Lüders rule, so the result depends on the order whenever the projectors do not commute (the source of question-order effects).
- Parameters:
psi (
numpy.ndarray) – Initial normalised state.projectors (
dict) – Maps a question name to the projector of its “yes” answer.order (
sequenceofstr) – Question names in the order they are asked.
- Returns:
dict–{(a1, a2, ...): probability}witha = 1for yes and0for no. The values sum to 1.
Examples
>>> import numpy as np >>> from quantum_mind.core import projector, sequence_probabilities >>> P = {'A': projector([1, 0]), 'B': projector([1, 1])} >>> p = sequence_probabilities(np.array([1.0, 0.0]), P, ['A', 'B']) >>> round(p[(1, 1)], 3) 0.5
- angles_to_unit(angles)[source]#
Unit vector from hyperspherical angles.
- Parameters:
angles (
array_like) –d - 1angles \(\theta_1, \dots, \theta_{d-1}\).- Returns:
numpy.ndarray– Real unit vector in \(\mathbb{R}^d\) with \(v_i = \cos\theta_i \prod_{j<i} \sin\theta_j\) (the last entry has no cosine).
- givens_frame(angles, d)[source]#
Orthonormal frame built from Givens rotations.
- Parameters:
angles (
array_like) –d (d - 1) / 2rotation angles, one per coordinate plane(i, j)withi < j.d (
int) – Dimension.
- Returns:
numpy.ndarray– Orthogonal(d, d)matrix whose columns form an orthonormal basis. Every rotation of \(\mathbb{R}^d\) with determinant 1 can be written this way.
- density(psi)[source]#
Density matrix of a pure state.
- Parameters:
psi (
array_like) – Normalised state vector.- Returns:
numpy.ndarray– \(\rho = |\psi\rangle\langle\psi|\).
- dephase(rho, strength, basis_projectors=None)[source]#
Partial dephasing channel.
\[\rho \mapsto (1 - s)\,\rho + s \sum_k P_k \rho P_k\]- Parameters:
rho (
numpy.ndarray) – Density matrix.strength (
float) – Dephasing strengthsin [0, 1];s = 1removes all coherences between the subspaces.basis_projectors (
sequenceofnumpy.ndarray, optional) – Projectors \(P_k\) that sum to the identity. Defaults to the computational basis.
- Returns:
numpy.ndarray– The dephased density matrix.
- lindblad_superoperator(H, jumps, rates)[source]#
Lindblad generator as a matrix acting on the row-stacked density matrix.
\[\dot\rho = -i[H, \rho] + \sum_k \gamma_k \left(L_k \rho L_k^\dagger - \tfrac12 \{L_k^\dagger L_k, \rho\}\right)\]- Parameters:
H (
array_like) – Hamiltonian, shape(n, n).jumps (
sequenceofarray_like) – Jump operators \(L_k\).rates (
sequenceoffloat) – Rates \(\gamma_k \ge 0\), one per jump operator.
- Returns:
numpy.ndarray– Superoperator of shape(n**2, n**2); use it withevolve_density().
- evolve_density(rho, superop, t)[source]#
Evolve a density matrix under a Lindblad generator.
- Parameters:
rho (
numpy.ndarray) – Initial density matrix, shape(n, n).superop (
numpy.ndarray) – Generator fromlindblad_superoperator().t (
float) – Evolution time.
- Returns:
numpy.ndarray– \(\rho(t)\), computed with a matrix exponential.
- unitary(H, t)[source]#
Time-evolution operator \(e^{-iHt}\).
- Parameters:
H (
array_like) – Hermitian Hamiltonian.t (
float) – Time.
- Returns:
numpy.ndarray– Unitary matrix.
- is_projector(P, tol=1e-09)[source]#
Test whether a matrix is an orthogonal projector.
- Parameters:
P (
numpy.ndarray) – Square matrix.tol (
float, optional) – Absolute tolerance for \(P^2 = P\) and \(P = P^\dagger\).
- Returns:
bool– True ifPis Hermitian and idempotent withintol.