00001
00002 #ifndef vnl_diag_matrix_h_
00003 #define vnl_diag_matrix_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <vcl_cassert.h>
00022 #include <vcl_iosfwd.h>
00023 #include <vnl/vnl_vector.h>
00024 #include <vnl/vnl_matrix.h>
00025
00026
00027 template <class T> class vnl_diag_matrix;
00028 template <class T> vnl_vector<T> operator*(vnl_diag_matrix<T> const&, vnl_vector<T> const&);
00029
00030
00031
00032
00033
00034
00035
00036 export
00037 template <class T>
00038 class vnl_diag_matrix
00039 {
00040 vnl_vector<T> diagonal_;
00041
00042 public:
00043 vnl_diag_matrix() {}
00044
00045
00046 vnl_diag_matrix(unsigned nn) : diagonal_(nn) {}
00047
00048
00049 vnl_diag_matrix(unsigned nn, T const& value) : diagonal_(nn, value) {}
00050
00051
00052
00053 vnl_diag_matrix(vnl_vector<T> const& that): diagonal_(that) {}
00054 ~vnl_diag_matrix() {}
00055
00056 inline vnl_diag_matrix& operator=(vnl_diag_matrix<T> const& that) {
00057 this->diagonal_ = that.diagonal_;
00058 return *this;
00059 }
00060
00061
00062
00063
00064 inline vnl_diag_matrix<T>& operator*=(T v) { diagonal_ *= v; return *this; }
00065
00066 inline vnl_diag_matrix<T>& operator/=(T v) { diagonal_ /= v; return *this; }
00067
00068
00069
00070 void invert_in_place();
00071 T determinant() const;
00072 vnl_vector<T> solve(vnl_vector<T> const& b) const;
00073 void solve(vnl_vector<T> const& b, vnl_vector<T>* out) const;
00074
00075
00076
00077 inline T operator () (unsigned i, unsigned j) const {
00078 return (i != j) ? T(0) : diagonal_[i];
00079 }
00080
00081 inline T& operator () (unsigned i, unsigned j) {
00082 assert(i == j);
00083 return diagonal_[i];
00084 }
00085 inline T& operator() (unsigned i) { return diagonal_[i]; }
00086 inline T const& operator() (unsigned i) const { return diagonal_[i]; }
00087
00088 inline T& operator[] (unsigned i) { return diagonal_[i]; }
00089 inline T const& operator[] (unsigned i) const { return diagonal_[i]; }
00090
00091
00092 inline void put (unsigned r, unsigned c, T const& v) {
00093 assert(r == c); assert (r<size()); diagonal_[r] = v;
00094 }
00095
00096
00097 inline T get (unsigned r, unsigned c) const {
00098 assert(r == c); assert (r<size()); return diagonal_[r];
00099 }
00100
00101
00102 inline void fill_diagonal (T const& v) { diagonal_.fill(v); }
00103
00104
00105
00106 typedef typename vnl_vector<T>::iterator iterator;
00107 inline iterator begin() { return diagonal_.begin(); }
00108 inline iterator end() { return diagonal_.end(); }
00109 typedef typename vnl_vector<T>::const_iterator const_iterator;
00110 inline const_iterator begin() const { return diagonal_.begin(); }
00111 inline const_iterator end() const { return diagonal_.end(); }
00112
00113 inline unsigned size() const { return diagonal_.size(); }
00114 inline unsigned rows() const { return diagonal_.size(); }
00115 inline unsigned cols() const { return diagonal_.size(); }
00116 inline unsigned columns() const { return diagonal_.size(); }
00117
00118
00119 inline vnl_matrix<T> asMatrix() const;
00120
00121 inline vnl_matrix<T> as_ref() const { return asMatrix(); }
00122
00123
00124 inline operator vnl_matrix<T> () const { return asMatrix(); }
00125
00126 inline void set_size(int n) { diagonal_.set_size(n); }
00127
00128 inline void clear() { diagonal_.clear(); }
00129 inline void fill(T const &x) { diagonal_.fill(x); }
00130
00131
00132 inline T* data_block() { return diagonal_.data_block(); }
00133 inline T const* data_block() const { return diagonal_.data_block(); }
00134
00135
00136 inline vnl_vector<T> const& diagonal() const { return diagonal_; }
00137
00138
00139 inline void set(vnl_vector<T> const& v) { diagonal_=v; }
00140
00141 private:
00142 #if VCL_NEED_FRIEND_FOR_TEMPLATE_OVERLOAD
00143 friend vnl_vector<T> operator*(vnl_diag_matrix<T> const&,vnl_vector<T> const&);
00144 #endif
00145 };
00146
00147
00148
00149 template <class T>
00150 vcl_ostream& operator<< (vcl_ostream&, vnl_diag_matrix<T> const&);
00151
00152
00153 template <class T>
00154 inline vnl_matrix<T> vnl_diag_matrix<T>::asMatrix() const
00155 {
00156 unsigned len = diagonal_.size();
00157 vnl_matrix<T> ret(len, len);
00158 for (unsigned i = 0; i < len; ++i)
00159 {
00160 unsigned j;
00161 for (j = 0; j < i; ++j)
00162 ret(i,j) = T(0);
00163 for (j = i+1; j < len; ++j)
00164 ret(i,j) = T(0);
00165 ret(i,i) = diagonal_[i];
00166 }
00167 return ret;
00168 }
00169
00170
00171
00172 template <class T>
00173 inline void vnl_diag_matrix<T>::invert_in_place()
00174 {
00175 unsigned len = diagonal_.size();
00176 T* d = data_block();
00177 T one = T(1);
00178 for (unsigned i = 0; i < len; ++i)
00179 d[i] = one / d[i];
00180 }
00181
00182
00183 template <class T>
00184 inline T vnl_diag_matrix<T>::determinant() const
00185 {
00186 T det = T(1);
00187 T const* d = data_block();
00188 unsigned len = diagonal_.size();
00189 for (unsigned i = 0; i < len; ++i)
00190 det *= d[i];
00191 return det;
00192 }
00193
00194
00195
00196 template <class T>
00197 inline vnl_diag_matrix<T> operator* (vnl_diag_matrix<T> const& A, vnl_diag_matrix<T> const& B)
00198 {
00199 assert(A.size() == B.size());
00200 vnl_diag_matrix<T> ret = A;
00201 for (unsigned i = 0; i < A.size(); ++i)
00202 ret(i,i) *= B(i,i);
00203 return ret;
00204 }
00205
00206
00207
00208
00209 template <class T>
00210 inline vnl_matrix<T> operator* (vnl_matrix<T> const& A, vnl_diag_matrix<T> const& D)
00211 {
00212 assert(A.columns() == D.size());
00213 vnl_matrix<T> ret(A.rows(), A.columns());
00214 for (unsigned i = 0; i < A.rows(); ++i)
00215 for (unsigned j = 0; j < A.columns(); ++j)
00216 ret(i,j) = A(i,j) * D(j,j);
00217 return ret;
00218 }
00219
00220
00221
00222
00223 template <class T>
00224 inline vnl_matrix<T> operator* (vnl_diag_matrix<T> const& D, vnl_matrix<T> const& A)
00225 {
00226 assert(A.rows() == D.size());
00227 vnl_matrix<T> ret(A.rows(), A.columns());
00228 T const* d = D.data_block();
00229 for (unsigned i = 0; i < A.rows(); ++i)
00230 for (unsigned j = 0; j < A.columns(); ++j)
00231 ret(i,j) = A(i,j) * d[i];
00232 return ret;
00233 }
00234
00235
00236
00237 template <class T>
00238 inline vnl_diag_matrix<T> operator+ (vnl_diag_matrix<T> const& A, vnl_diag_matrix<T> const& B)
00239 {
00240 assert(A.size() == B.size());
00241 vnl_diag_matrix<T> ret = A;
00242 for (unsigned i = 0; i < A.size(); ++i)
00243 ret(i,i) += B(i,i);
00244 return ret;
00245 }
00246
00247
00248
00249
00250 template <class T>
00251 inline vnl_matrix<T> operator+ (vnl_matrix<T> const& A, vnl_diag_matrix<T> const& D)
00252 {
00253 const unsigned n = D.size();
00254 assert(A.rows() == n); assert(A.columns() == n);
00255 vnl_matrix<T> ret(A);
00256 T const* d = D.data_block();
00257 for (unsigned j = 0; j < n; ++j)
00258 ret(j,j) += d[j];
00259 return ret;
00260 }
00261
00262
00263
00264
00265 template <class T>
00266 inline vnl_matrix<T> operator+ (vnl_diag_matrix<T> const& D, vnl_matrix<T> const& A)
00267 {
00268 return A + D;
00269 }
00270
00271
00272
00273 template <class T>
00274 inline vnl_diag_matrix<T> operator- (vnl_diag_matrix<T> const& A, vnl_diag_matrix<T> const& B)
00275 {
00276 assert(A.size() == B.size());
00277 vnl_diag_matrix<T> ret = A;
00278 for (unsigned i = 0; i < A.size(); ++i)
00279 ret(i,i) -= B(i,i);
00280 return ret;
00281 }
00282
00283
00284
00285
00286 template <class T>
00287 inline vnl_matrix<T> operator- (vnl_matrix<T> const& A, vnl_diag_matrix<T> const& D)
00288 {
00289 const unsigned n = D.size();
00290 assert(A.rows() == n); assert(A.columns() == n);
00291 vnl_matrix<T> ret(A);
00292 T const* d = D.data_block();
00293 for (unsigned j = 0; j < n; ++j)
00294 ret(j,j) -= d[j];
00295 return ret;
00296 }
00297
00298
00299
00300
00301 template <class T>
00302 inline vnl_matrix<T> operator- (vnl_diag_matrix<T> const& D, vnl_matrix<T> const& A)
00303 {
00304 const unsigned n = D.size();
00305 assert(A.rows() == n); assert(A.columns() == n);
00306 vnl_matrix<T> ret(n, n);
00307 T const* d = D.data_block();
00308 for (unsigned i = 0; i < n; ++i)
00309 {
00310 for (unsigned j = 0; j < i; ++j)
00311 ret(i,j) = -A(i,j);
00312 for (unsigned j = i+1; j < n; ++j)
00313 ret(i,j) = -A(i,j);
00314 ret(i,i) = d[i] - A(i,i);
00315 }
00316 return ret;
00317 }
00318
00319
00320
00321
00322 template <class T>
00323 inline vnl_vector<T> operator* (vnl_diag_matrix<T> const& D, vnl_vector<T> const& A)
00324 {
00325 assert(A.size() == D.size());
00326 return element_product(D.diagonal(), A);
00327 }
00328
00329
00330
00331
00332 template <class T>
00333 inline vnl_vector<T> operator* (vnl_vector<T> const& A, vnl_diag_matrix<T> const& D)
00334 {
00335 assert(A.size() == D.size());
00336 return element_product(D.diagonal(), A);
00337 }
00338
00339 #endif // vnl_diag_matrix_h_