Define parameter-dependent operator for custom site type

Hi everyone,
I have defined a custom Hilbert space to describe particles with arbitrary spin S and introduced general expressions for the spin operators S_x, S_y and S_z.
I am now struggling to implement as a custom ITensor operator the projector P_m=|m\rangle \langle m| on the state |m\rangle of the computational basis (i.e. S_z |m\rangle = m |m\rangle). P_m is simply a matrix whose m-th diagonal element is 1, while the rest is 0.
Ideally, I would like to define a general operator with a parameter m, so that I can easily vary it for each element of the computational basis. This would greatly simplify the calculation of the corresponding expectation value at each site of the chain.

I have also another question regarding the site type “Qudit” and the definition of arbitrary operators. For example, a^\dagger is defined as

function op(::OpName"Adag", ::SiteType"Qudit", d::Int)
  mat = zeros(d, d)
  for k in 1:(d - 1)
    mat[k + 1, k] = √k
  end
  return mat
end

but what is the meaning of d? Once the qudit site type has been defined, then it is possible to call the operator without specifying the dimension, e.g.

N=10
sites=siteinds("Qudit", N; dim=2);
op("Adag", sites[5])

Am I missing something?

Thanks!

1 Like

To answer the first part of your question, you can define an op overload which takes custom keyword arguments then pass these keywords through a call to the top level op function. Here is some example code:

using ITensors

function ITensors.op(::OpName"Proj",::SiteType"S=1/2";m=1)
  M = zeros(2,2)
  M[m,m] = 1.0
  return M
end

let
  s = siteind("S=1/2")

  P1 = op("Proj",s;m=1)
  P2 = op("Proj",s;m=2)
  @show P1
  @show P2

  return
end

Notice above how my custom overload ITensors.op(::OpName"Proj",::SiteType"S=1/2";m=1) takes the m keyword argument then I pass m through the call to op in the main code below.


Regarding your other question about the "Qudit " site type, the purpose of the d::Int argument is so that our system internally can pass the dimension of the site to the op functions. Without it, they would not have the information needed to make the correct size matrix to return. This information gets automatically read off from the size of the Index passed to the op function at the user level, so you don’t have to pass it yourself (answering your questions about how it’s possible to call op without manually specifying the dimension yourself - that information is already contained in sites[5] in your example). You can just think of it as a required extra argument that all op overloads for the “Qudit” site type are required to have for internal, developer-level reasons.

Hi Miles,
Thanks for the help and your detailed answer.
Now I want to compute the expectation value of each projection operator P_m with respect to a random state. For the qudit case I was thinking of something of this kind

using ITensors

function ITensors.op(::OpName"Proj", ::SiteType"Qudit", d::Int; m=1)
  M = zeros(d,d)
  M[m,m] = 1.0
  return M
end

let 
    N=4
    d=5
    s = siteinds("Qudit", N, dim=d)
    psi_init=randomMPS(s, 10)

    P2=op("Proj", s[3]; m=2)
    
    for idxm in 1:d
        @show expect(psi_init, "Proj"; m=idxm)
    end

    return
    
end

but for each idxm I get the same results. I was wondering if there is a way to pass the parameter m directly in the expect function, without having to overload every time the definition of the projector.
Thanks!

Currently the expect function doesn’t forward its keyword arguments to the op function inside, which I think we have good reasons for doing (mainly that not all of the op overloads accept keywords).

So a different solution that could work well for you is to use the version of expect that takes a Julia Matrix as input rather than the name (string) of an operator.

So for example:

for idxm in 1:d
   Pi = zeros(d,d)
   Pi[idxm,idxm] = 1.0
   @show expect(psi_init,Pi)
end

You can see the interface for expect in the following documentation:
https://itensor.github.io/ITensors.jl/stable/MPSandMPO.html#ITensors.expect-Tuple{MPS,%20Any}

1 Like

Thanks!

1 Like