IT++ Logo Newcom Logo

gf2mat.cpp

Go to the documentation of this file.
00001 
00033 #include <itpp/base/gf2mat.h>
00034 #include <itpp/base/specmat.h>
00035 #include <itpp/base/matfunc.h>
00036 #include <iostream>
00037 
00038 namespace itpp {
00039 
00040   GF2mat::GF2mat(int i, int j) 
00041   {
00042     int k = j/(1<<lImax)+1;
00043     nrows=i;
00044     ncols=j;
00045     nwords=k;
00046     data.set_size(nrows,nwords);
00047     for (int i=0; i<nrows; i++) {
00048       for (int j=0; j<nwords; j++) {
00049         data(i,j) = 0;
00050       }
00051     }
00052   }
00053 
00054   GF2mat::GF2mat()   
00055   {
00056     nrows=1;
00057     ncols=1;
00058     nwords=1;
00059     data.set_size(1,1);
00060     data(0,0) = 0;
00061   }
00062 
00063   GF2mat::GF2mat(const bvec &x, bool row_or_column)
00064   {
00065     if (row_or_column==1) {     // create column vector
00066       nrows=length(x);
00067       ncols=1;
00068       nwords=1;
00069       data.set_size(nrows,1);
00070       for (int i=0; i<nrows; i++) {
00071         data(i,0) = 0;
00072         set(i,0,x(i));
00073       }
00074     } else {    // create row vector
00075       nrows=1;
00076       ncols=length(x);
00077       nwords=ncols/(1<<lImax)+1;
00078       data.set_size(1,nwords);
00079       for (int i=0; i<nwords; i++) {
00080         data(0,i) = 0;
00081       }
00082       for (int i=0; i<ncols; i++) {
00083         set(0,i,x(i));
00084       }
00085     }
00086   }
00087   
00088 
00089   GF2mat::GF2mat(const bmat &X)
00090   {
00091     it_error("not yet implemented");
00092   }
00093 
00094 
00095   GF2mat::GF2mat(const GF2mat_sparse &X)
00096   {
00097     nrows=X.rows();
00098     ncols=X.cols();
00099     //  GF2mat(m,n);
00100     int k = ncols/(1<<lImax)+1;
00101     nwords=k;
00102     data.set_size(nrows,nwords);
00103     for (int i=0; i<nrows; i++) {
00104       for (int j=0; j<nwords; j++) {
00105         data(i,j) = 0;
00106       }
00107     }
00108 
00109     for (int j=0; j<ncols; j++) {
00110       for (int i=0; i<X.get_col(j).nnz(); i++)   {
00111         bin b = X.get_col(j).get_nz_data(i);
00112         set(X.get_col(j).get_nz_index(i),j,b);
00113       }
00114     }
00115   }
00116 
00117   GF2mat::GF2mat(const GF2mat_sparse &X, int m1, int n1, int m2, int n2)
00118   {
00119     it_assert1(X.rows()>m2,"GF2mat()");
00120     it_assert1(X.cols()>n2,"GF2mat()");
00121     it_assert1(m1>=0 && n1>=0 && m2>=m1 && n2>=n1,"GF2mat::GF2mat()");
00122   
00123     nrows=m2-m1+1;
00124     ncols=n2-n1+1;
00125     nwords=ncols/(1<<lImax)+1;
00126     data.set_size(nrows,nwords);
00127 
00128     for (int i=0; i<nrows; i++) {
00129       for (int j=0; j<nwords; j++) {
00130         data(i,j) = 0;
00131       }
00132     }
00133   
00134     for (int i=0; i<nrows; i++) {
00135       for (int j=0; j<ncols; j++)   {
00136         bin b = X(i+m1,j+n1);
00137         set(i,j,b);
00138       }
00139     }
00140   }
00141 
00142 
00143   GF2mat::GF2mat(const GF2mat_sparse &X, ivec &columns)
00144   {
00145     it_assert1(X.cols()>max(columns),"GF2mat()");
00146     it_assert1(min(columns)>=0,"GF2mat()");
00147   
00148     nrows=X.rows();
00149     ncols=length(columns);
00150     nwords=ncols/(1<<lImax)+1;
00151     data.set_size(nrows,nwords);
00152 
00153     for (int i=0; i<nrows; i++) {
00154       for (int j=0; j<nwords; j++) {
00155         data(i,j) = 0;
00156       }
00157     }
00158   
00159     for (int j=0; j<ncols; j++) {
00160       for (int i=0; i<X.get_col(columns(j)).nnz(); i++)   {
00161         bin b = X.get_col(columns(j)).get_nz_data(i);
00162         set(X.get_col(columns(j)).get_nz_index(i),j,b);
00163       }
00164     }
00165   }
00166 
00167   GF2mat_sparse GF2mat::sparsify()
00168   {
00169     GF2mat_sparse Z(nrows,ncols);
00170     for (int i=0; i<nrows; i++) {
00171       for (int j=0; j<ncols; j++) {
00172         if (get(i,j)==1) {
00173           Z.set(i,j,1);
00174         }
00175       }
00176     }
00177   
00178     return Z;
00179   }
00180 
00181   bvec GF2mat::bvecify()
00182   {
00183     it_assert1(nrows==1 || ncols==1,"GF2mat::bvecify()");
00184     int n=(nrows==1 ? ncols : nrows);
00185     bvec result(n);
00186     for (int i=0; i<n; i++) {
00187       result(i)=(nrows==1 ? get(0,i) : get(i,0));
00188     }
00189     return result;
00190   }
00191 
00192 
00193   void GF2mat::set_row(int i, bvec x)
00194   {
00195     it_assert1(length(x)==ncols,"GF2mat::set_row()");
00196     for (int j=0; j<ncols; j++) {
00197       set(i,j,x(j));
00198     }
00199   }
00200  
00201   void GF2mat::set_col(int j, bvec x)
00202   {
00203     it_assert1(length(x)==nrows,"GF2mat::set_col()");
00204     for (int i=0; i<nrows; i++) {
00205       set(i,j,x(i));
00206     }
00207   }
00208 
00209 
00210   GF2mat gf2dense_eye(int m)
00211   {
00212     GF2mat Z(m,m);
00213     for (int i=0; i<m; i++) {
00214       Z.set(i,i,1);
00215     }
00216     return Z;
00217   }
00218 
00219   GF2mat GF2mat::get_submatrix(int m1, int n1, int m2, int n2)
00220   {
00221     it_assert1(m1>=0 && n1>=0 && m2>=m1 && n2>=n1 && m2<nrows && n2<ncols,"GF2mat::submatrix");
00222     GF2mat result(m2-m1+1,n2-n1+1);
00223 
00224     for (int i=m1; i<=m2; i++) {
00225       for (int j=n1; j<=n2; j++) {
00226         result.set(i-m1,j-n1,get(i,j));
00227       }
00228     }
00229 
00230     return result;
00231   }
00232 
00233 
00234   GF2mat GF2mat::concatenate_vertical(const GF2mat &X)
00235   {
00236     it_assert1(X.ncols==ncols,"GF2mat::concatenate_vertical()");
00237     it_assert1(X.nwords==nwords,"GF2mat::concatenate_vertical()");
00238   
00239     GF2mat result(nrows+X.nrows,ncols);
00240     for (int i=0; i<nrows; i++) {
00241       for (int j=0; j<nwords; j++) {
00242         result.data(i,j) = data(i,j);
00243       }
00244     }
00245 
00246     for (int i=0; i<X.nrows; i++) {
00247       for (int j=0; j<nwords; j++) {
00248         result.data(i+nrows,j) = X.data(i,j);
00249       }
00250     }
00251   
00252     return result;
00253   }
00254 
00255   GF2mat GF2mat::concatenate_horizontal(const GF2mat &X)
00256   {
00257     //  std::cout << X.nrows << "     " << X.ncols << std::endl;
00258     //  std::cout << nrows << "     " << ncols << std::endl;
00259     it_assert1(X.nrows==nrows,"GF2mat::concatenate_horizontal()");
00260 
00261     GF2mat result(nrows,X.ncols+ncols);
00262     for (int i=0; i<nrows; i++) {
00263       for (int j=0; j<ncols; j++) {
00264         result.set(i,j,get(i,j));
00265       }
00266     }
00267 
00268     for (int i=0; i<nrows; i++) {
00269       for (int j=0; j<X.ncols; j++) {
00270         result.set(i,j+ncols,X.get(i,j));
00271       }
00272     }
00273 
00274     return result;
00275   }
00276 
00277   bvec GF2mat::get_row(int i)
00278   {
00279     bvec result = zeros_b(ncols);
00280     for (int j=0; j<ncols; j++) {
00281       result(j) = get(i,j);
00282     }
00283 
00284     return result;
00285   }
00286 
00287   bvec GF2mat::get_col(int j)
00288   {
00289     bvec result = zeros_b(nrows);
00290     for (int i=0; i<nrows; i++) {
00291       result(i) = get(i,j);
00292     }
00293   
00294     return result;
00295   }
00296   
00297 
00298   int GF2mat::T_fact(GF2mat &T, GF2mat &U, ivec &perm)
00299   {
00300     T = gf2dense_eye(nrows);
00301     U = *this;
00302 
00303     perm = zeros_i(ncols);
00304     for (int i=0; i<ncols; i++) {
00305       perm(i) = i;
00306     }
00307   
00308     if (nrows>250) {     // avoid cluttering output with this for small matrices...
00309       std::cout << "Performing T-factorization of GF(2) matrix...  rows: " << nrows << " cols: " 
00310            << ncols << " .... " << std::endl;
00311       std::cout.flush();
00312     }
00313     int pdone=0;
00314     for (int j=0; j<nrows; j++) {
00315       // Now working on diagonal element j,j
00316       // First try find a row with a 1 in column i
00317       int i1,j1;
00318       for (i1=j; i1<nrows; i1++) {
00319         for (j1=j; j1<ncols; j1++) {
00320           if (U.get(i1,j1)==1) { goto found; }
00321         }
00322       }
00323 
00324       return j;
00325     
00326     found: 
00327       U.swap_rows(i1,j);
00328       T.swap_rows(i1,j);
00329       U.swap_cols(j1,j);
00330     
00331       int temp = perm(j);
00332       perm(j) = perm(j1);
00333       perm(j1) = temp;
00334     
00335       // now subtract row i from remaining rows
00336       for (int i1=j+1; i1<nrows; i1++)  {
00337         if (U.get(i1,j)==1) { 
00338           int ptemp = floor_i(100.0*(i1+j*nrows)/(nrows*nrows));
00339           if (nrows>250 && ptemp>pdone+10) {     // this is only disturbing for small matrices
00340             std::cout << ptemp << "% done." << std::endl;
00341             std::cout.flush();
00342             pdone=ptemp;
00343           }
00344           U.add_rows(i1,j);
00345           T.add_rows(i1,j);
00346         }
00347       }
00348     }
00349     return nrows;
00350   }
00351 
00352 
00353   int GF2mat::T_fact_update_bitflip(GF2mat &T, GF2mat &U, ivec &perm, int rank, int r, int c)
00354   {
00355     // First, update U (before re-triangulization)
00356     int c0=c;
00357     for (c=0; c<ncols; c++) {
00358       if (perm(c)==c0) {
00359         goto foundidx;
00360       }
00361     }
00362     it_error("GF2mat::T_fact_update_bitflip() - internal error");  // should never reach this line
00363 
00364   foundidx:
00365     for (int i=0; i<nrows; i++) {
00366       if (T.get(i,r)==1) {
00367         U.addto_element(i,c,1);
00368       }
00369     }
00370 
00371     // first move column c to the end
00372     bvec lastcol = U.get_col(c);
00373     int temp_perm = perm(c);
00374     for (int j=c; j<ncols-1; j++) {
00375       U.set_col(j,U.get_col(j+1));
00376       perm(j) = perm(j+1);
00377     }
00378     U.set_col(ncols-1,lastcol);
00379     perm(ncols-1) = temp_perm;
00380 
00381     // then, if the matrix is tall, also move row c to the end 
00382     if (nrows>=ncols) {
00383       bvec lastrow_U = U.get_row(c);    
00384       bvec lastrow_T = T.get_row(c);
00385       for (int i=c; i<nrows-1; i++) {
00386         U.set_row(i,U.get_row(i+1));
00387         T.set_row(i,T.get_row(i+1));      
00388       }
00389       U.set_row(nrows-1,lastrow_U);
00390       T.set_row(nrows-1,lastrow_T);
00391     
00392       // Do Gaussian elimination on the last row 
00393       for (int j=c; j<ncols; j++)  {       
00394         if (U.get(nrows-1,j)==1) { 
00395           U.add_rows(nrows-1,j);
00396           T.add_rows(nrows-1,j);
00397         }
00398       }
00399     }
00400  
00401     // Now, continue T-factorization from the point (rank-1,rank-1)
00402     for (int j=rank-1; j<nrows; j++) { 
00403       int i1,j1;
00404       for (i1=j; i1<nrows; i1++) {
00405         for (j1=j; j1<ncols; j1++) {
00406           if (U.get(i1,j1)==1) { 
00407             goto found; 
00408           }
00409         }
00410       }
00411     
00412       return j;
00413     
00414     found: 
00415       U.swap_rows(i1,j);
00416       T.swap_rows(i1,j);
00417       U.swap_cols(j1,j);
00418     
00419       int temp = perm(j);
00420       perm(j) = perm(j1);
00421       perm(j1) = temp;
00422     
00423       for (int i1=j+1; i1<nrows; i1++)  {
00424         if (U.get(i1,j)==1) { 
00425           U.add_rows(i1,j);
00426           T.add_rows(i1,j);
00427         }
00428       }
00429     }
00430   
00431     return nrows;
00432   }
00433 
00434   int GF2mat::T_fact_update_addcol(GF2mat &T, GF2mat &U, ivec &perm, bvec newcol)
00435   {
00436     int i0 = T.rows();
00437     int j0 = U.cols();
00438     it_assert1(j0>0,"GF2mat::T_fact_update_addcol()");
00439     it_assert1(i0==T.cols(),"GF2mat::T_fact_update_addcol()");
00440     it_assert1(i0==U.rows(),"GF2mat::T_fact_update_addcol()");
00441     it_assert1(length(perm)==j0,"GF2mat::T_fact_update_addcol()");
00442     it_assert1(U.get(j0-1,j0-1)==1,"GF2mat::T_fact_update_addcol()");
00443     it_assert0(U.row_rank()==j0,"GF2mat::T_fact_update_addcol()");  // VERY TIME CONSUMING TEST
00444 
00445     bvec z = T*newcol;
00446     GF2mat Utemp = U.concatenate_horizontal(GF2mat(z,1));
00447 
00448     // start working on position (j0,j0)
00449     int i;
00450     for (i=j0; i<i0; i++) {
00451       if (Utemp.get(i,j0)==1) {
00452         goto found;
00453       }
00454     }
00455     return 0; // adding the new column would not improve the rank
00456 
00457   found:
00458     perm.set_length(j0+1,true);
00459     perm(j0) = j0;
00460 
00461     Utemp.swap_rows(i,j0);
00462     T.swap_rows(i,j0);
00463   
00464     for (int i1=j0+1; i1<i0; i1++)  {
00465       if (Utemp.get(i1,j0)==1) { 
00466         Utemp.add_rows(i1,j0);
00467         T.add_rows(i1,j0);
00468       }
00469     }
00470 
00471     U = Utemp;
00472     return 1; // the new column was successfully added
00473   }
00474 
00475 
00476 
00477 
00478   GF2mat GF2mat::inverse()
00479   {
00480     it_assert1(nrows==ncols,"GF2mat::inverse(): Matrix must be square");
00481 
00482     // first compute the T-factorization
00483     GF2mat T,U;
00484     ivec perm;
00485     int rank = T_fact(T,U,perm);
00486     it_assert1(rank==ncols,"GF2mat::inverse(): Matrix is not full rank"); 
00487  
00488     // backward substitution
00489     for (int i=ncols-2; i>=0; i--) {
00490       for (int j=ncols-1; j>i; j--) {
00491         if (U.get(i,j)==1) {
00492           U.add_rows(i,j);
00493           T.add_rows(i,j);
00494         }
00495       }
00496     }
00497     T.permute_rows(perm,1);
00498     return T;
00499   }
00500 
00501   int GF2mat::row_rank()
00502   {
00503     GF2mat T,U;
00504     ivec perm;
00505     int rank = T_fact(T,U,perm);
00506     return rank;  
00507   }
00508 
00509   bool GF2mat::is_zero()
00510   {
00511     for (int i=0; i<nrows; i++) {
00512       for (int j=0; j<nwords; j++) {
00513         if (data(i,j)!=0) { 
00514           return false; 
00515         }
00516       }
00517     }
00518     return true;
00519   }
00520 
00521   bool GF2mat::operator==(const GF2mat &X) const
00522   {
00523     if (X.nrows!=nrows) { return false; }
00524     if (X.ncols!=ncols) { return false; }
00525     it_assert1(X.nwords==nwords,"GF2mat::operator==()");
00526  
00527     for (int i=0; i<nrows; i++) {
00528       for (int j=0; j<nwords; j++) {
00529         //      if (X.get(i,j)!=get(i,j)) { 
00530         if (X.data(i,j)!=data(i,j)) {
00531           return false; 
00532         }
00533       }
00534     }
00535     return true;  
00536   }
00537 
00538 
00539   void GF2mat::add_rows(int i, int j)
00540   {
00541     it_assert0(i>=0 && i<nrows,"GF2mat::add_rows() - out of range");
00542     it_assert0(j>=0 && j<nrows,"GF2mat::add_rows() - out of range");
00543     for (int k=0; k<nwords; k++)   {
00544       data(i,k) ^= data(j,k);    
00545     }  
00546   }
00547 
00548   void GF2mat::swap_rows(int i, int j)
00549   {
00550     it_assert0(i>=0 && i<nrows,"GF2mat::swap_rows()");
00551     it_assert0(j>=0 && j<nrows,"GF2mat::swap_rows()");
00552     for (int k=0; k<nwords; k++) {
00553       int temp = data(i,k);
00554       data(i,k) = data(j,k);
00555       data(j,k) = temp;
00556     }
00557   }
00558 
00559   void GF2mat::swap_cols(int i, int j)
00560   {
00561     it_assert0(i>=0 && i<ncols,"GF2mat::swap_cols()");
00562     it_assert0(j>=0 && j<ncols,"GF2mat::swap_cols()");
00563     bvec temp = get_col(i);
00564     set_col(i,get_col(j));
00565     set_col(j,temp);
00566   }
00567 
00568 
00569   void GF2mat::operator=(const GF2mat &X)
00570   {
00571     nrows=X.nrows;
00572     ncols=X.ncols;
00573     nwords=X.nwords;
00574     data = X.data;
00575   }
00576 
00577   GF2mat operator*(const GF2mat &X, const GF2mat &Y)
00578   {
00579     it_assert1(X.ncols==Y.nrows,"GF2mat::operator*");
00580     it_assert0(X.nwords>0,"Gfmat::operator*");
00581     it_assert0(Y.nwords>0,"Gfmat::operator*");
00582 
00583     /*  
00584     // this can be done more efficiently?
00585     GF2mat result(X.nrows,Y.ncols);
00586     for (int i=0; i<X.nrows; i++) {
00587     for (int j=0; j<Y.ncols; j++) {
00588     bin b=0;
00589     for (int k=0; k<X.ncols; k++) {
00590     bin x = X.get(i,k);
00591     bin y = Y.get(k,j);
00592     b ^= (x&y);
00593     }
00594     result.set(i,j,b);
00595     }
00596     }
00597     return result; */
00598 
00599     // is this better?
00600     return mult_trans(X,Y.transpose());
00601   }
00602 
00603   bvec operator*(const GF2mat &X, const bvec &y) 
00604   {
00605     it_assert1(length(y)==X.ncols,"GF2mat::operator*");
00606     it_assert0(X.nwords>0,"Gfmat::operator*");
00607 
00608     /*  
00609     // this can be done more efficiently?
00610     bvec result = zeros_b(X.nrows);
00611     for (int i=0; i<X.nrows; i++) {
00612     // do the nwords-1 data columns first
00613     for (int j=0; j<X.nwords-1; j++) {
00614     int ind = j<<lImax;
00615     unsigned short r=X.data(i,j); // NB. THIS MUST BE UNSIGNED FOR >> TO BE WELL DEFINED
00616     while (r) {
00617     result(i) ^= (r & y(ind));
00618     r >>= 1;    
00619     ind++;
00620     }
00621     }
00622     // do the last column separately
00623     for (int j=(X.nwords-1)<<lImax; j<X.ncols; j++) {
00624     result(i) ^= (X.get(i,j) & y(j));
00625     }
00626     }      
00627     return result; */
00628 
00629     // is this better?
00630     return (mult_trans(X,GF2mat(y,0))).bvecify();
00631   }
00632 
00633   GF2mat mult_trans(const GF2mat &X, const GF2mat &Y)
00634   {
00635     it_assert1(X.ncols==Y.ncols,"GF2mat mult_trans");
00636     it_assert0(X.nwords>0,"GF2mat mult_trans");
00637     it_assert0(Y.nwords>0,"GF2mat mult_trans");
00638     it_assert0(X.nwords==Y.nwords,"GF2mat mult_trans");
00639   
00640     GF2mat result(X.nrows,Y.nrows);
00641 
00642     for (int i=0; i<X.nrows; i++) {
00643       for (int j=0; j<Y.nrows; j++) {
00644         bin b=0;
00645         int kindx =i; 
00646         int kindy =j;
00647         for (int k=0; k<X.nwords; k++) {
00648           //    unsigned short int r=(X.data(i,k) & Y.data(j,k));
00649           unsigned short int r=X.data(kindx) & Y.data(kindy);
00650           /* The following can be speeded up by using a small lookup
00651              table for the number of ones and shift only a few times (or
00652              not at all if table is large) */
00653           while (r) {
00654             b ^= r&1;
00655             r>>=1;
00656           };
00657           kindx += X.nrows;
00658           kindy += Y.nrows;
00659         }
00660         result.set(i,j,b);
00661       }
00662     }
00663     return result;
00664   }
00665 
00666   GF2mat GF2mat::transpose() const
00667   {
00668     // CAN BE SPEEDED UP
00669     GF2mat result(ncols,nrows);
00670   
00671     for (int i=0; i<nrows; i++) {
00672       for (int j=0; j<ncols; j++) {
00673         result.set(j,i,get(i,j));
00674       }
00675     }
00676     return result;
00677   }
00678 
00679   GF2mat operator+(const GF2mat &X, const GF2mat &Y)
00680   {
00681     it_assert1(X.nrows==Y.nrows,"GF2mat operator+");
00682     it_assert1(X.ncols==Y.ncols,"GF2mat operator+");
00683     it_assert1(X.nwords==Y.nwords,"GF2mat operator+");
00684     GF2mat result(X.nrows,X.ncols);
00685   
00686     for (int i=0; i<X.nrows; i++) {
00687       for (int j=0; j<X.nwords; j++) {
00688         result.data(i,j) = X.data(i,j) ^ Y.data(i,j);
00689       }
00690     }
00691 
00692     return result;
00693   }
00694 
00695   void GF2mat::permute_cols(ivec &perm, bool I)
00696   {
00697     it_assert1(length(perm)==ncols,"GF2mat::permute_cols()");
00698 
00699     GF2mat temp = (*this);
00700     for (int j=0; j<ncols; j++) {
00701       if (I==0) {
00702         set_col(j,temp.get_col(perm(j)));
00703       }  else { 
00704         set_col(perm(j),temp.get_col(j));
00705       }
00706     }
00707   }
00708 
00709   void GF2mat::permute_rows(ivec &perm, bool I)
00710   {
00711     it_assert1(length(perm)==nrows,"GF2mat::permute_rows()");
00712 
00713     GF2mat temp = (*this);
00714     for (int i=0; i<nrows; i++) {
00715       if (I==0) {
00716         for (int j=0; j<nwords; j++) {
00717           data(i,j) = temp.data(perm(i),j);
00718         }
00719         //      set_row(i,temp.get_col(perm(i)));
00720       }  else { 
00721         for (int j=0; j<nwords; j++) {
00722           data(perm(i),j) = temp.data(i,j);
00723         }
00724         //      set_row(perm(i),temp.get_row(i));
00725       }
00726     }
00727   }
00728 
00729 
00730   std::ostream &operator<<(std::ostream &os, const GF2mat &X)
00731   {
00732     int i,j;
00733     os << "---- GF(2) matrix of dimension " << X.nrows << "*" << X.ncols
00734        << " -- Density: " << X.density() << " ----" << std::endl;
00735 
00736     for (i=0; i<X.nrows; i++) {
00737       std::cout << "      ";
00738       for (j=0; j<X.ncols; j++) {
00739         os << X.get(i,j) << " ";
00740       }
00741       os << std::endl;
00742     }
00743 
00744     return os;
00745   }
00746 
00747   double GF2mat::density() const
00748   {
00749     int no_of_ones=0;
00750 
00751     for (int i=0; i<nrows; i++) {
00752       for (int j=0; j<ncols; j++) {
00753         no_of_ones += (get(i,j)==1 ? 1 : 0);
00754       }
00755     }
00756 
00757     return ((double) no_of_ones)/(nrows*ncols);
00758   }
00759 
00760 
00761   it_file &operator<<(it_file &f, const GF2mat &X)
00762   {
00763     int bytecount = 3*sizeof(int)+X.nrows*X.nwords*sizeof(int);
00764     f.write_data_header("GF2mat", bytecount);
00765 
00766     f.low_level_write(X.nrows);
00767     f.low_level_write(X.ncols);
00768     f.low_level_write(X.nwords);
00769     for (int i=0; i<X.nrows; i++) {
00770       for (int j=0; j<X.nwords; j++) {
00771         short r=X.data(i,j);
00772         f.low_level_write(r);
00773       }
00774     }
00775     return f; 
00776   }
00777 
00778   it_ifile &operator>>(it_ifile &f, GF2mat &X)
00779   {
00780     it_file::data_header h;
00781   
00782     f.read_data_header(h);
00783     if (h.type == "GF2mat") {
00784       f.low_level_read(X.nrows);
00785       f.low_level_read(X.ncols);
00786       f.low_level_read(X.nwords);
00787       X.data.set_size(X.nrows,X.nwords);
00788       for (int i=0; i<X.nrows; i++) {
00789         for (int j=0; j<X.nwords; j++) {
00790           short r;
00791           f.low_level_read(r);
00792           X.data(i,j) = ((unsigned short int) r);
00793         }
00794       }
00795     
00796     }  else {
00797       //    throw it_file_base::Error("Wrong type");
00798       it_error("it_ifile &operator>>() - internal error");
00799     }
00800 
00801     return f;
00802   }
00803 
00804 } // namespace itpp
00805 
SourceForge Logo

Generated on Thu Apr 19 14:19:51 2007 for IT++ by Doxygen 1.4.6