One of the fundamental phenomena in quantum physics and computer programming is quantum entanglement. This phenomenon occurs in the case of two quantum particels which are entangled and that causes that making a measurement on one of these qubits will not only determine the value for this qubit, but will also determine the value for the other qubit, immediately. Regardless of the distance between them. The CNOT gate described in the previous article is most often used to entangle qubits. However, nothing stands in the way of entangling more qubits in more advanced algorithms.
As in the previous article, we create a host that is a classical computer that queries the quantum library and waits for the results.
using Microsoft.Quantum.Simulation.Simulators;
using Quantum.QuantumDreamLibrary;
using System;
namespace QuantumDream
{
static class Program
{
static void Main(string[] args)
{
using (var sim = new QuantumSimulator())
{
var result = EntangleTest.Run(sim,10000).Result;
var (numZeros1, numOnes1, numZeros2, numOnes2) = result;
Console.WriteLine($"Zero1 {numZeros1}, One1 {numOnes1}, Zero2 {numZeros2}, One2 {numOnes2}");
Console.WriteLine("Press any key to continue");
Console.ReadKey();
}
}
}
}
var result = EntangleTest.Run(sim,10000).Result;
In the run method, we pass the simulator and the parameters needed to start the operation. In this case, the operations are repeated 10,000 times.
var (numZeros1, numOnes1, numZeros2, numOnes2) = result;
We read the obtained results.
The quantum code looks like this:
namespace Quantum.QuantumDreamLibrary {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
@EntryPoint()
operation EntangleTest(count : Int) : (Int, Int, Int, Int) { //the operation accepts only one parameter responsible for the number of measurements, four Int values are returned {
mutable numOnesQubit1 = 0; // occurrence counter 1 for the first qubit
mutable numOnesQubit2 = 0; // occurrence counter 1 for the second qubit
use (qubit1, qubit2) = (Qubit(), Qubit()); //allocating 2 qubits
for i in 1..count {
SetQubitState(Zero, qubit1); //resetting qubits before another iteration
SetQubitState(Zero, qubit2);
H(qubit1); //using a Hadamar gate to set qubit in a superposition state
CNOT(qubit1, qubit2); //using a CNOT gate to Entangle qubits
let resultQubit1 = M(qubit1); //making a measurement on qubit 1 determines the values for qubit1 and qubit2
let resultQubit2 = M(qubit2); //taking a measurement of qubit 2 which already has a fixed value
if resultQubit1 == One {
set numOnesQubit1 += 1;
}
if resultQubit2 == One {
set numOnesQubit2 += 1;
}
}
// reset qubits to state |0>
SetQubitState(Zero, qubit1);
SetQubitState(Zero, qubit2);
// returning values
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQubit1, numOnesQubit1, count - numOnesQubit2, numOnesQubit2 );
}
//an operation that sets the state of a qubit to |0> or |1>
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) { // taking a measurement and checking if the qubit value is as expected
X(target); //using the Not gate (pauli gate X) to reverse the value
}
}
}
We should get the same number of ones and zeros for the first and second qubits. The probability for the first and second outcomes is 50%, so the outcomes for both values will be close to 5000.
The project is available for download here