* Bug 8297 fixed: cat() slowness was crippling. Rewritten 78/19278/3
Samuel GOUGEON [Tue, 6 Jun 2017 00:05:22 +0000 (02:05 +0200)]
  * http://bugzilla.scilab.org/8297
  * fastens cat() by x300 for stacking (250,250) matrices
              by > x60000 for stacking (500,500) matrices
                              (0.25s instead of 4h), etc.
  * All non reg tests for other former cat() bugs pass:
    test_run elementary_functions bug_4439
    test_run elementary_functions bug_4460
    test_run elementary_functions bug_4751
    test_run elementary_functions bug_13409
  * Unit test extended.

Change-Id: I7f8d547e3f5549c060e0c97f4e4a08bd32a1bc47

scilab/CHANGES.md
scilab/modules/elementary_functions/macros/cat.sci
scilab/modules/elementary_functions/tests/nonreg_tests/bug_8297.tst [new file with mode: 0644]
scilab/modules/elementary_functions/tests/nonreg_tests/bug_8297_cat_old.sci [new file with mode: 0644]
scilab/modules/elementary_functions/tests/unit_tests/cat.dia.ref [deleted file]
scilab/modules/elementary_functions/tests/unit_tests/cat.tst

index a3b59b8..25323c0 100644 (file)
@@ -212,6 +212,7 @@ bounds selected out of the axes areas is now restored, after the Scilab 5.4 regr
   in a dynamical list set from Scinotes favorite and most recent directories.
 * `size` can now be overloadable for tlist lists, as it already could for mlist lists.
 * `gcd` now accepts `int64` and `uint64` integers. The input can now be any array instead of a row.
+* `cat` has been rewritten. It is now fast and can process heavy arrays at high dimensions.
 
 
 Help pages:
