gsl_permutation__permutation.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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. #include "gsl__config.h"
  20. #include "gsl_errno.h"
  21. #include "gsl_permutation.h"
  22. size_t
  23. gsl_permutation_size (const gsl_permutation * p)
  24. {
  25. return p->size ;
  26. }
  27. size_t *
  28. gsl_permutation_data (const gsl_permutation * p)
  29. {
  30. return p->data ;
  31. }
  32. #ifndef HIDE_INLINE_STATIC
  33. size_t
  34. gsl_permutation_get (const gsl_permutation * p, const size_t i)
  35. {
  36. if (gsl_check_range)
  37. {
  38. if (i >= p->size) /* size_t is unsigned, can't be negative */
  39. {
  40. GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0);
  41. }
  42. }
  43. return p->data[i];
  44. }
  45. #endif
  46. int
  47. gsl_permutation_swap (gsl_permutation * p, const size_t i, const size_t j)
  48. {
  49. const size_t size = p->size ;
  50. if (i >= size)
  51. {
  52. GSL_ERROR("first index is out of range", GSL_EINVAL);
  53. }
  54. if (j >= size)
  55. {
  56. GSL_ERROR("second index is out of range", GSL_EINVAL);
  57. }
  58. if (i != j)
  59. {
  60. size_t tmp = p->data[i];
  61. p->data[i] = p->data[j];
  62. p->data[j] = tmp;
  63. }
  64. return GSL_SUCCESS;
  65. }
  66. int
  67. gsl_permutation_valid (gsl_permutation * p)
  68. {
  69. const size_t size = p->size ;
  70. size_t i, j ;
  71. for (i = 0; i < size; i++)
  72. {
  73. if (p->data[i] >= size)
  74. {
  75. GSL_ERROR("permutation index outside range", GSL_FAILURE) ;
  76. }
  77. for (j = 0; j < i; j++)
  78. {
  79. if (p->data[i] == p->data[j])
  80. {
  81. GSL_ERROR("duplicate permutation index", GSL_FAILURE) ;
  82. }
  83. }
  84. }
  85. return GSL_SUCCESS;
  86. }
  87. void
  88. gsl_permutation_reverse (gsl_permutation * p)
  89. {
  90. const size_t size = p->size ;
  91. size_t i ;
  92. for (i = 0; i < (size / 2); i++)
  93. {
  94. size_t j = size - i - 1;
  95. size_t tmp = p->data[i] ;
  96. p->data[i] = p->data[j] ;
  97. p->data[j] = tmp ;
  98. }
  99. }
  100. int
  101. gsl_permutation_inverse (gsl_permutation * inv, const gsl_permutation * p)
  102. {
  103. const size_t size = p->size ;
  104. size_t i ;
  105. if (inv->size != size)
  106. {
  107. GSL_ERROR("permutation lengths are not equal", GSL_EBADLEN);
  108. }
  109. for (i = 0; i < size; i++)
  110. {
  111. inv->data[p->data[i]] = i ;
  112. }
  113. return GSL_SUCCESS ;
  114. }
  115. int
  116. gsl_permutation_next (gsl_permutation * p)
  117. {
  118. /* Replaces p with the next permutation (in the standard lexicographical
  119. * ordering). Returns GSL_FAILURE if there is no next permutation.
  120. */
  121. const size_t size = p->size;
  122. size_t i, j, k;
  123. if (size < 2)
  124. {
  125. return GSL_FAILURE;
  126. }
  127. i = size - 2;
  128. while ((p->data[i] > p->data[i+1]) && (i != 0))
  129. {
  130. i--;
  131. }
  132. if ((i == 0) && (p->data[0] > p->data[1]))
  133. {
  134. return GSL_FAILURE;
  135. }
  136. k = i + 1;
  137. for (j = i + 2; j < size; j++ )
  138. {
  139. if ((p->data[j] > p->data[i]) && (p->data[j] < p->data[k]))
  140. {
  141. k = j;
  142. }
  143. }
  144. /* swap i and k */
  145. {
  146. size_t tmp = p->data[i];
  147. p->data[i] = p->data[k];
  148. p->data[k] = tmp;
  149. }
  150. for (j = i + 1; j <= ((size + i) / 2); j++)
  151. {
  152. size_t tmp = p->data[j];
  153. p->data[j] = p->data[size + i - j];
  154. p->data[size + i - j] = tmp;
  155. }
  156. return GSL_SUCCESS;
  157. }
  158. int
  159. gsl_permutation_prev (gsl_permutation * p)
  160. {
  161. const size_t size = p->size;
  162. size_t i, j, k;
  163. if (size < 2)
  164. {
  165. return GSL_FAILURE;
  166. }
  167. i = size - 2;
  168. while ((p->data[i] < p->data[i+1]) && (i != 0))
  169. {
  170. i--;
  171. }
  172. if ((i == 0) && (p->data[0] < p->data[1]))
  173. {
  174. return GSL_FAILURE;
  175. }
  176. k = i + 1;
  177. for (j = i + 2; j < size; j++ )
  178. {
  179. if ((p->data[j] < p->data[i]) && (p->data[j] > p->data[k]))
  180. {
  181. k = j;
  182. }
  183. }
  184. /* swap i and k */
  185. {
  186. size_t tmp = p->data[i];
  187. p->data[i] = p->data[k];
  188. p->data[k] = tmp;
  189. }
  190. for (j = i + 1; j <= ((size + i) / 2); j++)
  191. {
  192. size_t tmp = p->data[j];
  193. p->data[j] = p->data[size + i - j];
  194. p->data[size + i - j] = tmp;
  195. }
  196. return GSL_SUCCESS;
  197. }
  198. int
  199. gsl_permutation_mul (gsl_permutation * p, const gsl_permutation * pa, const gsl_permutation * pb)
  200. {
  201. size_t i;
  202. const size_t size = p->size;
  203. if (pa->size != size)
  204. {
  205. GSL_ERROR("size of result does not match size of pa", GSL_EINVAL);
  206. }
  207. if (pb->size != size)
  208. {
  209. GSL_ERROR("size of result does not match size of pb", GSL_EINVAL);
  210. }
  211. for (i = 0; i < size; i++)
  212. {
  213. p->data[i] = pb->data[pa->data[i]];
  214. }
  215. return GSL_SUCCESS;
  216. }
  217. int
  218. gsl_permutation_memcpy (gsl_permutation * dest,
  219. const gsl_permutation * src)
  220. {
  221. const size_t src_size = src->size;
  222. const size_t dest_size = dest->size;
  223. if (src_size != dest_size)
  224. {
  225. GSL_ERROR ("permutation lengths are not equal", GSL_EBADLEN);
  226. }
  227. {
  228. size_t j;
  229. for (j = 0; j < src_size; j++)
  230. {
  231. dest->data[j] = src->data[j];
  232. }
  233. }
  234. return GSL_SUCCESS;
  235. }