Skip to content

Addition

The Classiq engine implements the addition operation, denoted '+', according to the following truth table. Here, \(a\) and \(b\) denote numbers, \(i\) a bit index, and \(c_{in / out}\) the incoming and outgoing carries of that step, respectively.

\(a_i\) \(b_i\) \(c_{in}\) \({(a + b)}_i\) \(c_{out}\)
0 0 0 0 0
0 1 0 1 0
1 0 0 1 0
1 1 0 0 1
0 0 1 1 0
0 1 1 0 1
1 0 1 0 1
1 1 1 1 1

Note that integer and fixed-point numbers are represented in a two-complement method during function evaluation. The binary number is extended in the case of a register size mismatch. For example, the positive signed number \((110)_2=6\) is expressed as \((00110)_2\) when operating with a 5-qubit register. Similarly, the negative signed number \((110)_2=-2\) is expressed as \((11110)_2\).

Examples

  • 5 + 3 = 8 , 0101 + 0011 = 1000
  • 5 + -3 = 2, 0101 + 1101 = 0010
  • -5 + -3 = -8, 1011 + 1101 = 1000

Several adder algorithms, differing in depth, number of gates used, and number of auxiliaries, are implemented [1][2].

Syntax

Function: Adder

Parameters:

  • left_arg: Union[float, int, RegisterUserInput] (see RegisterUserInput)
  • right_arg: Union[float, int, RegisterUserInput]
  • output_size: Optional[PositiveInt]
  • inplace_arg: Optional[str] = None

Register names:

  • left_arg: left_arg
  • right_arg: right_arg
  • result: sum
{
  "functions": [
    {
      "name": "main",
      "body": [
        {
          "function": "Adder",
          "function_params": {
            "left_arg": 3.5,
            "right_arg": { "size": 3 },
            "inplace_arg": null
          }
        }
      ]
    }
  ]
}

Argument Override

The inplace_arg argument sets the argument to override. If it is set to None, the input registers are also available as output registers, with the same names. If it is set to left or right, only the right or left argument is available, respectively. The qubits of the overriden argument are used for the result.

Two-Register Addition Example

{
  "functions": [
    {
      "name": "main",
      "body": [
        {
          "function": "Adder",
          "function_params": {
            "left_arg": {"size": 3},
            "right_arg": {"size": 3}
          }
        }
      ]
    }
  ]
}
from classiq import Model, RegisterUserInput, synthesize
from classiq.builtin_functions import Adder

params = Adder(left_arg=RegisterUserInput(size=3), right_arg=RegisterUserInput(size=3))
model = Model()
model.Adder(params)
quantum_program = synthesize(model.get_model())

This code example synthesized a quantum program that adds two arguments. Both left_arg and right_arg are defined as quantum registers of size 3.

This is the synthesized quantum program.

img.png

Float and Register Addition Example

{
  "functions": [
    {
      "name": "main",
      "body": [
        {
          "function": "Adder",
          "function_params": {
            "left_arg": 3.5,
            "right_arg": { "size": 3 },
            "inplace_arg": null
          }
        }
      ]
    }
  ]
}
from classiq import Model, RegisterUserInput, synthesize
from classiq.builtin_functions import Adder

params = Adder(left_arg=3.5, right_arg=RegisterUserInput(size=3))
model = Model()
model.Adder(params)
quantum_program = synthesize(model.get_model())

This code example synthesized a quantum program that adds two arguments. Here left_arg is a fixed-point number \((11.1)_2\) and right_arg is a quantum register of size 3.

This is the synthesized quantum program.

img_1.png

References

[1]S. A. Cuccaro, T. G. Draper, S. A. Kutin, and D. P. Moulton, “A new quantum ripple-carry addition circuit,” Oct. 2004, Accessed: Aug. 09, 2021. http://arxiv.org/abs/quant-ph/0410184

[2]T. G. Draper, “Addition on a Quantum Computer,” Aug. 2000, Accessed: Aug. 09, 2021. http://arxiv.org/abs/quant-ph/0008033