q

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2023 License: MIT Imports: 5 Imported by: 13

README

q

PkgGoDev Go Report Card tests codecov

  • quantum computation simulator
  • pure Go implementation
  • using only the standard library

Example

Bell state

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)
fmt.Println(m0.IsZero() == m1.IsZero()) // always 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

Quantum teleportation

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.CondX(mx.IsOne(), q1)
qsim.CondZ(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

Error correction

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.CondX(m3.IsOne() && m4.IsZero(), q0)
qsim.CondX(m3.IsOne() && m4.IsOne(), q1)
qsim.CondX(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

Grover's search algorithm

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++ {
  // oracle for |110>|x>
  qsim.X(q2, q3)
  qsim.H(q3).CCCNOT(q0, q1, q2, q3).H(q3)
  qsim.X(q2, q3)

  // amplification
  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

Shor's factoring algorithm

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(q6, q4).CCNOT(q1, q4, q6).CNOT(q6, q4)

  // 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)

References

  • Michael A. Nielsen, Issac L. Chuang. Quantum Computation and Quantum Information.

Documentation

Overview

Example (BellState)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.Zero()

	qsim.H(q0).CNOT(q0, q1)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 0.7071 0.0000i): 0.5000
[11][  3]( 0.7071 0.0000i): 0.5000
Example (BellState2)
package main

import (
	"fmt"

	"github.com/itsubaki/q"

	rnd "github.com/itsubaki/q/math/rand"
)

func main() {
	qsim := q.New()
	qsim.Rand = rnd.Const()

	r := qsim.ZeroWith(2)

	qsim.H(r[0])
	qsim.CNOT(r[0], r[1])

	c0 := qsim.Measure(r[0]).Int()
	c1 := qsim.Measure(r[1]).Int()

	fmt.Printf("%v%v\n", c0, c1)

}
Output:

11
Example (DeutschJozsa)
package main

import (
	"fmt"
	"math/rand"
	"time"

	"github.com/itsubaki/q"
)

func main() {
	type FuncType int
	const (
		Constant FuncType = iota
		Balanced
	)

	oracle := func(qsim *q.Q, q0, q1 q.Qubit) FuncType {
		r := rand.New(rand.NewSource(time.Now().UnixNano()))
		if r.Float64() > 0.5 {
			return Constant
		}

		qsim.CNOT(q0, q1)
		return Balanced
	}

	qsim := q.New()
	q0 := qsim.Zero()
	q1 := qsim.One()

	qsim.H(q0, q1)
	ans := oracle(qsim, q0, q1)
	qsim.H(q0)
	m0 := qsim.M(q0)

	if m0.IsZero() && ans == Constant {
		fmt.Println("Correct!")
	}

	if m0.IsOne() && ans == Balanced {
		fmt.Println("Correct!")
	}

}
Output:

Correct!
Example (ErrorCorrection)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.New(1, 2)

	fmt.Println("q0:")
	for _, s := range qsim.State(q0) {
		fmt.Println(s)
	}

	// encoding
	q1 := qsim.Zero()
	q2 := qsim.Zero()
	qsim.CNOT(q0, q1).CNOT(q0, q2)

	// error: first qubit is flipped
	qsim.X(q0)

	fmt.Println("q0(flipped):")
	for _, s := range qsim.State(q0) {
		fmt.Println(s)
	}

	// 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.CondX(m3.IsOne() && m4.IsZero(), q0)
	qsim.CondX(m3.IsOne() && m4.IsOne(), q1)
	qsim.CondX(m3.IsZero() && m4.IsOne(), q2)

	// decoding
	qsim.CNOT(q0, q2).CNOT(q0, q1)

	fmt.Println("q0(corrected):")
	for _, s := range qsim.State(q0) {
		fmt.Println(s)
	}

}
Output:

q0:
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
q0(flipped):
[0][  0]( 0.8944 0.0000i): 0.8000
[1][  1]( 0.4472 0.0000i): 0.2000
q0(corrected):
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
Example (Grover3qubit)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	// NOTE: 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.
	qsim := q.New()

	// initial state
	r := qsim.ZeroWith(3)
	a := qsim.One()

	// superposition
	qsim.H(r...).H(a)

	// oracle for |011>|1>
	qsim.X(r[0]).CCCNOT(r[0], r[1], r[2], a).X(r[0])

	// amplification
	qsim.H(r...).H(a)
	qsim.X(r...).CCZ(r[0], r[1], r[2]).X(r...)
	qsim.H(r...)

	for _, s := range qsim.State(r, a) {
		fmt.Println(s)
	}

}
Output:

