diff --git a/latest b/latest index 98610aa42..9d3ffadc3 120000 --- a/latest +++ b/latest @@ -1 +1 @@ -v1.6.2 \ No newline at end of file +v1.6.3 \ No newline at end of file diff --git a/v1.6.3/404.html b/v1.6.3/404.html new file mode 100644 index 000000000..9d7525bca --- /dev/null +++ b/v1.6.3/404.html @@ -0,0 +1,2307 @@ + + + +
+ + + + + + + + + + + + + + +Backend(name, supports_ad, support_bp, supports_adjoint, is_remote, with_measurements, native_endianness, engine, with_noise, config)
+
+
+ dataclass
+
+
+
+ Bases: ABC
The abstract class that defines the interface for the backends.
+ + +ATTRIBUTE | +DESCRIPTION | +
---|---|
name |
+
+
+
+ backend unique string identifier +
+
+ TYPE:
+ |
+
supports_ad |
+
+
+
+ whether or not the backend has a native autograd +
+
+ TYPE:
+ |
+
supports_bp |
+
+
+
+ whether or not the backend has a native backprop +
+
+ TYPE:
+ |
+
supports_adjoint |
+
+
+
+ Does the backend support native adjoint differentation. +
+
+ TYPE:
+ |
+
is_remote |
+
+
+
+ whether computations are executed locally or remotely on this +backend, useful when using cloud platforms where credentials are +needed for example. +
+
+ TYPE:
+ |
+
with_measurements |
+
+
+
+ whether it supports counts or not +
+
+ TYPE:
+ |
+
with_noise |
+
+
+
+ whether to add realistic noise or not +
+
+ TYPE:
+ |
+
native_endianness |
+
+
+
+ The native endianness of the backend +
+
+ TYPE:
+ |
+
engine |
+
+
+
+ The underlying (native) automatic differentiation engine of the backend. +
+
+ TYPE:
+ |
+
circuit(circuit)
+
+
+ abstractmethod
+
+
+Converts an abstract QuantumCircuit
to the native backend representation.
PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ A circuit, for example:
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ConvertedCircuit
+
+ |
+
+
+
+ A converted circuit |
+
+
+ ConvertedCircuit
+
+ |
+
+
+
+ and the converted (or backend native) circuit via |
+
qadence/backend.py
convert(circuit, observable=None)
+
+Convert an abstract circuit and an optional observable to their native representation.
+Additionally, this function constructs an embedding function which maps from +user-facing parameters to device parameters (read more on parameter embedding +here).
+ +qadence/backend.py
174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 |
|
expectation(circuit, observable, param_values={}, state=None, measurement=None, noise=None, mitigation=None, endianness=Endianness.BIG)
+
+
+ abstractmethod
+
+
+Compute the expectation value of the circuit
with the given observable
.
PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ A converted circuit as returned by
+
+ TYPE:
+ |
+
param_values |
+
+
+
+ Already embedded parameters of the circuit. See
+
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
measurement |
+
+
+
+ Optional measurement protocol. If None, use +exact expectation value with a statevector simulator. +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ A noise model to use. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ Endianness of the resulting bit strings. +
+
+ TYPE:
+ |
+
qadence/backend.py
observable(observable, n_qubits)
+
+
+ abstractmethod
+
+
+Converts an abstract observable (which is just an AbstractBlock
) to the native backend.
representation.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
observable |
+
+
+
+ An observable. +
+
+ TYPE:
+ |
+
n_qubits |
+
+
+
+ Number of qubits the observable covers. This is typically
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ConvertedObservable
+
+ |
+
+
+
+ A converted observable |
+
+
+ ConvertedObservable
+
+ |
+
+
+
+
|
+
qadence/backend.py
run(circuit, param_values={}, state=None, endianness=Endianness.BIG, *args, **kwargs)
+
+Run a circuit and return the resulting wave function.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ A converted circuit as returned by
+
+ TYPE:
+ |
+
param_values |
+
+
+
+ Already embedded parameters of the circuit. See
+
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ Endianness of the resulting wavefunction. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ArrayLike
+
+ |
+
+
+
+ A list of Counter objects where each key represents a bitstring + |
+
+
+ ArrayLike
+
+ |
+
+
+
+ and its value the number of times it has been sampled from the given wave function. + |
+
qadence/backend.py
run_dm(circuit, noise, param_values={}, state=None, endianness=Endianness.BIG)
+
+
+ abstractmethod
+
+
+Run a circuit and return the resulting the density matrix.
+TODO: Temporary method for the purposes of noise model implementation. +To be removed in a later refactoring.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ A converted circuit as returned by
+
+ TYPE:
+ |
+
param_values |
+
+
+
+ Already embedded parameters of the circuit. See
+
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ Endianness of the resulting density matrix. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A list of Counter objects where each key represents a bitstring + |
+
+
+ Tensor
+
+ |
+
+
+
+ and its value the number of times it has been sampled from the given wave function. + |
+
qadence/backend.py
sample(circuit, param_values={}, n_shots=1000, state=None, noise=None, mitigation=None, endianness=Endianness.BIG)
+
+
+ abstractmethod
+
+
+Sample bit strings.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ A converted circuit as returned by
+
+ TYPE:
+ |
+
param_values |
+
+
+
+ Already embedded parameters of the circuit. See
+
+
+ TYPE:
+ |
+
n_shots |
+
+
+
+ Number of shots to sample. +
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ A noise model to use. +
+
+ TYPE:
+ |
+
mitigation |
+
+
+
+ An error mitigation protocol to apply. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ Endianness of the resulting bit strings. +
+
+ TYPE:
+ |
+
qadence/backend.py
BackendConfiguration(_use_gate_params=True, use_sparse_observable=False, use_gradient_checkpointing=False, use_single_qubit_composition=False, transpilation_passes=None)
+
+
+ dataclass
+
+
+available_options()
+
+Return as a string the available fields with types of the configuration.
+ + +RETURNS | +DESCRIPTION | +
---|---|
+ str
+ |
+
+
+
+ a string with all the available fields, one per line +
+
+ TYPE:
+ |
+
qadence/backend.py
get_param_name(blk)
+
+Return parameter names for the current backend.
+Depending on which backend is in use this +function returns either UUIDs or expressions of parameters.
+ +qadence/backend.py
DifferentiableBackend(backend, diff_mode=DiffMode.AD, **psr_args)
+
+
+ Bases: DifferentiableBackend
A class which wraps a QuantumBackend with the automatic differentation engine TORCH.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
backend |
+
+
+
+ An instance of the QuantumBackend type perform execution. +
+
+ TYPE:
+ |
+
diff_mode |
+
+
+
+ A differentiable mode supported by the differentiation engine. +
+
+ TYPE:
+ |
+
**psr_args |
+
+
+
+ Arguments that will be passed on to
+
+ TYPE:
+ |
+
qadence/engines/torch/differentiable_backend.py
expectation(circuit, observable, param_values={}, state=None, measurement=None, noise=None, mitigation=None, endianness=Endianness.BIG)
+
+Compute the expectation value of the circuit
with the given observable
.
PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ A converted circuit as returned by
+
+ TYPE:
+ |
+
observable |
+
+
+
+ A converted observable as returned by
+
+ TYPE:
+ |
+
param_values |
+
+
+
+ Already embedded parameters of the circuit. See
+
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
measurement |
+
+
+
+ Optional measurement protocol. If None, use +exact expectation value with a statevector simulator. +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ A noise model to use. +
+
+ TYPE:
+ |
+
mitigation |
+
+
+
+ The error mitigation to use. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ Endianness of the resulting bit strings. +
+
+ TYPE:
+ |
+
qadence/engines/torch/differentiable_backend.py
DifferentiableBackend(backend, diff_mode=DiffMode.AD, **psr_args)
+
+
+ Bases: DifferentiableBackend
A class which wraps a QuantumBackend with the automatic differentation engine JAX.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
backend |
+
+
+
+ An instance of the QuantumBackend type perform execution. +
+
+ TYPE:
+ |
+
diff_mode |
+
+
+
+ A differentiable mode supported by the differentiation engine. +
+
+ TYPE:
+ |
+
**psr_args |
+
+
+
+ Arguments that will be passed on to
+
+ TYPE:
+ |
+
qadence/engines/jax/differentiable_backend.py
expectation(circuit, observable, param_values={}, state=None, measurement=None, noise=None, mitigation=None, endianness=Endianness.BIG)
+
+Compute the expectation value of the circuit
with the given observable
.
PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ A converted circuit as returned by
+
+ TYPE:
+ |
+
observable |
+
+
+
+ A converted observable as returned by
+
+ TYPE:
+ |
+
param_values |
+
+
+
+ Already embedded parameters of the circuit. See
+
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
measurement |
+
+
+
+ Optional measurement protocol. If None, use +exact expectation value with a statevector simulator. +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ A noise model to use. +
+
+ TYPE:
+ |
+
mitigation |
+
+
+
+ The error mitigation to use. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ Endianness of the resulting bit strings. +
+
+ TYPE:
+ |
+
qadence/engines/jax/differentiable_backend.py
The Pulser backend features a basic integration with the pulse-level programming +interface Pulser. This backend offers for now few simple operations +which are translated into a valid, non time-dependent pulse sequence. In particular, one has access to:
+AnalogRx
and AnalogRy
blocksAnalogWait
blockAnalogEntanglement
Rx
and Ry
Backend(name=BackendName.PULSER, supports_ad=False, support_bp=False, supports_adjoint=False, is_remote=False, with_measurements=True, native_endianness=Endianness.BIG, engine=Engine.TORCH, with_noise=False, config=Configuration())
+
+
+ dataclass
+
+
+create_register(register)
+
+Convert Qadence Register to Pulser Register.
+ + +Fast differentiable statevector emulator based on PyTorch. The code is open source, +hosted on Github and maintained by Pasqal.
+ + +Backend(name=BackendName.PYQTORCH, supports_ad=True, support_bp=True, supports_adjoint=True, is_remote=False, with_measurements=True, native_endianness=Endianness.BIG, engine=Engine.TORCH, with_noise=False, config=Configuration())
+
+
+ dataclass
+
+
+
+ Bases: Backend
PyQTorch backend.
+ + + + +convert(circuit, observable=None)
+
+Convert an abstract circuit and an optional observable to their native representation.
+Additionally, this function constructs an embedding function which maps from +user-facing parameters to device parameters (read more on parameter embedding +here).
+ +qadence/backend.py
174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 |
|
Configuration(_use_gate_params=True, use_sparse_observable=False, use_gradient_checkpointing=False, use_single_qubit_composition=False, transpilation_passes=None, algo_hevo=AlgoHEvo.EXP, n_steps_hevo=100, loop_expectation=False)
+
+
+ dataclass
+
+
+
+ Bases: BackendConfiguration
algo_hevo: AlgoHEvo = AlgoHEvo.EXP
+
+
+ class-attribute
+ instance-attribute
+
+
+Determine which kind of Hamiltonian evolution algorithm to use.
+loop_expectation: bool = False
+
+
+ class-attribute
+ instance-attribute
+
+
+When computing batches of expectation values, only allocate one wavefunction.
+Loop over the batch of parameters to only allocate a single wavefunction at any given time.
+n_steps_hevo: int = 100
+
+
+ class-attribute
+ instance-attribute
+
+
+Default number of steps for the Hamiltonian evolution.
+use_gradient_checkpointing: bool = False
+
+
+ class-attribute
+ instance-attribute
+
+
+Use gradient checkpointing.
+Recommended for higher-order optimization tasks.
+use_single_qubit_composition: bool = False
+
+
+ class-attribute
+ instance-attribute
+
+
+Composes chains of single qubit gates into a single matmul if possible.
+supported_gates = list(set(OpName.list()) - set([OpName.TDAGGER]))
+
+
+ module-attribute
+
+
+The set of supported gates.
+Tdagger is currently not supported.
+PyQHamiltonianEvolution(qubit_support, n_qubits, block, config)
+
+
+ Bases: Module
qadence/backends/pyqtorch/convert_ops.py
dagger(values)
+
+Dagger of the evolved operator given the current parameter values.
+ + +jacobian_generator(values)
+
+Approximate jacobian of the evolved operator with respect to generator parameter(s).
+ +qadence/backends/pyqtorch/convert_ops.py
jacobian_time(values)
+
+Approximate jacobian of the evolved operator with respect to time evolution.
+ +qadence/backends/pyqtorch/convert_ops.py
unitary(values)
+
+The evolved operator given current parameter values for generator and time evolution.
+ +qadence/backends/pyqtorch/convert_ops.py
qadence
offers a block-based system to construct quantum circuits in a flexible manner.
AbstractBlock(tag=None, __array_priority__=1000)
+
+
+ dataclass
+
+
+
+ Bases: ABC
Base class for both primitive and composite blocks.
+ + +ATTRIBUTE | +DESCRIPTION | +
---|---|
name |
+
+
+
+ A human-readable name attached to the block type. Notice, this is +the same for all the class instances so it cannot be used for identifying +different blocks +
+
+ TYPE:
+ |
+
qubit_support |
+
+
+
+ The qubit support of the block expressed as +a tuple of integers +
+
+ TYPE:
+ |
+
tag |
+
+
+
+ A tag identifying a particular instance of the block which can +be used for identification and pretty printing +
+
+ TYPE:
+ |
+
eigenvalues |
+
+
+
+ The eigenvalues of the matrix representing the block. +This is used mainly for primitive blocks and it's needed for generalized parameter +shift rule computations. Currently unused. +
+
+ TYPE:
+ |
+
is_identity: bool
+
+
+ property
+
+
+Identity predicate for blocks.
+n_qubits()
+
+The number of qubits in the whole system.
+A block acting on qubit N would has at least n_qubits >= N + 1.
+ + +n_supports()
+
+qubit_support()
+
+The indices of the qubit(s) the block is acting on.
+Qadence uses the ordering [0..,N-1] for qubits.
+ + +ControlBlock(control, target_block)
+
+
+ Bases: PrimitiveBlock
The abstract ControlBlock.
+ +qadence/blocks/primitive.py
ParametricBlock(qubit_support)
+
+
+ dataclass
+
+
+
+ Bases: PrimitiveBlock
Parameterized primitive blocks.
+ +qadence/blocks/primitive.py
num_parameters()
+
+
+ abstractmethod
+
+
+The number of parameters required by the block.
+This is a class property since the number of parameters is defined +automatically before instantiating the operation. Also, this could +correspond to a larger number of actual user-facing parameters +since any parameter expression is allowed
+Examples: +- RX operation has 1 parameter +- U operation has 3 parameters +- HamEvo has 2 parameters (generator and time evolution)
+ +qadence/blocks/primitive.py
ParametricControlBlock(control, target_block)
+
+
+ Bases: ParametricBlock
The abstract parametrized ControlBlock.
+ +qadence/blocks/primitive.py
PrimitiveBlock(qubit_support)
+
+
+ Bases: AbstractBlock
Primitive blocks represent elementary unitary operations.
+Examples are single/multi-qubit gates or Hamiltonian evolution.
+See qadence.operations
for a full list of
+primitive blocks.
qadence/blocks/primitive.py
digital_decomposition()
+
+Decomposition into purely digital gates.
+This method returns a decomposition of the Block in a +combination of purely digital single-qubit and two-qubit +'gates', by manual/custom knowledge of how this can be done efficiently. +:return:
+ +qadence/blocks/primitive.py
ProjectorBlock(ket, bra, qubit_support)
+
+
+ Bases: PrimitiveBlock
The abstract ProjectorBlock.
+ +Arguments:
+ket (str): The ket given as a bitstring.
+bra (str): The bra given as a bitstring.
+qubit_support (int | tuple[int]): The qubit_support of the block.
+
qadence/blocks/primitive.py
ScaleBlock(block, parameter)
+
+
+ Bases: ParametricBlock
Scale blocks are created when multiplying a block by a number or parameter.
+Example: +
+ + +qadence/blocks/primitive.py
TimeEvolutionBlock(qubit_support)
+
+
+ dataclass
+
+
+
+ Bases: ParametricBlock
Simple time evolution block with time-independent Hamiltonian.
+This class is just a convenience class which is used to label +blocks which contains simple time evolution with time-independent +Hamiltonian operators
+ +qadence/blocks/primitive.py
To learn how to use analog blocks and how to mix digital & analog blocks, check out the +digital-analog section of the documentation.
+Examples on how to use digital-analog blocks can be found in the +*examples folder of the qadence repo:
+examples/digital-analog/fit-sin.py
examples/digital-analog/qubo.py
AnalogChain(blocks)
+
+
+ dataclass
+
+
+
+ Bases: AnalogComposite
A chain of analog blocks.
+Needed because analog blocks require
+stricter validation than the general ChainBlock
.
AnalogChain
s can only be constructed from AnalogKron
blocks or
+globally supported, primitive, analog blocks (like InteractionBlock
s and
+ConstantAnalogRotation
s).
Automatically constructed by the chain
+function if only analog blocks are given.
Example: +
from qadence import X, chain, AnalogInteraction
+
+b = chain(AnalogInteraction(200), AnalogInteraction(200))
+print(type(b)) # this is an `AnalogChain`
+
+b = chain(X(0), AnalogInteraction(200))
+print(type(b)) # this is a general `ChainBlock`
+
qadence/blocks/analog.py
AnalogKron(blocks, interaction=Interaction.NN)
+
+
+ dataclass
+
+
+
+ Bases: AnalogComposite
Stack analog blocks vertically (i.e. in time).
+Needed because analog require
+stricter validation than the general KronBlock
.
AnalogKron
s can only be constructed from non-global, analog blocks
+with the same duration.
qadence/blocks/analog.py
ConstantAnalogRotation(tag=None, __array_priority__=1000, _eigenvalues_generator=None, parameters=ParamMap(alpha=0.0, duration=1000.0, omega=0.0, delta=0.0, phase=0.0), qubit_support=QubitSupport('global'), add_pattern=True)
+
+
+ dataclass
+
+
+
+ Bases: AnalogBlock
Implements a constant analog rotation with interaction dictated by the chosen Hamiltonian.
+H/h = ∑ᵢ(Ω/2 cos(φ)*Xᵢ - sin(φ)*Yᵢ - δnᵢ) + Hᵢₙₜ.
+
To construct this block you can use of the following convenience wrappers:
+- The general rotation operation AnalogRot
+- Shorthands for rotatins around an axis:
+ AnalogRX
,
+ AnalogRY
,
+ AnalogRZ
WARNING: do not use ConstantAnalogRotation
with alpha
as differentiable parameter - use
+the convenience wrappers mentioned above.
InteractionBlock(tag=None, __array_priority__=1000, _eigenvalues_generator=None, parameters=ParamMap(duration=1000.0), qubit_support=QubitSupport('global'), add_pattern=True)
+
+
+ dataclass
+
+
+
+ Bases: AnalogBlock
Free-evolution for the Hamiltonian interaction term of a register of qubits.
+In real interacting quantum devices, it means letting the system evolve freely according +to the time-dependent Schrodinger equation. With emulators, this block is translated to an +appropriate interaction Hamiltonian, for example, an Ising interaction
+Hᵢₙₜ = ∑ᵢⱼ C₆/rᵢⱼ⁶ nᵢnⱼ
+
or an XY-interaction
+Hᵢₙₜ = ∑ᵢⱼ C₃/rⱼⱼ³ (XᵢXⱼ + ZᵢZⱼ)
+
with nᵢ = (1-Zᵢ)/2
.
To construct, use the AnalogInteraction
function.
chain(*args)
+
+Chain blocks sequentially.
+On digital backends this can be interpreted +loosely as a matrix mutliplication of blocks. In the analog case it chains +blocks in time.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
*args |
+
+
+
+ Blocks to chain. Can also be a generator. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ChainBlock
+
+ |
+
+
+
+ ChainBlock + |
+
Example: +
from qadence import X, Y, chain
+
+b = chain(X(0), Y(0))
+
+# or use a generator
+b = chain(X(i) for i in range(3))
+print(b)
+
qadence/blocks/utils.py
kron(*args)
+
+Stack blocks vertically.
+On digital backends this can be intepreted +loosely as a kronecker product of blocks. In the analog case it executes +blocks parallel in time.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
*args |
+
+
+
+ Blocks to kron. Can also be a generator. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ KronBlock
+
+ |
+
+
+
+ KronBlock + |
+
Example: +
from qadence import X, Y, kron
+
+b = kron(X(0), Y(1))
+
+# or use a generator
+b = kron(X(i) for i in range(3))
+print(b)
+
qadence/blocks/utils.py
add(*args)
+
+Sums blocks.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
*args |
+
+
+
+ Blocks to add. Can also be a generator. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ AddBlock
+
+ |
+
+
+
+ AddBlock + |
+
Example: +
from qadence import X, Y, add
+
+b = add(X(0), Y(0))
+
+# or use a generator
+b = add(X(i) for i in range(3))
+print(b)
+
qadence/blocks/utils.py
AddBlock(blocks)
+
+
+ Bases: CompositeBlock
Adds blocks.
+Constructed via add
.
qadence/blocks/composite.py
ChainBlock(blocks)
+
+
+ Bases: CompositeBlock
Chains blocks sequentially.
+Constructed via chain
qadence/blocks/composite.py
CompositeBlock(tag=None, __array_priority__=1000)
+
+
+ dataclass
+
+
+
+ Bases: AbstractBlock
Block which composes multiple blocks into one larger block (which can again be composed).
+Composite blocks are constructed via chain
,
+kron
, and add
.
KronBlock(blocks)
+
+
+ Bases: CompositeBlock
Stacks blocks horizontally.
+Constructed via kron
.
qadence/blocks/composite.py
block_to_tensor(block, values={}, qubit_support=None, use_full_support=True, tensor_type=TensorType.DENSE, endianness=Endianness.BIG, device=None)
+
+Convert a block into a torch tensor.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
block |
+
+
+
+ The block to convert. +
+
+ TYPE:
+ |
+
values |
+
+
+
+ A optional dict with values for parameters. +
+
+ TYPE:
+ |
+
qubit_support |
+
+
+
+ The qubit_support of the block. +
+
+ TYPE:
+ |
+
use_full_support |
+
+
+
+ True infers the total number of qubits. +
+
+ TYPE:
+ |
+
tensor_type |
+
+
+
+ the target tensor type. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
from qadence import hea, hamiltonian_factory, Z, block_to_tensor
+
+block = hea(2,2)
+print(block_to_tensor(block))
+
+# In case you have a diagonal observable, you can use
+obs = hamiltonian_factory(2, detuning = Z)
+print(block_to_tensor(obs, tensor_type="SparseDiagonal"))
+
tensor([[[ 0.1487+0.1236j, -0.4120-0.7575j, -0.0646+0.3580j, -0.0484+0.2905j],
+ [ 0.3019-0.6510j, 0.1086+0.2301j, -0.4163+0.3769j, -0.1255+0.2987j],
+ [ 0.1675-0.5122j, -0.0530-0.3565j, 0.0846-0.0748j, 0.0711-0.7496j],
+ [-0.1421-0.3702j, -0.0690-0.2389j, -0.1030-0.7273j, 0.2478+0.4242j]]],
+ grad_fn=<UnsafeViewBackward0>)
+tensor(indices=tensor([[0, 3],
+ [0, 3]]),
+ values=tensor([ 2.+0.j, -2.+0.j]),
+ size=(4, 4), nnz=2, layout=torch.sparse_coo)
+
qadence/blocks/block_to_tensor.py
exp_fourier_feature_map(n_qubits, support=None, param='x', feature_range=None)
+
+Exponential fourier feature map.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ number of qubits in the feature +
+
+ TYPE:
+ |
+
support |
+
+
+
+ qubit support +
+
+ TYPE:
+ |
+
param |
+
+
+
+ name of feature
+
+ TYPE:
+ |
+
feature_range |
+
+
+
+ min and max value of the feature, as floats in a Tuple +
+
+ TYPE:
+ |
+
qadence/constructors/feature_maps.py
feature_map(n_qubits, support=None, param='phi', op=RX, fm_type=BasisSet.FOURIER, reupload_scaling=ReuploadScaling.CONSTANT, feature_range=None, target_range=None, multiplier=None, param_prefix=None)
+
+Construct a feature map of a given type.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ Number of qubits the feature map covers. Results in
+
+ TYPE:
+ |
+
support |
+
+
+
+ Puts one feature-encoding rotation gate on every qubit in
+
+ TYPE:
+ |
+
param |
+
+
+
+ Parameter of the feature map; you can pass a string or Parameter; +it will be set as non-trainable (FeatureParameter) regardless. +
+
+ TYPE:
+ |
+
op |
+
+
+
+ Rotation operation of the feature map; choose from RX, RY, RZ or PHASE. +
+
+ TYPE:
+ |
+
fm_type |
+
+
+
+ Basis set for data encoding; choose from
+
+ TYPE:
+ |
+
reupload_scaling |
+
+
+
+ how the feature map scales the data that is re-uploaded for each qubit.
+choose from
+
+ TYPE:
+ |
+
feature_range |
+
+
+
+ range of data that the input data provided comes from. Used to map input data +to the correct domain of the feature-encoding function. +
+
+ TYPE:
+ |
+
target_range |
+
+
+
+ range of data the data encoder assumes as the natural range. For example, +in Chebyshev polynomials it is (-1, 1), while for Fourier it may be chosen as (0, 2*PI). +Used to map data to the correct domain of the feature-encoding function. +
+
+ TYPE:
+ |
+
multiplier |
+
+
+
+ overall multiplier; this is useful for reuploading the feature map serially with +different scalings; can be a number or parameter/expression. +
+
+ TYPE:
+ |
+
param_prefix |
+
+
+
+ string prefix to create trainable parameters multiplying the feature parameter +inside the feature-encoding function. Note that currently this does not take into +account the domain of the feature-encoding function. +
+
+ TYPE:
+ |
+
Example: +
from qadence import feature_map, BasisSet, ReuploadScaling
+
+fm = feature_map(3, fm_type=BasisSet.FOURIER)
+print(f"{fm = }")
+
+fm = feature_map(3, fm_type=BasisSet.CHEBYSHEV)
+print(f"{fm = }")
+
+fm = feature_map(3, fm_type=BasisSet.FOURIER, reupload_scaling = ReuploadScaling.TOWER)
+print(f"{fm = }")
+
fm = KronBlock(0,1,2) [tag: Constant Fourier FM]
+├── RX(0) [params: ['phi']]
+├── RX(1) [params: ['phi']]
+└── RX(2) [params: ['phi']]
+fm = KronBlock(0,1,2) [tag: Constant Chebyshev FM]
+├── RX(0) [params: ['acos(phi)']]
+├── RX(1) [params: ['acos(phi)']]
+└── RX(2) [params: ['acos(phi)']]
+fm = KronBlock(0,1,2) [tag: Tower Fourier FM]
+├── RX(0) [params: ['1_0*phi']]
+├── RX(1) [params: ['2_0*phi']]
+└── RX(2) [params: ['3_0*phi']]
+
qadence/constructors/feature_maps.py
110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 |
|
hea(n_qubits, depth=1, param_prefix='theta', support=None, strategy=Strategy.DIGITAL, **strategy_args)
+
+Factory function for the Hardware Efficient Ansatz (HEA).
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ number of qubits in the block +
+
+ TYPE:
+ |
+
depth |
+
+
+
+ number of layers of the HEA +
+
+ TYPE:
+ |
+
param_prefix |
+
+
+
+ the base name of the variational parameters +
+
+ TYPE:
+ |
+
support |
+
+
+
+ qubit indexes where the HEA is applied +
+
+ TYPE:
+ |
+
strategy |
+
+
+
+
+ Strategy.Digital or Strategy.DigitalAnalog + |
+
**strategy_args |
+
+
+
+ see below +
+
+ TYPE:
+ |
+
PARAMETER | +DESCRIPTION | +
---|---|
operations |
+
+
+
+ list of operations to cycle through in the +digital single-qubit rotations of each layer. Valid for +Digital and DigitalAnalog HEA. +
+
+ TYPE:
+ |
+
periodic |
+
+
+
+ if the qubits should be linked periodically. +periodic=False is not supported in emu-c. Valid for only +for Digital HEA. +
+
+ TYPE:
+ |
+
entangler |
+
+
+
+
+
+ TYPE:
+ |
+
Examples: +
from qadence import RZ, RX
+from qadence import hea
+
+# create the circuit
+n_qubits, depth = 2, 4
+ansatz = hea(
+ n_qubits=n_qubits,
+ depth=depth,
+ strategy="sDAQC",
+ operations=[RZ,RX,RZ]
+)
+
qadence/constructors/ansatze.py
hea_digital(n_qubits, depth=1, param_prefix='theta', periodic=False, operations=[RX, RY, RX], support=None, entangler=CNOT)
+
+Construct the Digital Hardware Efficient Ansatz (HEA).
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ number of qubits in the block. +
+
+ TYPE:
+ |
+
depth |
+
+
+
+ number of layers of the HEA. +
+
+ TYPE:
+ |
+
param_prefix |
+
+
+
+ the base name of the variational parameters +
+
+ TYPE:
+ |
+
periodic |
+
+
+
+ if the qubits should be linked periodically. +periodic=False is not supported in emu-c. +
+
+ TYPE:
+ |
+
operations |
+
+
+
+
+ list of operations to cycle through in the +digital single-qubit rotations of each layer. + |
+
support |
+
+
+
+ qubit indexes where the HEA is applied. +
+
+ TYPE:
+ |
+
entangler |
+
+
+
+ 2-qubit entangling operation. +Supports CNOT, CZ, CRX, CRY, CRZ. Controlld rotations +will have variational parameters on the rotation angles. +
+
+ TYPE:
+ |
+
qadence/constructors/ansatze.py
hea_sDAQC(n_qubits, depth=1, param_prefix='theta', operations=[RX, RY, RX], support=None, entangler=None)
+
+Construct the Hardware Efficient Ansatz (HEA) with analog entangling layers.
+It uses step-wise digital-analog computation.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ number of qubits in the block. +
+
+ TYPE:
+ |
+
depth |
+
+
+
+ number of layers of the HEA. +
+
+ TYPE:
+ |
+
param_prefix |
+
+
+
+ the base name of the variational parameters +
+
+ TYPE:
+ |
+
operations |
+
+
+
+
+ list of operations to cycle through in the +digital single-qubit rotations of each layer. + |
+
support |
+
+
+
+ qubit indexes where the HEA is applied. +
+
+ TYPE:
+ |
+
entangler |
+
+
+
+ Hamiltonian generator for the +analog entangling layer. Defaults to global ZZ Hamiltonian. +Time parameter is considered variational. +
+
+ TYPE:
+ |
+
qadence/constructors/ansatze.py
hamiltonian_factory(register, interaction=None, detuning=None, interaction_strength=None, detuning_strength=None, random_strength=False, use_all_node_pairs=False)
+
+General Hamiltonian creation function.
+Can be used to create Hamiltonians with 2-qubit +interactions and single-qubit detunings, both with arbitrary strength or parameterized.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
register |
+
+
+
+ register of qubits with a specific graph topology, or number of qubits. +When passing a number of qubits a register with all-to-all connectivity +is created. +
+
+ TYPE:
+ |
+
interaction |
+
+
+
+ Interaction.ZZ, Interaction.NN, Interaction.XY, or Interacton.XYZ. +
+
+ TYPE:
+ |
+
detuning |
+
+
+
+ single-qubit operator N, X, Y, or Z. +
+
+ TYPE:
+ |
+
interaction_strength |
+
+
+
+ list of values to be used as the interaction strength for each
+pair of qubits. Should be ordered following the order of
+
+ TYPE:
+ |
+
detuning_strength |
+
+
+
+ list of values to be used as the detuning strength for each qubit.
+Alternatively, some string "x" can be passed, which will create a parameterized
+detuning for each qubit, each labelled as
+
+ TYPE:
+ |
+
random_strength |
+
+
+
+ set random interaction and detuning strengths between -1 and 1. +
+
+ TYPE:
+ |
+
use_all_node_pairs |
+
+
+
+ computes an interaction term for every pair of nodes in the graph, +independent of the edge topology in the register. Useful for defining Hamiltonians +where the interaction strength decays with the distance. +
+
+ TYPE:
+ |
+
Examples:
+from qadence import hamiltonian_factory, Interaction, Register, Z
+
+n_qubits = 3
+
+# Constant total magnetization observable:
+observable = hamiltonian_factory(n_qubits, detuning = Z)
+
+# Parameterized total magnetization observable:
+observable = hamiltonian_factory(n_qubits, detuning = Z, detuning_strength = "z")
+
+# Random all-to-all XY Hamiltonian generator:
+generator = hamiltonian_factory(
+ n_qubits,
+ interaction = Interaction.XY,
+ random_strength = True,
+ )
+
+# Parameterized NN Hamiltonian generator with a square grid interaction topology:
+register = Register.square(qubits_side = n_qubits)
+generator = hamiltonian_factory(
+ register,
+ interaction = Interaction.NN,
+ interaction_strength = "theta"
+ )
+
qadence/constructors/hamiltonians.py
52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 |
|
interaction_nn(i, j)
+
+interaction_xy(i, j)
+
+interaction_xyz(i, j)
+
+qft(n_qubits, support=None, inverse=False, reverse_in=False, swaps_out=False, strategy=Strategy.DIGITAL, gen_build=None)
+
+The Quantum Fourier Transform.
+Depending on the application, user should be careful with qubit ordering +in the input and output. This can be controlled with reverse_in and swaps_out +arguments.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ number of qubits in the QFT +
+
+ TYPE:
+ |
+
support |
+
+
+
+ qubit support to use +
+
+ TYPE:
+ |
+
inverse |
+
+
+
+ True performs the inverse QFT +
+
+ TYPE:
+ |
+
reverse_in |
+
+
+
+ Reverses the input qubits to account for endianness +
+
+ TYPE:
+ |
+
swaps_out |
+
+
+
+ Performs swaps on the output qubits to match the "textbook" QFT. +
+
+ TYPE:
+ |
+
strategy |
+
+
+
+
+ Strategy.Digital or Strategy.sDAQC + |
+
gen_build |
+
+
+
+ building block Ising Hamiltonian for the DAQC transform. +Defaults to constant all-to-all Ising. +
+
+ TYPE:
+ |
+
Examples:
+ + + +qadence/constructors/qft.py
rydberg_hea(register, n_layers=1, addressable_detuning=True, addressable_drive=False, tunable_phase=False, additional_prefix=None)
+
+Hardware efficient ansatz for neutral atom (Rydberg) platforms.
+This constructor implements a variational ansatz which is very close to +what is implementable on 2nd generation PASQAL quantum devices. In particular, +it implements evolution over a specific Hamiltonian which can be realized on +the device. This Hamiltonian contains:
+an interaction term given by the standard NN interaction and determined starting + from the positions in the input register: Hᵢₙₜ = ∑ᵢⱼ C₆/rᵢⱼ⁶ nᵢnⱼ
+a detuning term which corresponding to a n_i = (1+sigma_i^z)/2 applied to
+ all the qubits. If the addressable_detuning
flag is set to True, the routine
+ effectively a local n_i = (1+sigma_i^z)/2 term in the
+ evolved Hamiltonian with a different coefficient for each atom. These
+ coefficients determine a local addressing pattern for the detuning on a subset
+ of the qubits. In this routine, the coefficients are variational parameters
+ and they will therefore be optimized at each optimizer step
a drive term which corresponding to a sigma^x evolution operation applied to
+ all the qubits. If the addressable_drive
flag is set to True, the routine
+ effectively a local sigma_i^x term in the evolved Hamiltonian with a different
+ coefficient for each atom. These coefficients determine a local addressing pattern
+ for the drive on a subset of the qubits. In this routine, the coefficients are
+ variational parameters and they will therefore be optimized at each optimizer step
if the tunable_phase
flag is set to True, the drive term is modified in the following
+ way: drive = cos(phi) * sigma^x - sin(phi) * sigma^y
+ The addressable pattern above is maintained and the phase is considered just as an
+ additional variational parameter which is optimized with the rest
Notice that, on real devices, the coefficients assigned to each qubit in both the detuning +and drive patterns should be non-negative and they should always sum to 1. This is not the +case for the implementation in this routine since the coefficients (weights) do not have any +constraint. Therefore, this HEA is not completely realizable on neutral atom devices.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
register |
+
+
+
+ the input atomic register with Cartesian coordinates. +
+
+ TYPE:
+ |
+
n_layers |
+
+
+
+ number layers in the HEA, each layer includes a drive, detuning and +pure interaction pulses whose is a variational parameter +
+
+ TYPE:
+ |
+
addressable_detuning |
+
+
+
+ whether to turn on the trainable semi-local addressing pattern +on the detuning (n_i terms in the Hamiltonian) +
+
+ TYPE:
+ |
+
addressable_drive |
+
+
+
+ whether to turn on the trainable semi-local addressing pattern +on the drive (sigma_i^x terms in the Hamiltonian) +
+
+ TYPE:
+ |
+
tunable_phase |
+
+
+
+ whether to have a tunable phase to get both sigma^x and sigma^y rotations +in the drive term. If False, only a sigma^x term will be included in the drive part +of the Hamiltonian generator +
+
+ TYPE:
+ |
+
additional_prefix |
+
+
+
+ an additional prefix to attach to the parameter names +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ChainBlock
+
+ |
+
+
+
+ The Rydberg HEA block + |
+
qadence/constructors/rydberg_hea.py
104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 |
|
rydberg_hea_layer(register, tevo_drive, tevo_det, tevo_wait, phase=None, detunings=None, drives=None, drive_scaling=1.0)
+
+A single layer of the Rydberg hardware efficient ansatz.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
register |
+
+
+
+ the input register with atomic coordinates needed to build the interaction. +
+
+ TYPE:
+ |
+
tevo_drive |
+
+
+
+ a variational parameter for the duration of the drive term of +the Hamiltonian generator, including optional semi-local addressing +
+
+ TYPE:
+ |
+
tevo_det |
+
+
+
+ a variational parameter for the duration of the detuning term of the +Hamiltonian generator, including optional semi-local addressing +
+
+ TYPE:
+ |
+
tevo_wait |
+
+
+
+ a variational parameter for the duration of the waiting +time with interaction only +
+
+ TYPE:
+ |
+
phase |
+
+
+
+ a variational parameter representing the global phase. If None, the +global phase is set to 0 which results in a drive term in sigma^x only. Otherwise +both sigma^x and sigma^y terms will be present +
+
+ TYPE:
+ |
+
detunings |
+
+
+
+ a list of parameters with the weights of the locally addressed +detuning terms. These are variational parameters which are tuned by the optimizer +
+
+ TYPE:
+ |
+
drives |
+
+
+
+ a list of parameters with the weights of the locally addressed +drive terms. These are variational parameters which are tuned by the optimizer +
+
+ TYPE:
+ |
+
drive_scaling |
+
+
+
+ a scaling term to be added to the drive Hamiltonian generator +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ChainBlock
+
+ |
+
+
+
+ A block with a single layer of Rydberg HEA + |
+
qadence/constructors/rydberg_hea.py
daqc_transform(n_qubits, gen_target, t_f, gen_build=None, zero_tol=1e-08, strategy=Strategy.SDAQC, ignore_global_phases=False)
+
+Implements the DAQC transform for representing an arbitrary 2-body Hamiltonian.
+The result is another fixed 2-body Hamiltonian.
+Reference for universality of 2-body Hamiltonians:
+-- https://arxiv.org/abs/quant-ph/0106064
+Based on the transformation for Ising (ZZ) interactions, as described in the paper
+-- https://arxiv.org/abs/1812.03637
+The transform translates a target weighted generator of the type:
+`gen_target = add(g_jk * kron(op(j), op(k)) for j < k)`
+
To a circuit using analog evolutions with a fixed building block generator:
+`gen_build = add(f_jk * kron(op(j), op(k)) for j < k)`
+
where op = Z
or op = N
.
PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ total number of qubits to use. +
+
+ TYPE:
+ |
+
gen_target |
+
+
+
+ target generator built with the structure above. The type +of the generator will be automatically evaluated when parsing. +
+
+ TYPE:
+ |
+
t_f |
+
+
+
+ total time for the gen_target evolution. +
+
+ TYPE:
+ |
+
gen_build |
+
+
+
+ fixed generator to act as a building block. Defaults to +constant NN: add(1.0 * kron(N(j), N(k)) for j < k). The type +of the generator will be automatically evaluated when parsing. +
+
+ TYPE:
+ |
+
zero_tol |
+
+
+
+ default "zero" for a missing interaction. Included for +numerical reasons, see notes below. +
+
+ TYPE:
+ |
+
strategy |
+
+
+
+
+ sDAQC or bDAQC, following definitions in the reference paper. + |
+
ignore_global_phases |
+
+
+
+ if
+
+ TYPE:
+ |
+
Notes:
+The paper follows an index convention of running from 1 to N. A few functions
+here also use that convention to be consistent with the paper. However, for qadence
+related things the indices are converted to [0, N-1].
+
+The case for `n_qubits = 4` is an edge case where the sign matrix is not invertible.
+There is a workaround for this described in the paper, but it is currently not implemented.
+
+The current implementation may result in evolution times that are both positive or
+negative. In practice, both can be represented by simply changing the signs of the
+interactions. However, for a real implementation where the interactions should remain
+fixed, the paper discusses a workaround that is not currently implemented.
+
+The transformation works by representing each interaction in the target hamiltonian by
+a set of evolutions using the build hamiltonian. As a consequence, some care must be
+taken when choosing the build hamiltonian. Some cases:
+
+- The target hamiltonian can have any interaction, as long as it is sufficiently
+represented in the build hamiltonian. E.g., if the interaction `g_01 * kron(Z(0), Z(1))`
+is in the target hamiltonian, the corresponding interaction `f_01 * kron(Z(0), Z(1))`
+needs to be in the build hamiltonian. This is checked when the generators are parsed.
+
+- The build hamiltonian can have any interaction, irrespectively of it being needed
+for the target hamiltonian. This is especially useful for designing local operations
+through the repeated evolution of a "global" hamiltonian.
+
+- The parameter `zero_tol` controls what it means for an interaction to be "missing".
+Any interaction strength smaller than `zero_tol` in the build hamiltonian will not be
+considered, and thus that interaction is missing.
+
+- The various ratios `g_jk / f_jk` will influence the time parameter for the various
+evolution slices, meaning that if there is a big discrepancy in the interaction strength
+for a given qubit pair (j, k), the output circuit may require the usage of hamiltonian
+evolutions with very large times.
+
+- A warning will be issued for evolution times larger than `1/sqrt(zero_tol)`. Evolution
+times smaller than `zero_tol` will not be represented.
+
Examples:
+from qadence import Z, N, daqc_transform
+
+n_qubits = 3
+
+gen_build = 0.5 * (N(0)@N(1)) + 0.7 * (N(1)@N(2)) + 0.2 * (N(0)@N(2))
+
+gen_target = 0.1 * (Z(1)@Z(2))
+
+t_f = 2.0
+
+transformed_circuit = daqc_transform(
+ n_qubits = n_qubits,
+ gen_target = gen_target,
+ t_f = t_f,
+ gen_build = gen_build,
+)
+
qadence/constructors/daqc/daqc.py
19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 |
|
build_idx_fms(basis, fm_pauli, fm_strategy, n_features, n_qubits, spectrum)
+
+Builds the index feature maps based on the given parameters.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
basis |
+
+
+
+ Type of basis chosen for the feature map. +
+
+ TYPE:
+ |
+
fm_pauli |
+
+
+
+ The chosen Pauli rotation type. +
+
+ TYPE:
+ |
+
fm_strategy |
+
+
+
+ The feature map strategy to be used. Possible values are +'parallel' or 'serial'. +
+
+ TYPE:
+ |
+
n_features |
+
+
+
+ The number of features. +
+
+ TYPE:
+ |
+
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
spectrum |
+
+
+
+ The chosen spectrum. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ list[KronBlock]
+
+ |
+
+
+
+ List[KronBlock]: The list of index feature maps. + |
+
qadence/constructors/utils.py
generator_prefactor(spectrum, qubit_index)
+
+Converts a spectrum string, e.g. tower or exponential.
+The result is the correct generator prefactor.
+ +qadence/constructors/utils.py
get_fm_qubits(fm_strategy, i, n_qubits, n_features)
+
+Returns the list of target qubits for the given feature map strategy and feature index.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
fm_strategy |
+
+
+
+ The feature map strategy to be used. Possible values +are 'parallel' or 'serial'. +
+
+ TYPE:
+ |
+
i |
+
+
+
+ The feature index. +
+
+ TYPE:
+ |
+
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
n_features |
+
+
+
+ The number of features. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Iterable
+
+ |
+
+
+
+ List[int]: The list of target qubits. + |
+
RAISES | +DESCRIPTION | +
---|---|
+
+ ValueError
+
+ |
+
+
+
+ If the feature map strategy is not implemented. + |
+
qadence/constructors/utils.py
display(x, qcd=None, layout='LR', theme='light', fill=True, **kwargs)
+
+Display a block, circuit, or quantum model.
+The kwargs
are forwarded to
+the underlying nx.Graph
, so you can e.g. specify the size of the resulting plot via
+size="2,2"
(see examples)
PARAMETER | +DESCRIPTION | +
---|---|
x |
+
+
+
+
+
+ TYPE:
+ |
+
qcd |
+
+
+
+ Circuit diagram to plot the block into. +
+
+ TYPE:
+ |
+
layout |
+
+
+
+ Can be either "LR" (left-right), or "TB" (top-bottom). +
+
+ TYPE:
+ |
+
theme |
+
+
+
+ Available themes are: ["light", "dark", "black", "white"]. +
+
+ TYPE:
+ |
+
fill |
+
+
+
+ Whether to fill the passed
+
+ TYPE:
+ |
+
kwargs |
+
+
+
+ Passed on to
+
+ TYPE:
+ |
+
Examples: +
from qadence import X, Y, kron
+from qadence.draw import display
+
+b = kron(X(0), Y(1))
+display(b, size="1,1", theme="dark")
+
qadence/draw/__init__.py
savefig(x, filename, *args, **kwargs)
+
+Save a block, circuit, or quantum model to file. Accepts the same args/kwargs as display
.
PARAMETER | +DESCRIPTION | +
---|---|
x |
+
+
+
+
+
+ TYPE:
+ |
+
filename |
+
+
+
+ Should end in svg/png. +
+
+ TYPE:
+ |
+
args |
+
+
+
+ Same as in
+
+ TYPE:
+ |
+
kwargs |
+
+
+
+ Same as in
+
+ TYPE:
+ |
+
Examples: +
from qadence import X, Y, kron
+from qadence.draw import display
+
+b = kron(X(0), Y(1))
+savefig(b, "test.svg", size="1,1", theme="dark")
+
qadence/draw/__init__.py
expectation(x, observable, values={}, state=None, backend=BackendName.PYQTORCH, diff_mode=None, noise=None, endianness=Endianness.BIG, configuration=None)
+
+Convenience wrapper for the QuantumModel.expectation
method.
PARAMETER | +DESCRIPTION | +
---|---|
x |
+
+
+
+ Circuit, block, or (register+block) to run. +
+
+ TYPE:
+ |
+
observable |
+
+
+
+ Observable(s) w.r.t. which the expectation is computed. +
+
+ TYPE:
+ |
+
values |
+
+
+
+ User-facing parameter dict. +
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
backend |
+
+
+
+ Name of the backend to run on. +
+
+ TYPE:
+ |
+
diff_mode |
+
+
+
+ Which differentiation mode to use. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ The target device endianness. +
+
+ TYPE:
+ |
+
configuration |
+
+
+
+ The backend configuration. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A wavefunction + |
+
from qadence import RX, Z, Register, QuantumCircuit, expectation
+
+reg = Register(1)
+block = RX(0, 0.5)
+observable = Z(0)
+circ = QuantumCircuit(reg, block)
+
+# You can compute the expectation for a
+# QuantumCircuit with a given observable.
+expectation(circ, observable)
+
+# You can also use only a block.
+# In this case the register is constructed automatically to
+# Register.line(block.n_qubits)
+expectation(block, observable)
+
+# Or a register and block
+expectation(reg, block, observable)
+
qadence/execution.py
run(x, *args, values={}, state=None, backend=BackendName.PYQTORCH, endianness=Endianness.BIG, configuration=None)
+
+Convenience wrapper for the QuantumModel.run
method.
This is a
+functools.singledispatch
ed function so it can be called with a number of different arguments.
+See the examples of the expectation
function. This function
+works exactly the same.
PARAMETER | +DESCRIPTION | +
---|---|
x |
+
+
+
+ Circuit, block, or (register+block) to run. +
+
+ TYPE:
+ |
+
values |
+
+
+
+ User-facing parameter dict. +
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
backend |
+
+
+
+ Name of the backend to run on. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ The target device endianness. +
+
+ TYPE:
+ |
+
configuration |
+
+
+
+ The backend configuration. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A wavefunction + |
+
qadence/execution.py
sample(x, *args, values={}, state=None, n_shots=100, backend=BackendName.PYQTORCH, endianness=Endianness.BIG, noise=None, configuration=None)
+
+Convenience wrapper for the QuantumModel.sample
method.
PARAMETER | +DESCRIPTION | +
---|---|
x |
+
+
+
+ Circuit, block, or (register+block) to run. +
+
+ TYPE:
+ |
+
values |
+
+
+
+ User-facing parameter dict. +
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
n_shots |
+
+
+
+ Number of shots per element in the batch. +
+
+ TYPE:
+ |
+
backend |
+
+
+
+ Name of the backend to run on. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ The target device endianness. +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ The noise model to use if any. +
+
+ TYPE:
+ |
+
configuration |
+
+
+
+ The backend configuration. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ list[Counter]
+
+ |
+
+
+
+ A list of Counter instances with the sample results + |
+
qadence/execution.py
This module implements gradient-free and gradient-based training loops for torch Modules and QuantumModel.
+ + +TrainConfig(max_iter=10000, print_every=1000, write_every=50, checkpoint_every=5000, folder=None, create_subfolder_per_run=False, checkpoint_best_only=False, val_every=None, val_epsilon=1e-05, validation_criterion=None, trainstop_criterion=None, batch_size=1, verbose=True)
+
+
+ dataclass
+
+
+Default config for the train function.
+The default value of +each field can be customized with the constructor:
+ +TrainConfig(max_iter=10000, print_every=1000, write_every=50, checkpoint_every=5000, folder=PosixPath('/tmp/train'), create_subfolder_per_run=False, checkpoint_best_only=False, val_every=None, val_epsilon=1e-05, validation_criterion=<function TrainConfig.__post_init__.<locals>.<lambda> at 0x7ff7bc57a8c0>, trainstop_criterion=<function TrainConfig.__post_init__.<locals>.<lambda> at 0x7ff7bc578f70>, batch_size=1, verbose=True)
+
batch_size: int = 1
+
+
+ class-attribute
+ instance-attribute
+
+
+The batch_size to use when passing a list/tuple of torch.Tensors.
+checkpoint_best_only: bool = False
+
+
+ class-attribute
+ instance-attribute
+
+
+Write model/optimizer checkpoint only if a metric has improved.
+checkpoint_every: int = 5000
+
+
+ class-attribute
+ instance-attribute
+
+
+Write model/optimizer checkpoint.
+create_subfolder_per_run: bool = False
+
+
+ class-attribute
+ instance-attribute
+
+
+Checkpoint/tensorboard logs stored in subfolder with name <timestamp>_<PID>
.
Prevents continuing from previous checkpoint, useful for fast prototyping.
+folder: Optional[Path] = None
+
+
+ class-attribute
+ instance-attribute
+
+
+Checkpoint/tensorboard logs folder.
+max_iter: int = 10000
+
+
+ class-attribute
+ instance-attribute
+
+
+Number of training iterations.
+print_every: int = 1000
+
+
+ class-attribute
+ instance-attribute
+
+
+Print loss/metrics.
+trainstop_criterion: Optional[Callable] = None
+
+
+ class-attribute
+ instance-attribute
+
+
+A boolean function which evaluates a given training stopping metric is satisfied.
+val_epsilon: float = 1e-05
+
+
+ class-attribute
+ instance-attribute
+
+
+Safety margin to check if validation loss is smaller than the lowest.
+validation loss across previous iterations.
+val_every: int | None = None
+
+
+ class-attribute
+ instance-attribute
+
+
+Calculate validation metric.
+If None, validation check is not performed.
+validation_criterion: Optional[Callable] = None
+
+
+ class-attribute
+ instance-attribute
+
+
+A boolean function which evaluates a given validation metric is satisfied.
+verbose: bool = True
+
+
+ class-attribute
+ instance-attribute
+
+
+Whether or not to print out metrics values during training.
+write_every: int = 50
+
+
+ class-attribute
+ instance-attribute
+
+
+Write tensorboard logs.
+get_parameters(model)
+
+Retrieve all trainable model parameters in a single vector.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
model |
+
+
+
+ the input PyTorch model +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+ Tensor
+ |
+
+
+
+ a 1-dimensional tensor with the parameters +
+
+ TYPE:
+ |
+
qadence/ml_tools/parameters.py
num_parameters(model)
+
+set_parameters(model, theta)
+
+Set all trainable parameters of a model from a single vector.
+Notice that this function assumes prior knowledge of right number +of parameters in the model
+ + +PARAMETER | +DESCRIPTION | +
---|---|
model |
+
+
+
+ the input PyTorch model +
+
+ TYPE:
+ |
+
theta |
+
+
+
+ the parameters to assign +
+
+ TYPE:
+ |
+
qadence/ml_tools/parameters.py
optimize_step(model, optimizer, loss_fn, xs, device=None, dtype=None)
+
+Default Torch optimize step with closure.
+This is the default optimization step which should work for most +of the standard use cases of optimization of Torch models
+ + +PARAMETER | +DESCRIPTION | +
---|---|
model |
+
+
+
+ The input model +
+
+ TYPE:
+ |
+
optimizer |
+
+
+
+ The chosen Torch optimizer +
+
+ TYPE:
+ |
+
loss_fn |
+
+
+
+ A custom loss function +
+
+ TYPE:
+ |
+
xs |
+
+
+
+ the input data. If None it means +that the given model does not require any input data +
+
+ TYPE:
+ |
+
device |
+
+
+
+ A target device to run computation on. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+ tuple
+ |
+
+
+
+ tuple containing the model, the optimizer, a dictionary with +the collected metrics and the compute value loss +
+
+ TYPE:
+ |
+
qadence/ml_tools/optimize_step.py
train(model, dataloader, optimizer, config, loss_fn, device=None, optimize_step=optimize_step, write_tensorboard=write_tensorboard, dtype=None)
+
+Runs the training loop with gradient-based optimizer.
+Assumes that loss_fn
returns a tuple of (loss,
+metrics: dict), where metrics
is a dict of scalars. Loss and metrics are
+written to tensorboard. Checkpoints are written every
+config.checkpoint_every
steps (and after the last training step). If a
+checkpoint is found at config.folder
we resume training from there. The
+tensorboard logs can be viewed via tensorboard --logdir /path/to/folder
.
PARAMETER | +DESCRIPTION | +
---|---|
model |
+
+
+
+ The model to train. +
+
+ TYPE:
+ |
+
dataloader |
+
+
+
+ dataloader of different types. If None, no data is required by +the model +
+
+ TYPE:
+ |
+
optimizer |
+
+
+
+ The optimizer to use. +
+
+ TYPE:
+ |
+
config |
+
+
+
+
+
+ TYPE:
+ |
+
loss_fn |
+
+
+
+ Loss function returning (loss: float, metrics: dict[str, float]) +
+
+ TYPE:
+ |
+
device |
+
+
+
+ String defining device to train on, pass 'cuda' for GPU. +
+
+ TYPE:
+ |
+
optimize_step |
+
+
+
+ Customizable optimization callback which is called at every iteration.=
+The function must have the signature
+
+ TYPE:
+ |
+
write_tensorboard |
+
+
+
+ Customizable tensorboard logging callback which is
+called every
+
+ TYPE:
+ |
+
Example: +
from pathlib import Path
+import torch
+from itertools import count
+from qadence import Parameter, QuantumCircuit, Z
+from qadence import hamiltonian_factory, hea, feature_map, chain
+from qadence.models import QNN
+from qadence.ml_tools import TrainConfig, train_with_grad, to_dataloader
+
+n_qubits = 2
+fm = feature_map(n_qubits)
+ansatz = hea(n_qubits=n_qubits, depth=3)
+observable = hamiltonian_factory(n_qubits, detuning = Z)
+circuit = QuantumCircuit(n_qubits, fm, ansatz)
+
+model = QNN(circuit, observable, backend="pyqtorch", diff_mode="ad")
+batch_size = 1
+input_values = {"phi": torch.rand(batch_size, requires_grad=True)}
+pred = model(input_values)
+
+## lets prepare the train routine
+
+cnt = count()
+criterion = torch.nn.MSELoss()
+optimizer = torch.optim.Adam(model.parameters(), lr=0.1)
+
+def loss_fn(model: torch.nn.Module, data: torch.Tensor) -> tuple[torch.Tensor, dict]:
+ next(cnt)
+ x, y = data[0], data[1]
+ out = model(x)
+ loss = criterion(out, y)
+ return loss, {}
+
+tmp_path = Path("/tmp")
+n_epochs = 5
+batch_size = 25
+config = TrainConfig(
+ folder=tmp_path,
+ max_iter=n_epochs,
+ checkpoint_every=100,
+ write_every=100,
+)
+x = torch.linspace(0, 1, batch_size).reshape(-1, 1)
+y = torch.sin(x)
+data = to_dataloader(x, y, batch_size=batch_size, infinite=True)
+train_with_grad(model, data, optimizer, config, loss_fn=loss_fn)
+
qadence/ml_tools/train_grad.py
25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 |
|
train(model, dataloader, optimizer, config, loss_fn)
+
+Runs the training loop with a gradient-free optimizer.
+Assumes that loss_fn
returns a tuple of (loss, metrics: dict), where
+metrics
is a dict of scalars. Loss and metrics are written to
+tensorboard. Checkpoints are written every config.checkpoint_every
steps
+(and after the last training step). If a checkpoint is found at config.folder
+we resume training from there. The tensorboard logs can be viewed via
+tensorboard --logdir /path/to/folder
.
PARAMETER | +DESCRIPTION | +
---|---|
model |
+
+
+
+ The model to train +
+
+ TYPE:
+ |
+
dataloader |
+
+
+
+ Dataloader constructed via
+
+ TYPE:
+ |
+
optimizer |
+
+
+
+ The optimizer to use taken from the Nevergrad library. If this is not +the case the function will raise an AssertionError +
+
+ TYPE:
+ |
+
loss_fn |
+
+
+
+ Loss function returning (loss: float, metrics: dict[str, float]) +
+
+ TYPE:
+ |
+
qadence/ml_tools/train_no_grad.py
24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 |
|
DictDataLoader(dataloaders)
+
+
+ dataclass
+
+
+This class only holds a dictionary of DataLoader
s and samples from them.
InfiniteTensorDataset(*tensors)
+
+
+ Bases: IterableDataset
Randomly sample points from the first dimension of the given tensors.
+Behaves like a normal torch Dataset
just that we can sample from it as
+many times as we want.
Examples: +
import torch
+from qadence.ml_tools.data import InfiniteTensorDataset
+
+x_data, y_data = torch.rand(5,2), torch.ones(5,1)
+# The dataset accepts any number of tensors with the same batch dimension
+ds = InfiniteTensorDataset(x_data, y_data)
+
+# call `next` to get one sample from each tensor:
+xs = next(iter(ds))
+
qadence/ml_tools/data.py
data_to_device(xs, *args, **kwargs)
+
+Utility method to move arbitrary data to 'device'.
+ + +to_dataloader(*tensors, batch_size=1, infinite=False)
+
+Convert torch tensors an (infinite) Dataloader.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
*tensors |
+
+
+
+ Torch tensors to use in the dataloader. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ batch size of sampled tensors +
+
+ TYPE:
+ |
+
infinite |
+
+
+
+ if
+
+ TYPE:
+ |
+
Examples:
+import torch
+from qadence.ml_tools import to_dataloader
+
+(x, y, z) = [torch.rand(10) for _ in range(3)]
+loader = iter(to_dataloader(x, y, z, batch_size=5, infinite=True))
+print(next(loader))
+print(next(loader))
+print(next(loader))
+
[tensor([0.8141, 0.2472, 0.1905, 0.9859, 0.3615]), tensor([0.2275, 0.6321, 0.1678, 0.3225, 0.4860]), tensor([0.9558, 0.8472, 0.9771, 0.1041, 0.0494])]
+[tensor([0.9518, 0.3813, 0.4100, 0.3718, 0.2732]), tensor([0.6272, 0.6748, 0.3437, 0.9004, 0.7706]), tensor([0.2962, 0.4654, 0.4198, 0.5610, 0.3932])]
+[tensor([0.8141, 0.2472, 0.1905, 0.9859, 0.3615]), tensor([0.2275, 0.6321, 0.1678, 0.3225, 0.4860]), tensor([0.9558, 0.8472, 0.9771, 0.1041, 0.0494])]
+
qadence/ml_tools/data.py
QuantumModel(circuit, observable=None, backend=BackendName.PYQTORCH, diff_mode=DiffMode.AD, measurement=None, noise=None, mitigation=None, configuration=None)
+
+
+ Bases: Module
The central class of qadence that executes QuantumCircuit
s and make them differentiable.
This class should be used as base class for any new quantum model supported in the qadence +framework for information on the implementation of custom models see +here.
+ +Initialize a generic QuantumModel instance.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ The circuit that is executed. +
+
+ TYPE:
+ |
+
observable |
+
+
+
+ Optional observable(s) that are used only in the
+
+ TYPE:
+ |
+
backend |
+
+
+
+ A backend for circuit execution. +
+
+ TYPE:
+ |
+
diff_mode |
+
+
+
+ A differentiability mode. Parameter shift based modes work on all backends. +AD based modes only on PyTorch based backends. +
+
+ TYPE:
+ |
+
measurement |
+
+
+
+ Optional measurement protocol. If None, use +exact expectation value with a statevector simulator. +
+
+ TYPE:
+ |
+
configuration |
+
+
+
+ Configuration for the backend. +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ A noise model to use. +
+
+ TYPE:
+ |
+
RAISES | +DESCRIPTION | +
---|---|
+
+ ValueError
+
+ |
+
+
+
+ if the |
+
qadence/models/quantum_model.py
49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 |
|
in_features: int
+
+
+ property
+
+
+Number of inputs.
+num_vparams: int
+
+
+ property
+
+
+The number of variational parameters.
+out_features: int | None
+
+
+ property
+
+
+Number of outputs.
+vals_vparams: Tensor
+
+
+ property
+
+
+Dictionary with parameters which are actually updated during optimization.
+assign_parameters(values)
+
+Return the final, assigned circuit that is used in e.g. backend.run
.
qadence/models/quantum_model.py
expectation(values={}, observable=None, state=None, measurement=None, noise=None, mitigation=None, endianness=Endianness.BIG)
+
+Compute expectation using the given backend.
+ + +RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor of shape n_batches x n_obs + |
+
qadence/models/quantum_model.py
reset_vparams(values)
+
+Reset all the variational parameters with a given list of values.
+ +qadence/models/quantum_model.py
QNN(circuit, observable, transform=None, backend=BackendName.PYQTORCH, diff_mode=DiffMode.AD, measurement=None, noise=None, configuration=None, inputs=None)
+
+
+ Bases: QuantumModel
Quantum neural network model for n-dimensional inputs.
+Examples: +
import torch
+from qadence import QuantumCircuit, QNN, Z
+from qadence import hea, feature_map, hamiltonian_factory, kron
+
+# create the circuit
+n_qubits, depth = 2, 4
+fm = kron(
+ feature_map(1, support=(0,), param="x"),
+ feature_map(1, support=(1,), param="y")
+)
+ansatz = hea(n_qubits=n_qubits, depth=depth)
+circuit = QuantumCircuit(n_qubits, fm, ansatz)
+obs_base = hamiltonian_factory(n_qubits, detuning=Z)
+
+# the QNN will yield two outputs
+obs = [2.0 * obs_base, 4.0 * obs_base]
+
+# initialize and use the model
+qnn = QNN(circuit, obs, inputs=["x", "y"])
+y = qnn(torch.rand(3, 2))
+
Initialize the QNN.
+The number of inputs is determined by the feature parameters in the input +quantum circuit while the number of outputs is determined by how many +observables are provided as input
+ + +PARAMETER | +DESCRIPTION | +
---|---|
circuit |
+
+
+
+ The quantum circuit to use for the QNN. +
+
+ TYPE:
+ |
+
transform |
+
+
+
+ A transformation applied to the output of the QNN. +
+
+ TYPE:
+ |
+
inputs |
+
+
+
+ Tuple that indicates the order of variables of the tensors that are passed
+to the model. Given input tensors
+
+ TYPE:
+ |
+
backend |
+
+
+
+ The chosen quantum backend. +
+
+ TYPE:
+ |
+
diff_mode |
+
+
+
+ The differentiation engine to use. Choices 'gpsr' or 'ad'. +
+
+ TYPE:
+ |
+
measurement |
+
+
+
+ optional measurement protocol. If None, +use exact expectation value with a statevector simulator +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ A noise model to use. +
+
+ TYPE:
+ |
+
configuration |
+
+
+
+ optional configuration for the backend +
+
+ TYPE:
+ |
+
qadence/models/qnn.py
52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 |
|
forward(values=None, state=None, measurement=None, noise=None, endianness=Endianness.BIG)
+
+Forward pass of the model.
+This returns the (differentiable) expectation value of the given observable
+operator defined in the constructor. Differently from the base QuantumModel
+class, the QNN accepts also a tensor as input for the forward pass. The
+tensor is expected to have shape: n_batches x in_features
where n_batches
+is the number of data points and in_features
is the dimensionality of the problem
The output of the forward pass is the expectation value of the input
+observable(s). If a single observable is given, the output shape is
+n_batches
while if multiple observables are given the output shape
+is instead n_batches x n_observables
PARAMETER | +DESCRIPTION | +
---|---|
values |
+
+
+
+ the values of the feature parameters +
+
+ TYPE:
+ |
+
state |
+
+
+
+ Initial state. +
+
+ TYPE:
+ |
+
measurement |
+
+
+
+ optional measurement protocol. If None, +use exact expectation value with a statevector simulator +
+
+ TYPE:
+ |
+
noise |
+
+
+
+ A noise model to use. +
+
+ TYPE:
+ |
+
endianness |
+
+
+
+ Endianness of the resulting bit strings. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+ Tensor
+ |
+
+
+
+ a tensor with the expectation value of the observables passed +in the constructor of the model +
+
+ TYPE:
+ |
+
qadence/models/qnn.py
Operations are common PrimitiveBlocks
, these are often
+called gates elsewhere.
X(target)
+
+
+ Bases: PrimitiveBlock
The X gate.
+ +qadence/operations/primitive.py
Y(target)
+
+
+ Bases: PrimitiveBlock
The Y gate.
+ +qadence/operations/primitive.py
Z(target)
+
+
+ Bases: PrimitiveBlock
The Z gate.
+ +qadence/operations/primitive.py
I(target)
+
+
+ Bases: PrimitiveBlock
The identity gate.
+ +qadence/operations/primitive.py
H(target)
+
+
+ Bases: PrimitiveBlock
The Hadamard or H gate.
+ +qadence/operations/primitive.py
S(target)
+
+
+ Bases: PrimitiveBlock
The S / Phase gate.
+ +qadence/operations/primitive.py
SDagger(target)
+
+
+ Bases: PrimitiveBlock
The Hermitian adjoint/conjugate transpose of the S / Phase gate.
+ +qadence/operations/primitive.py
SWAP(control, target)
+
+
+ Bases: PrimitiveBlock
The SWAP gate.
+ +qadence/operations/primitive.py
T(target)
+
+
+ Bases: PrimitiveBlock
The T gate.
+ +qadence/operations/primitive.py
TDagger(target)
+
+
+ Bases: PrimitiveBlock
The Hermitian adjoint/conjugate transpose of the T gate.
+ +qadence/operations/primitive.py
CNOT(control, target)
+
+
+ Bases: ControlBlock
The CNot, or CX, gate.
+ +qadence/operations/control_ops.py
CY gate not implemented
+CZ(control, target)
+
+CPHASE(control, target, parameter)
+
+
+ Bases: MCPHASE
The CPHASE gate.
+ +qadence/operations/control_ops.py
RX(target, parameter)
+
+
+ Bases: ParametricBlock
The Rx gate.
+ +qadence/operations/parametric.py
RY(target, parameter)
+
+
+ Bases: ParametricBlock
The Ry gate.
+ +qadence/operations/parametric.py
RZ(target, parameter)
+
+
+ Bases: ParametricBlock
The Rz gate.
+ +qadence/operations/parametric.py
CRX(control, target, parameter)
+
+
+ Bases: MCRX
The CRX gate.
+ +qadence/operations/control_ops.py
CRY(control, target, parameter)
+
+CRZ(control, target, parameter)
+
+
+ Bases: MCRZ
The CRZ gate.
+ +qadence/operations/control_ops.py
PHASE(target, parameter)
+
+
+ Bases: ParametricBlock
The Parametric Phase / S gate.
+ +qadence/operations/parametric.py
HamEvo(generator, parameter, qubit_support=None)
+
+
+ Bases: TimeEvolutionBlock
A block implementing the Hamiltonian evolution operation H where:
+H = exp(-iG, t)
+
where G represents a square generator and t represents the time parameter +which can be parametrized.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
generator |
+
+
+
+ Either a AbstractBlock, torch.Tensor or numpy.ndarray. +
+
+ TYPE:
+ |
+
parameter |
+
+
+
+ A scalar or vector of numeric or torch.Tensor type. +
+
+ TYPE:
+ |
+
qubit_support |
+
+
+
+ The qubits on which the evolution will be performed on. +
+
+ TYPE:
+ |
+
Examples:
+from qadence import RX, HamEvo, run, PI
+import torch
+hevo = HamEvo(generator=RX(0, PI), parameter=torch.rand(2))
+print(run(hevo))
+# Now lets use a torch.Tensor as a generator, Now we have to pass the support
+gen = torch.rand(2,2, dtype=torch.complex128)
+hevo = HamEvo(generator=gen, parameter=torch.rand(2), qubit_support=(0,))
+print(run(hevo))
+
qadence/operations/ham_evo.py
digital_decomposition(approximation=LTSOrder.ST4)
+
+Decompose the Hamiltonian evolution into digital gates.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
approximation |
+
+
+
+ Choose the type of decomposition. Defaults to "st4". +Available types are: +* 'basic' = apply first-order Trotter formula and decompose each term of + the exponential into digital gates. It is exact only if applied to an + operator whose terms are mutually commuting. +* 'st2' = Trotter-Suzuki 2nd order formula for approximating non-commuting + Hamiltonians. +* 'st4' = Trotter-Suzuki 4th order formula for approximating non-commuting + Hamiltonians. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+ AbstractBlock
+ |
+
+
+
+ a block with the digital decomposition +
+
+ TYPE:
+ |
+
qadence/operations/ham_evo.py
138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 |
|
AnalogSWAP(control, target, parameter=3 * PI / 4)
+
+
+ Bases: HamEvo
Single time-independent Hamiltonian evolution over a Rydberg Ising.
+hamiltonian yielding a SWAP (up to global phase).
+Derived from +Bapat et al. +where it is applied to XX-type Hamiltonian
+ +qadence/operations/analog.py
AnalogSWAP should be turned into a proper analog block
+AnalogRX(angle, qubit_support='global', add_pattern=True)
+
+Analog X rotation.
+Shorthand for AnalogRot
:
PARAMETER | +DESCRIPTION | +
---|---|
angle |
+
+
+
+ Rotation angle [rad] +
+
+ TYPE:
+ |
+
qubit_support |
+
+
+
+ Defines the (local/global) qubit support +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ConstantAnalogRotation
+
+ |
+
+
+
+ ConstantAnalogRotation + |
+
qadence/operations/analog.py
AnalogRY(angle, qubit_support='global', add_pattern=True)
+
+Analog Y rotation.
+Shorthand for AnalogRot
:
RETURNS | +DESCRIPTION | +
---|---|
+
+ ConstantAnalogRotation
+
+ |
+
+
+
+ ConstantAnalogRotation + |
+
qadence/operations/analog.py
AnalogRZ(angle, qubit_support='global', add_pattern=True)
+
+Analog Z rotation. Shorthand for AnalogRot
:
+
qadence/operations/analog.py
AnalogRot(duration, omega=0, delta=0, phase=0, qubit_support='global', add_pattern=True)
+
+General analog rotation operation.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
duration |
+
+
+
+ Duration of the rotation [ns]. +
+
+ TYPE:
+ |
+
omega |
+
+
+
+ Rotation frequency [rad/μs] +
+
+ TYPE:
+ |
+
delta |
+
+
+
+ Rotation frequency [rad/μs] +
+
+ TYPE:
+ |
+
phase |
+
+
+
+ Phase angle [rad] +
+
+ TYPE:
+ |
+
qubit_support |
+
+
+
+ Defines the (local/global) qubit support +
+
+ TYPE:
+ |
+
add_pattern |
+
+
+
+ False disables the semi-local addressing pattern +for the execution of this specific block. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ConstantAnalogRotation
+
+ |
+
+
+
+ ConstantAnalogRotation + |
+
qadence/operations/analog.py
AnalogInteraction(duration, qubit_support='global', add_pattern=True)
+
+Evolution of the interaction term for a register of qubits.
+Constructs a InteractionBlock
.
PARAMETER | +DESCRIPTION | +
---|---|
duration |
+
+
+
+ Time to evolve the interaction for in nanoseconds. +
+
+ TYPE:
+ |
+
qubit_support |
+
+
+
+ Qubits the
+
+ TYPE:
+ |
+
add_pattern |
+
+
+
+ False disables the semi-local addressing pattern +for the execution of this specific block. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ InteractionBlock
+
+ |
+
+
+
+ a |
+
qadence/operations/analog.py
ParamMap(**kwargs)
+
+Connects UUIDs of parameters to their expressions and names.
+This class is not user-facing +and only needed for more complex block definitions. It provides convenient access to +expressions/UUIDs/names needed in different backends.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
kwargs |
+
+
+
+ Parameters. +
+
+ TYPE:
+ |
+
Example: +
import sympy
+from qadence.parameters import ParamMap
+
+(x,y) = sympy.symbols("x y")
+ps = ParamMap(omega=2.0, duration=x+y)
+
+print(f"{ps.names() = }")
+print(f"{ps.expressions() = }")
+print(f"{ps.uuids() = }")
+
qadence/parameters.py
Parameter
+
+
+
+ Bases: Symbol
A wrapper on top of sympy.Symbol
.
Includes two additional keywords: trainable
and value
.
+This class is to define both feature parameter and variational parameters.
trainable: bool
+
+
+ instance-attribute
+
+
+Trainable parameters are variational parameters.
+Non-trainable parameters are feature +parameters.
+value: TNumber
+
+
+ instance-attribute
+
+
+(Initial) value of the parameter.
+__new__(name, **assumptions)
+
+Arguments:
+name: When given a string only, the class
+ constructs a trainable Parameter with a a randomly initialized value.
+**assumptions: are passed on to the parent class `sympy.Symbol`. Two new assumption
+ kwargs are supported by this constructor: `trainable: bool`, and `value: TNumber`.
+
Example: +
from qadence.parameters import Parameter, VariationalParameter
+
+theta = Parameter("theta")
+print(f"{theta}: trainable={theta.trainable} value={theta.value}")
+assert not theta.is_number
+
+# you can specify both trainable/value in the constructor
+theta = Parameter("theta", trainable=True, value=2.0)
+print(f"{theta}: trainable={theta.trainable} value={theta.value}")
+
+# VariationalParameter/FeatureParameter are constructing
+# trainable/untrainable Parameters
+theta = VariationalParameter("theta", value=2.0)
+assert theta == Parameter("theta", trainable=True, value=2.0)
+
+# When provided with a numeric type, Parameter constructs a sympy numeric type":
+constant_zero = Parameter(0)
+assert constant_zero.is_number
+
+# When passed a Parameter or a sympy expression, it just returns it.
+expr = Parameter("x") * Parameter("y")
+print(f"{expr=} : {expr.free_symbols}")
+
qadence/parameters.py
64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 |
|
FeatureParameter(name, **kwargs)
+
+VariationalParameter(name, **kwargs)
+
+evaluate(expr, values={}, as_torch=False)
+
+Arguments:
+expr: An expression consisting of Parameters.
+values: values dict which contains values for the Parameters,
+ if empty, Parameter.value will be used.
+as_torch: Whether to retrieve a torch-differentiable expression result.
+
Example: +
from qadence.parameters import Parameter, evaluate
+
+expr = Parameter("x") * Parameter("y")
+
+# Unless specified, Parameter initialized random values
+# Lets evaluate this expression and see what the result is
+res = evaluate(expr)
+print(res)
+
+# We can also evaluate the expr using a custom dict
+d = {"x": 1, "y":2}
+res = evaluate(expr, d)
+print(res)
+
+# Lastly, if we want a differentiable result, lets put the as_torch flag
+res = evaluate(expr, d, as_torch=True)
+print(res)
+
qadence/parameters.py
extract_original_param_entry(param)
+
+Given an Expression, what was the original "param" given by the user? It is either.
+going to be a numeric value, or a sympy Expression (in case a string was given, +it was converted via Parameter("string").
+ +qadence/parameters.py
embedding(block, to_gate_params=False, engine=Engine.TORCH)
+
+Construct embedding function which maps user-facing parameters to either expression-level.
+parameters or gate-level parameters. The constructed embedding function has the signature:
+ embedding_fn(params: ParamDictType, inputs: ParamDictType) -> ParamDictType:
+
which means that it maps the variational parameter dict params
and the feature parameter
+dict inputs
to one new parameter dict embedded_dict
which holds all parameters that are
+needed to execute a circuit on a given backend. There are two different modes for this
+mapping:
len(embedded_dict) == len(unique_parameter_expressions)
.len(embedded_dict) ==
+ len(parametric_gates)
. This is needed because PSR requires to shift the angles of every
+ gate where the same parameter appears.PARAMETER | +DESCRIPTION | +
---|---|
block |
+
+
+
+ parametrized block into which we want to embed parameters. +
+
+ TYPE:
+ |
+
to_gate_params |
+
+
+
+ A boolean flag whether to generate gate-level parameters or +expression-level parameters. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ tuple[ParamDictType, Callable[[ParamDictType, ParamDictType], ParamDictType]]
+
+ |
+
+
+
+ A tuple with variational parameter dict and the embedding function. + |
+
qadence/blocks/embedding.py
42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 |
|
The abstract QuantumCircuit
is the key object in Qadence, as it is what can be executed.
QuantumCircuit(support, *blocks)
+
+
+ dataclass
+
+
+Am abstract QuantumCircuit instance.
+It needs to be passed to a quantum backend for execution.
+ +Arguments:
+support: `Register` or number of qubits. If an integer is provided, a register is
+ constructed with `Register.all_to_all(x)`
+*blocks: (Possibly multiple) blocks to construct the circuit from.
+
qadence/circuit.py
unique_parameters: list[Parameter]
+
+
+ property
+
+
+Return the unique parameters in the circuit.
+These parameters are the actual user-facing parameters which +can be assigned by the user. Multiple gates can contain the +same unique parameter
+ + +RETURNS | +DESCRIPTION | +
---|---|
+
+ list[Parameter]
+
+ |
+
+
+
+ list[Parameter]: List of unique parameters in the circuit + |
+
dagger()
+
+get_blocks_by_tag(tag)
+
+Extract one or more blocks using the human-readable tag.
+This function recursively explores all composite blocks to find +all the occurrences of a certain tag in the blocks.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
tag |
+
+
+
+ the tag to look for +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ list[AbstractBlock]
+
+ |
+
+
+
+ list[AbstractBlock]: The block(s) corresponding to the given tag + |
+
qadence/circuit.py
parameters()
+
+Extract all parameters for primitive blocks in the circuit.
+Notice that this function returns all the unique Parameters used +in the quantum circuit. These can correspond to constants too.
+ + +RETURNS | +DESCRIPTION | +
---|---|
+
+ list[Parameter | Basic] | list[tuple[Parameter | Basic, ...]]
+
+ |
+
+
+
+ List[tuple[Parameter]]: A list of tuples containing the Parameter + |
+
+
+ list[Parameter | Basic] | list[tuple[Parameter | Basic, ...]]
+
+ |
+
+
+
+ instance of each of the primitive blocks in the circuit or, if the |
+
+
+ list[Parameter | Basic] | list[tuple[Parameter | Basic, ...]]
+
+ |
+
+
+
+ flag is set to True, a flattened list of all circuit parameters + |
+
qadence/circuit.py
Register(support, spacing=1.0, device_specs=DEFAULT_DEVICE)
+
+A 2D register of qubits which includes their coordinates.
+It is needed for e.g. analog computing.
+The coordinates are ignored in backends that don't need them. The easiest
+way to construct a register is via its classmethods like Register.triangular_lattice
.
PARAMETER | +DESCRIPTION | +
---|---|
support |
+
+
+
+ A graph or number of qubits. Nodes can include a
+
+ TYPE:
+ |
+
spacing |
+
+
+
+ Value set as the distance between the two closest qubits. +
+
+ TYPE:
+ |
+
Examples: +
+ + +qadence/register.py
line_graph(n_qubits)
+
+Create graph representing linear lattice.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ number of nodes in the graph +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Graph
+
+ |
+
+
+
+ graph instance + |
+
qadence/register.py
SerializationModel(d=dict())
+
+
+ dataclass
+
+
+A serialization model class to serialize data from QuantumModel
s,.
torch.nn.Module
and similar structures. The data included in the
+serialization logic includes: the AbstractBlock
and its children
+classes, QuantumCircuit
, Register
, and sympy
expressions
+(including Parameter
class from qadence.parameters
).
A children class must define the value
attribute type and how to
+handle it, since it is the main property for the class to be used
+by the serialization process. For instance:
@dataclass
+class QuantumCircuitSerialization(SerializationModel):
+ value: QuantumCircuit = dataclass_field(init=False)
+
+ def __post_init__(self) -> None:
+ self.value = (
+ QuantumCircuit._from_dict(self.d)
+ if isinstance(self.d, dict)
+ else self.d
+ )
+
deserialize(d, as_torch=False)
+
+Supported Types:
+AbstractBlock | QuantumCircuit | QuantumModel | Register | torch.nn.Module +Deserializes a dict to one of the supported types.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
d |
+
+
+
+ A dict containing a serialized object. +
+
+ TYPE:
+ |
+
as_torch |
+
+
+
+ Whether to transform to torch for the deserialized object. +
+
+ TYPE:
+ |
+
Returns: + AbstractBlock, QuantumCircuit, QuantumModel, Register, torch.nn.Module.
+Examples: +
import torch
+from qadence import serialize, deserialize, hea, hamiltonian_factory, Z
+from qadence import QuantumCircuit, QuantumModel
+
+n_qubits = 2
+myblock = hea(n_qubits=n_qubits, depth=1)
+block_dict = serialize(myblock)
+print(block_dict)
+
+## Lets use myblock in a QuantumCircuit and serialize it.
+
+qc = QuantumCircuit(n_qubits, myblock)
+qc_dict = serialize(qc)
+qc_deserialized = deserialize(qc_dict)
+assert qc == qc_deserialized
+
+## Finally, let's wrap it in a QuantumModel
+obs = hamiltonian_factory(n_qubits, detuning = Z)
+qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
+
+qm_dict = serialize(qm)
+qm_deserialized = deserialize(qm_dict)
+# Lets check if the loaded QuantumModel returns the same expectation
+assert torch.isclose(qm.expectation({}), qm_deserialized.expectation({}))
+
{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': 'HEA', 'blocks': [{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('ff59ec8b-db16-4815-ad4f-9b94bf2a2beb', {'name': 'theta_0', 'expression': "Parameter('theta_0')", 'symbols': {'theta_0': {'name': 'theta_0', 'trainable': 'True', 'value': '0.495582402021744'}}})}}}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('5915ab3c-a24f-442b-832b-7ddccd3ff5cf', {'name': 'theta_1', 'expression': "Parameter('theta_1')", 'symbols': {'theta_1': {'name': 'theta_1', 'trainable': 'True', 'value': '0.08840193195718948'}}})}}}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RY', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('65b89ef4-a66d-4bba-acc3-baa6b2a0a413', {'name': 'theta_2', 'expression': "Parameter('theta_2')", 'symbols': {'theta_2': {'name': 'theta_2', 'trainable': 'True', 'value': '0.017883402670038295'}}})}}}, {'type': 'RY', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('b4cd28b9-b8b4-484e-90ab-402f74f21da5', {'name': 'theta_3', 'expression': "Parameter('theta_3')", 'symbols': {'theta_3': {'name': 'theta_3', 'trainable': 'True', 'value': '0.13607528101808786'}}})}}}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('aac51b7f-3b0a-4cb5-b948-ba81950a8c18', {'name': 'theta_4', 'expression': "Parameter('theta_4')", 'symbols': {'theta_4': {'name': 'theta_4', 'trainable': 'True', 'value': '0.8621633901369974'}}})}}}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('0d4c745b-a485-4869-8b72-2a0df22b0b43', {'name': 'theta_5', 'expression': "Parameter('theta_5')", 'symbols': {'theta_5': {'name': 'theta_5', 'trainable': 'True', 'value': '0.9714993709424635'}}})}}}]}]}, {'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'CNOT', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'X', 'qubit_support': (1,), 'tag': None}]}]}]}]}
+
qadence/serialization.py
load(file_path, map_location='cpu')
+
+Same as serialize/deserialize but for storing/loading files.
+Supported types: AbstractBlock | QuantumCircuit | QuantumModel | TransformedModule | Register +Loads a .json or .pt file to one of the supported types.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
file_path |
+
+
+
+ The name of the file. +
+
+ TYPE:
+ |
+
map_location |
+
+
+
+ In case of a .pt file, on which device to load the object (cpu,cuda). +
+
+ TYPE:
+ |
+
Returns: + A object of type AbstractBlock, QuantumCircuit, QuantumModel, TransformedModule, Register.
+Examples: +
import torch
+from pathlib import Path
+import os
+
+from qadence import save, load, hea, hamiltonian_factory, Z
+from qadence import QuantumCircuit, QuantumModel
+
+n_qubits = 2
+myblock = hea(n_qubits=n_qubits, depth=1)
+qc = QuantumCircuit(n_qubits, myblock)
+# Lets store the circuit in a json file
+save(qc, '.', 'circ')
+loaded_qc = load(Path('circ.json'))
+qc == loaded_qc
+os.remove('circ.json')
+## Let's wrap it in a QuantumModel and store that
+obs = hamiltonian_factory(n_qubits, detuning = Z)
+qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
+save(qm, folder= '.',file_name= 'quantum_model')
+qm_loaded = load('quantum_model.json')
+os.remove('quantum_model.json')
+
qadence/serialization.py
parse_expr_fn(code)
+
+A parsing expressions function that checks whether a given code is valid on.
+the parsing grammar. The grammar is defined to be compatible with sympy
+expressions, such as Float('-0.33261030434342942', precision=53)
, while
+avoiding code injection such as 2*3
or __import__('os').system('ls -la')
.
PARAMETER | +DESCRIPTION | +
---|---|
code |
+
+
+
+ code to be parsed and checked. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ bool
+
+ |
+
+
+
+ Boolean indicating whether the code matches the defined grammar or not. + |
+
qadence/serialization.py
save(obj, folder, file_name='', format=SerializationFormat.JSON)
+
+Same as serialize/deserialize but for storing/loading files.
+Supported types: +AbstractBlock | QuantumCircuit | QuantumModel | TransformedModule | Register | torch.nn.Module +Saves a qadence object to a json/.pt.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
obj |
+
+
+
+
+
+ TYPE:
+ |
+
file_name |
+
+
+
+ The name of the file. +
+
+ TYPE:
+ |
+
format |
+
+
+
+ The type of file to save. +
+
+ TYPE:
+ |
+
Returns: + None.
+Examples: +
import torch
+from pathlib import Path
+import os
+
+from qadence import save, load, hea, hamiltonian_factory, Z
+from qadence import QuantumCircuit, QuantumModel
+
+n_qubits = 2
+myblock = hea(n_qubits=n_qubits, depth=1)
+qc = QuantumCircuit(n_qubits, myblock)
+# Lets store the circuit in a json file
+save(qc, '.', 'circ')
+loaded_qc = load(Path('circ.json'))
+qc == loaded_qc
+os.remove('circ.json')
+## Let's wrap it in a QuantumModel and store that
+obs = hamiltonian_factory(n_qubits, detuning = Z)
+qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
+save(qm, folder= '.',file_name= 'quantum_model')
+qm_loaded = load('quantum_model.json')
+os.remove('quantum_model.json')
+
qadence/serialization.py
367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 |
|
serialize(obj, save_params=False)
+
+Supported Types:
+AbstractBlock | QuantumCircuit | QuantumModel | torch.nn.Module | Register | Module +Serializes a qadence object to a dictionary.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
obj |
+
+
+
+
+
+
+ TYPE:
+ |
+
Returns: + A dict.
+Examples: +
import torch
+from qadence import serialize, deserialize, hea, hamiltonian_factory, Z
+from qadence import QuantumCircuit, QuantumModel
+
+n_qubits = 2
+myblock = hea(n_qubits=n_qubits, depth=1)
+block_dict = serialize(myblock)
+print(block_dict)
+
+## Lets use myblock in a QuantumCircuit and serialize it.
+
+qc = QuantumCircuit(n_qubits, myblock)
+qc_dict = serialize(qc)
+qc_deserialized = deserialize(qc_dict)
+assert qc == qc_deserialized
+
+## Finally, let's wrap it in a QuantumModel
+obs = hamiltonian_factory(n_qubits, detuning = Z)
+qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
+
+qm_dict = serialize(qm)
+qm_deserialized = deserialize(qm_dict)
+# Lets check if the loaded QuantumModel returns the same expectation
+assert torch.isclose(qm.expectation({}), qm_deserialized.expectation({}))
+
{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': 'HEA', 'blocks': [{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('a171ebde-9ed2-4d72-8116-c562cd40695b', {'name': 'theta_0', 'expression': "Parameter('theta_0')", 'symbols': {'theta_0': {'name': 'theta_0', 'trainable': 'True', 'value': '0.544649028517595'}}})}}}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('882fc09d-8133-4e5a-8251-9d584a63ced6', {'name': 'theta_1', 'expression': "Parameter('theta_1')", 'symbols': {'theta_1': {'name': 'theta_1', 'trainable': 'True', 'value': '0.8040643239062514'}}})}}}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RY', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('a3308016-ef7f-4f5f-9827-ff49ef5bdfcc', {'name': 'theta_2', 'expression': "Parameter('theta_2')", 'symbols': {'theta_2': {'name': 'theta_2', 'trainable': 'True', 'value': '0.0963085508396101'}}})}}}, {'type': 'RY', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('c5788bef-688d-4e04-b223-6232f041f4ee', {'name': 'theta_3', 'expression': "Parameter('theta_3')", 'symbols': {'theta_3': {'name': 'theta_3', 'trainable': 'True', 'value': '0.629923691597065'}}})}}}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('1f2c30f5-2a62-4204-b581-54cd4af3c323', {'name': 'theta_4', 'expression': "Parameter('theta_4')", 'symbols': {'theta_4': {'name': 'theta_4', 'trainable': 'True', 'value': '0.895849390462047'}}})}}}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('0f7ab827-07d2-477c-9c64-0f8175ab202e', {'name': 'theta_5', 'expression': "Parameter('theta_5')", 'symbols': {'theta_5': {'name': 'theta_5', 'trainable': 'True', 'value': '0.898787499949708'}}})}}}]}]}, {'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'CNOT', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'X', 'qubit_support': (1,), 'tag': None}]}]}]}]}
+
qadence/serialization.py
243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 |
|
ghz_block(n_qubits)
+
+Generates the abstract ghz state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ChainBlock
+
+ |
+
+
+
+ A ChainBlock representing the GHZ state. + |
+
Examples: +
+ + +qadence/states.py
ghz_state(n_qubits, batch_size=1)
+
+Creates a GHZ state.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ How many bitstrings to use. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
+qadence/states.py
is_normalized(wf, atol=NORMALIZATION_ATOL)
+
+Checks if a wave function is normalized.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
wf |
+
+
+
+ The wave function as a torch tensor. +
+
+ TYPE:
+ |
+
atol |
+
+
+
+ The tolerance. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ bool
+
+ |
+
+
+
+ A bool. + |
+
Examples: +
+ + +qadence/states.py
normalize(wf)
+
+Normalizes a wavefunction or batch of wave functions.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
wf |
+
+
+
+ Normalized wavefunctions. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
+qadence/states.py
one_block(n_qubits)
+
+Generates the abstract one state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ KronBlock
+
+ |
+
+
+
+ A KronBlock representing the one state. + |
+
Examples: +
+ + +qadence/states.py
one_state(n_qubits, batch_size=1)
+
+Generates the one state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ The batch size. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
+ + +qadence/states.py
pmf(wf)
+
+Converts a wave function into a torch Distribution.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
wf |
+
+
+
+ The wave function as a torch tensor. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Distribution
+
+ |
+
+
+
+ A torch.distributions.Distribution. + |
+
Examples: +
+ + +qadence/states.py
product_block(bitstring)
+
+Creates an abstract product state from a bitstring.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
bitstring |
+
+
+
+ A bitstring. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ KronBlock
+
+ |
+
+
+
+ A KronBlock representing the product state. + |
+
Examples: +
+ + +qadence/states.py
product_state(bitstring, batch_size=1, endianness=Endianness.BIG, backend=BackendName.PYQTORCH)
+
+Creates a product state from a bitstring.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
bitstring |
+
+
+
+ A bitstring. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ Batch size. +
+
+ TYPE:
+ |
+
backend |
+
+
+
+ The backend to use. Default is "pyqtorch". +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ ArrayLike
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
from qadence.states import product_state
+
+print(product_state("1100", backend="pyqtorch"))
+print(product_state("1100", backend="horqrux"))
+
qadence/states.py
rand_bitstring(N)
+
+Creates a random bistring.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
N |
+
+
+
+ The length of the bitstring. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ str
+
+ |
+
+
+
+ A string. + |
+
Examples: +
+ + +qadence/states.py
rand_product_block(n_qubits)
+
+Creates a block representing a random abstract product state.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ KronBlock
+
+ |
+
+
+
+ A KronBlock representing the product state. + |
+
Examples: +
+ + +qadence/states.py
rand_product_state(n_qubits, batch_size=1)
+
+Creates a random product state.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ How many bitstrings to use. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
from qadence.states import rand_product_state
+
+print(rand_product_state(n_qubits=2, batch_size=2))
+
qadence/states.py
random_state(n_qubits, batch_size=1, backend=BackendName.PYQTORCH, type=StateGeneratorType.HAAR_MEASURE_FAST)
+
+Generates a random state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
backend |
+
+
+
+ The backend to use. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ The batch size. +
+
+ TYPE:
+ |
+
type |
+
+
+
+ StateGeneratorType. +
+
+ DEFAULT:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
from qadence.states import random_state, StateGeneratorType
+from qadence.states import random_state, is_normalized, pmf
+from qadence.types import BackendName
+from torch.distributions import Distribution
+
+### We have the following options:
+print([g.value for g in StateGeneratorType])
+
+n_qubits = 2
+# The default is StateGeneratorType.HAAR_MEASURE_FAST
+state = random_state(n_qubits=n_qubits)
+print(state)
+
+### Lets initialize a state using random rotations, i.e., StateGeneratorType.RANDOM_ROTATIONS.
+random = random_state(n_qubits=n_qubits, type=StateGeneratorType.RANDOM_ROTATIONS)
+print(random)
+
qadence/states.py
uniform_block(n_qubits)
+
+Generates the abstract uniform state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ KronBlock
+
+ |
+
+
+
+ A KronBlock representing the uniform state. + |
+
Examples: +
+ + +qadence/states.py
uniform_state(n_qubits, batch_size=1)
+
+Generates the uniform state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ The batch size. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
+ + +qadence/states.py
zero_block(n_qubits)
+
+Generates the abstract zero state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ KronBlock
+
+ |
+
+
+
+ A KronBlock representing the zero state. + |
+
Examples: +
+ + +qadence/states.py
zero_state(n_qubits, batch_size=1)
+
+Generates the zero state for a specified number of qubits.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
n_qubits |
+
+
+
+ The number of qubits for which the zero state is to be generated. +
+
+ TYPE:
+ |
+
batch_size |
+
+
+
+ The batch size for the zero state. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Tensor
+
+ |
+
+
+
+ A torch.Tensor. + |
+
Examples: +
+ + +qadence/states.py
Contains functions that operate on blocks and circuits to transpile
them to new blocks/circuits.
transpile(*fs)
+
+AbstractBlock
or QuantumCircuit
transpilation.
Compose functions that +accept a circuit/block and returns a circuit/block.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
*fs |
+
+
+
+ composable functions that either map blocks to blocks
+(
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ Callable
+
+ |
+
+
+
+ Composed function. + |
+
Examples:
+Flatten a block of nested chains and krons: +
from qadence import *
+from qadence.transpile import transpile, flatten, scale_primitive_blocks_only
+
+b = chain(2 * chain(chain(X(0), Y(0))), kron(kron(X(0), X(1))))
+print(b)
+
+# both flatten and scale_primitive_blocks_only are functions that accept and
+# return a block
+t = transpile(flatten, scale_primitive_blocks_only)(b)
+print(t)
+
We also proved a decorator to easily turn a function Callable[[AbstractBlock], AbstractBlock]
+into a Callable[[QuantumCircuit], QuantumCircuit]
to be used in circuit transpilation.
+
from qadence import *
+from qadence.transpile import transpile, blockfn_to_circfn, flatten
+
+# We want to pass this circuit to `transpile` instead of a block,
+# so we need functions that map from a circuit to a circuit.
+circ = QuantumCircuit(2, chain(chain(X(0), chain(X(1)))))
+
+@blockfn_to_circfn
+def fn(block):
+ # un-decorated function accepts a block and returns a block
+ return block * block
+
+transp = transpile(
+ # the decorated function accepts a circuit and returns a circuit
+ fn,
+ # already existing functions can also be decorated
+ blockfn_to_circfn(flatten)
+)
+print(transp(circ))
+
qadence/transpile/transpile.py
chain_single_qubit_ops(block)
+
+Transpile a chain of krons into a kron of chains of single qubit operations.
+Examples: +
from qadence import hea
+from qadence.transpile.block import chain_single_qubit_ops
+
+# Consider a single HEA layer
+block = hea(2,1)
+print(block)
+
+# After applying chain_single_qubit_ops, we get:
+print(chain_single_qubit_ops(block))
+
ChainBlock(0,1) [tag: HEA]
+├── ChainBlock(0,1)
+│ ├── KronBlock(0,1)
+│ │ ├── RX(0) [params: ['theta_0']]
+│ │ └── RX(1) [params: ['theta_1']]
+│ ├── KronBlock(0,1)
+│ │ ├── RY(0) [params: ['theta_2']]
+│ │ └── RY(1) [params: ['theta_3']]
+│ └── KronBlock(0,1)
+│ ├── RX(0) [params: ['theta_4']]
+│ └── RX(1) [params: ['theta_5']]
+└── ChainBlock(0,1)
+ └── KronBlock(0,1)
+ └── CNOT(0, 1)
+ChainBlock(0,1)
+├── KronBlock(0,1)
+│ ├── ChainBlock(0)
+│ │ ├── RX(0) [params: ['theta_0']]
+│ │ ├── RY(0) [params: ['theta_2']]
+│ │ └── RX(0) [params: ['theta_4']]
+│ └── ChainBlock(1)
+│ ├── RX(1) [params: ['theta_1']]
+│ ├── RY(1) [params: ['theta_3']]
+│ └── RX(1) [params: ['theta_5']]
+└── ChainBlock(0,1)
+ └── KronBlock(0,1)
+ └── CNOT(0, 1)
+
qadence/transpile/block.py
scale_primitive_blocks_only(block, scale=None)
+
+Push the scale all the way down into the leaves of the block tree.
+When given a scaled CompositeBlock consisting of several PrimitiveBlocks.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
block |
+
+
+
+ The block to be transpiled. +
+
+ TYPE:
+ |
+
scale |
+
+
+
+ An optional scale parameter. Only to be used for recursive calls internally. +
+
+ TYPE:
+ |
+
RETURNS | +DESCRIPTION | +
---|---|
+ AbstractBlock
+ |
+
+
+
+ A block of the same type where the scales have been moved into the subblocks. +
+
+ TYPE:
+ |
+
Examples:
+There are two different cases:
+ChainBlock
s/KronBlock
s: Only the first subblock needs to be scaled because chains/krons
+represent multiplications.
+
from qadence import chain, X, RX
+from qadence.transpile import scale_primitive_blocks_only
+b = 2 * chain(X(0), RX(0, "theta"))
+print(b)
+# After applying scale_primitive_blocks_only
+print(scale_primitive_blocks_only(b))
+
[mul: 2]
+└── ChainBlock(0)
+ ├── X(0)
+ └── RX(0) [params: ['theta']]
+ChainBlock(0)
+├── [mul: 2.000]
+│ └── X(0)
+└── RX(0) [params: ['theta']]
+
AddBlock
s: Consider 2 * add(X(0), RX(0, "theta")). The scale needs to be added to all
+subblocks. We get add(2 * X(0), 2 * RX(0, "theta")).
+
from qadence import add, X, RX
+from qadence.transpile import scale_primitive_blocks_only
+b = 2 * add(X(0), RX(0, "theta"))
+print(b)
+# After applying scale_primitive_blocks_only
+print(scale_primitive_blocks_only(b))
+
[mul: 2]
+└── AddBlock(0)
+ ├── X(0)
+ └── RX(0) [params: ['theta']]
+AddBlock(0)
+├── [mul: 2.000]
+│ └── X(0)
+└── [mul: 2.000]
+ └── RX(0) [params: ['theta']]
+
qadence/transpile/block.py
set_trainable(blocks, value=True, inplace=True)
+
+Set the trainability of all parameters in a block to a given value.
+ + +PARAMETER | +DESCRIPTION | +
---|---|
blocks |
+
+
+
+ Block or list of blocks for which +to set the trainable attribute +
+
+ TYPE:
+ |
+
value |
+
+
+
+ The value of the trainable attribute to assign to the input blocks +
+
+ TYPE:
+ |
+
inplace |
+
+
+
+ Whether to modify the block(s) in place or not. Currently, only +
+
+ TYPE:
+ |
+
RAISES | +DESCRIPTION | +
---|---|
+
+ NotImplementedError
+
+ |
+
+
+
+ if the |
+
RETURNS | +DESCRIPTION | +
---|---|
+
+ AbstractBlock | list[AbstractBlock]
+
+ |
+
+
+
+ AbstractBlock | list[AbstractBlock]: the input block or list of blocks with the trainable +attribute set to the given value + |
+
qadence/transpile/block.py
validate(block)
+
+Moves a block from global to local qubit numbers by adding PutBlocks.
+Reassigns qubit locations appropriately.
+from qadence.blocks import chain
+from qadence.operations import X
+from qadence.transpile import validate
+
+x = chain(chain(X(0)), chain(X(1)))
+print(x)
+print(validate(x))
+
ChainBlock(0,1)
+├── ChainBlock(0)
+│ └── X(0)
+└── ChainBlock(1)
+ └── X(1)
+ChainBlock(0,1)
+├── put on (0)
+│ └── ChainBlock(0)
+│ └── put on (0)
+│ └── X(0)
+└── put on (1)
+ └── ChainBlock(0)
+ └── put on (0)
+ └── X(0)
+
qadence/transpile/block.py
TArray = Union[Iterable, Tensor, np.ndarray]
+
+
+ module-attribute
+
+
+Union of common array types.
+TGenerator = Union[Tensor, sympy.Array, sympy.Basic]
+
+
+ module-attribute
+
+
+Union of torch tensors and numpy arrays.
+TNumber = Union[int, float, complex, np.int64, np.float64]
+
+
+ module-attribute
+
+
+Union of python and numpy numeric types.
+TParameter = Union[TNumber, Tensor, sympy.Basic, str]
+
+
+ module-attribute
+
+
+Union of numbers, tensors, and parameter types.
+AlgoHEvo
+
+
+
+ Bases: StrEnum
Hamiltonian Evolution algorithms that can be used by the backend.
+ + + + +EIG = 'EIG'
+
+
+ class-attribute
+ instance-attribute
+
+
+Using Hamiltonian diagonalization.
+EXP = 'EXP'
+
+
+ class-attribute
+ instance-attribute
+
+
+Using torch.matrix_exp on the generator matrix.
+RK4 = 'RK4'
+
+
+ class-attribute
+ instance-attribute
+
+
+4th order Runge-Kutta approximation.
+BasisSet
+
+
+
+ Bases: StrEnum
Basis set for feature maps.
+ + + + +CHEBYSHEV = 'Chebyshev'
+
+
+ class-attribute
+ instance-attribute
+
+
+Chebyshev polynomials of the first kind.
+FOURIER = 'Fourier'
+
+
+ class-attribute
+ instance-attribute
+
+
+Fourier basis set.
+DeviceType
+
+
+
+ Bases: StrEnum
Supported types of devices for Pulser backend.
+ + + + +IDEALIZED = 'IdealDevice'
+
+
+ class-attribute
+ instance-attribute
+
+
+Idealized device, least realistic.
+REALISTIC = 'RealisticDevice'
+
+
+ class-attribute
+ instance-attribute
+
+
+Device with realistic specs.
+Endianness
+
+
+
+ Bases: StrEnum
The endianness convention to use.
+ + + + +BIG = 'Big'
+
+
+ class-attribute
+ instance-attribute
+
+
+Use Big endianness.
+LITTLE = 'Little'
+
+
+ class-attribute
+ instance-attribute
+
+
+Use little endianness.
+FigFormat
+
+
+
+ Bases: StrEnum
Available output formats for exporting visualized circuits to a file.
+ + + + +PDF = 'PDF'
+
+
+ class-attribute
+ instance-attribute
+
+
+PDF format.
+PNG = 'PNG'
+
+
+ class-attribute
+ instance-attribute
+
+
+PNG format.
+SVG = 'SVG'
+
+
+ class-attribute
+ instance-attribute
+
+
+SVG format.
+GenDAQC
+
+
+
+ Bases: StrEnum
The type of interaction for the DAQC transform.
+ + + + +NN = 'NN'
+
+
+ class-attribute
+ instance-attribute
+
+
+NN
+ZZ = 'ZZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+ZZ
+Interaction
+
+
+
+ Bases: StrEnum
Interaction types used in.
+RydbergDevice
.hamiltonian_factory
.NN = 'NN'
+
+
+ class-attribute
+ instance-attribute
+
+
+NN-Ising Interaction, N=(I-Z)/2.
+XY = 'XY'
+
+
+ class-attribute
+ instance-attribute
+
+
+XY Interaction.
+XYZ = 'XYZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+XYZ Interaction.
+ZZ = 'ZZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+ZZ-Ising Interaction.
+LTSOrder
+
+
+
+ Bases: StrEnum
Lie-Trotter-Suzuki approximation order.
+ + + + +BASIC = 'BASIC'
+
+
+ class-attribute
+ instance-attribute
+
+
+Basic.
+ST2 = 'ST2'
+
+
+ class-attribute
+ instance-attribute
+
+
+ST2.
+ST4 = 'ST4'
+
+
+ class-attribute
+ instance-attribute
+
+
+ST4.
+LatticeTopology
+
+
+
+ Bases: StrEnum
Lattice topologies to choose from for the register.
+ + + + +ALL_TO_ALL = 'all_to_all'
+
+
+ class-attribute
+ instance-attribute
+
+
+All to all- connected lattice.
+ARBITRARY = 'arbitrary'
+
+
+ class-attribute
+ instance-attribute
+
+
+Arbitrarily-shaped lattice.
+CIRCLE = 'circle'
+
+
+ class-attribute
+ instance-attribute
+
+
+Circular lattice.
+HONEYCOMB_LATTICE = 'honeycomb_lattice'
+
+
+ class-attribute
+ instance-attribute
+
+
+Honeycomb-shaped lattice.
+LINE = 'line'
+
+
+ class-attribute
+ instance-attribute
+
+
+Line-format lattice.
+RECTANGULAR_LATTICE = 'rectangular_lattice'
+
+
+ class-attribute
+ instance-attribute
+
+
+Rectangular-shaped lattice.
+SQUARE = 'square'
+
+
+ class-attribute
+ instance-attribute
+
+
+Square lattice.
+TRIANGULAR_LATTICE = 'triangular_lattice'
+
+
+ class-attribute
+ instance-attribute
+
+
+Triangular-shaped shape.
+OpName
+
+
+
+ Bases: StrEnum
A list of all available of digital-analog operations.
+ + + + +ANALOGENTANG = 'AnalogEntanglement'
+
+
+ class-attribute
+ instance-attribute
+
+
+The analog entanglement operation.
+ANALOGINTERACTION = 'AnalogInteraction'
+
+
+ class-attribute
+ instance-attribute
+
+
+The analog interaction operation.
+ANALOGRX = 'AnalogRX'
+
+
+ class-attribute
+ instance-attribute
+
+
+The analog RX operation.
+ANALOGRY = 'AnalogRY'
+
+
+ class-attribute
+ instance-attribute
+
+
+The analog RY operation.
+ANALOGRZ = 'AnalogRZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+The analog RZ operation.
+ANALOGSWAP = 'AnalogSWAP'
+
+
+ class-attribute
+ instance-attribute
+
+
+The analog SWAP operation.
+CNOT = 'CNOT'
+
+
+ class-attribute
+ instance-attribute
+
+
+The CNOT gate.
+CPHASE = 'CPHASE'
+
+
+ class-attribute
+ instance-attribute
+
+
+The controlled PHASE gate.
+CRX = 'CRX'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Control RX gate.
+CRY = 'CRY'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Controlled RY gate.
+CRZ = 'CRZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Control RZ gate.
+CSWAP = 'CSWAP'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Control SWAP gate.
+CZ = 'CZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+The CZ gate.
+ENTANGLE = 'entangle'
+
+
+ class-attribute
+ instance-attribute
+
+
+The entanglement operation.
+H = 'H'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Hadamard gate.
+HAMEVO = 'HamEvo'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Hamiltonian Evolution operation.
+I = 'I'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Identity gate.
+MCPHASE = 'MCPHASE'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Multicontrol PHASE gate.
+MCRX = 'MCRX'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Multicontrol RX gate.
+MCRY = 'MCRY'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Multicontrol RY gate.
+MCRZ = 'MCRZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Multicontrol RZ gate.
+MCZ = 'MCZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Multicontrol CZ gate.
+N = 'N'
+
+
+ class-attribute
+ instance-attribute
+
+
+The N = (1/2)(I-Z) operator.
+PHASE = 'PHASE'
+
+
+ class-attribute
+ instance-attribute
+
+
+The PHASE gate.
+PROJ = 'Projector'
+
+
+ class-attribute
+ instance-attribute
+
+
+The projector operation.
+RX = 'RX'
+
+
+ class-attribute
+ instance-attribute
+
+
+The RX gate.
+RY = 'RY'
+
+
+ class-attribute
+ instance-attribute
+
+
+The RY gate.
+RZ = 'RZ'
+
+
+ class-attribute
+ instance-attribute
+
+
+The RZ gate.
+S = 'S'
+
+
+ class-attribute
+ instance-attribute
+
+
+The S gate.
+SDAGGER = 'SDagger'
+
+
+ class-attribute
+ instance-attribute
+
+
+The S dagger gate.
+SWAP = 'SWAP'
+
+
+ class-attribute
+ instance-attribute
+
+
+The SWAP gate.
+T = 'T'
+
+
+ class-attribute
+ instance-attribute
+
+
+The T gate.
+TDAGGER = 'TDagger'
+
+
+ class-attribute
+ instance-attribute
+
+
+The T dagger gate.
+TOFFOLI = 'Toffoli'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Toffoli gate.
+U = 'U'
+
+
+ class-attribute
+ instance-attribute
+
+
+The U gate.
+X = 'X'
+
+
+ class-attribute
+ instance-attribute
+
+
+The X gate.
+Y = 'Y'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Y gate.
+Z = 'Z'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Z gate.
+ZERO = 'Zero'
+
+
+ class-attribute
+ instance-attribute
+
+
+The zero gate.
+OverlapMethod
+
+
+
+ Bases: StrEnum
Overlap Methods to choose from.
+ + + + +COMPUTE_UNCOMPUTE = 'compute_uncompute'
+
+
+ class-attribute
+ instance-attribute
+
+
+Compute-uncompute.
+EXACT = 'exact'
+
+
+ class-attribute
+ instance-attribute
+
+
+Exact.
+HADAMARD_TEST = 'hadamard_test'
+
+
+ class-attribute
+ instance-attribute
+
+
+Hadamard-test.
+JENSEN_SHANNON = 'jensen_shannon'
+
+
+ class-attribute
+ instance-attribute
+
+
+Jensen-shannon.
+SWAP_TEST = 'swap_test'
+
+
+ class-attribute
+ instance-attribute
+
+
+Swap-test.
+ParameterType
+
+
+
+ Bases: StrEnum
Parameter types available in qadence.
+ + + + +FEATURE = 'Feature'
+
+
+ class-attribute
+ instance-attribute
+
+
+FeatureParameters act as input and are not trainable.
+FIXED = 'Fixed'
+
+
+ class-attribute
+ instance-attribute
+
+
+Fixed/ constant parameters are neither trainable nor act as input.
+VARIATIONAL = 'Variational'
+
+
+ class-attribute
+ instance-attribute
+
+
+VariationalParameters are trainable.
+QubitSupportType
+
+
+
+ Bases: StrEnum
Qubit support types.
+ + + + +GLOBAL = 'global'
+
+
+ class-attribute
+ instance-attribute
+
+
+Use global qubit support.
+ResultType
+
+
+
+ Bases: StrEnum
Available data types for generating certain results.
+ + + + +NUMPY = 'Numpy'
+
+
+ class-attribute
+ instance-attribute
+
+
+Numpy Array Type.
+STRING = 'String'
+
+
+ class-attribute
+ instance-attribute
+
+
+String Type.
+TORCH = 'Torch'
+
+
+ class-attribute
+ instance-attribute
+
+
+Torch Tensor Type.
+ReuploadScaling
+
+
+
+ Bases: StrEnum
Scaling for data reuploads in feature maps.
+ + + + +CONSTANT = 'Constant'
+
+
+ class-attribute
+ instance-attribute
+
+
+Constant scaling.
+EXP = 'Exponential'
+
+
+ class-attribute
+ instance-attribute
+
+
+Exponentially increasing scaling.
+TOWER = 'Tower'
+
+
+ class-attribute
+ instance-attribute
+
+
+Linearly increasing scaling.
+SerializationFormat
+
+
+
+ Bases: StrEnum
Available serialization formats for circuits.
+ + + + +JSON = 'JSON'
+
+
+ class-attribute
+ instance-attribute
+
+
+The Json format.
+PT = 'PT'
+
+
+ class-attribute
+ instance-attribute
+
+
+The PT format used by Torch.
+StateGeneratorType
+
+
+
+ Bases: StrEnum
Methods to generate random states.
+ + + + +HAAR_MEASURE_FAST = 'HaarMeasureFast'
+
+
+ class-attribute
+ instance-attribute
+
+
+HaarMeasure.
+HAAR_MEASURE_SLOW = 'HaarMeasureSlow'
+
+
+ class-attribute
+ instance-attribute
+
+
+HaarMeasure non-optimized version.
+RANDOM_ROTATIONS = 'RandomRotations'
+
+
+ class-attribute
+ instance-attribute
+
+
+Random Rotations.
+StrEnum
+
+
+
+ Bases: str
, Enum
Strategy
+
+
+
+ Bases: StrEnum
Computing paradigm.
+ + + + +ANALOG = 'Analog'
+
+
+ class-attribute
+ instance-attribute
+
+
+Use the analog paradigm.
+BDAQC = 'bDAQC'
+
+
+ class-attribute
+ instance-attribute
+
+
+Use the banged digital-analog QC paradigm.
+DIGITAL = 'Digital'
+
+
+ class-attribute
+ instance-attribute
+
+
+Use the digital paradigm.
+SDAQC = 'sDAQC'
+
+
+ class-attribute
+ instance-attribute
+
+
+Use the step-wise digital-analog QC paradigm.
+TensorType
+
+
+
+ Bases: StrEnum
Tensor Types for converting blocks to tensors.
+ + + + +DENSE = 'Dense'
+
+
+ class-attribute
+ instance-attribute
+
+
+Convert a block to a dense tensor.
+SPARSE = 'Sparse'
+
+
+ class-attribute
+ instance-attribute
+
+
+Convert a observable block to a sparse tensor.
+SPARSEDIAGONAL = 'SparseDiagonal'
+
+
+ class-attribute
+ instance-attribute
+
+
+Convert a diagonal observable block to a sparse diagonal if possible.
+