Infleqtion / qLDPC

Tools for constructing and analyzing quantum low density parity check (qLDPC) codes.
Apache License 2.0
72 stars 8 forks source link

PSL #94

Closed michaelontiveros closed 2 months ago

perlinm commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 :slightly_smiling_face:

Thanks again for the contribution!

michaelontiveros commented 2 months ago

Welcome! Thanks for the help