Design  Quantum Operations
Quantum computing resembles classical computing in some aspects, and is substantially different in other aspects. One of the key advantages of Qmod is that it captures the core concepts which are uniquely quantum in a simple and natural way. This begins with the quantum objects and variables described in the previous tutorial (see Quantum Variables and Functions) and continues with the meaningful native quantum operations.
Simply put, quantum operations are functions of functions applied on quantum objects that are very common in quantum computing, hence receive a special place in the Qmod language. More accurately, these are builtin statements in the Qmod language. A statement is a building block of a programming language, such that programming languages are composed from statements. For example, if
and for
loops are common statements in programming languages like in Python.
There are a few quantum operation statements in Qmod, and in the following we focus on arguably the most useful one  control
. It applies a specified quantum function conditioned on some state (value) of a given quantum variable. Other quantum operations are invert
, power
, and within_apply
, and one can see all the quantum operations here.
Let's understand it through a concrete example.
Concrete Example
Our task is to first prepare a quantum number x
in a superposition of all possible integers between \(0\) to \(15\), i.e. \(x\rangle = \frac{1}{\sqrt{16}}(0\rangle + 1\rangle + \dots + 15\rangle)\). Then to prepare another quantum number y
that is in the state \(17\rangle\) only if \(x\rangle\) is in the state \(15\rangle\), otherwise the state of y
should be \(0\rangle\). Mathematically, the task is to prepare the following state:
\(\begin{equation}
x\rangley\rangle = \frac{1}{\sqrt{16}}(0\rangle0\rangle+1\rangle0\rangle+\dots+14\rangle0\rangle+15\rangle17\rangle).
\end{equation}\)
How to approach this task? We have already seen that we can create a uniform superposition with the hadamard_transform
. Then, conditioned on the value of \(x\rangle\) being \(15\rangle\), we will prepare the state of \(y\rangle\) to be \(17\rangle\) with the inplace_prepare_int
function.
We shell start by creating our own function called apply_control
that received two quantum numbers x
and y
that are already initialized, and conditioned on the values of x
being \(15\), it prepares the state of y
to the integer value \(17\) using the inplace_prepare_int
function.
What's the difference between `inplace_prepare_int` and `prepare_int`?
The function `prepare_int` initializes a specific quantum variable to a specific integer value. On the other hand, the function `inplace_prepare_int` receives an initialized quantum variable, and assumed its value is $0$, it prepares its state to the desired integer values. Note that for all the `prepare` functions there is the option to use also `inplace_prepare` in case you want to apply the function on an already initialized quantum variable.from classiq import QNum, control, inplace_prepare_int, qfunc
@qfunc
def apply_control(x: QNum, y: QNum):
control(ctrl=(x == 15), operand=lambda: inplace_prepare_int(17, y))
In the Python syntax, control
is a Python function with two arguments. The ctrl
argument is the condition for which the operand
will be applied. The operand
argument is the specific operation/function we want to apply given the condition is satisfied. The way to pass a function as an argument of another function is with the lambda:
keyword. So anytime you pass a function as argument in the Python SDK use the prefix lambda:
.
More on `lambda:`
The `lambda:` keyword is used to define inline functions.In the Native syntax, control
is embedded within the Qmod language such that the condition is specified with the ()
parenthesis, and the operand that needs to be applied is specified within the scope of the control
, i.e. within the {}
parenthesis.
Now for the main
function. At the end, we want to evaluate the execution results of both x
and y
so both of them will be arguments of the main
function. x
is initialized with \(4\) qubits since it needs to be in a superposition of \(16 (=2^4)\) states, and y
is initialized with \(5\) qubits since this is the minimal number of qubits that is needed for representing the number \(17\) (\(ceiling(log_2(17))=5\)).
from classiq import Output, allocate, hadamard_transform
@qfunc
def main(x: Output[QNum], y: Output[QNum]):
allocate(4, x)
allocate(5, y)
hadamard_transform(x)
apply_control(x, y)
After the initialization, hadamard_transform
is applied on x
in order to prepare the initial superposition, and then the apply_control
function we defined earlier is applied on both x
and y
.
That's it! The desired quantum program can be now synthesized and viewed:
from classiq import create_model, show, synthesize
quantum_program = synthesize(create_model(main))
show(quantum_program)
Opening: https://platform.classiq.io/circuit/ce544494280d4c50b99166b86a27e617?version=0.41.0.dev39%2B79c8fd0855
And then the quantum program can be executed in order to receive the execution results:
from classiq import execute
job = execute(quantum_program)
results = job.result()[0].value.parsed_counts
print(results)
[{'x': 13.0, 'y': 0.0}: 80, {'x': 14.0, 'y': 0.0}: 70, {'x': 8.0, 'y': 0.0}: 70, {'x': 15.0, 'y': 17.0}: 67, {'x': 5.0, 'y': 0.0}: 66, {'x': 12.0, 'y': 0.0}: 65, {'x': 4.0, 'y': 0.0}: 64, {'x': 6.0, 'y': 0.0}: 63, {'x': 1.0, 'y': 0.0}: 61, {'x': 7.0, 'y': 0.0}: 59, {'x': 3.0, 'y': 0.0}: 59, {'x': 10.0, 'y': 0.0}: 59, {'x': 0.0, 'y': 0.0}: 57, {'x': 2.0, 'y': 0.0}: 56, {'x': 11.0, 'y': 0.0}: 54, {'x': 9.0, 'y': 0.0}: 50]
We can see that we receive \(16\) possible values for x
and y
, and in all the pairs of values \(y=0\) besides when \(x=15\) as desired!
Summary  Quantum Operations
The following summarizes the main takeaways from the example in terms of quantum operations:

Quantum operations receive both quantum objects and quantum functions as inputs, and they apply the quantum functions on the quantum objects according to the nature of the quantum operation. In the above example, the
control
operation applies theinplace_prepare_int
function on the quantum variabley
conditioned on the value of the quantum variablex
being \(15\). 
In the Native syntax, the quantum operations are statements of the Qmod language and have a special syntax. In the above example, the syntax for
control
iscontrol(){;}
where the condition is given in the parentheses and the operation/function that is applied is within the curly brackets. 
In the Python SDK, the quantum operations are written just like any other Python function. The arguments of the quantum operation that are functions by themselves must be passed with the
lambda:
keyword. In the above example, theoperand
argument of thecontrol
function is a function by itself (inplace_prepare_int
), hence it is prefixed withlambda:
. 
Other quantum operations are:
power
 raising a unitary to some power,invert
 applying the inverse of a unitary,within_apply
 applying two unitaries \(U\) and \(V\) in the following way: \(UVU^\dagger\). See more detailed description of all the quantum operators here.
from classiq import write_qmod
write_qmod(create_model(main), "quantum_operations")