[000 1][  0   1](-0.1768 0.0000i): 0.0313
[001 1][  1   1](-0.1768 0.0000i): 0.0313
[010 1][  2   1](-0.1768 0.0000i): 0.0313
[011 1][  3   1](-0.8839 0.0000i): 0.7813
[100 1][  4   1](-0.1768 0.0000i): 0.0313
[101 1][  5   1](-0.1768 0.0000i): 0.0313
[110 1][  6   1](-0.1768 0.0000i): 0.0313
[111 1][  7   1](-0.1768 0.0000i): 0.0313
Example (Grover4qubit)
package main

import (
	"fmt"
	"math"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/math/number"
)

func main() {
	// NOTE: Eric R. Johnson, Nic Harrigan, and Merecedes Gimeno-Segovia. Programming Quantum Computers. O'Reilly.
	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++ {
		// oracle for |110>|x>
		qsim.X(q2, q3)
		qsim.H(q3).CCCNOT(q0, q1, q2, q3).H(q3)
		qsim.X(q2, q3)

		// amplification
		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)
	}

}
Output:

[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
[1101][ 13]( 0.0508 0.0000i): 0.0026
[1110][ 14]( 0.0508 0.0000i): 0.0026
[1111][ 15]( 0.0508 0.0000i): 0.0026
Example (QFT)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.One()
	q2 := qsim.Zero()

	qsim.H(q0)
	qsim.CR(q.Theta(2), q1, q0)
	qsim.CR(q.Theta(3), q2, q0)
	qsim.H(q1)
	qsim.CR(q.Theta(2), q2, q1)
	qsim.H(q2)
	qsim.Swap(q0, q2)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[000][  0]( 0.3536 0.0000i): 0.1250
[001][  1]( 0.0000 0.3536i): 0.1250
[010][  2](-0.3536 0.0000i): 0.1250
[011][  3]( 0.0000-0.3536i): 0.1250
[100][  4]( 0.3536 0.0000i): 0.1250
[101][  5]( 0.0000 0.3536i): 0.1250
[110][  6](-0.3536 0.0000i): 0.1250
[111][  7]( 0.0000-0.3536i): 0.1250
Example (QuantumTeleportation)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	phi := qsim.New(1, 2)
	q0 := qsim.Zero()
	q1 := qsim.Zero()

	fmt.Println("phi:")
	for _, s := range qsim.State(phi) {
		fmt.Println(s)
	}

	qsim.H(q0).CNOT(q0, q1)
	qsim.CNOT(phi, q0).H(phi)

	qsim.CNOT(q0, q1)
	qsim.CZ(phi, q1)

	qsim.Measure(phi, q0)

	fmt.Println("q1:")
	for _, s := range qsim.State(q1) {
		fmt.Println(s)
	}

}
Output:

phi:
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
q1:
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
Example (QuantumTeleportation2)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	phi := qsim.New(1, 2)
	q0 := qsim.Zero()
	q1 := qsim.Zero()

	fmt.Println("phi:")
	for _, s := range qsim.State(phi) {
		fmt.Println(s)
	}

	qsim.H(q0).CNOT(q0, q1)
	qsim.CNOT(phi, q0).H(phi)

	mz := qsim.Measure(phi)
	mx := qsim.Measure(q0)

	qsim.CondX(mx.IsOne(), q1)
	qsim.CondZ(mz.IsOne(), q1)

	fmt.Println("q1:")
	for _, s := range qsim.State(q1) {
		fmt.Println(s)
	}

}
Output:

phi:
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
q1:
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
Example (ShorFactoring15)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/math/number"

	rnd "github.com/itsubaki/q/math/rand"
)

func main() {
	// NOTE: Zhengjun Cao, Zhenfu Cao, Lihua Liu. Remarks on Quantum Modular Exponentiation and Some Experimental Demonstrations of Shor’s Algorithm.
	N := 15
	a := 7

	qsim := q.New()
	qsim.Rand = rnd.Const()

	// 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^(2^0)
	qsim.CNOT(q2, q4)
	qsim.CNOT(q2, q5)

	// Controlled-U^(2^1)
	qsim.CNOT(q3, q5).CCNOT(q1, q5, q3).CNOT(q3, q5)
	qsim.CNOT(q6, q4).CCNOT(q1, q4, q6).CNOT(q6, q4)

	// 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) {
		return
	}

	// 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)

	// check non-trivial factor
	if number.IsTrivial(N, p0, p1) {
		return
	}

	fmt.Printf("N=%d, a=%d. p=%v, q=%v. s/r=%d/%d ([0.%v]~%.3f)\n", N, a, p0, p1, s, r, m, d)

}
Output:

