00001 #ifndef JMATH_MATOFMAT_HPP
00002 #define JMATH_MATOFMAT_HPP
00003
00004 #include <cstdlib>
00005 #include <fstream>
00006 #include <vector>
00007
00008 #include "kernel/jafarMacro.hpp"
00009
00010 #include "jmath/jblas.hpp"
00011
00012 namespace jafar {
00013
00014 namespace jmath {
00015
00016 template<typename T, std::size_t M, std::size_t N> class matofmat {
00017
00022 unsigned int *indextab;
00023
00026 unsigned int nbnze;
00027
00030 bool isSparse_;
00031
00034 unsigned int nbc;
00035
00036
00037
00038 unsigned int nbr;
00039
00042 std::vector < typename ublas::bounded_matrix<T,M,N> > data;
00043
00044 public:
00045
00046 typedef boost::numeric::ublas::bounded_matrix<T,M,N>& reference;
00047 typedef const boost::numeric::ublas::bounded_matrix<T,M,N>& const_reference;
00048
00049
00050
00051
00052
00053
00054
00058 matofmat(int nbr_, int nbc_) :
00059 data(nbr_*nbc_) {
00060
00061 unsigned int cpt;
00062
00063
00064 isSparse_ = false;
00065 nbr = nbr_;
00066 nbc = nbc_;
00067 nbnze = nbr_*nbc_;
00068
00069
00070 indextab = new unsigned int[nbnze];
00071
00072
00073 for (cpt=0; cpt<nbnze; cpt++)
00074 indextab[cpt] = cpt;
00075
00076 }
00077
00082 matofmat(jblas::bool_mat const& matvis_) :
00083 data() {
00084
00085 unsigned int cpt1, cpt2, pos, indTrue=0;
00086 ublas::bounded_matrix<T,M,N> nullmatrix;
00087
00088
00089 isSparse_ = true;
00090 nbr = matvis_.size1();
00091 nbc = matvis_.size2();
00092
00093
00094 indextab = new unsigned int[nbr*nbc];
00095
00096
00097 nbnze = 0;
00098 for (cpt1=0; cpt1<nbr; cpt1++)
00099 for (cpt2=0; cpt2<nbc; cpt2++)
00100 if (matvis_(cpt1, cpt2)) {
00101 ++nbnze;
00102 }
00103
00104 if (nbnze==nbr*nbc) {
00105 isSparse_ = false;
00106 data.resize(nbnze);
00107
00108 for (pos=0; pos<nbnze; pos++)
00109 indextab[pos] = pos;
00110 } else {
00111
00112 data.resize(nbnze+1);
00113
00114
00115 for (cpt1 = 0, indTrue=0, pos = 0; cpt1<nbr; cpt1++)
00116 for (cpt2 = 0; cpt2<nbc; cpt2++, pos++)
00117 if (matvis_(cpt1, cpt2))
00118 indextab[pos] = indTrue++;
00119 else
00120 indextab[pos] = nbnze;
00121
00122
00123 for (cpt1=0; cpt1<nullmatrix.size1(); cpt1++)
00124 for (cpt2=0; cpt2<nullmatrix.size2(); cpt2++)
00125 nullmatrix(cpt1, cpt2) = 0.0;
00126
00127 data[nbnze].assign(nullmatrix);
00128 }
00129 }
00130
00133 matofmat(const matofmat& mom) :
00134 data(mom.capacity()) {
00135
00136 unsigned int cpt1, cpt2, pos;
00137 ublas::bounded_matrix<T,M,N> nullmatrix;
00138
00139
00140 isSparse_ = mom.isSparse();
00141 nbr = mom.size1();
00142 nbc = mom.size2();
00143 nbnze = mom.capacity();
00144
00145
00146 indextab = new unsigned int[nbr*nbc];
00147 mom.getIndexTab(indextab);
00148
00149 if (isSparse_) {
00150
00151 data.resize(nbnze+1);
00152
00153
00154 for (cpt1=0; cpt1<nullmatrix.size1(); cpt1++)
00155 for (cpt2=0; cpt2<nullmatrix.size2(); cpt2++)
00156 nullmatrix(cpt1, cpt2) = 0.0;
00157 data[0] = nullmatrix;
00158
00159
00160 for (cpt1=0, pos=0; cpt1<nbr; cpt1++)
00161 for (cpt2=0; cpt2<nbc; pos++, cpt2++) {
00162 if (indextab[pos] != 0)
00163 data[indextab[pos]] = mom(cpt1, cpt2);
00164 }
00165 } else {
00166
00167 for (cpt1=0, pos=0; cpt1<nbr; cpt1++)
00168 for (cpt2=0; cpt2<nbc; pos++, cpt2++)
00169 data[indextab[pos]] = mom(cpt1, cpt2);
00170 }
00171 }
00172
00175 ~matofmat() {
00176
00177 data.clear();
00178
00179 delete[] indextab;
00180
00181 }
00182
00183
00184
00185
00186
00187
00188 void exportFullMatrix(jblas::mat &MatM) {
00189 JFR_PRECOND(MatM.size1()==(M*nbr),
00190 " M has an invalid size to store the exported matrix");
00191 JFR_PRECOND(MatM.size2()==(N*nbc),
00192 " M has an invalid size to store the exported matrix");
00193
00194 unsigned int cptc, cptr, pos;
00195 unsigned int ii, jj, decalR, decalC;
00196 ublas::bounded_matrix<T,M,N> toto;
00197
00198 for (cptr=0, pos=0; cptr<nbr; cptr++) {
00199 for (cptc=0; cptc<nbc; cptc++, pos++) {
00200 toto = data[indextab[pos]];
00201
00202 decalR = cptr*M;
00203 decalC = cptc*N;
00204
00205 for (ii=0; ii<M; ii++)
00206 for (jj=0; jj< N; jj++)
00207 MatM(decalR+ii, decalC+jj) = toto(ii, jj);
00208 }
00209
00210 }
00211
00212 }
00213
00214
00215
00216
00217
00218
00221 bool isSparse() const {
00222 return (isSparse_);
00223 }
00224
00227 unsigned int size1() const {
00228 return (nbr);
00229 }
00230
00233 unsigned int size2() const {
00234 return (nbc);
00235 }
00236
00239 unsigned int capacity() const {
00240 return (nbnze);
00241 }
00242
00243 void getIndexTab(unsigned int *tab) const {
00244 unsigned int cpt;
00245
00246 for (cpt=0; cpt<nbr*nbc; cpt++)
00247 tab[cpt] = (this->indextab)[cpt];
00248 }
00249
00253 void getIndexTab2(unsigned int **tab) const {
00254
00255 unsigned int cpt;
00256
00257 *tab = new unsigned int(nbr*nbc);
00258 for (cpt=0; cpt<nbr*nbc; cpt++)
00259 (*tab)[cpt] = indextab[cpt];
00260 }
00261
00262 void assign(jblas::mat const Mat, unsigned int i, unsigned int j) {
00263
00264
00265 JFR_PRECOND((i>=0)&&(i<nbr),
00266 "jmath::matofmat : you try to put an element outside of the matrix");
00267 JFR_PRECOND((j>=0)&&(j<nbc),
00268 "jmath::matofmat : you try to put an element outside of the matrix");
00269 JFR_PRECOND(indextab[i*nbc+j]>0,
00270 "jmath::matofmat : you try to put an element on an zero element");
00271
00272 data[indextab[i*nbc+j]].assign(Mat);
00273
00274 }
00275 ;
00276
00277 void add(jblas::mat const Mat, unsigned int i, unsigned int j) {
00278 JFR_PRECOND((i>=0)&&(i<nbr),
00279 "jmath::matofmat : you try to put an element outside of the matrix");
00280 JFR_PRECOND((j>=0)&&(j<nbc),
00281 "jmath::matofmat : you try to put an element outside of the matrix");
00282 JFR_PRECOND(indextab[i*nbc+j]>0,
00283 "jmath::matofmat : you try to put an element on an zero element");
00284
00285 data[indextab[i*nbc*j]].assign(data[indextab[i*nbc*j]]+Mat);
00286 }
00287
00288
00289
00290
00291
00292
00295 reference operator ()(unsigned int i, unsigned int j) {
00296 JFR_PRECOND((i>=0)&&(i<nbr),
00297 "jmath::matofmat : you try to put an element outside of the matrix");
00298 JFR_PRECOND((j>=0)&&(j<nbc),
00299 "jmath::matofmat : you try to put an element outside of the matrix");
00300 JFR_PRECOND(indextab[i*nbc+j]>=0,
00301 "jmath::matofmat : you try to put an element on an zero element");
00302
00303 return data [indextab[i*nbc+j]];
00304 }
00305
00308 const_reference operator ()(unsigned int i, unsigned int j) const {
00309 return data [indextab[i*nbc+j]];
00310 }
00311
00312
00313
00314
00315
00316 void clear() {
00317 data.clear();
00318 delete[] indextab;
00319 nbr = 0;
00320 nbc = 0;
00321 nbnze = 0;
00322 isSparse_ = false;
00323 }
00324
00325 };
00326 }
00327 }
00328 #endif