core/vnl/vnl_diag_matrix_fixed.h

Go to the documentation of this file.
00001 // This is core/vnl/vnl_diag_matrix_fixed.h
00002 #ifndef vnl_diag_matrix_fixed_h_
00003 #define vnl_diag_matrix_fixed_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Contains class for diagonal matrices
00010 // \author Andrew W. Fitzgibbon (Oxford RRG)
00011 // \date   5 Aug 1996
00012 //
00013 // \verbatim
00014 //  Modifications
00015 //   IMS (Manchester) 16 Mar 2001: Tidied up the documentation + added binary_io
00016 //   Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
00017 //   Sep.2002 - Peter Vanroose - Added operator+, operator-, operator*
00018 //   Mar.2004 - Peter Vanroose - removed deprecated resize()
00019 // \endverbatim
00020 
00021 #include <vcl_cassert.h>
00022 #include <vcl_iosfwd.h>
00023 #include <vnl/vnl_vector_fixed.h>
00024 #include <vnl/vnl_matrix_fixed.h>
00025 
00026 // forward declarations
00027 template <class T, unsigned int N> class vnl_diag_matrix_fixed;
00028 template <class T, unsigned int N> vnl_vector_fixed<T,N> operator*(vnl_diag_matrix_fixed<T,N> const&, vnl_vector_fixed<T,N> const&);
00029 
00030 //: stores a diagonal matrix as a single vector.
00031 //  vnl_diag_matrix_fixed stores a diagonal matrix for time and space efficiency.
00032 //  Specifically, only the diagonal elements are stored, and some matrix
00033 //  operations (currently *, + and -) are overloaded to use more efficient
00034 //  algorithms.
00035 
00036 export
00037 template <class T, unsigned int N>
00038 class vnl_diag_matrix_fixed
00039 {
00040   vnl_vector_fixed<T,N> diagonal_;
00041 
00042  public:
00043   vnl_diag_matrix_fixed() {}
00044 
00045 
00046   //: Construct a diagonal matrix with diagonal elements equal to value.
00047   vnl_diag_matrix_fixed(T const& value) : diagonal_(N, value) {}
00048 
00049   //: Construct a diagonal matrix from a vnl_vector_fixed.
00050   //  The vector elements become the diagonal elements.
00051   explicit vnl_diag_matrix_fixed(vnl_vector_fixed<T,N> const& that): diagonal_(that) {}
00052  ~vnl_diag_matrix_fixed() {}
00053 
00054   inline vnl_diag_matrix_fixed& operator=(vnl_diag_matrix_fixed<T,N> const& that) {
00055     this->diagonal_ = that.diagonal_;
00056     return *this;
00057   }
00058 
00059   // Operations----------------------------------------------------------------
00060 
00061   //: In-place arithmetic operation
00062   inline vnl_diag_matrix_fixed<T,N>& operator*=(T v) { diagonal_ *= v; return *this; }
00063   //: In-place arithmetic operation
00064   inline vnl_diag_matrix_fixed<T,N>& operator/=(T v) { diagonal_ /= v; return *this; }
00065 
00066   // Computations--------------------------------------------------------------
00067 
00068   void invert_in_place();
00069   T determinant() const;
00070   vnl_vector_fixed<T,N> solve(vnl_vector_fixed<T,N> const& b) const;
00071   void solve(vnl_vector_fixed<T,N> const& b, vnl_vector_fixed<T,N>* out) const;
00072 
00073   // Data Access---------------------------------------------------------------
00074 
00075   inline T operator () (unsigned i, unsigned j) const {
00076     return (i != j) ? T(0) : diagonal_[i];
00077   }
00078 
00079   inline T& operator () (unsigned i, unsigned j) {
00080     assert(i == j);
00081     return diagonal_[i];
00082   }
00083   inline T& operator() (unsigned i) { return diagonal_[i]; }
00084   inline T const& operator() (unsigned i) const { return diagonal_[i]; }
00085 
00086   inline T& operator[] (unsigned i) { return diagonal_[i]; }
00087   inline T const& operator[] (unsigned i) const { return diagonal_[i]; }
00088 
00089   //: set element with boundary checks.
00090   inline void put (unsigned r, unsigned c, T const& v) {
00091     assert(r == c); assert (r<size()); diagonal_[r] = v;
00092   }
00093 
00094   //: get element with boundary checks.
00095   inline T get (unsigned r, unsigned c) const {
00096     assert(r == c); assert (r<size()); return diagonal_[r];
00097   }
00098 
00099   //: Set all diagonal elements of matrix to specified value.
00100   inline void fill_diagonal (T const& v) { diagonal_.fill(v); }
00101 
00102   // iterators
00103 
00104   typedef typename vnl_vector_fixed<T,N>::iterator iterator;
00105   inline iterator begin() { return diagonal_.begin(); }
00106   inline iterator end() { return diagonal_.end(); }
00107   typedef typename vnl_vector_fixed<T,N>::const_iterator const_iterator;
00108   inline const_iterator begin() const { return diagonal_.begin(); }
00109   inline const_iterator end() const { return diagonal_.end(); }
00110 
00111   inline unsigned size() const { return diagonal_.size(); }
00112   inline unsigned rows() const { return diagonal_.size(); }
00113   inline unsigned cols() const { return diagonal_.size(); }
00114   inline unsigned columns() const { return diagonal_.size(); }
00115 
00116   // Need this until we add a vnl_diag_matrix_fixed ctor to vnl_matrix;
00117   inline vnl_matrix_fixed<T,N,N> as_matrix_fixed() const;
00118 
00119   inline vnl_matrix_fixed<T,N,N> as_ref() const { return as_matrix_fixed(); }
00120 
00121   // This is as good as a vnl_diag_matrix_fixed ctor for vnl_matrix_fixed:
00122   inline operator vnl_matrix_fixed<T,N,N> () const { return as_matrix_fixed(); }
00123 
00124   inline void fill(T const &x) { diagonal_.fill(x); }
00125 
00126   //: Return pointer to the diagonal elements as a contiguous 1D C array;
00127   inline T*       data_block()       { return diagonal_.data_block(); }
00128   inline T const* data_block() const { return diagonal_.data_block(); }
00129 
00130   //: Return diagonal elements as a vector
00131   inline vnl_vector_fixed<T,N> const& diagonal() const { return diagonal_; }
00132 
00133   //: Set diagonal elements using vector
00134   inline void set(vnl_vector_fixed<T,N> const& v)  { diagonal_=v; }
00135 
00136  private:
00137   #if VCL_NEED_FRIEND_FOR_TEMPLATE_OVERLOAD
00138   friend vnl_vector_fixed<T,N> operator*(vnl_diag_matrix_fixed<T,N> const&,vnl_vector_fixed<T,N> const&);
00139   #endif
00140 };
00141 
00142 //:
00143 // \relatesalso vnl_diag_matrix_fixed
00144 template <class T, unsigned int N>
00145 vcl_ostream& operator<< (vcl_ostream&, vnl_diag_matrix_fixed<T,N> const&);
00146 
00147 //: Convert a vnl_diag_matrix_fixed to a Matrix.
00148 template <class T, unsigned int N>
00149 inline vnl_matrix_fixed<T,N,N> vnl_diag_matrix_fixed<T,N>::as_matrix_fixed() const
00150 {
00151   vnl_matrix_fixed<T,N,N> ret;
00152   for (unsigned i = 0; i < N; ++i)
00153   {
00154     unsigned j;
00155     for (j = 0; j < i; ++j)
00156       ret(i,j) = T(0);
00157     for (j = i+1; j < N; ++j)
00158       ret(i,j) = T(0);
00159     ret(i,i) = diagonal_[i];
00160   }
00161   return ret;
00162 }
00163 
00164 //: Invert a vnl_diag_matrix_fixed in-situ.
00165 // Just replaces each element with its reciprocal.
00166 template <class T, unsigned int N>
00167 inline void vnl_diag_matrix_fixed<T,N>::invert_in_place()
00168 {
00169   T* d = data_block();
00170   T one = T(1);
00171   for (unsigned i = 0; i < N; ++i)
00172     d[i] = one / d[i];
00173 }
00174 
00175 //: Return determinant as product of diagonal values.
00176 template <class T, unsigned int N>
00177 inline T vnl_diag_matrix_fixed<T,N>::determinant() const
00178 {
00179   T det = T(1);
00180   T const* d = data_block();
00181   for (unsigned i = 0; i < N; ++i)
00182     det *= d[i];
00183   return det;
00184 }
00185 
00186 //: Multiply two vnl_diag_matrices.  Just multiply the diag elements - n flops
00187 // \relatesalso vnl_diag_matrix_fixed
00188 template <class T, unsigned int N>
00189 inline vnl_diag_matrix_fixed<T,N> operator* (vnl_diag_matrix_fixed<T,N> const& A, vnl_diag_matrix_fixed<T,N> const& B)
00190 {
00191   vnl_diag_matrix_fixed<T,N> ret = A;
00192   for (unsigned i = 0; i < N; ++i)
00193     ret(i,i) *= B(i,i);
00194   return ret;
00195 }
00196 
00197 //: Multiply a vnl_matrix by a vnl_diag_matrix_fixed.  Just scales the columns - mn flops
00198 // \relatesalso vnl_diag_matrix_fixed
00199 // \relatesalso vnl_matrix
00200 template <class T, unsigned int R, unsigned int C>
00201 inline vnl_matrix_fixed<T,R,C> operator* (vnl_matrix_fixed<T,R,C> const& A, vnl_diag_matrix_fixed<T,C> const& D)
00202 {
00203   vnl_matrix_fixed<T,R,C> ret;
00204   for (unsigned i = 0; i < R; ++i)
00205     for (unsigned j = 0; j < C; ++j)
00206       ret(i,j) = A(i,j) * D(j,j);
00207   return ret;
00208 }
00209 
00210 //: Multiply a vnl_diag_matrix_fixed by a vnl_matrix.  Just scales the rows - mn flops
00211 // \relatesalso vnl_diag_matrix_fixed
00212 // \relatesalso vnl_matrix
00213 template <class T, unsigned int R, unsigned int C>
00214 inline vnl_matrix_fixed<T,R,C> operator* (vnl_diag_matrix_fixed<T,R> const& D, vnl_matrix_fixed<T,R,C> const& A)
00215 {
00216   vnl_matrix_fixed<T,R,C> ret;
00217   T const* d = D.data_block();
00218   for (unsigned i = 0; i < R; ++i)
00219     for (unsigned j = 0; j < C; ++j)
00220       ret(i,j) = A(i,j) * d[i];
00221   return ret;
00222 }
00223 
00224 //: Add two vnl_diag_matrices.  Just add the diag elements - n flops
00225 // \relatesalso vnl_diag_matrix_fixed
00226 template <class T, unsigned int N>
00227 inline vnl_diag_matrix_fixed<T,N> operator+ (vnl_diag_matrix_fixed<T,N> const& A, vnl_diag_matrix_fixed<T,N> const& B)
00228 {
00229   vnl_diag_matrix_fixed<T,N> ret = A;
00230   for (unsigned i = 0; i < N; ++i)
00231     ret(i,i) += B(i,i);
00232   return ret;
00233 }
00234 
00235 //: Add a vnl_diag_matrix_fixed to a vnl_matrix.  n adds, mn copies.
00236 // \relatesalso vnl_diag_matrix_fixed
00237 // \relatesalso vnl_matrix
00238 template <class T, unsigned int N>
00239 inline vnl_matrix_fixed<T,N,N> operator+ (vnl_matrix_fixed<T,N,N> const& A, vnl_diag_matrix_fixed<T,N> const& D)
00240 {
00241   vnl_matrix_fixed<T,N,N> ret(A);
00242   T const* d = D.data_block();
00243   for (unsigned j = 0; j < N; ++j)
00244     ret(j,j) += d[j];
00245   return ret;
00246 }
00247 
00248 //: Add a vnl_matrix to a vnl_diag_matrix_fixed.  n adds, mn copies.
00249 // \relatesalso vnl_diag_matrix_fixed
00250 // \relatesalso vnl_matrix
00251 template <class T, unsigned int N>
00252 inline vnl_matrix_fixed<T,N,N> operator+ (vnl_diag_matrix_fixed<T,N> const& D, vnl_matrix_fixed<T,N,N> const& A)
00253 {
00254   return A + D;
00255 }
00256 
00257 //: Subtract two vnl_diag_matrices.  Just subtract the diag elements - n flops
00258 // \relatesalso vnl_diag_matrix_fixed
00259 template <class T, unsigned int N>
00260 inline vnl_diag_matrix_fixed<T,N> operator- (vnl_diag_matrix_fixed<T,N> const& A, vnl_diag_matrix_fixed<T,N> const& B)
00261 {
00262   vnl_diag_matrix_fixed<T,N> ret(A);
00263   for (unsigned i = 0; i < N; ++i)
00264     ret(i,i) -= B(i,i);
00265   return ret;
00266 }
00267 
00268 //: Subtract a vnl_diag_matrix_fixed from a vnl_matrix.  n adds, mn copies.
00269 // \relatesalso vnl_diag_matrix_fixed
00270 // \relatesalso vnl_matrix
00271 template <class T, unsigned int N>
00272 inline vnl_matrix_fixed<T,N,N> operator- (vnl_matrix_fixed<T,N,N> const& A, vnl_diag_matrix_fixed<T,N> const& D)
00273 {
00274   vnl_matrix_fixed<T,N,N> ret(A);
00275   T const* d = D.data_block();
00276   for (unsigned j = 0; j < N; ++j)
00277     ret(j,j) -= d[j];
00278   return ret;
00279 }
00280 
00281 //: Subtract a vnl_matrix from a vnl_diag_matrix_fixed.  n adds, mn copies.
00282 // \relatesalso vnl_diag_matrix_fixed
00283 // \relatesalso vnl_matrix
00284 template <class T, unsigned int N>
00285 inline vnl_matrix_fixed<T,N,N> operator- (vnl_diag_matrix_fixed<T,N> const& D, vnl_matrix_fixed<T,N,N> const& A)
00286 {
00287   vnl_matrix_fixed<T,N,N> ret;
00288   T const* d = D.data_block();
00289   for (unsigned i = 0; i < N; ++i)
00290   {
00291     for (unsigned j = 0; j < i; ++j)
00292       ret(i,j) = -A(i,j);
00293     for (unsigned j = i+1; j < N; ++j)
00294       ret(i,j) = -A(i,j);
00295     ret(i,i) = d[i] - A(i,i);
00296   }
00297   return ret;
00298 }
00299 
00300 //: Multiply a vnl_diag_matrix_fixed by a vnl_vector_fixed.  n flops.
00301 // \relatesalso vnl_diag_matrix_fixed
00302 // \relatesalso vnl_vector_fixed
00303 template <class T, unsigned int N>
00304 inline vnl_vector_fixed<T,N> operator* (vnl_diag_matrix_fixed<T,N> const& D, vnl_vector_fixed<T,N> const& A)
00305 {
00306   return element_product(D.diagonal(), A);
00307 }
00308 
00309 //: Multiply a vnl_vector_fixed by a vnl_diag_matrix_fixed.  n flops.
00310 // \relatesalso vnl_diag_matrix_fixed
00311 // \relatesalso vnl_vector_fixed
00312 template <class T, unsigned int N>
00313 inline vnl_vector_fixed<T,N> operator* (vnl_vector_fixed<T,N> const& A, vnl_diag_matrix_fixed<T,N> const& D)
00314 {
00315   return element_product(D.diagonal(), A);
00316 }
00317 
00318 #endif // vnl_diag_matrix_fixed_h_

Generated on Mon Mar 8 05:06:44 2010 for core/vnl by  doxygen 1.5.1