Python
qblaze
- class qblaze.Simulator
Create a new simulator object.
The simulator supports
Simulator.max_qubit_count()
qubits, which are initially all0
.Example:
>>> from qblaze import Simulator >>> sim = Simulator()
Read the amplitudes of the \(\ket{00\ldots}\) and \(\ket{10\ldots}\) basis states:
>>> state = numpy.zeros(2**1, numpy.complex128) >>> sim.copy_amplitudes(state) >>> state array([1.+0.j, 0.+0.j])
Apply a Hadamard gate to qubit 0, and then a controlled X gate to qubit 1:
>>> sim.h(0) >>> sim.cx(0, 1)
Read the amplitudes of the basis states \(\ket{ij0\dots}\), where \(i, j \in \{0, 1\}\):
>>> state = numpy.zeros(2**2, numpy.complex128) >>> sim.copy_amplitudes(state) >>> state array([0.70710678+0.j, 0. +0.j, 0. +0.j, 0.70710678+0.j])
Measure qubit 1:
>>> sim.measure(1, 11853927852089066602) True
Read the amplitudes again:
>>> state = numpy.zeros(2**2, numpy.complex128) >>> sim.copy_amplitudes(state) >>> state array([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j])
- classmethod max_qubit_count() int
Return the maxumum supported qubit count.
Example:
>>> Simulator.max_qubit_count() 3968
- flush() None
Apply all gates in the gate queue.
Example:
>>> sim.flush()
- dump() None
Dump the state vector to stderr.
- x(target: int, /) None
Apply an X gate.
Equivalent to
sim.u3(target, math.pi, math.pi, 0)
.Example:
>>> sim.x(0)
- y(target: int, /) None
Apply a Y gate.
Equivalent to
sim.u3(target, math.pi, 0, 0)
.Example:
>>> sim.y(0)
- z(target: int, /) None
Apply a Z gate.
Equivalent to
sim.u3(target, 0, math.pi, 0)
.Example:
>>> sim.z(0)
- h(target: int, /) None
Apply a Hadamard gate.
Equivalent to
sim.u3(target, math.pi / 2, 0, math.pi)
.Example:
>>> sim.h(0)
- s(target: int, /) None
Apply an S gate.
Equivalent to
sim.u3(target, 0, math.pi / 2, 0)
.Example:
>>> sim.s(0)
- sdg(target: int, /) None
Apply an inverse S gate.
Equivalent to
sim.u3(target, 0, -math.pi / 2, 0)
.Example:
>>> sim.sdg(0)
- t(target: int, /) None
Apply a T gate.
Equivalent to
sim.u3(target, 0, math.pi / 4, 0)
.Example:
>>> sim.t(0)
- tdg(target: int, /) None
Apply an inverse T gate.
Equivalent to
sim.u3(target, 0, -math.pi / 4, 0).
Example:
>>> sim.tdg(0)
- rx(target: int, theta: float, /) None
Apply a rotation about the X axis.
Equivalent to
sim.u3(target, theta, -math.pi / 2, math.pi / 2)
.Example:
>>> sim.rx(0, math.pi / 2)
- ry(target: int, theta: float, /) None
Apply a rotation about the Y axis.
Equivalent to
sim.u3(target, theta, 0, 0)
.Example:
>>> sim.ry(0, math.pi / 2)
- rz(target: int, theta: float, /) None
Apply a rotation about the Z axis.
Equivalent to
sim.u3(target, 0, theta, 0)
.Example:
>>> sim.rz(0, math.pi / 2)
- u3(target: int, theta: float, phi: float, lam: float, /) None
Apply a general single-qubit gate.
The definition is equivalent up to global phase to the OpenQASM
U
gate:\[\begin{split}U3(\theta, \phi, \lambda) = \left( \begin{matrix} \cos \frac{\theta}{2} & -e^{i \lambda} \sin \frac{\theta}{2} \\ e^{i \phi} \sin \frac{\theta}{2} & e^{i(\phi + \lambda)} \cos \frac{\theta}{2} \end{matrix} \right)\end{split}\]Example:
>>> sim.u3(0, math.pi / 2, math.pi / 2, math.pi / 2)
- cx(control: int, target: int, /) None
Apply a controlled X gate.
Example:
>>> sim.cx(0, 1)
- ccx(control1: int, control2: int, target: int, /) None
Apply a doubly-controlled X gate.
Example:
>>> sim.ccx(0, 1, 2)
- mcx(controls: list[tuple[int, bool]], target: int, /) None
Apply a multiply-controlled X gate.
Each of the
controls
is a pair of(qubit, value)
. The gate is applied to all basis states where the controls have the desired values.Example:
>>> sim.mcx([(0, True), (1, True), (2, True)], 3)
- swap(target1: int, target2: int, /) None
Apply a swap gate.
Example:
>>> sim.swap(0, 1)
- cswap(control: int, target1: int, target2: int, /) None
Apply a controlled swap gate.
Example:
>>> sim.cswap(0, 1, 2)
- mcswap(controls: list[tuple[int, bool]], target1: int, target2: int, /) None
Apply a multiply-controlled swap gate.
Each of the
controls
is a pair of(qubit, value)
. The gate is applied to all basis states where the controls have the desired values.Example:
>>> sim.mcswap([(0, True), (1, True), (2, True)], 3, 4)
- cz(control: int, target: int, /) None
Apply a controlled Z gate.
Example:
>>> sim.cz(0, 1)
- mcphase(controls: list[tuple[int, bool]], theta: float, /) None
Apply a multi-controlled global phase gate.
Each of the
controls
is a pair of(qubit, value)
. The gate is applied to all basis states where the controls have the desired values.Example: The gate
sim.cz(0, 1)
is equivalent to>>> sim.mcphase([(0, True), (1, True)], math.pi)
- measure(target: int, random: int | None = None, /) bool
Measure a single qubit. Return the outcome.
The state vector is collapsed.
The parameter
random
must be a random 64-bit integer (e.g.,random.getrandbits(64)
).Example:
>>> sim.h(0) >>> sim.measure(0, 2375645456254334209) False
- measure_ext(target: int, random: int | None = None, /) tuple[bool, float, float]
Similar to
measure
, but also returns the probabilities.Example:
>>> sim.h(0) >>> sim.measure_ext(0, 2375645456254334209) (False, 0.5, 0.5)
- qubit_probs(target: int, /) tuple[float, float]
Compute the measurement probabilities for the target qubit without measuring it.
Example:
>>> sim.qubit_probs(0) (1.0, 0.0) >>> sim.h(0) >>> sim.qubit_probs(0) (0.5, 0.5)
- copy_amplitudes(buffer: Buffer, /) None
Copy the state vector amplitudes to
buffer
.The amplitude of the ‘i’th state vector is stored at position ‘i’, where the ‘k’th bit of ‘i’ equals the basis value of the ‘k’th qubit.
The buffer must be one of the following:
A single-dimensional array of complex double-precision floating-point numbers.
A single-dimensional array of double-precision floating-point numbers of even length. Even-indexed elements will store the real parts and odd-indexed elements will store the imaginary parts.
A C-contiguous two-dimensional array of double-precision floating-point numbers with shape
(n, 2)
. Elementsbuf[i][0]
will store the real part andbuf[i][1]
will store the imaginary part.
Example:
>>> for i in range(3): sim.h(i) >>> state = numpy.zeros(2**3, numpy.complex128) >>> sim.copy_amplitudes(state) >>> state array([0.35355339+0.j, 0.35355339+0.j, 0.35355339+0.j, 0.35355339+0.j, 0.35355339+0.j, 0.35355339+0.j, 0.35355339+0.j, 0.35355339+0.j])
- clone() Simulator
Clone the quantum state.
A new independent simulator is returned with a copy of the state of this one.
Example:
>>> sim.h(0) >>> sim2 = sim.clone() >>> sim2.measure_ext(0, 15980756942077321109) (True, 0.5, 0.5) >>> sim.measure_ext(0, 1933827847985506032) (False, 0.5, 0.5) >>> sim3 = sim.clone() >>> sim3.measure_ext(0, 15980756942077321109) (False, 1.0, 0.0)
- class qblaze.Config
Simulator configuration options.
Examples:
>>> sim = Simulator(dump_config=False)
>>> sim = Simulator(qubit_count=1)
>>> sim = Simulator(thread_count=16)
>>> sim = Simulator(chunk_size=128*2**10)
>>> sim = Simulator(multithreading_threshold=64*2**10)
>>> sim = Simulator(work_item_min_size=1*2**10)
>>> sim = Simulator(work_item_max_size=16*2**20)
- dump_config: bool
Dumps the simulator configuration to stderr.
Default: no.
- qubit_count: int
Hint about how many qubits will be used.
This option determines how many bits are used to represent qubit indices. The representation is changed automatically when a qubit with a higher index is used. The maximum supported qubit count is returned by by
Simulator.max_qubit_count()
.Default: 1.
- thread_count: int
The number of threads in the thread pool.
Default: nproc.
- chunk_size: int
The chunk size for processing superposition-free gates (in bytes).
If set to SIZE_MAX, then a single chunk is used.
Default: smallest L2 cache size.
- multithreading_threshold: int
The state vector size after which multiple threads will be used (in bytes).
Default: 64 KiB.
- work_item_min_size: int
The minimum size of a thread work item (in bytes).
Use to ensure that the work per item is larger that the communication overhead.
Default: 1 KiB.
- work_item_max_size: int
The maximum size of a thread work item (in bytes).
Use to ensure that there are enough items for threads that finish early.
Default: 16 MiB.
qblaze.qiskit
- qblaze.qiskit.run_circuit(sim: Simulator, qc: QuantumCircuit, /, rng: Random | None = None, *, force_clbits: dict[Clbit, bool] = {}, respect_barriers: bool = False) tuple[dict[Clbit, bool], list[ndarray[tuple[int, ...], dtype[complex128]]]]
Run a circuit on the given simulator.
force_clbits
can be used to force the outcomes of measurements associated with particular classical bits. Simulation will fail if a force outcome has zero (or very close to zero) probability.Returns
(clbits, statevectors)
, whereclbits
is the value of all classical bits at the end of the simulation, andstatevectors
is the list of all statevectors atsave_statevector
instructions.Example:
>>> import qiskit >>> import qiskit_aer >>> from qblaze.qiskit import run_circuit >>> >>> def make_circuit(): ... circ = qiskit.QuantumCircuit(2, 1) ... circ.h(0) ... circ.save_statevector() ... circ.cx(0, 1) ... circ.measure(1, 0) ... circ.save_statevector() ... return circ >>> >>> circ = make_circuit() >>> sim = Simulator() >>> rng = random.Random(42) >>> >>> (clbits, [sv1, sv2]) = run_circuit(sim, circ, rng=rng) >>> >>> [complex(v) for v in sv1] [(0.7071067812+0j), (0.7071067812+0j), 0j, 0j] >>> clbits[circ.clbits[0]] False >>> [complex(v) for v in sv2] [(1+0j), 0j, 0j, 0j]