Skip to content

Commit 0281e47

Browse files
committed
Fix some aliasing issues
1 parent 9b28192 commit 0281e47

File tree

5 files changed

+118
-73
lines changed

5 files changed

+118
-73
lines changed

src/op.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,17 @@ end
516516

517517
@op_alias "CCCNOT" "Controlled" ncontrol = 3 op = OpName"X"()
518518

519+
## # 1-qudit rotation around generic axis n̂.
520+
## # exp(-im * α / 2 * n̂ ⋅ σ⃗)
521+
## function (n::OpName"Rn")(domain)
522+
## # TODO: Is this a good parametrization?
523+
## n̂ = (sin(n.θ/2) * cos(n.ϕ), sin(n.θ/2) * sin(n.ϕ/2), cos(n.θ/2))
524+
## σ⃗ = (OpName"X"(domain), OpName"Y"(domain), OpName"Z"(domain))
525+
## n̂σ⃗ = mapreduce(*, +, n̂, σ⃗)
526+
## return cis(-(n.λ/2) * n̂σ⃗)
527+
## end
528+
## @op_alias "Rn̂" "Rn"
529+
519530
# Version of `sign` that returns one
520531
# if `x == 0`.
521532
function nonzero_sign(x)

src/sitetypes/qubit.jl

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,39 @@ alias(::SiteType"SpinHalf=1/2") = SiteType"Qubit"()
66

77
Base.length(::SiteType"Qubit") = 2
88

9-
(::StateName"↑")(::SiteType"Qubit") = StateName"0"()(2)
10-
(::StateName"Up")(::SiteType"Qubit") = StateName"0"()(2)
9+
# Avoid aliases since these aren't generic
10+
# to Qudits/higher spin.
1111
(::StateName"Z+")(::SiteType"Qubit") = StateName"0"()(2)
12-
(::StateName"Zp")(::SiteType"Qubit") = StateName"0"()(2)
13-
(::StateName"Emp")(::SiteType"Qubit") = StateName"0"()(2)
12+
(::StateName"Zp")(domain::SiteType"Qubit") = StateName"Z+"()(domain)
13+
(::StateName"↑")(domain::SiteType"Qubit") = StateName"Z+"()(domain)
14+
(::StateName"Up")(domain::SiteType"Qubit") = StateName"Z+"()(domain)
15+
(::StateName"Emp")(domain::SiteType"Qubit") = StateName"Z+"()(domain)
1416

15-
(::StateName"↓")(::SiteType"Qubit") = StateName"1"()(2)
16-
(::StateName"Dn")(::SiteType"Qubit") = StateName"1"()(2)
17+
# Avoid aliases since these aren't generic
18+
# to Qudits/higher spin.
1719
(::StateName"Z-")(::SiteType"Qubit") = StateName"1"()(2)
18-
(::StateName"Zm")(::SiteType"Qubit") = StateName"1"()(2)
19-
(::StateName"Occ")(::SiteType"Qubit") = StateName"1"()(2)
20+
(::StateName"Zm")(domain::SiteType"Qubit") = StateName"Z-"()(domain)
21+
(::StateName"↓")(domain::SiteType"Qubit") = StateName"Z-"()(domain)
22+
(::StateName"Dn")(domain::SiteType"Qubit") = StateName"Z-"()(domain)
23+
(::StateName"Occ")(domain::SiteType"Qubit") = StateName"Z-"()(domain)
2024

2125
# `eigvecs(X)`
22-
alias(::StateName"+") = (StateName"0"() + StateName"1"()) / 2
23-
@state_alias "X+" "+"
24-
@state_alias "Xp" "+"
26+
(::StateName"X+")(::SiteType"Qubit") = ((StateName"0"() + StateName"1"()) / 2)(2)
27+
(::StateName"Xp")(domain::SiteType"Qubit") = StateName"X+"()(domain)
28+
(::StateName"+")(domain::SiteType"Qubit") = StateName"X+"()(domain)
2529

