Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux.fr machine (x86_64 architecture), and agregate them in the final report:

The target is 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - basemath - ZV.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.10.0 lcov report (development 20459-9710128) Lines: 761 837 90.9 %
Date: 2017-04-28 05:33:48 Functions: 108 114 94.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2000  The PARI group.
       2             : 
       3             : This file is part of the PARI/GP package.
       4             : 
       5             : PARI/GP is free software; you can redistribute it and/or modify it under the
       6             : terms of the GNU General Public License as published by the Free Software
       7             : Foundation. It is distributed in the hope that it will be useful, but WITHOUT
       8             : ANY WARRANTY WHATSOEVER.
       9             : 
      10             : Check the License for details. You should have received a copy of it, along
      11             : with the package; see the file 'COPYING'. If not, write to the Free Software
      12             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      13             : 
      14             : #include "pari.h"
      15             : #include "paripriv.h"
      16             : 
      17             : static int
      18      352098 : check_ZV(GEN x, long l)
      19             : {
      20             :   long i;
      21     1796376 :   for (i=1; i<l; i++)
      22     1444350 :     if (typ(gel(x,i)) != t_INT) return 0;
      23      352026 :   return 1;
      24             : }
      25             : void
      26      407838 : RgV_check_ZV(GEN A, const char *s)
      27             : {
      28      407838 :   if (!RgV_is_ZV(A)) pari_err_TYPE(stack_strcat(s," [integer vector]"), A);
      29      407832 : }
      30             : void
      31      124680 : RgM_check_ZM(GEN A, const char *s)
      32             : {
      33      124680 :   long n = lg(A);
      34      124680 :   if (n != 1)
      35             :   {
      36      124650 :     long j, m = lgcols(A);
      37      476676 :     for (j=1; j<n; j++)
      38      352098 :       if (!check_ZV(gel(A,j), m))
      39          72 :         pari_err_TYPE(stack_strcat(s," [integer matrix]"), A);
      40             :   }
      41      124608 : }
      42             : 
      43             : long
      44        9096 : ZV_max_lg(GEN x)
      45             : {
      46        9096 :   long i, prec = 2, m = lg(x);
      47        9096 :   for (i=1; i<m; i++) { long l = lgefint(gel(x,i)); if (l > prec) prec = l; }
      48        9096 :   return prec;
      49             : }
      50             : long
      51        1368 : ZM_max_lg(GEN x)
      52             : {
      53        1368 :   long i, prec = 2, n = lg(x);
      54        1368 :   if (n != 1)
      55             :   {
      56        1368 :     long j, m = lgcols(x);
      57        9366 :     for (j=1; j<n; j++)
      58             :     {
      59        7998 :       GEN c = gel(x,j);
      60        7998 :       for (i=1; i<m; i++) { long l = lgefint(gel(c,i)); if (l > prec) prec = l; }
      61             :     }
      62             :   }
      63        1368 :   return prec;
      64             : }
      65             : 
      66             : GEN
      67        1890 : ZM_supnorm(GEN x)
      68             : {
      69        1890 :   long i, j, h, lx = lg(x);
      70        1890 :   GEN s = gen_0;
      71        1890 :   if (lx == 1) return gen_1;
      72        1890 :   h = lgcols(x);
      73       13902 :   for (j=1; j<lx; j++)
      74             :   {
      75       12012 :     GEN xj = gel(x,j);
      76      186840 :     for (i=1; i<h; i++)
      77             :     {
      78      174828 :       GEN c = gel(xj,i);
      79      174828 :       if (abscmpii(c, s) > 0) s = c;
      80             :     }
      81             :   }
      82        1890 :   return absi(s);
      83             : }
      84             : 
      85             : /********************************************************************/
      86             : /**                                                                **/
      87             : /**                           MULTIPLICATION                       **/
      88             : /**                                                                **/
      89             : /********************************************************************/
      90             : /* x non-empty ZM, y a compatible nc (dimension > 0). */
      91             : static GEN
      92      447900 : ZM_nc_mul_i(GEN x, GEN y, long c, long l)
      93             : {
      94             :   long i, j;
      95             :   pari_sp av;
      96      447900 :   GEN z = cgetg(l,t_COL), s;
      97             : 
      98     3996438 :   for (i=1; i<l; i++)
      99             :   {
     100     3548538 :     av = avma; s = muliu(gcoeff(x,i,1),y[1]);
     101   127313910 :     for (j=2; j<c; j++)
     102   123765372 :       if (y[j]) s = addii(s, muliu(gcoeff(x,i,j),y[j]));
     103     3548538 :     gel(z,i) = gerepileuptoint(av,s);
     104             :   }
     105      447900 :   return z;
     106             : }
     107             : 
     108             : /* x ZV, y a compatible zc. */
     109             : GEN
     110        1410 : ZV_zc_mul(GEN x, GEN y)
     111             : {
     112        1410 :   long j, l = lg(x);
     113        1410 :   pari_sp av = avma;
     114        1410 :   GEN s = mulis(gel(x,1),y[1]);
     115       43194 :   for (j=2; j<l; j++)
     116       41784 :     if (y[j]) s = addii(s, mulis(gel(x,j),y[j]));
     117        1410 :   return gerepileuptoint(av,s);
     118             : }
     119             : 
     120             : /* x non-empty ZM, y a compatible zc (dimension > 0). */
     121             : static GEN
     122     2282880 : ZM_zc_mul_i(GEN x, GEN y, long c, long l)
     123             : {
     124             :   long i, j;
     125     2282880 :   GEN z = cgetg(l,t_COL);
     126             : 
     127    13995682 :   for (i=1; i<l; i++)
     128             :   {
     129    11712802 :     pari_sp av = avma;
     130    11712802 :     GEN s = mulis(gcoeff(x,i,1),y[1]);
     131   209584041 :     for (j=2; j<c; j++)
     132   197871239 :       if (y[j]) s = addii(s, mulis(gcoeff(x,i,j),y[j]));
     133    11712802 :     gel(z,i) = gerepileuptoint(av,s);
     134             :   }
     135     2282880 :   return z;
     136             : }
     137             : GEN
     138     1244880 : ZM_zc_mul(GEN x, GEN y) {
     139     1244880 :   long l = lg(x);
     140     1244880 :   if (l == 1) return cgetg(1, t_COL);
     141     1244880 :   return ZM_zc_mul_i(x,y, l, lgcols(x));
     142             : }
     143             : 
     144             : /* y non-empty ZM, x a compatible zv (dimension > 0). */
     145             : GEN
     146        1110 : zv_ZM_mul(GEN x, GEN y) {
     147        1110 :   long i,j, lx = lg(x), ly = lg(y);
     148             :   GEN z;
     149        1110 :   if (lx == 1) return zerovec(ly-1);
     150        1110 :   z = cgetg(ly,t_VEC);
     151        2700 :   for (j=1; j<ly; j++)
     152             :   {
     153        1590 :     pari_sp av = avma;
     154        1590 :     GEN s = mulsi(x[1], gcoeff(y,1,j));
     155        3006 :     for (i=2; i<lx; i++)
     156        1416 :       if (x[i]) s = addii(s, mulsi(x[i], gcoeff(y,i,j)));
     157        1590 :     gel(z,j) = gerepileuptoint(av,s);
     158             :   }
     159        1110 :   return z;
     160             : }
     161             : 
     162             : /* x ZM, y a compatible zm (dimension > 0). */
     163             : GEN
     164      504085 : ZM_zm_mul(GEN x, GEN y)
     165             : {
     166      504085 :   long j, c, l = lg(x), ly = lg(y);
     167      504085 :   GEN z = cgetg(ly, t_MAT);
     168      504085 :   if (l == 1) return z;
     169      504085 :   c = lgcols(x);
     170      504085 :   for (j = 1; j < ly; j++) gel(z,j) = ZM_zc_mul_i(x, gel(y,j), l,c);
     171      504085 :   return z;
     172             : }
     173             : /* x ZM, y a compatible zn (dimension > 0). */
     174             : GEN
     175      426240 : ZM_nm_mul(GEN x, GEN y)
     176             : {
     177      426240 :   long j, c, l = lg(x), ly = lg(y);
     178      426240 :   GEN z = cgetg(ly, t_MAT);
     179      426240 :   if (l == 1) return z;
     180      426240 :   c = lgcols(x);
     181      426240 :   for (j = 1; j < ly; j++) gel(z,j) = ZM_nc_mul_i(x, gel(y,j), l,c);
     182      426240 :   return z;
     183             : }
     184             : 
     185             : /* Strassen-Winograd algorithm */
     186             : 
     187             : /*
     188             :   Return A[ma+1..ma+da, na+1..na+ea] - B[mb+1..mb+db, nb+1..nb+eb]
     189             :   as an (m x n)-matrix, padding the input with zeroes as necessary.
     190             : */
     191             : static GEN
     192       77136 : add_slices(long m, long n,
     193             :            GEN A, long ma, long da, long na, long ea,
     194             :            GEN B, long mb, long db, long nb, long eb)
     195             : {
     196       77136 :   long min_d = minss(da, db), min_e = minss(ea, eb), i, j;
     197       77136 :   GEN M = cgetg(n + 1, t_MAT), C;
     198             : 
     199     2032284 :   for (j = 1; j <= min_e; j++) {
     200     1955148 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     201    55634934 :     for (i = 1; i <= min_d; i++)
     202   107359572 :       gel(C, i) = addii(gcoeff(A, ma + i, na + j),
     203    53679786 :                         gcoeff(B, mb + i, nb + j));
     204     1992384 :     for (; i <= da; i++)
     205       37236 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     206     1955148 :     for (; i <= db; i++)
     207           0 :       gel(C, i) = gcoeff(B, mb + i, nb + j);
     208     1955148 :     for (; i <= m; i++)
     209           0 :       gel(C, i) = gen_0;
     210             :   }
     211       80352 :   for (; j <= ea; j++) {
     212        3216 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     213       92712 :     for (i = 1; i <= da; i++)
     214       89496 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     215        3216 :     for (; i <= m; i++)
     216           0 :       gel(C, i) = gen_0;
     217             :   }
     218       77136 :   for (; j <= eb; j++) {
     219           0 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     220           0 :     for (i = 1; i <= db; i++)
     221           0 :       gel(C, i) = gcoeff(B, mb + i, nb + j);
     222           0 :     for (; i <= m; i++)
     223           0 :       gel(C, i) = gen_0;
     224             :   }
     225       77136 :   for (; j <= n; j++)
     226           0 :     gel(M, j) = zerocol(m);
     227       77136 :   return M;
     228             : }
     229             : 
     230             : /*
     231             :   Return A[ma+1..ma+da, na+1..na+ea] - B[mb+1..mb+db, nb+1..nb+eb]
     232             :   as an (m x n)-matrix, padding the input with zeroes as necessary.
     233             : */
     234             : static GEN
     235       67494 : subtract_slices(long m, long n,
     236             :                 GEN A, long ma, long da, long na, long ea,
     237             :                 GEN B, long mb, long db, long nb, long eb)
     238             : {
     239       67494 :   long min_d = minss(da, db), min_e = minss(ea, eb), i, j;
     240       67494 :   GEN M = cgetg(n + 1, t_MAT), C;
     241             : 
     242     1845120 :   for (j = 1; j <= min_e; j++) {
     243     1777626 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     244    53429058 :     for (i = 1; i <= min_d; i++)
     245   103302864 :       gel(C, i) = subii(gcoeff(A, ma + i, na + j),
     246    51651432 :                         gcoeff(B, mb + i, nb + j));
     247     1824444 :     for (; i <= da; i++)
     248       46818 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     249     1828968 :     for (; i <= db; i++)
     250       51342 :       gel(C, i) = negi(gcoeff(B, mb + i, nb + j));
     251     1777626 :     for (; i <= m; i++)
     252           0 :       gel(C, i) = gen_0;
     253             :   }
     254       67494 :   for (; j <= ea; j++) {
     255           0 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     256           0 :     for (i = 1; i <= da; i++)
     257           0 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     258           0 :     for (; i <= m; i++)
     259           0 :       gel(C, i) = gen_0;
     260             :   }
     261       68970 :   for (; j <= eb; j++) {
     262        1476 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     263       53346 :     for (i = 1; i <= db; i++)
     264       51870 :       gel(C, i) = negi(gcoeff(B, mb + i, nb + j));
     265        1476 :     for (; i <= m; i++)
     266           0 :       gel(C, i) = gen_0;
     267             :   }
     268       68970 :   for (; j <= n; j++)
     269        1476 :     gel(M, j) = zerocol(m);
     270       67494 :   return M;
     271             : }
     272             : 
     273             : static GEN ZM_mul_i(GEN x, GEN y, long l, long lx, long ly);
     274             : 
     275             : /* Strassen-Winograd matrix product A (m x n) * B (n x p) */
     276             : static GEN
     277        9642 : ZM_mul_sw(GEN A, GEN B, long m, long n, long p)
     278             : {
     279        9642 :   pari_sp av = avma;
     280        9642 :   long m1 = (m + 1)/2, m2 = m/2,
     281        9642 :     n1 = (n + 1)/2, n2 = n/2,
     282        9642 :     p1 = (p + 1)/2, p2 = p/2;
     283             :   GEN A11, A12, A22, B11, B21, B22,
     284             :     S1, S2, S3, S4, T1, T2, T3, T4,
     285             :     M1, M2, M3, M4, M5, M6, M7,
     286             :     V1, V2, V3, C11, C12, C21, C22, C;
     287             : 
     288        9642 :   T2 = subtract_slices(n1, p2, B, 0, n1, p1, p2, B, n1, n2, p1, p2);
     289        9642 :   S1 = subtract_slices(m2, n1, A, m1, m2, 0, n1, A, 0, m2, 0, n1);
     290        9642 :   M2 = ZM_mul_i(S1, T2, m2 + 1, n1 + 1, p2 + 1);
     291        9642 :   if (gc_needed(av, 1))
     292           0 :     gerepileall(av, 2, &T2, &M2);  /* destroy S1 */
     293        9642 :   T3 = subtract_slices(n1, p1, T2, 0, n1, 0, p2, B, 0, n1, 0, p1);
     294        9642 :   if (gc_needed(av, 1))
     295           0 :     gerepileall(av, 2, &M2, &T3);  /* destroy T2 */
     296        9642 :   S2 = add_slices(m2, n1, A, m1, m2, 0, n1, A, m1, m2, n1, n2);
     297        9642 :   T1 = subtract_slices(n1, p1, B, 0, n1, p1, p2, B, 0, n1, 0, p2);
     298        9642 :   M3 = ZM_mul_i(S2, T1, m2 + 1, n1 + 1, p2 + 1);
     299        9642 :   if (gc_needed(av, 1))
     300           0 :     gerepileall(av, 4, &M2, &T3, &S2, &M3);  /* destroy T1 */
     301        9642 :   S3 = subtract_slices(m1, n1, S2, 0, m2, 0, n1, A, 0, m1, 0, n1);
     302        9642 :   if (gc_needed(av, 1))
     303           0 :     gerepileall(av, 4, &M2, &T3, &M3, &S3);  /* destroy S2 */
     304        9642 :   A11 = matslice(A, 1, m1, 1, n1);
     305        9642 :   B11 = matslice(B, 1, n1, 1, p1);
     306        9642 :   M1 = ZM_mul_i(A11, B11, m1 + 1, n1 + 1, p1 + 1);
     307        9642 :   if (gc_needed(av, 1))
     308           0 :     gerepileall(av, 5, &M2, &T3, &M3, &S3, &M1);  /* destroy A11, B11 */
     309        9642 :   A12 = matslice(A, 1, m1, n1 + 1, n);
     310        9642 :   B21 = matslice(B, n1 + 1, n, 1, p1);
     311        9642 :   M4 = ZM_mul_i(A12, B21, m1 + 1, n2 + 1, p1 + 1);
     312        9642 :   if (gc_needed(av, 1))
     313           0 :     gerepileall(av, 6, &M2, &T3, &M3, &S3, &M1, &M4);  /* destroy A12, B21 */
     314        9642 :   C11 = add_slices(m1, p1, M1, 0, m1, 0, p1, M4, 0, m1, 0, p1);
     315        9642 :   if (gc_needed(av, 1))
     316           0 :     gerepileall(av, 6, &M2, &T3, &M3, &S3, &M1, &C11);  /* destroy M4 */
     317        9642 :   M5 = ZM_mul_i(S3, T3, m1 + 1, n1 + 1, p1 + 1);
     318        9642 :   S4 = subtract_slices(m1, n2, A, 0, m1, n1, n2, S3, 0, m1, 0, n2);
     319        9642 :   if (gc_needed(av, 1))
     320           0 :     gerepileall(av, 7, &M2, &T3, &M3, &M1, &C11, &M5, &S4);  /* destroy S3 */
     321        9642 :   T4 = add_slices(n2, p1, B, n1, n2, 0, p1, T3, 0, n2, 0, p1);
     322        9642 :   if (gc_needed(av, 1))
     323           0 :     gerepileall(av, 7, &M2, &M3, &M1, &C11, &M5, &S4, &T4);  /* destroy T3 */
     324        9642 :   V1 = subtract_slices(m1, p1, M1, 0, m1, 0, p1, M5, 0, m1, 0, p1);
     325        9642 :   if (gc_needed(av, 1))
     326           0 :     gerepileall(av, 6, &M2, &M3, &S4, &T4, &C11, &V1);  /* destroy M1, M5 */
     327        9642 :   B22 = matslice(B, n1 + 1, n, p1 + 1, p);
     328        9642 :   M6 = ZM_mul_i(S4, B22, m1 + 1, n2 + 1, p2 + 1);
     329        9642 :   if (gc_needed(av, 1))
     330           0 :     gerepileall(av, 6, &M2, &M3, &T4, &C11, &V1, &M6);  /* destroy S4, B22 */
     331        9642 :   A22 = matslice(A, m1 + 1, m, n1 + 1, n);
     332        9642 :   M7 = ZM_mul_i(A22, T4, m2 + 1, n2 + 1, p1 + 1);
     333        9642 :   if (gc_needed(av, 1))
     334           0 :     gerepileall(av, 6, &M2, &M3, &C11, &V1, &M6, &M7);  /* destroy A22, T4 */
     335        9642 :   V3 = add_slices(m1, p2, V1, 0, m1, 0, p2, M3, 0, m2, 0, p2);
     336        9642 :   C12 = add_slices(m1, p2, V3, 0, m1, 0, p2, M6, 0, m1, 0, p2);
     337        9642 :   if (gc_needed(av, 1))
     338           0 :     gerepileall(av, 6, &M2, &M3, &C11, &V1, &M7, &C12);  /* destroy V3, M6 */
     339        9642 :   V2 = add_slices(m2, p1, V1, 0, m2, 0, p1, M2, 0, m2, 0, p2);
     340        9642 :   if (gc_needed(av, 1))
     341           0 :     gerepileall(av, 5, &M3, &C11, &M7, &C12, &V2);  /* destroy V1, M2 */
     342        9642 :   C21 = add_slices(m2, p1, V2, 0, m2, 0, p1, M7, 0, m2, 0, p1);
     343        9642 :   if (gc_needed(av, 1))
     344           0 :     gerepileall(av, 5, &M3, &C11, &C12, &V2, &C21);  /* destroy M7 */
     345        9642 :   C22 = add_slices(m2, p2, V2, 0, m2, 0, p2, M3, 0, m2, 0, p2);
     346        9642 :   if (gc_needed(av, 1))
     347           0 :     gerepileall(av, 4, &C11, &C12, &C21, &C22);  /* destroy V2, M3 */
     348        9642 :   C = mkmat2(mkcol2(C11, C21), mkcol2(C12, C22));
     349        9642 :   return gerepilecopy(av, shallowmatconcat(C));
     350             : }
     351             : 
     352             : /* x[i,]*y. Assume lg(x) > 1 and 0 < i < lgcols(x) */
     353             : static GEN
     354   126711850 : ZMrow_ZC_mul_i(GEN x, GEN y, long i, long lx)
     355             : {
     356   126711850 :   pari_sp av = avma;
     357   126711850 :   GEN c = mulii(gcoeff(x,i,1), gel(y,1)), ZERO = gen_0;
     358             :   long k;
     359  2127939484 :   for (k = 2; k < lx; k++)
     360             :   {
     361  2001227634 :     GEN t = mulii(gcoeff(x,i,k), gel(y,k));
     362  2001227634 :     if (t != ZERO) c = addii(c, t);
     363             :   }
     364   126711850 :   return gerepileuptoint(av, c);
     365             : }
     366             : GEN
     367    20247126 : ZMrow_ZC_mul(GEN x, GEN y, long i)
     368    20247126 : { return ZMrow_ZC_mul_i(x, y, i, lg(x)); }
     369             : 
     370             : /* return x * y, 1 < lx = lg(x), l = lgcols(x) */
     371             : static GEN
     372    16872944 : ZM_ZC_mul_i(GEN x, GEN y, long lx, long l)
     373             : {
     374    16872944 :   GEN z = cgetg(l,t_COL);
     375             :   long i;
     376    16872944 :   for (i=1; i<l; i++) gel(z,i) = ZMrow_ZC_mul_i(x,y,i,lx);
     377    16872944 :   return z;
     378             : }
     379             : 
     380             : static GEN
     381     3789421 : ZM_mul_classical(GEN x, GEN y, long l, long lx, long ly)
     382             : {
     383             :   long j;
     384     3789421 :   GEN z = cgetg(ly, t_MAT);
     385    16732917 :   for (j = 1; j < ly; j++)
     386    12943496 :     gel(z, j) = ZM_ZC_mul_i(x, gel(y, j), lx, l);
     387     3789421 :   return z;
     388             : }
     389             : 
     390             : /* Strassen-Winograd used for dim >= ZM_sw_bound */
     391             : static const long ZM_sw_bound = 36;
     392             : 
     393             : static GEN
     394     3798175 : ZM_mul_i(GEN x, GEN y, long l, long lx, long ly)
     395             : {
     396     3798175 :   if (l <= ZM_sw_bound || lx <= ZM_sw_bound || ly <= ZM_sw_bound)
     397     3788533 :     return ZM_mul_classical(x, y, l, lx, ly);
     398             :   else
     399        9642 :     return ZM_mul_sw(x, y, l - 1, lx - 1, ly - 1);
     400             : }
     401             : 
     402             : GEN
     403     3771121 : ZM_mul(GEN x, GEN y)
     404             : {
     405     3771121 :   long lx=lg(x), ly=lg(y);
     406     3771121 :   if (ly==1) return cgetg(1,t_MAT);
     407     3731467 :   if (lx==1) return zeromat(0, ly-1);
     408     3730681 :   return ZM_mul_i(x, y, lgcols(x), lx, ly);
     409             : }
     410             : /* assume result is symmetric */
     411             : GEN
     412           0 : ZM_multosym(GEN x, GEN y)
     413             : {
     414           0 :   long j, lx, ly = lg(y);
     415             :   GEN M;
     416           0 :   if (ly == 1) return cgetg(1,t_MAT);
     417           0 :   lx = lg(x); /* = lgcols(y) */
     418           0 :   if (lx == 1) return cgetg(1,t_MAT);
     419             :   /* ly = lgcols(x) */
     420           0 :   M = cgetg(ly, t_MAT);
     421           0 :   for (j=1; j<ly; j++)
     422             :   {
     423           0 :     GEN z = cgetg(ly,t_COL), yj = gel(y,j);
     424             :     long i;
     425           0 :     for (i=1; i<j; i++) gel(z,i) = gcoeff(M,j,i);
     426           0 :     for (i=j; i<ly; i++)gel(z,i) = ZMrow_ZC_mul_i(x,yj,i,lx);
     427           0 :     gel(M,j) = z;
     428             :   }
     429           0 :   return M;
     430             : }
     431             : 
     432             : /* compute m*diagonal(d), assume lg(d) = lg(m). Shallow */
     433             : GEN
     434          12 : ZM_mul_diag(GEN m, GEN d)
     435             : {
     436             :   long j, l;
     437          12 :   GEN y = cgetg_copy(m, &l);
     438          48 :   for (j=1; j<l; j++)
     439             :   {
     440          36 :     GEN c = gel(d,j);
     441          36 :     gel(y,j) = equali1(c)? gel(m,j): ZC_Z_mul(gel(m,j), c);
     442             :   }
     443          12 :   return y;
     444             : }
     445             : /* compute diagonal(d)*m, assume lg(d) = lg(m~). Shallow */
     446             : GEN
     447       31177 : ZM_diag_mul(GEN d, GEN m)
     448             : {
     449       31177 :   long i, j, l = lg(d), lm = lg(m);
     450       31177 :   GEN y = cgetg(lm, t_MAT);
     451       31177 :   for (j=1; j<lm; j++) gel(y,j) = cgetg(l, t_COL);
     452       90763 :   for (i=1; i<l; i++)
     453             :   {
     454       59586 :     GEN c = gel(d,i);
     455       59586 :     if (equali1(c))
     456        3324 :       for (j=1; j<lm; j++) gcoeff(y,i,j) = gcoeff(m,i,j);
     457             :     else
     458       56262 :       for (j=1; j<lm; j++) gcoeff(y,i,j) = mulii(gcoeff(m,i,j), c);
     459             :   }
     460       31177 :   return y;
     461             : }
     462             : 
     463             : /* assume lx > 1 is lg(x) = lg(y) */
     464             : static GEN
     465     9304632 : ZV_dotproduct_i(GEN x, GEN y, long lx)
     466             : {
     467     9304632 :   pari_sp av = avma;
     468     9304632 :   GEN c = mulii(gel(x,1), gel(y,1));
     469             :   long i;
     470    77752470 :   for (i = 2; i < lx; i++)
     471             :   {
     472    68447838 :     GEN t = mulii(gel(x,i), gel(y,i));
     473    68447838 :     if (t != gen_0) c = addii(c, t);
     474             :   }
     475     9304632 :   return gerepileuptoint(av, c);
     476             : }
     477             : 
     478             : /* x~ * y, assuming result is symmetric */
     479             : GEN
     480      137370 : ZM_transmultosym(GEN x, GEN y)
     481             : {
     482      137370 :   long i, j, l, ly = lg(y);
     483             :   GEN M;
     484      137370 :   if (ly == 1) return cgetg(1,t_MAT);
     485             :   /* lg(x) = ly */
     486      137370 :   l = lgcols(y); /* = lgcols(x) */
     487      137370 :   M = cgetg(ly, t_MAT);
     488     1072302 :   for (i=1; i<ly; i++)
     489             :   {
     490      934932 :     GEN xi = gel(x,i), c = cgetg(ly,t_COL);
     491      934932 :     gel(M,i) = c;
     492     4211118 :     for (j=1; j<i; j++)
     493     3276186 :       gcoeff(M,i,j) = gel(c,j) = ZV_dotproduct_i(xi,gel(y,j),l);
     494      934932 :     gel(c,i) = ZV_dotproduct_i(xi,gel(y,i),l);
     495             :   }
     496      137370 :   return M;
     497             : }
     498             : /* x~ * y */
     499             : GEN
     500         426 : ZM_transmul(GEN x, GEN y)
     501             : {
     502         426 :   long i, j, l, lx, ly = lg(y);
     503             :   GEN M;
     504         426 :   if (ly == 1) return cgetg(1,t_MAT);
     505         426 :   lx = lg(x);
     506         426 :   l = lgcols(y);
     507         426 :   if (lgcols(x) != l) pari_err_OP("operation 'ZM_transmul'", x,y);
     508         426 :   M = cgetg(ly, t_MAT);
     509        1386 :   for (i=1; i<ly; i++)
     510             :   {
     511         960 :     GEN yi = gel(y,i), c = cgetg(lx,t_COL);
     512         960 :     gel(M,i) = c;
     513         960 :     for (j=1; j<lx; j++) gel(c,j) = ZV_dotproduct_i(yi,gel(x,j),l);
     514             :   }
     515         426 :   return M;
     516             : }
     517             : 
     518             : static GEN
     519         888 : ZM_sqr_i(GEN x, long l)
     520             : {
     521         888 :   if (l <= ZM_sw_bound)
     522         888 :     return ZM_mul_classical(x, x, l, l, l);
     523             :   else
     524           0 :     return ZM_mul_sw(x, x, l - 1, l - 1, l - 1);
     525             : }
     526             : 
     527             : GEN
     528         888 : ZM_sqr(GEN x)
     529             : {
     530         888 :   long lx=lg(x);
     531         888 :   if (lx==1) return cgetg(1,t_MAT);
     532         888 :   return ZM_sqr_i(x, lx);
     533             : }
     534             : GEN
     535     3989526 : ZM_ZC_mul(GEN x, GEN y)
     536             : {
     537     3989526 :   long lx = lg(x);
     538     3989526 :   return lx==1? cgetg(1,t_COL): ZM_ZC_mul_i(x, y, lx, lgcols(x));
     539             : }
     540             : 
     541             : GEN
     542      138900 : ZC_Z_div(GEN x, GEN c)
     543             : {
     544             :   long i, l;
     545      138900 :   GEN a = cgetg_copy(x, &l);
     546      138900 :   for (i = 1; i < l; i++) gel(a,i) = Qdivii(gel(x,i), c);
     547      138900 :   return a;
     548             : }
     549             : GEN
     550        8298 : ZM_Z_div(GEN X, GEN c)
     551             : {
     552        8298 :   long j, l = lg(X);
     553        8298 :   GEN A = cgetg(l, t_MAT);
     554        8298 :   for (j = 1; j < l; j++) gel(A,j) = ZC_Z_div(gel(X,j), c);
     555        8298 :   return A;
     556             : }
     557             : 
     558             : long
     559   129434964 : zv_dotproduct(GEN x, GEN y)
     560             : {
     561   129434964 :   long i, lx = lg(x);
     562             :   ulong c;
     563   129434964 :   if (lx == 1) return 0;
     564   129434964 :   c = uel(x,1)*uel(y,1);
     565  1996413930 :   for (i = 2; i < lx; i++)
     566  1866978966 :     c += uel(x,i)*uel(y,i);
     567   129434964 :   return c;
     568             : }
     569             : 
     570             : GEN
     571        5436 : ZV_ZM_mul(GEN x, GEN y)
     572             : {
     573        5436 :   long i, lx = lg(x), ly = lg(y);
     574             :   GEN z;
     575        5436 :   if (lx == 1) return zerovec(ly-1);
     576        5424 :   z = cgetg(ly, t_VEC);
     577        5424 :   for (i = 1; i < ly; i++) gel(z,i) = ZV_dotproduct_i(x, gel(y,i), lx);
     578        5424 :   return z;
     579             : }
     580             : 
     581             : GEN
     582           0 : ZC_ZV_mul(GEN x, GEN y)
     583             : {
     584           0 :   long i,j, lx=lg(x), ly=lg(y);
     585             :   GEN z;
     586           0 :   if (ly==1) return cgetg(1,t_MAT);
     587           0 :   z = cgetg(ly,t_MAT);
     588           0 :   for (j=1; j < ly; j++)
     589             :   {
     590           0 :     gel(z,j) = cgetg(lx,t_COL);
     591           0 :     for (i=1; i<lx; i++) gcoeff(z,i,j) = mulii(gel(x,i),gel(y,j));
     592             :   }
     593           0 :   return z;
     594             : }
     595             : 
     596             : GEN
     597     2764308 : ZV_dotsquare(GEN x)
     598             : {
     599             :   long i, lx;
     600             :   pari_sp av;
     601             :   GEN z;
     602     2764308 :   lx = lg(x);
     603     2764308 :   if (lx == 1) return gen_0;
     604     2764308 :   av = avma; z = sqri(gel(x,1));
     605     2764308 :   for (i=2; i<lx; i++) z = addii(z, sqri(gel(x,i)));
     606     2764308 :   return gerepileuptoint(av,z);
     607             : }
     608             : 
     609             : GEN
     610     6964794 : ZV_dotproduct(GEN x,GEN y)
     611             : {
     612             :   long lx;
     613     6964794 :   if (x == y) return ZV_dotsquare(x);
     614     5080560 :   lx = lg(x);
     615     5080560 :   if (lx == 1) return gen_0;
     616     5080560 :   return ZV_dotproduct_i(x, y, lx);
     617             : }
     618             : 
     619             : static GEN
     620          48 : _ZM_mul(void *data /*ignored*/, GEN x, GEN y)
     621          48 : { (void)data; return ZM_mul(x,y); }
     622             : static GEN
     623         480 : _ZM_sqr(void *data /*ignored*/, GEN x)
     624         480 : { (void)data; return ZM_sqr(x); }
     625             : GEN
     626           0 : ZM_pow(GEN x, GEN n)
     627             : {
     628           0 :   pari_sp av = avma;
     629           0 :   if (!signe(n)) return matid(lg(x)-1);
     630           0 :   return gerepileupto(av, gen_pow(x, n, NULL, &_ZM_sqr, &_ZM_mul));
     631             : }
     632             : GEN
     633         360 : ZM_powu(GEN x, ulong n)
     634             : {
     635         360 :   pari_sp av = avma;
     636         360 :   if (!n) return matid(lg(x)-1);
     637         360 :   return gerepileupto(av, gen_powu(x, n, NULL, &_ZM_sqr, &_ZM_mul));
     638             : }
     639             : /********************************************************************/
     640             : /**                                                                **/
     641             : /**                           ADD, SUB                             **/
     642             : /**                                                                **/
     643             : /********************************************************************/
     644             : static GEN
     645    14797758 : ZC_add_i(GEN x, GEN y, long lx)
     646             : {
     647    14797758 :   GEN A = cgetg(lx, t_COL);
     648             :   long i;
     649    14797758 :   for (i=1; i<lx; i++) gel(A,i) = addii(gel(x,i), gel(y,i));
     650    14797758 :   return A;
     651             : }
     652             : GEN
     653     4907490 : ZC_add(GEN x, GEN y) { return ZC_add_i(x, y, lg(x)); }
     654             : GEN
     655       52974 : ZC_Z_add(GEN x, GEN y)
     656             : {
     657       52974 :   long k, lx = lg(x);
     658       52974 :   GEN z = cgetg(lx, t_COL);
     659       52974 :   if (lx == 1) pari_err_TYPE2("+",x,y);
     660       52974 :   gel(z,1) = addii(y,gel(x,1));
     661       52974 :   for (k = 2; k < lx; k++) gel(z,k) = icopy(gel(x,k));
     662       52974 :   return z;
     663             : }
     664             : 
     665             : static GEN
     666     1414031 : ZC_sub_i(GEN x, GEN y, long lx)
     667             : {
     668             :   long i;
     669     1414031 :   GEN A = cgetg(lx, t_COL);
     670     1414031 :   for (i=1; i<lx; i++) gel(A,i) = subii(gel(x,i), gel(y,i));
     671     1414031 :   return A;
     672             : }
     673             : GEN
     674      903935 : ZC_sub(GEN x, GEN y) { return ZC_sub_i(x, y, lg(x)); }
     675             : GEN
     676           0 : ZC_Z_sub(GEN x, GEN y)
     677             : {
     678           0 :   long k, lx = lg(x);
     679           0 :   GEN z = cgetg(lx, t_COL);
     680           0 :   if (lx == 1) pari_err_TYPE2("+",x,y);
     681           0 :   gel(z,1) = subii(gel(x,1), y);
     682           0 :   for (k = 2; k < lx; k++) gel(z,k) = icopy(gel(x,k));
     683           0 :   return z;
     684             : }
     685             : GEN
     686      114054 : Z_ZC_sub(GEN a, GEN x)
     687             : {
     688      114054 :   long k, lx = lg(x);
     689      114054 :   GEN z = cgetg(lx, t_COL);
     690      114054 :   if (lx == 1) pari_err_TYPE2("-",a,x);
     691      114054 :   gel(z,1) = subii(a, gel(x,1));
     692      114054 :   for (k = 2; k < lx; k++) gel(z,k) = negi(gel(x,k));
     693      114054 :   return z;
     694             : }
     695             : 
     696             : GEN
     697      827616 : ZM_add(GEN x, GEN y)
     698             : {
     699      827616 :   long lx = lg(x), l, j;
     700             :   GEN z;
     701      827616 :   if (lx == 1) return cgetg(1, t_MAT);
     702      826260 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     703      826260 :   for (j = 1; j < lx; j++) gel(z,j) = ZC_add_i(gel(x,j), gel(y,j), l);
     704      826260 :   return z;
     705             : }
     706             : GEN
     707      441475 : ZM_sub(GEN x, GEN y)
     708             : {
     709      441475 :   long lx = lg(x), l, j;
     710             :   GEN z;
     711      441475 :   if (lx == 1) return cgetg(1, t_MAT);
     712      441475 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     713      441475 :   for (j = 1; j < lx; j++) gel(z,j) = ZC_sub_i(gel(x,j), gel(y,j), l);
     714      441475 :   return z;
     715             : }
     716             : /********************************************************************/
     717             : /**                                                                **/
     718             : /**                         LINEAR COMBINATION                     **/
     719             : /**                                                                **/
     720             : /********************************************************************/
     721             : /* return X/c assuming division is exact */
     722             : GEN
     723     1959102 : ZC_Z_divexact(GEN X, GEN c)
     724             : {
     725     1959102 :   long i, l = lg(X);
     726     1959102 :   GEN A = cgetg(l, t_COL);
     727     1959102 :   for (i=1; i<l; i++) gel(A,i) = diviiexact(gel(X,i), c);
     728     1959096 :   return A;
     729             : }
     730             : GEN
     731      552204 : ZM_Z_divexact(GEN X, GEN c)
     732             : {
     733      552204 :   long i, l = lg(X);
     734      552204 :   GEN A = cgetg(l, t_MAT);
     735      552204 :   for (i = 1; i < l; i++) gel(A,i) = ZC_Z_divexact(gel(X,i), c);
     736      552198 :   return A;
     737             : }
     738             : /* Return c * X */
     739             : GEN
     740     7546140 : ZC_Z_mul(GEN X, GEN c)
     741             : {
     742             :   long i, l;
     743             :   GEN A;
     744     7546140 :   if (!signe(c)) return zerocol(lg(X)-1);
     745     7392696 :   if (is_pm1(c)) return (signe(c) > 0)? ZC_copy(X): ZC_neg(X);
     746     6137428 :   l = lg(X); A = cgetg(l, t_COL);
     747     6137428 :   for (i=1; i<l; i++) gel(A,i) = mulii(c,gel(X,i));
     748     6137428 :   return A;
     749             : }
     750             : GEN
     751       11724 : ZC_z_mul(GEN X, long c)
     752             : {
     753             :   long i, l;
     754             :   GEN A;
     755       11724 :   if (!c) return zerocol(lg(X)-1);
     756        6132 :   if (c == 1) return ZC_copy(X);
     757        1956 :   if (c ==-1) return ZC_neg(X);
     758         708 :   l = lg(X); A = cgetg(l, t_COL);
     759         708 :   for (i=1; i<l; i++) gel(A,i) = mulsi(c,gel(X,i));
     760         708 :   return A;
     761             : }
     762             : 
     763             : GEN
     764        7036 : zv_z_mul(GEN M, long n)
     765             : {
     766             :   long l;
     767        7036 :   GEN N = cgetg_copy(M, &l);
     768        7036 :   while (--l > 0) N[l] = M[l]*n;
     769        7036 :   return N;
     770             : }
     771             : 
     772             : /* return a ZM */
     773             : GEN
     774      426240 : nm_Z_mul(GEN X, GEN c)
     775             : {
     776      426240 :   long i, j, h, l = lg(X), s = signe(c);
     777             :   GEN A;
     778      426240 :   if (l == 1) return cgetg(1, t_MAT);
     779      426240 :   h = lgcols(X);
     780      426240 :   if (!s) return zeromat(h-1, l-1);
     781      426240 :   if (is_pm1(c)) {
     782           0 :     if (s > 0) return Flm_to_ZM(X);
     783           0 :     X = Flm_to_ZM(X); ZM_togglesign(X); return X;
     784             :   }
     785      426240 :   A = cgetg(l, t_MAT);
     786      874140 :   for (j = 1; j < l; j++)
     787             :   {
     788      447900 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     789      447900 :     for (i = 1; i < h; i++) gel(a,i) = muliu(c, x[i]);
     790      447900 :     gel(A,j) = a;
     791             :   }
     792      426240 :   return A;
     793             : }
     794             : GEN
     795      510438 : ZM_Z_mul(GEN X, GEN c)
     796             : {
     797      510438 :   long i, j, h, l = lg(X);
     798             :   GEN A;
     799      510438 :   if (l == 1) return cgetg(1, t_MAT);
     800      510438 :   h = lgcols(X);
     801      510438 :   if (!signe(c)) return zeromat(h-1, l-1);
     802      510396 :   if (is_pm1(c)) return (signe(c) > 0)? ZM_copy(X): ZM_neg(X);
     803      380256 :   A = cgetg(l, t_MAT);
     804     8592450 :   for (j = 1; j < l; j++)
     805             :   {
     806     8212194 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     807     8212194 :     for (i = 1; i < h; i++) gel(a,i) = mulii(c, gel(x,i));
     808     8212194 :     gel(A,j) = a;
     809             :   }
     810      380256 :   return A;
     811             : }
     812             : 
     813             : /* X <- X + v Y (elementary col operation) */
     814             : void
     815    27624663 : ZC_lincomb1_inplace(GEN X, GEN Y, GEN v)
     816             : {
     817    27624663 :   long i, m = lgefint(v);
     818    55249326 :   if (m == 2) return; /* v = 0 */
     819    27624663 :   for (i = lg(X)-1; i; i--) gel(X,i) = addmulii_inplace(gel(X,i), gel(Y,i), v);
     820             : }
     821             : void
     822     7531104 : Flc_lincomb1_inplace(GEN X, GEN Y, ulong v, ulong q)
     823             : {
     824             :   long i;
     825    15062208 :   if (!v) return; /* v = 0 */
     826     7531104 :   for (i = lg(X)-1; i; i--) X[i] = Fl_add(X[i], Fl_mul(Y[i], v, q), q);
     827             : }
     828             : 
     829             : /* X + v Y, wasteful if (v = 0) */
     830             : static GEN
     831     1580640 : ZC_lincomb1(GEN v, GEN X, GEN Y)
     832             : {
     833     1580640 :   long i, lx = lg(X);
     834     1580640 :   GEN A = cgetg(lx,t_COL);
     835     1580640 :   for (i=1; i<lx; i++) gel(A,i) = addmulii(gel(X,i), gel(Y,i), v);
     836     1580640 :   return A;
     837             : }
     838             : /* -X + vY */
     839             : static GEN
     840      190136 : ZC_lincomb_1(GEN v, GEN X, GEN Y)
     841             : {
     842      190136 :   long i, lx = lg(X);
     843      190136 :   GEN A = cgetg(lx,t_COL);
     844      190136 :   for (i=1; i<lx; i++) gel(A,i) = mulsubii(gel(Y,i), v, gel(X,i));
     845      190136 :   return A;
     846             : }
     847             : /* X,Y compatible ZV; u,v in Z. Returns A = u*X + v*Y */
     848             : GEN
     849     6022341 : ZC_lincomb(GEN u, GEN v, GEN X, GEN Y)
     850             : {
     851             :   long su, sv;
     852             :   GEN A;
     853             : 
     854     6022341 :   su = signe(u); if (!su) return ZC_Z_mul(Y, v);
     855     6022263 :   sv = signe(v); if (!sv) return ZC_Z_mul(X, u);
     856     6022161 :   if (is_pm1(v))
     857             :   {
     858     1141163 :     if (is_pm1(u))
     859             :     {
     860      776279 :       if (su != sv) A = ZC_sub(X, Y);
     861      263550 :       else          A = ZC_add(X, Y);
     862      776279 :       if (su < 0) ZV_togglesign(A); /* in place but was created above */
     863             :     }
     864             :     else
     865             :     {
     866      364884 :       if (sv > 0) A = ZC_lincomb1 (u, Y, X);
     867      140334 :       else        A = ZC_lincomb_1(u, Y, X);
     868             :     }
     869             :   }
     870     4880998 :   else if (is_pm1(u))
     871             :   {
     872     1405892 :     if (su > 0) A = ZC_lincomb1 (v, X, Y);
     873       49802 :     else        A = ZC_lincomb_1(v, X, Y);
     874             :   }
     875             :   else
     876             :   { /* not cgetg_copy: x may be a t_VEC */
     877     3475106 :     long i, lx = lg(X);
     878     3475106 :     A = cgetg(lx,t_COL);
     879     3475106 :     for (i=1; i<lx; i++) gel(A,i) = lincombii(u,v,gel(X,i),gel(Y,i));
     880             :   }
     881     6022161 :   return A;
     882             : }
     883             : 
     884             : /********************************************************************/
     885             : /**                                                                **/
     886             : /**                           CONVERSIONS                          **/
     887             : /**                                                                **/
     888             : /********************************************************************/
     889             : GEN
     890        5574 : ZV_to_nv(GEN z)
     891             : {
     892        5574 :   long i, l = lg(z);
     893        5574 :   GEN x = cgetg(l, t_VECSMALL);
     894        5574 :   for (i=1; i<l; i++) x[i] = itou(gel(z,i));
     895        5574 :   return x;
     896             : }
     897             : 
     898             : GEN
     899      316093 : zm_to_ZM(GEN z)
     900             : {
     901      316093 :   long i, l = lg(z);
     902      316093 :   GEN x = cgetg(l,t_MAT);
     903      316093 :   for (i=1; i<l; i++) gel(x,i) = zc_to_ZC(gel(z,i));
     904      316093 :   return x;
     905             : }
     906             : 
     907             : GEN
     908          84 : zmV_to_ZMV(GEN z)
     909             : {
     910          84 :   long i, l = lg(z);
     911          84 :   GEN x = cgetg(l,t_VEC);
     912          84 :   for (i=1; i<l; i++) gel(x,i) = zm_to_ZM(gel(z,i));
     913          84 :   return x;
     914             : }
     915             : 
     916             : /* same as Flm_to_ZM but do not assume positivity */
     917             : GEN
     918         744 : ZM_to_zm(GEN z)
     919             : {
     920         744 :   long i, l = lg(z);
     921         744 :   GEN x = cgetg(l,t_MAT);
     922         744 :   for (i=1; i<l; i++) gel(x,i) = ZV_to_zv(gel(z,i));
     923         744 :   return x;
     924             : }
     925             : 
     926             : GEN
     927      191412 : zv_to_Flv(GEN z, ulong p)
     928             : {
     929      191412 :   long i, l = lg(z);
     930      191412 :   GEN x = cgetg(l,t_VECSMALL);
     931      191412 :   for (i=1; i<l; i++) x[i] = umodsu(z[i], p);
     932      191412 :   return x;
     933             : }
     934             : 
     935             : GEN
     936       13536 : zm_to_Flm(GEN z, ulong p)
     937             : {
     938       13536 :   long i, l = lg(z);
     939       13536 :   GEN x = cgetg(l,t_MAT);
     940       13536 :   for (i=1; i<l; i++) gel(x,i) = zv_to_Flv(gel(z,i),p);
     941       13536 :   return x;
     942             : }
     943             : 
     944             : GEN
     945          18 : ZMV_to_zmV(GEN z)
     946             : {
     947          18 :   long i,l = lg(z);
     948          18 :   GEN x = cgetg(l, t_VEC);
     949          18 :   for (i=1; i<l; i++) gel(x,i) = ZM_to_zm(gel(z,i));
     950          18 :   return x;
     951             : }
     952             : 
     953             : /********************************************************************/
     954             : /**                                                                **/
     955             : /**                         COPY, NEGATION                         **/
     956             : /**                                                                **/
     957             : /********************************************************************/
     958             : GEN
     959     3764702 : ZC_copy(GEN x)
     960             : {
     961     3764702 :   long i, lx = lg(x);
     962     3764702 :   GEN y = cgetg(lx, t_COL);
     963    75230759 :   for (i=1; i<lx; i++)
     964             :   {
     965    71466057 :     GEN c = gel(x,i);
     966    71466057 :     gel(y,i) = lgefint(c) == 2? gen_0: icopy(c);
     967             :   }
     968     3764702 :   return y;
     969             : }
     970             : 
     971             : GEN
     972      157609 : ZM_copy(GEN x)
     973             : {
     974             :   long l;
     975      157609 :   GEN y = cgetg_copy(x, &l);
     976      157609 :   while (--l > 0) gel(y,l) = ZC_copy(gel(x,l));
     977      157609 :   return y;
     978             : }
     979             : 
     980             : void
     981       47208 : ZV_neg_inplace(GEN M)
     982             : {
     983       47208 :   long l = lg(M);
     984       47208 :   while (--l > 0) gel(M,l) = negi(gel(M,l));
     985       47208 : }
     986             : GEN
     987     1708500 : ZC_neg(GEN M)
     988             : {
     989     1708500 :   long l = lg(M);
     990     1708500 :   GEN N = cgetg(l, t_COL);
     991     1708500 :   while (--l > 0) gel(N,l) = negi(gel(M,l));
     992     1708500 :   return N;
     993             : }
     994             : GEN
     995       19982 : zv_neg(GEN M)
     996             : {
     997             :   long l;
     998       19982 :   GEN N = cgetg_copy(M, &l);
     999       19982 :   while (--l > 0) N[l] = -M[l];
    1000       19982 :   return N;
    1001             : }
    1002             : GEN
    1003         211 : zv_neg_inplace(GEN M)
    1004             : {
    1005         211 :   long l = lg(M);
    1006         211 :   while (--l > 0) M[l] = -M[l];
    1007         211 :   return M;
    1008             : }
    1009             : GEN
    1010      227670 : ZM_neg(GEN x)
    1011             : {
    1012             :   long l;
    1013      227670 :   GEN y = cgetg_copy(x, &l);
    1014      227670 :   while (--l > 0) gel(y,l) = ZC_neg(gel(x,l));
    1015      227670 :   return y;
    1016             : }
    1017             : 
    1018             : void
    1019     1507983 : ZV_togglesign(GEN M)
    1020             : {
    1021     1507983 :   long l = lg(M);
    1022     1507983 :   while (--l > 0) togglesign_safe(&gel(M,l));
    1023     1507983 : }
    1024             : void
    1025           0 : ZM_togglesign(GEN M)
    1026             : {
    1027           0 :   long l = lg(M);
    1028           0 :   while (--l > 0) ZV_togglesign(gel(M,l));
    1029           0 : }
    1030             : 
    1031             : /********************************************************************/
    1032             : /**                                                                **/
    1033             : /**                        "DIVISION" mod HNF                      **/
    1034             : /**                                                                **/
    1035             : /********************************************************************/
    1036             : /* Reduce ZC x modulo ZM y in HNF, may return x itself (not a copy) */
    1037             : GEN
    1038      671436 : ZC_hnfremdiv(GEN x, GEN y, GEN *Q)
    1039             : {
    1040      671436 :   long i, l = lg(x);
    1041             :   GEN q;
    1042             : 
    1043      671436 :   if (Q) *Q = cgetg(l,t_COL);
    1044      671436 :   if (l == 1) return cgetg(1,t_COL);
    1045     4154930 :   for (i = l-1; i>0; i--)
    1046             :   {
    1047     3483494 :     q = diviiround(gel(x,i), gcoeff(y,i,i));
    1048     3483494 :     if (signe(q)) {
    1049     1881917 :       togglesign(q);
    1050     1881917 :       x = ZC_lincomb(gen_1, q, x, gel(y,i));
    1051             :     }
    1052     3483494 :     if (Q) gel(*Q, i) = q;
    1053             :   }
    1054      671436 :   return x;
    1055             : }
    1056             : 
    1057             : /* x = y Q + R, may return some columns of x (not copies) */
    1058             : GEN
    1059       23429 : ZM_hnfdivrem(GEN x, GEN y, GEN *Q)
    1060             : {
    1061       23429 :   long lx = lg(x), i;
    1062       23429 :   GEN R = cgetg(lx, t_MAT);
    1063       23429 :   if (Q)
    1064             :   {
    1065        3348 :     GEN q = cgetg(lx, t_MAT); *Q = q;
    1066        3348 :     for (i=1; i<lx; i++) gel(R,i) = ZC_hnfremdiv(gel(x,i),y,(GEN*)(q+i));
    1067             :   }
    1068             :   else
    1069       82247 :     for (i=1; i<lx; i++)
    1070             :     {
    1071       62166 :       pari_sp av = avma;
    1072       62166 :       GEN z = ZC_hnfrem(gel(x,i),y);
    1073       62166 :       gel(R,i) = (avma == av)? ZC_copy(z): gerepileupto(av, z);
    1074             :     }
    1075       23429 :   return R;
    1076             : }
    1077             : 
    1078             : 
    1079             : /********************************************************************/
    1080             : /**                                                                **/
    1081             : /**                               TESTS                            **/
    1082             : /**                                                                **/
    1083             : /********************************************************************/
    1084             : int
    1085    14871978 : zv_equal0(GEN V)
    1086             : {
    1087    14871978 :   long l = lg(V);
    1088    38665764 :   while (--l > 0)
    1089    19248486 :     if (V[l]) return 0;
    1090     4545300 :   return 1;
    1091             : }
    1092             : 
    1093             : int
    1094      412150 : ZV_equal0(GEN V)
    1095             : {
    1096      412150 :   long l = lg(V);
    1097     1971500 :   while (--l > 0)
    1098     1482323 :     if (signe(gel(V,l))) return 0;
    1099       77027 :   return 1;
    1100             : }
    1101             : 
    1102             : static int
    1103     7668501 : ZV_equal_lg(GEN V, GEN W, long l)
    1104             : {
    1105    21674326 :   while (--l > 0)
    1106    12378185 :     if (!equalii(gel(V,l), gel(W,l))) return 0;
    1107     1627640 :   return 1;
    1108             : }
    1109             : int
    1110     6669141 : ZV_equal(GEN V, GEN W)
    1111             : {
    1112     6669141 :   long l = lg(V);
    1113     6669141 :   if (lg(W) != l) return 0;
    1114     6669141 :   return ZV_equal_lg(V, W, l);
    1115             : }
    1116             : int
    1117      314934 : ZM_equal(GEN A, GEN B)
    1118             : {
    1119      314934 :   long i, m, l = lg(A);
    1120      314934 :   if (lg(B) != l) return 0;
    1121      314460 :   if (l == 1) return 1;
    1122      314460 :   m = lgcols(A);
    1123      314460 :   if (lgcols(B) != m) return 0;
    1124     1250172 :   for (i = 1; i < l; i++)
    1125      999360 :     if (!ZV_equal_lg(gel(A,i), gel(B,i), m)) return 0;
    1126      250812 :   return 1;
    1127             : }
    1128             : int
    1129    19433497 : zv_equal(GEN V, GEN W)
    1130             : {
    1131    19433497 :   long l = lg(V);
    1132    19433497 :   if (lg(W) != l) return 0;
    1133   188971863 :   while (--l > 0)
    1134   150772764 :     if (V[l] != W[l]) return 0;
    1135    19078412 :   return 1;
    1136             : }
    1137             : 
    1138             : int
    1139         330 : zvV_equal(GEN V, GEN W)
    1140             : {
    1141         330 :   long l = lg(V);
    1142         330 :   if (lg(W) != l) return 0;
    1143       50556 :   while (--l > 0)
    1144       50034 :     if (!zv_equal(gel(V,l),gel(W,l))) return 0;
    1145         198 :   return 1;
    1146             : }
    1147             : 
    1148             : int
    1149       60852 : ZM_ishnf(GEN x)
    1150             : {
    1151       60852 :   long i,j, lx = lg(x);
    1152      209195 :   for (i=1; i<lx; i++)
    1153             :   {
    1154      154787 :     GEN xii = gcoeff(x,i,i);
    1155      154787 :     if (signe(xii) <= 0) return 0;
    1156      467681 :     for (j=1; j<i; j++)
    1157      313302 :       if (signe(gcoeff(x,i,j))) return 0;
    1158      492683 :     for (j=i+1; j<lx; j++)
    1159             :     {
    1160      344340 :       GEN xij = gcoeff(x,i,j);
    1161      344340 :       if (signe(xij)<0 || cmpii(xij,xii)>=0) return 0;
    1162             :     }
    1163             :   }
    1164       54408 :   return 1;
    1165             : }
    1166             : int
    1167      233202 : ZM_isidentity(GEN x)
    1168             : {
    1169      233202 :   long i,j, lx = lg(x);
    1170             : 
    1171      233202 :   if (lx == 1) return 1;
    1172      233202 :   if (lx != lgcols(x)) return 0;
    1173     1008054 :   for (j=1; j<lx; j++)
    1174             :   {
    1175      905418 :     GEN c = gel(x,j);
    1176     4343034 :     for (i=1; i<j; )
    1177     2625186 :       if (signe(gel(c,i++))) return 0;
    1178             :     /* i = j */
    1179      812430 :       if (!equali1(gel(c,i++))) return 0;
    1180     4177026 :     for (   ; i<lx; )
    1181     2626254 :       if (signe(gel(c,i++))) return 0;
    1182             :   }
    1183      102636 :   return 1;
    1184             : }
    1185             : int
    1186       46386 : ZM_isdiagonal(GEN x)
    1187             : {
    1188       46386 :   long i,j, lx = lg(x);
    1189       46386 :   if (lx == 1) return 1;
    1190       46386 :   if (lx != lgcols(x)) return 0;
    1191             : 
    1192      142661 :   for (j=1; j<lx; j++)
    1193             :   {
    1194      116356 :     GEN c = gel(x,j);
    1195      275001 :     for (i=1; i<j; i++)
    1196      178720 :       if (signe(gel(c,i))) return 0;
    1197      411652 :     for (i++; i<lx; i++)
    1198      315377 :       if (signe(gel(c,i))) return 0;
    1199             :   }
    1200       26305 :   return 1;
    1201             : }
    1202             : int
    1203       13296 : ZM_isscalar(GEN x, GEN s)
    1204             : {
    1205       13296 :   long i, j, lx = lg(x);
    1206             : 
    1207       13296 :   if (lx == 1) return 1;
    1208       13296 :   if (lx != lgcols(x)) return 0;
    1209       13296 :   if (!s) s = gcoeff(x,1,1);
    1210      107208 :   for (j=1; j<lx; j++)
    1211             :   {
    1212       93942 :     GEN c = gel(x,j);
    1213     1082382 :     for (i=1; i<j; )
    1214      894504 :       if (signe(gel(c,i++))) return 0;
    1215             :     /* i = j */
    1216       93936 :       if (!equalii(gel(c,i++), s)) return 0;
    1217     1082346 :     for (   ; i<lx; )
    1218      894522 :       if (signe(gel(c,i++))) return 0;
    1219             :   }
    1220       13266 :   return 1;
    1221             : }
    1222             : 
    1223             : 
    1224             : long
    1225       66894 : ZC_is_ei(GEN x)
    1226             : {
    1227       66894 :   long i, j = 0, l = lg(x);
    1228      887214 :   for (i = 1; i < l; i++)
    1229             :   {
    1230      820320 :     GEN c = gel(x,i);
    1231      820320 :     long s = signe(c);
    1232      820320 :     if (!s) continue;
    1233       66882 :     if (s < 0 || !is_pm1(c) || j) return 0;
    1234       66882 :     j = i;
    1235             :   }
    1236       66894 :   return j;
    1237             : }
    1238             : 
    1239             : /********************************************************************/
    1240             : /**                                                                **/
    1241             : /**                       MISCELLANEOUS                            **/
    1242             : /**                                                                **/
    1243             : /********************************************************************/
    1244             : /* assume lg(x) = lg(y), x,y in Z^n */
    1245             : int
    1246      497829 : ZV_cmp(GEN x, GEN y)
    1247             : {
    1248      497829 :   long fl,i, lx = lg(x);
    1249     1000077 :   for (i=1; i<lx; i++)
    1250      804553 :     if (( fl = cmpii(gel(x,i), gel(y,i)) )) return fl;
    1251      195524 :   return 0;
    1252             : }
    1253             : /* assume lg(x) = lg(y), x,y in Z^n */
    1254             : int
    1255        2982 : ZV_abscmp(GEN x, GEN y)
    1256             : {
    1257        2982 :   long fl,i, lx = lg(x);
    1258       16674 :   for (i=1; i<lx; i++)
    1259       16608 :     if (( fl = abscmpii(gel(x,i), gel(y,i)) )) return fl;
    1260          66 :   return 0;
    1261             : }
    1262             : 
    1263             : long
    1264      830244 : zv_content(GEN x)
    1265             : {
    1266      830244 :   long i, s, l = lg(x);
    1267      830244 :   if (l == 1) return 0;
    1268      830238 :   s = labs(x[1]);
    1269      830238 :   for (i=2; i<l && s!=1; i++) s = cgcd(x[i],s);
    1270      830238 :   return s;
    1271             : }
    1272             : GEN
    1273        8496 : ZV_content(GEN x)
    1274             : {
    1275        8496 :   long i, l = lg(x);
    1276        8496 :   pari_sp av = avma;
    1277             :   GEN c;
    1278        8496 :   if (l == 1) return gen_0;
    1279        8496 :   if (l == 2) return absi(gel(x,1));
    1280        3516 :   c = gel(x,1);
    1281        6534 :   for (i = 2; i < l; i++)
    1282             :   {
    1283        4254 :     c = gcdii(c, gel(x,i));
    1284        4254 :     if (is_pm1(c)) { avma = av; return gen_1; }
    1285             :   }
    1286        2280 :   return gerepileuptoint(av, c);
    1287             : }
    1288             : 
    1289             : GEN
    1290      633797 : ZM_det_triangular(GEN mat)
    1291             : {
    1292             :   pari_sp av;
    1293      633797 :   long i,l = lg(mat);
    1294             :   GEN s;
    1295             : 
    1296      633797 :   if (l<3) return l<2? gen_1: icopy(gcoeff(mat,1,1));
    1297      578024 :   av = avma; s = gcoeff(mat,1,1);
    1298      578024 :   for (i=2; i<l; i++) s = mulii(s,gcoeff(mat,i,i));
    1299      578024 :   return gerepileuptoint(av,s);
    1300             : }
    1301             : 
    1302             : /* assumes no overflow */
    1303             : long
    1304      251244 : zv_prod(GEN v)
    1305             : {
    1306      251244 :   long n, i, l = lg(v);
    1307      251244 :   if (l == 1) return 1;
    1308      182172 :   n = v[1]; for (i = 2; i < l; i++) n *= v[i];
    1309      182172 :   return n;
    1310             : }
    1311             : 
    1312             : static GEN
    1313   233830144 : _mulii(void *E, GEN a, GEN b)
    1314   233830144 : { (void) E; return mulii(a, b); }
    1315             : 
    1316             : /* product of ulongs */
    1317             : GEN
    1318      312790 : zv_prod_Z(GEN v)
    1319             : {
    1320      312790 :   pari_sp av = avma;
    1321      312790 :   long k, m, n = lg(v)-1;
    1322             :   GEN V;
    1323      312790 :   switch(n) {
    1324       16704 :     case 0: return gen_1;
    1325       48546 :     case 1: return utoi(v[1]);
    1326      107442 :     case 2: return muluu(v[1], v[2]);
    1327             :   }
    1328      140098 :   m = n >> 1;
    1329      140098 :   V = cgetg(m + (odd(n)? 2: 1), t_VEC);
    1330      140098 :   for (k = 1; k <= m; k++) gel(V,k) = muluu(v[k<<1], v[(k<<1)-1]);
    1331      140098 :   if (odd(n)) gel(V,k) = utoipos(v[n]);
    1332      140098 :   return gerepileuptoint(av, gen_product(V, NULL, &_mulii));
    1333             : }
    1334             : GEN
    1335    12595194 : vecsmall_prod(GEN v)
    1336             : {
    1337    12595194 :   pari_sp av = avma;
    1338    12595194 :   long k, m, n = lg(v)-1;
    1339             :   GEN V;
    1340    12595194 :   switch (n) {
    1341           0 :     case 0: return gen_1;
    1342           0 :     case 1: return stoi(v[1]);
    1343          18 :     case 2: return mulss(v[1], v[2]);
    1344             :   }
    1345    12595176 :   m = n >> 1;
    1346    12595176 :   V = cgetg(m + (odd(n)? 2: 1), t_VEC);
    1347    12595176 :   for (k = 1; k <= m; k++) gel(V,k) = mulss(v[k<<1], v[(k<<1)-1]);
    1348    12595176 :   if (odd(n)) gel(V,k) = stoi(v[n]);
    1349    12595176 :   return gerepileuptoint(av, gen_product(V, NULL, &_mulii));
    1350             : }
    1351             : 
    1352             : GEN
    1353     6326086 : ZV_prod(GEN v)
    1354             : {
    1355     6326086 :   pari_sp av = avma;
    1356     6326086 :   long i, l = lg(v);
    1357             :   GEN n;
    1358     6326086 :   if (l == 1) return gen_1;
    1359     6324946 :   if (l > 7) return gerepileuptoint(av, gen_product(v, NULL, _mulii));
    1360       25866 :   n = gel(v,1);
    1361       25866 :   if (l == 2) return icopy(n);
    1362       11958 :   for (i = 2; i < l; i++) n = mulii(n, gel(v,i));
    1363       11958 :   return gerepileuptoint(av, n);
    1364             : }
    1365             : /* assumes no overflow */
    1366             : long
    1367        1356 : zv_sum(GEN v)
    1368             : {
    1369        1356 :   long n, i, l = lg(v);
    1370        1356 :   if (l == 1) return 0;
    1371        1338 :   n = v[1]; for (i = 2; i < l; i++) n += v[i];
    1372        1338 :   return n;
    1373             : }
    1374             : GEN
    1375          48 : ZV_sum(GEN v)
    1376             : {
    1377          48 :   pari_sp av = avma;
    1378          48 :   long i, l = lg(v);
    1379             :   GEN n;
    1380          48 :   if (l == 1) return gen_0;
    1381          48 :   n = gel(v,1);
    1382          48 :   if (l == 2) return icopy(n);
    1383          48 :   for (i = 2; i < l; i++) n = addii(n, gel(v,i));
    1384          48 :   return gerepileuptoint(av, n);
    1385             : }
    1386             : 
    1387             : /********************************************************************/
    1388             : /**                                                                **/
    1389             : /**         GRAM SCHMIDT REDUCTION (integer matrices)              **/
    1390             : /**                                                                **/
    1391             : /********************************************************************/
    1392             : 
    1393             : /* L[k,] += q * L[l,], l < k. Inefficient if q = 0 */
    1394             : static void
    1395       25884 : Zupdate_row(long k, long l, GEN q, GEN L, GEN B)
    1396             : {
    1397       25884 :   long i, qq = itos_or_0(q);
    1398       25884 :   if (!qq)
    1399             :   {
    1400        1656 :     for(i=1;i<l;i++)  gcoeff(L,k,i) = addii(gcoeff(L,k,i),mulii(q,gcoeff(L,l,i)));
    1401        1656 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), mulii(q,B));
    1402       27540 :     return;
    1403             :   }
    1404       24228 :   if (qq == 1) {
    1405        6282 :     for (i=1;i<l; i++) gcoeff(L,k,i) = addii(gcoeff(L,k,i),gcoeff(L,l,i));
    1406        6282 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), B);
    1407       17946 :   } else if (qq == -1) {
    1408        3822 :     for (i=1;i<l; i++) gcoeff(L,k,i) = subii(gcoeff(L,k,i),gcoeff(L,l,i));
    1409        3822 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), negi(B));
    1410             :   } else {
    1411       14124 :     for(i=1;i<l;i++) gcoeff(L,k,i) = addii(gcoeff(L,k,i),mulsi(qq,gcoeff(L,l,i)));
    1412       14124 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), mulsi(qq,B));
    1413             :   }
    1414             : }
    1415             : 
    1416             : /* update L[k,] */
    1417             : static void
    1418       49476 : ZRED(long k, long l, GEN x, GEN L, GEN B)
    1419             : {
    1420       49476 :   GEN q = truedivii(addii(B,shifti(gcoeff(L,k,l),1)), shifti(B,1));
    1421       98952 :   if (!signe(q)) return;
    1422       25884 :   q = negi(q);
    1423       25884 :   Zupdate_row(k,l,q,L,B);
    1424       25884 :   gel(x,k) = ZC_lincomb(gen_1, q, gel(x,k), gel(x,l));
    1425             : }
    1426             : 
    1427             : /* Gram-Schmidt reduction, x a ZM */
    1428             : static void
    1429       58890 : ZincrementalGS(GEN x, GEN L, GEN B, long k)
    1430             : {
    1431             :   long i, j;
    1432      197394 :   for (j=1; j<=k; j++)
    1433             :   {
    1434      138504 :     pari_sp av = avma;
    1435      138504 :     GEN u = ZV_dotproduct(gel(x,k), gel(x,j));
    1436      292086 :     for (i=1; i<j; i++)
    1437             :     {
    1438      153582 :       u = subii(mulii(gel(B,i+1), u), mulii(gcoeff(L,k,i), gcoeff(L,j,i)));
    1439      153582 :       u = diviiexact(u, gel(B,i));
    1440             :     }
    1441      138504 :     gcoeff(L,k,j) = gerepileuptoint(av, u);
    1442             :   }
    1443       58890 :   gel(B,k+1) = gcoeff(L,k,k); gcoeff(L,k,k) = gen_1;
    1444       58890 : }
    1445             : 
    1446             : /* Variant reducemodinvertible(ZC v, ZM y), when y singular.
    1447             :  * Very inefficient if y is not LLL-reduced of maximal rank */
    1448             : static GEN
    1449       13140 : ZC_reducemodmatrix_i(GEN v, GEN y)
    1450             : {
    1451       13140 :   GEN B, L, x = shallowconcat(y, v);
    1452       13140 :   long k, lx = lg(x), nx = lx-1;
    1453             : 
    1454       13140 :   B = scalarcol_shallow(gen_1, lx);
    1455       13140 :   L = zeromatcopy(nx, nx);
    1456       13140 :   for (k=1; k <= nx; k++) ZincrementalGS(x, L, B, k);
    1457       13140 :   for (k = nx-1; k >= 1; k--) ZRED(nx,k, x,L,gel(B,k+1));
    1458       13140 :   return gel(x,nx);
    1459             : }
    1460             : GEN
    1461       13140 : ZC_reducemodmatrix(GEN v, GEN y) {
    1462       13140 :   pari_sp av = avma;
    1463       13140 :   return gerepilecopy(av, ZC_reducemodmatrix_i(v,y));
    1464             : }
    1465             : 
    1466             : /* Variant reducemodinvertible(ZM v, ZM y), when y singular.
    1467             :  * Very inefficient if y is not LLL-reduced of maximal rank */
    1468             : static GEN
    1469        3768 : ZM_reducemodmatrix_i(GEN v, GEN y)
    1470             : {
    1471             :   GEN B, L, V;
    1472        3768 :   long j, k, lv = lg(v), nx = lg(y), lx = nx+1;
    1473             : 
    1474        3768 :   V = cgetg(lv, t_MAT);
    1475        3768 :   B = scalarcol_shallow(gen_1, lx);
    1476        3768 :   L = zeromatcopy(nx, nx);
    1477        3768 :   for (k=1; k < nx; k++) ZincrementalGS(y, L, B, k);
    1478       12732 :   for (j = 1; j < lg(v); j++)
    1479             :   {
    1480        8964 :     GEN x = shallowconcat(y, gel(v,j));
    1481        8964 :     ZincrementalGS(x, L, B, nx); /* overwrite last */
    1482        8964 :     for (k = nx-1; k >= 1; k--) ZRED(nx,k, x,L,gel(B,k+1));
    1483        8964 :     gel(V,j) = gel(x,nx);
    1484             :   }
    1485        3768 :   return V;
    1486             : }
    1487             : GEN
    1488        3768 : ZM_reducemodmatrix(GEN v, GEN y) {
    1489        3768 :   pari_sp av = avma;
    1490        3768 :   return gerepilecopy(av, ZM_reducemodmatrix_i(v,y));
    1491             : }
    1492             : 
    1493             : GEN
    1494        5598 : ZC_reducemodlll(GEN x,GEN y)
    1495             : {
    1496        5598 :   pari_sp av = avma;
    1497        5598 :   GEN z = ZC_reducemodmatrix(x, ZM_lll(y, 0.75, LLL_INPLACE));
    1498        5598 :   return gerepilecopy(av, z);
    1499             : }
    1500             : GEN
    1501           0 : ZM_reducemodlll(GEN x,GEN y)
    1502             : {
    1503           0 :   pari_sp av = avma;
    1504           0 :   GEN z = ZM_reducemodmatrix(x, ZM_lll(y, 0.75, LLL_INPLACE));
    1505           0 :   return gerepilecopy(av, z);
    1506             : }

Generated by: LCOV version 1.11