Implement quantum teleportation in qiskit - quantum-computing

I am trying to implement the quantum teleportation protocol from the qiskit textbook in qiskit:
I start with q_0 bit = 1 and I expect that q_3 = 1 at the end but it does not work.
from qiskit import *
qc = QuantumCircuit(3, 3)
qc.x(0) #q -> 1
qc.barrier()
qc.h(1)
qc.cx(1, 2)
qc.barrier()
# Next, apply the teleportation protocol.
qc.cx(0, 1)
qc.h(0)
qc.barrier()
# We measure these qubits and use the classical results to perform an operation
qc.measure(0, 0)
qc.measure(1, 1)
qc.cx(1, 2)
qc.cz(0, 2)
#qc.barrier()
backend = Aer.get_backend('qasm_simulator')
job = execute(qc, backend, shots=1, memory=True).result()
result = job.get_memory()[0]
qc.measure(2, 2)
print(job.get_memory()[0]) #q = 0

It looks like it is working as intended. In the textbook, it says towards the end of the code cell:
In principle, if the teleportation protocol worked, we have q[2] = secret_unitary|0>
As a result, we should be able to recover q[2] = |0> by applying the reverse of secret_unitary
since for a unitary u, u^dagger u = I.
You had your secret_unitary as 'x', which does in fact change Alice's first qubit to 1. But, at the end of the circuit, the dagger of the secret_unitary is applied, cancelling the original application of the secret_unitary. You should expect to see 0 for q[2], as that means that the state from q[0] (in this case, 1) was successfully teleported to q[2], and then brought back to 0 by the dagger of the secret_unitary.

From your code, I have got the circuit. I think the reason that can not get q_3 rightly. Is " Qubit measurement is followed by instructions".After the measurement, you can't do operations anymore.
But I'm not sure this is the reason or not.

Related

Difference between different Quantum states with the same result

What is the practical and theoretical difference is between these 3 states, which ultimately produce the same output result.
Could you tell me some examples of different results obtained starting from these 3 states and doing the same operations below.
The concept is unclear to me.
Thank you
|0> -> RY(pi/2) -> RX(pi) -> cnot q[0] q[1]
|0> -> RX(pi/2) -> cnot q[0] q[1]
|0> -> H -> cnot q[0] q[1]
Not all of these states are the same, assuming that you're talking about the single-qubit states obtained before application of the CNOT gate (otherwise please specify which single-qubit gates are applied to which qubit in the 2-qubit state).
The last state is H|0⟩ = 1/sqrt(2) (|0⟩ + |1⟩).
The first state ends up being the same state, up to a global phase, which means there is no way to observe a difference between these two states.
But the second state is 1/sqrt(2) (|0⟩ - i|1⟩), which behaves differently.
To observe the difference between the second and the last states, apply a Hadamard gate to both and measure them multiple times: you'll always get 0 result for the last state, but you'll get both 0 and 1 for the second state.
To quickly run this experiment, you can use Q#: running the following snippet will give you ~50 0 measurements for the state prepared using Rx and 100 0 measurements for the state prepared using H.
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Math;
operation RunTests (prep : (Qubit => Unit)) : Unit {
mutable n0 = 0;
use q = Qubit();
for _ in 1 .. 100 {
// Prepare the qubit in the given state.
prep(q);
// Apply Hadamard gate and measure.
H(q);
if M(q) == Zero {
set n0 += 1;
}
Reset(q);
}
Message($"{n0} zeros measured");
}
operation QubitsDemo () : Unit {
RunTests(Rx(PI() / 2.0, _));
RunTests(H);
}

Quantum V gate 1/sqrt(5) ( I + 2iZ)

