C:/programs/SCPPNT/src/include/vec.h

Go to the documentation of this file.
00001 /*! \file vec.h
00002  \brief Definition of simple concrete vector class.
00003  
00004  Templated numerical vector class based on Template Numerical Toolkit 
00005  (http://math.nist.gov/tnt) Vector class.
00006 
00007  This class adds the following to the TNT Vector class:
00008  
00009  -# Assignment operators (+=, -=, *=, /=)
00010  -# Errors result in an exception being thrown rather than the program being aborted.
00011 
00012  */
00013 
00014 /*
00015 
00016  Simple C++ Numerical Toolkit (SCPPNT)
00017  http://www.smallwaters.com/software/cpp/scppnt.html
00018  This release updates original work contributed by 
00019  Brad Hanson (http://www.b-a-h.com/) in 2001.
00020 
00021  */
00022 
00023 // This class is based on the Vector class in:
00024 /*
00025  *
00026  * Template Numerical Toolkit (TNT): Linear Algebra Module
00027  *
00028  * Mathematical and Computational Sciences Division
00029  * National Institute of Technology,
00030  * Gaithersburg, MD USA
00031  *
00032  *
00033  * This software was developed at the National Institute of Standards and
00034  * Technology (NIST) by employees of the Federal Government in the course
00035  * of their official duties. Pursuant to title 17 Section 105 of the
00036  * United States Code, this software is not subject to copyright protection
00037  * and is in the public domain.  The Template Numerical Toolkit (TNT) is
00038  * an experimental system.  NIST assumes no responsibility whatsoever for
00039  * its use by other parties, and makes no guarantees, expressed or implied,
00040  * about its quality, reliability, or any other characteristic.
00041  *
00042  * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
00043  * see http://math.nist.gov/tnt for latest updates.
00044  *
00045  */
00046 
00047 // Basic TNT  numerical vector (0-based [i] AND 1-based (i) indexing )
00048 //
00049 
00050 #ifndef SCPPNT_VEC_H
00051 #define SCPPNT_VEC_H
00052 
00053 #include <iterator>
00054 
00055 #ifdef SCPPNT_NO_DIR_PREFIX
00056 #include "scppnt.h"
00057 #include "scppnt_error.h"
00058 #else
00059 #include "scppnt/scppnt.h"
00060 #include "scppnt/scppnt_error.h"
00061 #endif
00062 
00063 #ifdef SCPPNT_BOUNDS_CHECK
00064 #ifdef SCPPNT_NO_DIR_PREFIX
00065 #include "slice_pointer.h"
00066 #else
00067 #include "scppnt/slice_pointer.h"
00068 #endif
00069 #endif
00070 
00071 // If SCPPNT_NO_IO is defined then functions that read and write a vector to a file
00072 // and the constructor from a string are not compiled
00073 #ifndef SCPPNT_NO_IO
00074 #include <string>
00075 #include <iostream>
00076 #include <strstream>
00077 #endif
00078 #include <cstdlib> // for NULL
00079 #include <iterator>
00080 #include <algorithm>
00081 
00082 namespace SCPPNT
00083 {
00084 
00085   /*!
00086    \brief Simple concrete vector class for numerical computation.
00087    
00088    
00089    Templated numerical vector class based on Template Numerical Toolkit
00090    Vector class. Element access through 0-based [i] and 1-based (i)
00091    indexing, and iterators.
00092 
00093    This class adds the following to the TNT Matrix class:
00094    
00095    -# Assignment operators (+=, -=, *=, /=)
00096    -# Errors result in an exception being thrown rather than the program being aborted.
00097 
00098    */
00099   template<class T> class Vector
00100   {
00101 
00102 public:
00103 
00104     typedef Subscript size_type; //!< Subscript type
00105     typedef T value_type; //!< Type of elements stored in vector
00106     typedef T element_type; //!< Type of elements stored in vector
00107     typedef T& reference; //!< Reference to type stored in vector
00108     typedef const T& const_reference;//!< Reference to type stored in constant vector
00109 
00110     // If SCPPNT_BOUNDS_CHECK is defined use slice_pointer_base
00111     // in order to check for an iterator pointing to an
00112     // element outside of the vector
00113 #ifdef SCPPNT_BOUNDS_CHECK
00114     typedef slice_pointer_base<T, T*, T&> pointer;
00115     typedef slice_pointer_base<T, T*, T&> iterator;
00116     typedef slice_pointer_base<T, const T*, const T&> const_iterator;
00117 #else
00118     typedef T* pointer; //!< Pointer to type stored in vector
00119     typedef T* iterator; //!< Iterator over elements in vector
00120     typedef const T* const_iterator; //!< Iterator over elements in constant vector
00121 #endif
00122 
00123     //! Returns lower bound of subscript
00124     Subscript lbound() const;
00125 
00126     // iterators
00127 
00128     iterator begin(); //!< Return iterator pointing to first element of vector.
00129     iterator end(); //!< Return iterator pointing to one past last element of vector.
00130     const_iterator begin() const; //!< Return iterator pointing to first element of constant vector.
00131     const_iterator end() const; //!< Return iterator pointing to one past last element of constant vector.
00132 
00133     //! Destructor
00134     ~Vector();
00135 
00136     //! Default constructor
00137     Vector();
00138 
00139     //! Construct vector of given size, do not initialize
00140     Vector(Subscript N);
00141 
00142     //! Copy constructor
00143     Vector(const Vector<T> &A);
00144 
00145     //! Constructor which assigns all elements to a particular value.
00146     Vector(Subscript N, const T& value);
00147 
00148 #ifndef SCPPNT_NO_IO
00149     //! Constructor that reads elements from a string
00150     Vector(Subscript N, const std::string &s);
00151 #endif
00152 
00153     /* The following member template must be defined within
00154      the class definition for some compilers (such as Visual C++ 6).
00155      The definitions of other members are given outside the class definition */
00156 
00157     /*! \brief Create a vector and assign elements from an iterator.
00158      
00159      \param begin Iterator pointing to the first element of a sequence
00160      of values assigned to elements of the vector created.
00161      
00162      \param end Iterator pointing to one past last element of a sequence
00163      of values assigned to elements of the vector created.
00164      
00165      */
00166     template<class IT> Vector(IT begin, IT end) :
00167       v_(0)
00168     {
00169 #ifndef BOOST_MSVC
00170       // "typename" keyword added (ww, 12-2-2007)
00171       typename std::iterator_traits<IT>::difference_type N = std::distance(begin, end);
00172 #else
00173       // std::iterator_traits<IT>::difference_type does not compile
00174       // with Microsoft Visual C++ 6.
00175       unsigned long N = std::distance(begin, end);
00176 #endif
00177       initialize(N);
00178 
00179       iterator i = this->begin();
00180       while (N--)
00181       {
00182         *i = *begin;
00183         ++i;
00184         ++begin;
00185       }
00186     }
00187 
00188     //! Resize vector (current elements are not retained).
00189     Vector<T>& newsize(Subscript N);
00190 
00191     // assignments
00192     //
00193 
00194     //! Assignment from vector.
00195     Vector<T>& operator=(const Vector<T> &A);
00196 
00197     //! Assign all elements to be equal to a scalar.
00198     Vector<T>& operator=(const T& scalar);
00199 
00200     // assignment operators
00201 
00202     //! Add vector rhs to vector
00203     Vector<T>& operator+=(const Vector<T> &rhs);
00204 
00205     //! Add scalar to elements of vector
00206     Vector<T>& operator+=(const T& value);
00207 
00208     //! Subtract vector rhs from vector.
00209     Vector<T>& operator-=(const Vector<T> &rhs);
00210 
00211     //! Subtract scalar from elements of vector.
00212     Vector<T>& operator-=(const T& value);
00213 
00214     //! Multiply each element of vector by corresponding element in rhs (element-wise multiply)
00215     Vector<T>& operator*=(const Vector<T> &rhs);
00216 
00217     //! Multiply each element of vector by scalar.
00218     Vector<T>& operator*=(const T& value);
00219 
00220     //! Divide each element of vector by corresponding element in rhs (element-wise divide)
00221     Vector<T>& operator/=(const T& value);
00222 
00223     //! Return number of elements in vector
00224     Subscript dim() const;
00225 
00226     //! Return number of elements in vector
00227     Subscript size() const;
00228 
00229     /***** subscripting *****/
00230 
00231     //! One-based subscripting (v(1) returns first element of v)
00232     inline reference operator()(Subscript i);
00233 
00234     //! One-based subscripting for constant vector
00235     inline const_reference operator()(Subscript i) const;
00236 
00237     //! Zero-based subscripting (v[0] returns first element of v)
00238     inline reference operator[](Subscript i);
00239 
00240     //! Zero-based subscripting for constant vector
00241     inline const_reference operator[](Subscript i) const;
00242 
00243 protected:
00244     T* v_; //!< Pointer to contents of vector.
00245     T* vm1_; //!< Pointer adjustment for optimizied 1-based indexing.
00246     Subscript n_; //!< Number of elements in vector.
00247 
00248     // internal helper functions for allocation, initialization, and deallocation
00249 
00250     //! Allocate storage for vector
00251     void initialize(Subscript N);
00252 
00253     //! Assign elements of vector from array v
00254     void copy(const T* v);
00255 
00256     //! Set all elements of vector equal to val
00257     void set(const T& val);
00258 
00259     //! Release storage allocated for vector
00260     void destroy();
00261 
00262   };
00263 
00264   /***** Definitions of member functions *****/
00265 
00266   template<class T> void Vector<T>::initialize(Subscript N)
00267   {
00268     // adjust pointers so that they are 1-offset:
00269     // v_[] is the internal contiguous array, it is still 0-offset
00270     //
00271 
00272     if (v_ != NULL)
00273       throw LogicError(0, "v_ is not NULL", "SCPPNT::Vector::initialize");
00274 
00275     v_ = new T[N];
00276 
00277     vm1_ = v_-1;
00278     n_ = N;
00279   }
00280 
00281   template<class T> void Vector<T>::copy(const T* v)
00282   {
00283     Subscript N = n_;
00284     Subscript i;
00285 
00286 #ifdef SCPPNT_UNROLL_LOOPS
00287     Subscript Nmod4 = N & 3;
00288     Subscript N4 = N - Nmod4;
00289 
00290     for (i=0; i<N4; i+=4)
00291     {
00292       v_[i] = v[i];
00293       v_[i+1] = v[i+1];
00294       v_[i+2] = v[i+2];
00295       v_[i+3] = v[i+3];
00296     }
00297 
00298     for (i=N4; i< N; i++)
00299     v_[i] = v[i];
00300 #else
00301 
00302     for (i=0; i< N; i++)
00303       v_[i] = v[i];
00304 #endif      
00305   }
00306 
00307   template<class T> void Vector<T>::set(const T& val)
00308   {
00309     Subscript N = n_;
00310     Subscript i;
00311 
00312 #ifdef SCPPNT_UNROLL_LOOPS
00313     Subscript Nmod4 = N & 3;
00314     Subscript N4 = N - Nmod4;
00315 
00316     for (i=0; i<N4; i+=4)
00317     {
00318       v_[i] = val;
00319       v_[i+1] = val;
00320       v_[i+2] = val;
00321       v_[i+3] = val;
00322     }
00323 
00324     for (i=N4; i< N; i++)
00325     v_[i] = val;
00326 #else
00327 
00328     for (i=0; i< N; i++)
00329       v_[i] = val;
00330 
00331 #endif      
00332   }
00333 
00334   template<class T> void Vector<T>::destroy()
00335   {
00336     /* do nothing, if no memory has been previously allocated */
00337     if (v_ == NULL)
00338       return;
00339 
00340     /* if we are here, then matrix was previously allocated */
00341     delete [] (v_);
00342 
00343     v_ = NULL;
00344     vm1_ = NULL;
00345   }
00346 
00347   // destructor
00348   template<class T> Vector<T>::~Vector()
00349   {
00350     destroy();
00351   }
00352 
00353   // constructors
00354 
00355   template<class T> Vector<T>::Vector() :
00356     v_(0), vm1_(0), n_(0)
00357   {
00358   }
00359 
00360   template<class T> Vector<T>::Vector(Subscript N) :
00361     v_(0), vm1_(0)
00362   {
00363     initialize(N);
00364   }
00365 
00366   template<class T> Vector<T>::Vector(const Vector<T> &A) :
00367     v_(0), vm1_(0), n_(0)
00368   {
00369     initialize(A.n_);
00370     copy(A.v_);
00371   }
00372 
00373   template<class T> Vector<T>::Vector(Subscript N, const T& value) :
00374     v_(0), vm1_(0)
00375   {
00376     initialize(N);
00377     set(value);
00378   }
00379 
00380   // Initialize from an iterator
00381   // This definition is contained within the class definition above
00382   // so that it will compile using Visual C++ 6.
00383   // template <class T>
00384   // template <class IT>
00385   // Vector<T>::Vector(IT begin, IT end)
00386 
00387 #ifndef SCPPNT_NO_IO
00388   /*!
00389    Constructor that reads elements from a string
00390    
00391    \param N
00392    Number of elements in vector.
00393    \param s
00394    String containing initial elements of matrix in
00395    row-major order separated by white space.
00396    */
00397   template<class T> Vector<T>::Vector(Subscript N, const std::string &s) :
00398     v_(0), vm1_(0), n_(0)
00399   {
00400     initialize(N);
00401     std::istrstream ins(s.c_str());
00402 
00403     Subscript i;
00404 
00405     for (i=0; i<N; i++)
00406       ins >> v_[i];
00407   }
00408 #endif
00409 
00410   // methods
00411   // 
00412   template<class T> Vector<T>& Vector<T>::newsize(Subscript N)
00413   {
00414     if (n_ == N)
00415       return *this;
00416 
00417     destroy();
00418     initialize(N);
00419 
00420     return *this;
00421   }
00422 
00423   // assignments
00424   //
00425   template<class T> Vector<T>& Vector<T>::operator=(const Vector<T> &A)
00426   {
00427     if (v_ == A.v_)
00428     return *this;
00429 
00430     if (n_ == A.n_) // no need to re-alloc
00431     copy(A.v_);
00432 
00433     else
00434     {
00435       destroy();
00436       initialize(A.n_);
00437       copy(A.v_);
00438     }
00439 
00440     return *this;
00441   }
00442 
00443   // assign all elements to equal a scalar
00444   template <class T>
00445   Vector<T>& Vector<T>::operator=(const T& scalar)
00446   {
00447     set(scalar);
00448     return *this;
00449   }
00450 
00451   // vector operator +=
00452   // Replace each element of vector with the element plus
00453   // the corresponding element of rhs.
00454   template <class T>
00455   Vector<T>& Vector<T>::operator+=(const Vector<T> &rhs)
00456   {
00457 
00458     if (n_ != rhs.dim()) throw BadDimension("SCPPNT::Vector::operator+=");
00459 
00460     const_iterator rhsiter = rhs.begin();
00461     iterator end = this->end();
00462     for (iterator p = begin(); p != end; ++p, ++rhsiter)
00463     {
00464       *p += *rhsiter;
00465     }
00466 
00467     return *this;
00468 
00469   }
00470 
00471   // scalar operator += (add a scalar to each element)
00472   template <class T>
00473   Vector<T>& Vector<T>::operator+=(const T& value)
00474   {
00475     iterator end = this->end();
00476     for (iterator p = begin(); p != end; ++p)
00477     {
00478       *p += value;
00479     }
00480 
00481     return *this;
00482 
00483   }
00484 
00485   // vector operator -=
00486   // Replace each element of vector with the element minus
00487   // the corresponding element of rhs.
00488   template <class T>
00489   Vector<T>& Vector<T>::operator-=(const Vector<T> &rhs)
00490   {
00491 
00492     if (n_ != rhs.dim()) throw BadDimension("SCPPNT::Vector::operator-=");
00493 
00494     const_iterator rhsiter = rhs.begin();
00495     iterator end = this->end();
00496     for (iterator p = begin(); p != end; ++p, ++rhsiter)
00497     {
00498       *p -= *rhsiter;
00499     }
00500 
00501     return *this;
00502 
00503   }
00504 
00505   // scalar operator -= (subtract a scalar from each element)
00506   template <class T>
00507   Vector<T>& Vector<T>::operator-=(const T& value)
00508   {
00509     iterator end = this->end();
00510     for (iterator p = begin(); p != end; ++p)
00511     {
00512       *p -= value;
00513     }
00514 
00515     return *this;
00516 
00517   }
00518 
00519   // vector operator *=
00520   // Replace each element of vector with the product of the
00521   // element and the corresponding element of rhs.
00522   template <class T>
00523   Vector<T>& Vector<T>::operator*=(const Vector<T> &rhs)
00524   {
00525 
00526     if (n_ != rhs.dim()) throw BadDimension("SCPPNT::Vector::operator*=");
00527 
00528     const_iterator rhsiter = rhs.begin();
00529     iterator end = this->end();
00530     for (iterator p = begin(); p != end; ++p, ++rhsiter)
00531     {
00532       *p *= *rhsiter;
00533     }
00534 
00535     return *this;
00536 
00537   }
00538 
00539   // scalar operator *= (multiply each element by scalar)
00540   template <class T>
00541   Vector<T>& Vector<T>::operator*=(const T& value)
00542   {
00543     iterator end = this->end();
00544     for (iterator p = begin(); p != end; ++p)
00545     {
00546       *p *= value;
00547     }
00548 
00549     return *this;
00550 
00551   }
00552 
00553   // scalar operator /= (divide each element by scalar)
00554   template <class T>
00555   Vector<T>& Vector<T>::operator/=(const T& value)
00556   {
00557     iterator end = this->end();
00558     for (iterator p = begin(); p != end; ++p)
00559     {
00560       *p /= value;
00561     }
00562 
00563     return *this;
00564 
00565   }
00566 
00567   template <class T>
00568   inline Subscript Vector<T>::lbound() const
00569   { return 1;}
00570 
00571   template <class T>
00572   inline Subscript Vector<T>::dim() const
00573   {
00574     return n_;
00575   }
00576 
00577   template <class T>
00578   inline Subscript Vector<T>::size() const
00579   {
00580     return n_;
00581   }
00582 
00583   // subscripting
00584   template <class T>
00585   inline typename Vector<T>::reference Vector<T>::operator()(Subscript i)
00586   {
00587 #ifdef SCPPNT_BOUNDS_CHECK
00588     if (i < 1 || i > n_) throw BoundsError("SCPPNT::Vector::operator()");
00589 #endif
00590     return vm1_[i];
00591   }
00592 
00593   template <class T>
00594   inline typename Vector<T>::const_reference Vector<T>::operator() (Subscript i) const
00595   {
00596 #ifdef SCPPNT_BOUNDS_CHECK
00597     if (i < 1 || i > n_) throw BoundsError("SCPPNT::Vector::operator() const");
00598 #endif
00599     return vm1_[i];
00600   }
00601 
00602   template <class T>
00603   inline typename Vector<T>::reference Vector<T>::operator[](Subscript i)
00604   {
00605 #ifdef SCPPNT_BOUNDS_CHECK
00606     if (i < 0 || i >= n_) throw BoundsError("SCPPNT::Vector::operator[]");
00607 #endif
00608     return v_[i];
00609   }
00610 
00611   template <class T>
00612   inline typename Vector<T>::const_reference Vector<T>::operator[](Subscript i) const
00613   {
00614 #ifdef SCPPNT_BOUNDS_CHECK
00615     if (i < 0 || i >= n_) throw BoundsError("SCPPNT::Vector::operator[] const");
00616 #endif
00617     return v_[i];
00618   }
00619 
00620   // iterators
00621   template <class T>
00622   inline typename Vector<T>::iterator Vector<T>::begin()
00623   {
00624 #ifdef SCPPNT_BOUNDS_CHECK
00625     return iterator(v_, 1, n_);
00626 #else
00627     return v_;
00628 #endif
00629   }
00630 
00631   template <class T>
00632   inline typename Vector<T>::iterator Vector<T>::end()
00633   {
00634 #ifdef SCPPNT_BOUNDS_CHECK
00635     iterator p(v_, 1, n_);
00636     return p + n_;
00637 #else
00638     return v_ + n_;
00639 #endif
00640   }
00641 
00642   template <class T>
00643   inline typename Vector<T>::const_iterator Vector<T>::begin() const
00644   {
00645 #ifdef SCPPNT_BOUNDS_CHECK
00646     return const_iterator(v_, 1, n_);
00647 #else
00648     return v_;
00649 #endif
00650   }
00651 
00652   template <class T>
00653   inline typename Vector<T>::const_iterator Vector<T>::end() const
00654   {
00655 #ifdef SCPPNT_BOUNDS_CHECK
00656     const const_iterator p(v_, 1, n_);
00657     return p + n_;
00658 #else
00659     return v_ + n_;
00660 #endif
00661   }
00662 
00663 #ifndef SCPPNT_NO_IO
00664   /* ***************************  I/O  ********************************/
00665 
00666   /*!
00667    \brief Write a vector to an output stream.
00668    
00669    Writes the number of elements in the vector, followed
00670    by a new line. The elements of the vector are then
00671    written on consecutive lines.
00672    */
00673   template <class T>
00674   std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
00675   {
00676     Subscript N=A.dim();
00677 
00678     s << N << std::endl;
00679 
00680     for (Subscript i=0; i<N; i++)
00681     s << A[i] << " " << std::endl;
00682     s << std::endl;
00683 
00684     return s;
00685   }
00686 
00687   /*!
00688    \brief Read elements of a vector from an input stream.
00689    
00690    Reads the number of elements in the vector followed
00691    by the elements of the vector. All values read
00692    should be separated by white space.
00693    */
00694   template <class T>
00695   std::istream & operator>>(std::istream &s, Vector<T> &A)
00696   {
00697 
00698     Subscript N;
00699 
00700     s >> N;
00701 
00702     A.newsize(N);
00703 
00704     for (Subscript i=0; i<N; i++)
00705     s >> A[i];
00706 
00707     return s;
00708   }
00709 #endif
00710 
00711   // *******************[ basic vector algorithms ]***************************
00712 
00713   //! Add a vector to a vector and return a new vector containing the sum.
00714   template <class T>
00715   Vector<T> operator+(const Vector<T> &lhs,
00716       const Vector<T> &rhs)
00717   {
00718     return Vector<T>(lhs) += rhs;
00719   }
00720 
00721   //! Add add a scalar to each element of a vector and return a new vector containing the sum.
00722   template <class T>
00723   Vector<T> operator+(const Vector<T> &lhs,
00724       const T value)
00725   {
00726     return Vector<T>(lhs) += value;
00727   }
00728 
00729   //! Subtract the vector rhs from the vector lhs and return a new vector containing the difference.
00730   template <class T>
00731   Vector<T> operator-(const Vector<T> &lhs,
00732       const Vector<T> &rhs)
00733   {
00734     return Vector<T>(lhs) -= rhs;
00735   }
00736 
00737   //! Subtract scalar from each element of a vector a return a new vector containing the difference.
00738   template <class T>
00739   Vector<T> operator-(const Vector<T> &lhs,
00740       const T value)
00741   {
00742     return Vector<T>(lhs) -= value;
00743   }
00744 
00745   //! Multiply corresponding elements of two vectors and return a new vector containing the product.
00746   template <class T>
00747   Vector<T> operator*(const Vector<T> &lhs,
00748       const Vector<T> &rhs)
00749   {
00750     return Vector<T>(lhs) *= rhs;
00751   }
00752 
00753   //! Multiply each element of a vector by a scalar and return a new vector containing the product.
00754   template <class T>
00755   Vector<T> operator*(const Vector<T> &lhs,
00756       const T value)
00757   {
00758     return Vector<T>(lhs) *= value;
00759   }
00760 
00761   /***** Dot products *****/
00762 
00763   /*! \brief Dot product of values pointed to by two iterators
00764 
00765    Returns sum of products of corresponding elements pointed to by
00766    the iterators i1 and i2.
00767    
00768    \param N Number of elements in dot product
00769    \param i1 Iterator to first sequence of elements to use for product.
00770    \param i2 Iterator to second sequence of elements to use for product.
00771 
00772    */
00773   template <class IT1, class IT2>
00774   typename std::iterator_traits<IT1>::value_type dot_prod(Subscript N, IT1 i1, IT2 i2)
00775   {
00776 
00777     typename std::iterator_traits<IT1>::value_type sum = 0;
00778     while(N--)
00779     {
00780       sum += *i1 * *i2;
00781       ++i1;
00782       ++i2;
00783     }
00784 
00785     return sum;
00786   }
00787 
00788   //! Dot product of two vectors.
00789   template <class T>
00790   inline T dot_prod(const Vector<T> &A, const Vector<T> &B)
00791   {
00792     Subscript N = A.dim();
00793 
00794     if (N != B.dim()) throw BadDimension("SCPPNT::dot_prod()");
00795 
00796     return dot_prod(N, A.begin(), B.begin());
00797   }
00798 
00799 } /* namespace SCPPNT */
00800 
00801 #endif
00802 // SCPPNT_VEC_H

Generated on Tue Dec 18 23:34:06 2007 for SCPPNT by  doxygen 1.5.4