summarylogtreecommitdiffstats
path: root/sagemath-cypari2.patch
blob: 165c4c1a53a2689439e49d8d1d179859e36857f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
diff --git a/src/sage/matrix/matrix_integer_dense.pxd b/src/sage/matrix/matrix_integer_dense.pxd
index bc3af7c..5dd2a8e 100644
--- a/src/sage/matrix/matrix_integer_dense.pxd
+++ b/src/sage/matrix/matrix_integer_dense.pxd
@@ -30,6 +30,5 @@ cdef class Matrix_integer_dense(Matrix_dense):
 
     cdef Matrix_integer_dense _new(self, Py_ssize_t nrows, Py_ssize_t ncols)
 
-    cdef extract_hnf_from_pari_matrix(self, GEN H, int flag, bint include_zero_rows)
 
 cpdef _lift_crt(Matrix_integer_dense M, residues, moduli=*)
diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx
index effbb9e..ebc0519 100644
--- a/src/sage/matrix/matrix_integer_dense.pyx
+++ b/src/sage/matrix/matrix_integer_dense.pyx
@@ -87,11 +87,11 @@ from .args cimport SparseEntry, MatrixArgs_init
 #########################################################
 # PARI C library
 from cypari2.gen cimport Gen
+from cypari2.stack cimport clear_stack, new_gen
+from cypari2.paridecl cimport *
 from sage.libs.pari.convert_gmp cimport INT_to_mpz
 from sage.libs.pari.convert_flint cimport (_new_GEN_from_fmpz_mat_t,
            _new_GEN_from_fmpz_mat_t_rotate90, integer_matrix)
-from cypari2.stack cimport clear_stack
-from cypari2.paridecl cimport *
 #########################################################
 
 from sage.arith.multi_modular cimport MultiModularBasis
@@ -2016,10 +2016,7 @@ cdef class Matrix_integer_dense(Matrix_dense):
             raise ValueError("transformation matrix only available with p-adic algorithm")
         elif algorithm in ["pari", "pari0", "pari1", "pari4"]:
             flag = int(algorithm[-1]) if algorithm != "pari" else 1
-            if self.height().ndigits() > 10000 or n >= 50:
-                H_m = self._hnf_pari_big(flag, include_zero_rows=include_zero_rows)
-            else:
-                H_m = self._hnf_pari(flag, include_zero_rows=include_zero_rows)
+            H_m = self._hnf_pari(flag, include_zero_rows=include_zero_rows)
         elif algorithm == 'ntl':
             if nr != nc:
                 raise ValueError("ntl only computes HNF for square matrices of full rank.")
@@ -5676,6 +5673,7 @@ cdef class Matrix_integer_dense(Matrix_dense):
         matrices.
 
         EXAMPLES::
+
             sage: matrix(ZZ,3,[1..9])._rank_pari()
             2
         """
@@ -5686,16 +5684,12 @@ cdef class Matrix_integer_dense(Matrix_dense):
 
     def _hnf_pari(self, int flag=0, bint include_zero_rows=True):
         """
-        Hermite form of this matrix, computed using PARI.  The
-        computation is done entirely on the PARI stack, then the PARI
-        stack is cleared.  This function is only useful for small
-        matrices, and can crash on large matrices (e.g., if the PARI
-        stack overflows).
+        Hermite normal form of this matrix, computed using PARI.
 
         INPUT:
 
         - ``flag`` -- 0 (default), 1, 3 or 4 (see docstring for
-          gp.mathnf).
+          ``pari.mathnf``).
 
         - ``include_zero_rows`` -- boolean. if False, do not include
           any of the zero rows at the bottom of the matrix in the
