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 to exceed 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 - RgV.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.13.0 lcov report (development 25825-edc109b529) Lines: 515 573 89.9 %
Date: 2020-09-21 06:08:33 Functions: 93 101 92.1 %
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             : int
      18      511921 : RgM_is_ZM(GEN x)
      19             : {
      20      511921 :   long i, j, h, l = lg(x);
      21      511921 :   if (l == 1) return 1;
      22      511683 :   h = lgcols(x);
      23      511683 :   if (h == 1) return 1;
      24     2285475 :   for (j = l-1; j > 0; j--)
      25    12104311 :     for (i = h-1; i > 0; i--)
      26    10330519 :       if (typ(gcoeff(x,i,j)) != t_INT) return 0;
      27      471484 :   return 1;
      28             : }
      29             : 
      30             : int
      31         203 : RgM_is_QM(GEN x)
      32             : {
      33         203 :   long i, j, h, l = lg(x);
      34         203 :   if (l == 1) return 1;
      35         189 :   h = lgcols(x);
      36         189 :   if (h == 1) return 1;
      37        1218 :   for (j = l-1; j > 0; j--)
      38       15057 :     for (i = h-1; i > 0; i--)
      39       14028 :       if (!is_rational_t(typ(gcoeff(x,i,j)))) return 0;
      40         175 :   return 1;
      41             : }
      42             : 
      43             : int
      44          35 : RgV_is_ZMV(GEN V)
      45             : {
      46          35 :   long i, l = lg(V);
      47         357 :   for (i=1; i<l; i++)
      48         322 :     if (typ(gel(V,i))!=t_MAT || !RgM_is_ZM(gel(V,i)))
      49           0 :       return 0;
      50          35 :   return 1;
      51             : }
      52             : 
      53             : /********************************************************************/
      54             : /**                                                                **/
      55             : /**                   GENERIC LINEAR ALGEBRA                       **/
      56             : /**                                                                **/
      57             : /********************************************************************/
      58             : /*           GENERIC  MULTIPLICATION involving zc/zm                */
      59             : 
      60             : /* x[i,] * y */
      61             : static GEN
      62     8875551 : RgMrow_zc_mul_i(GEN x, GEN y, long c, long i)
      63             : {
      64     8875551 :   pari_sp av = avma;
      65     8875551 :   GEN s = NULL;
      66             :   long j;
      67   858946990 :   for (j=1; j<c; j++)
      68             :   {
      69   850071439 :     long t = y[j];
      70   850071439 :     if (!t) continue;
      71    33097962 :     if (!s) { s = gmulgs(gcoeff(x,i,j),t); continue; }
      72    24298999 :     switch(t)
      73             :     {
      74    13116406 :       case  1: s = gadd(s, gcoeff(x,i,j)); break;
      75      233443 :       case -1: s = gsub(s, gcoeff(x,i,j)); break;
      76    10949150 :       default: s = gadd(s, gmulgs(gcoeff(x,i,j), t)); break;
      77             :     }
      78             :   }
      79     8875551 :   return s? gerepileupto(av, s): gc_const(av, gen_0);
      80             : }
      81             : GEN
      82       69937 : RgMrow_zc_mul(GEN x, GEN y, long i) { return RgMrow_zc_mul_i(x,y,lg(y),i); }
      83             : /* x non-empty t_MAT, y a compatible zc (dimension > 0). */
      84             : static GEN
      85      143812 : RgM_zc_mul_i(GEN x, GEN y, long c, long l)
      86             : {
      87      143812 :   GEN z = cgetg(l,t_COL);
      88             :   long i;
      89     8949426 :   for (i = 1; i < l; i++) gel(z,i) = RgMrow_zc_mul_i(x,y,c,i);
      90      143812 :   return z;
      91             : }
      92             : GEN
      93       71736 : RgM_zc_mul(GEN x, GEN y) { return RgM_zc_mul_i(x,y, lg(x), lgcols(x)); }
      94             : /* x t_MAT, y a compatible zm (dimension > 0). */
      95             : GEN
      96       19116 : RgM_zm_mul(GEN x, GEN y)
      97             : {
      98       19116 :   long j, c, l = lg(x), ly = lg(y);
      99       19116 :   GEN z = cgetg(ly, t_MAT);
     100       19116 :   if (l == 1) return z;
     101       19116 :   c = lgcols(x);
     102       91192 :   for (j = 1; j < ly; j++) gel(z,j) = RgM_zc_mul_i(x, gel(y,j), l,c);
     103       19116 :   return z;
     104             : }
     105             : 
     106             : /* x[i,]*y, l = lg(y) > 1 */
     107             : static GEN
     108     2835429 : RgMrow_ZC_mul_i(GEN x, GEN y, long i, long l)
     109             : {
     110     2835429 :   pari_sp av = avma;
     111     2835429 :   GEN t = gmul(gcoeff(x,i,1), gel(y,1)); /* l > 1 ! */
     112             :   long j;
     113   296244723 :   for (j=2; j<l; j++)
     114   293409294 :     if (signe(gel(y,j))) t = gadd(t, gmul(gcoeff(x,i,j), gel(y,j)));
     115     2835429 :   return gerepileupto(av,t);
     116             : }
     117             : 
     118             : /* compatible t_MAT * t_COL, lx = lg(x) = lg(y) > 1, l = lgcols(x) */
     119             : static GEN
     120      239276 : RgM_ZC_mul_i(GEN x, GEN y, long lx, long l)
     121             : {
     122      239276 :   GEN z = cgetg(l,t_COL);
     123             :   long i;
     124     3074705 :   for (i=1; i<l; i++) gel(z,i) = RgMrow_ZC_mul_i(x,y,i,lx);
     125      239276 :   return z;
     126             : }
     127             : 
     128             : /* mostly useful when y is sparse */
     129             : GEN
     130       46596 : RgM_ZM_mul(GEN x, GEN y)
     131             : {
     132       46596 :   long j, c, l = lg(x), ly = lg(y);
     133       46596 :   GEN z = cgetg(ly, t_MAT);
     134       46596 :   if (l == 1) return z;
     135       46596 :   c = lgcols(x);
     136      285872 :   for (j = 1; j < ly; j++) gel(z,j) = RgM_ZC_mul_i(x, gel(y,j), l,c);
     137       46596 :   return z;
     138             : }
     139             : 
     140             : static GEN
     141       38026 : RgV_zc_mul_i(GEN x, GEN y, long l)
     142             : {
     143             :   long i;
     144       38026 :   GEN z = gen_0;
     145       38026 :   pari_sp av = avma;
     146     4295503 :   for (i = 1; i < l; i++) z = gadd(z, gmulgs(gel(x,i), y[i]));
     147       38026 :   return gerepileupto(av, z);
     148             : }
     149             : GEN
     150        6804 : RgV_zc_mul(GEN x, GEN y) { return RgV_zc_mul_i(x, y, lg(x)); }
     151             : 
     152             : GEN
     153        7552 : RgV_zm_mul(GEN x, GEN y)
     154             : {
     155        7552 :   long j, l = lg(x), ly = lg(y);
     156        7552 :   GEN z = cgetg(ly, t_VEC);
     157       38774 :   for (j = 1; j < ly; j++) gel(z,j) = RgV_zc_mul_i(x, gel(y,j), l);
     158        7552 :   return z;
     159             : }
     160             : 
     161             : /* scalar product x.x */
     162             : GEN
     163        5132 : RgV_dotsquare(GEN x)
     164             : {
     165        5132 :   long i, lx = lg(x);
     166        5132 :   pari_sp av = avma;
     167             :   GEN z;
     168        5132 :   if (lx == 1) return gen_0;
     169        5132 :   z = gsqr(gel(x,1));
     170      669267 :   for (i=2; i<lx; i++)
     171             :   {
     172      664135 :     z = gadd(z, gsqr(gel(x,i)));
     173      664135 :     if (gc_needed(av,3))
     174             :     {
     175           0 :       if(DEBUGMEM>1) pari_warn(warnmem,"RgV_dotsquare, i = %ld",i);
     176           0 :       z = gerepileupto(av, z);
     177             :     }
     178             :   }
     179        5132 :   return gerepileupto(av,z);
     180             : }
     181             : 
     182             : /* scalar product x.y, lx = lg(x) = lg(y) */
     183             : static GEN
     184     2185826 : RgV_dotproduct_i(GEN x, GEN y, long lx)
     185             : {
     186     2185826 :   pari_sp av = avma;
     187             :   long i;
     188             :   GEN z;
     189     2185826 :   if (lx == 1) return gen_0;
     190     2185770 :   z = gmul(gel(x,1),gel(y,1));
     191    48760167 :   for (i=2; i<lx; i++)
     192             :   {
     193    46574390 :     z = gadd(z, gmul(gel(x,i), gel(y,i)));
     194    46574419 :     if (gc_needed(av,3))
     195             :     {
     196           0 :       if(DEBUGMEM>1) pari_warn(warnmem,"RgV_dotproduct, i = %ld",i);
     197           0 :       z = gerepileupto(av, z);
     198             :     }
     199             :   }
     200     2185777 :   return gerepileupto(av,z);
     201             : }
     202             : GEN
     203      163260 : RgV_dotproduct(GEN x,GEN y)
     204             : {
     205      163260 :   if (x == y) return RgV_dotsquare(x);
     206      163260 :   return RgV_dotproduct_i(x, y, lg(x));
     207             : }
     208             : /* v[1] + ... + v[lg(v)-1] */
     209             : GEN
     210      599878 : RgV_sum(GEN v)
     211             : {
     212             :   GEN p;
     213      599878 :   long i, l = lg(v);
     214      599878 :   if (l == 1) return gen_0;
     215     1582008 :   p = gel(v,1); for (i=2; i<l; i++) p = gadd(p, gel(v,i));
     216      599878 :   return p;
     217             : }
     218             : /* v[1] + ... + v[n]. Assume lg(v) > n. */
     219             : GEN
     220           0 : RgV_sumpart(GEN v, long n)
     221             : {
     222             :   GEN p;
     223             :   long i;
     224           0 :   if (!n) return gen_0;
     225           0 :   p = gel(v,1); for (i=2; i<=n; i++) p = gadd(p, gel(v,i));
     226           0 :   return p;
     227             : }
     228             : /* v[m] + ... + v[n]. Assume lg(v) > n, m > 0. */
     229             : GEN
     230           0 : RgV_sumpart2(GEN v, long m, long n)
     231             : {
     232             :   GEN p;
     233             :   long i;
     234           0 :   if (n < m) return gen_0;
     235           0 :   p = gel(v,m); for (i=m+1; i<=n; i++) p = gadd(p, gel(v,i));
     236           0 :   return p;
     237             : }
     238             : GEN
     239         362 : RgM_sumcol(GEN A)
     240             : {
     241         362 :   long i,j,m,l = lg(A);
     242             :   GEN v;
     243             : 
     244         362 :   if (l == 1) return cgetg(1,t_MAT);
     245         362 :   if (l == 2) return gcopy(gel(A,1));
     246         208 :   m = lgcols(A);
     247         208 :   v = cgetg(m, t_COL);
     248         680 :   for (i = 1; i < m; i++)
     249             :   {
     250         472 :     pari_sp av = avma;
     251         472 :     GEN s = gcoeff(A,i,1);
     252        1112 :     for (j = 2; j < l; j++) s = gadd(s, gcoeff(A,i,j));
     253         472 :     gel(v, i) = gerepileupto(av, s);
     254             :   }
     255         208 :   return v;
     256             : }
     257             : 
     258             : static GEN
     259      993811 : _gmul(void *data, GEN x, GEN y)
     260      993811 : { (void)data; return gmul(x,y); }
     261             : 
     262             : GEN
     263       69779 : RgV_prod(GEN x)
     264             : {
     265       69779 :   return gen_product(x, NULL, _gmul);
     266             : }
     267             : 
     268             : /*                    ADDITION SCALAR + MATRIX                     */
     269             : /* x square matrix, y scalar; create the square matrix x + y*Id */
     270             : GEN
     271        5725 : RgM_Rg_add(GEN x, GEN y)
     272             : {
     273        5725 :   long l = lg(x), i, j;
     274        5725 :   GEN z = cgetg(l,t_MAT);
     275             : 
     276        5725 :   if (l==1) return z;
     277        5725 :   if (l != lgcols(x)) pari_err_OP( "+", x, y);
     278        5725 :   z = cgetg(l,t_MAT);
     279       42564 :   for (i=1; i<l; i++)
     280             :   {
     281       36839 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     282       36839 :     gel(z,i) = zi;
     283     1893844 :     for (j=1; j<l; j++)
     284     1857005 :       gel(zi,j) = i==j? gadd(y,gel(xi,j)): gcopy(gel(xi,j));
     285             :   }
     286        5725 :   return z;
     287             : }
     288             : GEN
     289        7725 : RgM_Rg_sub(GEN x, GEN y)
     290             : {
     291        7725 :   long l = lg(x), i, j;
     292        7725 :   GEN z = cgetg(l,t_MAT);
     293             : 
     294        7725 :   if (l==1) return z;
     295        7725 :   if (l != lgcols(x)) pari_err_OP( "-", x, y);
     296        7725 :   z = cgetg(l,t_MAT);
     297       29780 :   for (i=1; i<l; i++)
     298             :   {
     299       22055 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     300       22055 :     gel(z,i) = zi;
     301      106790 :     for (j=1; j<l; j++)
     302       84735 :       gel(zi,j) = i==j? gsub(gel(xi,j), y): gcopy(gel(xi,j));
     303             :   }
     304        7725 :   return z;
     305             : }
     306             : GEN
     307         497 : RgM_Rg_add_shallow(GEN x, GEN y)
     308             : {
     309         497 :   long l = lg(x), i, j;
     310         497 :   GEN z = cgetg(l,t_MAT);
     311             : 
     312         497 :   if (l==1) return z;
     313         497 :   if (l != lgcols(x)) pari_err_OP( "+", x, y);
     314        1729 :   for (i=1; i<l; i++)
     315             :   {
     316        1232 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     317        1232 :     gel(z,i) = zi;
     318        8218 :     for (j=1; j<l; j++) gel(zi,j) = gel(xi,j);
     319        1232 :     gel(zi,i) = gadd(gel(zi,i), y);
     320             :   }
     321         497 :   return z;
     322             : }
     323             : GEN
     324      494033 : RgM_Rg_sub_shallow(GEN x, GEN y)
     325             : {
     326      494033 :   long l = lg(x), i, j;
     327      494033 :   GEN z = cgetg(l,t_MAT);
     328             : 
     329      494033 :   if (l==1) return z;
     330      494033 :   if (l != lgcols(x)) pari_err_OP( "-", x, y);
     331     2447968 :   for (i=1; i<l; i++)
     332             :   {
     333     1953935 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     334     1953935 :     gel(z,i) = zi;
     335    25660764 :     for (j=1; j<l; j++) gel(zi,j) = gel(xi,j);
     336     1953935 :     gel(zi,i) = gsub(gel(zi,i), y);
     337             :   }
     338      494033 :   return z;
     339             : }
     340             : 
     341             : GEN
     342     3562113 : RgC_Rg_add(GEN x, GEN y)
     343             : {
     344     3562113 :   long k, lx = lg(x);
     345     3562113 :   GEN z = cgetg(lx, t_COL);
     346     3562113 :   if (lx == 1)
     347             :   {
     348           0 :     if (isintzero(y)) return z;
     349           0 :     pari_err_TYPE2("+",x,y);
     350             :   }
     351     3562113 :   gel(z,1) = gadd(y,gel(x,1));
     352     8065944 :   for (k = 2; k < lx; k++) gel(z,k) = gcopy(gel(x,k));
     353     3562113 :   return z;
     354             : }
     355             : GEN
     356       25445 : RgC_Rg_sub(GEN x, GEN y)
     357             : {
     358       25445 :   long k, lx = lg(x);
     359       25445 :   GEN z = cgetg(lx, t_COL);
     360       25445 :   if (lx == 1)
     361             :   {
     362           0 :     if (isintzero(y)) return z;
     363           0 :     pari_err_TYPE2("-",x,y);
     364             :   }
     365       25445 :   gel(z,1) = gsub(gel(x,1), y);
     366       58394 :   for (k = 2; k < lx; k++) gel(z,k) = gcopy(gel(x,k));
     367       25445 :   return z;
     368             : }
     369             : /* a - x */
     370             : GEN
     371      109102 : Rg_RgC_sub(GEN a, GEN x)
     372             : {
     373      109102 :   long k, lx = lg(x);
     374      109102 :   GEN z = cgetg(lx,t_COL);
     375      109102 :   if (lx == 1)
     376             :   {
     377           0 :     if (isintzero(a)) return z;
     378           0 :     pari_err_TYPE2("-",a,x);
     379             :   }
     380      109102 :   gel(z,1) = gsub(a, gel(x,1));
     381      232848 :   for (k = 2; k < lx; k++) gel(z,k) = gneg(gel(x,k));
     382      109102 :   return z;
     383             : }
     384             : 
     385             : static GEN
     386    14644323 : RgC_add_i(GEN x, GEN y, long lx)
     387             : {
     388    14644323 :   GEN A = cgetg(lx, t_COL);
     389             :   long i;
     390   115960451 :   for (i=1; i<lx; i++) gel(A,i) = gadd(gel(x,i), gel(y,i));
     391    14644323 :   return A;
     392             : }
     393             : GEN
     394    11416343 : RgC_add(GEN x, GEN y) { return RgC_add_i(x, y, lg(x)); }
     395             : GEN
     396      163066 : RgV_add(GEN x, GEN y)
     397     2824029 : { pari_APPLY_type(t_VEC, gadd(gel(x,i), gel(y,i))) }
     398             : 
     399             : static GEN
     400     6149358 : RgC_sub_i(GEN x, GEN y, long lx)
     401             : {
     402             :   long i;
     403     6149358 :   GEN A = cgetg(lx, t_COL);
     404   622609494 :   for (i=1; i<lx; i++) gel(A,i) = gsub(gel(x,i), gel(y,i));
     405     6149358 :   return A;
     406             : }
     407             : GEN
     408     6049603 : RgC_sub(GEN x, GEN y) { return RgC_sub_i(x, y, lg(x)); }
     409             : GEN
     410      286477 : RgV_sub(GEN x, GEN y)
     411     2676422 : { pari_APPLY_type(t_VEC, gsub(gel(x,i), gel(y,i))) }
     412             : 
     413             : GEN
     414      675885 : RgM_add(GEN x, GEN y)
     415             : {
     416      675885 :   long lx = lg(x), l, j;
     417             :   GEN z;
     418      675885 :   if (lx == 1) return cgetg(1, t_MAT);
     419      675885 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     420     3903865 :   for (j = 1; j < lx; j++) gel(z,j) = RgC_add_i(gel(x,j), gel(y,j), l);
     421      675885 :   return z;
     422             : }
     423             : GEN
     424       35762 : RgM_sub(GEN x, GEN y)
     425             : {
     426       35762 :   long lx = lg(x), l, j;
     427             :   GEN z;
     428       35762 :   if (lx == 1) return cgetg(1, t_MAT);
     429       35762 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     430      135517 :   for (j = 1; j < lx; j++) gel(z,j) = RgC_sub_i(gel(x,j), gel(y,j), l);
     431       35762 :   return z;
     432             : }
     433             : 
     434             : static GEN
     435     3128551 : RgC_neg_i(GEN x, long lx)
     436             : {
     437             :   long i;
     438     3128551 :   GEN y = cgetg(lx, t_COL);
     439    26038625 :   for (i=1; i<lx; i++) gel(y,i) = gneg(gel(x,i));
     440     3128551 :   return y;
     441             : }
     442             : GEN
     443      160037 : RgC_neg(GEN x) { return RgC_neg_i(x, lg(x)); }
     444             : GEN
     445        3542 : RgV_neg(GEN x)
     446       56994 : { pari_APPLY_type(t_VEC, gneg(gel(x,i))) }
     447             : GEN
     448      536062 : RgM_neg(GEN x)
     449             : {
     450      536062 :   long i, hx, lx = lg(x);
     451      536062 :   GEN y = cgetg(lx, t_MAT);
     452      536062 :   if (lx == 1) return y;
     453      536055 :   hx = lgcols(x);
     454     3504569 :   for (i=1; i<lx; i++) gel(y,i) = RgC_neg_i(gel(x,i), hx);
     455      536055 :   return y;
     456             : }
     457             : 
     458             : GEN
     459     1164395 : RgV_RgC_mul(GEN x, GEN y)
     460             : {
     461     1164395 :   long lx = lg(x);
     462     1164395 :   if (lx != lg(y)) pari_err_OP("operation 'RgV_RgC_mul'", x, y);
     463     1164332 :   return RgV_dotproduct_i(x, y, lx);
     464             : }
     465             : GEN
     466        1687 : RgC_RgV_mul(GEN x, GEN y)
     467             : {
     468        1687 :   long i, ly = lg(y);
     469        1687 :   GEN z = cgetg(ly,t_MAT);
     470        5061 :   for (i=1; i<ly; i++) gel(z,i) = RgC_Rg_mul(x, gel(y,i));
     471        1687 :   return z;
     472             : }
     473             : GEN
     474           0 : RgC_RgM_mul(GEN x, GEN y)
     475             : {
     476           0 :   long i, ly = lg(y);
     477           0 :   GEN z = cgetg(ly,t_MAT);
     478           0 :   if (ly != 1 && lgcols(y) != 2) pari_err_OP("operation 'RgC_RgM_mul'",x,y);
     479           0 :   for (i=1; i<ly; i++) gel(z,i) = RgC_Rg_mul(x, gcoeff(y,1,i));
     480           0 :   return z;
     481             : }
     482             : GEN
     483           0 : RgM_RgV_mul(GEN x, GEN y)
     484             : {
     485           0 :   if (lg(x) != 2) pari_err_OP("operation 'RgM_RgV_mul'", x,y);
     486           0 :   return RgC_RgV_mul(gel(x,1), y);
     487             : }
     488             : 
     489             : /* x[i,]*y, l = lg(y) > 1 */
     490             : static GEN
     491    47526754 : RgMrow_RgC_mul_i(GEN x, GEN y, long i, long l)
     492             : {
     493    47526754 :   pari_sp av = avma;
     494    47526754 :   GEN t = gmul(gcoeff(x,i,1), gel(y,1)); /* l > 1 ! */
     495             :   long j;
     496   421390061 :   for (j=2; j<l; j++) t = gadd(t, gmul(gcoeff(x,i,j), gel(y,j)));
     497    47526754 :   return gerepileupto(av,t);
     498             : }
     499             : GEN
     500        4494 : RgMrow_RgC_mul(GEN x, GEN y, long i)
     501        4494 : { return RgMrow_RgC_mul_i(x, y, i, lg(x)); }
     502             : 
     503             : static GEN
     504          28 : RgM_RgC_mul_FpM(GEN x, GEN y, GEN p)
     505             : {
     506          28 :   pari_sp av = avma;
     507             :   GEN r;
     508          28 :   if (lgefint(p) == 3)
     509             :   {
     510          14 :     ulong pp = uel(p, 2);
     511          14 :     r = Flc_to_ZC_inplace(Flm_Flc_mul(RgM_to_Flm(x, pp),
     512             :                                   RgV_to_Flv(y, pp), pp));
     513             :   }
     514             :   else
     515          14 :     r = FpM_FpC_mul(RgM_to_FpM(x, p), RgC_to_FpC(y, p), p);
     516          28 :   return gerepileupto(av, FpC_to_mod(r, p));
     517             : }
     518             : 
     519             : static GEN
     520          14 : RgM_RgC_mul_FqM(GEN x, GEN y, GEN pol, GEN p)
     521             : {
     522          14 :   pari_sp av = avma;
     523          14 :   GEN b, T = RgX_to_FpX(pol, p);
     524          14 :   if (signe(T) == 0) pari_err_OP("*", x, y);
     525          14 :   b = FqM_FqC_mul(RgM_to_FqM(x, T, p), RgC_to_FqC(y, T, p), T, p);
     526          14 :   return gerepileupto(av, FqC_to_mod(b, T, p));
     527             : }
     528             : 
     529             : #define code(t1,t2) ((t1 << 6) | t2)
     530             : static GEN
     531    12889501 : RgM_RgC_mul_fast(GEN x, GEN y)
     532             : {
     533             :   GEN p, pol;
     534             :   long pa;
     535    12889501 :   long t = RgM_RgC_type(x,y, &p,&pol,&pa);
     536    12889501 :   switch(t)
     537             :   {
     538     7827307 :     case t_INT:    return ZM_ZC_mul(x,y);
     539      116198 :     case t_FRAC:   return QM_QC_mul(x,y);
     540          91 :     case t_FFELT:  return FFM_FFC_mul(x, y, pol);
     541          28 :     case t_INTMOD: return RgM_RgC_mul_FpM(x, y, p);
     542          14 :     case code(t_POLMOD, t_INTMOD):
     543          14 :                    return RgM_RgC_mul_FqM(x, y, pol, p);
     544     4945863 :     default:       return NULL;
     545             :   }
     546             : }
     547             : #undef code
     548             : 
     549             : /* compatible t_MAT * t_COL, lx = lg(x) = lg(y) > 1, l = lgcols(x) */
     550             : static GEN
     551    10246701 : RgM_RgC_mul_i(GEN x, GEN y, long lx, long l)
     552             : {
     553    10246701 :   GEN z = cgetg(l,t_COL);
     554             :   long i;
     555    57768961 :   for (i=1; i<l; i++) gel(z,i) = RgMrow_RgC_mul_i(x,y,i,lx);
     556    10246701 :   return z;
     557             : }
     558             : 
     559             : GEN
     560    12889501 : RgM_RgC_mul(GEN x, GEN y)
     561             : {
     562    12889501 :   long lx = lg(x);
     563             :   GEN z;
     564    12889501 :   if (lx != lg(y)) pari_err_OP("operation 'RgM_RgC_mul'", x,y);
     565    12889501 :   if (lx == 1) return cgetg(1,t_COL);
     566    12889501 :   z = RgM_RgC_mul_fast(x, y);
     567    12889501 :   if (z) return z;
     568     4945863 :   return RgM_RgC_mul_i(x, y, lx, lgcols(x));
     569             : }
     570             : 
     571             : GEN
     572       64833 : RgV_RgM_mul(GEN x, GEN y)
     573             : {
     574       64833 :   long i, lx, ly = lg(y);
     575             :   GEN z;
     576       64833 :   if (ly == 1) return cgetg(1,t_VEC);
     577       64826 :   lx = lg(x);
     578       64826 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgV_RgM_mul'", x,y);
     579       64819 :   z = cgetg(ly, t_VEC);
     580      918229 :   for (i=1; i<ly; i++) gel(z,i) = RgV_dotproduct_i(x, gel(y,i), lx);
     581       64819 :   return z;
     582             : }
     583             : 
     584             : static GEN
     585       56238 : RgM_mul_FpM(GEN x, GEN y, GEN p)
     586             : {
     587       56238 :   pari_sp av = avma;
     588             :   GEN r;
     589       56238 :   if (lgefint(p) == 3)
     590             :   {
     591       56166 :     ulong pp = uel(p, 2);
     592       56166 :     r = Flm_to_ZM_inplace(Flm_mul(RgM_to_Flm(x, pp),
     593             :                                   RgM_to_Flm(y, pp), pp));
     594             :   }
     595             :   else
     596          72 :     r = FpM_mul(RgM_to_FpM(x, p), RgM_to_FpM(y, p), p);
     597       56238 :   return gerepileupto(av, FpM_to_mod(r, p));
     598             : }
     599             : 
     600             : static GEN
     601       26019 : RgM_mul_FqM(GEN x, GEN y, GEN pol, GEN p)
     602             : {
     603       26019 :   pari_sp av = avma;
     604       26019 :   GEN b, T = RgX_to_FpX(pol, p);
     605       26019 :   if (signe(T) == 0) pari_err_OP("*", x, y);
     606       26019 :   b = FqM_mul(RgM_to_FqM(x, T, p), RgM_to_FqM(y, T, p), T, p);
     607       26019 :   return gerepileupto(av, FqM_to_mod(b, T, p));
     608             : }
     609             : 
     610             : static GEN
     611       14812 : RgM_liftred(GEN x, GEN T)
     612       14812 : { return RgXQM_red(liftpol_shallow(x), T); }
     613             : 
     614             : static GEN
     615        2765 : RgM_mul_ZXQM(GEN x, GEN y, GEN T)
     616             : {
     617        2765 :   pari_sp av = avma;
     618        2765 :   GEN b = ZXQM_mul(RgM_liftred(x,T), RgM_liftred(y, T), T);
     619        2765 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     620             : }
     621             : 
     622             : static GEN
     623         133 : RgM_sqr_ZXQM(GEN x, GEN T)
     624             : {
     625         133 :   pari_sp av = avma;
     626         133 :   GEN b = ZXQM_sqr(RgM_liftred(x, T), T);
     627         133 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     628             : }
     629             : 
     630             : static GEN
     631        4571 : RgM_mul_QXQM(GEN x, GEN y, GEN T)
     632             : {
     633        4571 :   pari_sp av = avma;
     634        4571 :   GEN b = QXQM_mul(RgM_liftred(x, T), RgM_liftred(y, T), T);
     635        4571 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     636             : }
     637             : 
     638             : static GEN
     639           7 : RgM_sqr_QXQM(GEN x, GEN T)
     640             : {
     641           7 :   pari_sp av = avma;
     642           7 :   GEN b = QXQM_sqr(RgM_liftred(x, T), T);
     643           7 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     644             : }
     645             : 
     646             : INLINE int
     647        4620 : RgX_is_monic_ZX(GEN pol)
     648        4620 : { return RgX_is_ZX(pol) && ZX_is_monic(pol); }
     649             : 
     650             : #define code(t1,t2) ((t1 << 6) | t2)
     651             : static GEN
     652     4898487 : RgM_mul_fast(GEN x, GEN y)
     653             : {
     654             :   GEN p, pol;
     655             :   long pa;
     656     4898487 :   long t = RgM_type2(x,y, &p,&pol,&pa);
     657     4898487 :   switch(t)
     658             :   {
     659     2652691 :     case t_INT:    return ZM_mul(x,y);
     660      139165 :     case t_FRAC:   return QM_mul(x,y);
     661        4200 :     case t_FFELT:  return FFM_mul(x, y, pol);
     662       56175 :     case t_INTMOD: return RgM_mul_FpM(x, y, p);
     663        2772 :     case code(t_POLMOD, t_INT):
     664        2772 :                    return ZX_is_monic(pol)? RgM_mul_ZXQM(x, y, pol): NULL;
     665        4592 :     case code(t_POLMOD, t_FRAC):
     666        4592 :                    return RgX_is_monic_ZX(pol)? RgM_mul_QXQM(x, y, pol): NULL;
     667       26019 :     case code(t_POLMOD, t_INTMOD):
     668       26019 :                    return RgM_mul_FqM(x, y, pol, p);
     669     2012873 :     default:       return NULL;
     670             :   }
     671             : }
     672             : 
     673             : static GEN
     674        1183 : RgM_sqr_fast(GEN x)
     675             : {
     676             :   GEN p, pol;
     677             :   long pa;
     678        1183 :   long t = RgM_type(x, &p,&pol,&pa);
     679        1183 :   switch(t)
     680             :   {
     681         126 :     case t_INT:    return ZM_sqr(x);
     682         700 :     case t_FRAC:   return QM_sqr(x);
     683         105 :     case t_FFELT:  return FFM_mul(x, x, pol);
     684          63 :     case t_INTMOD: return RgM_mul_FpM(x, x, p);
     685         140 :     case code(t_POLMOD, t_INT):
     686         140 :                    return ZX_is_monic(pol)? RgM_sqr_ZXQM(x, pol): NULL;
     687          28 :     case code(t_POLMOD, t_FRAC):
     688          28 :                    return RgX_is_monic_ZX(pol)? RgM_sqr_QXQM(x, pol): NULL;
     689           0 :     case code(t_POLMOD, t_INTMOD):
     690           0 :                    return RgM_mul_FqM(x, x, pol, p);
     691          21 :     default:       return NULL;
     692             :   }
     693             : }
     694             : 
     695             : #undef code
     696             : 
     697             : GEN
     698     4912774 : RgM_mul(GEN x, GEN y)
     699             : {
     700     4912774 :   long j, l, lx, ly = lg(y);
     701             :   GEN z;
     702     4912774 :   if (ly == 1) return cgetg(1,t_MAT);
     703     4898508 :   lx = lg(x);
     704     4898508 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgM_mul'", x,y);
     705     4898508 :   if (lx == 1) return zeromat(0,ly-1);
     706     4898487 :   z = RgM_mul_fast(x, y);
     707     4898487 :   if (z) return z;
     708     2012901 :   z = cgetg(ly, t_MAT);
     709     2012901 :   l = lgcols(x);
     710     7313522 :   for (j=1; j<ly; j++) gel(z,j) = RgM_RgC_mul_i(x, gel(y,j), lx, l);
     711     2012901 :   return z;
     712             : }
     713             : 
     714             : GEN
     715        1218 : RgM_sqr(GEN x)
     716             : {
     717        1218 :   long j, lx = lg(x);
     718             :   GEN z;
     719        1218 :   if (lx == 1) return cgetg(1, t_MAT);
     720        1183 :   if (lx != lgcols(x)) pari_err_OP("operation 'RgM_mul'", x,x);
     721        1183 :   z = RgM_sqr_fast(x);
     722        1183 :   if (z) return z;
     723          49 :   z = cgetg(lx, t_MAT);
     724         266 :   for (j=1; j<lx; j++) gel(z,j) = RgM_RgC_mul_i(x, gel(x,j), lx, lx);
     725          49 :   return z;
     726             : }
     727             : 
     728             : /* assume result is symmetric */
     729             : GEN
     730           0 : RgM_multosym(GEN x, GEN y)
     731             : {
     732           0 :   long j, lx, ly = lg(y);
     733             :   GEN M;
     734           0 :   if (ly == 1) return cgetg(1,t_MAT);
     735           0 :   lx = lg(x);
     736           0 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgM_multosym'", x,y);
     737           0 :   if (lx == 1) return cgetg(1,t_MAT);
     738           0 :   if (ly != lgcols(x)) pari_err_OP("operation 'RgM_multosym'", x,y);
     739           0 :   M = cgetg(ly, t_MAT);
     740           0 :   for (j=1; j<ly; j++)
     741             :   {
     742           0 :     GEN z = cgetg(ly,t_COL), yj = gel(y,j);
     743             :     long i;
     744           0 :     for (i=1; i<j; i++) gel(z,i) = gcoeff(M,j,i);
     745           0 :     for (i=j; i<ly; i++)gel(z,i) = RgMrow_RgC_mul_i(x,yj,i,lx);
     746           0 :     gel(M,j) = z;
     747             :   }
     748           0 :   return M;
     749             : }
     750             : /* x~ * y, assuming result is symmetric */
     751             : GEN
     752         503 : RgM_transmultosym(GEN x, GEN y)
     753             : {
     754         503 :   long i, j, l, ly = lg(y);
     755             :   GEN M;
     756         503 :   if (ly == 1) return cgetg(1,t_MAT);
     757         503 :   if (lg(x) != ly) pari_err_OP("operation 'RgM_transmultosym'", x,y);
     758         503 :   l = lgcols(y);
     759         503 :   if (lgcols(x) != l) pari_err_OP("operation 'RgM_transmultosym'", x,y);
     760         503 :   M = cgetg(ly, t_MAT);
     761        2236 :   for (i=1; i<ly; i++)
     762             :   {
     763        1733 :     GEN xi = gel(x,i), c = cgetg(ly,t_COL);
     764        1733 :     gel(M,i) = c;
     765        4733 :     for (j=1; j<i; j++)
     766        3000 :       gcoeff(M,i,j) = gel(c,j) = RgV_dotproduct_i(xi,gel(y,j),l);
     767        1733 :     gel(c,i) = RgV_dotproduct_i(xi,gel(y,i),l);
     768             :   }
     769         503 :   return M;
     770             : }
     771             : /* x~ * y */
     772             : GEN
     773           0 : RgM_transmul(GEN x, GEN y)
     774             : {
     775           0 :   long i, j, l, lx, ly = lg(y);
     776             :   GEN M;
     777           0 :   if (ly == 1) return cgetg(1,t_MAT);
     778           0 :   lx = lg(x);
     779           0 :   l = lgcols(y);
     780           0 :   if (lgcols(x) != l) pari_err_OP("operation 'RgM_transmul'", x,y);
     781           0 :   M = cgetg(ly, t_MAT);
     782           0 :   for (i=1; i<ly; i++)
     783             :   {
     784           0 :     GEN yi = gel(y,i), c = cgetg(lx,t_COL);
     785           0 :     gel(M,i) = c;
     786           0 :     for (j=1; j<lx; j++) gel(c,j) = RgV_dotproduct_i(yi,gel(x,j),l);
     787             :   }
     788           0 :   return M;
     789             : }
     790             : 
     791             : GEN
     792         119 : gram_matrix(GEN x)
     793             : {
     794         119 :   long i,j, l, lx = lg(x);
     795             :   GEN M;
     796         119 :   if (!is_matvec_t(typ(x))) pari_err_TYPE("gram",x);
     797         119 :   if (lx == 1) return cgetg(1,t_MAT);
     798         105 :   l = lgcols(x);
     799         105 :   M = cgetg(lx,t_MAT);
     800         294 :   for (i=1; i<lx; i++)
     801             :   {
     802         189 :     GEN xi = gel(x,i), c = cgetg(lx,t_COL);
     803         189 :     gel(M,i) = c;
     804         280 :     for (j=1; j<i; j++)
     805          91 :       gcoeff(M,i,j) = gel(c,j) = RgV_dotproduct_i(xi,gel(x,j),l);
     806         189 :     gel(c,i) = RgV_dotsquare(xi);
     807             :   }
     808         105 :   return M;
     809             : }
     810             : 
     811             : static GEN
     812        3542 : _RgM_add(void *E, GEN x, GEN y) { (void)E; return RgM_add(x, y); }
     813             : 
     814             : static GEN
     815           0 : _RgM_sub(void *E, GEN x, GEN y) { (void)E; return RgM_sub(x, y); }
     816             : 
     817             : static GEN
     818        5229 : _RgM_cmul(void *E, GEN P, long a, GEN x) { (void)E; return RgM_Rg_mul(x,gel(P,a+2)); }
     819             : 
     820             : static GEN
     821         238 : _RgM_sqr(void *E, GEN x) { (void) E; return RgM_sqr(x); }
     822             : 
     823             : static GEN
     824         686 : _RgM_mul(void *E, GEN x, GEN y) { (void) E; return RgM_mul(x, y); }
     825             : 
     826             : static GEN
     827        3591 : _RgM_one(void *E) { long *n = (long*) E; return matid(*n); }
     828             : 
     829             : static GEN
     830           0 : _RgM_zero(void *E) { long *n = (long*) E; return zeromat(*n,*n); }
     831             : 
     832             : static GEN
     833        2506 : _RgM_red(void *E, GEN x) { (void)E; return x; }
     834             : 
     835             : static struct bb_algebra RgM_algebra = { _RgM_red, _RgM_add, _RgM_sub,
     836             :        _RgM_mul, _RgM_sqr, _RgM_one, _RgM_zero };
     837             : 
     838             : /* generates the list of powers of x of degree 0,1,2,...,l*/
     839             : GEN
     840         168 : RgM_powers(GEN x, long l)
     841             : {
     842         168 :   long n = lg(x)-1;
     843         168 :   return gen_powers(x,l,1,(void *) &n, &_RgM_sqr, &_RgM_mul, &_RgM_one);
     844             : }
     845             : 
     846             : GEN
     847         490 : RgX_RgMV_eval(GEN Q, GEN x)
     848             : {
     849         490 :   long n = lg(x)>1 ? lg(gel(x,1))-1:0;
     850         490 :   return gen_bkeval_powers(Q,degpol(Q),x,(void*)&n,&RgM_algebra,&_RgM_cmul);
     851             : }
     852             : 
     853             : GEN
     854        1197 : RgX_RgM_eval(GEN Q, GEN x)
     855             : {
     856        1197 :   long n = lg(x)-1;
     857        1197 :   return gen_bkeval(Q,degpol(Q),x,1,(void*)&n,&RgM_algebra,&_RgM_cmul);
     858             : }
     859             : 
     860             : GEN
     861     1194335 : RgC_Rg_div(GEN x, GEN y)
     862     6244099 : { pari_APPLY_type(t_COL, gdiv(gel(x,i),y)) }
     863             : 
     864             : GEN
     865     6179283 : RgC_Rg_mul(GEN x, GEN y)
     866    36192873 : { pari_APPLY_type(t_COL, gmul(gel(x,i),y)) }
     867             : 
     868             : GEN
     869        6937 : RgV_Rg_mul(GEN x, GEN y)
     870      671405 : { pari_APPLY_type(t_VEC, gmul(gel(x,i),y)) }
     871             : 
     872             : GEN
     873      154064 : RgM_Rg_div(GEN X, GEN c) {
     874      154064 :   long i, j, h, l = lg(X);
     875      154064 :   GEN A = cgetg(l, t_MAT);
     876      154064 :   if (l == 1) return A;
     877      154064 :   h = lgcols(X);
     878     1027513 :   for (j=1; j<l; j++)
     879             :   {
     880      873449 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     881    10960351 :     for (i = 1; i < h; i++) gel(a,i) = gdiv(gel(x,i), c);
     882      873449 :     gel(A,j) = a;
     883             :   }
     884      154064 :   return A;
     885             : }
     886             : GEN
     887      154196 : RgM_Rg_mul(GEN X, GEN c) {
     888      154196 :   long i, j, h, l = lg(X);
     889      154196 :   GEN A = cgetg(l, t_MAT);
     890      154196 :   if (l == 1) return A;
     891      153839 :   h = lgcols(X);
     892      786268 :   for (j=1; j<l; j++)
     893             :   {
     894      632429 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     895     6180825 :     for (i = 1; i < h; i++) gel(a,i) = gmul(gel(x,i), c);
     896      632429 :     gel(A,j) = a;
     897             :   }
     898      153839 :   return A;
     899             : }
     900             : 
     901             : /********************************************************************/
     902             : /*                                                                  */
     903             : /*                    SCALAR TO MATRIX/VECTOR                       */
     904             : /*                                                                  */
     905             : /********************************************************************/
     906             : /* fill the square nxn matrix equal to t*Id */
     907             : static void
     908     6202018 : fill_scalmat(GEN y, GEN t, long n)
     909             : {
     910             :   long i;
     911    23848060 :   for (i = 1; i <= n; i++)
     912             :   {
     913    17645998 :     gel(y,i) = zerocol(n);
     914    17646042 :     gcoeff(y,i,i) = t;
     915             :   }
     916     6202062 : }
     917             : 
     918             : GEN
     919      446769 : scalarmat(GEN x, long n) {
     920      446769 :   GEN y = cgetg(n+1, t_MAT);
     921      446769 :   if (!n) return y;
     922      446769 :   fill_scalmat(y, gcopy(x), n); return y;
     923             : }
     924             : GEN
     925     2135238 : scalarmat_shallow(GEN x, long n) {
     926     2135238 :   GEN y = cgetg(n+1, t_MAT);
     927     2135245 :   fill_scalmat(y, x, n); return y;
     928             : }
     929             : GEN
     930         189 : scalarmat_s(long x, long n) {
     931         189 :   GEN y = cgetg(n+1, t_MAT);
     932         189 :   if (!n) return y;
     933         189 :   fill_scalmat(y, stoi(x), n); return y;
     934             : }
     935             : GEN
     936     3619825 : matid(long n) {
     937             :   GEN y;
     938     3619825 :   if (n < 0) pari_err_DOMAIN("matid", "size", "<", gen_0, stoi(n));
     939     3619818 :   y = cgetg(n+1, t_MAT);
     940     3619818 :   fill_scalmat(y, gen_1, n); return y;
     941             : }
     942             : 
     943             : INLINE GEN
     944      445221 : scalarcol_i(GEN x, long n, long c)
     945             : {
     946             :   long i;
     947      445221 :   GEN y = cgetg(n+1,t_COL);
     948      445221 :   if (!n) return y;
     949      445221 :   gel(y,1) = c? gcopy(x): x;
     950     1678709 :   for (i=2; i<=n; i++) gel(y,i) = gen_0;
     951      445221 :   return y;
     952             : }
     953             : 
     954             : GEN
     955      155035 : scalarcol(GEN x, long n) { return scalarcol_i(x,n,1); }
     956             : 
     957             : GEN
     958      290186 : scalarcol_shallow(GEN x, long n) { return scalarcol_i(x,n,0); }
     959             : 
     960             : int
     961       26894 : RgM_isscalar(GEN x, GEN s)
     962             : {
     963       26894 :   long i, j, lx = lg(x);
     964             : 
     965       26894 :   if (lx == 1) return 1;
     966       26894 :   if (lx != lgcols(x)) return 0;
     967       26894 :   if (!s) s = gcoeff(x,1,1);
     968             : 
     969       70826 :   for (j=1; j<lx; j++)
     970             :   {
     971       56490 :     GEN c = gel(x,j);
     972       78631 :     for (i=1; i<j; )
     973       33103 :       if (!gequal0(gel(c,i++))) return 0;
     974             :     /* i = j */
     975       45528 :     if (!gequal(gel(c,i++),s)) return 0;
     976       80325 :     for (   ; i<lx; )
     977       36393 :       if (!gequal0(gel(c,i++))) return 0;
     978             :   }
     979       14336 :   return 1;
     980             : }
     981             : 
     982             : int
     983       12187 : RgM_isidentity(GEN x)
     984             : {
     985       12187 :   long i,j, lx = lg(x);
     986             : 
     987       12187 :   if (lx == 1) return 1;
     988       12187 :   if (lx != lgcols(x)) return 0;
     989       16975 :   for (j=1; j<lx; j++)
     990             :   {
     991       16828 :     GEN c = gel(x,j);
     992       18725 :     for (i=1; i<j; )
     993        5306 :       if (!gequal0(gel(c,i++))) return 0;
     994             :     /* i = j */
     995       13419 :     if (!gequal1(gel(c,i++))) return 0;
     996       11088 :     for (   ; i<lx; )
     997        6300 :       if (!gequal0(gel(c,i++))) return 0;
     998             :   }
     999         147 :   return 1;
    1000             : }
    1001             : 
    1002             : long
    1003         308 : RgC_is_ei(GEN x)
    1004             : {
    1005         308 :   long i, j = 0, l = lg(x);
    1006        1792 :   for (i = 1; i < l; i++)
    1007             :   {
    1008        1484 :     GEN c = gel(x,i);
    1009        1484 :     if (gequal0(c)) continue;
    1010         308 :     if (!gequal1(c) || j) return 0;
    1011         308 :     j = i;
    1012             :   }
    1013         308 :   return j;
    1014             : }
    1015             : 
    1016             : int
    1017         336 : RgM_isdiagonal(GEN x)
    1018             : {
    1019         336 :   long i,j, lx = lg(x);
    1020         336 :   if (lx == 1) return 1;
    1021         336 :   if (lx != lgcols(x)) return 0;
    1022             : 
    1023        3220 :   for (j=1; j<lx; j++)
    1024             :   {
    1025        2891 :     GEN c = gel(x,j);
    1026       18452 :     for (i=1; i<j; i++)
    1027       15561 :       if (!gequal0(gel(c,i))) return 0;
    1028       18452 :     for (i++; i<lx; i++)
    1029       15568 :       if (!gequal0(gel(c,i))) return 0;
    1030             :   }
    1031         329 :   return 1;
    1032             : }
    1033             : int
    1034         315 : isdiagonal(GEN x) { return (typ(x)==t_MAT) && RgM_isdiagonal(x); }
    1035             : 
    1036             : GEN
    1037       16240 : RgM_det_triangular(GEN mat)
    1038             : {
    1039       16240 :   long i,l = lg(mat);
    1040             :   pari_sp av;
    1041             :   GEN s;
    1042             : 
    1043       16240 :   if (l<3) return l<2? gen_1: gcopy(gcoeff(mat,1,1));
    1044       14945 :   av = avma; s = gcoeff(mat,1,1);
    1045      100233 :   for (i=2; i<l; i++) s = gmul(s,gcoeff(mat,i,i));
    1046       14945 :   return av==avma? gcopy(s): gerepileupto(av,s);
    1047             : }
    1048             : 
    1049             : GEN
    1050       30856 : RgV_kill0(GEN v)
    1051             : {
    1052             :   long i, l;
    1053       30856 :   GEN w = cgetg_copy(v, &l);
    1054    12104609 :   for (i = 1; i < l; i++)
    1055             :   {
    1056    12074642 :     GEN a = gel(v,i);
    1057    12074642 :     gel(w,i) = gequal0(a) ? NULL: a;
    1058             :   }
    1059       29967 :   return w;
    1060             : }

Generated by: LCOV version 1.13