Line data Source code
1 : % Copyright (C) 2012-2021,2022 John E. Davis
2 : %
3 : % This file is part of the S-Lang Library and may be distributed under the
4 : % terms of the GNU General Public License. See the file COPYING for
5 : % more information.
6 : %---------------------------------------------------------------------------
7 : define reverse (a)
8 : {
9 : #ifexists array_reverse
10 1 : a = @a;
11 1 : array_reverse (a);
12 1 : return a;
13 : #else
14 : variable i = length (a);
15 : if (i <= 1)
16 : return a;
17 :
18 : i--;
19 : __tmp(a)[[i:0:-1]];
20 : #endif
21 : }
22 :
23 : define shift (x, n)
24 : {
25 9 : variable len = length(x);
26 9 : ifnot (len) return x;
27 :
28 : % allow n to be negative and large
29 9 : n = len + n mod len;
30 9 : return x[[n:n+len-1] mod len];
31 : }
32 :
33 : % This routine rearranges an array according to a permutation. It
34 : % modifies the indices of the permutation array while running, but
35 : % preserves it upon return. This code is based upon
36 : % <http://gams.nist.gov/serve.cgi/ModuleComponent/11449/Source/ITL/DPPERM.f>.
37 : define rearrange (a, indices)
38 : {
39 138 : variable i, j, n = length (indices);
40 :
41 138 : if (__is_same (a, indices))
42 0 : throw InvalidParmError, "The array to be rearranged must not be the same as the permutation.";
43 :
44 : % Check the permutation and make it 1-based
45 138 : _for i (0, n-1, 1)
46 : {
47 1684 : j = indices[i];
48 2459 : if (j < 0) j = -(j+1);
49 1684 : if ((0 <= j < n)
50 : && (indices[j] >= 0))
51 1683 : indices[j] = -indices[j]-1;
52 : else
53 1 : throw InvalidParmError, "Invalid permutation.";
54 : }
55 :
56 137 : _for i (0, n-1, 1)
57 : {
58 1676 : if (indices[i] >= 0)
59 1330 : continue;
60 :
61 346 : j = i;
62 346 : variable j0 = j;
63 346 : variable tmp = a[j0];
64 :
65 346 : variable indices_j = indices[j];
66 : forever
67 : {
68 1676 : j0 = j;
69 1676 : j = -indices_j-1; % back to 0-based
70 1676 : indices[j0] = j;
71 1676 : indices_j = indices[j];
72 1676 : if (indices_j >= 0)
73 346 : break;
74 1330 : a[j0] = a[j];
75 : }
76 346 : a[j0] = tmp;
77 : }
78 : }
79 :
80 4 : $1 = path_concat (path_dirname (__FILE__), "help/arrayfuns.hlp");
81 4 : if (NULL != stat_file ($1))
82 4 : add_doc_file ($1);
83 :
84 4 : provide ("arrayfuns");
|