@@ -5745,98 +5739,13 @@ cdef class Matrix_integer_dense(Matrix_dense):
             sage: pari('mathnf(Mat([0,1]), 4)')
             [Mat(1), [1, 0; 0, 1]]
         """
-        cdef GEN A
         sig_on()
         A = _new_GEN_from_fmpz_mat_t_rotate90(self._matrix)
-        cdef GEN H = mathnf0(A, flag)
-        B = self.extract_hnf_from_pari_matrix(H, flag, include_zero_rows)
-        clear_stack()  # This calls sig_off()
-        return B
-
-
-    def _hnf_pari_big(self, int flag=0, bint include_zero_rows=True):
-        """
-        Hermite form of this matrix, computed using PARI.
-
-        INPUT:
-
-        - ``flag`` -- 0 (default), 1, 3 or 4 (see docstring for
-          gp.mathnf).
-
-        - ``include_zero_rows`` -- boolean. if False, do not include
-          any of the zero rows at the bottom of the matrix in the
-          output.
-
-        .. NOTE::
-
-            In no cases is the transformation matrix returned by this
-            function.
-
-        EXAMPLES::
-
-            sage: a = matrix(ZZ,3,3,[1..9])
-            sage: a._hnf_pari_big(flag=0, include_zero_rows=True)
-            [1 2 3]
-            [0 3 6]
-            [0 0 0]
-            sage: a._hnf_pari_big(flag=1, include_zero_rows=True)
-            [1 2 3]
-            [0 3 6]
-            [0 0 0]
-            sage: a._hnf_pari_big(flag=3, include_zero_rows=True)
-            [1 2 3]
-            [0 3 6]
-            [0 0 0]
-            sage: a._hnf_pari_big(flag=4, include_zero_rows=True)
-            [1 2 3]
-            [0 3 6]
-            [0 0 0]
-
-        Check that ``include_zero_rows=False`` works correctly::
-
-            sage: matrix(ZZ,3,[1..9])._hnf_pari_big(0, include_zero_rows=False)
-            [1 2 3]
-            [0 3 6]
-            sage: matrix(ZZ,3,[1..9])._hnf_pari_big(1, include_zero_rows=False)
-            [1 2 3]
-            [0 3 6]
-            sage: matrix(ZZ,3,[1..9])._hnf_pari_big(3, include_zero_rows=False)
-            [1 2 3]
-            [0 3 6]
-            sage: matrix(ZZ,3,[1..9])._hnf_pari_big(4, include_zero_rows=False)
-            [1 2 3]
-            [0 3 6]
-        """
-        cdef Gen H = integer_matrix(self._matrix, 1)
-        H = H.mathnf(flag)
-        sig_on()
-        B = self.extract_hnf_from_pari_matrix(H.g, flag, include_zero_rows)
-        clear_stack()  # This calls sig_off()
-        return B
-
-    cdef extract_hnf_from_pari_matrix(self, GEN H, int flag, bint include_zero_rows):
-        # Throw away the transformation matrix (yes, we should later
-        # code this to keep track of it).
-        cdef mpz_t tmp
-        mpz_init(tmp)
-        if flag > 0:
-            H = gel(H,1)
-
-        # Figure out how many columns we got back.
-        cdef Py_ssize_t H_nc = glength(H)  # number of columns
-        # Now get the resulting Hermite form matrix back to Sage, suitably re-arranged.
-        cdef Matrix_integer_dense B
-        if include_zero_rows:
-            B = self.new_matrix()
-        else:
-            B = self.new_matrix(nrows=H_nc)
-        for i in range(self._ncols):
-            for j in range(H_nc):
-                INT_to_mpz(tmp, gcoeff(H, i+1, H_nc-j))
-                fmpz_set_mpz(fmpz_mat_entry(B._matrix,j,self._ncols-i-1),tmp)
-        mpz_clear(tmp)
-        return B
-
+        H = mathnf0(A, flag)
+        if typ(H) == t_VEC:
+            H = gel(H, 1)
+        GenH = new_gen(H)
+        return extract_hnf_from_pari_matrix(self, GenH, include_zero_rows)
 
     def p_minimal_polynomials(self, p, s_max=None):
         r"""
@@ -5978,7 +5887,27 @@ cdef inline GEN pari_GEN(Matrix_integer_dense B):
     return A
 
 
