Creating a product MPS state out of custom parameterized states

Hi! I would like to create a product state with custom parameterized states defined on each site. In this example, the custom parameterized states are coherent states with an input parameter \alpha. The code below successfully passes \alpha into the construction of the coherent state ITensor, but I am not sure the best way to then pass it into the productMPS construction.

I was able to reference these posts about defining custom (coherent) states (Defining states with parameters as keyword arguments and Definition of a new bosonic state - #4 by kmp5) , but I would like to go one step further and make it a customized productMPS state.

I figure this could be done either by

  1. Inputing an array of ITensor states, which would then be input into the productMPS function
using ITensors, ITensorMPS
using LinearAlgebra

# annihilation operator
a_op(d) = diagm(1 => [sqrt(i) for i in 1:(d-1)]) 
# matrix elements of the displacement operator
D(α::ComplexF64, d::Int) = exp(α*a_op(d)'-α'*a_op(d)) 

# Coherent state on a single site
function ITensors.state(::StateName"coherent", ::SiteType"Boson", s::Index; α::Union{Float64, ComplexF64})
    @show α
    D(α, dim(s))*[if n==1 1 else 0 end for n=1:dim(s)]
end

# Number of sites
N = 3
# Hilbert Space truncation
d = 10

sites = siteinds("Boson", N; dim=d);

# Prepare the product state from an array of ITensor 
# coherent states on each site
α = 10*im
states = [state("coherent", sites[i]; α=α) for i in 1:N ]
ψ_coherent = productMPS(ComplexF64, states)

which gives the following error:

ERROR: LoadError: MethodError: no method matching MPS(::Type{ComplexF64}, ::Vector{ITensor})
  1. Or, alternatively, pass the parameter directly into the productMPS like
# # Or be able to pass the parameter values directly into the productMPS (Prefered)
ψ_coherent = productMPS(ComplexF64, sites, "coherent"; α = α)

which gives the following error

ERROR: LoadError: MethodError: no method matching MPS(::Type{ComplexF64}, ::Vector{Index{Int64}}, ::String; α::ComplexF64)

I think I’m missing how to best input these states into the productMPS function and any guidance would be greatly appreciated!

Not sure if this is what you’re looking for, but here’s some custom code you can use that makes a product state just by assigning each tensor of an MPS to be a vector. Then you can make the vectors to be anything you want, and use similar code (wrapped up in a function) to make the product states you would like:

using ITensors
using ITensorMPS

let
  N = 10

  states = Vector{Vector{Float64}}(undef,N)
  for j=1:N
    states[j] = randn(2)
  end

  s = siteinds("S=1/2",N)
  psi = MPS(s)
  for j=1:N
    psi[j] = ITensor(states[j],s[j])
  end
  psi = orthogonalize(psi,1)
  psi = normalize(psi)

  return
end

All you would do is replace the loop that assigns states[j] to be a random vector with any other code you want to make those vectors to be the ones you want (and of the correct size for the sites you have). The call to orthogonalize will automatically put in (dimension 1) link indices connecting the site tensors and normalize will ensure that the state is normalized to 1.0.

2 Likes

Please note that you should use MPS instead of productMPS, productMPS is deprecated and will be removed.

Ah, good to know - thank you!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.