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) Hit Total Coverage
Test: PARI/GP v2.18.1 lcov report (development 30849-48ff4d246c) Lines: 344 381 90.3 %
Date: 2026-05-01 09:26:53 Functions: 17 18 94.4 %
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    20850997 : vconcat(GEN A, GEN B)
      82             : {
      83             :   long la, ha, hb, hc, i, j, T;
      84             :   GEN M, a, b, c;
      85             : 
      86    20850997 :   if (!A) return B;
      87    20804693 :   if (!B) return A;
      88    20804693 :   la = lg(A); if (la==1) return B;
      89    20744353 :   T = typ(gel(A,1)); /* t_COL or t_VECSMALL */
      90    20744353 :   ha = lgcols(A); M = cgetg(la,t_MAT);
      91    20744513 :   hb = lgcols(B); hc = ha+hb-1;
      92   261730800 :   for (j=1; j<la; j++)
      93             :   {
      94   240985356 :     c = cgetg(hc, T); gel(M, j) = c;
      95   240970231 :     a = gel(A,j);
      96   240970231 :     b = gel(B,j);
      97  1074681855 :     for (i=1; i<ha; i++) *++c = *++a;
      98  1068050289 :     for (i=1; i<hb; i++) *++c = *++b;
      99             :   }
     100    20745444 :   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    25860222 : shallowconcat(GEN x, GEN y)
     108             : {
     109    25860222 :   long tx=typ(x),ty=typ(y),lx=lg(x),ly=lg(y),i;
     110             :   GEN z,p1;
     111             : 
     112    25860222 :   if (tx==t_STR  || ty==t_STR)  return strconcat(x,y);
     113    25859905 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     114             : 
     115    25859880 :   if (tx==t_MAT && lx==1)
     116             :   {
     117      199203 :     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    25660677 :   if (ty==t_MAT && ly==1)
     122             :   {
     123      170176 :     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    25490977 :   if (tx == ty)
     129             :   {
     130    16936620 :     if (tx == t_MAT)
     131    13036283 :     { if (lgcols(x) != lgcols(y)) err_cat(x,y); }
     132             :     else
     133     3900337 :       if (!is_matvec_t(tx) && tx != t_VECSMALL) return mkvec2(x, y);
     134    16936555 :     z=cgetg(lx+ly-1,tx);
     135   181965187 :     for (i=1; i<lx; i++) z[i]     = x[i];
     136    86912141 :     for (i=1; i<ly; i++) z[lx+i-1]= y[i];
     137    16936473 :     return z;
     138             :   }
     139             : 
     140     8554357 :   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     8533508 :   if (! is_matvec_t(ty))
     154             :   {
     155     1523884 :     z=cgetg(lx+1,tx);
     156     1523884 :     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    39764574 :     for (i=1; i<lx; i++) z[i]=x[i];
     163     1523884 :     gel(z, lx) = p1; return z;
     164             :   }
     165             : 
     166     7009576 :   switch(tx)
     167             :   {
     168       16751 :     case t_VEC:
     169             :       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      109126 :     case t_COL:
     183             :       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      108698 :         case t_MAT:
     190      108698 :           if (lx != lgcols(y)) break;
     191      108698 :           z=cgetg(ly+1,t_MAT);  gel(z,1) = x;
     192      684120 :           for (i=2; i<=ly; i++) gel(z,i) = gel(y,i-1);
     193      108698 :           return z;
     194             :       }
     195           0 :       break;
     196             : 
     197     6883720 :     case t_MAT:
     198             :       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     6883712 :         case t_COL:
     205     6883712 :           if (ly != lgcols(x)) break;
     206     6883714 :           z=cgetg(lx+1,t_MAT); gel(z,lx) = y;
     207    24818075 :           for (i=1; i<lx; i++) z[i]=x[i];
     208     6883883 :           return z;
     209             :       }
     210           8 :       break;
     211             :   }
     212           0 :   err_cat(x,y);
     213             :   return NULL; /* LCOV_EXCL_LINE */
     214             : }
     215             : 
     216             : /* see catmany() */
     217             : static GEN
     218       20797 : catmanyMAT(GEN y1, GEN y2)
     219             : {
     220       20797 :   long i, h = 0, L = 1;
     221             :   GEN z, y;
     222       71494 :   for (y = y2; y >= y1; y--)
     223             :   {
     224       50697 :     GEN c = gel(y,0);
     225       50697 :     long nc = lg(c)-1;
     226       50697 :     if (nc == 0) continue;
     227       50669 :     if (h != lgcols(c))
     228             :     {
     229       20790 :       if (h) err_cat(gel(y2,0), c);
     230       20790 :       h = lgcols(c);
     231             :     }
     232       50669 :     L += nc;
     233       50669 :     z = new_chunk(nc) - 1;
     234      181602 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     235             :   }
     236       20797 :   z = new_chunk(1);
     237       20797 :   *z = evaltyp(t_MAT) | evallg(L);
     238       20797 :   return z;
     239             : }
     240             : static GEN
     241         147 : catmanySTR(GEN y1, GEN y2)
     242             : {
     243         147 :   long L = 1; /* final \0 */
     244             :   GEN z, y;
     245             :   char *s;
     246        7364 :   for (y = y1; y <= y2; y++)
     247             :   {
     248        7217 :     char *c = GSTR( gel(y,0) );
     249        7217 :     L += strlen(c);
     250             :   }
     251         147 :   z = cgetg(nchar2nlong(L)+1, t_STR);
     252         147 :   s = GSTR(z);
     253        7364 :   for (y = y1; y <= y2; y++)
     254             :   {
     255        7217 :     char *c = GSTR( gel(y,0) );
     256        7217 :     long nc = strlen(c);
     257        7217 :     if (nc) { (void)memcpy(s, c, nc); s += nc; }
     258             :   }
     259         147 :   *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     2277841 : catmany(GEN y1, GEN y2, long t)
     266             : {
     267             :   long i, L;
     268             :   GEN z, y;
     269     2277841 :   if (y1 == y2) return gel(y1,0);
     270     2275741 :   if (t == t_MAT) return catmanyMAT(y1, y2);
     271     2254944 :   if (t == t_STR) return catmanySTR(y1, y2);
     272     2254797 :   L = 1;
     273     8363313 :   for (y = y2; y >= y1; y--)
     274             :   {
     275     6108516 :     GEN c = gel(y,0);
     276     6108516 :     long nc = lg(c)-1;
     277     6108516 :     if (nc == 0) continue;
     278     5537410 :     L += nc;
     279     5537410 :     z = new_chunk(nc) - 1;
     280    17818742 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     281             :   }
     282     2254797 :   z = new_chunk(1);
     283     2254827 :   *z = evaltyp(t) | evallg(L);
     284     2254830 :   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     8262196 : shallowconcat1(GEN x)
     326             : {
     327     8262196 :   pari_sp av = avma;
     328             :   long lx, t, i;
     329             :   GEN z;
     330     8262196 :   switch(typ(x))
     331             :   {
     332     8262192 :     case t_VEC: case t_COL:
     333     8262192 :       lx = lg(x);
     334     8262192 :       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     8262199 :   if (lx==1) pari_err_DOMAIN("concat","vector","=",x,x);
     345     8262241 :   if (lx==2) return gel(x,1);
     346     2277882 :   z = gel(x,1); t = typ(z); i = 2;
     347     2277882 :   if (is_matvec_t(t) || t == t_VECSMALL || t == t_STR)
     348             :   { /* detect a "homogeneous" object: catmany is faster */
     349     6168559 :     for (; i<lx; i++)
     350     3893021 :       if (typ(gel(x,i)) != t) break;
     351     2277862 :     z = catmany(x + 1, x + i-1, t);
     352             :   }
     353     2280814 :   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     2277888 :   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    17026118 : matfill(GEN M, GEN c, long xoff, long yoff, long n)
     374             : {
     375             :   long i, j, h, l;
     376    17026118 :   l = lg(c); if (l == 1) return;
     377    16998559 :   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      162094 :     case t_COL:
     384     1189852 :       for (i = 1; i < l; i++)
     385     1027758 :         gcoeff(M,xoff+i,yoff+1) = gel(c,i);
     386      162094 :       break;
     387     9656797 :     case t_MAT:
     388     9656797 :       h = lgcols(c);
     389    28584453 :       for (j = 1; j < l; j++)
     390    76357402 :         for (i = 1; i < h; i++) gcoeff(M,xoff+i,yoff+j) = gcoeff(c,i,j);
     391     9656794 :       break;
     392     7135344 :     default:
     393    16103867 :       for (i = 1; i <= n; i++)
     394     8968523 :         gcoeff(M, xoff+i, yoff+i) = c;
     395     7135344 :       break;
     396             :   }
     397             : }
     398             : 
     399             : static GEN
     400    19389228 : _matsize(GEN x)
     401             : {
     402    19389228 :   long t = typ(x), L = lg(x) - 1;
     403    19389228 :   switch(t)
     404             :   { /* matsize */
     405       88662 :     case t_VEC: return mkvecsmall2(1, L);
     406      324132 :     case t_COL: return mkvecsmall2(L, 1);
     407    11839658 :     case t_MAT: return mkvecsmall2(L? nbrows(x): 0, L);
     408     7136776 :     default:
     409     7136776 :       if (is_noncalc_t(t)) pari_err_TYPE("_matsize", x);
     410     7136787 :       return mkvecsmall2(1, 1);
     411             :   }
     412             : }
     413             : 
     414             : GEN
     415     3833017 : shallowmatconcat(GEN v)
     416             : {
     417     3833017 :   long i, j, h, l = lg(v), L = 0, H = 0;
     418             :   GEN M, maxh, maxl;
     419     3833017 :   if (l == 1) return cgetg(1,t_MAT);
     420     3827886 :   switch(typ(v))
     421             :   {
     422     1120943 :     case t_VEC:
     423     3437891 :       for (i = 1; i < l; i++)
     424             :       {
     425     2316964 :         GEN c = gel(v,i);
     426     2316964 :         GEN s = _matsize(c);
     427     2316957 :         H = maxss(H, s[1]);
     428     2316948 :         L += s[2];
     429             :       }
     430     1120927 :       M = zeromatcopy(H, L);
     431     1120952 :       L = 0;
     432     3437949 :       for (i = 1; i < l; i++)
     433             :       {
     434     2316998 :         GEN c = gel(v,i);
     435     2316998 :         GEN s = _matsize(c);
     436     2317000 :         matfill(M, c, 0, L, 1);
     437     2316997 :         L += s[2];
     438             :       }
     439     1120951 :       return M;
     440             : 
     441        3703 :     case t_COL:
     442       49903 :       for (i = 1; i < l; i++)
     443             :       {
     444       46200 :         GEN c = gel(v,i);
     445       46200 :         GEN s = _matsize(c);
     446       46200 :         H += s[1];
     447       46200 :         L = maxss(L, s[2]);
     448             :       }
     449        3703 :       M = zeromatcopy(H, L);
     450        3703 :       H = 0;
     451       49903 :       for (i = 1; i < l; i++)
     452             :       {
     453       46200 :         GEN c = gel(v,i);
     454       46200 :         GEN s = _matsize(c);
     455       46200 :         matfill(M, c, H, 0, 1);
     456       46200 :         H += s[1];
     457             :       }
     458        3703 :       return M;
     459     2703240 :     case t_MAT:
     460     2703240 :       h = lgcols(v);
     461     2703240 :       maxh = zero_zv(h-1);
     462     2703239 :       maxl = zero_zv(l-1);
     463     8879687 :       for (j = 1; j < l; j++)
     464    20839359 :         for (i = 1; i < h; i++)
     465             :         {
     466    14662913 :           GEN c = gcoeff(v,i,j);
     467    14662913 :           GEN s = _matsize(c);
     468    14662912 :           if (s[1] > maxh[i]) maxh[i] = s[1];
     469    14662912 :           if (s[2] > maxl[j]) maxl[j] = s[2];
     470             :         }
     471     8879695 :       for (i = 1, H = 0; i < h; i++) H += maxh[i];
     472     8879688 :       for (j = 1, L = 0; j < l; j++) L += maxl[j];
     473     2703240 :       M = zeromatcopy(H, L);
     474     8879685 :       for (j = 1, L = 0; j < l; j++)
     475             :       {
     476    20839368 :         for (i = 1, H = 0; i < h; i++)
     477             :         {
     478    14662922 :           GEN c = gcoeff(v,i,j);
     479    14662922 :           matfill(M, c, H, L, minss(maxh[i], maxl[j]));
     480    14662922 :           H += maxh[i];
     481             :         }
     482     6176446 :         L += maxl[j];
     483             :       }
     484     2703239 :       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    19436982 : gconcat(GEN x, GEN y)
     499             : {
     500             :   long tx, lx,ty,ly,i;
     501             :   GEN z,p1;
     502             : 
     503    19436982 :   if (!y) return gconcat1(x);
     504    19436128 :   tx = typ(x);
     505    19436128 :   ty = typ(y);
     506    19436128 :   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    19436121 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     512    19436100 :   lx=lg(x); ly=lg(y);
     513             : 
     514    19436100 :   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    19435512 :   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    19435491 :   if (tx == ty)
     528             :   {
     529      653466 :     if (tx == t_MAT && lgcols(x) != lgcols(y)) err_cat(x,y);
     530      653466 :     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      653256 :     z=cgetg(lx+ly-1,tx);
     539     3301642 :     for (i=1; i<lx; i++) gel(z,i)     = gcopy(gel(x,i));
     540     2529715 :     for (i=1; i<ly; i++) gel(z,lx+i-1)= gcopy(gel(y,i));
     541      653256 :     return z;
     542             :   }
     543             : 
     544    18782025 :   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    18781857 :   if (! is_matvec_t(ty))
     558             :   {
     559    18781759 :     z=cgetg(lx+1,tx);
     560    18781759 :     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  2547690282 :     for (i=1; i<lx; i++) gel(z,i) = gcopy(gel(x,i));
     567    18781752 :     gel(z,lx) = p1; return z;
     568             :   }
     569             : 
     570          98 :   switch(tx)
     571             :   {
     572          35 :     case t_VEC:
     573             :       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             :       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             :       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 1.16