Python API
The session class
The session class provides a way to set up the experiment table.
You can use the experiment table to run a list of quantum circuits under different conditions, such as number of measurement shots, backends, parameters, etc.
- class core.session
- property all_bitstring_counts
all_bitstring_counts:
After calling session.run(), the counts from running sn shots are stored in a list of shot counts. The indices of this list correspond to the different possible base-2 bitstring solutions, with the mapping from bitstring to list index provided by the function bitstring_index.
- property all_bitstring_probabilities
all_bitstring_probabilities:
The probability distribution from running sn shots stored in a list of solution output probabilities, provided after calling session.run() with calc_gradients set True. The indices of this list correspond to the different possible base-2 bitstring solutions, with the mapping from bitstring to list index provided by the function bitstring_index.
- property all_bitstring_probability_gradients
all_bitstring_probability_gradients:
The probability Jacobians from running sn shots, after calling session.run() with calc_gradients set True. The Jacobian is an array of gradients of the probability of each bitstring combination with respect to the runtime parameters, in the following format (where y is the list of probabilities and x is the parameter list):
\[\begin{split}\begin{bmatrix} \frac{dy_0}{dx_0} & \frac{dy_0}{dx_1} & ... & \frac{dy_0}{dx_n} \\ \frac{dy_1}{dx_0} & \frac{dy_1}{dx_1} & ... & \frac{dy_1}{dx_n} \\ ... \\ \frac{dy_m}{dx_0} & \frac{dy_m}{dx_1} & ... & \frac{dy_m}{dx_n} \end{bmatrix}\end{split}\]As the Jacobian is returned as a list-of-lists, it can be accessed in row major format, and indexing the above matrix can be done accordingly, i.e. all_bitstring_probability_gradients()[0][1] corresponds to the dy_0/dx_1 value. The entry x_i corresponds to the ith parameter in the parameter list (i.e. the parameters ordered by their first appearance in the circuit.) The entry y_i is the output probability of ith bitstring, indexed in the same manner as the all_bitstring_counts. Explicitly, the index i corresponding to a specific bitstring can be obtained by calling bitstring_index(bitstring), with bitstring given as a list of bit values.
- bitstring_index(*args, **kwargs)
Overloaded function.
bitstring_index(self: core.session, arg0: core.VectorBool) -> int
Get the (base-10) integer index for the counts/probabilities list, corresponding to a specific output state specified by a list of bit values.
bitstring_index(self: core.session, arg0: numpy.ndarray[bool]) -> int
Get the (base-10) integer index for the counts/probabilities list, corresponding to a specific output state specified by a list of bit values.
- draw_shot(self: core.session) core.VectorBool
draw_shot : Draw a single shot from the saved results of circuit i, condition j.
- property gpu_device_ids
gpu_device_ids:
Set list of GPU device IDs to use with GPU-enabled backends.
- property irtarget
Circuit object to be executed.
- property noise_model
Circuit object to be executed.
- property num_threads
The number of threads in the Qristal thread pool
- Type:
num_threads
- property one_qubit_gate_depths
one_qubit_gate_depths:
After calling session.run(), get the number of single qubit gates applied to each qubit, using a dictionary where the keys are integers corresponding to qubit indices.
- property qbjson
qbjson:
Get the output QB JSON string sent to QB hardware, after calling session.run().
- property qobj
qobj:
Retrieve the input passed to the aer simulator backend in .qobj JSON format, after calling session.run().
- property results
results:
After calling session.run(), the counts from running sn shots are stored in a dictionary of shot counts. The dictionary keys are bit lists of length qn, with the same bit indexation as the processor registers.
- property results_native
results_native:
An additional results container holding the native measurement results if automatic SPAM correction was enabled in session.
- run(self: core.session) None
Execute quantum circuit synchronously (blocking).
- run_async(self: core.session) core.Handle
Execute quantum circuit asynchronously (non-blocking).
- run_with_SPAM(self: core.session, arg0: int) None
Automatically execute a SPAM measurement and enable automatic SPAM correction. Then automatically exexute run().
- property state_vec
state_vec:
Get the full complex state vector – works with qpp and aer statevector backends only!
- property timing_estimates
timing_estimates:
After calling session.run(), get estimated circuit execution times on hardware, in ms.
- Keys (integers):
0: Total time 1: Initialisation component 2: Gate (max. depth) component 3: Readout component 4: Total time (from classical simulation) 5: PC transfer to controller time
- property transpiled_circuit
transpiled_circuit:
Retrieve the transpiled version of the executed circuit after calling session.run().
- property two_qubit_gate_depths
two_qubit_gate_depths:
After calling session.run(), get the number of two qubit gates applied to each qubit, using a dictionary where the keys are integers corresponding to qubit indices.
- property z_op_expectation
z_op_expectation:
After calling session.run(), get the output expected value in the Z basis, from the shot counts observed.
The Circuit class
The Circuit class represents a quantum circuit, i.e., an ordered sequence of [quantum gates and measurements](https://qristal.readthedocs.io/en/latest/rst/quantum_computing.html).
In addition to elementary gates, it also supports pre-built circuit templates for commonly-used algorithms, such as Quantum Fourier Transform (QFT), algebraic circuits, etc.
- class core.Circuit
- acz(self: core.Circuit, ctrl_idx: int, target_idx: int) None
ACZ gate
This method adds an anti-controlled-Z (ACZ) gate to the circuit.
The ACZ gate performs a Z gate on the target qubit conditional on the control qubit being in the 0 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
- amcu(self: core.Circuit, U: object, qubits_control: numpy.ndarray[numpy.int32], qubits_ancilla: numpy.ndarray[numpy.int32]) None
Multi Controlled Unitary With Ancilla
This method decomposes a multi-controlled unitary into Toffoli gates and the unitary itself, with the use of ancilla qubits. With N control qubits there should be N-1 ancilla. The resulting instructions are added to the circuit (AMCU gate).
Parameters:
U The unitary operation [CircuitBuilder]
qubits_control The indices of the control qubits [list of int]
qubits_ancilla The indices of the ancilla qubits [list of int]
- amplitude_amplification(self: core.Circuit, oracle: object, state_prep: object, power: int = 1) None
Amplitude Amplification
This method adds a number of Grovers operators to the circuit.
Grovers operators are used to amplify the amplitude of some desired subspace of your quantum state.
Parameters:
oracle The oracle circuit O that marks the good subspace [CircuitBuilder]
state_prep The circuit A used to prepare the input state [CircuitBuilder]
power The number of Grovers operators to append to the circuit [int]
- append(self: core.Circuit, other: core.Circuit) None
Append the ‘other’ quantum circuit to this circuit.
- canonical_ae(self: core.Circuit, state_prep: object, grover_op: object, precision: int, num_state_prep_qubits: int, num_trial_qubits: int, precision_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), trial_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), no_state_prep: bool = False) None
Canonical Amplitude Estimation
This method adds the canonical version of Quantum Amplitude Estimation (QAE) to the circuit.
Given a quantum state split into a good subspace and a bad subspace, the QAE sub-routine provides a k-bit approximation to the amplitude of the good subspace, a.
QAE works by using the Grovers operator Q, which amplifies the amplitude of the good subspace, as the unitary input to a Quantum Phase Estimation routine.
Parameters:
state_prep The circuit A used to prepare the input state [CircuitBuilder]
grover_op The circuit for the Grovers operator Q for the good subspace [CircuitBuilder]
precision The number of bits k used to approximate the amplitude [int]
num_state_prep_qubits The number of qubits acted on by the state_prep circuit A [int]
num_trial_qubits The number of qubits acted on by the grover_op circuit Q [int]
trial_qubits The indices of the qubits acted on by the grover_op circuit Q [list of int]
precision_qubits The indices of the qubits used to store the approximate amplitude [list of int]
no_state_prep If true, assumes the state is already prepared in the appropriate register [bool]
- ccx(self: core.Circuit, ctrl_idx1: int, ctrl_idx2: int, target_idx: int) None
Toffoli gate
This method adds a Toffoli gate (CCX) to the circuit.
The CCX gate performs an X gate on the target qubit conditional on the two control qubits being in the 1 state.
Parameters:
ctrl_idx1 the index of the first control qubit [int]
ctrl_idx2 the index of the second control qubit [int]
target_idx the index of the target qubit [int]
- ch(self: core.Circuit, ctrl_idx: int, target_idx: int) None
CH gate
This method adds a controlled-H (CH) gate to the circuit.
The CH gate performs an H gate on the target qubit conditional on the control qubit being in the 1 state.
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
- cnot(self: core.Circuit, ctrl_idx: int, target_idx: int) None
CNOT gate
This method adds a controlled-X (CNOT) gate to the circuit.
The CNOT gate performs an X gate on the target qubit conditional on the control qubit being in the 1 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
- comparator(self: core.Circuit, best_score: int, num_scoring_qubits: int, trial_score_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), flag_qubit: int = - 1, best_score_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), ancilla_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), is_LSB: bool = True, controls_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_off: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Comparator
This method adds a quantum bit string comparator to the circuit.
The quantum bit string comparator is used to compare the values of two bit string. If the trial score is greater than the best score, the flag qubit is flipped.
Parameters:
best_score The score we are comparing strings to [int]
num_scoring_qubits The number of qubits used to encode the scores [int]
trial_score_qubits The indices of the qubits encoding the trial states [list of int]
flag_qubit The index of the flag qubit which is flipped whenever trial score > BestScore [int]
best_score_qubits The indices of the qubits encoding the BestScore value [list of int]
ancilla_qubits The indices of the ancilla qubits required for the comparator circuit, if num_scoring_qubits = N we need 3N-1 ancilla [list of int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
controls_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
controls_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
- comparator_as_oracle(self: core.Circuit, best_score: int, num_scoring_qubits: int, trial_score_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), flag_qubit: int = - 1, best_score_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), ancilla_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), is_LSB: bool = True, controls_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_off: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Comparator as Oracle
This method adds a quantum bit string comparator oracle to the circuit.
The quantum bit string comparator is used to add a negative phase to any trial state whose bit string value is greater than the state being compared to. In this way it can be used as an oracle in a Grovers operator that amplifies higher scoring strings. This may be useful in many search problems.
Parameters:
best_score The score we are comparing strings to [int]
num_scoring_qubits The number of qubits used to encode the scores [int]
trial_score_qubits The indices of the qubits encoding the trial states [list of int]
flag_qubit The index of the flag qubit which acquires a negative phase whenever trial score > BestScore [int]
best_score_qubits The indices of the qubits encoding the BestScore value [list of int]
ancilla_qubits The indices of the ancilla qubits required for the comparator circuit, if num_scoring_qubits = N we need 3N-1 ancilla [list of int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
controls_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
controls_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
- compare_beam_oracle(self: core.Circuit, q0: int, q1: int, q2: int, FA: numpy.ndarray[numpy.int32], FB: numpy.ndarray[numpy.int32], SA: numpy.ndarray[numpy.int32], SB: numpy.ndarray[numpy.int32] = array([], dtype=int32), simplified: bool = True) None
Compare Beam Oracle
This method adds a compare beam oracle to the circuit.
This method is required for the quantum decoder algorithm.
- compare_gt(self: core.Circuit, qubits_a: numpy.ndarray[numpy.int32], qubits_b: numpy.ndarray[numpy.int32], qubit_flag: int, qubit_ancilla: int, is_LSB: bool = True) None
Compare Greater Than
This method adds a greater-than comparator to the circuit.
Given two binary strings a and b, this comparator flips a flag qubit whenever a>b. This method uses far less ancilla than the more general comparator method provided.
Parameters:
qubits_a The indices of the qubits encoding a [list of int]
qubits_b The indices of the qubits encoding b [list of int]
qubit_flag The index of the flag qubit that is flipped whenever a>b [int]
qubit_ancilla The index of the single ancilla qubit required [int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
- controlled_multiplication(self: core.Circuit, qubit_ancilla: numpy.ndarray[numpy.int32], qubits_a: numpy.ndarray[numpy.int32], qubits_b: numpy.ndarray[numpy.int32], qubits_result: int, is_LSB: bool = True, controls_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_off: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Controlled Multiplication
This method adds a controlled Multiplication to the circuit.
Performs a Multiplication operation on a and b if an only if the controls are satisfied.
Parameters:
qubits_a the indices of the qubits encoding a [list of int]
qubits_b the indices of the qubits encoding b [list of int]
qubits_result the indices of the qubits that will ecode the multiplication result [list of int]
qubits_ancilla the index of the single required ancilla [int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
controls_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
controls_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
- controlled_proper_fraction_division(self: core.Circuit, qubits_numerator: numpy.ndarray[numpy.int32], qubits_denominator: numpy.ndarray[numpy.int32], qubits_fraction: numpy.ndarray[numpy.int32], qubits_ancilla: numpy.ndarray[numpy.int32], controls_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_off: numpy.ndarray[numpy.int32] = array([], dtype=int32), is_LSB: bool = True) None
Controlled Proper Fraction Division
This method adds a controlled proper fraction division to the circuit.
Performs a PFD operation on a and b if an only if the controls are satisfied.
Parameters:
qubits_numerator the indices of the qubits encoding the numerator [list of int]
qubits_denominator the indices of the qubits encoding the denominator [list of int]
qubits_fraction the indices of the qubits that will ecode the division result [list of int]
qubit_ancilla the index of the required ancilla [list of int]
controls_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
controls_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
- controlled_ripple_carry_adder(self: core.Circuit, qubits_adder: numpy.ndarray[numpy.int32], qubits_sum: numpy.ndarray[numpy.int32], c_in: int, flags_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), flags_off: numpy.ndarray[numpy.int32] = array([], dtype=int32), no_overflow: bool = False) None
Controlled Addition
This method adds a controlled ripple carry adder to the circuit.
Performs a RippleAdd operation on adder_bits and sum_bits if and only if the controls are satisfied.
Parameters:
qubits_adder the indices of the qubits encoding adder_bits [list of int]
qubits_sum the indices of the qubits encoding sum_bits [list of int]
c_in the index of the carry-in bit [int]
flags_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
flags_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
no_overflow Indicates that the total of the addition can be encoded on the same number of qubits as sum_bits without overflowing [bool]
- controlled_subtraction(self: core.Circuit, qubits_larger: numpy.ndarray[numpy.int32], qubits_smaller: numpy.ndarray[numpy.int32], controls_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_off: numpy.ndarray[numpy.int32] = array([], dtype=int32), is_LSB: bool = True, qubit_ancilla: int = - 1) None
Controlled Subtraction
This method adds a controlled subtraction to the circuit.
Performs a subtraction operation on a and b if an only if the controls are satisfied.
Parameters:
qubits_larger the indices of the qubits encoding the larger value [list of int]
qubits_smaller the indices of the qubits encoding the smaller value [list of int]
controls_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
controls_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
qubit_ancilla the index of the required ancilla [list of int]
- controlled_swap(self: core.Circuit, qubits_a: numpy.ndarray[numpy.int32], qubits_b: numpy.ndarray[numpy.int32], flags_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), flags_off: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Controlled SWAP
This method adds a controlled SWAP to the circuit.
Performs a SWAP operation on a and b if an only if the controls are satisfied.
Parameters:
qubits_a the indices of the qubits encoding a [list of int]
qubits_b the indices of the qubits encoding b [list of int]
flags_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
flags_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
- copy(self: core.Circuit) core.Circuit
- cphase(*args, **kwargs)
Overloaded function.
cphase(self: core.Circuit, ctrl_idx: int, target_idx: int, theta: float) -> None
CPhase gate
This method adds a controlled-U1 (CPhase) gate to the circuit.
The CPHase gate performs a U1(theta) gate on the target qubit conditional on the control qubit being in the 1 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
theta the value of the phase [double]
cphase(self: core.Circuit, ctrl_idx: int, target_idx: int, param_name: str) -> None
CPhase gate
This method adds a controlled-U1 (CPhase) gate with a free parameter ” “to the circuit.
The CPHase gate performs a U1(theta) gate on the target qubit conditional on the control qubit being in the 1 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
name the name of the free parameter [string]
- crx(*args, **kwargs)
Overloaded function.
crx(self: core.Circuit, ctrl_idx: int, target_idx: int, theta: float) -> None
CRX gate
The CRX gate performs a RX(theta) gate on the target qubit conditional on the control qubit being in the 1 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
theta the value of the phase [double]
crx(self: core.Circuit, ctrl_idx: int, target_idx: int, param_name: str) -> None
CRX gate
This method adds a controlled parameterized z-axis rotation (CRX) gate to the circuit.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the qubit being acted on [int]
name the name of the free parameter [string]
- cry(*args, **kwargs)
Overloaded function.
cry(self: core.Circuit, ctrl_idx: int, target_idx: int, theta: float) -> None
CRY gate
The CRY gate performs a RY(theta) gate on the target qubit conditional on the control qubit being in the 1 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
theta the value of the phase [double]
cry(self: core.Circuit, ctrl_idx: int, target_idx: int, param_name: str) -> None
CRY gate
This method adds a controlled parameterized z-axis rotation (CRY) gate to the circuit.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the qubit being acted on [int]
name the name of the free parameter [string]
- crz(*args, **kwargs)
Overloaded function.
crz(self: core.Circuit, ctrl_idx: int, target_idx: int, theta: float) -> None
CRZ gate
This method adds a controlled-U1 (CPhase) gate to the circuit.
The CRZ gate performs a RZ(theta) gate on the target qubit conditional on the control qubit being in the 1 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
theta the value of the phase [double]
crz(self: core.Circuit, ctrl_idx: int, target_idx: int, param_name: str) -> None
CRZ gate
This method adds a controlled parameterized z-axis rotation (CRZ) gate to the circuit.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the qubit being acted on [int]
name the name of the free parameter [string]
- cz(self: core.Circuit, ctrl_idx: int, target_idx: int) None
CZ gate
This method adds a controlled-Z (CZ) gate to the circuit.
The CZ gate performs a Z gate on the target qubit conditional on the control qubit being in the 1 state.
Parameters:
ctrl_idx the index of the control qubit [int]
target_idx the index of the target qubit [int]
- efficient_encoding(self: core.Circuit, scoring_function: Callable[[int], int], num_state_qubits: int, num_scoring_qubits: int, state_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), scoring_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), is_LSB: bool = True, use_ancilla: bool = False, qubits_init_flags: numpy.ndarray[numpy.int32] = array([], dtype=int32), flag_integer: int = 0) None
Efficient Encoding
This method adds an efficient encoding routine to the circuit.
Given a lookup function f that assigns a score to each binary string, we entangle each string to its score. Rather than encoding states sequentially we cut down on the amount of X gates required by instead following the Gray code ordering of states.
This module can optionally also flag strings of a certain value.
Parameters:
scoring_function A function that inputs the integer value of a binary string and outputs its score [func(int) -> int]
num_state_qubits The number of qubits encoding the strings [int]
num_scoring_qubits The number of qubits encoding the scores [int]
state_qubits The indices of the qubits encoding the strings [list of int]
scoring_qubits The indices of the qubits encoding the scores [list of int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
use_ancilla Indicates that ancilla qubits can be used to decompose MCX gates [bool]
qubits_init_flag The indices of any flag qubits [list of int]
flag_integer The integer value of binary strings that should be flagged [int]
- equality_checker(self: core.Circuit, qubits_a: numpy.ndarray[numpy.int32], qubits_b: numpy.ndarray[numpy.int32], flag: int, use_ancilla: bool = False, qubits_ancilla: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_off: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Equality Checker
This method adds an equality checker to the circuit.
Given two input bitstrings a and b the equality checker is used to flip a flag qubit whenever a=b.
Parameters:
qubits_a the indices of the qubits encoding a [list of int]
qubits_b the indices of the qubits encoding b [list of int]
flag the index of the flag qubit that gets flipped whenever a=b [int]
use_ancilla Indicates that ancilla qubits can be used to decompose MCX gates [bool]
qubits_ancilla The indices of the qubits to be used as ancilla qubits if use_ancilla=true [list of int]
controls_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
controls_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
- execute(self: core.Circuit, QPU: str = 'qpp', NUM_SHOTS: int = 1024, NUM_QUBITS: int = - 1) str
Run the circuit.
This method is used to pass the circuit to an accelerator backend for execution.
The optional parameters are:
QPU The accelerator name [string]
NUM_SHOTS The number of shots to use [int]
NUM_QUBITS The number of qubits required for the circuit [int]
- exponent(self: core.Circuit, qubits_log: numpy.ndarray[numpy.int32] = array([], dtype=int32), qubits_exponent: numpy.ndarray[numpy.int32] = array([], dtype=int32), qubits_ancilla: numpy.ndarray[numpy.int32] = array([], dtype=int32), min_significance: int = 1, is_LSB: bool = True) bool
Exponent Base 2
This method adds an exponent to the circuit. This is used to replace some value by its exponent base 2.
Parameters:
qubits_log the indices of the qubits encoding the original value [list of int]
qubits_exponent the indices of the qubits used to store the result [list of int]
qubits_ancilla the indices of the required ancilla qubits [list of int]
min_significance the accuracy cutoff [int]
is_LSB indicates LSB ordering is used [bool]
- exponential_search(self: core.Circuit, method: str, state_prep: object, oracle: Callable[[int], core.Circuit], best_score: int, f_score: Callable[[int], int], total_num_qubits: int, qubits_string: numpy.ndarray[numpy.int32], total_metric: numpy.ndarray[numpy.int32], qpu: str = 'qpp') int
Exponential Search
This method sets up and executes the exponential search routine.
Exponential search is a way to perform amplitude estimation when the size of the “good” subspace is unknown (so the number of Grovers operators to use is unknown).
We implement three variants: - canonical exponential search is a specific “guess and check” method - MLQAE exponential search uses MLQAE to first estimate the size of the good subspace then perform regular amplitude estimation with the appropriate number of Grovers operators - CQAE exponential search uses canonical QAE to first estimate the size of the good subspace then perform regular amplitude estimation with the appropriate number of Grovers operators
Parameters:
method indicates which method to use. Options are “canonical”, “MLQAE”, “CQAE” [string]
state_prep a function which produces the state prep circuit [StatePrepFuncCType]
oracle a function which produces the oracle circuit that marks the good subspace [OracleFuncCType]
best_score the current best score [int]
f_score a function that returns a 1 if the input binary string has value greater than the current best score and 0 otherwise [func(int)->int]
total_num_qubits total number of qubits [int]
qubits_string the indices of the qubits encoding the strings [list of int]
total_metric the indices of the qubits encoding the string scores after any required pre-processing of qubits_metric (required by decoder) [list of int]
qpu the name of the accelerator used to execute the algorithm [string]
Returns: a better score if found, otherwise returns the current best score
- generalised_mcx(self: core.Circuit, target: int, controls_on: numpy.ndarray[numpy.int32] = array([], dtype=int32), controls_off: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Generalised MCX
This method adds a generalised MCX gate to the circuit.
By generalised MCX we mean that we allow the control qubits to be conditional on being off or conditional on being on.
Parameters:
target The index of the target qubit [int]
controls_on The indices of any qubits that should be “on” controls (i.e. circuit executed if qubit = 1) [list of int]
controls_off The indices of any qubits that should be “off” controls (i.e. circuit executed if qubit = 0) [list of int]
- h(self: core.Circuit, idx: int) None
Hadamard gate
This method adds a Hadamard (H) gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
- inverse_circuit(self: core.Circuit, circ: object) None
Inverse Circuit
This method adds the inverse of a circuit to the current circuit.
Given some collection of unitary operations,
U = U_NU_{N-1}…U_2U_1
this method appends the inverse to the circuit:
U^{-1} = U_1dg U_2dg…U_{N-1}dg U_Ndg
This may be useful for un-computing ancilla or for constructing Grovers operators.
Parameters:
circ The circuit whose inverse we want to add to the current circuit [CircuitBuilder]
- iqft(self: core.Circuit, qubits: numpy.ndarray[numpy.int32]) None
Inverse Quantum Fourier Transform
This method adds the inverse of the Quantum Fourier Transform (IQFT) to the circuit.
Parameters:
qubits the indices of the target qubits [list of int]
- mcx(self: core.Circuit, ctrl_inds: numpy.ndarray[numpy.int32], target_idx: int) None
MCX gate
This method adds a multi-controlled X (MCX) gate to the circuit.
The MCX gate performs an X gate on the target qubit conditional on all control qubits being in the 1 state.
Parameters:
ctrl_inds the indices of the control qubits [list of int]
target_idx the index of the target qubit [int]
- measure(self: core.Circuit, idx: int) None
Measurement
This method is used to indicate a qubit in the circuit should be measured.
Parameters:
idx the index of the qubit to be measured [int]
- measure_all(self: core.Circuit, NUM_QUBITS: int = - 1) None
Measure all qubits
This method adds a measurement for all qubits involved in the circuit.
Parameters:
NUM_QUBITS the number of qubits in the circuit [int] [optional, the default value of -1 becomes the output of the XACC nPhysicalBits method.]
- multiplication(self: core.Circuit, qubit_ancilla: numpy.ndarray[numpy.int32], qubits_a: numpy.ndarray[numpy.int32], qubits_b: numpy.ndarray[numpy.int32], qubits_result: int, is_LSB: bool = True) None
Multiplication
This method adds a Multiplication to the circuit.
Given two inputs a and b, computes the product a*b and stores the result on a new register.
Parameters:
qubits_a the indices of the qubits encoding a [list of int]
qubits_b the indices of the qubits encoding b [list of int]
qubits_result the indices of the qubits that will ecode the multiplication result [list of int]
qubits_ancilla the index of the single required ancilla [int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
- num_free_params(self: core.Circuit) int
Returns the number of free parameters in the (parametrized) circuit.
- num_qubits(self: core.Circuit) int
Returns the number of (physical) qubits in the circuit.
- openqasm(self: core.Circuit) str
Get the OpenQASM representation of the (non-parametrized) circuit.
- param_dict_to_list(self: core.Circuit, arg0: dict[str, float]) list[float]
Convert a dictionary that defines parameter assignments to a vector for input to the session object. The vector will be ordered according to the definition of the free parameter in the circuit; for example, if a gate is defined with the free parameter “alpha” in an empty circuit, its mapped parameter will be at index 0 in the vector. If another gate exists in this circuit with the parameter “beta”, the value for this mapped parameter will be at index 1, and so on.
Parameters:
param_dict the dictionary
Returns:
A vector containing the ordered parameter values.
- print(self: core.Circuit) None
Print the quantum circuit that has been built
- proper_fraction_division(self: core.Circuit, qubits_numerator: numpy.ndarray[numpy.int32], qubits_denominator: numpy.ndarray[numpy.int32], qubits_fraction: numpy.ndarray[numpy.int32], qubits_ancilla: numpy.ndarray[numpy.int32], is_LSB: bool = True) None
Proper Fraction Division
This method adds a proper fraction division to the circuit.
Given two inputs num and denom, calculates num/denom and stores the result in a new register, assuming denom > num
Parameters:
qubits_numerator the indices of the qubits encoding the numerator [list of int]
qubits_denominator the indices of the qubits encoding the denominator [list of int]
qubits_fraction the indices of the qubits that will ecode the division result [list of int]
qubit_ancilla the index of the required ancilla [list of int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
- q_prime_unitary(self: core.Circuit, nb_qubits_ancilla_metric: int, nb_qubits_ancilla_letter: int, nb_qubits_next_letter_probabilities: int, nb_qubits_next_letter: int) None
Q’ Unitary
This method adds a Q’ unitary to the circuit.
Q’ is a unitary required for the quantum decoder algorithm.
- qft(self: core.Circuit, qubits: numpy.ndarray[numpy.int32]) None
Quantum Fourier Transform
This method adds the Quantum Fourier Transform (QFT) to the circuit. This is a quantum analogue of the discrete Fourier Transform.
Parameters:
qubits the indices of the target qubits [list of int]
- qpe(self: core.Circuit, oracle: object, precision: int, trial_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), precision_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Quantum Phase Estimation
This method adds the Quantum Phase Estimation (QPE) sub-routine to the circuit.
Given some unitary operator U and and eigenvector v of U, QPE is used to provide a k-bit approximation to the corresponding eigenvalue’s phase, storing the result in an evaluation register whilst leaving the eigenvector unchanged.
Parameters:
oracle The unitary operator U involved in the QPE routine [CircuitBuilder]
precision The number of bits k used to approximate the phase [int]
trial_qubits The indices of the qubits encoding the eigenvector of the unitary [list of int]
precision_qubits The indices of the qubits that will be used to store the approximate phase [list of int]
- ripple_add(self: core.Circuit, a: numpy.ndarray[numpy.int32], b: numpy.ndarray[numpy.int32], carry_bit: int) None
Ripple Carry Adder
This method adds a ripple carry adder to the circuit.
The ripple carry adder is an efficient in-line addition operation with a carry-in bit.
Parameters:
a The qubit indices of the first register in the addition [list of int]
b The qubit indices of the second register in the addition. This is where the result of a+b will be stored [list of int]
carry_bit The index of the carry-in bit [int]
- run_MLQAE(self: core.Circuit, state_prep: object, oracle: object, is_in_good_subspace: Callable[[str, int], int], score_qubits: numpy.ndarray[numpy.int32], total_num_qubits: int, num_runs: int = 4, shots: int = 100, qpu: str = 'qpp') str
Run Maximum-Likelihood Amplitude Estimation
This method sets up and executes an instance of the maximum-likelihood amplitude estimation circuit.
Given a state split into a good subspace and a bad subspace, MLQAE is an alternative to canonical QAE to find an estimate for the amplitude of the good subspace, a. It works by performing several runs of amplitude amplification with various iterations and recording the number of good shots measured. Given this data, it finds the value of a that maximises the likelihood function.
Parameters:
state_prep The circuit A used to prepare the input state [CircuitBuilder]
oracle The oracle circuit O that marks the good subspace [CircuitBuilder]
is_in_good_subspace A function that, given a measured bitstring and potentially some other input value, returns a 1 if the measurement is in the good subspace and a 0 otherwise. [func(str, int) -> int]
score_qubits The indices of the qubits that determine whether the state is in the good or bad subspace [list of int]
total_num_qubits The total number of qubits in the circuit [int]
num_runs The number of runs of amplitude amplification (~4-6 is usually sufficient)
shots The number of shots in each run [int]
qpu The name of the accelerator used to execute the circuit [string]
Returns: The output buffer of the execution
- run_canonical_ae(self: core.Circuit, state_prep: object, grover_op: object, precision: int, num_state_prep_qubits: int, num_trial_qubits: int, precision_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), trial_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), qpu: str = 'qpp') str
Run Canonical Amplitude Estimation
This method sets up and executes an instance of the canonical amplitude estimation circuit.
Parameters:
state_prep The circuit A used to prepare the input state [CircuitBuilder]
grover_op The circuit for the Grovers operator Q for the good subspace [CircuitBuilder]
precision The number of bits k used to approximate the amplitude [int]
num_state_prep_qubits The number of qubits acted on by the state_prep circuit A [int]
num_trial_qubits The number of qubits acted on by the grover_op circuit Q [int]
trial_qubits The indices of the qubits acted on by the grover_op circuit Q [list of int]
precision_qubits The indices of the qubits used to store the approximate amplitude [list of int]
qpu The name of the accelerator used to execute the circuit [string]
Returns: The output buffer of the execution
- run_canonical_ae_with_oracle(self: core.Circuit, state_prep: object, oracle: object, precision: int, num_state_prep_qubits: int, num_trial_qubits: int, precision_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), trial_qubits: numpy.ndarray[numpy.int32] = array([], dtype=int32), qpu: str = 'qpp') str
Run Canonical Amplitude Estimation with Oracle
This method sets up and executes an instance of the canonical amplitude estimation circuit, but instead of providing the grovers_op Q, we provide the oracle circuit O which marks the good elements.
The Grovvers operator Q is then constructed within the method from O and the state_prep circuit A.
Parameters:
state_prep The circuit A used to prepare the input state [CircuitBuilder]
oracle The oracle circuit O that marks the good subspace [CircuitBuilder]
precision The number of bits k used to approximate the amplitude [int]
num_state_prep_qubits The number of qubits acted on by the state_prep circuit A [int]
num_trial_qubits The number of qubits acted on by the grover_op circuit Q [int]
precision_qubits The indices of the qubits used to store the approximate amplitude [list of int]
trial_qubits The indices of the qubits acted on by the grover_op circuit Q [list of int]
qpu The name of the accelerator used to execute the circuit [string]
Returns: The output buffer of the execution
- rx(*args, **kwargs)
Overloaded function.
rx(self: core.Circuit, idx: int, theta: float) -> None
RX gate
This method adds an x-axis rotation (RX) gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
theta the angle of rotation about the x-axis [double]
rx(self: core.Circuit, idx: int, name: str) -> None
RX gate
This method adds an x-axis rotation (RX) gate with a free parameter ” “to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
name the name of the free parameter [string]
- ry(*args, **kwargs)
Overloaded function.
ry(self: core.Circuit, idx: int, theta: float) -> None
RY gate
This method adds a y-axis rotation (RY) gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
theta the angle of rotation about the y-axis [double]
ry(self: core.Circuit, idx: int, param_name: str) -> None
RY gate
This method adds a y-axis rotation (RY) gate with a free parameter ” “to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
name the name of the free parameter [string]
- rz(*args, **kwargs)
Overloaded function.
rz(self: core.Circuit, idx: int, theta: float) -> None
RZ gate
This method adds a z-axis rotation (RZ) gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
theta the angle of rotation about the z-axis [double]
rz(self: core.Circuit, idx: int, param_name: str) -> None
RZ gate
This method adds a z-axis rotation (RZ) gate with a free parameter ” “to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
name the name of the free parameter [string]
- s(self: core.Circuit, idx: int) None
S gate
This method adds an S gate to the circuit.
The S gate is defined by its action on the basis states
Parameters:
idx the index of the qubit being acted on [int]
- sdg(self: core.Circuit, idx: int) None
Sdg gate
This method adds an inverse of the S gate (Sdg) to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
- subtraction(self: core.Circuit, qubits_larger: numpy.ndarray[numpy.int32], qubits_smaller: numpy.ndarray[numpy.int32], is_LSB: bool = True, qubit_ancilla: int = - 1) None
Subtraction
This method adds a subtraction to the circuit.
Given two inputs a and b, leaves b unchanged but maps a to the difference a-b, assuming a>b.
Parameters:
qubits_larger the indices of the qubits encoding the larger value [list of int]
qubits_smaller the indices of the qubits encoding the smaller value [list of int]
is_LSB Indicates that the trial scores are encoded with LSB ordering [bool]
qubit_ancilla the index of the required ancilla [list of int]
- superposition_adder(self: core.Circuit, q0: int, q1: int, q2: int, qubits_flags: numpy.ndarray[numpy.int32] = array([], dtype=int32), qubits_string: numpy.ndarray[numpy.int32] = array([], dtype=int32), qubits_metric: numpy.ndarray[numpy.int32] = array([], dtype=int32), ae_state_prep_circ: object, qubits_ancilla: numpy.ndarray[numpy.int32] = array([], dtype=int32), qubits_beam_metric: numpy.ndarray[numpy.int32] = array([], dtype=int32)) None
Superposition adder
This method adds a Superposition Adder to the circuit.
Given a superposition state, this circuit computes the mean of the amplitudes of the superposition components.
Parameters:
q0 the index of the single required ancilla [int]
q1 the index of the single required ancilla [int]
q2 the index of the single required ancilla [int]
qubits_flags the indices of the flag qubits [list of int]
qubits_string the indices of the qubits encoding the string [list of int]
qubits_metric the indices of the qubits encoding the metric value corresponding to the string [list of int]
ae_state_prep_circ The circuit A used to prepare the input state [CircuitBuilder]
qubits_ancilla the indices of the required ancilla qubits [list of int]
qubits_beam_metric the indices of the qubits encoding class’ metric [list of int]
- swap(self: core.Circuit, q1: int, q2: int) None
SWAP gate
This method adds a SWAP gate to the circuit. The SWAP gate is used to swap the quantum state of two qubits.
Parameters:
q1 the index of the first qubit [int]
q2 the index of the second qubit [int]
- t(self: core.Circuit, idx: int) None
T gate
This method adds a T gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
- tdg(self: core.Circuit, idx: int) None
Tdg gate
This method adds an inverse of the T gate (Tdg) to the circuit.
The Tdg gate is defined by its action on the basis states
Parameters:
idx the index of the qubit being acted on [int]
- u1(*args, **kwargs)
Overloaded function.
u1(self: core.Circuit, idx: int, theta: float) -> None
U1 gate
This method adds a phase (U1) gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
theta the value of the phase [double]
u1(self: core.Circuit, idx: int, param_name: str) -> None
U1 gate
This method adds a phase (U1) gate with a free parameter ” “to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
name the name of the free parameter [string]
- u3(*args, **kwargs)
Overloaded function.
u3(self: core.Circuit, idx: int, param_1: str, param_2: str, param_3: str) -> None
Parameterized U3 gate U3 gate
This method adds an arbitrary parametrized single qubit gate (U3) to the circuit, shown as U at https://qristal.readthedocs.io/en/latest/rst/quantum_gates.html Parameters:
idx the index of the qubit being acted on [int]
param_1 the name of the 1st free parameter (theta) [string]
param_2 the name of the 2nd free parameter (phi) [string]
param_3 the name of the 3rd free parameter (lambda) [string]
u3(self: core.Circuit, idx: int, theta: float, phi: float, lambda: float) -> None
U3 gate
This method adds an arbitrary single qubit gate (U3) to the circuit, shown as U at https://qristal.readthedocs.io/en/latest/rst/quantum_gates.html
Parameters:
idx the index of the qubit being acted on [int]
theta [double]
phi [double]
lambda [double]
- x(self: core.Circuit, idx: int) None
Pauli-X gate
This method adds a Pauli-X (X) gate to the circuit.
The X gate is defined by its action on the basis states
- Parameters:
[int] (- idx the index of the qubit being acted on) –
- y(self: core.Circuit, idx: int) None
Pauli-Y gate
This method adds a Pauli-Y (Y) gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
- z(self: core.Circuit, idx: int) None
Pauli-Z gate
This method adds a Pauli-Z (Z) gate to the circuit.
Parameters:
idx the index of the qubit being acted on [int]
Noise Modelling
QB Qristal allows an end-user to implement noise models in Python.
- class core.NoiseModel
Noise model class allowing specification of noise parameters and connectivity for each gate.
- add_gate_error(self: core.NoiseModel, arg0: list[core.KrausOperator], arg1: str, arg2: list) None
Add a gate error channel for a gate operation
Parameters:
noise_channel Noise channel to be associated with the gate [List(KrausOperator)]
gate_name Name of the gates [String]
qubits Qubit indices of the gate. [List(Integer)]
- add_qubit_connectivity(self: core.NoiseModel, arg0: int, arg1: int) None
Add a connected qubit pair to the topology model
Parameters:
q1 First qubit index [Integer]
q2 Second qubit index [Integer]
- property connectivity
Get connectivity as a list of connected qubit pairs
- property name
The colloquial name of the noise model
- property qobj_basis_gates
The list of basis gates that the AER QObj will be referring to.
- property qobj_compiler
‘xacc-qobj’ | ‘qristal-qobj’.
- Type:
The name of the QObj compiler to use with the AER simulator. Valid options
- set_qubit_readout_error(self: core.NoiseModel, arg0: int, arg1: core.ReadoutError) None
Set the qubit readout error
Parameters:
qubitIdx Qubit to set [Integer]
ro_error Readout error [ReadoutError]
- to_json(self: core.NoiseModel) str
Convert noise model to json string
This NoiseModel can be constructed from the quantum device NoiseProperties.
- class core.NoiseProperties
- Use NoiseProperties to accept user input parameters for custom noise models. There are 3 types of inputs used for constructing a custom noise model:
Qubit topology
Time duration of quantum gate operations
Parameters for quantum noise channels and classical errors
- property gate_pauli_errors
gate_pauli_errors is the parameter for gate error derived from randomized benchmarking of a quantum gate operation that is applied at a target set of qubits.
Unit: none (range: [0.0, 1.0])
Code example: 4 qubits: “u3” single-qubit gate, uniform gate error parameter = 0.03 (3%); “cx” between neighboring qubits (on a line), gate error parameter = 0.1 (10%):
# Initialize an empty NoiseProperties t_qbnp = NoiseProperties() t_qbnp.gate_pauli_errors["u3"] = {} t_qbnp.gate_pauli_errors["cx"] = {} num_qubits = 4 for i in range(num_qubits): t_qbnp.gate_pauli_errors["u3"][[i]] = 0.03 # Qubits on a line: if i != num_qubits - 1: t_qbnp.gate_pauli_errors["cx"][[i, i + 1]] = 0.1 # Print out the gate error map: print(t_qbnp.gate_pauli_errors)
- property gate_time_us
gate_time_us is the duration for a quantum gate operation when applied at a target set of qubits.
Unit: microseconds
Code example: 4 qubits: “u3” single-qubit gate, uniform duration of 5.2us; “cx” between neighboring qubits (on a line), uniform duration of 20us:
# Initialize an empty NoiseProperties t_qbnp = NoiseProperties() t_qbnp.gate_time_us["u3"] = {} t_qbnp.gate_time_us["cx"] = {} num_qubits = 4 for i in range(num_qubits): t_qbnp.gate_time_us["u3"][[i]] = 5.2 # Qubits on a line: if i != num_qubits - 1: t_qbnp.gate_time_us["cx"][[i, i + 1]] = 20.0 # Print out the gate time map: print(t_qbnp.gate_time_us)
- property qubit_topology
qubit_topology is a graph comprised of directed edges {control qubit, target qubit} with control qubit as the source of the edge -> target qubit as the destination of the edge.
Code example: “cx” symmetrical two-qubit gate with 4 qubits in the topology below:
# Topology # q0 <--cx--> q1 # ^ ^ # | | # cx cx # | | # v v # q3 <--cx--> q2 # Initialize an empty NoiseProperties t_qbnp = NoiseProperties() t_qbnp.qubit_topology = [[0, 1], [1, 2], [2, 3], [3, 0]]
- property readout_errors
readout_errors is the classical readout error (off-diagonal elements of the confusion matrix).
For a qubit register, with individual qubits zero-indexed by i, readout_errors is a map from qubit[i] -> ReadoutError[i].
Unit: none (quantities are probabilities).
Code example: 4-qubit device: 2 qubits (Q0 and Q1) with p(0|1) = p(1|0) = 0.05, 2 qubits (Q2 and Q3) with p(0|1) = 0.1 and p(1|0) = 0.08:
# Initialize an empty NoiseProperties t_qbnp = NoiseProperties() t_qbnpro_balanced = ReadoutError() t_qbnpro_balanced.p_01 = 0.05 t_qbnpro_balanced.p_10 = 0.05 t_qbnpro_asym = ReadoutError() t_qbnpro_asym.p_01 = 0.10 t_qbnpro_asym.p_10 = 0.08 # Q0 and Q1 readout errors t_qbnp.readout_errors[0] = t_qbnpro_balanced t_qbnp.readout_errors[1] = t_qbnpro_balanced # Q2 and Q3 readout errors t_qbnp.readout_errors[2] = t_qbnpro_asym t_qbnp.readout_errors[3] = t_qbnpro_asym
- property t1_us
\(T_1\) is the qubit relaxation time.
For a qubit register, with individual qubits zero-indexed by i; t1_us is a map from qubit[i] -> T1[i].
Unit: microseconds
Code example: 4 qubits all with T1 = 1.5us:
# Initialize an empty NoiseProperties t_qbnp = NoiseProperties() # Set T1 of qubits (all with 1.5 us) for i in range(4): t_qbnp.t1_us[i] = 1.5
- property t2_us
\(T_2\) is the qubit dephasing time.
For a qubit register, with individual qubits zero-indexed by i; t2_us is a map from qubit[i] -> T2[i].
Unit: microseconds
Code example: 4 qubits all with T2 = 0.15us:
# Initialize an empty NoiseProperties t_qbnp = NoiseProperties() # Set T2 of qubits (all with 0.15 us) for i in range(4): t_qbnp.t2_us[i] = 0.15
Additionally, users can use these builtin classes to construct commonly-used noise channels when building the NoiseModel.
- class core.AmplitudeDampingChannel
Amplitude damping channel factory
- Create(self: int, arg0: float) list[core.KrausOperator]
- class core.PhaseDampingChannel
Phase damping channel factory
- Create(self: int, arg0: float) list[core.KrausOperator]
- class core.DepolarizingChannel
Depolarizing channel factory
- Create(*args, **kwargs)
Overloaded function.
Create(self: int, arg0: float) -> list[core.KrausOperator]
Create single-qubit depolarizing channel (balanced/symmetric)
Parameters:
q Qubit index
p Total depolarizing probability
Create(self: int, arg0: int, arg1: float) -> list[core.KrausOperator]
Create two-qubit depolarizing channel (balanced/symmetric)
Parameters:
q1 First qubit
q2 Second qubit
p Total depolarizing probability
- class core.GeneralizedPhaseAmplitudeDampingChannel
Generalized Single-qubit combined phase and amplitude damping quantum error channel
- Create(self: int, arg0: float, arg1: float, arg2: float) list[core.KrausOperator]
Create a generalized amplitude and phase damping channel
Parameters:
q Qubit
excited_state_population Excited state population
param_amp Amplitude damping parameter
param_phase Phase damping parameter
- class core.GeneralizedAmplitudeDampingChannel
Generalized amplitude damping quantum error channel
- Create(self: int, arg0: float, arg1: float) list[core.KrausOperator]
Create a generalized amplitude damping channel
Parameters:
q Qubit
excited_state_population Excited state population
param_amp Amplitude damping parameter
- class core.ReadoutError
Probabilities of reading out a value for a qubit that does not reflect its true state.
- property p_01
Classical probability of detecting 0 whereas the true state was \(|1\rangle\)
- property p_10
Classical probability of detecting 1 whereas the true state was \(|0\rangle\)
In case no builtin noise channels are available for your use case, a fully-customized noise channel can be constructed in terms of instances of the KrausOperator class.
Placement
Qristal contains placement methods to perform mapping from program (logical) qubits to device (physical) qubits satisfying qubit connectivity constraints.
Noise-aware placement
The noise_aware_placement_pass takes into account gate error rates and readout errors to find the best placement map.
- class core.noise_aware_placement_pass
The noise_aware_placement_pass class uses device connectivity, gate errors (1-q and 2-q) and readout errors to find the best placement map.
- apply(self: core.noise_aware_placement_pass, circuit: qristal::CircuitBuilder) None
Apply noise-aware placement on the input circuit.
- Parameters:
circuit – Circuit to be placed (map qubit indices and inject SWAP gates as necessary)
Device configuration for the noise-aware placement is defined by noise_aware_placement_config.
- class core.noise_aware_placement_config
The noise_aware_placement_config class encapsulates generic backend information required by the noise-aware placement pass.
Swap-based placement
The swap_placement_pass performs circuit placement by swapping qubits (along the shortest possible path) when there are gates between uncoupled qubits.
- class core.swap_placement_pass
Circuit placement pass based on injection of SWAP gates to satisfy device connectivity topology.
- apply(self: core.swap_placement_pass, circuit: qristal::CircuitBuilder) None
Apply SWAP-based placement on the input circuit.
- Parameters:
circuit – Circuit to be placed (map qubit indices and inject SWAP gates as necessary)