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.18.0 lcov report (development 29695-ed6e635faa) Lines: 509 578 88.1 %
Date: 2024-11-12 09:08:44 Functions: 95 104 91.3 %
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; either version 2 of the License, or (at your option) any later
       8             : version. It is distributed in the hope that it will be useful, but WITHOUT
       9             : ANY WARRANTY WHATSOEVER.
      10             : 
      11             : Check the License for details. You should have received a copy of it, along
      12             : with the package; see the file 'COPYING'. If not, write to the Free Software
      13             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      14             : 
      15             : #include "pari.h"
      16             : #include "paripriv.h"
      17             : 
      18             : int
      19     1243905 : RgM_is_ZM(GEN x)
      20             : {
      21     1243905 :   long i, j, h, l = lg(x);
      22     1243905 :   if (l == 1) return 1;
      23     1243240 :   h = lgcols(x);
      24     1243235 :   if (h == 1) return 1;
      25     4698412 :   for (j = l-1; j > 0; j--)
      26    22380496 :     for (i = h-1; i > 0; i--)
      27    18925158 :       if (typ(gcoeff(x,i,j)) != t_INT) return 0;
      28     1082893 :   return 1;
      29             : }
      30             : 
      31             : int
      32         203 : RgM_is_QM(GEN x)
      33             : {
      34         203 :   long i, j, h, l = lg(x);
      35         203 :   if (l == 1) return 1;
      36         189 :   h = lgcols(x);
      37         189 :   if (h == 1) return 1;
      38        1218 :   for (j = l-1; j > 0; j--)
      39       15057 :     for (i = h-1; i > 0; i--)
      40       14028 :       if (!is_rational_t(typ(gcoeff(x,i,j)))) return 0;
      41         175 :   return 1;
      42             : }
      43             : 
      44             : int
      45          49 : RgV_is_ZMV(GEN V)
      46             : {
      47          49 :   long i, l = lg(V);
      48         399 :   for (i=1; i<l; i++)
      49         350 :     if (typ(gel(V,i))!=t_MAT || !RgM_is_ZM(gel(V,i)))
      50           0 :       return 0;
      51          49 :   return 1;
      52             : }
      53             : 
      54             : /********************************************************************/
      55             : /**                                                                **/
      56             : /**                   GENERIC LINEAR ALGEBRA                       **/
      57             : /**                                                                **/
      58             : /********************************************************************/
      59             : /*           GENERIC  MULTIPLICATION involving zc/zm                */
      60             : 
      61             : /* x[i,] * y */
      62             : static GEN
      63     8289346 : RgMrow_zc_mul_i(GEN x, GEN y, long c, long i)
      64             : {
      65     8289346 :   pari_sp av = avma;
      66     8289346 :   GEN s = NULL;
      67             :   long j;
      68   828977485 :   for (j=1; j<c; j++)
      69             :   {
      70   820691825 :     long t = y[j];
      71   820691825 :     if (!t) continue;
      72    28444369 :     if (!s) { s = gmulgs(gcoeff(x,i,j),t); continue; }
      73    20368359 :     switch(t)
      74             :     {
      75    14793180 :       case  1: s = gadd(s, gcoeff(x,i,j)); break;
      76      239856 :       case -1: s = gsub(s, gcoeff(x,i,j)); break;
      77     5335323 :       default: s = gadd(s, gmulgs(gcoeff(x,i,j), t)); break;
      78             :     }
      79             :   }
      80     8285660 :   return s? gerepileupto(av, s): gc_const(av, gen_0);
      81             : }
      82             : GEN
      83       70028 : RgMrow_zc_mul(GEN x, GEN y, long i) { return RgMrow_zc_mul_i(x,y,lg(y),i); }
      84             : /* x nonempty t_MAT, y a compatible zc (dimension > 0). */
      85             : static GEN
      86      239051 : RgM_zc_mul_i(GEN x, GEN y, long c, long l)
      87             : {
      88      239051 :   GEN z = cgetg(l,t_COL);
      89             :   long i;
      90     8458353 :   for (i = 1; i < l; i++) gel(z,i) = RgMrow_zc_mul_i(x,y,c,i);
      91      239048 :   return z;
      92             : }
      93             : GEN
      94       71967 : RgM_zc_mul(GEN x, GEN y) { return RgM_zc_mul_i(x,y, lg(x), lgcols(x)); }
      95             : /* x t_MAT, y a compatible zm (dimension > 0). */
      96             : GEN
      97       56782 : RgM_zm_mul(GEN x, GEN y)
      98             : {
      99       56782 :   long j, c, l = lg(x), ly = lg(y);
     100       56782 :   GEN z = cgetg(ly, t_MAT);
     101       56782 :   if (l == 1) return z;
     102       56782 :   c = lgcols(x);
     103      223866 :   for (j = 1; j < ly; j++) gel(z,j) = RgM_zc_mul_i(x, gel(y,j), l,c);
     104       56782 :   return z;
     105             : }
     106             : 
     107             : /* x[i,]*y, l = lg(y) > 1 */
     108             : static GEN
     109    32308077 : RgMrow_ZC_mul_i(GEN x, GEN y, long i, long l)
     110             : {
     111    32308077 :   pari_sp av = avma;
     112    32308077 :   GEN t = gmul(gcoeff(x,i,1), gel(y,1)); /* l > 1 ! */
     113             :   long j;
     114  5020877189 :   for (j=2; j<l; j++)
     115  4988703837 :     if (signe(gel(y,j))) t = gadd(t, gmul(gcoeff(x,i,j), gel(y,j)));
     116    32173352 :   return gerepileupto(av,t);
     117             : }
     118             : 
     119             : /* compatible t_MAT * t_COL, lx = lg(x) = lg(y) > 1, l = lgcols(x) */
     120             : static GEN
     121     1927610 : RgM_ZC_mul_i(GEN x, GEN y, long lx, long l)
     122             : {
     123     1927610 :   GEN z = cgetg(l,t_COL);
     124             :   long i;
     125    34239279 :   for (i=1; i<l; i++) gel(z,i) = RgMrow_ZC_mul_i(x,y,i,lx);
     126     1925118 :   return z;
     127             : }
     128             : 
     129             : GEN
     130     1927640 : RgM_ZM_mul_worker(GEN y, GEN x)
     131     1927640 : { return RgM_ZC_mul_i(x, y, lg(x), lgcols(x)); }
     132             : 
     133             : /* mostly useful when y is sparse */
     134             : GEN
     135      354666 : RgM_ZM_mul(GEN x, GEN y)
     136             : {
     137      354666 :   pari_sp av = avma;
     138             :   GEN worker;
     139      354666 :   if (lg(x) == 1) return cgetg(lg(y), t_MAT);
     140      354666 :   worker = snm_closure(is_entry("_RgM_ZM_mul_worker"),mkvec(x));
     141      354671 :   return gerepileupto(av, gen_parapply(worker, y));
     142             : }
     143             : 
     144             : static GEN
     145      209918 : RgV_zc_mul_i(GEN x, GEN y, long l)
     146             : {
     147             :   long i;
     148      209918 :   GEN z = gen_0;
     149      209918 :   pari_sp av = avma;
     150     8212225 :   for (i = 1; i < l; i++) z = gadd(z, gmulgs(gel(x,i), y[i]));
     151      209915 :   return gerepileupto(av, z);
     152             : }
     153             : GEN
     154       83384 : RgV_zc_mul(GEN x, GEN y) { return RgV_zc_mul_i(x, y, lg(x)); }
     155             : 
     156             : GEN
     157       34193 : RgV_zm_mul(GEN x, GEN y)
     158             : {
     159       34193 :   long j, l = lg(x), ly = lg(y);
     160       34193 :   GEN z = cgetg(ly, t_VEC);
     161      160727 :   for (j = 1; j < ly; j++) gel(z,j) = RgV_zc_mul_i(x, gel(y,j), l);
     162       34193 :   return z;
     163             : }
     164             : 
     165             : /* scalar product x.x */
     166             : GEN
     167     9441206 : RgV_dotsquare(GEN x)
     168             : {
     169     9441206 :   long i, lx = lg(x);
     170     9441206 :   pari_sp av = avma;
     171             :   GEN z;
     172     9441206 :   if (lx == 1) return gen_0;
     173     9441206 :   z = gsqr(gel(x,1));
     174    21152077 :   for (i=2; i<lx; i++)
     175             :   {
     176    11711103 :     z = gadd(z, gsqr(gel(x,i)));
     177    11711023 :     if (gc_needed(av,3))
     178             :     {
     179           0 :       if(DEBUGMEM>1) pari_warn(warnmem,"RgV_dotsquare, i = %ld",i);
     180           0 :       z = gerepileupto(av, z);
     181             :     }
     182             :   }
     183     9440974 :   return gerepileupto(av,z);
     184             : }
     185             : 
     186             : /* scalar product x.y, lx = lg(x) = lg(y) */
     187             : static GEN
     188    13591694 : RgV_dotproduct_i(GEN x, GEN y, long lx)
     189             : {
     190    13591694 :   pari_sp av = avma;
     191             :   long i;
     192             :   GEN z;
     193    13591694 :   if (lx == 1) return gen_0;
     194    13591295 :   z = gmul(gel(x,1),gel(y,1));
     195   218970672 :   for (i=2; i<lx; i++)
     196             :   {
     197   205382026 :     z = gadd(z, gmul(gel(x,i), gel(y,i)));
     198   205382044 :     if (gc_needed(av,3))
     199             :     {
     200           0 :       if(DEBUGMEM>1) pari_warn(warnmem,"RgV_dotproduct, i = %ld",i);
     201           0 :       z = gerepileupto(av, z);
     202             :     }
     203             :   }
     204    13588646 :   return gerepileupto(av,z);
     205             : }
     206             : GEN
     207     1009450 : RgV_dotproduct(GEN x,GEN y)
     208             : {
     209     1009450 :   if (x == y) return RgV_dotsquare(x);
     210     1009450 :   return RgV_dotproduct_i(x, y, lg(x));
     211             : }
     212             : /* v[1] + ... + v[lg(v)-1] */
     213             : GEN
     214     3032228 : RgV_sum(GEN v)
     215             : {
     216             :   GEN p;
     217     3032228 :   long i, l = lg(v);
     218     3032228 :   if (l == 1) return gen_0;
     219     7379527 :   p = gel(v,1); for (i=2; i<l; i++) p = gadd(p, gel(v,i));
     220     3032188 :   return p;
     221             : }
     222             : /* v[1] + ... + v[n]. Assume lg(v) > n. */
     223             : GEN
     224           0 : RgV_sumpart(GEN v, long n)
     225             : {
     226             :   GEN p;
     227             :   long i;
     228           0 :   if (!n) return gen_0;
     229           0 :   p = gel(v,1); for (i=2; i<=n; i++) p = gadd(p, gel(v,i));
     230           0 :   return p;
     231             : }
     232             : /* v[m] + ... + v[n]. Assume lg(v) > n, m > 0. */
     233             : GEN
     234           0 : RgV_sumpart2(GEN v, long m, long n)
     235             : {
     236             :   GEN p;
     237             :   long i;
     238           0 :   if (n < m) return gen_0;
     239           0 :   p = gel(v,m); for (i=m+1; i<=n; i++) p = gadd(p, gel(v,i));
     240           0 :   return p;
     241             : }
     242             : GEN
     243         400 : RgM_sumcol(GEN A)
     244             : {
     245         400 :   long i,j,m,l = lg(A);
     246             :   GEN v;
     247             : 
     248         400 :   if (l == 1) return cgetg(1,t_MAT);
     249         400 :   if (l == 2) return gcopy(gel(A,1));
     250         216 :   m = lgcols(A);
     251         216 :   v = cgetg(m, t_COL);
     252         718 :   for (i = 1; i < m; i++)
     253             :   {
     254         502 :     pari_sp av = avma;
     255         502 :     GEN s = gcoeff(A,i,1);
     256        1214 :     for (j = 2; j < l; j++) s = gadd(s, gcoeff(A,i,j));
     257         502 :     gel(v, i) = gerepileupto(av, s);
     258             :   }
     259         216 :   return v;
     260             : }
     261             : 
     262             : static GEN
     263     3335131 : _gmul(void *data, GEN x, GEN y)
     264     3335131 : { (void)data; return gmul(x,y); }
     265             : 
     266             : GEN
     267      451819 : RgV_prod(GEN x)
     268             : {
     269      451819 :   return gen_product(x, NULL, _gmul);
     270             : }
     271             : 
     272             : /*                    ADDITION SCALAR + MATRIX                     */
     273             : /* x square matrix, y scalar; create the square matrix x + y*Id */
     274             : GEN
     275        7874 : RgM_Rg_add(GEN x, GEN y)
     276             : {
     277        7874 :   long l = lg(x), i, j;
     278        7874 :   GEN z = cgetg(l,t_MAT);
     279             : 
     280        7874 :   if (l==1) return z;
     281        7874 :   if (l != lgcols(x)) pari_err_OP("+", x, y);
     282       58132 :   for (i=1; i<l; i++)
     283             :   {
     284       50258 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     285       50258 :     gel(z,i) = zi;
     286     2058760 :     for (j=1; j<l; j++)
     287     2008502 :       gel(zi,j) = i==j? gadd(y,gel(xi,j)): gcopy(gel(xi,j));
     288             :   }
     289        7874 :   return z;
     290             : }
     291             : GEN
     292           0 : RgM_Rg_sub(GEN x, GEN y)
     293             : {
     294           0 :   long l = lg(x), i, j;
     295           0 :   GEN z = cgetg(l,t_MAT);
     296             : 
     297           0 :   if (l==1) return z;
     298           0 :   if (l != lgcols(x)) pari_err_OP("-", x, y);
     299           0 :   for (i=1; i<l; i++)
     300             :   {
     301           0 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     302           0 :     gel(z,i) = zi;
     303           0 :     for (j=1; j<l; j++)
     304           0 :       gel(zi,j) = i==j? gsub(gel(xi,j), y): gcopy(gel(xi,j));
     305             :   }
     306           0 :   return z;
     307             : }
     308             : GEN
     309         739 : RgM_Rg_add_shallow(GEN x, GEN y)
     310             : {
     311         739 :   long l = lg(x), i, j;
     312         739 :   GEN z = cgetg(l,t_MAT);
     313             : 
     314         739 :   if (l==1) return z;
     315         739 :   if (l != lgcols(x)) pari_err_OP( "+", x, y);
     316        2384 :   for (i=1; i<l; i++)
     317             :   {
     318        1645 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     319        1645 :     gel(z,i) = zi;
     320        9456 :     for (j=1; j<l; j++) gel(zi,j) = gel(xi,j);
     321        1645 :     gel(zi,i) = gadd(gel(zi,i), y);
     322             :   }
     323         739 :   return z;
     324             : }
     325             : GEN
     326      312562 : RgM_Rg_sub_shallow(GEN x, GEN y)
     327             : {
     328      312562 :   long l = lg(x), i, j;
     329      312562 :   GEN z = cgetg(l,t_MAT);
     330             : 
     331      312562 :   if (l==1) return z;
     332      312562 :   if (l != lgcols(x)) pari_err_OP( "-", x, y);
     333     2015179 :   for (i=1; i<l; i++)
     334             :   {
     335     1702636 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     336     1702636 :     gel(z,i) = zi;
     337    27145064 :     for (j=1; j<l; j++) gel(zi,j) = gel(xi,j);
     338     1702636 :     gel(zi,i) = gsub(gel(zi,i), y);
     339             :   }
     340      312543 :   return z;
     341             : }
     342             : 
     343             : GEN
     344     5182680 : RgC_Rg_add(GEN x, GEN y)
     345             : {
     346     5182680 :   long k, lx = lg(x);
     347     5182680 :   GEN z = cgetg(lx, t_COL);
     348     5182681 :   if (lx == 1)
     349             :   {
     350           0 :     if (isintzero(y)) return z;
     351           0 :     pari_err_TYPE2("+",x,y);
     352             :   }
     353     5182681 :   gel(z,1) = gadd(y,gel(x,1));
     354    13028189 :   for (k = 2; k < lx; k++) gel(z,k) = gcopy(gel(x,k));
     355     5182680 :   return z;
     356             : }
     357             : GEN
     358       42043 : RgC_Rg_sub(GEN x, GEN y)
     359             : {
     360       42043 :   long k, lx = lg(x);
     361       42043 :   GEN z = cgetg(lx, t_COL);
     362       42043 :   if (lx == 1)
     363             :   {
     364           0 :     if (isintzero(y)) return z;
     365           0 :     pari_err_TYPE2("-",x,y);
     366             :   }
     367       42043 :   gel(z,1) = gsub(gel(x,1), y);
     368      108421 :   for (k = 2; k < lx; k++) gel(z,k) = gcopy(gel(x,k));
     369       42043 :   return z;
     370             : }
     371             : /* a - x */
     372             : GEN
     373      135442 : Rg_RgC_sub(GEN a, GEN x)
     374             : {
     375      135442 :   long k, lx = lg(x);
     376      135442 :   GEN z = cgetg(lx,t_COL);
     377      135442 :   if (lx == 1)
     378             :   {
     379           0 :     if (isintzero(a)) return z;
     380           0 :     pari_err_TYPE2("-",a,x);
     381             :   }
     382      135442 :   gel(z,1) = gsub(a, gel(x,1));
     383      305962 :   for (k = 2; k < lx; k++) gel(z,k) = gneg(gel(x,k));
     384      135442 :   return z;
     385             : }
     386             : 
     387             : static GEN
     388    19432101 : RgC_add_i(GEN x, GEN y, long lx)
     389             : {
     390    19432101 :   GEN A = cgetg(lx, t_COL);
     391             :   long i;
     392   144445644 :   for (i=1; i<lx; i++) gel(A,i) = gadd(gel(x,i), gel(y,i));
     393    19431856 :   return A;
     394             : }
     395             : GEN
     396    16166082 : RgC_add(GEN x, GEN y) { return RgC_add_i(x, y, lg(x)); }
     397             : GEN
     398     2521465 : RgV_add(GEN x, GEN y)
     399    10384543 : { pari_APPLY_type(t_VEC, gadd(gel(x,i), gel(y,i))) }
     400             : 
     401             : static GEN
     402     5995906 : RgC_sub_i(GEN x, GEN y, long lx)
     403             : {
     404             :   long i;
     405     5995906 :   GEN A = cgetg(lx, t_COL);
     406   635036903 :   for (i=1; i<lx; i++) gel(A,i) = gsub(gel(x,i), gel(y,i));
     407     5994721 :   return A;
     408             : }
     409             : GEN
     410     5095323 : RgC_sub(GEN x, GEN y) { return RgC_sub_i(x, y, lg(x)); }
     411             : GEN
     412      356260 : RgV_sub(GEN x, GEN y)
     413     3020572 : { pari_APPLY_type(t_VEC, gsub(gel(x,i), gel(y,i))) }
     414             : 
     415             : GEN
     416      690732 : RgM_add(GEN x, GEN y)
     417             : {
     418      690732 :   long lx = lg(x), l, j;
     419             :   GEN z;
     420      690732 :   if (lx == 1) return cgetg(1, t_MAT);
     421      690732 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     422     3956750 :   for (j = 1; j < lx; j++) gel(z,j) = RgC_add_i(gel(x,j), gel(y,j), l);
     423      690732 :   return z;
     424             : }
     425             : GEN
     426      172349 : RgM_sub(GEN x, GEN y)
     427             : {
     428      172349 :   long lx = lg(x), l, j;
     429             :   GEN z;
     430      172349 :   if (lx == 1) return cgetg(1, t_MAT);
     431      172349 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     432     1072964 :   for (j = 1; j < lx; j++) gel(z,j) = RgC_sub_i(gel(x,j), gel(y,j), l);
     433      172350 :   return z;
     434             : }
     435             : 
     436             : static GEN
     437     3974467 : RgC_neg_i(GEN x, long lx)
     438             : {
     439             :   long i;
     440     3974467 :   GEN y = cgetg(lx, t_COL);
     441    30152972 :   for (i=1; i<lx; i++) gel(y,i) = gneg(gel(x,i));
     442     3974463 :   return y;
     443             : }
     444             : GEN
     445      990229 : RgC_neg(GEN x) { return RgC_neg_i(x, lg(x)); }
     446             : GEN
     447        4515 : RgV_neg(GEN x)
     448       60473 : { pari_APPLY_type(t_VEC, gneg(gel(x,i))) }
     449             : GEN
     450      541274 : RgM_neg(GEN x)
     451             : {
     452      541274 :   long i, hx, lx = lg(x);
     453      541274 :   GEN y = cgetg(lx, t_MAT);
     454      541274 :   if (lx == 1) return y;
     455      541267 :   hx = lgcols(x);
     456     3525504 :   for (i=1; i<lx; i++) gel(y,i) = RgC_neg_i(gel(x,i), hx);
     457      541267 :   return y;
     458             : }
     459             : 
     460             : GEN
     461     4717187 : RgV_RgC_mul(GEN x, GEN y)
     462             : {
     463     4717187 :   long lx = lg(x);
     464     4717187 :   if (lx != lg(y)) pari_err_OP("operation 'RgV_RgC_mul'", x, y);
     465     4717103 :   return RgV_dotproduct_i(x, y, lx);
     466             : }
     467             : GEN
     468        1687 : RgC_RgV_mul(GEN x, GEN y)
     469             : {
     470        1687 :   long i, ly = lg(y);
     471        1687 :   GEN z = cgetg(ly,t_MAT);
     472        5061 :   for (i=1; i<ly; i++) gel(z,i) = RgC_Rg_mul(x, gel(y,i));
     473        1687 :   return z;
     474             : }
     475             : GEN
     476           0 : RgC_RgM_mul(GEN x, GEN y)
     477             : {
     478           0 :   long i, ly = lg(y);
     479           0 :   GEN z = cgetg(ly,t_MAT);
     480           0 :   if (ly != 1 && lgcols(y) != 2) pari_err_OP("operation 'RgC_RgM_mul'",x,y);
     481           0 :   for (i=1; i<ly; i++) gel(z,i) = RgC_Rg_mul(x, gcoeff(y,1,i));
     482           0 :   return z;
     483             : }
     484             : GEN
     485           0 : RgM_RgV_mul(GEN x, GEN y)
     486             : {
     487           0 :   if (lg(x) != 2) pari_err_OP("operation 'RgM_RgV_mul'", x,y);
     488           0 :   return RgC_RgV_mul(gel(x,1), y);
     489             : }
     490             : 
     491             : /* x[i,]*y, l = lg(y) > 1 */
     492             : static GEN
     493   115762749 : RgMrow_RgC_mul_i(GEN x, GEN y, long i, long l)
     494             : {
     495   115762749 :   pari_sp av = avma;
     496   115762749 :   GEN t = gmul(gcoeff(x,i,1), gel(y,1)); /* l > 1 ! */
     497             :   long j;
     498   985195097 :   for (j=2; j<l; j++)
     499             :   {
     500   869435997 :     GEN c = gcoeff(x,i,j);
     501   869435997 :     if (!isintzero(c)) t = gadd(t, gmul(c, gel(y,j)));
     502             :   }
     503   115759100 :   return gerepileupto(av,t);
     504             : }
     505             : GEN
     506        4641 : RgMrow_RgC_mul(GEN x, GEN y, long i)
     507        4641 : { return RgMrow_RgC_mul_i(x, y, i, lg(x)); }
     508             : 
     509             : static GEN
     510          28 : RgM_RgC_mul_FpM(GEN x, GEN y, GEN p)
     511             : {
     512          28 :   pari_sp av = avma;
     513             :   GEN r;
     514          28 :   if (lgefint(p) == 3)
     515             :   {
     516          14 :     ulong pp = uel(p, 2);
     517          14 :     r = Flm_Flc_mul(RgM_to_Flm(x, pp), RgV_to_Flv(y, pp), pp);
     518          14 :     r = Flc_to_ZC_inplace(r);
     519             :   }
     520             :   else
     521          14 :     r = FpM_FpC_mul(RgM_to_FpM(x, p), RgC_to_FpC(y, p), p);
     522          28 :   return gerepileupto(av, FpC_to_mod(r, p));
     523             : }
     524             : 
     525             : static GEN
     526          28 : RgM_RgC_mul_FqM(GEN x, GEN y, GEN pol, GEN p)
     527             : {
     528          28 :   pari_sp av = avma;
     529          28 :   GEN b, T = RgX_to_FpX(pol, p);
     530          28 :   if (signe(T) == 0) pari_err_OP("*", x, y);
     531          28 :   b = FqM_FqC_mul(RgM_to_FqM(x, T, p), RgC_to_FqC(y, T, p), T, p);
     532          28 :   return gerepileupto(av, FqC_to_mod(b, T, p));
     533             : }
     534             : 
     535             : #define code(t1,t2) ((t1 << 6) | t2)
     536             : static GEN
     537    31178915 : RgM_RgC_mul_fast(GEN x, GEN y)
     538             : {
     539             :   GEN p, pol;
     540             :   long pa;
     541    31178915 :   long t = RgM_RgC_type(x,y, &p,&pol,&pa);
     542    31179187 :   switch(t)
     543             :   {
     544     8823484 :     case t_INT:    return ZM_ZC_mul(x,y);
     545      142572 :     case t_FRAC:   return QM_QC_mul(x,y);
     546          91 :     case t_FFELT:  return FFM_FFC_mul(x, y, pol);
     547          28 :     case t_INTMOD: return RgM_RgC_mul_FpM(x, y, p);
     548          26 :     case code(t_POLMOD, t_INTMOD):
     549          26 :                    return RgM_RgC_mul_FqM(x, y, pol, p);
     550    22212986 :     default:       return NULL;
     551             :   }
     552             : }
     553             : #undef code
     554             : 
     555             : /* compatible t_MAT * t_COL, lx = lg(x) = lg(y) > 1, l = lgcols(x) */
     556             : static GEN
     557    33991527 : RgM_RgC_mul_i(GEN x, GEN y, long lx, long l)
     558             : {
     559    33991527 :   GEN z = cgetg(l,t_COL);
     560             :   long i;
     561   149744898 :   for (i=1; i<l; i++) gel(z,i) = RgMrow_RgC_mul_i(x,y,i,lx);
     562    33987355 :   return z;
     563             : }
     564             : 
     565             : GEN
     566    31178912 : RgM_RgC_mul(GEN x, GEN y)
     567             : {
     568    31178912 :   long lx = lg(x);
     569             :   GEN z;
     570    31178912 :   if (lx != lg(y)) pari_err_OP("operation 'RgM_RgC_mul'", x,y);
     571    31178916 :   if (lx == 1) return cgetg(1,t_COL);
     572    31178916 :   z = RgM_RgC_mul_fast(x, y);
     573    31179177 :   if (z) return z;
     574    22212974 :   return RgM_RgC_mul_i(x, y, lx, lgcols(x));
     575             : }
     576             : 
     577             : GEN
     578      295172 : RgV_RgM_mul(GEN x, GEN y)
     579             : {
     580      295172 :   long i, lx, ly = lg(y);
     581             :   GEN z;
     582      295172 :   if (ly == 1) return cgetg(1,t_VEC);
     583      295165 :   lx = lg(x);
     584      295165 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgV_RgM_mul'", x,y);
     585      295158 :   z = cgetg(ly, t_VEC);
     586     3421476 :   for (i=1; i<ly; i++) gel(z,i) = RgV_dotproduct_i(x, gel(y,i), lx);
     587      295097 :   return z;
     588             : }
     589             : 
     590             : static GEN
     591       57148 : RgM_mul_FpM_i(GEN x, GEN y, GEN p)
     592             : {
     593       57148 :   if (lgefint(p) == 3)
     594             :   {
     595       57076 :     ulong pp = uel(p, 2);
     596       57076 :     if (pp==2) return F2m_to_mod(F2m_mul(RgM_to_F2m(x), RgM_to_F2m(y)));
     597       57027 :     if (pp==3) return F3m_to_mod(F3m_mul(RgM_to_F3m(x), RgM_to_F3m(y)));
     598       56873 :     return Flm_to_mod(Flm_mul(RgM_to_Flm(x, pp), RgM_to_Flm(y, pp), pp), pp);
     599             :   }
     600          72 :   return FpM_to_mod(FpM_mul(RgM_to_FpM(x,p), RgM_to_FpM(y,p), p), p);
     601             : }
     602             : static GEN
     603       57148 : RgM_mul_FpM(GEN x, GEN y, GEN p)
     604       57148 : { pari_sp av = avma; return gerepileupto(av, RgM_mul_FpM_i(x, y, p)); }
     605             : 
     606             : static GEN
     607       26005 : RgM_mul_FqM(GEN x, GEN y, GEN pol, GEN p)
     608             : {
     609       26005 :   pari_sp av = avma;
     610       26005 :   GEN b, T = RgX_to_FpX(pol, p);
     611       26005 :   if (signe(T) == 0) pari_err_OP("*", x, y);
     612       26005 :   b = FqM_mul(RgM_to_FqM(x, T, p), RgM_to_FqM(y, T, p), T, p);
     613       26005 :   return gerepileupto(av, FqM_to_mod(b, T, p));
     614             : }
     615             : 
     616             : static GEN
     617       11956 : RgM_liftred(GEN x, GEN T)
     618       11956 : { return RgXQM_red(liftpol_shallow(x), T); }
     619             : 
     620             : static GEN
     621        1442 : RgM_mul_ZXQM(GEN x, GEN y, GEN T)
     622             : {
     623        1442 :   pari_sp av = avma;
     624        1442 :   GEN b = ZXQM_mul(RgM_liftred(x,T), RgM_liftred(y, T), T);
     625        1442 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     626             : }
     627             : 
     628             : static GEN
     629         133 : RgM_sqr_ZXQM(GEN x, GEN T)
     630             : {
     631         133 :   pari_sp av = avma;
     632         133 :   GEN b = ZXQM_sqr(RgM_liftred(x, T), T);
     633         133 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     634             : }
     635             : 
     636             : static GEN
     637        4466 : RgM_mul_QXQM(GEN x, GEN y, GEN T)
     638             : {
     639        4466 :   pari_sp av = avma;
     640        4466 :   GEN b = QXQM_mul(RgM_liftred(x, T), RgM_liftred(y, T), T);
     641        4466 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     642             : }
     643             : 
     644             : static GEN
     645           7 : RgM_sqr_QXQM(GEN x, GEN T)
     646             : {
     647           7 :   pari_sp av = avma;
     648           7 :   GEN b = QXQM_sqr(RgM_liftred(x, T), T);
     649           7 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     650             : }
     651             : 
     652             : INLINE int
     653        4515 : RgX_is_monic_ZX(GEN pol)
     654        4515 : { return RgX_is_ZX(pol) && ZX_is_monic(pol); }
     655             : 
     656             : #define code(t1,t2) ((t1 << 6) | t2)
     657             : static GEN
     658     7568181 : RgM_mul_fast(GEN x, GEN y)
     659             : {
     660             :   GEN p, pol;
     661             :   long pa;
     662     7568181 :   long t = RgM_type2(x,y, &p,&pol,&pa);
     663     7568223 :   switch(t)
     664             :   {
     665     2689290 :     case t_INT:    return ZM_mul(x,y);
     666      117117 :     case t_FRAC:   return QM_mul(x,y);
     667        4403 :     case t_FFELT:  return FFM_mul(x, y, pol);
     668       57085 :     case t_INTMOD: return RgM_mul_FpM(x, y, p);
     669        1449 :     case code(t_POLMOD, t_INT):
     670        1449 :                    return ZX_is_monic(pol)? RgM_mul_ZXQM(x, y, pol): NULL;
     671        4487 :     case code(t_POLMOD, t_FRAC):
     672        4487 :                    return RgX_is_monic_ZX(pol)? RgM_mul_QXQM(x, y, pol): NULL;
     673       26003 :     case code(t_POLMOD, t_INTMOD):
     674       26003 :                    return RgM_mul_FqM(x, y, pol, p);
     675     4668389 :     default:       return NULL;
     676             :   }
     677             : }
     678             : 
     679             : static GEN
     680        1316 : RgM_sqr_fast(GEN x)
     681             : {
     682             :   GEN p, pol;
     683             :   long pa;
     684        1316 :   long t = RgM_type(x, &p,&pol,&pa);
     685        1316 :   switch(t)
     686             :   {
     687         175 :     case t_INT:    return ZM_sqr(x);
     688         700 :     case t_FRAC:   return QM_sqr(x);
     689         112 :     case t_FFELT:  return FFM_mul(x, x, pol);
     690          63 :     case t_INTMOD: return RgM_mul_FpM(x, x, p);
     691         140 :     case code(t_POLMOD, t_INT):
     692         140 :                    return ZX_is_monic(pol)? RgM_sqr_ZXQM(x, pol): NULL;
     693          28 :     case code(t_POLMOD, t_FRAC):
     694          28 :                    return RgX_is_monic_ZX(pol)? RgM_sqr_QXQM(x, pol): NULL;
     695           0 :     case code(t_POLMOD, t_INTMOD):
     696           0 :                    return RgM_mul_FqM(x, x, pol, p);
     697          98 :     default:       return NULL;
     698             :   }
     699             : }
     700             : 
     701             : #undef code
     702             : 
     703             : /* lx, ly > 1 */
     704             : static GEN
     705     4668415 : RgM_mul_i(GEN x, GEN y, long lx, long ly)
     706             : {
     707     4668415 :   GEN z = cgetg(ly, t_MAT);
     708     4668412 :   long j, l = lgcols(x);
     709    16446757 :   for (j = 1; j < ly; j++) gel(z,j) = RgM_RgC_mul_i(x, gel(y,j), lx, l);
     710     4668381 :   return z;
     711             : }
     712             : GEN
     713     7583962 : RgM_mul(GEN x, GEN y)
     714             : {
     715     7583962 :   long lx, ly = lg(y);
     716             :   GEN z;
     717     7583962 :   if (ly == 1) return cgetg(1,t_MAT);
     718     7568212 :   lx = lg(x);
     719     7568212 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgM_mul'", x,y);
     720     7568211 :   if (lx == 1) return zeromat(0,ly-1);
     721     7568183 :   z = RgM_mul_fast(x, y);
     722     7568224 :   if (z) return z;
     723     4668417 :   return RgM_mul_i(x, y, lx, ly);
     724             : }
     725             : 
     726             : GEN
     727        1351 : RgM_sqr(GEN x)
     728             : {
     729        1351 :   long j, lx = lg(x);
     730             :   GEN z;
     731        1351 :   if (lx == 1) return cgetg(1, t_MAT);
     732        1316 :   if (lx != lgcols(x)) pari_err_OP("operation 'RgM_mul'", x,x);
     733        1316 :   z = RgM_sqr_fast(x);
     734        1316 :   if (z) return z;
     735         126 :   z = cgetg(lx, t_MAT);
     736         497 :   for (j=1; j<lx; j++) gel(z,j) = RgM_RgC_mul_i(x, gel(x,j), lx, lx);
     737         126 :   return z;
     738             : }
     739             : 
     740             : /* assume result is symmetric */
     741             : GEN
     742           0 : RgM_multosym(GEN x, GEN y)
     743             : {
     744           0 :   long j, lx, ly = lg(y);
     745             :   GEN M;
     746           0 :   if (ly == 1) return cgetg(1,t_MAT);
     747           0 :   lx = lg(x);
     748           0 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgM_multosym'", x,y);
     749           0 :   if (lx == 1) return cgetg(1,t_MAT);
     750           0 :   if (ly != lgcols(x)) pari_err_OP("operation 'RgM_multosym'", x,y);
     751           0 :   M = cgetg(ly, t_MAT);
     752           0 :   for (j=1; j<ly; j++)
     753             :   {
     754           0 :     GEN z = cgetg(ly,t_COL), yj = gel(y,j);
     755             :     long i;
     756           0 :     for (i=1; i<j; i++) gel(z,i) = gcoeff(M,j,i);
     757           0 :     for (i=j; i<ly; i++)gel(z,i) = RgMrow_RgC_mul_i(x,yj,i,lx);
     758           0 :     gel(M,j) = z;
     759             :   }
     760           0 :   return M;
     761             : }
     762             : /* x~ * y, assuming result is symmetric */
     763             : GEN
     764        7663 : RgM_transmultosym(GEN x, GEN y)
     765             : {
     766        7663 :   long i, j, l, ly = lg(y);
     767             :   GEN M;
     768        7663 :   if (ly == 1) return cgetg(1,t_MAT);
     769        7663 :   if (lg(x) != ly) pari_err_OP("operation 'RgM_transmultosym'", x,y);
     770        7663 :   l = lgcols(y);
     771        7663 :   if (lgcols(x) != l) pari_err_OP("operation 'RgM_transmultosym'", x,y);
     772        7663 :   M = cgetg(ly, t_MAT);
     773       30820 :   for (i=1; i<ly; i++)
     774             :   {
     775       23157 :     GEN xi = gel(x,i), c = cgetg(ly,t_COL);
     776       23157 :     gel(M,i) = c;
     777       47490 :     for (j=1; j<i; j++)
     778       24333 :       gcoeff(M,i,j) = gel(c,j) = RgV_dotproduct_i(xi,gel(y,j),l);
     779       23157 :     gel(c,i) = RgV_dotproduct_i(xi,gel(y,i),l);
     780             :   }
     781        7663 :   return M;
     782             : }
     783             : /* x~ * y */
     784             : GEN
     785           0 : RgM_transmul(GEN x, GEN y)
     786             : {
     787           0 :   long i, j, l, lx, ly = lg(y);
     788             :   GEN M;
     789           0 :   if (ly == 1) return cgetg(1,t_MAT);
     790           0 :   lx = lg(x);
     791           0 :   l = lgcols(y);
     792           0 :   if (lgcols(x) != l) pari_err_OP("operation 'RgM_transmul'", x,y);
     793           0 :   M = cgetg(ly, t_MAT);
     794           0 :   for (i=1; i<ly; i++)
     795             :   {
     796           0 :     GEN yi = gel(y,i), c = cgetg(lx,t_COL);
     797           0 :     gel(M,i) = c;
     798           0 :     for (j=1; j<lx; j++) gel(c,j) = RgV_dotproduct_i(yi,gel(x,j),l);
     799             :   }
     800           0 :   return M;
     801             : }
     802             : 
     803             : GEN
     804     4691373 : gram_matrix(GEN x)
     805             : {
     806     4691373 :   long i,j, l, lx = lg(x);
     807             :   GEN M;
     808     4691373 :   if (!is_matvec_t(typ(x))) pari_err_TYPE("gram",x);
     809     4691372 :   if (lx == 1) return cgetg(1,t_MAT);
     810     4691358 :   l = lgcols(x);
     811     4691357 :   M = cgetg(lx,t_MAT);
     812    14073997 :   for (i=1; i<lx; i++)
     813             :   {
     814     9382657 :     GEN xi = gel(x,i), c = cgetg(lx,t_COL);
     815     9382656 :     gel(M,i) = c;
     816    14073974 :     for (j=1; j<i; j++)
     817     4691326 :       gcoeff(M,i,j) = gel(c,j) = RgV_dotproduct_i(xi,gel(x,j),l);
     818     9382648 :     gel(c,i) = RgV_dotsquare(xi);
     819             :   }
     820     4691340 :   return M;
     821             : }
     822             : 
     823             : static GEN
     824        3801 : _RgM_add(void *E, GEN x, GEN y) { (void)E; return RgM_add(x, y); }
     825             : 
     826             : static GEN
     827           0 : _RgM_sub(void *E, GEN x, GEN y) { (void)E; return RgM_sub(x, y); }
     828             : 
     829             : static GEN
     830        5684 : _RgM_cmul(void *E, GEN P, long a, GEN x) { (void)E; return RgM_Rg_mul(x,gel(P,a+2)); }
     831             : 
     832             : static GEN
     833         238 : _RgM_sqr(void *E, GEN x) { (void) E; return RgM_sqr(x); }
     834             : 
     835             : static GEN
     836         749 : _RgM_mul(void *E, GEN x, GEN y) { (void) E; return RgM_mul(x, y); }
     837             : 
     838             : static GEN
     839        4046 : _RgM_one(void *E) { long *n = (long*) E; return matid(*n); }
     840             : 
     841             : static GEN
     842           0 : _RgM_zero(void *E) { long *n = (long*) E; return zeromat(*n,*n); }
     843             : 
     844             : static GEN
     845        2828 : _RgM_red(void *E, GEN x) { (void)E; return x; }
     846             : 
     847             : static struct bb_algebra RgM_algebra = { _RgM_red, _RgM_add, _RgM_sub,
     848             :        _RgM_mul, _RgM_sqr, _RgM_one, _RgM_zero };
     849             : 
     850             : /* generates the list of powers of x of degree 0,1,2,...,l*/
     851             : GEN
     852         168 : RgM_powers(GEN x, long l)
     853             : {
     854         168 :   long n = lg(x)-1;
     855         168 :   return gen_powers(x,l,1,(void *) &n, &_RgM_sqr, &_RgM_mul, &_RgM_one);
     856             : }
     857             : 
     858             : GEN
     859         490 : RgX_RgMV_eval(GEN Q, GEN x)
     860             : {
     861         490 :   long n = lg(x)>1 ? lg(gel(x,1))-1:0;
     862         490 :   return gen_bkeval_powers(Q,degpol(Q),x,(void*)&n,&RgM_algebra,&_RgM_cmul);
     863             : }
     864             : 
     865             : GEN
     866        1393 : RgX_RgM_eval(GEN Q, GEN x)
     867             : {
     868        1393 :   long n = lg(x)-1;
     869        1393 :   return gen_bkeval(Q,degpol(Q),x,1,(void*)&n,&RgM_algebra,&_RgM_cmul);
     870             : }
     871             : 
     872             : GEN
     873     4455931 : RgC_Rg_div(GEN x, GEN y)
     874    19188214 : { pari_APPLY_type(t_COL, gdiv(gel(x,i),y)) }
     875             : 
     876             : GEN
     877    13153535 : RgC_Rg_mul(GEN x, GEN y)
     878    79214232 : { pari_APPLY_type(t_COL, gmul(gel(x,i),y)) }
     879             : 
     880             : GEN
     881       30954 : RgV_Rg_mul(GEN x, GEN y)
     882     1172220 : { pari_APPLY_type(t_VEC, gmul(gel(x,i),y)) }
     883             : 
     884             : GEN
     885      608985 : RgM_Rg_div(GEN X, GEN c) {
     886      608985 :   long i, j, h, l = lg(X);
     887      608985 :   GEN A = cgetg(l, t_MAT);
     888      608983 :   if (l == 1) return A;
     889      608983 :   h = lgcols(X);
     890     2789321 :   for (j=1; j<l; j++)
     891             :   {
     892     2180354 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     893    17262237 :     for (i = 1; i < h; i++) gel(a,i) = gdiv(gel(x,i), c);
     894     2180337 :     gel(A,j) = a;
     895             :   }
     896      608967 :   return A;
     897             : }
     898             : GEN
     899      247151 : RgM_Rg_mul(GEN X, GEN c) {
     900      247151 :   long i, j, h, l = lg(X);
     901      247151 :   GEN A = cgetg(l, t_MAT);
     902      247150 :   if (l == 1) return A;
     903      247150 :   h = lgcols(X);
     904     1086831 :   for (j=1; j<l; j++)
     905             :   {
     906      839702 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     907     7062918 :     for (i = 1; i < h; i++) gel(a,i) = gmul(gel(x,i), c);
     908      839677 :     gel(A,j) = a;
     909             :   }
     910      247129 :   return A;
     911             : }
     912             : 
     913             : /********************************************************************/
     914             : /*                                                                  */
     915             : /*                    SCALAR TO MATRIX/VECTOR                       */
     916             : /*                                                                  */
     917             : /********************************************************************/
     918             : /* fill the square nxn matrix equal to t*Id */
     919             : static void
     920    13397241 : fill_scalmat(GEN y, GEN t, long n)
     921             : {
     922             :   long i;
     923    51025998 :   for (i = 1; i <= n; i++)
     924             :   {
     925    37629061 :     gel(y,i) = zerocol(n);
     926    37628757 :     gcoeff(y,i,i) = t;
     927             :   }
     928    13396937 : }
     929             : 
     930             : GEN
     931      928190 : scalarmat(GEN x, long n) {
     932      928190 :   GEN y = cgetg(n+1, t_MAT);
     933      928158 :   if (!n) return y;
     934      928158 :   fill_scalmat(y, gcopy(x), n); return y;
     935             : }
     936             : GEN
     937     3154437 : scalarmat_shallow(GEN x, long n) {
     938     3154437 :   GEN y = cgetg(n+1, t_MAT);
     939     3154474 :   fill_scalmat(y, x, n); return y;
     940             : }
     941             : GEN
     942         217 : scalarmat_s(long x, long n) {
     943         217 :   GEN y = cgetg(n+1, t_MAT);
     944         217 :   if (!n) return y;
     945         217 :   fill_scalmat(y, stoi(x), n); return y;
     946             : }
     947             : GEN
     948     9314921 : matid(long n) {
     949             :   GEN y;
     950     9314921 :   if (n < 0) pari_err_DOMAIN("matid", "size", "<", gen_0, stoi(n));
     951     9314914 :   y = cgetg(n+1, t_MAT);
     952     9315036 :   fill_scalmat(y, gen_1, n); return y;
     953             : }
     954             : 
     955             : INLINE GEN
     956     2253680 : scalarcol_i(GEN x, long n, long c)
     957             : {
     958             :   long i;
     959     2253680 :   GEN y = cgetg(n+1,t_COL);
     960     2253679 :   if (!n) return y;
     961     2253679 :   gel(y,1) = c? gcopy(x): x;
     962     6729171 :   for (i=2; i<=n; i++) gel(y,i) = gen_0;
     963     2253682 :   return y;
     964             : }
     965             : 
     966             : GEN
     967      772236 : scalarcol(GEN x, long n) { return scalarcol_i(x,n,1); }
     968             : 
     969             : GEN
     970     1481445 : scalarcol_shallow(GEN x, long n) { return scalarcol_i(x,n,0); }
     971             : 
     972             : int
     973       33077 : RgM_isscalar(GEN x, GEN s)
     974             : {
     975       33077 :   long i, j, lx = lg(x);
     976             : 
     977       33077 :   if (lx == 1) return 1;
     978       33077 :   if (lx != lgcols(x)) return 0;
     979       33077 :   if (!s) s = gcoeff(x,1,1);
     980             : 
     981       91621 :   for (j=1; j<lx; j++)
     982             :   {
     983       74495 :     GEN c = gel(x,j);
     984      201501 :     for (i=1; i<j; )
     985      140395 :       if (!gequal0(gel(c,i++))) return 0;
     986             :     /* i = j */
     987       61106 :     if (!gequal(gel(c,i++),s)) return 0;
     988      224451 :     for (   ; i<lx; )
     989      165907 :       if (!gequal0(gel(c,i++))) return 0;
     990             :   }
     991       17126 :   return 1;
     992             : }
     993             : 
     994             : int
     995       15322 : RgM_isidentity(GEN x)
     996             : {
     997       15322 :   long i,j, lx = lg(x);
     998             : 
     999       15322 :   if (lx == 1) return 1;
    1000       15322 :   if (lx != lgcols(x)) return 0;
    1001       25172 :   for (j=1; j<lx; j++)
    1002             :   {
    1003       24976 :     GEN c = gel(x,j);
    1004       58246 :     for (i=1; i<j; )
    1005       38225 :       if (!gequal0(gel(c,i++))) return 0;
    1006             :     /* i = j */
    1007       20021 :     if (!gequal1(gel(c,i++))) return 0;
    1008       61007 :     for (   ; i<lx; )
    1009       51157 :       if (!gequal0(gel(c,i++))) return 0;
    1010             :   }
    1011         196 :   return 1;
    1012             : }
    1013             : 
    1014             : long
    1015         434 : RgC_is_ei(GEN x)
    1016             : {
    1017         434 :   long i, j = 0, l = lg(x);
    1018        2422 :   for (i = 1; i < l; i++)
    1019             :   {
    1020        1988 :     GEN c = gel(x,i);
    1021        1988 :     if (gequal0(c)) continue;
    1022         434 :     if (!gequal1(c) || j) return 0;
    1023         434 :     j = i;
    1024             :   }
    1025         434 :   return j;
    1026             : }
    1027             : 
    1028             : int
    1029         336 : RgM_isdiagonal(GEN x)
    1030             : {
    1031         336 :   long i,j, lx = lg(x);
    1032         336 :   if (lx == 1) return 1;
    1033         336 :   if (lx != lgcols(x)) return 0;
    1034             : 
    1035        3220 :   for (j=1; j<lx; j++)
    1036             :   {
    1037        2891 :     GEN c = gel(x,j);
    1038       18452 :     for (i=1; i<j; i++)
    1039       15561 :       if (!gequal0(gel(c,i))) return 0;
    1040       18452 :     for (i++; i<lx; i++)
    1041       15568 :       if (!gequal0(gel(c,i))) return 0;
    1042             :   }
    1043         329 :   return 1;
    1044             : }
    1045             : int
    1046         315 : isdiagonal(GEN x) { return (typ(x)==t_MAT) && RgM_isdiagonal(x); }
    1047             : 
    1048             : GEN
    1049       21337 : RgM_det_triangular(GEN mat)
    1050             : {
    1051       21337 :   long i,l = lg(mat);
    1052             :   pari_sp av;
    1053             :   GEN s;
    1054             : 
    1055       21337 :   if (l<3) return l<2? gen_1: gcopy(gcoeff(mat,1,1));
    1056       19762 :   av = avma; s = gcoeff(mat,1,1);
    1057      119922 :   for (i=2; i<l; i++) s = gmul(s,gcoeff(mat,i,i));
    1058       19762 :   return av==avma? gcopy(s): gerepileupto(av,s);
    1059             : }
    1060             : 
    1061             : GEN
    1062      478033 : RgV_kill0(GEN v)
    1063             : {
    1064             :   long i, l;
    1065      478033 :   GEN w = cgetg_copy(v, &l);
    1066   129995377 :   for (i = 1; i < l; i++)
    1067             :   {
    1068   129518257 :     GEN a = gel(v,i);
    1069   129518257 :     gel(w,i) = gequal0(a) ? NULL: a;
    1070             :   }
    1071      477120 :   return w;
    1072             : }

Generated by: LCOV version 1.16