Skip to content

Revamp count cycles#504

Open
Krzmbrzl wants to merge 2 commits intoValeevGroup:masterfrom
Krzmbrzl:revamp-count-cycles
Open

Revamp count cycles#504
Krzmbrzl wants to merge 2 commits intoValeevGroup:masterfrom
Krzmbrzl:revamp-count-cycles

Conversation

@Krzmbrzl
Copy link
Collaborator

@Krzmbrzl Krzmbrzl commented Mar 2, 2026

No description provided.

@Krzmbrzl Krzmbrzl linked an issue Mar 2, 2026 that may be closed by this pull request
@Krzmbrzl Krzmbrzl added bug Something isn't working feature New feature and removed bug Something isn't working labels Mar 2, 2026
@Krzmbrzl Krzmbrzl force-pushed the revamp-count-cycles branch 3 times, most recently from c16af57 to 3ef7dde Compare March 2, 2026 15:45
@Krzmbrzl Krzmbrzl marked this pull request as draft March 2, 2026 15:47
@Krzmbrzl Krzmbrzl force-pushed the revamp-count-cycles branch from 3ef7dde to 4f035e4 Compare March 2, 2026 15:51
@Krzmbrzl Krzmbrzl marked this pull request as ready for review March 2, 2026 15:54

idx1 = std::distance(v1.begin(), it1);
SEQUANT_ASSERT(idx1 >= 0);
it0 = std::find(begin(v0), end(v0), *val_it);
Copy link
Member

Choose a reason for hiding this comment

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

isn't it0 always equal to val_it? There are no duplicates in v0 (or v1)...

Copy link
Collaborator Author

@Krzmbrzl Krzmbrzl Mar 3, 2026

Choose a reason for hiding this comment

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

I thought so, too. But actually that's not true. Consider this example:

┎ it0
|  ┎ val_it
i1 i2 i3
i3 i1 i2
   ┖ it1

The thing is that we have to perform a positional lookup (look for the thing that is in the same column as it1 but in v0, rather than looking for a specific element (that one of the other iterators would point to).

When using one of the two iterators instead of val_it, we get an endless loop (which is evident from the above sketch).

std::remove_reference_t<Seq0> v(std::forward<Seq0>(v0));
using T = std::decay_t<decltype(v[0])>;
SEQUANT_ASSERT(ranges::is_permutation(v, v1));
std::size_t count_cycles(Seq0&& v0, Seq1&& v1) {
Copy link
Member

Choose a reason for hiding this comment

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

can probably take both via const lvalue ref?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Unfortunately no - ranges can't be iterated (in general) when they are const. Hence, the only way to write a function that works for generic ranges is by taking them as non-const. Personally, I consider this a major flaw in the standard, but that's what it is... ¯_(ツ)_/¯

@evaleev evaleev added this to the 2.3 milestone Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Get rid of requirement for index space p to exist

2 participants