root/trunk/sorting.lisp

Revision 37 (checked in by lhealy, 7 months ago)

The functions #'sort-vector-smallest-index and
#'sort-vector-largest-index now work on 64-bit platforms. It was
necessary to change the API in order to do this: instead of taking a
GSL vector fixnum as the first argument, they now take either a
positive integer, or a CL vector. This is because it appears to be
very difficult to find a GSL vector type that matches a C array of
size_ts. Thus, the GSLL policy of using only GSL vectors and not raw
C vectors needs to be altered. However, now the GSLL policy of not
requiring an object to be passed as an argument if it is used only
for returning values is fulfilled.

  • Property svn:keywords set to Id
Line 
1 ;; Sorting
2 ;; Liam Healy, Fri Apr 14 2006 - 20:20
3 ;; Time-stamp: <2008-03-15 22:09:56EDT sorting.lisp>
4 ;; $Id$
5
6 (in-package :gsl)
7
8 ;;; #'heapsort has just a cursory port, use CL's #'sort.
9 ;;; Raw C array functions not ported, not policy.
10
11 ;;;;****************************************************************************
12 ;;;; Heapsort, not recommended
13 ;;;;****************************************************************************
14
15 (defmacro defcomparison (name &body body)
16   `(cffi:defcallback ,name :int ((a :pointer) (b :pointer))
17     ,body))
18
19 (defmfun heapsort (array count size function)
20   "gsl_heapsort"
21   ((array :pointer) (count size) (size size) (function :pointer))
22   :documentation                        ; FDL
23   "Sort the count elements of the array of size specified
24    into ascending order using the comparison
25    function.  The type of the comparison function is defined by,
26    A comparison function should return a negative integer if the first
27    argument is less than the second argument, zero if the two arguments
28    are equal and a positive integer if the first argument is greater than
29    the second argument."
30   :c-return :void)
31
32 (defmfun heapsort-index (p array count size function)
33   "gsl_heapsort_index"
34   ((p size) (array :pointer) (count size) (size size) (function :pointer))
35   :documentation                        ; FDL
36   "Indirectly sort the count elements of the array
37    array, each of size given, into ascending order using the
38    comparison function.  The resulting permutation is stored
39    in p, an array of length n.  The elements of p give the
40    index of the array element which would have been stored in that position
41    if the array had been sorted in place.  The first element of p
42    gives the index of the least element in array, and the last
43    element of p gives the index of the greatest element in
44    array.  The array itself is not changed.")
45
46 ;;;;****************************************************************************
47 ;;;; Vector sort
48 ;;;;****************************************************************************
49
50 ;;; Port only _vector_ sort functions?
51
52 (export 'sort-vector)
53 (defgeneric sort-vector (vector)
54   (:documentation                       ; FDL
55    "Sort the elements of the vector into ascending numerical order."))
56
57 (defmfun-vdsf sort-vector ((vector vector))
58   "gsl_sort_vector" (((pointer vector) gsl-vector-c))
59   :c-return :void)
60
61 (export 'sort-vector-index)
62 (defgeneric sort-vector-index (permutation vector)
63   (:documentation                       ; FDL
64    "Indirectly sort the elements of the vector v into
65    ascending order, storing the resulting permutation in p.  The
66    elements of p give the index of the vector element which would
67    have been stored in that position if the vector had been sorted in
68    place.  The first element of p gives the index of the least element
69    in v and the last element of p gives the index of the
70    greatest element in v.  The vector v is not changed."))
71
72 (defmfun-vdsf sort-vector-index (permutation (vector vector))
73   "gsl_sort_vector_index"
74   (((pointer permutation) gsl-permutation-c)
75    ((pointer vector) gsl-vector-c)))
76
77 (export 'sort-vector-smallest)
78 (defgeneric sort-vector-smallest (destination vector)
79   (:documentation                       ; FDL
80    "Find the smallest elements of the vector v and put them into dest,
81    which must be shorter than v."))
82
83 (defmfun-vdsf sort-vector-smallest (dest (v vector))
84   "gsl_sort_vector_smallest"
85   (((gsl-array dest) :pointer) ((dim0 dest) size)
86    ((pointer v) gsl-vector-c))
87   :c-return :void
88   :invalidate (dest))
89
90 (export 'sort-vector-smallest-index)
91 (defgeneric sort-vector-smallest-index (indices vector)
92   (:documentation
93    "The indices of the smallest elements of the vector stored,
94     returned as a CL vector of element type fixnum.  If
95     indices is a positive initeger, a vector will be
96     allocated and returned.  If it is a CL vector,
97     it will be filled with the indices."))
98
99 (defmfun-vdsf sort-vector-smallest-index
100     (indices (v vector))
101   "gsl_sort_vector_smallest_index"
102   ((p (size number)) (number size) ((pointer v) :pointer))
103   :type :method
104   :global ((number (if (numberp indices) indices (length indices))))
105   :c-return :void
106   :return
107   ((let* ((vector
108            (if (numberp indices)
109                (make-array (list indices) :element-type 'fixnum)
110                indices)))
111      (dotimes (i number vector)
112        (setf (aref vector i) (scref p i))))))
113
114 (export 'sort-vector-largest)
115 (defgeneric sort-vector-largest (dest vector)
116   (:documentation                       ; FDL
117   "Find the largest elements of the vector and put them into dest,
118    which must be shorter than the vector."))
119
120 (defmfun-vdsf sort-vector-largest (dest (v vector))
121   "gsl_sort_vector_largest"
122   (((gsl-array dest) :pointer) ((dim0 dest) size)
123    ((pointer v) gsl-vector-c))
124   :c-return :void
125   :invalidate (dest))
126
127 (export 'sort-vector-largest-index)
128 ;;; p should be gsl-vector-unsigned-fixnum, if that can be made to
129 ;;; work (see vector.lisp).
130 (defgeneric sort-vector-largest-index (indices vector)
131   (:documentation               
132    "The indices of the largest elements of the vector stored,
133     returned as a CL vector of element type fixnum.  If
134     indices is a positive initeger, a vector will be
135     allocated and returned.  If it is a CL vector,
136     it will be filled with the indices."))
137
138 (defmfun-vdsf sort-vector-largest-index (indices (v vector))
139   "gsl_sort_vector_largest_index"
140   ((p (size number)) (number size) ((pointer v) :pointer))
141   :type :method
142   :global ((number (if (numberp indices) indices (length indices))))
143   :c-return :void
144   :return
145   ((let* ((vector
146            (if (numberp indices)
147                (make-array (list indices) :element-type 'fixnum)
148                indices)))
149      (dotimes (i number vector)
150        (setf (aref vector i) (scref p i))))))
151
152 ;;;;****************************************************************************
153 ;;;; Examples and unit test
154 ;;;;****************************************************************************
155
156 #|
157 (make-tests sorting
158  (letm ((vec (vector-double-float #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
159    (sort-vector vec)
160    (data vec))
161  (letm ((perm (permutation 5))
162         (vec (vector-double-float #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
163    (sort-vector-index perm vec)
164    (data perm))
165  (letm ((vec (vector-double-float #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0)))
166         (smallest (vector-double-float 3)))
167    (sort-vector-smallest smallest vec)
168    (data smallest))
169  (letm ((vec (vector-double-float #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
170    (sort-vector-smallest-index 3 vec))
171  (letm ((vec (vector-double-float #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0)))
172         (largest (vector-double-float 3)))
173    (sort-vector-largest largest vec)
174    (data largest))
175  (letm ((vec (vector-double-float #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
176    (sort-vector-largest-index 3 vec)))
177 |#
178
179
180 (LISP-UNIT:DEFINE-TEST SORTING
181   (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
182    (LIST #(-3.21d0 -2.0d0 1.0d0 7.1d0 12.8d0))
183    (MULTIPLE-VALUE-LIST
184     (LETM
185         ((VEC
186           (VECTOR-DOUBLE-FLOAT
187            #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
188       (SORT-VECTOR VEC) (DATA VEC))))
189   (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
190    (LIST #(3 1 4 0 2))
191    (MULTIPLE-VALUE-LIST
192     (LETM ((PERM (PERMUTATION 5))
193            (VEC (VECTOR-DOUBLE-FLOAT #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
194       (SORT-VECTOR-INDEX PERM VEC)
195       (DATA PERM))))
196   (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
197    (LIST #(-3.21d0 -2.0d0 1.0d0))
198    (MULTIPLE-VALUE-LIST
199     (LETM ((VEC (VECTOR-DOUBLE-FLOAT #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0)))
200            (SMALLEST (VECTOR-DOUBLE-FLOAT 3)))
201       (SORT-VECTOR-SMALLEST SMALLEST VEC)
202       (DATA SMALLEST))))
203   (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
204    (LIST #(3 1 4))
205    (MULTIPLE-VALUE-LIST
206     (LETM ((VEC (VECTOR-DOUBLE-FLOAT #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
207       (SORT-VECTOR-SMALLEST-INDEX 3 VEC))))
208   (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
209    (LIST #(12.8d0 7.1d0 1.0d0))
210    (MULTIPLE-VALUE-LIST
211     (LETM ((VEC (VECTOR-DOUBLE-FLOAT #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0)))
212            (LARGEST (VECTOR-DOUBLE-FLOAT 3)))
213       (SORT-VECTOR-LARGEST LARGEST VEC) (DATA LARGEST))))
214   (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
215    (LIST #(2 0 4))
216    (MULTIPLE-VALUE-LIST
217     (LETM ((VEC (VECTOR-DOUBLE-FLOAT #(7.1d0 -2.0d0 12.8d0 -3.21d0 1.0d0))))
218       (SORT-VECTOR-LARGEST-INDEX 3 VEC)))))
Note: See TracBrowser for help on using the browser.