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 - concat.c (source / functions) Coverage Total Hit
Test: PARI/GP v2.18.1 lcov report (development 31053-95e3b72995) Lines: 90.2 % 387 349
Test Date: 2026-07-24 17:03:07 Functions: 94.4 % 18 17
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              : /*******************************************************************/
      16              : /*                                                                 */
      17              : /*                          CONCATENATION                          */
      18              : /*                                                                 */
      19              : /*******************************************************************/
      20              : #include "pari.h"
      21              : #include "paripriv.h"
      22              : 
      23              : /* assume A or B is a t_LIST */
      24              : static GEN
      25           21 : listconcat(GEN A, GEN B)
      26              : {
      27              :   long i, l1, lx;
      28              :   GEN L, z, L1, L2;
      29              : 
      30           21 :   if (typ(A) != t_LIST) {
      31            7 :     if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
      32            7 :     L2 = list_data(B);
      33            7 :     if (!L2) return mklistcopy(A);
      34            7 :     lx = lg(L2) + 1;
      35            7 :     z = mklist();
      36            7 :     list_data(z) = L = cgetg(lx, t_VEC);
      37           35 :     for (i = 2; i < lx; i++) gel(L,i) = gcopy(gel(L2,i-1));
      38            7 :     gel(L,1) = gcopy(A); return z;
      39           14 :   } else if (typ(B) != t_LIST) {
      40            7 :     if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
      41            7 :     L1 = list_data(A);
      42            7 :     if (!L1) return mklistcopy(B);
      43            7 :     lx = lg(L1) + 1;
      44            7 :     z = mklist();
      45            7 :     list_data(z) = L = cgetg(lx, t_VEC);
      46           35 :     for (i = 1; i < lx-1; i++) gel(L,i) = gcopy(gel(L1,i));
      47            7 :     gel(L,i) = gcopy(B); return z;
      48              :   }
      49              :   /* A, B both t_LISTs */
      50            7 :   if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
      51            7 :   if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
      52            7 :   L1 = list_data(A); if (!L1) return listcopy(B);
      53            7 :   L2 = list_data(B); if (!L2) return listcopy(A);
      54              : 
      55            7 :   l1 = lg(L1);
      56            7 :   lx = l1-1 + lg(L2);
      57            7 :   z = mklist();
      58            7 :   list_data(z) = L = cgetg(lx, t_VEC);
      59            7 :   L2 -= l1-1;
      60           35 :   for (i=1; i<l1; i++) gel(L,i) = gcopy(gel(L1,i));
      61           35 :   for (   ; i<lx; i++) gel(L,i) = gcopy(gel(L2,i));
      62            7 :   return z;
      63              : }
      64              : 
      65              : /* assume A or B is a t_STR */
      66              : static GEN
      67          385 : strconcat(GEN x, GEN y)
      68              : {
      69              :   size_t l, lx;
      70          385 :   char *sx = GENtostr_unquoted(x);
      71          385 :   char *sy = GENtostr_unquoted(y), *str;
      72          385 :   lx = strlen(sx);
      73          385 :   l = nchar2nlong(lx + strlen(sy) + 1);
      74          385 :   x = cgetg(l + 1, t_STR); str = GSTR(x);
      75          385 :   strcpy(str,   sx);
      76          385 :   strcpy(str+lx,sy); return x;
      77              : }
      78              : 
      79              : /* concat A and B vertically. Internal */
      80              : GEN
      81     21020649 : vconcat(GEN A, GEN B)
      82              : {
      83              :   long la, ha, hb, hc, i, j, T;
      84              :   GEN M, a, b, c;
      85              : 
      86     21020649 :   if (!A) return B;
      87     20974344 :   if (!B) return A;
      88     20974344 :   la = lg(A); if (la==1) return B;
      89     20913954 :   T = typ(gel(A,1)); /* t_COL or t_VECSMALL */
      90     20913954 :   ha = lgcols(A); M = cgetg(la,t_MAT);
      91     20913954 :   hb = lgcols(B); hc = ha+hb-1;
      92    266988429 :   for (j=1; j<la; j++)
      93              :   {
      94    246074475 :     c = cgetg(hc, T); gel(M, j) = c;
      95    246074475 :     a = gel(A,j);
      96    246074475 :     b = gel(B,j);
      97   1100119234 :     for (i=1; i<ha; i++) *++c = *++a;
      98   1092571623 :     for (i=1; i<hb; i++) *++c = *++b;
      99              :   }
     100     20913954 :   return M;
     101              : }
     102              : 
     103              : static void
     104           49 : err_cat(GEN x, GEN y) { pari_err_OP("concatenation",x,y); }
     105              : 
     106              : GEN
     107     26027711 : shallowconcat(GEN x, GEN y)
     108              : {
     109     26027711 :   long tx=typ(x),ty=typ(y),lx=lg(x),ly=lg(y),i;
     110              :   GEN z,p1;
     111              : 
     112     26027711 :   if (tx==t_STR  || ty==t_STR)  return strconcat(x,y);
     113     26027333 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     114              : 
     115     26027333 :   if (tx==t_MAT && lx==1)
     116              :   {
     117       199104 :     if (ty!=t_VEC) return gtomat(y);
     118            0 :     if (ly==1) return cgetg(1, t_MAT);
     119            0 :     err_cat(x,y);
     120              :   }
     121     25828229 :   if (ty==t_MAT && ly==1)
     122              :   {
     123       170315 :     if (tx!=t_VEC) return gtomat(x);
     124            0 :     if (lx==1) return cgetg(1, t_MAT);
     125            0 :     err_cat(x,y);
     126              :   }
     127              : 
     128     25657914 :   if (tx == ty)
     129              :   {
     130     17041836 :     if (tx == t_MAT)
     131     13150887 :     { if (lgcols(x) != lgcols(y)) err_cat(x,y); }
     132              :     else
     133      3890949 :       if (!is_matvec_t(tx) && tx != t_VECSMALL) return mkvec2(x, y);
     134     17041836 :     z=cgetg(lx+ly-1,tx);
     135    181494207 :     for (i=1; i<lx; i++) z[i]     = x[i];
     136     87399200 :     for (i=1; i<ly; i++) z[lx+i-1]= y[i];
     137     17041836 :     return z;
     138              :   }
     139              : 
     140      8616078 :   if (! is_matvec_t(tx))
     141              :   {
     142        20851 :     if (! is_matvec_t(ty)) return mkvec2(x, y);
     143        20851 :     z=cgetg(ly+1,ty);
     144        20851 :     if (ty != t_MAT) p1 = x;
     145              :     else
     146              :     {
     147            0 :       if (lgcols(y)!=2) err_cat(x,y);
     148            0 :       p1 = mkcol(x);
     149              :     }
     150        67642 :     for (i=2; i<=ly; i++) z[i] = y[i-1];
     151        20851 :     gel(z, 1) = p1; return z;
     152              :   }
     153      8595227 :   if (! is_matvec_t(ty))
     154              :   {
     155      1579829 :     z=cgetg(lx+1,tx);
     156      1579829 :     if (tx != t_MAT) p1 = y;
     157              :     else
     158              :     {
     159            0 :       if (lgcols(x)!=2) err_cat(x,y);
     160            0 :       p1 = mkcol(y);
     161              :     }
     162     39911142 :     for (i=1; i<lx; i++) z[i]=x[i];
     163      1579829 :     gel(z, lx) = p1; return z;
     164              :   }
     165              : 
     166      7015398 :   switch(tx)
     167              :   {
     168        16751 :     case t_VEC:
     169        16751 :       switch(ty)
     170              :       {
     171        16751 :         case t_COL:
     172        16751 :           if (lx<=2) return (lx==1)? y: shallowconcat(gel(x,1),y);
     173            0 :           if (ly>=3) break;
     174            0 :           return (ly==1)? x: shallowconcat(x,gel(y,1));
     175            0 :         case t_MAT:
     176            0 :           z=cgetg(ly,t_MAT); if (lx != ly) break;
     177            0 :           for (i=1; i<ly; i++) gel(z,i) = shallowconcat(gel(x,i),gel(y,i));
     178            0 :           return z;
     179              :       }
     180            0 :       break;
     181              : 
     182       108984 :     case t_COL:
     183       108984 :       switch(ty)
     184              :       {
     185          428 :         case t_VEC:
     186          428 :           if (lx<=2) return (lx==1)? y: shallowconcat(gel(x,1), y);
     187          190 :           if (ly>=3) break;
     188          190 :           return (ly==1)? x: shallowconcat(x, gel(y,1));
     189       108556 :         case t_MAT:
     190       108556 :           if (lx != lgcols(y)) break;
     191       108556 :           z=cgetg(ly+1,t_MAT);  gel(z,1) = x;
     192       678651 :           for (i=2; i<=ly; i++) gel(z,i) = gel(y,i-1);
     193       108556 :           return z;
     194              :       }
     195            0 :       break;
     196              : 
     197      6889663 :     case t_MAT:
     198      6889663 :       switch(ty)
     199              :       {
     200            0 :         case t_VEC:
     201            0 :           z=cgetg(lx, t_MAT); if (ly != lx) break;
     202            0 :           for (i=1; i<lx; i++) gel(z,i) = shallowconcat(gel(x,i), gel(y,i));
     203            0 :           return z;
     204      6889663 :         case t_COL:
     205      6889663 :           if (ly != lgcols(x)) break;
     206      6889663 :           z=cgetg(lx+1,t_MAT); gel(z,lx) = y;
     207     24848912 :           for (i=1; i<lx; i++) z[i]=x[i];
     208      6889663 :           return z;
     209              :       }
     210            0 :       break;
     211              :   }
     212            0 :   err_cat(x,y);
     213              :   return NULL; /* LCOV_EXCL_LINE */
     214              : }
     215              : 
     216              : /* see catmany() */
     217              : static GEN
     218        20902 : catmanyMAT(GEN y1, GEN y2)
     219              : {
     220        20902 :   long i, h = 0, L = 1;
     221              :   GEN z, y;
     222        71809 :   for (y = y2; y >= y1; y--)
     223              :   {
     224        50907 :     GEN c = gel(y,0);
     225        50907 :     long nc = lg(c)-1;
     226        50907 :     if (nc == 0) continue;
     227        50879 :     if (h != lgcols(c))
     228              :     {
     229        20895 :       if (h) err_cat(gel(y2,0), c);
     230        20895 :       h = lgcols(c);
     231              :     }
     232        50879 :     L += nc;
     233        50879 :     z = new_chunk(nc) - 1;
     234       182246 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     235              :   }
     236        20902 :   z = new_chunk(1);
     237        20902 :   *z = evaltyp(t_MAT) | evallg(L);
     238        20902 :   return z;
     239              : }
     240              : static GEN
     241          154 : catmanySTR(GEN y1, GEN y2)
     242              : {
     243          154 :   long L = 1; /* final \0 */
     244              :   GEN z, y;
     245              :   char *s;
     246         8218 :   for (y = y1; y <= y2; y++)
     247              :   {
     248         8064 :     char *c = GSTR( gel(y,0) );
     249         8064 :     L += strlen(c);
     250              :   }
     251          154 :   z = cgetg(nchar2nlong(L)+1, t_STR);
     252          154 :   s = GSTR(z);
     253         8218 :   for (y = y1; y <= y2; y++)
     254              :   {
     255         8064 :     char *c = GSTR( gel(y,0) );
     256         8064 :     long nc = strlen(c);
     257         8064 :     if (nc) { (void)memcpy(s, c, nc); s += nc; }
     258              :   }
     259          154 :   *s = 0; return z;
     260              : }
     261              : 
     262              : /* all entries in y have the same type t = t_VEC, COL, MAT or VECSMALL
     263              :  * concatenate y[k1..k2], with yi = y + ki, k1 <= k2 */
     264              : static GEN
     265      2280176 : catmany(GEN y1, GEN y2, long t)
     266              : {
     267              :   long i, L;
     268              :   GEN z, y;
     269      2280176 :   if (y1 == y2) return gel(y1,0);
     270      2278076 :   if (t == t_MAT) return catmanyMAT(y1, y2);
     271      2257174 :   if (t == t_STR) return catmanySTR(y1, y2);
     272      2257020 :   L = 1;
     273      8372108 :   for (y = y2; y >= y1; y--)
     274              :   {
     275      6115088 :     GEN c = gel(y,0);
     276      6115088 :     long nc = lg(c)-1;
     277      6115088 :     if (nc == 0) continue;
     278      5539782 :     L += nc;
     279      5539782 :     z = new_chunk(nc) - 1;
     280     17826321 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     281              :   }
     282      2257020 :   z = new_chunk(1);
     283      2257020 :   *z = evaltyp(t) | evallg(L);
     284      2257020 :   return z;
     285              : }
     286              : 
     287              : static long
     288          322 : RgMdim(long m, long n)
     289              : {
     290          322 :   ulong mn = itou_or_0(muluu(n, m));
     291          322 :   if (!mn || (mn & ~LGBITS)) pari_err_OVERFLOW("lg()");
     292          322 :   return (long)mn;
     293              : }
     294              : 
     295              : GEN
     296          322 : RgM_flatten_RgC(GEN x)
     297              : {
     298          322 :   long i, j, k, m, n = lg(x)-1;
     299              :   GEN V;
     300          322 :   if (n == 0) return cgetg(1, t_COL);
     301          322 :   if (n == 1) return gel(x,1);
     302          322 :   m = nbrows(x); /* m x n matrix */
     303          322 :   if (m == 0) return cgetg(1, t_COL);
     304          322 :   V = cgetg(RgMdim(m,n) + 1, t_COL);
     305          966 :   for (i = k = 1; i <= n;i++)
     306         1932 :     for (j = 1; j <= m ; j++) gel(V,k++) = gcoeff(x,j,i);
     307          322 :   return V;
     308              : }
     309              : 
     310              : GEN
     311            0 : RgM_flatten_RgV(GEN x)
     312              : {
     313            0 :   long i, j, k, m, n = lg(x)-1;
     314              :   GEN V;
     315            0 :   if (n == 0) return cgetg(1, t_VEC);
     316            0 :   m = nbrows(x); /* m x n matrix */
     317            0 :   if (m == 0) return cgetg(1, t_VEC);
     318            0 :   V = cgetg(RgMdim(m,n) + 1, t_VEC);
     319            0 :   for (i = k = 1; i <= n; i++)
     320            0 :     for (j = 1; j <= m; j++) gel(V,k++) = gcoeff(x,i,j);
     321            0 :   return V;
     322              : }
     323              : 
     324              : GEN
     325      8287443 : shallowconcat1(GEN x)
     326              : {
     327      8287443 :   pari_sp av = avma;
     328              :   long lx, t, i;
     329              :   GEN z;
     330      8287443 :   switch(typ(x))
     331              :   {
     332      8287422 :     case t_VEC: case t_COL:
     333      8287422 :       lx = lg(x);
     334      8287422 :       break;
     335           21 :     case t_LIST:
     336           21 :       if (list_typ(x)!=t_LIST_RAW) pari_err_TYPE("concat",x);
     337           21 :       if (!list_data(x)) pari_err_DOMAIN("concat","vector","=",x,x);
     338            7 :       x = list_data(x); lx = lg(x);
     339            7 :       break;
     340            0 :     default:
     341            0 :       pari_err_TYPE("concat",x);
     342              :       return NULL; /* LCOV_EXCL_LINE */
     343              :   }
     344      8287429 :   if (lx==1) pari_err_DOMAIN("concat","vector","=",x,x);
     345      8287422 :   if (lx==2) return gel(x,1);
     346      2280190 :   z = gel(x,1); t = typ(z); i = 2;
     347      2280190 :   if (is_matvec_t(t) || t == t_VECSMALL || t == t_STR)
     348              :   { /* detect a "homogeneous" object: catmany is faster */
     349      6176159 :     for (; i<lx; i++)
     350      3898307 :       if (typ(gel(x,i)) != t) break;
     351      2280176 :     z = catmany(x + 1, x + i-1, t);
     352              :   }
     353      2283116 :   for (; i<lx; i++) {
     354         2926 :     z = shallowconcat(z, gel(x,i));
     355         2926 :     if (gc_needed(av,3))
     356              :     {
     357            0 :       if (DEBUGMEM>1) pari_warn(warnmem,"concat: i = %ld", i);
     358            0 :       z = gc_GEN(av, z);
     359              :     }
     360              :   }
     361      2280190 :   return z;
     362              : }
     363              : 
     364              : GEN
     365          854 : gconcat1(GEN x)
     366              : {
     367          854 :   pari_sp av = avma;
     368          854 :   return gc_GEN(av, shallowconcat1(x));
     369              : }
     370              : 
     371              : /* fill M[xoff+i, yoff+j] with the contents of c ( c * Id_n if scalar ) */
     372              : static void
     373     17035316 : matfill(GEN M, GEN c, long xoff, long yoff, long n)
     374              : {
     375              :   long i, j, h, l;
     376     17035316 :   l = lg(c); if (l == 1) return;
     377     17007743 :   switch(typ(c))
     378              :   {
     379        44324 :     case t_VEC:
     380      1033032 :       for (i = 1; i < l; i++)
     381       988708 :         gcoeff(M,xoff+1,yoff+i) = gel(c,i);
     382        44324 :       break;
     383       162122 :     case t_COL:
     384      1189964 :       for (i = 1; i < l; i++)
     385      1027842 :         gcoeff(M,xoff+i,yoff+1) = gel(c,i);
     386       162122 :       break;
     387      9661355 :     case t_MAT:
     388      9661355 :       h = lgcols(c);
     389     28622623 :       for (j = 1; j < l; j++)
     390     76972520 :         for (i = 1; i < h; i++) gcoeff(M,xoff+i,yoff+j) = gcoeff(c,i,j);
     391      9661355 :       break;
     392      7139942 :     default:
     393     16134136 :       for (i = 1; i <= n; i++)
     394      8994194 :         gcoeff(M, xoff+i, yoff+i) = c;
     395      7139942 :       break;
     396              :   }
     397              : }
     398              : 
     399              : static GEN
     400     19399068 : _matsize(GEN x)
     401              : {
     402     19399068 :   long t = typ(x), L = lg(x) - 1;
     403     19399068 :   switch(t)
     404              :   { /* matsize */
     405        88662 :     case t_VEC: return mkvecsmall2(1, L);
     406       324188 :     case t_COL: return mkvecsmall2(L, 1);
     407     11844833 :     case t_MAT: return mkvecsmall2(L? nbrows(x): 0, L);
     408      7141385 :     default:
     409      7141385 :       if (is_noncalc_t(t)) pari_err_TYPE("_matsize", x);
     410      7141385 :       return mkvecsmall2(1, 1);
     411              :   }
     412              : }
     413              : 
     414              : GEN
     415      3834633 : shallowmatconcat(GEN v)
     416              : {
     417      3834633 :   long i, j, h, l = lg(v), L = 0, H = 0;
     418              :   GEN M, maxh, maxl;
     419      3834633 :   if (l == 1) return cgetg(1,t_MAT);
     420      3829495 :   switch(typ(v))
     421              :   {
     422      1121216 :     case t_VEC:
     423      3438754 :       for (i = 1; i < l; i++)
     424              :       {
     425      2317538 :         GEN c = gel(v,i);
     426      2317538 :         GEN s = _matsize(c);
     427      2317538 :         H = maxss(H, s[1]);
     428      2317538 :         L += s[2];
     429              :       }
     430      1121216 :       M = zeromatcopy(H, L);
     431      1121216 :       L = 0;
     432      3438754 :       for (i = 1; i < l; i++)
     433              :       {
     434      2317538 :         GEN c = gel(v,i);
     435      2317538 :         GEN s = _matsize(c);
     436      2317538 :         matfill(M, c, 0, L, 1);
     437      2317538 :         L += s[2];
     438              :       }
     439      1121216 :       return M;
     440              : 
     441         3710 :     case t_COL:
     442        49924 :       for (i = 1; i < l; i++)
     443              :       {
     444        46214 :         GEN c = gel(v,i);
     445        46214 :         GEN s = _matsize(c);
     446        46214 :         H += s[1];
     447        46214 :         L = maxss(L, s[2]);
     448              :       }
     449         3710 :       M = zeromatcopy(H, L);
     450         3710 :       H = 0;
     451        49924 :       for (i = 1; i < l; i++)
     452              :       {
     453        46214 :         GEN c = gel(v,i);
     454        46214 :         GEN s = _matsize(c);
     455        46214 :         matfill(M, c, H, 0, 1);
     456        46214 :         H += s[1];
     457              :       }
     458         3710 :       return M;
     459      2704569 :     case t_MAT:
     460      2704569 :       h = lgcols(v);
     461      2704569 :       maxh = zero_zv(h-1);
     462      2704569 :       maxl = zero_zv(l-1);
     463      8884345 :       for (j = 1; j < l; j++)
     464     20851340 :         for (i = 1; i < h; i++)
     465              :         {
     466     14671564 :           GEN c = gcoeff(v,i,j);
     467     14671564 :           GEN s = _matsize(c);
     468     14671564 :           if (s[1] > maxh[i]) maxh[i] = s[1];
     469     14671564 :           if (s[2] > maxl[j]) maxl[j] = s[2];
     470              :         }
     471      8884352 :       for (i = 1, H = 0; i < h; i++) H += maxh[i];
     472      8884345 :       for (j = 1, L = 0; j < l; j++) L += maxl[j];
     473      2704569 :       M = zeromatcopy(H, L);
     474      8884345 :       for (j = 1, L = 0; j < l; j++)
     475              :       {
     476     20851340 :         for (i = 1, H = 0; i < h; i++)
     477              :         {
     478     14671564 :           GEN c = gcoeff(v,i,j);
     479     14671564 :           matfill(M, c, H, L, minss(maxh[i], maxl[j]));
     480     14671564 :           H += maxh[i];
     481              :         }
     482      6179776 :         L += maxl[j];
     483              :       }
     484      2704569 :       return M;
     485            0 :     default:
     486            0 :       pari_err_TYPE("shallowmatconcat", v);
     487              :       return NULL;/*LCOV_EXCL_LINE*/
     488              :   }
     489              : }
     490              : GEN
     491        76580 : matconcat(GEN v)
     492              : {
     493        76580 :   pari_sp av = avma;
     494        76580 :   return gc_GEN(av, shallowmatconcat(v));
     495              : }
     496              : 
     497              : GEN
     498     19438754 : gconcat(GEN x, GEN y)
     499              : {
     500              :   long tx, lx,ty,ly,i;
     501              :   GEN z,p1;
     502              : 
     503     19438754 :   if (!y) return gconcat1(x);
     504     19437900 :   tx = typ(x);
     505     19437900 :   ty = typ(y);
     506     19437900 :   if (tx==t_STR  || ty==t_STR)
     507              :   {
     508            7 :     pari_sp av = avma;
     509            7 :     return gc_leaf(av, strconcat(x,y));
     510              :   }
     511     19437893 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     512     19437872 :   lx=lg(x); ly=lg(y);
     513              : 
     514     19437872 :   if (tx==t_MAT && lx==1)
     515              :   {
     516          588 :     if (ty!=t_VEC) return gtomat(y);
     517           21 :     if (ly==1) return cgetg(1, t_MAT);
     518            7 :     err_cat(x,y);
     519              :   }
     520     19437284 :   if (ty==t_MAT && ly==1)
     521              :   {
     522           21 :     if (tx!=t_VEC) return gtomat(x);
     523           14 :     if (lx==1) return cgetg(1, t_MAT);
     524            7 :     err_cat(x,y);
     525              :   }
     526              : 
     527     19437263 :   if (tx == ty)
     528              :   {
     529       653438 :     if (tx == t_MAT && lgcols(x) != lgcols(y)) err_cat(x,y);
     530       653438 :     if (!is_matvec_t(tx))
     531              :     {
     532          210 :       if (tx != t_VECSMALL) return mkvec2copy(x, y);
     533          203 :       z = cgetg(lx+ly-1,t_VECSMALL);
     534          301 :       for (i=1; i<lx; i++) z[i]     = x[i];
     535          294 :       for (i=1; i<ly; i++) z[lx+i-1]= y[i];
     536          203 :       return z;
     537              :     }
     538       653228 :     z=cgetg(lx+ly-1,tx);
     539      3301610 :     for (i=1; i<lx; i++) gel(z,i)     = gcopy(gel(x,i));
     540      2529701 :     for (i=1; i<ly; i++) gel(z,lx+i-1)= gcopy(gel(y,i));
     541       653228 :     return z;
     542              :   }
     543              : 
     544     18783825 :   if (! is_matvec_t(tx))
     545              :   {
     546          168 :     if (! is_matvec_t(ty)) return mkvec2copy(x, y);
     547          168 :     z=cgetg(ly+1,ty);
     548          168 :     if (ty != t_MAT) p1 = gcopy(x);
     549              :     else
     550              :     {
     551           14 :       if (lgcols(y)!=2) err_cat(x,y);
     552            7 :       p1 = mkcolcopy(x);
     553              :     }
     554         3514 :     for (i=2; i<=ly; i++) gel(z,i) = gcopy(gel(y,i-1));
     555          161 :     gel(z,1) = p1; return z;
     556              :   }
     557     18783657 :   if (! is_matvec_t(ty))
     558              :   {
     559     18783559 :     z=cgetg(lx+1,tx);
     560     18783559 :     if (tx != t_MAT) p1 = gcopy(y);
     561              :     else
     562              :     {
     563           14 :       if (lgcols(x)!=2) err_cat(x,y);
     564            7 :       p1 = mkcolcopy(y);
     565              :     }
     566   2547693842 :     for (i=1; i<lx; i++) gel(z,i) = gcopy(gel(x,i));
     567     18783552 :     gel(z,lx) = p1; return z;
     568              :   }
     569              : 
     570           98 :   switch(tx)
     571              :   {
     572           35 :     case t_VEC:
     573           35 :       switch(ty)
     574              :       {
     575           28 :         case t_COL:
     576           28 :           if (lx<=2) return (lx==1)? gcopy(y): gconcat(gel(x,1),y);
     577           28 :           if (ly>=3) break;
     578           14 :           return (ly==1)? gcopy(x): gconcat(x,gel(y,1));
     579            7 :         case t_MAT:
     580            7 :           z=cgetg(ly,t_MAT); if (lx != ly) break;
     581           21 :           for (i=1; i<ly; i++) gel(z,i) = gconcat(gel(x,i),gel(y,i));
     582            7 :           return z;
     583              :       }
     584           14 :       break;
     585              : 
     586           49 :     case t_COL:
     587           49 :       switch(ty)
     588              :       {
     589           42 :         case t_VEC:
     590           42 :           if (lx<=2) return (lx==1)? gcopy(y): gconcat(gel(x,1),y);
     591           28 :           if (ly>=3) break;
     592           21 :           return (ly==1)? gcopy(x): gconcat(x,gel(y,1));
     593            7 :         case t_MAT:
     594            7 :           if (lx != lgcols(y)) break;
     595            7 :           z=cgetg(ly+1,t_MAT); gel(z,1) = gcopy(x);
     596           14 :           for (i=2; i<=ly; i++) gel(z,i) = gcopy(gel(y,i-1));
     597            7 :           return z;
     598              :       }
     599            7 :       break;
     600              : 
     601           14 :     case t_MAT:
     602           14 :       switch(ty)
     603              :       {
     604            7 :         case t_VEC:
     605            7 :           z=cgetg(lx,t_MAT); if (ly != lx) break;
     606           21 :           for (i=1; i<lx; i++) gel(z,i) = gconcat(gel(x,i),gel(y,i));
     607            7 :           return z;
     608            7 :         case t_COL:
     609            7 :           if (ly != lgcols(x)) break;
     610            7 :           z=cgetg(lx+1,t_MAT); gel(z,lx) = gcopy(y);
     611           14 :           for (i=1; i<lx; i++) gel(z,i) = gcopy(gel(x,i));
     612            7 :           return z;
     613              :       }
     614            0 :       break;
     615              :   }
     616           21 :   err_cat(x,y);
     617              :   return NULL; /* LCOV_EXCL_LINE */
     618              : }
        

Generated by: LCOV version 2.0-1