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; 00486 // 2007-07-12 ediap: workaround to fix unused variable warning 00487 rank = T_fact(T,U,perm); 00488 it_assert1(rank==ncols,"GF2mat::inverse(): Matrix is not full rank"); 00489 00490 // backward substitution 00491 for (int i=ncols-2; i>=0; i--) { 00492 for (int j=ncols-1; j>i; j--) { 00493 if (U.get(i,j)==1) { 00494 U.add_rows(i,j); 00495 T.add_rows(i,j); 00496 } 00497 } 00498 } 00499 T.permute_rows(perm,1); 00500 return T; 00501 } 00502 00503 int GF2mat::row_rank() 00504 { 00505 GF2mat T,U; 00506 ivec perm; 00507 int rank = T_fact(T,U,perm); 00508 return rank; 00509 } 00510 00511 bool GF2mat::is_zero() 00512 { 00513 for (int i=0; i<nrows; i++) { 00514 for (int j=0; j<nwords; j++) { 00515 if (data(i,j)!=0) { 00516 return false; 00517 } 00518 } 00519 } 00520 return true; 00521 } 00522 00523 bool GF2mat::operator==(const GF2mat &X) const 00524 { 00525 if (X.nrows!=nrows) { return false; } 00526 if (X.ncols!=ncols) { return false; } 00527 it_assert1(X.nwords==nwords,"GF2mat::operator==()"); 00528 00529 for (int i=0; i<nrows; i++) { 00530 for (int j=0; j<nwords; j++) { 00531 // if (X.get(i,j)!=get(i,j)) { 00532 if (X.data(i,j)!=data(i,j)) { 00533 return false; 00534 } 00535 } 00536 } 00537 return true; 00538 } 00539 00540 00541 void GF2mat::add_rows(int i, int j) 00542 { 00543 it_assert0(i>=0 && i<nrows,"GF2mat::add_rows() - out of range"); 00544 it_assert0(j>=0 && j<nrows,"GF2mat::add_rows() - out of range"); 00545 for (int k=0; k<nwords; k++) { 00546 data(i,k) ^= data(j,k); 00547 } 00548 } 00549 00550 void GF2mat::swap_rows(int i, int j) 00551 { 00552 it_assert0(i>=0 && i<nrows,"GF2mat::swap_rows()"); 00553 it_assert0(j>=0 && j<nrows,"GF2mat::swap_rows()"); 00554 for (int k=0; k<nwords; k++) { 00555 int temp = data(i,k); 00556 data(i,k) = data(j,k); 00557 data(j,k) = temp; 00558 } 00559 } 00560 00561 void GF2mat::swap_cols(int i, int j) 00562 { 00563 it_assert0(i>=0 && i<ncols,"GF2mat::swap_cols()"); 00564 it_assert0(j>=0 && j<ncols,"GF2mat::swap_cols()"); 00565 bvec temp = get_col(i); 00566 set_col(i,get_col(j)); 00567 set_col(j,temp); 00568 } 00569 00570 00571 void GF2mat::operator=(const GF2mat &X) 00572 { 00573 nrows=X.nrows; 00574 ncols=X.ncols; 00575 nwords=X.nwords; 00576 data = X.data; 00577 } 00578 00579 GF2mat operator*(const GF2mat &X, const GF2mat &Y) 00580 { 00581 it_assert1(X.ncols==Y.nrows,"GF2mat::operator*"); 00582 it_assert0(X.nwords>0,"Gfmat::operator*"); 00583 it_assert0(Y.nwords>0,"Gfmat::operator*"); 00584 00585 /* 00586 // this can be done more efficiently? 00587 GF2mat result(X.nrows,Y.ncols); 00588 for (int i=0; i<X.nrows; i++) { 00589 for (int j=0; j<Y.ncols; j++) { 00590 bin b=0; 00591 for (int k=0; k<X.ncols; k++) { 00592 bin x = X.get(i,k); 00593 bin y = Y.get(k,j); 00594 b ^= (x&y); 00595 } 00596 result.set(i,j,b); 00597 } 00598 } 00599 return result; */ 00600 00601 // is this better? 00602 return mult_trans(X,Y.transpose()); 00603 } 00604 00605 bvec operator*(const GF2mat &X, const bvec &y) 00606 { 00607 it_assert1(length(y)==X.ncols,"GF2mat::operator*"); 00608 it_assert0(X.nwords>0,"Gfmat::operator*"); 00609 00610 /* 00611 // this can be done more efficiently? 00612 bvec result = zeros_b(X.nrows); 00613 for (int i=0; i<X.nrows; i++) { 00614 // do the nwords-1 data columns first 00615 for (int j=0; j<X.nwords-1; j++) { 00616 int ind = j<<lImax; 00617 unsigned short r=X.data(i,j); // NB. THIS MUST BE UNSIGNED FOR >> TO BE WELL DEFINED 00618 while (r) { 00619 result(i) ^= (r & y(ind)); 00620 r >>= 1; 00621 ind++; 00622 } 00623 } 00624 // do the last column separately 00625 for (int j=(X.nwords-1)<<lImax; j<X.ncols; j++) { 00626 result(i) ^= (X.get(i,j) & y(j)); 00627 } 00628 } 00629 return result; */ 00630 00631 // is this better? 00632 return (mult_trans(X,GF2mat(y,0))).bvecify(); 00633 } 00634 00635 GF2mat mult_trans(const GF2mat &X, const GF2mat &Y) 00636 { 00637 it_assert1(X.ncols==Y.ncols,"GF2mat mult_trans"); 00638 it_assert0(X.nwords>0,"GF2mat mult_trans"); 00639 it_assert0(Y.nwords>0,"GF2mat mult_trans"); 00640 it_assert0(X.nwords==Y.nwords,"GF2mat mult_trans"); 00641 00642 GF2mat result(X.nrows,Y.nrows); 00643 00644 for (int i=0; i<X.nrows; i++) { 00645 for (int j=0; j<Y.nrows; j++) { 00646 bin b=0; 00647 int kindx =i; 00648 int kindy =j; 00649 for (int k=0; k<X.nwords; k++) { 00650 // unsigned short int r=(X.data(i,k) & Y.data(j,k)); 00651 unsigned short int r=X.data(kindx) & Y.data(kindy); 00652 /* The following can be speeded up by using a small lookup 00653 table for the number of ones and shift only a few times (or 00654 not at all if table is large) */ 00655 while (r) { 00656 b ^= r&1; 00657 r>>=1; 00658 }; 00659 kindx += X.nrows; 00660 kindy += Y.nrows; 00661 } 00662 result.set(i,j,b); 00663 } 00664 } 00665 return result; 00666 } 00667 00668 GF2mat GF2mat::transpose() const 00669 { 00670 // CAN BE SPEEDED UP 00671 GF2mat result(ncols,nrows); 00672 00673 for (int i=0; i<nrows; i++) { 00674 for (int j=0; j<ncols; j++) { 00675 result.set(j,i,get(i,j)); 00676 } 00677 } 00678 return result; 00679 } 00680 00681 GF2mat operator+(const GF2mat &X, const GF2mat &Y) 00682 { 00683 it_assert1(X.nrows==Y.nrows,"GF2mat operator+"); 00684 it_assert1(X.ncols==Y.ncols,"GF2mat operator+"); 00685 it_assert1(X.nwords==Y.nwords,"GF2mat operator+"); 00686 GF2mat result(X.nrows,X.ncols); 00687 00688 for (int i=0; i<X.nrows; i++) { 00689 for (int j=0; j<X.nwords; j++) { 00690 result.data(i,j) = X.data(i,j) ^ Y.data(i,j); 00691 } 00692 } 00693 00694 return result; 00695 } 00696 00697 void GF2mat::permute_cols(ivec &perm, bool I) 00698 { 00699 it_assert1(length(perm)==ncols,"GF2mat::permute_cols()"); 00700 00701 GF2mat temp = (*this); 00702 for (int j=0; j<ncols; j++) { 00703 if (I==0) { 00704 set_col(j,temp.get_col(perm(j))); 00705 } else { 00706 set_col(perm(j),temp.get_col(j)); 00707 } 00708 } 00709 } 00710 00711 void GF2mat::permute_rows(ivec &perm, bool I) 00712 { 00713 it_assert1(length(perm)==nrows,"GF2mat::permute_rows()"); 00714 00715 GF2mat temp = (*this); 00716 for (int i=0; i<nrows; i++) { 00717 if (I==0) { 00718 for (int j=0; j<nwords; j++) { 00719 data(i,j) = temp.data(perm(i),j); 00720 } 00721 // set_row(i,temp.get_col(perm(i))); 00722 } else { 00723 for (int j=0; j<nwords; j++) { 00724 data(perm(i),j) = temp.data(i,j); 00725 } 00726 // set_row(perm(i),temp.get_row(i)); 00727 } 00728 } 00729 } 00730 00731 00732 std::ostream &operator<<(std::ostream &os, const GF2mat &X) 00733 { 00734 int i,j; 00735 os << "---- GF(2) matrix of dimension " << X.nrows << "*" << X.ncols 00736 << " -- Density: " << X.density() << " ----" << std::endl; 00737 00738 for (i=0; i<X.nrows; i++) { 00739 std::cout << " "; 00740 for (j=0; j<X.ncols; j++) { 00741 os << X.get(i,j) << " "; 00742 } 00743 os << std::endl; 00744 } 00745 00746 return os; 00747 } 00748 00749 double GF2mat::density() const 00750 { 00751 int no_of_ones=0; 00752 00753 for (int i=0; i<nrows; i++) { 00754 for (int j=0; j<ncols; j++) { 00755 no_of_ones += (get(i,j)==1 ? 1 : 0); 00756 } 00757 } 00758 00759 return ((double) no_of_ones)/(nrows*ncols); 00760 } 00761 00762 00763 it_file &operator<<(it_file &f, const GF2mat &X) 00764 { 00765 int bytecount = 3*sizeof(int)+X.nrows*X.nwords*sizeof(int); 00766 f.write_data_header("GF2mat", bytecount); 00767 00768 f.low_level_write(X.nrows); 00769 f.low_level_write(X.ncols); 00770 f.low_level_write(X.nwords); 00771 for (int i=0; i<X.nrows; i++) { 00772 for (int j=0; j<X.nwords; j++) { 00773 short r=X.data(i,j); 00774 f.low_level_write(r); 00775 } 00776 } 00777 return f; 00778 } 00779 00780 it_ifile &operator>>(it_ifile &f, GF2mat &X) 00781 { 00782 it_file::data_header h; 00783 00784 f.read_data_header(h); 00785 if (h.type == "GF2mat") { 00786 f.low_level_read(X.nrows); 00787 f.low_level_read(X.ncols); 00788 f.low_level_read(X.nwords); 00789 X.data.set_size(X.nrows,X.nwords); 00790 for (int i=0; i<X.nrows; i++) { 00791 for (int j=0; j<X.nwords; j++) { 00792 short r; 00793 f.low_level_read(r); 00794 X.data(i,j) = ((unsigned short int) r); 00795 } 00796 } 00797 00798 } else { 00799 // throw it_file_base::Error("Wrong type"); 00800 it_error("it_ifile &operator>>() - internal error"); 00801 } 00802 00803 return f; 00804 } 00805 00806 } // namespace itpp 00807
Generated on Sat Aug 25 23:40:52 2007 for IT++ by Doxygen 1.5.2