00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace Bayesian_filter_matrix
00025 {
00026
00027 using ublas::row;
00028 using ublas::column;
00029 using ublas::trans;
00030 using ublas::prod;
00031 using ublas::inner_prod;
00032 using ublas::outer_prod;
00033
00034 enum EmptyTag {Empty};
00035
00036
00037 #ifndef BOOST_UBLAS_TYPENAME
00038 #define BOOST_UBLAS_TYPENAME typename
00039 #endif
00040
00041 #if (BOOST_VERSION >= 103100)
00042 using ublas::noalias;
00043 #else
00044 namespace detail
00045 {
00046
00047
00048 template<class C>
00049 class noalias_proxy {
00050 public:
00051 BOOST_UBLAS_INLINE
00052 noalias_proxy (C& lval):
00053 lval_ (lval) {}
00054
00055 template <class E>
00056 BOOST_UBLAS_INLINE
00057 void operator= (const E& e) {
00058 lval_.assign (e);
00059 }
00060
00061 template <class E>
00062 BOOST_UBLAS_INLINE
00063 void operator+= (const E& e) {
00064 lval_.plus_assign (e);
00065 }
00066
00067 template <class E>
00068 BOOST_UBLAS_INLINE
00069 void operator-= (const E& e) {
00070 lval_.minus_assign (e);
00071 }
00072
00073 private:
00074 void operator=( const noalias_proxy& );
00075 private:
00076 C& lval_;
00077 };
00078
00079 }
00080
00081
00082
00083 template <class E>
00084 BOOST_UBLAS_INLINE
00085 detail::noalias_proxy<E> noalias (ublas::matrix_expression<E>& lvalue) {
00086 return detail::noalias_proxy<E> (lvalue() );
00087 }
00088 template <class E>
00089 BOOST_UBLAS_INLINE
00090 detail::noalias_proxy<E> noalias (ublas::vector_expression<E>& lvalue) {
00091 return detail::noalias_proxy<E> (lvalue() );
00092 }
00093
00094 #endif
00095
00096
00097 namespace detail
00098 {
00099
00100
00101
00102
00103 template <class VecBase>
00104 class FMVec : public VecBase
00105 {
00106 public:
00107 typedef typename VecBase::value_type value_type;
00108 typedef typename VecBase::vector_temporary_type vector_temporary_type;
00109
00110
00111 explicit FMVec(EmptyTag) : VecBase()
00112 {}
00113 explicit FMVec(std::size_t size) : VecBase(size)
00114 {}
00115 FMVec(const FMVec& c) : VecBase(static_cast<const VecBase&>(c))
00116 {}
00117 template <class E>
00118 explicit FMVec(const ublas::vector_expression<E>& e) : VecBase(e)
00119 {}
00120 template <class E>
00121 FMVec(const ublas::matrix_column<E>& e) : VecBase(e)
00122 {}
00123
00124 template <class E>
00125 FMVec& operator= (const ublas::vector_expression<E>& r)
00126 {
00127 VecBase::operator=(r);
00128 return *this;
00129 }
00130 FMVec& operator= (const FMVec& r)
00131 {
00132 VecBase::assign(r);
00133 return *this;
00134 }
00135
00136
00137 const ublas::vector_range<const VecBase> sub_range(std::size_t b, std::size_t e) const
00138 {
00139 return ublas::vector_range<const VecBase>(*this, ublas::range(b,e));
00140 }
00141 ublas::vector_range<VecBase> sub_range(std::size_t b, std::size_t e)
00142 {
00143 return ublas::vector_range<VecBase>(*this, ublas::range(b,e));
00144 }
00145 };
00146
00147
00148
00149
00150
00151 template <class MatrixBase>
00152 class FMMatrix : public MatrixBase
00153 {
00154 public:
00155 typedef typename MatrixBase::value_type value_type;
00156 typedef typename MatrixBase::vector_temporary_type vector_temporary_type;
00157 typedef typename MatrixBase::matrix_temporary_type matrix_temporary_type;
00158
00159
00160 explicit FMMatrix(EmptyTag) : MatrixBase()
00161 {}
00162 FMMatrix(std::size_t size1, std::size_t size2) : MatrixBase(size1,size2)
00163 {}
00164 FMMatrix(const FMMatrix& c) : MatrixBase(static_cast<const MatrixBase&>(c))
00165 {}
00166 template <class E>
00167 explicit FMMatrix(const ublas::matrix_expression<E>& e) : MatrixBase(e)
00168 {}
00169
00170 template <class E>
00171 FMMatrix& operator= (const ublas::matrix_expression<E>& r)
00172 {
00173 MatrixBase::operator=(r);
00174 return *this;
00175 }
00176 FMMatrix& operator= (const FMMatrix& r)
00177 {
00178 MatrixBase::assign (r);
00179 return *this;
00180 }
00181
00182
00183 typedef ublas::matrix_row<FMMatrix> Row;
00184 typedef const ublas::matrix_row<const FMMatrix> const_Row;
00185 typedef ublas::matrix_column<FMMatrix> Column;
00186 typedef const ublas::matrix_column<const FMMatrix> const_Column;
00187
00188
00189
00190 static Row rowi(const typename MatrixBase::iterator1& ri)
00191 {
00192 return Row(static_cast<FMMatrix&>(ri()), ri.index1());
00193 }
00194 static const_Row rowi(const typename MatrixBase::const_iterator1& ri)
00195 {
00196 return const_Row(static_cast<const FMMatrix&>(ri()), ri.index1());
00197 }
00198 static Column columni(const typename MatrixBase::iterator2& ci)
00199 {
00200 return Column(static_cast<FMMatrix&>(ci()), ci.index2());
00201 }
00202 static const_Column columni(const typename MatrixBase::const_iterator2& ci)
00203 {
00204 return const_Column(static_cast<const FMMatrix&>(ci()), ci.index2());
00205 }
00206
00207
00208 ublas::matrix_range<const MatrixBase>
00209 sub_matrix(std::size_t s1, std::size_t e1, std::size_t s2, std::size_t e2) const
00210 {
00211 return ublas::matrix_range<const MatrixBase> (*this, ublas::range(s1,e1), ublas::range(s2,e2));
00212 }
00213 ublas::matrix_range<MatrixBase>
00214 sub_matrix(std::size_t s1, std::size_t e1, std::size_t s2, std::size_t e2)
00215 {
00216 return ublas::matrix_range<MatrixBase> (*this, ublas::range(s1,e1), ublas::range(s2,e2));
00217 }
00218
00219
00220 ublas::matrix_vector_slice<const MatrixBase>
00221 sub_column(std::size_t s1, std::size_t e1, std::size_t s2) const
00222
00223 {
00224 return ublas::matrix_vector_slice<const MatrixBase> (*this, ublas::slice(s1,1,e1-s1), ublas::slice(s2,0,e1-s1));
00225 }
00226 ublas::matrix_vector_slice<MatrixBase>
00227 sub_column(std::size_t s1, std::size_t e1, std::size_t s2)
00228
00229 {
00230 return ublas::matrix_vector_slice<MatrixBase> (*this, ublas::slice(s1,1,e1-s1), ublas::slice(s2,0,e1-s1));
00231 }
00232 };
00233
00234
00235
00236
00237
00238
00239 template <typename MemberType>
00240 class BaseFromMember
00241 {
00242 protected:
00243 MemberType member;
00244 explicit BaseFromMember() : member()
00245 {}
00246
00247 template <typename T1>
00248 explicit BaseFromMember( const T1& x1 ) : member( x1 )
00249 {}
00250
00251 template <typename T1, typename T2>
00252 explicit BaseFromMember( const T1& x1, const T2& x2 ) : member( x1, x2 )
00253 {}
00254 };
00255
00256
00257
00258
00259
00260
00261
00262 template <class MatrixBase>
00263 class SymMatrixWrapper :
00264 private BaseFromMember<MatrixBase>,
00265 public ublas::symmetric_adaptor<MatrixBase, ublas::upper>
00266 {
00267 typedef BaseFromMember<MatrixBase> matrix_type;
00268 typedef ublas::symmetric_adaptor<MatrixBase, ublas::upper> symadaptor_type;
00269 public:
00270 typedef typename MatrixBase::value_type value_type;
00271 typedef typename MatrixBase::vector_temporary_type vector_temporary_type;
00272 typedef typename MatrixBase::matrix_temporary_type matrix_temporary_type;
00273
00274 SymMatrixWrapper () : matrix_type(), symadaptor_type(matrix_type::member)
00275 {}
00276 SymMatrixWrapper (std::size_t size1, std::size_t size2) : matrix_type(size1,size2), symadaptor_type(matrix_type::member)
00277 {}
00278 explicit SymMatrixWrapper (const SymMatrixWrapper& r) : matrix_type(reinterpret_cast<const MatrixBase&>(r)), symadaptor_type(matrix_type::member)
00279 {}
00280 template <class E>
00281 explicit SymMatrixWrapper (const ublas::matrix_expression<E>& e) : matrix_type(e), symadaptor_type(matrix_type::member)
00282 {}
00283
00284 template <class E>
00285 SymMatrixWrapper& operator=(const ublas::matrix_expression<E>& r)
00286 {
00287 symadaptor_type::operator=(r);
00288 return *this;
00289 }
00290
00291
00292 const FMMatrix<MatrixBase>& asRowMatrix() const
00293 {
00294 return static_cast<const FMMatrix<MatrixBase>& >(matrix_type::member);
00295 }
00296 FMMatrix<MatrixBase>& asRowMatrix()
00297 {
00298 return static_cast<FMMatrix<MatrixBase>& >(matrix_type::member);
00299 }
00300
00301
00302 void clear()
00303 { matrix_type::member.clear();
00304 }
00305 void resize(std::size_t nsize1, std::size_t nsize2, bool preserve = true)
00306 {
00307 matrix_type::member.resize(nsize1, nsize2, preserve);
00308 }
00309 };
00310
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 using detail::FMVec;
00320 using detail::FMMatrix;
00321
00322
00323 typedef FMVec<detail::BaseVector> Vec;
00324 typedef FMMatrix<detail::BaseRowMatrix> RowMatrix;
00325 typedef RowMatrix Matrix;
00326 typedef FMMatrix<detail::BaseColMatrix> ColMatrix;
00327 typedef FMMatrix<detail::SymMatrixWrapper<detail::BaseRowMatrix> > SymMatrix;
00328 typedef FMMatrix<detail::BaseUpperTriMatrix> UTriMatrix;
00329 typedef FMMatrix<detail::BaseLowerTriMatrix> LTriMatrix;
00330 typedef FMMatrix<detail::BaseDiagMatrix> DiagMatrix;
00331
00332
00333 typedef FMVec<detail::BaseDenseVector> DenseVec;
00334 typedef FMMatrix<detail::BaseDenseRowMatrix> DenseRowMatrix;
00335 typedef DenseRowMatrix DenseMatrix;
00336 typedef FMMatrix<detail::BaseDenseColMatrix> DenseColMatrix;
00337 typedef FMMatrix<detail::SymMatrixWrapper<detail::BaseDenseRowMatrix> > DenseSymMatrix;
00338 typedef FMMatrix<detail::BaseDenseUpperTriMatrix> DenseUTriMatrix;
00339 typedef FMMatrix<detail::BaseDenseLowerTriMatrix> DenseLTriMatrix;
00340 typedef FMMatrix<detail::BaseDenseDiagMatrix> DenseDiagMatrix;
00341
00342
00343 #ifdef BAYES_FILTER_GAPPY
00344 typedef FMVec<detail::BaseSparseVector> SparseVec;
00345 typedef FMMatrix<detail::BaseDenseRowMatrix> SparseRowMatrix;
00346 typedef SparseRowMatrix SparseMatrix;
00347 typedef FMMatrix<detail::BaseSparseColMatrix> SparseColMatrix;
00348 typedef FMMatrix<detail::SymMatrixWrapper<detail::BaseSparseRowMatrix> > SparseSymMatrix;
00349 #endif
00350
00351
00352
00353
00354
00355 template <class M>
00356 const ublas::triangular_adaptor<const M, ublas::upper>
00357 UpperTri(const M& m)
00358
00359
00360
00361
00362 {
00363 return ublas::triangular_adaptor<const M, ublas::upper>(m);
00364 }
00365
00366 template <class M>
00367 const ublas::triangular_adaptor<const M, ublas::lower>
00368 LowerTri(const M& m)
00369
00370
00371
00372 {
00373 return ublas::triangular_adaptor<const M, ublas::lower>(m);
00374 }
00375
00376
00377
00378
00379
00380
00381 template <class Base>
00382 ublas::matrix_vector_range<FMMatrix<Base> >
00383 diag(FMMatrix<Base>& M, std::size_t n)
00384 {
00385 return ublas::matrix_vector_range<FMMatrix<Base> >(M, ublas::range(0,n), ublas::range(0,n));
00386 }
00387
00388 template <class Base>
00389 const ublas::matrix_vector_range<const FMMatrix<Base> >
00390 diag(const FMMatrix<Base>& M, std::size_t n)
00391 {
00392 return ublas::matrix_vector_range<const FMMatrix<Base> >(M, ublas::range(0,n), ublas::range(0,n));
00393 }
00394
00395 template <class Base>
00396 ublas::matrix_vector_range<FMMatrix<Base> >
00397 diag(FMMatrix<Base>& M)
00398 {
00399 const std::size_t common_size = std::min(M.size1(),M.size2());
00400 return ublas::matrix_vector_range<FMMatrix<Base> >(M, ublas::range(0,common_size), ublas::range(0,common_size));
00401 }
00402
00403 template <class Base>
00404 const ublas::matrix_vector_range<const FMMatrix<Base> >
00405 diag(const FMMatrix<Base>& M)
00406 {
00407 const std::size_t common_size = std::min(M.size1(),M.size2());
00408 return ublas::matrix_vector_range<const FMMatrix<Base> >(M, ublas::range(0,common_size), ublas::range(0,common_size));
00409 }
00410
00411 template <class Base>
00412 void identity(FMMatrix<Base>& I)
00413 {
00414 I.clear();
00415
00416 std::size_t common_size = std::min(I.size1(),I.size2());
00417 typedef typename Base::value_type Base_value_type;
00418 diag(I).assign (ublas::scalar_vector<Base_value_type>(common_size, Base_value_type(1)));
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 namespace detail {
00431
00432 template <class MatrixX>
00433 void mult_SPD (const MatrixX& X, const Vec& s, SymMatrix& P)
00434
00435
00436
00437 {
00438 Vec::const_iterator si, send = s.end();
00439 typename MatrixX::const_iterator1 Xa = X.begin1();
00440 const typename MatrixX::const_iterator1 Xend = X.end1();
00441 typename MatrixX::const_iterator1 Xb;
00442
00443
00444 for (; Xa != Xend; ++Xa)
00445 {
00446 typename MatrixX::const_Row Xav = MatrixX::rowi(Xa);
00447 Xb = Xa;
00448 for (; Xb != Xend; ++Xb)
00449 {
00450 SymMatrix::value_type p = 0;
00451 typename MatrixX::const_Row Xbv = MatrixX::rowi(Xb);
00452 for (si = s.begin(); si != send; ++si) {
00453 Vec::size_type i = si.index();
00454 p += Xav[i] * (*si) * Xbv[i];
00455 }
00456 P(Xa.index1(),Xb.index1()) += p;
00457 }
00458 }
00459 }
00460
00461 template <class MatrixX>
00462 void mult_SPDT (const MatrixX& X, const Vec& s, SymMatrix& P)
00463
00464
00465
00466 {
00467 Vec::const_iterator si, send = s.end();
00468 typename MatrixX::const_iterator2 Xa = X.begin2();
00469 const typename MatrixX::const_iterator2 Xend = X.end2();
00470 typename MatrixX::const_iterator2 Xb;
00471
00472
00473 for (; Xa != Xend; ++Xa)
00474 {
00475 typename MatrixX::const_Column Xav = MatrixX::columni(Xa);
00476 Xb = Xa;
00477 for (; Xb != Xend; ++Xb)
00478 {
00479 SymMatrix::value_type p = 0;
00480 typename MatrixX::const_Column Xbv = MatrixX::columni(Xb);
00481 for (si = s.begin(); si != send; ++si) {
00482 Vec::size_type i = si.index();
00483 p += Xav[i] * (*si) * Xbv[i];
00484 }
00485 P(Xa.index2(),Xb.index2()) += p;
00486 }
00487 }
00488 }
00489
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 template <class E1, class E2>
00501 struct prod_expression_result
00502 {
00503 typedef BOOST_UBLAS_TYPENAME ublas::matrix_unary2_traits<E2, ublas::scalar_identity<BOOST_UBLAS_TYPENAME E2::value_type> >::result_type E2T_type;
00504 typedef BOOST_UBLAS_TYPENAME ublas::matrix_matrix_binary_traits<BOOST_UBLAS_TYPENAME E1::value_type, E1,
00505 BOOST_UBLAS_TYPENAME E2T_type::value_type, E2T_type>::result_type E1E2T_type;
00506
00507
00508 typedef BOOST_UBLAS_TYPENAME ublas::matrix_unary2_traits<E1, ublas::scalar_identity<BOOST_UBLAS_TYPENAME E1::value_type> >::result_type E1T_type;
00509 typedef BOOST_UBLAS_TYPENAME ublas::matrix_matrix_binary_traits<BOOST_UBLAS_TYPENAME E1T_type::value_type, E1T_type,
00510 BOOST_UBLAS_TYPENAME E2::value_type, E2>::result_type E1TE2_type;
00511 };
00512
00513
00514 template<class E> inline
00515 typename prod_expression_result<E,E>::E1E2T_type
00516 prod_SPD (const ublas::matrix_expression<E>& X)
00517
00518
00519
00520 {
00521
00522
00523 return prod( X, trans(const_cast<ublas::matrix_expression<E>&>(X) ));
00524 }
00525
00526 template<class EX, class ES, class ET> inline
00527 typename prod_expression_result<EX,ET>::E1E2T_type
00528 prod_SPD (const ublas::matrix_expression<EX>& X, const ublas::matrix_expression<ES>& S, ublas::matrix_expression<ET>& XStemp)
00529
00530
00531
00532
00533 {
00534 return prod( X, trans(prod(X,S,XStemp())) );
00535 }
00536
00537 template<class EX, class ES, class ET> inline
00538 ET prod_SPD (const ublas::matrix_expression<EX>& X, const ublas::vector_expression<ES>& s, ublas::matrix_expression<ET>& Ptemp)
00539
00540
00541
00542
00543
00544 {
00545 Vec::const_iterator si, send = s().end();
00546 const EX& XX = X();
00547 typename EX::const_iterator1 Xa = XX.begin1();
00548 const typename EX::const_iterator1 Xend = XX.end1();
00549 typename EX::const_iterator1 Xb;
00550
00551
00552 for (; Xa != Xend; ++Xa)
00553 {
00554 typedef const ublas::matrix_row<const EX> EX_row;
00555 EX_row Xav (ublas::row(XX, Xa.index1()));
00556 Xb = Xa;
00557 for (; Xb != Xend; ++Xb)
00558 {
00559 typename EX::value_type p = 0;
00560 EX_row Xbv (ublas::row(XX, Xb.index1()));
00561 for (si = s().begin(); si != send; ++si) {
00562 Vec::size_type i = si.index();
00563 p += Xav[i] * (*si) * Xbv[i];
00564 }
00565 Ptemp()(Xa.index1(),Xb.index1()) = p;
00566 Ptemp()(Xb.index1(),Xa.index1()) = p;
00567 }
00568 }
00569 return Ptemp();
00570 }
00571
00572 template<class EX, class ES> inline
00573 SymMatrix prod_SPD (const ublas::matrix_expression<EX>& X, const ublas::vector_expression<ES>& s)
00574
00575
00576
00577
00578 {
00579 SymMatrix Ptemp(X().size1(),X().size1());
00580 Ptemp.clear();
00581
00582 (void) prod_SPD (X(),s(), Ptemp);
00583 return Ptemp;
00584 }
00585
00586
00587 template<class E> inline
00588 typename prod_expression_result<E,E>::E1TE2_type
00589 prod_SPDT (const ublas::matrix_expression<E>& X)
00590
00591
00592
00593 {
00594
00595 return prod( trans(const_cast<ublas::matrix_expression<E>&>(X) ), X);
00596 }
00597
00598 template<class EX, class ES, class ET> inline
00599 typename prod_expression_result<ET,EX>::E1TE2_type
00600 prod_SPDT (const ublas::matrix_expression<EX>& X, const ublas::matrix_expression<ES>& S, ublas::matrix_expression<ET>& SXtemp)
00601
00602
00603
00604
00605 {
00606 return prod( trans(prod(S,X,SXtemp())), X);
00607 }
00608
00609 template<class EX, class ES, class ET> inline
00610 ET prod_SPDT (const ublas::matrix_expression<EX>& X, const ublas::vector_expression<ES>& s, ublas::matrix_expression<ET>& Ptemp)
00611
00612
00613
00614
00615
00616 {
00617 const EX& XX = X();
00618 Vec::const_iterator si, send = s().end();
00619 typename EX::const_iterator2 Xa = X.begin2();
00620 const typename EX::const_iterator2 Xend = X.end2();
00621 typename EX::const_iterator2 Xb;
00622
00623
00624 for (; Xa != Xend; ++Xa)
00625 {
00626 typedef const ublas::matrix_column<const EX> EX_column;
00627 EX_column Xav = ublas::column(XX, Xa.index2());
00628 Xb = Xa;
00629 for (; Xb != Xend; ++Xb)
00630 {
00631 typename EX::value_type p = 0;
00632 EX_column Xbv = ublas::column(XX, Xb.index2());
00633 for (si = s().begin(); si != send; ++si) {
00634 Vec::size_type i = si.index();
00635 p += Xav[i] * (*si) * Xbv[i];
00636 }
00637 Ptemp()(Xa.index2(),Xb.index2()) = p;
00638 Ptemp()(Xb.index2(),Xa.index2()) = p;
00639 }
00640 }
00641 return Ptemp();
00642 }
00643
00644 template<class EX, class ES> inline
00645 SymMatrix prod_SPDT (const ublas::matrix_expression<EX>& X, const ublas::vector_expression<ES>& s)
00646
00647
00648
00649
00650 {
00651 SymMatrix Ptemp(X().size1(),X().size1());
00652 Ptemp.clear();
00653
00654 (void) prod_SPDT (X(),s(), Ptemp);
00655 return Ptemp;
00656 }
00657
00658 inline Vec::value_type prod_SPDT (const Vec& x, const Vec& s)
00659
00660
00661
00662 {
00663 const Vec::const_iterator xi_end = x.end();
00664 Vec::const_iterator si = s.begin();
00665 Vec::const_iterator xi=x.begin();
00666 Vec::value_type p = Vec::value_type(0);
00667 while (xi != xi_end)
00668 {
00669 p += (*xi) * (*si) * (*xi);
00670 ++xi; ++ si;
00671 }
00672
00673 return p;
00674 }
00675
00676 inline Vec::value_type prod_SPDT (const Vec& x, const SymMatrix& S)
00677
00678
00679
00680 {
00681 return inner_prod (x, prod(S,x) );
00682 }
00683
00684 }