00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007 #include "vnl_sparse_lu.h"
00008 #include <vcl_cassert.h>
00009 #include <vcl_iostream.h>
00010
00011 #include <sparse/spMatrix.h>
00012
00013
00014
00015 vnl_sparse_lu::~vnl_sparse_lu()
00016 {
00017 spDestroy( pmatrix_ );
00018 }
00019
00020
00021 vnl_sparse_lu::vnl_sparse_lu(vnl_sparse_matrix<double> const & M, operation mode):
00022 A_(M), factored_(false),condition_computed_(false), mode_(mode),norm_(0), rcond_(0), largest_(0), pivot_thresh_(0),absolute_thresh_(0),diag_pivoting_(1),pmatrix_(0)
00023 {
00024 int n = (int)M.columns();
00025 assert(n == (int)(M.rows()));
00026 int error = 0;
00027 pmatrix_ = spCreate(n, 0, &error);
00028 if (error!=spOKAY)
00029 {
00030 vcl_cout << "In vnl_sparse_lu::vnl_sparse_lu - error in creating matrix\n";
00031 return;
00032 }
00033
00034 spElement* pelement = 0;
00035 for (A_.reset(); A_.next();)
00036 {
00037 int r = A_.getrow();
00038 int c = A_.getcolumn();
00039 double v = A_.value();
00040 pelement = spGetElement(pmatrix_, r+1, c+1);
00041 if (pelement == 0)
00042 {
00043 vcl_cout<< "In vnl_sparse_lu::vnl_sparse_lu - error in getting element\n";
00044 return;
00045 }
00046 *pelement = v;
00047 }
00048 if (mode==estimate_condition || mode_==estimate_condition_verbose)
00049 {
00050 largest_ = spLargestElement(pmatrix_);
00051 if (mode_==estimate_condition_verbose)
00052 vcl_cout << " Largest element in matrix = " << largest_ << '\n';
00053 norm_ = spNorm(pmatrix_);
00054 }
00055 }
00056
00057
00058 bool vnl_sparse_lu::est_condition()
00059 {
00060 int error = spOKAY;
00061 rcond_ = spCondition(pmatrix_, norm_, &error);
00062 if (error!=spOKAY)
00063 {
00064 vcl_cout << "In vnl_sparse_lu::est_condition(..) - error in condition number calculation\n";
00065 return false;
00066 }
00067 condition_computed_ = true;
00068 return true;
00069 }
00070
00071
00072 void vnl_sparse_lu::solve(vnl_vector<double> const& b, vnl_vector<double>* x)
00073 {
00074 if (!pmatrix_)
00075 {
00076 vcl_cout << "In vnl_sparse_lu::solve(..) - matrix not defined\n";
00077 return;
00078 }
00079 unsigned n = b.size();
00080 assert(n == A_.columns());
00081 spREAL* rhs = new spREAL[n+1];
00082 for (unsigned i = 0; i<n; ++i)
00083 rhs[i+1]=b[i];
00084 if (mode_==verbose || mode_==estimate_condition_verbose)
00085 {
00086 vcl_cout << "Matrix before ordering\n";
00087 spPrint(pmatrix_,1,1,1);
00088 }
00089
00090 int error = 0;
00091
00092
00093 if (!factored_)
00094 {
00095 error = spOrderAndFactor(pmatrix_, rhs, pivot_thresh_,
00096 absolute_thresh_, diag_pivoting_);
00097 if (error != spOKAY)
00098 {
00099 vcl_cout << "In vnl_sparse_lu::solve(..) - error in factoring\n";
00100 return;
00101 }
00102 if (mode_==estimate_condition || mode_==estimate_condition_verbose)
00103 if (!est_condition())
00104 return;
00105 factored_ = true;
00106 }
00107
00108 if (mode_==verbose || mode_==estimate_condition_verbose)
00109 {
00110 vcl_cout << "Matrix after ordering\n";
00111 spPrint(pmatrix_,1,1,1);
00112 }
00113
00114 spSolve(pmatrix_, rhs, rhs);
00115
00116 for (unsigned i = 0; i<n; ++i)
00117 (*x)[i]=rhs[i+1];
00118
00119 delete [] rhs;
00120 }
00121
00122
00123 vnl_vector<double> vnl_sparse_lu::solve(vnl_vector<double> const& b)
00124 {
00125 vnl_vector<double> ret(b.size());
00126 this->solve(b, &ret);
00127 return ret;
00128 }
00129
00130
00131 void vnl_sparse_lu::solve_transpose(vnl_vector<double> const& b, vnl_vector<double>* x)
00132 {
00133 if (!pmatrix_)
00134 {
00135 vcl_cout << "In vnl_sparse_lu::solve(..) - matrix not defined\n";
00136 return;
00137 }
00138 unsigned n = b.size();
00139 assert(n == A_.columns());
00140 spREAL* rhs = new spREAL[n+1];
00141 for (unsigned i = 0; i<n; ++i)
00142 rhs[i+1]=b[i];
00143 int error = 0;
00144 if (mode_== verbose || mode_== estimate_condition_verbose)
00145 {
00146 vcl_cout << "Matrix before ordering\n";
00147 spPrint(pmatrix_,1,1,1);
00148 }
00149
00150
00151
00152 if (!factored_)
00153 {
00154 error = spOrderAndFactor(pmatrix_, rhs, pivot_thresh_,
00155 absolute_thresh_, diag_pivoting_);
00156 if (error != spOKAY)
00157 {
00158 vcl_cout << "In vnl_sparse_lu::solve(..) - error in factoring\n";
00159 return;
00160 }
00161 if (mode_==estimate_condition || mode_==estimate_condition_verbose)
00162 if (!est_condition())
00163 return;
00164 factored_ = true;
00165 }
00166
00167 if (mode_==verbose || mode_== estimate_condition_verbose)
00168 {
00169 vcl_cout << "Matrix after ordering\n";
00170 spPrint(pmatrix_,1,1,1);
00171 }
00172
00173 spSolveTransposed(pmatrix_, rhs, rhs);
00174
00175 for (unsigned i = 0; i<n; ++i)
00176 (*x)[i]=rhs[i+1];
00177
00178 delete [] rhs;
00179 }
00180
00181
00182 vnl_vector<double> vnl_sparse_lu::solve_transpose(vnl_vector<double> const& b)
00183 {
00184 vnl_vector<double> ret(b.size());
00185 this->solve_transpose(b, &ret);
00186 return ret;
00187 }
00188
00189
00190
00191
00192 #if 0
00193
00194 vnl_sparse_matrix<double> vnl_sparse_lu::lu_matrix()
00195 {
00196 unsigned n = A_.rows();
00197 vnl_sparse_matrix<double> temp(n, n);
00198 int error = 0;
00199 spElement* pelement = 0;
00200 if (!factored_)
00201 {
00202 error = spFactor(pmatrix_);
00203 if (error != spOKAY)
00204 {
00205 vcl_cout << "In vnl_sparse_lu::lu_matrix() - factoring failed\n";
00206 return temp;
00207 }
00208 factored_=true;
00209 }
00210
00211 int* row_map = new int[n+1];
00212 int* col_map = new int[n+1];
00213 spRowColOrder(pmatrix_, row_map, col_map);
00214
00215
00216 int* inv_row_map = new int[n+1];
00217 int* inv_col_map = new int[n+1];
00218 for (unsigned i = 1; i<=n; ++i)
00219 {
00220 inv_row_map[row_map[i]]=i;
00221 inv_col_map[col_map[i]]=i;
00222 }
00223
00224 if (mode_==verbose || mode_==estimate_condition_verbose)
00225 for (unsigned i = 1; i<=n; ++i)
00226 vcl_cout << "inv_row_map[" << i << "]= " << inv_row_map[i]
00227 << " inv_col_map[" << i << "]= " << inv_col_map[i] << '\n';
00228 for (unsigned r = 0; r<n; r++)
00229 for (unsigned c = 0; c<n; c++)
00230 {
00231 pelement = spGetElement(pmatrix_, inv_row_map[r+1], inv_col_map[c+1]);
00232 if (pelement)
00233 {
00234 double v = *pelement;
00235 temp(r,c)= v;
00236 }
00237 }
00238 delete [] row_map;
00239 delete [] col_map;
00240 return temp;
00241 }
00242 #endif
00243
00244
00245 double vnl_sparse_lu::determinant()
00246 {
00247 int exponent;
00248 double determ;
00249 if (!factored_)
00250 {
00251 spFactor(pmatrix_);
00252 if (mode_==estimate_condition || mode_==estimate_condition_verbose)
00253 if (!est_condition())
00254 return 0;
00255 factored_ = true;
00256 }
00257 spDeterminant(pmatrix_, &exponent, &determ);
00258 if (exponent<0)
00259 {
00260 while (exponent<0)
00261 {
00262 determ *= 0.1;
00263 exponent++;
00264 }
00265 return determ;
00266 }
00267 else if (exponent>0)
00268 while (exponent>0)
00269 {
00270 determ *= 10.0;
00271 exponent--;
00272 }
00273
00274 return determ;
00275 }
00276
00277
00278 double vnl_sparse_lu::rcond()
00279 {
00280 if (!factored_)
00281 {
00282 spFactor(pmatrix_);
00283 if (mode_==estimate_condition || mode_==estimate_condition_verbose)
00284 if (!est_condition())
00285 return 0;
00286 factored_ = true;
00287 }
00288 return rcond_;
00289 }
00290
00291
00292 double vnl_sparse_lu::max_error_bound()
00293 {
00294 if (mode_!=estimate_condition && mode_ != estimate_condition_verbose)
00295 return 0;
00296
00297 if (!factored_)
00298 {
00299 spFactor(pmatrix_);
00300 if (!est_condition())
00301 return 0;
00302 factored_ = true;
00303 }
00304 double roundoff = spRoundoff(pmatrix_, largest_);
00305 if (rcond_>0)
00306 return roundoff/rcond_;
00307 return 0;
00308 }