00001 #ifndef vnl_diag_matrix_h_
00002 #define vnl_diag_matrix_h_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <vcl_cassert.h>
00025 #include <vnl/vnl_vector.h>
00026 #include <vnl/vnl_matrix.h>
00027
00028
00029
00030
00031
00032
00033
00034 export
00035 template <class T>
00036 class vnl_diag_matrix {
00037 public:
00038 vnl_diag_matrix() {}
00039
00040
00041 vnl_diag_matrix(unsigned nn) : diagonal_(nn) {}
00042
00043
00044 vnl_diag_matrix(unsigned nn, T const& value) : diagonal_(nn, value) {}
00045
00046
00047
00048 vnl_diag_matrix(vnl_vector<T> const& that): diagonal_(that) {}
00049 ~vnl_diag_matrix() {}
00050
00051
00052 vnl_diag_matrix& operator=(vnl_diag_matrix<T> const& that) {
00053 this->diagonal_ = that.diagonal_;
00054 return *this;
00055 }
00056
00057
00058
00059 vnl_diag_matrix<T>& operator*=(T v) { diagonal_ *= v; return *this; }
00060
00061 vnl_diag_matrix<T>& operator/=(T v) { diagonal_ /= v; return *this; }
00062
00063
00064 void invert_in_place();
00065 T determinant() const;
00066 vnl_vector<T> solve(vnl_vector<T> const& b);
00067 void solve(vnl_vector<T> const& b, vnl_vector<T>* out);
00068
00069
00070 T operator () (unsigned i, unsigned j) const {
00071 return (i != j) ? T(0) : diagonal_[i];
00072 }
00073
00074 T& operator () (unsigned i, unsigned j) {
00075 assert(i == j);
00076 return diagonal_[i];
00077 }
00078 T& operator() (unsigned i) { return diagonal_[i]; }
00079 T const& operator() (unsigned i) const { return diagonal_[i]; }
00080
00081
00082 typedef typename vnl_vector<T>::iterator iterator;
00083 inline iterator begin() { return diagonal_.begin(); }
00084 inline iterator end() { return diagonal_.end(); }
00085 typedef typename vnl_vector<T>::const_iterator const_iterator;
00086 inline const_iterator begin() const { return diagonal_.begin(); }
00087 inline const_iterator end() const { return diagonal_.end(); }
00088
00089 unsigned size() const { return diagonal_.size(); }
00090 unsigned n() const { return diagonal_.size(); }
00091 unsigned rows() const { return diagonal_.size(); }
00092 unsigned cols() const { return diagonal_.size(); }
00093 unsigned columns() const { return diagonal_.size(); }
00094
00095
00096 inline vnl_matrix<T> asMatrix() const;
00097
00098 void resize(int n) { diagonal_.resize(n); }
00099 void clear() { diagonal_.clear(); }
00100
00101
00102 T* data_block() { return diagonal_.data_block(); }
00103 T const* data_block() const { return diagonal_.data_block(); }
00104
00105
00106 vnl_vector<T> const& diagonal() const { return diagonal_; }
00107
00108
00109 void set(vnl_vector<T> const& v) { diagonal_=v; }
00110
00111 protected:
00112 vnl_vector<T> diagonal_;
00113
00114 private:
00115
00116
00117
00118
00119
00120 #if VCL_NEED_FRIEND_FOR_TEMPLATE_OVERLOAD
00121 friend vnl_vector<T> operator*(vnl_diag_matrix<T> const&,vnl_vector<T> const&);
00122 #endif
00123 };
00124
00125 template <class T>
00126 vcl_ostream& operator<< (vcl_ostream&, vnl_diag_matrix<T> const&);
00127
00128
00129
00130
00131
00132
00133
00134 template <class T> vcl_ostream& operator<< (vcl_ostream&, vnl_diag_matrix<T> const&);
00135
00136
00137 template <class T>
00138 inline vnl_matrix<T> vnl_diag_matrix<T>::asMatrix() const
00139 {
00140 unsigned len = diagonal_.size();
00141 vnl_matrix<T> ret(len, len);
00142 for(unsigned i = 0; i < len; ++i)
00143 for(unsigned j = 0; j < len; ++j)
00144 ret(i,j) = ((i == j) ? diagonal_[i] : T(0));
00145 return ret;
00146 }
00147
00148
00149
00150 template <class T>
00151 inline void vnl_diag_matrix<T>::invert_in_place()
00152 {
00153 unsigned len = diagonal_.size();
00154 T* d = data_block();
00155 T one = T(1);
00156 for(unsigned i = 0; i < len; ++i)
00157 d[i] = one / d[i];
00158 }
00159
00160
00161 template <class T>
00162 inline T vnl_diag_matrix<T>::determinant() const
00163 {
00164 T det = T(1);
00165 T const* d = data_block();
00166 unsigned len = diagonal_.size();
00167 for(unsigned i = 0; i < len; ++i)
00168 det *= d[i];
00169 return det;
00170 }
00171
00172
00173 template <class T>
00174 inline vnl_matrix<T> operator* (vnl_matrix<T> const& A, vnl_diag_matrix<T> const& D)
00175 {
00176 vnl_matrix<T> ret(A.rows(), A.columns());
00177 for(unsigned i = 0; i < A.rows(); ++i)
00178 for(unsigned j = 0; j < A.columns(); ++j)
00179 ret(i,j) = A(i,j) * D(j,j);
00180 return ret;
00181 }
00182
00183
00184 template <class T>
00185 inline vnl_matrix<T> operator* (vnl_diag_matrix<T> const& D, vnl_matrix<T> const& A)
00186 {
00187 vnl_matrix<T> ret(A.rows(), A.columns());
00188 T const* d = D.data_block();
00189 for(unsigned i = 0; i < A.rows(); ++i)
00190 for(unsigned j = 0; j < A.columns(); ++j)
00191 ret(i,j) = A(i,j) * d[i];
00192 return ret;
00193 }
00194
00195
00196 template <class T>
00197 inline vnl_matrix<T> operator + (vnl_matrix<T> const& A, vnl_diag_matrix<T> const& D)
00198 {
00199 unsigned n = D.n();
00200 vnl_matrix<T> ret(A);
00201 T const* d = D.data_block();
00202 for(unsigned j = 0; j < n; ++j)
00203 ret(j,j) += d[j];
00204 return ret;
00205 }
00206
00207
00208 template <class T>
00209 inline vnl_matrix<T> operator + (vnl_diag_matrix<T> const& D, vnl_matrix<T> const& A)
00210 {
00211 return A + D;
00212 }
00213
00214
00215 template <class T>
00216 inline vnl_matrix<T> operator - (vnl_matrix<T> const& A, vnl_diag_matrix<T> const& D)
00217 {
00218 unsigned n = D.n();
00219 vnl_matrix<T> ret(A);
00220 T const* d = D.data_block();
00221 for(unsigned j = 0; j < n; ++j)
00222 ret(j,j) -= d[j];
00223 return ret;
00224 }
00225
00226
00227 template <class T>
00228 inline vnl_matrix<T> operator - (vnl_diag_matrix<T> const& D, vnl_matrix<T> const& A)
00229 {
00230 unsigned n = D.n();
00231 vnl_matrix<T> ret(n, n);
00232 T const* d = D.data_block();
00233 for(unsigned i = 0; i < n; ++i)
00234 for(unsigned j = 0; j < n; ++j)
00235 if (i == j)
00236 ret(i,j) = d[j] - A(i,j);
00237 else
00238 ret(i,j) = -A(i,j);
00239 return ret;
00240 }
00241
00242
00243 template <class T>
00244 inline vnl_vector<T> operator* (vnl_diag_matrix<T> const& D, vnl_vector<T> const& A)
00245 {
00246 return element_product(D.diagonal(), A);
00247 }
00248
00249
00250 template <class T>
00251 inline vnl_vector<T> operator* (vnl_vector<T> const& A, vnl_diag_matrix<T> const& D)
00252 {
00253 return element_product(D.diagonal(), A);
00254 }
00255
00256
00257 #endif // vnl_diag_matrix_h_