root/trunk/data/combination.lisp

Revision 34, 6.8 kB (checked in by lhealy, 9 months ago)

The classes/types in the different contexts are now gathered together
in one place, in *type-names* for the types and in *data-class-name*
for data classes, populated by #'add-data-class. Both defdata and
defmfun-all use the table and so mapping between various names is
consistent. The data class names are now different, *-double-float
and *-single-float replaces *-double and *-single. The regression
tests give the same results as before.

  • Property svn:keywords set to Id
Line 
1;; Combinations
2;; Liam Healy, Sun Mar 26 2006 - 11:51
3;; Time-stamp: <2008-03-09 22:07:29EDT combination.lisp>
4;; $Id$
5
6(in-package :gsl)
7
8;;;;****************************************************************************
9;;;; Combination structure and CL object
10;;;;****************************************************************************
11
12;;; GSL-combination definition
13(cffi:defcstruct gsl-combination-c
14  (n size)
15  (k size)
16  (data :pointer))
17
18;;; Allocation, freeing, reading and writing
19(add-data-class combination fixnum combination gsl-data "combination")
20(defdata combination fixnum 2 "")
21
22(defmethod gsl-array ((object combination))
23  (foreign-slot-value (pointer object) 'gsl-combination-c 'data))
24
25;;;;****************************************************************************
26;;;; Getting values
27;;;;****************************************************************************
28
29(defmfun maref ((combination combination) &rest indices)
30  "gsl_combination_get"
31  (((pointer combination) :pointer) ((first indices) size))
32  :type :method
33  :c-return size
34  :documentation                        ; FDL
35  "The ith element of the combination.")
36
37(defmethod data ((object combination) &optional sequence)
38  (let ((seq (or sequence
39                 (make-sequence 'list (combination-size object)))))
40    (loop for i from 0
41          below (min (length seq) (combination-size object))
42          do (setf (elt seq i) (maref object i)))
43    seq))
44
45;;;;****************************************************************************
46;;;; Setting values
47;;;;****************************************************************************
48
49(defmfun init-first (combination)
50  "gsl_combination_init_first"
51  (((pointer combination) gsl-combination-c))
52  :c-return :void
53  :invalidate (combination)
54  :documentation                        ; FDL
55  "Initialize the combination c to the lexicographically
56      first combination, i.e.  (0,1,2,...,k-1).")
57
58(defmfun init-last (combination)
59  "gsl_combination_init_last"
60  (((pointer combination) gsl-combination-c))
61  :c-return :void
62  :invalidate (combination)
63  :documentation                        ; FDL
64  "Initialize the combination c to the lexicographically
65   last combination, i.e. (n-k,n-k+1,...,n-1).")
66
67(defmfun copy (destination source)
68  "gsl_combination_memcpy"
69  (((pointer destination) gsl-combination-c)
70   ((pointer source) gsl-combination-c))
71  :type :method
72  :invalidate (destination)
73  :documentation                        ; FDL
74  "Copy the elements of the combination source into the
75  combination destination.  The two combinations must have the same size.")
76
77;;;;****************************************************************************
78;;;; Combination properties
79;;;;****************************************************************************
80
81(defmfun combination-range (c)
82  "gsl_combination_n"
83  (((pointer c) gsl-combination-c))
84  :c-return size
85  :documentation                        ; FDL
86  "The range (n) of the combination c.")
87
88(defmfun combination-size (c)
89  "gsl_combination_k"
90  (((pointer c) gsl-combination-c))
91  :c-return size
92  :documentation                        ; FDL
93  "The number of elements (k) in the combination c.")
94
95#|
96;;; Unnecessary, gsl-array serves this function.
97(defmfun combination-data (c)
98  "gsl_combination_data"
99  (((pointer c) gsl-combination-c))
100  :c-return :pointer
101  :documentation                        ; FDL
102  "A pointer to the array of elements in the combination.")
103|#
104
105(defmfun data-valid ((combination combination))
106  "gsl_combination_valid"
107  (((pointer combination) :pointer))
108  :type :method
109  :c-return :boolean
110  :documentation                        ; FDL
111  "Check that the combination is valid.  The k
112   elements should lie in the range 0 to n-1, with each
113   value occurring once at most and in increasing order.")
114
115;;;;****************************************************************************
116;;;; Combination functions
117;;;;****************************************************************************
118
119(defmfun combination-next (c)
120  "gsl_combination_next" (((pointer c) gsl-combination-c))
121  :c-return :success-failure
122  :invalidate (c)
123  :documentation                        ; FDL
124  "Advance the combination c to the next combination
125   in lexicographic order and return T and c.  If no further
126   combinations are available it return NIL and c with
127   c unmodified.  Starting with the first combination and
128   repeatedly applying this function will iterate through all possible
129   combinations of a given order.")
130
131(defmfun combination-previous (c)
132  "gsl_combination_prev"
133  (((pointer c) gsl-combination-c))
134  :c-return :success-failure
135  :invalidate (c)
136  :documentation                        ; FDL
137  "Step backwards from the combination c to the
138   previous combination in lexicographic order, returning
139   T and c.  If no previous combination is available it returns
140   NIL and c with c unmodified.")
141
142;;;;****************************************************************************
143;;;; Examples and unit test
144;;;;****************************************************************************
145
146#|
147(make-tests combination
148 (letm ((comb (combination 4 2 t)))     ; combination-range
149   (combination-range comb))
150 (letm ((comb (combination 4 2 t)))     ; combination-size
151   (combination-size comb))
152 (letm ((comb (combination 4 2 t)))     ; init-first, combination-next
153   (init-first comb)
154   (loop collect (data comb)
155         while (combination-next comb)))
156 (letm ((comb (combination 4 2 t)))  ; init-last, combination-previous
157   (init-last comb)
158   (loop collect (data comb)
159         while (combination-previous comb)))
160 (loop for i from 0 to 4                ; combination-next
161       append
162       (letm ((comb (combination 4 i t)))
163         (init-first comb)
164         (loop collect (data comb)
165               while (combination-next comb)))))
166|#
167
168(LISP-UNIT:DEFINE-TEST COMBINATION
169  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
170   (LIST 4)
171   (MULTIPLE-VALUE-LIST
172    (LETM ((COMB (COMBINATION 4 2 T)))
173      (COMBINATION-RANGE COMB))))
174  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
175   (LIST 2)
176   (MULTIPLE-VALUE-LIST
177    (LETM ((COMB (COMBINATION 4 2 T)))
178      (COMBINATION-SIZE COMB))))
179  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
180   (LIST
181    (LIST (LIST 0 1) (LIST 0 2) (LIST 0 3) (LIST 1 2)
182          (LIST 1 3) (LIST 2 3)))
183   (MULTIPLE-VALUE-LIST
184    (LETM ((COMB (COMBINATION 4 2 T))) (INIT-FIRST COMB)
185          (LOOP COLLECT (DATA COMB) WHILE
186                (COMBINATION-NEXT COMB)))))
187  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
188   (LIST (LIST (LIST 2 3) (LIST 1 3) (LIST 1 2) (LIST 0 3)
189               (LIST 0 2) (LIST 0 1)))
190   (MULTIPLE-VALUE-LIST
191    (LETM ((COMB (COMBINATION 4 2 T))) (INIT-LAST COMB)
192          (LOOP COLLECT (DATA COMB) WHILE
193                (COMBINATION-PREVIOUS COMB)))))
194  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
195   (LIST
196    (LIST (LIST) (LIST 0) (LIST 1) (LIST 2) (LIST 3)
197          (LIST 0 1) (LIST 0 2) (LIST 0 3) (LIST 1 2)
198          (LIST 1 3) (LIST 2 3) (LIST 0 1 2) (LIST 0 1 3)
199          (LIST 0 2 3) (LIST 1 2 3) (LIST 0 1 2 3)))
200   (MULTIPLE-VALUE-LIST
201    (LOOP FOR I FROM 0 TO 4 APPEND
202          (LETM ((COMB (COMBINATION 4 I T)))
203            (INIT-FIRST COMB)
204            (LOOP COLLECT (DATA COMB) WHILE
205                  (COMBINATION-NEXT COMB)))))))
206
Note: See TracBrowser for help on using the browser.