Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ublasExtra.hpp
00001 /* $Id$ */
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         // a small value
00053         const double EPSILON = 1e-8;
00054       }
00055 
00056 
00057 
00058       /*
00059        * Vector
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         // create a working copy of the input
00251         jblas::mat mLu(m);
00252 
00253         // perform LU-factorization
00254         JFR_TRACE_BEGIN;
00255         lu_factorize(mLu);
00256         JFR_TRACE_END("ublasExtra::lu_inv");
00257 
00258         // create identity matrix of "inverse"
00259         jblas::mat mLuInv(jblas::identity_mat(m.size1()));
00260 
00261         // backsubstitute to get the inverse
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             /* begin maple copy/paste */
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             /* end maple copy/paste */
00334           }
00335             return;
00336           case 3: {
00337             double x = v(0);
00338             double y = v(1);
00339             double z = v(2);
00340             /* begin maple copy/paste */
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             /* end maple copy/paste */
00362 
00363           }
00364             return;
00365           default: {
00366             // We use the general formula:
00367             // VN_v = d(vn)/d(v) = (I*norm(v)^2 - v*v') / norm(v)^3
00368             double n2 = ublas::inner_prod(v, v); // norm square
00369             double n = sqrt(n2); // norm
00370             double n3 = n * n2; // norm cube
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             //            J = (n2 * ublas::identity_matrix(v.size()) - ublas::outer_prod(v, v)) / n3;
00376             return;
00377             //    JFR_RUN_TIME("ublasExtra::normalizeJac: not implemented yet");
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) // to avoid nan ; return a non zero value to avoid being stuck at 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        * Matrix
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       } // namespace details
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         // create a working copy of the input
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     } // namespace ublasExtra
00818   /*\@}*/
00819 
00820   } // namespace jmath
00821 } // namespace jafar
00822 
00823 #endif // JMATH_UBLAS_EXTRA_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:24 for Jafar by doxygen 1.7.6.1
LAAS-CNRS