Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ITensors] [ENHANCEMENT] Combining operators with parenthesis in single line in OpSum #1182

Open
muuusso opened this issue Aug 22, 2023 · 1 comment

Comments

@muuusso
Copy link

muuusso commented Aug 22, 2023

Since the documentation for OpSum is lacking, I'd like to know if there is a way of writing on one line an expression like

$$\sigma_1 (\sigma_2 + \sigma_3)$$

Now I'm able to do it in two lines as

os = OpSum()

os += "Z", 1, "Z", 2
os += "Z", 1, "Z", 3

but since I have expressions with many terms I'd like to able to write on one line. I tried something like

os = OpSum()

os += "Z", 1, "(", "Z", 2, "+", "Z", 3, ")"

or similar to this but it doesn't work.

@mtfishman
Copy link
Member

mtfishman commented Aug 22, 2023

Maybe not quite what you're hoping for, but you can do this:

julia> (OpSum() + ("Z", 1)) * (OpSum() + ("Z", 2) + ("Z", 3))
prod(
  sum(
  1.0 Z(1,)
)
  sum(
  1.0 Z(2,)
  1.0 Z(3,)
)
)

julia> Ops.expand((OpSum() + ("Z", 1)) * (OpSum() + ("Z", 2) + ("Z", 3)))
sum(
  1.0 Z(1,) Z(2,)
  1.0 Z(1,) Z(3,)
)

An alternative which isn't documented is that all of these operations are based on converting tuples like ("Z", 2) which represent operators on a certain site to an object Op("Z", 2). Those operators have various algebra operations defined for them. So you can do the same thing as the above with:

julia> Op("Z", 1) * (Op("Z", 2) + Op("Z", 3))
sum(
  Z(1,) Z(2,)
  Z(1,) Z(3,)
)

I don't think we will support the parentheses syntax you propose above. I was trying to move more towards lazy operations happening at the Op level using normal Julia algebra syntax, rather than through specialized syntax or parsing.

Something that isn't working now but should work is:

julia> ("Z", 1) * (OpSum() + ("Z", 2) + ("Z", 3))
ERROR: MethodError: no method matching *(::Op, ::Scaled{ComplexF64, Prod{Op}})

Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...)
   @ Base operators.jl:578
  *(::Union{InitialValues.NonspecificInitialValue, InitialValues.SpecificInitialValue{typeof(*)}}, ::Any)
   @ InitialValues ~/.julia/packages/InitialValues/OWP8V/src/InitialValues.jl:154
  *(::Number, ::ITensors.LazyApply.Applied{typeof(*), Tuple{C, A}, NamedTuple{(), Tuple{}}} where A) where C
   @ ITensors ~/.julia/packages/ITensors/hLDmL/src/LazyApply/LazyApply.jl:72
  ...

Stacktrace:
 [1] (::ITensors.Ops.var"#3#4"{Op})(a::Scaled{ComplexF64, Prod{Op}})
   @ ITensors.Ops ~/.julia/packages/ITensors/hLDmL/src/Ops/Ops.jl:208
 [2] iterate
   @ ./generator.jl:47 [inlined]
 [3] _collect
   @ ./array.jl:802 [inlined]
 [4] collect_similar
   @ ./array.jl:711 [inlined]
 [5] map
   @ ./abstractarray.jl:3261 [inlined]
 [6] *
   @ ~/.julia/packages/ITensors/hLDmL/src/Ops/Ops.jl:208 [inlined]
 [7] *(o1::Tuple{String, Int64}, o2::Sum{Scaled{ComplexF64, Prod{Op}}})
   @ ITensors.Ops ~/.julia/packages/ITensors/hLDmL/src/Ops/Ops.jl:296
 [8] top-level scope
   @ REPL[28]:1

julia> Op("Z", 1) * (OpSum() + ("Z", 2) + ("Z", 3))
ERROR: MethodError: no method matching *(::Op, ::Scaled{ComplexF64, Prod{Op}})

Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...)
   @ Base operators.jl:578
  *(::Union{InitialValues.NonspecificInitialValue, InitialValues.SpecificInitialValue{typeof(*)}}, ::Any)
   @ InitialValues ~/.julia/packages/InitialValues/OWP8V/src/InitialValues.jl:154
  *(::Number, ::ITensors.LazyApply.Applied{typeof(*), Tuple{C, A}, NamedTuple{(), Tuple{}}} where A) where C
   @ ITensors ~/.julia/packages/ITensors/hLDmL/src/LazyApply/LazyApply.jl:72
  ...

Stacktrace:
 [1] (::ITensors.Ops.var"#3#4"{Op})(a::Scaled{ComplexF64, Prod{Op}})
   @ ITensors.Ops ~/.julia/packages/ITensors/hLDmL/src/Ops/Ops.jl:208
 [2] iterate
   @ ./generator.jl:47 [inlined]
 [3] _collect
   @ ./array.jl:802 [inlined]
 [4] collect_similar
   @ ./array.jl:711 [inlined]
 [5] map
   @ ./abstractarray.jl:3261 [inlined]
 [6] *(o1::Op, o2::Sum{Scaled{ComplexF64, Prod{Op}}})
   @ ITensors.Ops ~/.julia/packages/ITensors/hLDmL/src/Ops/Ops.jl:208
 [7] top-level scope
   @ REPL[29]:1

I'll have to look into that, I think just a missing definition.

I'll leave this open as a remind to fix the last two bugs.

@mtfishman mtfishman changed the title Combining operators with parenthesis in single line in OpSum [ITensors] [ENHANCEMENT] Combining operators with parenthesis in single line in OpSum Aug 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants