Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "vnl_cholesky.h"
00014 #include <vcl_cmath.h>
00015 #include <vcl_cassert.h>
00016 #include <vcl_iostream.h>
00017 #include <vnl/algo/vnl_netlib.h>
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 vnl_cholesky::vnl_cholesky(vnl_matrix<double> const & M, Operation mode):
00030 A_(M)
00031 {
00032 long n = M.columns();
00033 assert(n == (int)(M.rows()));
00034 num_dims_rank_def_ = -1;
00035 if (vcl_fabs(M(0,n-1) - M(n-1,0)) > 1e-8) {
00036 vcl_cerr << "vnl_cholesky: WARNING: non-symmetric: " << M << vcl_endl;
00037 }
00038
00039 if (mode != estimate_condition) {
00040
00041 v3p_netlib_dpofa_(A_.data_block(), &n, &n, &num_dims_rank_def_);
00042 if (mode == verbose && num_dims_rank_def_ != 0)
00043 vcl_cerr << "vnl_cholesky: " << num_dims_rank_def_ << " dimensions of non-posdeffness\n";
00044 }
00045 else {
00046 vnl_vector<double> nullvec(n);
00047 v3p_netlib_dpoco_(A_.data_block(), &n, &n, &rcond_, nullvec.data_block(), &num_dims_rank_def_);
00048 if (num_dims_rank_def_ != 0)
00049 vcl_cerr << "vnl_cholesky: rcond=" << rcond_ << " so " << num_dims_rank_def_ << " dimensions of non-posdeffness\n";
00050 }
00051 }
00052
00053
00054
00055
00056 void vnl_cholesky::solve(vnl_vector<double> const& b, vnl_vector<double>* x) const
00057 {
00058 assert(b.size() == A_.columns());
00059
00060 *x = b;
00061 long n = A_.columns();
00062 v3p_netlib_dposl_(A_.data_block(), &n, &n, x->data_block());
00063 }
00064
00065
00066 vnl_vector<double> vnl_cholesky::solve(vnl_vector<double> const& b) const
00067 {
00068 assert(b.size() == A_.columns());
00069
00070 long n = A_.columns();
00071 vnl_vector<double> ret = b;
00072 v3p_netlib_dposl_(A_.data_block(), &n, &n, ret.data_block());
00073 return ret;
00074 }
00075
00076
00077 double vnl_cholesky::determinant() const
00078 {
00079 long n = A_.columns();
00080 vnl_matrix<double> I = A_;
00081 double det[2];
00082 long job = 10;
00083 v3p_netlib_dpodi_(I.data_block(), &n, &n, det, &job);
00084 return det[0] * vcl_pow(10.0, det[1]);
00085 }
00086
00087
00088 vnl_matrix<double> vnl_cholesky::inverse() const
00089 {
00090 if (num_dims_rank_def_) {
00091 vcl_cerr << "vnl_cholesky: Calling inverse() on rank-deficient matrix\n";
00092 return vnl_matrix<double>();
00093 }
00094
00095 long n = A_.columns();
00096 vnl_matrix<double> I = A_;
00097 long job = 01;
00098 v3p_netlib_dpodi_(I.data_block(), &n, &n, 0, &job);
00099
00100
00101 for (int i = 0; i < n; ++i)
00102 for (int j = i+1; j < n; ++j)
00103 I(i,j) = I(j,i);
00104
00105 return I;
00106 }
00107
00108
00109 vnl_matrix<double> vnl_cholesky::lower_triangle() const
00110 {
00111 unsigned n = A_.columns();
00112 vnl_matrix<double> L(n,n);
00113
00114 for (unsigned i = 0; i < n; ++i) {
00115 L(i,i) = A_(i,i);
00116 for (unsigned j = i+1; j < n; ++j) {
00117 L(j,i) = A_(j,i);
00118 L(i,j) = 0;
00119 }
00120 }
00121 return L;
00122 }
00123
00124
00125
00126 vnl_matrix<double> vnl_cholesky::upper_triangle() const
00127 {
00128 unsigned n = A_.columns();
00129 vnl_matrix<double> U(n,n);
00130
00131 for (unsigned i = 0; i < n; ++i) {
00132 U(i,i) = A_(i,i);
00133 for (unsigned j = i+1; j < n; ++j) {
00134 U(i,j) = A_(j,i);
00135 U(j,i) = 0;
00136 }
00137 }
00138 return U;
00139 }
00140