ML Reference
MeVis/Foundation/Sources/MLLinearAlgebra/mlFloatingPointVector.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //=====================================================================================
00004 
00009 //=====================================================================================
00010 #ifndef __mlFloatingPointVector_H
00011 #define __mlFloatingPointVector_H
00012 
00013 //------------------------------------------------------------------------
00014 // Includes
00015 //----------------------------------------------------------------------
00016 #ifndef __mlLinearAlgebraSystem_H
00017 #include "mlLinearAlgebraSystem.h"
00018 #endif
00019 
00020 //------------------------------------------------------------------------
00022 //------------------------------------------------------------------------
00023 typedef double (*ML_LA_FROM_DOUBLE_TO_DOUBLE)(double);
00024 
00025 //------------------------------------------------------------------------
00026 // Put all stuff in a specific ML_LA_NAMESPACE namespace to avoid
00027 // collisions with other libraries.
00028 //------------------------------------------------------------------------
00029 ML_LA_START_NAMESPACE
00030 
00033 template <class DT, size_t size>
00034 class FloatingPointVectorDataContainerBase
00035 {
00036 protected:
00037   DT _buffer[size];
00038 };
00039 
00040 
00041 //------------------------------------------------------------------------
00053 //------------------------------------------------------------------------
00054 template <class T, size_t size, class DataContainer = FloatingPointVectorDataContainerBase<T, size> >
00055 class FloatingPointVector : public DataContainer
00056 {
00057 
00058 public:
00059 
00061   typedef T ComponentType;
00062 
00065   enum { Size = size };
00066 
00067   //----------------------------------------------------------------------
00069 
00070   //----------------------------------------------------------------------
00073   explicit FloatingPointVector(T value=T(0));
00074 
00076   FloatingPointVector<T, size, DataContainer>& operator=(T value);
00078 
00079 
00080   //----------------------------------------------------------------------
00082 
00083   //----------------------------------------------------------------------
00085   bool operator==(const FloatingPointVector<T, size, DataContainer>& buffer) const;
00086 
00088   bool operator!=(const FloatingPointVector<T, size, DataContainer>& buffer) const;
00089 
00097   bool operator <(const FloatingPointVector<T, size, DataContainer>& buffer) const;
00099 
00100 
00101   //----------------------------------------------------------------------
00103 
00104   //----------------------------------------------------------------------
00108   const T& operator[](const size_t i) const;
00109 
00113   T& operator[](const size_t i);
00115 
00116 
00117   //----------------------------------------------------------------------
00119 
00120   //----------------------------------------------------------------------
00122   size_t getSize() const;
00123 
00126   T norm2() const;
00127 
00130   T norm2(const FloatingPointVector<T, size, DataContainer>& weight) const;
00131 
00134   T dot(const FloatingPointVector<T, size, DataContainer>& buffer) const;
00135 
00138   T normalize();
00139 
00141   T length() const;
00142 
00144   inline T distance(const FloatingPointVector<T, size, DataContainer>& buffer) const
00145   {
00146     return (*this - buffer).length();
00147   }
00148 
00150   inline T distanceSquared(const FloatingPointVector<T, size, DataContainer>& buffer) const
00151   {
00152     return (*this - buffer).lengthSquared();
00153   }
00154 
00155 
00156 
00157 #ifdef ML_DEPRECATED
00158 
00159 
00160 
00161 
00162   inline ML_DEPRECATED T Normalize() { return normalize(); }
00163 
00166   inline ML_DEPRECATED T Length() const { return length(); }
00167 
00170   inline ML_DEPRECATED T Distance(const FloatingPointVector<T, size, DataContainer>& buffer) const
00171   {
00172     return distance(buffer);
00173   }
00176   inline ML_DEPRECATED T DistanceSquared(const FloatingPointVector<T, size, DataContainer>& buffer) const
00177   {
00178     return distanceSquared(buffer);
00179   }
00182   inline ML_DEPRECATED T Dot(const FloatingPointVector<T, size, DataContainer>& b) const
00183   {
00184     ML_TRACE_IN_TIME_CRITICAL("Dot(const FloatingPointVector<T, size, DataContainer>& b)");
00185 
00186     return dot(b);
00187   }
00190   inline ML_DEPRECATED T length2() const { return lengthSquared(); }
00193   inline ML_DEPRECATED T LengthSquared() const { return lengthSquared(); }
00194 
00197   inline ML_DEPRECATED FloatingPointVector<T, 3, DataContainer> Cross(const FloatingPointVector<T, 3, DataContainer>& b) const
00198   {
00199     ML_TRACE_IN_TIME_CRITICAL("Cross(const FloatingPointVector<T, 3, DataContainer>& b)");
00200 
00201     return cross(b);
00202   }
00204 #endif // ML_DEPRECATED
00205 
00207   T lengthSquared() const;
00208 
00210   T compSum() const;
00211 
00213   T compMul() const;
00214 
00216   T compMaxAbs() const;
00217 
00219   void compMin(FloatingPointVector<T, size, DataContainer> buffer);
00220 
00222   void compMax(FloatingPointVector<T, size, DataContainer> buffer);
00223 
00225   void compAbs();
00226 
00229   void compDiv(const FloatingPointVector<T, size, DataContainer>& d);
00230 
00232   void compSqr();
00233 
00236   void compSqrt();
00237 
00240   void clampMin(const FloatingPointVector<T, size, DataContainer>& lower);
00241 
00244   void clampMax(const FloatingPointVector<T, size, DataContainer>& upper);
00245 
00251   void clamp(const FloatingPointVector<T, size, DataContainer>& lower,
00252              const FloatingPointVector<T, size, DataContainer>& upper);
00253 
00255   void compRound();
00256 
00258   void compFloor();
00259 
00261   void compCeil();
00262 
00264   inline FloatingPointVector<T, 3, DataContainer> cross(const FloatingPointVector<T, 3, DataContainer> &b) const
00265   {
00266     FloatingPointVector<T, 3, DataContainer> r;
00267     r[0] = this->_buffer[1]*b._buffer[2] - this->_buffer[2]*b._buffer[1];
00268     r[1] = this->_buffer[2]*b._buffer[0] - this->_buffer[0]*b._buffer[2];
00269     r[2] = this->_buffer[0]*b._buffer[1] - this->_buffer[1]*b._buffer[0];
00270     return r;
00271   }
00272 
00274   void apply(ML_LA_FROM_DOUBLE_TO_DOUBLE f);
00275 
00278   std::ostream& writeOut(std::ostream& os) const;
00279 
00281   std::istream& readIn(std::istream& is);
00283 
00284 }; // end of class *FloatingPointVector*
00285 
00286 
00287 //-----------------------------------------------------------------------------------
00289 
00290 //-----------------------------------------------------------------------------------
00291 //-----------------------------------------------------------------------------------
00294 //-----------------------------------------------------------------------------------
00295 template <class T, size_t size, class DataContainer>
00296 inline FloatingPointVector<T, size, DataContainer>& operator+=(FloatingPointVector<T, size, DataContainer>& op1, const FloatingPointVector<T, size, DataContainer>& buffer)
00297 {
00298   for (size_t i=0; i<size; ++i){ op1[i] += buffer[i]; }
00299   return op1;
00300 }
00301 
00302 //-----------------------------------------------------------------------------------
00305 //-----------------------------------------------------------------------------------
00306 template <class T, size_t size, class DataContainer>
00307 inline FloatingPointVector<T, size, DataContainer>& operator-=(FloatingPointVector<T, size, DataContainer>& op1, const FloatingPointVector<T, size, DataContainer>& buffer)
00308 {
00309   for (size_t i=0; i<size; ++i){ op1[i] -= buffer[i]; }
00310   return op1;
00311 }
00312 
00313 //-----------------------------------------------------------------------------------
00316 //-----------------------------------------------------------------------------------
00317 //template <class T, size_t size, class DataContainer>
00318 //inline FloatingPointVector<T, size, DataContainer>& operator*=(FloatingPointVector<T, size, DataContainer>& op1, T value)
00319 //{
00320 //  for (size_t i=0; i<size; ++i){ op1[i] *= value; }
00321 //  return op1;
00322 //}
00323 
00324 //-----------------------------------------------------------------------------------
00327 //-----------------------------------------------------------------------------------
00328 template <class T, size_t size, class DataContainer>
00329 inline FloatingPointVector<T, size, DataContainer>& operator*=(FloatingPointVector<T, size, DataContainer>& op1, MLdouble value)
00330 {
00331   for (size_t i=0; i<size; ++i){ op1[i] *= static_cast<T>(value); }
00332   return op1;
00333 }
00334 
00335 //-----------------------------------------------------------------------------------
00338 //-----------------------------------------------------------------------------------
00339 template <class T, size_t size, class DataContainer>
00340 inline FloatingPointVector<T, size, DataContainer>& operator*=(FloatingPointVector<T, size, DataContainer>& op1, const FloatingPointVector<T, size, DataContainer>& op2)
00341 {
00342   for (size_t i=0; i<size; ++i){ op1[i] *= op2[i]; }
00343   return op1;
00344 }
00345 
00346 //-----------------------------------------------------------------------------------
00350 //-----------------------------------------------------------------------------------
00351 template <class T, size_t size, class DataContainer>
00352 inline FloatingPointVector<T, size, DataContainer>& operator/=(FloatingPointVector<T, size, DataContainer>& op1, MLdouble value)
00353 {
00354   // The desired optimization by multiplying by 1.0/value we cannot do since some
00355   // people simply use this class also for integer types although that's not really ok.
00356   // We don't want to force bad errors for those people; so we spend the time here...
00357   for (size_t i=0; i<size; ++i){ op1[i] /= static_cast<T>(value); }
00358   return op1;
00359 }
00360 
00361 //-----------------------------------------------------------------------------------
00365 //-----------------------------------------------------------------------------------
00366 template <class T, size_t size, class DataContainer>
00367 inline FloatingPointVector<T, size, DataContainer>& operator/=(FloatingPointVector<T, size, DataContainer>& op1, const FloatingPointVector<T, size, DataContainer>& op2)
00368 {
00369   // The desired optimization by multiplying by 1.0/value we cannot do since some
00370   // people simply use this class also for integer types although that's not really ok.
00371   // We don't want to force bad errors for those people; so we spend the time here...
00372   for (size_t i=0; i<size; ++i){ op1[i] /= op2[i]; }
00373   return op1;
00374 }
00375 
00376 //--------------------------------------------------------------------
00379 //--------------------------------------------------------------------
00380 template <class T, size_t size, class DataContainer>
00381 inline bool operator!(const FloatingPointVector<T, size, DataContainer>& a)
00382 {
00383   bool v = !a[0];
00384   for (size_t c=1; c<size; c++){ v &= !a[c]; }
00385   return v;
00386 }
00387 
00388 //-----------------------------------------------------------------------------------
00391 //-----------------------------------------------------------------------------------
00392 template <class T, size_t size, class DataContainer>
00393 inline FloatingPointVector<T, size, DataContainer> operator+(      FloatingPointVector<T, size, DataContainer>  lhs,
00394                                                               const FloatingPointVector<T, size, DataContainer>& rhs)
00395 {
00396   return lhs += rhs;
00397 }
00398 
00399 //-----------------------------------------------------------------------------------
00402 //-----------------------------------------------------------------------------------
00403 template <class T, size_t size, class DataContainer>
00404 inline FloatingPointVector<T, size, DataContainer> operator-(      FloatingPointVector<T, size, DataContainer>  lhs,
00405                                                               const FloatingPointVector<T, size, DataContainer>& rhs)
00406 {
00407   return lhs -= rhs;
00408 }
00409 
00410 //-----------------------------------------------------------------------------------
00413 //-----------------------------------------------------------------------------------
00414 template <class T, size_t size, class DataContainer>
00415 inline FloatingPointVector<T, size, DataContainer> operator+(const FloatingPointVector<T, size, DataContainer>& buffer)
00416 {
00417   return FloatingPointVector<T, size, DataContainer>(buffer);
00418 }
00419 
00420 
00421 //-----------------------------------------------------------------------------------
00424 //-----------------------------------------------------------------------------------
00425 template <class T, size_t size, class DataContainer>
00426 inline FloatingPointVector<T, size, DataContainer> operator-(const FloatingPointVector<T, size, DataContainer>& buffer)
00427 {
00428   FloatingPointVector<T, size, DataContainer> buf(buffer);
00429   for (size_t i=0; i<size; ++i){ buf[i] *= -1; }
00430   return buf;
00431 }
00432 
00433 //-----------------------------------------------------------------------------------
00436 //-----------------------------------------------------------------------------------
00437 template <class T, size_t size, class DataContainer>
00438 inline T operator*(const FloatingPointVector<T, size, DataContainer>& a, const FloatingPointVector<T, size, DataContainer>& b)
00439 {
00440   return a.dot(b);
00441 }
00442 
00443 //-----------------------------------------------------------------------------------
00446 //-----------------------------------------------------------------------------------
00447 template <class T, size_t size, class DataContainer>
00448 inline FloatingPointVector<T, size, DataContainer> operator*(FloatingPointVector<T, size, DataContainer> lhs, MLdouble rhs)
00449 {
00450   return lhs *= static_cast<T>(rhs);
00451 }
00452 
00453 //-----------------------------------------------------------------------------------
00456 //-----------------------------------------------------------------------------------
00457 template <class T, size_t size, class DataContainer>
00458 inline FloatingPointVector<T, size, DataContainer> operator*(MLdouble lhs, FloatingPointVector<T, size, DataContainer> rhs)
00459 {
00460   return rhs *= static_cast<T>(lhs);
00461 }
00462 
00463 //-----------------------------------------------------------------------------------
00466 //-----------------------------------------------------------------------------------
00467 template <class T, size_t size, class DataContainer>
00468 inline FloatingPointVector<T, size, DataContainer> operator/(FloatingPointVector<T, size, DataContainer> lhs, MLdouble rhs)
00469 {
00470   return lhs /= static_cast<T>(rhs);
00471 }
00472 
00473 //-----------------------------------------------------------------------------------
00476 //-----------------------------------------------------------------------------------
00477 template <class T, size_t size, class DataContainer>
00478 inline FloatingPointVector<T, size, DataContainer> compMin(      FloatingPointVector<T, size, DataContainer>  buffer1,
00479                                                             const FloatingPointVector<T, size, DataContainer>& buffer2)
00480 {
00481   buffer1.compMin(buffer2);
00482   return buffer1;
00483 }
00484 
00485 //-----------------------------------------------------------------------------------
00488 //-----------------------------------------------------------------------------------
00489 template <class T, size_t size, class DataContainer>
00490 inline FloatingPointVector<T, size, DataContainer> compMax(      FloatingPointVector<T, size, DataContainer>  buffer1,
00491                                                             const FloatingPointVector<T, size, DataContainer>& buffer2)
00492 {
00493   buffer1.compMax(buffer2);
00494   return buffer1;
00495 }
00496 
00497 //-----------------------------------------------------------------------------------
00500 //-----------------------------------------------------------------------------------
00501 template <class T, size_t size, class DataContainer>
00502 inline FloatingPointVector<T, size, DataContainer> compAbs(FloatingPointVector<T, size, DataContainer> a)
00503 {
00504   a.compAbs();
00505   return a;
00506 }
00507 
00508 //-----------------------------------------------------------------------------------
00511 //-----------------------------------------------------------------------------------
00512 template <class T, size_t size, class DataContainer>
00513 inline FloatingPointVector<T, size, DataContainer> compSqr(FloatingPointVector<T, size, DataContainer> a)
00514 {
00515   a.compSqr();
00516   return a;
00517 }
00518 
00519 
00520 //-----------------------------------------------------------------------------------
00523 //-----------------------------------------------------------------------------------
00524 template <class T, size_t size, class DataContainer>
00525 inline FloatingPointVector<T, size, DataContainer> compSqrt(FloatingPointVector<T, size, DataContainer> a)
00526 {
00527   a.compSqrt();
00528   return a;
00529 }
00530 
00531 //-----------------------------------------------------------------------------------
00535 //-----------------------------------------------------------------------------------
00536 template <class T, size_t size, class DataContainer>
00537 inline FloatingPointVector<T, size, DataContainer> compDiv(      FloatingPointVector<T, size, DataContainer>  a,
00538                                                             const FloatingPointVector<T, size, DataContainer> &d)
00539 {
00540   a.compDiv(d);
00541   return a;
00542 }
00543 
00544 //-----------------------------------------------------------------------------------
00548 //-----------------------------------------------------------------------------------
00549 template <class T, size_t size, class DataContainer>
00550 inline FloatingPointVector<T, size, DataContainer> clampMin(      FloatingPointVector<T, size, DataContainer>  a,
00551                                                              const FloatingPointVector<T, size, DataContainer> &m)
00552 {
00553   a.clampMin(m);
00554   return a;
00555 }
00556 
00557 //-----------------------------------------------------------------------------------
00561 //-----------------------------------------------------------------------------------
00562 template <class T, size_t size, class DataContainer>
00563 inline FloatingPointVector<T, size, DataContainer> clampMax(      FloatingPointVector<T, size, DataContainer>  a,
00564                                                              const FloatingPointVector<T, size, DataContainer> &m)
00565 {
00566   a.clampMax(m);
00567   return a;
00568 }
00569 
00570 //-----------------------------------------------------------------------------------
00576 //-----------------------------------------------------------------------------------
00577 template <class T, size_t size, class DataContainer>
00578 inline FloatingPointVector<T, size, DataContainer> clamp(FloatingPointVector<T, size, DataContainer> a,
00579                                                           const FloatingPointVector<T, size, DataContainer> &lower,
00580                                                           const FloatingPointVector<T, size, DataContainer> &upper)
00581 {
00582   a.clampMax(upper);
00583   a.clampMin(lower);
00584   return a;
00585 }
00586 
00587 //-----------------------------------------------------------------------------------
00590 //-----------------------------------------------------------------------------------
00591 template <class T, size_t size, class DataContainer>
00592 inline T compMul(const FloatingPointVector<T, size, DataContainer> &a)
00593 {
00594   return a.compMul();
00595 }
00597 
00598 ML_LA_END_NAMESPACE
00599 
00600 //-----------------------------------------------------------------------------------
00601 // Some IO stream operators are implemented in this namespace by this library.
00602 //-----------------------------------------------------------------------------------
00603 namespace std {
00604 
00605   //-----------------------------------------------------------------------------------
00607   //-----------------------------------------------------------------------------------
00608   template <class T, size_t size, class DataContainer>
00609   inline ostream& operator<<(ostream& os, const ML_LA_NAMESPACE::FloatingPointVector<T, size, DataContainer>& v)
00610   {
00611     return v.writeOut(os);
00612   }
00613 
00614   //-----------------------------------------------------------------------------------
00616   //-----------------------------------------------------------------------------------
00617   template <class T, size_t size, class DataContainer>
00618   inline istream& operator>>(istream& is, ML_LA_NAMESPACE::FloatingPointVector<T, size, DataContainer>& v)
00619   {
00620     return v.readIn(is);
00621   }
00622 
00623 }
00624 
00625 ML_LA_START_NAMESPACE
00626 
00627 //-----------------------------------------------------------------------------------
00628 //
00629 //                              IMPLEMENTATION.
00630 //
00631 //-----------------------------------------------------------------------------------
00632 
00633 //-----------------------------------------------------------------------------------
00634 //                     Constructors and assignment operators.
00635 //-----------------------------------------------------------------------------------
00636 //-----------------------------------------------------------------------------------
00637 // Default and value constructor. Default is the initialization of all
00638 // components with value whose default is 0.
00639 //-----------------------------------------------------------------------------------
00640 template <class T, size_t size, class DataContainer>
00641 inline FloatingPointVector<T, size, DataContainer>::FloatingPointVector(T value)
00642 {
00643   for (size_t i=0; i<size; ++i){ this->_buffer[i] = value; }
00644 }
00645 
00646 //-----------------------------------------------------------------------------------
00647 // Assignment of scalar value to all components.
00648 //-----------------------------------------------------------------------------------
00649 template <class T, size_t size, class DataContainer>
00650 inline FloatingPointVector<T, size, DataContainer>& FloatingPointVector<T, size, DataContainer>::operator=(T value)
00651 {
00652   for (size_t i=0; i<size; ++i){ this->_buffer[i] = value; }
00653   return *this;
00654 }
00655 
00656 
00657 //----------------------------------------------------------------------
00658 //                           Comparison.
00659 //----------------------------------------------------------------------
00660 //-----------------------------------------------------------------------------------
00661 // Returns true if *this and buffer are component wise equal, otherwise false.
00662 //-----------------------------------------------------------------------------------
00663 template <class T, size_t size, class DataContainer>
00664 inline bool FloatingPointVector<T, size, DataContainer>::operator==(const FloatingPointVector<T, size, DataContainer>& buffer) const
00665 {
00666   for (size_t i=0; i<size; ++i){
00667     // Use the numerically better method (although slower to compare) floats to ensure that
00668     // insignificant differences after least significant mantissa bit are not considered as
00669     // difference.
00670     if (MLValuesDifferWOM(this->_buffer[i], buffer._buffer[i])){ return false; }
00671   }
00672   return true;
00673 }
00674 
00675 //-----------------------------------------------------------------------------------
00676 // Returns true if any components of *this and buffer are not equal, otherwise false.
00677 //-----------------------------------------------------------------------------------
00678 template <class T, size_t size, class DataContainer>
00679 inline bool FloatingPointVector<T, size, DataContainer>::operator!=(const FloatingPointVector<T, size, DataContainer>& buffer) const
00680 {
00681   for (size_t i=0; i<size; ++i){
00682     // Use the numerically better method (although slower to compare) floats to ensure that
00683     // insignificant differences after least significant mantissa bit are not considered as
00684     // difference.
00685     if (MLValuesDifferWOM(this->_buffer[i], buffer._buffer[i])){ return true; }
00686   }
00687   return false;
00688 }
00689 
00690 //-----------------------------------------------------------------------------------
00691 // Defines an artificial order for use in sort algorithms (lexicographical
00692 // order). Starting from the first component(i.e. index 0) all components
00693 // from *this are compared with the corresponding one in buffer:
00694 // If the components of *this is smaller than the corresponding on in
00695 // buffer then true is returned, if the comparison is bigger then
00696 // false is returned and on equality the components for the next index are
00697 // compared. If all components are equal then false is returned.
00698 //-----------------------------------------------------------------------------------
00699 template <class T, size_t size, class DataContainer>
00700 inline bool FloatingPointVector<T, size, DataContainer>::operator<(const FloatingPointVector<T, size, DataContainer>& buffer) const
00701 {
00702   for (size_t i=0; i<size; ++i) {
00703     if (MLValuesDifferWOM(this->_buffer[i], buffer._buffer[i])){ return (this->_buffer[i]<buffer._buffer[i]); }
00704   }
00705   return false;
00706 }
00707 
00708 
00709 
00710 
00711 
00712 //-----------------------------------------------------------------------------------
00713 //                   Value access and indexing operators.
00714 //-----------------------------------------------------------------------------------
00715 //-----------------------------------------------------------------------------------
00716 // Constant indexing operators. The caller must guarantee that is in [0, size-1].
00717 // It is legal to consider all elements as a subsequent array in memory for
00718 // pointer addressing of all elements.
00719 //-----------------------------------------------------------------------------------
00720 template <class T, size_t size, class DataContainer>
00721 inline const T& FloatingPointVector<T, size, DataContainer>::operator[](const size_t i) const
00722 {
00723   return this->_buffer[i];
00724 }
00725 
00726 //-----------------------------------------------------------------------------------
00727 // Indexing operator. The caller must guarantee that is in [0, size-1].
00728 // It is legal to consider all elements as a subsequent array in memory for
00729 // pointer addressing of all elements.
00730 //-----------------------------------------------------------------------------------
00731 template <class T, size_t size, class DataContainer>
00732 inline T& FloatingPointVector<T, size, DataContainer>::operator[](const size_t i)
00733 {
00734   return this->_buffer[i];
00735 }
00736 
00737 
00738 
00739 
00740 
00741 
00742 
00743 
00744 //----------------------------------------------------------------------
00745 //                     Other operations.
00746 //----------------------------------------------------------------------
00747 //-----------------------------------------------------------------------------------
00748 // Return number of elements of value buffer.
00749 //-----------------------------------------------------------------------------------
00750 template <class T, size_t size, class DataContainer>
00751 inline size_t FloatingPointVector<T, size, DataContainer>::getSize() const
00752 {
00753   return size;
00754 }
00755 
00756 //-----------------------------------------------------------------------------------
00757 // Return euclidean norm (the vector length), i.e. square root of sum
00758 // of squares of all components.
00759 //-----------------------------------------------------------------------------------
00760 template <class T, size_t size, class DataContainer>
00761 inline T FloatingPointVector<T, size, DataContainer>::norm2() const
00762 {
00763   T norm = 0;
00764   for (size_t i=0; i<size; ++i){ norm += this->_buffer[i]*this->_buffer[i]; }
00765 #ifdef WIN32
00766   return static_cast<T>(sqrt(norm));
00767 #else
00768   return static_cast<T>(::sqrt(norm));
00769 #endif
00770 }
00771 
00772 //-----------------------------------------------------------------------------------
00773 // Return weighted euclidean norm, i.e. square root of sum of squares of all
00774 // components multiplied with corresponding squared component of weight.
00775 //-----------------------------------------------------------------------------------
00776 template <class T, size_t size, class DataContainer>
00777 inline T FloatingPointVector<T, size, DataContainer>::norm2(const FloatingPointVector<T, size, DataContainer>& weight) const
00778 {
00779   T norm = 0;
00780   for (size_t i=0; i<size; ++i){
00781     norm += this->_buffer[i]*this->_buffer[i] * weight._buffer[i]*weight._buffer[i];
00782   }
00783 #ifdef WIN32
00784   return sqrt(norm);
00785 #else
00786   return ::sqrt(norm);
00787 #endif
00788 }
00789 
00790 
00791 //-----------------------------------------------------------------------------------
00792 // Return dot product, i.e. sum of all components multiplied with corresponding
00793 // components of buffer.
00794 //-----------------------------------------------------------------------------------
00795 template <class T, size_t size, class DataContainer>
00796 inline T FloatingPointVector<T, size, DataContainer>::dot(const FloatingPointVector<T, size, DataContainer>& buffer) const
00797 {
00798   T sum = 0;
00799   for (size_t i=0; i<size; ++i){ sum += this->_buffer[i]*buffer._buffer[i]; }
00800   return sum;
00801 }
00802 
00803 //-----------------------------------------------------------------------------------
00804 // Normalizes buffer and returns euclidean length of vector before normalization,
00805 // i.e.norm2. On zero vector length the vector is left unchanged.
00806 //-----------------------------------------------------------------------------------
00807 template <class T, size_t size, class DataContainer>
00808 inline T FloatingPointVector<T, size, DataContainer>::normalize()
00809 {
00810   T norm = norm2();
00811 
00812   if (!MLValueIs0WOM(norm)) {
00813     T inv_norm = static_cast<T>(1.0/norm);
00814     for (size_t i=0; i<size; ++i){ this->_buffer[i] *= inv_norm; }
00815   }
00816 
00817   return norm;
00818 }
00819 
00820 //-----------------------------------------------------------------------------------
00821 // Return the length of the vector, i.e. norm2().
00822 //-----------------------------------------------------------------------------------
00823 template <class T, size_t size, class DataContainer>
00824 inline T FloatingPointVector<T, size, DataContainer>::length() const
00825 {
00826   return norm2();
00827 }
00828 
00829 //-----------------------------------------------------------------------------------
00830 // Returns squared length of vector.
00831 //-----------------------------------------------------------------------------------
00832 template <class T, size_t size, class DataContainer>
00833 inline T FloatingPointVector<T, size, DataContainer>::lengthSquared() const
00834 {
00835   return dot(*this);
00836 }
00837 
00838 //-----------------------------------------------------------------------------------
00839 // Return sum of all components.
00840 //-----------------------------------------------------------------------------------
00841 template <class T, size_t size, class DataContainer>
00842 inline T FloatingPointVector<T, size, DataContainer>::compSum() const
00843 {
00844   T retVal=this->_buffer[0];
00845   for (size_t i=1; i<size; ++i){ retVal += this->_buffer[i]; }
00846   return retVal;
00847 }
00848 
00849 //-----------------------------------------------------------------------------------
00850 // Return product of all vector components.
00851 //-----------------------------------------------------------------------------------
00852 template <class T, size_t size, class DataContainer>
00853 inline T FloatingPointVector<T, size, DataContainer>::compMul() const
00854 {
00855   T retVal=this->_buffer[0];
00856   for (size_t i=1; i<size; ++i){ retVal *= this->_buffer[i]; }
00857   return retVal;
00858 }
00859 
00860 //-----------------------------------------------------------------------------------
00861 // Return maximum of absolute component values.
00862 //-----------------------------------------------------------------------------------
00863 template <class T, size_t size, class DataContainer>
00864 inline T FloatingPointVector<T, size, DataContainer>::compMaxAbs() const
00865 {
00866   size_t i = 0;
00867   T m = static_cast<T>(  MLAbs(this->_buffer[i++]));
00868   T n = 0;
00869   for (; i<size; ++i){ m = (n = static_cast<T>(  MLAbs(this->_buffer[i]))  ) > m ? n : m; }
00870   return m;
00871 }
00872 
00873 //-----------------------------------------------------------------------------------
00874 // Sets the component wise minimum of *this and buffer in *this.
00875 //-----------------------------------------------------------------------------------
00876 template <class T, size_t size, class DataContainer>
00877 inline void FloatingPointVector<T, size, DataContainer>::compMin(FloatingPointVector<T, size, DataContainer> buffer)
00878 {
00879   for (size_t i=0; i<size; ++i){
00880     this->_buffer[i] = this->_buffer[i] < buffer._buffer[i] ? this->_buffer[i] : buffer._buffer[i];
00881   }
00882 }
00883 
00884 //-----------------------------------------------------------------------------------
00885 // Sets the component wise maximum of *this and buffer in *this.
00886 //-----------------------------------------------------------------------------------
00887 template <class T, size_t size, class DataContainer>
00888 inline void FloatingPointVector<T, size, DataContainer>::compMax(FloatingPointVector<T, size, DataContainer> buffer)
00889 {
00890   for (size_t i=0; i<size; ++i){
00891     this->_buffer[i] = this->_buffer[i] < buffer._buffer[i] ? buffer._buffer[i] :this->_buffer[i];
00892   }
00893 }
00894 
00895 //-----------------------------------------------------------------------------------
00896 // Kill negative signs from all components.
00897 //-----------------------------------------------------------------------------------
00898 template <class T, size_t size, class DataContainer>
00899 inline void FloatingPointVector<T, size, DataContainer>::compAbs()
00900 {
00901   for (size_t i=0; i<size; ++i){ this->_buffer[i] = static_cast<T>(  MLAbs(this->_buffer[i])); }
00902 }
00903 
00904 //-----------------------------------------------------------------------------------
00905 // Divide each vector component by the corresponding one of d.
00906 // Divisions by zero are not handled; the caller must avoid them.
00907 //-----------------------------------------------------------------------------------
00908 template <class T, size_t size, class DataContainer>
00909 inline void FloatingPointVector<T, size, DataContainer>::compDiv(const FloatingPointVector<T, size, DataContainer>& d)
00910 {
00911   for (size_t i=0; i<size; ++i){ this->_buffer[i] /= d._buffer[i]; }
00912 }
00913 
00914 //-----------------------------------------------------------------------------------
00915 // Calculate and set the square of all components.
00916 //-----------------------------------------------------------------------------------
00917 template <class T, size_t size, class DataContainer>
00918 inline void FloatingPointVector<T, size, DataContainer>::compSqr()
00919 {
00920   for (size_t i=0; i<size; ++i){ this->_buffer[i] *= this->_buffer[i]; }
00921 }
00922 
00923 //-----------------------------------------------------------------------------------
00924 // Calculate and set square root of all components.
00925 // Negative values have to be avoided by caller.
00926 //-----------------------------------------------------------------------------------
00927 template <class T, size_t size, class DataContainer>
00928 inline void FloatingPointVector<T, size, DataContainer>::compSqrt()
00929 {
00930   for (size_t i=0; i<size; ++i){
00931 #ifdef WIN32
00932     this->_buffer[i] = static_cast<T>(  sqrt(this->_buffer[i]));
00933 #else
00934     this->_buffer[i] = static_cast<T>(::sqrt(this->_buffer[i]));
00935 #endif
00936   }
00937 }
00938 
00939 //-----------------------------------------------------------------------------------
00940 // Calculate and set all components clamped to lower, i.e. if any component is
00941 // smaller than the corresponding one in lower then it is set to the one from lower.
00942 //-----------------------------------------------------------------------------------
00943 template <class T, size_t size, class DataContainer>
00944 inline void FloatingPointVector<T, size, DataContainer>::clampMin(const FloatingPointVector<T, size, DataContainer>& lower)
00945 {
00946   compMax(lower);
00947 }
00948 
00949 //-----------------------------------------------------------------------------------
00950 // Calculate and set all components clamped to upper, i.e. if any component is
00951 // greater than the corresponding one in upper then it is set to the one from upper.
00952 //-----------------------------------------------------------------------------------
00953 template <class T, size_t size, class DataContainer>
00954 inline void FloatingPointVector<T, size, DataContainer>::clampMax(const FloatingPointVector<T, size, DataContainer>& upper)
00955 {
00956   compMin(upper);
00957 }
00958 
00959 //-----------------------------------------------------------------------------------
00960 // Calculate and set all components of *this so that they are between minimum
00961 // min and maximum max. This is done by applying clampMin(lower) first
00962 // and then clampMax(upper). Note that components can become smaller than
00963 // lower if a component in upper is smaller than their corresponding one in
00964 // in lower.
00965 //-----------------------------------------------------------------------------------
00966 template <class T, size_t size, class DataContainer>
00967 inline void FloatingPointVector<T, size, DataContainer>::clamp(const FloatingPointVector<T, size, DataContainer>& lower,
00968                                                                 const FloatingPointVector<T, size, DataContainer>& upper)
00969 {
00970   // Make copy to avoid self modification if lower or upper is equal to *this.
00971   FloatingPointVector<T, size, DataContainer> buf(*this);
00972   buf.clampMin(lower);
00973   buf.clampMax(upper);
00974   *this = buf;
00975 }
00976 
00977 //-----------------------------------------------------------------------------------
00978 // Round all components of this vector using floor(component + 0.5).
00979 //-----------------------------------------------------------------------------------
00980 template <class T, size_t size, class DataContainer>
00981 inline void FloatingPointVector<T, size, DataContainer>::compRound()
00982 {
00983   for (size_t i=0; i<size; ++i){ this->_buffer[i] = floor(this->_buffer[i] + 0.5); }
00984 }
00985 
00986 //-----------------------------------------------------------------------------------
00987 // Round all components of this vector using floor(component).
00988 //-----------------------------------------------------------------------------------
00989 template <class T, size_t size, class DataContainer>
00990 inline void FloatingPointVector<T, size, DataContainer>::compFloor()
00991 {
00992   for (size_t i=0; i<size; ++i){ this->_buffer[i] = floor(this->_buffer[i]); }
00993 }
00994 
00995 //-----------------------------------------------------------------------------------
00996 // Round all components of this vector to integer using ceil(component).
00997 //-----------------------------------------------------------------------------------
00998 template <class T, size_t size, class DataContainer>
00999 inline void FloatingPointVector<T, size, DataContainer>::compCeil()
01000 {
01001   for (size_t i=0; i<size; ++i){ this->_buffer[i] = ceil(this->_buffer[i]); }
01002 }
01003 
01004 //-----------------------------------------------------------------------------------
01005 // Apply function f to each component starting form index 0 to index size-1.
01006 //-----------------------------------------------------------------------------------
01007 template <class T, size_t size, class DataContainer>
01008 inline void FloatingPointVector<T, size, DataContainer>::apply(ML_LA_FROM_DOUBLE_TO_DOUBLE f)
01009 {
01010   for (size_t i=0; i<size; ++i){ this->_buffer[i] = f(this->_buffer[i]); }
01011 }
01012 
01013 //-----------------------------------------------------------------------------------
01014 // Write all components to ostream os starting from index 0 to size-1.
01015 // Each buffer elements is followed separated by a space symbols " ".
01016 //-----------------------------------------------------------------------------------
01017 template <class T, size_t size, class DataContainer>
01018 inline std::ostream& FloatingPointVector<T, size, DataContainer>::writeOut(std::ostream& os) const
01019 {
01020   for (size_t i=0; i<size; ++i){ os << this->_buffer[i] << " "; }
01021   return os;
01022 }
01023 
01024 //-----------------------------------------------------------------------------------
01025 // Read all components from istream is starting starting from index 0 to size-1.
01026 //-----------------------------------------------------------------------------------
01027 template <class T, size_t size, class DataContainer>
01028 inline std::istream& FloatingPointVector<T, size, DataContainer>::readIn(std::istream& is)
01029 {
01030   for (size_t i=0; i<size; ++i){ is >> this->_buffer[i]; }
01031   return is;
01032 }
01033 
01034 #ifdef ML_DEPRECATED
01035 
01036 
01037 
01038 
01039 #define ScalarVectorTemplate FloatingPointVector
01040 
01041 #if defined(WIN32) && defined(ML_WARN_DEPRECATED)
01042 #pragma deprecated("ScalarVectorTemplate")
01043 #endif
01044 
01046 #endif // ML_DEPRECATED
01047 
01048 ML_LA_END_NAMESPACE
01049 
01050 
01051 #endif // __mlFloatingPointVector_H
01052 
01053 
01054