Design - Classical Variables and Operations
Classical variables and operations lie at the heart of the Qmod language, but they are complemented by classical control flow and operations, making it easier to design quantum algorithms with hybrid quantum-classical logic. With the latest updates, Qmod now fully supports Python's classical operations, such as for
loops, if-else
statements, and more, smoothly integrating with quantum workflows.
In Qmod, equivalent types for common Python int
, float
, list
, and bool
types are denoted by int
, real
, array
, and bool
in the native syntax and by CInt
, CReal
, CArray
, and CBool
in the Python SDK. The Qmod types can be used in quantum workflows, though Python types can also be passed as classical parameters. For example, when writing quantum workflows, it is possible to use both the length of a quantum array, which is a Qmod quantity, or a Python int
quantity to control the action of a loop. This ensures the type consistency required for quantum control flow operations like repeat
(the Qmod equivalent of a Python for
loop) and if-else
statements, which enable sophisticated hybrid control logic, see a detailed description. Additionally, Qmod supports arrays of classical values and more configurable data structures called Struct
s (equivalent to Python dataclasses without methods). See the full list of classical variables and types supported in Qmod.
While Qmod enables the integration of Python types within its quantum workflows, the converse is not true with the capabilities covered so far. Python control flow constructs, such as range
, for
loops and if-else
statements, cannot yet incorporate Qmod-specific quantities such as the len
of a quantum array, within Python’s native control flow. Qmod quantities remain tightly integrated within the Qmod execution environment and cannot directly influence Python logic, ensuring a clear separation between classical Python constructs and Qmod quantum operations.
Generative Functions in Qmod
Generative functions in Qmod offer a powerful way to create and manipulate classical objects of Qmod with Python constructs. These functions allow the interaction between quantum and classical variables, enabling advanced logic and operations. Currently, it is possible to benefit from the following Python features within quantum programs using generative functions:
-
range
: Generate sequences of classical values to iterate quantum operations dynamically over classical types within Qmod types. -
if
statements: Define conditional logic for generating and applying quantum operations using Qmod types as classical control parameters. -
Treating quantum constants as classical: Converts parameters intricate to the quantum systems to Python types. This allows one to use, for example, integration of functions from external packages such as
math.sqrt
over classical quantities of a quantum object, such as thelen
of a quantum array.
Generative functions provide an elegant way to manage hybrid classical-quantum workflows, enhancing the expressiveness of your quantum algorithms. For more details and examples, refer to the Generative Functions documentation.
To enable generative functions in quantum function, it is necessary to modify the @qfunc
decorator to @qfunc(generative=True)
.
First Example: State preparation
The task is to create a quantum array with \(10\) qubits in the state of \(|1010101010\rangle\); i.e., a quantum state with alternating qubit states of zeros and ones.
The way of doing this is based on knowing that a general qubit array can be easily initialized to the state of all zeros; i.e., \(|0000000000\rangle\), it should be sufficient to flip the state of every all the qubits in an even position (the qubits in the \(0th\) position, \(2nd\) position, \(4th\) position, etc.).
The argument of the main
function is a qubit array named x
. Initalize it to the state \(|0000000000\rangle\) with \(10\) qubits using the allocate
function.
After that, by allowing generative functions by setting @qfunc(generative=True)
, it is possible to use the length of the qubit array x
as a classical variable, and apply quantum operations over qubits dynamically, using Python's if
and for
statements over the qmod x.len
quantity, according to the pre-defined rule of flipping the state of the even qubits.
The condition of whether i
is even evaluated is using the %
modulo operation, which calculates the reminder of the integer i
divided by \(2\).
from classiq import *
@qfunc(generative=True)
def main(x: Output[QArray]):
allocate(10, x)
print(x.len)
for i in range(x.len):
if i%2==0:
X(x[i])
That's it, the algorithm can be synthesized and viewed in the IDE:
quantum_program = synthesize(create_model(main))
show(quantum_program)
10
Opening: https://platform.classiq.io/circuit/c66bf31f-0016-4690-bca5-6a0959df4599?version=0.60.1
Evaluate the results by executing the quantum program on the default simulator:
results = execute(quantum_program).result()[0].value
print(results.counts)
{'0101010101': 2048}
The only measured bit string is \(0101010101\), which in Classiq notation is read from right to left when interpreted. Hence, it corresponds to the \(|1010101010\rangle\) state, which is exactly the target state.
State preparation: Slicing qubits
In this example, the task is to prepare the \(N\)-qubit state \(|00011111000\dots\rangle\), where the state \(|1\rangle\) is prepared in the qubits over the integer interval \((N/3, N/2)\). For this, it is possible to create a program that apply alternately the \(X\) operation to the correct qubits. In this example, consider a total of \(N=24\) qubits.
from classiq import *
@qfunc(generative=True)
def main(x: Output[QArray]):
allocate(24, x)
k=0
for i in range(x.len//3,x.len//2):
X(x[i])
quantum_program = synthesize(create_model(main))
show(quantum_program)
Opening: https://platform.classiq.io/circuit/8a864834-32a8-445e-a0e0-e38515edf8c1?version=0.60.1
Summary - Classical Variables and Operations
Key features of this tutorial:
-
Classical data types: Data types
int
,real
, andbool
are denoted asCInt
,CReal
, andCBool
in the Python SDK. Complex structures like arrays andStruct
s (similar to Python dataclasses) are also supported. -
Quantum control flow: Qmod fully supports Python types such as
float
,int
andbool
variables within Qmod control flow, such asrepeat
andif-for
statements.
Generative Functions in Qmod
Generative functions are employed to enhance hybrid quantum-classical workflows by treating quantum objects into classical variables:
-
Dynamic iteration: Using
range
andfor
loops integration with Qmod types, such aslen
. -
Conditional operations: Using
if
statements controlled by Qmod types.