@@ -8,8 +8,8 @@ struct OpName{Name,Params}
8
8
end
9
9
name (:: OpName{Name} ) where {Name} = Name
10
10
params (n:: OpName ) = getfield (n, :params )
11
-
12
11
Base. getproperty (n:: OpName , name:: Symbol ) = getfield (params (n), name)
12
+ Base. get (t:: OpName , name:: Symbol , default) = get (params (t), name, default)
13
13
14
14
OpName {N} (; kwargs... ) where {N} = OpName {N} ((; kwargs... ))
15
15
54
54
# Generic to `StateName` or `OpName`.
55
55
const StateOrOpName = Union{StateName,OpName}
56
56
alias (n:: StateOrOpName ) = n
57
- function (arrtype:: Type{<:AbstractArray} )(n:: StateOrOpName , domain:: Integer... )
57
+ function (arrtype:: Type{<:AbstractArray} )(
58
+ n:: StateOrOpName , domain:: Union{Integer,AbstractUnitRange} ...
59
+ )
58
60
return arrtype (n, domain)
59
61
end
62
+ function (arrtype:: Type{<:AbstractArray} )(n:: StateOrOpName , domain:: Tuple{Vararg{Integer}} )
63
+ return arrtype (n, Base. oneto .(domain))
64
+ end
60
65
(arrtype:: Type{<:AbstractArray} )(n:: StateOrOpName , ts:: SiteType... ) = arrtype (n, ts)
61
66
function (n:: StateOrOpName )(domain... )
62
67
# TODO : Try one alias at a time?
@@ -87,32 +92,58 @@ function nsites(n::StateOrOpName)
87
92
return nsites (n′)
88
93
end
89
94
90
- function op_convert (
91
- arrtype:: Type{<:AbstractArray{<:Any,N}} ,
92
- domain:: Tuple{Vararg{Integer}} ,
93
- a:: AbstractArray{<:Any,N} ,
94
- ) where {N}
95
- # TODO : Check the dimensions.
96
- return convert (arrtype, a)
95
+ # TODO : This does some unwanted conversions, like turning
96
+ # `Diagonal` dense.
97
+ function array (a:: AbstractArray , ax:: Tuple{Vararg{AbstractUnitRange}} )
98
+ return a[ax... ]
97
99
end
98
- function op_convert (
99
- arrtype:: Type{<:AbstractArray} , domain:: Tuple{Vararg{Integer}} , a:: AbstractArray
100
- )
101
- # TODO : Check the dimensions.
102
- return convert (arrtype, a)
100
+
101
+ function Base. axes (:: OpName , domain:: Tuple{Vararg{AbstractUnitRange}} )
102
+ return (domain... , domain... )
103
+ end
104
+ function Base. axes (n:: StateOrOpName , domain:: Tuple{Vararg{Integer}} )
105
+ return axes (n, Base. OneTo .(domain))
106
+ end
107
+ function Base. axes (n:: StateOrOpName , domain:: Tuple{Vararg{SiteType}} )
108
+ return axes (n, AbstractUnitRange .(domain))
109
+ end
110
+
111
+ # # function Base.axes(::OpName"SWAP", domain::Tuple{Vararg{AbstractUnitRange}})
112
+ # # return (reverse(domain)..., domain...)
113
+ # # end
114
+
115
+ function reversed_sites (n:: StateOrOpName , domain)
116
+ return reverse_sites (n, reshape (n (domain... ), length .(axes (n, reverse (domain)))))
117
+ end
118
+ function reverse_sites (n:: OpName , a:: AbstractArray )
119
+ ndomain = Int (ndims (a)// 2 )
120
+ perm1 = reverse (ntuple (identity, ndomain))
121
+ perm2 = perm1 .+ ndomain
122
+ perm = (perm1... , perm2... )
123
+ return permutedims (a, perm)
103
124
end
104
- function op_convert (
105
- arrtype:: Type{<:AbstractArray{<:Any,N}} , domain:: Tuple{Vararg{Integer}} , a:: AbstractArray
106
- ) where {N}
107
- size = (domain... , domain... )
108
- @assert length (size) == N
109
- return convert (arrtype, reshape (a, size))
125
+
126
+ function state_or_op_convert (
127
+ n:: StateOrOpName ,
128
+ arrtype:: Type{<:AbstractArray} ,
129
+ domain:: Tuple{Vararg{AbstractUnitRange}} ,
130
+ a:: AbstractArray ,
131
+ )
132
+ ax = axes (n, domain)
133
+ a′ = reshape (a, length .(ax))
134
+ a′′ = array (a′, ax)
135
+ return convert (arrtype, a′′)
110
136
end
111
- function (arrtype:: Type{<:AbstractArray} )(n:: OpName , domain:: Tuple{Vararg{SiteType}} )
112
- return op_convert (arrtype, length .(domain), n (domain... ))
137
+
138
+ function (arrtype:: Type{<:AbstractArray} )(n:: StateOrOpName , domain:: Tuple{Vararg{SiteType}} )
139
+ domain′ = AbstractUnitRange .(domain)
140
+ return state_or_op_convert (n, arrtype, domain′, reversed_sites (n, domain))
113
141
end
114
- function (arrtype:: Type{<:AbstractArray} )(n:: OpName , domain:: Tuple{Vararg{Integer}} )
115
- return op_convert (arrtype, domain, n (Int .(domain)... ))
142
+ function (arrtype:: Type{<:AbstractArray} )(
143
+ n:: StateOrOpName , domain:: Tuple{Vararg{AbstractUnitRange}}
144
+ )
145
+ # TODO : Make `(::OpName)(domain...)` constructor process more general inputs.
146
+ return state_or_op_convert (n, arrtype, domain, reversed_sites (n, Int .(length .(domain))))
116
147
end
117
148
118
149
function op (arrtype:: Type{<:AbstractArray} , n:: String , domain... ; kwargs... )
@@ -475,13 +506,13 @@ function (n::OpName"Controlled")(domain...)
475
506
# Number of control sites.
476
507
nc = get (params (n), :ncontrol , length (domain) - nt)
477
508
@assert length (domain) == nc + nt
478
- d_control = prod (to_dim .(domain[ 1 : nc ]))
509
+ d_control = prod (to_dim .(domain)) - prod ( to_dim .(domain[(nc + 1 ) : end ]))
479
510
return cat (I (d_control), n. arg (domain[(nc + 1 ): end ]. .. ); dims= (1 , 2 ))
480
511
end
481
- @op_alias " CNOT" " Controlled" op = OpName " X" ()
482
- @op_alias " CX" " Controlled" op = OpName " X" ()
483
- @op_alias " CY" " Controlled" op = OpName " Y" ()
484
- @op_alias " CZ" " Controlled" op = OpName " Z" ()
512
+ @op_alias " CNOT" " Controlled" arg = OpName " X" ()
513
+ @op_alias " CX" " Controlled" arg = OpName " X" ()
514
+ @op_alias " CY" " Controlled" arg = OpName " Y" ()
515
+ @op_alias " CZ" " Controlled" arg = OpName " Z" ()
485
516
function alias (n:: OpName"CPhase" )
486
517
return controlled (OpName " Phase" (; params (n)... ))
487
518
end
@@ -504,17 +535,17 @@ function alias(::OpName"CRn")
504
535
end
505
536
@op_alias " CRn̂" " CRn"
506
537
507
- @op_alias " CCNOT" " Controlled" ncontrol = 2 op = OpName " X" ()
538
+ @op_alias " CCNOT" " Controlled" ncontrol = 2 arg = OpName " X" ()
508
539
@op_alias " Toffoli" " CCNOT"
509
540
@op_alias " CCX" " CCNOT"
510
541
@op_alias " TOFF" " CCNOT"
511
542
512
- @op_alias " CSWAP" " Controlled" ncontrol = 2 op = OpName " SWAP" ()
543
+ @op_alias " CSWAP" " Controlled" ncontrol = 2 arg = OpName " SWAP" ()
513
544
@op_alias " Fredkin" " CSWAP"
514
545
@op_alias " CSwap" " CSWAP"
515
546
@op_alias " CS" " CSWAP"
516
547
517
- @op_alias " CCCNOT" " Controlled" ncontrol = 3 op = OpName " X" ()
548
+ @op_alias " CCCNOT" " Controlled" ncontrol = 3 arg = OpName " X" ()
518
549
519
550
# # # 1-qudit rotation around generic axis n̂.
520
551
# # # exp(-im * α / 2 * n̂ ⋅ σ⃗)
0 commit comments