OpSum definition for new sitetype

Hi,

I am trying to define a new sitetype which I call “SpinBoson”. It should be used to create sites with dimension 2*d, where d is the boson cutoff (essentially a qudit, where the operators should be Kronecker products of spin and boson operators).

Please see how I define a state and an OpSum:

using ITensors

ITensors.space(::SiteType"SpinBoson", d::Int) = 2*d # space dimension is twice the phonon cutoff
ITensors.state(::StateName"↓0", ::SiteType"SpinBoson", s::Index) = [if i==1 1.0 else 0.0 end for i=1:dim(s)] # ground state

""" Setup parameters """

N = 2 # number of sites
d = 6 # boson cutoff dimension

sites = [siteind("SpinBoson", d) for _ in 1:N] # site indices
states = ["↓0" for _ in 1:N] # ground state
psi = MPS(sites, states); # initialize state in ground state
@show psi

""" apply some operator """
function ITensors.op(::OpName"Ia", ::SiteType"SpinBoson", s::Index)
    d = Int(dim(s)/2)
    mat = zeros(d, d)
    for k in 1:(d - 1)
      mat[k+1, k] = √k
    end
    return kron(Matrix(I,2,2), mat)
end

os = OpSum()
os += 1.0,"Ia",1,"Ia",2
Op = MPO(os, sites)

psi_new = apply(Op, psi)

I get the error:

ERROR: MethodError: Cannot `convert` an object of type Matrix{Float64} to an object of type ITensor

What am I doing wrong here? I can define a single site operator “Ia” and construct an MPO from it, But the OpSum does not work for some reason.

Would be happy for some advice about that.
Thanks

If you use an op definition that includes the index s you’ll need to return an ITensor. If you leave out the index, then your example will work but will miss the necessary d value.
To include the d like in the example,

function ITensors.op(::OpName"Ia", ::SiteType"SpinBoson", d::Int)
    mat = zeros(d, d)
    for k in 1:(d - 1)
      mat[k+1, k] = √k
    end
    return kron(Matrix(I,2,2), mat)
end

you will need to build up the sitetype so that the dim d is being passed like the boson states (see for example here: ITensors.jl/src/lib/SiteTypes/src/sitetypes/boson.jl at main · ITensor/ITensors.jl · GitHub )

The quick fix for your operator is to return ITensor(kron(Matrix(I,2,2), mat), s, s')

1 Like

Thanks! It works.

1 Like