Defining states with parameters as keyword arguments

Hi everyone!

I defined a custom SiteType vecOsc and I’m trying to define some states and operator associated with it, by overloading the ITensors.state and ITensors.op functions.
The construction of a certain state “Therm” requires additional arguments, say a temperature T, so I figured I could overload state like

ITensors.state(::StateName"Therm", ::SiteType"vecOsc"; T::Real)

which returns a vector. When I want to create such a state on an Index s with the tag vecOsc, I would call

ITensors.state(s, "Therm"; T=t)

If I understand correctly, the first thing that happens (looking at src/physics/sitetype.jl:551) is that the library calls

state(StateName("Therm"), SiteType(st); kwargs...)

trying each st from the tags of s. If the result is nothing, then it skips the tag and tries with the next one.

Here is the issue: if I create “vecOsc” sites through siteinds they will have the tags “Site” and “n=N” (for some N) too, and there is no

state(::StateName"Therm", ::SiteType"Site"; kwargs...)

defined. As a consequence, a MethodError exception is thrown, saying that there is no method matching my call.
Only the following functions

state(::StateName, ::SiteType) = nothing
state(::StateName, ::SiteType, ::Index) = nothing
state!(::ITensor, ::StateName, ::SiteType, ::Index) = nothing

are defined as default, and none of them has keyword arguments, so they don’t match state(::StateName"Therm", ::SiteType"Site"; kwargs...) above.
To solve this, I added in my script the following function

ITensors.state(::StateName, ::SiteType, ::Index; kwargs...) = nothing

and I got no more errors.

Now, I would also like to create a Julia package from my scripts, and these “states with parameters” are in it. When I load my package in the REPL, however, it warns me that the method definition state(ITensors.StateName{Name} where Name, ITensors.SiteType{T} where T, ITensors.Index{T} where T) in module ITensors at .../src/physics/sitetype.jl:516 is overwritten by my own definition I added (the last one), and that as a consequence “incremental compilation may be fatally broken for this module”.

This obviously doesn’t feel right, so I ask you, is my workaround the right way to allow my states to have keyword arguments? Or are there better alternatives to create states with parameters?

I think it was just an oversight that we don’t forward the keyword arguments through the ITensors.state function, it would be nice to add support for that so the code you are trying above will work (we have that supported for ITensors.op but I think we just didn’t have examples of state definitions with parameters so far). Would you mind making a pull request with the change you made above? Then we can include it in the next version of ITensors.jl.

Sure thing! I always wondered why the code was there for op but not for state. I should just add the ; kwargs... bit to the signatures of the three “default” functions, then, right? Or do I need to overload them separately?

It looks like ; kwargs... should be added to these lines: