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 e9cb961
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 9 deletions.
6 changes: 5 additions & 1 deletion docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ Destroy
Create
```

```@docs
GroundStateProjection
```

```@docs
Transition
```
Expand Down Expand Up @@ -330,4 +334,4 @@ MeanfieldNoiseEquations

```@docs
IndexedMeanfieldNoiseEquations
```
```
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
67 changes: 60 additions & 7 deletions src/fock.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,31 @@ 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.
Warning: The ground state projection is not meant to be used in the cumulant
expansion.
"""
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 +95,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 +110,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
4 changes: 4 additions & 0 deletions src/latexify_recipes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ function _postwalk_func(x)
elseif MacroTools.@capture(x, dagger(arg_))
s = "$(arg)^\\dagger"
return s
elseif MacroTools.@capture(x, GroundStateProjection(arg_))
s = "\\vert \\emptyset_$(arg) \\rangle \\langle \\emptyset_$(arg) \\vert"
return s
elseif MacroTools.@capture(x, Transition(arg_,i_,j_))
s = "{$(arg)}$(transition_idx_script[]){{$(i)$(j)}}"
return s
Expand Down Expand Up @@ -202,6 +205,7 @@ function _to_expression(x::Complex{Symbolics.Num}) # forward complex Nums to Sym
end
_to_expression(op::QSym) = op.name
_to_expression(op::Create) = :(dagger($(op.name)))
_to_expression(op::GroundStateProjection) = :(GroundStateProjection($(op.name)))
_to_expression(op::Transition) = :(Transition($(op.name),$(op.i),$(op.j)) )
xyz_sym=[:x,:y,:z]
_to_expression(op::Pauli) = :(Pauli($(op.name),$(xyz_sym[op.axis])))
Expand Down
1 change: 1 addition & 0 deletions src/printing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ end

Base.show(io::IO,x::QSym) = write(io, x.name)
Base.show(io::IO,x::Create) = write(io, string(x.name, ""))
Base.show(io::IO,x::GroundStateProjection) = write(io, string("∅_", x.name))
Base.show(io::IO,x::Transition) = write(io, Symbol(x.name,x.i,x.j))
Base.show(io::IO,x::Pauli) = write(io, Symbol(x.name,xyz_sym[x.axis]))
Base.show(io::IO,x::Spin) = write(io, Symbol(x.name,xyz_sym[x.axis]))
Expand Down
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, :a)
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 e9cb961

Please sign in to comment.