By definition, the gate 1/sqrt(5) (I + 2iZ) should act on a qubit a|0> + b|1> to transform it into 1/sqrt(5) ((1+2i)a|0> + (1-2i)b|1>) but transformations of each RUS step does the following-
The ancillas are in |+> state at first
Starting form: 1/sqrt(2) (a,b,a,b,a,b,a,b)
CCNOT(ancillas, input): 1/sqrt(2) (a,b,a,b,a,b,b,a)
S(input): 1/sqrt(2) (a,ib,a,ib,a,ib,b,ia)
CCNOT(ancillas, input): 1/sqrt(2) (a,ib,a,ib,a,ib,ia,b)
Z(input) : 1/sqrt(2) (a,-ib,a,-ib,a,-ib,ia,-b)
Now measuring the ancillas in PauliX basis is equivalent to PauliZ measurement after applying H() to the state. Now I have 2 confusions, should I apply H x H x I or H x H x H to the combined state. Also neither of these transformations turn out to be equivalent to the V-gate defined in the first paragraph when both measurements are Zero. Where did I go wrong?
Reference: https://github.com/microsoft/Quantum/blob/master/samples/diagnostics/unit-testing/RepeatUntilSuccessCircuits.qs (1st sample code)
The transformation is correct, though it takes some time with pen and paper to verify it.
As a side note, we start with a state |+>|+>(a|0> + b|1>), which is 0.5 (a,b,a,b,a,b,a,b) in vector form (both |+> states contribute a 1/sqrt(2) to the coefficients). It will not affect our calculations of the state after the measurement, since it will have to be renormalized, but it's still worth noting.
After a sequence of CCNOT, S, CCNOT, Z we get 0.5 (a,-ib,a,-ib,a,-ib,ia,-b). Since we're measuring only the first two qubits in PauliX basis, we need to apply Hadamards only to the first two qubits, or H x H x I to the combined state.
I'll take the liberty to skip writing out the whole expression after applying Hadamards and fast-forward to the results of measurements, and here is why. We're only interested in the state of the input qubit if both measurements yielded 0, so it's sufficient to gather only the terms of the overall state which have |00> as the state of the first two qubits.
The state of the third qubit after measuring |00> on the first qubit will be: (3+i)a |0> - (3i+1)b |1>, multiplied by some normalization coefficient c.
c = 1/sqrt(|3+i|^2 + |3i+1|^2) = 1/sqrt(10)).
Now we need to check whether the state we got, |S_actual> = 1/sqrt(10) ((3+i)a |0> - (3i+1)b |1>)
is the same state as we'd expect to get from applying the V gate,
|S_expected> = 1/sqrt(5) ((1+2i)a |0> + (1-2i)b |1>). They do not look the same, but remember that in quantum computing the states are defined up to a global phase. Thus, if we can find a complex number p with an absolute value 1 for which |S_actual> = p * |S_expected>, the states will be effectively the same.
This translates into the following equations for p and amplitudes of |0> and |1>: (3+i)/sqrt(2) = p (1+2i) and -(3i+1)/sqrt(2) = p (1-2i). We solve both equations to get p = (1-i)/sqrt(2) which has indeed the absolute value 1.
Thus, we can conclude that indeed the state we got after all the transformations is indeed equivalent to the state we'd get by applying a V gate.

R apply-like function for updating 2 arrays simultaneously?

I am new to R, and looking for an apply type function to work with 2 arrays at once (simultaneous update).
For example, let's say I have some variables X and P:
X = array(rep(0, 10), dim=c(10, 1))
P = array(rep(1, 10), dim=c(10, 1))
which are governed by the system of equations:
X[k,] = 2*X[k-1]
P[k,] = 3*X[k] + X[k-1] + 3
Obviously, this can easily be accomplished with a for-loop, however, I have read/confirmed myself that for loops work horrendously for large inputs, and I wanted to start getting into good R coding practice, so I am wondering, what is the best way to do this in an apply-type logic? I am looking for something like,
sapply(2:dim(X)[1], function(k) {
X[k,] = 2*X[k-1]
P[k,] = 3*X[k] + X[k-1] + 3
})
But this obviously won't work, as it doesn't actually update X and P internally. Any tips/tricks for how to make my for-loops faster, and get in better R coding practice? Thanks in advance!
You could do the following below. The <<- operator will set X and P outside of the function
sapply(2:dim(X)[1], function(k) {
X[k,] <<- 2*X[k-1]
P[k,] <<- 3*X[k] + X[k-1] + 3
})
As pointed out by thelatemail in the comments, using <<- can be problematic because of the side effects it can have. See the links below, the one comparing for loops (and other loops) to the apply family of functions.
Here is a link to documentation on assignment operators in R.
Here is a StackOverflow link on for loop vs. apply functions that talks about performance.

Freefem Fisher's equation

