Skip to content

Modulo

The Modulo operation (denoted as '%') returns the remainder (called "modulus") of a division. Given two numbers \(a\) and \(n\), the result of (\(a\) % \(n\)) is the remainder of the division of a by n. When n equals \(2^m\) for an integer \(m\), the modulo operation's result will be the \(m\) least significant bits.

For example, The binary representation of the number \(53\) is \(0b110101\). The expression (\(53\) % \(8\)) equals \(0b101 = 5\), because \(8 = 2^3\), which means we only account for the \(3\) least significant bits of \(53\).

Implementation

Modulo is not implemented in the Classiq platform as a function like other arithmetic operations. Instead, it changes the size of the output register of the previous function.

The modulo operation is supported only for \(n = 2^m\) for an integer \(m\), and only for the modulo of a function, like (\((a + b) % 4\)). The modulo operation does not currently support modulo of a register directly (e.g. the expression (\(a\) % \(4\))).

If an expression is defined using modulo operation, the output size is set recursively to all of its subexpressions. But if for some sub-expressions, another modulo operation is used, the sub-expression's output_size will be determined by the minimal value between the output_size of the sub-expression and the expression.

Let's explain it, using an example: \(((a + b) % 4) + (c + d) % 8\). In this case, the result of expression \(a + b\) is saved on a 2-qubit register, and the results of expressions \(c + d\) and \((a + b) % 4) + (c + d)\) are saved using 3 qubits each.

Example: Modulo after an adder function

{
  "logic_flow": [
    {
      "function": "Arithmetic",
      "function_params": {
        "expression": "(a + b) % 4 == 3",
        "definitions": {
          "a": {
            "size": 5
          },
          "b": {
            "size": 5
          }
        }
      }
    }
  ]
}
from classiq import Model, RegisterUserInput
from classiq.builtin_functions import Arithmetic

expression = "(a + b) % 4 == 3"
definitions = dict(a=RegisterUserInput(size=5), b=RegisterUserInput(size=5))
oracle_params = Arithmetic(expression=expression, definitions=definitions)
model = Model()
model.Arithmetic(oracle_params)
circuit = model.synthesize()
circuit.show_interactive()

This example generates a circuit which adds two 5-qubit arguments: a on qubits 0-4, and b on qubits 5-9. The adder result should have been calculated on a 6 qubits register. However, the modulo operation decides that the output register of the adder will only contain its 2 least significant qubits, and thus the adder result is written to a 2 qubits register, on qubits 10-11.

Output circuit:

img_1.png