# Quantum Programming Tutorial 1: Bell State

“The Bell state, $$| x_1 x_2 > = \frac{1}{\sqrt{2}} | 00 > + \frac{1}{\sqrt{2}} | 11 >$$ , is of particular interest: if we pick any of the two qubits to measure, we would obtain outcome j0i or j1i with equal probability; and the other qubit is guaranteed to be measured in the same state as the first. This “correlation” between the two qubits are called quantum entanglement. However, this is not to be confused with two correlated random bits each with equal probability of being observed |0> or |1> . Proof of the distinction is omitted for the sake of brevity; we refer the interested reader to the studies on “local hidden variables” theory, Bell’s inequality, and the CHSH game. In essence, the measurement of one qubit intrinsically alters and determines the state of the other. Perhaps even more surprising is that these two qubits can be physically far apart as long as they were previous entangled as a Bell state. To form such a relationship between the two qubits, they must interact with each other, either directly through a two- qubit gate as shown above, or indirectly through a photon or a third qubit (Ding (2020),Chong (2020), University of Chicago, book,Quantum Computer Systems: Research for Noisy Intermediate-Scale Quantum Computers Synthesis Lectures on Computer Architecture)”.

The simplest example for quantum computation is to generate a Bell state from the controlled-not gate to or Cnot with a previous superposition of the qubit and control with the Hadamard gate.

# Qiskit Program

The qiskit code to perform the previously mentioned state of bell is described.

import qiskit
from qiskit.quantum_info import Statevector # the state vector of the required qubits is generated
from qiskit.visualization import plot_state_qsphere # plot the qubits in a qsphere

sv = Statevector.from_label('00') # show the input state 00
plot_state_qsphere(sv.data)  #plot the previous state


mycircuit = qiskit.QuantumCircuit(2,2)# generate the circuit's bell state
mycircuit.h(0)
mycircuit.cx(0,1)
mycircuit.draw('mpl')


new_sv = sv.evolve(mycircuit) # show the output vector state
print(new_sv)
plot_state_qsphere(new_sv.data) # show the plot of  the output qubits

Statevector([0.70710678+0.j, 0.        +0.j, 0.        +0.j,
0.70710678+0.j],
dims=(2, 2))


counts = new_sv.sample_counts(shots=1000) # simulate  with 1000 iterations

from qiskit.visualization import plot_histogram
plot_histogram(counts) # plot the output istogram


### Qiskit Real Quantum Computing

Generate the same circuit on a real quantum computing that use 15 qubits.

qiskit.IBMQ.load_account() # load the token
provider = qiskit.IBMQ.get_provider('ibm-q') # select the provider
backend = provider.get_backend('ibmq_16_melbourne') # select the name of the quatum computer to use
print("real device:",backend.name())

real device: ibmq_16_melbourne

mycircuit.measure([0,1],[0,1]) # we apply the measurement
job = qiskit.execute( mycircuit, backend)
result = job.result()
counts =result.get_counts(mycircuit) # obtain he output values
print("counts: ", counts ) # show the result

counts:  {'01': 47, '00': 502, '11': 442, '10': 33}

qiskit.visualization.plot_histogram(counts) # plot the histogram


# Cirq Program

The cirq code to perform the previously mentioned state of bell is described.

import cirq # call the library

q0 = cirq.GridQubit(0, 0) # call the qubit (0,0)
q1 = cirq.GridQubit(0, 1) # call the qubit (0,1)

circuit = cirq.Circuit() # call the method circuit

circuit.append(cirq.CX(q0,q1)) # adder in the circuit the CX or Cnot gate between q0 and q1

circuit.append(cirq.measure(q0, key='m0'))  # adder the measure in q0
circuit.append(cirq.measure(q1, key='m1')) # adder the measure in q1

print("Circuit:")
print(circuit) # print the circuit at this moment

# Simulate the circuit.

shots = 100 # number of shots in the simulation
simulator = cirq.Simulator() # call the Simulator method
result = simulator.run(circuit, repetitions=shots) # run the circuit in shots time (100 times)
print("Results:")
print(result) # show the results


Circuit:
(0, 0): ───H───@───M('m0')───
│
(0, 1): ───────X───M('m1')───
Results:
m0=0001000110111001000100001000101111100110101111010100101000011000000101101011101111010110001111001011
m1=0001000110111001000100001000101111100110101111010100101000011000000101101011101111010110001111001011

counts = cirq.plot_state_histogram(result) # cal the method to generate a plot


print("Probabiity =", counts/shots) # print the probabilities of every qubit_state

