Fancier teleportation code
rgobbel opened this issue · 1 comments
rgobbel commented
This code is a bit messy, and I don't have time to do a proper cleanup on it, so I'm submitting it here in the hopes that someone can get some use out of it. I found the results of the sample code for Example 1-4 confusing, so I added some more code to make the output easier to understand. The Javascript version uses functions that might not be available in the context of a real quantum computer, so beware.
First the Javascript:
// Programming Quantum Computers
// by Eric Johnston, Nic Harrigan and Mercedes Gimeno-Segovia
// O'Reilly Media
// To run this online, go to http://oreilly-qc.github.io?p=4-1
// This sample demonstrates basic teleportation.
qc.reset(5);
qc.clearOutput();
function random_bit() {
if (Math.random() < 0.5)
return 0;
else
return 1;
}
var inPhase = 45
function random_phase() {
if (Math.random() < 0.5)
return inPhase;
else
return -inPhase;
}
function gen_payload()
{
qc.label('gen payload');
result = random_bit();
qc.label('');
qc.nop();
return result;
}
var check = qint.new(1, 'check');
var signal = qint.new(1, 'signal');
var alice = qint.new(1, 'alice');
var ep = qint.new(1, 'ep');
var bob = qint.new(1, 'bob');
//var alice_out = 0;
//var ep_out = 0;
var b_in = 0;
var rphase = random_phase();
var payload = gen_payload();
signal.write(payload);
qc.print('payload='+payload+'\n');
// This will work with entangle() and alice_prep() in either order.
// Try swapping them to verify this.
entangle();
alice_prep(payload);
var [alice_out, ep_out] = alice_send();
//alice_out = outs[0];
//ep_out = outs[1];
qc.print('after send, a='+alice_out+', e='+ep_out+'\n');
bob_receive(alice_out, ep_out);
bob_verify(payload);
function entangle()
{
// First, create an entangled pair
qc.label('entangle');
qc.write(0, ep.bits()|bob.bits());
ep.had();
bob.cnot(ep);
qc.label('');
qc.nop();
}
function alice_prep(pl)
{
// Alice prepares her payload to teleport
qc.label('prep payload');
alice.write(pl);
alice.had();
qc.print('rphase='+rphase+'\n');
alice.phase(rphase);
alice.had();
qc.print('ppa:'+alice.peekProbability().toFixed(2)+'\n');
qc.label('');
qc.nop();
}
function alice_send()
{
// Alice sends the payload (and destroys it in the process)
qc.label('send');
ep.cnot(alice);
alice.had();
a_out = alice.read();
e_out = ep.read();
qc.print('in send, a='+a_out+', e='+e_out+'\n');
qc.label('');
qc.nop();
return [a_out, e_out];
}
function bob_receive(a_val, ep_val)
{
// Bob receives the payload, using the two bits Alice sent
qc.label('receive');
var bob_is_asleep = false;
var use_conditonal_gates = true;
// Option 1: Bob is asleep (can't respond to Alice's data), so he just does whatever.
if (bob_is_asleep)
{
bob.not();
bob.phase(180);
}
// // Option 2: Bob is responsive, and we use conditional-ops for visual clarity
else if (use_conditonal_gates)
{
// Here, we use conditional gates, just for visual clarity.
// The "conditions" are on qubits which have already been read and
// turned into classical bits.
bob.cnot(ep);
bob.cz(alice);
}
// Option 3: Bob is responsive, and we use straightforward "if" in the code.
else
{
if (ep_val)
bob.not();
if (a_val)
bob.phase(180);
}
qc.print('ppb:'+bob.peekProbability().toFixed(2)+'\n');
qc.label('');
qc.nop();
}
function bob_verify(payload)
{
// Verify that the teleportation worked
qc.label('verify');
bob.had();
bob.phase(-rphase);
bob.had();
check.write(0);
check.had();
bob.exchange(signal, 0x1, check.bits());
// bob.exchange(signal, 0x1);
check.had();
check.not();
check_ok = check.read();
//result = bob.read();
// if (result == payload)
if (check_ok == 1)
qc.print('MATCH: ');
else
qc.print('MISMATCH: ');
// qc.print('payload = '+payload+', result = '+result+', a_out = '+a_out+', e_out = '+e_out+' -> ('+check_ok+''+e_out+''+a_out+''+result+')\n');
qc.print('a_out = '+a_out+', e_out = '+e_out+' -> ('+check_ok+''+e_out+''+a_out+')\n');
qc.label('');
qc.nop();
}
then the OpenQASM:
// Programming Quantum Computers
// by Eric Johnston, Nic Harrigan and Mercedes Gimeno-Segovia
// O'Reilly Media
// To run this on an actual quantum computer,
// 1. go to https://quantum-computing.ibm.com
// 2. Click "Switch to Qasm Editor" and paste in the code sample.
// To run the JS version in a browser, go to http://oreilly-qc.github.io?p=4-1
// This sample demonstrates basic teleportation (postselected).
include "qelib1.inc";
qreg check[1];
qreg signal[1]; // for checking: this register must match alice
qreg alice[1];
qreg ep[1];
qreg bob[1];
creg read_send[4];
creg results[1];
// Step 1: Create an entangled pair
h ep[0];
reset check[0];
cx ep[0], bob[0];
barrier check[0], signal[0], alice[0], ep[0], bob[0];
// Step 2: Prepare a payload
reset alice[0];
reset signal[0];
x alice[0];
x signal[0];
h alice[0];
t alice[0];
h alice[0];
barrier check[0], signal[0], alice[0], ep[0], bob[0];
// Step 3: Send
cx alice[0], ep[0];
h alice[0];
measure ep[0] -> read_send[1];
measure alice[0] -> read_send[0];
barrier alice[0], ep[0], bob[0];
// Step 4: Receive
cx ep[0], bob[0];
cz alice[0], bob[0];
barrier alice[0], ep[0], bob[0];
// Step 5: Verify
// correct results will have a 1 in the top bit,
// with the next two bits having the same value
h bob[0];
tdg bob[0];
h bob[0];
barrier check[0], signal[0], bob[0];
h check[0];
cswap check[0], signal[0], bob[0];
h check[0];
x check[0];
measure check[0] -> results[0];
barrier check[0], signal[0], bob[0];
// these two are optional, just for information, could be omitted
measure signal[0] -> read_send[2];
measure bob[0] -> read_send[3];