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 21342-bb34613) Lines: 759 831 91.3 %
Date: 2017-11-18 06:21:14 Functions: 113 119 95.0 %
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     1196148 : check_ZV(GEN x, long l)
      19             : {
      20             :   long i;
      21     8034533 :   for (i=1; i<l; i++)
      22     6838469 :     if (typ(gel(x,i)) != t_INT) return 0;
      23     1196064 :   return 1;
      24             : }
      25             : void
      26      504624 : RgV_check_ZV(GEN A, const char *s)
      27             : {
      28      504624 :   if (!RgV_is_ZV(A)) pari_err_TYPE(stack_strcat(s," [integer vector]"), A);
      29      504617 : }
      30             : void
      31      308114 : RgM_check_ZM(GEN A, const char *s)
      32             : {
      33      308114 :   long n = lg(A);
      34      308114 :   if (n != 1)
      35             :   {
      36      308079 :     long j, m = lgcols(A);
      37     1504143 :     for (j=1; j<n; j++)
      38     1196148 :       if (!check_ZV(gel(A,j), m))
      39          84 :         pari_err_TYPE(stack_strcat(s," [integer matrix]"), A);
      40             :   }
      41      308030 : }
      42             : 
      43             : static long
      44    33560334 : ZV_max_lg_i(GEN x, long m)
      45             : {
      46    33560334 :   long i, prec = 2;
      47    33560334 :   for (i=1; i<m; i++) { long l = lgefint(gel(x,i)); if (l > prec) prec = l; }
      48    33560334 :   return prec;
      49             : }
      50             : 
      51             : long
      52       10612 : ZV_max_lg(GEN x)
      53       10612 : { return ZV_max_lg_i(x, lg(x)); }
      54             : 
      55             : static long
      56     9663589 : ZM_max_lg_i(GEN x, long n, long m)
      57             : {
      58     9663589 :   long prec = 2;
      59     9663589 :   if (n != 1)
      60             :   {
      61             :     long j;
      62    43213311 :     for (j=1; j<n; j++)
      63             :     {
      64    33549722 :       long l = ZV_max_lg_i(gel(x,j), m);
      65    33549722 :       if (l > prec) prec = l;
      66             :     }
      67             :   }
      68     9663589 :   return prec;
      69             : }
      70             : 
      71             : long
      72        3222 : ZM_max_lg(GEN x)
      73             : {
      74        3222 :   long n = lg(x);
      75        3222 :   if (n==1) return 2;
      76        3222 :   return ZM_max_lg_i(x, n, lgcols(x));
      77             : }
      78             : 
      79             : GEN
      80        3059 : ZM_supnorm(GEN x)
      81             : {
      82        3059 :   long i, j, h, lx = lg(x);
      83        3059 :   GEN s = gen_0;
      84        3059 :   if (lx == 1) return gen_1;
      85        3059 :   h = lgcols(x);
      86       19082 :   for (j=1; j<lx; j++)
      87             :   {
      88       16023 :     GEN xj = gel(x,j);
      89      238756 :     for (i=1; i<h; i++)
      90             :     {
      91      222733 :       GEN c = gel(xj,i);
      92      222733 :       if (abscmpii(c, s) > 0) s = c;
      93             :     }
      94             :   }
      95        3059 :   return absi(s);
      96             : }
      97             : 
      98             : /********************************************************************/
      99             : /**                                                                **/
     100             : /**                           MULTIPLICATION                       **/
     101             : /**                                                                **/
     102             : /********************************************************************/
     103             : /* x non-empty ZM, y a compatible nc (dimension > 0). */
     104             : static GEN
     105      664319 : ZM_nc_mul_i(GEN x, GEN y, long c, long l)
     106             : {
     107             :   long i, j;
     108             :   pari_sp av;
     109      664319 :   GEN z = cgetg(l,t_COL), s;
     110             : 
     111     6014634 :   for (i=1; i<l; i++)
     112             :   {
     113     5350315 :     av = avma; s = muliu(gcoeff(x,i,1),y[1]);
     114   178034919 :     for (j=2; j<c; j++)
     115   172684604 :       if (y[j]) s = addii(s, muliu(gcoeff(x,i,j),y[j]));
     116     5350315 :     gel(z,i) = gerepileuptoint(av,s);
     117             :   }
     118      664319 :   return z;
     119             : }
     120             : 
     121             : /* x ZV, y a compatible zc. */
     122             : GEN
     123        1645 : ZV_zc_mul(GEN x, GEN y)
     124             : {
     125        1645 :   long j, l = lg(x);
     126        1645 :   pari_sp av = avma;
     127        1645 :   GEN s = mulis(gel(x,1),y[1]);
     128       50393 :   for (j=2; j<l; j++)
     129       48748 :     if (y[j]) s = addii(s, mulis(gel(x,j),y[j]));
     130        1645 :   return gerepileuptoint(av,s);
     131             : }
     132             : 
     133             : /* x non-empty ZM, y a compatible zc (dimension > 0). */
     134             : static GEN
     135     2806375 : ZM_zc_mul_i(GEN x, GEN y, long c, long l)
     136             : {
     137             :   long i, j;
     138     2806375 :   GEN z = cgetg(l,t_COL);
     139             : 
     140    17137296 :   for (i=1; i<l; i++)
     141             :   {
     142    14330921 :     pari_sp av = avma;
     143    14330921 :     GEN s = mulis(gcoeff(x,i,1),y[1]);
     144   253497624 :     for (j=2; j<c; j++)
     145   239166703 :       if (y[j]) s = addii(s, mulis(gcoeff(x,i,j),y[j]));
     146    14330921 :     gel(z,i) = gerepileuptoint(av,s);
     147             :   }
     148     2806375 :   return z;
     149             : }
     150             : GEN
     151     1598660 : ZM_zc_mul(GEN x, GEN y) {
     152     1598660 :   long l = lg(x);
     153     1598660 :   if (l == 1) return cgetg(1, t_COL);
     154     1598660 :   return ZM_zc_mul_i(x,y, l, lgcols(x));
     155             : }
     156             : 
     157             : /* y non-empty ZM, x a compatible zv (dimension > 0). */
     158             : GEN
     159        1309 : zv_ZM_mul(GEN x, GEN y) {
     160        1309 :   long i,j, lx = lg(x), ly = lg(y);
     161             :   GEN z;
     162        1309 :   if (lx == 1) return zerovec(ly-1);
     163        1309 :   z = cgetg(ly,t_VEC);
     164        3178 :   for (j=1; j<ly; j++)
     165             :   {
     166        1869 :     pari_sp av = avma;
     167        1869 :     GEN s = mulsi(x[1], gcoeff(y,1,j));
     168        3521 :     for (i=2; i<lx; i++)
     169        1652 :       if (x[i]) s = addii(s, mulsi(x[i], gcoeff(y,i,j)));
     170        1869 :     gel(z,j) = gerepileuptoint(av,s);
     171             :   }
     172        1309 :   return z;
     173             : }
     174             : 
     175             : /* x ZM, y a compatible zm (dimension > 0). */
     176             : GEN
     177      587790 : ZM_zm_mul(GEN x, GEN y)
     178             : {
     179      587790 :   long j, c, l = lg(x), ly = lg(y);
     180      587790 :   GEN z = cgetg(ly, t_MAT);
     181      587790 :   if (l == 1) return z;
     182      587790 :   c = lgcols(x);
     183      587790 :   for (j = 1; j < ly; j++) gel(z,j) = ZM_zc_mul_i(x, gel(y,j), l,c);
     184      587790 :   return z;
     185             : }
     186             : /* x ZM, y a compatible zn (dimension > 0). */
     187             : GEN
     188      634746 : ZM_nm_mul(GEN x, GEN y)
     189             : {
     190      634746 :   long j, c, l = lg(x), ly = lg(y);
     191      634746 :   GEN z = cgetg(ly, t_MAT);
     192      634746 :   if (l == 1) return z;
     193      634746 :   c = lgcols(x);
     194      634746 :   for (j = 1; j < ly; j++) gel(z,j) = ZM_nc_mul_i(x, gel(y,j), l,c);
     195      634746 :   return z;
     196             : }
     197             : 
     198             : /* Strassen-Winograd algorithm */
     199             : 
     200             : /*
     201             :   Return A[ma+1..ma+da, na+1..na+ea] - B[mb+1..mb+db, nb+1..nb+eb]
     202             :   as an (m x n)-matrix, padding the input with zeroes as necessary.
     203             : */
     204             : static GEN
     205       90672 : add_slices(long m, long n,
     206             :            GEN A, long ma, long da, long na, long ea,
     207             :            GEN B, long mb, long db, long nb, long eb)
     208             : {
     209       90672 :   long min_d = minss(da, db), min_e = minss(ea, eb), i, j;
     210       90672 :   GEN M = cgetg(n + 1, t_MAT), C;
     211             : 
     212     1827124 :   for (j = 1; j <= min_e; j++) {
     213     1736452 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     214    45786610 :     for (i = 1; i <= min_d; i++)
     215    88100316 :       gel(C, i) = addii(gcoeff(A, ma + i, na + j),
     216    44050158 :                         gcoeff(B, mb + i, nb + j));
     217     1863251 :     for (; i <= da; i++)
     218      126799 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     219     1736452 :     for (; i <= db; i++)
     220           0 :       gel(C, i) = gcoeff(B, mb + i, nb + j);
     221     1736452 :     for (; i <= m; i++)
     222           0 :       gel(C, i) = gen_0;
     223             :   }
     224      104043 :   for (; j <= ea; j++) {
     225       13371 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     226      270371 :     for (i = 1; i <= da; i++)
     227      257000 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     228       13371 :     for (; i <= m; i++)
     229           0 :       gel(C, i) = gen_0;
     230             :   }
     231       90672 :   for (; j <= eb; j++) {
     232           0 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     233           0 :     for (i = 1; i <= db; i++)
     234           0 :       gel(C, i) = gcoeff(B, mb + i, nb + j);
     235           0 :     for (; i <= m; i++)
     236           0 :       gel(C, i) = gen_0;
     237             :   }
     238       90672 :   for (; j <= n; j++)
     239           0 :     gel(M, j) = zerocol(m);
     240       90672 :   return M;
     241             : }
     242             : 
     243             : /*
     244             :   Return A[ma+1..ma+da, na+1..na+ea] - B[mb+1..mb+db, nb+1..nb+eb]
     245             :   as an (m x n)-matrix, padding the input with zeroes as necessary.
     246             : */
     247             : static GEN
     248       79338 : subtract_slices(long m, long n,
     249             :                 GEN A, long ma, long da, long na, long ea,
     250             :                 GEN B, long mb, long db, long nb, long eb)
     251             : {
     252       79338 :   long min_d = minss(da, db), min_e = minss(ea, eb), i, j;
     253       79338 :   GEN M = cgetg(n + 1, t_MAT), C;
     254             : 
     255     1764622 :   for (j = 1; j <= min_e; j++) {
     256     1685284 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     257    49497364 :     for (i = 1; i <= min_d; i++)
     258    95624160 :       gel(C, i) = subii(gcoeff(A, ma + i, na + j),
     259    47812080 :                         gcoeff(B, mb + i, nb + j));
     260     1808282 :     for (; i <= da; i++)
     261      122998 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     262     1870790 :     for (; i <= db; i++)
     263      185506 :       gel(C, i) = negi(gcoeff(B, mb + i, nb + j));
     264     1685284 :     for (; i <= m; i++)
     265           0 :       gel(C, i) = gen_0;
     266             :   }
     267       79338 :   for (; j <= ea; j++) {
     268           0 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     269           0 :     for (i = 1; i <= da; i++)
     270           0 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     271           0 :     for (; i <= m; i++)
     272           0 :       gel(C, i) = gen_0;
     273             :   }
     274       86324 :   for (; j <= eb; j++) {
     275        6986 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     276      193800 :     for (i = 1; i <= db; i++)
     277      186814 :       gel(C, i) = negi(gcoeff(B, mb + i, nb + j));
     278        6986 :     for (; i <= m; i++)
     279           0 :       gel(C, i) = gen_0;
     280             :   }
     281       86324 :   for (; j <= n; j++)
     282        6986 :     gel(M, j) = zerocol(m);
     283       79338 :   return M;
     284             : }
     285             : 
     286             : static GEN ZM_mul_i(GEN x, GEN y, long l, long lx, long ly);
     287             : 
     288             : /* Strassen-Winograd matrix product A (m x n) * B (n x p) */
     289             : static GEN
     290       11334 : ZM_mul_sw(GEN A, GEN B, long m, long n, long p)
     291             : {
     292       11334 :   pari_sp av = avma;
     293       11334 :   long m1 = (m + 1)/2, m2 = m/2,
     294       11334 :     n1 = (n + 1)/2, n2 = n/2,
     295       11334 :     p1 = (p + 1)/2, p2 = p/2;
     296             :   GEN A11, A12, A22, B11, B21, B22,
     297             :     S1, S2, S3, S4, T1, T2, T3, T4,
     298             :     M1, M2, M3, M4, M5, M6, M7,
     299             :     V1, V2, V3, C11, C12, C21, C22, C;
     300             : 
     301       11334 :   T2 = subtract_slices(n1, p2, B, 0, n1, p1, p2, B, n1, n2, p1, p2);
     302       11334 :   S1 = subtract_slices(m2, n1, A, m1, m2, 0, n1, A, 0, m2, 0, n1);
     303       11334 :   M2 = ZM_mul_i(S1, T2, m2 + 1, n1 + 1, p2 + 1);
     304       11334 :   if (gc_needed(av, 1))
     305           0 :     gerepileall(av, 2, &T2, &M2);  /* destroy S1 */
     306       11334 :   T3 = subtract_slices(n1, p1, T2, 0, n1, 0, p2, B, 0, n1, 0, p1);
     307       11334 :   if (gc_needed(av, 1))
     308           0 :     gerepileall(av, 2, &M2, &T3);  /* destroy T2 */
     309       11334 :   S2 = add_slices(m2, n1, A, m1, m2, 0, n1, A, m1, m2, n1, n2);
     310       11334 :   T1 = subtract_slices(n1, p1, B, 0, n1, p1, p2, B, 0, n1, 0, p2);
     311       11334 :   M3 = ZM_mul_i(S2, T1, m2 + 1, n1 + 1, p2 + 1);
     312       11334 :   if (gc_needed(av, 1))
     313           0 :     gerepileall(av, 4, &M2, &T3, &S2, &M3);  /* destroy T1 */
     314       11334 :   S3 = subtract_slices(m1, n1, S2, 0, m2, 0, n1, A, 0, m1, 0, n1);
     315       11334 :   if (gc_needed(av, 1))
     316           0 :     gerepileall(av, 4, &M2, &T3, &M3, &S3);  /* destroy S2 */
     317       11334 :   A11 = matslice(A, 1, m1, 1, n1);
     318       11334 :   B11 = matslice(B, 1, n1, 1, p1);
     319       11334 :   M1 = ZM_mul_i(A11, B11, m1 + 1, n1 + 1, p1 + 1);
     320       11334 :   if (gc_needed(av, 1))
     321           0 :     gerepileall(av, 5, &M2, &T3, &M3, &S3, &M1);  /* destroy A11, B11 */
     322       11334 :   A12 = matslice(A, 1, m1, n1 + 1, n);
     323       11334 :   B21 = matslice(B, n1 + 1, n, 1, p1);
     324       11334 :   M4 = ZM_mul_i(A12, B21, m1 + 1, n2 + 1, p1 + 1);
     325       11334 :   if (gc_needed(av, 1))
     326           0 :     gerepileall(av, 6, &M2, &T3, &M3, &S3, &M1, &M4);  /* destroy A12, B21 */
     327       11334 :   C11 = add_slices(m1, p1, M1, 0, m1, 0, p1, M4, 0, m1, 0, p1);
     328       11334 :   if (gc_needed(av, 1))
     329           0 :     gerepileall(av, 6, &M2, &T3, &M3, &S3, &M1, &C11);  /* destroy M4 */
     330       11334 :   M5 = ZM_mul_i(S3, T3, m1 + 1, n1 + 1, p1 + 1);
     331       11334 :   S4 = subtract_slices(m1, n2, A, 0, m1, n1, n2, S3, 0, m1, 0, n2);
     332       11334 :   if (gc_needed(av, 1))
     333           6 :     gerepileall(av, 7, &M2, &T3, &M3, &M1, &C11, &M5, &S4);  /* destroy S3 */
     334       11334 :   T4 = add_slices(n2, p1, B, n1, n2, 0, p1, T3, 0, n2, 0, p1);
     335       11334 :   if (gc_needed(av, 1))
     336           0 :     gerepileall(av, 7, &M2, &M3, &M1, &C11, &M5, &S4, &T4);  /* destroy T3 */
     337       11334 :   V1 = subtract_slices(m1, p1, M1, 0, m1, 0, p1, M5, 0, m1, 0, p1);
     338       11334 :   if (gc_needed(av, 1))
     339           0 :     gerepileall(av, 6, &M2, &M3, &S4, &T4, &C11, &V1);  /* destroy M1, M5 */
     340       11334 :   B22 = matslice(B, n1 + 1, n, p1 + 1, p);
     341       11334 :   M6 = ZM_mul_i(S4, B22, m1 + 1, n2 + 1, p2 + 1);
     342       11334 :   if (gc_needed(av, 1))
     343           0 :     gerepileall(av, 6, &M2, &M3, &T4, &C11, &V1, &M6);  /* destroy S4, B22 */
     344       11334 :   A22 = matslice(A, m1 + 1, m, n1 + 1, n);
     345       11334 :   M7 = ZM_mul_i(A22, T4, m2 + 1, n2 + 1, p1 + 1);
     346       11334 :   if (gc_needed(av, 1))
     347           6 :     gerepileall(av, 6, &M2, &M3, &C11, &V1, &M6, &M7);  /* destroy A22, T4 */
     348       11334 :   V3 = add_slices(m1, p2, V1, 0, m1, 0, p2, M3, 0, m2, 0, p2);
     349       11334 :   C12 = add_slices(m1, p2, V3, 0, m1, 0, p2, M6, 0, m1, 0, p2);
     350       11334 :   if (gc_needed(av, 1))
     351          12 :     gerepileall(av, 6, &M2, &M3, &C11, &V1, &M7, &C12);  /* destroy V3, M6 */
     352       11334 :   V2 = add_slices(m2, p1, V1, 0, m2, 0, p1, M2, 0, m2, 0, p2);
     353       11334 :   if (gc_needed(av, 1))
     354           0 :     gerepileall(av, 5, &M3, &C11, &M7, &C12, &V2);  /* destroy V1, M2 */
     355       11334 :   C21 = add_slices(m2, p1, V2, 0, m2, 0, p1, M7, 0, m2, 0, p1);
     356       11334 :   if (gc_needed(av, 1))
     357           0 :     gerepileall(av, 5, &M3, &C11, &C12, &V2, &C21);  /* destroy M7 */
     358       11334 :   C22 = add_slices(m2, p2, V2, 0, m2, 0, p2, M3, 0, m2, 0, p2);
     359       11334 :   if (gc_needed(av, 1))
     360           0 :     gerepileall(av, 4, &C11, &C12, &C21, &C22);  /* destroy V2, M3 */
     361       11334 :   C = mkmat2(mkcol2(C11, C21), mkcol2(C12, C22));
     362       11334 :   return gerepilecopy(av, shallowmatconcat(C));
     363             : }
     364             : 
     365             : /* x[i,]*y. Assume lg(x) > 1 and 0 < i < lgcols(x) */
     366             : static GEN
     367   137328128 : ZMrow_ZC_mul_i(GEN x, GEN y, long i, long lx)
     368             : {
     369   137328128 :   pari_sp av = avma;
     370   137328128 :   GEN c = mulii(gcoeff(x,i,1), gel(y,1)), ZERO = gen_0;
     371             :   long k;
     372  1872479164 :   for (k = 2; k < lx; k++)
     373             :   {
     374  1735151036 :     GEN t = mulii(gcoeff(x,i,k), gel(y,k));
     375  1735151036 :     if (t != ZERO) c = addii(c, t);
     376             :   }
     377   137328128 :   return gerepileuptoint(av, c);
     378             : }
     379             : GEN
     380    25426248 : ZMrow_ZC_mul(GEN x, GEN y, long i)
     381    25426248 : { return ZMrow_ZC_mul_i(x, y, i, lg(x)); }
     382             : 
     383             : /* return x * y, 1 < lx = lg(x), l = lgcols(x) */
     384             : static GEN
     385    21230435 : ZM_ZC_mul_i(GEN x, GEN y, long lx, long l)
     386             : {
     387    21230435 :   GEN z = cgetg(l,t_COL);
     388             :   long i;
     389    21230435 :   for (i=1; i<l; i++) gel(z,i) = ZMrow_ZC_mul_i(x,y,i,lx);
     390    21230435 :   return z;
     391             : }
     392             : 
     393             : static GEN
     394     4820477 : ZM_mul_classical(GEN x, GEN y, long l, long lx, long ly)
     395             : {
     396             :   long j;
     397     4820477 :   GEN z = cgetg(ly, t_MAT);
     398    20716043 :   for (j = 1; j < ly; j++)
     399    15895566 :     gel(z, j) = ZM_ZC_mul_i(x, gel(y, j), lx, l);
     400     4820477 :   return z;
     401             : }
     402             : 
     403             : /* Strassen-Winograd used for dim >= ZM_sw_bound */
     404             : static GEN
     405     4828556 : ZM_mul_i(GEN x, GEN y, long l, long lx, long ly)
     406             : {
     407     4828556 :   long s = maxss(ZM_max_lg_i(x,lx,l), ZM_max_lg_i(y,ly,lx));
     408     4828556 :   long ZM_sw_bound = s > 60 ? 2: s > 25 ? 4: s>15 ? 8 : s > 8 ? 16 : 32;
     409     4828556 :   if (l <= ZM_sw_bound || lx <= ZM_sw_bound || ly <= ZM_sw_bound)
     410     4817229 :     return ZM_mul_classical(x, y, l, lx, ly);
     411             :   else
     412       11327 :     return ZM_mul_sw(x, y, l - 1, lx - 1, ly - 1);
     413             : }
     414             : 
     415             : GEN
     416     4808837 : ZM_mul(GEN x, GEN y)
     417             : {
     418     4808837 :   long lx=lg(x), ly=lg(y);
     419     4808837 :   if (ly==1) return cgetg(1,t_MAT);
     420     4750142 :   if (lx==1) return zeromat(0, ly-1);
     421     4749218 :   return ZM_mul_i(x, y, lgcols(x), lx, ly);
     422             : }
     423             : 
     424             : GEN
     425      272033 : QM_mul(GEN x, GEN y)
     426             : {
     427      272033 :   GEN dx, nx = Q_primitive_part(x, &dx);
     428      272033 :   GEN dy, ny = Q_primitive_part(y, &dy);
     429      272033 :   GEN z = ZM_mul(nx, ny);
     430      272033 :   if (dx || dy)
     431             :   {
     432      215665 :     GEN d = dx ? dy ? gmul(dx, dy): dx : dy;
     433      215665 :     if (!gequal1(d)) z = ZM_Q_mul(z, d);
     434             :   }
     435      272033 :   return z;
     436             : }
     437             : 
     438             : /* assume result is symmetric */
     439             : GEN
     440           0 : ZM_multosym(GEN x, GEN y)
     441             : {
     442           0 :   long j, lx, ly = lg(y);
     443             :   GEN M;
     444           0 :   if (ly == 1) return cgetg(1,t_MAT);
     445           0 :   lx = lg(x); /* = lgcols(y) */
     446           0 :   if (lx == 1) return cgetg(1,t_MAT);
     447             :   /* ly = lgcols(x) */
     448           0 :   M = cgetg(ly, t_MAT);
     449           0 :   for (j=1; j<ly; j++)
     450             :   {
     451           0 :     GEN z = cgetg(ly,t_COL), yj = gel(y,j);
     452             :     long i;
     453           0 :     for (i=1; i<j; i++) gel(z,i) = gcoeff(M,j,i);
     454           0 :     for (i=j; i<ly; i++)gel(z,i) = ZMrow_ZC_mul_i(x,yj,i,lx);
     455           0 :     gel(M,j) = z;
     456             :   }
     457           0 :   return M;
     458             : }
     459             : 
     460             : /* compute m*diagonal(d), assume lg(d) = lg(m). Shallow */
     461             : GEN
     462          14 : ZM_mul_diag(GEN m, GEN d)
     463             : {
     464             :   long j, l;
     465          14 :   GEN y = cgetg_copy(m, &l);
     466          56 :   for (j=1; j<l; j++)
     467             :   {
     468          42 :     GEN c = gel(d,j);
     469          42 :     gel(y,j) = equali1(c)? gel(m,j): ZC_Z_mul(gel(m,j), c);
     470             :   }
     471          14 :   return y;
     472             : }
     473             : /* compute diagonal(d)*m, assume lg(d) = lg(m~). Shallow */
     474             : GEN
     475       85249 : ZM_diag_mul(GEN d, GEN m)
     476             : {
     477       85249 :   long i, j, l = lg(d), lm = lg(m);
     478       85249 :   GEN y = cgetg(lm, t_MAT);
     479       85249 :   for (j=1; j<lm; j++) gel(y,j) = cgetg(l, t_COL);
     480      275777 :   for (i=1; i<l; i++)
     481             :   {
     482      190528 :     GEN c = gel(d,i);
     483      190528 :     if (equali1(c))
     484        9058 :       for (j=1; j<lm; j++) gcoeff(y,i,j) = gcoeff(m,i,j);
     485             :     else
     486      181470 :       for (j=1; j<lm; j++) gcoeff(y,i,j) = mulii(gcoeff(m,i,j), c);
     487             :   }
     488       85249 :   return y;
     489             : }
     490             : 
     491             : /* assume lx > 1 is lg(x) = lg(y) */
     492             : static GEN
     493    12041350 : ZV_dotproduct_i(GEN x, GEN y, long lx)
     494             : {
     495    12041350 :   pari_sp av = avma;
     496    12041350 :   GEN c = mulii(gel(x,1), gel(y,1));
     497             :   long i;
     498    96778976 :   for (i = 2; i < lx; i++)
     499             :   {
     500    84737626 :     GEN t = mulii(gel(x,i), gel(y,i));
     501    84737626 :     if (t != gen_0) c = addii(c, t);
     502             :   }
     503    12041350 :   return gerepileuptoint(av, c);
     504             : }
     505             : 
     506             : /* x~ * y, assuming result is symmetric */
     507             : GEN
     508      160286 : ZM_transmultosym(GEN x, GEN y)
     509             : {
     510      160286 :   long i, j, l, ly = lg(y);
     511             :   GEN M;
     512      160286 :   if (ly == 1) return cgetg(1,t_MAT);
     513             :   /* lg(x) = ly */
     514      160286 :   l = lgcols(y); /* = lgcols(x) */
     515      160286 :   M = cgetg(ly, t_MAT);
     516     1251141 :   for (i=1; i<ly; i++)
     517             :   {
     518     1090855 :     GEN xi = gel(x,i), c = cgetg(ly,t_COL);
     519     1090855 :     gel(M,i) = c;
     520     4913406 :     for (j=1; j<i; j++)
     521     3822551 :       gcoeff(M,i,j) = gel(c,j) = ZV_dotproduct_i(xi,gel(y,j),l);
     522     1090855 :     gel(c,i) = ZV_dotproduct_i(xi,gel(y,i),l);
     523             :   }
     524      160286 :   return M;
     525             : }
     526             : /* x~ * y */
     527             : GEN
     528         497 : ZM_transmul(GEN x, GEN y)
     529             : {
     530         497 :   long i, j, l, lx, ly = lg(y);
     531             :   GEN M;
     532         497 :   if (ly == 1) return cgetg(1,t_MAT);
     533         497 :   lx = lg(x);
     534         497 :   l = lgcols(y);
     535         497 :   if (lgcols(x) != l) pari_err_OP("operation 'ZM_transmul'", x,y);
     536         497 :   M = cgetg(ly, t_MAT);
     537        1617 :   for (i=1; i<ly; i++)
     538             :   {
     539        1120 :     GEN yi = gel(y,i), c = cgetg(lx,t_COL);
     540        1120 :     gel(M,i) = c;
     541        1120 :     for (j=1; j<lx; j++) gel(c,j) = ZV_dotproduct_i(yi,gel(x,j),l);
     542             :   }
     543         497 :   return M;
     544             : }
     545             : 
     546             : static GEN
     547        3255 : ZM_sqr_i(GEN x, long l)
     548             : {
     549        3255 :   long s = ZM_max_lg_i(x,l,l);
     550        3255 :   long ZM_sw_bound = s > 60 ? 2: s > 25 ? 4: s>15 ? 8 : s > 8 ? 16 : 32;
     551        3255 :   if (l <= ZM_sw_bound)
     552        3248 :     return ZM_mul_classical(x, x, l, l, l);
     553             :   else
     554           7 :     return ZM_mul_sw(x, x, l - 1, l - 1, l - 1);
     555             : }
     556             : 
     557             : GEN
     558        3255 : ZM_sqr(GEN x)
     559             : {
     560        3255 :   long lx=lg(x);
     561        3255 :   if (lx==1) return cgetg(1,t_MAT);
     562        3255 :   return ZM_sqr_i(x, lx);
     563             : }
     564             : GEN
     565     5426262 : ZM_ZC_mul(GEN x, GEN y)
     566             : {
     567     5426262 :   long lx = lg(x);
     568     5426262 :   return lx==1? cgetg(1,t_COL): ZM_ZC_mul_i(x, y, lx, lgcols(x));
     569             : }
     570             : 
     571             : GEN
     572      121842 : ZC_Z_div(GEN x, GEN c)
     573             : {
     574             :   long i, l;
     575      121842 :   GEN a = cgetg_copy(x, &l);
     576      121842 :   for (i = 1; i < l; i++) gel(a,i) = Qdivii(gel(x,i), c);
     577      121842 :   return a;
     578             : }
     579             : GEN
     580       12194 : ZM_Z_div(GEN X, GEN c)
     581             : {
     582       12194 :   long j, l = lg(X);
     583       12194 :   GEN A = cgetg(l, t_MAT);
     584       12194 :   for (j = 1; j < l; j++) gel(A,j) = ZC_Z_div(gel(X,j), c);
     585       12194 :   return A;
     586             : }
     587             : 
     588             : GEN
     589     1193172 : ZC_Q_mul(GEN A, GEN z)
     590             : {
     591     1193172 :   pari_sp av = avma;
     592     1193172 :   long i, l = lg(A);
     593             :   GEN d, n, Ad, B, u;
     594     1193172 :   if (typ(z)==t_INT) return ZC_Z_mul(A,z);
     595     1193172 :   n = gel(z, 1); d = gel(z, 2);
     596     1193172 :   Ad = FpC_red(A, d);
     597     1193172 :   u = gcdii(d, FpV_factorback(Ad, NULL, d));
     598     1193172 :   B = cgetg(l, t_COL);
     599     1193172 :   if (equali1(u))
     600             :   {
     601      176602 :     for(i=1; i<l; i++)
     602      143664 :       gel(B, i) = mkfrac(mulii(n, gel(A,i)), d);
     603             :   } else
     604             :   {
     605    11490700 :     for(i=1; i<l; i++)
     606             :     {
     607    10330466 :       GEN di = gcdii(gel(Ad, i), u), ni = mulii(n, diviiexact(gel(A,i), di));
     608    10330466 :       if (equalii(d, di))
     609     7757800 :         gel(B, i) = ni;
     610             :       else
     611     2572666 :         gel(B, i) = mkfrac(ni, diviiexact(d, di));
     612             :     }
     613             :   }
     614     1193172 :   return gerepilecopy(av, B);
     615             : }
     616             : 
     617             : GEN
     618      285046 : ZM_Q_mul(GEN A, GEN z)
     619             : {
     620      285046 :   long i, l = lg(A);
     621             :   GEN B;
     622      285046 :   if (typ(z)==t_INT) return ZM_Z_mul(A,z);
     623      210698 :   B = cgetg(l, t_MAT);
     624     1403870 :   for(i=1; i<l; i++)
     625     1193172 :     gel(B, i) = ZC_Q_mul(gel(A, i), z);
     626      210698 :   return B;
     627             : }
     628             : 
     629             : long
     630   151102651 : zv_dotproduct(GEN x, GEN y)
     631             : {
     632   151102651 :   long i, lx = lg(x);
     633             :   ulong c;
     634   151102651 :   if (lx == 1) return 0;
     635   151102651 :   c = uel(x,1)*uel(y,1);
     636  2329284041 :   for (i = 2; i < lx; i++)
     637  2178181390 :     c += uel(x,i)*uel(y,i);
     638   151102651 :   return c;
     639             : }
     640             : 
     641             : GEN
     642      142702 : ZV_ZM_mul(GEN x, GEN y)
     643             : {
     644      142702 :   long i, lx = lg(x), ly = lg(y);
     645             :   GEN z;
     646      142702 :   if (lx == 1) return zerovec(ly-1);
     647      142688 :   z = cgetg(ly, t_VEC);
     648      142688 :   for (i = 1; i < ly; i++) gel(z,i) = ZV_dotproduct_i(x, gel(y,i), lx);
     649      142688 :   return z;
     650             : }
     651             : 
     652             : GEN
     653           0 : ZC_ZV_mul(GEN x, GEN y)
     654             : {
     655           0 :   long i,j, lx=lg(x), ly=lg(y);
     656             :   GEN z;
     657           0 :   if (ly==1) return cgetg(1,t_MAT);
     658           0 :   z = cgetg(ly,t_MAT);
     659           0 :   for (j=1; j < ly; j++)
     660             :   {
     661           0 :     gel(z,j) = cgetg(lx,t_COL);
     662           0 :     for (i=1; i<lx; i++) gcoeff(z,i,j) = mulii(gel(x,i),gel(y,j));
     663             :   }
     664           0 :   return z;
     665             : }
     666             : 
     667             : GEN
     668     3799356 : ZV_dotsquare(GEN x)
     669             : {
     670             :   long i, lx;
     671             :   pari_sp av;
     672             :   GEN z;
     673     3799356 :   lx = lg(x);
     674     3799356 :   if (lx == 1) return gen_0;
     675     3799356 :   av = avma; z = sqri(gel(x,1));
     676     3799356 :   for (i=2; i<lx; i++) z = addii(z, sqri(gel(x,i)));
     677     3799356 :   return gerepileuptoint(av,z);
     678             : }
     679             : 
     680             : GEN
     681     9360731 : ZV_dotproduct(GEN x,GEN y)
     682             : {
     683             :   long lx;
     684     9360731 :   if (x == y) return ZV_dotsquare(x);
     685     6717863 :   lx = lg(x);
     686     6717863 :   if (lx == 1) return gen_0;
     687     6717863 :   return ZV_dotproduct_i(x, y, lx);
     688             : }
     689             : 
     690             : static GEN
     691         280 : _ZM_mul(void *data /*ignored*/, GEN x, GEN y)
     692         280 : { (void)data; return ZM_mul(x,y); }
     693             : static GEN
     694        2604 : _ZM_sqr(void *data /*ignored*/, GEN x)
     695        2604 : { (void)data; return ZM_sqr(x); }
     696             : GEN
     697           0 : ZM_pow(GEN x, GEN n)
     698             : {
     699           0 :   pari_sp av = avma;
     700           0 :   if (!signe(n)) return matid(lg(x)-1);
     701           0 :   return gerepileupto(av, gen_pow(x, n, NULL, &_ZM_sqr, &_ZM_mul));
     702             : }
     703             : GEN
     704        2170 : ZM_powu(GEN x, ulong n)
     705             : {
     706        2170 :   pari_sp av = avma;
     707        2170 :   if (!n) return matid(lg(x)-1);
     708        2170 :   return gerepileupto(av, gen_powu(x, n, NULL, &_ZM_sqr, &_ZM_mul));
     709             : }
     710             : /********************************************************************/
     711             : /**                                                                **/
     712             : /**                           ADD, SUB                             **/
     713             : /**                                                                **/
     714             : /********************************************************************/
     715             : static GEN
     716    12882807 : ZC_add_i(GEN x, GEN y, long lx)
     717             : {
     718    12882807 :   GEN A = cgetg(lx, t_COL);
     719             :   long i;
     720    12882833 :   for (i=1; i<lx; i++) gel(A,i) = addii(gel(x,i), gel(y,i));
     721    12882810 :   return A;
     722             : }
     723             : GEN
     724     6883076 : ZC_add(GEN x, GEN y) { return ZC_add_i(x, y, lg(x)); }
     725             : GEN
     726      102989 : ZC_Z_add(GEN x, GEN y)
     727             : {
     728      102989 :   long k, lx = lg(x);
     729      102989 :   GEN z = cgetg(lx, t_COL);
     730      102989 :   if (lx == 1) pari_err_TYPE2("+",x,y);
     731      102989 :   gel(z,1) = addii(y,gel(x,1));
     732      102989 :   for (k = 2; k < lx; k++) gel(z,k) = icopy(gel(x,k));
     733      102989 :   return z;
     734             : }
     735             : 
     736             : static GEN
     737     1927544 : ZC_sub_i(GEN x, GEN y, long lx)
     738             : {
     739             :   long i;
     740     1927544 :   GEN A = cgetg(lx, t_COL);
     741     1927544 :   for (i=1; i<lx; i++) gel(A,i) = subii(gel(x,i), gel(y,i));
     742     1927544 :   return A;
     743             : }
     744             : GEN
     745     1193220 : ZC_sub(GEN x, GEN y) { return ZC_sub_i(x, y, lg(x)); }
     746             : GEN
     747           0 : ZC_Z_sub(GEN x, GEN y)
     748             : {
     749           0 :   long k, lx = lg(x);
     750           0 :   GEN z = cgetg(lx, t_COL);
     751           0 :   if (lx == 1) pari_err_TYPE2("+",x,y);
     752           0 :   gel(z,1) = subii(gel(x,1), y);
     753           0 :   for (k = 2; k < lx; k++) gel(z,k) = icopy(gel(x,k));
     754           0 :   return z;
     755             : }
     756             : GEN
     757       94649 : Z_ZC_sub(GEN a, GEN x)
     758             : {
     759       94649 :   long k, lx = lg(x);
     760       94649 :   GEN z = cgetg(lx, t_COL);
     761       94649 :   if (lx == 1) pari_err_TYPE2("-",a,x);
     762       94649 :   gel(z,1) = subii(a, gel(x,1));
     763       94649 :   for (k = 2; k < lx; k++) gel(z,k) = negi(gel(x,k));
     764       94649 :   return z;
     765             : }
     766             : 
     767             : GEN
     768     1097023 : ZM_add(GEN x, GEN y)
     769             : {
     770     1097023 :   long lx = lg(x), l, j;
     771             :   GEN z;
     772     1097023 :   if (lx == 1) return cgetg(1, t_MAT);
     773     1090709 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     774     1090709 :   for (j = 1; j < lx; j++) gel(z,j) = ZC_add_i(gel(x,j), gel(y,j), l);
     775     1090709 :   return z;
     776             : }
     777             : GEN
     778      652225 : ZM_sub(GEN x, GEN y)
     779             : {
     780      652225 :   long lx = lg(x), l, j;
     781             :   GEN z;
     782      652225 :   if (lx == 1) return cgetg(1, t_MAT);
     783      652225 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     784      652225 :   for (j = 1; j < lx; j++) gel(z,j) = ZC_sub_i(gel(x,j), gel(y,j), l);
     785      652225 :   return z;
     786             : }
     787             : /********************************************************************/
     788             : /**                                                                **/
     789             : /**                         LINEAR COMBINATION                     **/
     790             : /**                                                                **/
     791             : /********************************************************************/
     792             : /* return X/c assuming division is exact */
     793             : GEN
     794     2527672 : ZC_Z_divexact(GEN x, GEN c)
     795     2527672 : { pari_APPLY_type(t_COL, diviiexact(gel(x,i), c)) }
     796             : 
     797             : GEN
     798      836772 : ZM_Z_divexact(GEN x, GEN c)
     799      836772 : { pari_APPLY_same(ZC_Z_divexact(gel(x,i), c)) }
     800             : 
     801             : GEN
     802    10485366 : ZC_Z_mul(GEN x, GEN c)
     803             : {
     804    10485366 :   if (!signe(c)) return zerocol(lg(x)-1);
     805    10187237 :   if (is_pm1(c)) return (signe(c) > 0)? ZC_copy(x): ZC_neg(x);
     806     8246724 :   pari_APPLY_type(t_COL, mulii(gel(x,i), c))
     807             : }
     808             : 
     809             : GEN
     810       13958 : ZC_z_mul(GEN x, long c)
     811             : {
     812       13958 :   if (!c) return zerocol(lg(x)-1);
     813        7343 :   if (c == 1) return ZC_copy(x);
     814        2471 :   if (c ==-1) return ZC_neg(x);
     815        1015 :   pari_APPLY_type(t_COL, mulsi(c, gel(x,i)))
     816             : }
     817             : 
     818             : GEN
     819       10372 : zv_z_mul(GEN x, long n)
     820       10372 : { pari_APPLY_long(x[i]*n) }
     821             : 
     822             : /* return a ZM */
     823             : GEN
     824      634746 : nm_Z_mul(GEN X, GEN c)
     825             : {
     826      634746 :   long i, j, h, l = lg(X), s = signe(c);
     827             :   GEN A;
     828      634746 :   if (l == 1) return cgetg(1, t_MAT);
     829      634746 :   h = lgcols(X);
     830      634746 :   if (!s) return zeromat(h-1, l-1);
     831      634746 :   if (is_pm1(c)) {
     832           0 :     if (s > 0) return Flm_to_ZM(X);
     833           0 :     X = Flm_to_ZM(X); ZM_togglesign(X); return X;
     834             :   }
     835      634746 :   A = cgetg(l, t_MAT);
     836     1299065 :   for (j = 1; j < l; j++)
     837             :   {
     838      664319 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     839      664319 :     for (i = 1; i < h; i++) gel(a,i) = muliu(c, x[i]);
     840      664319 :     gel(A,j) = a;
     841             :   }
     842      634746 :   return A;
     843             : }
     844             : GEN
     845      718214 : ZM_Z_mul(GEN X, GEN c)
     846             : {
     847      718214 :   long i, j, h, l = lg(X);
     848             :   GEN A;
     849      718214 :   if (l == 1) return cgetg(1, t_MAT);
     850      703206 :   h = lgcols(X);
     851      703206 :   if (!signe(c)) return zeromat(h-1, l-1);
     852      701792 :   if (is_pm1(c)) return (signe(c) > 0)? ZM_copy(X): ZM_neg(X);
     853      531751 :   A = cgetg(l, t_MAT);
     854     6006246 :   for (j = 1; j < l; j++)
     855             :   {
     856     5474495 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     857     5474495 :     for (i = 1; i < h; i++) gel(a,i) = mulii(c, gel(x,i));
     858     5474495 :     gel(A,j) = a;
     859             :   }
     860      531751 :   return A;
     861             : }
     862             : 
     863             : /* X <- X + v Y (elementary col operation) */
     864             : void
     865    38699277 : ZC_lincomb1_inplace(GEN X, GEN Y, GEN v)
     866             : {
     867    38699277 :   long i, m = lgefint(v);
     868    77398554 :   if (m == 2) return; /* v = 0 */
     869    38699277 :   for (i = lg(X)-1; i; i--) gel(X,i) = addmulii_inplace(gel(X,i), gel(Y,i), v);
     870             : }
     871             : void
     872     8549391 : Flc_lincomb1_inplace(GEN X, GEN Y, ulong v, ulong q)
     873             : {
     874             :   long i;
     875    17098782 :   if (!v) return; /* v = 0 */
     876     8549391 :   for (i = lg(X)-1; i; i--) X[i] = Fl_add(X[i], Fl_mul(Y[i], v, q), q);
     877             : }
     878             : 
     879             : /* X + v Y, wasteful if (v = 0) */
     880             : static GEN
     881     2102548 : ZC_lincomb1(GEN v, GEN x, GEN y)
     882     2102548 : { pari_APPLY_type(t_COL, addmulii(gel(x,i), gel(y,i), v)) }
     883             : 
     884             : /* -X + vY */
     885             : static GEN
     886      382019 : ZC_lincomb_1(GEN v, GEN x, GEN y)
     887      382019 : { pari_APPLY_type(t_COL, mulsubii(gel(y,i), v, gel(x,i))) }
     888             : 
     889             : /* X,Y compatible ZV; u,v in Z. Returns A = u*X + v*Y */
     890             : GEN
     891     9040832 : ZC_lincomb(GEN u, GEN v, GEN X, GEN Y)
     892             : {
     893             :   long su, sv;
     894             :   GEN A;
     895             : 
     896     9040832 :   su = signe(u); if (!su) return ZC_Z_mul(Y, v);
     897     9040636 :   sv = signe(v); if (!sv) return ZC_Z_mul(X, u);
     898     9040412 :   if (is_pm1(v))
     899             :   {
     900     1622236 :     if (is_pm1(u))
     901             :     {
     902     1008801 :       if (su != sv) A = ZC_sub(X, Y);
     903      337008 :       else          A = ZC_add(X, Y);
     904     1008801 :       if (su < 0) ZV_togglesign(A); /* in place but was created above */
     905             :     }
     906             :     else
     907             :     {
     908      613435 :       if (sv > 0) A = ZC_lincomb1 (u, Y, X);
     909      243626 :       else        A = ZC_lincomb_1(u, Y, X);
     910             :     }
     911             :   }
     912     7418176 :   else if (is_pm1(u))
     913             :   {
     914     1871132 :     if (su > 0) A = ZC_lincomb1 (v, X, Y);
     915      138393 :     else        A = ZC_lincomb_1(v, X, Y);
     916             :   }
     917             :   else
     918             :   { /* not cgetg_copy: x may be a t_VEC */
     919     5547044 :     long i, lx = lg(X);
     920     5547044 :     A = cgetg(lx,t_COL);
     921     5547044 :     for (i=1; i<lx; i++) gel(A,i) = lincombii(u,v,gel(X,i),gel(Y,i));
     922             :   }
     923     9040412 :   return A;
     924             : }
     925             : 
     926             : /********************************************************************/
     927             : /**                                                                **/
     928             : /**                           CONVERSIONS                          **/
     929             : /**                                                                **/
     930             : /********************************************************************/
     931             : GEN
     932       46480 : ZV_to_nv(GEN x)
     933       46480 : { pari_APPLY_ulong(itou(gel(x,i))) }
     934             : 
     935             : GEN
     936       25025 : zm_to_ZM(GEN x)
     937       25025 : { pari_APPLY_type(t_MAT, zc_to_ZC(gel(x,i))) }
     938             : 
     939             : GEN
     940          98 : zmV_to_ZMV(GEN x)
     941          98 : { pari_APPLY_type(t_VEC, zm_to_ZM(gel(x,i))) }
     942             : 
     943             : /* same as Flm_to_ZM but do not assume positivity */
     944             : GEN
     945         868 : ZM_to_zm(GEN x)
     946         868 : { pari_APPLY_same(ZV_to_zv(gel(x,i))) }
     947             : 
     948             : GEN
     949      223314 : zv_to_Flv(GEN x, ulong p)
     950      223314 : { pari_APPLY_ulong(umodsu(x[i], p)) }
     951             : 
     952             : GEN
     953       15792 : zm_to_Flm(GEN x, ulong p)
     954       15792 : { pari_APPLY_same(zv_to_Flv(gel(x,i),p)) }
     955             : 
     956             : GEN
     957          21 : ZMV_to_zmV(GEN x)
     958          21 : { pari_APPLY_type(t_VEC, ZM_to_zm(gel(x,i))) }
     959             : 
     960             : /********************************************************************/
     961             : /**                                                                **/
     962             : /**                         COPY, NEGATION                         **/
     963             : /**                                                                **/
     964             : /********************************************************************/
     965             : GEN
     966     3753874 : ZC_copy(GEN x)
     967             : {
     968     3753874 :   long i, lx = lg(x);
     969     3753874 :   GEN y = cgetg(lx, t_COL);
     970    31726329 :   for (i=1; i<lx; i++)
     971             :   {
     972    27972455 :     GEN c = gel(x,i);
     973    27972455 :     gel(y,i) = lgefint(c) == 2? gen_0: icopy(c);
     974             :   }
     975     3753874 :   return y;
     976             : }
     977             : 
     978             : GEN
     979      208576 : ZM_copy(GEN x)
     980      208576 : { pari_APPLY_same(ZC_copy(gel(x,i))) }
     981             : 
     982             : void
     983      125768 : ZV_neg_inplace(GEN M)
     984             : {
     985      125768 :   long l = lg(M);
     986      125768 :   while (--l > 0) gel(M,l) = negi(gel(M,l));
     987      125768 : }
     988             : GEN
     989     1763289 : ZC_neg(GEN x)
     990     1763289 : { pari_APPLY_type(t_COL, negi(gel(x,i))) }
     991             : GEN
     992       23332 : zv_neg(GEN x)
     993       23332 : { pari_APPLY_long(-x[i]) }
     994             : GEN
     995         261 : zv_neg_inplace(GEN M)
     996             : {
     997         261 :   long l = lg(M);
     998         261 :   while (--l > 0) M[l] = -M[l];
     999         261 :   return M;
    1000             : }
    1001             : GEN
    1002      257383 : ZM_neg(GEN x)
    1003      257383 : { pari_APPLY_same(ZC_neg(gel(x,i))) }
    1004             : 
    1005             : void
    1006     1391100 : ZV_togglesign(GEN M)
    1007             : {
    1008     1391100 :   long l = lg(M);
    1009     1391100 :   while (--l > 0) togglesign_safe(&gel(M,l));
    1010     1391100 : }
    1011             : void
    1012           0 : ZM_togglesign(GEN M)
    1013             : {
    1014           0 :   long l = lg(M);
    1015           0 :   while (--l > 0) ZV_togglesign(gel(M,l));
    1016           0 : }
    1017             : 
    1018             : /********************************************************************/
    1019             : /**                                                                **/
    1020             : /**                        "DIVISION" mod HNF                      **/
    1021             : /**                                                                **/
    1022             : /********************************************************************/
    1023             : /* Reduce ZC x modulo ZM y in HNF, may return x itself (not a copy) */
    1024             : GEN
    1025      852126 : ZC_hnfremdiv(GEN x, GEN y, GEN *Q)
    1026             : {
    1027      852126 :   long i, l = lg(x);
    1028             :   GEN q;
    1029             : 
    1030      852126 :   if (Q) *Q = cgetg(l,t_COL);
    1031      852126 :   if (l == 1) return cgetg(1,t_COL);
    1032     5054702 :   for (i = l-1; i>0; i--)
    1033             :   {
    1034     4202576 :     q = diviiround(gel(x,i), gcoeff(y,i,i));
    1035     4202576 :     if (signe(q)) {
    1036     2272457 :       togglesign(q);
    1037     2272457 :       x = ZC_lincomb(gen_1, q, x, gel(y,i));
    1038             :     }
    1039     4202576 :     if (Q) gel(*Q, i) = q;
    1040             :   }
    1041      852126 :   return x;
    1042             : }
    1043             : 
    1044             : /* x = y Q + R, may return some columns of x (not copies) */
    1045             : GEN
    1046       51547 : ZM_hnfdivrem(GEN x, GEN y, GEN *Q)
    1047             : {
    1048       51547 :   long lx = lg(x), i;
    1049       51547 :   GEN R = cgetg(lx, t_MAT);
    1050       51547 :   if (Q)
    1051             :   {
    1052       15936 :     GEN q = cgetg(lx, t_MAT); *Q = q;
    1053       15936 :     for (i=1; i<lx; i++) gel(R,i) = ZC_hnfremdiv(gel(x,i),y,(GEN*)(q+i));
    1054             :   }
    1055             :   else
    1056      121140 :     for (i=1; i<lx; i++)
    1057             :     {
    1058       85529 :       pari_sp av = avma;
    1059       85529 :       GEN z = ZC_hnfrem(gel(x,i),y);
    1060       85529 :       gel(R,i) = (avma == av)? ZC_copy(z): gerepileupto(av, z);
    1061             :     }
    1062       51547 :   return R;
    1063             : }
    1064             : 
    1065             : 
    1066             : /********************************************************************/
    1067             : /**                                                                **/
    1068             : /**                               TESTS                            **/
    1069             : /**                                                                **/
    1070             : /********************************************************************/
    1071             : int
    1072    17351054 : zv_equal0(GEN V)
    1073             : {
    1074    17351054 :   long l = lg(V);
    1075    45111374 :   while (--l > 0)
    1076    22457421 :     if (V[l]) return 0;
    1077     5302899 :   return 1;
    1078             : }
    1079             : 
    1080             : int
    1081      842732 : ZV_equal0(GEN V)
    1082             : {
    1083      842732 :   long l = lg(V);
    1084     3395260 :   while (--l > 0)
    1085     2363084 :     if (signe(gel(V,l))) return 0;
    1086      189444 :   return 1;
    1087             : }
    1088             : 
    1089             : static int
    1090     9157374 : ZV_equal_lg(GEN V, GEN W, long l)
    1091             : {
    1092    26229786 :   while (--l > 0)
    1093    15063439 :     if (!equalii(gel(V,l), gel(W,l))) return 0;
    1094     2008973 :   return 1;
    1095             : }
    1096             : int
    1097     7927447 : ZV_equal(GEN V, GEN W)
    1098             : {
    1099     7927447 :   long l = lg(V);
    1100     7927447 :   if (lg(W) != l) return 0;
    1101     7927447 :   return ZV_equal_lg(V, W, l);
    1102             : }
    1103             : int
    1104      399331 : ZM_equal(GEN A, GEN B)
    1105             : {
    1106      399331 :   long i, m, l = lg(A);
    1107      399331 :   if (lg(B) != l) return 0;
    1108      398932 :   if (l == 1) return 1;
    1109      398932 :   m = lgcols(A);
    1110      398932 :   if (lgcols(B) != m) return 0;
    1111     1556878 :   for (i = 1; i < l; i++)
    1112     1229927 :     if (!ZV_equal_lg(gel(A,i), gel(B,i), m)) return 0;
    1113      326951 :   return 1;
    1114             : }
    1115             : int
    1116    20958818 : zv_equal(GEN V, GEN W)
    1117             : {
    1118    20958818 :   long l = lg(V);
    1119    20958818 :   if (lg(W) != l) return 0;
    1120   199166255 :   while (--l > 0)
    1121   158022322 :     if (V[l] != W[l]) return 0;
    1122    20546945 :   return 1;
    1123             : }
    1124             : 
    1125             : int
    1126         385 : zvV_equal(GEN V, GEN W)
    1127             : {
    1128         385 :   long l = lg(V);
    1129         385 :   if (lg(W) != l) return 0;
    1130       58982 :   while (--l > 0)
    1131       58373 :     if (!zv_equal(gel(V,l),gel(W,l))) return 0;
    1132         231 :   return 1;
    1133             : }
    1134             : 
    1135             : int
    1136      114457 : ZM_ishnf(GEN x)
    1137             : {
    1138      114457 :   long i,j, lx = lg(x);
    1139      363440 :   for (i=1; i<lx; i++)
    1140             :   {
    1141      275653 :     GEN xii = gcoeff(x,i,i);
    1142      275653 :     if (signe(xii) <= 0) return 0;
    1143      674113 :     for (j=1; j<i; j++)
    1144      411809 :       if (signe(gcoeff(x,i,j))) return 0;
    1145      716155 :     for (j=i+1; j<lx; j++)
    1146             :     {
    1147      467172 :       GEN xij = gcoeff(x,i,j);
    1148      467172 :       if (signe(xij)<0 || cmpii(xij,xii)>=0) return 0;
    1149             :     }
    1150             :   }
    1151       87787 :   return 1;
    1152             : }
    1153             : int
    1154      179928 : ZM_isidentity(GEN x)
    1155             : {
    1156      179928 :   long i,j, lx = lg(x);
    1157             : 
    1158      179928 :   if (lx == 1) return 1;
    1159      179928 :   if (lx != lgcols(x)) return 0;
    1160      411082 :   for (j=1; j<lx; j++)
    1161             :   {
    1162      383481 :     GEN c = gel(x,j);
    1163     1179703 :     for (i=1; i<j; )
    1164      521227 :       if (signe(gel(c,i++))) return 0;
    1165             :     /* i = j */
    1166      274995 :       if (!equali1(gel(c,i++))) return 0;
    1167      986027 :     for (   ; i<lx; )
    1168      522473 :       if (signe(gel(c,i++))) return 0;
    1169             :   }
    1170       27601 :   return 1;
    1171             : }
    1172             : int
    1173       60170 : ZM_isdiagonal(GEN x)
    1174             : {
    1175       60170 :   long i,j, lx = lg(x);
    1176       60170 :   if (lx == 1) return 1;
    1177       60170 :   if (lx != lgcols(x)) return 0;
    1178             : 
    1179      186566 :   for (j=1; j<lx; j++)
    1180             :   {
    1181      162007 :     GEN c = gel(x,j);
    1182      356697 :     for (i=1; i<j; i++)
    1183      230294 :       if (signe(gel(c,i))) return 0;
    1184      520215 :     for (i++; i<lx; i++)
    1185      393819 :       if (signe(gel(c,i))) return 0;
    1186             :   }
    1187       24559 :   return 1;
    1188             : }
    1189             : int
    1190        4105 : ZM_isscalar(GEN x, GEN s)
    1191             : {
    1192        4105 :   long i, j, lx = lg(x);
    1193             : 
    1194        4105 :   if (lx == 1) return 1;
    1195        4105 :   if (!s) s = gcoeff(x,1,1);
    1196        4105 :   if (equali1(s)) return ZM_isidentity(x);
    1197        3510 :   if (lx != lgcols(x)) return 0;
    1198       25915 :   for (j=1; j<lx; j++)
    1199             :   {
    1200       22422 :     GEN c = gel(x,j);
    1201      282123 :     for (i=1; i<j; )
    1202      237290 :       if (signe(gel(c,i++))) return 0;
    1203             :     /* i = j */
    1204       22411 :       if (!equalii(gel(c,i++), s)) return 0;
    1205      282392 :     for (   ; i<lx; )
    1206      237580 :       if (signe(gel(c,i++))) return 0;
    1207             :   }
    1208        3493 :   return 1;
    1209             : }
    1210             : 
    1211             : long
    1212       59241 : ZC_is_ei(GEN x)
    1213             : {
    1214       59241 :   long i, j = 0, l = lg(x);
    1215      554953 :   for (i = 1; i < l; i++)
    1216             :   {
    1217      495712 :     GEN c = gel(x,i);
    1218      495712 :     long s = signe(c);
    1219      495712 :     if (!s) continue;
    1220       59227 :     if (s < 0 || !is_pm1(c) || j) return 0;
    1221       59227 :     j = i;
    1222             :   }
    1223       59241 :   return j;
    1224             : }
    1225             : 
    1226             : /********************************************************************/
    1227             : /**                                                                **/
    1228             : /**                       MISCELLANEOUS                            **/
    1229             : /**                                                                **/
    1230             : /********************************************************************/
    1231             : /* assume lg(x) = lg(y), x,y in Z^n */
    1232             : int
    1233      660185 : ZV_cmp(GEN x, GEN y)
    1234             : {
    1235      660185 :   long fl,i, lx = lg(x);
    1236     1319201 :   for (i=1; i<lx; i++)
    1237     1061369 :     if (( fl = cmpii(gel(x,i), gel(y,i)) )) return fl;
    1238      257832 :   return 0;
    1239             : }
    1240             : /* assume lg(x) = lg(y), x,y in Z^n */
    1241             : int
    1242        3550 : ZV_abscmp(GEN x, GEN y)
    1243             : {
    1244        3550 :   long fl,i, lx = lg(x);
    1245       19587 :   for (i=1; i<lx; i++)
    1246       19507 :     if (( fl = abscmpii(gel(x,i), gel(y,i)) )) return fl;
    1247          80 :   return 0;
    1248             : }
    1249             : 
    1250             : long
    1251     1015230 : zv_content(GEN x)
    1252             : {
    1253     1015230 :   long i, s, l = lg(x);
    1254     1015230 :   if (l == 1) return 0;
    1255     1015223 :   s = labs(x[1]);
    1256     1015223 :   for (i=2; i<l && s!=1; i++) s = cgcd(x[i],s);
    1257     1015223 :   return s;
    1258             : }
    1259             : GEN
    1260      154987 : ZV_content(GEN x)
    1261             : {
    1262      154987 :   long i, l = lg(x);
    1263      154987 :   pari_sp av = avma;
    1264             :   GEN c;
    1265      154987 :   if (l == 1) return gen_0;
    1266      154987 :   if (l == 2) return absi(gel(x,1));
    1267      119910 :   c = gel(x,1);
    1268      296513 :   for (i = 2; i < l; i++)
    1269             :   {
    1270      206906 :     c = gcdii(c, gel(x,i));
    1271      206906 :     if (is_pm1(c)) { avma = av; return gen_1; }
    1272             :   }
    1273       89607 :   return gerepileuptoint(av, c);
    1274             : }
    1275             : 
    1276             : GEN
    1277      978448 : ZM_det_triangular(GEN mat)
    1278             : {
    1279             :   pari_sp av;
    1280      978448 :   long i,l = lg(mat);
    1281             :   GEN s;
    1282             : 
    1283      978448 :   if (l<3) return l<2? gen_1: icopy(gcoeff(mat,1,1));
    1284      898666 :   av = avma; s = gcoeff(mat,1,1);
    1285      898666 :   for (i=2; i<l; i++) s = mulii(s,gcoeff(mat,i,i));
    1286      898666 :   return gerepileuptoint(av,s);
    1287             : }
    1288             : 
    1289             : /* assumes no overflow */
    1290             : long
    1291      362530 : zv_prod(GEN v)
    1292             : {
    1293      362530 :   long n, i, l = lg(v);
    1294      362530 :   if (l == 1) return 1;
    1295      269710 :   n = v[1]; for (i = 2; i < l; i++) n *= v[i];
    1296      269710 :   return n;
    1297             : }
    1298             : 
    1299             : static GEN
    1300   272803985 : _mulii(void *E, GEN a, GEN b)
    1301   272803985 : { (void) E; return mulii(a, b); }
    1302             : 
    1303             : /* product of ulongs */
    1304             : GEN
    1305      364884 : zv_prod_Z(GEN v)
    1306             : {
    1307      364884 :   pari_sp av = avma;
    1308      364884 :   long k, m, n = lg(v)-1;
    1309             :   GEN V;
    1310      364884 :   switch(n) {
    1311       19509 :     case 0: return gen_1;
    1312       56553 :     case 1: return utoi(v[1]);
    1313      125426 :     case 2: return muluu(v[1], v[2]);
    1314             :   }
    1315      163396 :   m = n >> 1;
    1316      163396 :   V = cgetg(m + (odd(n)? 2: 1), t_VEC);
    1317      163396 :   for (k = 1; k <= m; k++) gel(V,k) = muluu(v[k<<1], v[(k<<1)-1]);
    1318      163396 :   if (odd(n)) gel(V,k) = utoipos(v[n]);
    1319      163396 :   return gerepileuptoint(av, gen_product(V, NULL, &_mulii));
    1320             : }
    1321             : GEN
    1322    14694393 : vecsmall_prod(GEN v)
    1323             : {
    1324    14694393 :   pari_sp av = avma;
    1325    14694393 :   long k, m, n = lg(v)-1;
    1326             :   GEN V;
    1327    14694393 :   switch (n) {
    1328           0 :     case 0: return gen_1;
    1329           0 :     case 1: return stoi(v[1]);
    1330          21 :     case 2: return mulss(v[1], v[2]);
    1331             :   }
    1332    14694372 :   m = n >> 1;
    1333    14694372 :   V = cgetg(m + (odd(n)? 2: 1), t_VEC);
    1334    14694372 :   for (k = 1; k <= m; k++) gel(V,k) = mulss(v[k<<1], v[(k<<1)-1]);
    1335    14694372 :   if (odd(n)) gel(V,k) = stoi(v[n]);
    1336    14694372 :   return gerepileuptoint(av, gen_product(V, NULL, &_mulii));
    1337             : }
    1338             : 
    1339             : GEN
    1340     7475294 : ZV_prod(GEN v)
    1341             : {
    1342     7475294 :   pari_sp av = avma;
    1343     7475294 :   long i, l = lg(v);
    1344             :   GEN n;
    1345     7475294 :   if (l == 1) return gen_1;
    1346     7465991 :   if (l > 7) return gerepileuptoint(av, gen_product(v, NULL, _mulii));
    1347      117065 :   n = gel(v,1);
    1348      117065 :   if (l == 2) return icopy(n);
    1349       63102 :   for (i = 2; i < l; i++) n = mulii(n, gel(v,i));
    1350       63102 :   return gerepileuptoint(av, n);
    1351             : }
    1352             : /* assumes no overflow */
    1353             : long
    1354        1596 : zv_sum(GEN v)
    1355             : {
    1356        1596 :   long n, i, l = lg(v);
    1357        1596 :   if (l == 1) return 0;
    1358        1575 :   n = v[1]; for (i = 2; i < l; i++) n += v[i];
    1359        1575 :   return n;
    1360             : }
    1361             : GEN
    1362          56 : ZV_sum(GEN v)
    1363             : {
    1364          56 :   pari_sp av = avma;
    1365          56 :   long i, l = lg(v);
    1366             :   GEN n;
    1367          56 :   if (l == 1) return gen_0;
    1368          56 :   n = gel(v,1);
    1369          56 :   if (l == 2) return icopy(n);
    1370          56 :   for (i = 2; i < l; i++) n = addii(n, gel(v,i));
    1371          56 :   return gerepileuptoint(av, n);
    1372             : }
    1373             : 
    1374             : /********************************************************************/
    1375             : /**                                                                **/
    1376             : /**         GRAM SCHMIDT REDUCTION (integer matrices)              **/
    1377             : /**                                                                **/
    1378             : /********************************************************************/
    1379             : 
    1380             : /* L[k,] += q * L[l,], l < k. Inefficient if q = 0 */
    1381             : static void
    1382       52048 : Zupdate_row(long k, long l, GEN q, GEN L, GEN B)
    1383             : {
    1384       52048 :   long i, qq = itos_or_0(q);
    1385       52048 :   if (!qq)
    1386             :   {
    1387        2662 :     for(i=1;i<l;i++)  gcoeff(L,k,i) = addii(gcoeff(L,k,i),mulii(q,gcoeff(L,l,i)));
    1388        2662 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), mulii(q,B));
    1389       54710 :     return;
    1390             :   }
    1391       49386 :   if (qq == 1) {
    1392       13664 :     for (i=1;i<l; i++) gcoeff(L,k,i) = addii(gcoeff(L,k,i),gcoeff(L,l,i));
    1393       13664 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), B);
    1394       35722 :   } else if (qq == -1) {
    1395       10897 :     for (i=1;i<l; i++) gcoeff(L,k,i) = subii(gcoeff(L,k,i),gcoeff(L,l,i));
    1396       10897 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), negi(B));
    1397             :   } else {
    1398       24825 :     for(i=1;i<l;i++) gcoeff(L,k,i) = addii(gcoeff(L,k,i),mulsi(qq,gcoeff(L,l,i)));
    1399       24825 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), mulsi(qq,B));
    1400             :   }
    1401             : }
    1402             : 
    1403             : /* update L[k,] */
    1404             : static void
    1405      245816 : ZRED(long k, long l, GEN x, GEN L, GEN B)
    1406             : {
    1407      245816 :   GEN q = truedivii(addii(B,shifti(gcoeff(L,k,l),1)), shifti(B,1));
    1408      491632 :   if (!signe(q)) return;
    1409       52048 :   q = negi(q);
    1410       52048 :   Zupdate_row(k,l,q,L,B);
    1411       52048 :   gel(x,k) = ZC_lincomb(gen_1, q, gel(x,k), gel(x,l));
    1412             : }
    1413             : 
    1414             : /* Gram-Schmidt reduction, x a ZM */
    1415             : static void
    1416      311919 : ZincrementalGS(GEN x, GEN L, GEN B, long k)
    1417             : {
    1418             :   long i, j;
    1419     1109028 :   for (j=1; j<=k; j++)
    1420             :   {
    1421      797109 :     pari_sp av = avma;
    1422      797109 :     GEN u = ZV_dotproduct(gel(x,k), gel(x,j));
    1423     1776781 :     for (i=1; i<j; i++)
    1424             :     {
    1425      979672 :       u = subii(mulii(gel(B,i+1), u), mulii(gcoeff(L,k,i), gcoeff(L,j,i)));
    1426      979672 :       u = diviiexact(u, gel(B,i));
    1427             :     }
    1428      797109 :     gcoeff(L,k,j) = gerepileuptoint(av, u);
    1429             :   }
    1430      311919 :   gel(B,k+1) = gcoeff(L,k,k); gcoeff(L,k,k) = gen_1;
    1431      311919 : }
    1432             : 
    1433             : /* Variant reducemodinvertible(ZC v, ZM y), when y singular.
    1434             :  * Very inefficient if y is not LLL-reduced of maximal rank */
    1435             : static GEN
    1436       62512 : ZC_reducemodmatrix_i(GEN v, GEN y)
    1437             : {
    1438       62512 :   GEN B, L, x = shallowconcat(y, v);
    1439       62512 :   long k, lx = lg(x), nx = lx-1;
    1440             : 
    1441       62512 :   B = scalarcol_shallow(gen_1, lx);
    1442       62512 :   L = zeromatcopy(nx, nx);
    1443       62512 :   for (k=1; k <= nx; k++) ZincrementalGS(x, L, B, k);
    1444       62512 :   for (k = nx-1; k >= 1; k--) ZRED(nx,k, x,L,gel(B,k+1));
    1445       62512 :   return gel(x,nx);
    1446             : }
    1447             : GEN
    1448       62512 : ZC_reducemodmatrix(GEN v, GEN y) {
    1449       62512 :   pari_sp av = avma;
    1450       62512 :   return gerepilecopy(av, ZC_reducemodmatrix_i(v,y));
    1451             : }
    1452             : 
    1453             : /* Variant reducemodinvertible(ZM v, ZM y), when y singular.
    1454             :  * Very inefficient if y is not LLL-reduced of maximal rank */
    1455             : static GEN
    1456       21280 : ZM_reducemodmatrix_i(GEN v, GEN y)
    1457             : {
    1458             :   GEN B, L, V;
    1459       21280 :   long j, k, lv = lg(v), nx = lg(y), lx = nx+1;
    1460             : 
    1461       21280 :   V = cgetg(lv, t_MAT);
    1462       21280 :   B = scalarcol_shallow(gen_1, lx);
    1463       21280 :   L = zeromatcopy(nx, nx);
    1464       21280 :   for (k=1; k < nx; k++) ZincrementalGS(y, L, B, k);
    1465       61551 :   for (j = 1; j < lg(v); j++)
    1466             :   {
    1467       40271 :     GEN x = shallowconcat(y, gel(v,j));
    1468       40271 :     ZincrementalGS(x, L, B, nx); /* overwrite last */
    1469       40271 :     for (k = nx-1; k >= 1; k--) ZRED(nx,k, x,L,gel(B,k+1));
    1470       40271 :     gel(V,j) = gel(x,nx);
    1471             :   }
    1472       21280 :   return V;
    1473             : }
    1474             : GEN
    1475       21280 : ZM_reducemodmatrix(GEN v, GEN y) {
    1476       21280 :   pari_sp av = avma;
    1477       21280 :   return gerepilecopy(av, ZM_reducemodmatrix_i(v,y));
    1478             : }
    1479             : 
    1480             : GEN
    1481        9907 : ZC_reducemodlll(GEN x,GEN y)
    1482             : {
    1483        9907 :   pari_sp av = avma;
    1484        9907 :   GEN z = ZC_reducemodmatrix(x, ZM_lll(y, 0.75, LLL_INPLACE));
    1485        9907 :   return gerepilecopy(av, z);
    1486             : }
    1487             : GEN
    1488           0 : ZM_reducemodlll(GEN x,GEN y)
    1489             : {
    1490           0 :   pari_sp av = avma;
    1491           0 :   GEN z = ZM_reducemodmatrix(x, ZM_lll(y, 0.75, LLL_INPLACE));
    1492           0 :   return gerepilecopy(av, z);
    1493             : }

Generated by: LCOV version 1.11