haiqu.sdk.qml.equivariant.su2_equivariant_2_qubit_gate(theta)
The 2-qubit SU(2)-equivariant gate. Under total spin, two qubits split into a 1-dimensional spin-0 “singlet” subspace (the antisymmetric state(|01> - |10>)/sqrt(2)) and a
3-dimensional spin-1 “triplet” subspace (the symmetric states). This gate
phases the singlet by exp(i*theta) and acts as identity on the
triplet. It is the unique 2-qubit SU(2)-equivariant gate (up to global
phase) and the building block for the n-qubit ansatz.
Hardware form: cx . crx(theta) . p(theta/2) . cx.
- Parameters:
theta — Angle. Accepts
floator a qiskitParameter/ParameterExpression; the gate is equivariant for any value. - Returns:
A 2-qubit
QuantumCircuitimplementing the gate. - Return type: QuantumCircuit
Example
haiqu.sdk.qml.equivariant.su2_equivariant_3_qubit_gate(theta0, theta1, theta2, theta3)
The exact 3-qubit SU(2)-equivariant gate. The 3-qubit Hilbert space decomposes as spin-3/2 (dim 4, multiplicity 1) plus two copies of spin-1/2 (dim 2, multiplicity 2). The equivariant gate is identity on the spin-3/2 sector and applies a genericU_2 (x) I_2
that mixes the two spin-1/2 copies while leaving the magnetic label
intact. The four angles parametrize U_2.
Constructed as S_3 . diag(I_4, U_2(theta) (x) I_2) . S_3^dagger where
S_3 is the 3-qubit Schur transform. The four angles are the Euler
angles of U_2 in qiskit’s CUGate(theta, phi, lam, gamma)
convention (a controlled U(theta, phi, lam) with global phase
gamma):
- Parameters:
- theta0 — Global phase applied to the
U_2block (PhaseGate). - theta1 — The
lamEuler angle ofU_2. - theta2 — The
theta(rotation) Euler angle ofU_2. - theta3 — The
phiEuler angle ofU_2.
- theta0 — Global phase applied to the
- Returns:
A 3-qubit
QuantumCircuitimplementing the gate. - Return type: QuantumCircuit
haiqu.sdk.qml.equivariant.su2_equivariant_ansatz(num_qubits, layout=‘brickwork’, num_layers=1, name=‘theta’)
Build a parametrized SU(2)-equivariant ansatz. Returns aQuantumCircuit with a ParameterVector of free angles,
one per 2-qubit su2 gate. Equivariance is a structural property of
the building block and holds for any parameter binding the optimiser
ever tries: su2(theta) = exp(i*theta*P_ij) where
P_ij = (I - SWAP_ij) / 2 is the pair-singlet projector, and
P_ij commutes with the global S_x, S_y, S_z. Products
of equivariant unitaries are equivariant, so the whole parametrized
circuit lies inside the equivariant subgroup of unitaries.
Contrast with Qiskit’s EfficientSU2: that ansatz uses single-qubit
Pauli rotations, which do NOT commute with the global spin operators,
so it is not equivariant for any non-trivial parameter binding.
- Parameters:
- num_qubits (int) — Number of qubits.
- layout (str | List *[*List *[*int ] ]) —
"brickwork"(nearest-neighbour even-then-odd; the default),"linear"(chain of adjacent pairs), or a list of[i, j]qubit-pair lists for a custom layout. - num_layers (int) — Repetitions of the chosen layout pattern. Defaults to 1.
- name (str) —
ParameterVectorname (default"theta").
- Returns:
A parametrized
QuantumCircuitovernum_qubitsqubits. Free parameters are accessible viacircuit.parameters.
- Raises:
ValueError — If
layoutis not a recognised string or a list of qubit pairs.
- Return type: QuantumCircuit
Example
haiqu.sdk.qml.equivariant.brickwork_pattern(num_qubits, num_layers)
Nearest-neighbour brickwork pattern: even bonds, then odd bonds, repeated.- Parameters:
- num_qubits (int) — Number of qubits.
- num_layers (int) — Number of brickwork layers.
- Returns:
A list of
[i, j]qubit pairs in application order. - Return type: List[List[int]]
Example
haiqu.sdk.qml.equivariant.is_su2_equivariant(U, tol=1e-08)
Check whether a unitary is SU(2)-equivariant. A gateU on n qubits is SU(2)-equivariant iff it commutes with the
three global spin generators S_x, S_y, S_z. Commuting with
every generator is necessary AND sufficient for commuting with the whole
SU(2) group, and avoids forming the total-spin Casimir
S^2 = S_x^2 + S_y^2 + S_z^2 (each S_a is a sparse sum of n Paulis).
Checking only [U, S^2] = [U, S_z] = 0 (with S^2 the Casimir above)
is strictly weaker: for example exp(i*phi*S_z) commutes with both yet
is NOT equivariant.
- Parameters:
- U —
2^nby2^nunitary as an array-like. - tol (float) — Threshold on the largest commutator entry.
- U —
- Returns:
Tuple
(ok, violation)whereok = (max_a |[U, S_a]| < tol)andviolationis the maximum commutator entry overain{x, y, z}.
- Raises:
ValueError — If the matrix shape is not
(2^n, 2^n).
- Return type: Tuple[bool, float]
haiqu.sdk.qml.equivariant.spin_generators(n)
Dense SU(2) generators(S_x, S_y, S_z) for n qubits.
- Parameters: n (int) — Number of qubits.
- Returns:
A tuple
(S_x, S_y, S_z)of dense(2**n, 2**n)complex matrices. - Return type: Tuple[ndarray, ndarray, ndarray]
haiqu.sdk.qml.equivariant.total_spin_ops(n)
Return dense matrices(S^2, S_z) for n qubits.
- Parameters: n (int) — Number of qubits.
- Returns:
Tuple of dense
(2**n, 2**n)matrices for the total-spin Casimir operatorS^2 = S_x^2 + S_y^2 + S_z^2and the z-componentS_z. - Return type: Tuple[ndarray, ndarray]
Haiqu.su2_equivariant_compilation(target, *, target_fidelity=0.99, max_layers=6, num_restarts=10, seed=0)
Compress an SU(2)-equivariant gate into a brick of 2-qubitsu2 gates.
Submits a job that fits a shallow brickwork of 2-qubit su2 gates to
target and returns the compressed circuit. The headline use is
compressing the exact 3-qubit equivariant gate into a 2q brick, which
transpiles to substantially fewer two-qubit gates.
The target must be SU(2)-equivariant (commute with the global spin
generators); non-equivariant inputs fail the job. Inherently small-n:
the fit needs the dense 2^n by 2^n target unitary, so the
target is capped at 10 qubits. For larger systems, build a
parametrized su2_equivariant_ansatz() and optimise
at the state level instead.
- Parameters:
- target (QuantumCircuit | Gate | np.ndarray) — SU(2)-equivariant
target. Accepts a
QuantumCircuit, aGate, or a2^nby2^nnumpy.ndarray. - target_fidelity (float) — Requested process fidelity to the target
unitary (default
0.99); a gate (process) fidelity, distinct from the state fidelity used elsewhere in the SDK. This is the goal the fit aims for, not a guarantee: the returned circuit may fall short, so checkjob.fidelityon the result. The fit escalates brickwork depth trying to clear this bar. - max_layers (int) — Cap on brickwork depth before giving up.
- num_restarts (int) — Number of optimiser restarts.
- seed (int) — Random seed for restart initialisation.
- target (QuantumCircuit | Gate | np.ndarray) — SU(2)-equivariant
target. Accepts a
- Returns:
The compression job. Call
job.result()to retrieve the compressed circuit as aCircuitModeland readjob.fidelityfor the achieved process fidelity. - Return type: Su2EquivariantCompilationJobModel
- Raises:
- ValueError — If
targetexceeds the 10-qubit limit. - TypeError — If
targetis not a QuantumCircuit, Gate, or ndarray.
- ValueError — If
Example
class haiqu.sdk.schemas.Su2EquivariantCompilationJobModel(*, id, name=None, description=None, user_id, experiment_id, status, job_type, device_id=‘Haiqu OS’, creation_date, run_date=None, finish_date=None, logs=None, quality=None, info=None, time=None, parameters, circuit_id=None, compression_type)
Job returned for SU(2)-equivariant gate compilation. Mirrors the state-compression surface:result() returns the
compressed circuit and fidelity is the achieved process fidelity of
the compressed brick to the target unitary. The fit runs server-side;
only the circuit and the fidelity are exposed.
- Parameters:
- id (str)
- name (str | None)
- description (str | None)
- user_id (int)
- experiment_id (str)
- status (JobStatus)
- job_type (JobType)
- device_id (str | None)
- creation_date (datetime)
- run_date (datetime | None)
- finish_date (datetime | None)
- logs (str | None)
- quality (float | None)
- info (dict | None)
- time (float | None)
- parameters (dict)
- circuit_id (str | None)
- compression_type (CompressionJobType)
property fidelity : float | None
Process fidelity of the compressed brick to the target unitary.progress()
Display the progress widget, stream logs from the job.result()
Return job result - the compressed circuit. Block and wait for the job to complete.- Return type: CircuitModel
retrieve_status()
Query backend for the job status.- Return type: JobStatus