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-bordeaux1.fr machine (x86_64 architecture), and agregate them in the final report:

The target is 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.8.0 lcov report (development 17934-aad8e41) Lines: 310 339 91.4 %
Date: 2015-08-05 Functions: 15 15 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 275 357 77.0 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright (C) 2000  The PARI group.
       2                 :            : 
       3                 :            : This file is part of the PARI/GP package.
       4                 :            : 
       5                 :            : PARI/GP is free software; you can redistribute it and/or modify it under the
       6                 :            : terms of the GNU General Public License as published by the Free Software
       7                 :            : Foundation. It is distributed in the hope that it will be useful, but WITHOUT
       8                 :            : ANY WARRANTY WHATSOEVER.
       9                 :            : 
      10                 :            : Check the License for details. You should have received a copy of it, along
      11                 :            : with the package; see the file 'COPYING'. If not, write to the Free Software
      12                 :            : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      13                 :            : 
      14                 :            : /*******************************************************************/
      15                 :            : /*                                                                 */
      16                 :            : /*                          CONCATENATION                          */
      17                 :            : /*                                                                 */
      18                 :            : /*******************************************************************/
      19                 :            : #include "pari.h"
      20                 :            : #include "paripriv.h"
      21                 :            : 
      22                 :            : /* assume A or B is a t_LIST */
      23                 :            : static GEN
      24                 :         21 : listconcat(GEN A, GEN B)
      25                 :            : {
      26                 :            :   long i, l1, lx;
      27                 :            :   GEN L, z, L1, L2;
      28                 :            : 
      29         [ +  + ]:         21 :   if (typ(A) != t_LIST) {
      30         [ -  + ]:          7 :     if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
      31                 :          7 :     L2 = list_data(B);
      32         [ -  + ]:          7 :     if (!L2) return mklistcopy(A);
      33                 :          7 :     lx = lg(L2) + 1;
      34                 :          7 :     z = listcreate();
      35                 :          7 :     list_data(z) = L = cgetg(lx, t_VEC);
      36         [ +  + ]:         35 :     for (i = 2; i < lx; i++) gel(L,i) = gcopy(gel(L2,i-1));
      37                 :          7 :     gel(L,1) = gcopy(A); return z;
      38         [ +  + ]:         14 :   } else if (typ(B) != t_LIST) {
      39         [ -  + ]:          7 :     if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
      40                 :          7 :     L1 = list_data(A);
      41         [ -  + ]:          7 :     if (!L1) return mklistcopy(B);
      42                 :          7 :     lx = lg(L1) + 1;
      43                 :          7 :     z = listcreate();
      44                 :          7 :     list_data(z) = L = cgetg(lx, t_VEC);
      45         [ +  + ]:         35 :     for (i = 1; i < lx-1; i++) gel(L,i) = gcopy(gel(L1,i));
      46                 :          7 :     gel(L,i) = gcopy(B); return z;
      47                 :            :   }
      48                 :            :   /* A, B both t_LISTs */
      49         [ -  + ]:          7 :   if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
      50         [ -  + ]:          7 :   if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
      51         [ -  + ]:          7 :   L1 = list_data(A); if (!L1) return listcopy(B);
      52         [ -  + ]:          7 :   L2 = list_data(B); if (!L2) return listcopy(A);
      53                 :            : 
      54                 :          7 :   l1 = lg(L1);
      55                 :          7 :   lx = l1-1 + lg(L2);
      56                 :          7 :   z = cgetg(3, t_LIST);
      57                 :          7 :   z[1] = 0UL;
      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) = gclone(gel(L1,i));
      61         [ +  + ]:         35 :   for (   ; i<lx; i++) gel(L,i) = gclone(gel(L2,i));
      62                 :         21 :   return z;
      63                 :            : }
      64                 :            : 
      65                 :            : /* assume A or B is a t_STR */
      66                 :            : static GEN
      67                 :         35 : strconcat(GEN x, GEN y)
      68                 :            : {
      69                 :            :   size_t l, lx;
      70                 :         35 :   char *sx = GENtostr_unquoted(x);
      71                 :         35 :   char *sy = GENtostr_unquoted(y), *str;
      72                 :         35 :   lx = strlen(sx);
      73                 :         35 :   l = nchar2nlong(lx + strlen(sy) + 1);
      74                 :         35 :   x = cgetg(l + 1, t_STR); str = GSTR(x);
      75                 :         35 :   strcpy(str,   sx);
      76                 :         35 :   strcpy(str+lx,sy); return x;
      77                 :            : }
      78                 :            : 
      79                 :            : /* concat A and B vertically. Internal */
      80                 :            : GEN
      81                 :      23210 : vconcat(GEN A, GEN B)
      82                 :            : {
      83                 :            :   long la, ha, hb, hc, i, j, T;
      84                 :            :   GEN M, a, b, c;
      85                 :            : 
      86         [ +  + ]:      23210 :   if (!A) return B;
      87         [ -  + ]:      22930 :   if (!B) return A;
      88         [ +  + ]:      22930 :   la = lg(A); if (la==1) return A;
      89                 :      21405 :   T = typ(gel(A,1)); /* t_COL or t_VECSMALL */
      90                 :      21405 :   ha = lgcols(A); M = cgetg(la,t_MAT);
      91                 :      21405 :   hb = lgcols(B); hc = ha+hb-1;
      92         [ +  + ]:      90757 :   for (j=1; j<la; j++)
      93                 :            :   {
      94                 :      69352 :     c = cgetg(hc, T); gel(M, j) = c;
      95                 :      69352 :     a = gel(A,j);
      96                 :      69352 :     b = gel(B,j);
      97         [ +  + ]:     736357 :     for (i=1; i<ha; i++) *++c = *++a;
      98         [ +  + ]:     385428 :     for (i=1; i<hb; i++) *++c = *++b;
      99                 :            :   }
     100                 :      23210 :   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                 :    3775296 : shallowconcat(GEN x, GEN y)
     108                 :            : {
     109                 :    3775296 :   long tx=typ(x),ty=typ(y),lx=lg(x),ly=lg(y),i;
     110                 :            :   GEN z,p1;
     111                 :            : 
     112 [ +  + ][ +  + ]:    3775296 :   if (tx==t_STR  || ty==t_STR)  return strconcat(x,y);
     113 [ +  - ][ -  + ]:    3775268 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     114                 :            : 
     115 [ +  + ][ +  + ]:    3775268 :   if (tx==t_MAT && lx==1)
     116                 :            :   {
     117         [ +  - ]:      16995 :     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 [ +  + ][ +  + ]:    3758273 :   if (ty==t_MAT && ly==1)
     122                 :            :   {
     123         [ +  - ]:       6464 :     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         [ +  + ]:    3751809 :   if (tx == ty)
     129                 :            :   {
     130         [ +  + ]:     862121 :     if (tx == t_MAT)
     131         [ -  + ]:     182341 :     { if (lgcols(x) != lgcols(y)) err_cat(x,y); }
     132                 :            :     else
     133 [ +  + ][ -  + ]:     679780 :       if (!is_matvec_t(tx) && tx != t_VECSMALL) return mkvec2(x, y);
     134                 :     862121 :     z=cgetg(lx+ly-1,tx);
     135         [ +  + ]:    3163406 :     for (i=1; i<lx; i++) z[i]     = x[i];
     136         [ +  + ]:    4967221 :     for (i=1; i<ly; i++) z[lx+i-1]= y[i];
     137                 :     862121 :     return z;
     138                 :            :   }
     139                 :            : 
     140         [ +  + ]:    2889688 :   if (! is_matvec_t(tx))
     141                 :            :   {
     142         [ -  + ]:        322 :     if (! is_matvec_t(ty)) return mkvec2(x, y);
     143                 :        322 :     z=cgetg(ly+1,ty);
     144         [ +  - ]:        322 :     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         [ +  + ]:       1358 :     for (i=2; i<=ly; i++) z[i] = y[i-1];
     151                 :        322 :     gel(z, 1) = p1; return z;
     152                 :            :   }
     153         [ +  + ]:    2889366 :   if (! is_matvec_t(ty))
     154                 :            :   {
     155                 :      19132 :     z=cgetg(lx+1,tx);
     156         [ +  - ]:      19132 :     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         [ +  + ]:      95750 :     for (i=1; i<lx; i++) z[i]=x[i];
     163                 :      19132 :     gel(z, lx) = p1; return z;
     164                 :            :   }
     165                 :            : 
     166   [ +  +  +  - ]:    2870234 :   switch(tx)
     167                 :            :   {
     168                 :            :     case t_VEC:
     169      [ +  -  - ]:        280 :       switch(ty)
     170                 :            :       {
     171                 :            :         case t_COL:
     172 [ +  - ][ -  + ]:        280 :           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                 :            :         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                 :            :     case t_COL:
     183      [ -  +  - ]:       5159 :       switch(ty)
     184                 :            :       {
     185                 :            :         case t_VEC:
     186 [ #  # ][ #  # ]:          0 :           if (lx<=2) return (lx==1)? y: shallowconcat(gel(x,1), y);
     187         [ #  # ]:          0 :           if (ly>=3) break;
     188         [ #  # ]:          0 :           return (ly==1)? x: shallowconcat(x, gel(y,1));
     189                 :            :         case t_MAT:
     190         [ -  + ]:       5159 :           if (lx != lgcols(y)) break;
     191                 :       5159 :           z=cgetg(ly+1,t_MAT);  gel(z,1) = x;
     192         [ +  + ]:      90247 :           for (i=2; i<=ly; i++) gel(z,i) = gel(y,i-1);
     193                 :       5159 :           return z;
     194                 :            :       }
     195                 :          0 :       break;
     196                 :            : 
     197                 :            :     case t_MAT:
     198      [ -  +  - ]:    2864795 :       switch(ty)
     199                 :            :       {
     200                 :            :         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                 :            :         case t_COL:
     205         [ -  + ]:    2864795 :           if (ly != lgcols(x)) break;
     206                 :    2864795 :           z=cgetg(lx+1,t_MAT); gel(z,lx) = y;
     207         [ +  + ]:   11986775 :           for (i=1; i<lx; i++) z[i]=x[i];
     208                 :    2864795 :           return z;
     209                 :            :       }
     210                 :          0 :       break;
     211                 :            :   }
     212                 :          0 :   err_cat(x,y);
     213                 :    3775296 :   return NULL; /* not reached */
     214                 :            : }
     215                 :            : 
     216                 :            : /* see catmany() */
     217                 :            : static GEN
     218                 :       9737 : catmanyMAT(GEN y1, GEN y2)
     219                 :            : {
     220                 :       9737 :   long i, h = 0, L = 1;
     221                 :            :   GEN z, y;
     222         [ +  + ]:      37506 :   for (y = y2; y >= y1; y--)
     223                 :            :   {
     224                 :      27769 :     GEN c = gel(y,0);
     225                 :      27769 :     long nc = lg(c)-1;
     226         [ +  + ]:      27769 :     if (nc == 0) continue;
     227         [ +  + ]:      27741 :     if (h != lgcols(c))
     228                 :            :     {
     229         [ -  + ]:       9730 :       if (h) err_cat(gel(y2,0), c);
     230                 :       9730 :       h = lgcols(c);
     231                 :            :     }
     232                 :      27741 :     L += nc;
     233                 :      27741 :     z = new_chunk(nc) - 1;
     234         [ +  + ]:     100233 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     235                 :            :   }
     236                 :       9737 :   z = new_chunk(1);
     237                 :       9737 :   *z = evaltyp(t_MAT) | evallg(L);
     238                 :       9737 :   return z;
     239                 :            : }
     240                 :            : static GEN
     241                 :         70 : catmanySTR(GEN y1, GEN y2)
     242                 :            : {
     243                 :         70 :   long L = 1; /* final \0 */
     244                 :            :   GEN z, y;
     245                 :            :   char *s;
     246         [ +  + ]:       1988 :   for (y = y1; y <= y2; y++)
     247                 :            :   {
     248                 :       1918 :     char *c = GSTR( gel(y,0) );
     249                 :       1918 :     L += strlen(c);
     250                 :            :   }
     251                 :         70 :   z = cgetg(nchar2nlong(L)+1, t_STR);
     252                 :         70 :   s = GSTR(z);
     253         [ +  + ]:       1988 :   for (y = y1; y <= y2; y++)
     254                 :            :   {
     255                 :       1918 :     char *c = GSTR( gel(y,0) );
     256                 :       1918 :     long nc = strlen(c);
     257         [ +  - ]:       1918 :     if (nc) { (void)strncpy(s, c, nc); s += nc; }
     258                 :            :   }
     259                 :         70 :   *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                 :      26803 : catmany(GEN y1, GEN y2, long t)
     266                 :            : {
     267                 :            :   long i, L;
     268                 :            :   GEN z, y;
     269         [ -  + ]:      26803 :   if (y1 == y2) return gel(y1,0);
     270         [ +  + ]:      26803 :   if (t == t_MAT) return catmanyMAT(y1, y2);
     271         [ +  + ]:      17066 :   if (t == t_STR) return catmanySTR(y1, y2);
     272                 :      16996 :   L = 1;
     273         [ +  + ]:      85232 :   for (y = y2; y >= y1; y--)
     274                 :            :   {
     275                 :      68236 :     GEN c = gel(y,0);
     276                 :      68236 :     long nc = lg(c)-1;
     277         [ +  + ]:      68236 :     if (nc == 0) continue;
     278                 :      49035 :     L += nc;
     279                 :      49035 :     z = new_chunk(nc) - 1;
     280         [ +  + ]:     154854 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     281                 :            :   }
     282                 :      16996 :   z = new_chunk(1);
     283                 :      16996 :   *z = evaltyp(t) | evallg(L);
     284                 :      26803 :   return z;
     285                 :            : }
     286                 :            : 
     287                 :            : GEN
     288                 :      29512 : shallowconcat1(GEN x)
     289                 :            : {
     290                 :      29512 :   pari_sp av = avma;
     291                 :            :   long lx, t, i;
     292                 :            :   GEN z;
     293      [ +  +  - ]:      29512 :   switch(typ(x))
     294                 :            :   {
     295                 :            :     case t_VEC:
     296                 :      29498 :       lx = lg(x);
     297         [ +  + ]:      29498 :       if (lx==1) pari_err_DOMAIN("concat","vector","=",x,x);
     298                 :      29491 :       break;
     299                 :            :     case t_LIST:
     300         [ -  + ]:         14 :       if (list_typ(x)!=t_LIST_RAW) pari_err_TYPE("concat",x);
     301         [ +  + ]:         14 :       if (!list_data(x)) pari_err_DOMAIN("concat","vector","=",x,x);
     302                 :          7 :       x = list_data(x); lx = lg(x);
     303                 :          7 :       break;
     304                 :            :     default:
     305                 :          0 :       pari_err_TYPE("concat",x);
     306                 :          0 :       return NULL; /* not reached */
     307                 :            :   }
     308         [ +  + ]:      29498 :   if (lx==2) return gel(x,1);
     309                 :      26817 :   z = gel(x,1); t = typ(z); i = 2;
     310 [ +  + ][ +  + ]:      26817 :   if (is_matvec_t(t) || t == t_VECSMALL || t == t_STR)
                 [ +  + ]
     311                 :            :   { /* detect a "homogeneous" object: catmany is faster */
     312         [ +  + ]:      97923 :     for (; i<lx; i++)
     313         [ -  + ]:      71120 :       if (typ(gel(x,i)) != t) break;
     314                 :      26803 :     z = catmany(x + 1, x + i-1, t);
     315                 :            :   }
     316         [ +  + ]:      26845 :   for (; i<lx; i++) {
     317                 :         28 :     z = shallowconcat(z, gel(x,i));
     318         [ -  + ]:         28 :     if (gc_needed(av,3))
     319                 :            :     {
     320         [ #  # ]:          0 :       if (DEBUGMEM>1) pari_warn(warnmem,"concat: i = %ld", i);
     321                 :          0 :       z = gerepilecopy(av, z);
     322                 :            :     }
     323                 :            :   }
     324                 :      29498 :   return z;
     325                 :            : }
     326                 :            : 
     327                 :            : GEN
     328                 :         21 : concat1(GEN x)
     329                 :            : {
     330                 :         21 :   pari_sp av = avma;
     331                 :         21 :   return gerepilecopy(av, shallowconcat1(x));
     332                 :            : }
     333                 :            : 
     334                 :            : /* fill M[xoff+i, yoff+j] with the contents of c ( c * Id_n if scalar ) */
     335                 :            : static void
     336                 :      66689 : matfill(GEN M, GEN c, long xoff, long yoff, long n)
     337                 :            : {
     338                 :            :   long i, j, h, l;
     339         [ +  + ]:     132097 :   l = lg(c); if (l == 1) return;
     340   [ +  +  +  + ]:      65408 :   switch(typ(c))
     341                 :            :   {
     342                 :            :     case t_VEC:
     343         [ +  + ]:        112 :       for (i = 1; i < l; i++)
     344                 :         77 :         gcoeff(M,xoff+1,yoff+i) = gel(c,i);
     345                 :         35 :       break;
     346                 :            :     case t_COL:
     347         [ +  + ]:        112 :       for (i = 1; i < l; i++)
     348                 :         77 :         gcoeff(M,xoff+i,yoff+1) = gel(c,i);
     349                 :         35 :       break;
     350                 :            :     case t_MAT:
     351                 :      55524 :       h = lgcols(c);
     352         [ +  + ]:    1158885 :       for (j = 1; j < l; j++)
     353         [ +  + ]:   29974329 :         for (i = 1; i < h; i++) gcoeff(M,xoff+i,yoff+j) = gcoeff(c,i,j);
     354                 :      55524 :       break;
     355                 :            :     default:
     356         [ +  + ]:      24955 :       for (i = 1; i <= n; i++)
     357                 :      15141 :         gcoeff(M, xoff+i, yoff+i) = c;
     358                 :       9814 :       break;
     359                 :            :   }
     360                 :            : }
     361                 :            : 
     362                 :            : static GEN
     363                 :      75194 : _matsize(GEN x)
     364                 :            : {
     365                 :      75194 :   long t = typ(x), L = lg(x) - 1;
     366   [ +  +  +  + ]:      75194 :   switch(t)
     367                 :            :   { /* matsize */
     368                 :         56 :     case t_VEC: return mkvecsmall2(1, L);
     369                 :         56 :     case t_COL: return mkvecsmall2(L, 1);
     370         [ +  + ]:      64946 :     case t_MAT: return mkvecsmall2(L? nbrows(x): 0, L);
     371                 :            :     default:
     372         [ -  + ]:      10136 :       if (is_noncalc_t(t)) pari_err_TYPE("_matsize", x);
     373                 :      75194 :       return mkvecsmall2(1, 1);
     374                 :            :   }
     375                 :            : }
     376                 :            : 
     377                 :            : GEN
     378                 :      20167 : shallowmatconcat(GEN v)
     379                 :            : {
     380                 :      20167 :   long i, j, h, l = lg(v), L = 0, H = 0;
     381                 :            :   GEN M, maxh, maxl;
     382         [ +  + ]:      20167 :   if (l == 1) return cgetg(1,t_MAT);
     383   [ +  +  +  - ]:      18865 :   switch(typ(v))
     384                 :            :   {
     385                 :            :     case t_VEC:
     386         [ +  + ]:      12698 :       for (i = 1; i < l; i++)
     387                 :            :       {
     388                 :       8414 :         GEN c = gel(v,i);
     389                 :       8414 :         GEN s = _matsize(c);
     390                 :       8414 :         H = maxss(H, s[1]);
     391                 :       8414 :         L += s[2];
     392                 :            :       }
     393                 :       4284 :       M = zeromatcopy(H, L);
     394                 :       4284 :       L = 0;
     395         [ +  + ]:      12698 :       for (i = 1; i < l; i++)
     396                 :            :       {
     397                 :       8414 :         GEN c = gel(v,i);
     398                 :       8414 :         GEN s = _matsize(c);
     399                 :       8414 :         matfill(M, c, 0, L, 1);
     400                 :       8414 :         L += s[2];
     401                 :            :       }
     402                 :       4284 :       return M;
     403                 :            : 
     404                 :            :     case t_COL:
     405         [ +  + ]:        119 :       for (i = 1; i < l; i++)
     406                 :            :       {
     407                 :         91 :         GEN c = gel(v,i);
     408                 :         91 :         GEN s = _matsize(c);
     409                 :         91 :         H += s[1];
     410                 :         91 :         L = maxss(L, s[2]);
     411                 :            :       }
     412                 :         28 :       M = zeromatcopy(H, L);
     413                 :         28 :       H = 0;
     414         [ +  + ]:        119 :       for (i = 1; i < l; i++)
     415                 :            :       {
     416                 :         91 :         GEN c = gel(v,i);
     417                 :         91 :         GEN s = _matsize(c);
     418                 :         91 :         matfill(M, c, H, 0, 1);
     419                 :         91 :         H += s[1];
     420                 :            :       }
     421                 :         28 :       return M;
     422                 :            :     case t_MAT:
     423                 :      14553 :       h = lgcols(v);
     424                 :      14553 :       maxh = zero_zv(h-1);
     425                 :      14553 :       maxl = zero_zv(l-1);
     426         [ +  + ]:      43659 :       for (j = 1; j < l; j++)
     427         [ +  + ]:      87290 :         for (i = 1; i < h; i++)
     428                 :            :         {
     429                 :      58184 :           GEN c = gcoeff(v,i,j);
     430                 :      58184 :           GEN s = _matsize(c);
     431         [ +  + ]:      58184 :           if (s[1] > maxh[i]) maxh[i] = s[1];
     432         [ +  + ]:      58184 :           if (s[2] > maxl[j]) maxl[j] = s[2];
     433                 :            :         }
     434         [ +  + ]:      43645 :       for (i = 1, H = 0; i < h; i++) H += maxh[i];
     435         [ +  + ]:      43659 :       for (j = 1, L = 0; j < l; j++) L += maxl[j];
     436                 :      14553 :       M = zeromatcopy(H, L);
     437         [ +  + ]:      43659 :       for (j = 1, L = 0; j < l; j++)
     438                 :            :       {
     439         [ +  + ]:      87290 :         for (i = 1, H = 0; i < h; i++)
     440                 :            :         {
     441                 :      58184 :           GEN c = gcoeff(v,i,j);
     442                 :      58184 :           matfill(M, c, H, L, minss(maxh[i], maxl[j]));
     443                 :      58184 :           H += maxh[i];
     444                 :            :         }
     445                 :      29106 :         L += maxl[j];
     446                 :            :       }
     447                 :      14553 :       return M;
     448                 :            :     default:
     449                 :          0 :       pari_err_TYPE("shallowmatconcat", v);
     450                 :      20167 :       return NULL;
     451                 :            :   }
     452                 :            : }
     453                 :            : GEN
     454                 :       9884 : matconcat(GEN v)
     455                 :            : {
     456                 :       9884 :   pari_sp av = avma;
     457                 :       9884 :   return gerepilecopy(av, shallowmatconcat(v));
     458                 :            : }
     459                 :            : 
     460                 :            : GEN
     461                 :   16302043 : concat(GEN x, GEN y)
     462                 :            : {
     463                 :            :   long tx, lx,ty,ly,i;
     464                 :            :   GEN z,p1;
     465                 :            : 
     466         [ +  + ]:   16302043 :   if (!y) return concat1(x);
     467                 :   16302022 :   tx = typ(x);
     468                 :   16302022 :   ty = typ(y);
     469 [ +  + ][ -  + ]:   16302022 :   if (tx==t_STR  || ty==t_STR)
     470                 :            :   {
     471                 :          7 :     pari_sp av = avma;
     472                 :          7 :     return gerepileuptoleaf(av, strconcat(x,y));
     473                 :            :   }
     474 [ +  + ][ +  + ]:   16302015 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     475                 :   16301994 :   lx=lg(x); ly=lg(y);
     476                 :            : 
     477 [ +  + ][ +  + ]:   16301994 :   if (tx==t_MAT && lx==1)
     478                 :            :   {
     479         [ +  + ]:         28 :     if (ty!=t_VEC) return gtomat(y);
     480         [ +  + ]:         21 :     if (ly==1) return cgetg(1, t_MAT);
     481                 :          7 :     err_cat(x,y);
     482                 :            :   }
     483 [ +  + ][ +  + ]:   16301966 :   if (ty==t_MAT && ly==1)
     484                 :            :   {
     485         [ +  + ]:         21 :     if (tx!=t_VEC) return gtomat(x);
     486         [ +  + ]:         14 :     if (lx==1) return cgetg(1, t_MAT);
     487                 :          7 :     err_cat(x,y);
     488                 :            :   }
     489                 :            : 
     490         [ +  + ]:   16301945 :   if (tx == ty)
     491                 :            :   {
     492 [ +  + ][ -  + ]:      39624 :     if (tx == t_MAT && lgcols(x) != lgcols(y)) err_cat(x,y);
     493         [ +  + ]:      39624 :     if (!is_matvec_t(tx))
     494                 :            :     {
     495         [ +  + ]:        231 :       if (tx != t_VECSMALL) return mkvec2copy(x, y);
     496                 :        224 :       z = cgetg(lx+ly-1,t_VECSMALL);
     497         [ +  + ]:        434 :       for (i=1; i<lx; i++) z[i]     = x[i];
     498         [ +  + ]:        462 :       for (i=1; i<ly; i++) z[lx+i-1]= y[i];
     499                 :        224 :       return z;
     500                 :            :     }
     501                 :      39393 :     z=cgetg(lx+ly-1,tx);
     502         [ +  + ]:     197019 :     for (i=1; i<lx; i++) gel(z,i)     = gcopy(gel(x,i));
     503         [ +  + ]:     224190 :     for (i=1; i<ly; i++) gel(z,lx+i-1)= gcopy(gel(y,i));
     504                 :      39393 :     return z;
     505                 :            :   }
     506                 :            : 
     507         [ +  + ]:   16262321 :   if (! is_matvec_t(tx))
     508                 :            :   {
     509         [ -  + ]:         70 :     if (! is_matvec_t(ty)) return mkvec2copy(x, y);
     510                 :         70 :     z=cgetg(ly+1,ty);
     511         [ +  + ]:         70 :     if (ty != t_MAT) p1 = gcopy(x);
     512                 :            :     else
     513                 :            :     {
     514         [ +  + ]:         14 :       if (lgcols(y)!=2) err_cat(x,y);
     515                 :          7 :       p1 = mkcolcopy(x);
     516                 :            :     }
     517         [ +  + ]:        231 :     for (i=2; i<=ly; i++) gel(z,i) = gcopy(gel(y,i-1));
     518                 :         63 :     gel(z,1) = p1; return z;
     519                 :            :   }
     520         [ +  + ]:   16262251 :   if (! is_matvec_t(ty))
     521                 :            :   {
     522                 :   16262160 :     z=cgetg(lx+1,tx);
     523         [ +  + ]:   16262160 :     if (tx != t_MAT) p1 = gcopy(y);
     524                 :            :     else
     525                 :            :     {
     526         [ +  + ]:         14 :       if (lgcols(x)!=2) err_cat(x,y);
     527                 :          7 :       p1 = mkcolcopy(y);
     528                 :            :     }
     529         [ +  + ]: 2273222924 :     for (i=1; i<lx; i++) gel(z,i) = gcopy(gel(x,i));
     530                 :   16262153 :     gel(z,lx) = p1; return z;
     531                 :            :   }
     532                 :            : 
     533   [ +  +  +  - ]:         91 :   switch(tx)
     534                 :            :   {
     535                 :            :     case t_VEC:
     536      [ +  +  - ]:         35 :       switch(ty)
     537                 :            :       {
     538                 :            :         case t_COL:
     539 [ -  + ][ #  # ]:         28 :           if (lx<=2) return (lx==1)? gcopy(y): concat(gel(x,1),y);
     540         [ +  + ]:         28 :           if (ly>=3) break;
     541         [ +  + ]:         14 :           return (ly==1)? gcopy(x): concat(x,gel(y,1));
     542                 :            :         case t_MAT:
     543         [ -  + ]:          7 :           z=cgetg(ly,t_MAT); if (lx != ly) break;
     544         [ +  + ]:         21 :           for (i=1; i<ly; i++) gel(z,i) = concat(gel(x,i),gel(y,i));
     545                 :          7 :           return z;
     546                 :            :       }
     547                 :         14 :       break;
     548                 :            : 
     549                 :            :     case t_COL:
     550      [ +  +  - ]:         42 :       switch(ty)
     551                 :            :       {
     552                 :            :         case t_VEC:
     553 [ +  + ][ +  + ]:         35 :           if (lx<=2) return (lx==1)? gcopy(y): concat(gel(x,1),y);
     554         [ +  + ]:         21 :           if (ly>=3) break;
     555         [ +  + ]:         14 :           return (ly==1)? gcopy(x): concat(x,gel(y,1));
     556                 :            :         case t_MAT:
     557         [ -  + ]:          7 :           if (lx != lgcols(y)) break;
     558                 :          7 :           z=cgetg(ly+1,t_MAT); gel(z,1) = gcopy(x);
     559         [ +  + ]:         14 :           for (i=2; i<=ly; i++) gel(z,i) = gcopy(gel(y,i-1));
     560                 :          7 :           return z;
     561                 :            :       }
     562                 :          7 :       break;
     563                 :            : 
     564                 :            :     case t_MAT:
     565      [ +  +  - ]:         14 :       switch(ty)
     566                 :            :       {
     567                 :            :         case t_VEC:
     568         [ -  + ]:          7 :           z=cgetg(lx,t_MAT); if (ly != lx) break;
     569         [ +  + ]:         21 :           for (i=1; i<lx; i++) gel(z,i) = concat(gel(x,i),gel(y,i));
     570                 :          7 :           return z;
     571                 :            :         case t_COL:
     572         [ -  + ]:          7 :           if (ly != lgcols(x)) break;
     573                 :          7 :           z=cgetg(lx+1,t_MAT); gel(z,lx) = gcopy(y);
     574         [ +  + ]:         14 :           for (i=1; i<lx; i++) gel(z,i) = gcopy(gel(x,i));
     575                 :          7 :           return z;
     576                 :            :       }
     577                 :          0 :       break;
     578                 :            :   }
     579                 :         21 :   err_cat(x,y);
     580                 :   16301980 :   return NULL; /* not reached */
     581                 :            : }

Generated by: LCOV version 1.9