00001
00002
00003 #ifndef JMATH_UBLAS_EXTRA_HPP
00004 #define JMATH_UBLAS_EXTRA_HPP
00005
00006 #include <cmath>
00007
00008 #include "jafarConfig.h"
00009
00010 #if BOOST_VERSION < 103301 // missing includes in lu.hpp
00011 #include "boost/numeric/ublas/vector.hpp"
00012 #include "boost/numeric/ublas/vector_proxy.hpp"
00013 #include "boost/numeric/ublas/matrix.hpp"
00014 #include "boost/numeric/ublas/matrix_proxy.hpp"
00015 #include "boost/numeric/ublas/triangular.hpp"
00016 #include "boost/numeric/ublas/operation.hpp"
00017 #endif
00018
00019 #if BOOST_VERSION == 103301 // missing includes in lu.hpp
00020 #include "boost/numeric/ublas/triangular.hpp"
00021 #endif
00022
00023 #ifdef HAVE_BOOST_SANDBOX
00024 #ifdef HAVE_LAPACK
00025 #include "boost/numeric/bindings/lapack/driver/gesdd.hpp"
00026 #include "boost/numeric/bindings/ublas/matrix.hpp"
00027 #include "boost/numeric/bindings/ublas/vector.hpp"
00028 #endif
00029 #endif
00030
00031 #include "boost/numeric/ublas/lu.hpp"
00032 #include "boost/numeric/ublas/io.hpp"
00033
00034 #include "kernel/jafarException.hpp"
00035 #include "kernel/jafarDebug.hpp"
00036
00037 #include "jmath/jblas.hpp"
00038 #include "jmath/jmathException.hpp"
00039
00040 namespace jafar {
00041 namespace jmath {
00042
00044
00045
00049 namespace ublasExtra {
00050
00051 namespace details {
00052
00053 const double EPSILON = 1e-8;
00054 }
00055
00056
00057
00058
00059
00060
00061 template<class V>
00062 void setVectorValue(V& v, const double* val_, std::size_t size_) {
00063 JFR_PRECOND(v.size()==size_,
00064 "ublasExtra::setValue: size of v does not match");
00065 for (std::size_t i = 0; i < v.size(); i++) {
00066 v(i) = val_[i];
00067 }
00068 }
00069
00072 template<class V>
00073 void fillVector(V& v, const double& value = 0.0) {
00074 for (std::size_t i = 0; i < v.size(); ++i)
00075 v(i) = value;
00076 }
00077
00080 template<class V, typename W>
00081 void fillVector(V& out, const W* in) {
00082 for (std::size_t i = 0; i < out.size(); ++i)
00083 out(i) = in[i];
00084 }
00085
00088 template<int size, typename W>
00089 jblas::vec createVector(const W in[size]) {
00090 jblas::vec out(size);
00091 for (std::size_t i = 0; i < size; ++i)
00092 out(i) = in[i];
00093 return out;
00094 }
00095
00102 template <class T>
00103 jblas::vec createVector(T const & v, size_t pos, size_t size)
00104 {
00105 jblas::vec res(size);
00106
00107 for(size_t i = 0; i < size; ++i)
00108 res(i) = v[pos+i];
00109
00110 return res;
00111 }
00112
00115 template<int size, typename W>
00116 jblas::sym_mat createSymMat(const W std[size]) {
00117 jblas::sym_mat out(size);
00118 out.clear();
00119 for (std::size_t i = 0; i < size; ++i)
00120 out(i,i) = std[i] * std[i];
00121 return out;
00122 }
00123
00132 template <class T>
00133 jblas::sym_mat createSymMat(T const & v, size_t shift, size_t csize, size_t pos, size_t size)
00134 {
00135 jblas::sym_mat m(size);
00136
00137 for(size_t i = 0; i < size; ++i)
00138 {
00139 size_t k = shift + (csize)*(csize+1)/2 - (csize-(i+pos))*(csize-(i+pos)+1)/2;
00140 for(size_t j = i; j < size; ++j) m(i,j) = v[k+(j-i)];
00141 }
00142
00143 return m;
00144 }
00145
00155 template <class T>
00156 void explodeSymMat(jblas::sym_mat const & m, T & v, size_t shift, size_t csize, size_t pos, size_t size)
00157 {
00158 for(size_t i = 0; i < size; ++i)
00159 {
00160 size_t k = shift + (csize)*(csize+1)/2 - (csize-(i+pos))*(csize-(i+pos)+1)/2;
00161 for(size_t j = i; j < size; ++j) v[k+(j-i)] = m(i,j);
00162 }
00163 }
00164
00165
00166 #define DECL_VEC(name,size,values) jblas::vec name(size); { const double tmp[size] = {values}; fillVector(name, tmp); }
00167 #define INIT_VEC(size,values) fillVector2<size>((double[]){ values })
00168
00169
00170 template<class V>
00171 bool isZeroVector(const V& v) {
00172 bool isZero = true;
00173 for (std::size_t i = 0; i < v.size(); ++i) {
00174 if (v(i) != 0.0) {
00175 isZero = false;
00176 break;
00177 }
00178 }
00179 return isZero;
00180 }
00181
00191 template<typename T>
00192 ublas::diagonal_matrix<T> scalar_diag_mat(const size_t size, const T val) {
00193 jblas::diag_mat D(size, size);
00194 D.clear();
00195 for (size_t i = 0; i < size; i++)
00196 D(i, i) = val;
00197 return D;
00198 }
00199
00208 template<class V>
00209 jblas::diag_mat vec_diag_mat(const V & v) {
00210 jblas::diag_mat D(v.size(), v.size());
00211 D.clear();
00212 for (size_t i = 0; i < v.size(); i++)
00213 D(i, i) = v(i);
00214 return D;
00215 }
00216
00217
00218
00221 template<class V>
00222 void normalize(V& v) {
00223 double n = ublas::norm_2(v);
00224 JFR_NUMERIC(n > details::EPSILON,
00225 "ublasExtra::normalize: vector too small");
00226 v /= n;
00227 }
00228
00231 template<class V>
00232 jblas::vec normalized(V const & v) {
00233 double n = ublas::norm_2(v);
00234 JFR_NUMERIC(n > details::EPSILON,
00235 "ublasExtra::normalize: vector too small");
00236 return v / n;
00237 }
00238
00242 template<class M1, class M2>
00243 void lu_inv(M1 const& m, M2& inv) {
00244 JFR_PRECOND(m.size1() == m.size2(),
00245 "ublasExtra::lu_inv(): input matrix must be squared");
00246 JFR_PRECOND(inv.size1() == m.size1() && inv.size2() == m.size2(),
00247 "ublasExtra::lu_inv(): invalid size for inverse matrix");
00248
00249 using namespace boost::numeric::ublas;
00250
00251 jblas::mat mLu(m);
00252
00253
00254 JFR_TRACE_BEGIN;
00255 lu_factorize(mLu);
00256 JFR_TRACE_END("ublasExtra::lu_inv");
00257
00258
00259 jblas::mat mLuInv(jblas::identity_mat(m.size1()));
00260
00261
00262 JFR_TRACE_BEGIN;
00263 lu_substitute<jblas::mat const, jblas::mat> (mLu, mLuInv);
00264 JFR_TRACE_END("ublasExtra::lu_inv");
00265 inv.assign(mLuInv);
00266 }
00273 template<class SymMat>
00274 jblas::sym_mat prod_JPJt(const SymMat & P, const jblas::mat & J) {
00275 JFR_PRECOND((J.size2()==P.size1()) && (P.size2()==P.size1()),
00276 "ublasExtra::prod_JPJt: size mismatch.");
00277 return ublas::prod<jblas::sym_mat>(J, ublas::prod<jblas::mat>(P, ublas::trans(J)));
00278 }
00279
00286 template<class SymMat, class V>
00287 double prod_xt_P_x(const SymMat & P, const V & x) {
00288 JFR_PRECOND(x.size() == P.size1(),
00289 "ublasExtra::prod_xt_P_x: size mismatch.");
00290 jblas::sym_mat iP(P.size1());
00291 lu_inv(P, iP);
00292 return ublas::inner_prod(x, ublas::prod<jblas::vec>(iP, x));
00293 }
00294
00301 template<class SymMat, class V>
00302 double prod_xt_iP_x(SymMat & iP, V & x) {
00303 JFR_PRECOND(x.size()==iP.size1(),
00304 "ublasExtra::prod_xt_iP_x: size mismatch.");
00305 return ublas::inner_prod(x, ublas::prod(iP, x));
00306 }
00307
00311 template<class V, class M>
00312 void normalizeJac(V& v, M& J) {
00313 JFR_NUMERIC(ublas::norm_2(v) > details::EPSILON,
00314 "ublasExtra::normalizeJac: vector too small");
00315 JFR_PRECOND(J.size1() == v.size() && J.size2() == v.size(),
00316 "ublasExtra::normalizeJac: size of J is invalid");
00317 switch (v.size()) {
00318 case 2: {
00319 double x = v(0);
00320 double y = v(1);
00321
00322 double t1 = x * x;
00323 double t2 = y * y;
00324 double t3 = t1 + t2;
00325 double t4 = sqrt(t3);
00326 double t6 = 0.1e1 / t4 / t3;
00327 double t8 = 0.1e1 / t4;
00328 double t11 = t6 * x * y;
00329 J(0, 0) = -t6 * t1 + t8;
00330 J(0, 1) = -t11;
00331 J(1, 0) = -t11;
00332 J(1, 1) = -t6 * t2 + t8;
00333
00334 }
00335 return;
00336 case 3: {
00337 double x = v(0);
00338 double y = v(1);
00339 double z = v(2);
00340
00341 double t1 = x * x;
00342 double t2 = y * y;
00343 double t3 = z * z;
00344 double t4 = t1 + t2 + t3;
00345 double t5 = sqrt(t4);
00346 double t7 = 0.1e1 / t5 / t4;
00347 double t9 = 0.1e1 / t5;
00348 double t11 = t7 * x;
00349 double t12 = t11 * y;
00350 double t13 = t11 * z;
00351 double t17 = t7 * y * z;
00352 J(0, 0) = -t7 * t1 + t9;
00353 J(0, 1) = -t12;
00354 J(0, 2) = -t13;
00355 J(1, 0) = -t12;
00356 J(1, 1) = -t7 * t2 + t9;
00357 J(1, 2) = -t17;
00358 J(2, 0) = -t13;
00359 J(2, 1) = -t17;
00360 J(2, 2) = -t7 * t3 + t9;
00361
00362
00363 }
00364 return;
00365 default: {
00366
00367
00368 double n2 = ublas::inner_prod(v, v);
00369 double n = sqrt(n2);
00370 double n3 = n * n2;
00371 jblas::identity_mat I(v.size());
00372 jblas::mat vvt(v.size(), v.size());
00373 vvt = ublas::outer_prod(v, v);
00374 J = (n2 * I - vvt) / n3;
00375
00376 return;
00377
00378 }
00379 };
00380 }
00381
00385 template<std::size_t N, class Vec1, class Vec2, class Mat>
00386 void inner_prodJac(Vec1 const& u1, Vec2 const& u2, Mat& J) {
00387 JFR_PRECOND(u1.size() == N && u2.size() == N,
00388 "ublasExtra::inner_prodJac:" << N << "-vectors");
00389 JFR_PRECOND(J.size1() == 1 && J.size2() == 2*N,
00390 "ublasExtra::inner_prodJac:");
00391 for (std::size_t i = 0; i < N; ++i) {
00392 J(0, i) = u2(i);
00393 J(0, N + i) = u1(i);
00394 }
00395 }
00396
00399 template<class Vec, class Mat>
00400 double norm_2(Vec const& u, Mat& J)
00401 {
00402 JFR_PRECOND(J.size1() == 1 && J.size2() == u.size(), "ublasExtra::norm_2Jac:");
00403 const size_t N = u.size();
00404 double d = ublas::norm_2(u);
00405 if (d == 0)
00406 for (std::size_t i = 0; i < N; ++i) J(0, i) = 0.1;
00407 else
00408 for (std::size_t i = 0; i < N; ++i) J(0, i) = u(i) / d;
00409 return d;
00410 }
00411
00412 template<std::size_t N, class Vec, class Mat>
00413 void norm_2Jac(Vec const& u, Mat& J) {
00414 JFR_PRECOND(u.size() == N,
00415 "ublasExtra::norm_2Jac: " << N << "-vectors");
00416 JFR_PRECOND(J.size1() == 1 && J.size2() == N,
00417 "ublasExtra::norm_2Jac:");
00418 norm_2(u, J);
00419 }
00420
00424 template<class Vec1, class Vec2, class VecRes>
00425 void crossProd(Vec1 const& v1, Vec2 const& v2, VecRes& vRes) {
00426 JFR_PRECOND(v1.size()==3 && v2.size()==3 && vRes.size()==3,
00427 "ublasExtra::crossProd: 3D vector");
00428
00429 vRes(0) = v1(1) * v2(2) - v1(2) * v2(1);
00430 vRes(1) = v1(2) * v2(0) - v1(0) * v2(2);
00431 vRes(2) = v1(0) * v2(1) - v1(1) * v2(0);
00432 }
00433
00437 template<class Vec1, class Vec2>
00438 jblas::vec3 crossProd(Vec1 const& v1, Vec2 const& v2) {
00439 jblas::vec3 vRes;
00440 crossProd(v1, v2, vRes);
00441 return vRes;
00442 }
00443
00444
00445
00446
00447
00451 template<class Mat>
00452 std::string prettyFormat(Mat const& m_) {
00453 std::stringstream s;
00454 for (std::size_t i = 0; i < m_.size1(); ++i) {
00455 for (std::size_t j = 0; j < m_.size2(); ++j) {
00456 s << m_(i, j) << "\t";
00457 }
00458 s << std::endl;
00459 }
00460 return s.str();
00461 }
00462
00466 template<class Mat>
00467 std::string matlabFormat(Mat const& m_) {
00468 std::stringstream s;
00469 s << "[";
00470 for (std::size_t i = 0; i < m_.size1(); ++i) {
00471 for (std::size_t j = 0; j < m_.size2(); ++j) {
00472 if (j != (m_.size2() - 1))
00473 s << m_(i, j) << ",";
00474 else
00475 s << m_(i, j);
00476 }
00477 if (i != (m_.size1() - 1))
00478 s << ";";
00479 else
00480 s << "]";
00481 };
00482
00483 return s.str();
00484 }
00485
00486 template<class M>
00487 void setMatrixValue(M& m, const double* val_, std::size_t size1_, std::size_t size2_) {
00488 JFR_PRECOND(m.size1()==size1_ && m.size2()==size2_,
00489 "ublasExtra::setValue: size of m does not match");
00490 unsigned int k = 0;
00491 for (std::size_t i = 0; i < m.size1(); i++) {
00492 for (std::size_t j = 0; j < m.size2(); j++) {
00493 m(i, j) = val_[k];
00494 k++;
00495 }
00496 }
00497 }
00498
00499 namespace details {
00500
00501 template<class M>
00502 double det2(const M& m_) {
00503 return m_(0, 0) * m_(1, 1) - m_(1, 0) * m_(0, 1);
00504 }
00505
00506 template<class M>
00507 double det3(const M& m_) {
00508 return m_(0, 0) * m_(1, 1) * m_(2, 2) + m_(0, 1) * m_(1, 2) * m_(2, 0) + m_(0, 2) * m_(1, 0) * m_(2, 1) - m_(
00509 2, 0) * m_(1, 1) * m_(0, 2) - m_(2, 1) * m_(1, 2) * m_(0, 0) - m_(2, 2) * m_(1, 0) * m_(0, 1);
00510 }
00511
00512 template<class M>
00513 void inv2(const M& m_, M& m_inv) {
00514 m_inv(0, 0) = m_(1, 1);
00515 m_inv(0, 1) = -1.0 * m_(0, 1);
00516 m_inv(1, 0) = -1.0 * m_(1, 0);
00517 m_inv(1, 1) = m_(0, 0);
00518 m_inv /= det2(m_);
00519 }
00520
00521 template<class M>
00522 void inv3(const M& m_, M& m_inv) {
00523 m_inv(0, 0) = m_(1, 1) * m_(2, 2) - m_(1, 2) * m_(2, 1);
00524 m_inv(0, 1) = m_(2, 1) * m_(0, 2) - m_(2, 2) * m_(0, 1);
00525 m_inv(0, 2) = m_(0, 1) * m_(1, 2) - m_(0, 2) * m_(1, 1);
00526 m_inv(1, 0) = m_(2, 0) * m_(1, 2) - m_(1, 0) * m_(2, 2);
00527 m_inv(1, 1) = m_(0, 0) * m_(2, 2) - m_(2, 0) * m_(0, 2);
00528 m_inv(1, 2) = m_(1, 0) * m_(0, 2) - m_(0, 0) * m_(1, 2);
00529 m_inv(2, 0) = m_(1, 0) * m_(2, 1) - m_(2, 0) * m_(1, 1);
00530 m_inv(2, 1) = m_(2, 0) * m_(0, 1) - m_(0, 0) * m_(2, 1);
00531 m_inv(2, 2) = m_(0, 0) * m_(1, 1) - m_(1, 0) * m_(0, 1);
00532
00533 m_inv /= det3(m_);
00534 }
00535
00536 }
00537
00538 #ifdef THALES_TAROT
00539 #undef max
00540 #endif
00541
00545 template<class M>
00546 double max(const M& m_) {
00547 double max = m_(0, 0);
00548 for (std::size_t i = 0; i < m_.size1(); i++) {
00549 for (std::size_t j = 0; j < m_.size2(); j++) {
00550 if (m_(i, j) > max) {
00551 max = m_(i, j);
00552 }
00553 }
00554 }
00555 return max;
00556 }
00557
00561 template<class V>
00562 double maxV(const V& v_) {
00563 double max = v_(0);
00564 for (std::size_t i = 1; i < v_.size(); i++) {
00565 if (v_(i) > max) {
00566 max = v_(i);
00567 }
00568 }
00569 return max;
00570 }
00574 template<class M>
00575 double trace(const M& m_) {
00576 JFR_PRECOND(m_.size1() == m_.size2(),
00577 "ublasExtra::trace: m_ must be square");
00578 double t = 0;
00579 for (std::size_t i = 0; i < m_.size1(); i++) {
00580 t += m_(i, i);
00581 }
00582 return t;
00583 }
00584
00588 template<class M>
00589 double lu_det(M const& m) {
00590 JFR_PRECOND(m.size1() == m.size2(),
00591 "ublasExtra::lu_det: matrix must be square");
00592
00593
00594 jblas::mat mLu(m);
00595 ublas::permutation_matrix<std::size_t> pivots(m.size1());
00596
00597 JFR_TRACE_BEGIN;
00598 lu_factorize(mLu, pivots);
00599 JFR_TRACE_END("ublasExtra::lu_det");
00600
00601 double det = 1.0;
00602
00603 for (std::size_t i = 0; i < pivots.size(); ++i) {
00604 if (pivots(i) != i)
00605 det *= -1.0;
00606 det *= mLu(i, i);
00607 }
00608 return det;
00609 }
00610
00611 template<class M>
00612 double det(const M& m_) {
00613 JFR_PRECOND(m_.size1() == m_.size2(),
00614 "ublasExtra::det: m_ must be a square matrix");
00615 switch (m_.size1()) {
00616 case 1:
00617 return m_(0, 0);
00618 case 2:
00619 return details::det2(m_);
00620 case 3:
00621 return details::det3(m_);
00622 default:
00623 return lu_det(m_);
00624 }
00625 }
00626
00627 template<class M>
00628 void inv(const M& m_, M& m_inv) {
00629 JFR_PRECOND(m_.size1() == m_.size2(),
00630 "ublasExtra::inv: m_ must be a square matrix");
00631 switch (m_.size1()) {
00632 case 1:
00633 m_inv(0, 0) = 1 / m_(0, 0);
00634 break;
00635 case 2:
00636 details::inv2(m_, m_inv);
00637 break;
00638 case 3:
00639 details::inv3(m_, m_inv);
00640 break;
00641 default:
00642 lu_inv(m_, m_inv);
00643 }
00644 }
00645
00646
00647 #ifdef HAVE_BOOST_SANDBOX
00648 #ifdef HAVE_LAPACK
00649
00654 template<class M1, class M2>
00655 void svd_inv(M1 const& m, M2& inv) {
00656 JFR_PRECOND(m.size1() >= m.size2(),"ublasExtra::svd_inv: wrong matrix size");
00657 JFR_PRECOND(inv.size1() == m.size1() && inv.size2() == m.size2(),
00658 "ublasExtra::svd_inv(): invalid size for inverse matrix");
00659 jblas::mat_column_major working_m(m);
00660 jblas::vec s(m.size2());
00661 jblas::mat_column_major U(m.size1(), m.size2());
00662 jblas::mat_column_major VT(m.size1(), m.size2());
00663 int ierr = boost::numeric::bindings::lapack::gesdd('A',working_m, s, U, VT);
00664 if (ierr != 0) {
00665 throw(jmath::LapackException(ierr, "LinearLeastSquares::solve: error in lapack::gesdd() routine", __FILE__,
00666 __LINE__));
00667 }
00668 jblas::mat S(jblas::zero_mat(s.size(), s.size()));
00669 for (unsigned int i = 0; i < s.size(); i++) {
00670 JFR_ASSERT(s(i)!=0, "ublasExtra::svd_inv: singular matrix");
00671 S(i, i) = 1 / s(i);
00672 }
00673 inv = ublas::prod(S, ublas::trans(U));
00674 inv = ublas::prod(ublas::trans(VT), inv);
00675 }
00676
00677 #endif
00678 #endif
00679
00680
00684 inline jblas::vec2 eigenValues(const jblas::mat22& m) {
00685 double tr = m(0, 0) + m(1, 1);
00686 double diff = m(0, 0) - m(1, 1);
00687 double sq = sqrt(4 * m(0, 1) * m(1, 0) + diff * diff);
00688 jblas::vec2 v;
00689 v(0) = 0.5 * (tr + sq);
00690 v(1) = 0.5 * (tr - sq);
00691 return v;
00692 }
00693
00698 template<typename T>
00699 void minus_vector(const ublas::matrix<T> &M, const ublas::vector<T> &v,
00700 ublas::matrix<T> &M_v)
00701 {
00702 size_t n_cols;
00703 size_t n_rows;
00704 JFR_ASSERT(((n_rows = M.size1()) == M_v.size1()) &&
00705 ((n_cols = M.size2()) == M_v.size2()),
00706 "M and M_v must be same size");
00707 JFR_ASSERT(n_cols == v.size(),
00708 "vector size and matrix coulmns size must be equal");
00709 for(size_t r = 0; r < n_rows; r++)
00710 for(size_t c = 0; c < n_cols; c++)
00711 M_v(r, c) = M(r,c) - v[c];
00712 }
00713
00717 template<typename T>
00718 void minus_vector(ublas::matrix<T> &M, const ublas::vector<T> &v)
00719 {
00720 size_t n_cols;
00721 JFR_ASSERT((n_cols = M.size2()) == v.size(),
00722 "vector size and matrix coulmns size must be equal");
00723 size_t n_rows = M.size1();
00724 for(size_t r = 0; r < n_rows; r++)
00725 for(size_t c = 0; c < n_cols; c++)
00726 M(r, c)-= v[c];
00727 }
00728
00732 template<typename T>
00733 void plus_vector(ublas::matrix<T> &M, const ublas::vector<T> &v)
00734 {
00735 JFR_ASSERT(M.size2() == v.size(),
00736 "vector size and matrix coulmns size must be equal");
00737 for(size_t r = 0; r < M.size1(); r++)
00738 for(size_t c = 0; c < M.size2(); c++)
00739 M(r, c)+= v[c];
00740 }
00741
00746 template<typename T>
00747 void delete_row(ublas::matrix<T> &M, size_t index)
00748 {
00749 JFR_ASSERT((index < M.size1() && (index>=0)),
00750 "index must be in [0.."<<M.size1()<<"[ range");
00751 if (index == M.size1() -1)
00752 M.resize(index, M.size2(), true);
00753 else {
00754 for(size_t row_counter = index+1; row_counter < M.size1();row_counter++)
00755 row(M,row_counter-1) = row(M,row_counter);
00756 M.resize(M.size1() - 1, M.size2(), true);
00757 }
00758 }
00759
00764 template<typename T>
00765 void delete_column(ublas::matrix<T> &M, size_t index)
00766 {
00767 JFR_ASSERT((index < M.size2() && (index>=0)),
00768 "index must be in [0.."<<M.size2()<<"[ range");
00769 if (index == M.size2() - 1)
00770 M.resize(M.size1(), index, true);
00771 else {
00772 for(size_t col_counter = index+1; col_counter < M.size1();col_counter++)
00773 column(M,col_counter-1) = column(M,col_counter);
00774 M.resize(M.size1() , M.size2() - 1, true);
00775 }
00776 }
00782 template<typename T>
00783 void delete_columns(ublas::matrix<T> &M,
00784 std::vector<size_t> indices,
00785 bool is_sorted = false)
00786 {
00787 JFR_ASSERT(((indices.size() <= M.size2()) && (indices.size() > 0)),
00788 "indices size is "<<indices.size()<<
00789 " whereas M columns size is "<<M.size2());
00790 if(!is_sorted)
00791 std::sort(indices.begin(), indices.end());
00792 for(std::vector<size_t>::reverse_iterator rit = indices.rbegin();
00793 rit != indices.rend();
00794 ++rit)
00795 delete_column(M, *rit);
00796 }
00802 template<typename T>
00803 void delete_rows(ublas::matrix<T> &M,
00804 std::vector<size_t> indices,
00805 bool is_sorted = false)
00806 {
00807 JFR_ASSERT(((indices.size() <= M.size2()) && (indices.size() > 0)),
00808 "indices size is "<<indices.size()<<
00809 " whereas M rows size is "<<M.size2());
00810 if(!is_sorted)
00811 std::sort(indices.begin(), indices.end());
00812 for(std::vector<size_t>::reverse_iterator rit = indices.rbegin();
00813 rit != indices.rend();
00814 ++rit)
00815 delete_row(M, *rit);
00816 }
00817 }
00818
00819
00820 }
00821 }
00822
00823 #endif // JMATH_UBLAS_EXTRA_HPP