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 21203-392a176) Lines: 772 847 91.1 %
Date: 2017-10-23 06:23:29 Functions: 110 116 94.8 %
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     1198395 : check_ZV(GEN x, long l)
      19             : {
      20             :   long i;
      21     8050619 :   for (i=1; i<l; i++)
      22     6852308 :     if (typ(gel(x,i)) != t_INT) return 0;
      23     1198311 :   return 1;
      24             : }
      25             : void
      26      505737 : RgV_check_ZV(GEN A, const char *s)
      27             : {
      28      505737 :   if (!RgV_is_ZV(A)) pari_err_TYPE(stack_strcat(s," [integer vector]"), A);
      29      505730 : }
      30             : void
      31      308597 : RgM_check_ZM(GEN A, const char *s)
      32             : {
      33      308597 :   long n = lg(A);
      34      308597 :   if (n != 1)
      35             :   {
      36      308562 :     long j, m = lgcols(A);
      37     1506873 :     for (j=1; j<n; j++)
      38     1198395 :       if (!check_ZV(gel(A,j), m))
      39          84 :         pari_err_TYPE(stack_strcat(s," [integer matrix]"), A);
      40             :   }
      41      308513 : }
      42             : 
      43             : static long
      44    31033216 : ZV_max_lg_i(GEN x, long m)
      45             : {
      46    31033216 :   long i, prec = 2;
      47    31033216 :   for (i=1; i<m; i++) { long l = lgefint(gel(x,i)); if (l > prec) prec = l; }
      48    31033216 :   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     9314207 : ZM_max_lg_i(GEN x, long n, long m)
      57             : {
      58     9314207 :   long prec = 2;
      59     9314207 :   if (n != 1)
      60             :   {
      61             :     long j;
      62    40336811 :     for (j=1; j<n; j++)
      63             :     {
      64    31022604 :       long l = ZV_max_lg_i(gel(x,j), m);
      65    31022604 :       if (l > prec) prec = l;
      66             :     }
      67             :   }
      68     9314207 :   return prec;
      69             : }
      70             : 
      71             : long
      72        3201 : ZM_max_lg(GEN x)
      73             : {
      74        3201 :   long n = lg(x);
      75        3201 :   if (n==1) return 2;
      76        3201 :   return ZM_max_lg_i(x, n, lgcols(x));
      77             : }
      78             : 
      79             : GEN
      80        2961 : ZM_supnorm(GEN x)
      81             : {
      82        2961 :   long i, j, h, lx = lg(x);
      83        2961 :   GEN s = gen_0;
      84        2961 :   if (lx == 1) return gen_1;
      85        2961 :   h = lgcols(x);
      86       18298 :   for (j=1; j<lx; j++)
      87             :   {
      88       15337 :     GEN xj = gel(x,j);
      89      224280 :     for (i=1; i<h; i++)
      90             :     {
      91      208943 :       GEN c = gel(xj,i);
      92      208943 :       if (abscmpii(c, s) > 0) s = c;
      93             :     }
      94             :   }
      95        2961 :   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      663666 : ZM_nc_mul_i(GEN x, GEN y, long c, long l)
     106             : {
     107             :   long i, j;
     108             :   pari_sp av;
     109      663666 :   GEN z = cgetg(l,t_COL), s;
     110             : 
     111     5999476 :   for (i=1; i<l; i++)
     112             :   {
     113     5335810 :     av = avma; s = muliu(gcoeff(x,i,1),y[1]);
     114   177713172 :     for (j=2; j<c; j++)
     115   172377362 :       if (y[j]) s = addii(s, muliu(gcoeff(x,i,j),y[j]));
     116     5335810 :     gel(z,i) = gerepileuptoint(av,s);
     117             :   }
     118      663666 :   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     2811202 : ZM_zc_mul_i(GEN x, GEN y, long c, long l)
     136             : {
     137             :   long i, j;
     138     2811202 :   GEN z = cgetg(l,t_COL);
     139             : 
     140    17134298 :   for (i=1; i<l; i++)
     141             :   {
     142    14323096 :     pari_sp av = avma;
     143    14323096 :     GEN s = mulis(gcoeff(x,i,1),y[1]);
     144   253188888 :     for (j=2; j<c; j++)
     145   238865792 :       if (y[j]) s = addii(s, mulis(gcoeff(x,i,j),y[j]));
     146    14323096 :     gel(z,i) = gerepileuptoint(av,s);
     147             :   }
     148     2811202 :   return z;
     149             : }
     150             : GEN
     151     1603558 : ZM_zc_mul(GEN x, GEN y) {
     152     1603558 :   long l = lg(x);
     153     1603558 :   if (l == 1) return cgetg(1, t_COL);
     154     1603558 :   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      587741 : ZM_zm_mul(GEN x, GEN y)
     178             : {
     179      587741 :   long j, c, l = lg(x), ly = lg(y);
     180      587741 :   GEN z = cgetg(ly, t_MAT);
     181      587741 :   if (l == 1) return z;
     182      587741 :   c = lgcols(x);
     183      587741 :   for (j = 1; j < ly; j++) gel(z,j) = ZM_zc_mul_i(x, gel(y,j), l,c);
     184      587741 :   return z;
     185             : }
     186             : /* x ZM, y a compatible zn (dimension > 0). */
     187             : GEN
     188      634495 : ZM_nm_mul(GEN x, GEN y)
     189             : {
     190      634495 :   long j, c, l = lg(x), ly = lg(y);
     191      634495 :   GEN z = cgetg(ly, t_MAT);
     192      634495 :   if (l == 1) return z;
     193      634495 :   c = lgcols(x);
     194      634495 :   for (j = 1; j < ly; j++) gel(z,j) = ZM_nc_mul_i(x, gel(y,j), l,c);
     195      634495 :   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       87984 : 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       87984 :   long min_d = minss(da, db), min_e = minss(ea, eb), i, j;
     210       87984 :   GEN M = cgetg(n + 1, t_MAT), C;
     211             : 
     212     1757074 :   for (j = 1; j <= min_e; j++) {
     213     1669090 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     214    44057012 :     for (i = 1; i <= min_d; i++)
     215    84775844 :       gel(C, i) = addii(gcoeff(A, ma + i, na + j),
     216    42387922 :                         gcoeff(B, mb + i, nb + j));
     217     1795514 :     for (; i <= da; i++)
     218      126424 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     219     1669090 :     for (; i <= db; i++)
     220           0 :       gel(C, i) = gcoeff(B, mb + i, nb + j);
     221     1669090 :     for (; i <= m; i++)
     222           0 :       gel(C, i) = gen_0;
     223             :   }
     224      101345 :   for (; j <= ea; j++) {
     225       13361 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     226      269794 :     for (i = 1; i <= da; i++)
     227      256433 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     228       13361 :     for (; i <= m; i++)
     229           0 :       gel(C, i) = gen_0;
     230             :   }
     231       87984 :   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       87984 :   for (; j <= n; j++)
     239           0 :     gel(M, j) = zerocol(m);
     240       87984 :   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       76986 : 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       76986 :   long min_d = minss(da, db), min_e = minss(ea, eb), i, j;
     253       76986 :   GEN M = cgetg(n + 1, t_MAT), C;
     254             : 
     255     1694859 :   for (j = 1; j <= min_e; j++) {
     256     1617873 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     257    47534141 :     for (i = 1; i <= min_d; i++)
     258    91832536 :       gel(C, i) = subii(gcoeff(A, ma + i, na + j),
     259    45916268 :                         gcoeff(B, mb + i, nb + j));
     260     1740497 :     for (; i <= da; i++)
     261      122624 :       gel(C, i) = gcoeff(A, ma + i, na + j);
     262     1802967 :     for (; i <= db; i++)
     263      185094 :       gel(C, i) = negi(gcoeff(B, mb + i, nb + j));
     264     1617873 :     for (; i <= m; i++)
     265           0 :       gel(C, i) = gen_0;
     266             :   }
     267       76986 :   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       83992 :   for (; j <= eb; j++) {
     275        7006 :     gel(M, j) = C = cgetg(m + 1, t_COL);
     276      194305 :     for (i = 1; i <= db; i++)
     277      187299 :       gel(C, i) = negi(gcoeff(B, mb + i, nb + j));
     278        7006 :     for (; i <= m; i++)
     279           0 :       gel(C, i) = gen_0;
     280             :   }
     281       83992 :   for (; j <= n; j++)
     282        7006 :     gel(M, j) = zerocol(m);
     283       76986 :   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       10998 : ZM_mul_sw(GEN A, GEN B, long m, long n, long p)
     291             : {
     292       10998 :   pari_sp av = avma;
     293       10998 :   long m1 = (m + 1)/2, m2 = m/2,
     294       10998 :     n1 = (n + 1)/2, n2 = n/2,
     295       10998 :     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       10998 :   T2 = subtract_slices(n1, p2, B, 0, n1, p1, p2, B, n1, n2, p1, p2);
     302       10998 :   S1 = subtract_slices(m2, n1, A, m1, m2, 0, n1, A, 0, m2, 0, n1);
     303       10998 :   M2 = ZM_mul_i(S1, T2, m2 + 1, n1 + 1, p2 + 1);
     304       10998 :   if (gc_needed(av, 1))
     305           0 :     gerepileall(av, 2, &T2, &M2);  /* destroy S1 */
     306       10998 :   T3 = subtract_slices(n1, p1, T2, 0, n1, 0, p2, B, 0, n1, 0, p1);
     307       10998 :   if (gc_needed(av, 1))
     308           0 :     gerepileall(av, 2, &M2, &T3);  /* destroy T2 */
     309       10998 :   S2 = add_slices(m2, n1, A, m1, m2, 0, n1, A, m1, m2, n1, n2);
     310       10998 :   T1 = subtract_slices(n1, p1, B, 0, n1, p1, p2, B, 0, n1, 0, p2);
     311       10998 :   M3 = ZM_mul_i(S2, T1, m2 + 1, n1 + 1, p2 + 1);
     312       10998 :   if (gc_needed(av, 1))
     313           0 :     gerepileall(av, 4, &M2, &T3, &S2, &M3);  /* destroy T1 */
     314       10998 :   S3 = subtract_slices(m1, n1, S2, 0, m2, 0, n1, A, 0, m1, 0, n1);
     315       10998 :   if (gc_needed(av, 1))
     316           0 :     gerepileall(av, 4, &M2, &T3, &M3, &S3);  /* destroy S2 */
     317       10998 :   A11 = matslice(A, 1, m1, 1, n1);
     318       10998 :   B11 = matslice(B, 1, n1, 1, p1);
     319       10998 :   M1 = ZM_mul_i(A11, B11, m1 + 1, n1 + 1, p1 + 1);
     320       10998 :   if (gc_needed(av, 1))
     321           0 :     gerepileall(av, 5, &M2, &T3, &M3, &S3, &M1);  /* destroy A11, B11 */
     322       10998 :   A12 = matslice(A, 1, m1, n1 + 1, n);
     323       10998 :   B21 = matslice(B, n1 + 1, n, 1, p1);
     324       10998 :   M4 = ZM_mul_i(A12, B21, m1 + 1, n2 + 1, p1 + 1);
     325       10998 :   if (gc_needed(av, 1))
     326           0 :     gerepileall(av, 6, &M2, &T3, &M3, &S3, &M1, &M4);  /* destroy A12, B21 */
     327       10998 :   C11 = add_slices(m1, p1, M1, 0, m1, 0, p1, M4, 0, m1, 0, p1);
     328       10998 :   if (gc_needed(av, 1))
     329           0 :     gerepileall(av, 6, &M2, &T3, &M3, &S3, &M1, &C11);  /* destroy M4 */
     330       10998 :   M5 = ZM_mul_i(S3, T3, m1 + 1, n1 + 1, p1 + 1);
     331       10998 :   S4 = subtract_slices(m1, n2, A, 0, m1, n1, n2, S3, 0, m1, 0, n2);
     332       10998 :   if (gc_needed(av, 1))
     333           0 :     gerepileall(av, 7, &M2, &T3, &M3, &M1, &C11, &M5, &S4);  /* destroy S3 */
     334       10998 :   T4 = add_slices(n2, p1, B, n1, n2, 0, p1, T3, 0, n2, 0, p1);
     335       10998 :   if (gc_needed(av, 1))
     336           0 :     gerepileall(av, 7, &M2, &M3, &M1, &C11, &M5, &S4, &T4);  /* destroy T3 */
     337       10998 :   V1 = subtract_slices(m1, p1, M1, 0, m1, 0, p1, M5, 0, m1, 0, p1);
     338       10998 :   if (gc_needed(av, 1))
     339           0 :     gerepileall(av, 6, &M2, &M3, &S4, &T4, &C11, &V1);  /* destroy M1, M5 */
     340       10998 :   B22 = matslice(B, n1 + 1, n, p1 + 1, p);
     341       10998 :   M6 = ZM_mul_i(S4, B22, m1 + 1, n2 + 1, p2 + 1);
     342       10998 :   if (gc_needed(av, 1))
     343           0 :     gerepileall(av, 6, &M2, &M3, &T4, &C11, &V1, &M6);  /* destroy S4, B22 */
     344       10998 :   A22 = matslice(A, m1 + 1, m, n1 + 1, n);
     345       10998 :   M7 = ZM_mul_i(A22, T4, m2 + 1, n2 + 1, p1 + 1);
     346       10998 :   if (gc_needed(av, 1))
     347           0 :     gerepileall(av, 6, &M2, &M3, &C11, &V1, &M6, &M7);  /* destroy A22, T4 */
     348       10998 :   V3 = add_slices(m1, p2, V1, 0, m1, 0, p2, M3, 0, m2, 0, p2);
     349       10998 :   C12 = add_slices(m1, p2, V3, 0, m1, 0, p2, M6, 0, m1, 0, p2);
     350       10998 :   if (gc_needed(av, 1))
     351           0 :     gerepileall(av, 6, &M2, &M3, &C11, &V1, &M7, &C12);  /* destroy V3, M6 */
     352       10998 :   V2 = add_slices(m2, p1, V1, 0, m2, 0, p1, M2, 0, m2, 0, p2);
     353       10998 :   if (gc_needed(av, 1))
     354           0 :     gerepileall(av, 5, &M3, &C11, &M7, &C12, &V2);  /* destroy V1, M2 */
     355       10998 :   C21 = add_slices(m2, p1, V2, 0, m2, 0, p1, M7, 0, m2, 0, p1);
     356       10998 :   if (gc_needed(av, 1))
     357           0 :     gerepileall(av, 5, &M3, &C11, &C12, &V2, &C21);  /* destroy M7 */
     358       10998 :   C22 = add_slices(m2, p2, V2, 0, m2, 0, p2, M3, 0, m2, 0, p2);
     359       10998 :   if (gc_needed(av, 1))
     360           0 :     gerepileall(av, 4, &C11, &C12, &C21, &C22);  /* destroy V2, M3 */
     361       10998 :   C = mkmat2(mkcol2(C11, C21), mkcol2(C12, C22));
     362       10998 :   return gerepilecopy(av, shallowmatconcat(C));
     363             : }
     364             : 
     365             : /* x[i,]*y. Assume lg(x) > 1 and 0 < i < lgcols(x) */
     366             : static GEN
     367   126671626 : ZMrow_ZC_mul_i(GEN x, GEN y, long i, long lx)
     368             : {
     369   126671626 :   pari_sp av = avma;
     370   126671626 :   GEN c = mulii(gcoeff(x,i,1), gel(y,1)), ZERO = gen_0;
     371             :   long k;
     372  1711280582 :   for (k = 2; k < lx; k++)
     373             :   {
     374  1584608956 :     GEN t = mulii(gcoeff(x,i,k), gel(y,k));
     375  1584608956 :     if (t != ZERO) c = addii(c, t);
     376             :   }
     377   126671626 :   return gerepileuptoint(av, c);
     378             : }
     379             : GEN
     380    25444051 : ZMrow_ZC_mul(GEN x, GEN y, long i)
     381    25444051 : { 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    20110121 : ZM_ZC_mul_i(GEN x, GEN y, long lx, long l)
     386             : {
     387    20110121 :   GEN z = cgetg(l,t_COL);
     388             :   long i;
     389    20110121 :   for (i=1; i<l; i++) gel(z,i) = ZMrow_ZC_mul_i(x,y,i,lx);
     390    20110121 :   return z;
     391             : }
     392             : 
     393             : static GEN
     394     4646059 : ZM_mul_classical(GEN x, GEN y, long l, long lx, long ly)
     395             : {
     396             :   long j;
     397     4646059 :   GEN z = cgetg(ly, t_MAT);
     398    19394423 :   for (j = 1; j < ly; j++)
     399    14748364 :     gel(z, j) = ZM_ZC_mul_i(x, gel(y, j), lx, l);
     400     4646059 :   return z;
     401             : }
     402             : 
     403             : /* Strassen-Winograd used for dim >= ZM_sw_bound */
     404             : static GEN
     405     4653949 : ZM_mul_i(GEN x, GEN y, long l, long lx, long ly)
     406             : {
     407     4653949 :   long s = maxss(ZM_max_lg_i(x,lx,l), ZM_max_lg_i(y,ly,lx));
     408     4653949 :   long ZM_sw_bound = s > 60 ? 2: s > 25 ? 4: s>15 ? 8 : s > 8 ? 16 : 32;
     409     4653949 :   if (l <= ZM_sw_bound || lx <= ZM_sw_bound || ly <= ZM_sw_bound)
     410     4642958 :     return ZM_mul_classical(x, y, l, lx, ly);
     411             :   else
     412       10991 :     return ZM_mul_sw(x, y, l - 1, lx - 1, ly - 1);
     413             : }
     414             : 
     415             : GEN
     416     4636365 : ZM_mul(GEN x, GEN y)
     417             : {
     418     4636365 :   long lx=lg(x), ly=lg(y);
     419     4636365 :   if (ly==1) return cgetg(1,t_MAT);
     420     4577887 :   if (lx==1) return zeromat(0, ly-1);
     421     4576963 :   return ZM_mul_i(x, y, lgcols(x), lx, ly);
     422             : }
     423             : /* assume result is symmetric */
     424             : GEN
     425           0 : ZM_multosym(GEN x, GEN y)
     426             : {
     427           0 :   long j, lx, ly = lg(y);
     428             :   GEN M;
     429           0 :   if (ly == 1) return cgetg(1,t_MAT);
     430           0 :   lx = lg(x); /* = lgcols(y) */
     431           0 :   if (lx == 1) return cgetg(1,t_MAT);
     432             :   /* ly = lgcols(x) */
     433           0 :   M = cgetg(ly, t_MAT);
     434           0 :   for (j=1; j<ly; j++)
     435             :   {
     436           0 :     GEN z = cgetg(ly,t_COL), yj = gel(y,j);
     437             :     long i;
     438           0 :     for (i=1; i<j; i++) gel(z,i) = gcoeff(M,j,i);
     439           0 :     for (i=j; i<ly; i++)gel(z,i) = ZMrow_ZC_mul_i(x,yj,i,lx);
     440           0 :     gel(M,j) = z;
     441             :   }
     442           0 :   return M;
     443             : }
     444             : 
     445             : /* compute m*diagonal(d), assume lg(d) = lg(m). Shallow */
     446             : GEN
     447          14 : ZM_mul_diag(GEN m, GEN d)
     448             : {
     449             :   long j, l;
     450          14 :   GEN y = cgetg_copy(m, &l);
     451          56 :   for (j=1; j<l; j++)
     452             :   {
     453          42 :     GEN c = gel(d,j);
     454          42 :     gel(y,j) = equali1(c)? gel(m,j): ZC_Z_mul(gel(m,j), c);
     455             :   }
     456          14 :   return y;
     457             : }
     458             : /* compute diagonal(d)*m, assume lg(d) = lg(m~). Shallow */
     459             : GEN
     460       89211 : ZM_diag_mul(GEN d, GEN m)
     461             : {
     462       89211 :   long i, j, l = lg(d), lm = lg(m);
     463       89211 :   GEN y = cgetg(lm, t_MAT);
     464       89211 :   for (j=1; j<lm; j++) gel(y,j) = cgetg(l, t_COL);
     465      284002 :   for (i=1; i<l; i++)
     466             :   {
     467      194791 :     GEN c = gel(d,i);
     468      194791 :     if (equali1(c))
     469        9058 :       for (j=1; j<lm; j++) gcoeff(y,i,j) = gcoeff(m,i,j);
     470             :     else
     471      185733 :       for (j=1; j<lm; j++) gcoeff(y,i,j) = mulii(gcoeff(m,i,j), c);
     472             :   }
     473       89211 :   return y;
     474             : }
     475             : 
     476             : /* assume lx > 1 is lg(x) = lg(y) */
     477             : static GEN
     478    11759967 : ZV_dotproduct_i(GEN x, GEN y, long lx)
     479             : {
     480    11759967 :   pari_sp av = avma;
     481    11759967 :   GEN c = mulii(gel(x,1), gel(y,1));
     482             :   long i;
     483    95693017 :   for (i = 2; i < lx; i++)
     484             :   {
     485    83933050 :     GEN t = mulii(gel(x,i), gel(y,i));
     486    83933050 :     if (t != gen_0) c = addii(c, t);
     487             :   }
     488    11759967 :   return gerepileuptoint(av, c);
     489             : }
     490             : 
     491             : /* x~ * y, assuming result is symmetric */
     492             : GEN
     493      160286 : ZM_transmultosym(GEN x, GEN y)
     494             : {
     495      160286 :   long i, j, l, ly = lg(y);
     496             :   GEN M;
     497      160286 :   if (ly == 1) return cgetg(1,t_MAT);
     498             :   /* lg(x) = ly */
     499      160286 :   l = lgcols(y); /* = lgcols(x) */
     500      160286 :   M = cgetg(ly, t_MAT);
     501     1251141 :   for (i=1; i<ly; i++)
     502             :   {
     503     1090855 :     GEN xi = gel(x,i), c = cgetg(ly,t_COL);
     504     1090855 :     gel(M,i) = c;
     505     4913406 :     for (j=1; j<i; j++)
     506     3822551 :       gcoeff(M,i,j) = gel(c,j) = ZV_dotproduct_i(xi,gel(y,j),l);
     507     1090855 :     gel(c,i) = ZV_dotproduct_i(xi,gel(y,i),l);
     508             :   }
     509      160286 :   return M;
     510             : }
     511             : /* x~ * y */
     512             : GEN
     513         497 : ZM_transmul(GEN x, GEN y)
     514             : {
     515         497 :   long i, j, l, lx, ly = lg(y);
     516             :   GEN M;
     517         497 :   if (ly == 1) return cgetg(1,t_MAT);
     518         497 :   lx = lg(x);
     519         497 :   l = lgcols(y);
     520         497 :   if (lgcols(x) != l) pari_err_OP("operation 'ZM_transmul'", x,y);
     521         497 :   M = cgetg(ly, t_MAT);
     522        1617 :   for (i=1; i<ly; i++)
     523             :   {
     524        1120 :     GEN yi = gel(y,i), c = cgetg(lx,t_COL);
     525        1120 :     gel(M,i) = c;
     526        1120 :     for (j=1; j<lx; j++) gel(c,j) = ZV_dotproduct_i(yi,gel(x,j),l);
     527             :   }
     528         497 :   return M;
     529             : }
     530             : 
     531             : static GEN
     532        3108 : ZM_sqr_i(GEN x, long l)
     533             : {
     534        3108 :   long s = ZM_max_lg_i(x,l,l);
     535        3108 :   long ZM_sw_bound = s > 60 ? 2: s > 25 ? 4: s>15 ? 8 : s > 8 ? 16 : 32;
     536        3108 :   if (l <= ZM_sw_bound)
     537        3101 :     return ZM_mul_classical(x, x, l, l, l);
     538             :   else
     539           7 :     return ZM_mul_sw(x, x, l - 1, l - 1, l - 1);
     540             : }
     541             : 
     542             : GEN
     543        3108 : ZM_sqr(GEN x)
     544             : {
     545        3108 :   long lx=lg(x);
     546        3108 :   if (lx==1) return cgetg(1,t_MAT);
     547        3108 :   return ZM_sqr_i(x, lx);
     548             : }
     549             : GEN
     550     5454130 : ZM_ZC_mul(GEN x, GEN y)
     551             : {
     552     5454130 :   long lx = lg(x);
     553     5454130 :   return lx==1? cgetg(1,t_COL): ZM_ZC_mul_i(x, y, lx, lgcols(x));
     554             : }
     555             : 
     556             : GEN
     557      121842 : ZC_Z_div(GEN x, GEN c)
     558             : {
     559             :   long i, l;
     560      121842 :   GEN a = cgetg_copy(x, &l);
     561      121842 :   for (i = 1; i < l; i++) gel(a,i) = Qdivii(gel(x,i), c);
     562      121842 :   return a;
     563             : }
     564             : GEN
     565       12194 : ZM_Z_div(GEN X, GEN c)
     566             : {
     567       12194 :   long j, l = lg(X);
     568       12194 :   GEN A = cgetg(l, t_MAT);
     569       12194 :   for (j = 1; j < l; j++) gel(A,j) = ZC_Z_div(gel(X,j), c);
     570       12194 :   return A;
     571             : }
     572             : 
     573             : long
     574   151102651 : zv_dotproduct(GEN x, GEN y)
     575             : {
     576   151102651 :   long i, lx = lg(x);
     577             :   ulong c;
     578   151102651 :   if (lx == 1) return 0;
     579   151102651 :   c = uel(x,1)*uel(y,1);
     580  2329284041 :   for (i = 2; i < lx; i++)
     581  2178181390 :     c += uel(x,i)*uel(y,i);
     582   151102651 :   return c;
     583             : }
     584             : 
     585             : GEN
     586       67613 : ZV_ZM_mul(GEN x, GEN y)
     587             : {
     588       67613 :   long i, lx = lg(x), ly = lg(y);
     589             :   GEN z;
     590       67613 :   if (lx == 1) return zerovec(ly-1);
     591       67599 :   z = cgetg(ly, t_VEC);
     592       67599 :   for (i = 1; i < ly; i++) gel(z,i) = ZV_dotproduct_i(x, gel(y,i), lx);
     593       67599 :   return z;
     594             : }
     595             : 
     596             : GEN
     597           0 : ZC_ZV_mul(GEN x, GEN y)
     598             : {
     599           0 :   long i,j, lx=lg(x), ly=lg(y);
     600             :   GEN z;
     601           0 :   if (ly==1) return cgetg(1,t_MAT);
     602           0 :   z = cgetg(ly,t_MAT);
     603           0 :   for (j=1; j < ly; j++)
     604             :   {
     605           0 :     gel(z,j) = cgetg(lx,t_COL);
     606           0 :     for (i=1; i<lx; i++) gcoeff(z,i,j) = mulii(gel(x,i),gel(y,j));
     607             :   }
     608           0 :   return z;
     609             : }
     610             : 
     611             : GEN
     612     3794081 : ZV_dotsquare(GEN x)
     613             : {
     614             :   long i, lx;
     615             :   pari_sp av;
     616             :   GEN z;
     617     3794081 :   lx = lg(x);
     618     3794081 :   if (lx == 1) return gen_0;
     619     3794081 :   av = avma; z = sqri(gel(x,1));
     620     3794081 :   for (i=2; i<lx; i++) z = addii(z, sqri(gel(x,i)));
     621     3794081 :   return gerepileuptoint(av,z);
     622             : }
     623             : 
     624             : GEN
     625     9328574 : ZV_dotproduct(GEN x,GEN y)
     626             : {
     627             :   long lx;
     628     9328574 :   if (x == y) return ZV_dotsquare(x);
     629     6693128 :   lx = lg(x);
     630     6693128 :   if (lx == 1) return gen_0;
     631     6693128 :   return ZV_dotproduct_i(x, y, lx);
     632             : }
     633             : 
     634             : static GEN
     635         280 : _ZM_mul(void *data /*ignored*/, GEN x, GEN y)
     636         280 : { (void)data; return ZM_mul(x,y); }
     637             : static GEN
     638        2604 : _ZM_sqr(void *data /*ignored*/, GEN x)
     639        2604 : { (void)data; return ZM_sqr(x); }
     640             : GEN
     641           0 : ZM_pow(GEN x, GEN n)
     642             : {
     643           0 :   pari_sp av = avma;
     644           0 :   if (!signe(n)) return matid(lg(x)-1);
     645           0 :   return gerepileupto(av, gen_pow(x, n, NULL, &_ZM_sqr, &_ZM_mul));
     646             : }
     647             : GEN
     648        2170 : ZM_powu(GEN x, ulong n)
     649             : {
     650        2170 :   pari_sp av = avma;
     651        2170 :   if (!n) return matid(lg(x)-1);
     652        2170 :   return gerepileupto(av, gen_powu(x, n, NULL, &_ZM_sqr, &_ZM_mul));
     653             : }
     654             : /********************************************************************/
     655             : /**                                                                **/
     656             : /**                           ADD, SUB                             **/
     657             : /**                                                                **/
     658             : /********************************************************************/
     659             : static GEN
     660    12894591 : ZC_add_i(GEN x, GEN y, long lx)
     661             : {
     662    12894591 :   GEN A = cgetg(lx, t_COL);
     663             :   long i;
     664    12894607 :   for (i=1; i<lx; i++) gel(A,i) = addii(gel(x,i), gel(y,i));
     665    12894600 :   return A;
     666             : }
     667             : GEN
     668     6896331 : ZC_add(GEN x, GEN y) { return ZC_add_i(x, y, lg(x)); }
     669             : GEN
     670      103451 : ZC_Z_add(GEN x, GEN y)
     671             : {
     672      103451 :   long k, lx = lg(x);
     673      103451 :   GEN z = cgetg(lx, t_COL);
     674      103451 :   if (lx == 1) pari_err_TYPE2("+",x,y);
     675      103451 :   gel(z,1) = addii(y,gel(x,1));
     676      103451 :   for (k = 2; k < lx; k++) gel(z,k) = icopy(gel(x,k));
     677      103451 :   return z;
     678             : }
     679             : 
     680             : static GEN
     681     1932217 : ZC_sub_i(GEN x, GEN y, long lx)
     682             : {
     683             :   long i;
     684     1932217 :   GEN A = cgetg(lx, t_COL);
     685     1932217 :   for (i=1; i<lx; i++) gel(A,i) = subii(gel(x,i), gel(y,i));
     686     1932217 :   return A;
     687             : }
     688             : GEN
     689     1198617 : ZC_sub(GEN x, GEN y) { return ZC_sub_i(x, y, lg(x)); }
     690             : GEN
     691           0 : ZC_Z_sub(GEN x, GEN y)
     692             : {
     693           0 :   long k, lx = lg(x);
     694           0 :   GEN z = cgetg(lx, t_COL);
     695           0 :   if (lx == 1) pari_err_TYPE2("+",x,y);
     696           0 :   gel(z,1) = subii(gel(x,1), y);
     697           0 :   for (k = 2; k < lx; k++) gel(z,k) = icopy(gel(x,k));
     698           0 :   return z;
     699             : }
     700             : GEN
     701       94824 : Z_ZC_sub(GEN a, GEN x)
     702             : {
     703       94824 :   long k, lx = lg(x);
     704       94824 :   GEN z = cgetg(lx, t_COL);
     705       94824 :   if (lx == 1) pari_err_TYPE2("-",a,x);
     706       94824 :   gel(z,1) = subii(a, gel(x,1));
     707       94824 :   for (k = 2; k < lx; k++) gel(z,k) = negi(gel(x,k));
     708       94824 :   return z;
     709             : }
     710             : 
     711             : GEN
     712     1097150 : ZM_add(GEN x, GEN y)
     713             : {
     714     1097150 :   long lx = lg(x), l, j;
     715             :   GEN z;
     716     1097150 :   if (lx == 1) return cgetg(1, t_MAT);
     717     1090780 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     718     1090780 :   for (j = 1; j < lx; j++) gel(z,j) = ZC_add_i(gel(x,j), gel(y,j), l);
     719     1090780 :   return z;
     720             : }
     721             : GEN
     722      651925 : ZM_sub(GEN x, GEN y)
     723             : {
     724      651925 :   long lx = lg(x), l, j;
     725             :   GEN z;
     726      651925 :   if (lx == 1) return cgetg(1, t_MAT);
     727      651925 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     728      651925 :   for (j = 1; j < lx; j++) gel(z,j) = ZC_sub_i(gel(x,j), gel(y,j), l);
     729      651925 :   return z;
     730             : }
     731             : /********************************************************************/
     732             : /**                                                                **/
     733             : /**                         LINEAR COMBINATION                     **/
     734             : /**                                                                **/
     735             : /********************************************************************/
     736             : /* return X/c assuming division is exact */
     737             : GEN
     738     2454100 : ZC_Z_divexact(GEN X, GEN c)
     739             : {
     740     2454100 :   long i, l = lg(X);
     741     2454100 :   GEN A = cgetg(l, t_COL);
     742     2454100 :   for (i=1; i<l; i++) gel(A,i) = diviiexact(gel(X,i), c);
     743     2454100 :   return A;
     744             : }
     745             : GEN
     746      842695 : ZM_Z_divexact(GEN X, GEN c)
     747             : {
     748      842695 :   long i, l = lg(X);
     749      842695 :   GEN A = cgetg(l, t_MAT);
     750      842695 :   for (i = 1; i < l; i++) gel(A,i) = ZC_Z_divexact(gel(X,i), c);
     751      842695 :   return A;
     752             : }
     753             : /* Return c * X */
     754             : GEN
     755    10519421 : ZC_Z_mul(GEN X, GEN c)
     756             : {
     757             :   long i, l;
     758             :   GEN A;
     759    10519421 :   if (!signe(c)) return zerocol(lg(X)-1);
     760    10221593 :   if (is_pm1(c)) return (signe(c) > 0)? ZC_copy(X): ZC_neg(X);
     761     8267390 :   l = lg(X); A = cgetg(l, t_COL);
     762     8267421 :   for (i=1; i<l; i++) gel(A,i) = mulii(c,gel(X,i));
     763     8267380 :   return A;
     764             : }
     765             : GEN
     766       13769 : ZC_z_mul(GEN X, long c)
     767             : {
     768             :   long i, l;
     769             :   GEN A;
     770       13769 :   if (!c) return zerocol(lg(X)-1);
     771        7154 :   if (c == 1) return ZC_copy(X);
     772        2282 :   if (c ==-1) return ZC_neg(X);
     773         826 :   l = lg(X); A = cgetg(l, t_COL);
     774         826 :   for (i=1; i<l; i++) gel(A,i) = mulsi(c,gel(X,i));
     775         826 :   return A;
     776             : }
     777             : 
     778             : GEN
     779        8287 : zv_z_mul(GEN M, long n)
     780             : {
     781             :   long l;
     782        8287 :   GEN N = cgetg_copy(M, &l);
     783        8287 :   while (--l > 0) N[l] = M[l]*n;
     784        8287 :   return N;
     785             : }
     786             : 
     787             : /* return a ZM */
     788             : GEN
     789      634495 : nm_Z_mul(GEN X, GEN c)
     790             : {
     791      634495 :   long i, j, h, l = lg(X), s = signe(c);
     792             :   GEN A;
     793      634495 :   if (l == 1) return cgetg(1, t_MAT);
     794      634495 :   h = lgcols(X);
     795      634495 :   if (!s) return zeromat(h-1, l-1);
     796      634495 :   if (is_pm1(c)) {
     797           0 :     if (s > 0) return Flm_to_ZM(X);
     798           0 :     X = Flm_to_ZM(X); ZM_togglesign(X); return X;
     799             :   }
     800      634495 :   A = cgetg(l, t_MAT);
     801     1298161 :   for (j = 1; j < l; j++)
     802             :   {
     803      663666 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     804      663666 :     for (i = 1; i < h; i++) gel(a,i) = muliu(c, x[i]);
     805      663666 :     gel(A,j) = a;
     806             :   }
     807      634495 :   return A;
     808             : }
     809             : GEN
     810      689108 : ZM_Z_mul(GEN X, GEN c)
     811             : {
     812      689108 :   long i, j, h, l = lg(X);
     813             :   GEN A;
     814      689108 :   if (l == 1) return cgetg(1, t_MAT);
     815      689108 :   h = lgcols(X);
     816      689108 :   if (!signe(c)) return zeromat(h-1, l-1);
     817      688555 :   if (is_pm1(c)) return (signe(c) > 0)? ZM_copy(X): ZM_neg(X);
     818      518696 :   A = cgetg(l, t_MAT);
     819     5990851 :   for (j = 1; j < l; j++)
     820             :   {
     821     5472155 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     822     5472155 :     for (i = 1; i < h; i++) gel(a,i) = mulii(c, gel(x,i));
     823     5472155 :     gel(A,j) = a;
     824             :   }
     825      518696 :   return A;
     826             : }
     827             : 
     828             : /* X <- X + v Y (elementary col operation) */
     829             : void
     830    38835272 : ZC_lincomb1_inplace(GEN X, GEN Y, GEN v)
     831             : {
     832    38835272 :   long i, m = lgefint(v);
     833    77670544 :   if (m == 2) return; /* v = 0 */
     834    38835272 :   for (i = lg(X)-1; i; i--) gel(X,i) = addmulii_inplace(gel(X,i), gel(Y,i), v);
     835             : }
     836             : void
     837     8554702 : Flc_lincomb1_inplace(GEN X, GEN Y, ulong v, ulong q)
     838             : {
     839             :   long i;
     840    17109404 :   if (!v) return; /* v = 0 */
     841     8554702 :   for (i = lg(X)-1; i; i--) X[i] = Fl_add(X[i], Fl_mul(Y[i], v, q), q);
     842             : }
     843             : 
     844             : /* X + v Y, wasteful if (v = 0) */
     845             : static GEN
     846     2105233 : ZC_lincomb1(GEN v, GEN X, GEN Y)
     847             : {
     848     2105233 :   long i, lx = lg(X);
     849     2105233 :   GEN A = cgetg(lx,t_COL);
     850     2105233 :   for (i=1; i<lx; i++) gel(A,i) = addmulii(gel(X,i), gel(Y,i), v);
     851     2105233 :   return A;
     852             : }
     853             : /* -X + vY */
     854             : static GEN
     855      383612 : ZC_lincomb_1(GEN v, GEN X, GEN Y)
     856             : {
     857      383612 :   long i, lx = lg(X);
     858      383612 :   GEN A = cgetg(lx,t_COL);
     859      383612 :   for (i=1; i<lx; i++) gel(A,i) = mulsubii(gel(Y,i), v, gel(X,i));
     860      383612 :   return A;
     861             : }
     862             : /* X,Y compatible ZV; u,v in Z. Returns A = u*X + v*Y */
     863             : GEN
     864     9072399 : ZC_lincomb(GEN u, GEN v, GEN X, GEN Y)
     865             : {
     866             :   long su, sv;
     867             :   GEN A;
     868             : 
     869     9072399 :   su = signe(u); if (!su) return ZC_Z_mul(Y, v);
     870     9072210 :   sv = signe(v); if (!sv) return ZC_Z_mul(X, u);
     871     9071993 :   if (is_pm1(v))
     872             :   {
     873     1626667 :     if (is_pm1(u))
     874             :     {
     875     1010802 :       if (su != sv) A = ZC_sub(X, Y);
     876      338182 :       else          A = ZC_add(X, Y);
     877     1010802 :       if (su < 0) ZV_togglesign(A); /* in place but was created above */
     878             :     }
     879             :     else
     880             :     {
     881      615865 :       if (sv > 0) A = ZC_lincomb1 (u, Y, X);
     882      244630 :       else        A = ZC_lincomb_1(u, Y, X);
     883             :     }
     884             :   }
     885     7445326 :   else if (is_pm1(u))
     886             :   {
     887     1872980 :     if (su > 0) A = ZC_lincomb1 (v, X, Y);
     888      138982 :     else        A = ZC_lincomb_1(v, X, Y);
     889             :   }
     890             :   else
     891             :   { /* not cgetg_copy: x may be a t_VEC */
     892     5572346 :     long i, lx = lg(X);
     893     5572346 :     A = cgetg(lx,t_COL);
     894     5572346 :     for (i=1; i<lx; i++) gel(A,i) = lincombii(u,v,gel(X,i),gel(Y,i));
     895             :   }
     896     9071993 :   return A;
     897             : }
     898             : 
     899             : /********************************************************************/
     900             : /**                                                                **/
     901             : /**                           CONVERSIONS                          **/
     902             : /**                                                                **/
     903             : /********************************************************************/
     904             : GEN
     905       50463 : ZV_to_nv(GEN z)
     906             : {
     907       50463 :   long i, l = lg(z);
     908       50463 :   GEN x = cgetg(l, t_VECSMALL);
     909       50463 :   for (i=1; i<l; i++) x[i] = itou(gel(z,i));
     910       50463 :   return x;
     911             : }
     912             : 
     913             : GEN
     914      368417 : zm_to_ZM(GEN z)
     915             : {
     916      368417 :   long i, l = lg(z);
     917      368417 :   GEN x = cgetg(l,t_MAT);
     918      368417 :   for (i=1; i<l; i++) gel(x,i) = zc_to_ZC(gel(z,i));
     919      368417 :   return x;
     920             : }
     921             : 
     922             : GEN
     923          98 : zmV_to_ZMV(GEN z)
     924             : {
     925          98 :   long i, l = lg(z);
     926          98 :   GEN x = cgetg(l,t_VEC);
     927          98 :   for (i=1; i<l; i++) gel(x,i) = zm_to_ZM(gel(z,i));
     928          98 :   return x;
     929             : }
     930             : 
     931             : /* same as Flm_to_ZM but do not assume positivity */
     932             : GEN
     933         868 : ZM_to_zm(GEN z)
     934             : {
     935         868 :   long i, l = lg(z);
     936         868 :   GEN x = cgetg(l,t_MAT);
     937         868 :   for (i=1; i<l; i++) gel(x,i) = ZV_to_zv(gel(z,i));
     938         868 :   return x;
     939             : }
     940             : 
     941             : GEN
     942      223314 : zv_to_Flv(GEN z, ulong p)
     943             : {
     944      223314 :   long i, l = lg(z);
     945      223314 :   GEN x = cgetg(l,t_VECSMALL);
     946      223314 :   for (i=1; i<l; i++) x[i] = umodsu(z[i], p);
     947      223314 :   return x;
     948             : }
     949             : 
     950             : GEN
     951       15792 : zm_to_Flm(GEN z, ulong p)
     952             : {
     953       15792 :   long i, l = lg(z);
     954       15792 :   GEN x = cgetg(l,t_MAT);
     955       15792 :   for (i=1; i<l; i++) gel(x,i) = zv_to_Flv(gel(z,i),p);
     956       15792 :   return x;
     957             : }
     958             : 
     959             : GEN
     960          21 : ZMV_to_zmV(GEN z)
     961             : {
     962          21 :   long i,l = lg(z);
     963          21 :   GEN x = cgetg(l, t_VEC);
     964          21 :   for (i=1; i<l; i++) gel(x,i) = ZM_to_zm(gel(z,i));
     965          21 :   return x;
     966             : }
     967             : 
     968             : /********************************************************************/
     969             : /**                                                                **/
     970             : /**                         COPY, NEGATION                         **/
     971             : /**                                                                **/
     972             : /********************************************************************/
     973             : GEN
     974     3770998 : ZC_copy(GEN x)
     975             : {
     976     3770998 :   long i, lx = lg(x);
     977     3770998 :   GEN y = cgetg(lx, t_COL);
     978    31768522 :   for (i=1; i<lx; i++)
     979             :   {
     980    27997524 :     GEN c = gel(x,i);
     981    27997524 :     gel(y,i) = lgefint(c) == 2? gen_0: icopy(c);
     982             :   }
     983     3770998 :   return y;
     984             : }
     985             : 
     986             : GEN
     987      209017 : ZM_copy(GEN x)
     988             : {
     989             :   long l;
     990      209017 :   GEN y = cgetg_copy(x, &l);
     991      209017 :   while (--l > 0) gel(y,l) = ZC_copy(gel(x,l));
     992      209017 :   return y;
     993             : }
     994             : 
     995             : void
     996      125621 : ZV_neg_inplace(GEN M)
     997             : {
     998      125621 :   long l = lg(M);
     999      125621 :   while (--l > 0) gel(M,l) = negi(gel(M,l));
    1000      125621 : }
    1001             : GEN
    1002     1768153 : ZC_neg(GEN M)
    1003             : {
    1004     1768153 :   long l = lg(M);
    1005     1768153 :   GEN N = cgetg(l, t_COL);
    1006     1768153 :   while (--l > 0) gel(N,l) = negi(gel(M,l));
    1007     1768153 :   return N;
    1008             : }
    1009             : GEN
    1010       23341 : zv_neg(GEN M)
    1011             : {
    1012             :   long l;
    1013       23341 :   GEN N = cgetg_copy(M, &l);
    1014       23341 :   while (--l > 0) N[l] = -M[l];
    1015       23341 :   return N;
    1016             : }
    1017             : GEN
    1018         257 : zv_neg_inplace(GEN M)
    1019             : {
    1020         257 :   long l = lg(M);
    1021         257 :   while (--l > 0) M[l] = -M[l];
    1022         257 :   return M;
    1023             : }
    1024             : GEN
    1025      257383 : ZM_neg(GEN x)
    1026             : {
    1027             :   long l;
    1028      257383 :   GEN y = cgetg_copy(x, &l);
    1029      257383 :   while (--l > 0) gel(y,l) = ZC_neg(gel(x,l));
    1030      257383 :   return y;
    1031             : }
    1032             : 
    1033             : void
    1034     1394834 : ZV_togglesign(GEN M)
    1035             : {
    1036     1394834 :   long l = lg(M);
    1037     1394834 :   while (--l > 0) togglesign_safe(&gel(M,l));
    1038     1394834 : }
    1039             : void
    1040           0 : ZM_togglesign(GEN M)
    1041             : {
    1042           0 :   long l = lg(M);
    1043           0 :   while (--l > 0) ZV_togglesign(gel(M,l));
    1044           0 : }
    1045             : 
    1046             : /********************************************************************/
    1047             : /**                                                                **/
    1048             : /**                        "DIVISION" mod HNF                      **/
    1049             : /**                                                                **/
    1050             : /********************************************************************/
    1051             : /* Reduce ZC x modulo ZM y in HNF, may return x itself (not a copy) */
    1052             : GEN
    1053      852973 : ZC_hnfremdiv(GEN x, GEN y, GEN *Q)
    1054             : {
    1055      852973 :   long i, l = lg(x);
    1056             :   GEN q;
    1057             : 
    1058      852973 :   if (Q) *Q = cgetg(l,t_COL);
    1059      852973 :   if (l == 1) return cgetg(1,t_COL);
    1060     5056585 :   for (i = l-1; i>0; i--)
    1061             :   {
    1062     4203612 :     q = diviiround(gel(x,i), gcoeff(y,i,i));
    1063     4203612 :     if (signe(q)) {
    1064     2272833 :       togglesign(q);
    1065     2272833 :       x = ZC_lincomb(gen_1, q, x, gel(y,i));
    1066             :     }
    1067     4203612 :     if (Q) gel(*Q, i) = q;
    1068             :   }
    1069      852973 :   return x;
    1070             : }
    1071             : 
    1072             : /* x = y Q + R, may return some columns of x (not copies) */
    1073             : GEN
    1074       52002 : ZM_hnfdivrem(GEN x, GEN y, GEN *Q)
    1075             : {
    1076       52002 :   long lx = lg(x), i;
    1077       52002 :   GEN R = cgetg(lx, t_MAT);
    1078       52002 :   if (Q)
    1079             :   {
    1080       16398 :     GEN q = cgetg(lx, t_MAT); *Q = q;
    1081       16398 :     for (i=1; i<lx; i++) gel(R,i) = ZC_hnfremdiv(gel(x,i),y,(GEN*)(q+i));
    1082             :   }
    1083             :   else
    1084      121126 :     for (i=1; i<lx; i++)
    1085             :     {
    1086       85522 :       pari_sp av = avma;
    1087       85522 :       GEN z = ZC_hnfrem(gel(x,i),y);
    1088       85522 :       gel(R,i) = (avma == av)? ZC_copy(z): gerepileupto(av, z);
    1089             :     }
    1090       52002 :   return R;
    1091             : }
    1092             : 
    1093             : 
    1094             : /********************************************************************/
    1095             : /**                                                                **/
    1096             : /**                               TESTS                            **/
    1097             : /**                                                                **/
    1098             : /********************************************************************/
    1099             : int
    1100    17351061 : zv_equal0(GEN V)
    1101             : {
    1102    17351061 :   long l = lg(V);
    1103    45111415 :   while (--l > 0)
    1104    22457448 :     if (V[l]) return 0;
    1105     5302906 :   return 1;
    1106             : }
    1107             : 
    1108             : int
    1109      553395 : ZV_equal0(GEN V)
    1110             : {
    1111      553395 :   long l = lg(V);
    1112     2525207 :   while (--l > 0)
    1113     1853401 :     if (signe(gel(V,l))) return 0;
    1114      118411 :   return 1;
    1115             : }
    1116             : 
    1117             : static int
    1118     9170590 : ZV_equal_lg(GEN V, GEN W, long l)
    1119             : {
    1120    26313737 :   while (--l > 0)
    1121    15122988 :     if (!equalii(gel(V,l), gel(W,l))) return 0;
    1122     2020159 :   return 1;
    1123             : }
    1124             : int
    1125     7927370 : ZV_equal(GEN V, GEN W)
    1126             : {
    1127     7927370 :   long l = lg(V);
    1128     7927370 :   if (lg(W) != l) return 0;
    1129     7927370 :   return ZV_equal_lg(V, W, l);
    1130             : }
    1131             : int
    1132      403391 : ZM_equal(GEN A, GEN B)
    1133             : {
    1134      403391 :   long i, m, l = lg(A);
    1135      403391 :   if (lg(B) != l) return 0;
    1136      402992 :   if (l == 1) return 1;
    1137      402992 :   m = lgcols(A);
    1138      402992 :   if (lgcols(B) != m) return 0;
    1139     1572418 :   for (i = 1; i < l; i++)
    1140     1243220 :     if (!ZV_equal_lg(gel(A,i), gel(B,i), m)) return 0;
    1141      329198 :   return 1;
    1142             : }
    1143             : int
    1144    20821171 : zv_equal(GEN V, GEN W)
    1145             : {
    1146    20821171 :   long l = lg(V);
    1147    20821171 :   if (lg(W) != l) return 0;
    1148   198216404 :   while (--l > 0)
    1149   157347807 :     if (V[l] != W[l]) return 0;
    1150    20409256 :   return 1;
    1151             : }
    1152             : 
    1153             : int
    1154         385 : zvV_equal(GEN V, GEN W)
    1155             : {
    1156         385 :   long l = lg(V);
    1157         385 :   if (lg(W) != l) return 0;
    1158       58982 :   while (--l > 0)
    1159       58373 :     if (!zv_equal(gel(V,l),gel(W,l))) return 0;
    1160         231 :   return 1;
    1161             : }
    1162             : 
    1163             : int
    1164      114583 : ZM_ishnf(GEN x)
    1165             : {
    1166      114583 :   long i,j, lx = lg(x);
    1167      363636 :   for (i=1; i<lx; i++)
    1168             :   {
    1169      275723 :     GEN xii = gcoeff(x,i,i);
    1170      275723 :     if (signe(xii) <= 0) return 0;
    1171      673959 :     for (j=1; j<i; j++)
    1172      411585 :       if (signe(gcoeff(x,i,j))) return 0;
    1173      716001 :     for (j=i+1; j<lx; j++)
    1174             :     {
    1175      466948 :       GEN xij = gcoeff(x,i,j);
    1176      466948 :       if (signe(xij)<0 || cmpii(xij,xii)>=0) return 0;
    1177             :     }
    1178             :   }
    1179       87913 :   return 1;
    1180             : }
    1181             : int
    1182      181706 : ZM_isidentity(GEN x)
    1183             : {
    1184      181706 :   long i,j, lx = lg(x);
    1185             : 
    1186      181706 :   if (lx == 1) return 1;
    1187      181706 :   if (lx != lgcols(x)) return 0;
    1188      415331 :   for (j=1; j<lx; j++)
    1189             :   {
    1190      385952 :     GEN c = gel(x,j);
    1191     1185268 :     for (i=1; i<j; )
    1192      521850 :       if (signe(gel(c,i++))) return 0;
    1193             :     /* i = j */
    1194      277466 :       if (!equali1(gel(c,i++))) return 0;
    1195      991592 :     for (   ; i<lx; )
    1196      523096 :       if (signe(gel(c,i++))) return 0;
    1197             :   }
    1198       29379 :   return 1;
    1199             : }
    1200             : int
    1201       60142 : ZM_isdiagonal(GEN x)
    1202             : {
    1203       60142 :   long i,j, lx = lg(x);
    1204       60142 :   if (lx == 1) return 1;
    1205       60142 :   if (lx != lgcols(x)) return 0;
    1206             : 
    1207      186510 :   for (j=1; j<lx; j++)
    1208             :   {
    1209      161972 :     GEN c = gel(x,j);
    1210      356662 :     for (i=1; i<j; i++)
    1211      230287 :       if (signe(gel(c,i))) return 0;
    1212      520180 :     for (i++; i<lx; i++)
    1213      393812 :       if (signe(gel(c,i))) return 0;
    1214             :   }
    1215       24538 :   return 1;
    1216             : }
    1217             : int
    1218        9173 : ZM_isscalar(GEN x, GEN s)
    1219             : {
    1220        9173 :   long i, j, lx = lg(x);
    1221             : 
    1222        9173 :   if (lx == 1) return 1;
    1223        9173 :   if (!s) s = gcoeff(x,1,1);
    1224        9173 :   if (equali1(s)) return ZM_isidentity(x);
    1225        6772 :   if (lx != lgcols(x)) return 0;
    1226       51556 :   for (j=1; j<lx; j++)
    1227             :   {
    1228       44850 :     GEN c = gel(x,j);
    1229      509546 :     for (i=1; i<j; )
    1230      419864 :       if (signe(gel(c,i++))) return 0;
    1231             :     /* i = j */
    1232       44832 :       if (!equalii(gel(c,i++), s)) return 0;
    1233      509726 :     for (   ; i<lx; )
    1234      420155 :       if (signe(gel(c,i++))) return 0;
    1235             :   }
    1236        6706 :   return 1;
    1237             : }
    1238             : 
    1239             : long
    1240       59213 : ZC_is_ei(GEN x)
    1241             : {
    1242       59213 :   long i, j = 0, l = lg(x);
    1243      554701 :   for (i = 1; i < l; i++)
    1244             :   {
    1245      495488 :     GEN c = gel(x,i);
    1246      495488 :     long s = signe(c);
    1247      495488 :     if (!s) continue;
    1248       59199 :     if (s < 0 || !is_pm1(c) || j) return 0;
    1249       59199 :     j = i;
    1250             :   }
    1251       59213 :   return j;
    1252             : }
    1253             : 
    1254             : /********************************************************************/
    1255             : /**                                                                **/
    1256             : /**                       MISCELLANEOUS                            **/
    1257             : /**                                                                **/
    1258             : /********************************************************************/
    1259             : /* assume lg(x) = lg(y), x,y in Z^n */
    1260             : int
    1261      663723 : ZV_cmp(GEN x, GEN y)
    1262             : {
    1263      663723 :   long fl,i, lx = lg(x);
    1264     1325551 :   for (i=1; i<lx; i++)
    1265     1066544 :     if (( fl = cmpii(gel(x,i), gel(y,i)) )) return fl;
    1266      259007 :   return 0;
    1267             : }
    1268             : /* assume lg(x) = lg(y), x,y in Z^n */
    1269             : int
    1270        3550 : ZV_abscmp(GEN x, GEN y)
    1271             : {
    1272        3550 :   long fl,i, lx = lg(x);
    1273       19587 :   for (i=1; i<lx; i++)
    1274       19507 :     if (( fl = abscmpii(gel(x,i), gel(y,i)) )) return fl;
    1275          80 :   return 0;
    1276             : }
    1277             : 
    1278             : long
    1279     1015760 : zv_content(GEN x)
    1280             : {
    1281     1015760 :   long i, s, l = lg(x);
    1282     1015760 :   if (l == 1) return 0;
    1283     1015753 :   s = labs(x[1]);
    1284     1015753 :   for (i=2; i<l && s!=1; i++) s = cgcd(x[i],s);
    1285     1015753 :   return s;
    1286             : }
    1287             : GEN
    1288       67963 : ZV_content(GEN x)
    1289             : {
    1290       67963 :   long i, l = lg(x);
    1291       67963 :   pari_sp av = avma;
    1292             :   GEN c;
    1293       67963 :   if (l == 1) return gen_0;
    1294       67963 :   if (l == 2) return absi(gel(x,1));
    1295       33208 :   c = gel(x,1);
    1296       62097 :   for (i = 2; i < l; i++)
    1297             :   {
    1298       40012 :     c = gcdii(c, gel(x,i));
    1299       40012 :     if (is_pm1(c)) { avma = av; return gen_1; }
    1300             :   }
    1301       22085 :   return gerepileuptoint(av, c);
    1302             : }
    1303             : 
    1304             : GEN
    1305      987231 : ZM_det_triangular(GEN mat)
    1306             : {
    1307             :   pari_sp av;
    1308      987231 :   long i,l = lg(mat);
    1309             :   GEN s;
    1310             : 
    1311      987231 :   if (l<3) return l<2? gen_1: icopy(gcoeff(mat,1,1));
    1312      906511 :   av = avma; s = gcoeff(mat,1,1);
    1313      906511 :   for (i=2; i<l; i++) s = mulii(s,gcoeff(mat,i,i));
    1314      906511 :   return gerepileuptoint(av,s);
    1315             : }
    1316             : 
    1317             : /* assumes no overflow */
    1318             : long
    1319      340851 : zv_prod(GEN v)
    1320             : {
    1321      340851 :   long n, i, l = lg(v);
    1322      340851 :   if (l == 1) return 1;
    1323      251195 :   n = v[1]; for (i = 2; i < l; i++) n *= v[i];
    1324      251195 :   return n;
    1325             : }
    1326             : 
    1327             : static GEN
    1328   272805272 : _mulii(void *E, GEN a, GEN b)
    1329   272805272 : { (void) E; return mulii(a, b); }
    1330             : 
    1331             : /* product of ulongs */
    1332             : GEN
    1333      365685 : zv_prod_Z(GEN v)
    1334             : {
    1335      365685 :   pari_sp av = avma;
    1336      365685 :   long k, m, n = lg(v)-1;
    1337             :   GEN V;
    1338      365685 :   switch(n) {
    1339       19509 :     case 0: return gen_1;
    1340       56882 :     case 1: return utoi(v[1]);
    1341      125762 :     case 2: return muluu(v[1], v[2]);
    1342             :   }
    1343      163532 :   m = n >> 1;
    1344      163532 :   V = cgetg(m + (odd(n)? 2: 1), t_VEC);
    1345      163532 :   for (k = 1; k <= m; k++) gel(V,k) = muluu(v[k<<1], v[(k<<1)-1]);
    1346      163532 :   if (odd(n)) gel(V,k) = utoipos(v[n]);
    1347      163532 :   return gerepileuptoint(av, gen_product(V, NULL, &_mulii));
    1348             : }
    1349             : GEN
    1350    14694393 : vecsmall_prod(GEN v)
    1351             : {
    1352    14694393 :   pari_sp av = avma;
    1353    14694393 :   long k, m, n = lg(v)-1;
    1354             :   GEN V;
    1355    14694393 :   switch (n) {
    1356           0 :     case 0: return gen_1;
    1357           0 :     case 1: return stoi(v[1]);
    1358          21 :     case 2: return mulss(v[1], v[2]);
    1359             :   }
    1360    14694372 :   m = n >> 1;
    1361    14694372 :   V = cgetg(m + (odd(n)? 2: 1), t_VEC);
    1362    14694372 :   for (k = 1; k <= m; k++) gel(V,k) = mulss(v[k<<1], v[(k<<1)-1]);
    1363    14694372 :   if (odd(n)) gel(V,k) = stoi(v[n]);
    1364    14694372 :   return gerepileuptoint(av, gen_product(V, NULL, &_mulii));
    1365             : }
    1366             : 
    1367             : GEN
    1368     7468812 : ZV_prod(GEN v)
    1369             : {
    1370     7468812 :   pari_sp av = avma;
    1371     7468812 :   long i, l = lg(v);
    1372             :   GEN n;
    1373     7468812 :   if (l == 1) return gen_1;
    1374     7460349 :   if (l > 7) return gerepileuptoint(av, gen_product(v, NULL, _mulii));
    1375      111388 :   n = gel(v,1);
    1376      111388 :   if (l == 2) return icopy(n);
    1377       61128 :   for (i = 2; i < l; i++) n = mulii(n, gel(v,i));
    1378       61128 :   return gerepileuptoint(av, n);
    1379             : }
    1380             : /* assumes no overflow */
    1381             : long
    1382        1596 : zv_sum(GEN v)
    1383             : {
    1384        1596 :   long n, i, l = lg(v);
    1385        1596 :   if (l == 1) return 0;
    1386        1575 :   n = v[1]; for (i = 2; i < l; i++) n += v[i];
    1387        1575 :   return n;
    1388             : }
    1389             : GEN
    1390          56 : ZV_sum(GEN v)
    1391             : {
    1392          56 :   pari_sp av = avma;
    1393          56 :   long i, l = lg(v);
    1394             :   GEN n;
    1395          56 :   if (l == 1) return gen_0;
    1396          56 :   n = gel(v,1);
    1397          56 :   if (l == 2) return icopy(n);
    1398          56 :   for (i = 2; i < l; i++) n = addii(n, gel(v,i));
    1399          56 :   return gerepileuptoint(av, n);
    1400             : }
    1401             : 
    1402             : /********************************************************************/
    1403             : /**                                                                **/
    1404             : /**         GRAM SCHMIDT REDUCTION (integer matrices)              **/
    1405             : /**                                                                **/
    1406             : /********************************************************************/
    1407             : 
    1408             : /* L[k,] += q * L[l,], l < k. Inefficient if q = 0 */
    1409             : static void
    1410       52188 : Zupdate_row(long k, long l, GEN q, GEN L, GEN B)
    1411             : {
    1412       52188 :   long i, qq = itos_or_0(q);
    1413       52188 :   if (!qq)
    1414             :   {
    1415        2687 :     for(i=1;i<l;i++)  gcoeff(L,k,i) = addii(gcoeff(L,k,i),mulii(q,gcoeff(L,l,i)));
    1416        2687 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), mulii(q,B));
    1417       54875 :     return;
    1418             :   }
    1419       49501 :   if (qq == 1) {
    1420       13685 :     for (i=1;i<l; i++) gcoeff(L,k,i) = addii(gcoeff(L,k,i),gcoeff(L,l,i));
    1421       13685 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), B);
    1422       35816 :   } else if (qq == -1) {
    1423       11030 :     for (i=1;i<l; i++) gcoeff(L,k,i) = subii(gcoeff(L,k,i),gcoeff(L,l,i));
    1424       11030 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), negi(B));
    1425             :   } else {
    1426       24786 :     for(i=1;i<l;i++) gcoeff(L,k,i) = addii(gcoeff(L,k,i),mulsi(qq,gcoeff(L,l,i)));
    1427       24786 :     gcoeff(L,k,l) = addii(gcoeff(L,k,l), mulsi(qq,B));
    1428             :   }
    1429             : }
    1430             : 
    1431             : /* update L[k,] */
    1432             : static void
    1433      245788 : ZRED(long k, long l, GEN x, GEN L, GEN B)
    1434             : {
    1435      245788 :   GEN q = truedivii(addii(B,shifti(gcoeff(L,k,l),1)), shifti(B,1));
    1436      491576 :   if (!signe(q)) return;
    1437       52188 :   q = negi(q);
    1438       52188 :   Zupdate_row(k,l,q,L,B);
    1439       52188 :   gel(x,k) = ZC_lincomb(gen_1, q, gel(x,k), gel(x,l));
    1440             : }
    1441             : 
    1442             : /* Gram-Schmidt reduction, x a ZM */
    1443             : static void
    1444      311863 : ZincrementalGS(GEN x, GEN L, GEN B, long k)
    1445             : {
    1446             :   long i, j;
    1447     1108888 :   for (j=1; j<=k; j++)
    1448             :   {
    1449      797025 :     pari_sp av = avma;
    1450      797025 :     GEN u = ZV_dotproduct(gel(x,k), gel(x,j));
    1451     1776669 :     for (i=1; i<j; i++)
    1452             :     {
    1453      979644 :       u = subii(mulii(gel(B,i+1), u), mulii(gcoeff(L,k,i), gcoeff(L,j,i)));
    1454      979644 :       u = diviiexact(u, gel(B,i));
    1455             :     }
    1456      797025 :     gcoeff(L,k,j) = gerepileuptoint(av, u);
    1457             :   }
    1458      311863 :   gel(B,k+1) = gcoeff(L,k,k); gcoeff(L,k,k) = gen_1;
    1459      311863 : }
    1460             : 
    1461             : /* Variant reducemodinvertible(ZC v, ZM y), when y singular.
    1462             :  * Very inefficient if y is not LLL-reduced of maximal rank */
    1463             : static GEN
    1464       62505 : ZC_reducemodmatrix_i(GEN v, GEN y)
    1465             : {
    1466       62505 :   GEN B, L, x = shallowconcat(y, v);
    1467       62505 :   long k, lx = lg(x), nx = lx-1;
    1468             : 
    1469       62505 :   B = scalarcol_shallow(gen_1, lx);
    1470       62505 :   L = zeromatcopy(nx, nx);
    1471       62505 :   for (k=1; k <= nx; k++) ZincrementalGS(x, L, B, k);
    1472       62505 :   for (k = nx-1; k >= 1; k--) ZRED(nx,k, x,L,gel(B,k+1));
    1473       62505 :   return gel(x,nx);
    1474             : }
    1475             : GEN
    1476       62505 : ZC_reducemodmatrix(GEN v, GEN y) {
    1477       62505 :   pari_sp av = avma;
    1478       62505 :   return gerepilecopy(av, ZC_reducemodmatrix_i(v,y));
    1479             : }
    1480             : 
    1481             : /* Variant reducemodinvertible(ZM v, ZM y), when y singular.
    1482             :  * Very inefficient if y is not LLL-reduced of maximal rank */
    1483             : static GEN
    1484       21259 : ZM_reducemodmatrix_i(GEN v, GEN y)
    1485             : {
    1486             :   GEN B, L, V;
    1487       21259 :   long j, k, lv = lg(v), nx = lg(y), lx = nx+1;
    1488             : 
    1489       21259 :   V = cgetg(lv, t_MAT);
    1490       21259 :   B = scalarcol_shallow(gen_1, lx);
    1491       21259 :   L = zeromatcopy(nx, nx);
    1492       21259 :   for (k=1; k < nx; k++) ZincrementalGS(y, L, B, k);
    1493       61509 :   for (j = 1; j < lg(v); j++)
    1494             :   {
    1495       40250 :     GEN x = shallowconcat(y, gel(v,j));
    1496       40250 :     ZincrementalGS(x, L, B, nx); /* overwrite last */
    1497       40250 :     for (k = nx-1; k >= 1; k--) ZRED(nx,k, x,L,gel(B,k+1));
    1498       40250 :     gel(V,j) = gel(x,nx);
    1499             :   }
    1500       21259 :   return V;
    1501             : }
    1502             : GEN
    1503       21259 : ZM_reducemodmatrix(GEN v, GEN y) {
    1504       21259 :   pari_sp av = avma;
    1505       21259 :   return gerepilecopy(av, ZM_reducemodmatrix_i(v,y));
    1506             : }
    1507             : 
    1508             : GEN
    1509        9907 : ZC_reducemodlll(GEN x,GEN y)
    1510             : {
    1511        9907 :   pari_sp av = avma;
    1512        9907 :   GEN z = ZC_reducemodmatrix(x, ZM_lll(y, 0.75, LLL_INPLACE));
    1513        9907 :   return gerepilecopy(av, z);
    1514             : }
    1515             : GEN
    1516           0 : ZM_reducemodlll(GEN x,GEN y)
    1517             : {
    1518           0 :   pari_sp av = avma;
    1519           0 :   GEN z = ZM_reducemodmatrix(x, ZM_lll(y, 0.75, LLL_INPLACE));
    1520           0 :   return gerepilecopy(av, z);
    1521             : }

Generated by: LCOV version 1.11