N=15, a=7. p=3, q=5. s/r=3/4 ([0.110]~0.750)
Example (ShorFactoring21)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/math/number"

	rnd "github.com/itsubaki/q/math/rand"
)

func main() {
	N := 21
	a := 8

	qsim := q.New()
	qsim.Rand = rnd.Const()

	r0 := qsim.ZeroWith(4)
	r1 := qsim.ZeroLog2(N)

	qsim.X(r1[len(r1)-1])
	qsim.H(r0...)
	qsim.CModExp2(a, N, r0, r1)
	qsim.InvQFT(r0...)

	m := qsim.Measure(r0...).BinaryString()
	s, r, d, ok := number.FindOrder(a, N, fmt.Sprintf("0.%s", m))
	if !ok || number.IsOdd(r) {
		return
	}

	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) {
		return
	}

	fmt.Printf("N=%d, a=%d. p=%v, q=%v. s/r=%d/%d ([0.%v]~%.3f)\n", N, a, p0, p1, s, r, m, d)

}
Output:

N=21, a=8. p=7, q=3. s/r=1/2 ([0.1000]~0.500)
Example (ShorFactoring51)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/math/number"

	rnd "github.com/itsubaki/q/math/rand"
)

func main() {
	// NOTE: Michael R. Geller, Zhongyuan Zhou. Factoring 51 and 85 with 8 qubits.
	N := 51
	a := 5 // 5, 7, 10, 11, 14, 20, 22, 23, 28, 29, 31, 37, 40, 41, 44, 46
	rng := rnd.Const()

	for {
		qsim := q.New()
		qsim.Rand = rng

		q0 := qsim.Zero()
		q1 := qsim.Zero()
		q2 := qsim.Zero()
		q3 := qsim.Zero()

		q4 := qsim.Zero()
		q5 := qsim.Zero()
		q6 := qsim.Zero()
		q7 := qsim.Zero()

		qsim.H(q0, q1, q2, q3)

		qsim.CNOT(q0, q4)
		qsim.CNOT(q1, q5)
		qsim.CNOT(q2, q6)
		qsim.CNOT(q3, q7)

		// inverse QFT
		qsim.Swap(q0, q1, q2, q3)
		qsim.H(q3)
		qsim.CR(-1*q.Theta(2), q3, q2)
		qsim.H(q2)
		qsim.CR(-1*q.Theta(3), q3, q1)
		qsim.CR(-1*q.Theta(2), q2, q1)
		qsim.H(q1)
		qsim.CR(-1*q.Theta(4), q3, q0)
		qsim.CR(-1*q.Theta(3), q2, q0)
		qsim.CR(-1*q.Theta(2), q1, q0)
		qsim.H(q0)

		m := qsim.Measure(q0, q1, q2, q3).BinaryString()
		s, r, d, ok := number.FindOrder(a, N, fmt.Sprintf("0.%s", m))
		if !ok || number.IsOdd(r) {
			continue
		}

		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
		}

		fmt.Printf("N=%d, a=%d. p=%v, q=%v. s/r=%d/%d ([0.%v]~%.3f)\n", N, a, p0, p1, s, r, m, d)
		break
	}

}
Output:

N=51, a=5. p=3, q=17. s/r=3/16 ([0.0011]~0.188)
Example (ShorFactoring85)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/math/number"

	rnd "github.com/itsubaki/q/math/rand"
)

