Skip to content

Using QMOD Classical Types

QMOD functions may take classical parameters of different types - scalars, lists, and structs. When declaring and calling QMOD functions in Python, the builtin Python scalar types are used - int, float, and bool. int is also used to represent QMOD enumerated types. The builtin Python list (or typing.List) is used for QMOD lists. Each QMOD struct type has a corresponding Python class definition.

Defining and using structs

QMOD struct types can be declared by writing a Python class and decorating it with the QStruct decorator. With this decorator, a class behaves like a Python data-class (i.e. a class decorated with dataclasses.dataclass). Note that subclassing is not supported for QMOD structs.

In the following example a struct with two scalar fields is declared and used by a function:

from classiq import QStruct, QFunc, QParam, QBit, repeat, PHASE


@QStruct
class MyStruct:
    count: int
    angle: float


@QFunc
def foo(ms: QParam[MyStruct], qv: QBit) -> None:
    repeat(
        count=ms.count,
        iteration=lambda index, qbv: PHASE(ms.angle + index, qbv),
        qbv=qv,
    )

Using aggregate types

QMOD lists can store elements of any QMOD type, as long as they are of the same type. List elements are accessed with the native Python subscript ([...]) operator, and list literals are specified using native Python constructs.

QMOD structs can have fields of any QMOD types. Struct fields are accessed with the native Python dot (.) operator. Native class constructor is used to specify the literal value of a struct. Note that recursive struct definition is not allowed.

Here is a more elaborate example, in which structs and lists are aggregated to form a data-structure. An instances of the struct is created in function main and queried in different contexts within function foo.

from typing import List
from classiq import QStruct, QFunc, QParam, QBit, QArray, Output, PHASE, allocate


@QStruct
class MyStruct:
    position: List[int]
    angle: float


@QStruct
class YourStruct:
    msl: List[MyStruct]


@QFunc
def foo(ys: QParam[YourStruct], index: QParam[int], qbv: QArray[QBit, 5]) -> None:
    PHASE(ys.msl[index].angle + 0.5, qbv[ys.msl[index].position[0]]),


@QFunc
def main(res: Output[QArray[QBit]]) -> None:
    ys = YourStruct(
        msl=[
            MyStruct(position=[1, 2], angle=0.1),
            MyStruct(position=[0, 3, 4], angle=0.2),
        ],
    )
    allocate(5, res)
    H(res[0])
    foo(ys, 0, res)

Fixed-sized Arrays

In addition to lists, QMOD supports array types, which declare both the element type and number of elements. The main application of array types is to define execution parameters of a model, typically in hybrid algorithms.

Array parameters are declared with type hint of the form Array[<element-type>, <size>]. The operators [<index>] and <array>.len() apply to arrays in the same way as lists.

In the example below function main expects an array of 6 angle values, and applies an X rotation to the respective qubit in its output.

from classiq import (
    QFunc,
    QParam,
    QBit,
    Array,
    Output,
    QArray,
    RX,
    allocate,
    repeat,
)


@QFunc
def main(angle: QParam[Array[float, 6]], res: Output[QArray[QBit, 6]]) -> None:
    allocate(6, res)
    repeat(
        count=angle.len(),
        iteration=lambda index, qbv: RX(angle[index], qbv[index]),
        qbv=res,
    )

Builtin types

Struct types required for builtin functions are available for use (see the full list of builtin structs under classiq/qmod/builtins.py). In the following example the builtin function suzuki_trotter is used, which in turn takes a list of struct type PauliTerm as parameter.

from classiq import (
    Output,
    QArray,
    QBit,
    allocate,
    suzuki_trotter,
    PauliTerm,
    QFunc,
    Pauli,
)


@QFunc
def main(res: Output[QArray[QBit]]) -> None:
    allocate(3, res)
    suzuki_trotter(
        pauli_operator=[
            PauliTerm(pauli=[Pauli.X, Pauli.X, Pauli.Z], coefficient=1),
            PauliTerm(pauli=[Pauli.Y, Pauli.X, Pauli.Y], coefficient=0.5),
        ],
        evolution_coefficient=0.7,
        order=4,
        repetitions=2,
        qbv=res,
    )

Note that a native Python enum class Pauli can be used for the corresponding QMOD enumerated type.