CLEAR ALL

' medium.com/@dakk/quantum-computing-on-a-commodore-64-in-200-lines-of-basic-eda7658b32a4

REM r* are real parts and i* are imagenary parts of the sv
r0= 1 :i0= 0 :r1= 0 :i1= 0
r2= 0 :i2= 0 :r3= 0 :i3= 0
a0= 0
shots= 28
RANDOMIZE TIMER
CLS
PRINT "C64 Quantum Simulator"
PRINT "Created by Davide Gessa (dakk)"
PRINT "Enter gate seq (x0,x1,y0,y1,z0,z1,h0,h1,cx,sw)"
PRINT "e.g. h0cx"
INPUT g$
g$=LCASE$(TRIM$(g$))
PRINT "Calculating the statevector...";
FOR i = 1 TO LEN(g$) STEP 2
    gate$= MID$(g$, i, 2)
    GOSUB simulate
    PRINT ".";
NEXT i
PRINT

sq= r0*r0 + i0*i0 + r1*r1 + i1*i1 + r2*r2 + i2*i2 + r3*r3 + i3*i3
IF ABS(sq - 1) > 0.00001 THEN GOSUB normalize

PRINT "Running " shots " iterations..."
z0= 0 :z1= 0 :z2= 0 :z3= 0
p0= (r0 * r0 + i0 * i0)
p1= (r1 * r1 + i1 * i1) + p0
p2= (r2 * r2 + i2 * i2) + p1
p3= (r3 * r3 + i3 * i3) + p2

FOR i = 1 TO shots
    r= RND(1)
    IF r < p0 THEN z0 = z0 + 1
    IF r >= p0 AND r < p1 THEN z1 = z1 + 1
    IF r >= p1 AND r < p2 THEN z2 = z2 + 1
    IF r >= p2 AND r < p3 THEN z3 = z3 + 1
NEXT i

PRINT "Results:"
PRINT "00: ["z0"] "; :FOR i = 1 TO z0 :PRINT "O"; :NEXT i :PRINT
PRINT "01: ["z2"] "; :FOR i = 1 TO z2 :PRINT "O"; :NEXT i :PRINT
PRINT "10: ["z1"] "; :FOR i = 1 TO z1 :PRINT "O"; :NEXT i :PRINT
PRINT "11: ["z3"] "; :FOR i = 1 TO z3 :PRINT "O"; :NEXT i :PRINT
GOTO done

REM simulate gate operation
simulate:
IF gate$ = "x0" THEN GOSUB x0Gate
IF gate$ = "x1" THEN GOSUB x1Gate
IF gate$ = "y0" THEN GOSUB y0Gate
IF gate$ = "y1" THEN GOSUB y1Gate
IF gate$ = "z0" THEN GOSUB z0Gate
IF gate$ = "z1" THEN GOSUB z1Gate
IF gate$ = "h0" THEN GOSUB h0Gate
IF gate$ = "h1" THEN GOSUB h1Gate
IF gate$ = "cx" THEN GOSUB cxGate
IF gate$ = "sw" THEN GOSUB swGate
RETURN

REM x0 gate
x0Gate:
a0= r0 :r0= r1 :r1= a0
a0= i0 :i0= i1 :i1= a0
a0= r2 :r2= r3 :r3= a0
a0= i2 :i2= i3 :i3= a0
RETURN

REM x1 gate
x1Gate:
a0= r1 :r1= r3 :r3= a0
a0= i1 :i1= i3 :i3= a0
a0= r0 :r0= r2 :r2= a0
a0= i0 :i0= i2 :i2= a0

REM y0 gate
y0Gate:
a0= i0 :i0= -r0 :r0= a0
a0= i1 :i1= -r1 :r1= a0
a0= i2 :i2= -r2 :r2= a0
a0= i3 :i3= -r3 :r3= a0
RETURN

REM y1 gate
y1Gate:
a0= i1 :i1= -r1 :r1= a0
a0= i3 :i3= -r3 :r3= a0
RETURN

REM z0 gate
z0Gate:
i2= -i2 :i3= -i3
RETURN

REM z1 gate
z1Gate:
i1= -i1 :i3= -i3
RETURN

REM h0 gate
h0Gate:
a0= (r0 + r1) / SQR(2) :a1= (i0 + i1) / SQR(2)
b0= (r0 - r1) / SQR(2) :b1= (i0 - i1) / SQR(2)
r0= a0 :i0= a1 :r1= b0 :i1= b1
a0= (r2 + r3) / SQR(2) :a1= (i2 + i3) / SQR(2)
b0= (r2 - r3) / SQR(2) :b1= (i2 - i3) / SQR(2)
r2= a0 :i2= a1 :r3= b0 :i3= b1
RETURN

REM h1 gate
h1Gate:
a0= (r0 + r2) / SQR(2) :a1= (i0 + i2) / SQR(2)
b0= (r0 - r2) / SQR(2) :b1= (i0 - i2) / SQR(2)
r0= a0 :i0= a1 :r2= b0 :i2= b1
a0= (r1 + r3) / SQR(2) :a1= (i1 + i3) / SQR(2)
b0= (r1 - r3) / SQR(2) :b1= (i1 - i3) / SQR(2)
r1= a0 :i1= a1 :r3= b0 :i3= b1
RETURN

REM cx gate
cxGate:
a0= r1 :r1= r3 :r3= a0
a0= i1 :i1= i3 :i3= a0
RETURN

REM sw gate
swGate:
a0= r1 :r1= r2 :r2= a0
a0= i1 :i1= i2 :i2= a0
RETURN

REM statevcector normalization
normalize:
nf= SQR(1 / sq)
r0= r0 * nf
i0= i0 * nf
r1= r1 * nf
i1= i1 * nf
r2= r2 * nf
i2= i2 * nf
r3= r3 * nf
i3= i3 * nf
RETURN

done:
GETKEY a$
END
