Parametric programs
Qadence provides a flexible parameter system built on top of Sympy. Parameters can be of different types:
- Fixed parameter: a constant with a fixed, non-trainable value (e.g. \(\dfrac{\pi}{2}\)).
- Variational parameter: a trainable parameter which will be automatically picked up by the optimizer.
- Feature parameter: a non-trainable parameter which can be used to pass input values.
Fixed parameters
Section titled “Fixed parameters”Passing fixed parameters to blocks can be done by simply passing a Python numeric type or a torch.Tensor.
import torchfrom qadence import RX, run, PI
wf = run(RX(0, torch.tensor(PI)))
wf = run(RX(0, PI))<span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="err">w</span><span class="kc">f</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="kc">tens</span><span class="err">or(</span><span class="p">[[</span><span class="mf">6.1232e-17+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0000e+00-1.</span><span class="err">j</span><span class="p">]]</span><span class="err">)</span><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="err">w</span><span class="kc">f</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="kc">tens</span><span class="err">or(</span><span class="p">[[</span><span class="mf">6.1232e-17+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0000e+00-1.</span><span class="err">j</span><span class="p">]]</span><span class="err">)</span></code>Variational parameters
Section titled “Variational parameters”To parametrize a block a VariationalParameter instance is required. In most cases Qadence also accepts a Python string, which will be used to automatically initialize a VariationalParameter:
from qadence import RX, run, VariationalParameter
block = RX(0, VariationalParameter("theta"))block = RX(0, "theta") # Equivalent
wf = run(block)<span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="err">w</span><span class="kc">f</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="kc">tens</span><span class="err">or(</span><span class="p">[[</span><span class="mf">0.9949+0.0000</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0000-0.1006</span><span class="err">j</span><span class="p">]]</span><span class="err">)</span></code>By calling run, a random value for "theta" is initialized at execution. In a QuantumModel, variational parameters are stored in the underlying model parameter dictionary.
Feature parameters
Section titled “Feature parameters”A FeatureParameter type can also be used. It requires an input value or a batch of values. In most cases, Qadence accepts a values dictionary to set the input of feature parameters.
from torch import tensorfrom qadence import RX, PI, run, FeatureParameter
block = RX(0, FeatureParameter("phi"))
wf = run(block, values = {"phi": tensor([PI, PI/2])})<span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="err">w</span><span class="kc">f</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="kc">tens</span><span class="err">or(</span><span class="p">[[</span><span class="mf">6.1232e-17+0.0000</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0000e+00-1.0000</span><span class="err">j</span><span class="p">],</span><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="w"> </span><span class="p">[</span><span class="mf">7.0711e-01+0.0000</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0000e+00-0.7071</span><span class="err">j</span><span class="p">]]</span><span class="err">)</span></code>Since a batch of input values was passed, the run function returns a batch of output states. Note that FeatureParameter("x") and VariationalParameter("x") are simply aliases for Parameter("x", trainable = False) and Parameter("x", trainable = True).
Multiparameter expressions and analog integration
Section titled “Multiparameter expressions and analog integration”The integration with Sympy becomes useful when one wishes to write arbitrary parameter compositions. Parameters can also be used as scaling coefficients in the block system, which is essential when defining arbitrary analog operations.
from torch import tensorfrom qadence import RX, Z, HamEvo, PIfrom qadence import VariationalParameter, FeatureParameter, runfrom sympy import sin
theta, phi = VariationalParameter("theta"), FeatureParameter("phi")
# Arbitrary parameter compositionexpr = PI * sin(theta + phi)
# Use as unitary gate argumentsgate = RX(0, expr)
# Or as scaling coefficients for Hermitian operatorsh_op = expr * (Z(0) @ Z(1))
wf = run(gate * HamEvo(h_op, 1.0), values = {"phi": tensor(PI)})<span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="err">w</span><span class="kc">f</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="kc">tens</span><span class="err">or(</span><span class="p">[[</span><span class="mf">-0.2592+0.2091</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0000+0.0000</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5922-0.7338</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0000+0.0000</span><span class="err">j</span><span class="p">]]</span><span class="err">)</span></code>Parameter redundancy
Section titled “Parameter redundancy”Parameters are uniquely defined by their name and redundancy is allowed in composite blocks to assign the same value to different blocks. This is useful, for example, when defining layers of rotation gates typically used as feature maps.
from torch import tensorfrom qadence import RY, PI, run, kron, FeatureParameter
n_qubits = 3
param = FeatureParameter("phi")
block = kron(RY(i, (i+1) * param) for i in range(n_qubits))
wf = run(block, values = {"phi": tensor(PI)})<span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="err">w</span><span class="kc">f</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="kc">tens</span><span class="err">or(</span><span class="p">[[</span><span class="w"> </span><span class="mf">1.1248e-32+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">6.1232e-17+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">-1.3775e-48+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">-7.4988e-33+0.</span><span class="err">j</span><span class="p">,</span><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="w"> </span><span class="mf">1.8370e-16+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0000e+00+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">-2.2496e-32+0.</span><span class="err">j</span><span class="p">,</span><span class="w"> </span><span class="mf">-1.2246e-16+0.</span><span class="err">j</span><span class="p">]]</span><span class="err">)</span></code>Parametrized circuits
Section titled “Parametrized circuits”Let's look at a final example of an arbitrary composition of digital and analog parameterized blocks:
import sympyfrom qadence import RX, RY, RZ, CNOT, CPHASE, Z, HamEvofrom qadence import run, chain, add, kron, FeatureParameter, VariationalParameter, PI
n_qubits = 3
phi = FeatureParameter("Φ")theta = VariationalParameter("θ")
rotation_block = kron( RX(0, phi/theta), RY(1, theta*2), RZ(2, sympy.cos(phi)))digital_entangler = CNOT(0, 1) * CPHASE(1, 2, PI)
hamiltonian = add(theta * (Z(i) @ Z(i+1)) for i in range(n_qubits-1))
analog_evo = HamEvo(hamiltonian, phi)
program = chain(rotation_block, digital_entangler, analog_evo)<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
%3
cluster_809c9b2a26f54d068ca440ece0dc4fcf
8bce00e5a1694ebc8bf08601d63d60180
2f05bb5ff7684440a474d24024331af3
RX(Φ/θ)
8bce00e5a1694ebc8bf08601d63d6018--2f05bb5ff7684440a474d24024331af3
6623b773b34949fbba2cb9c7de932b931
627d1375cba74d5eb8f916dd2919431a
2f05bb5ff7684440a474d24024331af3--627d1375cba74d5eb8f916dd2919431a
5bc93949688b4f60940c6c0bdae3feee
627d1375cba74d5eb8f916dd2919431a--5bc93949688b4f60940c6c0bdae3feee
db3595b4d2074cd39ef01b47674b47adHamEvo
5bc93949688b4f60940c6c0bdae3feee--db3595b4d2074cd39ef01b47674b47ad
18bd2a6ad0924204afe3055b8c5ea9db
db3595b4d2074cd39ef01b47674b47ad--18bd2a6ad0924204afe3055b8c5ea9db
ee6bd6b61b084f1f871d7bbbc5369b61
2db4aebbd32743f4ac4bdc3acc7e8782
RY(2*θ)
6623b773b34949fbba2cb9c7de932b93--2db4aebbd32743f4ac4bdc3acc7e8782
23bc3ffbc4a74e63ad1d6ef1e3ab9ca12
4db28ffb07744e739498331362646370
X
2db4aebbd32743f4ac4bdc3acc7e8782--4db28ffb07744e739498331362646370
4db28ffb07744e739498331362646370--627d1375cba74d5eb8f916dd2919431a
e0179c859d294fa9bb176cc4fa5407f5
4db28ffb07744e739498331362646370--e0179c859d294fa9bb176cc4fa5407f5
7f9b3c09389a40a79d58260710f05f94t = Φ
e0179c859d294fa9bb176cc4fa5407f5--7f9b3c09389a40a79d58260710f05f94
7f9b3c09389a40a79d58260710f05f94--ee6bd6b61b084f1f871d7bbbc5369b61
6fba849cb7134803a0600ab4bad05779
10995fb246464729a04e25059a906573
RZ(cos(Φ))
23bc3ffbc4a74e63ad1d6ef1e3ab9ca1--10995fb246464729a04e25059a906573
069e1c9ac3574f34ab57f9ecae09379b
10995fb246464729a04e25059a906573--069e1c9ac3574f34ab57f9ecae09379b
44a4a4f713de432595e2b511f28fe16d
PHASE(3.142)
069e1c9ac3574f34ab57f9ecae09379b--44a4a4f713de432595e2b511f28fe16d
44a4a4f713de432595e2b511f28fe16d--e0179c859d294fa9bb176cc4fa5407f5
54b03e6abc6e459c8228c3e2adb17dc8
44a4a4f713de432595e2b511f28fe16d--54b03e6abc6e459c8228c3e2adb17dc8
54b03e6abc6e459c8228c3e2adb17dc8--6fba849cb7134803a0600ab4bad05779Please note the different colors for the parametrization with different types. The default palette assigns blue for VariationalParameter, green for FeatureParameter, orange for numeric values, and shaded red for non-parametric gates.
