00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef mrpt_math_matrix_ops_H
00029 #define mrpt_math_matrix_ops_H
00030
00031 #include <mrpt/math/math_frwds.h>
00032
00033 #include <mrpt/math/CMatrix.h>
00034 #include <mrpt/math/CMatrixD.h>
00035 #include <mrpt/utils/CStream.h>
00036
00037 #include <mrpt/math/CMatrixTemplateNumeric.h>
00038 #include <mrpt/math/CMatrixFixedNumeric.h>
00039
00040 #include <mrpt/math/ops_containers.h>
00041
00042 #include <mrpt/utils/metaprogramming.h>
00043
00044
00045
00046
00047
00048
00049
00050 namespace mrpt
00051 {
00052 namespace math
00053 {
00054
00055
00056
00057
00058
00059
00060
00061 template <size_t NROWS,size_t NCOLS>
00062 mrpt::utils::CStream &operator>>(mrpt::utils::CStream &in, CMatrixFixedNumeric<float,NROWS,NCOLS> & M) {
00063 CMatrix aux;
00064 in.ReadObject(&aux);
00065 ASSERTMSG_(M.cols()==aux.cols() && M.rows()==aux.rows(), format("Size mismatch: deserialized is %ux%u, expected is %ux%u",(unsigned)aux.getRowCount(),(unsigned)aux.getColCount(),(unsigned)NROWS,(unsigned)NCOLS))
00066 M = aux;
00067 return in;
00068 }
00069
00070 template <size_t NROWS,size_t NCOLS>
00071 mrpt::utils::CStream &operator>>(mrpt::utils::CStream &in, CMatrixFixedNumeric<double,NROWS,NCOLS> & M) {
00072 CMatrixD aux;
00073 in.ReadObject(&aux);
00074 ASSERTMSG_(M.cols()==aux.cols() && M.rows()==aux.rows(), format("Size mismatch: deserialized is %ux%u, expected is %ux%u",(unsigned)aux.getRowCount(),(unsigned)aux.getColCount(),(unsigned)NROWS,(unsigned)NCOLS))
00075 M = aux;
00076 return in;
00077 }
00078
00079
00080 template <size_t NROWS,size_t NCOLS>
00081 mrpt::utils::CStream &operator<<(mrpt::utils::CStream &out,const CMatrixFixedNumeric<float,NROWS,NCOLS> & M) {
00082 CMatrix aux = CMatrixFloat(M);
00083 out.WriteObject(&aux);
00084 return out;
00085 }
00086
00087 template <size_t NROWS,size_t NCOLS>
00088 mrpt::utils::CStream &operator<<(mrpt::utils::CStream &out,const CMatrixFixedNumeric<double,NROWS,NCOLS> & M) {
00089 CMatrixD aux = CMatrixDouble(M);
00090 out.WriteObject(&aux);
00091 return out;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 template <typename T,size_t NROWS,size_t NCOLS>
00103 inline std::ostream & operator << (std::ostream & s, const CMatrixFixedNumeric<T,NROWS,NCOLS>& m)
00104 {
00105 Eigen::IOFormat fmt; fmt.matSuffix="\n";
00106 return s << m.format(fmt);
00107 }
00108
00109
00110 template<typename T>
00111 inline std::ostream & operator << (std::ostream & s, const CMatrixTemplateNumeric<T>& m)
00112 {
00113 Eigen::IOFormat fmt; fmt.matSuffix="\n";
00114 return s << m.format(fmt);
00115 }
00116
00117
00118 template<typename T>
00119 inline std::ostream & operator << (std::ostream & s, const mrpt::dynamicsize_vector<T>& m)
00120 {
00121 Eigen::IOFormat fmt; fmt.rowSeparator=" "; fmt.matPrefix="["; fmt.matSuffix="]";
00122 return s << m.format(fmt);
00123 }
00124
00125
00126
00127
00128
00129 template <class Derived>
00130 inline const typename Eigen::MatrixBase<Derived>::AdjointReturnType operator ~(const Eigen::MatrixBase<Derived> &m) {
00131 return m.adjoint();
00132 }
00133
00134
00135 template <class Derived>
00136 inline typename Eigen::MatrixBase<Derived>::PlainObject operator !(const Eigen::MatrixBase<Derived> &m) {
00137 return m.inv();
00138 }
00139
00140
00141
00142
00143
00144 template <typename MAT_H, typename MAT_C, typename MAT_R>
00145 inline void multiply_HCHt(
00146 const MAT_H &H,
00147 const MAT_C &C,
00148 MAT_R &R,
00149 bool accumResultInOutput )
00150 {
00151 if (accumResultInOutput)
00152 R += ( (H * C.template selfadjointView<Eigen::Lower>()).eval() * H.adjoint()).eval().template selfadjointView<Eigen::Lower>();
00153 else
00154 R = ( (H * C.template selfadjointView<Eigen::Lower>()).eval() * H.adjoint()).eval().template selfadjointView<Eigen::Lower>();
00155 }
00156
00157
00158 template <typename VECTOR_H, typename MAT_C>
00159 typename MAT_C::value_type
00160 multiply_HCHt_scalar(const VECTOR_H &H, const MAT_C &C)
00161 {
00162 return (H.matrix().adjoint() * C * H.matrix()).eval()(0,0);
00163 }
00164
00165
00166 template <typename MAT_H, typename MAT_C, typename MAT_R>
00167 void multiply_HtCH(
00168 const MAT_H &H,
00169 const MAT_C &C,
00170 MAT_R &R,
00171 bool accumResultInOutput)
00172 {
00173 if (accumResultInOutput)
00174 R += ( (H.adjoint() * C.template selfadjointView<Eigen::Lower>()).eval() * H).eval().template selfadjointView<Eigen::Lower>();
00175 else
00176 R = ( (H.adjoint() * C.template selfadjointView<Eigen::Lower>()).eval() * H).eval().template selfadjointView<Eigen::Lower>();
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 template<class MAT_IN,class VECTOR, class MAT_OUT>
00187 void meanAndCovMat(
00188 const MAT_IN & v,
00189 VECTOR & out_mean,
00190 MAT_OUT & out_cov
00191 )
00192 {
00193 const size_t N = v.rows();
00194 ASSERTMSG_(N>0,"The input matrix contains no elements");
00195 const double N_inv = 1.0/N;
00196
00197 const size_t M = v.cols();
00198 ASSERTMSG_(M>0,"The input matrix contains rows of length 0");
00199
00200
00201 out_mean.assign(M,0);
00202 for (size_t i=0;i<N;i++)
00203 for (size_t j=0;j<M;j++)
00204 out_mean[j]+=v.coeff(i,j);
00205 out_mean*=N_inv;
00206
00207
00208
00209
00210 out_cov.zeros(M,M);
00211 for (size_t i=0;i<N;i++)
00212 {
00213 for (size_t j=0;j<M;j++)
00214 out_cov.get_unsafe(j,j)+=square(v.get_unsafe(i,j)-out_mean[j]);
00215
00216 for (size_t j=0;j<M;j++)
00217 for (size_t k=j+1;k<M;k++)
00218 out_cov.get_unsafe(j,k)+=(v.get_unsafe(i,j)-out_mean[j])*(v.get_unsafe(i,k)-out_mean[k]);
00219 }
00220 for (size_t j=0;j<M;j++)
00221 for (size_t k=j+1;k<M;k++)
00222 out_cov.get_unsafe(k,j) = out_cov.get_unsafe(j,k);
00223 out_cov*=N_inv;
00224 }
00225
00226
00227
00228
00229
00230
00231 template<class MATRIX>
00232 inline Eigen::Matrix<typename MATRIX::Scalar,MATRIX::ColsAtCompileTime,MATRIX::ColsAtCompileTime>
00233 cov( const MATRIX &v )
00234 {
00235 Eigen::Matrix<double,MATRIX::ColsAtCompileTime,1> m;
00236 Eigen::Matrix<typename MATRIX::Scalar,MATRIX::ColsAtCompileTime,MATRIX::ColsAtCompileTime> C;
00237 meanAndCovMat(v,m,C);
00238 return C;
00239 }
00240
00241
00242 #define SAVE_MATRIX(M) M.saveToTextFile(#M ".txt");
00243
00244
00245
00246
00247 template <class MAT_A,class SKEW_3VECTOR,class MAT_OUT>
00248 void multiply_A_skew3(const MAT_A &A,const SKEW_3VECTOR &v, MAT_OUT &out)
00249 {
00250 MRPT_START
00251 ASSERT_EQUAL_(size(A,2),3)
00252 ASSERT_EQUAL_(v.size(),3)
00253 const size_t N = size(A,1);
00254 out.setSize(N,3);
00255 for (size_t i=0;i<N;i++)
00256 {
00257 out.set_unsafe(i,0, A.get_unsafe(i,1)*v[2]-A.get_unsafe(i,2)*v[1] );
00258 out.set_unsafe(i,1,-A.get_unsafe(i,0)*v[2]+A.get_unsafe(i,2)*v[0] );
00259 out.set_unsafe(i,2, A.get_unsafe(i,0)*v[1]-A.get_unsafe(i,1)*v[0] );
00260 }
00261 MRPT_END
00262 }
00263
00264
00265
00266 template <class SKEW_3VECTOR,class MAT_A,class MAT_OUT>
00267 void multiply_skew3_A(const SKEW_3VECTOR &v, const MAT_A &A,MAT_OUT &out)
00268 {
00269 MRPT_START
00270 ASSERT_EQUAL_(size(A,1),3)
00271 ASSERT_EQUAL_(v.size(),3)
00272 const size_t N = size(A,2);
00273 out.setSize(3,N);
00274 for (size_t i=0;i<N;i++)
00275 {
00276 out.set_unsafe(0,i,-A.get_unsafe(1,i)*v[2]+A.get_unsafe(2,i)*v[1] );
00277 out.set_unsafe(1,i, A.get_unsafe(0,i)*v[2]-A.get_unsafe(2,i)*v[0] );
00278 out.set_unsafe(2,i,-A.get_unsafe(0,i)*v[1]+A.get_unsafe(1,i)*v[0] );
00279 }
00280 MRPT_END
00281 }
00282
00283
00284
00285 namespace detail
00286 {
00287
00288 template <class MATORG, class MATDEST>
00289 void extractMatrix(
00290 const MATORG &M,
00291 const size_t first_row,
00292 const size_t first_col,
00293 MATDEST &outMat)
00294 {
00295 const size_t NR = outMat.getRowCount();
00296 const size_t NC = outMat.getColCount();
00297 ASSERT_BELOWEQ_( first_row+NR, M.getRowCount() )
00298 ASSERT_BELOWEQ_( first_col+NC, M.getColCount() )
00299 for (size_t r=0;r<NR;r++)
00300 for (size_t c=0;c<NC;c++)
00301 outMat.get_unsafe(r,c) = M.get_unsafe(first_row+r,first_col+c);
00302 }
00303
00304 }
00305
00306
00307
00308 }
00309 }
00310
00311
00312 #endif