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

PSL #94

Merged
merged 5 commits into from
May 14, 2024
Merged

PSL #94

merged 5 commits into from
May 14, 2024

Conversation

michaelontiveros
Copy link
Contributor

No description provided.

@michaelontiveros michaelontiveros requested a review from perlinm as a code owner May 6, 2024 17:43
@perlinm
Copy link
Collaborator

perlinm commented May 6, 2024

Thanks for opening a PR! And apologies in advance that I am a bit bandwidth-limited at the moment, so it might take me some time to review this.

Some immediate questions:

  1. Why are the generator matrices for PSL the same as for SL? I can define a group from the set of its generator matrices (namely: the subspace of matrices spanned by arbitrary products of the generators), so equal generator matrices should mean equal groups, no?
  2. It looks like this assertion that PSL(2, 2).generators == SL(2, 2).generators is now broken --- which may be fine, but might warrant investigation to understand why. More worryingly, this assertion that PSL(2, 3).order == 24 is now broken. Why is that? Was the previous assertion wrong?

@perlinm
Copy link
Collaborator

perlinm commented May 6, 2024

I can answer my last question: it looks like PSL(2, 3).order should indeed be 12 and not 24. The GAP command Size(PSL(2, 3)); prints 12.

@michaelontiveros
Copy link
Contributor Author

The finite groups SL and PSL are this big:

SL(n, q).order = q**( n*(n-1)/2 ) * ( q**2 - 1 )*( q**3 - 1 ) *...* ( q**n - 1 )
PSL(n, q).order = SL(n, q).order / gcd(n, q-1)

@michaelontiveros
Copy link
Contributor Author

PSL(2, 2).generators and SL(2, 2).generators are different, but conjugate. This is because the elements of the target spaces are ordered differently.

@michaelontiveros
Copy link
Contributor Author

michaelontiveros commented May 6, 2024

Why are the generator matrices for PSL the same as for SL? I can define a group from the set of its generator matrices (namely: the subspace of matrices spanned by arbitrary products of the generators), so equal generator matrices should mean equal groups, no?

You are right, I don't actually construct a linear representation of PSL(n, q). As things stand, if linear_rep == False, then PSL constructs SL. All I do is quotient SL(n, q) by the action of the center. This maps the generators of the standard representation of SL(n, q) to equivalence classes of matrices, and I work out the multiplication table for PSL using coset representatives and the multiplication table for SL. The result is a permutation representation of PSL in Sym( Fq^n / (nth roots in Fq) ). To get a linear representation, we can compose with the standard linear representation of the symmetric group.

@michaelontiveros
Copy link
Contributor Author

michaelontiveros commented May 7, 2024

Okay now PSL.get_generator_mats() returns SL.get_generator_mats() in the n**2dimensional adjoint representation of SL. The adjoint representation extends to a faithful representation of the quotient group PSL(n) = SL(n)/center, so the PSL constructor should work even when linear_rep == false.

@perlinm
Copy link
Collaborator

perlinm commented May 13, 2024

Sorry again for the delay.

To clarify: is it currently the case that

Group.from_generating_mats(*PSL(dim, field).get_generator_mats())

essentially returns PSL(dim, field) (albeit with a different lift/representation)?

(Incidentally, I should probably make the naming of Group.from_generating_mats and Group.get_generator_mats consistent with each other. I'll probably switch to Group.get_generating_mats)

@michaelontiveros
Copy link
Contributor Author

To clarify: is it currently the case that

Group.from_generating_mats(*PSL(dim, field).get_generator_mats())

returns PSL(dim, field) (albeit with a different lift/representation)?

Yes, that is the case :)

@perlinm perlinm changed the base branch from main to PSL May 14, 2024 01:54
@perlinm
Copy link
Collaborator

perlinm commented May 14, 2024

Great! There is a bit of cleanup (formatting, typing, etc.) that would be required before merging into main, but I'm happy to merge this into a PSL branch for now and take care of the cleanup myself 🙂

Thanks again for the contribution!

@perlinm perlinm merged commit 8997da5 into Infleqtion:PSL May 14, 2024
0 of 5 checks passed
@michaelontiveros
Copy link
Contributor Author

Welcome!
Thanks for the help

Comment on lines +950 to +955
#root generates the cyclic subgroup of roots of unity of order 'dimension' of the multiplicative group of self.field.
num_roots = galois.gcd(self.dimension, self.field.order - 1 )
root = self.field.primitive_element ** ( ( self.field.order - 1 ) // num_roots )
roots = [ root ** k for k in range(num_roots) ]

# PSL acts on the quotient of the target space of SL by roots of unity of order 'dimension'.
Copy link
Collaborator

@perlinm perlinm May 15, 2024

Choose a reason for hiding this comment

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

@michaelontiveros can you help me understand why we use roots of unity here, rather than all non-zero scalars (1, 2, ..., self.field.order - 1)?

PSL should be SL mod scalars, no? I guess I'm missing what that implies for the target space of PSL (or rather, I'm missing why it implies that the target space of PSL is equal to [target space of SL] mod [roots of unity of order dimension]).

Copy link
Collaborator

@perlinm perlinm May 15, 2024

Choose a reason for hiding this comment

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

Also, I cleaned up this contribution a bit on the PSL branch. Do you want to open a new PR from PSL to main to have an "official" contribution into main? 🙂

I would also a appreciate a quick review (if you have the time) to make sure that I did not make any incorrect modifications to the code or comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We mod out by roots of unity of order dimension because the scalar matrix rI is in the group SL(dimension) if and only if the determinant is 1, and the determinant is r**dimension, which is 1 if and only if r is a root of unity of order dimension.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a typo in test_PSL():

order = order_SL // math.gcd(2, field - 1)

The 2 should be dimension.

Otherwise looks great, thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Awesome, that makes sense. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Super, I think it's ready.
I will draft a PR to merge PSL to main :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I get an error

Pull request creation failed. Validation failed: must be a collaborator

Copy link
Collaborator

@perlinm perlinm May 16, 2024

Choose a reason for hiding this comment

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

Hmm... can you maybe fork the repo and make a PR from michaelontiveros:PSL into Infleqtion:main (similarly to how you did with this PR)?

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

Successfully merging this pull request may close these issues.

2 participants