Probabiity = [0.51 0.   0.   0.49]


# QDK Program

The QDK (using Q#) code to perform the previously mentioned state of bell is described.

open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;

operation SetQubitState(desired : Result, target : Qubit) : Unit {
if (desired != M(target)) { // change the target qubit with the  desired value
X(target);
}
}

@EntryPoint()
operation TestBellState(count : Int, initial : Result) : (Int, Int) { // generate the Bell State
mutable numOnes = 0;  // vriable to count
using (qubit = Qubit()) {  // call a qubit

for (test in 1..count) { // for from 1 to 1000
SetQubitState(initial, qubit); // call the  function with (Zero/One,qubit)
H(qubit); // superposition of the value
let res = M(qubit); // measurement  the value of the quit

// Count the number of ones we saw:
if (res == One) {
set numOnes += 1;
}
}

SetQubitState(Zero, qubit);
}

// Return number of times we saw a |0> and number of times we saw a |1>
return (count - numOnes, numOnes);
}

/snippet:(1,94): warning QS6003: The namespace is already open.
/snippet:(2,10): warning QS6003: The namespace is already open.


• SetQubitState
• TestBellState
operation BellState(): Unit{
let (nZero,nOne) = TestBellState(1000,Zero); // call the function with 1000 iterations and flag to detect Zero state
Message($"Probablity of obtain the state |00> :{nZero} ");// print results Message($"Probablity of obtain the state |11> :{nOne} ");

}

• BellState

%simulate BellState

Probablity of obtain the state |00> :510
Probablity of obtain the state |11> :490

()


# Silq Program

The silq code to perform the previously mentioned state of bell is described.

## Introduction to Silq

For this first example we must take into account the following properties of the silq language:

### B type variables are Boolean variables.

x := false:B; // variable boolean x with the value in False

// x, means variable name
// :=, means  assignment
// false, means value in false;
// :B, indicates the type of false value


### Apply pre-defined functions

x := H(x); // the Hadamard gate is applied to the boolean variable x and assigned to the same variable x

// x, means variable name


### Generate a function

def classicalExample(x:𝔹,f:𝔹->𝔹){ // generate a examle function that has a boolean variable x
//and function f that  Boolean mapping to another Boolean
return f(x);              // return the function f
}


To know more about the documentation check the following link : https://silq.ethz.ch/documentation

## Generate cnot function

To generate the denied controlled gate it is necessary to indicate two boolean variables: x,y where x represents the control qubit and if it is true it denies the variable y.

// B means the boolean type
// const mens constant value in this case in the boolean variable x

def cnot(const x:B,y:B):B{ //generate the function Cnot gate
if x{  // if x is true  apply the sentence inside the {}
y := X(y);  // apply X gate in the boolean variable x
}
return y; // return the only
}


## Define main function

We initialize the boolean variables x,y in false or zero state, to the variable x we apply the Hadamard gate, followed by the cnot function where x is the control qubit over the qubit y. Finally, we measure and return the values of the qubits (obtaining their classic values from the two qubits used in the program).

def main(){ // main function

x := false:B;    // A boolean (B type) variable x is initialized in false or zero state (|0>)
y := false:B;    // A boolean (B type) variable x is initialized in false or zero state (|0>)
x := H(x);       // Applying Hadamard to the boolean variable x
y := cnot(x,y);  // It called the function cnot(x,y)
return  measure(x,y);  // return the measure by the x and y variables or qubits.
}


## Expected outputs

(1,1)
or
(0,0)


The previous silq code is in the file called bell_state.sql

# Strawberry Fields

The strawberry fields code to perform the previously mentioned state of bell is described.

import strawberryfields as sf
from strawberryfields import ops


# create a quantum program with 3 qubits
prog = sf.Program(2)

# describe the circuit
with prog.context as q:
ops.Rgate(1.57) | q[0] # call the Sgate
ops.CXgate() | (q[0], q[1]) # call the BSGate
ops.MeasureFock() | q # perform the measurement on all qubits of the variable q

prog.print()
eng = sf.Engine("fock", backend_options={"cutoff_dim": 5}) # generate the simulation
result = eng.run(prog)
print(result.state)
state = result.state
state.trace()
state.dm().shape # density matrix
result.samples #print the output states


Rgate(1.57) | (q[0])
CXgate(1) | (q[0], q[1])
MeasureFock | (q[0], q[1])
<FockState: num_modes=2, cutoff=5, pure=True, hbar=2>

array([[0, 0]])


Tags:

Categories:

Updated: