qubit

package
v0.0.10 Latest Latest
Warning

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

Go to latest
Published: Jan 31, 2026 License: MIT Imports: 10 Imported by: 2

Documentation

Overview

Example (Bell)
package main

import (
	"fmt"

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

func main() {
	q := qubit.Zero(2).Apply(
		gate.H().TensorProduct(gate.I()),
		gate.CNOT(2, 0, 1),
	)

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

}
Output:

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

import (
	"fmt"

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

func main() {
	phi := qubit.New(vector.New(1, 2))

	// encoding
	phi.TensorProduct(qubit.Zero(2))
	phi.Apply(
		gate.CNOT(3, 0, 1),
		gate.CNOT(3, 0, 2),
	)

	// error: first qubit is flipped
	phi.Apply(matrix.TensorProduct(gate.X(), gate.I(2)))

	// add ancilla qubit
	phi.TensorProduct(qubit.Zero(2))

	// z1z2
	phi.Apply(
		gate.CNOT(5, 0, 3),
		gate.CNOT(5, 1, 3),
	)

	// z2z3
	phi.Apply(
		gate.CNOT(5, 1, 4),
		gate.CNOT(5, 2, 4),
	)

	// measure
	m3 := phi.Measure(3)
	m4 := phi.Measure(4)

	// recover
	if m3.IsOne() && m4.IsZero() {
		phi.Apply(matrix.TensorProduct(gate.X(), gate.I(4)))
	}

	if m3.IsOne() && m4.IsOne() {
		phi.Apply(matrix.TensorProduct(gate.I(), gate.X(), gate.I(3)))
	}

	if m3.IsZero() && m4.IsOne() {
		phi.Apply(matrix.TensorProduct(gate.I(2), gate.X(), gate.I(2)))
	}

	// decoding
	phi.Apply(
		gate.CNOT(5, 0, 2),
		gate.CNOT(5, 0, 1),
	)

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

}
Output:

[00010][  2]( 0.4472 0.0000i): 0.2000
[10010][ 18]( 0.8944 0.0000i): 0.8000
Example (EccPhaseFlip)
package main

import (
	"fmt"

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

func main() {
	phi := qubit.New(vector.New(1, 2))

	// encoding
	phi.TensorProduct(qubit.Zero(2))
	phi.Apply(
		gate.CNOT(3, 0, 1),
		gate.CNOT(3, 0, 2),
		gate.H(3),
	)

	// error: first qubit is flipped
	phi.Apply(matrix.TensorProduct(gate.Z(), gate.I(2)))

	// H
	phi.Apply(gate.H(3))

	// add ancilla qubit
	phi.TensorProduct(qubit.Zero(2))

	// x1x2
	phi.Apply(
		gate.CNOT(5, 0, 3),
		gate.CNOT(5, 1, 3),
	)

	// x2x3
	phi.Apply(
		gate.CNOT(5, 1, 4),
		gate.CNOT(5, 2, 4),
	)

	// H
	phi.Apply(matrix.TensorProduct(gate.H(3), gate.I(2)))

	// measure
	m3 := phi.Measure(3)
	m4 := phi.Measure(4)

	// recover
	if m3.IsOne() && m4.IsZero() {
		phi.Apply(matrix.TensorProduct(gate.Z(), gate.I(4)))
	}

	if m3.IsOne() && m4.IsOne() {
		phi.Apply(matrix.TensorProduct(gate.I(), gate.Z(), gate.I(3)))
	}

	if m3.IsZero() && m4.IsOne() {
		phi.Apply(matrix.TensorProduct(gate.I(2), gate.Z(), gate.I(2)))
	}

	// decoding
	phi.Apply(
		matrix.TensorProduct(gate.H(3), gate.I(2)),
		gate.CNOT(5, 0, 2),
		gate.CNOT(5, 0, 1),
	)

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

}
Output:

[00010][  2]( 0.4472 0.0000i): 0.2000
[10010][ 18]( 0.8944 0.0000i): 0.8000
Example (Grover2)
package main

import (
	"fmt"

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

func main() {
	oracle := gate.CZ(2, 0, 1)
	amp := matrix.Apply(
		gate.H(2),
		gate.X(2),
		gate.CZ(2, 0, 1),
		gate.X(2),
		gate.H(2),
	)

	q := qubit.Zero(2).Apply(
		gate.H(2),
		oracle,
		amp,
	)

	q.Measure(0)
	q.Measure(1)

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

}
Output:

[11][  3](-1.0000 0.0000i): 1.0000
Example (Grover3)
package main

import (
	"fmt"

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

func main() {
	oracle := matrix.Apply(
		matrix.TensorProduct(gate.X(), gate.I(3)),
		gate.ControlledNot(4, []int{0, 1, 2}, 3),
		matrix.TensorProduct(gate.X(), gate.I(3)),
	)

	amp := matrix.Apply(
		matrix.TensorProduct(gate.H(3), gate.H()),
		matrix.TensorProduct(gate.X(3), gate.I()),
		matrix.TensorProduct(gate.ControlledZ(3, []int{0, 1}, 2), gate.I()),
		matrix.TensorProduct(gate.X(3), gate.I()),
		matrix.TensorProduct(gate.H(3), gate.I()),
	)

	q := qubit.TensorProduct(
		qubit.Zero(3),
		qubit.One(),
	).Apply(
		gate.H(4),
		oracle,
		amp,
	)

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

}
Output:

[0001][  1](-0.1768 0.0000i): 0.0313
[0011][  3](-0.1768 0.0000i): 0.0313
[0101][  5](-0.1768 0.0000i): 0.0313
[0111][  7](-0.8839 0.0000i): 0.7813
[1001][  9](-0.1768 0.0000i): 0.0313
[1011][ 11](-0.1768 0.0000i): 0.0313
[1101][ 13](-0.1768 0.0000i): 0.0313
[1111][ 15](-0.1768 0.0000i): 0.0313
Example (Povm)
package main

import (
	"fmt"
	"math"

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

func main() {
	E1 := gate.New(
		[]complex128{0, 0},
		[]complex128{0, 1},
	).Mul(complex(math.Sqrt(2)/(1.0+math.Sqrt(2)), 0))

	E2 := gate.New(
		[]complex128{1, -1},
		[]complex128{-1, 1},
	).Mul(complex(math.Sqrt(2)/(1.0+math.Sqrt(2)), 0)).Mul(complex(0.5, 0))

	E3 := gate.I().Sub(E1).Sub(E2)

	add := E1.Add(E2).Add(E3)
	fmt.Println("euqlas:", add.Equal(gate.I()))

	{
		q0 := qubit.Zero().Apply(E1) // E1|0>
		q1 := qubit.Zero().Apply(E2) // E2|0>
		q2 := qubit.Zero().Apply(E3) // E3|0>

		fmt.Println("zero:")
		fmt.Printf("%.4v\n", q0.InnerProduct(qubit.Zero())) // <0|E1|0>
		fmt.Printf("%.4v\n", q1.InnerProduct(qubit.Zero())) // <0|E2|0>
		fmt.Printf("%.4v\n", q2.InnerProduct(qubit.Zero())) // <0|E3|0>
	}

	{
		q0 := qubit.Plus().Apply(E1) // E1|+>
		q1 := qubit.Plus().Apply(E2) // E2|+>
		q2 := qubit.Plus().Apply(E3) // E3|+>

		fmt.Println("H(zero):")
		fmt.Printf("%.4v\n", q0.InnerProduct(qubit.Plus())) // <+|E1|+>
		fmt.Printf("%.4v\n", q1.InnerProduct(qubit.Plus())) // <+|E2|+>
		fmt.Printf("%.4v\n", q2.InnerProduct(qubit.Plus())) // <+|E3|+>
	}

}
Output:

euqlas: true
zero:
(0+0i)
(0.2929+0i)
(0.7071+0i)
H(zero):
(0.2929+0i)
(0+0i)
(0.7071+0i)
Example (Round)
package main

import (
	"fmt"

	"github.com/itsubaki/q/math/vector"
	"github.com/itsubaki/q/quantum/qubit"
)

func main() {
	qb := qubit.New(vector.New(
		complex(1e-15, 0.5),
		complex(0.5, 1e-15),
	))
	for _, s := range qb.State() {
		fmt.Println(s)
	}

}
Output:

[0][  0]( 0.0000 0.7071i): 0.5000
[1][  1]( 0.7071 0.0000i): 0.5000
Example (Teleportation)
package main

import (
	"fmt"

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

func main() {
	phi := qubit.New(vector.New(1, 2))
	phi.Rand = rand.Const()

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

	bell := qubit.Zero(2).Apply(
		matrix.TensorProduct(gate.H(), gate.I()),
		gate.CNOT(2, 0, 1),
	)
	phi.TensorProduct(bell)

	phi.Apply(
		gate.CNOT(3, 0, 1),
		matrix.TensorProduct(gate.H(), gate.I(2)),
		gate.CNOT(3, 1, 2),
		gate.CZ(3, 0, 2),
	)

	phi.Measure(0)
	phi.Measure(1)

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

}
Output:

before:
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
after:
[110][  6]( 0.4472 0.0000i): 0.2000
[111][  7]( 0.8944 0.0000i): 0.8000
Example (TeleportationCond)
package main

import (
	"fmt"

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

func main() {
	phi := qubit.New(vector.New(1, 2))
	phi.Rand = rand.Const()

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

	bell := qubit.Zero(2).Apply(
		matrix.TensorProduct(gate.H(), gate.I()),
		gate.CNOT(2, 0, 1),
	)
	phi.TensorProduct(bell)

	phi.Apply(
		gate.CNOT(3, 0, 1),
		matrix.TensorProduct(gate.H(), gate.I(2)),
	)

	mz := phi.Measure(0)
	mx := phi.Measure(1)

	if mx.IsOne() {
		phi.Apply(matrix.TensorProduct(gate.I(2), gate.X()))
	}

	if mz.IsOne() {
		phi.Apply(matrix.TensorProduct(gate.I(2), gate.Z()))
	}

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

}
Output:

before:
[0][  0]( 0.4472 0.0000i): 0.2000
[1][  1]( 0.8944 0.0000i): 0.8000
after:
[110][  6]( 0.4472 0.0000i): 0.2000
[111][  7]( 0.8944 0.0000i): 0.8000

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Equal added in v0.0.9

func Equal(s, v []State, tol ...float64) bool

Equal returns true if s equals v.

Types

type Qubit

type Qubit struct {
	Rand func() float64 // Random number generator
	// contains filtered or unexported fields
}

Qubit is a qubit.

func From added in v0.0.10

func From(binary string) *Qubit

From returns a new qubit from a binary string.

Example
package main

import (
	"fmt"

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

func main() {
	z := qubit.From("0011")
	for _, s := range z.State() {
		fmt.Println(s)
	}

}
Output:

[0011][  3]( 1.0000 0.0000i): 1.0000
Example (Plus)
package main

import (
	"fmt"

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

func main() {
	z := qubit.From("+-")
	for _, s := range z.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 Minus added in v0.0.7

func Minus(n ...int) *Qubit

Minus returns a qubit in the minus state. The minus state is defined as (|0> - |1>) / sqrt(2).

func New

func New(v *vector.Vector) *Qubit

New returns a new qubit.

func NewWithIndex added in v0.0.8

func NewWithIndex(n, idx int) *Qubit

NewWithIndex returns a new qubit with the given index.

func One

func One(n ...int) *Qubit

One returns a qubit in the one state.

func Plus added in v0.0.7

func Plus(n ...int) *Qubit

Plus returns a qubit in the plus state. The plus state is defined as (|0> + |1>) / sqrt(2).

func TensorProduct

func TensorProduct(qb ...*Qubit) *Qubit

func Zero

func Zero(n ...int) *Qubit

Zero returns a qubit in the zero state.

Example
package main

import (
	"fmt"

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

func main() {
	z := qubit.Zero()
	fmt.Print("z : ")
	for _, s := range z.State() {
		fmt.Println(s)
	}

	z2 := qubit.Zero(2)
	fmt.Print("z2:")
	for _, s := range z2.State() {
		fmt.Println(s)
	}

}
Output:

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

func (*Qubit) Amplitude

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

Amplitude returns the amplitude of q.

func (*Qubit) Apply

func (q *Qubit) Apply(g ...*matrix.Matrix) *Qubit

Apply applies a list of gates to the qubit.

func (*Qubit) BinaryString

func (q *Qubit) BinaryString() string

BinaryString measures the quantum state and returns its binary string representation.

func (*Qubit) C added in v0.0.8

func (q *Qubit) C(g *matrix.Matrix, control, target int) *Qubit

C applies a controlled gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.H(0)
	qb.C(gate.X(), 0, 1)

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

}
Output:

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

func (*Qubit) CH added in v0.0.8

func (q *Qubit) CH(control, target int) *Qubit

CH applies the controlled-H gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.H(0)
	qb.CH(0, 1)

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

}
Output:

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

func (*Qubit) CR added in v0.0.8

func (q *Qubit) CR(thehta float64, control, target int) *Qubit

CR applies a controlled rotation around the Z-axis.

func (*Qubit) CU added in v0.0.8

func (q *Qubit) CU(theta, phi, lambda float64, control, target int) *Qubit

CU applies a controlled unitary operation.

Example
package main

import (
	"fmt"
	"math"

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

func main() {
	qb := qubit.Zero(2)
	qb.H(0)
	qb.CU(math.Pi, 0, math.Pi, 0, 1)

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

}
Output:

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

func (*Qubit) CX added in v0.0.8

func (q *Qubit) CX(control, target int) *Qubit

CX applies the controlled-X gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.H(0)
	qb.CX(0, 1)

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

}
Output:

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

func (*Qubit) CZ added in v0.0.8

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

CZ applies the controlled-Z gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.H(0)
	qb.H(1)
	qb.CZ(0, 1)

	for _, s := range qb.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 (*Qubit) Clone

func (q *Qubit) Clone() *Qubit

Clone returns a clone of q.

func (*Qubit) Controlled added in v0.0.8

func (q *Qubit) Controlled(g *matrix.Matrix, control []int, target int) *Qubit

Controlled applies a controlled 2x2 unitary gate U to the target qubit.

func (*Qubit) ControlledH added in v0.0.8

func (q *Qubit) ControlledH(control []int, target int) *Qubit

ControlledH applies the controlled Hadamard gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.H(0)
	qb.ControlledH([]int{0}, 1)

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

}
Output:

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

func (*Qubit) ControlledR added in v0.0.8

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

ControlledR applies a controlled rotation around the Z-axis.

func (*Qubit) ControlledU added in v0.0.8

func (q *Qubit) ControlledU(theta, phi, lambda float64, control []int, target int) *Qubit

ControlledU applies a controlled unitary operation.

func (*Qubit) ControlledX added in v0.0.8

func (q *Qubit) ControlledX(control []int, target int) *Qubit

ControlledX applies the controlled-X gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(3)
	qb.X(0)
	qb.X(1)
	qb.ControlledX([]int{0, 1}, 2)

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

}
Output:

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

func (*Qubit) ControlledZ added in v0.0.8

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

ControlledZ applies the controlled-Z gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.H(0)
	qb.H(1)
	qb.ControlledZ([]int{0}, 1)

	for _, s := range qb.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 (*Qubit) Dim added in v0.0.7

func (q *Qubit) Dim() int

Dim returns the dimension of q.

func (*Qubit) Equal added in v0.0.9

func (q *Qubit) Equal(qb *Qubit, tol ...float64) bool

Equal returns true if q and qb are equal.

func (*Qubit) G added in v0.0.8

func (q *Qubit) G(g *matrix.Matrix, idx int)

G applies a gate to the qubit at the given index.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)

	h := gate.H()
	cnot := gate.CNOT(2, 0, 1)

	qb.G(h, 0)
	qb.Apply(cnot)

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

}
Output:

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

func (*Qubit) H added in v0.0.8

func (q *Qubit) H(idx int) *Qubit

H applies H gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)

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

}
Output:

[0][  0]( 0.7071 0.0000i): 0.5000
[1][  1]( 0.7071 0.0000i): 0.5000

func (*Qubit) I added in v0.0.8

func (q *Qubit) I(idx int) *Qubit

I applies I gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.I(0)

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

}
Output:

[0][  0]( 0.7071 0.0000i): 0.5000
[1][  1]( 0.7071 0.0000i): 0.5000

func (*Qubit) InnerProduct

func (q *Qubit) InnerProduct(qb *Qubit) complex128

InnerProduct returns the inner product of q and qb.

func (*Qubit) Int

func (q *Qubit) Int() int

Int measures the quantum state and returns its int representation.

func (*Qubit) InvQFT added in v0.0.8

func (q *Qubit) InvQFT(idx ...int) *Qubit

InvQFT applies the inverse quantum Fourier transform.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(3)
	qb.X(2)
	qb.QFT()
	qb.InvQFT()

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

}
Output:

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

func (*Qubit) IsOne

func (q *Qubit) IsOne(tol ...float64) bool

IsOne returns true if q is one qubit.

func (*Qubit) IsZero

func (q *Qubit) IsZero(tol ...float64) bool

IsZero returns true if q is zero qubit.

func (*Qubit) Measure

func (q *Qubit) Measure(idx int) *Qubit

Measure returns a measured qubit.

func (*Qubit) Normalize

func (q *Qubit) Normalize() *Qubit

Normalize returns a normalized qubit.

func (*Qubit) NumQubits added in v0.0.6

func (q *Qubit) NumQubits() int

NumQubits returns the number of qubits.

func (*Qubit) OuterProduct

func (q *Qubit) OuterProduct(qb *Qubit) *matrix.Matrix

OuterProduct returns the outer product of q and qb.

Example
package main

import (
	"fmt"

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

func main() {
	v := qubit.Zero()
	op := v.OuterProduct(v)

	for _, r := range op.Seq2() {
		fmt.Println(r)
	}

}
Output:

[(1+0i) (0+0i)]
[(0+0i) (0+0i)]
Example (OperatorSum)
package main

import (
	"fmt"

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

func main() {
	v := qubit.Zero()
	q := v.OuterProduct(v)
	e := gate.X().Dagger().Apply(q.Apply(gate.X()))

	for _, r := range e.Seq2() {
		fmt.Println(r)
	}

}
Output:

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

func (*Qubit) Probability

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

Probability returns the probability of q.

func (*Qubit) QFT added in v0.0.8

func (q *Qubit) QFT(idx ...int) *Qubit

QFT applies the quantum Fourier transform.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(3)
	qb.X(2)
	qb.QFT()
	qb.Swap(0, 2)

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

}
Output:

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

func (*Qubit) R added in v0.0.8

func (q *Qubit) R(theta float64, idx int) *Qubit

R applies a phase rotation of theta.

Example
package main

import (
	"fmt"
	"math"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.R(math.Pi, 0)

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

}
Output:

[0][  0]( 0.7071 0.0000i): 0.5000
[1][  1](-0.7071 0.0000i): 0.5000

func (*Qubit) RX added in v0.0.8

func (q *Qubit) RX(theta float64, idx int) *Qubit

RX applies the rotation around X-axis.

Example
package main

import (
	"fmt"
	"math"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.RX(math.Pi, 0)

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

}
Output:

[0][  0]( 0.0000-0.7071i): 0.5000
[1][  1]( 0.0000-0.7071i): 0.5000

func (*Qubit) RY added in v0.0.8

func (q *Qubit) RY(theta float64, idx int) *Qubit

RY applies the rotation around Y-axis.

Example
package main

import (
	"fmt"
	"math"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.RY(math.Pi, 0)

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

}
Output:

[0][  0](-0.7071 0.0000i): 0.5000
[1][  1]( 0.7071 0.0000i): 0.5000

func (*Qubit) RZ added in v0.0.8

func (q *Qubit) RZ(theta float64, idx int) *Qubit

RZ applies the rotation around Z-axis.

Example
package main

import (
	"fmt"
	"math"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.RZ(math.Pi, 0)

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

}
Output:

[0][  0]( 0.0000-0.7071i): 0.5000
[1][  1]( 0.0000 0.7071i): 0.5000

func (*Qubit) S added in v0.0.8

func (q *Qubit) S(idx int) *Qubit

S applies the S gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.S(0)

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

}
Output:

[0][  0]( 0.7071 0.0000i): 0.5000
[1][  1]( 0.0000 0.7071i): 0.5000

func (*Qubit) Set added in v0.0.10

func (q *Qubit) Set(state *vector.Vector)

Set sets the state vector of the qubit and normalized it.

Example
package main

import (
	"fmt"

	"github.com/itsubaki/q/math/vector"
	"github.com/itsubaki/q/quantum/qubit"
)

func main() {
	qb := qubit.Zero(2)
	qb.Set(vector.New(1, 0, 0, 1))

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

}
Output:

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

func (*Qubit) State

func (q *Qubit) State(idx ...[]int) []State

State returns the state of the qubit at the given index. If no index is provided, it returns the state vector of all qubits.

Example
package main

import (
	"fmt"

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

func main() {
	v := qubit.Zero(4).Apply(gate.H(4))

	for _, s := range v.State([]int{0, 1, 2, 3}) {
		fmt.Println(s)
	}

}
Output:

[0000][  0]( 0.2500 0.0000i): 0.0625
[0001][  1]( 0.2500 0.0000i): 0.0625
[0010][  2]( 0.2500 0.0000i): 0.0625
[0011][  3]( 0.2500 0.0000i): 0.0625
[0100][  4]( 0.2500 0.0000i): 0.0625
[0101][  5]( 0.2500 0.0000i): 0.0625
[0110][  6]( 0.2500 0.0000i): 0.0625
[0111][  7]( 0.2500 0.0000i): 0.0625
[1000][  8]( 0.2500 0.0000i): 0.0625
[1001][  9]( 0.2500 0.0000i): 0.0625
[1010][ 10]( 0.2500 0.0000i): 0.0625
[1011][ 11]( 0.2500 0.0000i): 0.0625
[1100][ 12]( 0.2500 0.0000i): 0.0625
[1101][ 13]( 0.2500 0.0000i): 0.0625
[1110][ 14]( 0.2500 0.0000i): 0.0625
[1111][ 15]( 0.2500 0.0000i): 0.0625
Example (Order)
package main

import (
	"fmt"

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

func main() {
	v := qubit.Zero(4).Apply(gate.H(4))

	for _, s := range v.State([]int{0}, []int{1, 2, 3}) {
		fmt.Println(s)
	}

	for _, s := range v.State([]int{1, 2, 3}, []int{0}) {
		fmt.Println(s)
	}

}
Output:

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

func (*Qubit) String

func (q *Qubit) String() string

String returns the string representation of q.

func (*Qubit) Swap added in v0.0.8

func (q *Qubit) Swap(i, j int) *Qubit

Swap swaps the states of two qubits.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.X(0)

	qb.Swap(0, 1)
	for _, s := range qb.State() {
		fmt.Println(s)
	}

}
Output:

[01][  1]( 1.0000 0.0000i): 1.0000
Example (Eq)
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero(2)
	qb.X(0)

	qb.Swap(0, 0)
	for _, s := range qb.State() {
		fmt.Println(s)
	}

}
Output:

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

func (*Qubit) T added in v0.0.8

func (q *Qubit) T(idx int) *Qubit

T applies the T gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.T(0)

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

}
Output:

[0][  0]( 0.7071 0.0000i): 0.5000
[1][  1]( 0.5000 0.5000i): 0.5000

func (*Qubit) TensorProduct

func (q *Qubit) TensorProduct(qb *Qubit) *Qubit

TensorProduct returns the tensor product of q and qb.

func (*Qubit) U added in v0.0.8

func (q *Qubit) U(theta, phi, lambda float64, idx int) *Qubit

U applies a unitary gate.

Example
package main

import (
	"fmt"
	"math"

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

func main() {
	qb := qubit.Zero(2)
	qb.U(math.Pi/2, 0, 0, 0)
	qb.U(math.Pi/2, 0, 0, 1)

	for _, s := range qb.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 (*Qubit) X added in v0.0.8

func (q *Qubit) X(idx int) *Qubit

X applies X gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero()
	qb.X(0)

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

}
Output:

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

func (*Qubit) Y added in v0.0.8

func (q *Qubit) Y(idx int) *Qubit

Y applies Y gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.Y(0)

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

}
Output:

[0][  0]( 0.0000-0.7071i): 0.5000
[1][  1]( 0.0000 0.7071i): 0.5000

func (*Qubit) Z added in v0.0.8

func (q *Qubit) Z(idx int) *Qubit

Z applies Z gate.

Example
package main

import (
	"fmt"

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

func main() {
	qb := qubit.Zero()
	qb.H(0)
	qb.Z(0)

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

}
Output:

[0][  0]( 0.7071 0.0000i): 0.5000
[1][  1](-0.7071 0.0000i): 0.5000

type State

type State struct {
	// contains filtered or unexported fields
}

State is a quantum state.

Example
package main

import (
	"fmt"

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

func main() {
	s := qubit.NewState(complex(1, 0), []string{"0100", "1010", "1000"}...)

	fmt.Println(s.BinaryString(), s.Int(), s.Amplitude(), s.Probability())
	fmt.Println(s.String())

}
Output:

[0100 1010 1000] [4 10 8] (1+0i) 1
[0100 1010 1000][  4  10   8]( 1.0000 0.0000i): 1.0000

func NewState added in v0.0.5

func NewState(amp complex128, binary ...string) State

NewState returns a new State.

func (State) Amplitude

func (s State) Amplitude() complex128

func (State) BinaryString

func (s State) BinaryString() []string

func (State) Equal added in v0.0.9

func (s State) Equal(v State, tol ...float64) bool

Equal returns true if s equals v.

func (State) Int

func (s State) Int() []int

func (State) Probability

func (s State) Probability() float64

func (State) String

func (s State) String() string

Jump to

Keyboard shortcuts

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