func main() {
	// NOTE: Michael R. Geller, Zhongyuan Zhou. Factoring 51 and 85 with 8 qubits.
	N := 85
	a := 14
	rng := rnd.Const()

	for {
		qsim := q.New()
		qsim.Rand = rng

		q0 := qsim.Zero()
		q1 := qsim.Zero()
		q2 := qsim.Zero()
		q3 := qsim.Zero()

		q4 := qsim.Zero()
		q5 := qsim.Zero()
		q6 := qsim.Zero()
		q7 := qsim.Zero()

		qsim.H(q0, q1, q2, q3)

		qsim.CNOT(q0, q4)
		qsim.CNOT(q1, q5)
		qsim.CNOT(q2, q6)
		qsim.CNOT(q3, q7)

		// inverse QFT
		qsim.Swap(q0, q1, q2, q3)
		qsim.H(q3)
		qsim.CR(-1*q.Theta(2), q3, q2).H(q2)
		qsim.CR(-1*q.Theta(3), q3, q1).CR(-1*q.Theta(2), q2, q1).H(q1)
		qsim.CR(-1*q.Theta(4), q3, q0).CR(-1*q.Theta(3), q2, q0).CR(-1*q.Theta(2), q1, q0).H(q0)

		m := qsim.Measure(q0, q1, q2, q3).BinaryString()
		s, r, d, ok := number.FindOrder(a, N, fmt.Sprintf("0.%s", m))
		if !ok || number.IsOdd(r) {
			continue
		}

		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
		}

		fmt.Printf("N=%d, a=%d. p=%v, q=%v. s/r=%d/%d ([0.%v]~%.3f)\n", N, a, p0, p1, s, r, m, d)
		break
	}

}
Output:

N=85, a=14. p=5, q=17. s/r=3/16 ([0.0011]~0.188)
Example (SuperDenseCoding)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/math/matrix"
	"github.com/itsubaki/q/quantum/gate"
)

func main() {
	sdc := func(g matrix.Matrix) string {
		qsim := q.New()

		// initial state
		q0 := qsim.Zero()
		q1 := qsim.Zero()

		qsim.H(q0)
		qsim.CNOT(q0, q1)

		// encode
		qsim.Apply(g, q0)

		// decode
		qsim.CNOT(q0, q1)
		qsim.H(q0)

		// measure
		return qsim.M(q0, q1).BinaryString()
	}

	fmt.Printf("I : %v\n", sdc(gate.I()))
	fmt.Printf("X : %v\n", sdc(gate.X()))
	fmt.Printf("Z : %v\n", sdc(gate.Z()))
	fmt.Printf("ZX: %v\n", sdc(gate.Z().Apply(gate.X())))

}
Output:

I : 00
X : 01
Z : 10
ZX: 11
Example (Top)
package main

import (
	"fmt"
	"sort"

	"github.com/itsubaki/q"

	rnd "github.com/itsubaki/q/math/rand"
	"github.com/itsubaki/q/quantum/qubit"
)

func main() {
	N := 21
	a := 11

	qsim := q.New()
	qsim.Rand = rnd.Const()

	r0 := qsim.ZeroWith(4)
	r1 := qsim.ZeroLog2(N)

	qsim.X(r1[len(r1)-1])
	qsim.H(r0...)
	qsim.CModExp2(a, N, r0, r1)
	qsim.IQFT(r0...)
	qsim.M(r1...)

	top := func(s []qubit.State, n int) []qubit.State {
		sort.Slice(s, func(i, j int) bool { return s[i].Probability > s[j].Probability })
		if len(s) < n {
			return s
		}

		return s[:n]
	}

	for _, s := range top(qsim.State(r0), 10) {
		fmt.Println(s)
	}

}
Output:

[1000][  8](-0.4330 0.0000i): 0.1875
[0000][  0]( 0.4330 0.0000i): 0.1875
[1011][ 11]( 0.1334-0.3219i): 0.1214
[0011][  3](-0.1334 0.3219i): 0.1214
[1101][ 13](-0.1334-0.3219i): 0.1214
[0101][  5]( 0.1334 0.3219i): 0.1214
[0100][  4]( 0.0000 0.1443i): 0.0208
[0110][  6](-0.1021-0.1021i): 0.0208
[1010][ 10](-0.1021 0.1021i): 0.0208
[0010][  2]( 0.1021-0.1021i): 0.0208

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Index

func Index(qb ...Qubit) []int

Index returns the index list of qubits.

func Theta added in v0.0.3

func Theta(k int) float64

Theta returns 2 * pi / 2**k

Types

type Q

type Q struct {
	Rand func() float64
	// contains filtered or unexported fields
}

Q is a quantum computation simulator.

func New

func New() *Q

New returns a new quantum computation simulator.

func (*Q) Amplitude

func (q *Q) Amplitude() []complex128

