Skip to content

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

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))
wf = tensor([[6.1232e-17+0.j, 0.0000e+00-1.j]])
wf = tensor([[6.1232e-17+0.j, 0.0000e+00-1.j]])

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)
wf = tensor([[0.8961+0.0000j, 0.0000-0.4439j]])

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

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])})
wf = tensor([[6.1232e-17+0.0000j, 0.0000e+00-1.0000j],
        [7.0711e-01+0.0000j, 0.0000e+00-0.7071j]])

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

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)})
wf = tensor([[0.2074+0.7665j, 0.0000+0.0000j, 0.5867+0.1587j, 0.0000+0.0000j]])

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 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)})
wf = tensor([[ 1.1248e-32+0.j,  6.1232e-17+0.j, -1.3775e-48+0.j, -7.4988e-33+0.j,
          1.8370e-16+0.j,  1.0000e+00+0.j, -2.2496e-32+0.j, -1.2246e-16+0.j]])

Parametrized circuits

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)
%3 cluster_8021f7f4f2cf4aa583da87c71e2281d4 12b93bd22f1740a689f4b2eae604e505 0 e95b21fe80204f7aa69ee65eb6fd9722 RX(Φ/θ) 12b93bd22f1740a689f4b2eae604e505--e95b21fe80204f7aa69ee65eb6fd9722 4b124394c3634f78a873d8755c9df528 1 43ae7f11a4044e31ac6df48c5e43b1b1 e95b21fe80204f7aa69ee65eb6fd9722--43ae7f11a4044e31ac6df48c5e43b1b1 cb6bca573049456a8140786e7077ac09 43ae7f11a4044e31ac6df48c5e43b1b1--cb6bca573049456a8140786e7077ac09 591b451a2d364c6ea9c763091d2b240d HamEvo cb6bca573049456a8140786e7077ac09--591b451a2d364c6ea9c763091d2b240d a5f5d3a23c004782a676cdf1177a6f9e 591b451a2d364c6ea9c763091d2b240d--a5f5d3a23c004782a676cdf1177a6f9e 9d4c30f5d84748689bb23698dc53d32a 112fb922b3ae44ebb96f19c96064b05b RY(2*θ) 4b124394c3634f78a873d8755c9df528--112fb922b3ae44ebb96f19c96064b05b c0fd3602782347a892d4ff7d99f15b66 2 8dd89898603142219a1837198ad90dce X 112fb922b3ae44ebb96f19c96064b05b--8dd89898603142219a1837198ad90dce 8dd89898603142219a1837198ad90dce--43ae7f11a4044e31ac6df48c5e43b1b1 3e2ababa0a774d06ada686ba1124ef44 8dd89898603142219a1837198ad90dce--3e2ababa0a774d06ada686ba1124ef44 2d76d1928ca14801b17e8b6e85d07267 t = Φ 3e2ababa0a774d06ada686ba1124ef44--2d76d1928ca14801b17e8b6e85d07267 2d76d1928ca14801b17e8b6e85d07267--9d4c30f5d84748689bb23698dc53d32a b73b25a124d046d5a5b934bb4244a9da a571f588d2dd40918cca2da23be06b34 RZ(cos(Φ)) c0fd3602782347a892d4ff7d99f15b66--a571f588d2dd40918cca2da23be06b34 81d9db332bca45269e0c649bd68df7ba a571f588d2dd40918cca2da23be06b34--81d9db332bca45269e0c649bd68df7ba db60e8f3852c42c689c37940ae82bb08 PHASE(3.142) 81d9db332bca45269e0c649bd68df7ba--db60e8f3852c42c689c37940ae82bb08 db60e8f3852c42c689c37940ae82bb08--3e2ababa0a774d06ada686ba1124ef44 2faf392ad96849f08fe564f373bab9a6 db60e8f3852c42c689c37940ae82bb08--2faf392ad96849f08fe564f373bab9a6 2faf392ad96849f08fe564f373bab9a6--b73b25a124d046d5a5b934bb4244a9da

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.