-    #####################################################################################
+cdef extract_hnf_from_pari_matrix(Matrix_integer_dense self, Gen H, bint include_zero_rows):
+    cdef mpz_t tmp
+    mpz_init(tmp)
+
+    # Figure out how many columns we got back.
+    cdef long H_nc = glength(H.g)  # number of columns
+    # Now get the resulting Hermite form matrix back to Sage, suitably re-arranged.
+    cdef Matrix_integer_dense B
+    if include_zero_rows:
+        B = self.new_matrix()
+    else:
+        B = self.new_matrix(nrows=H_nc)
+    cdef long i, j
+    for i in range(self._ncols):
+        for j in range(H_nc):
+            sig_check()
+            INT_to_mpz(tmp, gcoeff(H.g, i+1, H_nc-j))
+            fmpz_set_mpz(fmpz_mat_entry(B._matrix,j,self._ncols-i-1),tmp)
+    mpz_clear(tmp)
+    return B
+
 
 cdef _clear_columns(Matrix_integer_dense A, pivots, Py_ssize_t n):
     # Clear all columns
@@ -6002,11 +5931,6 @@ cdef _clear_columns(Matrix_integer_dense A, pivots, Py_ssize_t n):
     fmpz_clear(t)
     sig_off()
 
-###############################################################
-
-
-
-
 
 cpdef _lift_crt(Matrix_integer_dense M, residues, moduli=None):
     """
diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx
index f5345c4..87f02c2 100644
--- a/src/sage/rings/integer.pyx
+++ b/src/sage/rings/integer.pyx
@@ -6815,6 +6815,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
             ....:         (2^100).binomial(2^22, algorithm='pari')
             ....:     except AlarmInterrupt:
             ....:         pass
+            doctest:...: RuntimeWarning: cypari2 leaked ... bytes on the PARI stack...
         """
         cdef Integer x
         cdef Integer mm
diff --git a/src/sage/rings/number_field/maps.py b/src/sage/rings/number_field/maps.py
index 1727c13..5717227 100644
--- a/src/sage/rings/number_field/maps.py
+++ b/src/sage/rings/number_field/maps.py
@@ -358,7 +358,7 @@ class MapRelativeNumberFieldToRelativeVectorSpace(NumberFieldIsomorphism):
             g = g(beta).lift()
         # Convert the coefficients to elements of the base field.
         B, from_B, _ = K.absolute_base_field()
-        return self.codomain()([from_B(B(z.lift(), check=False)) for z in g.Vecrev(-K.relative_degree())])
+        return self.codomain()([from_B(B(z.lift(), check=False)) for z in g.Vecrev(K.relative_degree())])
 
 
 class NameChangeMap(NumberFieldIsomorphism):
diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx
index f956927..ae42664 100644
--- a/src/sage/rings/polynomial/polynomial_element.pyx
+++ b/src/sage/rings/polynomial/polynomial_element.pyx
@@ -4372,8 +4372,7 @@ cdef class Polynomial(CommutativeAlgebraElement):
             sage: G.prod() == g
             True
         """
-        pols = G[0]
-        exps = G[1]
+        pols, exps = G
         R = self._parent
         F = [(R(f), int(e)) for f, e in zip(pols, exps)]
 
diff --git a/src/sage/rings/power_series_pari.pyx b/src/sage/rings/power_series_pari.pyx
index e37e0a3..2e03ade 100644
--- a/src/sage/rings/power_series_pari.pyx
+++ b/src/sage/rings/power_series_pari.pyx
@@ -678,7 +678,8 @@ cdef class PowerSeries_pari(PowerSeries):
             g = g.truncate()
         if typ(g.g) == t_POL and varn(g.g) == vn:
             # t_POL has 2 codewords.  Use new_ref instead of g[i] for speed.
-            return [R(g.new_ref(gel(g.g, i))) for i in range(2, lg(g.g))]
+            G = g.fixGEN()
+            return [R(g.new_ref(gel(G, i))) for i in range(2, lg(G))]
         else:
             return [R(g)]
 
@@ -729,6 +730,7 @@ cdef class PowerSeries_pari(PowerSeries):
             return []
 
         cdef pari_gen g = self.g
+        g.fixGEN()
         cdef long l, m
 
         R = self.base_ring()