core/vnl/vnl_vector_fixed.h

Go to the documentation of this file.
00001 // This is core/vnl/vnl_vector_fixed.h
00002 #ifndef vnl_vector_fixed_h_
00003 #define vnl_vector_fixed_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Fixed length stack-stored vector
00010 //
00011 // The operators are inlined because (1) they are small and
00012 // (2) we then have less explicit instantiation trouble.
00013 //
00014 // \author Andrew W. Fitzgibbon, Oxford RRG
00015 // \date   04 Aug 96
00016 //
00017 // \verbatim
00018 //  Modifications
00019 //   LSB Manchester 16/3/01 Binary I/O added
00020 //   Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
00021 //   Oct.2002 - Amitha Perera - decoupled vnl_vector and vnl_vector_fixed for
00022 //              space efficiency, removed necessity for vnl_vector_fixed_ref
00023 //   Jun.2003 - Paul Smyth - added as_fixed_ref() to convert to fixed-size ref
00024 //              removed duplicate cross_3d
00025 //   Jun.2003 - Peter Vanroose - added cross_2d
00026 //   Oct.2003 - Peter Vanroose - removed deprecated x(), y(), z(), t()
00027 //   Mar.2009 - Peter Vanroose - added arg_min() and arg_max()
00028 // \endverbatim
00029 
00030 #include <vcl_cstring.h> // memcpy()
00031 #include <vcl_cassert.h>
00032 #include <vcl_iosfwd.h>
00033 #include "vnl_vector.h"
00034 #include "vnl_vector_ref.h"
00035 #include <vnl/vnl_c_vector.h>
00036 #include <vnl/vnl_matrix.h> // outerproduct
00037 #include <vnl/vnl_config.h> // for VNL_CONFIG_CHECK_BOUNDS
00038 
00039 export template <class T, unsigned int n> class vnl_vector_fixed;
00040 export template <class T, unsigned int num_rows, unsigned int num_cols> class vnl_matrix_fixed;
00041 
00042 //: Fixed length stack-stored, space-efficient vector.
00043 // vnl_vector_fixed is a fixed-length, stack storage vector. It has
00044 // the same storage size as a C-style array. It is not related via
00045 // inheritance to vnl_vector. However, it can be converted cheaply to
00046 // a vnl_vector_ref.
00047 //
00048 // In most cases, a vnl_vector_fixed can be used where a vnl_vector is
00049 // expected. There are some situations, however, when the automatic
00050 // conversion cannot be applied. In those cases, you need to call the
00051 // as_ref() method to perform an explicit conversion. This occurs most
00052 // often when the called function is templated, since the user-defined
00053 // conversion operators are then suppressed.
00054 // \code
00055 //    template<class T>
00056 //    void do_something( const vnl_vector<T>& v );
00057 //    ...
00058 //    vnl_vector_fixed<double,4> my_vec;
00059 //
00060 //    do_something( my_vec );
00061 //      // Error: no do_something( vnl_vector_fixed<double,4> ) found
00062 //
00063 //    do_something( my_vec.as_ref() );  // works
00064 // \endcode
00065 //
00066 // Since the conversion operator creates a temporary vnl_vector_ref
00067 // object, the conversion cannot be used directly to a function that
00068 // expects a non-const vnl_vector reference. Use
00069 // vnl_vector_ref::non_const method for this (and only this).
00070 // \code
00071 //    void mutator( vnl_vector<double>& v );
00072 //    ...
00073 //    vnl_vector_fixed<double,4> my_vec;
00074 //    mutator( my_vec.as_ref().non_const() );
00075 // \endcode
00076 // If the mutator only accesses the data, all should be fine. If the
00077 // mutator attempts to resize the vector, you are doomed.
00078 //
00079 // vnl_vector_fixed defines most of the operators defined by
00080 // vnl_vector, and does so efficiently. If you try to mix
00081 // vnl_vector_fixed and vnl_vector, however, you will probably get a
00082 // vnl_vector result, with the corresponding malloc cost.
00083 template <class T, unsigned int n>
00084 class vnl_vector_fixed
00085 {
00086  public:
00087   typedef vnl_vector_fixed<T,n> self;
00088   typedef unsigned int size_type;
00089   // Compile-time accessible attribute to get the dimensionality of the vector.
00090   enum{ SIZE = n };
00091 
00092  protected:
00093   T data_[n];
00094 
00095  public:
00096   // Don't out-of-line the constructors, as extra the function call
00097   // adds a significant overhead. (memcpy is often implemented with a
00098   // couple of assembly instructions.)
00099 
00100   //: Construct an uninitialized n-vector
00101   vnl_vector_fixed() {}
00102 
00103   //: Copy constructor
00104   //  The dimensions must match.
00105   vnl_vector_fixed( const vnl_vector_fixed<T,n>& rhs )
00106   {
00107     vcl_memcpy( data_, rhs.data_, sizeof data_ );
00108   }
00109 
00110   //: Construct a fixed-n-vector copy of \a rhs.
00111   //  The dimensions must match.
00112   vnl_vector_fixed( const vnl_vector<T>& rhs )
00113   {
00114     assert( n == rhs.size() );
00115     vcl_memcpy( data_, rhs.data_block(), sizeof data_ );
00116   }
00117 
00118   //: Constructs n-vector with all elements initialised to \a v
00119   explicit vnl_vector_fixed( const T& v ) { fill( v ); }
00120 
00121   //: Construct an fixed-n-vector initialized from \a datablck
00122   //  The data *must* have enough data. No checks performed.
00123   explicit vnl_vector_fixed( const T* datablck )
00124   {
00125     vcl_memcpy( data_, datablck, sizeof data_ );
00126   }
00127 
00128   //: Convenience constructor for 2-D vectors
00129   // While this constructor is sometimes useful, consider using
00130   // vnl_double_2 or vnl_float_2 instead.
00131   vnl_vector_fixed( const T& x0, const T& x1 )
00132   {
00133     assert( n == 2 );
00134     data_[0] = x0; data_[1] = x1;
00135   }
00136 
00137   //: Convenience constructor for 3-D vectors
00138   // While this constructor is sometimes useful, consider using
00139   // vnl_double_3 or vnl_float_3 instead.
00140   vnl_vector_fixed( const T& x0, const T& x1, const T& x2 )
00141   {
00142     assert( n == 3 );
00143     data_[0] = x0; data_[1] = x1; data_[2] = x2;
00144   }
00145 
00146   //: Convenience constructor for 4-D vectors
00147   vnl_vector_fixed( const T& x0, const T& x1, const T& x2, const T& x3 )
00148   {
00149     assert( n == 4 );
00150     data_[0] = x0; data_[1] = x1; data_[2] = x2; data_[3] = x3;
00151   }
00152 
00153   //: Copy operator
00154   vnl_vector_fixed<T,n>& operator=( const vnl_vector_fixed<T,n>& rhs ) {
00155     vcl_memcpy( data_, rhs.data_, sizeof data_ );
00156     return *this;
00157   }
00158 
00159   //: Copy data from a dynamic vector
00160   // The dimensions must match.
00161   vnl_vector_fixed<T,n>& operator=( const vnl_vector<T>& rhs) {
00162     assert( n == rhs.size() );
00163     vcl_memcpy( data_, rhs.data_block(), sizeof data_ );
00164     return *this;
00165   }
00166 
00167   //: Length of the vector.
00168   // This is always \a n.
00169   unsigned size() const { return n; }
00170 
00171   //: Put value at given position in vector.
00172   void put (unsigned int i, T const& v) { data_[i] = v; }
00173 
00174   //: Get value at element i
00175   T get (unsigned int i) const { return data_[i]; }
00176 
00177   //: Set all values to v
00178   void fill( T const& v )
00179   {
00180     for ( size_type i = 0; i < n; ++i )
00181       data_[i] = v;
00182   }
00183 
00184   //: Sets elements to ptr[i]
00185   //  Note: ptr[i] must be valid for i=0..size()-1
00186   void copy_in( T const * ptr )
00187   {
00188     for ( size_type i = 0; i < n; ++i )
00189       data_[i] = ptr[i];
00190   }
00191 
00192   //: Copy elements to ptr[i]
00193   //  Note: ptr[i] must be valid for i=0..size()-1
00194   void copy_out( T* ptr ) const
00195   {
00196     for ( size_type i = 0; i < n; ++i )
00197       ptr[i] = data_[i];
00198   }
00199 
00200   //: Sets elements to ptr[i]
00201   //  Note: ptr[i] must be valid for i=0..size()-1
00202   void set( T const *ptr ) { copy_in(ptr); }
00203 
00204 
00205   //: Return reference to the element at specified index.
00206   // There are assert style boundary checks - #define NDEBUG to turn them off.
00207   T       & operator() (unsigned int i)
00208   {
00209 #if VNL_CONFIG_CHECK_BOUNDS  && (!defined NDEBUG)
00210     assert(i<n);   // Check the index is valid.
00211 #endif
00212     return data_[i];
00213   }
00214 
00215   //: Return reference to the element at specified index.
00216   // There are assert style boundary checks - #define NDEBUG to turn them off.
00217   T const & operator() (unsigned int i) const
00218   {
00219 #if VNL_CONFIG_CHECK_BOUNDS  && (!defined NDEBUG)
00220     assert(i<n);   // Check the index is valid
00221 #endif
00222     return data_[i];
00223   }
00224 
00225   //: Return the i-th element
00226   T& operator[] ( unsigned int i ) { return data_[i]; }
00227 
00228   //: Return the i-th element
00229   const T& operator[] ( unsigned int i ) const { return data_[i]; }
00230 
00231   //: Access the contiguous block storing the elements in the vector.
00232   //  O(1).
00233   //  data_block()[0] is the first element of the vector
00234   T const* data_block() const { return data_; }
00235 
00236   //: Access the contiguous block storing the elements in the vector.
00237   //  O(1).
00238   //  data_block()[0] is the first element of the vector
00239   T      * data_block() { return data_; }
00240 
00241   //----------------------------------------------------------------------
00242   // Conversion to vnl_vector_ref.
00243 
00244   // The const version of as_ref should return a const vnl_vector_ref
00245   // so that the vnl_vector_ref::non_const() cannot be used on
00246   // it. This prevents a const vnl_vector_fixed from being cast into a
00247   // non-const vnl_vector reference, giving a slight increase in type safety.
00248 
00249   //: Explicit conversion to a vnl_vector_ref.
00250   // This is a cheap conversion for those functions that have an interface
00251   // for vnl_vector but not for vnl_vector_fixed. There is also a
00252   // conversion operator that should work most of the time.
00253   // \sa vnl_vector_ref::non_const
00254   vnl_vector_ref<T> as_ref() { return vnl_vector_ref<T>( n, data_ ); }
00255 
00256   //: Explicit conversion to a vnl_vector_ref.
00257   // This is a cheap conversion for those functions that have an interface
00258   // for vnl_vector but not for vnl_vector_fixed. There is also a
00259   // conversion operator that should work most of the time.
00260   // \sa vnl_vector_ref::non_const
00261   const vnl_vector_ref<T> as_ref() const { return vnl_vector_ref<T>( n, const_cast<T*>(data_) ); }
00262 
00263   //: Cheap conversion to vnl_vector_ref
00264   // Sometimes, such as with templated functions, the compiler cannot
00265   // use this user-defined conversion. For those cases, use the
00266   // explicit as_ref() method instead.
00267   operator const vnl_vector_ref<T>() const { return vnl_vector_ref<T>( n, const_cast<T*>(data_) ); }
00268 
00269   //----------------------------------------------------------------------
00270 
00271   //: Type defs for iterators
00272   typedef T element_type;
00273   //: Type defs for iterators
00274   typedef T       *iterator;
00275   //: Iterator pointing to start of data
00276   iterator begin() { return data_; }
00277 
00278   //: Iterator pointing to element beyond end of data
00279   iterator end() { return data_+n; }
00280 
00281   //: Const iterator type
00282   typedef T const *const_iterator;
00283   //: Iterator pointing to start of data
00284   const_iterator begin() const { return data_; }
00285   //: Iterator pointing to element beyond end of data
00286   const_iterator end() const { return data_+n; }
00287 
00288 
00289   //: Apply f to each element.
00290   // Returns a new vector with the result.
00291   vnl_vector_fixed<T,n> apply(T (*f)(T));
00292 
00293   //: Apply f to each element.
00294   // Returns a new vector with the result.
00295   vnl_vector_fixed<T,n> apply(T (*f)(const T&));
00296 
00297   //:
00298   vnl_vector_fixed<T,n>& operator+=( T s ) { self::add( data_, s, data_ ); return *this; }
00299 
00300   //:
00301   vnl_vector_fixed<T,n>& operator-=( T s ) { self::sub( data_, s, data_ ); return *this; }
00302 
00303   //:
00304   vnl_vector_fixed<T,n>& operator*=( T s ) { self::mul( data_, s, data_ ); return *this; }
00305 
00306   //:
00307   vnl_vector_fixed<T,n>& operator/=( T s ) { self::div( data_, s, data_ ); return *this; }
00308 
00309   //:
00310   vnl_vector_fixed<T,n>& operator+=( const vnl_vector_fixed<T,n>& v ) { self::add( data_, v.data_block(), data_ ); return *this; }
00311 
00312   //:
00313   vnl_vector_fixed<T,n>& operator-=( const vnl_vector_fixed<T,n>& v ) { self::sub( data_, v.data_block(), data_ ); return *this; }
00314 
00315   //:
00316   vnl_vector_fixed<T,n>& operator+=( const vnl_vector<T>& v )
00317   {
00318     assert( v.size() == n );
00319     self::add( data_, v.data_block(), data_ ); return *this;
00320   }
00321 
00322   //:
00323   vnl_vector_fixed<T,n>& operator-=( const vnl_vector<T>& v )
00324   {
00325     assert( v.size() == n );
00326     self::sub( data_, v.data_block(), data_ ); return *this;
00327   }
00328 
00329   //:
00330   vnl_vector_fixed<T,n> operator-() const
00331   {
00332     vnl_vector_fixed<T,n> result;
00333     self::sub( (T)0, data_, result.data_ );
00334     return result;
00335   }
00336 
00337   //: Returns a subvector specified by the start index and length. O(n).
00338   vnl_vector<T> extract (unsigned int len, unsigned int start=0) const;
00339 
00340   //: Convert to a vnl_vector.
00341   vnl_vector<T> as_vector() const { return extract(n); }
00342 
00343   //: Replaces elements with index beginning at start, by values of v. O(n).
00344   vnl_vector_fixed& update (vnl_vector<T> const&, unsigned int start=0);
00345 
00346   // norms etc
00347   typedef typename vnl_c_vector<T>::abs_t abs_t;
00348 
00349   //: Return sum of squares of elements
00350   abs_t squared_magnitude() const { return vnl_c_vector<T>::two_nrm2(begin(), size()); }
00351 
00352   //: Return magnitude (length) of vector
00353   abs_t magnitude() const { return two_norm(); }
00354 
00355   //: Return sum of absolute values of the elements
00356   abs_t one_norm() const { return vnl_c_vector<T>::one_norm(begin(), size()); }
00357 
00358   //: Return sqrt of sum of squares of values of elements
00359   abs_t two_norm() const { return vnl_c_vector<T>::two_norm(begin(), size()); }
00360 
00361   //: Return largest absolute element value
00362   abs_t inf_norm() const { return vnl_c_vector<T>::inf_norm(begin(), size()); }
00363 
00364   //: Normalise by dividing through by the magnitude
00365   vnl_vector_fixed<T,n>& normalize() { vnl_c_vector<T>::normalize(begin(), size()); return *this; }
00366 
00367   // These next 6 functions are should really be helper functions since they aren't
00368   // really proper functions on a vector in a philosophical sense.
00369 
00370   //: Root Mean Squares of values
00371   abs_t rms     () const { return vnl_c_vector<T>::rms_norm(begin(), size()); }
00372 
00373   //: Smallest value
00374   T min_value () const { return vnl_c_vector<T>::min_value(begin(), size()); }
00375 
00376   //: Largest value
00377   T max_value () const { return vnl_c_vector<T>::max_value(begin(), size()); }
00378 
00379   //: Location of smallest value
00380   unsigned arg_min() const { return vnl_c_vector<T>::arg_min(begin(), size()); }
00381 
00382   //: Location of largest value
00383   unsigned arg_max() const { return vnl_c_vector<T>::arg_max(begin(), size()); }
00384 
00385   //: Mean of values in vector
00386   T mean() const { return vnl_c_vector<T>::mean(begin(), size()); }
00387 
00388   //: Sum of values in a vector
00389   T sum() const { return vnl_c_vector<T>::sum(begin(), size()); }
00390 
00391   //: Reverse the order of the elements
00392   //  Element i swaps with element size()-1-i
00393   void flip();
00394 
00395   //: Check that size()==sz if not, abort();
00396   // This function does or tests nothing if NDEBUG is defined
00397   void assert_size( unsigned sz ) const { assert( sz == n ); }
00398 
00399   //: Check that this is finite if not, abort();
00400   // This function does or tests nothing if NDEBUG is defined
00401   void assert_finite() const
00402   {
00403 #ifndef NDEBUG
00404     assert_finite_internal();
00405 #endif
00406   }
00407 
00408   //: Return true if its finite
00409   bool is_finite() const;
00410 
00411   //: Return true iff all the entries are zero.
00412   bool is_zero() const;
00413 
00414   //: Return true iff the size is zero.
00415   bool empty() const { return n==0; }
00416 
00417   //: Return true if *this == v
00418   bool operator_eq (vnl_vector_fixed<T,n> const& v) const
00419   {
00420     for ( size_type i = 0; i < n; ++i )
00421       if ( (*this)[i] != v[i] )
00422         return false;
00423     return true;
00424   }
00425 
00426   //: Return true if *this == v
00427   bool operator_eq (vnl_vector<T> const& v) const
00428   {
00429     assert( v.size() == n );
00430     for ( size_type i = 0; i < n; ++i )
00431       if ( (*this)[i] != v[i] )
00432         return false;
00433     return true;
00434   }
00435 
00436 
00437   //: Read from text stream
00438   bool read_ascii(vcl_istream& s);
00439 
00440   //: Display the vector
00441   // Output each element separated by a single space.
00442   void print( vcl_ostream& s ) const;
00443 
00444  public:
00445   // Helper routines for arithmetic. n is the size, and is the
00446   // template parameter.
00447 
00448   inline static void add( const T* a, const T* b, T* r )
00449   {
00450     for ( unsigned int i=0; i < n; ++i,++r,++a,++b )
00451       *r = *a + *b;
00452   }
00453 
00454   inline static void add( const T* a, T b, T* r )
00455   {
00456     for ( unsigned int i=0; i < n; ++i,++r,++a )
00457       *r = *a + b;
00458   }
00459 
00460   inline static void sub( const T* a, const T* b, T* r )
00461   {
00462     for ( unsigned int i=0; i < n; ++i,++r,++a,++b )
00463       *r = *a - *b;
00464   }
00465 
00466   inline static void sub( const T* a, T b, T* r )
00467   {
00468     for ( unsigned int i=0; i < n; ++i,++r,++a )
00469       *r = *a - b;
00470   }
00471 
00472   inline static void sub( T a, const T* b, T* r )
00473   {
00474     for ( unsigned int i=0; i < n; ++i,++r,++b )
00475       *r = a - *b;
00476   }
00477 
00478   inline static void mul( const T* a, const T* b, T* r )
00479   {
00480     for ( unsigned int i=0; i < n; ++i,++r,++a,++b )
00481       *r = *a * *b;
00482   }
00483 
00484   inline static void mul( const T* a, T b, T* r )
00485   {
00486     for ( unsigned int i=0; i < n; ++i,++r,++a )
00487       *r = *a * b;
00488   }
00489 
00490   inline static void div( const T* a, const T* b, T* r )
00491   {
00492     for ( unsigned int i=0; i < n; ++i,++r,++a,++b )
00493       *r = *a / *b;
00494   }
00495 
00496   inline static void div( const T* a, T b, T* r )
00497   {
00498     for ( unsigned int i=0; i < n; ++i,++r,++a )
00499       *r = *a / b;
00500   }
00501 
00502  private:
00503   //: See assert_finite().
00504   void assert_finite_internal() const;
00505 };
00506 
00507 
00508 // --- Vector-scalar operators ----------------------------------------
00509 
00510 //:
00511 // \relatesalso vnl_vector_fixed
00512 template<class T, unsigned int n>
00513 inline vnl_vector_fixed<T,n> operator+( const vnl_vector_fixed<T,n>& v, T s )
00514 {
00515   vnl_vector_fixed<T,n> r;
00516   vnl_vector_fixed<T,n>::add( v.data_block(), s, r.data_block() );
00517   return r;
00518 }
00519 
00520 //:
00521 // \relatesalso vnl_vector_fixed
00522 template<class T, unsigned int n>
00523 inline vnl_vector_fixed<T,n> operator+( const T& s,
00524                                         const vnl_vector_fixed<T,n>& v )
00525 {
00526   vnl_vector_fixed<T,n> r;
00527   vnl_vector_fixed<T,n>::add( v.data_block(), s, r.data_block() );
00528   return r;
00529 }
00530 
00531 //:
00532 // \relatesalso vnl_vector_fixed
00533 template<class T, unsigned int n>
00534 inline vnl_vector_fixed<T,n> operator-( const vnl_vector_fixed<T,n>& v, T s )
00535 {
00536   vnl_vector_fixed<T,n> r;
00537   vnl_vector_fixed<T,n>::sub( v.data_block(), s, r.data_block() );
00538   return r;
00539 }
00540 
00541 //:
00542 // \relatesalso vnl_vector_fixed
00543 template<class T, unsigned int n>
00544 inline vnl_vector_fixed<T,n> operator-( const T& s,
00545                                         const vnl_vector_fixed<T,n>& v )
00546 {
00547   vnl_vector_fixed<T,n> r;
00548   vnl_vector_fixed<T,n>::sub( s, v.data_block(), r.data_block() );
00549   return r;
00550 }
00551 
00552 //:
00553 // \relatesalso vnl_vector_fixed
00554 template<class T, unsigned int n>
00555 inline vnl_vector_fixed<T,n> operator*( const vnl_vector_fixed<T,n>& v, T s )
00556 {
00557   vnl_vector_fixed<T,n> r;
00558   vnl_vector_fixed<T,n>::mul( v.data_block(), s, r.data_block() );
00559   return r;
00560 }
00561 
00562 //:
00563 // \relatesalso vnl_vector_fixed
00564 template<class T, unsigned int n>
00565 inline vnl_vector_fixed<T,n> operator*( const T& s,
00566                                         const vnl_vector_fixed<T,n>& v )
00567 {
00568   vnl_vector_fixed<T,n> r;
00569   vnl_vector_fixed<T,n>::mul( v.data_block(), s, r.data_block() );
00570   return r;
00571 }
00572 
00573 //:
00574 // \relatesalso vnl_vector_fixed
00575 template<class T, unsigned int n>
00576 inline vnl_vector_fixed<T,n> operator/( const vnl_vector_fixed<T,n>& v, T s )
00577 {
00578   vnl_vector_fixed<T,n> r;
00579   vnl_vector_fixed<T,n>::div( v.data_block(), s, r.data_block() );
00580   return r;
00581 }
00582 
00583 
00584 // --- Vector-vector operators ----------------------------------------
00585 //
00586 // Includes overloads for the common case of mixing a fixed with a
00587 // non-fixed. Because the operators are templated, the fixed will not
00588 // be automatically converted to a non-fixed-ref. These do it for you.
00589 
00590 //:
00591 // \relatesalso vnl_vector_fixed
00592 template<class T, unsigned int n>
00593 inline vnl_vector_fixed<T,n> operator+( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00594 {
00595   vnl_vector_fixed<T,n> r;
00596   vnl_vector_fixed<T,n>::add( a.data_block(), b.data_block(), r.data_block() );
00597   return r;
00598 }
00599 
00600 //:
00601 // \relatesalso vnl_vector
00602 // \relatesalso vnl_vector_fixed
00603 template<class T, unsigned int n>
00604 inline vnl_vector<T> operator+( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00605 {
00606   return a.as_ref() + b;
00607 }
00608 
00609 //:
00610 // \relatesalso vnl_vector
00611 // \relatesalso vnl_vector_fixed
00612 template<class T, unsigned int n>
00613 inline vnl_vector<T> operator+( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00614 {
00615   return a + b.as_ref();
00616 }
00617 
00618 //:
00619 // \relatesalso vnl_vector_fixed
00620 template<class T, unsigned int n>
00621 inline vnl_vector_fixed<T,n> operator-( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00622 {
00623   vnl_vector_fixed<T,n> r;
00624   vnl_vector_fixed<T,n>::sub( a.data_block(), b.data_block(), r.data_block() );
00625   return r;
00626 }
00627 
00628 //:
00629 // \relatesalso vnl_vector
00630 // \relatesalso vnl_vector_fixed
00631 template<class T, unsigned int n>
00632 inline vnl_vector<T> operator-( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00633 {
00634   return a.as_ref() - b;
00635 }
00636 
00637 //:
00638 // \relatesalso vnl_vector
00639 // \relatesalso vnl_vector_fixed
00640 template<class T, unsigned int n>
00641 inline vnl_vector<T> operator-( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00642 {
00643   return a - b.as_ref();
00644 }
00645 
00646 //:
00647 // \relatesalso vnl_vector_fixed
00648 template<class T, unsigned int n>
00649 inline vnl_vector_fixed<T,n> element_product( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00650 {
00651   vnl_vector_fixed<T,n> r;
00652   vnl_vector_fixed<T,n>::mul( a.data_block(), b.data_block(), r.data_block() );
00653   return r;
00654 }
00655 
00656 //:
00657 // \relatesalso vnl_vector
00658 // \relatesalso vnl_vector_fixed
00659 template<class T, unsigned int n>
00660 inline vnl_vector<T> element_product( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00661 {
00662   assert( b.size() == n );
00663   vnl_vector<T> r(n);
00664   vnl_vector_fixed<T,n>::mul( a.data_block(), b.data_block(), r.data_block() );
00665   return r;
00666 }
00667 
00668 //:
00669 // \relatesalso vnl_vector
00670 // \relatesalso vnl_vector_fixed
00671 template<class T, unsigned int n>
00672 inline vnl_vector<T> element_product( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00673 {
00674   assert( a.size() == n );
00675   vnl_vector<T> r(n);
00676   vnl_vector_fixed<T,n>::mul( a.data_block(), b.data_block(), r.data_block() );
00677   return r;
00678 }
00679 
00680 //:
00681 // \relatesalso vnl_vector_fixed
00682 template<class T, unsigned int n>
00683 inline vnl_vector_fixed<T,n> element_quotient( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00684 {
00685   vnl_vector_fixed<T,n> r;
00686   vnl_vector_fixed<T,n>::div( a.data_block(), b.data_block(), r.data_block() );
00687   return r;
00688 }
00689 
00690 //:
00691 // \relatesalso vnl_vector
00692 // \relatesalso vnl_vector_fixed
00693 template<class T, unsigned int n>
00694 inline vnl_vector<T> element_quotient( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00695 {
00696   assert( b.size() == n );
00697   vnl_vector<T> r(n);
00698   vnl_vector_fixed<T,n>::div( a.data_block(), b.data_block(), r.data_block() );
00699   return r;
00700 }
00701 
00702 //:
00703 // \relatesalso vnl_vector
00704 // \relatesalso vnl_vector_fixed
00705 template<class T, unsigned int n>
00706 inline vnl_vector<T> element_quotient( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00707 {
00708   assert( a.size() == n );
00709   vnl_vector<T> r(n);
00710   vnl_vector_fixed<T,n>::div( a.data_block(), b.data_block(), r.data_block() );
00711   return r;
00712 }
00713 
00714 //:
00715 // \relatesalso vnl_vector_fixed
00716 template<class T, unsigned n>
00717 inline T dot_product( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00718 {
00719   return dot_product( a.as_ref(), b.as_ref() );
00720 }
00721 
00722 //:
00723 // \relatesalso vnl_vector
00724 // \relatesalso vnl_vector_fixed
00725 template<class T, unsigned n>
00726 inline T dot_product( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00727 {
00728   return dot_product( a.as_ref(), b );
00729 }
00730 
00731 //:
00732 // \relatesalso vnl_vector
00733 // \relatesalso vnl_vector_fixed
00734 template<class T, unsigned n>
00735 inline T dot_product( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00736 {
00737   return dot_product( a, b.as_ref() );
00738 }
00739 
00740 //:
00741 // \relatesalso vnl_vector
00742 // \relatesalso vnl_vector_fixed
00743 template<class T, unsigned int n>
00744 inline vnl_matrix<T> outer_product( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00745 {
00746   return outer_product( a, b.as_ref());
00747 }
00748 
00749 //:
00750 // \relatesalso vnl_vector
00751 // \relatesalso vnl_vector_fixed
00752 template<class T, unsigned int n>
00753 inline vnl_matrix<T> outer_product( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00754 {
00755   return outer_product( a.as_ref(), b);
00756 }
00757 
00758 //:
00759 // \relatesalso vnl_vector_fixed
00760 template<class T, unsigned n>
00761 inline T angle( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00762 {
00763   return angle( a.as_ref(), b.as_ref() );
00764 }
00765 
00766 //:
00767 // \relatesalso vnl_vector
00768 // \relatesalso vnl_vector_fixed
00769 template<class T, unsigned n>
00770 inline T angle( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00771 {
00772   return angle( a.as_ref(), b );
00773 }
00774 
00775 //:
00776 // \relatesalso vnl_vector
00777 // \relatesalso vnl_vector_fixed
00778 template<class T, unsigned n>
00779 inline T angle( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00780 {
00781   return angle( a, b.as_ref() );
00782 }
00783 
00784 
00785 //:
00786 // \relatesalso vnl_vector_fixed
00787 template<class T, unsigned n>
00788 inline T vnl_vector_ssd( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00789 {
00790   return vnl_vector_ssd( a.as_ref(), b.as_ref() );
00791 }
00792 
00793 //:
00794 // \relatesalso vnl_vector
00795 // \relatesalso vnl_vector_fixed
00796 template<class T, unsigned n>
00797 inline T vnl_vector_ssd( const vnl_vector_fixed<T,n>& a, const vnl_vector<T>& b )
00798 {
00799   return vnl_vector_ssd( a.as_ref(), b );
00800 }
00801 
00802 //:
00803 // \relatesalso vnl_vector
00804 // \relatesalso vnl_vector_fixed
00805 template<class T, unsigned n>
00806 inline T vnl_vector_ssd( const vnl_vector<T>& a, const vnl_vector_fixed<T,n>& b )
00807 {
00808   return vnl_vector_ssd( a, b.as_ref() );
00809 }
00810 
00811 
00812 //:
00813 // \relatesalso vnl_vector_fixed
00814 template<class T, unsigned int n>
00815 inline bool operator==( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00816 {
00817   return a.operator_eq(b);
00818 }
00819 
00820 //:
00821 // \relatesalso vnl_vector
00822 // \relatesalso vnl_vector_fixed
00823 template<class T, unsigned int n>
00824 inline bool operator==( vnl_vector_fixed<T,n> const& a, vnl_vector<T> const& b )
00825 {
00826   return a.operator_eq(b);
00827 }
00828 
00829 //:
00830 // \relatesalso vnl_vector
00831 // \relatesalso vnl_vector_fixed
00832 template<class T, unsigned int n>
00833 inline bool operator==( vnl_vector<T> const& a, vnl_vector_fixed<T,n> const& b )
00834 {
00835   return b.operator_eq(a);
00836 }
00837 
00838 //:
00839 // \relatesalso vnl_vector_fixed
00840 template<class T, unsigned int n>
00841 inline bool operator!=( const vnl_vector_fixed<T,n>& a, const vnl_vector_fixed<T,n>& b )
00842 {
00843   return ! a.operator_eq(b);
00844 }
00845 
00846 //:
00847 // \relatesalso vnl_vector
00848 // \relatesalso vnl_vector_fixed
00849 template<class T, unsigned int n>
00850 inline bool operator!=( vnl_vector_fixed<T,n> const& a, vnl_vector<T> const& b )
00851 {
00852   return ! a.operator_eq(b);
00853 }
00854 
00855 //:
00856 // \relatesalso vnl_vector
00857 // \relatesalso vnl_vector_fixed
00858 template<class T, unsigned int n>
00859 inline bool operator!=( vnl_vector<T> const& a, vnl_vector_fixed<T,n> const& b )
00860 {
00861   return ! b.operator_eq(a);
00862 }
00863 
00864 
00865 // --- I/O operators -------------------------------------------------
00866 
00867 
00868 //:
00869 // \relatesalso vnl_vector_fixed
00870 template<class T, unsigned int n>
00871 inline
00872 vcl_ostream& operator<< ( vcl_ostream& ostr, const vnl_vector_fixed<T,n>& v )
00873 {
00874   v.print( ostr );
00875   return ostr;
00876 }
00877 
00878 //:
00879 // \relatesalso vnl_vector_fixed
00880 template<class T, unsigned int n>
00881 inline
00882 vcl_istream& operator>> ( vcl_istream& ostr, vnl_vector_fixed<T,n>& v )
00883 {
00884   v.read_ascii( ostr );
00885   return ostr;
00886 }
00887 
00888 #endif // vnl_vector_fixed_h_

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