core/vnl/vnl_matrix.h

Go to the documentation of this file.
00001 // This is core/vnl/vnl_matrix.h
00002 #ifndef vnl_matrix_h_
00003 #define vnl_matrix_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief An ordinary mathematical matrix
00010 
00011 #include <vcl_iosfwd.h>
00012 #include <vnl/vnl_tag.h>
00013 #include <vnl/vnl_c_vector.h>
00014 #include <vnl/vnl_config.h>
00015 #ifndef NDEBUG
00016 # if VNL_CONFIG_CHECK_BOUNDS
00017 #  include <vnl/vnl_error.h>
00018 #  include <vcl_cassert.h>
00019 # endif
00020 #else
00021 # undef VNL_CONFIG_CHECK_BOUNDS
00022 # define VNL_CONFIG_CHECK_BOUNDS 0
00023 # undef ERROR_CHECKING
00024 #endif
00025 
00026 export template <class T> class vnl_vector;
00027 export template <class T> class vnl_matrix;
00028 
00029 //--------------------------------------------------------------------------------
00030 
00031 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00032 #define v vnl_vector<T>
00033 #define m vnl_matrix<T>
00034 #endif // DOXYGEN_SHOULD_SKIP_THIS
00035 template <class T> m operator+(T const&, m const&);
00036 template <class T> m operator-(T const&, m const&);
00037 template <class T> m operator*(T const&, m const&);
00038 template <class T> m element_product(m const&, m const&);
00039 template <class T> m element_quotient(m const&, m const&);
00040 template <class T> T dot_product(m const&, m const&);
00041 template <class T> T inner_product(m const&, m const&);
00042 template <class T> T cos_angle(m const&, m const& );
00043 template <class T> vcl_ostream& operator<<(vcl_ostream&, m const&);
00044 template <class T> vcl_istream& operator>>(vcl_istream&, m&);
00045 #undef v
00046 #undef m
00047 
00048 //--------------------------------------------------------------------------------
00049 
00050 enum vnl_matrix_type
00051 {
00052   vnl_matrix_null,
00053   vnl_matrix_identity
00054 };
00055 
00056 //:  An ordinary mathematical matrix
00057 // The vnl_matrix<T> class implements two-dimensional arithmetic
00058 // matrices  for  a user-specified numeric data type. Using the
00059 // parameterized types facility of C++,  it  is  possible,  for
00060 // example, for the user to create a matrix of rational numbers
00061 // by parameterizing the vnl_matrix class over the Rational  class.
00062 // The  only  requirement  for the type is that it supports the
00063 // basic arithmetic operators.
00064 //
00065 // Note: Unlike   the   other   sequence   classes,   the
00066 // vnl_matrix<T>  class is fixed-size. It will not grow once the
00067 // size has been specified to the constructor or changed by the
00068 // assignment  or  multiplication  operators.  The vnl_matrix<T>
00069 // class is row-based with addresses of rows being cached,  and
00070 // elements accessed as m[row][col].
00071 //
00072 // Note: The matrix can, however, be resized using the set_size(nr,nc) function.
00073 //
00074 // Note: Indexing of the matrix is zero-based, so the top-left element is M(0,0).
00075 //
00076 // Note: Inversion of matrix M, and other operations such as solving systems of linear
00077 // equations are handled by the matrix decomposition classes in vnl/algo, such
00078 // as matrix_inverse, svd, qr etc.
00079 //
00080 // Note: Use a vnl_vector<T> with these matrices.
00081 
00082 template<class T>
00083 class vnl_matrix
00084 {
00085  public:
00086   //: Default constructor creates an empty matrix of size 0,0.
00087   vnl_matrix() :
00088     num_rows(0),
00089     num_cols(0),
00090     data(0)
00091   {
00092   }
00093 
00094   //: Construct a matrix of size r rows by c columns
00095   // Contents are unspecified.
00096   // Complexity $O(1)$
00097   vnl_matrix(unsigned r, unsigned c);                           // r rows, c cols.
00098 
00099   //: Construct a matrix of size r rows by c columns, and all emelemnts equal to v0
00100   // Complexity $O(r.c)$
00101   vnl_matrix(unsigned r, unsigned c, T const& v0);              // r rows, c cols, value v0.
00102 
00103   //: Construct a matrix of size r rows by c columns, with a special type
00104   // Contents are specified by t
00105   // Complexity $O(r.c)$
00106   vnl_matrix(unsigned r, unsigned c, vnl_matrix_type t);        // r rows, c cols, special type
00107 
00108   //: Construct a matrix of size r rows by c columns, initialised by an automatic array
00109   // The first n elements, are initialised row-wise, to values.
00110   // Complexity $O(n)$
00111   vnl_matrix(unsigned r, unsigned c, unsigned n, T const values[]);  // use automatic arrays.
00112 
00113   //: Construct a matrix of size r rows by c columns, initialised by a memory block
00114   // The values are initialise row wise from the data.
00115   // Complexity $O(r.c)$
00116   vnl_matrix(T const* data_block, unsigned r, unsigned c);      // fill row-wise.
00117 
00118   //: Copy construct a matrix
00119   // Complexity $O(r.c)$
00120   vnl_matrix(vnl_matrix<T> const&);                             // from another matrix.
00121 
00122 #ifndef VXL_DOXYGEN_SHOULD_SKIP_THIS
00123 // <internal>
00124   // These constructors are here so that operator* etc can take
00125   // advantage of the C++ return value optimization.
00126   vnl_matrix(vnl_matrix<T> const &, vnl_matrix<T> const &, vnl_tag_add); // M + M
00127   vnl_matrix(vnl_matrix<T> const &, vnl_matrix<T> const &, vnl_tag_sub); // M - M
00128   vnl_matrix(vnl_matrix<T> const &, T,                     vnl_tag_mul); // M * s
00129   vnl_matrix(vnl_matrix<T> const &, T,                     vnl_tag_div); // M / s
00130   vnl_matrix(vnl_matrix<T> const &, T,                     vnl_tag_add); // M + s
00131   vnl_matrix(vnl_matrix<T> const &, T,                     vnl_tag_sub); // M - s
00132   vnl_matrix(vnl_matrix<T> const &, vnl_matrix<T> const &, vnl_tag_mul); // M * M
00133   vnl_matrix(vnl_matrix<T> &that, vnl_tag_grab)
00134     : num_rows(that.num_rows), num_cols(that.num_cols), data(that.data)
00135   { that.num_cols=that.num_rows=0; that.data=0; } // "*this" now uses "that"'s data.
00136 // </internal>
00137 #endif
00138 
00139   //: Matrix destructor
00140   ~vnl_matrix();
00141 
00142 // Basic 2D-Array functionality-------------------------------------------
00143 
00144   //: Return number of rows
00145   unsigned rows()    const { return num_rows; }
00146 
00147   //: Return number of columns
00148   // A synonym for cols()
00149   unsigned columns()  const { return num_cols; }
00150 
00151   //: Return number of columns
00152   // A synonym for columns()
00153   unsigned cols()    const { return num_cols; }
00154 
00155   //: Return number of elements
00156   // This equals rows() * cols()
00157   unsigned size()    const { return rows()*cols(); }
00158 
00159   //: set element with boundary checks if error checking is on.
00160   void put(unsigned r, unsigned c, T const&);
00161 
00162   //: get element with boundary checks if error checking is on.
00163   T    get(unsigned r, unsigned c) const;
00164 
00165   //: return pointer to given row
00166   // No boundary checking here.
00167   T       * operator[](unsigned r) { return data[r]; }
00168 
00169   //: return pointer to given row
00170   // No boundary checking here.
00171   T const * operator[](unsigned r) const { return data[r]; }
00172 
00173   //: Access an element for reading or writing
00174   // There are assert style boundary checks - #define NDEBUG to turn them off.
00175   T       & operator()(unsigned r, unsigned c)
00176   {
00177 #if VNL_CONFIG_CHECK_BOUNDS
00178     assert(r<rows());   // Check the row index is valid
00179     assert(c<cols());   // Check the column index is valid
00180 #endif
00181     return this->data[r][c];
00182   }
00183 
00184   //: Access an element for reading
00185   // There are assert style boundary checks - #define NDEBUG to turn them off.
00186   T const & operator()(unsigned r, unsigned c) const
00187   {
00188 #if VNL_CONFIG_CHECK_BOUNDS
00189     assert(r<rows());   // Check the row index is valid
00190     assert(c<cols());   // Check the column index is valid
00191 #endif
00192     return this->data[r][c];
00193   }
00194 
00195 
00196 // Filling and copying------------------------------------------------
00197 
00198   //: Set all elements of matrix to specified value.
00199   // Complexity $O(r.c)$
00200   void fill(T const&);
00201 
00202   //: Set all diagonal elements of matrix to specified value.
00203   // Complexity $O(\min(r,c))$
00204   void fill_diagonal(T const&);
00205 
00206   //: Fill (laminate) this matrix with the given data.
00207   // We assume that p points to a contiguous rows*cols array, stored rowwise.
00208   void copy_in(T const *);
00209 
00210   //: Fill (laminate) this matrix with the given data.
00211   // A synonym for copy_in()
00212   void set(T const *d) { copy_in(d); }
00213 
00214   //: Fill the given array with this matrix.
00215   // We assume that p points to a contiguous rows*cols array, stored rowwise.
00216   // No bounds checking on the array.
00217   void copy_out(T *) const;
00218 
00219 
00220   //: Set all elements to value v
00221   // Complexity $O(r.c)$
00222   vnl_matrix<T>& operator=(T const&v) { fill(v); return *this; }
00223 
00224   //: Copies all elements of rhs matrix into lhs matrix.
00225   // Complexity $O(\min(r,c))$
00226   vnl_matrix<T>& operator=(vnl_matrix<T> const&);
00227 
00228 // Arithmetic ----------------------------------------------------
00229   // note that these functions should not pass scalar as a const&.
00230   // Look what would happen to A /= A(0,0).
00231 
00232   //: Add rhs to each element of lhs matrix in situ
00233   vnl_matrix<T>& operator+=(T value);
00234 
00235   //: Subtract rhs from each element of lhs matrix in situ
00236   vnl_matrix<T>& operator-=(T value);
00237 
00238   //: Scalar multiplication in situ of lhs matrix  by rhs
00239   vnl_matrix<T>& operator*=(T value);
00240 
00241   //: Scalar division of lhs matrix  in situ by rhs
00242   vnl_matrix<T>& operator/=(T value);
00243 
00244   //: Add rhs to lhs  matrix in situ
00245   vnl_matrix<T>& operator+=(vnl_matrix<T> const&);
00246   //: Subtract rhs from lhs matrix in situ
00247   vnl_matrix<T>& operator-=(vnl_matrix<T> const&);
00248   //: Multiply lhs matrix in situ by rhs
00249   vnl_matrix<T>& operator*=(vnl_matrix<T> const&rhs) { return *this = (*this) * rhs; }
00250 
00251   //: Negate all elements of matrix
00252   vnl_matrix<T> operator-() const;
00253 
00254 
00255   //: Add rhs to each element of lhs matrix and return result in new matrix
00256   vnl_matrix<T> operator+(T const& v) const { return vnl_matrix<T>(*this, v, vnl_tag_add()); }
00257 
00258   //: Subtract rhs from each element of lhs matrix and return result in new matrix
00259   vnl_matrix<T> operator-(T const& v) const { return vnl_matrix<T>(*this, v, vnl_tag_sub()); }
00260 
00261   //: Scalar multiplication of lhs matrix by rhs  and return result in new matrix
00262   vnl_matrix<T> operator*(T const& v) const { return vnl_matrix<T>(*this, v, vnl_tag_mul()); }
00263 
00264   //: Scalar division of lhs matrix by rhs and return result in new matrix
00265   vnl_matrix<T> operator/(T const& v) const { return vnl_matrix<T>(*this, v, vnl_tag_div()); }
00266 
00267   //: Matrix add rhs to lhs matrix and return result in new matrix
00268   vnl_matrix<T> operator+(vnl_matrix<T> const& rhs) const { return vnl_matrix<T>(*this, rhs, vnl_tag_add()); }
00269   //: Matrix subtract rhs from lhs and return result in new matrix
00270   vnl_matrix<T> operator-(vnl_matrix<T> const& rhs) const { return vnl_matrix<T>(*this, rhs, vnl_tag_sub()); }
00271   //: Matrix multiply lhs by rhs matrix and return result in new matrix
00272   vnl_matrix<T> operator*(vnl_matrix<T> const& rhs) const { return vnl_matrix<T>(*this, rhs, vnl_tag_mul()); }
00273 
00274   ////--------------------------- Additions ----------------------------
00275 
00276   //: Make a new matrix by applying function to each element.
00277   vnl_matrix<T> apply(T (*f)(T)) const;
00278 
00279   //: Make a new matrix by applying function to each element.
00280   vnl_matrix<T> apply(T (*f)(T const&)) const;
00281 
00282   //: Return transpose
00283   vnl_matrix<T> transpose() const;
00284 
00285   //: Return conjugate transpose
00286   vnl_matrix<T> conjugate_transpose() const;
00287 
00288   //: Set values of this matrix to those of M, starting at [top,left]
00289   vnl_matrix<T>& update(vnl_matrix<T> const&, unsigned top=0, unsigned left=0);
00290 
00291   //: Set the elements of the i'th column to v[j]  (No bounds checking)
00292   void set_column(unsigned i, T const * v);
00293 
00294   //: Set the elements of the i'th column to value
00295   void set_column(unsigned i, T value );
00296 
00297   //: Set j-th column to v
00298   void set_column(unsigned j, vnl_vector<T> const& v);
00299 
00300   //: Set columns to those in M, starting at starting_column
00301   void set_columns(unsigned starting_column, vnl_matrix<T> const& M);
00302 
00303   //: Set the elements of the i'th row to v[j]  (No bounds checking)
00304   void set_row(unsigned i, T const * v);
00305 
00306   //: Set the elements of the i'th row to value
00307   void set_row(unsigned i, T value );
00308 
00309   //: Set the i-th row
00310   void set_row(unsigned i, vnl_vector<T> const&);
00311 
00312   //: Extract a sub-matrix of size r x c, starting at (top,left)
00313   //  Thus it contains elements  [top,top+r-1][left,left+c-1]
00314   vnl_matrix<T> extract(unsigned r, unsigned c,
00315                         unsigned top=0, unsigned left=0) const;
00316 
00317   //: Extract a sub-matrix starting at (top,left)
00318   //
00319   //  The output is stored in \a sub_matrix, and it should have the
00320   //  required size on entry.  Thus the result will contain elements
00321   //  [top,top+sub_matrix.rows()-1][left,left+sub_matrix.cols()-1]
00322   void extract ( vnl_matrix<T>& sub_matrix,
00323                  unsigned top=0, unsigned left=0) const;
00324 
00325 
00326   //: Get a vector equal to the given row
00327   vnl_vector<T> get_row(unsigned r) const;
00328 
00329   //: Get a vector equal to the given column
00330   vnl_vector<T> get_column(unsigned c) const;
00331 
00332   //: Get n rows beginning at rowstart
00333   vnl_matrix<T> get_n_rows(unsigned rowstart, unsigned n) const;
00334 
00335   //: Get n columns beginning at colstart
00336   vnl_matrix<T> get_n_columns(unsigned colstart, unsigned n) const;
00337 
00338   // mutators
00339 
00340   //: Set this matrix to an identity matrix
00341   //  Abort if the matrix is not square
00342   void set_identity();
00343 
00344   //: Transpose this matrix efficiently
00345   void inplace_transpose();
00346 
00347   //: Reverse order of rows.
00348   void flipud();
00349   //: Reverse order of columns.
00350   void fliplr();
00351 
00352   //: Normalize each row so it is a unit vector
00353   //  Zero rows are ignored
00354   void normalize_rows();
00355 
00356   //: Normalize each column so it is a unit vector
00357   //  Zero columns are ignored
00358   void normalize_columns();
00359 
00360   //: Scale elements in given row by a factor of T
00361   void scale_row(unsigned row, T value);
00362 
00363   //: Scale elements in given column by a factor of T
00364   void scale_column(unsigned col, T value);
00365 
00366   //: Swap this matrix with that matrix
00367   void swap(vnl_matrix<T> & that);
00368 
00369   //: Type def for norms.
00370   typedef typename vnl_c_vector<T>::abs_t abs_t;
00371 
00372   //: Return sum of absolute values of elements
00373   abs_t array_one_norm() const { return vnl_c_vector<T>::one_norm(begin(), size()); }
00374 
00375   //: Return square root of sum of squared absolute element values
00376   abs_t array_two_norm() const { return vnl_c_vector<T>::two_norm(begin(), size()); }
00377 
00378   //: Return largest absolute element value
00379   abs_t array_inf_norm() const { return vnl_c_vector<T>::inf_norm(begin(), size()); }
00380 
00381   //: Return sum of absolute values of elements
00382   abs_t absolute_value_sum() const { return array_one_norm(); }
00383 
00384   //: Return largest absolute value
00385   abs_t absolute_value_max() const { return array_inf_norm(); }
00386 
00387   // $ || M ||_1 := \max_j \sum_i | M_{ij} | $
00388   abs_t operator_one_norm() const;
00389 
00390   // $ || M ||_\inf := \max_i \sum_j | M_{ij} | $
00391   abs_t operator_inf_norm() const;
00392 
00393   //: Return Frobenius norm of matrix (sqrt of sum of squares of its elements)
00394   abs_t frobenius_norm() const { return vnl_c_vector<T>::two_norm(begin(), size()); }
00395 
00396   //: Return Frobenius norm of matrix (sqrt of sum of squares of its elements)
00397   abs_t fro_norm() const { return frobenius_norm(); }
00398 
00399   //: Return RMS of all elements
00400   abs_t rms() const { return vnl_c_vector<T>::rms_norm(begin(), size()); }
00401 
00402   //: Return minimum value of elements
00403   T min_value() const { return vnl_c_vector<T>::min_value(begin(), size()); }
00404 
00405   //: Return maximum value of elements
00406   T max_value() const { return vnl_c_vector<T>::max_value(begin(), size()); }
00407 
00408   //: Return mean of all matrix elements
00409   T mean() const { return vnl_c_vector<T>::mean(begin(), size()); }
00410 
00411   // predicates
00412 
00413   //: Return true iff the size is zero.
00414   bool empty() const { return !data || !num_rows || !num_cols; }
00415 
00416   //:  Return true if all elements equal to identity.
00417   bool is_identity() const;
00418 
00419   //:  Return true if all elements equal to identity, within given tolerance
00420   bool is_identity(double tol) const;
00421 
00422   //: Return true if all elements equal to zero.
00423   bool is_zero() const;
00424 
00425   //: Return true if all elements equal to zero, within given tolerance
00426   bool is_zero(double tol) const;
00427 
00428   //: Return true if finite
00429   bool is_finite() const;
00430 
00431   //: Return true if matrix contains NaNs
00432   bool has_nans() const;
00433 
00434   //: abort if size is not as expected
00435   // This function does or tests nothing if NDEBUG is defined
00436   void assert_size(unsigned r, unsigned c) const
00437   {
00438 #ifndef NDEBUG
00439     assert_size_internal(r, c);
00440 #endif
00441   }
00442   //: abort if matrix contains any INFs or NANs.
00443   // This function does or tests nothing if NDEBUG is defined
00444   void assert_finite() const
00445   {
00446 #ifndef NDEBUG
00447     assert_finite_internal();
00448 #endif
00449   }
00450 
00451   ////----------------------- Input/Output ----------------------------
00452 
00453   //: Read a vnl_matrix from an ascii vcl_istream, automatically determining file size if the input matrix has zero size.
00454   static vnl_matrix<T> read(vcl_istream& s);
00455 
00456   // : Read a vnl_matrix from an ascii vcl_istream, automatically determining file size if the input matrix has zero size.
00457   bool read_ascii(vcl_istream& s);
00458 
00459   //--------------------------------------------------------------------------------
00460 
00461   //: Access the contiguous block storing the elements in the matrix row-wise. O(1).
00462   // 1d array, row-major order.
00463   T const* data_block() const { return data[0]; }
00464 
00465   //: Access the contiguous block storing the elements in the matrix row-wise. O(1).
00466   // 1d array, row-major order.
00467   T      * data_block() { return data[0]; }
00468 
00469   //: Access the 2D array, so that elements can be accessed with array[row][col] directly.
00470   //  2d array, [row][column].
00471   T const* const* data_array() const { return data; }
00472 
00473   //: Access the 2D array, so that elements can be accessed with array[row][col] directly.
00474   //  2d array, [row][column].
00475   T      *      * data_array() { return data; }
00476 
00477   typedef T element_type;
00478 
00479   //: Iterators
00480   typedef T       *iterator;
00481   //: Iterator pointing to start of data
00482   iterator       begin() { return data?data[0]:0; }
00483   //: Iterator pointing to element beyond end of data
00484   iterator       end() { return data?data[0]+num_rows*num_cols:0; }
00485 
00486   //: Const iterators
00487   typedef T const *const_iterator;
00488   //: Iterator pointing to start of data
00489   const_iterator begin() const { return data?data[0]:0; }
00490   //: Iterator pointing to element beyond end of data
00491   const_iterator end() const { return data?data[0]+num_rows*num_cols:0; }
00492 
00493   //: Return a reference to this.
00494   // Useful in code which would prefer not to know if its argument
00495   // is a matrix, matrix_ref or a matrix_fixed.  Note that it doesn't
00496   // return a matrix_ref, so it's only useful in templates or macros.
00497   vnl_matrix<T> const& as_ref() const { return *this; }
00498 
00499   //: Return a reference to this.
00500   vnl_matrix<T>&       as_ref()       { return *this; }
00501 
00502   //--------------------------------------------------------------------------------
00503 
00504   //: Return true if *this == rhs
00505   bool operator_eq(vnl_matrix<T> const & rhs) const;
00506 
00507   //: Equality operator
00508   bool operator==(vnl_matrix<T> const &that) const { return  this->operator_eq(that); }
00509 
00510   //: Inequality operator
00511   bool operator!=(vnl_matrix<T> const &that) const { return !this->operator_eq(that); }
00512 
00513   //: Print matrix to os in some hopefully sensible format
00514   void print(vcl_ostream& os) const;
00515 
00516   //: Make the matrix as if it had been default-constructed.
00517   void clear();
00518 
00519   //: Resize to r rows by c columns. Old data lost.
00520   // Returns true if size changed.
00521   bool set_size(unsigned r, unsigned c);
00522 
00523 //--------------------------------------------------------------------------------
00524 
00525  protected:
00526   unsigned num_rows;   // Number of rows
00527   unsigned num_cols;   // Number of columns
00528   T** data;            // Pointer to the vnl_matrix
00529 
00530 #if VCL_HAS_SLICED_DESTRUCTOR_BUG
00531   // Since this bug exists, we need a flag that can be set during
00532   // construction to tell our destructor whether we own data.
00533   char vnl_matrix_own_data;
00534 #endif
00535 
00536   void assert_size_internal(unsigned r, unsigned c) const;
00537   void assert_finite_internal() const;
00538 
00539   //: Delete data
00540   void destroy();
00541 
00542 #if VCL_NEED_FRIEND_FOR_TEMPLATE_OVERLOAD
00543 # define v vnl_vector<T>
00544 # define m vnl_matrix<T>
00545   friend m operator+         VCL_NULL_TMPL_ARGS (T const&, m const&);
00546   friend m operator-         VCL_NULL_TMPL_ARGS (T const&, m const&);
00547   friend m operator*         VCL_NULL_TMPL_ARGS (T const&, m const&);
00548   friend m element_product   VCL_NULL_TMPL_ARGS (m const&, m const&);
00549   friend m element_quotient  VCL_NULL_TMPL_ARGS (m const&, m const&);
00550   friend T dot_product       VCL_NULL_TMPL_ARGS (m const&, m const&);
00551   friend T inner_product     VCL_NULL_TMPL_ARGS (m const&, m const&);
00552   friend T cos_angle         VCL_NULL_TMPL_ARGS (m const&, m const&);
00553   friend vcl_ostream& operator<< VCL_NULL_TMPL_ARGS (vcl_ostream&, m const&);
00554   friend vcl_istream& operator>> VCL_NULL_TMPL_ARGS (vcl_istream&, m&);
00555 # undef v
00556 # undef m
00557 #endif
00558 
00559   // inline function template instantiation hack for gcc 2.97 -- fsm
00560   static void inline_function_tickler();
00561 };
00562 
00563 
00564 // Definitions of inline functions.
00565 
00566 
00567 //: Returns the value of the element at specified row and column. O(1).
00568 // Checks for valid range of indices.
00569 
00570 template<class T>
00571 inline T vnl_matrix<T>::get(unsigned row, unsigned column) const
00572 {
00573 #ifdef ERROR_CHECKING
00574   if (row >= this->num_rows)                   // If invalid size specified
00575     vnl_error_matrix_row_index("get", row);    // Raise exception
00576   if (column >= this->num_cols)                // If invalid size specified
00577     vnl_error_matrix_col_index("get", column); // Raise exception
00578 #endif
00579   return this->data[row][column];
00580 }
00581 
00582 //: Puts value into element at specified row and column. O(1).
00583 // Checks for valid range of indices.
00584 
00585 template<class T>
00586 inline void vnl_matrix<T>::put(unsigned row, unsigned column, T const& value)
00587 {
00588 #ifdef ERROR_CHECKING
00589   if (row >= this->num_rows)                   // If invalid size specified
00590     vnl_error_matrix_row_index("put", row);    // Raise exception
00591   if (column >= this->num_cols)                // If invalid size specified
00592     vnl_error_matrix_col_index("put", column); // Raise exception
00593 #endif
00594   this->data[row][column] = value;             // Assign data value
00595 }
00596 
00597 
00598 // non-member arithmetical operators.
00599 
00600 //:
00601 // \relates vnl_matrix
00602 template<class T>
00603 inline vnl_matrix<T> operator*(T const& value, vnl_matrix<T> const& m)
00604 {
00605   return vnl_matrix<T>(m, value, vnl_tag_mul());
00606 }
00607 
00608 //:
00609 // \relates vnl_matrix
00610 template<class T>
00611 inline vnl_matrix<T> operator+(T const& value, vnl_matrix<T> const& m)
00612 {
00613   return vnl_matrix<T>(m, value, vnl_tag_add());
00614 }
00615 
00616 //: Swap two matrices
00617 // \relates vnl_matrix
00618 template<class T>
00619 inline void swap(vnl_matrix<T> &A, vnl_matrix<T> &B) { A.swap(B); }
00620 
00621 
00622 #endif // vnl_matrix_h_

Generated on Sun Sep 7 05:06:16 2008 for core/vnl by  doxygen 1.5.1