* Bug 15236 fixed: isglobal() page was inaccurate + wrong examples
[scilab.git] / scilab / modules / elementary_functions / macros / cat.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) INRIA - Farid BELAHCENE
3 // Copyright (C) DIGITEO - 2011 - Allan CORNET
4 //
5 // Copyright (C) 2012 - 2016 - Scilab Enterprises
6 //
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
13
14 function  y = cat(dims, varargin)
15     //
16     // CAT function concatenates the inputs arguments (included in varargin) according to dims
17     // 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,...
18     // Output
19     // -y : a (multi) array, the result of the concatenation
20     // Input
21     // -dims : a scalar, the dimension chosen for the concatenation
22     // -varargin : scalars, matrices, hypermatrices to concatenate
23     // F.B
24
25
26     rhs = argn(2);
27     if rhs < 1 then
28         error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"),"cat", 1));
29     end
30
31     // dims must be a positive real
32     if type(dims)==1 & dims>=0 & size(dims,"*")==1
33         dims = max(1,round(dims));
34     else
35         error(msprintf(gettext("%s: Wrong type for input argument #%d: A positive real expected.\n"),"cat",1));
36     end
37
38     // verify if dims value is superior to the dimension of the input arguments
39     dimssupvar = %t;
40     for i = 1:size(varargin)
41         if ndims(varargin(i))>=dims then
42             dimssupvar = %f;
43         end
44     end
45
46     // delete all empty input arguments
47     for i = size(varargin):-1:2
48         if isempty(varargin(i)) then
49             varargin(i) = null();
50         end
51     end
52
53     // if just one input argument to concatenate then return this argument
54     if size(varargin) == 1 then
55         y = varargin(1);
56         return
57     elseif isempty(varargin(1)) then
58         varargin(1) = null();
59     end
60
61     // 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
62     onedims = ones(1,dims);
63     sizevarless = list();
64     sizevar = list();
65
66     for i=1:size(varargin)
67         var = onedims;
68         var(1:ndims(varargin(i))) = size(varargin(i));
69         sizevar(i) = var;
70         var(dims) = [];
71         sizevarless(i) = var;
72     end
73
74     for i=2:size(varargin)
75         if or(sizevarless(i-1)<> sizevarless(i))
76             error(msprintf(gettext("%s: Wrong size for input arguments: Same size expected.\n"),"cat"));
77         end
78     end
79
80     // case : input arguments are cells arrrays
81     if typeof(varargin(1))=="ce"
82         ytemp = cell();
83     else   // case : input arguments are arrays of doubles, strings, characters,...
84         ytemp = [];
85     end
86
87     vartype = typeof(varargin(1));
88
89     for j=2:size(varargin)
90         if  typeof(varargin(j)) ==vartype
91             vartype = typeof(varargin(j));
92         else
93             error(msprintf(gettext("%s: Wrong type for input arguments: Same types expected.\n"),"cat"));
94         end
95     end
96
97     // permorder is the order of the permutation
98     permuteorder = 1:size(sizevarless(1),"*")+1;
99     if ~dimssupvar then
100         permuteorder(dims) = [];
101         permuteorder = [dims permuteorder];
102     end
103
104     // permutevar is a list which contains the permuted input arguments arrays
105     permutevar = list();
106     for j=1:size(varargin)
107         permutevar(j) = permute(varargin(j),permuteorder);
108     end
109
110     for i=1:prod(sizevarless(1))
111         for j=1:size(varargin)
112             permutevarj = permutevar(j);
113             lj = size(varargin(j),"*")/prod(sizevarless(j));
114             if typeof(permutevarj)=="ce" then
115                 for k=1+lj*(i-1):lj*i
116                     ytemp{size(ytemp,"*")+1} = permutevarj{k};
117                 end
118             else
119                 ytemp= [ytemp (permutevarj(1+lj*(i-1):lj*i)).'];
120             end
121         end
122     end
123     ytemp = matrix(ytemp,1,-1);
124
125     sizevar = sizevar(1);
126     prodxdims = prod(sizevar(1:dims));
127     ny = prod(sizevar)/prodxdims;
128     ydimsize = size(ytemp,2)/(prod(sizevarless(1)));
129     prodxdimless = prod(sizevar(1:dims-1));
130     ind = 1;
131     for j=1:ydimsize-1
132         ind = [ind 1+prodxdimless*j];
133     end
134     for i=0:ny-1
135         index = [];
136         for j=0:prodxdimless-1
137             index = [index ind+j+i*(prodxdimless)*ydimsize];
138         end
139         if typeof(ytemp)=="ce"
140             ceindex = (1:ydimsize*prodxdimless)+ydimsize*prodxdimless*(i);
141             for k=1:size(index,"*")
142                 y{index(k)} = ytemp{ceindex(k)};
143             end
144         else
145             y(index) = ytemp((1:ydimsize*prodxdimless)+ydimsize*prodxdimless*(i));
146         end
147     end
148
149     // redimension of y
150     ysize = sizevarless(1);
151     if dimssupvar then
152         ysize($+1) = size(varargin);
153     else
154         if dims == size(sizevarless(1))+1
155             ysize(dims) = size(ytemp,2)/prod(sizevarless(1));
156         else
157             ysize = [ysize(1:dims-1) size(ytemp,2)/prod(sizevarless(1)) ysize(dims:$)];
158         end
159     end
160     y = matrix(y,ysize);
161
162 endfunction