Basic examples

We will show you how to write isQ code with some basic examples. For readers interested in the algorithm details, please refer to the textbook Quantum Computation and quantum information written by M.A. Nilsen and I. Chuang. All the examples can be found in the examples folder in isQ open-source code repository.


Bell state

The Bell's states or EPR pairs are specific quantum states of two qubits that represent the simplest (and maximal) examples of quantum entanglement. They can be created using the following circuit:

It can be easily expressed in isQ:

import std;

qbit a, b;

procedure main() {
    H(a);
    CNOT(a, b);
    print M(a);
    print M(b);
}

The measured result should both be 0, or both be 1.


Quantum teleportation

Quantum teleportation is the transfer of a quantum state over a distance. Alice and Bob share an EPR pair and each took one qubit before they became separated. Alice must deliver a qubit of information to Bob, but she does not know the state of this qubit and can only send classical information to Bob.

It is performed step by step as the following:

  1. Alice sends her qubits through a CNOT gate.
  2. Alice then sends the first qubit through a Hadamard gate.
  3. Alice measures her qubits, obtaining one of four results, and sends this information to Bob.
  4. Given Alice's measurements, Bob performs one of four operations on his half of the EPR pair and recovers the original quantum state. The following quantum circuit describes teleportation:

teleport

The corresponding isQ program is as follows:

import std;
procedure transform(qbit a, qbit b, qbit c){
    // Prepare the EPR pair
    H(b);
    CNOT(b, c);

    CNOT(a, b);
    H(a);

    // Fix up the state based on measurement result
    if (M(b)) { X(c); }
    if (M(a)) { Z(c); }
}
procedure main(){
    qbit q[3];
    Rx(pi/3, q[0]); // Set initial state as 'sqrt(0.75)|0>-sqrt(0.25)i|1>'
    transform(q[0], q[1], q[2]);
    print M(q[2]);
}

The measurement result will be consistent with the probability distribution of measuring .


Deutsch-Jozsa algorithm

The Deutsch–Jozsa algorithm is a deterministic quantum algorithm proposed by David Deutsch and Richard Jozsa in 1992. Although of little current practical use, it is one of the first examples of a quantum algorithm that is exponentially faster than any possible deterministic classical algorithm.

We are given a black box quantum computer known as an oracle that implements some function: The function takes n-bit binary values as input and produces either a 0 or a 1 as output for each such value. We are promised that the function is either constant (0 on all inputs or 1 on all inputs) or balanced (1 for exactly half of the input domain and 0 for the other half). The task then is to determine if is constant or balanced by using the oracle.

For a conventional deterministic algorithm, evaluations of will be required in the worst case. However, the quantum solution requires only one evaluation using the following circuit:

deutsch-jozsa

Its corresponding isQ program is as follows:

import std;

oracle bool[1] constant(bool a[4]) {
    bool res[] = {true};
    return res;
}

procedure main()
{
    qbit q[4], anc[1];
    X(anc[0]);
    H(q);
    H(anc[0]);
    constant(q, anc);
    H(q);
    print M(q);
}

Note that we defined a constant oracle that returns 1 for all inputs. Therefore, the printed result should be 0.


Bernstein-Vazirani algorithm

The Bernstein–Vazirani algorithm is a restricted version of the Deutsch–Jozsa algorithm where instead of distinguishing between two different classes of functions, it tries to learn a string encoded in a function. The oracle is defined as the function: where is a secret string and represents addition modulo 2.

Following the same circuit as the Deutsch–Jozsa algorithm, the measurement result of the first register is a secret string.

We write an isQ program to demonstrate the Bernstein–Vazirani algorithm. We select as the secret bitstring and use it to define the oracle g. Note that in its definition, is defined as a bool array, and the addition modulo 2 operation is implemented by the != operator.

import std;

oracle bool[1] g(bool a[4]) {
    bool s[] = {true, true, false, true};
    bool ba[] = s & a;  // bit-wise AND
    bool res[1];
    res[0] = ba[0] != ba[1] != ba[2] != ba[3];
    return res;
}

procedure main(){
    qbit q[4], res[1];
    X(res);
    H(res);
    H(q);
    g(q, res);
    H(q); 
    print M(q); // should print 11 (=0x1011)
}

After execution, the program should print 11, i.e., the secret string .