@@ -43,11 +43,31 @@ struct Create{H<:HilbertSpace,S,A,M} <: QSym
4343 end
4444end
4545
46- for T in (:Create , :Destroy )
46+ """
47+ GroundStateProjection <: QSym
48+
49+ Bosonic operator on a [`FockSpace`](@ref) representing the quantum harmonic
50+ oscillator ground state projection.
51+
52+ Warning: The ground state projection is not meant to be used in the cumulant
53+ expansion.
54+ """
55+ struct GroundStateProjection{H<: HilbertSpace ,S,A,M} <: QSym
56+ hilbert:: H
57+ name:: S
58+ aon:: A
59+ metadata:: M
60+ function GroundStateProjection {H,S,A,M} (hilbert:: H , name:: S , aon:: A , metadata:: M ) where {H,S,A,M}
61+ @assert has_hilbert (FockSpace,hilbert,aon)
62+ new (hilbert,name,aon,metadata)
63+ end
64+ end
65+
66+ for T in (:Create , :Destroy , :GroundStateProjection )
4767 @eval Base. isequal (a:: $T , b:: $T ) = isequal (a. hilbert, b. hilbert) && isequal (a. name, b. name) && isequal (a. aon, b. aon)
4868end
4969
50- for f in [:Destroy ,:Create ]
70+ for f in [:Destroy ,:Create , :GroundStateProjection ]
5171 @eval $ (f)(hilbert:: H , name:: S , aon:: A ; metadata:: M = NO_METADATA) where {H,S,A,M} = $ (f){H,S,A,M}(hilbert,name,aon,metadata)
5272 @eval $ (f)(hilbert:: FockSpace , name; metadata= NO_METADATA) = $ (f)(hilbert,name,1 ; metadata)
5373 @eval function $ (f)(hilbert:: H , name:: S , aon:: A ; metadata:: M = NO_METADATA) where {H<: ProductSpace ,S,A<: Int ,M}
7595
7696Base. adjoint (op:: Destroy ) = Create (op. hilbert,op. name,acts_on (op); op. metadata)
7797Base. adjoint (op:: Create ) = Destroy (op. hilbert,op. name,acts_on (op); op. metadata)
98+ Base. adjoint (op:: GroundStateProjection ) = op
7899
79100# Commutation relation in simplification
80101function * (a:: Destroy ,b:: Create )
@@ -89,11 +110,43 @@ function *(a::Destroy,b::Create)
89110 return QMul (1 , [b,a])
90111 end
91112end
92- # ismergeable(::Destroy,::Create) = true
93113
94- # TODO : test if faster; delete if and elseif in *- function above?
95- function ismergeable (a :: Destroy ,b :: Create )
114+ function * (a :: GroundStateProjection ,b :: GroundStateProjection )
115+ check_hilbert (a,b )
96116 aon_a = acts_on (a)
97117 aon_b = acts_on (b)
98- return aon_a == aon_b
99- end
118+ if aon_a == aon_b
119+ return a
120+ elseif aon_a < aon_b
121+ return QMul (1 , [a,b])
122+ else
123+ return QMul (1 , [b,a])
124+ end
125+ end
126+
127+ for (T1,T2) in ((:Destroy , :GroundStateProjection ), (:GroundStateProjection , :Create ))
128+ @eval function * (a:: $T1 ,b:: $T2 )
129+ check_hilbert (a,b)
130+ aon_a = acts_on (a)
131+ aon_b = acts_on (b)
132+ if aon_a == aon_b
133+ return 0
134+ elseif aon_a < aon_b
135+ return QMul (1 , [a,b])
136+ else
137+ return QMul (1 , [b,a])
138+ end
139+ end
140+ end
141+
142+ for T1 in (:Destroy , :GroundStateProjection )
143+ for T2 in (:Create , :GroundStateProjection )
144+ # ismergeable(::$T1,::$T2) = true
145+ # TODO : test if faster; delete if and elseif in *-function above?
146+ @eval function ismergeable (a:: $T1 ,b:: $T2 )
147+ aon_a = acts_on (a)
148+ aon_b = acts_on (b)
149+ return aon_a == aon_b
150+ end
151+ end
152+ end
0 commit comments