Main Page   Groups   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Concepts

vnl_matrix.h

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

Generated at Fri May 21 01:15:49 2004 for ITK by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2000