State-vector simulator#
A small batched state-vector simulator for parameterised circuits, in pure NumPy.
Qubit q is bit q of the basis-state index (Qiskit ordering). Gate angles are expressions: a
number, W (trainable weight k), X (feature j of each sample, scaled and shifted),
XX (a product feature) or a constant.
Circuits are simulated for a whole batch of samples at once, which makes training parameterised circuits
fast without a quantum SDK. Gradients are exact and cheap (Circuit.value_and_grad(), adjoint
method). Circuit.to_qiskit() produces the same circuit for Aer, IBM Quantum or Amazon Braket
(via quantum_mind.circuits.run()).
Examples
>>> import numpy as np
>>> from quantum_mind.quantum import Circuit, W
>>> c = Circuit(2).h(0).cx(0, 1) # Bell state
>>> c.probabilities().round(3)
array([[0.5, 0. , 0. , 0.5]])
>>> c = Circuit(1).ry(W(0), 0) # one trainable rotation
>>> c.probabilities([np.pi]).round(3)
array([[0., 1.]])
Classes
Trainable weight as a gate angle. |
|
Input feature as a gate angle. |
|
Product feature used by ZZ feature maps. |
|
Parameterised quantum circuit with a batched simulator. |
Functions
Apply a k-qubit matrix to a batch of states. |
|
Born-rule probabilities. |
|
Expectation of Pauli Z on one qubit. |
Data
beyond this a state vector does not fit in typical memory (2^22 x 16 bytes per sample). |
- class XX(i, j, a=3.141592653589793, scale=1.0)[source]#
Bases:
objectProduct feature used by ZZ feature maps.
- class Circuit(n)[source]#
Bases:
objectParameterised quantum circuit with a batched simulator.
Build the circuit with the gate methods (each returns
self, so calls chain) and simulate it withstate()orprobabilities().- Parameters:
n (
int) – Number of qubits, at mostMAX_QUBITS.- Variables:
- Raises:
ValueError – If
nexceedsMAX_QUBITS.
- diagonal(phases, label='D')[source]#
Diagonal unitary diag(exp(i phases)) on all qubits (for example a cost or oracle layer).
- state(w=None, X_=None, init=None)[source]#
Simulate the circuit.
- Parameters:
w (
array_like, optional) – Weights, shape(K,)shared by the batch or(B, K)one per sample. Default zeros.X (
array_like, optional) – Input samples, shape(B, n_features).init (
array_like, optional) – Initial state (default \(|0\dots0\rangle\)).
- Returns:
numpy.ndarray– Final states, shape(B, 2**n).- Raises:
ValueError – If fewer weights than
n_weightsare given.
- value_and_grad(w, X_, loss, chunk=None)[source]#
Loss and its exact gradient with respect to the weights (adjoint method).
The circuit is run forward once, then backwards once with the inverse gates, so the cost is about three simulations whatever the number of weights. Samples are processed in chunks (memory
O(chunk * 2**n)). Weights shared by several gates (for example a repeated rotation angle) are handled.- Parameters:
w (
array_like) – Weights, shape(K,).X (
array_likeorNone) – Input samples, shape(B, n_features).loss (
callable) –loss(psi, rows) -> (L, phi):Lis the loss summed over the samplesrowsof the chunk andphi= dL/d(conj psi), with the shape ofpsi.chunk (
int, optional) – Samples per chunk (default: about 2**21 amplitudes).
- Returns:
loss (
float) – Total loss.grad (
numpy.ndarray) – Gradient, shape(K,).
- probabilities(w=None, X_=None)[source]#
Born-rule probabilities of the final states.
- Parameters:
w (
array_like, optional) – Weights.X (
array_like, optional) – Input samples.
- Returns:
numpy.ndarray– Shape(B, 2**n).
- to_qiskit(w=None, x=None, measure=True)[source]#
Export to Qiskit with every angle bound.
- Parameters:
w (
array_like, optional) – Weights.x (
array_like, optional) – One input sample.measure (
bool, optional) – Add a final measurement of every qubit.
- Returns:
qiskit.QuantumCircuit– Ready forquantum_mind.circuits.run()on Aer, IBM Quantum or Amazon Braket.
- apply_matrix(state, M, qubits, n)[source]#
Apply a k-qubit matrix to a batch of states.
- Parameters:
state (
numpy.ndarray) – Batch of states, shape(B, 2**n).M (
numpy.ndarray) –(2**k, 2**k)matrix shared by the batch, or(B, 2**k, 2**k)one per sample. The first qubit inqubitsis the least significant bit of M’s index.qubits (
sequenceofint) – Qubits acted on.n (
int) – Total number of qubits.
- Returns:
numpy.ndarray– New batch of states, shape(B, 2**n). Diagonal two-qubit gates use a fast phase path.
- basis_probs(psi)[source]#
Born-rule probabilities.
- Parameters:
psi (
numpy.ndarray) – State or batch of states.- Returns:
numpy.ndarray– \(|\psi|^2\).
- expectation_z(psi, q, n)[source]#
Expectation of Pauli Z on one qubit.
- Parameters:
psi (
numpy.ndarray) – Batch of states, shape(B, 2**n).q (
int) – Qubit.n (
int) – Number of qubits.
- Returns:
numpy.ndarray– \(\langle Z_q \rangle\) for each state, shape(B,).
- MAX_QUBITS#
beyond this a state vector does not fit in typical memory (2^22 x 16 bytes per sample).
- Type:
Largest number of qubits