@@ -7,50 +7,22 @@ export AbstractDimensions, Dimensions, GeneralDimensions
77abstract type AbstractDimensions{M,N} end
88
99@doc raw """
10- struct Dimensions{N,T<:Tuple} <: AbstractDimensions{N, N}
11- to::T
12- end
13-
14- A structure that describes the Hilbert [`Space`](@ref) of each subsystems.
15- """
16- struct Dimensions{N,T<: Tuple } <: AbstractDimensions{N,N}
17- to:: T
18-
19- # make sure the elements in the tuple are all AbstractSpace
20- Dimensions (to:: NTuple{N,AbstractSpace} ) where {N} = new {N,typeof(to)} (to)
21- end
22- function Dimensions (dims:: Union{AbstractVector{T},NTuple{N,T}} ) where {T<: Integer ,N}
23- _non_static_array_warning (" dims" , dims)
24- L = length (dims)
25- (L > 0 ) || throw (DomainError (dims, " The argument dims must be of non-zero length" ))
26-
27- return Dimensions (Tuple (Space .(dims)))
28- end
29- Dimensions (dims:: Int ) = Dimensions (Space (dims))
30- Dimensions (dims:: DimType ) where {DimType<: AbstractSpace } = Dimensions ((dims,))
31- Dimensions (dims:: Any ) = throw (
32- ArgumentError (
33- " The argument dims must be a Tuple or a StaticVector of non-zero length and contain only positive integers." ,
34- ),
35- )
36-
37- @doc raw """
38- struct GeneralDimensions{N,T1<:Tuple,T2<:Tuple} <: AbstractDimensions{N}
10+ struct ProductDimensions{M,N,T1<:Tuple,T2<:Tuple} <: AbstractDimensions{M,N}
3911 to::T1
4012 from::T2
4113 end
4214
43- A structure that describes the left-hand side (`to`) and right-hand side (`from`) Hilbert [`Space`](@ref) of an [`Operator`](@ref) .
15+ A structure that describes the left-hand side (`to`) and right-hand side (`from`) dimensions of a quantum object .
4416"""
45- struct GeneralDimensions {M,N,T1<: Tuple ,T2<: Tuple } <: AbstractDimensions{M,N}
17+ struct ProductDimensions {M,N,T1<: Tuple ,T2<: Tuple } <: AbstractDimensions{M,N}
4618 to:: T1 # space acting on the left
4719 from:: T2 # space acting on the right
4820
4921 # make sure the elements in the tuple are all AbstractSpace
5022 GeneralDimensions (to:: NTuple{M,AbstractSpace} , from:: NTuple{N,AbstractSpace} ) where {M,N} =
5123 new {M,N,typeof(to),typeof(from)} (to, from)
5224end
53- function GeneralDimensions (dims:: Union{AbstractVector{T},NTuple{N,T}} ) where {T<: Union{AbstractVector,NTuple} ,N}
25+ function ProductDimensions (dims:: Union{AbstractVector{T},NTuple{N,T}} ) where {T<: Union{AbstractVector,NTuple} ,N}
5426 (length (dims) != 2 ) && throw (ArgumentError (" Invalid dims = $dims " ))
5527
5628 _non_static_array_warning (" dims[1]" , dims[1 ])
@@ -61,44 +33,40 @@ function GeneralDimensions(dims::Union{AbstractVector{T},NTuple{N,T}}) where {T<
6133 (L1 > 0 ) || throw (DomainError (L1, " The length of `dims[1]` must be larger or equal to 1." ))
6234 (L2 > 0 ) || throw (DomainError (L2, " The length of `dims[2]` must be larger or equal to 1." ))
6335
64- return GeneralDimensions (Tuple (Space .(dims[1 ])), Tuple (Space .(dims[2 ])))
36+ to = ntuple (i -> HilbertSpace (dims[1 ][i]), Val (L1))
37+ from = ntuple (i -> HilbertSpace (dims[2 ][i]), Val (L2))
38+
39+ return ProductDimensions (to, from)
6540end
6641
67- _gen_dimensions (dims:: AbstractDimensions ) = dims
68- _gen_dimensions (dims:: Union{AbstractVector{T},NTuple{N,T}} ) where {T<: Integer ,N} = Dimensions (dims)
69- _gen_dimensions (dims:: Union{AbstractVector{T},NTuple{N,T}} ) where {T<: Union{AbstractVector,NTuple} ,N} =
70- GeneralDimensions (dims)
71- _gen_dimensions (dims:: Any ) = Dimensions (dims)
42+ ProductDimensions (dims:: Union{Int, AbstractSpace} ) = ProductDimensions ((dims,), (dims,))
43+ ProductDimensions (to:: NTuple{M,Int} , from:: NTuple{N,Int} ) where {M,N} = ProductDimensions ((to, from))
44+ ProductDimensions (dims:: Union{AbstractVector{T},NTuple{N,T}} ) where {T<: Integer ,N} = ProductDimensions (dims, dims)
45+ ProductDimensions (dims:: ProductDimensions ) = dims
7246
7347# obtain dims in the type of SVector with integers
74- dimensions_to_dims (dimensions:: NTuple{N,AbstractSpace} ) where {N} = vcat (map (dimensions_to_dims, dimensions)... )
75- dimensions_to_dims (dimensions:: Dimensions ) = dimensions_to_dims (dimensions. to)
76- dimensions_to_dims (dimensions:: GeneralDimensions ) =
48+ dimensions_to_dims (dimensions:: NTuple{N,AbstractSpace} ) where {N} = SVector {N} (map (dimensions_to_dims, dimensions))
49+ dimensions_to_dims (dimensions:: ProductDimensions ) =
7750 SVector {2} (dimensions_to_dims (dimensions. to), dimensions_to_dims (dimensions. from))
78-
7951dimensions_to_dims (:: Nothing ) = nothing # for EigsolveResult.dimensions = nothing
8052
81- Base. length (:: AbstractDimensions{N} ) where {N} = N
53+ hilbert_dimensions_to_size (dimensions:: ProductDimensions ) = (prod (hilbert_dimensions_to_size, dimensions. to), prod (hilbert_dimensions_to_size, dimensions. from))
54+ liouvillian_dimensions_to_size (dimensions:: ProductDimensions ) =
55+ (prod (liouvillian_dimensions_to_size, dimensions. to), prod (liouvillian_dimensions_to_size, dimensions. from))
56+
8257
83- # need to specify return type `Int` for `_get_space_size`
84- # otherwise the type of `prod(::Dimensions)` will be unstable
85- _get_space_size (s:: AbstractSpace ):: Int = s. size
86- Base. prod (dims:: Dimensions ) = prod (dims. to)
87- Base. prod (spaces:: NTuple{N,AbstractSpace} ) where {N} = prod (_get_space_size, spaces)
58+ Base. length (:: AbstractDimensions{N} ) where {N} = N
8859
89- Base. transpose (dimensions:: Dimensions ) = dimensions
90- Base. transpose (dimensions:: GeneralDimensions ) = GeneralDimensions (dimensions. from, dimensions. to) # switch `to` and `from`
60+ Base. transpose (dimensions:: ProductDimensions ) = ProductDimensions (dimensions. from, dimensions. to) # switch `to` and `from`
9161Base. adjoint (dimensions:: AbstractDimensions ) = transpose (dimensions)
9262
9363# this is used to show `dims` for Qobj and QobjEvo
9464_get_dims_string (dimensions:: Dimensions ) = string (dimensions_to_dims (dimensions))
95- function _get_dims_string (dimensions:: GeneralDimensions )
65+ function _get_dims_string (dimensions:: ProductDimensions )
9666 dims = dimensions_to_dims (dimensions)
67+ dims[1 ] == dims[2 ] && return string (dims[1 ])
9768 return " [$(string (dims[1 ])) , $(string (dims[2 ])) ]"
9869end
9970_get_dims_string (:: Nothing ) = " nothing" # for EigsolveResult.dimensions = nothing
10071
101- Base.:(== )(dim1:: Dimensions , dim2:: Dimensions ) = dim1. to == dim2. to
102- Base.:(== )(dim1:: GeneralDimensions , dim2:: GeneralDimensions ) = (dim1. to == dim2. to) && (dim1. from == dim2. from)
103- Base.:(== )(dim1:: Dimensions , dim2:: GeneralDimensions ) = false
104- Base.:(== )(dim1:: GeneralDimensions , dim2:: Dimensions ) = false
72+ Base.:(== )(dim1:: ProductDimensions , dim2:: ProductDimensions ) = (dim1. to == dim2. to) && (dim1. from == dim2. from)
0 commit comments