tangelo.toolboxes.circuits package
Subpackages
Submodules
tangelo.toolboxes.circuits.diagonal_coulomb module
Module to generate the rotations to convert the 2-body integrals into a sum of diagonal terms
- Refs:
[1] Mario Motta, Erika Ye, Jarrod R. McClean, Zhendong Li, Austin J. Minnich, Ryan Babbush, Garnet Kin-Lic Chan “Low rank representations for quantum simulation of electronic structure”. https://arxiv.org/abs/1808.02625
- class tangelo.toolboxes.circuits.diagonal_coulomb.OrbitalRotations
Bases:
object
The class that holds the various rotations, operators and coefficients
- rotation_gates
The gates to apply to rotate the basis to a diagonal form for a given operator
- Type:
list
- qubit_operators
The qubit operators to measure from qubit_mapping=”JW” and up_then_down=False. Each is diagonal in the Z basis.
- Type:
list
- one_body_coefficients
The one-body coefficients corresponding to each operator
- Type:
list
- constants
The constants corresponding to each operator
- Type:
list
- two_body_coefficients
The two-body coefficients corresponding to each operator
- Type:
list
- add_elements(rot_mat, constant=0.0, one_body_coefs=None, two_body_coefs=None)
Add elements to the class for each term to diagonalize a portion of the Hamiltonian
- Parameters:
rot_mat (array) – The unitary rotation matrix
constant (float) – A constant value for this element
one_body_coefs (array) – The diagonal coefficients
two_body_coefs (array) – The two-body coefficients
- property n_rotations
- tangelo.toolboxes.circuits.diagonal_coulomb.bogoliubov_transform(umat, add_phase=True)
Generate the gates that implement the orbital rotation defined by a given unitary.
The given matrix is decomposed into umat=DU where U is unitary D is a diagonal matrix. If umat is unitary, the values of D will be exp(1j*theta) where theta is real and can be incorporated using add_phase=True. If umat is non-unitary, the values of D will be m*exp(1j*theta) where m and theta are real. m is ignored with only the phase (theta) incorporated in the circuit if add_phase=True.
This implementation uses the circuit outlined in https://arxiv.org/abs/1711.05395
- Parameters:
umat (array) – The square unitary matrix that descibes the basis rotation
add_phase (bool) – If True, adds PHASE gates according to givens decomposition values D
- Returns:
list of Gate – The sequence of Gates that implement the orbital rotation
- tangelo.toolboxes.circuits.diagonal_coulomb.get_orbital_rotations(molecule: SecondQuantizedMolecule)
Generate the gates that rotate the orbitals such that each operator is diagonal.
The orbital rotation gates generated are only applicable for qubit_mapping=”JW” and up_then_down=False.
- Parameters:
molecule (SecondQuantizedMolecule) – The molecule for which the diagonal representation is requested
- Returns:
OrbitalRotations – The class that contains the list of transformation gates and operators to measure
tangelo.toolboxes.circuits.discrete_clock module
Module to generate the circuits necessary to implement discrete clock time Refs:
[1] Jacob Watkins, Nathan Wiebe, Alessandro Roggero, Dean Lee, “Time-dependent Hamiltonian Simulation using Discrete Clock Constructions” arXiv: 2203.11353
- tangelo.toolboxes.circuits.discrete_clock.get_adder_circuit(qubit_list: List[int], t: int) Circuit
Return circuit that takes all bitstrings and add binary(t) to it.
- Parameters:
qubit_list (List[int]) – The qubits to apply the addition of t.
t (int) – The integer to add
- Returns:
Circuit – The circuit that applies the addition of t
- tangelo.toolboxes.circuits.discrete_clock.get_discrete_clock_circuit(trotter_func: Callable[[...], Circuit], trotter_kwargs: dict, n_state_qus: int, time: float, n_time_steps: int, mp_order: int) Circuit
Return discrete clock circuit as described in arXiv: 2203.11353
- Parameters:
trotter_func (Callable[..., Circuit]) – The function that implements the controlled 2nd order trotter time-evolution starting at “t0” for “time” using “n_trotter_steps” using “control”
trotter_kwargs (dict) – Other keyword arguments for trotter_func.
n_state_qus (int) – The number of qubits used to represent the state to time-evolve.
time (float) – The total time to evolve.
n_time_steps (int) – The number of time steps in the discrete clock.
mp_order (int) – The multi-product order to use for the time-evolution.
- Returns:
Circuit – The time-evolution circuit using the discrete clock construction.
tangelo.toolboxes.circuits.grid_circuits module
Module to generate the circuits for grid based computation
- tangelo.toolboxes.circuits.grid_circuits.get_psquared_circuit(dt: float, dx: float, mass: float, qubit_list: List[int], control: int | List[int] | None = None) Circuit
Return circuit for p^2/2/m as defined in arXiv:2006.09405 using qft
- Parameters:
dt (float) – Time to evolve.
dx (float) – Grid spacing.
mass (float) – The mass used for the time-evolution.
qubit_list (List[int]) – Qubits to apply circuit to. The order is important depending on lsq_first or msq_first
control (Union[int, List[int]]) – The control qubits
- Returns:
Circuit – The circuit that applies exp(-1j*dt*p^2/2/m)
- tangelo.toolboxes.circuits.grid_circuits.get_xsquared_circuit(dt: float, dx: float, fac: float, x0: float, delta: float, qubit_list: List[int], control: None | int | List[int] = None) Circuit
Return circuit for exp(-1j*dt*[fac*(x - x0)**2 + delta]) as defined in arXiv:2006.09405
- Parameters:
dt (float) – Time to evolve.
dx (float) – Grid spacing.
fac (float) – Factor in front of x^2 term.
x0 (float) – Shift for (x-x0)^2 term
delta (float) – Constant shift
qubit_list (List[int]) – Qubits to apply circuit to. The order is important depending on lsq_first or msq_first
control (Union[int, List[int]]) – The control qubits
- Returns:
Circuit – The circuit that applies exp(-1j*dt*[fac*(x-x0)**2 +delta])
tangelo.toolboxes.circuits.lcu module
Module to generate the circuits necessary to implement linear combinations of unitaries Refs:
[1] Dominic W. Berry, Andrew M. Childs, Richard Cleve, Robin Kothari, Rolando D. Somma, “Simulating Hamiltonian dynamics with a truncated Taylor series” arXiv: 1412.4687 Phys. Rev. Lett. 114, 090502 (2015)
- tangelo.toolboxes.circuits.lcu.USelectkl(unitaries: List[QubitOperator], n_qubits_sv: int, kmax: int, control: int | List[int] | None = None) Circuit
Generate the truncated Taylor series U_{Select} circuit for the list of QubitOperator as defined arXiv:1412.4687 The returned Circuit will have qubits defined in registers |n_qubits_sv>|kmax-1>|n_qubits_u>^{kmax-1}|ancilla> n_qubits_sv is the number of qubits to define the state to propagate. |kmax-1> defines the unary encoding of the Taylor series order. kmax-1 copies of length log2(len(unitaries)) to define the binary encoding of the linear combination of unitaries. Finally, one ancilla qubit to ensure the success of oblivious amplitude amplification. :param unitaries: The list of unitaries that defines the U_{Select} operation :type unitaries: list[QubitOperator] :param n_qubits_sv: The number of qubits in the statevector register :type n_qubits_sv: int :param kmax: The maximum Taylor series order :type kmax: int :param control: Control qubits for operation :type control: int or list[int]
- Returns:
Circuit – The circuit that implements the truncated Taylor series U_{Select} operation
- tangelo.toolboxes.circuits.lcu.Uprepkl(qu_op: QubitOperator, kmax: int, t: float) Tuple[Circuit, List[QubitOperator], int]
Generate Uprep circuit using qubit encoding defined in arXiv:1412.4687 :param qu_op: :type qu_op: QubitOperator :param kmax: the order of the truncated Taylor series :type kmax: int :param t: The evolution time :type t: float
- Returns:
Circuit – The Uprep circuit for the truncated Taylor series
list – the individual QubitOperator unitaries with only the prefactor remaining. i.e. all coefficients are 1, -1, 1j or -1j
int – The number of repeated applications of the circuit that need to be applied
- tangelo.toolboxes.circuits.lcu.get_lcu_qubit_op_info(qu_op: 0) Tuple[List[int], List[int], float]
Return the operator and auxillary qubit indices and 1-norm for the LCU block decomposition of given QubitOperator. :param qu_op: The qubit operator to decompose into an Linear Combination of Unitaries block encoding. :type qu_op: QubitOperator
- Returns:
List[int] – The qubit operator indices.
List[int] – The auxillary qubits for the uprep circuit.
float – The 1-norm of the qubit operator.
- tangelo.toolboxes.circuits.lcu.get_oaa_lcu_circuit(qu_op: QubitOperator, control: int | List[int] | None = None) Circuit
Apply qu_op using linear combination of unitaries (LCU) with oblivious amplitude amplification (OAA) 1-norm of coefficients must be less than 2. The unitarity of qu_op is not checked by the algorithm :param qu_op: The qu_op to apply. Must be nearly unitary for algorithm to succeed with high probability. :type qu_op: QubitOperator :param control: Control qubit(s) :type control: int or list[int]
- Returns:
Circuit – The circuit that implements the linear combination of unitaries for the qu_op
- tangelo.toolboxes.circuits.lcu.get_truncated_taylor_series(qu_op: QubitOperator, kmax: int, t: float, control: int | List[int] | None = None) Circuit
Generate Circuit to implement the truncated Taylor series algorithm as implemented in arXiv:1412.4687 :param qu_op: The qubit operator to apply the truncated Taylor series exponential :type qu_op: QubitOperator :param kmax: The maximum order of the Taylor series exp{-1j*t*qu_op} = sum_{k}^{kmax}(-1j*t)**k/k! qu_op**k :type kmax: int :param t: The total time to evolve :type t: float :param control: The control qubit(s) :type control: int or list[int]
- Returns:
Circuit – the circuit that implements the time-evolution of qu_op for time t with Taylor series kmax
- tangelo.toolboxes.circuits.lcu.get_truncated_taylor_series_qubits(qu_op: QubitOperator, kmax: int)
Return the list of qubits used in the Truncated Taylor series circuit :param qu_op: :type qu_op: QubitOperator :param kmax: the order of the truncated Taylor series :type kmax: int
- Returns:
List[int] – The list of qubit indices used
- tangelo.toolboxes.circuits.lcu.get_unary_prep(kvec: ndarray, kmax: int) Circuit
Generate the prep circuit for the unary+ancilla part of the Taylor series encoding. This implementation scales linearly with kmax whereas StateVector.initializing_circuit() scaled exponentially.
- Parameters:
kvec (array) – Array representing the coefficients needed to generate unary portion of encoding. Length of array is kmax+2. order “00…000”, “00…001”, “00…011”, …, “01…111”, “1000…”
kmax (int) – The Taylor series order
- Returns:
Circuit – The unary encoding prep circuit
- tangelo.toolboxes.circuits.lcu.get_uprep_uselect(qu_op: QubitOperator, control: int | List[int] | None = None, make_alpha_eq_2: bool = False) Tuple[Circuit, Circuit, List[int], List[int], float]
Get uprep and (controlled-)uselect circuits along with their corresponding qubits for a QubitOperator. :param qu_op: The qu_op to apply. :type qu_op: QubitOperator :param control: Control qubit(s). :type control: int or list[int] :param make_alpha_eq_2: Make 1-norm equal 2 by adding and subtracting identity terms. Useful for oblivious amplitude amplification
- Returns:
Circuit – Uprep circuit
Circuit – Uselect circuit
List[int] – QubitOperator qubits
List[int] – Auxillary qubits
float – alpha = 1-norm of coefficients of applied qu_op
- tangelo.toolboxes.circuits.lcu.sign_flip(qubit_list: List[int], control: int | List[int] | None = None) Circuit
Generate Circuit corresponding to the sign flip of the |0>^n vector for the given qubit_list :param qubit_list: The list of n qubits for which the 2*|0>^n-I operation is generated :type qubit_list: list[int] :param control: Control qubit or list of control qubits. :type control: int or list[int]
- Returns:
Circuit – The circuit that generates the sign flip on |0>^n
tangelo.toolboxes.circuits.multiproduct module
Module to generate the circuits necessary to implement multi-product time-evolution Refs:
[1] Guang Hao Low, Vadym Kliuchnikov and Nathan Wiebe, “Well-conditioned multi-product Hamiltonian simulation” arXiv: 1907.11679
- tangelo.toolboxes.circuits.multiproduct.get_ajs_kjs(order: int) Tuple[List[float], List[int], int]
Return aj coefficients and number of steps kj for multi-product order The first two indices of aj coefficients are the portion need to make the one-norm sum to two.
- Parameters:
order (int) – The desired order of expansion
- Returns:
List[float], List[int], int – aj coefficients, kj steps, number of ancilla qubits needed
- tangelo.toolboxes.circuits.multiproduct.get_multi_product_circuit(time: float, order: int, n_state_qus: int, operator: None | QubitOperator | FermionOperator = None, control: int | list | None = None, second_order_trotter: None | Callable[[...], Circuit] = None, trotter_kwargs: dict | None = None) Circuit
Return multi-product circuit as defined in arXiv: 1907.11679. Only up to 6th order is currently supported
- Parameters:
time (float) – The time to evolve.
order (int) – The order of the multi-product expansion
n_state_qus (int) – The number of qubits in the state to evolve.
operator (Union[QubitOperator, FermionOperator]) – The operator to evolve in time. Default None
control (Union[int, List[int]]) – The control qubit(s). Default None
second_order_trotter (Callable[..., Circuit]) – The callable function that defines the controlled 2nd order time-evolution. Must have arguments “control” and “n_trotter_steps”.
trotter_kwargs (dict) – Other keyword arguments necessary to evaluate second_order_trotter.
- Returns:
Circuit – The circuit representing the time-evolution using the multi-product construction.
tangelo.toolboxes.circuits.qsp module
Module to generate the circuits necessary to implement quantum signal processing (QSP) Hamiltonian Simulation
Ref: [1]: Yulong Dong, Xiang Meng, K. Birgitta Whaley, Lin Lin, “Efficient phase-factor evaluation in quantum signal processing” 2021, arXiv:2002.11649 (https://arxiv.org/abs/2002.11649)
- tangelo.toolboxes.circuits.qsp.get_qsp_circuit_no_anc(cua: Circuit, m_qs: List[int], angles: List[float], control: int | List[int] | None = None, with_z: bool = False) Circuit
Generate the ancilla free QSP circuit as defined in Fig 16 of https://arxiv.org/abs/2002.11649.
- Parameters:
cua (Circuit) – The controlled unitary (U_A).
m_qs (List[int]) – The m ancilla qubits used for the Uprep circuit.
angles (List[float]) – The phases for the QSP circuit.
control (Union[int, List[int]]) – The control qubit(s).
with_z (bool) – If True, an extra CZ gate is included. This adds a 1j phase to the operation.
- Returns:
Circuit – The ancilla free QSP circuit
- tangelo.toolboxes.circuits.qsp.get_qsp_hamiltonian_simulation_circuit(qu_op: QubitOperator, tau: float, eps: float = 0.0001, control: int | List[int] | None = None, n_attempts: int = 10, method: str = 'laurent', folder: str | None = None) Circuit
Returns Quantum Signal Processing (QSP) Hamiltonian simulation circuit for a given QubitOperator for time tau.
The circuits are derived from https://arxiv.org/abs/2002.11649. The list of qubits used for the circuit can be found by qubit_list = get_qs_hamiltonian_simulation_qubit_list(qu_op) qu_op must have it’s spectral range in [-1, 1]. This property is not checked by this function.
- Parameters:
qu_op (QubitOperator) – The qubit operator defining the QSP time-evolution circuit.
tau (float) – The evolution time.
eps (float) – The allowed error of the time-evolution. Higher accuracy requires longer circuits, and obtaining the phases can be unstable.
control (Union[int, List[int]]) – The control qubit(s).
n_attempts (int) – The number of attempts to calculate the phase factors using pyqsp.
method (str) – “laurent”: Use laurent polynomial method of pyqsp, “tf”: Use TensorFlow with pyqsp, “QSPPACK”: Use QSPPACK to calculate phases
folder (str) – Folder that contains QSPPACK.
- Returns:
Circuit – The QSP Hamiltonian simulation circuit with oblivious amplitude amplification to ensure very high success probability.
- tangelo.toolboxes.circuits.qsp.get_qsp_hamiltonian_simulation_qubit_list(qu_op: QubitOperator) List[int]
Returns the list of qubits used for the QSP Hamiltonian simulation algorithm
- tangelo.toolboxes.circuits.qsp.ham_sim_phases(tau: float, eps: float = 0.01, n_attempts: int = 10, method: str = 'laurent') Tuple[List[float], List[float]]
Generate the phases required for QSP time-evolution using the pyqsp package
- Parameters:
tau (float) – The evolution time.
eps (float) – The precision to calculate the factors. Higher precision is more likely to fail.
n_attempts (int) – The number of attempts to calculate the phase factors. Often multiple tries are required.
method – “laurent”: Laurent Polynomial method (unstable but fast). “tf” requires TensorFlow installed and is stable but very slow.
- Returns:
List[float] – The phases for Cos(Ht).
List[float] – The phases for i*Sin(Ht).
- tangelo.toolboxes.circuits.qsp.ham_sim_phases_QSPPACK(folder: str, tau: float, eps: float = 1e-07) Tuple[List[float], List[float]]
Generate the phases required for QSP time-evolution using the QSPPACK package.
QSPPACK is an Matlab/Octave based package that calculates the phase factors. To run this function, a user needs to have: 1) Octave installed and accessible in path. Octave can be found at https://octave.org/ 2) oct2py installed. pip install oct2py 3) QSPPACK downloaded in an accessible folder. Can be found at https://github.com/qsppack/QSPPACK/tree/dev
- Parameters:
folder (str) – The folder location of QSPPACK.
tau (float) – The evolution time.
eps (float) – The precision to calculate the factors.
- Returns:
List[float] – The phases for Cos(Ht).
List[float] – The phases for i*Sin(Ht).
- tangelo.toolboxes.circuits.qsp.zero_controlled_cnot(qubit_list: List[int], target: int, control: int | List[int]) Circuit
Return the circuit for a zero-controlled CNOT gate with possible extra controls on 1.
- Parameters:
qubit_list (List[int]) – The qubits controlled by zero.
target (int) – The target qubit.
control (List[int] or int) – The qubits controlled by one.
- Returns:
Circuit – The zero controlled cnot circuit with possible extra controls on 1.