26-
alias(::StateName"-") = (StateName"0"() - StateName"1"()) / 2
27-
@state_alias "X-" "-"
28-
@state_alias "Xm" "-"
30+
(::StateName"X-")(::SiteType"Qubit") = ((StateName"0"() - StateName"1"()) / 2)(2)
31+
(::StateName"Xm")(domain::SiteType"Qubit") = StateName"X-"()(domain)
32+
(::StateName"-")(domain::SiteType"Qubit") = StateName"X-"()(domain)
2933

3034
# `eigvecs(Y)`
31-
alias(::StateName"i") = (StateName"0"() + im * StateName"1"()) / 2
32-
@state_alias "Y+" "i"
33-
@state_alias "Yp" "i"
35+
(::StateName"Y+")(::SiteType"Qubit") = ((StateName"0"() + im * StateName"1"()) / 2)(2)
36+
(::StateName"Yp")(domain::SiteType"Qubit") = StateName"Y+"()(domain)
37+
(::StateName"i")(domain::SiteType"Qubit") = StateName"Y+"()(domain)
3438

35-
alias(::StateName"-i") = (StateName"0"() - im * StateName"1"()) / 2
36-
@state_alias "Y-" "-i"
37-
@state_alias "Ym" "-i"
39+
(::StateName"Y-")(::SiteType"Qubit") = ((StateName"0"() - im * StateName"1"()) / 2)(2)
40+
(::StateName"Ym")(domain::SiteType"Qubit") = StateName"Y-"()(domain)
41+
(::StateName"-i")(domain::SiteType"Qubit") = StateName"Y-"()(domain)
3842

3943
# SIC-POVMs
4044
(::StateName"Tetra0")(::SiteType"Qubit") = [
@@ -55,48 +59,51 @@ alias(::StateName"-i") = (StateName"0"() - im * StateName"1"()) / √2
5559
]
5660

5761
# TODO: Define as `(I + σᶻ) / 2`?
58-
alias(::OpName"ProjUp") = OpName"Proj"(; index=1)
59-
@op_alias "projUp" "ProjUp"
60-
@op_alias "Proj↑" "ProjUp"
61-
@op_alias "proj↑" "ProjUp"
62-
@op_alias "Proj0" "ProjUp"
63-
@op_alias "proj0" "ProjUp"
62+
(::OpName"ProjUp")(::SiteType"Qubit") = OpName"Proj"(; index=1)(2)
63+
(::OpName"projUp")(domain::SiteType"Qubit") = OpName"ProjUp"()(domain)
64+
(::OpName"Proj↑")(domain::SiteType"Qubit") = OpName"ProjUp"()(domain)
65+
(::OpName"proj↑")(domain::SiteType"Qubit") = OpName"ProjUp"()(domain)
66+
(::OpName"Proj0")(domain::SiteType"Qubit") = OpName"ProjUp"()(domain)
67+
(::OpName"proj0")(domain::SiteType"Qubit") = OpName"ProjUp"()(domain)
6468

6569
# TODO: Define as `σ⁺ * σ⁻`?
6670
# TODO: Define as `(I - σᶻ) / 2`?
67-
alias(::OpName"ProjDn") = OpName"Proj"(; index=2)
68-
@op_alias "projDn" "ProjDn"
69-
@op_alias "Proj↓" "ProjDn"
70-
@op_alias "proj↓" "ProjDn"
71-
@op_alias "Proj1" "ProjDn"
72-
@op_alias "proj1" "ProjDn"
71+
(::OpName"ProjDn")(::SiteType"Qubit") = OpName"Proj"(; index=2)(2)
72+
(::OpName"projDn")(domain::SiteType"Qubit") = OpName"ProjDn"()(domain)
73+
(::OpName"Proj↓")(domain::SiteType"Qubit") = OpName"ProjDn"()(domain)
74+
(::OpName"proj↓")(domain::SiteType"Qubit") = OpName"ProjDn"()(domain)
75+
(::OpName"Proj1")(domain::SiteType"Qubit") = OpName"ProjDn"()(domain)
76+
(::OpName"proj1")(domain::SiteType"Qubit") = OpName"ProjDn"()(domain)
7377

