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 /* linalg/hh.c 00024 * 00025 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough 00026 * 00027 * This program is free software; you can redistribute it and/or modify 00028 * it under the terms of the GNU General Public License as published by 00029 * the Free Software Foundation; either version 3 of the License, or (at 00030 * your option) any later version. 00031 * 00032 * This program is distributed in the hope that it will be useful, but 00033 * WITHOUT ANY WARRANTY; without even the implied warranty of 00034 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00035 * General Public License for more details. 00036 * 00037 * You should have received a copy of the GNU General Public License 00038 * along with this program; if not, write to the Free Software 00039 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00040 * 02110-1301, USA. 00041 */ 00042 /** \file hh_base.h 00043 \brief File for householder solver 00044 */ 00045 #include <o2scl/err_hnd.h> 00046 #include <o2scl/cblas.h> 00047 #include <o2scl/permutation.h> 00048 #include <o2scl/vec_arith.h> 00049 00050 #ifdef DOXYGENP 00051 namespace o2scl_linalg { 00052 #endif 00053 00054 /** 00055 \brief Solve linear system after Householder decomposition 00056 */ 00057 template<class mat_t, class vec_t> 00058 int HH_solve(size_t n, mat_t &A, const vec_t &b, vec_t &x) { 00059 for(size_t i=0;i<n;i++) O2SCL_IX(x,i)=O2SCL_IX(b,i); 00060 return HH_svx(n,n,A,x); 00061 } 00062 00063 /** 00064 \brief Solve a linear system after Householder decomposition in place 00065 */ 00066 template<class mat_t, class vec_t> 00067 int HH_svx(size_t N, size_t M, mat_t &A, vec_t &x) { 00068 size_t i, j, k; 00069 00070 double *d=(double *)malloc(N*sizeof(double)); 00071 if (d == 0) { 00072 O2SCL_ERR_RET("Could not allocate memory for workspace for HH_svx().", 00073 o2scl::gsl_enomem); 00074 } 00075 00076 /* Perform Householder transformation. */ 00077 00078 for (i = 0; i < N; i++) { 00079 const double aii = O2SCL_IX2(A,i,i); 00080 double alpha; 00081 double f; 00082 double ak; 00083 double max_norm = 0.0; 00084 double r = 0.0; 00085 00086 for (k = i; k < M; k++) { 00087 double aki = O2SCL_IX2(A,k,i); 00088 r += aki * aki; 00089 } 00090 00091 if (r == 0.0) { 00092 /* Rank of matrix is less than size1. */ 00093 free(d); 00094 O2SCL_ERR_RET("Matrix is rank deficient in HH_svx().", 00095 o2scl::gsl_esing); 00096 } 00097 00098 alpha = sqrt (r) * GSL_SIGN (aii); 00099 00100 ak = 1.0 / (r + alpha * aii); 00101 O2SCL_IX2(A,i,i)=aii+alpha; 00102 00103 d[i] = -alpha; 00104 00105 for (k = i + 1; k < N; k++) { 00106 double norm = 0.0; 00107 f = 0.0; 00108 for (j = i; j < M; j++) { 00109 double ajk = O2SCL_IX2(A,j,k); 00110 double aji = O2SCL_IX2(A,j,i); 00111 norm += ajk * ajk; 00112 f += ajk * aji; 00113 } 00114 max_norm = GSL_MAX (max_norm, norm); 00115 00116 f *= ak; 00117 00118 for (j = i; j < M; j++) { 00119 double ajk = O2SCL_IX2(A,j,k); 00120 double aji = O2SCL_IX2(A,j,i); 00121 O2SCL_IX2(A,j,k)=ajk-f*aji; 00122 } 00123 } 00124 00125 if (fabs (alpha) < 2.0 * GSL_DBL_EPSILON * sqrt (max_norm)) { 00126 /* Apparent singularity. */ 00127 free(d); 00128 O2SCL_ERR_RET("Apparent singularity in HH_svx().",o2scl::gsl_esing); 00129 } 00130 00131 /* Perform update of RHS. */ 00132 00133 f = 0.0; 00134 for (j = i; j < M; j++) { 00135 f += O2SCL_IX(x,j)*O2SCL_IX2(A,j,i); 00136 } 00137 f *= ak; 00138 for (j = i; j < M; j++) { 00139 double xj = O2SCL_IX(x,j); 00140 double aji = O2SCL_IX2(A,j,i); 00141 O2SCL_IX(x,j)=xj - f * aji; 00142 } 00143 } 00144 00145 /* Perform back-substitution. */ 00146 00147 for (i = N; i-- > 0; ) { 00148 double xi = O2SCL_IX(x,i); 00149 double sum = 0.0; 00150 for (k = i + 1; k < N; k++) { 00151 sum += O2SCL_IX2(A,i,k)*O2SCL_IX(x,k); 00152 } 00153 00154 O2SCL_IX(x,i)=(xi - sum) / d[i]; 00155 } 00156 00157 free(d); 00158 00159 return o2scl::gsl_success; 00160 } 00161 00162 #ifdef DOXYGENP 00163 } 00164 #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