/* * Copyright (C) 2009 * Robert Bosch LLC * Research and Technology Center North America * Palo Alto, California * * All rights reserved. * *------------------------------------------------------------------------------ * project ....: Autonomous Technologies * file .......: rtcVec.h * authors ....: Benjamin Pitzer * organization: Robert Bosch LLC * creation ...: 08/16/2006 * modified ...: $Date: 2009-02-16 17:39:28 -0800 (Mon, 16 Feb 2009) $ * changed by .: $Author: kls1pal $ * revision ...: $Revision: 48 $ */ #ifndef RTC_VEC_H #define RTC_VEC_H //== INCLUDES ================================================================== #include #include #include "rtcMath.h" #include "rtcMat.h" //== NAMESPACES ================================================================ namespace rtc { // Forward declarations template class Vec; // M-d vector template class Mat; // MxN Matrix template class SMat; // MxM Square Matrix /** * An M-Dimensional statically allocated vector. * Represents an M dimensional vector of type T */ template class Vec : public IOObject { public: // Constructors Vec(); Vec(const T* d); Vec(const T a); Vec(const Vec& v); // Cast Operation template Vec(const Vec& v); // Mutators void set(const T* d); void set(const T a); void set(const Vec& v); Vec& operator = (const T a); Vec& operator = (const T* d); Vec& operator = (const Vec& v); template void setSubVec(const int i, const Vec& v); // Casting Mutators template void set(const Vec& v); template Vec& operator = (const Vec& v); // Accessors T operator () (const int i) const; T& operator () (const int i); T operator [] (const int i) const; T& operator [] (const int i); T& at(const int i); const T& at(const int i) const; template Vec getSubVec(const int i) const; // Norms and Normalize T norm() const; T normSqr() const; T pnorm(float p) const; T normalize(); Vec normalized() const; // Reductions: Max/Min, Sum/Product T max() const; T min() const; T sum() const; T prod() const; Vec 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 Vec& v); Vec performed(T (*mathFun)(T)); Vec performed(T (*mathFun)(T,T), const T arg2); Vec performed(T (*mathFun)(T,T), const Vec& v); Vec minimize(const Vec& other); Vec maximize(const Vec& other); // Dot and Outer Products T dot(const Vec& v) const; SMat outer(const Vec& v) const; SMat outer() const; // Random vectors and sorting static Vec uniformRand(const T a = T(0), const T b = T(1)); static Vec normalRand(const T mean = T(0), const T stdev = T(1)); static Vec multivariateGauss(const Vec& mean, const SMat& cov); void sort(bool ascending = true); Vec sorted(bool ascending = true); // Addition and subtraction Vec& add(const Vec& v); Vec& subtract(const Vec& v); // Addition and subtraction operator Vec operator + (const Vec& v) const; void operator += (const Vec& v); Vec operator - (const Vec& v) const; void operator -= (const Vec& v); Vec operator - () const; Vec add(const T a); Vec operator + (const T a) const; void operator += (const T a); Vec subtract(const T a); Vec operator - (const T a) const; void operator -= (const T a); // Multiplication and division operator Vec operator * (const T a) const; Vec operator / (const T a) const; void operator *= (const T a); void operator /= (const T a); // Equality and inequality tests int compareTo(const Vec& v) const; bool equalTo(const Vec& v, const T tol = T(0)) const; // Equality and inequality tests operator bool operator == (const Vec& v) const; bool operator != (const Vec& v) const; // Vec operator == (const Vec& v) const; // Vec operator != (const Vec& v) const; Vec operator >= (const Vec& v) const; Vec operator <= (const Vec& v) const; Vec operator > (const Vec& v) const; Vec operator < (const Vec& v) const; // Element-wise operations Vec operator * (const Vec& v) const; Vec operator / (const Vec& v) const; void operator *= (const Vec& v); void operator /= (const Vec& v); // Serialization bool write(OutputHandler& oh) const; bool read(InputHandler& ih); //data T x[M]; ///< storage array }; // Global operators for cases where Vec // is the second argument in a binary operator template Vec operator + (const T a, const Vec& v); template Vec operator - (const T a, const Vec& v); template Vec operator * (const T a, const Vec& v); // ASCII stream IO template std::ostream& operator<<(std::ostream& os, const Vec& vec); template std::istream& operator>>(std::istream& is, Vec& vec); //============================================================================== // Vec //============================================================================== // Constructors /** Ctor that does no initalization. */ template inline Vec::Vec() {} /** Ctor that initializes elements from an array. * @param d pointer to the initalization array */ template inline Vec::Vec(const T* d) { set(d); } /** Ctor that initializes all elements from a scalar. * @param a the value to assign to all elements */ template inline Vec::Vec(const T a) { set(a); } /** Ctor that initialized from vector of different type * @param v is the vector to duplicate */ template inline Vec::Vec(const Vec& v) : IOObject() { set(v); } // Casting Operation /** Casting Ctor that initializes from passed vector. * @param v is the vector to duplicate */ template template inline Vec::Vec(const Vec& v) { set(v); } // Mutators /** Set all elements equal to a scalar. * @param a the value to assign to all elements */ template inline void Vec::set(const T a) { if (a == T(0)) memset(x,0,M*sizeof(T)); else for (int i=0;i inline void Vec::set(const T* d) { for (int i=0;i inline void Vec::set(const Vec& v) { memcpy((void*)x,(void*)v.x,M*sizeof(T)); } /** Set all elements equal to a scalar. * @param a the value to assign to all elements */ template inline Vec& Vec::operator = (const T a) { set(a); return *this; } /** Set all elements from an array. * @param d pointer to the initalization array */ template inline Vec& Vec::operator = (const T* d) { set(d); return *this; } /** Set this vector equal to passed vector * @param v the vector to replicate */ template inline Vec& Vec::operator = (const Vec& v) { set(v); return *this; } /** 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 template inline void Vec::setSubVec(const int i, const Vec& v) { for (int j=i,k=0;j template inline void Vec::set(const Vec& v) { for (int i=0;i template inline Vec& Vec::operator = (const Vec& 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 Vec::operator () (const int i) const { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > M) { std::cerr << "Vec<" << M << ">::(" << i << "): index out of range\n"; std::cerr << std::flush; exit(1); } #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& Vec::operator () (const int i) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > M) { std::cerr << "&Vec<" << M << ">::(" << i << "): index out of range\n"; std::cerr << std::flush; exit(1); } #endif return x[i]; } /** 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 Vec::operator [] (const int i) const { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > M) { std::cerr << "Vec<" << M << ">::(" << i << "): index out of range\n"; std::cerr << std::flush; exit(1); } #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& Vec::operator [] (const int i) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > M) { std::cerr << "&Vec<" << M << ">::(" << i << "): index out of range\n"; std::cerr << std::flush; exit(1); } #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& Vec::at(const int i) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > M) { std::cerr << "&Vec<" << M << ">::(" << i << "): index out of range\n"; std::cerr << std::flush; exit(1); } #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 const T& Vec::at(const int i) const { #if MATMATH_CHECK_BOUNDS if (i < 0 || i > M) { std::cerr << "&Vec<" << M << ">::(" << i << "): index out of range\n"; std::cerr << std::flush; exit(1); } #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 */ template template inline Vec Vec::getSubVec(const int i) const { Vec v(T(0)); for (int j=i,k=0;j inline T Vec::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 Vec::normSqr() const { T sum = T(0); for (int i=0;i inline T Vec::pnorm(float p) const { T sum = T(0); for (int i=0;i inline T Vec::normalize() { T l = norm(); if (l > T(0)) for (int i=0;i inline Vec Vec::normalized() const { Vec v(x); v.normalize(); return v; } // Maximum/Minimum value and Sum /** Find the maximum value of the vector * @returns the maximum value */ template inline T Vec::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 Vec::min() const { T m = x[0]; for (int i=1;i inline T Vec::sum() const { T s = T(0); for (int i=0;i inline Vec Vec::cumsum() const { Vec v; T s = T(0); for (int i=0;i inline T Vec::prod() const { T p = T(1); for (int i=0;i inline void Vec::perform(T (*mathFun)(T)) { for (int i=0;i inline void Vec::perform(T (*mathFun)(T,T), const T arg2) { for (int i=0;i inline void Vec::perform(T (*mathFun)(T,T), const Vec& v) { for (int i=0;i inline Vec Vec::performed(T (*mathFun)(T)) { Vec v; for (int i=0;i inline Vec Vec::performed(T (*mathFun)(T,T), const T arg2) { Vec v; for (int i=0;i inline Vec Vec::performed(T (*mathFun)(T,T), const Vec& vp) { Vec v; for (int i=0;i inline Vec Vec::minimize(const Vec& other) { for (int i=0;i inline Vec Vec::maximize(const Vec& other) { 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 Vec::dot(const Vec& v) const { T sum = T(0); for (int i=0;i inline SMat Vec::outer(const Vec& v) const { SMat m; for (int i=0,k=0;i inline SMat Vec::outer() const { SMat m; for (int i=0,k=0;i inline Vec Vec::uniformRand(const T a, const T b) { Vec 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 Vec Vec::normalRand(const T mean, const T stdev) { Vec v; for (int i=0;i(mean, stdev); return v; } /** Create vector from a multivariate gaussian distribution. * @param mean mean of normal distribution * @param cov covariance of normal distribution * @return vector of a multivariate gaussian distribution */ template inline Vec Vec::multivariateGauss(const Vec& mean, const SMat& cov) { Vec v; SMat S(cov); int n=S.choleskyDecomp(); S.transpose(); Vec X = normalRand(); v = mean + S*X; return v; } /** Sort elements in increasing order. * @return sorted vector */ template inline void Vec::sort(bool ascending) { int count; do { count = 0; for (int i=0;i<(M-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 in increasing order. * @return sorted vector */ template inline Vec Vec::sorted(bool ascending) { Vec v(x); v.sort(ascending); return v; } // Addition and subtraction /** Vector-Vector addition. */ template inline Vec& Vec::add(const Vec& v) { for (int i=0;i inline Vec& Vec::subtract(const Vec& v) { for (int i=0;i inline Vec Vec::operator + (const Vec& v) const { Vec vp; for (int i=0;i inline void Vec::operator += (const Vec& v) { for (int i=0;i inline Vec Vec::operator - (const Vec& v) const { Vec vp; for (int i=0;i inline void Vec::operator -= (const Vec& v) { for (int i=0;i inline Vec Vec::operator - () const { Vec vp; for (int i=0;i inline Vec Vec::add(const T a) { for (int i=0;i inline Vec Vec::operator + (const T a) const { Vec vp; for (int i=0;i inline void Vec::operator += (const T a) { for (int i=0;i inline Vec Vec::subtract(const T a) { for (int i=0;i inline Vec Vec::operator - (const T a) const { Vec vp; for (int i=0;i inline void Vec::operator -= (const T a) { for (int i=0;i inline Vec operator + (const T a, const Vec& v) { Vec vp; for (int i=0;i inline Vec operator - (const T a, const Vec& v) { Vec vp; for (int i=0;i inline Vec Vec::operator * (const T a) const { Vec vp; for (int i=0;i inline Vec Vec::operator / (const T a) const { Vec vp; for (int i=0;i inline void Vec::operator *= (const T a) { for (int i=0;i inline void Vec::operator /= (const T a) { for (int i=0;i inline Vec operator * (const T a, const Vec& v) { Vec vp; for (int i=0;i inline bool Vec::operator == (const Vec& v) const { for (int i=0;i inline bool Vec::operator != (const Vec& v) const { for (int i=0;i // inline Vec Vec::operator == (const Vec& v) const { // Vec b(false); // for (int i=0;i // inline Vec Vec::operator != (const Vec& v) const { // Vec b(false); // for (int i=0;i inline Vec Vec::operator >= (const Vec& v) const { Vec b(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 Vec Vec::operator <= (const Vec& v) const { Vec b(false); for (int i=0;i inline Vec Vec::operator > (const Vec& v) const { Vec b(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 Vec Vec::operator < (const Vec& v) const { Vec b(false); for (int i=0;i inline int Vec::compareTo(const Vec& v) const { int g=0, l=0; for (int i=0;i v.x[i]) g++; } if (l==M) return -1; else if (g==M) 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 Vec::equalTo(const Vec& v, const T tol) const { bool t = true; for (int i=0;i tol) t = false; return t; } // Element-wise multiplication and division /** Element-wise multiplication. */ template inline Vec Vec::operator * (const Vec& v) const { Vec vp; for (int i=0;i inline Vec Vec::operator / (const Vec& v) const { Vec vp; for (int i=0;i inline void Vec::operator *= (const Vec& v) { for (int i=0;i inline void Vec::operator /= (const Vec& v) { for (int i=0;i inline bool Vec::write(OutputHandler& oh) const { return oh.write((char *)(x),M*sizeof(T)); } /** Restores state from a binary stream. */ template inline bool Vec::read(InputHandler& ih) { return ih.read((char *)(x),M*sizeof(T)); } /** Write state to stream as formated ASCII */ template std::ostream& operator<<(std::ostream& os, const Vec& vec) { int minFieldWidth = os.precision()+2; os << "["; for (int i=0; i std::istream& operator>>(std::istream& is, Vec& 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 vector 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 != M){ std::stringstream ss; ss << "format error: formated text has " << colCount << " columns"; ss << " while destination vector has " << M << " columns" << endl; throw Exception(ss.str()); } //copy extracted data for (int i=0;i bool rtc_write(OutputHandler& oh, const Vec& data) { return data.write(oh); }; /** * handler functions with standard storable interface */ template bool rtc_read(InputHandler& ih, Vec& data) { return data.read(ih); }; //============================================================================== } // NAMESPACE rtc //============================================================================== #endif // RTC_VEC_H defined //==============================================================================