# Quantum Registers¶

Quantum registers, or QRegs, are objects that are available in the 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. As an example, let's call QFT twice. Here is a possible implementation:

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()