| 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)))) |
|---|