Amplitude returns the amplitude of qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.Zero()

	qsim.H(q0)
	qsim.CNOT(q0, q1)

	for _, a := range qsim.Amplitude() {
		fmt.Println(a)
	}

}
Output:

(0.7071067811865476+0i)
(0+0i)
(0+0i)
(0.7071067811865476+0i)

func (*Q) Apply

func (q *Q) Apply(m matrix.Matrix, qb ...Qubit) *Q

Apply applies matrix to qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/quantum/gate"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.Zero()
	n := qsim.NumberOfBit()

	qsim.Apply(gate.H(), q0)
	qsim.Apply(gate.CNOT(n, q0.Index(), q1.Index()))

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 0.7071 0.0000i): 0.5000
[11][  3]( 0.7071 0.0000i): 0.5000

func (*Q) C

func (q *Q) C(m matrix.Matrix, control, target Qubit) *Q
Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
	"github.com/itsubaki/q/quantum/gate"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.Zero()

	qsim.H(q0)
	qsim.C(gate.X(), q0, q1) // qsim.CNOT(q0, q1)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 0.7071 0.0000i): 0.5000
[11][  3]( 0.7071 0.0000i): 0.5000

func (*Q) CCCNOT

func (q *Q) CCCNOT(control0, control1, control2, target Qubit) *Q

CCCNOT applies CCCNOT gate.

func (*Q) CCNOT

func (q *Q) CCNOT(control0, control1, target Qubit) *Q

CCNOT applies CCNOT gate.

func (*Q) CCZ

func (q *Q) CCZ(control0, control1, target Qubit) *Q

func (*Q) CModExp2

func (q *Q) CModExp2(a, N int, control []Qubit, target []Qubit) *Q

CModExp2 applies Controlled-ModExp2 gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	c := qsim.ZeroWith(3)
	t := qsim.ZeroLog2(15)

	qsim.X(c...)
	qsim.X(t[len(t)-1])
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// qsim.ControlledModExp2(7, 0, 15, c[0], t)
	// qsim.ControlledModExp2(7, 1, 15, c[1], t)
	// qsim.ControlledModExp2(7, 2, 15, c[2], t)
	// equals to
	qsim.CModExp2(7, 15, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

}
Output:

[111 0001][  7   1]( 1.0000 0.0000i): 1.0000
[111 1101][  7  13]( 1.0000 0.0000i): 1.0000

func (*Q) CNOT

func (q *Q) CNOT(control, target Qubit) *Q

CNOT applies CNOT gate.

func (*Q) CR

func (q *Q) CR(theta float64, control, target Qubit) *Q

CR applies Controlled-R gate.

func (*Q) CZ

func (q *Q) CZ(control, target Qubit) *Q

func (*Q) Clone

func (q *Q) Clone() *Q

Clone returns a clone of a quantum computation simulator.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	clone := qsim.Clone()
	clone.Zero()
	clone.Zero()

	q0 := qsim.Zero()
	q1 := qsim.Zero()
	qsim.X(q0, q1)

	fmt.Println(clone)
	fmt.Println(qsim)
	fmt.Println(qsim.Clone())

}
Output:

[(1+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (1+0i)]
[(0+0i) (0+0i) (0+0i) (1+0i)]

func (*Q) Cond added in v0.0.3

func (q *Q) Cond(condition bool, m matrix.Matrix, qb ...Qubit) *Q

Cond applies m if condition is true.

func (*Q) CondX added in v0.0.3

func (q *Q) CondX(condition bool, qb ...Qubit) *Q

CondX applies X gate if condition is true.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()

	qsim.CondX(false, q0)
	for _, s := range qsim.State() {
		fmt.Println(s)
	}

	qsim.CondX(true, q0)
	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[0][  0]( 1.0000 0.0000i): 1.0000
[1][  1]( 1.0000 0.0000i): 1.0000

func (*Q) CondZ added in v0.0.3

func (q *Q) CondZ(condition bool, qb ...Qubit) *Q

CondZ applies Z gate if condition is true.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.One()

	qsim.CondZ(false, q0)
	for _, s := range qsim.State() {
		fmt.Println(s)
	}

	qsim.CondZ(true, q0)
	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 1.0000 0.0000i): 1.0000
[1][  1](-1.0000 0.0000i): 1.0000

func (*Q) Controlled

func (q *Q) Controlled(m matrix.Matrix, control []Qubit, target Qubit) *Q

