Skip to content

Commit

Permalink
Update bitwise operation
Browse files Browse the repository at this point in the history
  • Loading branch information
itsubaki committed Jan 8, 2025
1 parent b0f902a commit 462a421
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 108 deletions.
34 changes: 14 additions & 20 deletions quantum/density/matrix.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,24 +87,22 @@ func (m *Matrix) SquareTrace() float64 {
// PartialTrace returns the partial trace of the density matrix.
func (m *Matrix) PartialTrace(index ...int) *Matrix {
n := m.NumberOfBit()
f := fmt.Sprintf("%s%s%s", "%0", strconv.Itoa(n), "s")
p, q := m.Dimension()

d := number.Pow(2, n-1)
out := matrix.Zero(d, d)

p, q := m.Dimension()
for i := range p {
k, kr := take(fmt.Sprintf(f, strconv.FormatInt(int64(i), 2)), index)
k, kr := take(fmt.Sprintf("%0*b", n, i), index)

for j := range q {
l, lr := take(fmt.Sprintf(f, strconv.FormatInt(int64(j), 2)), index)
l, lr := take(fmt.Sprintf("%0*b", n, j), index)

if k != l {
continue
}

r := number.Must(strconv.ParseInt(kr, 2, 0))
c := number.Must(strconv.ParseInt(lr, 2, 0))

out[r][c] = out[r][c] + m.m[i][j]

// fmt.Printf("[%v][%v] = [%v][%v] + [%v][%v]\n", r, c, r, c, i, j)
Expand Down Expand Up @@ -136,28 +134,24 @@ func (m *Matrix) Depolarizing(p float64) (*Matrix, error) {
n := m.NumberOfBit()
i := gate.I(n).Mul(complex(p/2, 0))
r := m.m.Mul(complex(1-p, 0))

return &Matrix{i.Add(r)}, nil
}

func take(binary string, index []int) (string, string) {
var out, remain string
for i, v := range binary {
found := false
for _, j := range index {
if i == j {
out = out + string(v)
found = true
break
}
}
idx := make(map[int]struct{})
for _, i := range index {
idx[i] = struct{}{}
}

if found {
var out, remain []rune
for i, v := range binary {
if _, ok := idx[i]; ok {
out = append(out, v)
continue
}

remain = remain + string(v)
remain = append(remain, v)
}

return out, remain
return string(out), string(remain)
}
114 changes: 35 additions & 79 deletions quantum/gate/gate.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,52 +137,30 @@ func RZ(theta float64) matrix.Matrix {

// Controlled returns a controlled-u gate.
func Controlled(u matrix.Matrix, n int, c []int, t int) matrix.Matrix {
g := I(n)

for i := range g {
row := []rune(fmt.Sprintf("%0*b", n, i))

active := true
for _, j := range c {
if row[j] == '0' {
active = false
break
}
}
var mask int
for _, bit := range c {
mask |= (1 << (n - 1 - bit))
}

if !active {
s := (1 << n)
g := I(n)
for i := 0; i < s; i++ {
if (i & mask) != mask {
continue
}

for j := range g[i] {
col := []rune(fmt.Sprintf("%0*b", n, j))

active := true
for _, k := range c {
if col[k] == '0' {
active = false
break
}
}

if !active {
for j := 0; j < s; j++ {
if (j & mask) != mask {
continue
}

same := true
for i := range row {
if i != t && row[i] != col[i] {
same = false
break
}
}

if !same {
// modify only the target qubit
if (i & ^(1 << (n - 1 - t))) != (j & ^(1 << (n - 1 - t))) {
continue
}

r := number.Must(strconv.Atoi(string(row[t])))
c := number.Must(strconv.Atoi(string(col[t])))
c := (j >> (n - 1 - t)) & 1
r := (i >> (n - 1 - t)) & 1
g[j][i] = u[c][r]
}
}
Expand Down Expand Up @@ -236,21 +214,14 @@ func Toffoli(n, c0, c1, t int) matrix.Matrix {

// ControlledZ returns a controlled-z gate.
func ControlledZ(n int, c []int, t int) matrix.Matrix {
g := I(n)
d, _ := g.Dimension()

for i := range d {
bits := []rune(fmt.Sprintf("%0*b", n, i))

apply := true
for _, j := range c {
if bits[j] == '0' {
apply = false
break
}
}
var mask int
for _, bit := range c {
mask |= (1 << (n - 1 - bit))
}

if apply && bits[t] == '1' {
g := I(n)
for i := 0; i < (1 << n); i++ {
if (i&mask) == mask && (i&(1<<(n-1-t))) != 0 {
g[i][i] = -1 * g[i][i]
}
}
Expand All @@ -265,21 +236,14 @@ func CZ(n, c, t int) matrix.Matrix {

// ControlledS returns a controlled-s gate.
func ControlledS(n int, c []int, t int) matrix.Matrix {
g := I(n)
d, _ := g.Dimension()

for i := range d {
bits := []rune(fmt.Sprintf("%0*b", n, i))

apply := true
for _, j := range c {
if bits[j] == '0' {
apply = false
break
}
}
var mask int
for _, bit := range c {
mask |= (1 << (n - 1 - bit))
}

if apply && bits[t] == '1' {
g := I(n)
for i := 0; i < (1 << n); i++ {
if (i&mask) == mask && (i&(1<<(n-1-t))) != 0 {
g[i][i] = 1i * g[i][i]
}
}
Expand All @@ -297,22 +261,14 @@ func ControlledR(theta float64, n int, c []int, t int) matrix.Matrix {
// exp(i * theta)
e := cmplx.Exp(complex(0, theta))

g := I(n)
d, _ := g.Dimension()

for i := range d {
bits := []rune(fmt.Sprintf("%0*b", n, i))

// Apply R(k)
apply := true
for _, j := range c {
if bits[j] == '0' {
apply = false
break
}
}
var mask int
for _, bit := range c {
mask |= (1 << (n - 1 - bit))
}

if apply && bits[t] == '1' {
g := I(n)
for i := 0; i < (1 << n); i++ {
if (i&mask) == mask && (i&(1<<(n-1-t))) != 0 {
g[i][i] = e * g[i][i]
}
}
Expand Down
5 changes: 2 additions & 3 deletions quantum/gate/gate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,8 @@ func ExampleControlledModExp2() {
n, a, j, N := 5, 7, 0, 15
g := gate.ControlledModExp2(n, a, j, N, 0, []int{1, 2, 3, 4})

f := fmt.Sprintf("%s%s%s", "%0", strconv.Itoa(n), "s")
for i, r := range g.Transpose() {
bin := fmt.Sprintf(f, strconv.FormatInt(int64(i), 2))
bin := fmt.Sprintf("%0*b", n, i)
if bin[:1] == "0" { // control qubit is |0>
continue
}
Expand All @@ -120,7 +119,7 @@ func ExampleControlledModExp2() {
}

// decimal number representation of a^2^j * k mod N
a2jkmodNs := fmt.Sprintf(f, strconv.FormatInt(int64(ii), 2)[1:])
a2jkmodNs := fmt.Sprintf("%0*s", n, strconv.FormatInt(int64(ii), 2)[1:])
a2jkmodN := number.Must(strconv.ParseInt(a2jkmodNs, 2, 64))
got := (int64(number.ModExp2(a, j, N)) * k) % int64(N)

Expand Down
10 changes: 4 additions & 6 deletions quantum/qubit/qubit.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,11 @@ func (q *Qubit) Probability() []float64 {
// Measure returns a measured qubit.
func (q *Qubit) Measure(index int) *Qubit {
n := q.NumberOfBit()
f := fmt.Sprintf("%s%s%s", "%0", strconv.Itoa(n), "s")

zidx, oidx := make([]int, 0), make([]int, 0)
zprop := make([]float64, 0)
for i, p := range q.Probability() {
bits := []rune(fmt.Sprintf(f, strconv.FormatInt(int64(i), 2)))

bits := []rune(fmt.Sprintf("%0*b", n, i))
if bits[index] == '0' {
zidx, zprop = append(zidx, i), append(zprop, p)
continue
Expand Down Expand Up @@ -228,19 +226,19 @@ func (q *Qubit) State(index ...[]int) []State {

index = append(index, idx)
}
f := fmt.Sprintf("%s%s%s", "%0", strconv.Itoa(q.NumberOfBit()), "s")

n := q.NumberOfBit()
state := make([]State, 0)
for i, a := range q.Amplitude() {
amp := round(a)
if amp == 0 {
continue
}

b := fmt.Sprintf(f, strconv.FormatInt(int64(i), 2))
bit := fmt.Sprintf("%0*b", n, i)
var bin []string
for _, idx := range index {
bin = append(bin, take(b, idx))
bin = append(bin, take(bit, idx))
}

state = append(state, NewState(amp, bin...))
Expand Down

0 comments on commit 462a421

Please sign in to comment.