/* * Copyright (C) 2009 * Robert Bosch LLC * Research and Technology Center North America * Palo Alto, California * * All rights reserved. * *------------------------------------------------------------------------------ * project ....: Autonomous Technologies * file .......: rtcVarVec.h * authors ....: Benjamin Pitzer * organization: Robert Bosch LLC * creation ...: 08/16/2006 * modified ...: $Date: 2009-01-21 18:19:16 -0800 (Wed, 21 Jan 2009) $ * changed by .: $Author: benjaminpitzer $ * revision ...: $Revision: 14 $ */ #ifndef RTC_VARVEC_H #define RTC_VARVEC_H //== INCLUDES ================================================================== #include "rtcMath.h" #include "rtcArray1.h" //== NAMESPACES ================================================================ namespace rtc { // Forward declarations template class VarVec; // len-d vector template class VarSMat; // MxM Square Matrix /** * A dynamically allocated vector of type T */ template class VarVec : public Array1 { public: // Constructors VarVec(); VarVec(int len); VarVec(int len, const T* d); VarVec(int len, const T a); VarVec(const Array1& a); // Cast Operation template VarVec(const VarVec& v); template VarVec(const Vec& v); // Mutators void set(const T* d); void set(const T a); void set(const VarVec& v); VarVec& operator = (const T a); VarVec& operator = (const T* d); VarVec& operator = (const VarVec& v); void setSubVec(const int i, const VarVec& v); // Casting Mutators template void set(const VarVec& v); template void set(const Vec& v); template VarVec& operator = (const VarVec& v); // Accessors T operator [] (const int i) const; T& operator [] (const int i); VarVec getSubVec(const int i, int sub_len) const; // Norms and Normalize T norm() const; T normSqr() const; T pnorm(float p) const; T normalize(); VarVec normalized() const; // Reductions: Max/Min, Sum/Product T max() const; T min() const; T sum() const; T prod() const; VarVec cumsum() const; // General elementwise operations void perform(T (*mathFun)(T)); void perform(T (*mathFun)(T,T), const T arg2); void perform(T (*mathFun)(T,T), const VarVec& v); VarVec performed(T (*mathFun)(T)); VarVec performed(T (*mathFun)(T,T), const T arg2); VarVec performed(T (*mathFun)(T,T), const VarVec& v); VarVec minimize(const VarVec& other); VarVec maximize(const VarVec& other); // Dot and Outer Products T dot(const VarVec& v) const; VarSMat outer(const VarVec& v) const; VarSMat outer() const; // Random vectors and sorting // static VarVec uniformRand(const T a = T(0), const T b = T(1)); // static VarVec normalRand(const T mean = T(0), const T stdev = T(1)); // static VarVec multivariateGauss(const VarVec& mean, const SMat& cov); void sort(bool ascending = true); VarVec sorted(bool ascending = true); // Addition and subtraction VarVec& add(const VarVec& v); void addSubVec(const int i, const VarVec& v); VarVec& subtract(const VarVec& v); void subtractSubVec(const int i, const VarVec& v); // Addition and subtraction operator VarVec operator + (const VarVec& v) const; void operator += (const VarVec& v); VarVec operator - (const VarVec& v) const; void operator -= (const VarVec& v); VarVec operator - () const; VarVec add(const T a); VarVec operator + (const T a) const; void operator += (const T a); VarVec subtract(const T a); VarVec operator - (const T a) const; void operator -= (const T a); // Multiplication and division operator VarVec operator * (const T a) const; VarVec operator / (const T a) const; void operator *= (const T a); void operator /= (const T a); // Equality and inequality tests int compareTo(const VarVec& v) const; bool equalTo(const VarVec& v, const T tol = T(0)) const; // Equality and inequality tests operator bool operator == (const VarVec& v) const; bool operator != (const VarVec& v) const; // VarVec operator == (const VarVec& v) const; // VarVec operator != (const VarVec& v) const; VarVec operator >= (const VarVec& v) const; VarVec operator <= (const VarVec& v) const; VarVec operator > (const VarVec& v) const; VarVec operator < (const VarVec& v) const; // Element-wise operations VarVec operator * (const VarVec& v) const; VarVec operator / (const VarVec& v) const; void operator *= (const VarVec& v); void operator /= (const VarVec& v); // Serialization bool write(std::ostream& os) const; bool read(std::istream& is); // inherit member data and functions of parent using Array1::x; using Array1::reset; using Array1::at; using Array1::setSize; protected: // inherit member data and functions of parent using Array1::dim; using Array1::mul; using Array1::len; }; // Declare a few common typdefs typedef VarVec VarVecb; typedef VarVec VarVecc; typedef VarVec VarVecuc; typedef VarVec VarVeci; typedef VarVec VarVecf; typedef VarVec VarVecd; // Global operators for cases where VarVec // is the second argument in a binary operator template VarVec operator + (const T a, const VarVec& v); template VarVec operator - (const T a, const VarVec& v); template VarVec operator * (const T a, const VarVec& v); // ASCII stream IO template std::ostream& operator<<(std::ostream& os, const VarVec& vec); template std::istream& operator>>(std::istream& is, VarVec& vec); //============================================================================== // VarVec //============================================================================== // Constructors /** default Ctor */ template inline VarVec::VarVec() : Array1() {} /** Ctor that does no initalization. */ template inline VarVec::VarVec(int _len) : Array1(_len) {} /** Ctor that initializes elements from an array. * @param _len size of the vector * @param d pointer to the initalization array */ template inline VarVec::VarVec(int _len, const T* d) : Array1(_len,d) {} /** Ctor that initializes all elements from a scalar. * @param _len size of the vector * @param a the value to assign to all elements */ template inline VarVec::VarVec(int _len, const T a) : Array1(_len,a) {} /** Copy Ctor * @param a is the array to duplicate */ template inline VarVec::VarVec(const Array1& a) : Array1(a) {} // Casting Operation /** Casting Ctor that initializes from passed vector. * @param v is the vector to duplicate */ template template inline VarVec::VarVec(const VarVec& v) { set(v); } /** Casting Ctor that initializes from passed vector with type cast. * @param v is the vector to duplicate */ template template inline VarVec::VarVec(const Vec& v) : Array1() { setSize(N); set(v); } // Mutators /** Set all elements equal to a scalar. * @param a the value to assign to all elements */ template inline void VarVec::set(const T a) { Array1::set(a); } /** Set all elements from an array. * @param d pointer to the initalization array */ template inline void VarVec::set(const T* d) { Array1::set(d); } /** Set this vector equal to passed vector * @param v the vector to replicate */ template inline void VarVec::set(const VarVec& v) { if(len!=v.len) setSize(v.len); Array1::set(v); } /** Set a subvector by replacing elements from i onward with the * elements from v. * Replaces elements till the end of either vector is reached. * @param v the vector from which to copy values * @param i the (zero based) index of the start of the subvector */ template inline void VarVec::setSubVec(const int i, const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+v.len > len) { std::stringstream ss; ss << "VarVec<" << len << ">::setSubVec(" << i << ", "; ss << "VarVec<" << v.len << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int j=i,k=0;j inline VarVec& VarVec::operator = (const T a) { set(a); return *this; } /** Set all elements from an array. * @param d pointer to the initalization array */ template inline VarVec& VarVec::operator = (const T* d) { set(d); return *this; } /** Set this vector equal to passed vector * @param v the vector to replicate */ template inline VarVec& VarVec::operator = (const VarVec& v) { set(v); return *this; } // Casting Mutators /** Set this vector equal to passed vector with type cast. * @param v the vector to replicate */ template template inline void VarVec::set(const VarVec& v) { if(len!=v.len) setSize(v.len); for (int i=0;i template inline void VarVec::set(const Vec& v) { if(len!=N) setSize(N); for (int k=0;k template inline VarVec& VarVec::operator = (const VarVec& v) { set(v); return *this; } // Accessors /** Get an element of the vector (by value). * Does bounds checking if MATMATH_CHECK_BOUNDS is set * @param i the (zero based) index into the vector */ template inline T VarVec::operator [] (const int i) const { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > len) { std::stringstream ss; ss << "Vec<" << len << ">::(" << i << "): index out of range\n"; ss << std::flush; throw Exception(ss.str()); } #endif return x[i]; } /** Get an element of the vector (by reference). * Does bounds checking if MATMATH_CHECK_BOUNDS is set * @param i the (zero based) index into the vector */ template inline T& VarVec::operator [] (const int i) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > len) { std::stringstream ss; ss << "&Vec<" << len << ">::(" << i << "): index out of range"; throw Exception(ss.str()); } #endif return x[i]; } /** Get the subvector of length N starting at element i * @param i the (zero based) index of the first element of subvector * @param sub_len the length of the subvector * @return subvector of length sub_len */ template inline VarVec VarVec::getSubVec(const int i, int sub_len) const { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+sub_len > len) { std::stringstream ss; ss << "&Vec<" << len << ">::(" << i << "): index out of range"; throw Exception(ss.str()); } #endif VarVec v(sub_len,T(0)); for (int j=i,k=0;j inline T VarVec::norm() const { return T(sqrt(double(normSqr()))); } /** Calculate the square of the euclidan norm (2-norm). * @return the sum of squares of the elements */ template inline T VarVec::normSqr() const { T sum = T(0); for (int i=0;i inline T VarVec::pnorm(float p) const { T sum = T(0); for (int i=0;i inline T VarVec::normalize() { T l = norm(); if (l > T(0)) for (int i=0;i inline VarVec VarVec::normalized() const { VarVec v(len,x); v.normalize(); return v; } // Maximum/Minimum value and Sum /** Find the maximum value of the vector * @returns the maximum value */ template inline T VarVec::max() const { T m = x[0]; for (int i=1;im) m = x[i]; return m; } /** Find the minimum value of the vector * @returns the minimum value */ template inline T VarVec::min() const { T m = x[0]; for (int i=1;i inline T VarVec::sum() const { T s = T(0); for (int i=0;i inline VarVec VarVec::cumsum() const { VarVec v(len); T s = T(0); for (int i=0;i inline T VarVec::prod() const { T p = T(1); for (int i=0;i inline void VarVec::perform(T (*mathFun)(T)) { for (int i=0;i inline void VarVec::perform(T (*mathFun)(T,T), const T arg2) { for (int i=0;i inline void VarVec::perform(T (*mathFun)(T,T), const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::perform(" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif for (int i=0;i inline VarVec VarVec::performed(T (*mathFun)(T)) { VarVec v(len); for (int i=0;i inline VarVec VarVec::performed(T (*mathFun)(T,T), const T arg2) { VarVec v(len); for (int i=0;i inline VarVec VarVec::performed(T (*mathFun)(T,T), const VarVec& vp) { #if MATMATH_CHECK_BOUNDS if (len!=vp.len) { std::stringstream ss; ss << "VarVec<" << len << ">::performed(" << ss << "VarVec<" << vp.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarVec v(len); for (int i=0;i inline VarVec VarVec::minimize(const VarVec& other) { #if MATMATH_CHECK_BOUNDS if (len!=other.len) { std::stringstream ss; ss << "VarVec<" << len << ">::minimize(" << ss << "VarVec<" << other.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i inline VarVec VarVec::maximize(const VarVec& other) { #if MATMATH_CHECK_BOUNDS if (len!=other.len) { std::stringstream ss; ss << "VarVec<" << len << ">::maximize(" << ss << "VarVec<" << other.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i x[i]) x[i] = other.x[i]; } return *this; } // Dot, Cross, and Outer Products /** Calculate the dot (inner) product with another vector. * @param v the other vector * @return the inner product */ template inline T VarVec::dot(const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::dot(" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif T sum = T(0); for (int i=0;i inline VarSMat VarVec::outer(const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::outer(" << ss << "VarVec<" << v.len << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif VarSMat m(len); for (int i=0,k=0;i inline VarSMat VarVec::outer() const { VarSMat m(len); for (int i=0,k=0;i // inline VarVec VarVec::uniformRand(const T a, const T b) { // VarVec v; // for (int i=0;i(a,b); // return v; // } // // /** Create vector with samples from a normal distribution. // * @param mean mean of normal distribution // * @param stdev standard deviation of normal distribution // * @return vector of normal samples // */ // template // inline VarVec VarVec::normalRand(const T mean, const T stdev) { // VarVec v; // for (int i=0;i(mean, stdev); // return v; // } // // /** Create vector from a multivariate gaussian distribution. // * @param mean mean of normal distribution // * @param stdev standard deviation of normal distribution // * @return vector of a multivariate gaussian distribution // */ // template // inline VarVec VarVec::multivariateGauss(const VarVec& mean, const SMat& cov) { // VarVec v; // SMat S(cov); // int n=S.choleskyDecomp(); // assert(n==0); // S.transpose(); // VarVec X = normalRand(); // v = mean + S*X; // return v; // } /** Sort elements. * @param ascending sort in increasing order */ template inline void VarVec::sort(bool ascending) { int count; do { count = 0; for (int i=0;i<(len-1);i++) { if (ascending) { if (x[i]> x[i+1]) { rtc_swap(x[i],x[i+1]); count++; } } else { if (x[i] < x[i+1]) { rtc_swap(x[i+1],x[i]); count++; } } } } while (count> 0); } /** Create a copy of the vector with elements sorted. * @param ascending sort in increasing order * @return sorted vector */ template inline VarVec VarVec::sorted(bool ascending) { VarVec v(len,x); v.sort(ascending); return v; } // Addition and subtraction /** Vector-Vector addition. */ template inline VarVec& VarVec::add(const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::add(" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i inline void VarVec::addSubVec(const int i, const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+v.len > len) { std::stringstream ss; ss << "VarVec<" << len << ">::addSubVec(" << i << ", "; ss << "VarVec<" << v.len << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int j=i,k=0;j inline VarVec& VarVec::subtract(const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::subtract(" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i inline void VarVec::subtractSubVec(const int i, const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+v.len > len) { std::stringstream ss; ss << "VarVec<" << len << ">::addSubVec(" << i << ", "; ss << "VarVec<" << v.len << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int j=i,k=0;j inline VarVec VarVec::operator + (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator + (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarVec vp(len); for (int i=0;i inline void VarVec::operator += (const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator += (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i inline VarVec VarVec::operator - (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator - (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarVec vp(len); for (int i=0;i inline void VarVec::operator -= (const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator -= (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i inline VarVec VarVec::operator - () const { VarVec vp(len); for (int i=0;i inline VarVec VarVec::add(const T a) { for (int i=0;i inline VarVec VarVec::operator + (const T a) const { VarVec vp(len); for (int i=0;i inline void VarVec::operator += (const T a) { for (int i=0;i inline VarVec VarVec::subtract(const T a) { for (int i=0;i inline VarVec VarVec::operator - (const T a) const { VarVec vp(len); for (int i=0;i inline void VarVec::operator -= (const T a) { for (int i=0;i inline VarVec operator + (const T a, const VarVec& v) { VarVec vp(v.len); for (int i=0;i inline VarVec operator - (const T a, const VarVec& v) { VarVec vp(v.len); for (int i=0;i inline VarVec VarVec::operator * (const T a) const { VarVec vp(len); for (int i=0;i inline VarVec VarVec::operator / (const T a) const { VarVec vp(len); for (int i=0;i inline void VarVec::operator *= (const T a) { for (int i=0;i inline void VarVec::operator /= (const T a) { for (int i=0;i inline VarVec operator * (const T a, const VarVec& v) { VarVec vp(v.len); for (int i=0;i inline bool VarVec::operator == (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator == (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif for (int i=0;i inline bool VarVec::operator != (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator != (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif for (int i=0;i // inline VarVec VarVec::operator == (const VarVec& v) const { // VarVec b(len,false); // for (int i=0;i // inline VarVec VarVec::operator != (const VarVec& v) const { // VarVec b(len,false); // for (int i=0;i inline VarVec VarVec::operator >= (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator >= (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif VarVec b(len,false); for (int i=0;i= v.x[i]) b.x[i] = true; return b; } /** Element-wise test for less or equal. * @return vector of boolean results */ template inline VarVec VarVec::operator <= (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator <= (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif VarVec b(len,false); for (int i=0;i inline VarVec VarVec::operator > (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator > (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif VarVec b(len,false); for (int i=0;i v.x[i]) b.x[i] = true; return b; } /** Element-wise test for less. * @return vector of boolean results */ template inline VarVec VarVec::operator < (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator < (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif VarVec b(len,false); for (int i=0;i inline int VarVec::compareTo(const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::compareTo (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; ss << std::flush; throw Exception(ss.str()); } #endif int g=0, l=0; for (int i=0;i v.x[i]) g++; } if (l==len) return -1; else if (g==len) return 1; else return 0; } /** Compare the entire vector to the passed vector. * @returns true of all corresponding elements are within the given tolerance */ template inline bool VarVec::equalTo(const VarVec& v, const T tol) const { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::equalTo (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif bool t = true; for (int i=0;i tol) t = false; return t; } // Element-wise multiplication and division /** Element-wise multiplication. */ template inline VarVec VarVec::operator * (const VarVec& v) const { VarVec vp(v.len); for (int i=0;i inline VarVec VarVec::operator / (const VarVec& v) const { VarVec vp(v.len); for (int i=0;i inline void VarVec::operator *= (const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator *= (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i inline void VarVec::operator /= (const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (len!=v.len) { std::stringstream ss; ss << "VarVec<" << len << ">::operator /= (" << ss << "VarVec<" << v.len << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0;i inline bool VarVec::write(std::ostream& os) const { os.write((char *)(len),sizeof(int)); os.write((char *)(x),len*sizeof(T)); return os.good(); } /** Restores state from a binary stream. */ template inline bool VarVec::read(std::istream& is) { int new_len; is.read((char *)(new_len),sizeof(int)); if(new_len!=len) setSize(len); is.read((char *)(x),len*sizeof(T)); return is.good(); } /** Write state to stream as formated ASCII */ template std::ostream& operator<<(std::ostream& os, const VarVec& vec) { int minFieldWidth = os.precision()+2; os << "["; for (int i=0; i std::istream& operator>>(std::istream& is, VarVec& vec) { using namespace std; vector data; string vecString; stringstream vecStringStream; getline(is, vecString, ']'); int sPos = (int)vecString.find('['); if (sPos == (int)string::npos) throw Exception("format error: expecting formated matrix to start with '['"); //erase the starting '[' //note the ending ']' was removed by the getline function as the delim vecString.erase(0,sPos+1); trim(vecString); vecStringStream.str(vecString); //determine num of rows and cols int colCount = 0; T tmpVal; while(vecStringStream.good()){ vecStringStream >> tmpVal; data.push_back(tmpVal); ++colCount; } //check that dimensions agree if (colCount != vec.len) vec.setSize(colCount); //copy extracted data for (int i=0;i