/* * Copyright (C) 2009 * Robert Bosch LLC * Research and Technology Center North America * Palo Alto, California * * All rights reserved. * *------------------------------------------------------------------------------ * project ....: Autonomous Technologies * file .......: rtcVarMat.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_VARMAT_H #define RTC_VARMAT_H //== INCLUDES ================================================================== #include "rtcMath.h" #include "rtcVec2.h" #include "rtcVarVec.h" #include "rtcVarSMat.h" #include "rtcArray2.h" //== NAMESPACES ================================================================ namespace rtc { /// Forward declarations template class VarVec; // M-d vector template class VarMat; // MxN Matrix template class VarSMat; // MxM Matrix /** * Mathematical matrix container class. * * The VarMat class allows the representation of \e n x \e m matrices. * The rows will be indexed between 0 and n-1, and the columns between 0 * and m-1. * * The matrix class is a container class implemented as template. * * If you need to create a matrix of floats with 20 rows and 15 columns, * all elements initialized with an initial value of 4.27 just create it: * * \code * rtc::VarMat myMat(20,15,4.27f) // creates matrix with 300 elements * // all initialized with 4.27f * \endcode * * To access the matrix elements use the access operators. There are many * possibilities. With at(const int row, const int col) is possible to * access an element directly. * */ template class VarMat : public Array2 { public: // Constructors VarMat(); VarMat(int rows, int cols); VarMat(int rows, int cols, const T* d); VarMat(int rows, int cols, const T a); VarMat(const Array& a); // Cast Operation template VarMat(const VarMat& m); template VarMat(const Mat& m); // Mutators void setRow(int i, const VarVec& v); void setCol(int j, const VarVec& v); void setSubMat(int r, int c, const VarMat& m); // Casting Mutators template void set(const VarMat& m); template void set(const Mat& m); template VarMat& operator = (const VarMat& m); template VarMat& operator = (const Mat& m); // Accessors int length() const; VarVec getRow(int r) const; VarVec getCol(int c) const; VarMat getSubMat(int i, int j, int sub_rows, int sub_cols); // Addition and subtraction: +/- VarMat& add(const VarMat& m); void addSubMat(int r, int c, const VarMat& m); VarMat& subtract(const VarMat& m); void subtractSubMat(int r, int c, const VarMat& m); VarMat operator + (const VarMat& m) const; void operator += (const VarMat& m); VarMat operator - (const VarMat& m) const; void operator -= (const VarMat& m); VarMat operator - () const; // Addition and subtraction: +/- VarMat& add(const T a); VarMat& subtract(const T a); VarMat operator + (const T a) const; void operator += (const T a); VarMat operator - (const T a) const; void operator -= (const T a); // Multiplication and division: *// VarMat operator * (const T a) const; void operator *= (const T a); VarMat operator / (const T a) const; void operator /= (const T a); // Multiplication: * VarVec operator * (const VarVec& v) const; VarMat operator * (const VarMat& m) const; void operator *= (const VarMat& m); // Equality and inequality tests VarMat operator == (const VarMat& m) const; VarMat operator != (const VarMat& m) const; VarMat operator >= (const VarMat& m) const; VarMat operator <= (const VarMat& m) const; VarMat operator > (const VarMat& m) const; VarMat operator < (const VarMat& m) const; int compareTo(const VarMat& m) const; bool equalTo(const VarMat& m, const T tol = T(0)) const; // Other matrix operations VarMat transposed() const; // Random matrix VarMat uniformRand(const T a = T(0), const T b = T(1)); VarMat normalRand(const T mean = T(0), const T stdev = T(1)); // static VarMat multivariateGauss(const Vec& mean, const SMat& cov); // General elementwise operations void perform(T (*mathFun)(T)); // Reductions: Max/Min, Sum/Product //T max() const; //T min() const; VarVec sum() const; //T prod() const; // Bilinear Interpolation T interpolate(const float i, const float j) const; // statistical operations VarVec meanOfRows() const; VarSMat covarianceMatrixOfRows() const; // inherit member data and functions of parent using Array::x; using Array::len; using Array::set; using Array::mul; using Array2::setSize; using Array2::rows; using Array2::columns; }; // Declare a few common typdefs typedef VarMat VarMatb; typedef VarMat VarMatc; typedef VarMat VarMatuc; typedef VarMat VarMati; typedef VarMat VarMatf; typedef VarMat VarMatd; // Global operators to for cases where VarMat // is the second argument in a binary operator template VarMat operator * (const T a, const VarMat &m); // template Vec operator * (const Vec& v, const VarMat &m); // ASCII stream IO template std::ostream& operator<<(std::ostream& os, const VarMat& m); template std::istream& operator>>(std::istream& is, VarMat& m); //============================================================================== // VarMat //============================================================================== // Constructors /** * default Ctor */ template inline VarMat::VarMat() : Array2() {} /** Ctor that initializes an empty matrix. * @param rows the number of rows * @param cols the number of columns */ template inline VarMat::VarMat(int rows, int cols) : Array2(rows,cols) { } /** Ctor that initializes from an array. * @param rows the number of rows * @param cols the number of columns * @param d the (row major) data array of length rows*cols */ template inline VarMat::VarMat(int rows, int cols, const T* d) : Array2(rows,cols,d) { } /** Ctor that initializes ALL ELEMENTS to a scalar value. * @param rows the number of rows * @param cols the number of columns * @param a the value to which all elements will be set */ template inline VarMat::VarMat(int rows, int cols, const T a) : Array2(rows,cols,a) { } /** Ctor that initializes from passed matrix. * @param a the matrix to be copied. */ template inline VarMat::VarMat(const Array& a) : Array2(a) { } // Casting Operation /** Casting Ctor that initializes from passed matrix with type cast. * @param m the matrix to be copied. */ template template inline VarMat::VarMat(const VarMat& m) : Array2() { setSize(m.rows(),m.columns()); set(m); } // Mutators /** Casting Ctor that initializes from passed matrix with type cast. * @param m the matrix to be copied. */ template template inline VarMat::VarMat(const Mat& m) : Array2() { setSize(M,N); set(m); } // Mutators /** Set a row. * Does bounds checking if MATMATH_CHECK_BOUNDS is set * @param i zero based index of row to set * @param v source vector */ template inline void VarMat::setRow(int i, const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (columns()!=v.size() || i < 0 || i > rows() ) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::setRow(" << i << ", "; ss << "VarVec<" << v.size() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int j=0,k=i*columns();j inline void VarMat::setCol(int j, const VarVec& v) { #if MATMATH_CHECK_BOUNDS if (rows()!=v.size() || j < 0 || j > rows() ) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::setCol(" << j << ", "; ss << "VarVec<" << v.size() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int i=0,k=j;i inline void VarMat::setSubMat(int i, int j, const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+m.rows() > rows() || j < 0 || j+m.columns() > columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::setSubMat(" << i << ", " << j << ", "; ss << "VarMat<" << m.rows() << "," << m.columns() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int id=i,is=0;id template inline void VarMat::set(const VarMat& m) { if(rows()!=m.rows()||columns()!=m.columns()) setSize(m.rows(),m.columns()); for (int k=0;k template inline void VarMat::set(const Mat& m) { if(rows()!=M||columns()!=N) setSize(M,N); for (int k=0;k template inline VarMat& VarMat::operator = (const VarMat& m) { set(m); } /** Set from another matrix with type cast. * @param m the matrix to replicate. */ template template inline VarMat& VarMat::operator = (const Mat& m) { set(m); } // Accessors /** Returns the number of matrix elements * @return the number of matrix elements */ template inline int VarMat::length() const { return len; } /** Get a row. * Does bounds checking if MATMATH_CHECK_BOUNDS is set * @param i zero based index of row to get */ template inline VarVec VarMat::getRow(int i) const { #if MATMATH_CHECK_BOUNDS if (i < 0 || i >= rows()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::getRow(" << i; ss << "): index out of range\n"; throw Exception(ss.str()); } #endif VarVec v(columns()); for (int j=0,k=i*columns();j inline VarVec VarMat::getCol(int j) const { #if MATMATH_CHECK_BOUNDS if (j < 0 || j >= columns()) { std::stringstream ss; ss << "Mat<" << rows() << "," << columns() << ">::getCol(" << j; ss << "): index out of range\n"; throw Exception(ss.str()); } #endif VarVec v(rows()); for (int i=0,k=j;i inline VarMat VarMat::getSubMat(int i, int j, int sub_rows, int sub_cols) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+sub_rows > rows() || j < 0 || j+sub_cols > columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::getSubMat(" << i; ss << ", " << j << "): index out of range\n"; throw Exception(ss.str()); } #endif VarMat m(sub_rows,sub_cols,T(0)); for (int id=i,is=0;id +/- /** Addition. */ template inline VarMat& VarMat::add(const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::add (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int k=0;k inline void VarMat::addSubMat(int i, int j, const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+m.rows() > rows() || j < 0 || j+m.columns() > columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::setSubMat(" << i << ", " << j << ", "; ss << "VarVec<" << m.rows() << "," << m.columns() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int id=i,is=0;id inline VarMat& VarMat::subtract(const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::subtract (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int k=0;k inline void VarMat::subtractSubMat(int i, int j, const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (i < 0 || i+m.rows() > rows() || j < 0 || j+m.columns() > columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::setSubMat(" << i << ", " << j << ", "; ss << "VarVec<" << m.rows() << "," << m.columns() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int id=i,is=0;id +/- /** Addition operator. */ template inline VarMat VarMat::operator + (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator + (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat mp(rows(),columns()); for (int k=0;k inline void VarMat::operator += (const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator += (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int k=0;k inline VarMat VarMat::operator - (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator - (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat mp(rows(),columns()); for (int k=0;k inline void VarMat::operator -= (const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator -= (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif for (int k=0;k inline VarMat VarMat::operator - () const { VarMat mp(rows(),columns()); for (int k=0;k +/- /** Addition. */ template inline VarMat& VarMat::add(const T a) { for (int k=0;k inline VarMat& VarMat::subtract(const T a) { for (int k=0;k +/- inline VarMat VarMat::operator + (const T a) const { VarMat mp(rows(),columns()); for (int k=0;k inline void VarMat::operator += (const T a) { for (int k=0;k inline VarMat VarMat::operator - (const T a) const { VarMat mp(rows(),columns()); for (int k=0;k inline void VarMat::operator -= (const T a) { for (int k=0;k *// /** Matrix-Scalar multiplication operator. */ template inline VarMat VarMat::operator * (const T a) const { VarMat m(rows(),columns()); for (int k=0;k inline void VarMat::operator *= (const T a) { for (int k=0;k inline VarMat VarMat::operator / (const T a) const { VarMat m(rows(),columns()); for (int k=0;k inline void VarMat::operator /= (const T a) { for (int k=0;k VarMat operator * (const T a, const VarMat &m) { VarMat mp(m.rows(),m.columns()); for (int k=0;k * /** Matrix-Vector multiplication operator. */ template inline VarVec VarMat::operator * (const VarVec& v) const { #if MATMATH_CHECK_BOUNDS if (columns()!=v.length()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator * (" << ss << "VarVec<" << v.length() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarVec vp(rows(),T(0)); for (int i=0,k=0;i VarVec operator * (const VarVec& v, const VarMat &m) { #if MATMATH_CHECK_BOUNDS if (m.rows()!=v.length()) { std::stringstream ss; ss << "VarMat<" << m.rows() << "," << m.columns() << ">::operator * ("; ss << "VarVec<" << v.length() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarVec vp(m.columns(),T(0)); for (int i=0,k=0;i * /** Matrix-Matrix multiplication operator. */ template inline VarMat VarMat::operator * (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (columns()!=m.rows()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator * (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat mp(rows(),m.columns(),T(0)); for (int i=0;i inline void VarMat::operator *= (const VarMat& m) { #if MATMATH_CHECK_BOUNDS if (columns()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator *= (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif (*this) = (*this)*m; } // Equality and inequality tests. /** Element-wise test for equality. * @return matrix of boolean results */ template inline VarMat VarMat::operator == (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator == (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat b(rows(),columns(),false); for (int i=0;i inline VarMat VarMat::operator != (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator != (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat b(rows(),columns(),false); for (int i=0;i inline VarMat VarMat::operator >= (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator >= (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat b(rows(),columns(),false); for (int i=0;i= m.x[i]) b.x[i] = true; return b; } /** Element-wise test for less or equal. * @return matrix of boolean results */ template inline VarMat VarMat::operator <= (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator <= (" << ss << "VarMat<" << m.rows() << "," << m.columns() << "): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat b(rows(),columns(),false); for (int i=0;i inline VarMat VarMat::operator > (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator > (" << ss << "VarMat<" << m.rows() << "," << m.columns() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat b(rows(),columns(),false); for (int i=0;i m.x[i]) b.x[i] = true; return b; } /** Element-wise test for less. * @return matrix of boolean results */ template inline VarMat VarMat::operator < (const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::operator < (" << ss << "VarMat<" << m.rows() << "," << m.columns() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif VarMat b(rows(),columns(),false); for (int i=0;i inline int VarMat::compareTo(const VarMat& m) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::compareTo(" << ss << "VarMat<" << m.rows() << "," << m.columns() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif int g=0, l=0; for (int i=0;i m.x[i]) g++; } if (l==(len)) return -1; else if (g==(len)) return 1; else return 0; } /** Compare the entire matrix to the passed matrix. * @returns true of all corresponding elements are within the given tolerance */ template inline bool VarMat::equalTo(const VarMat& m, const T tol) const { #if MATMATH_CHECK_BOUNDS if (rows()!=m.rows() || columns()!=m.columns()) { std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::equalTo(" << ss << "VarMat<" << m.rows() << "," << m.columns() << ">): not a valid operation\n"; throw Exception(ss.str()); } #endif bool t = true; for (int i=0;i tol) t = false; return t; } // Transpose /** Return the transpose of the matrix without modifying matrix. */ template inline VarMat VarMat::transposed() const { VarMat mp(columns(),rows()); for (int i=0;i inline VarMat VarMat::uniformRand(const T a, const T b) { VarMat m(rows(),columns()); for (int i=0;i(a,b); return m; } /** Create matrix of samples from a normal distribution. * @param mean mean of normal distribution * @param stdev standard deviation of normal distribution * @return matrix of normal samples */ template inline VarMat VarMat::normalRand(const T mean, const T stdev) { VarMat m(rows(),columns()); for (int i=0;i(mean,stdev); return m; } // /** Create matrix of samples from a multivariate gaussian distribution. // * @param mean mean of normal distribution // * @param stdev standard deviation of normal distribution // * @return matrix of normal samples // */ // template // inline VarMat VarMat::multivariateGauss(const Vec& mean, const SMat& cov) { // VarMat m; // SMat S(cov); // int n=S.choleskyDecomp(); // assert(n==0); // S.transpose(); // VarMat X = normalRand(); // for(int j=0;j std::ostream& operator<<(std::ostream& os, const VarMat& mat) { int minFieldWidth = os.precision()+2; //case with 1 row if (mat.rows() == 1){ os << "[" ; for (int i=0; i std::istream& operator>>(std::istream& is, VarMat& mat){ using namespace std; vector data; string sizeString; string matString; stringstream matStringStream; string rowString; stringstream rowStringStream; int sPos; getline(is, matString, ']'); sPos = matString.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 matString.erase(0,sPos+1); matStringStream.str(matString); //determine num of rows and cols int rowCount = 0, colCount = 0; int cols = -1; float tmpVal; while(getline(matStringStream, rowString, ';')){ rowStringStream << rowString; colCount = 0; while(rowStringStream.good()){ rowStringStream >> tmpVal; data.push_back(tmpVal); ++colCount; } rowStringStream.clear(); //check that we have same num of entries in each row if (cols == -1) cols = colCount; else{ if (colCount != cols){ throw Exception("format error: different number of elements in rows."); } } ++rowCount; } //check that dimensions agree if (rowCount != mat.rows() || colCount != mat.columns()) mat.setSize(rowCount,colCount); //copy extracted data for (int i=0;i inline void VarMat::perform(T (*mathFun)(T)) { for (int i=0;i inline VarVec VarMat::sum() const { VarVec s(columns(),T(0)); for (int j=0;j inline T VarMat::interpolate(const float i, const float j) const { int r = rows(); int c = columns(); int truncR = rtc_clamp(static_cast(i),0,r-1); int truncR1 = rtc_clamp(truncR+1,0,r-1); const float fractR = i - static_cast(truncR); int truncC = rtc_clamp(static_cast(j),0,c-1); int truncC1 = rtc_clamp(truncC+1,0,c-1); const float fractC = j - static_cast(truncC); // do the interpolation const T syx = x[truncR*c+truncC]; const T syx1 = x[truncR*c+truncC1]; const T sy1x = x[truncR1*c+truncC]; const T sy1x1 = x[truncR1*c+truncC1]; // normal interpolation within range const T tmp1 = syx + (syx1-syx)*T(fractC); const T tmp2 = sy1x + (sy1x1-sy1x)*T(fractC); return (tmp1 + (tmp2-tmp1)*T(fractR)); } /** The meanOfRows means the mean of all rows, i.e. a row vector containing * (for the arithmetical mean) the sum of all row vectors divided by the * number of rows. * @returns the mean of all rows */ template inline VarVec VarMat::meanOfRows() const { VarVec m(columns(),T(0)); for (int j=0;j(rows()); return m; } /* * This is a new, faster version, written by Gu Xin: */ template inline VarSMat VarMat::covarianceMatrixOfRows() const { VarSMat dest(columns(),T(0)); //Implementation for the sum of Matrix[X]; if (rows()<2) { //just one row std::stringstream ss; ss << "VarMat<" << rows() << "," << columns() << ">::covarianceMatrixOfRows(): " << ss << "matrix has to have more than one row\n"; throw Exception(ss.str()); } // mean vector VarVec mu(columns(),T(0)); /* * the loop gets out the result of the Matrix[X]; * Matrix[X]=sum(Matrix[X(i)]);-- i from 0 to n-1-- */ for(int i=0;i tmpV = getRow(i); mu.add(tmpV); VarSMat tmp = tmpV.outer(tmpV); dest.add(tmp); //add the Matrix[X(i)] to Matrix[sumMatrix]; } //End of the Implementation for the sum of Matrix[X]; //Implementation for the Matrix[meanOf]; mu/=static_cast(rows()); VarSMat tmp = mu.outer(mu); tmp *= static_cast(rows()); //get the result of the difference from Matrix[X] and Matrix[meanOf]; dest.subtract(tmp); dest/=static_cast(rows()-1); return dest; } //============================================================================== } // NAMESPACE rtc //============================================================================== #endif // RTC_VARMAT_H defined //==============================================================================