@@ -8,8 +8,8 @@ struct OpName{Name,Params}
88end
99name (:: OpName{Name} ) where {Name} = Name
1010params (n:: OpName ) = getfield (n, :params )
11-
1211Base. getproperty (n:: OpName , name:: Symbol ) = getfield (params (n), name)
12+ Base. get (t:: OpName , name:: Symbol , default) = get (params (t), name, default)
1313
1414OpName {N} (; kwargs... ) where {N} = OpName {N} ((; kwargs... ))
1515
5454# Generic to `StateName` or `OpName`.
5555const StateOrOpName = Union{StateName,OpName}
5656alias (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+ )
5860 return arrtype (n, domain)
5961end
62+ function (arrtype:: Type{<:AbstractArray} )(n:: StateOrOpName , domain:: Tuple{Vararg{Integer}} )
63+ return arrtype (n, Base. oneto .(domain))
64+ end
6065(arrtype:: Type{<:AbstractArray} )(n:: StateOrOpName , ts:: SiteType... ) = arrtype (n, ts)
6166function (n:: StateOrOpName )(domain... )
6267 # TODO : Try one alias at a time?
@@ -87,32 +92,58 @@ function nsites(n::StateOrOpName)
8792 return nsites (n′)
8893end
8994
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... ]
9799end
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)
103124end
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′′)
110136end
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))
113141end
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))))
116147end
117148
118149function op (arrtype:: Type{<:AbstractArray} , n:: String , domain... ; kwargs... )
@@ -475,13 +506,13 @@ function (n::OpName"Controlled")(domain...)
475506 # Number of control sites.
476507 nc = get (params (n), :ncontrol , length (domain) - nt)
477508 @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 ]))
479510 return cat (I (d_control), n. arg (domain[(nc + 1 ): end ]. .. ); dims= (1 , 2 ))
480511end
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" ()
485516function alias (n:: OpName"CPhase" )
486517 return controlled (OpName " Phase" (; params (n)... ))
487518end
@@ -504,17 +535,17 @@ function alias(::OpName"CRn")
504535end
505536@op_alias " CRn̂" " CRn"
506537
507- @op_alias " CCNOT" " Controlled" ncontrol = 2 op = OpName " X" ()
538+ @op_alias " CCNOT" " Controlled" ncontrol = 2 arg = OpName " X" ()
508539@op_alias " Toffoli" " CCNOT"
509540@op_alias " CCX" " CCNOT"
510541@op_alias " TOFF" " CCNOT"
511542
512- @op_alias " CSWAP" " Controlled" ncontrol = 2 op = OpName " SWAP" ()
543+ @op_alias " CSWAP" " Controlled" ncontrol = 2 arg = OpName " SWAP" ()
513544@op_alias " Fredkin" " CSWAP"
514545@op_alias " CSwap" " CSWAP"
515546@op_alias " CS" " CSWAP"
516547
517- @op_alias " CCCNOT" " Controlled" ncontrol = 3 op = OpName " X" ()
548+ @op_alias " CCCNOT" " Controlled" ncontrol = 3 arg = OpName " X" ()
518549
519550# # # 1-qudit rotation around generic axis n̂.
520551# # # exp(-im * α / 2 * n̂ ⋅ σ⃗)
0 commit comments