qubit

package
v1.1.10 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2022 License: MIT Imports: 10 Imported by: 1

Documentation

Overview

Example (BellState)
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 (ErrorCorrectionBitFlip)
package main

import (
	"fmt"

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

func main() {
	phi := qubit.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 (ErrorCorrectionPhaseFlip)
package main

import (
	"fmt"

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

func main() {
	phi := qubit.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 (Grover2qubit)
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 (Grover3qubit)
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(0.5, 0)).
		Mul(complex(math.Sqrt(2)/(1.0+math.Sqrt(2)), 0))

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

	add := E1.Add(E2).Add(E3)
	fmt.Println(add.Equals(gate.I()))

	{
		q0 := qubit.Zero()
		q1 := qubit.Zero()
		q2 := qubit.Zero()

		fmt.Println("zero:")
		fmt.Println(q0.Apply(E1).InnerProduct(q0))
		fmt.Println(q1.Apply(E2).InnerProduct(q1))
		fmt.Println(q2.Apply(E3).InnerProduct(q2))
	}

	{
		q0 := qubit.Zero().Apply(gate.H())
		q1 := qubit.Zero().Apply(gate.H())
		q2 := qubit.Zero().Apply(gate.H())

		fmt.Println("H(zero):")
		fmt.Println(q0.Apply(E1).InnerProduct(q0))
		fmt.Println(q1.Apply(E2).InnerProduct(q1))
		fmt.Println(q2.Apply(E3).InnerProduct(q2))
	}

}
Output:

true
zero:
(0+0i)
(0.17157287525381+0i)
(0.5857864376269049+0i)
H(zero):
(0.17157287525381+0i)
(0+0i)
(0.5857864376269051+0i)
Example (QuantumTeleportation)
package main

import (
	"fmt"

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

func main() {
	phi := qubit.New(1, 2)
	phi.Seed = []int{1}
	phi.Rand = rand.Math

	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
Example (QuantumTeleportation2)
package main

import (
	"fmt"

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

func main() {
	phi := qubit.New(1, 2)
	phi.Seed = []int{1}
	phi.Rand = rand.Math

	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

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Equals

func Equals(s, v []State, eps ...float64) bool

Types

type Qubit

type Qubit struct {
	Seed []int
	Rand func(seed ...int) float64
	// contains filtered or unexported fields
}

func New

func New(z ...complex128) *Qubit

func One

func One(n ...int) *Qubit

func TensorProduct

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

func Zero

func Zero(n ...int) *Qubit
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

func (*Qubit) Apply

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

func (*Qubit) BinaryString

func (q *Qubit) BinaryString() string

func (*Qubit) Clone

func (q *Qubit) Clone() *Qubit

func (*Qubit) Dimension

func (q *Qubit) Dimension() int

func (*Qubit) Equals

func (q *Qubit) Equals(qb *Qubit, eps ...float64) bool

func (*Qubit) Fidelity

func (q *Qubit) Fidelity(qb *Qubit) float64

func (*Qubit) InnerProduct

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

func (*Qubit) Int

func (q *Qubit) Int() int64

func (*Qubit) IsOne

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

func (*Qubit) IsZero

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

func (*Qubit) Measure

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

func (*Qubit) Normalize

func (q *Qubit) Normalize() *Qubit

func (*Qubit) NumberOfBit

func (q *Qubit) NumberOfBit() int

func (*Qubit) OuterProduct

func (q *Qubit) OuterProduct(qb *Qubit) matrix.Matrix
Example
package main

import (
	"fmt"

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

func main() {
	v := qubit.New(1, 0)
	op := v.OuterProduct(v)
	fmt.Println(op)

}
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.New(1, 0)
	q := v.OuterProduct(v)
	e := gate.X().Dagger().Apply(q.Apply(gate.X()))

	fmt.Println(e)

}
Output:

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

func (*Qubit) Probability

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

func (*Qubit) State

func (q *Qubit) State(index ...[]int) []State
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

func (*Qubit) TensorProduct

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

func (*Qubit) TraceDistance

func (q *Qubit) TraceDistance(qb *Qubit) float64

type State

type State struct {
	Amplitude    complex128
	Probability  float64
	Int          []int64
	BinaryString []string
}
Example
package main

import (
	"fmt"

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

func main() {
	s := qubit.State{
		Amplitude:    1,
		Probability:  1,
		Int:          []int64{4, 10, 8},
		BinaryString: []string{"0100", "1010", "1000"},
	}

	fmt.Println(s.Value())
	fmt.Println(s.Value(0))
	fmt.Println(s.Value(1))
	fmt.Println(s.Value(2))
	fmt.Println(s.String())

}
Output:

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

func (*State) Add

func (s *State) Add(binary string)

func (State) Equals

func (s State) Equals(v State, eps ...float64) bool

func (State) String

func (s State) String() string

func (State) Value

func (s State) Value(index ...int) (int64, string)

Jump to

Keyboard shortcuts

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