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.14.0 lcov report (development 27775-aca467eab2) Lines: 521 579 90.0 %
Date: 2022-07-03 07:33:15 Functions: 95 103 92.2 %
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     1190963 : RgM_is_ZM(GEN x)
      20             : {
      21     1190963 :   long i, j, h, l = lg(x);
      22     1190963 :   if (l == 1) return 1;
      23     1190396 :   h = lgcols(x);
      24     1190415 :   if (h == 1) return 1;
      25     4353835 :   for (j = l-1; j > 0; j--)
      26    18051611 :     for (i = h-1; i > 0; i--)
      27    14888191 :       if (typ(gcoeff(x,i,j)) != t_INT) return 0;
      28     1048446 :   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    17936205 : RgMrow_zc_mul_i(GEN x, GEN y, long c, long i)
      64             : {
      65    17936205 :   pari_sp av = avma;
      66    17936205 :   GEN s = NULL;
      67             :   long j;
      68  1762366610 :   for (j=1; j<c; j++)
      69             :   {
      70  1744436969 :     long t = y[j];
      71  1744436969 :     if (!t) continue;
      72    72147760 :     if (!s) { s = gmulgs(gcoeff(x,i,j),t); continue; }
      73    54333607 :     switch(t)
      74             :     {
      75    30949726 :       case  1: s = gadd(s, gcoeff(x,i,j)); break;
      76      237895 :       case -1: s = gsub(s, gcoeff(x,i,j)); break;
      77    23145986 :       default: s = gadd(s, gmulgs(gcoeff(x,i,j), t)); break;
      78             :     }
      79             :   }
      80    17929641 :   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      232602 : RgM_zc_mul_i(GEN x, GEN y, long c, long l)
      87             : {
      88      232602 :   GEN z = cgetg(l,t_COL);
      89             :   long i;
      90    18098758 :   for (i = 1; i < l; i++) gel(z,i) = RgMrow_zc_mul_i(x,y,c,i);
      91      232594 :   return z;
      92             : }
      93             : GEN
      94       71806 : 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       50325 : RgM_zm_mul(GEN x, GEN y)
      98             : {
      99       50325 :   long j, c, l = lg(x), ly = lg(y);
     100       50325 :   GEN z = cgetg(ly, t_MAT);
     101       50325 :   if (l == 1) return z;
     102       50325 :   c = lgcols(x);
     103      211119 :   for (j = 1; j < ly; j++) gel(z,j) = RgM_zc_mul_i(x, gel(y,j), l,c);
     104       50323 :   return z;
     105             : }
     106             : 
     107             : /* x[i,]*y, l = lg(y) > 1 */
     108             : static GEN
     109    24662480 : RgMrow_ZC_mul_i(GEN x, GEN y, long i, long l)
     110             : {
     111    24662480 :   pari_sp av = avma;
     112    24662480 :   GEN t = gmul(gcoeff(x,i,1), gel(y,1)); /* l > 1 ! */
     113             :   long j;
     114  3069699920 :   for (j=2; j<l; j++)
     115  3045080730 :     if (signe(gel(y,j))) t = gadd(t, gmul(gcoeff(x,i,j), gel(y,j)));
     116    24619190 :   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     1900434 : RgM_ZC_mul_i(GEN x, GEN y, long lx, long l)
     122             : {
     123     1900434 :   GEN z = cgetg(l,t_COL);
     124             :   long i;
     125    26561830 :   for (i=1; i<l; i++) gel(z,i) = RgMrow_ZC_mul_i(x,y,i,lx);
     126     1899692 :   return z;
     127             : }
     128             : 
     129             : /* mostly useful when y is sparse */
     130             : GEN
     131      351042 : RgM_ZM_mul(GEN x, GEN y)
     132             : {
     133      351042 :   long j, c, l = lg(x), ly = lg(y);
     134      351042 :   GEN z = cgetg(ly, t_MAT);
     135      351042 :   if (l == 1) return z;
     136      351042 :   c = lgcols(x);
     137     2251430 :   for (j = 1; j < ly; j++) gel(z,j) = RgM_ZC_mul_i(x, gel(y,j), l,c);
     138      350994 :   return z;
     139             : }
     140             : 
     141             : static GEN
     142      124814 : RgV_zc_mul_i(GEN x, GEN y, long l)
     143             : {
     144             :   long i;
     145      124814 :   GEN z = gen_0;
     146      124814 :   pari_sp av = avma;
     147     5781815 :   for (i = 1; i < l; i++) z = gadd(z, gmulgs(gel(x,i), y[i]));
     148      124814 :   return gerepileupto(av, z);
     149             : }
     150             : GEN
     151        6804 : RgV_zc_mul(GEN x, GEN y) { return RgV_zc_mul_i(x, y, lg(x)); }
     152             : 
     153             : GEN
     154       33474 : RgV_zm_mul(GEN x, GEN y)
     155             : {
     156       33474 :   long j, l = lg(x), ly = lg(y);
     157       33474 :   GEN z = cgetg(ly, t_VEC);
     158      151484 :   for (j = 1; j < ly; j++) gel(z,j) = RgV_zc_mul_i(x, gel(y,j), l);
     159       33474 :   return z;
     160             : }
     161             : 
     162             : /* scalar product x.x */
     163             : GEN
     164       59524 : RgV_dotsquare(GEN x)
     165             : {
     166       59524 :   long i, lx = lg(x);
     167       59524 :   pari_sp av = avma;
     168             :   GEN z;
     169       59524 :   if (lx == 1) return gen_0;
     170       59524 :   z = gsqr(gel(x,1));
     171     2542130 :   for (i=2; i<lx; i++)
     172             :   {
     173     2482606 :     z = gadd(z, gsqr(gel(x,i)));
     174     2482606 :     if (gc_needed(av,3))
     175             :     {
     176           0 :       if(DEBUGMEM>1) pari_warn(warnmem,"RgV_dotsquare, i = %ld",i);
     177           0 :       z = gerepileupto(av, z);
     178             :     }
     179             :   }
     180       59524 :   return gerepileupto(av,z);
     181             : }
     182             : 
     183             : /* scalar product x.y, lx = lg(x) = lg(y) */
     184             : static GEN
     185     7014266 : RgV_dotproduct_i(GEN x, GEN y, long lx)
     186             : {
     187     7014266 :   pari_sp av = avma;
     188             :   long i;
     189             :   GEN z;
     190     7014266 :   if (lx == 1) return gen_0;
     191     7014238 :   z = gmul(gel(x,1),gel(y,1));
     192   203964328 :   for (i=2; i<lx; i++)
     193             :   {
     194   196951923 :     z = gadd(z, gmul(gel(x,i), gel(y,i)));
     195   196937520 :     if (gc_needed(av,3))
     196             :     {
     197           0 :       if(DEBUGMEM>1) pari_warn(warnmem,"RgV_dotproduct, i = %ld",i);
     198           0 :       z = gerepileupto(av, z);
     199             :     }
     200             :   }
     201     7012405 :   return gerepileupto(av,z);
     202             : }
     203             : GEN
     204     1000098 : RgV_dotproduct(GEN x,GEN y)
     205             : {
     206     1000098 :   if (x == y) return RgV_dotsquare(x);
     207     1000098 :   return RgV_dotproduct_i(x, y, lg(x));
     208             : }
     209             : /* v[1] + ... + v[lg(v)-1] */
     210             : GEN
     211     1803210 : RgV_sum(GEN v)
     212             : {
     213             :   GEN p;
     214     1803210 :   long i, l = lg(v);
     215     1803210 :   if (l == 1) return gen_0;
     216     4890167 :   p = gel(v,1); for (i=2; i<l; i++) p = gadd(p, gel(v,i));
     217     1803085 :   return p;
     218             : }
     219             : /* v[1] + ... + v[n]. Assume lg(v) > n. */
     220             : GEN
     221           0 : RgV_sumpart(GEN v, long n)
     222             : {
     223             :   GEN p;
     224             :   long i;
     225           0 :   if (!n) return gen_0;
     226           0 :   p = gel(v,1); for (i=2; i<=n; i++) p = gadd(p, gel(v,i));
     227           0 :   return p;
     228             : }
     229             : /* v[m] + ... + v[n]. Assume lg(v) > n, m > 0. */
     230             : GEN
     231           0 : RgV_sumpart2(GEN v, long m, long n)
     232             : {
     233             :   GEN p;
     234             :   long i;
     235           0 :   if (n < m) return gen_0;
     236           0 :   p = gel(v,m); for (i=m+1; i<=n; i++) p = gadd(p, gel(v,i));
     237           0 :   return p;
     238             : }
     239             : GEN
     240         382 : RgM_sumcol(GEN A)
     241             : {
     242         382 :   long i,j,m,l = lg(A);
     243             :   GEN v;
     244             : 
     245         382 :   if (l == 1) return cgetg(1,t_MAT);
     246         382 :   if (l == 2) return gcopy(gel(A,1));
     247         198 :   m = lgcols(A);
     248         198 :   v = cgetg(m, t_COL);
     249         664 :   for (i = 1; i < m; i++)
     250             :   {
     251         466 :     pari_sp av = avma;
     252         466 :     GEN s = gcoeff(A,i,1);
     253        1142 :     for (j = 2; j < l; j++) s = gadd(s, gcoeff(A,i,j));
     254         466 :     gel(v, i) = gerepileupto(av, s);
     255             :   }
     256         198 :   return v;
     257             : }
     258             : 
     259             : static GEN
     260     3308727 : _gmul(void *data, GEN x, GEN y)
     261     3308727 : { (void)data; return gmul(x,y); }
     262             : 
     263             : GEN
     264      439659 : RgV_prod(GEN x)
     265             : {
     266      439659 :   return gen_product(x, NULL, _gmul);
     267             : }
     268             : 
     269             : /*                    ADDITION SCALAR + MATRIX                     */
     270             : /* x square matrix, y scalar; create the square matrix x + y*Id */
     271             : GEN
     272        8121 : RgM_Rg_add(GEN x, GEN y)
     273             : {
     274        8121 :   long l = lg(x), i, j;
     275        8121 :   GEN z = cgetg(l,t_MAT);
     276             : 
     277        8121 :   if (l==1) return z;
     278        8107 :   if (l != lgcols(x)) pari_err_OP( "+", x, y);
     279        8107 :   z = cgetg(l,t_MAT);
     280       58275 :   for (i=1; i<l; i++)
     281             :   {
     282       50168 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     283       50168 :     gel(z,i) = zi;
     284     2051600 :     for (j=1; j<l; j++)
     285     2001432 :       gel(zi,j) = i==j? gadd(y,gel(xi,j)): gcopy(gel(xi,j));
     286             :   }
     287        8107 :   return z;
     288             : }
     289             : GEN
     290       57495 : RgM_Rg_sub(GEN x, GEN y)
     291             : {
     292       57495 :   long l = lg(x), i, j;
     293       57495 :   GEN z = cgetg(l,t_MAT);
     294             : 
     295       57495 :   if (l==1) return z;
     296       57495 :   if (l != lgcols(x)) pari_err_OP( "-", x, y);
     297       57495 :   z = cgetg(l,t_MAT);
     298      206819 :   for (i=1; i<l; i++)
     299             :   {
     300      149327 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     301      149327 :     gel(z,i) = zi;
     302      610979 :     for (j=1; j<l; j++)
     303      461656 :       gel(zi,j) = i==j? gsub(gel(xi,j), y): gcopy(gel(xi,j));
     304             :   }
     305       57492 :   return z;
     306             : }
     307             : GEN
     308         497 : RgM_Rg_add_shallow(GEN x, GEN y)
     309             : {
     310         497 :   long l = lg(x), i, j;
     311         497 :   GEN z = cgetg(l,t_MAT);
     312             : 
     313         497 :   if (l==1) return z;
     314         497 :   if (l != lgcols(x)) pari_err_OP( "+", x, y);
     315        1729 :   for (i=1; i<l; i++)
     316             :   {
     317        1232 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     318        1232 :     gel(z,i) = zi;
     319        8218 :     for (j=1; j<l; j++) gel(zi,j) = gel(xi,j);
     320        1232 :     gel(zi,i) = gadd(gel(zi,i), y);
     321             :   }
     322         497 :   return z;
     323             : }
     324             : GEN
     325     1245066 : RgM_Rg_sub_shallow(GEN x, GEN y)
     326             : {
     327     1245066 :   long l = lg(x), i, j;
     328     1245066 :   GEN z = cgetg(l,t_MAT);
     329             : 
     330     1245062 :   if (l==1) return z;
     331     1245062 :   if (l != lgcols(x)) pari_err_OP( "-", x, y);
     332     6315794 :   for (i=1; i<l; i++)
     333             :   {
     334     5070876 :     GEN zi = cgetg(l,t_COL), xi = gel(x,i);
     335     5071029 :     gel(z,i) = zi;
     336    49283987 :     for (j=1; j<l; j++) gel(zi,j) = gel(xi,j);
     337     5071029 :     gel(zi,i) = gsub(gel(zi,i), y);
     338             :   }
     339     1244918 :   return z;
     340             : }
     341             : 
     342             : GEN
     343     3846513 : RgC_Rg_add(GEN x, GEN y)
     344             : {
     345     3846513 :   long k, lx = lg(x);
     346     3846513 :   GEN z = cgetg(lx, t_COL);
     347     3846516 :   if (lx == 1)
     348             :   {
     349           0 :     if (isintzero(y)) return z;
     350           0 :     pari_err_TYPE2("+",x,y);
     351             :   }
     352     3846516 :   gel(z,1) = gadd(y,gel(x,1));
     353     8712419 :   for (k = 2; k < lx; k++) gel(z,k) = gcopy(gel(x,k));
     354     3846509 :   return z;
     355             : }
     356             : GEN
     357       28840 : RgC_Rg_sub(GEN x, GEN y)
     358             : {
     359       28840 :   long k, lx = lg(x);
     360       28840 :   GEN z = cgetg(lx, t_COL);
     361       28840 :   if (lx == 1)
     362             :   {
     363           0 :     if (isintzero(y)) return z;
     364           0 :     pari_err_TYPE2("-",x,y);
     365             :   }
     366       28840 :   gel(z,1) = gsub(gel(x,1), y);
     367       66290 :   for (k = 2; k < lx; k++) gel(z,k) = gcopy(gel(x,k));
     368       28840 :   return z;
     369             : }
     370             : /* a - x */
     371             : GEN
     372      119903 : Rg_RgC_sub(GEN a, GEN x)
     373             : {
     374      119903 :   long k, lx = lg(x);
     375      119903 :   GEN z = cgetg(lx,t_COL);
     376      119903 :   if (lx == 1)
     377             :   {
     378           0 :     if (isintzero(a)) return z;
     379           0 :     pari_err_TYPE2("-",a,x);
     380             :   }
     381      119903 :   gel(z,1) = gsub(a, gel(x,1));
     382      257061 :   for (k = 2; k < lx; k++) gel(z,k) = gneg(gel(x,k));
     383      119903 :   return z;
     384             : }
     385             : 
     386             : static GEN
     387    16119321 : RgC_add_i(GEN x, GEN y, long lx)
     388             : {
     389    16119321 :   GEN A = cgetg(lx, t_COL);
     390             :   long i;
     391   124149797 :   for (i=1; i<lx; i++) gel(A,i) = gadd(gel(x,i), gel(y,i));
     392    16118796 :   return A;
     393             : }
     394             : GEN
     395    12855459 : RgC_add(GEN x, GEN y) { return RgC_add_i(x, y, lg(x)); }
     396             : GEN
     397      758849 : RgV_add(GEN x, GEN y)
     398     5751479 : { pari_APPLY_type(t_VEC, gadd(gel(x,i), gel(y,i))) }
     399             : 
     400             : static GEN
     401     8349558 : RgC_sub_i(GEN x, GEN y, long lx)
     402             : {
     403             :   long i;
     404     8349558 :   GEN A = cgetg(lx, t_COL);
     405  1420040445 :   for (i=1; i<lx; i++) gel(A,i) = gsub(gel(x,i), gel(y,i));
     406     8348250 :   return A;
     407             : }
     408             : GEN
     409     7476116 : RgC_sub(GEN x, GEN y) { return RgC_sub_i(x, y, lg(x)); }
     410             : GEN
     411      353958 : RgV_sub(GEN x, GEN y)
     412     3007003 : { pari_APPLY_type(t_VEC, gsub(gel(x,i), gel(y,i))) }
     413             : 
     414             : GEN
     415      690116 : RgM_add(GEN x, GEN y)
     416             : {
     417      690116 :   long lx = lg(x), l, j;
     418             :   GEN z;
     419      690116 :   if (lx == 1) return cgetg(1, t_MAT);
     420      690116 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     421     3953957 :   for (j = 1; j < lx; j++) gel(z,j) = RgC_add_i(gel(x,j), gel(y,j), l);
     422      690116 :   return z;
     423             : }
     424             : GEN
     425      156001 : RgM_sub(GEN x, GEN y)
     426             : {
     427      156001 :   long lx = lg(x), l, j;
     428             :   GEN z;
     429      156001 :   if (lx == 1) return cgetg(1, t_MAT);
     430      156001 :   z = cgetg(lx, t_MAT); l = lgcols(x);
     431     1029451 :   for (j = 1; j < lx; j++) gel(z,j) = RgC_sub_i(gel(x,j), gel(y,j), l);
     432      156000 :   return z;
     433             : }
     434             : 
     435             : static GEN
     436     3940479 : RgC_neg_i(GEN x, long lx)
     437             : {
     438             :   long i;
     439     3940479 :   GEN y = cgetg(lx, t_COL);
     440    30011198 :   for (i=1; i<lx; i++) gel(y,i) = gneg(gel(x,i));
     441     3940475 :   return y;
     442             : }
     443             : GEN
     444      957479 : RgC_neg(GEN x) { return RgC_neg_i(x, lg(x)); }
     445             : GEN
     446        3976 : RgV_neg(GEN x)
     447       58681 : { pari_APPLY_type(t_VEC, gneg(gel(x,i))) }
     448             : GEN
     449      540855 : RgM_neg(GEN x)
     450             : {
     451      540855 :   long i, hx, lx = lg(x);
     452      540855 :   GEN y = cgetg(lx, t_MAT);
     453      540855 :   if (lx == 1) return y;
     454      540848 :   hx = lgcols(x);
     455     3523849 :   for (i=1; i<lx; i++) gel(y,i) = RgC_neg_i(gel(x,i), hx);
     456      540848 :   return y;
     457             : }
     458             : 
     459             : GEN
     460     2887916 : RgV_RgC_mul(GEN x, GEN y)
     461             : {
     462     2887916 :   long lx = lg(x);
     463     2887916 :   if (lx != lg(y)) pari_err_OP("operation 'RgV_RgC_mul'", x, y);
     464     2887853 :   return RgV_dotproduct_i(x, y, lx);
     465             : }
     466             : GEN
     467        1687 : RgC_RgV_mul(GEN x, GEN y)
     468             : {
     469        1687 :   long i, ly = lg(y);
     470        1687 :   GEN z = cgetg(ly,t_MAT);
     471        5061 :   for (i=1; i<ly; i++) gel(z,i) = RgC_Rg_mul(x, gel(y,i));
     472        1687 :   return z;
     473             : }
     474             : GEN
     475           0 : RgC_RgM_mul(GEN x, GEN y)
     476             : {
     477           0 :   long i, ly = lg(y);
     478           0 :   GEN z = cgetg(ly,t_MAT);
     479           0 :   if (ly != 1 && lgcols(y) != 2) pari_err_OP("operation 'RgC_RgM_mul'",x,y);
     480           0 :   for (i=1; i<ly; i++) gel(z,i) = RgC_Rg_mul(x, gcoeff(y,1,i));
     481           0 :   return z;
     482             : }
     483             : GEN
     484           0 : RgM_RgV_mul(GEN x, GEN y)
     485             : {
     486           0 :   if (lg(x) != 2) pari_err_OP("operation 'RgM_RgV_mul'", x,y);
     487           0 :   return RgC_RgV_mul(gel(x,1), y);
     488             : }
     489             : 
     490             : /* x[i,]*y, l = lg(y) > 1 */
     491             : static GEN
     492   133360248 : RgMrow_RgC_mul_i(GEN x, GEN y, long i, long l)
     493             : {
     494   133360248 :   pari_sp av = avma;
     495   133360248 :   GEN t = gmul(gcoeff(x,i,1), gel(y,1)); /* l > 1 ! */
     496             :   long j;
     497  1007461334 :   for (j=2; j<l; j++)
     498             :   {
     499   874114087 :     GEN c = gcoeff(x,i,j);
     500   874114087 :     if (!isintzero(c)) t = gadd(t, gmul(c, gel(y,j)));
     501             :   }
     502   133347247 :   return gerepileupto(av,t);
     503             : }
     504             : GEN
     505        4634 : RgMrow_RgC_mul(GEN x, GEN y, long i)
     506        4634 : { return RgMrow_RgC_mul_i(x, y, i, lg(x)); }
     507             : 
     508             : static GEN
     509          28 : RgM_RgC_mul_FpM(GEN x, GEN y, GEN p)
     510             : {
     511          28 :   pari_sp av = avma;
     512             :   GEN r;
     513          28 :   if (lgefint(p) == 3)
     514             :   {
     515          14 :     ulong pp = uel(p, 2);
     516          14 :     r = Flc_to_ZC_inplace(Flm_Flc_mul(RgM_to_Flm(x, pp),
     517             :                                   RgV_to_Flv(y, pp), pp));
     518             :   }
     519             :   else
     520          14 :     r = FpM_FpC_mul(RgM_to_FpM(x, p), RgC_to_FpC(y, p), p);
     521          28 :   return gerepileupto(av, FpC_to_mod(r, p));
     522             : }
     523             : 
     524             : static GEN
     525          14 : RgM_RgC_mul_FqM(GEN x, GEN y, GEN pol, GEN p)
     526             : {
     527          14 :   pari_sp av = avma;
     528          14 :   GEN b, T = RgX_to_FpX(pol, p);
     529          14 :   if (signe(T) == 0) pari_err_OP("*", x, y);
     530          14 :   b = FqM_FqC_mul(RgM_to_FqM(x, T, p), RgC_to_FqC(y, T, p), T, p);
     531          14 :   return gerepileupto(av, FqC_to_mod(b, T, p));
     532             : }
     533             : 
     534             : #define code(t1,t2) ((t1 << 6) | t2)
     535             : static GEN
     536    41014736 : RgM_RgC_mul_fast(GEN x, GEN y)
     537             : {
     538             :   GEN p, pol;
     539             :   long pa;
     540    41014736 :   long t = RgM_RgC_type(x,y, &p,&pol,&pa);
     541    41014840 :   switch(t)
     542             :   {
     543     8002132 :     case t_INT:    return ZM_ZC_mul(x,y);
     544      129322 :     case t_FRAC:   return QM_QC_mul(x,y);
     545          91 :     case t_FFELT:  return FFM_FFC_mul(x, y, pol);
     546          28 :     case t_INTMOD: return RgM_RgC_mul_FpM(x, y, p);
     547          13 :     case code(t_POLMOD, t_INTMOD):
     548          13 :                    return RgM_RgC_mul_FqM(x, y, pol, p);
     549    32883254 :     default:       return NULL;
     550             :   }
     551             : }
     552             : #undef code
     553             : 
     554             : /* compatible t_MAT * t_COL, lx = lg(x) = lg(y) > 1, l = lgcols(x) */
     555             : static GEN
     556    37093744 : RgM_RgC_mul_i(GEN x, GEN y, long lx, long l)
     557             : {
     558    37093744 :   GEN z = cgetg(l,t_COL);
     559             :   long i;
     560   170446564 :   for (i=1; i<l; i++) gel(z,i) = RgMrow_RgC_mul_i(x,y,i,lx);
     561    37091290 :   return z;
     562             : }
     563             : 
     564             : GEN
     565    41014714 : RgM_RgC_mul(GEN x, GEN y)
     566             : {
     567    41014714 :   long lx = lg(x);
     568             :   GEN z;
     569    41014714 :   if (lx != lg(y)) pari_err_OP("operation 'RgM_RgC_mul'", x,y);
     570    41014747 :   if (lx == 1) return cgetg(1,t_COL);
     571    41014747 :   z = RgM_RgC_mul_fast(x, y);
     572    41014819 :   if (z) return z;
     573    32883234 :   return RgM_RgC_mul_i(x, y, lx, lgcols(x));
     574             : }
     575             : 
     576             : GEN
     577      290511 : RgV_RgM_mul(GEN x, GEN y)
     578             : {
     579      290511 :   long i, lx, ly = lg(y);
     580             :   GEN z;
     581      290511 :   if (ly == 1) return cgetg(1,t_VEC);
     582      290504 :   lx = lg(x);
     583      290504 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgV_RgM_mul'", x,y);
     584      290497 :   z = cgetg(ly, t_VEC);
     585     3370220 :   for (i=1; i<ly; i++) gel(z,i) = RgV_dotproduct_i(x, gel(y,i), lx);
     586      290439 :   return z;
     587             : }
     588             : 
     589             : static GEN
     590       56238 : RgM_mul_FpM_i(GEN x, GEN y, GEN p)
     591             : {
     592       56238 :   if (lgefint(p) == 3)
     593             :   {
     594       56166 :     ulong pp = uel(p, 2);
     595       56166 :     if (pp==2) return F2m_to_mod(F2m_mul(RgM_to_F2m(x), RgM_to_F2m(y)));
     596       56117 :     if (pp==3) return F3m_to_mod(F3m_mul(RgM_to_F3m(x), RgM_to_F3m(y)));
     597       56103 :     return Flm_to_mod(Flm_mul(RgM_to_Flm(x, pp), RgM_to_Flm(y, pp), pp), pp);
     598             :   }
     599          72 :   return FpM_to_mod(FpM_mul(RgM_to_FpM(x,p), RgM_to_FpM(y,p), p), p);
     600             : }
     601             : static GEN
     602       56238 : RgM_mul_FpM(GEN x, GEN y, GEN p)
     603       56238 : { pari_sp av = avma; return gerepileupto(av, RgM_mul_FpM_i(x, y, p)); }
     604             : 
     605             : static GEN
     606       26019 : RgM_mul_FqM(GEN x, GEN y, GEN pol, GEN p)
     607             : {
     608       26019 :   pari_sp av = avma;
     609       26019 :   GEN b, T = RgX_to_FpX(pol, p);
     610       26019 :   if (signe(T) == 0) pari_err_OP("*", x, y);
     611       26019 :   b = FqM_mul(RgM_to_FqM(x, T, p), RgM_to_FqM(y, T, p), T, p);
     612       26019 :   return gerepileupto(av, FqM_to_mod(b, T, p));
     613             : }
     614             : 
     615             : static GEN
     616       11746 : RgM_liftred(GEN x, GEN T)
     617       11746 : { return RgXQM_red(liftpol_shallow(x), T); }
     618             : 
     619             : static GEN
     620        1414 : RgM_mul_ZXQM(GEN x, GEN y, GEN T)
     621             : {
     622        1414 :   pari_sp av = avma;
     623        1414 :   GEN b = ZXQM_mul(RgM_liftred(x,T), RgM_liftred(y, T), T);
     624        1414 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     625             : }
     626             : 
     627             : static GEN
     628         133 : RgM_sqr_ZXQM(GEN x, GEN T)
     629             : {
     630         133 :   pari_sp av = avma;
     631         133 :   GEN b = ZXQM_sqr(RgM_liftred(x, T), T);
     632         133 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     633             : }
     634             : 
     635             : static GEN
     636        4389 : RgM_mul_QXQM(GEN x, GEN y, GEN T)
     637             : {
     638        4389 :   pari_sp av = avma;
     639        4389 :   GEN b = QXQM_mul(RgM_liftred(x, T), RgM_liftred(y, T), T);
     640        4389 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     641             : }
     642             : 
     643             : static GEN
     644           7 : RgM_sqr_QXQM(GEN x, GEN T)
     645             : {
     646           7 :   pari_sp av = avma;
     647           7 :   GEN b = QXQM_sqr(RgM_liftred(x, T), T);
     648           7 :   return gerepilecopy(av, QXQM_to_mod_shallow(b,T));
     649             : }
     650             : 
     651             : INLINE int
     652        4438 : RgX_is_monic_ZX(GEN pol)
     653        4438 : { return RgX_is_ZX(pol) && ZX_is_monic(pol); }
     654             : 
     655             : #define code(t1,t2) ((t1 << 6) | t2)
     656             : static GEN
     657     3737914 : RgM_mul_fast(GEN x, GEN y)
     658             : {
     659             :   GEN p, pol;
     660             :   long pa;
     661     3737914 :   long t = RgM_type2(x,y, &p,&pol,&pa);
     662     3737936 :   switch(t)
     663             :   {
     664     2661874 :     case t_INT:    return ZM_mul(x,y);
     665      103887 :     case t_FRAC:   return QM_mul(x,y);
     666        4200 :     case t_FFELT:  return FFM_mul(x, y, pol);
     667       56175 :     case t_INTMOD: return RgM_mul_FpM(x, y, p);
     668        1421 :     case code(t_POLMOD, t_INT):
     669        1421 :                    return ZX_is_monic(pol)? RgM_mul_ZXQM(x, y, pol): NULL;
     670        4410 :     case code(t_POLMOD, t_FRAC):
     671        4410 :                    return RgX_is_monic_ZX(pol)? RgM_mul_QXQM(x, y, pol): NULL;
     672       26020 :     case code(t_POLMOD, t_INTMOD):
     673       26020 :                    return RgM_mul_FqM(x, y, pol, p);
     674      879949 :     default:       return NULL;
     675             :   }
     676             : }
     677             : 
     678             : static GEN
     679        1183 : RgM_sqr_fast(GEN x)
     680             : {
     681             :   GEN p, pol;
     682             :   long pa;
     683        1183 :   long t = RgM_type(x, &p,&pol,&pa);
     684        1183 :   switch(t)
     685             :   {
     686         126 :     case t_INT:    return ZM_sqr(x);
     687         700 :     case t_FRAC:   return QM_sqr(x);
     688         105 :     case t_FFELT:  return FFM_mul(x, x, pol);
     689          63 :     case t_INTMOD: return RgM_mul_FpM(x, x, p);
     690         140 :     case code(t_POLMOD, t_INT):
     691         140 :                    return ZX_is_monic(pol)? RgM_sqr_ZXQM(x, pol): NULL;
     692          28 :     case code(t_POLMOD, t_FRAC):
     693          28 :                    return RgX_is_monic_ZX(pol)? RgM_sqr_QXQM(x, pol): NULL;
     694           0 :     case code(t_POLMOD, t_INTMOD):
     695           0 :                    return RgM_mul_FqM(x, x, pol, p);
     696          21 :     default:       return NULL;
     697             :   }
     698             : }
     699             : 
     700             : #undef code
     701             : 
     702             : /* lx, ly > 1 */
     703             : static GEN
     704      879976 : RgM_mul_i(GEN x, GEN y, long lx, long ly)
     705             : {
     706      879976 :   GEN z = cgetg(ly, t_MAT);
     707      879973 :   long j, l = lgcols(x);
     708     5090480 :   for (j = 1; j < ly; j++) gel(z,j) = RgM_RgC_mul_i(x, gel(y,j), lx, l);
     709      879960 :   return z;
     710             : }
     711             : GEN
     712     3752212 : RgM_mul(GEN x, GEN y)
     713             : {
     714     3752212 :   long lx, ly = lg(y);
     715             :   GEN z;
     716     3752212 :   if (ly == 1) return cgetg(1,t_MAT);
     717     3737925 :   lx = lg(x);
     718     3737925 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgM_mul'", x,y);
     719     3737929 :   if (lx == 1) return zeromat(0,ly-1);
     720     3737908 :   z = RgM_mul_fast(x, y);
     721     3737930 :   if (z) return z;
     722      879972 :   return RgM_mul_i(x, y, lx, ly);
     723             : }
     724             : 
     725             : GEN
     726        1218 : RgM_sqr(GEN x)
     727             : {
     728        1218 :   long j, lx = lg(x);
     729             :   GEN z;
     730        1218 :   if (lx == 1) return cgetg(1, t_MAT);
     731        1183 :   if (lx != lgcols(x)) pari_err_OP("operation 'RgM_mul'", x,x);
     732        1183 :   z = RgM_sqr_fast(x);
     733        1183 :   if (z) return z;
     734          49 :   z = cgetg(lx, t_MAT);
     735         266 :   for (j=1; j<lx; j++) gel(z,j) = RgM_RgC_mul_i(x, gel(x,j), lx, lx);
     736          49 :   return z;
     737             : }
     738             : 
     739             : /* assume result is symmetric */
     740             : GEN
     741           0 : RgM_multosym(GEN x, GEN y)
     742             : {
     743           0 :   long j, lx, ly = lg(y);
     744             :   GEN M;
     745           0 :   if (ly == 1) return cgetg(1,t_MAT);
     746           0 :   lx = lg(x);
     747           0 :   if (lx != lgcols(y)) pari_err_OP("operation 'RgM_multosym'", x,y);
     748           0 :   if (lx == 1) return cgetg(1,t_MAT);
     749           0 :   if (ly != lgcols(x)) pari_err_OP("operation 'RgM_multosym'", x,y);
     750           0 :   M = cgetg(ly, t_MAT);
     751           0 :   for (j=1; j<ly; j++)
     752             :   {
     753           0 :     GEN z = cgetg(ly,t_COL), yj = gel(y,j);
     754             :     long i;
     755           0 :     for (i=1; i<j; i++) gel(z,i) = gcoeff(M,j,i);
     756           0 :     for (i=j; i<ly; i++)gel(z,i) = RgMrow_RgC_mul_i(x,yj,i,lx);
     757           0 :     gel(M,j) = z;
     758             :   }
     759           0 :   return M;
     760             : }
     761             : /* x~ * y, assuming result is symmetric */
     762             : GEN
     763        7461 : RgM_transmultosym(GEN x, GEN y)
     764             : {
     765        7461 :   long i, j, l, ly = lg(y);
     766             :   GEN M;
     767        7461 :   if (ly == 1) return cgetg(1,t_MAT);
     768        7461 :   if (lg(x) != ly) pari_err_OP("operation 'RgM_transmultosym'", x,y);
     769        7461 :   l = lgcols(y);
     770        7461 :   if (lgcols(x) != l) pari_err_OP("operation 'RgM_transmultosym'", x,y);
     771        7461 :   M = cgetg(ly, t_MAT);
     772       30054 :   for (i=1; i<ly; i++)
     773             :   {
     774       22593 :     GEN xi = gel(x,i), c = cgetg(ly,t_COL);
     775       22593 :     gel(M,i) = c;
     776       46446 :     for (j=1; j<i; j++)
     777       23853 :       gcoeff(M,i,j) = gel(c,j) = RgV_dotproduct_i(xi,gel(y,j),l);
     778       22593 :     gel(c,i) = RgV_dotproduct_i(xi,gel(y,i),l);
     779             :   }
     780        7461 :   return M;
     781             : }
     782             : /* x~ * y */
     783             : GEN
     784           0 : RgM_transmul(GEN x, GEN y)
     785             : {
     786           0 :   long i, j, l, lx, ly = lg(y);
     787             :   GEN M;
     788           0 :   if (ly == 1) return cgetg(1,t_MAT);
     789           0 :   lx = lg(x);
     790           0 :   l = lgcols(y);
     791           0 :   if (lgcols(x) != l) pari_err_OP("operation 'RgM_transmul'", x,y);
     792           0 :   M = cgetg(ly, t_MAT);
     793           0 :   for (i=1; i<ly; i++)
     794             :   {
     795           0 :     GEN yi = gel(y,i), c = cgetg(lx,t_COL);
     796           0 :     gel(M,i) = c;
     797           0 :     for (j=1; j<lx; j++) gel(c,j) = RgV_dotproduct_i(yi,gel(x,j),l);
     798             :   }
     799           0 :   return M;
     800             : }
     801             : 
     802             : GEN
     803         119 : gram_matrix(GEN x)
     804             : {
     805         119 :   long i,j, l, lx = lg(x);
     806             :   GEN M;
     807         119 :   if (!is_matvec_t(typ(x))) pari_err_TYPE("gram",x);
     808         119 :   if (lx == 1) return cgetg(1,t_MAT);
     809         105 :   l = lgcols(x);
     810         105 :   M = cgetg(lx,t_MAT);
     811         294 :   for (i=1; i<lx; i++)
     812             :   {
     813         189 :     GEN xi = gel(x,i), c = cgetg(lx,t_COL);
     814         189 :     gel(M,i) = c;
     815         280 :     for (j=1; j<i; j++)
     816          91 :       gcoeff(M,i,j) = gel(c,j) = RgV_dotproduct_i(xi,gel(x,j),l);
     817         189 :     gel(c,i) = RgV_dotsquare(xi);
     818             :   }
     819         105 :   return M;
     820             : }
     821             : 
     822             : static GEN
     823        3801 : _RgM_add(void *E, GEN x, GEN y) { (void)E; return RgM_add(x, y); }
     824             : 
     825             : static GEN
     826           0 : _RgM_sub(void *E, GEN x, GEN y) { (void)E; return RgM_sub(x, y); }
     827             : 
     828             : static GEN
     829        5684 : _RgM_cmul(void *E, GEN P, long a, GEN x) { (void)E; return RgM_Rg_mul(x,gel(P,a+2)); }
     830             : 
     831             : static GEN
     832         238 : _RgM_sqr(void *E, GEN x) { (void) E; return RgM_sqr(x); }
     833             : 
     834             : static GEN
     835         749 : _RgM_mul(void *E, GEN x, GEN y) { (void) E; return RgM_mul(x, y); }
     836             : 
     837             : static GEN
     838        4046 : _RgM_one(void *E) { long *n = (long*) E; return matid(*n); }
     839             : 
     840             : static GEN
     841           0 : _RgM_zero(void *E) { long *n = (long*) E; return zeromat(*n,*n); }
     842             : 
     843             : static GEN
     844        2828 : _RgM_red(void *E, GEN x) { (void)E; return x; }
     845             : 
     846             : static struct bb_algebra RgM_algebra = { _RgM_red, _RgM_add, _RgM_sub,
     847             :        _RgM_mul, _RgM_sqr, _RgM_one, _RgM_zero };
     848             : 
     849             : /* generates the list of powers of x of degree 0,1,2,...,l*/
     850             : GEN
     851         168 : RgM_powers(GEN x, long l)
     852             : {
     853         168 :   long n = lg(x)-1;
     854         168 :   return gen_powers(x,l,1,(void *) &n, &_RgM_sqr, &_RgM_mul, &_RgM_one);
     855             : }
     856             : 
     857             : GEN
     858         490 : RgX_RgMV_eval(GEN Q, GEN x)
     859             : {
     860         490 :   long n = lg(x)>1 ? lg(gel(x,1))-1:0;
     861         490 :   return gen_bkeval_powers(Q,degpol(Q),x,(void*)&n,&RgM_algebra,&_RgM_cmul);
     862             : }
     863             : 
     864             : GEN
     865        1393 : RgX_RgM_eval(GEN Q, GEN x)
     866             : {
     867        1393 :   long n = lg(x)-1;
     868        1393 :   return gen_bkeval(Q,degpol(Q),x,1,(void*)&n,&RgM_algebra,&_RgM_cmul);
     869             : }
     870             : 
     871             : GEN
     872     1964027 : RgC_Rg_div(GEN x, GEN y)
     873     9730114 : { pari_APPLY_type(t_COL, gdiv(gel(x,i),y)) }
     874             : 
     875             : GEN
     876     8440130 : RgC_Rg_mul(GEN x, GEN y)
     877    48096510 : { pari_APPLY_type(t_COL, gmul(gel(x,i),y)) }
     878             : 
     879             : GEN
     880       28175 : RgV_Rg_mul(GEN x, GEN y)
     881      755454 : { pari_APPLY_type(t_VEC, gmul(gel(x,i),y)) }
     882             : 
     883             : GEN
     884      596273 : RgM_Rg_div(GEN X, GEN c) {
     885      596273 :   long i, j, h, l = lg(X);
     886      596273 :   GEN A = cgetg(l, t_MAT);
     887      596275 :   if (l == 1) return A;
     888      596275 :   h = lgcols(X);
     889     2744651 :   for (j=1; j<l; j++)
     890             :   {
     891     2148464 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     892    17032569 :     for (i = 1; i < h; i++) gel(a,i) = gdiv(gel(x,i), c);
     893     2148378 :     gel(A,j) = a;
     894             :   }
     895      596187 :   return A;
     896             : }
     897             : GEN
     898      225586 : RgM_Rg_mul(GEN X, GEN c) {
     899      225586 :   long i, j, h, l = lg(X);
     900      225586 :   GEN A = cgetg(l, t_MAT);
     901      225592 :   if (l == 1) return A;
     902      225592 :   h = lgcols(X);
     903     1014460 :   for (j=1; j<l; j++)
     904             :   {
     905      788947 :     GEN a = cgetg(h, t_COL), x = gel(X, j);
     906     6758012 :     for (i = 1; i < h; i++) gel(a,i) = gmul(gel(x,i), c);
     907      788869 :     gel(A,j) = a;
     908             :   }
     909      225513 :   return A;
     910             : }
     911             : 
     912             : /********************************************************************/
     913             : /*                                                                  */
     914             : /*                    SCALAR TO MATRIX/VECTOR                       */
     915             : /*                                                                  */
     916             : /********************************************************************/
     917             : /* fill the square nxn matrix equal to t*Id */
     918             : static void
     919     9155338 : fill_scalmat(GEN y, GEN t, long n)
     920             : {
     921             :   long i;
     922    39622817 :   for (i = 1; i <= n; i++)
     923             :   {
     924    30467452 :     gel(y,i) = zerocol(n);
     925    30467479 :     gcoeff(y,i,i) = t;
     926             :   }
     927     9155365 : }
     928             : 
     929             : GEN
     930      836243 : scalarmat(GEN x, long n) {
     931      836243 :   GEN y = cgetg(n+1, t_MAT);
     932      836221 :   if (!n) return y;
     933      836221 :   fill_scalmat(y, gcopy(x), n); return y;
     934             : }
     935             : GEN
     936     2488320 : scalarmat_shallow(GEN x, long n) {
     937     2488320 :   GEN y = cgetg(n+1, t_MAT);
     938     2488334 :   fill_scalmat(y, x, n); return y;
     939             : }
     940             : GEN
     941         217 : scalarmat_s(long x, long n) {
     942         217 :   GEN y = cgetg(n+1, t_MAT);
     943         217 :   if (!n) return y;
     944         217 :   fill_scalmat(y, stoi(x), n); return y;
     945             : }
     946             : GEN
     947     5831647 : matid(long n) {
     948             :   GEN y;
     949     5831647 :   if (n < 0) pari_err_DOMAIN("matid", "size", "<", gen_0, stoi(n));
     950     5831640 :   y = cgetg(n+1, t_MAT);
     951     5831481 :   fill_scalmat(y, gen_1, n); return y;
     952             : }
     953             : 
     954             : INLINE GEN
     955     1435018 : scalarcol_i(GEN x, long n, long c)
     956             : {
     957             :   long i;
     958     1435018 :   GEN y = cgetg(n+1,t_COL);
     959     1435025 :   if (!n) return y;
     960     1435025 :   gel(y,1) = c? gcopy(x): x;
     961     5271547 :   for (i=2; i<=n; i++) gel(y,i) = gen_0;
     962     1435031 :   return y;
     963             : }
     964             : 
     965             : GEN
     966      353945 : scalarcol(GEN x, long n) { return scalarcol_i(x,n,1); }
     967             : 
     968             : GEN
     969     1081081 : scalarcol_shallow(GEN x, long n) { return scalarcol_i(x,n,0); }
     970             : 
     971             : int
     972       28315 : RgM_isscalar(GEN x, GEN s)
     973             : {
     974       28315 :   long i, j, lx = lg(x);
     975             : 
     976       28315 :   if (lx == 1) return 1;
     977       28315 :   if (lx != lgcols(x)) return 0;
     978       28315 :   if (!s) s = gcoeff(x,1,1);
     979             : 
     980       78022 :   for (j=1; j<lx; j++)
     981             :   {
     982       62307 :     GEN c = gel(x,j);
     983      181342 :     for (i=1; i<j; )
     984      130109 :       if (!gequal0(gel(c,i++))) return 0;
     985             :     /* i = j */
     986       51233 :     if (!gequal(gel(c,i++),s)) return 0;
     987      203098 :     for (   ; i<lx; )
     988      153391 :       if (!gequal0(gel(c,i++))) return 0;
     989             :   }
     990       15715 :   return 1;
     991             : }
     992             : 
     993             : int
     994       12460 : RgM_isidentity(GEN x)
     995             : {
     996       12460 :   long i,j, lx = lg(x);
     997             : 
     998       12460 :   if (lx == 1) return 1;
     999       12460 :   if (lx != lgcols(x)) return 0;
    1000       18249 :   for (j=1; j<lx; j++)
    1001             :   {
    1002       18102 :     GEN c = gel(x,j);
    1003       48111 :     for (i=1; i<j; )
    1004       33383 :       if (!gequal0(gel(c,i++))) return 0;
    1005             :     /* i = j */
    1006       14728 :     if (!gequal1(gel(c,i++))) return 0;
    1007       50120 :     for (   ; i<lx; )
    1008       44331 :       if (!gequal0(gel(c,i++))) return 0;
    1009             :   }
    1010         147 :   return 1;
    1011             : }
    1012             : 
    1013             : long
    1014         308 : RgC_is_ei(GEN x)
    1015             : {
    1016         308 :   long i, j = 0, l = lg(x);
    1017        1792 :   for (i = 1; i < l; i++)
    1018             :   {
    1019        1484 :     GEN c = gel(x,i);
    1020        1484 :     if (gequal0(c)) continue;
    1021         308 :     if (!gequal1(c) || j) return 0;
    1022         308 :     j = i;
    1023             :   }
    1024         308 :   return j;
    1025             : }
    1026             : 
    1027             : int
    1028         336 : RgM_isdiagonal(GEN x)
    1029             : {
    1030         336 :   long i,j, lx = lg(x);
    1031         336 :   if (lx == 1) return 1;
    1032         336 :   if (lx != lgcols(x)) return 0;
    1033             : 
    1034        3220 :   for (j=1; j<lx; j++)
    1035             :   {
    1036        2891 :     GEN c = gel(x,j);
    1037       18452 :     for (i=1; i<j; i++)
    1038       15561 :       if (!gequal0(gel(c,i))) return 0;
    1039       18452 :     for (i++; i<lx; i++)
    1040       15568 :       if (!gequal0(gel(c,i))) return 0;
    1041             :   }
    1042         329 :   return 1;
    1043             : }
    1044             : int
    1045         315 : isdiagonal(GEN x) { return (typ(x)==t_MAT) && RgM_isdiagonal(x); }
    1046             : 
    1047             : GEN
    1048       20581 : RgM_det_triangular(GEN mat)
    1049             : {
    1050       20581 :   long i,l = lg(mat);
    1051             :   pari_sp av;
    1052             :   GEN s;
    1053             : 
    1054       20581 :   if (l<3) return l<2? gen_1: gcopy(gcoeff(mat,1,1));
    1055       19314 :   av = avma; s = gcoeff(mat,1,1);
    1056      118749 :   for (i=2; i<l; i++) s = gmul(s,gcoeff(mat,i,i));
    1057       19314 :   return av==avma? gcopy(s): gerepileupto(av,s);
    1058             : }
    1059             : 
    1060             : GEN
    1061      464766 : RgV_kill0(GEN v)
    1062             : {
    1063             :   long i, l;
    1064      464766 :   GEN w = cgetg_copy(v, &l);
    1065   123026850 :   for (i = 1; i < l; i++)
    1066             :   {
    1067   122561517 :     GEN a = gel(v,i);
    1068   122561517 :     gel(w,i) = gequal0(a) ? NULL: a;
    1069             :   }
    1070      465333 :   return w;
    1071             : }

Generated by: LCOV version 1.13