summaryrefslogtreecommitdiff
path: root/modules/elementary_functions/macros/cat.sci
blob: 047aee01a2d74b2c3f6c5141122849a14442dda7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) INRIA - Farid BELAHCENE
// Copyright (C) DIGITEO - 2011 - Allan CORNET
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution.  The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt

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


    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

    if typeof(varargin(1))=="hypermat" then
        vartype = typeof(varargin(1).entries);
    else
        vartype = typeof(varargin(1));
    end

    for j=2:size(varargin)
        if typeof(varargin(j))=="hypermat" then
            if typeof(varargin(j).entries) ==vartype
                vartype = typeof(varargin(j).entries);
            else
                error(msprintf(gettext("%s: Wrong type for input arguments: Same types expected.\n"),"cat"));
            end
        elseif  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).entries = permutevarj(k).entries;
                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)).entries = ytemp(ceindex(k)).entries;
            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