1 /* combination/combination.c
2 * based on permutation/permutation.c by Brian Gough
4 * Copyright (C) 2001 Szymon Jaroszewicz
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or (at
9 * your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <gsl/gsl_errno.h>
23 #include <gsl/gsl_combination.h>
26 gsl_combination_n (const gsl_combination * c)
32 gsl_combination_k (const gsl_combination * c)
38 gsl_combination_data (const gsl_combination * c)
43 #ifndef HIDE_INLINE_STATIC
45 gsl_combination_get (const gsl_combination * c, const size_t i)
49 if (i >= c->k) /* size_t is unsigned, can't be negative */
51 GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0);
61 gsl_combination_valid (gsl_combination * c)
63 const size_t n = c->n ;
64 const size_t k = c->k ;
70 GSL_ERROR("combination has k greater than n", GSL_FAILURE) ;
72 for (i = 0; i < k; i++)
74 const size_t ci = c->data[i];
78 GSL_ERROR("combination index outside range", GSL_FAILURE) ;
81 for (j = 0; j < i; j++)
85 GSL_ERROR("duplicate combination index", GSL_FAILURE) ;
89 GSL_ERROR("combination indices not in increasing order",
100 gsl_combination_next (gsl_combination * c)
102 /* Replaces c with the next combination (in the standard lexicographical
103 * ordering). Returns GSL_FAILURE if there is no next combination.
105 const size_t n = c->n;
106 const size_t k = c->k;
107 size_t *data = c->data;
116 while(i > 0 && data[i] == n - k + i)
120 if(i == 0 && data[i] == n - k)
125 for(; i < k - 1; i++)
127 data[i + 1] = data[i] + 1;
133 gsl_combination_prev (gsl_combination * c)
135 /* Replaces c with the previous combination (in the standard
136 * lexicographical ordering). Returns GSL_FAILURE if there is no
137 * previous combination.
139 const size_t n = c->n;
140 const size_t k = c->k;
141 size_t *data = c->data;
150 while(i > 0 && data[i] == data[i-1] + 1)
154 if(i == 0 && data[i] == 0)
167 gsl_combination_memcpy (gsl_combination * dest, const gsl_combination * src)
169 const size_t src_n = src->n;
170 const size_t src_k = src->k;
171 const size_t dest_n = dest->n;
172 const size_t dest_k = dest->k;
174 if (src_n != dest_n || src_k != dest_k)
176 GSL_ERROR ("combination lengths are not equal", GSL_EBADLEN);
182 for (j = 0; j < src_k; j++)
184 dest->data[j] = src->data[j];