Documentation
¶
Index ¶
- func Index(qb ...Qubit) []int
- type Matrix
- func (m *Matrix) Apply(u *matrix.Matrix) *Matrix
- func (m *Matrix) ApplyChannel(p float64, u *matrix.Matrix, qb ...Qubit) *Matrix
- func (m *Matrix) At(i, j int) complex128
- func (m *Matrix) BitFlip(p float64, qb Qubit) *Matrix
- func (m *Matrix) BitPhaseFlip(p float64, qb Qubit) *Matrix
- func (m *Matrix) ComputationalBasis() []*qubit.Qubit
- func (m *Matrix) Depolarizing(p float64, qb Qubit) *Matrix
- func (m *Matrix) Dim() (rows int, cols int)
- func (m *Matrix) ExpectedValue(u *matrix.Matrix) float64
- func (m *Matrix) IsHermite(tol ...float64) bool
- func (m *Matrix) IsMixed(tol ...float64) bool
- func (m *Matrix) IsPure(tol ...float64) bool
- func (m *Matrix) NumQubits() int
- func (m *Matrix) PartialTrace(idx ...Qubit) *Matrix
- func (m *Matrix) PhaseFlip(p float64, qb Qubit) *Matrix
- func (m *Matrix) Probability(q *qubit.Qubit) float64
- func (m *Matrix) Project(q *qubit.Qubit, tol ...float64) (float64, *Matrix)
- func (m *Matrix) Purity() float64
- func (m *Matrix) Qubits() []Qubit
- func (m *Matrix) Seq2() iter.Seq2[int, []complex128]
- func (m *Matrix) TensorProduct(n *Matrix) *Matrix
- func (m *Matrix) Trace() float64
- func (m *Matrix) Underlying() *matrix.Matrix
- type Qubit
- type State
Examples ¶
- Matrix (Bell)
- Matrix (PhaseAndBitPhaseFlip)
- Matrix.ApplyChannel
- Matrix.ApplyChannel (Qb1)
- Matrix.BitFlip
- Matrix.BitPhaseFlip
- Matrix.ComputationalBasis
- Matrix.Depolarizing
- Matrix.ExpectedValue
- Matrix.IsHermite
- Matrix.PartialTrace
- Matrix.PartialTrace (X8)
- Matrix.PhaseFlip
- Matrix.Probability
- Matrix.Purity
- Matrix.TensorProduct
- Matrix.Trace
- Matrix.Underlying
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
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 NewPureState ¶ added in v0.0.7
NewPureState returns a new pure state density matrix for the given qubit.
func NewZeroState ¶ added in v0.0.7
NewZeroState returns a new zero state density matrix for the given number of qubits.
func (*Matrix) ApplyChannel ¶ added in v0.0.7
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
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
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
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 ¶
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) ExpectedValue ¶
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
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) PartialTrace ¶
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
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
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
Project returns the probability and post-measurement density matrix.
func (*Matrix) Purity ¶ added in v0.0.7
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) 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
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 ¶
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
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)]