74-
# Rotation around generic axis n̂
75-
# exp(-im * n.θ / 2 * n̂ ⋅ σ⃗)
76-
#=
77-
TODO: Define R-gate when `λ == -ϕ`, i.e.:
78-
```julia
79-
function Base.AbstractArray(n::OpName"R", ::Tuple{SiteType"Qubit"})
80-
return [
81-
cos(n.θ / 2) -exp(-im * n.ϕ)*sin(n.θ / 2)
82-
exp(im * n.ϕ)*sin(n.θ / 2) cos(n.θ / 2)
83-
]
84-
end
85-
```
86-
or:
87-
```julia
88-
alias(n::OpName"R") = OpName"Rn"(; θ=n.θ, ϕ=n.ϕ, λ=-n.ϕ)
89-
=#
90-
# https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.UGate
91-
# TODO: Generalize to `"Qudit"`, see:
92-
# https://quantumcomputing.stackexchange.com/questions/16251/how-does-a-general-rotation-r-hatn-theta-related-to-u-3-gate
93-
# https://quantumcomputing.stackexchange.com/questions/4249/decomposition-of-an-arbitrary-1-qubit-gate-into-a-specific-gateset
94-
# https://en.wikipedia.org/wiki/List_of_quantum_logic_gates#Other_named_gates
95-
# https://en.wikipedia.org/wiki/Spin_(physics)#Higher_spins
96-
function (n::OpName"Rn")(::SiteType"Qubit")
97-
return [
98-
cos(n.θ / 2) -exp(im * n.λ)*sin(n.θ / 2)
99-
exp(im * n.ϕ)*sin(n.θ / 2) exp(im * (n.ϕ + n.λ))*cos(n.θ / 2)
100-
]
101-
end
102-
@op_alias "Rn̂" "Rn"
78+
## TODO: Bring this back, decide on names and angle conventions.
79+
## # Related to rotation `"Rn"` around generic axis n̂:
80+
## # exp(-im * n.θ / 2 * n̂ ⋅ σ⃗)
81+
## #=
82+
## TODO: Define R-gate when `λ == -ϕ`, i.e.:
83+
## ```julia
84+
## function Base.AbstractArray(n::OpName"R", ::Tuple{SiteType"Qubit"})
85+
## return [
86+
## cos(n.θ / 2) -exp(-im * n.ϕ)*sin(n.θ / 2)
87+
## exp(im * n.ϕ)*sin(n.θ / 2) cos(n.θ / 2)
88+
## ]
89+
## end
90+
## ```
91+
## or:
92+
## ```julia
93+
## alias(n::OpName"R") = OpName"Rn"(; θ=n.θ, ϕ=n.ϕ, λ=-n.ϕ)
94+
## =#
95+
## # https://docs.quantum.ibm.com/api/qiskit/qiskit.circuit.library.UGate
96+
## # TODO: Generalize to `"Qudit"`, see:
97+
## # https://quantumcomputing.stackexchange.com/questions/16251/how-does-a-general-rotation-r-hatn-theta-related-to-u-3-gate
98+
## # https://quantumcomputing.stackexchange.com/questions/4249/decomposition-of-an-arbitrary-1-qubit-gate-into-a-specific-gateset
99+
## # https://en.wikipedia.org/wiki/List_of_quantum_logic_gates#Other_named_gates
100+
## # https://en.wikipedia.org/wiki/Spin_(physics)#Higher_spins
101+
## # https://qudev.phys.ethz.ch/static/content/courses/QSIT07/presentations/Schmassmann.pdf
102+
## # http://theory.caltech.edu/~preskill/ph219/chap5_15.pdf
103+
## # https://almuhammadi.com/sultan/books_2020/Nielsen_Chuang.pdf (Chapter 4)
104+
## function (n::OpName"GeneralRotation")(::SiteType"Qubit")
105+
## return [
106+
## cos(n.θ / 2) -exp(im * n.λ)*sin(n.θ / 2)
107+
## exp(im * n.ϕ)*sin(n.θ / 2) exp(im * (n.ϕ + n.λ))*cos(n.θ / 2)
108+
## ]
109+
## end

src/sitetypes/spinone.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ alias(::SiteType"SpinOne") = SiteType"S=1"()
99
(::StateName"Z-")(::SiteType"S=1") = [0, 0, 1]
1010

