1 /* permutation/permute_source.c
3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 /* In-place Permutations
22 permute: OUT[i] = IN[perm[i]] i = 0 .. N-1
23 invpermute: OUT[perm[i]] = IN[i] i = 0 .. N-1
25 PERM is an index map, i.e. a vector which contains a permutation of
26 the integers 0 .. N-1.
28 From Knuth "Sorting and Searching", Volume 3 (3rd ed), Section 5.2
29 Exercise 10 (answers), p 617
31 FIXME: these have not been fully tested.
35 TYPE (gsl_permute) (const size_t * p, ATOMIC * data, const size_t stride, const size_t n)
39 for (i = 0; i < n; i++)
49 /* Now have k == i, i.e the least in its cycle */
56 /* shuffle the elements of the cycle */
61 ATOMIC t[MULTIPLICITY];
63 for (a = 0; a < MULTIPLICITY; a++)
64 t[a] = data[i*stride*MULTIPLICITY + a];
68 for (a = 0; a < MULTIPLICITY; a++)
70 ATOMIC r1 = data[pk*stride*MULTIPLICITY + a];
71 data[k*stride*MULTIPLICITY + a] = r1;
77 for (a = 0; a < MULTIPLICITY; a++)
78 data[k*stride*MULTIPLICITY + a] = t[a];
86 FUNCTION (gsl_permute,inverse) (const size_t * p, ATOMIC * data, const size_t stride, const size_t n)
90 for (i = 0; i < n; i++)
100 /* Now have k == i, i.e the least in its cycle */
107 /* shuffle the elements of the cycle in the inverse direction */
112 ATOMIC t[MULTIPLICITY];
114 for (a = 0; a < MULTIPLICITY; a++)
115 t[a] = data[k*stride*MULTIPLICITY+a];
119 for (a = 0; a < MULTIPLICITY; a++)
121 ATOMIC r1 = data[pk*stride*MULTIPLICITY + a];
122 data[pk*stride*MULTIPLICITY + a] = t[a];
130 for (a = 0; a < MULTIPLICITY; a++)
131 data[pk*stride*MULTIPLICITY+a] = t[a];
140 TYPE (gsl_permute_vector) (const gsl_permutation * p, TYPE (gsl_vector) * v)
142 if (v->size != p->size)
144 GSL_ERROR ("vector and permutation must be the same length", GSL_EBADLEN);
147 TYPE (gsl_permute) (p->data, v->data, v->stride, v->size) ;
153 FUNCTION (gsl_permute_vector,inverse) (const gsl_permutation * p, TYPE (gsl_vector) * v)
155 if (v->size != p->size)
157 GSL_ERROR ("vector and permutation must be the same length", GSL_EBADLEN);
160 FUNCTION (gsl_permute,inverse) (p->data, v->data, v->stride, v->size) ;