I am trying to define a coherent state as an initial state for a 1d bosonic system. I thought of two equivalent ways of doing that:
Begin in the bosonic ground state and apply a displacement operator in MPO form to it. This approach works with the following code:
N = 2 # number of ions
dim = 5 # local oscillator cutoff dimension
α = 0.01 # the initial coherent state's parameter
sites = siteinds("Boson", N, dim=dim); # create the site indices for MPS representation
a_op(d) = diagm(1 => [sqrt(i) for i in 1:(d-1)]) # annihilation operator
D(α, d) = exp(α*a_op(d)'-α'*a_op(d)) # matrix elements of the displacement operator
ITensors.op(::OpName"disp", ::SiteType"Boson", d::Int) = D(α, d);
""" Phonos ground state """
ψgs = MPS(sites, "0");
""" Multiply each site by displacement """
disp_mpo = MPO(sites, "disp")
ψ₀ = apply(disp_mpo, ψgs)
Directly define a coherent state. I do it using the following code:
N = 2 # number of bosons
dim = 5 # local oscillator cutoff dimension
sites = siteinds("Boson", N, dim=dim); # create the site indices for MPS representation
α = 0.01 # the coherent state's parameter
a_op(d) = diagm(1 => [sqrt(i) for i in 1:(d-1)]) # annihilation operator
D(α, d) = exp(α*a_op(d)'-α'*a_op(d)) # matrix elements of the displacement operator
ITensors.state(::StateName"coherent", ::SiteType"Boson", d::Int) = D(α, d)*[if n==1 1 else 0 end for n=1:d]
ψ₀ = MPS(sites, "coherent")
However, after running the second code I get the error:
ArgumentError: invalid base 10 digit 'c' in "coherent"
Please overload the state function this way instead: ITensors.state(::StateName"coherent", ::SiteType"Boson", s::Index)
then obtain the dimension of the site by calling dim(s) on the Indexs that gets passed. (Also you’ll need to rename your variable “dim” which is shadowing the dim function.)
Here’s a fixed example:
using ITensors
let
N = 2 # number of bosons
d = 5 # local oscillator cutoff dimension
sites = siteinds("Boson", N; dim=d); # create the site indices for MPS representation
α = 0.01 # the coherent state's parameter
a_op(d) = diagm(1 => [sqrt(i) for i in 1:(d-1)]) # annihilation operator
D(α, d) = exp(α*a_op(d)'-α'*a_op(d)) # matrix elements of the displacement operator
ITensors.state(::StateName"coherent", ::SiteType"Boson", s::Index) = D(α, dim(s))*[if n==1 1 else 0 end for n=1:dim(s)]
ψ₀ = MPS(sites, "coherent")
return
end
I don’t think you need to pass alpha explicitly because its a variable in the function D. I ran a quick test
using ITensors
let
N = 2 # number of bosons
d = 5 # local oscillator cutoff dimension
sites = siteinds("Boson", N; dim=d); # create the site indices for MPS representation
α = 0.01 # the coherent state's parameter
a_op(d) = diagm(1 => [sqrt(i) for i in 1:(d-1)]) # annihilation operator
D(α, d) = exp(α*a_op(d)'-α'*a_op(d)) # matrix elements of the displacement operator
function ITensors.state(::StateName"coherent", ::SiteType"Boson", s::Index)
@show α
D(α, dim(s))*[if n==1 1 else 0 end for n=1:dim(s)]
end
ψ₀ = MPS(sites, "coherent")
println("Finished with ψ₀")
α = 0.2
ϕ = MPS(sites, "coherent")
println("Finished with ϕ")
return
end
and see this as the output
α = 0.01
α = 0.01
Finished with ψ₀
α = 0.2
α = 0.2
Finished with ϕ