-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqubit.go
90 lines (71 loc) · 1.74 KB
/
qubit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package qsim
import (
"fmt"
"math/cmplx"
"github.com/sp301415/qsim/math/number"
"github.com/sp301415/qsim/math/vec"
)
type Qubit struct {
data vec.Vec
size int
}
// NewQubit allocates new qubit from given vector. This does not copy vector.
// NOTE: This checks whether length of v is power of 2. Direct casting might lead to unexpected behavior.
func NewQubit(v vec.Vec) Qubit {
if (v.Dim()&(v.Dim()-1) != 0) && (v.Dim() <= 0) {
panic("Vector size must be power of two.")
}
return Qubit{data: v, size: number.BitLen(v.Dim()) - 1}
}
// NewBit allocates new qubit from classical bit.
// If size == 0, then it automatically adjust sizes.
func NewBit(n, size int) Qubit {
if n < 0 {
panic("Cannot convert negative number to qubit.")
}
if size == 0 {
size = number.BitLen(n)
}
if n > 1<<size {
panic("Size too small.")
}
v := vec.NewVec(1 << size)
v[n] = 1
return NewQubit(v)
}
// ToVec copies the underlying vec and returns.
func (q Qubit) ToVec() vec.Vec {
return q.data.Copy()
}
// Copy copies q.
func (q Qubit) Copy() Qubit {
return Qubit{data: q.data.Copy(), size: q.size}
}
// Size returns the bit length of a qubit.
func (q Qubit) Size() int {
return q.size
}
// At returns ith element of a qubit.
func (q Qubit) At(i int) complex128 {
return q.data[i]
}
// Dim returns the vector length of a qubit.
func (q Qubit) Dim() int {
return q.data.Dim()
}
// Equals checks if two qubits are equal.
func (q Qubit) Equals(p Qubit) bool {
return q.data.Equals(p.data)
}
// String implements Stringer interface.
func (q Qubit) String() string {
r := ""
idxpad := number.BitLen(q.Size())
for n, a := range q.data {
if cmplx.Abs(a) < 1e-6 {
continue
}
r += fmt.Sprintf("[%*d] |%0*b>: %f\n", idxpad, n, q.Size(), n, a)
}
return r
}