Added script front-end for primer-design code
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / permutation / permutation.c
1 /* permutation/permutation.c
2  * 
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
4  * 
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.
9  * 
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.
14  * 
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.
18  */
19
20 #include <config.h>
21 #include <gsl/gsl_errno.h>
22 #include <gsl/gsl_permutation.h>
23
24 size_t
25 gsl_permutation_size (const gsl_permutation * p)
26 {
27   return p->size ;
28 }
29
30 size_t *
31 gsl_permutation_data (const gsl_permutation * p)
32 {
33   return p->data ;
34 }
35
36 #ifndef HIDE_INLINE_STATIC
37 size_t
38 gsl_permutation_get (const gsl_permutation * p, const size_t i)
39 {
40   if (gsl_check_range)
41     {
42       if (i >= p->size)         /* size_t is unsigned, can't be negative */
43         {
44           GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0);
45         }
46     }
47
48   return p->data[i];
49 }
50 #endif
51
52 int
53 gsl_permutation_swap (gsl_permutation * p, const size_t i, const size_t j)
54 {
55   const size_t size = p->size ;
56   
57   if (i >= size)
58     {
59       GSL_ERROR("first index is out of range", GSL_EINVAL);
60     }
61
62   if (j >= size)
63     {
64       GSL_ERROR("second index is out of range", GSL_EINVAL);
65     }
66
67   if (i != j)
68     {
69       size_t tmp = p->data[i];
70       p->data[i] = p->data[j];
71       p->data[j] = tmp;
72     }
73   
74   return GSL_SUCCESS;
75 }
76
77
78 int
79 gsl_permutation_valid (const gsl_permutation * p)
80 {
81   const size_t size = p->size ;
82
83   size_t i, j ;
84
85   for (i = 0; i < size; i++) 
86     {
87       if (p->data[i] >= size)
88         {
89           GSL_ERROR("permutation index outside range", GSL_FAILURE) ;
90         }
91
92       for (j = 0; j < i; j++)
93         {
94           if (p->data[i] == p->data[j])
95             {
96               GSL_ERROR("duplicate permutation index", GSL_FAILURE) ;
97             }
98         }
99     }
100   
101   return GSL_SUCCESS;
102 }
103
104 void
105 gsl_permutation_reverse (gsl_permutation * p)
106 {
107   const size_t size = p->size ;
108
109   size_t i ;
110   
111   for (i = 0; i < (size / 2); i++) 
112     {
113       size_t j = size - i - 1;
114
115       size_t tmp = p->data[i] ;
116       p->data[i] = p->data[j] ;
117       p->data[j] = tmp ;
118     }
119 }
120
121 int 
122 gsl_permutation_inverse (gsl_permutation * inv, const gsl_permutation * p)
123 {
124   const size_t size = p->size ;
125
126   size_t i ;
127
128   if (inv->size != size)
129     {
130       GSL_ERROR("permutation lengths are not equal", GSL_EBADLEN);
131     }
132   
133   for (i = 0; i < size; i++) 
134     {
135       inv->data[p->data[i]] = i ;
136     }
137   
138   return GSL_SUCCESS ;
139 }
140
141 int
142 gsl_permutation_next (gsl_permutation * p)
143 {
144   /* Replaces p with the next permutation (in the standard lexicographical
145    * ordering).  Returns GSL_FAILURE if there is no next permutation.
146    */
147   const size_t size = p->size;
148   size_t i, j, k;
149
150   if (size < 2)
151     {
152       return GSL_FAILURE;
153     }
154
155   i = size - 2;
156
157   while ((p->data[i] > p->data[i+1]) && (i != 0))
158     {
159       i--;
160     }
161
162   if ((i == 0) && (p->data[0] > p->data[1]))
163     {
164      return GSL_FAILURE;
165     }
166
167   k = i + 1;
168
169   for (j = i + 2; j < size; j++ )
170     {
171       if ((p->data[j] > p->data[i]) && (p->data[j] < p->data[k]))
172         {
173           k = j;
174         }
175     }
176
177   /* swap i and k */
178
179   {
180     size_t tmp = p->data[i];
181     p->data[i] = p->data[k];
182     p->data[k] = tmp;
183   }
184
185   for (j = i + 1; j <= ((size + i) / 2); j++)
186     {
187       size_t tmp = p->data[j];
188       p->data[j] = p->data[size + i - j];
189       p->data[size + i - j] = tmp;
190     }
191
192   return GSL_SUCCESS;
193 }
194
195 int
196 gsl_permutation_prev (gsl_permutation * p)
197 {
198   const size_t size = p->size;
199   size_t i, j, k;
200
201   if (size < 2)
202     {
203       return GSL_FAILURE;
204     }
205
206   i = size - 2;
207
208   while ((p->data[i] < p->data[i+1]) && (i != 0))
209     {
210       i--;
211     }
212
213   if ((i == 0) && (p->data[0] < p->data[1]))
214     {
215       return GSL_FAILURE;
216     }
217
218   k = i + 1;
219
220   for (j = i + 2; j < size; j++ )
221     {
222       if ((p->data[j] < p->data[i]) && (p->data[j] > p->data[k]))
223         {
224           k = j;
225         }
226     }
227
228   /* swap i and k */
229
230   {
231     size_t tmp = p->data[i];
232     p->data[i] = p->data[k];
233     p->data[k] = tmp;
234   }
235
236   for (j = i + 1; j <= ((size + i) / 2); j++)
237     {
238       size_t tmp = p->data[j];
239       p->data[j] = p->data[size + i - j];
240       p->data[size + i - j] = tmp;
241     }
242
243   return GSL_SUCCESS;
244 }
245
246 int
247 gsl_permutation_mul (gsl_permutation * p, const gsl_permutation * pa, const gsl_permutation * pb)
248 {
249   size_t i;
250   const size_t size = p->size;
251
252   if (pa->size != size)
253     {
254       GSL_ERROR("size of result does not match size of pa", GSL_EINVAL);
255     }
256
257   if (pb->size != size)
258     {
259       GSL_ERROR("size of result does not match size of pb", GSL_EINVAL);
260     }
261
262   for (i = 0; i < size; i++)
263     {
264       p->data[i] = pb->data[pa->data[i]];
265     }
266
267   return GSL_SUCCESS;
268 }
269 int
270 gsl_permutation_memcpy (gsl_permutation * dest,
271                         const gsl_permutation * src)
272 {
273   const size_t src_size = src->size;
274   const size_t dest_size = dest->size;
275
276   if (src_size != dest_size)
277     {
278       GSL_ERROR ("permutation lengths are not equal", GSL_EBADLEN);
279     }
280
281   {
282     size_t j;
283
284     for (j = 0; j < src_size; j++)
285       {
286         dest->data[j] = src->data[j];
287       }
288   }
289
290   return GSL_SUCCESS;
291 }