00001
00009 #ifndef __LINALG_H__
00010 #define __LINALG_H__
00011
00012 #include <gsl/gsl_matrix.h>
00013 #include <gsl/gsl_vector.h>
00014 #include <gsl/gsl_permutation.h>
00015 #include "error.hpp"
00016
00018 namespace linalg{
00019 using namespace error_handling;
00020
00021 class slice;
00022 class vector;
00023 class vector_view;
00024
00026 class matrix{
00027 private:
00028 class LUmatrix;
00029
00030 public:
00031
00032
00034 matrix();
00040 matrix(const size_t m, const size_t n, const double fillvalue = 0) ;
00042 matrix(gsl_matrix *M);
00043
00045 matrix(const matrix& M);
00047 matrix operator=(const matrix& M);
00048
00049
00050
00052 ~matrix();
00053
00055 size_t precision() const;
00057 static void set_precision(size_t p);
00058
00060 size_t rows() const;
00062 size_t cols() const;
00063
00070 double& operator()(const size_t i, const size_t j);
00071
00073 const double& operator()(const size_t i, const size_t j) const;
00074
00082 vector_view operator()(const size_t i, const slice &b);
00084 const vector_view operator()(const size_t i, const slice &b) const;
00085
00093 vector_view operator()(const slice &a, const size_t j);
00095 const vector_view operator()(const slice &a, const size_t j) const;
00096
00097
00099 matrix operator*(const double a) const;
00101 matrix operator+(const matrix& N) const;
00103 matrix operator*(const matrix& N) const;
00105 matrix operator-(const matrix& N) const;
00107 vector operator*(const vector& v) const;
00108
00109
00110
00111
00119 matrix inv() const;
00125 matrix T() const;
00130 double tr() const;
00135 double det() const;
00136
00144 vector inv(const vector& w) const;
00145
00154 double cond() const;
00155
00156 friend class vector_view;
00157 private:
00166 LUmatrix* LU() const;
00167
00168 gsl_matrix * A;
00169
00171 static size_t precsn;
00173 static const double eps;
00174
00175
00176
00177 mutable LUmatrix* LUptr;
00178 mutable bool LUfactored;
00179
00180 mutable double condition_number;
00181 mutable gsl_vector* SVD;
00182 mutable bool SVDfactored;
00183
00184 void SVDfactor() const;
00185
00187 class LUmatrix{
00188 public:
00189 gsl_matrix* matrix_ptr();
00190 gsl_permutation* perm_ptr();
00191 int sgn();
00192 int* sgn_ptr();
00193
00194 LUmatrix(gsl_matrix* M);
00195 LUmatrix(const LUmatrix& LU);
00196 LUmatrix operator=(const LUmatrix& LU);
00197 ~LUmatrix();
00198 private:
00199
00200 gsl_permutation* p;
00201 gsl_matrix* A;
00202 int signum;
00203 LUmatrix();
00204 };
00205 };
00206
00208 class vector{
00209 public:
00210
00211
00213 vector();
00218 vector(const size_t n, const double fillvalue = 0);
00220 vector(gsl_vector *y);
00222 vector(const gsl_vector *y);
00223
00225 vector(const vector& y);
00227 vector& operator=(const vector &y);
00228
00229
00231 ~vector();
00232
00233
00235 size_t precision() const;
00237 static void set_precision(size_t p);
00238
00240 size_t size() const;
00241
00247 double& operator()(const size_t i);
00248
00250 const double& operator()(const size_t i) const;
00251
00258 vector_view operator()(const slice &v);
00260 const vector_view operator()(const slice &v) const;
00261
00262
00264 vector operator*(const double a) const;
00266 vector operator+(const vector& w) const;
00268 vector operator-(const vector& w) const;
00270 double operator*(const vector& w) const;
00272 vector operator*(const matrix& M) const;
00273
00274
00275
00277 bool operator==(const vector& w) const;
00284 bool operator<(const vector& w) const;
00285
00286
00288 double norm() const;
00289
00290 friend class vector_view;
00291 friend class matrix;
00292 private:
00294 gsl_vector * x;
00296 static size_t precsn;
00298 static const double eps;
00299 };
00300
00301
00305 class vector_view : public vector{
00306 friend class vector;
00307 friend class matrix;
00308 public:
00309 ~vector_view();
00312 vector_view& operator=(const vector& w);
00314 vector_view& operator=(const vector_view& w);
00315 private:
00318 vector_view();
00320 vector_view(gsl_vector* y, const slice& s);
00322 vector_view(gsl_matrix* A, const slice& a, const size_t j);
00324 vector_view(gsl_matrix* A, const size_t i, const slice& b);
00325 };
00326
00327
00343 class slice{
00344 public:
00351 slice(size_t a, size_t b, size_t k=1);
00352
00360 slice operator()(size_t a, size_t b, size_t k=1);
00361 slice set(size_t a, size_t b, size_t k=1) ;
00362
00363 size_t begin()const {return beg;};
00364 size_t end() const{return fin;};
00365 size_t stride() const{return str;};
00366
00367 private:
00369 slice(){};
00370 size_t beg,fin;
00371 size_t str;
00372 };
00373
00375 typedef vector point;
00376 }
00377
00378 namespace linalg{
00379
00380
00381
00383 std::ostream& operator<<(std::ostream& os, const vector &v);
00385 vector operator>>(std::istream& is, vector& v);
00387 std::ostream& operator<<(std::ostream& os, const matrix &M);
00389 matrix operator>>(std::istream& is, matrix& v);
00390
00391
00392
00394 vector operator*(double a, const vector& v);
00396 double norm(const vector& v);
00398 matrix operator*(double a, const matrix& M);
00400 matrix inv(const matrix& A);
00402 matrix T(const matrix& A);
00404 double tr(const matrix& A);
00406 double det(matrix& A);
00408 double cond(matrix& A);
00409
00410 }
00411
00412
00413 namespace linalg{
00414 inline double& matrix::operator()(const size_t i, const size_t j){
00415 try{
00416 if(LUfactored)
00417 delete LUptr;
00418 if(SVDfactored)
00419 gsl_vector_free(SVD);
00420
00421 LUfactored = false;
00422 SVDfactored = false;
00423 return(*gsl_matrix_ptr(A,i-1,j-1));
00424 }
00425 catch(indexOutOfRange& exc){
00426 exc.i = i;
00427 exc.j = j;
00428 exc.m = A -> size1;
00429 exc.n = A -> size2;
00430 throw exc;
00431 }
00432 }
00433 inline const double& matrix::operator()(const size_t i,
00434 const size_t j) const{
00435 try{
00436 return(*gsl_matrix_const_ptr(A,i-1,j-1));
00437 }
00438 catch(indexOutOfRange& exc){
00439 exc.i = i;
00440 exc.j = j;
00441 exc.m = A -> size1;
00442 exc.n = A -> size2;
00443 throw exc;
00444 }
00445 }
00446
00447 inline double& vector::operator()(const size_t i) {
00448 try{
00449 return *gsl_vector_ptr(x,i-1);
00450 }
00451 catch(indexOutOfRange& exc){
00452 exc.i = i;
00453 exc.n = x -> size;
00454 throw exc;
00455 }
00456 }
00457
00458 inline const double& vector::operator()(const size_t i) const {
00459 try{
00460 return *gsl_vector_const_ptr(x,i-1);
00461 }
00462 catch(indexOutOfRange& exc){
00463 exc.i = i;
00464 exc.n = x -> size;
00465 throw exc;
00466 }
00467 }
00468 }
00469 #endif //__LINALG_H__