quantum.py basic demonstration of many quantum operations quantum function initialization complete Dirac notation and corresponding computer program names. A quantum bit, qubit, is represented in bra and ket notation bra is a two complex element column vector with length 1.0 |x> = a|0> + b|1> a and b complex numbers, abs(a^2+b^2)=1 A two qubit system will be on surface of Bloch unit sphere |y> = c|0> + d|1> then |x>|y> = |xy> = four entry vector = ac|00> + ad|01> + bc|10> + bd|11> written as a vector = | ac ad bc bd | just four complex numbers, a 'state' mathematically, tensor product of |a b| with |c d| The complex conjugate of |y> is used, thus d is -d in ad and bd quantum physics computation must be reversible, qubits can not be copied, measurement causes qubit to collapse, Schrodinger's equation and Heisenberg Uncertainty Principle apply. This will work on quantum superposition, vector |ac ad bc bd| can be factored, when |a b| is known into |a b| and |c d| yet, will not work on quantum entanglement. Bell's theorem a quantum entangled state can not be factored notation z^2 is z raised to power 2 notation U^-1 is inverse of U, U^* is complex conjugate transpose of U Unitary transforms, U: U^* U = U U^* = I, U^-1 = U eigenvalues of U are on complex unit circle a state times a unitary transform is a valid state Python definitions of values of ket0, ket1, bra0, bra1 ket0 = [1,0] = |0> = [1, 0] ket1 = [0,1] = |1> = [0, 1] bra0 = [1,0] = <0| = [1, 0] bra1 = [0,1] = <1| = [0, 1] demonstrate use of functions and available constants TP for tensor product ket00 = TP(ket0, ket0) = |0>|0> = |00> = [1, 0, 0, 0] ket01 = TP(ket0, ket1) = |0>|1> = |01> = [0, 1, 0, 0] ket10 = TP(ket1, ket0) = |1>|0> = |10> = [0, 0, 1, 0] ket11 = TP(ket1, ket1) = |1>|1> = |11> = [0, 0, 0, 1] ket000 = TP(ket0, TP(ket0, ket0)) = |0>|0>|0> = |000> = [1, 0, 0, 0, 0, 0, 0, 0] ket000 = TP3(ket0, ket0, ket0) = |0>|0>|0> = |000> = [1, 0, 0, 0, 0, 0, 0, 0] ket001 = TP3(ket0, ket0, ket1) = |0>|0>|1> = |001> = [0, 1, 0, 0, 0, 0, 0, 0] ket010 = TP3(ket0, ket1, ket0) = |0>|1>|0> = |010> = [0, 0, 1, 0, 0, 0, 0, 0] ket011 = TP3(ket0, ket1, ket1) = |0>|1>|1> = |011> = [0, 0, 0, 1, 0, 0, 0, 0] ket100 = TP3(ket1, ket0, ket0) = |1>|0>|0> = |100> = [0, 0, 0, 0, 1, 0, 0, 0] ket101 = TP3(ket1, ket0, ket1) = |1>|0>|1> = |101> = [0, 0, 0, 0, 0, 1, 0, 0] ket110 = TP3(ket1, ket1, ket0) = |1>|1>|0> = |110> = [0, 0, 0, 0, 0, 0, 1, 0] ket111 = TP3(ket1, ket1, ket1) = |1>|1>|1> = |111> = [0, 0, 0, 0, 0, 0, 0, 1] kets can be complex, j in Python, keti = |i> = [1j, 0] complex keti01 = |i>|0>|1> = [0j, 1j, 0j, 0j, 0, 0, 0, 0] factor3(keti01) [1j, 0j] [(1+0j), 0j] [0j, (1+0j)] complex keti10 = |i>|1>|0> = [0j, 0j, 1j, 0j, 0, 0, 0, 0] factor3(keti10) [1, 0] [0j, (1+0j)] [(1+0j), 0j] DP for dot product (actually a measurement returning a probability) DP(bra0, ket0) = <0|0> = <0||0> = 1 DP(bra0, ket1) = <0|1> = <0||1> = 0 DP(bra1, ket0) = <1|0> = <1||0> = 0 DP(bra1, ket1) = <1|1> = <1||1> = 1 demonstrate gates, common unitary matrices Hadamard H= [[0.7071067811865475, 0.7071067811865475], [0.7071067811865475, -0.7071067811865475]] H[0][0]= 0.7071067811865475 H[1][1]= -0.7071067811865475 mulvm(bra0, H) = <0| H = [0.7071067811865475, 0.7071067811865475] mulvm(bra1, H) = <1| H = [0.7071067811865475, -0.7071067811865475] mulmv(H, ket0) = H |0> = [0.7071067811865475, 0.7071067811865475] mulmv(H, ket1) = H |1> = [0.7071067811865475, -0.7071067811865475] measure H |1> in standard basis <1| bra1, probability of |1> is ( <1| (H |1>) )^2 = 0.4999999999999999 probability = measure(bra1, H |1>) = ( <1| (H |1>) )^2 = 0.4999999999999999 Pauli X = Not = PX = [[0.0, 1.0], [1.0, 0.0]] PX |0> = |1> = [0.0, 1.0] PX |1> = |0> = [1.0, 0.0] <0| PX = <1| = [0.0, 1.0] <1| PX = <0| = [1.0, 0.0] Pauli Y PY = [[0.0, -1j], [1j, 0.0]] PY |0> = [0j, 1j] PY |1> = [-1j, 0j] Pauli Z = PZ = [[1, 0], [0, -1]] PZ |0> = [1, 0] PZ |1> = [0, -1] rotation 2/2^4 = 1/8 full circle = R8 = Rk(4) = [[1, 0], [0, (0.9238795325112867+0.3826834323650898j)]] mulmv(R8, ket0) = R8 |0> = [1, 0j] mulvm(R8, ket1) = R8 |1> = [0, (0.9238795325112867+0.3826834323650898j)] probability of |1> is ( <1| (R8 |1>) )^2 = 1.0 Euler's pi/8 R8 = [[1.0, 0.0], [0.0, (0.9238795325112867+0.3826834323650898j)]] controlled rotation CRk(4) = CR8 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, (0.9238795325112867+0.3826834323650898j)]] mulmv(CR4, ket00) = CR4 |0>|0> = [1, 0, 0, 0j] mulmv(CR4, ket01) = CR4 |0>|1> = [0, 1, 0, 0j] mulmv(CR4, ket10) = CR4 |1>|0> = [0, 0, 1, 0j] mulmv(CR4, ket11) = CR4 |1>|1> = [0, 0, 0, (0.9238795325112867+0.3826834323650898j)] extract rotated ket, (Physics?) = [0, (0.9238795325112867+0.3826834323650898j)] must use 'getket' rather than 'factor2' junk, ketx = factor2(mulmv(CR4, Ket11)) ketx = [0j, (1+0j)] two input controlled not gate Cnot = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] pure Cnot, first ket controls, |1> inverts second ket Cnot |00> = |00> = [1, 0, 0, 0] Cnot |01> = |01> = [0, 1, 0, 0] Cnot |10> = |11> = [0, 0, 0, 1] Cnot |11> = |10> = [0, 0, 1, 0] Cnot on a Hadamard ( |1> ( |0>H )) Cnot = [0.0, 0.0, 0.7071067811865475, 0.7071067811865475] extract inverted ket, (Physics?) = [0.7071067811865475, 0.7071067811865475] ( |1> ( |1>H )) Cnot = [0.0, 0.0, -0.7071067811865475, 0.7071067811865475] extract inverted ket = [-0.7071067811865475, 0.7071067811865475] three input controlled not gate CCnot = Toffoli = [[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 1, 0]] CCnot controlled Cnot for 8 cases mulvm(ket000, CCnot) = |000> CCnot = [1, 0, 0, 0, 0, 0, 0, 0] factor(previous) = [[1, 0], [1, 0], [1, 0]] mulvm(ket001, CCnot) = |001> CCnot = [0, 1, 0, 0, 0, 0, 0, 0] factor(previous) = [[0, 1], [0, 1], [0, 1]] mulvm(ket010, CCnot) = |010> CCnot = [0, 0, 1, 0, 0, 0, 0, 0] factor(previous) = [[0, 1], [0, 1], [1, 0]] mulvm(ket011, CCnot) = |011> CCnot = [0, 0, 0, 1, 0, 0, 0, 0] factor(previous) = [[0, 1], [0, 1], [0, 1]] mulvm(ket100, CCnot) = |100> CCnot = [0, 0, 0, 0, 1, 0, 0, 0] factor(previous) = [[0, 1], [1, 0], [1, 0]] mulvm(ket101, CCnot) = |101> CCnot = [0, 0, 0, 0, 0, 1, 0, 0] factor(previous) = [[0, 1], [0, 1], [0, 1]] mulvm(ket110, CCnot) = |110> CCnot = [0, 0, 0, 0, 0, 0, 0, 1] factor(previous) = [[0, 1], [0, 1], [0, 1]] mulvm(ket111, CCnot) = |111> CCnot = [0, 0, 0, 0, 0, 0, 1, 0] factor(previous) = [[0, 1], [0, 1], [1, 0]] unknown how physics would factor this to get output last two bits are correct ket only if first two |1> I used an artificial factor function two input gate Swap = [[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]] mulvm(ket00, Swap) = |0>|0>Swap = |00> Swap = [1, 0, 0, 0] factor(previous) = [[1, 0], [1, 0]] ['|0> ', '|0> '] mulvm(ket01, Swap) = |0>|1>Swap = |01> Swap = [0, 0, 1, 0] factor(previous) = [[0, 1], [1, 0]] ['|1> ', '|0> '] mulvm(ket10, Swap) = |1>|0>Swap = |10> Swap = [0, 1, 0, 0] factor(previous) = [[0, 1], [0, 1]] ['|1> ', '|1> '] mulvm(ket11, Swap) = |1>|1>Swap = |11> Swap = [0, 0, 0, 1] factor(previous) = [[0, 1], [0, 1]] ['|1> ', '|1> '] three input gate, controlled swap, CSwap = Fredkin = [[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1]] mulmv(CSwap, ket001) = CSwap |001> = [0, 1, 0, 0, 0, 0, 0, 0] factor and last two kets not swapped = [(1+0j), 0j] [0j, (1+0j)] mulmv(CSwap, ket101) = CSwap |101> = [0, 0, 0, 0, 0, 0, 1, 0] [(1+0j), 0j] [(1+0j), 0j] factor and last two kets swapped = [(1+0j), 0j] ([0, 1], [0j, (1+0j)], [(1+0j), 0j]) test S = -PZ - PX = [[-0.7071067811865475, -0.7071067811865475], [-0.7071067811865475, 0.7071067811865475]] T = PZ + PX = [[0.7071067811865475, -0.7071067811865475], [-0.7071067811865475, -0.7071067811865475]] QS = KP(Q, S) = [[-0.7071067811865475, -0.7071067811865475, -0.0, -0.0], [-0.7071067811865475, 0.7071067811865475, -0.0, 0.0], [-0.0, -0.0, 0.7071067811865475, 0.7071067811865475], [-0.0, 0.0, 0.7071067811865475, -0.7071067811865475]] RS = KP(R, S) = [[-0.0, -0.0, -0.7071067811865475, -0.7071067811865475], [-0.0, 0.0, -0.7071067811865475, 0.7071067811865475], [-0.7071067811865475, -0.7071067811865475, -0.0, -0.0], [-0.7071067811865475, 0.7071067811865475, -0.0, 0.0]] RT = KP(R, T) = [[0.0, -0.0, 0.7071067811865475, -0.7071067811865475], [-0.0, -0.0, -0.7071067811865475, -0.7071067811865475], [0.7071067811865475, -0.7071067811865475, 0.0, -0.0], [-0.7071067811865475, -0.7071067811865475, -0.0, -0.0]] QT = KP(Q, T) = [[0.7071067811865475, -0.7071067811865475, 0.0, -0.0], [-0.7071067811865475, -0.7071067811865475, -0.0, -0.0], [0.0, -0.0, -0.7071067811865475, 0.7071067811865475], [-0.0, -0.0, 0.7071067811865475, 0.7071067811865475]] s0110 = (ket01-ket10)/sqrt(2) = [0.0, 0.7071067811865475, -0.7071067811865475, 0.0] = -0.7071067811865474 s1001 = (ket10-ket01)/sqrt(2) = [0.0, -0.7071067811865475, 0.7071067811865475, 0.0] = -0.7071067811865474 test utility functions m1 = [[1, 2, 3, 4], [5, 6, 7, 8]] m2 = [[10, 11, 12], [13, 14, 15], [16, 17, 18], [19, 20, 21]] v1 = [10, 11] mulvm(v1,m1) = v1*m1 = [65, 86, 107, 128] v2= [10, 11, 12, 13] mulmv(m1,v2) = m1*v2 = [120, 304] m3 = m1*m2 = [[160, 170, 180], [392, 418, 444]] test getket by number, 0, 1, 2, ... getket(0,ket000) = [1, 0] getket(1,ket010) = [1, 0] getket(2,ket100) = [1, 0] getket(0,ket001) = [0, 1] getket(1,ket011) = [0, 1] getket(2,ket101) = [0, 1] getbra(1,bra01) = [0, 0] test factor on a pure kets, bras same results, added string printout factor(ket0) = [[1, 0]] factor_str(ket0) = ['|0> '] factor(ket00) = [[1, 0], [1, 0]] ['|0> ', '|0> '] factor(ket000) = [[1, 0], [1, 0], [1, 0]] ['|0> ', '|0> ', '|0> '] factor(ket001) = [[0, 1], [0, 1], [0, 1]] ['|1> ', '|1> ', '|1> '] factor(ket010) = [[0, 1], [0, 1], [1, 0]] ['|1> ', '|1> ', '|0> '] factor(ket011) = [[0, 1], [0, 1], [0, 1]] ['|1> ', '|1> ', '|1> '] factor(ket100) = [[0, 1], [1, 0], [1, 0]] ['|1> ', '|0> ', '|0> '] factor(ket101) = [[0, 1], [0, 1], [0, 1]] ['|1> ', '|1> ', '|1> '] factor(ket110) = [[0, 1], [0, 1], [1, 0]] ['|1> ', '|1> ', '|0> '] factor(ket111) = [[0, 1], [0, 1], [0, 1]] ['|1> ', '|1> ', '|1> '] factor_strb(bra01) = ['<1| ', '<1| '] |ab> = (0.1+0.2j) (1.0150803924823923-0.01970287294298902j) |cd> = (0.4+0.3j) (0.972231617366697-0.12342737867857216j) factor2( [(-0.01999999999999999+0.11000000000000001j), (0.12190863747238415+0.1821035856054822j), (0.41194301887585366+0.2966429685675221j), (0.9844613777805878-0.14444446802025063j)] ) = ketab |ab> = [(0.10000000000000002+0.20000000000000004j), (1.0150803924823923-0.01970287294298894j)] ketcd |cd> = [(0.4+0.29999999999999993j), (0.972231617366697-0.12342737867857215j)] |ab> = [(0.1+0.2j), (1.0150803924823923-0.01970287294298902j)] |cd> = [(0.4+0.3j), (0.972231617366697-0.12342737867857216j)] |ef> = [(0.5+0.7j), (1.1541096570313856-0.3032640770897577j)] factor3( [(-0.087+0.041j), (0.010276855339245647+0.1330173438152476j), (-0.06651819118764546+0.17638783903341j), (0.19592141160579904+0.17319699629499619j), (-0.0016785685593386276+0.43668159749685853j), (0.5653885723190807+0.21743099528128063j), (0.5933418165044694+0.6169007304362861j), (1.0923715647861172-0.4652565266100737j)] ) = ketab |ab> = [(0.10000000000000009+0.20000000000000004j), (1.0150803924823926-0.019702872942989204j)] ketcd |cd> = [(0.4+0.3j), (0.972231617366697-0.12342737867857216j)] ketef |ef> = [(0.49999999999999967+0.6999999999999998j), (1.1541096570313856-0.3032640770897575j)] test factor3 [0.5, -0.5, -0.5, 0.0, -0.5, 0.0, 0.0, 0.0] should be 0.5(|000> - |001> - |010> - |100>) [(0.9999999999999999+0j), (-0.9999999999999999+0j)] [(0.7071067811865476+0j), (0.7071067811865475+0j)] [(0.7071067811865476+0j), (0.7071067811865475+0j)] rebuild ketab tp ketcd tp ketef [(0.5+0j), (0.49999999999999994+0j), (0.49999999999999994+0j), (0.49999999999999983+0j), (-0.5+0j), (-0.49999999999999994+0j), (-0.49999999999999994+0j), (-0.49999999999999983+0j)] KP(A,B) Kronecker Product 2,3 * 4,5 = big 8,15 [[1, 2, 3], [4, 5, 6]] [[1, 1, 1, 1, 2], [2, 2, 2, 2, 3], [3, 3, 3, 3, 4], [4, 4, 4, 4, 5]] [[1, 1, 1, 1, 2, 2, 2, 2, 2, 4, 3, 3, 3, 3, 6], [2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 6, 6, 9], [3, 3, 3, 3, 4, 6, 6, 6, 6, 8, 9, 9, 9, 9, 12], [4, 4, 4, 4, 5, 8, 8, 8, 8, 10, 12, 12, 12, 12, 15], [4, 4, 4, 4, 8, 5, 5, 5, 5, 10, 6, 6, 6, 6, 12], [8, 8, 8, 8, 12, 10, 10, 10, 10, 15, 12, 12, 12, 12, 18], [12, 12, 12, 12, 16, 15, 15, 15, 15, 20, 18, 18, 18, 18, 24], [16, 16, 16, 16, 20, 20, 20, 20, 20, 25, 24, 24, 24, 24, 30]] quantum.py3 finished