qat.plugins.CostFunctionPlugin
In the myQLM framework, variational optimization plugins are designed to minimize the energy of an observable. This formalism requires to encode the quantity to be minimized using an observable (which is not always easy to do)
This plugin has been designed to encode this quantity using a Python function. The quantity computed by the cost function given to the will be minimized by the optimizer plugin present in the stack.
In this example, one will try to maximize the Hamming weigth of a sample (i.e. maximizing the number of 1 in the state - or minimizing the number of
0 in this state).
This cost function can be easily encoding using an observable but implementing this cost function in Python is easier. The CostFunctionPlugin
has two mode:
This example will focus on minimizing the Hamming weight. A basic circuit composed of two qubits, with one RX gate per qubit, will be chosen to illustrate this example
from qat.lang.AQASM import Program, RX
prog = Program()
qbits = prog.qalloc(2)
for idx, qb in enumerate(qbits):
angle = prog.new_var(float, f"V{idx}")
prog.apply(RX(angle), qb)
circ = prog.to_circ()
job = circ.to_job()
The cost function must be defined, in this mode, the code function takes a Sample
and returns a float. For instance,
one can write:
def cost_function(sample):
"""
This function should be minimize. Then, the number of 0 present in the state
will be computed
"""
return sample.state.bitstring.count("0")
Then, the plugin can be used to optimize the angles of our job
from qat.plugins import ScipyMinimizePlugin, CostFunctionPlugin
from qat.qpus import get_default_qpu
stack = ScipyMinimizePlugin() | CostFunctionPlugin(cost_function) | get_default_qpu()
result = stack.submit(job)
The final state can be be retrieved, state \(|11\rangle\) is the state having the higher probability
job_fixed_angles = job(**result.parameter_map)
result_fixed_angles = stack.submit(job_fixed_angles)
for sample in result_fixed_angles:
print(f"{sample.state} has a probability of {sample.probability:.2}")
|00> has a probability of 1e-23
|01> has a probability of 1.5e-11
|10> has a probability of 6.8e-13
|11> has a probability of 1.0
This example will focus on minimizing the Hamming weight. A basic circuit composed of two qubits, with one RX gate per qubit, will be chosen to illustrate this example
from qat.lang.AQASM import Program, RX
prog = Program()
qbits = prog.qalloc(2)
for idx, qb in enumerate(qbits):
angle = prog.new_var(float, f"V{idx}")
prog.apply(RX(angle), qb)
circ = prog.to_circ()
job = circ.to_job()
The cost function must be defined, in this mode, the code function takes a Result
and returns a float. For instance,
one can write:
def cost_function(result):
"""
This function should be minimize. Then, the number of 0 present in the state
will be computed
"""
return sum(sample.probability * sample.state.bitstring.count("0") for sample in result)
Then, the plugin can be used to optimize the angles of our job
Warning
CostFunctionPlugin
assume a function taking a Sample
as argument is provided. To change this
behavior, an argument is_result_argument=True must be specified
from qat.plugins import ScipyMinimizePlugin, CostFunctionPlugin
from qat.qpus import get_default_qpu
stack = ScipyMinimizePlugin() | CostFunctionPlugin(cost_function, is_result_argument=True) | get_default_qpu()
result = stack.submit(job)
The final state can be be retrieved, state \(|11\rangle\) is the state having the higher probability
job_fixed_angles = job(**result.parameter_map)
result_fixed_angles = stack.submit(job_fixed_angles)
for sample in result_fixed_angles:
print(f"{sample.state} has a probability of {sample.probability:.2}")
|01> has a probability of 2.2e-13
|10> has a probability of 2.2e-14
|11> has a probability of 1.0
- class qat.plugins.CostFunctionPlugin(cost_function, is_result_argument: bool = False)
Encoding a cost function using a
Observable
can be hard. This plugin can be used to encode a cost function directly in Python. This plugin is designed to be used between the optimizer and the QPUstack = ScipyMinimizePlugin() | CostFunctionPlugin(my_function) | PyLinalg()
A cost function takes a
Sample
(or aResult
) an return a number that should be minimized- Parameters
cost_function (callable) – cost function taking a
Sample
and return a numberis_result_argument (bool, optional) –
argument type passed to the cost function:
if
use_result=True
, “cost_function” parameter is expected to be a function taking aResult
and returning a floatif
use_result=False
, “cost_function” parameter is expected to be a function takingSample
and returning a float
Default: False
- compile(batch, specs)
Compiles a job. In practise, this method does nothing to the batch
- Parameters
batch (
Batch
) – batch to compilespecs (
HardwareSpecs
) – hardware specs
- Returns
compiled batch
- Return type