# Define parameter-dependent operator for custom site type

**URL:** <https://itensor.discourse.group/t/define-parameter-dependent-operator-for-custom-site-type/661>\
**Category:** ITensor Julia Questions\
**Created:** [February 23, 2023, 5:52pm UTC](https://itensor.discourse.group/t/define-parameter-dependent-operator-for-custom-site-type/661 "2023-02-23T17:52:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gc6020](https://avatars.discourse-cdn.com/v4/letter/g/ec9cab/32.png) [@gc6020](https://itensor.discourse.group/u/gc6020)\
**Post date:** [February 23, 2023, 5:52pm UTC](https://itensor.discourse.group/t/define-parameter-dependent-operator-for-custom-site-type/661/1 "2023-02-23T17:52:53Z")

</div>

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

```auto
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.

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

```

Am I missing something?

Thanks!

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [February 23, 2023, 6:34pm UTC](https://itensor.discourse.group/t/define-parameter-dependent-operator-for-custom-site-type/661/2 "2023-02-23T18:34:39Z")

</div>

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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![gc6020](https://avatars.discourse-cdn.com/v4/letter/g/ec9cab/32.png) [@gc6020](https://itensor.discourse.group/u/gc6020)\
**Post date:** [February 24, 2023, 9:09am UTC](https://itensor.discourse.group/t/define-parameter-dependent-operator-for-custom-site-type/661/3 "2023-02-24T09:09:07Z")

</div>

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

```auto
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!

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [February 24, 2023, 3:21pm UTC](https://itensor.discourse.group/t/define-parameter-dependent-operator-for-custom-site-type/661/4 "2023-02-24T15:21:42Z")

</div>

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:

```julia
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}](https://itensor.github.io/ITensors.jl/stable/MPSandMPO.html#ITensors.expect-Tuple%7BMPS,%20Any%7D)

---

<div class="post-metadata">

**Author:** ![gc6020](https://avatars.discourse-cdn.com/v4/letter/g/ec9cab/32.png) [@gc6020](https://itensor.discourse.group/u/gc6020)\
**Post date:** [February 24, 2023, 3:46pm UTC](https://itensor.discourse.group/t/define-parameter-dependent-operator-for-custom-site-type/661/5 "2023-02-24T15:46:07Z")

</div>

Thanks!
