Skip to content

Commit

Permalink
add GroundStateProjection operator for FockSpace
Browse files Browse the repository at this point in the history
  • Loading branch information
benneti committed Dec 11, 2024
1 parent 95499fa commit 4f218a1
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/QuantumCumulants.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import QuantumOpticsBase: ⊗, tensor

export HilbertSpace, ProductSpace, , tensor,
QSym, QTerm, @qnumbers,
FockSpace, Destroy, Create,
FockSpace, Destroy, Create, GroundStateProjection,
NLevelSpace, Transition,
PauliSpace, Pauli, SpinSpace, Spin,
MeanfieldEquations,
Expand Down
64 changes: 57 additions & 7 deletions src/fock.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,28 @@ struct Create{H<:HilbertSpace,S,A,M} <: QSym
end
end

for T in (:Create, :Destroy)
"""
GroundStateProjection <: QSym
Bosonic operator on a [`FockSpace`](@ref) representing the quantum harmonic
oscillator ground state projection.
"""
struct GroundStateProjection{H<:HilbertSpace,S,A,M} <: QSym
hilbert::H
name::S
aon::A
metadata::M
function GroundStateProjection{H,S,A,M}(hilbert::H, name::S, aon::A, metadata::M) where {H,S,A,M}
@assert has_hilbert(FockSpace,hilbert,aon)
new(hilbert,name,aon,metadata)
end
end

for T in (:Create, :Destroy, :GroundStateProjection)
@eval Base.isequal(a::$T, b::$T) = isequal(a.hilbert, b.hilbert) && isequal(a.name, b.name) && isequal(a.aon, b.aon)
end

for f in [:Destroy,:Create]
for f in [:Destroy,:Create, :GroundStateProjection]
@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)
@eval $(f)(hilbert::FockSpace, name; metadata=NO_METADATA) = $(f)(hilbert,name,1; metadata)
@eval function $(f)(hilbert::H, name::S, aon::A; metadata::M=NO_METADATA) where {H<:ProductSpace,S,A<:Int,M}
Expand Down Expand Up @@ -75,6 +92,7 @@ end

Base.adjoint(op::Destroy) = Create(op.hilbert,op.name,acts_on(op); op.metadata)
Base.adjoint(op::Create) = Destroy(op.hilbert,op.name,acts_on(op); op.metadata)
Base.adjoint(op::GroundStateProjection) = op

# Commutation relation in simplification
function *(a::Destroy,b::Create)
Expand All @@ -89,11 +107,43 @@ function *(a::Destroy,b::Create)
return QMul(1, [b,a])
end
end
# ismergeable(::Destroy,::Create) = true

# TODO: test if faster; delete if and elseif in *-function above?
function ismergeable(a::Destroy,b::Create)
function *(a::GroundStateProjection,b::GroundStateProjection)
check_hilbert(a,b)
aon_a = acts_on(a)
aon_b = acts_on(b)
return aon_a == aon_b
end
if aon_a == aon_b
return a
elseif aon_a < aon_b
return QMul(1, [a,b])
else
return QMul(1, [b,a])
end
end

for (T1,T2) in ((:Destroy, :GroundStateProjection), (:GroundStateProjection, :Create))
@eval function *(a::$T1,b::$T2)
check_hilbert(a,b)
aon_a = acts_on(a)
aon_b = acts_on(b)
if aon_a == aon_b
return 0
elseif aon_a < aon_b
return QMul(1, [a,b])
else
return QMul(1, [b,a])
end
end
end

for T1 in (:Destroy, :GroundStateProjection)
for T2 in (:Create, :GroundStateProjection)
# ismergeable(::$T1,::$T2) = true
# TODO: test if faster; delete if and elseif in *-function above?
@eval function ismergeable(a::$T1,b::$T2)
aon_a = acts_on(a)
aon_b = acts_on(b)
return aon_a == aon_b
end
end
end
12 changes: 12 additions & 0 deletions test/test_fock.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@ using Test
hf = FockSpace(:c)

a = Destroy(hf,:a)
P0 = GroundStateProjection(hf, :P_0)
ad = a'

@test !isequal(hash(a), hash(ad))
b = Destroy(hf,:b)
@test !isequal(hash(a), hash(b))
@test !isequal(hash(a), hash(P0))

@test isequal(a,ad')
@test isequal(simplify(a+a),2*a)
@test isequal(simplify(a/2 + 0.5*a),a)
@test isequal(a*a' , 1+a'*a)
@test isequal(simplify(a*a' + 1) , 2 + a'*a)
@test isequal(simplify(P0 + P0) , 2*P0)
@test isequal(simplify(P0^2) , P0)
@test isequal(simplify(a'*a*(a')^3*P0^2) , 3*(a')^3*P0)

@test isequal(simplify(-1*(a'*a + 1)*a + a) , -1*a'*a^2)
@test isequal(simplify(a'*a*a - a*a'*a) , -1*a)
@test isequal(simplify(P0 - P0) , 0)

# Single mode
ωc = 0.1313
Expand All @@ -34,11 +40,17 @@ da = simplify(1.0im*(H*a - a*H))
@test iszero(substitute(x*a, Dict(x=>0)))
@test isequal(substitute(x*a, Dict(x=>1)), a)
@test iszero(substitute(x*a, Dict(a=>0)))
@test iszero(substitute(x*P0, Dict(x=>0)))
@test isequal(substitute(x*P0, Dict(x=>1)), P0)
@test iszero(substitute(x*P0, Dict(P0=>0)))

# Test substitute by syms
@syms y
@test isequal(substitute(x*a, Dict(x=>y)), y*a)
@test isequal(substitute(x*a, Dict(a=>y)), x*y)
@test isequal(substitute(x*(a+a'), Dict(x => y)), y*(a + a'))
@test isequal(substitute(x*P0, Dict(x=>y)), y*P0)
@test isequal(substitute(x*P0, Dict(P0=>y)), x*y)
@test isequal(substitute(x*(P0+a'*P0), Dict(x => y)), y*(P0 + a'*P0))

end # testset

0 comments on commit 4f218a1

Please sign in to comment.