@@ -50,19 +50,54 @@ for op in (:(+), :(-), :(*))
5050 end
5151end
5252
53+ function check_mul_dims (from:: SVector{NA,AbstractSpace} , to:: SVector{NB,AbstractSpace} ) where {NA,NB}
54+ (from != to) && throw (
55+ DimensionMismatch (
56+ " The quantum object with dims = $from can not multiply a quantum object with dims = $to on the right-hand side." ,
57+ ),
58+ )
59+ return nothing
60+ end
61+
62+ for ADimType in (:Dimensions , :CompoundDimensions )
63+ for BDimType in (:Dimensions , :CompoundDimensions )
64+ if ADimType == BDimType == :Dimensions
65+ @eval begin
66+ function LinearAlgebra.:(* )(
67+ A:: AbstractQuantumObject{DT1,OperatorQuantumObject,$ADimType{NA}} ,
68+ B:: AbstractQuantumObject{DT2,OperatorQuantumObject,$BDimType{NB}} ,
69+ ) where {DT1,DT2,NA,NB}
70+ check_dims (A, B)
71+ return QuantumObject (A. data * B. data, Operator, A. dims)
72+ end
73+ end
74+ else
75+ @eval begin
76+ function LinearAlgebra.:(* )(
77+ A:: AbstractQuantumObject{DT1,OperatorQuantumObject,$ADimType{NA}} ,
78+ B:: AbstractQuantumObject{DT2,OperatorQuantumObject,$BDimType{NB}} ,
79+ ) where {DT1,DT2,NA,NB}
80+ check_mul_dims (A. from, B. to)
81+ return QuantumObject (A. data * B. data, Operator, CompoundDimensions (A. to, B. from))
82+ end
83+ end
84+ end
85+ end
86+ end
87+
5388function LinearAlgebra.:(* )(
5489 A:: AbstractQuantumObject{DT1,OperatorQuantumObject} ,
5590 B:: QuantumObject{DT2,KetQuantumObject} ,
5691) where {DT1,DT2}
57- check_dims (A , B)
58- return QuantumObject (A. data * B. data, Ket, A . dims )
92+ check_mul_dims (A . from , B. to )
93+ return QuantumObject (A. data * B. data, Ket, Dimensions (A . to) )
5994end
6095function LinearAlgebra.:(* )(
6196 A:: QuantumObject{DT1,BraQuantumObject} ,
6297 B:: AbstractQuantumObject{DT2,OperatorQuantumObject} ,
6398) where {DT1,DT2}
64- check_dims (A , B)
65- return QuantumObject (A. data * B. data, Bra, A . dims )
99+ check_mul_dims (A . from , B. to )
100+ return QuantumObject (A. data * B. data, Bra, Dimensions (B . from) )
66101end
67102function LinearAlgebra.:(* )(
68103 A:: QuantumObject{DT1,KetQuantumObject} ,
@@ -569,7 +604,7 @@ ptrace(QO::QuantumObject{<:AbstractArray,BraQuantumObject}, sel::Union{AbstractV
569604
570605function ptrace (QO:: QuantumObject{<:AbstractArray,OperatorQuantumObject} , sel:: Union{AbstractVector{Int},Tuple} )
571606 isa (QO. dims, CompoundDimensions) &&
572- (QO. dims . to != QO. dims . from) &&
607+ (QO. to != QO. from) &&
573608 throw (ArgumentError (" Invalid partial trace for dims = $(QO. dims) " ))
574609
575610 _non_static_array_warning (" sel" , sel)
@@ -587,7 +622,7 @@ function ptrace(QO::QuantumObject{<:AbstractArray,OperatorQuantumObject}, sel::U
587622 (n_d == 1 ) && return QO
588623 end
589624
590- dimslist = dims_to_list (QO. dims)
625+ dimslist = dims_to_list (QO. dims. to) # need `dims.to` here if QO is CompoundDimensions
591626 _sort_sel = sort (SVector {length(sel),Int} (sel))
592627 ρtr, dkeep = _ptrace_oper (QO. data, dimslist, _sort_sel)
593628 return QuantumObject (ρtr, type = Operator, dims = Dimensions (dkeep))
@@ -757,7 +792,7 @@ function permute(
757792 order:: Union{AbstractVector{Int},Tuple} ,
758793) where {T,ObjType<: Union{KetQuantumObject,BraQuantumObject,OperatorQuantumObject} }
759794 isa (A. dims, CompoundDimensions) &&
760- (A. dims . to != A. dims . from) &&
795+ (A. to != A. from) &&
761796 throw (ArgumentError (" Invalid permutation for dims = $(A. dims) " ))
762797
763798 (length (order) != length (A. dims)) &&
@@ -770,7 +805,7 @@ function permute(
770805 order_svector = SVector {length(order),Int} (order) # convert it to SVector for performance
771806
772807 # obtain the arguments: dims for reshape; perm for PermutedDimsArray
773- dimslist = dims_to_list (A. dims)
808+ dimslist = dims_to_list (A. dims. to) # need `dims.to` here if QO is CompoundDimensions
774809 dims, perm = _dims_and_perm (A. type, dimslist, order_svector, length (order_svector))
775810
776811 return QuantumObject (
0 commit comments