Why variables in quantum computers can be a little spooky

Dr James Wootton
Qiskit
Published in
7 min readMay 17, 2018

--

https://www.flickr.com/photos/ibm_research_zurich/35510970180/

Programming a computer means manipulating lots of variables. These come in various types, like int or float or bool. But they are all built from the same thing: bits.

In quantum computers, the basic building block will be a little different. We’ll use qubits, the quantum version of a bit. They have properties that sound a bit like philosophical mumbo-jumbo, like “being both 0 and 1 at the same time”. But it isn’t just mysticism: these properties are well defined and have powerful effects.

One of the most well known examples relates to the so called Bell tests. These are tests that are set up specifically so that standard variables will always pass, but quantum ones can sometimes fail. They therefore provide a measurable way to show that we have moved into the quantum realm.

We now have quantum computers on the cloud. And we have SDKs, like IBM’s QISKit, to program them with. So let’s do some Bell tests!

Bell test for classical variables

Normal computers are known as classical computers, at least by those of us working on more esoteric things. Let’s start off on familiar ground by defining a Bell test for the classical variables that these computers use.

Firstly, we need to define a pair of variables. These can be any type you want (I’ll go for floats) and can be initialized by any kind of process you want (I’ll use some randomness).

def setup_variables ():

r = random.random()

A = r*(2/3)
B = r*(1/3)

return A, B

Next, we need to define some simple hashes. These are just functions we’ll define that take one of the variables as input, and spits out a single bit as output. There are a multitude of ways that this can be done, but we just need to pick two. I refer to these as ‘V’ and ‘H’ type hashes.

Since my variables are floats, I’ll define the hashes as just comparisons to some value. The two different type of hash correspond to two different values used for this. But you could define the hashes to be whatever you want.

def hash2bit ( variable, hash ):

if hash=='V':
bit = (variable<0.5)
elif hash=='H':
bit = (variable<0.25)

bit = str(int(bit)) # output should be the string '0' or '1'

return bit

Bell tests are defined explicitly to determine whether the results we get from these hashes is consistent with what is possible for classical variables. It does this by calculating four numbers. We’ll store these in a Python dictionary, and call them P['HH'], P['HV'], P['VH'] and P['VV'].

Let’s focus on P['HV'] as an example. This is the probability that the bit value derived from an 'H' type hash on A is the same as that from a 'V' type has on B. We will estimate this probability by sampling many times and determining the fraction of samples for which the corresponding bit values agree.

The other probabilities are defined similarly: P['HH'] compares a 'H' type hash on both A and B, P['VV'] compares a V type hash on both, and P['VH'] compares a V type hash on A with a H type has on B.

These probabilities are calculated in the following function. The parameter shots is the number of samples we'll use.

shots = 1024
def calculate_P ( ):

P = {}
for hashes in ['VV','VH','HV','HH']:

P[hashes] = 0
for shot in range(shots):
A, B = setup_variables() a = hash2bit ( A, hashes[0] )
b = hash2bit ( B, hashes[1] )
P[hashes] += (a!=b) / shots

return P

The four numbers we’ll get out are not independent of each other. For example, if we found that P['HV'], P['VH'] and P['VV'] were all zero, we’d know that P['HH'] must be zero too.

To see why, let’s remember what P['HV']=0.0 means. It is the probability that hash2bit(A,H) and hash2bit(B,V) are different. So if it is zero, they must always agree.

hash2bit ( A, H ) = hash2bit ( B, V )        (1)

From P['VV']=0.0 and P['VH']=0.0 we can similarly get

hash2bit ( A, V ) = hash2bit ( B, V )        (2)hash2bit ( A, V ) = hash2bit ( B, H )        (3)

Putting (1) and (2) together implies that

hash2bit ( A, H ) = hash2bit ( A, V )        (4)

Combining this with (3) gives

hash2bit ( A, H ) = hash2bit ( B, H )        (5)

This tells us that hash2bit(A,H) and hash2bit(B,H) never disagree, which is exactly what we set out to prove: P['HH']=0.0.

