Skip to main content

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 float or a qiskit Parameter / ParameterExpression; the gate is equivariant for any value.
  • Returns: A 2-qubit QuantumCircuit implementing 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 generic U_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_2 block (PhaseGate).
    • theta1 — The lam Euler angle of U_2.
    • theta2 — The theta (rotation) Euler angle of U_2.
    • theta3 — The phi Euler angle of U_2.
  • Returns: A 3-qubit QuantumCircuit implementing 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 a QuantumCircuit 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) — ParameterVector name (default "theta").
  • Returns: A parametrized QuantumCircuit over num_qubits qubits. Free parameters are accessible via circuit.parameters.
  • Raises: ValueError — If layout is 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 gate U 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:
    • U2^n by 2^n unitary as an array-like.
    • tol (float) — Threshold on the largest commutator entry.
  • Returns: Tuple (ok, violation) where ok = (max_a |[U, S_a]| < tol) and violation is the maximum commutator entry over a in {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 operator S^2 = S_x^2 + S_y^2 + S_z^2 and the z-component S_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-qubit su2 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, a Gate, or a 2^n by 2^n numpy.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 check job.fidelity on 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.
  • Returns: The compression job. Call job.result() to retrieve the compressed circuit as a CircuitModel and read job.fidelity for the achieved process fidelity.
  • Return type: Su2EquivariantCompilationJobModel
  • Raises:
    • ValueError — If target exceeds the 10-qubit limit.
    • TypeError — If target is not a QuantumCircuit, Gate, or ndarray.

Example

Transpiling both to a device basis shows the two-qubit-gate drop:

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