I'm new with Freefem++, the problem I'm trying to solve is Fisher's equation:
du/dt = d^2u/dx^2 + d^2u/dy^2 + k * u * (1-u)
du/dn = 0 - border condition
I've tried to reformulate the problem in weak form, however Freefem shows a mistake with formula:
problem Fisher(uh, vh) = int2d(Th)(uh * vh/dt + Grad(uh)' * Grad(vh) ) - int2d(Th)(k * uh * vh) + int2d(Th)(uh0 * vh/dt) - int2d(Th)(k * uh * vh * uh);
Could you please tell what I do wrong? Something is wrong with last terms.
This is a 2D transient diffusion/conduction equation with a temperature-dependent, non-linear generation term.
If you leave off the non-linear generation term, the equations should look exactly like the weak form for the 2D transient diffusion/conduction equation.
How does freefem++ linearize that non-linear term? How did you plan to handle it?
You realize, of course, that the last term makes the solution a very different animal. You have to use iteration within time steps to solve it (e.g. a Newton-Raphson solver).
The algorithm becomes an iterative, non-linear one. You won't solve for u anymore; you'll solve for an increment du and iterate until convergence.
You linearize the last term like this:
d(k*u(1-u)) = k*du(1-u) - k*u*du = k*(1-2*u)*du ~ k*du
You still have a product u*du that's non-linear. What to do? Throw it away.
Now you're solving a non-linear transient equation for du.
The easiest way to model Fisher's equations is to linearize the nonlinear part so that the computational method stays stable. In our case it means that in discrete formulations we replace the term u_i(1 - u_i) with u_{i-1}(1 - u_i) (where i is time counter) and choose attentively the space and time steps. Here I provide an example of resulting code:
verbosity=0.;
real Dx=.1,Dy=.1;
mesh Th=square(floor(10./Dx),floor(10./Dy), [-5 + 10*x, -5 + 10*y]);
fespace Vh(Th,P1);
Vh uh, vh, uh0 = ((x)^2+(y)^2)<=1;
real mu = 0.1, dt=0.01, Tf=10., k = 3.0;
macro Grad(u)[dx(u),dy(u)]//
problem KFisher(uh,vh) = int2d(Th)(uh*vh/dt + Grad(uh)'*Grad(vh)*mu) - int2d(Th)(uh0*vh/dt) + int2d(Th)(k*uh0*uh*vh) - int2d(Th)(k*vh*uh0);
for (real t=0.;t<Tf;t+=dt)
{
KFisher;
uh0 = uh;
plot(uh0, cmm="t="+t+"[sec]", dim=2, fill=true, value=true, wait=0);
}

Solving Kakuro puzzles

Here's a good one to reflect on:
http://en.wikipedia.org/wiki/Kakuro
I'm attempting to make a solver for this game. The paperwork is done (reading an initial file with a variable number of columns and rows. It's assumed the input file follows the rules of the game so the game is always solvable. Take your time to read the game rules.
I've taken care of the data structure which I think will suit best:
struct aSquare { int verticalSum; int horizontalSum; int value; }
And made an "array" of these dynamically to work on.
I made it so that the black squares have value of -1 and white squares (the actual solution squares) initialize at 0. You can also get the position of each aSquare struct from the array easily, no need to make additional struct fields for it.
Now the algorithm ... How in the world will I conciliate all these sums and find a general way that will solve all types of grids. I been struggling with this all afternoon to no avail.
Help is appreciated, have fun!
*EDIT: I just realized the actual link I posted has some tips regarding solving techniques. I will still keep this up to see what people come up with.
Regarding Constraint Programming: Here are some different implementations of how to solve a Kakuro puzzle with Constraint Programming (all using the same basic principle). The problem instance is fixed in the program.
Google or-tools/Python: http://www.hakank.org/google_or_tools/kakuro.py
Comet: http://www.hakank.org/comet/kakuro.co
MiniZinc: http://www.hakank.org/minizinc/kakuro.mzn
SICStus: http://www.hakank.org/sicstus/kakuro.pl
ECLiPSe: http://www.hakank.org/eclipse/kakuro.ecl
Gecode: http://www.hakank.org/gecode/kakuro.cpp
Google or-tools/C#: http://hakank.org/google_or_tools/kakuro.cs
Answer Set Programming: http://hakank.org/asp/kakuro.lp
Edit: Added Google or-tools/C# and Answer Set Programming.
A simple brute-force solver for Sudoku takes miliseconds to run, so you don't need to bother implementing any special tactics. I think that in case of Kakuro this will be the same. A simple algorithm:
def solve(kakuro):
if kakuro has no empty fields:
print kakuro
stop.
else:
position = pick a position
values = [calculate possible legal values for that field]
for value in values:
kakuro[position] = value
solve(kakuro)
kakuro[position] = None # unset after trying all possibilities
This algorithm might work better if you find the best order of fields to fill. Try to choose fields which will be the most constrained (as in: there are not many values that are legal).
Anyway, this will be probably the simplest to implement, so try it and look for more sophisticated solvers only if this one will not work. (Actually this is one of the simplest constraint programming solvers; real CP solvers are much more complicated, of course).
If your interest is ultimately in making a software solver for these games, but not getting into the algorithmic details, I recommend using a Constraint Programming (CP) engine. CP is a declarative programming paradigm that is very well suited to these sorts of problems. Several commercial and open source CP engines are available.
http://en.wikipedia.org/wiki/Constraint_programming
I would guess that Linear Programming can be easily used to solve this kind of game.. then this is an integer problem for which exact solutions does exist.. (branch and bound? cutting-plane?)
In any case using a table with the most certain combinations will be useful for sure (eg http://www.enigmoteka.com/Kakuro%20Cheatsheet.pdf)
I have found some nice bit-manipulation tricks that speed up Kakuro solving. You can pick up the source here.
This is straight-forward linear algebra, use vector/matrix manipulation techniques to solve.
[edit - answering the comments]
a + b + 0 + d + 0 = n1
0 + b + c + 0 + e = n2
a + 0 + c + 0 + 0 = n3
a + b + c + 0 + e = n4
a + 0 + c + d + 0 = n5
Above is converted to a matrix, and by adding and subtracting multiples of the rows, you end up with:
a 0 0 0 0 na
0 b 0 0 0 nb
0 0 c 0 0 nc
0 0 0 d 0 nd
0 0 0 0 e ne
No combinatorics, all remain integers.

Resources