dbac.dbqite

One step of DBAC, called a DB-QITE step (double-bracket quantum imaginary-time evolution) in the code. A step takes the current state of the data qubit and a duration \(s\) and returns a colder state:

\[ \rho \mapsto e^{is\rho'}\,\rho\,e^{-is\rho'}, \qquad \rho' = e^{is\hat H}\rho\, e^{-is\hat H}, \qquad \hat H = -Z . \]

All step functions share the signature step(psi, s) -> density matrix, so any of them can be handed to dbac.gci.GCI to run several steps. They differ only in how \(e^{is\rho'}\) is applied.

See One DBAC step for a walkthrough with plots.

QITE_dme_select_M([M])

Build a DB-QITE step function that uses M DME (Trotter) steps.

ideal_DME(psi, s)

One DB-QITE step with the reflection applied exactly (the limit M -> infinity).

initial_psi(psi, s)

A step function that does nothing: returns psi unchanged.

QITE_GCI_dme(psi, s[, M])

One DB-QITE step with Trotterized DME, using M = 100 DME steps by default.

DME(instruction, data, t[, M])

Apply exp(i t instruction) to data with Trotterized density matrix exponentiation, without ever exponentiating instruction itself.

H

The Hamiltonian H = -Z = diag(-1, 1) whose ground state |0> DBAC cools towards.

target_energy

Energy of the target (ground) state |0>.

Step functions

QITE_dme_select_M(M: int = 100)[source]

Build a DB-QITE step function that uses M DME (Trotter) steps.

The returned function step(psi, s) performs one DBAC step of duration s on psi: it rotates a copy of the state about H to get the instruction exp(i s H) psi exp(-i s H), then applies it to psi with DME using M steps. M = 1 and M = 2 correspond to circuits A and B of the paper’s experiment.

Parameters:

M (int) – Number of DME steps per DBAC step.

Returns:

step(psi, s), which takes a (2, 1) state vector or 2x2 density matrix and returns the 2x2 density matrix after the step.

Return type:

Callable[[np.ndarray, float], np.ndarray]

Example

>>> import numpy as np
>>> from dbac.dbqite import QITE_dme_select_M, H
>>> from dbac.utils import rx_sweep
>>> psi = rx_sweep([0.5])[0]            # energy 0, halfway to |1>
>>> rho = QITE_dme_select_M(1)(psi, np.pi / 4)
>>> round(float(np.trace(rho @ H).real), 3)
-0.5
ideal_DME(psi: ndarray, s: float) → ndarray[source]

One DB-QITE step with the reflection applied exactly (the limit M -> infinity).

Same as QITE_dme_select_M(M)(psi, s) for very large M, but computes exp(i s rho') by matrix exponential instead of DME. For this step the paper gives the energy afterwards in closed form, E0 - 2 sin^2(s) (1 - E0^2) [(1 - cos s) E0 + cos s].

Parameters:
  • psi (np.ndarray) – Current state, a (2, 1) state vector or 2x2 density matrix.

  • s (float) – Step duration.

Returns:

The 2x2 density matrix after the step.

Return type:

np.ndarray

Example

>>> import numpy as np
>>> from dbac.dbqite import ideal_DME, H
>>> from dbac.utils import rx_sweep
>>> rho = ideal_DME(rx_sweep([0.5])[0], np.pi / 4)
>>> round(float(np.trace(rho @ H).real), 3)   # -1/sqrt(2)
-0.707
initial_psi(psi: ndarray, s: float) → ndarray[source]

A step function that does nothing: returns psi unchanged.

Useful as the “no cooling” baseline, since it has the same signature as the other step functions and can be passed to dbac.gci.GCI.

Parameters:
  • psi (np.ndarray) – Current state.

  • s (float) – Step duration (unused).

Returns:

The input state.

Return type:

np.ndarray

QITE_GCI_dme(psi: ndarray, s: float, M: int = 100) → ndarray[source]

One DB-QITE step with Trotterized DME, using M = 100 DME steps by default.

Equivalent to QITE_dme_select_M(M)(psi, s); prefer QITE_dme_select_M when passing a step function with a specific M to dbac.gci.GCI.

Parameters:
  • psi (np.ndarray) – Current state, a (2, 1) state vector or 2x2 density matrix.

  • s (float) – Step duration.

  • M (int) – Number of DME steps.

Returns:

The 2x2 density matrix after the step.

Return type:

np.ndarray

DME inside the step

DME(instruction: ndarray, data: ndarray, t: float, M: int = 100) → ndarray[source]

Apply exp(i t instruction) to data with Trotterized density matrix exponentiation, without ever exponentiating instruction itself.

Each of the M steps is the DME channel for duration t/M with a fresh copy of instruction, written in closed form: cos^2 data + sin^2 instruction + i sin cos [instruction, data]. The result approaches exp(i t instruction) data exp(-i t instruction) with an error of order t^2 / M.

Note the argument order: the instruction comes first, unlike the functions in dbac.dme.

Parameters:
  • instruction (np.ndarray) – 2x2 density matrix used as the Hamiltonian (the instruction state).

  • data (np.ndarray) – 2x2 density matrix to transform (the data state).

  • t (float) – Total DME duration.

  • M (int) – Number of Trotter steps, i.e. instruction copies consumed.

Returns:

The transformed 2x2 data density matrix.

Return type:

np.ndarray

Example

>>> import numpy as np
>>> from dbac.dbqite import DME
>>> zero = np.array([[1, 0], [0, 0]], dtype=complex)    # data |0><0|
>>> plus = np.full((2, 2), 0.5, dtype=complex)          # instruction |+><+|
>>> # t = pi/2 with one step is a full SWAP: the data becomes the instruction
>>> DME(plus, zero, t=np.pi / 2, M=1).real.round(3)
array([[0.5, 0.5],
       [0.5, 0.5]])

The Hamiltonian

H

The Hamiltonian H = -Z = diag(-1, 1) whose ground state |0> DBAC cools towards.

eigs

the ground-state energy -1 and the excited-state energy +1.

Type:

Eigenvalues of H

target_energy

Energy of the target (ground) state |0>.

H_sh

The same Hamiltonian as a qibo SymbolicHamiltonian, for qibo-circuit states.