root/trunk/eigensystems.lisp

Revision 34, 7.7 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;; Eigenvectors and eigenvalues
2;; Liam Healy, Sun May 21 2006 - 19:52
3;; Time-stamp: <2008-03-10 21:20:59EDT eigensystems.lisp>
4;; $Id$
5
6(in-package :gsl)
7
8;;;;****************************************************************************
9;;;; Real Symmetric Matrices
10;;;;****************************************************************************
11
12(defgo-s (eigen-symm n) eigen-symm-alloc eigen-symm-free)
13
14(defmfun eigen-symm-alloc (n)
15  "gsl_eigen_symm_alloc" ((n size))
16  :c-return :pointer
17  :export nil
18  :index '(letm eigen-symm)
19  :documentation                        ; FDL
20  "Allocate a workspace for computing eigenvalues of
21  n-by-n real symmetric matrices.  The size of the workspace
22  is O(2n).")
23
24(defmfun eigen-symm-free (w)
25  "gsl_eigen_symm_free" ((w :pointer))
26  :c-return :void
27  :export nil
28  :index '(letm eigen-symm)
29  :documentation                        ; FDL
30  "Free the memory associated with the workspace w.")
31
32(defgo-s (eigen-symmv n) eigen-symmv-alloc eigen-symmv-free)
33
34(defmfun eigen-symmv-alloc (n)
35  "gsl_eigen_symmv_alloc" ((n size))
36  :c-return :pointer
37  :export nil
38  :index '(letm eigen-symmv)
39  :documentation                        ; FDL
40  "Allocate a workspace for computing eigenvalues and
41  eigenvectors of n-by-n real symmetric matrices.  The size of
42  the workspace is O(4n).")
43
44(defmfun eigen-symmv-free (w)
45  "gsl_eigen_symmv_free" ((w :pointer))
46  :index '(letm eigen-symmv)
47  :c-return :void
48  :documentation                        ; FDL
49  "Free the memory associated with the workspace w.")
50
51(defmfun eigenvalues-symmetric (A eval ws)
52  "gsl_eigen_symm" ((A gsl-matrix-c) (eval gsl-vector-c) (ws :pointer))
53  :documentation                        ; FDL
54  "Eigenvalues of the real symmetric matrix
55  A.  Additional workspace of the appropriate size must be provided
56  in w.  The diagonal and lower triangular part of A are
57  destroyed during the computation, but the strict upper triangular part
58  is not referenced.  The eigenvalues are stored in the vector eval
59  and are unordered."
60  :invalidate (A eval)
61  :return (eval))
62
63(defmfun eigenvalues-eigenvectors-symmetric (A eval evec ws)
64  "gsl_eigen_symmv"
65  (((pointer A) :pointer) ((pointer eval) :pointer)
66   ((pointer evec) :pointer) (ws :pointer))
67  :documentation                        ; FDL
68  "The eigenvalues and eigenvectors of the real
69  symmetric matrix A.  Additional workspace of the appropriate size
70  must be provided in w.  The diagonal and lower triangular part of
71  A are destroyed during the computation, but the strict upper
72  triangular part is not referenced.  The eigenvalues are stored in the
73  vector eval and are unordered.  The corresponding eigenvectors are
74  stored in the columns of the matrix evec.  For example, the
75  eigenvector in the first column corresponds to the first eigenvalue.
76  The eigenvectors are guaranteed to be mutually orthogonal and normalised
77  to unit magnitude."
78  :invalidate (A eval evec)
79  :return (eval evec))
80
81;;;;****************************************************************************
82;;;; Complex Hermitian Matrices
83;;;;****************************************************************************
84
85(defgo-s (eigen-herm n) eigen-herm-alloc eigen-herm-free)
86
87(defmfun eigen-herm-alloc (n)
88  "gsl_eigen_herm_alloc" ((n size))
89  :documentation                        ; FDL
90  "Allocate a workspace for computing eigenvalues of
91  n-by-n complex hermitian matrices.  The size of the workspace
92  is O(3n)."
93  :c-return :pointer)
94
95(defmfun eigen-herm-free (w)
96  "gsl_eigen_herm_free" ((w :pointer))
97  :c-return :void
98  :documentation                        ; FDL
99  "Free the memory associated with the workspace w.")
100
101(defmfun eigenvalues-hermitian (A eval w)
102  "gsl_eigen_herm"
103  (((pointer A) gsl-matrix-c) ((pointer eval) gsl-vector-c) (w :pointer))
104  :documentation                        ; FDL
105  "Compute the eigenvalues of the complex hermitian matrix
106   A.  Additional workspace of the appropriate size must be provided
107   in w.  The diagonal and lower triangular part of A are
108   destroyed during the computation, but the strict upper triangular part
109   is not referenced.  The imaginary parts of the diagonal are assumed to be
110   zero and are not referenced. The eigenvalues are stored in the vector
111   eval and are unordered."
112  :invalidate (eval A)
113  :return (eval))
114
115(defgo-s (eigen-hermv n) eigen-hermv-alloc eigen-hermv-free)
116
117(defmfun eigen-hermv-alloc (n)
118  "gsl_eigen_hermv_alloc" ((n size))
119  :documentation                        ; FDL
120  "Allocate a workspace for computing eigenvalues and
121  eigenvectors of n-by-n complex hermitian matrices.  The size of
122  the workspace is O(5n)."
123  :c-return :pointer)
124
125(defmfun eigen-hermv-free (w)
126  "gsl_eigen_hermv_free" ((w :pointer))
127  :c-return :void
128  :documentation                        ; FDL
129  "Free the memory associated with the workspace w.")
130
131(defmfun eigenvalues-eigenvectors-hermitian (A eval evec w)
132  "gsl_eigen_hermv"
133  (((pointer A) gsl-matrix-c) ((pointer eval) gsl-vector-c)
134   ((pointer evec) gsl-matrix-c) (w :pointer))
135  :documentation                        ; FDL
136  "Compute the eigenvalues and eigenvectors of the complex
137  hermitian matrix A.  Additional workspace of the appropriate size
138  must be provided in w.  The diagonal and lower triangular part of
139  A are destroyed during the computation, but the strict upper
140  triangular part is not referenced. The imaginary parts of the diagonal
141  are assumed to be zero and are not referenced.  The eigenvalues are
142  stored in the vector eval and are unordered.  The corresponding
143  complex eigenvectors are stored in the columns of the matrix evec.
144  For example, the eigenvector in the first column corresponds to the
145  first eigenvalue.  The eigenvectors are guaranteed to be mutually
146  orthogonal and normalised to unit magnitude."
147  :invalidate (A eval evec)
148  :return (eval evec))
149
150;;;;****************************************************************************
151;;;; Sorting Eigenvalues and Eigenvectors
152;;;;****************************************************************************
153
154(cffi:defcenum eigen-sort-type
155  "gsl_eigen_sort_t from /usr/include/gsl/gsl_eigen.h."
156  :value-ascending :value-descending :absolute-ascending :absolute-descending)
157
158(export 'sort-eigenvalues-eigenvectors)
159(defgeneric sort-eigenvalues-eigenvectors (eval evec sort-type)
160  (:documentation                       ; FDL
161   "Simultaneously sort the eigenvalues stored in the vector
162  eval and the corresponding real eigenvectors stored in the columns
163  of the matrix evec into ascending or descending order according to
164  the value of the parameter sort-type: :value-ascending,
165  :value-descending, :absolute-ascending, :absolute-descending."))
166
167(defmfun sort-eigenvalues-eigenvectors
168    ((eval vector-double-float) evec sort-type)
169  "gsl_eigen_symmv_sort"
170  ((eval gsl-vector-c) (evec gsl-matrix-c) (sort-type eigen-sort-type))
171  :type :method
172  :invalidate (eval evec))
173
174(defmfun sort-eigenvalues-eigenvectors ((eval vector-complex) evec sort-type)
175  "gsl_eigen_hermv_sort"
176  ((eval gsl-vector-c) (evec gsl-matrix-c) (sort-type eigen-sort-type))
177  :type :method
178  :invalidate (eval evec))
179
180;;;;****************************************************************************
181;;;; Example
182;;;;****************************************************************************
183 
184(defun eigenvalue-eigenvectors-example ()
185  (letm ((evecs (matrix-double-float 3 3))
186         (evals (vector-double-float 3))
187         (ws (eigen-symmv 3))
188         (mat (matrix-double-float
189               #2A((20.0d0 -10.0d0 0.0d0)
190                   (-10.0d0 30.0d0 0.0d0)
191                   (0.0d0 0.0d0 40.0d0)))))
192    (eigenvalues-eigenvectors-symmetric mat evals evecs ws)
193    (values (data evals) (data evecs))))
194
195#|
196(make-tests eigensystems
197            (eigenvalue-eigenvectors-example))
198|#
199
200(LISP-UNIT:DEFINE-TEST EIGENSYSTEMS
201  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
202   (LIST
203    #(13.819660112501051d0 36.180339887498945d0 40.0d0)
204    #2A((0.8506508083520399d0 -0.5257311121191337d0 0.0d0)
205        (0.5257311121191337d0 0.8506508083520399d0 0.0d0)
206        (0.0d0 0.0d0 1.0d0)))
207   (MULTIPLE-VALUE-LIST
208    (EIGENVALUE-EIGENVECTORS-EXAMPLE))))
Note: See TracBrowser for help on using the browser.