combination.lisp 5.03 KB
Newer Older
1
2
3
4
5
;********************************************************
; file:        combination.lisp                        
; description: Combinations
; date:        Sun Mar 26 2006 - 11:51                   
; author:      Liam M. Healy                             
6
; modified:    Fri Apr 14 2006 - 17:50
7
8
9
10
11
12
;********************************************************
;;; $Id: $

(in-package :gsl)

;;;;****************************************************************************
13
;;;; Combination structure and CL object
14
15
16
17
18
19
20
21
22
;;;;****************************************************************************

;;; GSL-combination definition
(cffi:defcstruct gsl-combination-c
  (n :size)
  (k :size)
  (data :pointer))

;;; Allocation, freeing, reading and writing
23
(defdata "combination" :size 'fixnum 2)
24
25
26

(add-wrap-type gsl-combination-c (lambda (x) `(pointer ,x)))

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
;;;;****************************************************************************
;;;; Getting values
;;;;****************************************************************************

(defun-gsl gsl-aref
    (((pointer combination) :pointer) ((first indices) :size))
  "gsl_combination_get"
  :method ((combination gsl-combination) &rest indices)
  :return (:size)
  :c-return-value :return
  :documentation "The ith element of the combination.")

(defmethod data ((object gsl-combination) &optional sequence)
  (let ((seq (or sequence
		 (make-sequence 'list (combination-size object)))))
    (loop for i from 0
	  below (min (length seq) (combination-size object))
	  do (setf (elt seq i) (gsl-aref object i)))
    seq))

;;;;****************************************************************************
;;;; Setting values
;;;;****************************************************************************

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
(defun-gsl init-first ((combination gsl-combination-c))
  "gsl_combination_init_first"
  :c-return-value :void
  :documentation
  "Initialize the combination @var{c} to the lexicographically
      first combination, i.e.  @math{(0,1,2,@dots{},k-1)}.")

(defun-gsl init-last ((combination gsl-combination-c))
  "gsl_combination_init_last"
  :c-return-value :void
  :documentation
  "Initialize the combination @var{c} to the lexicographically
   last combination, i.e.  @math{(n-k,n-k+1,@dots{},n-1)}.")

(defun-gsl combination-copy
    ((destination gsl-combination-c) (source gsl-combination-c) )
  "gsl_combination_memcpy"
  :documentation
  "Copy the elements of the combination @var{src} into the
  combination @var{dest}.  The two combinations must have the same size.")

;;;;****************************************************************************
;;;; Combination properties
;;;;****************************************************************************

(defun-gsl combination-range ((c gsl-combination-c))
  "gsl_combination_n"
  :c-return-value :return
  :return (:size) 
  :documentation
  "The range (@math{n}) of the combination @var{c}.")

(defun-gsl combination-size ((c gsl-combination-c))
  "gsl_combination_k"
  :c-return-value :return
  :return (:size) 
  :documentation
  "The number of elements (@math{k}) in the combination @var{c}.")

(defun-gsl combination-data ((c gsl-combination-c))
  "gsl_combination_data"
  :c-return-value :return
  :return (:pointer) 
  :documentation
  "A pointer to the array of elements in the combination @var{p}.")

97
(defun-gsl data-valid (((pointer combination) :pointer))
98
  "gsl_combination_valid"
99
  :method ((combination gsl-combination))
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  :c-return-value :return
  :return (:boolean) 
  :documentation
  "Check that the combination @var{c} is valid.  The @var{k}
   elements should lie in the range 0 to @math{@var{n}-1}, with each
   value occurring once at most and in increasing order.")

;;;;****************************************************************************
;;;; Combination functions
;;;;****************************************************************************

(defun-gsl combination-next ((c gsl-combination-c))
  "gsl_combination_next"
  :c-return-value :success-failure
  :documentation
  "Advance the combination @var{c} to the next combination
   in lexicographic order and return T.  If no further
   combinations are available it return NIL and leave
   @var{c} unmodified.  Starting with the first combination and
   repeatedly applying this function will iterate through all possible
   combinations of a given order.")

122
(defun-gsl combination-previous ((c gsl-combination-c))
123
124
125
126
127
128
129
130
131
132
133
134
135
  "gsl_combination_prev"
  :c-return-value :success-failure
  :documentation
  "Step backwards from the combination @var{c} to the
   previous combination in lexicographic order, returning
   T.  If no previous combination is available it returns
   NIL and leaves @var{c} unmodified.")

;;;;****************************************************************************
;;;; Examples
;;;;****************************************************************************

#|
136
137
138
(loop for i from 0 to 4
      append
      (with-data (comb combination (4 i) t)
139
	(loop collect (data comb)
140
141
142
143
144
	      while (combination-next comb))))

(NIL (0) (1) (2) (3) (0 1) (0 2) (0 3) (1 2) (1 3) (2 3)
     (0 1 2) (0 1 3) (0 2 3) (1 2 3) (0 1 2 3))

145
|#