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
Generated on Thu Apr 19 14:19:51 2007 for IT++ by Doxygen 1.4.6