Definition of a new bosonic state

Dear ITensor team,

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:

  1. 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)
  1. 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"

Can you please explain why is that?

Thanks,
Yotam

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 Index s 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
1 Like

Thanks Miles!

Is it also possible to pass \alpha as an argument to the function, or only with some wrapper function over it?

Hi Yotam,

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 ϕ
1 Like

Got it, thanks :slight_smile: