Using Operators¶
The Classiq package supports defining QMOD operators, using the QCallable
type-hint to specify an operand declaration. Note that the arguments of the operand
declaration should follow the naming convention of arg{i}
where i
is the index of
the argument (starting at 0).
The QCallable
type-hint accepts a list of parameters that specify
the parameters of the QParam
or QVar
operand.
Following is an example.
from sympy import pi
from classiq import (
QFunc,
QParam,
QBit,
QCallable,
H,
PHASE,
allocate,
)
from classiq import create_model, synthesize, show
@QFunc
def foo(
n: QParam[int],
my_operand: QCallable[QParam[float], QBit],
qv: QBit,
) -> None:
H(target=qv)
for i in range(4):
my_operand((i / n) * pi, qv)
@QFunc
def bar(m: QParam[int], qv: QBit) -> None:
@QFunc
def goo(arg0: QParam[float], arg1: QBit) -> None:
PHASE(theta=arg0, target=arg1)
foo(n=m * 2, my_operand=goo, qv=qv)
@QFunc
def main() -> None:
qv = QBit("qv")
allocate(1, qv)
bar(m=2, qv=qv)
model = create_model(main)
qprog = synthesize(model)
show(qprog)
This results in the following quantum program.
You can also specify an operand without the @QFunc
decorator; instead, as a direct
Python def
or lambda
.
from sympy import pi
from classiq import (
QFunc,
QParam,
QBit,
QCallable,
H,
PHASE,
allocate,
)
from classiq import create_model, synthesize, show
@QFunc
def foo(
n: QParam[int],
my_operand: QCallable[QParam[float], QBit],
qv: QBit,
) -> None:
H(target=qv)
for i in range(4):
my_operand((i / n) * pi, qv)
@QFunc
def bar(m: QParam[int], qv: QBit) -> None:
def goo(angle, target):
PHASE(angle, target)
foo(n=m * 2, my_operand=goo, qv=qv)
foo(
n=m // 2,
my_operand=lambda angle, target: PHASE(angle, target),
qv=qv,
)
@QFunc
def main() -> None:
qv = QBit("qv")
allocate(1, qv)
bar(m=2, qv=qv)
model = create_model(main)
qprog = synthesize(model)
show(qprog)