qutip_qip.device¶
Simulation of quantum hardware.
Classes
|
The noisy quantum device simulator using QuTiP dynamic solvers. |
|
Template class for a physical model representing quantum hardware. |
|
The base class for a circuit processor simulating a physical device, e.g cavityQED, spinchain. |
|
Spin chain model with open-end topology. |
|
Spin chain model with circular topology. |
|
The physical model for the spin chian processor ( |
|
The processor based on the physical implementation of a dispersive cavity QED system ( |
|
The physical model for a dispersive cavity-QED processor ( |
|
A chain of superconducting qubits with fixed frequency ( |
|
The physical model for superconducting-qubit model processor ( |
|
A processor that uses |
- class qutip_qip.device.CavityQEDModel(num_qubits, num_levels=10, **params)[source]¶
Bases:
qutip_qip.device.processor.Model
The physical model for a dispersive cavity-QED processor (
DispersiveCavityQED
). It is a qubit-resonator model that describes a system composed of a single resonator and a few qubits connected to it. The coupling is kept small so that the resonator is rarely excited but acts only as a mediator for entanglement generation. The single-qubit control Hamiltonians used are \(\sigma_x\) and \(\sigma_z\). The dynamics between the resonator and the qubits is captured by the Tavis-Cummings Hamiltonian, \(\propto\sum_j a^\dagger \sigma_j^{-} + a \sigma_j^{+}\), where \(a\), \(a^\dagger\) are the destruction and creation operators of the resonator, while \(\sigma_j^{-}\), \(\sigma_j^{+}\) are those of each qubit. The control of the qubit-resonator coupling depends on the physical implementation, but in the most general case we have single and multi-qubit control in the form\[H= \sum_{j=0}^{N-1} \epsilon^{\rm{max}}_{j}(t) \sigma^x_{j} + \Delta^{\rm{max}}_{j}(t) \sigma^z_{j} + J_{j}(t) (a^\dagger \sigma^{-}_{j} + a \sigma^{+}_{j}).\]The effective qubit-qubit coupling is computed by the
\[J_j = \frac{g_j g_{j+1}}{2}(\frac{1}{\Delta_j} + \frac{1}{\Delta_{j+1}}),\]with \(\Delta=w_q-w_0\) and the dressed qubit frequency \(w_q\) defined as \(w_q=\sqrt{\epsilon^2+\delta^2}\).
- Parameters
- num_qubitsint
The number of qubits \(N\).
- num_levelsint, optional
The truncation level of the Hilbert space for the resonator.
- **params :
Keyword arguments for hardware parameters, in the unit of GHz. Qubit parameters can either be a float or a list of the length \(N\).
- deltamax: float or list, optional
The pulse strength of sigma-x control, \(\Delta^{\rm{max}}\), default
1.0
.
- epsmax: float or list, optional
The pulse strength of sigma-z control, \(\epsilon^{\rm{max}}\), default
9.5
.
- eps: float or list, optional
The bare transition frequency for each of the qubits, default
9.5
.
- deltafloat or list, optional
The coupling between qubit states, default
0.0
.
- gfloat or list, optional
The coupling strength between the resonator and the qubit, default
1.0
.
- w0float, optional
The bare frequency of the resonator \(w_0\). Should only be a float, default
0.01
.
- t1float or list, optional
Characterize the amplitude damping for each qubit.
- t2list of list, optional
Characterize the total dephasing for each qubit.
- get_all_drift()[source]¶
Get all the drift Hamiltonians.
- Returns
- drift_hamiltonian_listlist
A list of drift Hamiltonians in the form of
[(qobj, targets), ...]
.
- get_control_latex()[source]¶
Get the labels for each Hamiltonian. It is used in the method method
Processor.plot_pulses()
. It is a 2-d nested list, in the plot, a different color will be used for each sublist.
- class qutip_qip.device.CircularSpinChain(num_qubits=None, correct_global_phase=True, **params)[source]¶
Bases:
qutip_qip.device.spinchain.SpinChain
Spin chain model with circular topology. See
SpinChain
for details. For the control Hamiltonian please refer toSpinChainModel
.- Parameters
- num_qubitsint
The number of qubits in the system.
- correct_global_phasefloat, optional
Save the global phase, the analytical solution will track the global phase. It has no effect on the numerical solution.
- **params:
Hardware parameters. See
SpinChainModel
.
Examples
import numpy as np import qutip from qutip_qip.circuit import QubitCircuit from qutip_qip.device import CircularSpinChain qc = QubitCircuit(2) qc.add_gate("RX", 0, arg_value=np.pi) qc.add_gate("RY", 1, arg_value=np.pi) qc.add_gate("ISWAP", [1, 0]) processor = CircularSpinChain(2, g=0.1, t1=300) processor.load_circuit(qc) init_state = qutip.basis([2, 2], [0, 0]) result = processor.run_state(init_state) print(round(qutip.fidelity(result.states[-1], qc.run(init_state)), 4))
0.994
- load_circuit(qc, schedule_mode='ASAP', compiler=None)[source]¶
The default routine of compilation. It first calls the
transpile()
to convert the circuit to a suitable format for the hardware model. Then it calls the compiler and save the compiled pulses.- Parameters
- qc
QubitCircuit
Takes the quantum circuit to be implemented.
- schedule_mode: string
“ASAP” or “ALAP” or None.
- compiler: subclass of :class:`.GateCompiler`
The used compiler.
- qc
- Returns
- tlist, coeffs: dict of 1D NumPy array
A dictionary of pulse label and the time sequence and compiled pulse coefficients.
- property sxsy_ops¶
A list of tensor(sigmax, sigmay) interacting Hamiltonians for each qubit.
- Type
list
- property sxsy_u¶
Pulse coefficients for tensor(sigmax, sigmay) interacting Hamiltonians.
- Type
array-like
- class qutip_qip.device.DispersiveCavityQED(num_qubits, num_levels=10, correct_global_phase=True, **params)[source]¶
Bases:
qutip_qip.device.modelprocessor.ModelProcessor
The processor based on the physical implementation of a dispersive cavity QED system (
CavityQEDModel
). The available Hamiltonian of the system is predefined. For a given pulse amplitude matrix, the processor can calculate the state evolution under the given control pulse, either analytically or numerically. (Only additional attributes are documented here, for others please refer to the parent classModelProcessor
)- Parameters
- num_qubits: int
The number of qubits in the system.
- num_levels: int, optional
The number of energy levels in the resonator.
- correct_global_phase: float, optional
Save the global phase, the analytical solution will track the global phase. It has no effect on the numerical solution.
- **params:
Hardware parameters. See
CavityQEDModel
.
Examples
import numpy as np import qutip from qutip_qip.circuit import QubitCircuit from qutip_qip.device import DispersiveCavityQED qc = QubitCircuit(2) qc.add_gate("RX", 0, arg_value=np.pi) qc.add_gate("RY", 1, arg_value=np.pi) qc.add_gate("ISWAP", [1, 0]) processor = DispersiveCavityQED(2, g=0.1) processor.load_circuit(qc) result = processor.run_state( qutip.basis([10, 2, 2], [0, 0, 0]), options=qutip.Options(nsteps=5000)) final_qubit_state = result.states[-1].ptrace([1, 2]) print(round(qutip.fidelity( final_qubit_state, qc.run(qutip.basis([2, 2], [0, 0])) ), 4))
0.9994
- property cavityqubit_ops¶
A list of interacting Hamiltonians between cavity and each qubit.
- Type
list
- property g_u¶
Pulse matrix for interacting Hamiltonians between cavity and each qubit.
- Type
array-like
- load_circuit(qc, schedule_mode='ASAP', compiler=None)[source]¶
The default routine of compilation. It first calls the
transpile()
to convert the circuit to a suitable format for the hardware model. Then it calls the compiler and save the compiled pulses.- Parameters
- qc
QubitCircuit
Takes the quantum circuit to be implemented.
- schedule_mode: string
“ASAP” or “ALAP” or None.
- compiler: subclass of :class:`.GateCompiler`
The used compiler.
- qc
- Returns
- tlist, coeffs: dict of 1D NumPy array
A dictionary of pulse label and the time sequence and compiled pulse coefficients.
- property sx_ops¶
A list of sigmax Hamiltonians for each qubit.
- Type
list
- property sx_u¶
Pulse matrix for sigmax Hamiltonians.
- Type
array-like
- property sz_ops¶
A list of sigmaz Hamiltonians for each qubit.
- Type
list
- property sz_u¶
Pulse matrix for sigmaz Hamiltonians.
- Type
array-like
- class qutip_qip.device.LinearSpinChain(num_qubits=None, correct_global_phase=True, **params)[source]¶
Bases:
qutip_qip.device.spinchain.SpinChain
Spin chain model with open-end topology. For the control Hamiltonian please refer to
SpinChainModel
.- Parameters
- num_qubits: int
The number of qubits in the system.
- correct_global_phase: float, optional
Save the global phase, the analytical solution will track the global phase. It has no effect on the numerical solution.
- **params:
Hardware parameters. See
SpinChainModel
.
Examples
import numpy as np import qutip from qutip_qip.circuit import QubitCircuit from qutip_qip.device import LinearSpinChain qc = QubitCircuit(2) qc.add_gate("RX", 0, arg_value=np.pi) qc.add_gate("RY", 1, arg_value=np.pi) qc.add_gate("ISWAP", [1, 0]) processor = LinearSpinChain(2, g=0.1, t1=300) processor.load_circuit(qc) init_state = qutip.basis([2, 2], [0, 0]) result = processor.run_state(init_state) print(round(qutip.fidelity(result.states[-1], qc.run(init_state)), 4))
0.994
- load_circuit(qc, schedule_mode='ASAP', compiler=None)[source]¶
The default routine of compilation. It first calls the
transpile()
to convert the circuit to a suitable format for the hardware model. Then it calls the compiler and save the compiled pulses.- Parameters
- qc
QubitCircuit
Takes the quantum circuit to be implemented.
- schedule_mode: string
“ASAP” or “ALAP” or None.
- compiler: subclass of :class:`.GateCompiler`
The used compiler.
- qc
- Returns
- tlist, coeffs: dict of 1D NumPy array
A dictionary of pulse label and the time sequence and compiled pulse coefficients.
- property sxsy_ops¶
A list of tensor(sigmax, sigmay) interacting Hamiltonians for each qubit.
- Type
list
- property sxsy_u¶
Pulse coefficients for tensor(sigmax, sigmay) interacting Hamiltonians.
- Type
array-like
- class qutip_qip.device.Model(num_qubits, dims=None, **params)[source]¶
Bases:
object
Template class for a physical model representing quantum hardware. The concrete model class does not have to inherit from this, as long as the following methods are defined.
- Parameters
- num_The number of qubits
The number of qubits.
- dimslist, optional
The dimension of each component system. Default value is a qubit system of
dim=[2,2,2,...,2]
.- **params :
Hardware parameters for the model.
- Attributes
- num_The number of qubits
The number of qubits.
- dimslist, optional
The dimension of each component system.
- paramsdict
Hardware parameters for the model.
- get_all_drift() List[Tuple[qutip.qobj.Qobj, List[int]]] [source]¶
Get all the drift Hamiltonians.
- Returns
- drift_hamiltonian_listlist
A list of drift Hamiltonians in the form of
[(qobj, targets), ...]
.
- get_control(label: Hashable) Tuple[qutip.qobj.Qobj, List[int]] [source]¶
Get the control Hamiltonian corresponding to the label.
- Parameters
- labelhashable object
A label that identifies the Hamiltonian.
- Returns
- control_hamiltoniantuple
The control Hamiltonian in the form of
(qobj, targets)
.
- get_control_labels() List[Hashable] [source]¶
Get a list of all available control Hamiltonians. Optional, required only when plotting the pulses or using the optimal control algorithm.
- Returns
- label_listlist of hashable objects
A list of hashable objects each corresponds to an available control Hamiltonian.
- get_noise() List[qutip_qip.noise.Noise] [source]¶
Get a list of
Noise
objects. Single qubit relaxation (T1, T2) are not included here. Optional method.- Returns
- noise_listlist
A list of
Noise
.
- class qutip_qip.device.ModelProcessor(num_qubits=None, dims=None, correct_global_phase=True, model=None, **params)[source]¶
Bases:
qutip_qip.device.processor.Processor
The base class for a circuit processor simulating a physical device, e.g cavityQED, spinchain. The available Hamiltonian of the system is predefined. The processor can simulate the evolution under the given control pulses either numerically or analytically. It cannot be used alone, please refer to the sub-classes. (Only additional attributes are documented here, for others please refer to the parent class
Processor
)- Parameters
- num_qubits: int, optional
The number of qubits. It replaces the old API
N
.- dims: list, optional
The dimension of each component system. Default value is a qubit system of
dim=[2,2,2,...,2]
.- correct_global_phase: boolean, optional
If true, the analytical solution will track the global phase. It has no effect on the numerical solution.
- **params:
- t1: float or list, optional
Characterize the amplitude damping for each qubit. A list of size num_qubits or a float for all qubits.
- t2: float or list, optional
Characterize the total dephasing for each qubit. A list of size num_qubits or a float for all qubits.
- get_ops_and_u()[source]¶
Get the labels for each Hamiltonian.
- Returns
- ctrls: list
The list of Hamiltonians
- coeffs: array_like
The transposed pulse matrix
- load_circuit(qc, schedule_mode='ASAP', compiler=None)[source]¶
The default routine of compilation. It first calls the
transpile()
to convert the circuit to a suitable format for the hardware model. Then it calls the compiler and save the compiled pulses.- Parameters
- qc
QubitCircuit
Takes the quantum circuit to be implemented.
- schedule_mode: string
“ASAP” or “ALAP” or None.
- compiler: subclass of :class:`.GateCompiler`
The used compiler.
- qc
- Returns
- tlist, coeffs: dict of 1D NumPy array
A dictionary of pulse label and the time sequence and compiled pulse coefficients.
- pulse_matrix(dt=0.01)[source]¶
Generates the pulse matrix for the desired physical system.
- Returns
- t, u, labels:
Returns the total time and label for every operation.
- run_state(init_state=None, analytical=False, qc=None, states=None, **kwargs)[source]¶
If
analytical
is False, usequtip.mesolve()
to calculate the time of the state evolution and return the result. Other arguments ofqutip.mesolve()
can be given as keyword arguments. Ifanalytical
is True, calculate the propagator with matrix exponentiation and return a list of matrices.- Parameters
- init_state: Qobj
Initial density matrix or state vector (ket).
- analytical: boolean
If True, calculate the evolution with matrices exponentiation.
- qc
QubitCircuit
, optional A quantum circuit. If given, it first calls the
load_circuit
and then calculate the evolution.- states
qutip.Qobj
, optional Old API, same as init_state.
- **kwargs
Keyword arguments for the qutip solver.
- Returns
- evo_result:
qutip.Result
If
analytical
is False, an instance of the classqutip.Result
will be returned.If
analytical
is True, a list of matrices representation is returned.
- evo_result:
- set_up_params()[source]¶
Save the parameters in the attribute params and check the validity. (Defined in subclasses)
Notes
All parameters will be multiplied by 2*pi for simplicity
- transpile(qc)[source]¶
Convert the circuit to one that can be executed on given hardware. If there is a method
topology_map
defined, it will use it to map the circuit to the hardware topology. If the processor has a set of native gates defined, it will decompose the given circuit to the native gates.- Parameters
- qc: :class:`.QubitCircuit`
The input quantum circuit.
- Returns
- qc:
QubitCircuit
The transpiled quantum circuit.
- qc:
- class qutip_qip.device.OptPulseProcessor(num_qubits=None, drift=None, dims=None, **params)[source]¶
Bases:
qutip_qip.device.processor.Processor
A processor that uses
qutip.control.optimize_pulse_unitary
to find optimized pulses for a given quantum circuit. The processor can simulate the evolution under the given control pulses usingqutip.mesolve()
. (For attributes documentation, please refer to the parent classProcessor
)- Parameters
- num_qubitsint
The number of qubits.
- drift: `:class:`qutip.Qobj`
The drift Hamiltonian. The size must match the whole quantum system.
- dims: list
The dimension of each component system. Default value is a qubit system of
dim=[2,2,2,...,2]
- **params:
- t1float or list, optional
Characterize the amplitude damping for each qubit. A list of size num_qubits or a float for all qubits.
- t2float or list, optional
Characterize the total dephasing for each qubit. A list of size num_qubits or a float for all qubits.
- load_circuit(qc, min_fid_err=inf, merge_gates=True, setting_args=None, verbose=False, **kwargs)[source]¶
Find the pulses realizing a given
Circuit
usingqutip.control.optimize_pulse_unitary()
. Further parameter for forqutip.control.optimize_pulse_unitary()
needs to be given as keyword arguments. By default, it first merge all the gates into one unitary and then find the control pulses for it. It can be turned off and one can set different parameters for different gates. See examples for details.- Parameters
- qc
QubitCircuit
or list of Qobj The quantum circuit to be translated.
- min_fid_err: float, optional
The minimal fidelity tolerance, if the fidelity error of any gate decomposition is higher, a warning will be given. Default is infinite.
- merge_gates: boolean, optimal
If True, merge all gate/Qobj into one Qobj and then find the optimal pulses for this unitary matrix. If False, find the optimal pulses for each gate/Qobj.
- setting_args: dict, optional
Only considered if merge_gates is False. It is a dictionary containing keyword arguments for different gates.
- verbose: boolean, optional
If true, the information for each decomposed gate will be shown. Default is False.
- **kwargs
keyword arguments for :func:
qutip.control.optimize_pulse_unitary
- qc
- Returns
- tlist: array_like
A NumPy array specifies the time of each coefficient
- coeffs: array_like
A 2d NumPy array of the shape
(len(ctrls), len(tlist)-1)
. Each row corresponds to the control pulse sequence for one Hamiltonian.
Notes
len(tlist)-1=coeffs.shape[1]
since tlist gives the beginning and the end of the pulsesExamples
Same parameter for all the gates
>>> from qutip_qip.circuit import QubitCircuit >>> from qutip_qip.device import OptPulseProcessor >>> qc = QubitCircuit(1) >>> qc.add_gate("SNOT", 0) >>> num_tslots = 10 >>> evo_time = 10 >>> processor = OptPulseProcessor(1, drift=sigmaz()) >>> processor.add_control(sigmax()) >>> # num_tslots and evo_time are two keyword arguments >>> tlist, coeffs = processor.load_circuit( qc, num_tslots=num_tslots, evo_time=evo_time)
Different parameters for different gates
>>> from qutip_qip.circuit import QubitCircuit >>> from qutip_qip.device import OptPulseProcessor >>> qc = QubitCircuit(2) >>> qc.add_gate("SNOT", 0) >>> qc.add_gate("SWAP", targets=[0, 1]) >>> qc.add_gate('CNOT', controls=1, targets=[0]) >>> processor = OptPulseProcessor(2, drift=tensor([sigmaz()]*2)) >>> processor.add_control(sigmax(), cyclic_permutation=True) >>> processor.add_control(sigmay(), cyclic_permutation=True) >>> processor.add_control(tensor([sigmay(), sigmay()])) >>> setting_args = {"SNOT": {"num_tslots": 10, "evo_time": 1}, "SWAP": {"num_tslots": 30, "evo_time": 3}, "CNOT": {"num_tslots": 30, "evo_time": 3}} >>> tlist, coeffs = processor.load_circuit( qc, setting_args=setting_args, merge_gates=False)
- class qutip_qip.device.Processor(num_qubits=None, dims=None, spline_kind='step_func', model=None, N=None, t1=None, t2=None)[source]¶
Bases:
object
The noisy quantum device simulator using QuTiP dynamic solvers. It compiles quantum circuit into a Hamiltonian model and then simulate the time-evolution described by the master equation.
Note
This is an abstract class that includes the general API but has no concrete physical model implemented. In particular, it provides a series of low-level APIs that allow direct modification of the Hamiltonian model and control pulses, which can usually be achieved automatically using
Model
and build-in workflows. They provides more flexibility but are not always the most elegant approaches.- Parameters
- num_qubitsint, optional
The number of qubits. It replaces the old API
N
.- dimslist, optional
The dimension of each component system. Default value is a qubit system of
dim=[2,2,2,...,2]
.- spline_kindstr, optional
Type of the coefficient interpolation. Default is “step_func” Note that they have different requirements for the length of
coeff
.-“step_func”: The coefficient will be treated as a step function. E.g.
tlist=[0,1,2]
andcoeff=[3,2]
, means that the coefficient is 3 in t=[0,1) and 2 in t=[2,3). It requireslen(coeff)=len(tlist)-1
orlen(coeff)=len(tlist)
, but in the second case the last element ofcoeff
has no effect.-“cubic”: Use cubic interpolation for the coefficient. It requires
len(coeff)=len(tlist)
- model
Model
Provide a predefined physical model of the simulated hardware. If other parameters, such as t1 is given as input, it will overwrite those saved in
Processor.model.params
.- t1float or list, optional
Characterize the amplitude damping for each qubit. A list of size num_qubits or a float for all qubits.
- t2float or list, optional
Characterize the total dephasing for each qubit. A list of size num_qubits or a float for all qubits.
- add_control(qobj, targets=None, cyclic_permutation=False, label=None)[source]¶
Add a control Hamiltonian to the model. The new control Hamiltonian is saved in the
Processor.model
attributes.- Parameters
- qobj
qutip.Qobj
The control Hamiltonian.
- targetslist, optional
The indices of the target qubits (or composite quantum systems).
- cyclic_permutationbool, optional
If true, the Hamiltonian will be added for all qubits, e.g. if
targets=[0,1]
, and there are 2 qubits, the Hamiltonian will be added to the target qubits[0,1]
,[1,2]
and[2,0]
.- labelstr, optional
The hashable label (name) of the control Hamiltonian. If
None
, it will be set to the current number of control Hamiltonians in the system.
- qobj
Examples
>>> import qutip >>> from qutip_qip.device import Processor >>> processor = Processor(1) >>> processor.add_control(qutip.sigmax(), 0, label="sx") >>> processor.get_control_labels() ['sx'] >>> processor.get_control("sx") (Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True Qobj data = [[0. 1.] [1. 0.]], [0])
- add_drift(qobj, targets=None, cyclic_permutation=False)[source]¶
Add the drift Hamiltonian to the model. The drift Hamiltonians are intrinsic of the quantum system and cannot be controlled by an external field.
- Parameters
- qobj
qutip.Qobj
The drift Hamiltonian.
- targetslist, optional
The indices of the target qubits (or subquantum system of other dimensions).
- cyclic_permutationbool, optional
If true, the Hamiltonian will be added for all qubits, e.g. if
targets=[0,1]
, and there are 2 qubits, The Hamiltonian will be added to the target qubits[0,1]
,[1,2]
and[2,0]
.
- qobj
- add_noise(noise)[source]¶
Add a noise object to the processor.
- Parameters
- noise
Noise
The noise object defined outside the processor.
- noise
- add_pulse(pulse)[source]¶
Add a new pulse to the device.
- Parameters
- pulse
Pulse
Pulse object to be added.
- pulse
- property coeffs¶
A list of ideal control coefficients for all saved pulses. The order matches with
Processor.controls
- property controls¶
A list of the ideal control Hamiltonians in all saved pulses. Note that control Hamiltonians with no pulse will not be included. The order matches with
Processor.coeffs
- property ctrls¶
A list of the ideal control Hamiltonians in all saved pulses. Note that control Hamiltonians with no pulse will not be included. The order matches with
Processor.coeffs
- property dims¶
The dimension of each component system. :type: list
- property drift¶
The drift Hamiltonian in the form
[(qobj, targets), ...]
:type: list
- eliminate_auxillary_modes(U)[source]¶
Eliminate the auxillary modes like the cavity modes in cqed. (Defined in subclasses)
- get_all_drift()[source]¶
Get all the drift Hamiltonians.
- Returns
- drift_hamiltonian_listlist
A list of drift Hamiltonians in the form of
[(qobj, targets), ...]
.
- get_control(label)[source]¶
Get the control Hamiltonian corresponding to the label.
- Parameters
- label :
A label that identifies the Hamiltonian.
- Returns
- control_hamiltoniantuple
The control Hamiltonian in the form of
(qobj, targets)
.
Examples
>>> from qutip_qip.device import LinearSpinChain >>> processor = LinearSpinChain(1) >>> processor.get_control_labels() ['sx0', 'sz0'] >>> processor.get_control('sz0') (Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True Qobj data = [[ 6.28318531 0. ] [ 0. -6.28318531]], 0)
- get_control_labels()[source]¶
Get a list of all available control Hamiltonians.
- Returns
- label_listlist
A list of hashable objects each corresponds to an available control Hamiltonian.
- get_control_latex()[source]¶
Get the latex string for each Hamiltonian. It is used in the method
Processor.plot_pulses()
. It is a list of dictionaries. In the plot, a different color will be used for each dictionary in the list.- Returns
- nested_latex_strlist of dict
E.g.:
[{"sx": "\sigma_z"}, {"sy": "\sigma_y"}]
.
- get_full_coeffs(full_tlist=None)[source]¶
Return the full coefficients in a 2d matrix form. Each row corresponds to one pulse. If the tlist are different for different pulses, the length of each row will be the same as the full_tlist (see method get_full_tlist). Interpolation is used for adding the missing coefficients according to spline_kind.
- Returns
- coeffs: array-like 2d
The coefficients for all ideal pulses.
- get_full_tlist(tol=1e-10)[source]¶
Return the full tlist of the ideal pulses. If different pulses have different time steps, it will collect all the time steps in a sorted array.
- Returns
- full_tlist: array-like 1d
The full time sequence for the ideal evolution.
- get_noisy_pulses(device_noise=False, drift=False)[source]¶
It takes the pulses defined in the Processor and adds noise according to Processor.noise. It does not modify the pulses saved in Processor.pulses but returns a new list. The length of the new list of noisy pulses might be longer because of drift Hamiltonian and device noise. They will be added to the end of the pulses list.
- Parameters
- device_noise: bool, optional
If true, include pulse independent noise such as single qubit Relaxation. Default is False.
- drift: bool, optional
If true, include drift Hamiltonians. Default is False.
- Returns
- noisy_pulseslist of
Drift
A list of noisy pulses.
- noisy_pulseslist of
- get_qobjevo(args=None, noisy=False)[source]¶
Create a
qutip.QobjEvo
representation of the evolution. It calls the methodProcessor.get_noisy_pulses()
and create the QobjEvo from it.- Parameters
- args: dict, optional
Arguments for
qutip.QobjEvo
- noisy: bool, optional
If noise are included. Default is False.
- Returns
- qobjevo
qutip.QobjEvo
The
qutip.QobjEvo
representation of the unitary evolution.- c_ops: list of
qutip.QobjEvo
A list of lindblad operators is also returned. if
noisy==False
, it is always an empty list.
- qobjevo
- load_circuit(qc)[source]¶
Translate an
QubitCircuit
to its corresponding Hamiltonians. (Defined in subclasses)
- property noise¶
.coverage
- property num_qubits¶
Number of qubits (or subsystems). For backward compatibility. :type: int
- property params¶
Hardware parameters. :type: dict
- plot_pulses(title=None, figsize=(12, 6), dpi=None, show_axis=False, rescale_pulse_coeffs=True, num_steps=1000, pulse_labels=None, use_control_latex=True)[source]¶
Plot the ideal pulse coefficients.
- Parameters
- title: str, optional
Title for the plot.
- figsize: tuple, optional
The size of the figure.
- dpi: int, optional
The dpi of the figure.
- show_axis: bool, optional
If the axis are shown.
- rescale_pulse_coeffs: bool, optional
Rescale the hight of each pulses.
- num_steps: int, optional
Number of time steps in the plot.
- pulse_labels: list of dict, optional
A map between pulse labels and the labels shown in the y axis. E.g.
[{"sx": "sigmax"}]
. Pulses in each dictionary will get a different color. If not given anduse_control_latex==False
, the string label defined in eachPulse
is used.- use_control_latex: bool, optional
Use labels defined in
Processor.model.get_control_latex
.- pulse_labels: list of dict, optional
A map between pulse labels and the labels shown on the y axis. E.g.
["sx", "sigmax"]
. If not given anduse_control_latex==False
, the string label defined in eachPulse
is used.- use_control_latex: bool, optional
Use labels defined in
Processor.model.get_control_latex
.
- Returns
- fig: matplotlib.figure.Figure
The Figure object for the plot.
- axis: list of
matplotlib.axes._subplots.AxesSubplot
The axes for the plot.
Notes
:meth:.Processor.plot_pulses` only works for array_like coefficients.
- property pulse_mode¶
If the given pulse is going to be interpreted as “continuous” or “discrete”.
- Type
str
- read_coeff(file_name, inctime=True)[source]¶
Read the control amplitudes matrix and time list saved in the file by save_amp.
- Parameters
- file_name: string
Name of the file.
- inctime: bool, optional
True if the time list in included in the first column.
- Returns
- tlist: array_like
The time list read from the file.
- coeffs: array_like
The pulse matrix read from the file.
- remove_pulse(indices=None, label=None)[source]¶
Remove the control pulse with given indices.
- Parameters
- indices: int or list of int
The indices of the control Hamiltonians to be removed.
- label: str
The label of the pulse
- run(qc=None)[source]¶
Calculate the propagator of the evolution by matrix exponentiation. This method won’t include noise or collpase.
- Parameters
- qc
QubitCircuit
, optional Takes the quantum circuit to be implemented. If not given, use the quantum circuit saved in the processor by load_circuit.
- qc
- Returns
- U_list: list
The propagator matrix obtained from the physical implementation.
- run_analytically(init_state=None, qc=None)[source]¶
Simulate the state evolution under the given qutip.QubitCircuit with matrice exponentiation. It will calculate the propagator with matrix exponentiation and return a list of
qutip.Qobj
. This method won’t include noise or collpase.- Parameters
- qc
QubitCircuit
, optional Takes the quantum circuit to be implemented. If not given, use the quantum circuit saved in the processor by
load_circuit
.- init_state
qutip.Qobj
, optional The initial state of the qubits in the register.
- qc
- Returns
- U_list: list
A list of propagators obtained for the physical implementation.
- run_state(init_state=None, analytical=False, states=None, noisy=True, solver='mesolve', **kwargs)[source]¶
If analytical is False, use
qutip.mesolve()
to calculate the time of the state evolution and return the result. Other arguments of mesolve can be given as keyword arguments.If analytical is True, calculate the propagator with matrix exponentiation and return a list of matrices. Noise will be neglected in this option.
- Parameters
- init_state
qutip.Qobj
Initial density matrix or state vector (ket).
- analytical: bool
If True, calculate the evolution with matrices exponentiation.
- states
qutip.Qobj
, optional Old API, same as init_state.
- solver: str
“mesolve” or “mcsolve”, for
mesolve()
andmcsolve()
.- noisy: bool
Include noise or not.
- **kwargs
Keyword arguments for the qutip solver. E.g tlist for time points for recording intermediate states and expectation values; args for the solvers and qutip.QobjEvo.
- init_state
- Returns
- evo_result
qutip.Result
If
analytical
is False, an instance of the classqutip.Result
will be returned.If
analytical
is True, a list of matrices representation is returned.
- evo_result
- save_coeff(file_name, inctime=True)[source]¶
Save a file with the control amplitudes in each timeslot.
- Parameters
- file_name: string
Name of the file.
- inctime: bool, optional
True if the time list should be included in the first column.
- set_all_coeffs(coeffs)¶
Clear all the existing pulses and reset the coefficients for the control Hamiltonians.
- Parameters
- coeffs: NumPy arrays, dict or list.
If it is a dict, it should be a map of the label of control Hamiltonians and the corresponding coefficients. Use
Processor.get_control_labels()
to see the available Hamiltonians.If it is a list of arrays or a 2D NumPy array, it is treated same to
dict
, only that the pulse label is assumed to be integers from 0 tolen(coeffs)-1
.
- set_all_tlist(tlist)¶
Set the
tlist
for all existing pulses. It assumes that pulses all already added to the processor. To add pulses automatically, first useProcessor.set_coeffs
.- Parameters
- tlist: dict or list of NumPy arrays.
If it is a dict, it should be a map between pulse label and the time sequences. If it is a list of arrays or a 2D NumPy array, each array will be associated to a pulse, following the order in the pulse list.
- set_coeffs(coeffs)[source]¶
Clear all the existing pulses and reset the coefficients for the control Hamiltonians.
- Parameters
- coeffs: NumPy arrays, dict or list.
If it is a dict, it should be a map of the label of control Hamiltonians and the corresponding coefficients. Use
Processor.get_control_labels()
to see the available Hamiltonians.If it is a list of arrays or a 2D NumPy array, it is treated same to
dict
, only that the pulse label is assumed to be integers from 0 tolen(coeffs)-1
.
- set_tlist(tlist)[source]¶
Set the
tlist
for all existing pulses. It assumes that pulses all already added to the processor. To add pulses automatically, first useProcessor.set_coeffs
.- Parameters
- tlist: dict or list of NumPy arrays.
If it is a dict, it should be a map between pulse label and the time sequences. If it is a list of arrays or a 2D NumPy array, each array will be associated to a pulse, following the order in the pulse list.
- property t1¶
Characterize the total amplitude damping of each qubit. :type: float or list
- property t2¶
Characterize the total dephasing for each qubit. :type: float or list
- class qutip_qip.device.SCQubits(num_qubits, dims=None, zz_crosstalk=False, **params)[source]¶
Bases:
qutip_qip.device.modelprocessor.ModelProcessor
A chain of superconducting qubits with fixed frequency (
SCQubitsModel
). Single-qubit control is realized by rotation around the X and Y axis while two-qubit gates are implemented with Cross Resonance gates. A 3-level system is used to simulate the superconducting qubit system, in order to simulation leakage. Various types of interaction can be realized on a superconducting system, as a demonstration and for simplicity, we only use a ZX Hamiltonian for the two-qubit interaction.See the mathematical details in
SCQubitsCompiler
andSCQubitsModel
.- Parameters
- num_qubits: int
The number of qubits in the system.
- dims: list, optional
The dimension of each component system. Default value is a qubit system of
dim=[2,2,2,...,2]
.- zz_crosstalk: bool, optional
If ZZ cross-talk is included.
- **params:
Hardware parameters. See
SCQubitsModel
.
Examples
import numpy as np import qutip from qutip_qip.circuit import QubitCircuit from qutip_qip.device import SCQubits qc = QubitCircuit(2) qc.add_gate("RZ", 0, arg_value=np.pi) qc.add_gate("RY", 1, arg_value=np.pi) qc.add_gate("CNOT", targets=0, controls=1) processor = SCQubits(2) processor.load_circuit(qc) init_state = qutip.basis([3, 3], [0, 0]) result = processor.run_state(init_state)
- class qutip_qip.device.SCQubitsModel(num_qubits, dims=None, zz_crosstalk=False, **params)[source]¶
Bases:
qutip_qip.device.processor.Model
The physical model for superconducting-qubit model processor (
SCQubits
) with fixed frequency. Each qubit is simulated by a multi-level Duffing model [7], in which the qubit subspace is provided by the ground state and the first excited state. By default, the creation and annihilation operators are truncated at the third level, which can be adjusted. The multi-level representation can capture the leakage of the population out of the qubit subspace during single-qubit gates. The single-qubit control is generated by two orthogonal quadratures \(a_j^{\dagger}+a_j\) and \(i(a_j^{\dagger}-a_j)\). The interaction is possible only between adjacent qubits. Although this interaction is mediated by a resonator, for simplicity, we replace the complicated dynamics among two superconducting qubits and the resonator with a two-qubit effective Hamiltonian derived in Ref. [2].As an example, we choose the cross resonance interaction in the form of \(\sigma^z_{j} \sigma^x_{j+1}\), acting only on the two-qubit levels, which is widely used, e.g., in fixed-frequency superconducting qubits. We can write the Hamiltonian as
\[\begin{split}H &= H_{\rm{d}} + \sum_{j=0}^{N-1} \Omega^x_{j} (a_j^{\dagger} + a_j) + \Omega^y_{j} i(a_j^{\dagger} - a_j) \\ & + \sum_{j=0}^{N-2} \Omega^{\rm{cr}1}_{j} \sigma^z_j \sigma^x_{j+1} + \Omega^{\rm{cr}2}_{j} \sigma^x_j \sigma^z_{j+1}\end{split}\]where the drift Hamiltonian is defined as
\[H_{\rm{d}} = \sum_{j=0}^{N-1} \frac{\alpha_j}{2} a_j^{\dagger}a_j^{\dagger}a_j a_j\]- Parameters
- num_qubits: int
The number of qubits.
- dims: list, optional
The dimension of each component system. Default value is a qubit system of
dim=[2,2,2,...,2]
.- zz_crosstalk: bool, optional
If ZZ cross-talk is included.
- **params:
Keyword arguments for hardware parameters, in the unit of GHz. Each should be given as list:
- wqlist, optional
Qubits bare frequency, default 5.15 and 5.09 for each pair of superconducting qubits, default
[5.15, 5.09, 5.15, ...]
.
- wrlist, optional
Resonator bare frequency, default
[5.96]*num_qubits
.
- glist, optional
The coupling strength between the resonator and the qubits, default
[0.1]*(num_qubits - 1)
.
- alphalist, optional
Anharmonicity for each superconducting qubit, default
[-0.3]*num_qubits
.
- omega_singlelist, optional
The maximal control strength for single-qubit gate, \(\Omega^x\) and \(\Omega^y\), default
[0.01]*num_qubits
.
- omega_crlist, optional
Control strength for cross resonance gate, default
[0.01]*num_qubits
.
- t1float or list, optional
Characterize the amplitude damping for each qubit.
- t2list of list, optional
Characterize the total dephasing for each qubit.
- get_control_latex()[source]¶
Get the labels for each Hamiltonian. It is used in the method method
Processor.plot_pulses()
. It is a 2-d nested list, in the plot, a different color will be used for each sublist.
- class qutip_qip.device.SpinChainModel(num_qubits, setup, **params)[source]¶
Bases:
qutip_qip.device.processor.Model
The physical model for the spin chian processor (
CircularSpinChain
andLinearSpinChain
). The interaction is only possible between adjacent qubits. The single-qubit control Hamiltonians are \(\sigma_j^x\), \(\sigma_j^z\), while the interaction is realized by the exchange Hamiltonian \(\sigma^x_{j}\sigma^x_{j+1}+\sigma^y_{j}\sigma^y_{j+1}\). The overall Hamiltonian model is written as:\[H= \sum_{j=0}^{N-1} \Omega^x_{j}(t) \sigma^x_{j} + \Omega^z_{j}(t) \sigma^z_{j} + \sum_{j=0}^{N-2} g_{j}(t) (\sigma^x_{j}\sigma^x_{j+1}+ \sigma^y_{j}\sigma^y_{j+1}).\]- Parameters
- num_qubits: int
The number of qubits, \(N\).
- setupstr
“linear” for an open end and “circular” for a closed end chain.
- **params :
Keyword arguments for hardware parameters, in the unit of frequency (MHz, GHz etc, the unit of time list needs to be adjusted accordingly). Parameters can either be a float or list with parameters for each qubits.
- sxfloat or list, optional
The pulse strength of sigma-x control, \(\Omega^x\), default
0.25
.
- szfloat or list, optional
The pulse strength of sigma-z control, \(\Omega^z\), default
1.0
.
- sxsyfloat or list, optional
The pulse strength for the exchange interaction, \(g\), default
0.1
. It should be either a float or an array of the length \(N-1\) for the linear setup or \(N\) for the circular setup.
- t1float or list, optional
Characterize the amplitude damping for each qubit.
- t2list of list, optional
Characterize the total dephasing for each qubit.
- get_control_latex()[source]¶
Get the labels for each Hamiltonian. It is used in the method method
Processor.plot_pulses()
. It is a 2-d nested list, in the plot, a different color will be used for each sublist.