00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_LINEAR_SOLVER_H 00024 #define O2SCL_LINEAR_SOLVER_H 00025 00026 #include <gsl/gsl_linalg.h> 00027 00028 #include <o2scl/ovector_tlate.h> 00029 #include <o2scl/omatrix_tlate.h> 00030 #include <o2scl/permutation.h> 00031 #include <o2scl/lu.h> 00032 #include <o2scl/qr.h> 00033 #include <o2scl/hh.h> 00034 #include <o2scl/array.h> 00035 00036 namespace o2scl_linalg { 00037 00038 /** 00039 \brief A generic solver for the linear system \f$ A x = b \f$ 00040 [abstract base] 00041 00042 A generic solver for dense linear systems. 00043 00044 Those writing production level code should consider calling 00045 LAPACK directly using \o2 objects as described in the \ref 00046 linalg_section section of the User's Guide. 00047 00048 \future The test code uses a Hilbert matrix, which is known 00049 to be ill-conditioned, especially for the larger sizes. This 00050 should probably be changed. 00051 */ 00052 template<class vec_t=o2scl::ovector_base, class mat_t=o2scl::omatrix_base> 00053 class linear_solver { 00054 public: 00055 00056 virtual ~linear_solver() {} 00057 00058 /// Solve square linear system \f$ A x = b \f$ of size \c n 00059 virtual int solve(size_t n, mat_t &a, vec_t &b, vec_t &x)=0; 00060 }; 00061 00062 /// Generic linear solver using LU decomposition 00063 template <class vec_t=o2scl::ovector_base, class mat_t=o2scl::omatrix_base> 00064 class linear_solver_lu : 00065 public linear_solver<vec_t, mat_t> { 00066 00067 public: 00068 00069 /// Solve square linear system \f$ A x = b \f$ of size \c n 00070 virtual int solve(size_t n, mat_t &A, 00071 vec_t &b, vec_t &x) { 00072 int sig; 00073 o2scl::permutation p(n); 00074 LU_decomp(n,A,p,sig); 00075 LU_solve(n,A,p,b,x); 00076 return 0; 00077 }; 00078 00079 virtual ~linear_solver_lu() {} 00080 00081 }; 00082 00083 /// Generic linear solver using QR decomposition 00084 template <class vec_t=o2scl::ovector_base, class mat_t=o2scl::omatrix_base> 00085 class linear_solver_qr : 00086 public linear_solver<vec_t, mat_t> { 00087 00088 public: 00089 00090 /// Solve square linear system \f$ A x = b \f$ of size \c n 00091 virtual int solve(size_t n, mat_t &A, 00092 vec_t &b, vec_t &x) { 00093 double *tau=o2scl::new_array<double>(n); 00094 QR_decomp(n,n,A,tau); 00095 QR_solve(n,A,tau,b,x); 00096 o2scl::delete_array(tau); 00097 return 0; 00098 }; 00099 00100 virtual ~linear_solver_qr() {} 00101 00102 }; 00103 00104 /// Generic Householder linear solver 00105 template <class vec_t=o2scl::ovector_base, class mat_t=o2scl::omatrix_base> 00106 class linear_solver_hh : 00107 public linear_solver<vec_t, mat_t> { 00108 00109 public: 00110 00111 /// Solve square linear system \f$ A x = b \f$ of size \c n 00112 virtual int solve(size_t n, mat_t &A, 00113 vec_t &b, vec_t &x) { 00114 return HH_solve(n,A,b,x); 00115 }; 00116 00117 virtual ~linear_solver_hh() {} 00118 00119 }; 00120 00121 /// GSL solver by LU decomposition 00122 #ifdef DOXYGENP 00123 class gsl_solver_LU : public linear_solver 00124 #else 00125 class gsl_solver_LU : public linear_solver<o2scl::ovector_base, 00126 o2scl::omatrix_base> 00127 #endif 00128 { 00129 00130 public: 00131 00132 /// Solve square linear system \f$ A x = b \f$ of size \c n 00133 virtual int solve(size_t n, o2scl::omatrix_base &A, 00134 o2scl::ovector_base &b, 00135 o2scl::ovector_base &x) { 00136 gsl_permutation *P=gsl_permutation_alloc(n); 00137 int s; 00138 gsl_linalg_LU_decomp((gsl_matrix *)&A,P,&s); 00139 gsl_linalg_LU_solve((gsl_matrix *)&A,P,(gsl_vector *)&b, 00140 (gsl_vector *)&x); 00141 gsl_permutation_free(P); 00142 00143 return 0; 00144 }; 00145 00146 virtual ~gsl_solver_LU() {} 00147 00148 }; 00149 00150 /// GSL solver by QR decomposition 00151 #ifdef DOXYGENP 00152 class gsl_solver_QR : public linear_solver 00153 #else 00154 class gsl_solver_QR : public linear_solver<o2scl::ovector_base, 00155 o2scl::omatrix_base> 00156 #endif 00157 { 00158 00159 public: 00160 00161 /// Solve square linear system \f$ A x = b \f$ of size \c n 00162 virtual int solve(size_t n, o2scl::omatrix_base &A, 00163 o2scl::ovector_base &b, 00164 o2scl::ovector_base &x) { 00165 o2scl::ovector tau(n); 00166 gsl_linalg_QR_decomp((gsl_matrix *)&A,(gsl_vector *)&tau); 00167 gsl_linalg_QR_solve((gsl_matrix *)&A,(gsl_vector *)&tau, 00168 (gsl_vector *)&b,(gsl_vector *)&x); 00169 return 0; 00170 }; 00171 00172 virtual ~gsl_solver_QR() {} 00173 00174 }; 00175 00176 /// GSL Householder solver 00177 #ifdef DOXYGENP 00178 class gsl_solver_HH : public linear_solver 00179 #else 00180 class gsl_solver_HH : public linear_solver<o2scl::ovector_base, 00181 o2scl::omatrix_base> 00182 #endif 00183 { 00184 00185 public: 00186 00187 /// Solve square linear system \f$ A x = b \f$ of size \c n 00188 virtual int solve(size_t n, o2scl::omatrix_base &A, 00189 o2scl::ovector_base &b, 00190 o2scl::ovector_base &x) { 00191 return gsl_linalg_HH_solve((gsl_matrix *)(&A),(gsl_vector *)(&b), 00192 (gsl_vector *)(&x)); 00193 }; 00194 00195 virtual ~gsl_solver_HH() {} 00196 00197 }; 00198 00199 } 00200 00201 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page