ML Reference
|
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