Using this same principle, we can come up with a more generally applicable bound on what P['HH'] is allowed to do.

P['HH'] ≤ P['HV'] + P['VH'] + P['VV']

The same is true for P['HV'], P['VH'] and P['VV'] too: each of the four probabilities must be no greater than the sum of the other three.

This is what we test with the Bell tests: Do these probabilities obey their upper bound? If they are classical variables, they surely will.

Bell test for quantum variables

If the variables are quantum, the probabilities we derive from them might not obey these bounds.

If you want to see this actually happening, you can test it out for yourself. Here’s a Jupyter notebook with the setup_variables(), hash2bit() and calculate_P() functions all set up for a pair of qubits A and B.

All it needs is for you to fill in the quantum program to actually tell A and B what to do, and to convince them to do what classical variables cannot. Since that probably seems a rather daunting task, I made it into a game for you.

With this you can make a program that run counter to the logic we used before. It will do what we proved was impossible. It will give us an output that looks like this.

The upper bound for P['VV'] is 1.1484375
The value of P['VV'] is 0.150390625
The upper bound is obeyed :)

The upper bound for P['VH'] is 1.14453125
The value of P['VH'] is 0.154296875
The upper bound is obeyed :)

The upper bound for P['HV'] is 1.15625
The value of P['HV'] is 0.142578125
The upper bound is obeyed :)

The upper bound for P['HH'] is 0.447265625
The value of P['HH'] is 0.8515625
!!!!! This has gone well over the upper bound :O !!!!!

Here P['HH'] doesn’t just exceed its upper bound by a little bit. If it did, we could explain it away by numerical inaccuracies, or the statistical noise from averaging over a limited number of samples. But these can’t explain the fact that P['HH'] is almost double the value it supposedly can never be greater than.

So what is going on here? The chain of logic we based the Bell test on obviously doesn’t apply to quantum variables. But why?

The answer is that there is a hidden assumption in that logic. We used it to derive point (4).

hash2bit ( A, H ) = hash2bit ( A, V )        (4)

Here we compare the value we’d get from an H type of hash of the variable A with that for a V type hash.

For classical variables, this is perfectly sensible. There is nothing stopping us from calculating both hashes and comparing the results. Even if calculating the hash of a variable changes the variable, that’s not a problem. All we need to do is copy it beforehand and we can do both hashes without any issue.

The same is not true for quantum variables. The result of the hashes is not known until we actually do them. It’s only then that the qubit actually decides what bit value to give. And once it decides the value for one type of hash, we can never determine what it would have decided if we had used another type of hash. We can’t get around this by copying the quantum variables either, because quantum variables cannot be copied. This means there is no context in which the values hash2bit(A,H) and hash2bit A,V) are well-defined at the same time, and so it is impossible to compare them.

Another hidden assumption is that hash2bit(A,hash) depends only on the type of hash chosen for variable A, and not the one chosen for variable B. This is also perfectly sensible, since this exactly the way we set up the hash2bit() function. However, the very fact that the upper bound was violated does seem to imply that each variable knows what hash is being done to the other, so they they can conspire to give very different behaviour when both have a H type hash.

Even so, the effect is subtle. It is impossible to determine which variable is affecting which: You can change the order in which the hashes are done, or effectively do them at the same time, and you’ll get the same results. This means that it is not clear whether we can say they affect each other (see here for some discussion). But what we can say is that they are contextual: to fully understand results from one variable, it is sometimes required to look at what was done to another.

All this goes to show that quantum variables don’t always follow the logic we are used to. They follow different rules, the rules of quantum mechanics, which will allow us to find new ways of performing computation.

Now for actual applications

These tests weren’t designed to have any additional practical applications. So once you have proven quantumness with a Bell test, it might not be entirely clear what you should do with it. To find out about that, you might want to look elsewhere. The QISKit tutorial would be a good place to start.

--

--

Dr James Wootton
Qiskit

Helping to make quantum computers IBM Research . Occasionally misusing them for fun and/or science. Two Ts and no Es. All nonsense here is my own doing