1111
## TODO: Decide on these aliases.
12-
(::StateName"↑")(::SiteType"S=1") = StateName"Z+"()(domain)
13-
(::StateName"Up")(::SiteType"S=1") = StateName"Z+"()(domain)
14-
(::StateName"0")(::SiteType"S=1") = StateName"Z0"()(domain)
15-
(::StateName"↓")(::SiteType"S=1") = StateName"Z-"()(domain)
16-
(::StateName"Dn")(::SiteType"S=1") = StateName"Z-"()(domain)
12+
(::StateName"↑")(domain::SiteType"S=1") = StateName"Z+"()(domain)
13+
(::StateName"Up")(domain::SiteType"S=1") = StateName"Z+"()(domain)
14+
(::StateName"0")(domain::SiteType"S=1") = StateName"Z0"()(domain)
15+
(::StateName"↓")(domain::SiteType"S=1") = StateName"Z-"()(domain)
16+
(::StateName"Dn")(domain::SiteType"S=1") = StateName"Z-"()(domain)
1717

1818
# TODO: Make these more general, define as something like:
1919
# `(n::StateName"X")(::SiteType"S=1") = eigvecs(OpName"X"())[n.eigval]`

src/state.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,16 @@ function (n::StateName"StandardBasis")(domain)
141141
a[n.index] = one(Bool)
142142
return a
143143
end
144-
function (n::StateName{N})(domain) where {N}
144+
function (n::StateName{N})(domain...) where {N}
145+
# TODO: Try one alias at a time?
146+
# TODO: First call `alias(n, domain...)`
147+
# to allow for aliases specific to certain
148+
# SiteTypes?
145149
n′ = alias(n)
146-
if n == n′
150+
domain′ = alias.(domain)
151+
if n == n′ && domain′ == domain
147152
index = parse(Int, String(N)) + 1
148-
return StateName"StandardBasis"(; index)(domain)
153+
return StateName"StandardBasis"(; index)(domain...)
149154
end
150-
return n′(domain)
155+
return n′(domain...)
151156
end

test/test_basics.jl

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,31 @@ const elts = (real_elts..., complex_elts...)
223223
end
224224

225225
for t in (SiteType("S=1"), SiteType("SpinOne"))
226-
@test state("Z+", SiteType("S=1")) == [1, 0, 0]
227-
@test state("Z0", SiteType("S=1")) == [0, 1, 0]
228-
@test state("Z-", SiteType("S=1")) == [0, 0, 1]
226+
for (ns, x) in (
227+
(("Z+", "", "Up"), [1, 0, 0]),
228+
(("Z0", "0"), [0, 1, 0]),
229+
(("Z-", "", "Dn"), [0, 0, 1]),
230+
(("X+",), [1 / 2, 1 / sqrt(2), 1 / 2]),
231+
(("X0",), [-1 / sqrt(2), 0, 1 / sqrt(2)]),
232+
(("X-",), [1 / 2, -1 / sqrt(2), 1 / 2]),
233+
(("Y+",), [-1 / 2, -im / sqrt(2), 1 / 2]),
234+
(("Y0",), [1 / sqrt(2), 0, 1 / sqrt(2)]),
235+
(("Y-",), [-1 / 2, im / sqrt(2), 1 / 2]),
236+
)
237+
for n in ns
238+
@test state(n, t) x
239+
end
240+
end
241+
end
242+
243+
# Check they are eigenvalues
244+
(λ⁺, λ⁰, λ⁻) = (2, 0, -2)
245+
for t in (SiteType("S=1"), SiteType("SpinOne"))
246+
for n in ("X", "Y", "Z")
247+
@test op(n, t) * state("$(n)+", t) λ⁺ * state("$(n)+", t) atol = eps()
248+
@test op(n, t) * state("$(n)0", t) λ⁰ * state("$(n)0", t) atol = eps()
249+
@test op(n, t) * state("$(n)-", t) λ⁻ * state("$(n)-", t) atol = eps()
250+
end
229251
end
230252
end
231253
end

0 commit comments

Comments
 (0)