fplll / fpylll

A Python interface for https://github.com/fplll/fplll
GNU General Public License v2.0
115 stars 59 forks source link

feat: IntegerMatrix should supports mpz #268

Open alxiong opened 4 months ago

alxiong commented 4 months ago

I was reading assign_mpz and see that even if internally the IntegerMatrix uses mpz, it doesn't accept value passed in as type mpz.

ideally I want to do:

from fpylll import IntegerMatrix
from gmpy2 import mpz

A = IntegerMatrix(5, 5)
A.gen_identity(5)
a = mpz(1000)
A[2, 3] = a

(p.s. altho I agree that SageMath support is good enough if I want to use multi-precision integers, it would requires me to go for sage's own virtualenv, unlike a simpler gmpy2 package)

alxiong commented 1 month ago

this should do the work:

https://github.com/alxiong/fpylll/commit/207265d2a41fcaadd26e183c3bba769d0a03a095

for conveniences:

+++ b/src/fpylll/io.pyx
@@ -10,6 +10,7 @@ from .gmp.mpz cimport mpz_t, mpz_set_si, mpz_set
 from cpython.version cimport PY_MAJOR_VERSION
 from .fplll.fplll cimport FT_DEFAULT, FT_DOUBLE, FT_LONG_DOUBLE, FT_DPE, FT_MPFR
 from .fplll.fplll cimport ZT_MPZ, ZT_LONG
+cimport gmpy2

 # Note: this uses fpylll's numpy and not the global numpy package.
 from .numpy import is_numpy_integer
@@ -37,13 +38,17 @@ cdef int assign_Z_NR_mpz(Z_NR[mpz_t]& t, value) except -1:
 cdef int assign_mpz(mpz_t& t, value) except -1:
     if isinstance(value, long):
         mpz_set_pylong(t, value)
         return 0
+    if isinstance(value, gmpy2.mpz):
+        gmpy2.import_gmpy2()   # needed to initialize the C-API
+        mpz_set(t, gmpy2.MPZ(value))
+        return 0

tested locally, i can compile fpylll and also pass in gmpy2.mpz values.

malb commented 1 month ago

Is gmpy2 the mpz_t wrapper to use? I'm a bit hesitant to add more dependencies.

cr-marcstevens commented 1 month ago

I kind of agree with @malb here: are we going to support every multiprec python option by bringing it in as a requirement for fpylll?

My suggestion would be to look at a generic solution that works for any bigint type of python object by manually chopping it in limbs and reconstruct it in the fplll mpz.

alxiong commented 1 month ago

i agree with your concern, and don't have any strong opinion on how should fpylll handles these.

feel free to close this issue.

(i was only hoping to use this issue as future reference in case anyone wants to use gmpy2 library, since sagemath couldn't be easily installed as PyPI package like gmpy2 does. at least the 3 lines of code above, showcase how one can modify the fpylll to support that)

malb commented 1 month ago

I wonder if we could add Marc's idea though: an interface that takes an input and repeatedly considers it mod MAX_INT_SIZE to construct the internal integer? This then may or may not be faster than just reading in a string?