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

[ITensor] [Bug] Fix replaceinds for long inputs #1098

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/indexset.jl
Copy link
Member

@mtfishman mtfishman Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method:

function replaceinds(is::Indices, rep_inds::Vector{<:Pair{<:Index,<:Index}})
  return replaceinds(is, rep_inds...)
end

is also potentially problematic since splatting with ... has similar to using Tuple when it comes to performance for long lists (i.e. we should avoid splatting long lists).

I think we could just use this instead:

function replaceinds(is::Indices, rep_inds::Vector{<:Pair{<:Index,<:Index}})
  return replaceinds(is, first.(rep_inds), last.(rep_inds))
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would rewrite:

function replaceinds(is::Indices, rep_inds::Tuple{Vararg{Pair{<:Index,<:Index}}})
  return replaceinds(is, rep_inds...)
end

as:

function replaceinds(is::Indices, rep_inds::Tuple{Vararg{Pair{<:Index,<:Index}}})
  return replaceinds(is, first.(rep_inds), last.(rep_inds))
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another simplification I would suggest is changing:

function replaceinds(is::Indices, rep_inds::Pair{<:Index,<:Index}...)
  return replaceinds(is, zip(rep_inds...)...)
end

to:

function replaceinds(is::Indices, rep_inds::Pair{<:Index,<:Index}...)
  return replaceinds(is, first.(rep_inds), last.(rep_inds))
end

(The zip version is too clever by half.)

Another thing I noticed looking back through this code is that we might have to add a missing method:

replaceinds(is::Indices, i1::Index, i2::Index) = replaceinds(is, (i1,), (i2,))

for trying to replace a single Index.

Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ function replaceinds(is::Indices, rep_inds::Tuple{Vararg{Pair{<:Index,<:Index}}}
end

function replaceinds(is::Indices, rep_inds::Pair)
return replaceinds(is, Tuple(first(rep_inds)) .=> Tuple(last(rep_inds)))
return replaceinds(is, first(rep_inds) .=> last(rep_inds))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can just use:

  return replaceinds(is, first(rep_inds), last(rep_inds))

instead, which would then directly call the core version replaceinds(is::Indices, inds1, inds2). The logic of this code is a bit spaghetti-like, it's hard to track what is calling what and how it finally gets to the core implementation (which is my fault, this is some very early-days ITensors.jl code which has not been revisited in a while).

end

# Check that the QNs are all the same
Expand Down