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

vnl_vector.h

Go to the documentation of this file.
00001 #ifndef vnl_vector_h_
00002 #define vnl_vector_h_
00003 
00004 // This is vxl/vnl/vnl_vector.h
00005 
00006 //:
00007 // \file
00008 // \author Andrew W. Fitzgibbon
00009 //
00010 
00011 // Comments re-written by Tim Cootes, for his sins.
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> T      dot_product (v const&, v const&);
00027 template <class T> T      inner_product (v const&, v const&);
00028 template <class T> T      bracket (v const &, m const &, v const &);
00029 template <class T> T      cos_angle(v const&, v const& );
00030 template <class T> double angle (v const&, v const&);
00031 template <class T> m      outer_product (v const&, v const&);
00032 template <class T> v      operator+(T, v const&);
00033 template <class T> v      operator-(T, v const&);
00034 template <class T> v      operator*(T, v const&);
00035 template <class T> v      operator*(m const&, v const&);
00036 template <class T> v      element_product(v const&,v const&);
00037 template <class T> v      element_quotient(v const&,v const&);
00038 template <class T> T      cross_2d (v const&, v const&);
00039 template <class T> v      cross_3d (v const&, v const&);
00040 #undef v
00041 #undef m
00042 
00043 //----------------------------------------------------------------------
00044 
00045 //: Mathematical vector class, templated by type of element
00046 // The vnl_vector<T> class implements one-dimensional arithmetic
00047 // vectors to be used with the vnl_matrix<T> class. vnl_vector<T>
00048 // has size fixed by constructor time or changed by assignment
00049 // operator.
00050 // For faster, non-mallocing vectors with size known at compile
00051 // time, use vnl_vector_fixed* or vnl_T_n (e.g. vnl_double_3).
00052 //
00053 // NOTE: Vectors are indexed from zero!  Thus valid elements are [0,size()-1].
00054 template<class T>
00055 class vnl_vector {
00056 public:
00057   friend class vnl_matrix<T>;
00058 
00059   //: Creates an empty vector. O(1).
00060   vnl_vector () : num_elmts(0) , data(0) {}
00061 
00062   //: Creates vector containing n elements
00063   // Elements are not initialized
00064   vnl_vector (unsigned len);
00065 
00066   //: Creates vector of len elements, all sest to v0
00067   vnl_vector (unsigned len, T const& v0);
00068 
00069   //: Creates a vector of specified length and initialize first n elements with values. O(n).
00070   vnl_vector (unsigned len, int n, T const values[]);
00071 
00072   //: Creates a vector of length 3 and initializes with the arguments, x,y,z.
00073   vnl_vector (T const&, T const&, T const&);
00074 
00075   //: Create n element vector and copy data from data_block
00076   vnl_vector (T const* data_block,unsigned int n);
00077 
00078   //: Copy constructor
00079   vnl_vector (vnl_vector<T> const&);
00080 
00081   //: Takes responsibility for data in vector that
00082   //  that is emptied, this now uses that's data
00083   vnl_vector (vnl_vector<T> &that, vnl_tag_grab)
00084     : num_elmts(that.num_elmts), data(that.data)
00085     { that.num_elmts=0; that.data=0; }
00086 
00087 #ifndef VXL_DOXYGEN_SHOULD_SKIP_THIS 
00088   // <internal>
00089   // These constructors are here so that operator* etc can take
00090   // advantage of the C++ return value optimization.
00091   vnl_vector (vnl_vector<T> const &, vnl_vector<T> const &, const vnl_tag_add &); // v + v
00092   vnl_vector (vnl_vector<T> const &, vnl_vector<T> const &, const vnl_tag_sub &); // v - v
00093   vnl_vector (vnl_vector<T> const &, T,                     const vnl_tag_mul &); // v * s
00094   vnl_vector (vnl_vector<T> const &, T,                     const vnl_tag_div &); // v / s
00095   vnl_vector (vnl_vector<T> const &, T,                     const vnl_tag_add &); // v + s
00096   vnl_vector (vnl_vector<T> const &, T,                     const vnl_tag_sub &); // v - s
00097   vnl_vector (vnl_matrix<T> const &, vnl_vector<T> const &, const vnl_tag_mul &); // M * v
00098   vnl_vector (vnl_vector<T> const &, vnl_matrix<T> const &, const vnl_tag_mul &); // v * M
00099   // </internal>
00100 #endif
00101 
00102   //: Destructor
00103   ~vnl_vector() { if (data) destroy(); }
00104 
00105   //: Return the length, number of elements, dimension of this vector.
00106   unsigned size() const { return num_elmts; }
00107 
00108   //: put value at given position in vector.
00109   inline void put (unsigned int i, T const&);
00110 
00111   //: get value at element i
00112   inline T get (unsigned int i) const;
00113 
00114   //: Set all values to v
00115   void fill (T const& v);
00116 
00117   //: Sets elements to ptr[i]
00118   //  Note: ptr[i] must be valid for i=0..size()-1
00119   void copy_in(T const * ptr);
00120 
00121   //: Copy elements to ptr[i]
00122   //  Note: ptr[i] must be valid for i=0..size()-1
00123   void copy_out(T *) const; // from vector to array[].
00124 
00125 
00126   //: Sets elements to ptr[i]
00127   //  Note: ptr[i] must be valid for i=0..size()-1
00128   void set (T const *ptr) { copy_in(ptr); }
00129 
00130   //: Return reference to the element at specified index. No range checking.
00131   T       & operator() (unsigned int i) { return data[i]; }
00132   //: Return reference to the element at specified index. No range checking.
00133   T const & operator() (unsigned int i) const { return data[i]; }
00134 
00135   //: Return reference to the element at specified index. No range checking.
00136   T       & operator[] (unsigned int i) { return data[i]; }
00137   //: Return reference to the element at specified index. No range checking.
00138   T const & operator[] (unsigned int i) const { return data[i]; }
00139 
00140   //: Set all elements to value v
00141   vnl_vector<T>& operator= (T const&v) { fill(v); return *this; }
00142 
00143   //: Copy operator
00144   vnl_vector<T>& operator= (vnl_vector<T> const& rhs);
00145 
00146   //: Add scalar value to all elements
00147   vnl_vector<T>& operator+= (T );
00148 
00149   //: Subtract scalar value from all elements
00150   vnl_vector<T>& operator-= (T value) { return *this += (-value); }
00151 
00152   //: Multiply all elements by scalar
00153   vnl_vector<T>& operator*= (T );
00154 
00155   //: Divide all elements by scalar
00156   vnl_vector<T>& operator/= (T );
00157 
00158   //: Add rhs to this and return *this
00159   vnl_vector<T>& operator+= (vnl_vector<T> const& rhs);
00160 
00161   //: Subtract rhs from this and return *this
00162   vnl_vector<T>& operator-= (vnl_vector<T> const& rhs);
00163 
00164   //: *this = M*(*this) where M is a suitable matrix
00165   //  this is treated as a column vector
00166   vnl_vector<T>& pre_multiply (vnl_matrix<T> const& M);
00167 
00168   //: *this = (*this)*M where M is a suitable matrix
00169   //  this is treated as a row vector
00170   vnl_vector<T>& post_multiply (vnl_matrix<T> const& M);
00171 
00172   //: *this = (*this)*M where M is a suitable matrix
00173   //  this is treated as a row vector
00174   vnl_vector<T>& operator*= (vnl_matrix<T> const& m) { return this->post_multiply(m); }
00175 
00176 
00177   //: Unary plus operator
00178   // Return new vector = (*this)
00179   vnl_vector<T> operator+ () const { return *this; }
00180 
00181   //: Unary mnus operator
00182   // Return new vector = -1*(*this)
00183   vnl_vector<T> operator- () const;
00184 
00185 
00186   vnl_vector<T> operator+ (T v) const { return vnl_vector<T>(*this, v, vnl_tag_add()); }
00187   vnl_vector<T> operator- (T v) const { return vnl_vector<T>(*this, v, vnl_tag_sub()); }
00188   vnl_vector<T> operator* (T v) const { return vnl_vector<T>(*this, v, vnl_tag_mul()); }
00189   vnl_vector<T> operator/ (T v) const { return vnl_vector<T>(*this, v, vnl_tag_div()); }
00190 
00191   vnl_vector<T> operator+ (vnl_vector<T> const& v) const { return vnl_vector<T>(*this, v, vnl_tag_add()); }
00192   vnl_vector<T> operator- (vnl_vector<T> const& v) const { return vnl_vector<T>(*this, v, vnl_tag_sub()); }
00193   vnl_vector<T> operator* (vnl_matrix<T> const& M) const { return vnl_vector<T>(*this, M, vnl_tag_mul()); }
00194 
00195   //--------------------------------------------------------------------------------
00196 
00197   //: Access the contiguous block storing the elements in the vector. O(1).
00198   //  data_block()[0] is the first element of the vector
00199   T const* data_block () const { return data; }
00200 
00201   //: Access the contiguous block storing the elements in the vector. O(1).
00202   //  data_block()[0] is the first element of the vector
00203   T      * data_block () { return data; }
00204 
00205   //: Type defs for iterators
00206   typedef T element_type;
00207   //: Type defs for iterators
00208   typedef T       *iterator;
00209   //: Iterator pointing to start of data
00210   iterator begin() { return data; }
00211 
00212   //: Iterator pointing to element beyond end of data
00213   iterator end() { return data+num_elmts; }
00214 
00215   //: Const iterator type
00216   typedef T const *const_iterator;
00217   //: Iterator pointing to start of data
00218   const_iterator begin() const { return data; }
00219   //: Iterator pointing to element beyond end of data
00220   const_iterator end() const { return data+num_elmts; }
00221 
00222   //: Applies function to elements
00223   vnl_vector<T> apply(T (*f)(T)) const;
00224   //: Applies function to elements
00225   vnl_vector<T> apply(T (*f)(T const&)) const;
00226 
00227   //: Returns a subvector specified by the start index and length. O(n).
00228   vnl_vector<T> extract (unsigned int len, unsigned int start=0) const;
00229 
00230   //: Replaces elements with index begining at start, by values of v. O(n).
00231   vnl_vector<T>& update (vnl_vector<T> const&, unsigned int start=0);
00232 
00233   // norms etc
00234   typedef typename vnl_c_vector<T>::abs_t abs_t;
00235 
00236   //: Return sum of squares of elements
00237   abs_t squared_magnitude() const { return vnl_c_vector<T>::two_nrm2(begin(), size()); }
00238 
00239   //: Return magnitude (length) of vector
00240   abs_t magnitude() const { return two_norm(); }
00241 
00242   //: Return sum of absolute values of the elements
00243   abs_t one_norm() const { return vnl_c_vector<T>::one_norm(begin(), size()); }
00244 
00245   //: Return sqrt of sum of squares of values of elements
00246   abs_t two_norm() const { return vnl_c_vector<T>::two_norm(begin(), size()); }
00247 
00248   //: Return largest absolute element value
00249   abs_t inf_norm() const { return vnl_c_vector<T>::inf_norm(begin(), size()); }
00250 
00251   //: Root Mean Squares of values
00252   abs_t rms     () const { return vnl_c_vector<T>::rms_norm(begin(), size()); }
00253 
00254   //: Smallest value
00255   T min_value () const { return vnl_c_vector<T>::min_value(begin(), size()); }
00256 
00257   //: Largest value
00258   T max_value () const { return vnl_c_vector<T>::max_value(begin(), size()); }
00259 
00260   //: Mean of values in vector
00261   T mean() const { return vnl_c_vector<T>::mean(begin(), size()); }
00262 
00263   //: Normalise by dividing through by the magnitude
00264   vnl_vector<T>& normalize() { vnl_c_vector<T>::normalize(begin(), size()); return *this; }
00265 
00266   //: Reverse the order of the elements
00267   //  Element i swaps with element size()-1-i
00268   void flip();
00269 
00270   //: Set this to that and that to this
00271   void swap(vnl_vector<T> & that);
00272 
00273   //: Return first element of vector
00274   T& x() const { return data[0]; }
00275   //: Return second element of vector
00276   T& y() const { return data[1]; }
00277   //: Return third element of vector
00278   T& z() const { return data[2]; }
00279   //: Return fourth element of vector
00280   T& t() const { return data[3]; }
00281 
00282 #ifndef VXL_I_dont_want_crazy_methods_in_my_classes
00283   //: Set the first element (with bound checking)
00284   void set_x(T const&xx) { if (size() >= 1) data[0] = xx; }
00285   //: Set the second element (with bound checking)
00286   void set_y(T const&yy) { if (size() >= 2) data[1] = yy; }
00287   //: Set the third element (with bound checking)
00288   void set_z(T const&zz) { if (size() >= 3) data[2] = zz; }
00289   //: Set the fourth element (with bound checking)
00290   void set_t(T const&tt) { if (size() >= 4) data[3] = tt; }
00291 #endif
00292 
00293   //: Check that size()==sz - if not, abort();
00294   void assert_size(unsigned sz) const;
00295   //: Check that this is finite if not, abort();
00296   void assert_finite() const;
00297 
00298   //: Return true if its finite
00299   bool is_finite() const;
00300 
00301   //: Return true if *this == v
00302   bool operator_eq (vnl_vector<T> const& v) const;
00303 
00304   //: Equality test
00305   bool operator==(vnl_vector<T> const &that) const { return  this->operator_eq(that); }
00306 
00307   //: Inequality test
00308   bool operator!=(vnl_vector<T> const &that) const { return !this->operator_eq(that); }
00309 
00310   //: Resize to n elements.
00311   // Checks early and does nothing if already size n, otherwise
00312   // old data is discarded.  Returns true if size change successful.
00313   bool resize (unsigned n);
00314 
00315   //: Make the vector as if it had been default-constructed.
00316   void clear();
00317 
00318 
00319   //: Read from text stream
00320   bool read_ascii(vcl_istream& s);
00321 
00322   //: Read from text stream
00323   static vnl_vector<T> read(vcl_istream& s);
00324 
00325 
00326 protected:
00327   unsigned num_elmts;           // Number of elements
00328   T* data;                      // Pointer to the vnl_vector
00329 
00330   void destroy();
00331 
00332 #if VCL_NEED_FRIEND_FOR_TEMPLATE_OVERLOAD
00333 # define v vnl_vector<T>
00334 # define m vnl_matrix<T>
00335   friend T      dot_product      VCL_NULL_TMPL_ARGS (v const&, v const&);
00336   friend T      inner_product    VCL_NULL_TMPL_ARGS (v const&, v const&);
00337   friend T      bracket          VCL_NULL_TMPL_ARGS (v const&, m const&, v const&);
00338   friend T      cos_angle        VCL_NULL_TMPL_ARGS (v const&, v const&);
00339   friend double angle            VCL_NULL_TMPL_ARGS (v const&, v const&);
00340   friend m      outer_product    VCL_NULL_TMPL_ARGS (v const&, v const&);
00341   friend v      operator+        VCL_NULL_TMPL_ARGS (T const,  v const&);
00342   friend v      operator-        VCL_NULL_TMPL_ARGS (T const,  v const&);
00343   friend v      operator*        VCL_NULL_TMPL_ARGS (T const,  v const&);
00344   friend v      operator*        VCL_NULL_TMPL_ARGS (m const&, v const&);
00345   friend v      element_product  VCL_NULL_TMPL_ARGS (v const&, v const&);
00346   friend v      element_quotient VCL_NULL_TMPL_ARGS (v const&, v const&);
00347   friend T      cross_2d         VCL_NULL_TMPL_ARGS (v const&, v const&);
00348   friend v      cross_3d         VCL_NULL_TMPL_ARGS (v const&, v const&);
00349 # undef v
00350 # undef m
00351 #endif
00352 
00353   // inline function template instantiation hack for gcc 2.97 -- fsm
00354   static void inline_function_tickler();
00355 };
00356 
00357 
00358 // Definitions of inline functions
00359 
00360 
00361 //: Gets the element at specified index and return its value. O(1).
00362 // Range check is performed.
00363 
00364 template <class T>
00365 inline T vnl_vector<T>::get (unsigned int index) const {
00366 #if ERROR_CHECKING
00367   if (index >= this->num_elmts)     // If invalid index specified
00368     vnl_error_vector_index ("get", index);  // Raise exception
00369 #endif
00370   return this->data[index];
00371 }
00372 
00373 //: Puts the value at specified index. O(1).
00374 // Range check is performed.
00375 
00376 template <class T>
00377 inline void vnl_vector<T>::put (unsigned int index, T const& value) {
00378 #if ERROR_CHECKING
00379   if (index >= this->num_elmts)     // If invalid index specified
00380     vnl_error_vector_index ("put", index); // Raise exception
00381 #endif
00382   this->data[index] = value;    // Assign data value
00383 }
00384 
00385 //: multiply matrix and (column) vector. O(m*n).
00386 template<class T>
00387 inline vnl_vector<T> operator* (vnl_matrix<T> const& m, vnl_vector<T> const& v) {
00388   return vnl_vector<T>(m, v, vnl_tag_mul());
00389 }
00390 
00391 //: add scalar and vector. O(n).
00392 template<class T>
00393 inline vnl_vector<T> operator+ (T s, vnl_vector<T> const& v) {
00394   return vnl_vector<T>(v, s, vnl_tag_add());
00395 }
00396 
00397 //: subtract vector from scalar. O(n).
00398 template<class T>
00399 inline vnl_vector<T> operator- (T s, vnl_vector<T> const& v) {
00400   return vnl_vector<T>(-v, s, vnl_tag_add());
00401 }
00402 
00403 //: multiply scalar and vector. O(n).
00404 template<class T>
00405 inline vnl_vector<T> operator* (T s, vnl_vector<T> const& v) {
00406   return vnl_vector<T>(v, s, vnl_tag_mul());
00407 }
00408 
00409 template<class T>
00410 inline void swap(vnl_vector<T> &a, vnl_vector<T> &b) { a.swap(b); }
00411 
00412 //: Read/write vector from/to an istream :
00413 export template <class T> vcl_ostream& operator<< (vcl_ostream &, vnl_vector<T> const&);
00414 export template <class T> vcl_istream& operator>> (vcl_istream &, vnl_vector<T>      &);
00415 
00416 
00417 #endif // vnl_vector_h_

Generated at Wed Mar 12 01:13:16 2003 for ITK by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2000