func (*Q) ControlledModExp2

func (q *Q) ControlledModExp2(a, j, N int, control Qubit, target []Qubit) *Q

ControlledModExp2 applies Controlled-ModExp2 gate.

Example (Mod15)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	c := qsim.Zero()
	t := qsim.ZeroLog2(15)

	qsim.X(c)
	qsim.X(t[len(t)-1])
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// 7^2^0 * 1 mod 15 = 7
	qsim.ControlledModExp2(7, 0, 15, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// 7^2^1 * 7 mod 15 = 13
	qsim.ControlledModExp2(7, 1, 15, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// 7^2^2 * 13 mod 15 = 13
	qsim.ControlledModExp2(7, 2, 15, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

}
Output:

[1 0001][  1   1]( 1.0000 0.0000i): 1.0000
[1 0111][  1   7]( 1.0000 0.0000i): 1.0000
[1 1101][  1  13]( 1.0000 0.0000i): 1.0000
[1 1101][  1  13]( 1.0000 0.0000i): 1.0000
Example (Mod21)
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	c := qsim.Zero()
	t := qsim.ZeroLog2(21)

	qsim.X(c)
	qsim.X(t[len(t)-1])
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// 2^2^0 * 1 mod 21 = 2
	qsim.ControlledModExp2(2, 0, 21, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// 2^2^1 * 2 mod 21 = 8
	qsim.ControlledModExp2(2, 1, 21, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// 2^2^2 * 8 mod 21 = 2
	qsim.ControlledModExp2(2, 2, 21, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

	// 2^2^3 * 2 mod 21 = 8
	qsim.ControlledModExp2(2, 3, 21, c, t)
	for _, s := range qsim.State(c, t) {
		fmt.Println(s)
	}

}
Output:

[1 00001][  1   1]( 1.0000 0.0000i): 1.0000
[1 00010][  1   2]( 1.0000 0.0000i): 1.0000
[1 01000][  1   8]( 1.0000 0.0000i): 1.0000
[1 00010][  1   2]( 1.0000 0.0000i): 1.0000
[1 01000][  1   8]( 1.0000 0.0000i): 1.0000

func (*Q) ControlledNot

func (q *Q) ControlledNot(control []Qubit, target Qubit) *Q

ControlledNot applies CNOT gate.

func (*Q) ControlledR

func (q *Q) ControlledR(theta float64, control []Qubit, target Qubit) *Q

func (*Q) ControlledZ

func (q *Q) ControlledZ(control []Qubit, target Qubit) *Q

ControlledZ applies Controlled-Z gate.

func (*Q) H

func (q *Q) H(qb ...Qubit) *Q

H applies H gate.

func (*Q) I

func (q *Q) I(qb ...Qubit) *Q

I applies I gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	qsim.I(q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[0][  0]( 1.0000 0.0000i): 1.0000

func (*Q) IQFT

func (q *Q) IQFT(qb ...Qubit) *Q

IQFT applies Inverse Quantum Fourier Transform.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.One()
	q2 := qsim.Zero()

	qsim.QFT(q0, q1, q2)
	qsim.IQFT(q0, q1, q2)
	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[010][  2]( 1.0000 0.0000i): 1.0000

func (*Q) InvQFT

func (q *Q) InvQFT(qb ...Qubit) *Q

InvQFT applies Inverse Quantum Fourier Transform.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.One()
	q2 := qsim.Zero()

	qsim.QFT(q0, q1, q2)
	qsim.InvQFT(q0, q1, q2)
	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[010][  2]( 1.0000 0.0000i): 1.0000

func (*Q) InverseQFT

func (q *Q) InverseQFT(qb ...Qubit) *Q

InverseQFT applies Inverse Quantum Fourier Transform.

func (*Q) M

func (q *Q) M(qb ...Qubit) *qubit.Qubit

M returns the measured state of qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"

	rnd "github.com/itsubaki/q/math/rand"
)

func main() {
	qsim := q.New()
	qsim.Rand = rnd.Const()

	q0 := qsim.Zero()
	q1 := qsim.Zero()
	q2 := qsim.Zero()
	qsim.X(q0)

	fmt.Println(qsim.M(q0))
	fmt.Println(qsim.M(q0, q1, q2))
	fmt.Println(qsim.M())

}
Output:

[(0+0i) (1+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i) (1+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i) (1+0i) (0+0i) (0+0i) (0+0i)]

func (*Q) Measure

func (q *Q) Measure(qb ...Qubit) *qubit.Qubit

Measure returns the measured state of qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"

	rnd "github.com/itsubaki/q/math/rand"
)

func main() {
	qsim := q.New()
	qsim.Rand = rnd.Const()

	q0 := qsim.Zero()
	q1 := qsim.Zero()
	q2 := qsim.Zero()
	qsim.X(q0)

	fmt.Println(qsim.Measure(q0))
	fmt.Println(qsim.Measure(q0, q1, q2))
	fmt.Println(qsim.Measure())

}
Output:

[(0+0i) (1+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i) (1+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i) (1+0i) (0+0i) (0+0i) (0+0i)]

func (*Q) New

func (q *Q) New(v ...complex128) Qubit

New returns a new qubit.

func (*Q) NewOf

func (q *Q) NewOf(binary string) []Qubit

NewOf returns a new qubit from binary string.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	qb := qsim.NewOf("0101")
	m0 := qsim.Measure(qb[0]) // 0
	m1 := qsim.Measure(qb[1]) // 1
	m2 := qsim.Measure(qb[2]) // 0
	m3 := qsim.Measure(qb[3]) // 1

	fmt.Println(m0)
	fmt.Println(m1)
	fmt.Println(m2)
	fmt.Println(m3)

}
Output:

[(1+0i) (0+0i)]
[(0+0i) (1+0i)]
[(1+0i) (0+0i)]
[(0+0i) (1+0i)]

func (*Q) NumberOfBit

func (q *Q) NumberOfBit() int

NumberOfBit returns the number of qubits.

func (*Q) One

func (q *Q) One() Qubit

One returns a qubit in the one state.

func (*Q) OneWith

func (q *Q) OneWith(n int) []Qubit

One returns a qubit in the one state with n qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	r := qsim.OneWith(2)
	qsim.H(r...)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 0.5000 0.0000i): 0.2500
[01][  1](-0.5000 0.0000i): 0.2500
[10][  2](-0.5000 0.0000i): 0.2500
[11][  3]( 0.5000 0.0000i): 0.2500

func (*Q) Probability

func (q *Q) Probability() []float64

Probability returns the probability of qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.Zero()

	qsim.H(q0)
	qsim.CNOT(q0, q1)

	for _, p := range qsim.Probability() {
		fmt.Printf("%.4f\n", p)
	}

}
Output:

