Elementry_functions: permute() rewritten
[scilab.git] / scilab / modules / elementary_functions / macros / permute.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) INRIA - Farid BELAHCENE
3 // Copyright (C) 2013 - Samuel GOUGEON : processing rewritten, fixing http://bugzilla.scilab.org/5205
4 //
5 // This file must be used under the terms of the CeCILL.
6 // This source file is licensed as described in the file COPYING, which
7 // you should have received as part of this distribution.  The terms
8 // are also available at
9 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10
11 function y = permute(x, dims)
12
13     // This function returns an array y which results of the x permutation
14     // Input :
15     // -x a (multi-dimensionnnal) array of cells, or doubles or strings, ...
16     // -dims a vector which contains the permutation order
17     // Output :
18     // -y the result of the x permutation
19
20     // Verify input arguments number
21     if argn(2) <> 2 then
22         error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "permute", 2));
23     end
24
25     // Verify if the size of dims corresponds to dimension of x
26     if ndims(dims) <> 2 then
27         error(msprintf(gettext("%s: Wrong size for argument #%d: Vector expected.\n"), "permute", 2));
28
29     elseif or(gsort(dims,"c","i") <> (1:prod(size(dims)))) then
30         error(msprintf(gettext("%s: Wrong size for input argument #%d.\n"), "permute", 2));
31
32     elseif prod(size(dims)) < ndims(x) then
33         error(msprintf(gettext("%s: Wrong size for input argument #%d: At least the size of input argument #%d expected.\n"), "permute", 2, 1));
34     end
35
36     // Case x is empty
37     if isempty(x) then
38         y = x
39         return
40     end
41
42     // ---------------- PROCESSING --------------------
43     // Existing indices
44     s = size(x)
45     p = size(x, "*")
46     n = 1
47     for i = 1:length(s)
48         t = "x%d = ones(1,p/(prod(s(1:%d)))) .*. ((1:s(%d)) .*. ones(1,n)) ;"+..
49         " n = prod(s(1:%d))\n"
50         t = msprintf(t, i, i, i, i)
51         execstr(t)
52     end
53     xlist = strcat(msprintf("x%d\n",(1:length(s))'),",")
54     cstr = "sub2ind(s,"+ xlist +")"
55     execstr("LI = "+cstr)
56
57     // New indices
58     s = s(dims)
59     cstr = "sub2ind(s,"+ strcat(msprintf("x%d\n", dims(:)), ",")+")"
60     execstr("LI2 = "+cstr)
61
62     // Clearing intermediate memory used
63     execstr("clear "+strsubst(xlist, ",", " "))
64
65     // Permutation
66     if typeof(x) == "ce"
67         y = x
68         y.dims = int32(s)
69         y(LI2).entries = x(LI).entries
70     else
71         y(LI2) = x(LI)
72         y = matrix(y, s)
73     end
74
75 endfunction