Skip to content

Results are limited to the current section: Qadence

Product news

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.

Passing fixed parameters to blocks can be done by simply passing a Python numeric type or a torch.Tensor.

import torch
from 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>

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.

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 tensor
from 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 tensor
from qadence import RX, Z, HamEvo, PI
from qadence import VariationalParameter, FeatureParameter, run
from sympy import sin
theta, phi = VariationalParameter("theta"), FeatureParameter("phi")
# Arbitrary parameter composition
expr = PI * sin(theta + phi)
# Use as unitary gate arguments
gate = RX(0, expr)
# Or as scaling coefficients for Hermitian operators
h_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>

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 tensor
from 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>

Let's look at a final example of an arbitrary composition of digital and analog parameterized blocks:

import sympy
from qadence import RX, RY, RZ, CNOT, CPHASE, Z, HamEvo
from 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
8bce00e5a1694ebc8bf08601d63d6018
0
2f05bb5ff7684440a474d24024331af3
RX(Φ/θ)
8bce00e5a1694ebc8bf08601d63d6018--2f05bb5ff7684440a474d24024331af3
6623b773b34949fbba2cb9c7de932b93
1
627d1375cba74d5eb8f916dd2919431a
2f05bb5ff7684440a474d24024331af3--627d1375cba74d5eb8f916dd2919431a
5bc93949688b4f60940c6c0bdae3feee
627d1375cba74d5eb8f916dd2919431a--5bc93949688b4f60940c6c0bdae3feee
db3595b4d2074cd39ef01b47674b47ad
HamEvo
5bc93949688b4f60940c6c0bdae3feee--db3595b4d2074cd39ef01b47674b47ad
18bd2a6ad0924204afe3055b8c5ea9db
db3595b4d2074cd39ef01b47674b47ad--18bd2a6ad0924204afe3055b8c5ea9db
ee6bd6b61b084f1f871d7bbbc5369b61
2db4aebbd32743f4ac4bdc3acc7e8782
RY(2*θ)
6623b773b34949fbba2cb9c7de932b93--2db4aebbd32743f4ac4bdc3acc7e8782
23bc3ffbc4a74e63ad1d6ef1e3ab9ca1
2
4db28ffb07744e739498331362646370
X
2db4aebbd32743f4ac4bdc3acc7e8782--4db28ffb07744e739498331362646370
4db28ffb07744e739498331362646370--627d1375cba74d5eb8f916dd2919431a
e0179c859d294fa9bb176cc4fa5407f5
4db28ffb07744e739498331362646370--e0179c859d294fa9bb176cc4fa5407f5
7f9b3c09389a40a79d58260710f05f94
t = Φ
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--6fba849cb7134803a0600ab4bad05779

Please 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.