density

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: 9 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Index added in v0.0.10

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

Index returns the indices of the given qubits.

Types

type Matrix

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

Matrix is a density matrix.

Example (Bell)
package main

import (
	"fmt"

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

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

	qb := rho.Qubits()
	s1 := rho.PartialTrace(qb[0]) // Partial trace over qubit 0: returns the reduced density matrix for qubit 1
	s0 := rho.PartialTrace(qb[1]) // Partial trace over qubit 1: returns the reduced density matrix for qubit 0

	fmt.Printf("trace: %.2v, purity: %.2v\n", rho.Trace(), rho.Purity())
	fmt.Printf("trace: %.2v, purity: %.2v\n", s1.Trace(), s1.Purity())
	fmt.Printf("trace: %.2v, purity: %.2v\n", s0.Trace(), s0.Purity())

}
Output:

trace: 1, purity: 1
trace: 1, purity: 0.5
trace: 1, purity: 0.5
Example (PhaseAndBitPhaseFlip)
package main

import (
	"fmt"

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

func main() {
	rho := density.NewZeroState()

	qb := rho.Qubits()
	y := rho.BitPhaseFlip(0.3, qb[0])
	z := rho.PhaseFlip(0.3, qb[0])

	fmt.Printf("%.2f\n", y.Probability(qubit.Zero()))
	fmt.Printf("%.2f\n", y.Probability(qubit.One()))
	fmt.Printf("%.2f\n", z.Probability(qubit.Zero()))
	fmt.Printf("%.2f\n", z.Probability(qubit.One()))

}
Output:

0.70
0.30
1.00
0.00

func New

func New(ensemble []State) *Matrix

New returns a new density matrix.

func NewPureState added in v0.0.7

func NewPureState(qb *qubit.Qubit) *Matrix

NewPureState returns a new pure state density matrix for the given qubit.

func NewZeroState added in v0.0.7

func NewZeroState(n ...int) *Matrix

NewZeroState returns a new zero state density matrix for the given number of qubits.

func (*Matrix) Apply

func (m *Matrix) Apply(u *matrix.Matrix) *Matrix

Apply applies a unitary matrix to the density matrix.

func (*Matrix) ApplyChannel added in v0.0.7

func (m *Matrix) ApplyChannel(p float64, u *matrix.Matrix, qb ...Qubit) *Matrix

ApplyChannel applies a channel to the density matrix. It applies the identity with probability 1-p, and applies the gate g with probability p.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.NewZeroState(2)

	qb := rho.Qubits()
	x := rho.ApplyChannel(0.3, gate.X(), qb[0])

	fmt.Printf("%.2f\n", x.Probability(qubit.From("00")))
	fmt.Printf("%.2f\n", x.Probability(qubit.From("10")))

}
Output:

0.70
0.30
Example (Qb1)
package main

import (
	"fmt"

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

func main() {
	rho := density.NewZeroState(2)

	qb := rho.Qubits()
	x := rho.ApplyChannel(0.3, gate.X(), qb[1])

	fmt.Printf("%.2f\n", x.Probability(qubit.From("00")))
	fmt.Printf("%.2f\n", x.Probability(qubit.From("01")))

}
Output:

0.70
0.30

func (*Matrix) At added in v0.0.6

func (m *Matrix) At(i, j int) complex128

At returns a value of matrix at (i,j).

func (*Matrix) BitFlip added in v0.0.7

func (m *Matrix) BitFlip(p float64, qb Qubit) *Matrix

BitFlip applies a bit flip channel to the density matrix.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.NewZeroState()

	qb := rho.Qubits()
	x := rho.BitFlip(0.3, qb[0])

	fmt.Printf("%.2f\n", x.Probability(qubit.Zero()))
	fmt.Printf("%.2f\n", x.Probability(qubit.One()))

}
Output:

0.70
0.30

func (*Matrix) BitPhaseFlip added in v0.0.7

func (m *Matrix) BitPhaseFlip(p float64, qb Qubit) *Matrix

BitPhaseFlip applies a bit-phase flip channel to the density matrix.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.NewPureState(qubit.Plus())

	qb := rho.Qubits()
	y := rho.BitPhaseFlip(0.3, qb[0])

	fmt.Printf("%.2f\n", y.Probability(qubit.Plus()))
	fmt.Printf("%.2f\n", y.Probability(qubit.Minus()))

}
Output:

0.70
0.30

func (*Matrix) ComputationalBasis added in v0.0.7

func (m *Matrix) ComputationalBasis() []*qubit.Qubit
Example
package main

import (
	"fmt"

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

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

	for _, b := range rho.ComputationalBasis() {
		p, sigma := rho.Project(b)
		fmt.Printf("%v: %.2f\n", b.State(), p)

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

}
Output:

[[00][  0]( 1.0000 0.0000i): 1.0000]: 0.50
[(1+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[[01][  1]( 1.0000 0.0000i): 1.0000]: 0.00
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[[10][  2]( 1.0000 0.0000i): 1.0000]: 0.00
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[[11][  3]( 1.0000 0.0000i): 1.0000]: 0.50
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (1+0i)]

func (*Matrix) Depolarizing

func (m *Matrix) Depolarizing(p float64, qb Qubit) *Matrix

Depolarizing returns the depolarizing channel. It applies the identity with probability (1 - p), and applies each of the Pauli gates X, Y, and Z with probability p/3.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.NewZeroState()
	fmt.Printf("0: %.2f\n", rho.Probability(qubit.Zero()))
	fmt.Printf("1: %.2f\n", rho.Probability(qubit.One()))
	fmt.Println()

	qb := rho.Qubits()

	// XrhoX = |1><1|, YrhoY = |1><1|, ZrhoZ = |0><0|
	// E(rho) = 0.7|0><0| + 0.1|1><1| + 0.1|1><1| + 0.1|0><0| = 0.8|0><0| + 0.2|1><1|
	dep := rho.Depolarizing(0.3, qb[0])
	fmt.Printf("0: %.2f\n", dep.Probability(qubit.Zero()))
	fmt.Printf("1: %.2f\n", dep.Probability(qubit.One()))

}
Output:

0: 1.00
1: 0.00

0: 0.80
1: 0.20

func (*Matrix) Dim added in v0.0.7

func (m *Matrix) Dim() (rows int, cols int)

Dim returns the dimension of the density matrix.

func (*Matrix) ExpectedValue

func (m *Matrix) ExpectedValue(u *matrix.Matrix) float64

ExpectedValue returns the expectation value of the given operator.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.New([]density.State{
		{0.1, qubit.Zero()},
		{0.9, qubit.Plus()},
	})

	fmt.Printf("X: %.2v\n", rho.ExpectedValue(gate.X()))
	fmt.Printf("Y: %.2v\n", rho.ExpectedValue(gate.Y()))
	fmt.Printf("Z: %.2v\n", rho.ExpectedValue(gate.Z()))

}
Output:

X: 0.9
Y: 0
Z: 0.1

func (*Matrix) IsHermite added in v0.0.7

func (m *Matrix) IsHermite(tol ...float64) bool

IsHermite returns true if the density matrix is Hermitian.

Example
package main

import (
	"fmt"

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

func main() {
	s0 := density.NewZeroState()
	s1 := density.New([]density.State{
		{0.1, qubit.Zero()},
		{0.9, qubit.One()},
	})

	fmt.Println(s0.IsHermite())
	fmt.Println(s1.IsHermite())

}
Output:

true
true

func (*Matrix) IsMixed added in v0.0.7

func (m *Matrix) IsMixed(tol ...float64) bool

IsMixed returns true if the density matrix is mixed.

func (*Matrix) IsPure added in v0.0.7

func (m *Matrix) IsPure(tol ...float64) bool

IsPure returns true if the density matrix is pure.

func (*Matrix) NumQubits added in v0.0.6

func (m *Matrix) NumQubits() int

NumQubits returns the number of qubits.

func (*Matrix) PartialTrace

func (m *Matrix) PartialTrace(idx ...Qubit) *Matrix

PartialTrace returns the partial trace of the density matrix. The length of index must be less than or equal to n - 1, where n is the number of qubits in the matrix.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.New([]density.State{
		{0.5, qubit.From("00")},
		{0.5, qubit.From("10")},
	})

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

	qb := rho.Qubits()
	s1 := rho.PartialTrace(qb[0])
	s0 := rho.PartialTrace(qb[1])

	fmt.Printf("trace: %.2v, purity: %.2v\n", rho.Trace(), rho.Purity())
	fmt.Printf("trace: %.2v, purity: %.2v\n", s1.Trace(), s1.Purity())
	fmt.Printf("trace: %.2v, purity: %.2v\n", s0.Trace(), s0.Purity())

}
Output:

[(0.5+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]
[(0+0i) (0+0i) (0.5+0i) (0+0i)]
[(0+0i) (0+0i) (0+0i) (0+0i)]

trace: 1, purity: 0.5
trace: 1, purity: 1
trace: 1, purity: 0.5
Example (X8)
package main

import (
	"fmt"

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

func main() {
	rho := density.NewPureState(qubit.Zero(3).Apply(
		matrix.TensorProduct(gate.H(), gate.I(), gate.I()),
		gate.CNOT(3, 0, 1),
	))

	qb := rho.Qubits()
	s12 := rho.PartialTrace(qb[0])
	s02 := rho.PartialTrace(qb[1])
	s01 := rho.PartialTrace(qb[2])

	fmt.Printf("trace: %.2v, purity: %.2v\n", rho.Trace(), rho.Purity())
	fmt.Printf("trace: %.2v, purity: %.2v\n", s12.Trace(), s12.Purity())
	fmt.Printf("trace: %.2v, purity: %.2v\n", s02.Trace(), s02.Purity())
	fmt.Printf("trace: %.2v, purity: %.2v\n", s01.Trace(), s01.Purity())

}
Output:

trace: 1, purity: 1
trace: 1, purity: 0.5
trace: 1, purity: 0.5
trace: 1, purity: 1

func (*Matrix) PhaseFlip added in v0.0.7

func (m *Matrix) PhaseFlip(p float64, qb Qubit) *Matrix

PhaseFlip applies a phase flip channel to the density matrix.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.NewPureState(qubit.Plus())

	qb := rho.Qubits()
	z := rho.PhaseFlip(0.3, qb[0])

	fmt.Printf("%.2f\n", z.Probability(qubit.Plus()))
	fmt.Printf("%.2f\n", z.Probability(qubit.Minus()))

}
Output:

0.70
0.30

func (*Matrix) Probability added in v0.0.7

func (m *Matrix) Probability(q *qubit.Qubit) float64

Probability returns the probability of the qubit in the given state.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.New([]density.State{
		{0.1, qubit.Zero()},
		{0.9, qubit.One()},
	})

	fmt.Printf("0: %.2v\n", rho.Probability(qubit.Zero()))
	fmt.Printf("1: %.2v\n", rho.Probability(qubit.One()))

}
Output:

0: 0.1
1: 0.9

func (*Matrix) Project added in v0.0.7

func (m *Matrix) Project(q *qubit.Qubit, tol ...float64) (float64, *Matrix)

Project returns the probability and post-measurement density matrix.

func (*Matrix) Purity added in v0.0.7

func (m *Matrix) Purity() float64

Purity returns the purity of the density matrix, defined as Tr(rho^2).

Example
package main

import (
	"fmt"

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

func main() {
	s0 := density.NewZeroState()
	s1 := density.New([]density.State{
		{0.1, qubit.Zero()},
		{0.9, qubit.One()},
	})

	fmt.Printf("pure : %.2f, %v\n", s0.Purity(), s0.IsPure())
	fmt.Printf("mixed: %.2f, %v\n", s1.Purity(), s1.IsMixed())

}
Output:

pure : 1.00, true
mixed: 0.82, true

func (*Matrix) Qubits added in v0.0.6

func (m *Matrix) Qubits() []Qubit

Qubits returns the qubits of the density matrix.

func (*Matrix) Seq2 added in v0.0.7

func (m *Matrix) Seq2() iter.Seq2[int, []complex128]

Seq2 returns a sequence of rows.

func (*Matrix) TensorProduct added in v0.0.7

func (m *Matrix) TensorProduct(n *Matrix) *Matrix

TensorProduct returns the tensor product of two density matrices.

Example
package main

import (
	"fmt"

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

func main() {
	s0 := density.NewPureState(qubit.Zero())
	s1 := density.NewPureState(qubit.One())

	s01 := s0.TensorProduct(s1)
	for _, r := range s01.Seq2() {
		fmt.Println(r)
	}

}
Output:

[(0+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) (0+0i) (0+0i) (0+0i)]

func (*Matrix) Trace

func (m *Matrix) Trace() float64

Trace returns the trace of the density matrix.

Example
package main

import (
	"fmt"

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

func main() {
	s0 := density.NewZeroState()
	s1 := density.New([]density.State{
		{0.1, qubit.Zero()},
		{0.9, qubit.One()},
	})

	fmt.Printf("pure : %.2f\n", s0.Trace())
	fmt.Printf("mixed: %.2f\n", s1.Trace())

}
Output:

pure : 1.00
mixed: 1.00

func (*Matrix) Underlying added in v0.0.6

func (m *Matrix) Underlying() *matrix.Matrix

Underlying returns the internal matrix.

Example
package main

import (
	"fmt"

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

func main() {
	rho := density.New([]density.State{
		{0.1, qubit.Zero()},
		{0.9, qubit.One()},
	})

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

}
Output:

[(0.1+0i) (0+0i)]
[(0+0i) (0.9+0i)]

type Qubit added in v0.0.6

type Qubit int

Qubit is a quantum bit.

func (Qubit) Index added in v0.0.6

func (q Qubit) Index() int

Index returns the index of qubit.

type State

type State struct {
	Probability float64
	Qubit       *qubit.Qubit
}

State is a quantum state.

func Normalize added in v0.0.4

func Normalize(ensemble []State) []State

Normalize normalizes the probabilities of an ensemble.

Jump to

Keyboard shortcuts

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