Skip to content

[ENHANCEMENT] Have op_term(::Tuple{Number}) return the identity #154

@jlbosse

Description

@jlbosse

When programatically constructing OpSums I sometimes encounter terms that are simply proportional to the identity and would hence be represented by the empty tuple (if the prefactor is 1) or by a tuple just containing a number. Currently, constructing an op_term from such a tuple fails with a BoundsError as shown below:

julia> using ITensors

julia> ITensors.Ops.op_term((2.0, ))
ERROR: BoundsError: attempt to access 0-element Vector{Int64} at index [1]
Stacktrace:
 [1] throw_boundserror(A::Vector{Int64}, I::Tuple{Int64})
   @ Base ./essentials.jl:14
 [2] getindex(A::Vector{Int64}, i::Int64)
   @ Base ./essentials.jl:916
 [3] first
   @ ./abstractarray.jl:452 [inlined]
 [4] split(f::Function, t::Tuple{})
   @ ITensors.Ops ~/.julia/packages/ITensors/VGXV2/src/lib/Ops/src/op.jl:24
 [5] op_term(a::Tuple{})
   @ ITensors.Ops ~/.julia/packages/ITensors/VGXV2/src/lib/Ops/src/op.jl:262
 [6] op_term(a::Tuple{Float64})
   @ ITensors.Ops ~/.julia/packages/ITensors/VGXV2/src/lib/Ops/src/op.jl:245
 [7] top-level scope
   @ REPL[6]:1

The desired behaviour would be something along the lines of

julia> ITensors.Ops.op_term((2.0, ))
2.0 Id()

which would be consistent with the empty product being 1.

My current work-around is to explicitly pass in (2.0, "Id", site)

julia> ITensors.Ops.op_term((2.0, "Id", 1))
2.0 Id(1,)

but this requires writing an extra if noperators == 0 check in my code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions