- quantum computation simulator
- pure golang implementation
- no external library used
qsim := q.New()
// generate qubits of |0>|0>
q0 := qsim.Zero()
q1 := qsim.Zero()
// apply quantum circuit
qsim.H(q0).CNOT(q0, q1)
for _, s := range qsim.State() {
fmt.Println(s)
}
// [00][ 0]( 0.7071 0.0000i): 0.5000
// [11][ 3]( 0.7071 0.0000i): 0.5000
m0 := qsim.Measure(q0)
m1 := qsim.Measure(q1)
// if m0.IsZero() is true, m1.IsZero() is also true
// if m0.IsOne() is true, m1.IsOne() is also true
for _, s := range qsim.State() {
fmt.Println(s)
}
// [00][ 0]( 1.0000 0.0000i): 1.0000
// or
// [11][ 3]( 1.0000 0.0000i): 1.0000
qsim := q.New()
// generate qubits of |phi>|0>|0>
phi := qsim.New(1, 2)
q0 := qsim.Zero()
q1 := qsim.Zero()
// |phi> is normalized. |phi> = a|0> + b|1>, |a|^2 = 0.2, |b|^2 = 0.8
for _, s := range qsim.State(phi) {
fmt.Println(s)
}
// [0][ 0]( 0.4472 0.0000i): 0.2000
// [1][ 1]( 0.8944 0.0000i): 0.8000
qsim.H(q0).CNOT(q0, q1)
qsim.CNOT(phi, q0).H(phi)
// Alice send mz, mx to Bob
mz := qsim.Measure(phi)
mx := qsim.Measure(q0)
// Bob Apply X and Z
qsim.ConditionX(mx.IsOne(), q1)
qsim.ConditionZ(mz.IsOne(), q1)
// Bob got |phi> state with q1
for _, s := range qsim.State(q1) {
fmt.Println(s)
}
// [0][ 0]( 0.4472 0.0000i): 0.2000
// [1][ 1]( 0.8944 0.0000i): 0.8000
qsim := q.New()
q0 := qsim.New(1, 2) // (0.2, 0.8)
// encoding
q1 := qsim.Zero()
q2 := qsim.Zero()
qsim.CNOT(q0, q1).CNOT(q0, q2)
// error: first qubit is flipped
qsim.X(q0)
// add ancilla qubit
q3 := qsim.Zero()
q4 := qsim.Zero()
// error correction
qsim.CNOT(q0, q3).CNOT(q1, q3)
qsim.CNOT(q1, q4).CNOT(q2, q4)
m3 := qsim.Measure(q3)
m4 := qsim.Measure(q4)
qsim.ConditionX(m3.IsOne() && m4.IsZero(), q0)
qsim.ConditionX(m3.IsOne() && m4.IsOne(), q1)
qsim.ConditionX(m3.IsZero() && m4.IsOne(), q2)
// decoding
qsim.CNOT(q0, q2).CNOT(q0, q1)
for _, s := range qsim.State(q0) {
fmt.Println(s)
}
// [0][ 0]( 0.4472 0.0000i): 0.2000
// [1][ 1]( 0.8944 0.0000i): 0.8000
qsim := q.New()
// initial state
q0 := qsim.Zero()
q1 := qsim.Zero()
q2 := qsim.Zero()
q3 := qsim.Zero()
// superposition
qsim.H(q0, q1, q2, q3)
// iteration
N := number.Pow(2, qsim.NumberOfBit())
r := math.Floor(math.Pi / 4 * math.Sqrt(float64(N)))
for i := 0; i < int(r); i++ {
qsim.X(q2, q3)
qsim.H(q3).CCCNOT(q0, q1, q2, q3).H(q3)
qsim.X(q2, q3)
qsim.H(q0, q1, q2, q3)
qsim.X(q0, q1, q2, q3)
qsim.H(q3).CCCNOT(q0, q1, q2, q3).H(q3)
qsim.X(q0, q1, q2, q3)
qsim.H(q0, q1, q2, q3)
}
for _, s := range qsim.State() {
fmt.Println(s)
}
// [0000][ 0]( 0.0508 0.0000i): 0.0026
// [0001][ 1]( 0.0508 0.0000i): 0.0026
// [0010][ 2]( 0.0508 0.0000i): 0.0026
// [0011][ 3]( 0.0508 0.0000i): 0.0026
// [0100][ 4]( 0.0508 0.0000i): 0.0026
// [0101][ 5]( 0.0508 0.0000i): 0.0026
// [0110][ 6]( 0.0508 0.0000i): 0.0026
// [0111][ 7]( 0.0508 0.0000i): 0.0026
// [1000][ 8]( 0.0508 0.0000i): 0.0026
// [1001][ 9]( 0.0508 0.0000i): 0.0026
// [1010][ 10]( 0.0508 0.0000i): 0.0026
// [1011][ 11]( 0.0508 0.0000i): 0.0026
// [1100][ 12](-0.9805 0.0000i): 0.9613 -> answer!
// [1101][ 13]( 0.0508 0.0000i): 0.0026
// [1110][ 14]( 0.0508 0.0000i): 0.0026
// [1111][ 15]( 0.0508 0.0000i): 0.0026
N := 15
a := 7 // co-prime
for i := 0; i < 10; i++{
qsim := q.New()
// initial state
q0 := qsim.Zero()
q1 := qsim.Zero()
q2 := qsim.Zero()
q3 := qsim.Zero()
q4 := qsim.Zero()
q5 := qsim.Zero()
q6 := qsim.One()
// superposition
qsim.H(q0, q1, q2)
// Controlled-U
qsim.CNOT(q2, q4)
qsim.CNOT(q2, q5)
// Controlled-U^2
qsim.CNOT(q3, q5).CCNOT(q1, q5, q3).CNOT(q3, q5)
qsim.CNOT(q4, q6).CCNOT(q1, q6, q4).CNOT(q4, q6)
// inverse QFT
qsim.Swap(q0, q2)
qsim.InvQFT(q0, q1, q2)
// measure q0, q1, q2
m := qsim.Measure(q0, q1, q2).BinaryString()
// find s/r. 0.010 -> 0.25 -> 1/4, 0.110 -> 0.75 -> 3/4, ...
s, r, d, ok := number.FindOrder(a, N, fmt.Sprintf("0.%s", m))
if !ok || number.IsOdd(r) {
continue
}
// gcd(a^(r/2)-1, N), gcd(a^(r/2)+1, N)
p0 := number.GCD(number.Pow(a, r/2)-1, N)
p1 := number.GCD(number.Pow(a, r/2)+1, N)
if number.IsTrivial(N, p0, p1) {
continue
}
// result
fmt.Printf("i=%d: N=%d, a=%d. p=%v, q=%v. s/r=%d/%d ([0.%v]~%.3f)\n", i, N, a, p0, p1, s, r, m, d)
}
// i=2: N=15, a=7. p=3, q=5. s/r=1/4 ([0.010]~0.250)
p0, q0 := 0.1, qubit.Zero()
p1, q1 := 0.9, qubit.Zero().Apply(gate.H())
rho := density.New().Add(p0, q0).Add(p1, q1)
rho.Trace() // -> 1
rho.ExpectedValue(gate.X()) // -> 0.9
- Michael A. Nielsen, Issac L. Chuang, Quantum Computation and Quantum Information
- C. Figgatt, D. Maslov, K. A. Landsman, N. M. Linke, S. Debnath, and C. Monroe, Complete 3-Qubit Grover Search on a Programmable Quantum Computer
- Zhengjun Cao, Zhenfu Cao, Lihua Liu, Remarks on Quantum Modular Exponentiation and Some Experimental Demonstrations of Shor’s Algorithm
- Michael R. Geller, Zhongyuan Zhou, Factoring 51 and 85 with 8 qubits
- Programming Quantum Computers by Eric R. Johnson, Nic Harrigan, and Merecedes Gimeno-Segovia (O'Reilly)