@@ -351,6 +352,7 @@ the [development mailing list](dev@lists.scilab.org) for a particular toolbox.
 ### Bugs fixed in 6.0.1:
 * [#4276](http://bugzilla.scilab.org/show_bug.cgi?id=4276): `strsubst` replaced the first occurence in regex mode.
 * [#5278](http://bugzilla.scilab.org/show_bug.cgi?id=5278): obsolete `xset()` was still used in scripts, macros, tests and help pages.
+* [#8297](http://bugzilla.scilab.org/show_bug.cgi?id=8297): `cat` slowness was exponential, crippling, and made it useless.
 * [#11756](http://bugzilla.scilab.org/show_bug.cgi?id=11756): In the categories of the ATOMS GUI, actually available modules might be not listed.
 * [#12195](http://bugzilla.scilab.org/show_bug.cgi?id=12195): `generateBlockImage` sometimes changed the current graphic driver.
 * [#12771](http://bugzilla.scilab.org/show_bug.cgi?id=12771): xcosPalGenerateAllIcons help example was broken.
index 6c95814..8e2331e 100644 (file)
@@ -1,8 +1,6 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA - Farid BELAHCENE
-// Copyright (C) DIGITEO - 2011 - Allan CORNET
 //
-// Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2017 - Samuel GOUGEON : cat() rewritten: http://bugzilla.scilab.org/8297
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-function  y = cat(dims, varargin)
-    //
-    // CAT function concatenates the inputs arguments (included in varargin) according to dims
-    // if dims=1 then concatenation is done according to the rows of the input arguments, if dims=2 then concatenation is done according to the columns of the input arguments,...
-    // Output
-    // -y : a (multi) array, the result of the concatenation
-    // Input
-    // -dims : a scalar, the dimension chosen for the concatenation
-    // -varargin : scalars, matrices, hypermatrices to concatenate
-    // F.B
-
+function  y = cat(dim, varargin)
+    // dim: scalar = dimension # along which input arrays are stacked
+    // varargin: input arrays: matrices, hypermatrices, cells arrays, struct
+    //           arrays, custom mlists,.. For custom arrays, [,] and [;] may be
+    //           not defined. Must be all of the same sizes, except along dim.
+    // y : concatenated array
 
     rhs = argn(2);
-    if rhs < 1 then
-        error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"),"cat", 1));
+    if rhs < 2 then
+        msg = gettext("%s: Wrong number of input argument(s): %d expected.\n")
+        error(msprintf(msg,"cat", 1));
     end
 
-    // dims must be a positive real
-    if type(dims)==1 & dims>=0 & size(dims,"*")==1
-        dims = max(1,round(dims));
+    // dim must be a positive real
+    if type(dim)==1 & dim>=0 & size(dim,"*")==1
+        dim = max(1,round(dim));
     else
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: A positive real expected.\n"),"cat",1));
-    end
-
-    // verify if dims value is superior to the dimension of the input arguments
-    dimssupvar = %t;
-    for i = 1:size(varargin)
-        if ndims(varargin(i))>=dims then
-            dimssupvar = %f;
-        end
+        msg = gettext("%s: Wrong type for input argument #%d: A positive real expected.\n");
+        error(msprintf(msg, "cat", 1));
     end
 
-    // delete all empty input arguments
-    for i = size(varargin):-1:2
+    // CHECK INPUT ARRAYS
+    //  - empty arrays are ignored
+    for i = size(varargin):-1:1
         if isempty(varargin(i)) then
             varargin(i) = null();
         end
     end
-
-    // if just one input argument to concatenate then return this argument
+    // - cat(m,[]), cat(m)  => []
+    if isempty(varargin) then
+        y = [];
+        return
+    end
+    // - if just one input argument to concatenate, then return this argument
     if size(varargin) == 1 then
         y = varargin(1);
         return
-    elseif isempty(varargin(1)) then
-        varargin(1) = null();
     end
-
-    // create 2 lists sizevar and sizevarless which contains (respectively) the size of all input arguments (sizevar(i) = size(varargin(i))), and the size of all input arguments excluding the size of the dimension number dims
-    onedims = ones(1,dims);
-    sizevarless = list();
-    sizevar = list();
-
-    for i=1:size(varargin)
-        var = onedims;
-        var(1:ndims(varargin(i))) = size(varargin(i));
-        sizevar(i) = var;
-        var(dims) = [];
-        sizevarless(i) = var;
+    //  - they must all have the same sizes (except along dim)
+    v = varargin(1);
+    S = size(v);
+    if length(S) < dim then
+        S = [S ones(1, dim-length(S))];
     end
-
-    for i=2:size(varargin)
-        if or(sizevarless(i-1)<> sizevarless(i))
-            error(msprintf(gettext("%s: Wrong size for input arguments: Same size expected.\n"),"cat"));
+    S(dim) = -1;
+    for i = 2:size(varargin)
+        s = size(varargin(i));
+        s(dim) = -1;
+        s(find(s==0)) = 1;
+        if ~and(s==S)
+            msg = gettext("%s: Wrong size for input arguments: Same size expected.\n");
+            error(msprintf(msg, "cat"));
         end
     end
-
-    // case : input arguments are cells arrrays
-    if typeof(varargin(1))=="ce"
-        ytemp = cell();
-    else   // case : input arguments are arrays of doubles, strings, characters,...
-        ytemp = [];
-    end
-
-    vartype = typeof(varargin(1));
-
-    for j=2:size(varargin)
-        if  typeof(varargin(j)) ==vartype
-            vartype = typeof(varargin(j));
-        else
-            error(msprintf(gettext("%s: Wrong type for input arguments: Same types expected.\n"),"cat"));
+    // They must be all of the same type: cell, struct, or other
+    T = typeof(v)
+    for i = 2:size(varargin)
+        v = varargin(i)
+        if typeof(v)~=T
+            msg = gettext("%s: Wrong type for input arguments: Same types expected.\n");
+            error(msprintf(msg, "cat"));
         end
     end
 
-    // permorder is the order of the permutation
-    permuteorder = 1:size(sizevarless(1),"*")+1;
-    if ~dimssupvar then
-        permuteorder(dims) = [];
-        permuteorder = [dims permuteorder];
-    end
-
-    // permutevar is a list which contains the permuted input arguments arrays
-    permutevar = list();
-    for j=1:size(varargin)
-        permutevar(j) = permute(varargin(j),permuteorder);
-    end
-
-    for i=1:prod(sizevarless(1))
-        for j=1:size(varargin)
-            permutevarj = permutevar(j);
-            lj = size(varargin(j),"*")/prod(sizevarless(j));
-            if typeof(permutevarj)=="ce" then
-                for k=1+lj*(i-1):lj*i
-                    ytemp{size(ytemp,"*")+1} = permutevarj{k};
-                end
-            else
-                ytemp= [ytemp (permutevarj(1+lj*(i-1):lj*i)).'];
-            end
+    // PROCESSING
+    // ----------
+    y = varargin(1);
+    [vcat, hcat] = (%t, %t);
+    if type(y)>10
+        t = typeof(y, "overload");
+        if ~or(t==["ce" "st"])
+            [vcat, hcat] = (isdef("%"+t+"_f_"+t,"n"), isdef("%"+t+"_c_"+t,"n"));
         end
     end
-    ytemp = matrix(ytemp,1,-1);
-
-    sizevar = sizevar(1);
-    prodxdims = prod(sizevar(1:dims));
-    ny = prod(sizevar)/prodxdims;
-    ydimsize = size(ytemp,2)/(prod(sizevarless(1)));
-    prodxdimless = prod(sizevar(1:dims-1));
-    ind = 1;
-    for j=1:ydimsize-1
-        ind = [ind 1+prodxdimless*j];
-    end
-    for i=0:ny-1
-        index = [];
-        for j=0:prodxdimless-1
-            index = [index ind+j+i*(prodxdimless)*ydimsize];
+    if dim==1 & vcat then
+        for i = 2:length(varargin)
+            y = [y ; varargin(i)];
         end
-        if typeof(ytemp)=="ce"
-            ceindex = (1:ydimsize*prodxdimless)+ydimsize*prodxdimless*(i);
-            for k=1:size(index,"*")
-                y{index(k)} = ytemp{ceindex(k)};
-            end
-        else
-            y(index) = ytemp((1:ydimsize*prodxdimless)+ydimsize*prodxdimless*(i));
+    elseif dim==2 & hcat
+        for i = 2:length(varargin)
+            y = [y, varargin(i)];
         end
-    end
-
-    // redimension of y
-    ysize = sizevarless(1);
-    if dimssupvar then
-        ysize($+1) = size(varargin);
     else
-        if dims == size(sizevarless(1))+1
-            ysize(dims) = size(ytemp,2)/prod(sizevarless(1));
-        else
-            ysize = [ysize(1:dims-1) size(ytemp,2)/prod(sizevarless(1)) ysize(dims:$)];
+        nd = max(ndims(y),dim);
+        st = emptystr(1,nd) + ":";
+        st(dim) = "%d:%d";
+        st = strcat(st,",");
+        Cmd = "y("+st+") = varargin(i);"
+        sy = size(y,dim);
+        for i = 2:length(varargin)
+            s = size(varargin(i), dim);
+            cmd = msprintf(Cmd,sy+1,sy+s);
+            execstr(cmd);
+            sy = sy + s;
         end
     end
-    y = matrix(y,ysize);
-
 endfunction
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8297.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8297.tst
new file mode 100644 (file)
index 0000000..2a82b23
--- /dev/null
@@ -0,0 +1,32 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2017 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 8297 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/8297
+//
+// <-- Short Description -->
+// After M = rand(m,m);
+// cat(3, M, M) spent time was exponential vs m (~12 days for m = 500)
+
+cat(1,1,1);         // To load the function
+m = rand(250,250);
+tic();
+r = cat(3, m, m);
+tnew = toc();
+assert_checkequal(r(:,:,2), m);
+
+path = "SCI/modules/elementary_functions/tests/nonreg_tests/bug_8297_cat_old.sci";
+exec(path,-1);
+tic();
+r = cat_old(3, m, m);
+told = toc();
+assert_checktrue(told/tnew > 200);
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8297_cat_old.sci b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_8297_cat_old.sci
new file mode 100644 (file)
index 0000000..ff917ab
--- /dev/null
@@ -0,0 +1,161 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) INRIA - Farid BELAHCENE
+// Copyright (C) DIGITEO - 2011 - Allan CORNET
+//
+// Copyright (C) 2012 - 2016 - Scilab Enterprises
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// pursuant to article 5.3.4 of the CeCILL v.2.1.
+// This file was originally licensed under the terms of the CeCILL v2.1,
+// and continues to be available under such terms.
+// For more information, see the COPYING file which you should have received
+// along with this program.
+
+function  y = cat_old(dims, varargin)
+    //
+    // CAT function concatenates the inputs arguments (included in varargin) according to dims
+    // if dims=1 then concatenation is done according to the rows of the input arguments, if dims=2 then concatenation is done according to the columns of the input arguments,...
+    // Output
+    // -y : a (multi) array, the result of the concatenation
+    // Input
+    // -dims : a scalar, the dimension chosen for the concatenation
+    // -varargin : scalars, matrices, hypermatrices to concatenate
+    // F.B
+
+    rhs = argn(2);
+    if rhs < 1 then
+        error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"),"cat", 1));
+    end
+
+    // dims must be a positive real
+    if type(dims)==1 & dims>=0 & size(dims,"*")==1
+        dims = max(1,round(dims));
+    else
+        error(msprintf(gettext("%s: Wrong type for input argument #%d: A positive real expected.\n"),"cat",1));
+    end
+
+    // verify if dims value is superior to the dimension of the input arguments
+    dimssupvar = %t;
+    for i = 1:size(varargin)
+        if ndims(varargin(i))>=dims then
+            dimssupvar = %f;
+        end
+    end
+
+    // delete all empty input arguments
+    for i = size(varargin):-1:2
+        if isempty(varargin(i)) then
+            varargin(i) = null();
+        end
+    end
+
+    // if just one input argument to concatenate then return this argument
+    if size(varargin) == 1 then
+        y = varargin(1);
+        return
+    elseif isempty(varargin(1)) then
+        varargin(1) = null();
+    end
+
+    // create 2 lists sizevar and sizevarless which contains (respectively) the size of all input arguments (sizevar(i) = size(varargin(i))), and the size of all input arguments excluding the size of the dimension number dims
+    onedims = ones(1,dims);
+    sizevarless = list();
+    sizevar = list();
+
+    for i=1:size(varargin)
+        var = onedims;
+        var(1:ndims(varargin(i))) = size(varargin(i));
+        sizevar(i) = var;
+        var(dims) = [];
+        sizevarless(i) = var;
+    end
+
+    for i=2:size(varargin)
+        if or(sizevarless(i-1)<> sizevarless(i))
+            error(msprintf(gettext("%s: Wrong size for input arguments: Same size expected.\n"),"cat"));
+        end
+    end
+
+    // case : input arguments are cells arrrays
+    if typeof(varargin(1))=="ce"
+        ytemp = cell();
+    else   // case : input arguments are arrays of doubles, strings, characters,...
+        ytemp = [];
+    end
+
+    vartype = typeof(varargin(1));
+
+    for j=2:size(varargin)
+        if  typeof(varargin(j)) ==vartype
+            vartype = typeof(varargin(j));
+        else
+            error(msprintf(gettext("%s: Wrong type for input arguments: Same types expected.\n"),"cat"));
+        end
+    end
+
+    // permorder is the order of the permutation
+    permuteorder = 1:size(sizevarless(1),"*")+1;
+    if ~dimssupvar then
+        permuteorder(dims) = [];
+        permuteorder = [dims permuteorder];
+    end
+
+    // permutevar is a list which contains the permuted input arguments arrays
+    permutevar = list();
+    for j=1:size(varargin)
+        permutevar(j) = permute(varargin(j),permuteorder);
+    end
+
+    for i=1:prod(sizevarless(1))
+        for j=1:size(varargin)
+            permutevarj = permutevar(j);
+            lj = size(varargin(j),"*")/prod(sizevarless(j));
+            if typeof(permutevarj)=="ce" then
+                for k=1+lj*(i-1):lj*i
+                    ytemp{size(ytemp,"*")+1} = permutevarj{k};
+                end
+            else
+                ytemp= [ytemp (permutevarj(1+lj*(i-1):lj*i)).'];
+            end
+        end
+    end
+    ytemp = matrix(ytemp,1,-1);
+
+    sizevar = sizevar(1);
+    prodxdims = prod(sizevar(1:dims));
+    ny = prod(sizevar)/prodxdims;
+    ydimsize = size(ytemp,2)/(prod(sizevarless(1)));
+    prodxdimless = prod(sizevar(1:dims-1));
+    ind = 1;
+    for j=1:ydimsize-1
+        ind = [ind 1+prodxdimless*j];
+    end
+    for i=0:ny-1
+        index = [];
+        for j=0:prodxdimless-1
+            index = [index ind+j+i*(prodxdimless)*ydimsize];
+        end
+        if typeof(ytemp)=="ce"
+            ceindex = (1:ydimsize*prodxdimless)+ydimsize*prodxdimless*(i);
+            for k=1:size(index,"*")
+                y{index(k)} = ytemp{ceindex(k)};
+            end
+        else
+            y(index) = ytemp((1:ydimsize*prodxdimless)+ydimsize*prodxdimless*(i));
+        end
+    end
+
+    // redimension of y
+    ysize = sizevarless(1);
+    if dimssupvar then
+        ysize($+1) = size(varargin);
+    else
+        if dims == size(sizevarless(1))+1
+            ysize(dims) = size(ytemp,2)/prod(sizevarless(1));
+        else
+            ysize = [ysize(1:dims-1) size(ytemp,2)/prod(sizevarless(1)) ysize(dims:$)];
+        end
+    end
+    y = matrix(y,ysize);
+
+endfunction
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/cat.dia.ref b/scilab/modules/elementary_functions/tests/unit_tests/cat.dia.ref
deleted file mode 100644 (file)
index 5254d3e..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2016 - Scilab Enterprises - Pierre-Aimé AGNEL
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// Unit tests for cat.sci function
-// first example : concatenation according to the rows 
-dims=1; A1=[1 2 3]; A2=[4 5 6 ; 7 8 9]; A3=[10 11 12];
-y=cat(dims, A1, A2, A3);
-res = [1 2 3; 4 5 6; 7 8 9; 10 11 12];
-assert_checkequal(y, res);,
-// second example :  concatenation according to the columns
-dims=2; A1=[1 2 3]'; A2=[4 5;7 8;9 10];
-y=cat(dims, A1, A2)
- y  = 
-   1.   4.   5. 
-   2.   7.   8. 
-   3.   9.   10.
-res = [1 4 5; 2 7 8; 3 9 10];
-assert_checkequal(y, res);,
-// third example : concatenation according to the 3th dimension 
-dims=3; A1=matrix(1:12,[2,2,3]); A2=[13 15;14 16]; A3=matrix(17:32,[2,2,4]);
-y=cat(dims, A1, A2, A3);
-res = matrix( [1:32], [2, 2, 8] );
-assert_checkequal(y, res);
index 58e93a9..45146c0 100644 (file)
@@ -1,26 +1,82 @@
 // =============================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) 2016 - Scilab Enterprises - Pierre-Aimé AGNEL
+// Copyright (C) 2017 - Samuel GOUGEON
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
 
+// <-- NO CHECK REF -->
+// <-- CLI SHELL MODE -->
+
 // Unit tests for cat.sci function
+// ===============================
+
+assert_checkequal(cat(1,[]), []);
+assert_checkequal(cat(2,[]), []);
+assert_checkequal(cat(3,[]), []);
+m = rand(3,4,2);
+assert_checkequal(cat(1,m), m);
+assert_checkequal(cat(2,m), m);
+assert_checkequal(cat(3,m), m);
+
 // first example : concatenation according to the rows
-dims=1; A1=[1 2 3]; A2=[4 5 6 ; 7 8 9]; A3=[10 11 12];
+dims = 1; A1=[1 2 3]; A2=[4 5 6 ; 7 8 9]; A3=[10 11 12];
 y=cat(dims, A1, A2, A3);
 res = [1 2 3; 4 5 6; 7 8 9; 10 11 12];
 assert_checkequal(y, res);,
+y = cat(dims, A1<5, A2<5, A3<5);
+assert_checkequal(y, res<5);,
+y = cat(dims, uint8(A1), uint8(A2), uint8(A3));
+assert_checkequal(y, uint8(res));,
+y = cat(dims, string(A1), string(A2), string(A3));
+assert_checkequal(y, string(res));,
+A1 = makecell([1 3 2], %pi, %t, "hello", %s, list(-1,"3"), 1/(1-%s));
+y = cat(1,A1,A1);
+res = makecell([2 3 2], %pi, %t, "hello", ..
+                        %pi, %t, "hello", ..
+                        %s, list(-1,"3"), 1/(1-%s), ..
+                        %s, list(-1,"3"), 1/(1-%s));
+assert_checkequal(y, res);
+
 
 // second example :  concatenation according to the columns
-dims=2; A1=[1 2 3]'; A2=[4 5;7 8;9 10];
-y=cat(dims, A1, A2)
+dims = 2; A1=[1 2 3]'; A2=[4 5;7 8;9 10];
+y = cat(dims, A1, A2);
 res = [1 4 5; 2 7 8; 3 9 10];
 assert_checkequal(y, res);,
+y = cat(dims, A1<5, A2<5);
+assert_checkequal(y, res<5);,
+y = cat(dims, uint8(A1), uint8(A2));
+assert_checkequal(y, uint8(res));,
+y = cat(dims, string(A1), string(A2));
+assert_checkequal(y, string(res));,
+A1 = makecell([2 2 2], %pi, %t, "hello", %s, list(-1,"3"), 1/(1-%s), "abc", %i);
+y = cat(dims, A1, A1);
+res = makecell([2 4 2], %pi, %t, %pi, %t, ..
+                        "hello", %s, "hello", %s, ..
+                        list(-1,"3"), 1/(1-%s), list(-1,"3"), 1/(1-%s), ..
+                        "abc", %i, "abc", %i);
+assert_checkequal(y, res);
 
 // third example : concatenation according to the 3th dimension
-dims=3; A1=matrix(1:12,[2,2,3]); A2=[13 15;14 16]; A3=matrix(17:32,[2,2,4]);
+dims = 3; A1=matrix(1:12,[2,2,3]); A2=[13 15;14 16]; A3=matrix(17:32,[2,2,4]);
 y=cat(dims, A1, A2, A3);
 res = matrix( [1:32], [2, 2, 8] );
-
 assert_checkequal(y, res);
+y = cat(dims, A1<5, A2<5, A3<5);
+assert_checkequal(y, res<5);,
+y = cat(dims, uint8(A1), uint8(A2), uint8(A3));
+assert_checkequal(y, uint8(res));,
+y = cat(dims, string(A1), string(A2), string(A3));
+assert_checkequal(y, string(res));,
+A1 = makecell([2 2 2], %pi, %t, "hello", %s, list(-1,"3"), 1/(1-%s), "abc", %i);
+y = cat(dims, A1, A1(:,:,1));
+res = makecell([2 2 3], %pi, %t, ..
+                        "hello", %s,..
+                        list(-1,"3"), 1/(1-%s), ..
+                        "abc", %i, ..
+                        %pi, %t, ..
+                        "hello", %s);
+assert_checkequal(y, res);
+