2 ;;; Copyright (c) 2005--2007, by A.J. Rossini <blindglobe@gmail.com>
3 ;;; See COPYRIGHT file for any additional restrictions (BSD license).
4 ;;; Since 1991, ANSI was finally finished. Edited for ANSI Common Lisp.
6 ;;;; ladata -- Data handling functions for linear algebra interface
8 ;;;; Copyright (c) 1991, by Luke Tierney. Permission is granted for
15 ;;(in-package #:lisp-stat-basics)
16 ;;(in-package :cl-user)
18 (defpackage :lisp-stat-linalg-data
23 :lisp-stat-compound-data
25 (:export
;; more to add
26 +mode-in
+ +mode-re
+ +mode-cx
+ mode-of
28 la-data-mode la-allocate la-free
30 la-get-double la-put-double
33 la-matrix la-free-matrix la-matrix-to-data la-data-to-matrix
34 la-vector la-free-vector la-vector-to-data la-data-to-vector
))
37 (in-package :lisp-stat-linalg-data
)
40 (defctype size-t
:unsigned-long
)
42 (defctype size-t
:unsigned-int
)
44 ;; Should we do the same with int's and long's? There is some
45 ;; evidence that it might be useful?
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
50 ;;; Data Mode Functions
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55 ;;;; These constants need to be redefined if IN, RE or CX in linalg.h
59 ;;; FIXME:AJR: This is how Luke got around having appropriate
60 ;;; approaches for Linear Algebra. We want to cheat and instead use
61 ;;; CLEM or MATLISP as the underlying linear algebra package.
63 (defparameter +mode-in
+ 0)
64 (defparameter +mode-re
+ 1)
65 (defparameter +mode-cx
+ 2)
74 (defun la-data-mode (data)
75 (let ((data (compound-data-seq data
))
79 (let ((n (length data
)))
83 (setf mode
(max mode
(mode-of (aref data i
)))))))
84 ((consp data
) (dolist (x data mode
) (setf mode
(max mode
(mode-of x
)))))
85 (t (error "bad sequence - ~s" data
)))))
88 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
90 ;;;; Internal Allocation Funcitons
92 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
94 (defvar *la-allocations
* nil
)
97 ;;; CFFI glue for... Storage Allocation Functions
100 (defun null-ptr-p (p) (cffi:null-pointer-p p
))
101 (defun ptr-eq (p q
) (cffi:pointer-eq p q
))
103 (cffi:defcfun
("la_base_allocate" ccl-la-base-allocate
)
104 :pointer
(n size-t
) (m size-t
))
105 (defun la-base-allocate (n m
)
106 (ccl-la-base-allocate n m
))
108 (cffi:defcfun
("la_base_free_alloc" ccl-la-base-free-alloc
)
110 (defun la-base-free (p)
111 (ccl-la-base-free-alloc p
))
113 (cffi:defcfun
("la_mode_size" ccl-la-mode-size
)
116 (defun la-mode-size (mode)
117 (ccl-la-mode-size mode
))
120 ;;; Callbacks for Internal Storage
123 (cffi:defcallback lisp-la-allocate
:void
((n size-t
) (m size-t
))
124 (ccl-store-ptr (la-allocate n m
)))
125 (cffi:defcfun
("register_la_allocate" register-la-allocate
)
127 (register-la-allocate (cffi:callback lisp-la-allocate
))
128 (cffi:defcfun
("la_allocate" la
)
129 :pointer
(x size-t
) (y size-t
))
131 (cffi:defcallback lisp-la-free-alloc
135 (cffi:defcfun
("register_la_free_alloc" register-la-free-alloc
)
137 (register-la-free-alloc (cffi:callback lisp-la-free-alloc
))
138 (cffi:defcfun
("la_free_alloc" lf
)
143 ;;; CFFI glue for... Storage Access Functions
146 (cffi:defcfun
("la_get_integer" ccl-la-get-integer
)
147 :long
(p :pointer
) (i size-t
)) ;; was int, not long, for first
148 (defun la-get-integer (p i
)
149 (ccl-la-get-integer p i
))
151 (cffi:defcfun
("la_get_double" ccl-la-get-double
)
152 :double
(p :pointer
) (i size-t
))
153 (defun la-get-double (p i
)
154 (ccl-la-get-double p i
))
156 (cffi:defcfun
("la_get_complex_real" ccl-la-get-complex-real
)
157 :double
(p :pointer
) (i size-t
))
158 (defun la-get-complex-real (p i
)
159 (ccl-la-get-complex-real p i
))
161 (cffi:defcfun
("la_get_complex_imag" ccl-la-get-complex-imag
)
162 :double
(p :pointer
) (i size-t
))
163 (defun la-get-complex-imag (p i
)
164 (ccl-la-get-complex-imag p i
))
166 (defun la-get-complex (p i
)
167 (complex (la-get-complex-real p i
) (la-get-complex-imag p i
)))
169 (cffi:defcfun
("la_get_pointer" ccl-la-get-pointer
)
170 :pointer
(p :pointer
) (i size-t
))
171 (defun la-get-pointer (p i
)
172 (ccl-la-get-pointer p i
))
175 ;;; CFFI glue for Storage Mutation Functions
177 (cffi:defcfun
("la_put_integer" ccl-la-put-integer
)
178 :void
(p :pointer
) (i size-t
) (x :long
)) ;; last was :int ?
179 (defun la-put-integer (p i x
)
180 (ccl-la-put-integer p i x
))
182 (cffi:defcfun
("la_put_double" ccl-la-put-double
)
183 :void
(p :pointer
) (i size-t
) (x :double
))
184 (defun la-put-double (p i x
)
185 (ccl-la-put-double p i
(float x
1d0
)))
187 (cffi:defcfun
("la_put_complex" ccl-la-put-complex
)
188 :void
(p :pointer
) (i size-t
) (x :double
) (y :double
))
189 (defun la-put-complex (p i x y
)
190 (ccl-la-put-complex p i
(float x
1d0
) (float y
1d0
)))
192 (cffi:defcfun
("la_put_pointer" ccl-la-put-pointer
)
193 :void
(p :pointer
) (i size-t
) (q :pointer
))
194 (defun la-put-pointer (p i q
)
195 (ccl-la-put-pointer p i q
))
198 ;; User interface (exported)
200 (defun la-allocate (n m
)
201 (let ((p (la-base-allocate n m
)))
202 (if (null-ptr-p p
) (error "allocation failed"))
203 (if (member p
*la-allocations
* :test
#'ptr-eq
)
204 (error "pointer is already on the list"))
205 (push p
*la-allocations
*)
209 (when (and (not (null-ptr-p p
)) (member p
*la-allocations
* :test
#'ptr-eq
))
210 (setf *la-allocations
* (delete p
*la-allocations
* :test
#'ptr-eq
))
213 (defun la-cleanup-allocations ()
214 (let ((allocs (copy-list *la-allocations
*)))
215 (dolist (p allocs
) (la-free p
))))
217 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
219 ;;;; C Vector and Array Allocation
221 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
223 (defun la-vector(n mode
) (la-allocate n
(la-mode-size mode
)))
224 (defun la-free-vector (v) (la-free v
))
226 (defun la-matrix (n m mode
)
227 (let ((matrix (la-allocate n
(la-mode-size +mode-in
+))))
229 (la-put-pointer matrix i
(la-allocate m
(la-mode-size mode
))))
232 (defun la-free-matrix (matrix n
)
234 (la-free (la-get-pointer matrix i
)))
238 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240 ;;;; C to/from Lisp Data Conversion
242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
244 (defun la-data-to-vector (data mode
)
245 (check-sequence data
)
246 (let* ((n (length data
))
247 (vec (la-vector n mode
))
248 (d (make-next-element data
)))
254 (la-put-integer vec i
(get-next-element d i
))))
258 (la-put-double vec i
(get-next-element d i
))))
262 (let ((x (get-next-element d i
)))
263 (la-put-complex vec i
(realpart x
) (imagpart x
))))))
266 (defun la-data-to-matrix (data mode
)
268 (let* ((n (num-rows data
))
270 (mat (la-matrix n m mode
)))
271 (declare (fixnum n m
))
276 (let ((vec (la-get-pointer mat i
)))
278 (la-put-integer vec j
(aref data i j
))))))
282 (let ((vec (la-get-pointer mat i
)))
284 (la-put-double vec j
(aref data i j
))))))
288 (let ((vec (la-get-pointer mat i
)))
290 (let ((x (aref data i j
)))
291 (la-put-complex vec i
(realpart x
) (imagpart x
))))))))
294 (defun la-vector-to-data (vec n mode data
)
296 (check-sequence data
)
297 (let ((d (make-next-element data
))
299 ((= mode
+mode-in
+) #'la-get-integer
)
300 ((= mode
+mode-re
+) #'la-get-double
)
301 ((= mode
+mode-cx
+) #'la-get-complex
))))
304 (set-next-element d i
(funcall gf vec i
))))
307 (defun la-matrix-to-data (mat n m mode result
)
308 (declare (fixnum n m
))
309 (check-matrix result
)
311 ((= mode
+mode-in
+) #'la-get-integer
)
312 ((= mode
+mode-re
+) #'la-get-double
)
313 ((= mode
+mode-cx
+) #'la-get-complex
))))
316 (let ((vec (la-get-pointer mat i
)))
319 (setf (aref result i j
) (funcall gf vec j
))))))