Classical Computations in QUA

This section describes standard syntax rules for classical computations in QUA.

Arithmetic expressions

multiplication, addition and subtraction of fixed point varibales is supported.

Note

division incurs a computational overhead of approximately 400nsec per operation.

Operator

symbol

example

multiplication

*

a*b

division

/

a/b

addition

+

a+b

subtraction

-

a-b

left bitshift

<<

a<<2

right bitshift

>>

a>>2

with program() as prog:

        a = declare(fixed)
        b = declare(int)
        c = declare(fixed, value=0.3)
        d = declare(fixed, value=-0.02)
        e = declare(int, value=3)
        f = declare(int, value=5)

        assign(a, c*d-d+c*0.25)
        assign(b, e+f*123*e-e)
        assign(c, b/a)

        save(a, "a")
        save(b, "b")
        save(c, "c")

The evaluation of each operator takes only a few clock cycles. For example, the addition (+) and substraction (-) operations each take 1 clock cycle to evaluate, i.e. 4ns. However, the compiler parallelizes operations, resulting in a much reduced effective calculation time which will often be zero.

Boolean Operations

Operator

symbol

example

AND

&

a&b

OR

|

a|b

XOR

^

a^b

NOT

~

~a

compounded boolean expressions are supported.

Note

it is necessary to wrap the atomic boolean expressions in paranthesis as seen in the example below, due to python operator precedence rules.

Example:

with if_( (~( a > b )) | ( c > d) ):

Arrays

QUA arrays are defined and accessed as follows.

  1. Declare a new array:

syntax:

declare(fixed/int/bool, size=N)

declare(fixed/int/bool, value=[…])

Examples:

v1 = declare(int, size=3)
v2 = declare(int, value=[1,2,3])
  1. Access cell in array

# syntax and examples
assign(v1[0], 5)
assign(b, v1[i]+6)
assign(v1[i+5], v[i+4])
save(v1[2], "v1_2")
  1. Get array length

# syntax and examples
v1.length()
assign(length, v1.length())

Use example:

with program() as arrays_use:

  v1 = declare(int, value = [1, 2, 4, 8, 16])
  v2 = declare(int, size = 5) # will be initialized with zeros
  v3 = declare(fixed, size = 30)  # will be initialized with zeros
  i = declare(int)

  assign(v3[0], 16)

  with for_(i, 0, i < v2.length(), i + 1):
        assign(v2[i], i*2)

  with for_(i, 0, i < v1.length(), i + 1):
        assign(v2[i], v2[i] + v3[i])

  with for_(i, 0, i < v1.length(), i + 1):
        save(v1[i], "v1")
        save(v2[i], "v2")

  with for_(i, 0, i < v3.length(), i + 1):
        save(v3[i], "v3")

Note

array length is fixed and cannot be changed after declaration.

Note

No validation is performed for reading/writing out of bounds. This will be added in a future version.

Computational library functions

QUA allows the user the real time evaluation of several mathematical operators and functions. Besides the standard mathematical operators (+, -, *, /) the user can access various libraries including

  • Math - trigonometric functions, array reduction functions etc.

  • Random - pseudo-random number generation.

  • Cast - allows casting between QUA variable types.

  • Util - Miscellaneous operators, including a hardware optimized conditional expression.

Math

Trigonometric functions

  • Math.cos(x) : Take the cosine of a fixed in radians

  • Math.sin(x) : Take the sine of a fixed in radians

  • Math.cos2pi(x) : Take the cosine of a fixed in 2pi radians

  • Math.sin2pi(x) : Take the cosine of a fixed in 2pi radians

cos2pi(x) and sin2pi(x) are equivalent to cos(2*pi*x) and sin(2*pi*x) but save a few clock cycles as the extra multiplication stage required to calculate 2*pi are removed by simply having 2*pi stored in memory. So whenever working with degrees instead of radians we suggest using the latter. The usage is straightforward, for example:

amplitude = declare(fixed)
time = declare(int)frequency = declare(int)
assign(amplitude, 1)assign(frequency, 1e6)
with for_(time, 0, time<100, time+1):
    play('pulse_1' * amp(amplitude*Math.cos2pi(frequency*time)), 'element_1')

This program will play pulse_1 for 100 iterations, where for each iteration the amplitude will be modulated by the envelope function cos(2pi*frequency*time). For evaluation of non-real time mathematical expressions one can always use standard python libraries such as numpy.

Array reduction

QUA provides several function to reduce arrays. These functions run much more efficiently (with less latency) when compared to a manual implementing in QUA as they use hardware optimizations.

  • Math.sum(x) : sums an array. result must of the same type as array

  • Math.max(x), Math.min(x) : max,min an array. result must of the same type as array

  • Math.argmin(x)/Math.argmax(x): returns the index of the max/min

  • Math.dot(x,y): returns the dot product of two QUA arrays of the same size

Others

  • Math.abs(x) : absolute value of a QUA variable

Random()

This class generates a pseudo-random number using a the LCG algorithm with the following parameters: a = 137939405, c = 12345, m = 2**28.

The class constructor optionally takes a seed number and can generate int or fixed values.

with program() as prog:
r = Random()
        a = declare(int)
        b = declare(fixed)
        assign(a, r.rand_int(100)) # a will be a number between 0 and 99
        assign(b, r.rand_fixed()) # b will be a number between 0.0 and 1.0
        # you can set the seed:
        r.set_seed(123213)

Cast

  • Cast.mul_fixed_by_int(x,y): Multiplies a fixed x by an int y, returning a fixed

  • Cast.mul_int_by_fixed(x,y): Multiplies an int x by a fixed y, returning an int

  • Cast.to_int(x): Casts a variable to int. Supports int, fixed or bool

  • Cast.to_fixed(x): Casts a variable to fixed. Supports int, fixed or bool

  • Cast.to_bool(x): Casts a variable to bool. Supports int, fixed or bool

Util

  • Util.cond(a,b,c) : Quick conditional operation.

This is equivalent to a ternary operator available in some languages: i.e. a ? b : c, meaning ‘b’ if ‘a’ is true, or ‘c’ if ‘a’ is false. There is less computation overhead (less latency) when running this operation relative to the if_ conditional

assign(b, Util.cond(a > b, c, d))