0.5000
0.0000
0.0000
0.5000

func (*Q) QFT

func (q *Q) QFT(qb ...Qubit) *Q

QFT applies Quantum Fourier Transform.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.One()
	q2 := qsim.Zero()

	qsim.QFT(q0, q1, q2)
	qsim.Swap(q0, q2)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[000][  0]( 0.3536 0.0000i): 0.1250
[001][  1]( 0.0000 0.3536i): 0.1250
[010][  2](-0.3536 0.0000i): 0.1250
[011][  3]( 0.0000-0.3536i): 0.1250
[100][  4]( 0.3536 0.0000i): 0.1250
[101][  5]( 0.0000 0.3536i): 0.1250
[110][  6](-0.3536 0.0000i): 0.1250
[111][  7]( 0.0000-0.3536i): 0.1250

func (*Q) R

func (q *Q) R(theta float64, qb ...Qubit) *Q

R applies R gate with theta.

Example
package main

import (
	"fmt"
	"math"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.One()
	qsim.R(2*math.Pi/4, q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 0.0000 1.0000i): 1.0000

func (*Q) RX

func (q *Q) RX(theta float64, qb ...Qubit) *Q

RX applies RX gate with theta.

Example
package main

import (
	"fmt"
	"math"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	qsim.RX(math.Pi, q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 0.0000-1.0000i): 1.0000

func (*Q) RY

func (q *Q) RY(theta float64, qb ...Qubit) *Q

RY applies RY gate with theta.

Example
package main

import (
	"fmt"
	"math"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	qsim.RY(math.Pi, q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 1.0000 0.0000i): 1.0000

func (*Q) RZ

func (q *Q) RZ(theta float64, qb ...Qubit) *Q

RZ applies RZ gate with theta.

Example
package main

import (
	"fmt"
	"math"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	qsim.RZ(math.Pi, q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[0][  0]( 0.0000-1.0000i): 1.0000

func (*Q) Raw

func (q *Q) Raw() *qubit.Qubit

Raw returns the internal qubit.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()
	qsim.Zero()

	qb := qsim.Raw()

	d := qb.TraceDistance(qb)
	fmt.Println(d)

	f := qb.Fidelity(qb)
	fmt.Println(f)

}
Output:

0
1

func (*Q) Reset

func (q *Q) Reset(qb ...Qubit)

Reset sets qubits to the zero state.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	r := qsim.ZeroWith(2)
	qsim.Reset(r...)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

	qsim.X(r...)
	qsim.Reset(r...)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 1.0000 0.0000i): 1.0000
[00][  0]( 1.0000 0.0000i): 1.0000

func (*Q) S

func (q *Q) S(qb ...Qubit) *Q

S applies S gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.One()
	qsim.S(q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 0.0000 1.0000i): 1.0000

func (*Q) State

func (q *Q) State(reg ...any) []qubit.State

State returns the state of qubits.

func (*Q) String

func (q *Q) String() string

String returns the string representation of a quantum computation simulator.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.One()
	qsim.X(q0, q1)

	fmt.Println(qsim)

}
Output:

[(0+0i) (0+0i) (1+0i) (0+0i)]

func (*Q) Swap

func (q *Q) Swap(qb ...Qubit) *Q

Swap applies Swap gate.

func (*Q) T

func (q *Q) T(qb ...Qubit) *Q

T applies T gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.One()
	qsim.T(q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 0.7071 0.7071i): 1.0000

func (*Q) Toffoli

func (q *Q) Toffoli(control0, control1, target Qubit) *Q

Toffoli applies Toffoli gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.One()
	q1 := qsim.One()
	q2 := qsim.Zero()
	qsim.Toffoli(q0, q1, q2)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[111][  7]( 1.0000 0.0000i): 1.0000

func (*Q) U

func (q *Q) U(theta, phi, lambda float64, qb ...Qubit) *Q

U applies U gate.

Example
package main

import (
	"fmt"
	"math"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	qsim.U(math.Pi, 0, math.Pi, q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 1.0000 0.0000i): 1.0000

func (*Q) X

func (q *Q) X(qb ...Qubit) *Q

X applies X gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	qsim.X(q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1]( 1.0000 0.0000i): 1.0000

func (*Q) Y

func (q *Q) Y(qb ...Qubit) *Q

Y applies Y gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.One()
	qsim.Y(q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[0][  0]( 0.0000-1.0000i): 1.0000

func (*Q) Z

func (q *Q) Z(qb ...Qubit) *Q

Z applies Z gate.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.One()
	qsim.Z(q0)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[1][  1](-1.0000 0.0000i): 1.0000

func (*Q) Zero

func (q *Q) Zero() Qubit

Zero returns a qubit in the zero state.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	q0 := qsim.Zero()
	q1 := qsim.Zero()
	qsim.H(q0, q1)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 0.5000 0.0000i): 0.2500
[01][  1]( 0.5000 0.0000i): 0.2500
[10][  2]( 0.5000 0.0000i): 0.2500
[11][  3]( 0.5000 0.0000i): 0.2500

func (*Q) ZeroLog2

func (q *Q) ZeroLog2(N int) []Qubit

ZeroLog2 returns a qubit in the zero state with log2(N) qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	r := qsim.ZeroLog2(3)
	qsim.H(r...)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 0.5000 0.0000i): 0.2500
[01][  1]( 0.5000 0.0000i): 0.2500
[10][  2]( 0.5000 0.0000i): 0.2500
[11][  3]( 0.5000 0.0000i): 0.2500

func (*Q) ZeroWith

func (q *Q) ZeroWith(n int) []Qubit

ZeroWith returns a qubit in the zero state with n qubits.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q"
)

func main() {
	qsim := q.New()

	r := qsim.ZeroWith(2)
	qsim.H(r...)

	for _, s := range qsim.State() {
		fmt.Println(s)
	}

}
Output:

[00][  0]( 0.5000 0.0000i): 0.2500
[01][  1]( 0.5000 0.0000i): 0.2500
[10][  2]( 0.5000 0.0000i): 0.2500
[11][  3]( 0.5000 0.0000i): 0.2500

type Qubit

type Qubit int

Qubit is a quantum bit.

func (Qubit) Index

func (q Qubit) Index() int

Index returns the index of qubit.

Directories

Path Synopsis
cmd
math
quantum

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL