next up previous contents
Next: Quantum Registers and Expressions Up: QCL Previous: Introducing QCL   Contents

Subsections

Classic Expressions and Variables


Constant Expressions

The classic data-types of QCL are the arithmetic types int, real and complex and the general types boolean and string.


Table 2.2: classic types and literals
Type Description Examples
int integer 1234, -1
real real number 3.14, -0.001
complex complex number (0,-1), (0.5, 0.866)
boolean logic value true, false
string character string "hello world", ""


Integer

The QCL type int is based on the C data type singed long. On a 32bit computer, this typically allows values form $-2^{31}$ to $2^{31}-1$. While this is more than enough for any standard programming task, the implementation of certain combinatoric functions can require some attention.

However, the word-length limitation has no effect on the number of qubits which can be simulated or on the maximum size of quantum registers. 2.1

Real

The QCL type real is based on C data type double, which is typically 64bit. To improve readability, output of real numbers is truncated to a reasonable number of digits.

Real numbers are written in decimal notation and must include the decimal point.

Complex

QCL complex numbers are internally represented as two double floats. This holds for variables of type complex as well as the internal representation of the machine state. Complex numbers are given as (real,imag)-pairs:

\begin{eqnarray*}
\,\mbox{\it const}\,&\leftarrow &
{\,\mbox{\tt (}\,\,\mbox{\i...
...[ \,\mbox{\tt .}\,\left\{ \,\mbox{\it digit}\, \right\} \right]
\end{eqnarray*}



Boolean

Unlike C, logical values have their own data type in QCL. Literals for boolean are true and false:

Strings

String literals are quoted with "character string" and may contain any printable character except `"'.

Operators

Arithmetic Operators

Arithmetic operators generally work on all arithmetic data types and return the most general type (operator overloading), e.g.

qcl> print 2+2;          // evaluates to int
: 4 
qcl> print 2+2.0;        // evaluates to real
: 4.000000 
qcl> print 2+(2,0);      // evaluates to complex
: (4.000000,0.000000)
To allow for clean integer arithmetic there are some exceptions to avoid typecasts:

table 2.3 shows all arithmetic operators ordered from high to low precedence. All binary operators are left associative, thus $a \circ b \circ c=(a \circ b) \circ c$. Explicit grouping can be achieved by using parentheses.


Table 2.3: arithmetic operators
Op Description Example Type Value
^ power (0,1)^-1.5 complex $-\frac{1}{\sqrt{2}} (1+i)$
  integer power (-2)^11 int $-2048$
- unary minus -1 int $1$
* multiplication (0,1)*(0,1) complex $-1$
/ division 3./2 real $\frac{3}{2}$
  integer division 3/2 int $1$
mod integer modulus 100 mod 16 int $4$
+ addition 1.5+1.5 real $3$
- subtraction (1,2)-(0,2) complex $1$


Comparison and Logic Operators

Table 2.4 shows all comparison and logic operators with their argument types. The return type of all operators is boolean.


Table 2.4: comparison and logic operators
Op Description Argument type
== equal all arithmetic, string
!= unequal all arithmetic, string
< less integer, real
<= less or equal integer, real
> greater integer, real
>= greater or equal integer, real
not logic not boolean
and logic and boolean
or logic inclusive or boolean
xor logic exclusive or boolean


Other Operators

QCL defines two more operators, which are mainly used with quantum expressions. They are described in section 2.3.3 and mentioned her only for completeness.

Concatenation
The concatenation operator & combines two quantum registers or two strings. Its precedence is equal to the arithmetic operators + and -.
Size
The size-of operator # gives the length (i.e. the number of qubits) of any quantum expression. This is the operator with the highest precedence.

Functions

Unlike user defined functions (see section 2.5.2), most of QCL's built-in functions are overloaded. Like arithmetic operators, they often accept more then one argument type and evaluate to different return types.

Trigonometric Functions

Trigonometric functions (table 2.5) are defined for int, real and complex arguments. There return type is real or complex, depending on the argument type.

qcl> print sin(0);            // integer or real arguments
: 0.000000                    // evaluate to real, even if the
qcl> print sin(pi);           // result is an integer number
: 0.000000 
qcl> print tanh((0,1)*pi);    // complex arguments evaluate 
: (0.000000,-0.000000)        // to complex

Table 2.5: trigonometric and hyperbolic functions
Funct. Description Funct. Description
sin(x) sine of $x$ sinh(x) hyperbolic sine of $x$
cos(x) cosine of $x$ cosh(x) hyperbolic cosine of $x$
tan(x) tangent of $x$ tanh(x) hyperbolic tangent of $x$
cot(x) cotangent of $x$ coth(x) hyperbolic cotangent of $x$


Exponents and Logarithms

exp, log and sqrt also work on all arithmetic types (table 2.6). Square roots of negative real numbers trigger an error, as do non positive real logarithms.

qcl> print sqrt(-1);
! math error: real square root of negative number
qcl>  print log(-1.0);
! math error: real logarithm of non positive number
qcl> print sqrt((-1,0)),log((-1,0));
: (0.000000,1.000000) (0.000000,3.141593)


Table 2.6: exponential and related functions
Funct. Description
exp(x) $e$ raised to the power of $x$
log(x) natural logarithm of $x$
log(x,n) base-$n$ logarithm of $x$
sqrt(x) square root of $x$


Complex Numbers

For handling and conversion of complex expressions, the functions Re, Im, abs and conj are defined (table 2.7). abs also works on real and int arguments.


Table 2.7: functions for complex numbers
Funct. Description
Re(z) real part of $z$
Im(z) imaginary part of $z$
abs(z) magnitude of $z$
conj(z) complex conjugate of $z$


Rounding

ceil(x) and floor(x) round the real value $x$ up- or downwards to the nearest integer. The rounded value is returned as int.

Maximum and Minimum

The functions max and min take an arbitrary number of int or real arguments and return the maximum or minimum value. The return type is int, if all arguments are integer, and real otherwise.

qcl> print max(3,pi,4);
: 4.000000

GCD and LCM

The greatest common divisor and the least common multiple of a list of integers can be determined by gcd and lcm.

qcl> print gcd(48,72,180),lcm(48,72,180);
: 12 720


Random Numbers

The pseudo function random() returns a random value from the interval $[0,1)$. The generation of random numbers can be determined by providing a seed value with the option -seed. Random numbers cannot be used in the definition of functions and quantum operators.


Table 2.8: other QCL functions
Funct. Description
ceil(x) nearest integer to $x$ (rounded upwards)
floor(x) nearest integer to $x$ (rounded downward)
max(x,...) maximum
min(x,...) minimum
gcd(n,...) greatest common divisor
lcm(n,...) least common multiple
random() random value from $[0,1)$


Symbols

Identifiers

Identifiers are restricted to alphanumeric characters (no underscores) and must begin with a letter. As in C, there is no limit in length and case is significant. Names must not collide with internal keywords.

Constants

Frequently used values can be defined as symbolic constants. The syntax of a constant declaration is

\begin{eqnarray*}\,\mbox{\it const-def}\,\leftarrow \,\mbox{\tt const}\,\,\mbox{\it identifier}\,\,\mbox{\tt =}\,\,\mbox{\it expr}\,\,\mbox{\tt ;}\,\end{eqnarray*}



The definition of pi in the standard include file is e.g.
const pi=3.141592653589793238462643383279502884197;
Constant definitions are not restricted to constant expressions, but keep their value, once defined:
qcl> const seed=random();
qcl> print seed;     
: 0.378990 
qcl> print seed;
: 0.378990

Variables

The definition of variables in QCL is analogous to C:

\begin{eqnarray*}\,\mbox{\it var-def}\,\leftarrow \,\mbox{\it type}\,\,\mbox{\it...
...left[ \,\mbox{\tt =}\,\,\mbox{\it expr}\, \right]\,\mbox{\tt ;}\,\end{eqnarray*}



Classic data types are int, real, complex, boolean and string (see section 2.2.1). If no initial value is given, the new variable is initialised with zero, false or "", respectively.

The value of a variable can be changed by an assignment, as well as several other statements (see section 2.4):

qcl> complex z;          // declare complex variable z
qcl> print z;            // z was initialised with 0
: (0.000000,0.000000) 
qcl> z=(0,1);            // setting z to i
qcl> print z;
: (0.000000,1.000000) 
qcl> z=exp(z*pi);        // assignment to z may contain z
qcl> print z;
: (-1.000000,0.000000) 
qcl> input z;            // ask for user input
? complex z [(Re,Im)] ? (0.8,0.6)
qcl> print z;
: (0.800000,0.600000)
Since the value of variables is by definition not unique, global variables cannot be accessed in routines with mathematical semantics, namely functions and (pseudo-classic) operators.


Scopes and Namespaces

All Symbols share the same namespace, therefore all global identifiers have to be unique, even if they designate different objects. To guarantee consistent behaviour of defined functions and operators, there is no way to undefine a once declared global symbol.

qcl> int f;
qcl> int f(int n) { return f^2; }
! illegal scope: Global symbol f already defined
The option -allow-redefines can be used to suppress errors when a symbol is declared a second time. Redefinitions are then silently ignored and the processing of the input file or line continues. This can be useful for safely including files or shadowing definitions by private versions:
qufunct flip(qureg q) { /* define my own version of flip */ }
set allow-redefines true;
include "dft";          // flip-version in dft.qcl is ignored
set allow-redefines false;
The definition of a symbol can be shown with the list command (see below for an example).

When using qcl interactively (see section 2.1.3.3), the shell command can be used to open a subshell with a temporal scope. This means, that new definitions are only valid within the current subshell.2.2 All temporal symbols are destroyed again, when the subshell is left with exit.

qcl> list x;
: symbol x is undefined.
qcl> shell;
: shell escape
qcl1> int x;
qcl1> list x;
: global symbol x = 0:
int x;
qcl1> exit
qcl> list x;
: symbol x is undefined.



Footnotes

... registers.2.1
As quantum measurements also return integers, measurements must be split for larger registers
... subshell.2.2
Note that this doesn't compromise mathematical semantics of functions and operators, since the existence of used global symbols is checked already when the routine is defined and not just at execution-time.

next up previous contents
Next: Quantum Registers and Expressions Up: QCL Previous: Introducing QCL   Contents

(c) Bernhard Ömer - oemer@tph.tuwien.ac.at - http://tph.tuwien.ac.at/~oemer/