Skip to content

Quantum Registers

Quantum registers, or QRegs, are objects that are available in Classiq's Python SDK, and serve as a way of declaring registers.

The syntax is:

from classiq import QReg

x = QReg(size=3)

QRegs may be passed to functions both as their inputs and as their outputs. In the following example, we call QFT twice, where the output of the first call is the input of the second call.

from classiq import ModelDesigner, QReg
from classiq.builtin_functions import QFT

first_qft_output = QReg(size=3)
second_qft_output = QReg(size=3)

model_designer = ModelDesigner()

qft_params = QFT(num_qubits=first_qft_output.size)
# First call
model_designer.QFT(
    qft_params,
    out_wires=first_qft_output,
)

# Second call
model_designer.QFT(
    qft_params,
    in_wires=first_qft_output,
    out_wires=second_qft_output,
)

circuit = model_designer.synthesize()
circuit.show()

Functions with multiple inputs/outputs

When a function requires only one input or output (like QFT in the above example), then a single QReg can be passed. However, when functions require multiple inputs/outputs, then they may be passed either by order or by name (similar to most programming languages). When sending by order, an iterable of QRegs is required. e.g. in_wires=[QReg(size=3), QReg(size=4)]. When sending by name, a dictionary of type Dict[str, QReg] is required.

Quantum Registers - Arithmetic Types

A QReg can be thought of as a collection of qubits, with no particular meaning. Some meaning can be given, for example, by calling these collection of qubits an integer, or, QInt.

Thus, let us introduce 4 new types, which have 2 categories. The first category is whether the QReg is signed or unsigned. The second category treats numbers as fixed-points, i.e. a fractional number with a known amount of digits of their fractional part. Thus, an integer is a fixed-point number with 0 fractional digits.

The 4 new types are: QUInt, QSInt, QUFixed, QSFixed, with U and S signifying "Unsigned" or "Signed" respectively. They can be initialized as follows:

from classiq import QUInt, QSInt, QUFixed, QSFixed

my_quint = QUInt(size=1)
my_qsint = QSInt(size=2)
my_qufixed = QUFixed(size=3, fraction_places=1)
my_qsfixed = QSFixed(size=4, fraction_places=2)

Calling arithmetic functions

When calling arithmetic functions, we need to:

  1. Create a FunctionParams object
  2. Call the function using the model_designer

This is done as follows:

from classiq import ModelDesigner, QSInt, QUInt
from classiq.builtin_functions import BitwiseAnd

x = QSInt(size=5)
y = QUInt(size=3)

params = BitwiseAnd(
    left_arg=x.to_register_user_input(), right_arg=y.to_register_user_input()
)
model_designer = ModelDesigner()
model_designer.BitwiseAnd(
    params,
    out_wires=[x, y]
    # Alternatively, it is possible to pass it by order, as follows:
    # out_wires={
    #     "left_arg": x,
    #     "right_arg": y,
    # }
)
circuit = model_designer.synthesize()