| 1 | /*! |
|---|
| 2 | * \file |
|---|
| 3 | * \brief Definition of a class for algebra on GF(2) (binary) matrices |
|---|
| 4 | * \author Erik G. Larsson and Adam Piatyszek |
|---|
| 5 | * |
|---|
| 6 | * ------------------------------------------------------------------------- |
|---|
| 7 | * |
|---|
| 8 | * IT++ - C++ library of mathematical, signal processing, speech processing, |
|---|
| 9 | * and communications classes and functions |
|---|
| 10 | * |
|---|
| 11 | * Copyright (C) 1995-2007 (see AUTHORS file for a list of contributors) |
|---|
| 12 | * |
|---|
| 13 | * This program is free software; you can redistribute it and/or modify |
|---|
| 14 | * it under the terms of the GNU General Public License as published by |
|---|
| 15 | * the Free Software Foundation; either version 2 of the License, or |
|---|
| 16 | * (at your option) any later version. |
|---|
| 17 | * |
|---|
| 18 | * This program is distributed in the hope that it will be useful, |
|---|
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 21 | * GNU General Public License for more details. |
|---|
| 22 | * |
|---|
| 23 | * You should have received a copy of the GNU General Public License |
|---|
| 24 | * along with this program; if not, write to the Free Software |
|---|
| 25 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 26 | * |
|---|
| 27 | * ------------------------------------------------------------------------- |
|---|
| 28 | * |
|---|
| 29 | * Two representations are offered: GF2mat_sparse for sparse GF(2) |
|---|
| 30 | * matrices and GF2mat for dense GF(2) matrices. Conversions between |
|---|
| 31 | * dense and sparse GF(2) are also possible. |
|---|
| 32 | * |
|---|
| 33 | * Binary vectors are represented either via the bvec class (memory |
|---|
| 34 | * typically is not an issue here) or as n*1 (or 1*n) GF(2) matrix. |
|---|
| 35 | * |
|---|
| 36 | * Note that the \c bmat class also provides some functionality for |
|---|
| 37 | * matrix algebra over GF(2) but this class is based on \c Mat<> which |
|---|
| 38 | * has a fundamentally different addressing mechanism and which is |
|---|
| 39 | * much less memory efficient (\c Mat<> uses one byte memory minimum |
|---|
| 40 | * per element). |
|---|
| 41 | */ |
|---|
| 42 | |
|---|
| 43 | #ifndef GF2MAT_H |
|---|
| 44 | #define GF2MAT_H |
|---|
| 45 | |
|---|
| 46 | #include <itpp/base/vec.h> |
|---|
| 47 | #include <itpp/base/mat.h> |
|---|
| 48 | #include <itpp/base/svec.h> |
|---|
| 49 | #include <itpp/base/smat.h> |
|---|
| 50 | #include <itpp/base/itfile.h> |
|---|
| 51 | |
|---|
| 52 | |
|---|
| 53 | namespace itpp { |
|---|
| 54 | |
|---|
| 55 | // ---------------------------------------------------------------------- |
|---|
| 56 | // Sparse GF(2) matrix class |
|---|
| 57 | // ---------------------------------------------------------------------- |
|---|
| 58 | |
|---|
| 59 | //! Sparse GF(2) vector |
|---|
| 60 | typedef Sparse_Vec<bin> GF2vec_sparse; |
|---|
| 61 | |
|---|
| 62 | //! Sparse GF(2) matrix |
|---|
| 63 | typedef Sparse_Mat<bin> GF2mat_sparse; |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | // ---------------------------------------------------------------------- |
|---|
| 67 | // Alist parameterization of sparse GF(2) matrix class |
|---|
| 68 | // ---------------------------------------------------------------------- |
|---|
| 69 | |
|---|
| 70 | /*! |
|---|
| 71 | \relatesalso GF2mat_sparse |
|---|
| 72 | \brief Parameterized "alist" representation of sparse GF(2) matrix |
|---|
| 73 | \author Adam Piatyszek and Erik G. Larsson |
|---|
| 74 | |
|---|
| 75 | This class is used to provide a parameterized representation of a \c |
|---|
| 76 | GF2mat_sparse class. The format is compatible with the "alist" format |
|---|
| 77 | defined by David MacKay, Matthew Davey and John Lafferty: |
|---|
| 78 | - http://www.inference.phy.cam.ac.uk/mackay/codes/alist.html |
|---|
| 79 | |
|---|
| 80 | For examples of "alist" representation visit David MacKay's Encyclopedia |
|---|
| 81 | of Sparse Graph Codes: |
|---|
| 82 | - http://www.inference.phy.cam.ac.uk/mackay/codes/data.html |
|---|
| 83 | */ |
|---|
| 84 | class GF2mat_sparse_alist { |
|---|
| 85 | public: |
|---|
| 86 | //! Default constructor |
|---|
| 87 | GF2mat_sparse_alist() : data_ok(false) {} |
|---|
| 88 | //! Constructor, which reads alist data from a file named \c fname |
|---|
| 89 | GF2mat_sparse_alist(const std::string &fname); |
|---|
| 90 | |
|---|
| 91 | //! Read alist data from a file named \c fname |
|---|
| 92 | void read(const std::string &fname); |
|---|
| 93 | //! Write alist data to a file named \c fname |
|---|
| 94 | void write(const std::string &fname) const; |
|---|
| 95 | |
|---|
| 96 | /*! |
|---|
| 97 | \brief Convert "alist" representation to \c GF2mat_sparse |
|---|
| 98 | |
|---|
| 99 | \param transpose Indicates whether a matrix should be transposed |
|---|
| 100 | during the conversion process |
|---|
| 101 | */ |
|---|
| 102 | GF2mat_sparse to_sparse(bool transpose = false) const; |
|---|
| 103 | |
|---|
| 104 | /*! |
|---|
| 105 | \brief Import "alist" representation from \c GF2mat_sparse |
|---|
| 106 | |
|---|
| 107 | \param mat Matrix to import |
|---|
| 108 | \param transpose Indicates whether a matrix should be transposed |
|---|
| 109 | during the conversion process |
|---|
| 110 | */ |
|---|
| 111 | void from_sparse(const GF2mat_sparse &mat, bool transpose = false); |
|---|
| 112 | |
|---|
| 113 | protected: |
|---|
| 114 | //! Flag indicating that "alist" matrix data are properly set |
|---|
| 115 | bool data_ok; |
|---|
| 116 | //! Size of the matrix: \c M rows x \c N columns |
|---|
| 117 | int M; |
|---|
| 118 | //! Size of the matrix: \c M rows x \c N columns |
|---|
| 119 | int N; |
|---|
| 120 | //! List of integer coordinates in the m direction with non-zero entries |
|---|
| 121 | imat mlist; |
|---|
| 122 | //! List of integer coordinates in the n direction with non-zero entries |
|---|
| 123 | imat nlist; |
|---|
| 124 | //! Weight of each row m |
|---|
| 125 | ivec num_mlist; |
|---|
| 126 | //! Weight of each column n |
|---|
| 127 | ivec num_nlist; |
|---|
| 128 | //! Maximum weight of rows |
|---|
| 129 | int max_num_m; |
|---|
| 130 | //! Maximum weight of columns |
|---|
| 131 | int max_num_n; |
|---|
| 132 | }; |
|---|
| 133 | |
|---|
| 134 | |
|---|
| 135 | // ---------------------------------------------------------------------- |
|---|
| 136 | // Dense GF(2) matrix class |
|---|
| 137 | // ---------------------------------------------------------------------- |
|---|
| 138 | |
|---|
| 139 | /*! |
|---|
| 140 | \relatesalso bmat |
|---|
| 141 | \brief Class for dense GF(2) matrices |
|---|
| 142 | \author Erik G. Larsson |
|---|
| 143 | |
|---|
| 144 | This class can be used as an alternative to \c bmat to represent |
|---|
| 145 | GF(2) matrices. It extends the functionality of \c bmat in two ways: |
|---|
| 146 | |
|---|
| 147 | - \c GF2mat makes more efficient use of computer memory than \c bmat |
|---|
| 148 | (one bit in the matrix requires one bit of memory) |
|---|
| 149 | - \c GF2mat provides several functions for linear algebra and matrix |
|---|
| 150 | factorizations |
|---|
| 151 | |
|---|
| 152 | See also \c GF2mat_sparse which offers an efficient representation |
|---|
| 153 | of sparse GF(2) matrices, and \c GF2mat_sparse_alist for a |
|---|
| 154 | parameterized representation of sparse GF(2) matrices. |
|---|
| 155 | */ |
|---|
| 156 | class GF2mat { |
|---|
| 157 | public: |
|---|
| 158 | |
|---|
| 159 | // ----------- Constructors ----------- |
|---|
| 160 | |
|---|
| 161 | //! Default constructor (gives an empty 1 x 1 matrix) |
|---|
| 162 | GF2mat(); |
|---|
| 163 | |
|---|
| 164 | //! Construct an empty (all-zero) m x n matrix |
|---|
| 165 | GF2mat(int m, int n); |
|---|
| 166 | |
|---|
| 167 | //! Construct a dense GF(2) matrix from a sparse GF(2) matrix |
|---|
| 168 | GF2mat(const GF2mat_sparse &X); |
|---|
| 169 | |
|---|
| 170 | /*! \brief Constructor, from subset of sparse GF(2) matrix |
|---|
| 171 | |
|---|
| 172 | This constructor forms a dense GF(2) matrix from a subset (m1,n1) |
|---|
| 173 | to (m2,n2) of a sparse GF(2) matrix */ |
|---|
| 174 | GF2mat(const GF2mat_sparse &X, int m1, int n1, int m2, int n2); |
|---|
| 175 | |
|---|
| 176 | /*! \brief Constructor, from subset of sparse GF(2) matrix |
|---|
| 177 | |
|---|
| 178 | This constructor forms a dense GF(2) matrix from a subset of |
|---|
| 179 | columns in sparse GF(2) matrix |
|---|
| 180 | |
|---|
| 181 | \param X matrix to copy from |
|---|
| 182 | \param columns subset of columns to copy |
|---|
| 183 | */ |
|---|
| 184 | GF2mat(const GF2mat_sparse &X, const ivec &columns); |
|---|
| 185 | |
|---|
| 186 | /*! |
|---|
| 187 | \brief Create a dense GF(2) matrix from a single vector. |
|---|
| 188 | |
|---|
| 189 | \param x The input vector |
|---|
| 190 | \param is_column A parameter that indicates whether the result should |
|---|
| 191 | be a row vector (false), or a column vector (true - default) |
|---|
| 192 | */ |
|---|
| 193 | GF2mat(const bvec &x, bool is_column = true); |
|---|
| 194 | |
|---|
| 195 | //! Create a dense GF(2) matrix from a bmat |
|---|
| 196 | GF2mat(const bmat &X); |
|---|
| 197 | |
|---|
| 198 | //! Set size of GF(2) matrix. If copy = true, keep data before resizing. |
|---|
| 199 | void set_size(int m, int n, bool copy = false); |
|---|
| 200 | |
|---|
| 201 | //! Create a sparse GF(2) matrix from a dense GF(2) matrix |
|---|
| 202 | GF2mat_sparse sparsify() const; |
|---|
| 203 | |
|---|
| 204 | //! Create a bvec from a GF(2) matrix (must have one column or one row) |
|---|
| 205 | bvec bvecify() const; |
|---|
| 206 | |
|---|
| 207 | // ----------- Elementwise manipulation and simple functions ------------- |
|---|
| 208 | |
|---|
| 209 | //! Getting element |
|---|
| 210 | inline bin get(int i, int j) const; |
|---|
| 211 | |
|---|
| 212 | //! Getting element |
|---|
| 213 | inline bin operator()(int i, int j) const { return get(i,j); }; |
|---|
| 214 | |
|---|
| 215 | //! Set element i,j to s (0 or 1) |
|---|
| 216 | inline void set(int i, int j, bin s); |
|---|
| 217 | |
|---|
| 218 | //! Add s (0 or 1) to element (i,j) |
|---|
| 219 | inline void addto_element(int i, int j, bin s); |
|---|
| 220 | |
|---|
| 221 | //! Set column j to a binary vector x |
|---|
| 222 | void set_col(int j, bvec x); |
|---|
| 223 | |
|---|
| 224 | //! Set row i to a binary vector x |
|---|
| 225 | void set_row(int i, bvec x); |
|---|
| 226 | |
|---|
| 227 | //! Check whether the matrix is identical to zero |
|---|
| 228 | bool is_zero() const; |
|---|
| 229 | |
|---|
| 230 | //! Swap rows i and j |
|---|
| 231 | void swap_rows(int i, int j); |
|---|
| 232 | |
|---|
| 233 | //! Swap columns i and j |
|---|
| 234 | void swap_cols(int i, int j); |
|---|
| 235 | |
|---|
| 236 | /*! \brief Multiply from left with permutation matrix (permute rows). |
|---|
| 237 | |
|---|
| 238 | \param perm Permutation vector |
|---|
| 239 | \param I Parameter that determines permutation. |
|---|
| 240 | I=0: apply permutation, I=1: apply inverse permutation |
|---|
| 241 | */ |
|---|
| 242 | void permute_rows(ivec &perm, bool I); |
|---|
| 243 | |
|---|
| 244 | /*! \brief Multiply a matrix from right with a permutation matrix |
|---|
| 245 | (i.e., permute the columns). |
|---|
| 246 | |
|---|
| 247 | \param perm Permutation vector |
|---|
| 248 | \param I Parameter that determines permutation. |
|---|
| 249 | I=0: apply permutation, I=1: apply inverse permutation |
|---|
| 250 | */ |
|---|
| 251 | void permute_cols(ivec &perm, bool I); |
|---|
| 252 | |
|---|
| 253 | //! Transpose |
|---|
| 254 | GF2mat transpose() const; |
|---|
| 255 | |
|---|
| 256 | //! Submatrix from (m1,n1) to (m2,n2) |
|---|
| 257 | GF2mat get_submatrix(int m1, int n1, int m2, int n2) const; |
|---|
| 258 | |
|---|
| 259 | //! Concatenate horizontally (append X on the right side of matrix) |
|---|
| 260 | GF2mat concatenate_horizontal(const GF2mat &X) const; |
|---|
| 261 | |
|---|
| 262 | //! Concatenate vertically (append X underneath) |
|---|
| 263 | GF2mat concatenate_vertical(const GF2mat &X) const; |
|---|
| 264 | |
|---|
| 265 | //! Get row |
|---|
| 266 | bvec get_row(int i) const; |
|---|
| 267 | |
|---|
| 268 | //! Get column |
|---|
| 269 | bvec get_col(int j) const; |
|---|
| 270 | |
|---|
| 271 | //! Compute the matrix density (fraction of elements equal to "1") |
|---|
| 272 | double density() const; |
|---|
| 273 | |
|---|
| 274 | //! Get number of rows |
|---|
| 275 | int rows() const { return nrows; } |
|---|
| 276 | |
|---|
| 277 | //! Get number of columns |
|---|
| 278 | int cols() const { return ncols; } |
|---|
| 279 | |
|---|
| 280 | /*! \brief Add (or equivalently, subtract) rows |
|---|
| 281 | |
|---|
| 282 | This function updates row i according to row_i = row_i+row_j |
|---|
| 283 | |
|---|
| 284 | \param i Row to add to. This row will be modified |
|---|
| 285 | \param j Row to add. This row will <b>not</b> be modified. |
|---|
| 286 | */ |
|---|
| 287 | void add_rows(int i, int j); |
|---|
| 288 | |
|---|
| 289 | // ---------- Linear algebra -------------- |
|---|
| 290 | |
|---|
| 291 | /*! \brief Inversion. |
|---|
| 292 | |
|---|
| 293 | The matrix must be invertible, otherwise the |
|---|
| 294 | function will terminate with an error. |
|---|
| 295 | */ |
|---|
| 296 | GF2mat inverse() const; |
|---|
| 297 | |
|---|
| 298 | //! Returns the number of linearly independent rows |
|---|
| 299 | int row_rank() const; |
|---|
| 300 | |
|---|
| 301 | /*! \brief TXP factorization. |
|---|
| 302 | |
|---|
| 303 | Given X, compute a factorization of the form U=TXP, where U is |
|---|
| 304 | upper triangular, T is square and invertible, and P is a |
|---|
| 305 | permutation matrix. This is basically an "LU"-factorization, |
|---|
| 306 | but not called so here because T is not necessarily lower |
|---|
| 307 | trianglular. The matrix X may have any dimension. The |
|---|
| 308 | permutation matrix P is represented as a permutation vector. |
|---|
| 309 | |
|---|
| 310 | The function returns the row rank of X. (If X is full row rank, |
|---|
| 311 | then the number of rows is returned.) |
|---|
| 312 | |
|---|
| 313 | The function uses Gaussian elimination combined with |
|---|
| 314 | permutations. The computational complexity is O(m*m*n) for an |
|---|
| 315 | m*n matrix. |
|---|
| 316 | */ |
|---|
| 317 | int T_fact(GF2mat &T, GF2mat &U, ivec &P) const; |
|---|
| 318 | |
|---|
| 319 | /*! \brief TXP factorization update, when bit is flipped. |
|---|
| 320 | |
|---|
| 321 | Update upper triangular factor U in the TXP-factorization (U=TXP) |
|---|
| 322 | when the bit at position (r,c) is changed (0->1 or 1->0). The |
|---|
| 323 | purpose of this function is to avoid re-running a complete |
|---|
| 324 | T-factorization when a single bit is changed. The function assumes |
|---|
| 325 | that T, U, and P already exist and that U=TXP before the function |
|---|
| 326 | is called. The function also assumes that the rank provided is |
|---|
| 327 | correct. The function updates T, U and P these matrices. The |
|---|
| 328 | function returns the new rank of the matrix after the bitflip. |
|---|
| 329 | |
|---|
| 330 | \note T, U, P and the rank value supplied to the function must be |
|---|
| 331 | correct one. This is not checked by the function (for reasons of |
|---|
| 332 | efficiency). |
|---|
| 333 | |
|---|
| 334 | The function works by performing permutations to bring the matrix |
|---|
| 335 | to a form where the Gaussian eliminated can be restarted from the |
|---|
| 336 | point (rank-1,rank-1). The function is very fast for matrices with |
|---|
| 337 | close to full rank but it is generally slower for non-full rank |
|---|
| 338 | matrices. |
|---|
| 339 | */ |
|---|
| 340 | int T_fact_update_bitflip(GF2mat &T, GF2mat &U, |
|---|
| 341 | ivec &P, int rank, int r, int c) const; |
|---|
| 342 | |
|---|
| 343 | /*! \brief TXP factorization update, when column is added |
|---|
| 344 | |
|---|
| 345 | Update upper triangular factor U in the T-factorization (U=TXP) |
|---|
| 346 | when a column (newcol) is appended at the right side of the |
|---|
| 347 | matrix. The purpose of this function is to avoid re-running a |
|---|
| 348 | complete T-factorization when a column is added. The function ONLY |
|---|
| 349 | adds the column if it improves the rank of the matrix (nothing is |
|---|
| 350 | done otherwise). The function returns "true" if the column was |
|---|
| 351 | added, and "false" otherwise. |
|---|
| 352 | |
|---|
| 353 | \note This function does not actually add the column newcol to the |
|---|
| 354 | GF2 matrix. It only checks whether doing so would increase the |
|---|
| 355 | rank, and if this is the case, it updates the T-factorization. A |
|---|
| 356 | typical calling sequence would be |
|---|
| 357 | \code |
|---|
| 358 | bool rank_will_improve = X.T_fact_update_addcol(T,U,perm,c); |
|---|
| 359 | if (rank_will_improve) { X = X.concatenate_horizontal(c); } |
|---|
| 360 | \endcode |
|---|
| 361 | |
|---|
| 362 | The complexity is O(m^2) for an m*n matrix. |
|---|
| 363 | */ |
|---|
| 364 | bool T_fact_update_addcol(GF2mat &T, GF2mat &U, |
|---|
| 365 | ivec &P, bvec newcol) const; |
|---|
| 366 | |
|---|
| 367 | // ----- Operators ----------- |
|---|
| 368 | |
|---|
| 369 | //! Assignment operator |
|---|
| 370 | void operator=(const GF2mat &X); |
|---|
| 371 | |
|---|
| 372 | //! Check if equal |
|---|
| 373 | bool operator==(const GF2mat &X) const; |
|---|
| 374 | |
|---|
| 375 | // ----- Friends ------ |
|---|
| 376 | |
|---|
| 377 | //! Multiplication operator |
|---|
| 378 | friend GF2mat operator*(const GF2mat &X, const GF2mat &Y); |
|---|
| 379 | |
|---|
| 380 | //! Multiplication operator with binary vector |
|---|
| 381 | friend bvec operator*(const GF2mat &X, const bvec &y); |
|---|
| 382 | |
|---|
| 383 | /*! \brief Addition operator |
|---|
| 384 | |
|---|
| 385 | Subtraction is not implemented because it is |
|---|
| 386 | equivalent to addition. */ |
|---|
| 387 | friend GF2mat operator+(const GF2mat &X, const GF2mat &Y); |
|---|
| 388 | |
|---|
| 389 | //! Output stream operator (plain text) |
|---|
| 390 | friend std::ostream &operator<<(std::ostream &os, const GF2mat &X); |
|---|
| 391 | |
|---|
| 392 | //! Write the matrix to file |
|---|
| 393 | friend it_file &operator<<(it_file &f, const GF2mat &X); |
|---|
| 394 | |
|---|
| 395 | //! Read the matrix from file |
|---|
| 396 | friend it_ifile &operator>>(it_ifile &f, GF2mat &X); |
|---|
| 397 | |
|---|
| 398 | //!Multiplication X*Y' where X and Y are GF(2) matrices |
|---|
| 399 | friend GF2mat mult_trans(const GF2mat &X, const GF2mat &Y); |
|---|
| 400 | |
|---|
| 401 | private: |
|---|
| 402 | int nrows, ncols; // number of rows and columns of matrix |
|---|
| 403 | int nwords; // number of bytes used |
|---|
| 404 | Mat<unsigned char> data; // data structure |
|---|
| 405 | |
|---|
| 406 | // This value is used to perform division by bit shift and is equal to |
|---|
| 407 | // log2(8) |
|---|
| 408 | static const unsigned char shift_divisor = 3; |
|---|
| 409 | |
|---|
| 410 | // This value is used as a mask when computing the bit position of the |
|---|
| 411 | // division remainder |
|---|
| 412 | static const unsigned char rem_mask = (1 << shift_divisor) - 1; |
|---|
| 413 | }; |
|---|
| 414 | |
|---|
| 415 | |
|---|
| 416 | // ---------------------------------------------------------------------- |
|---|
| 417 | // GF2mat related functions |
|---|
| 418 | // ---------------------------------------------------------------------- |
|---|
| 419 | |
|---|
| 420 | /*! |
|---|
| 421 | /relatesalso GF2mat |
|---|
| 422 | /brief Write GF(2) matrix to file. |
|---|
| 423 | */ |
|---|
| 424 | it_file &operator<<(it_file &f, const GF2mat &X); |
|---|
| 425 | |
|---|
| 426 | /*! |
|---|
| 427 | /relatesalso GF2mat |
|---|
| 428 | /brief Read GF(2) matrix from file. |
|---|
| 429 | */ |
|---|
| 430 | it_ifile &operator>>(it_ifile &f, GF2mat &X); |
|---|
| 431 | |
|---|
| 432 | /*! |
|---|
| 433 | \relatesalso GF2mat |
|---|
| 434 | \brief GF(2) matrix multiplication |
|---|
| 435 | */ |
|---|
| 436 | GF2mat operator*(const GF2mat &X, const GF2mat &Y); |
|---|
| 437 | |
|---|
| 438 | /*! |
|---|
| 439 | \relatesalso GF2mat |
|---|
| 440 | \brief GF(2) matrix multiplication with "regular" binary vector |
|---|
| 441 | */ |
|---|
| 442 | bvec operator*(const GF2mat &X, const bvec &y); |
|---|
| 443 | |
|---|
| 444 | /*! |
|---|
| 445 | \relatesalso GF2mat |
|---|
| 446 | \brief GF(2) matrix addition |
|---|
| 447 | */ |
|---|
| 448 | GF2mat operator+(const GF2mat &X, const GF2mat &Y); |
|---|
| 449 | |
|---|
| 450 | /*! |
|---|
| 451 | \relatesalso GF2mat |
|---|
| 452 | \brief Output stream (plain text) operator for dense GF(2) matrices |
|---|
| 453 | */ |
|---|
| 454 | std::ostream &operator<<(std::ostream &os, const GF2mat &X); |
|---|
| 455 | |
|---|
| 456 | /*! |
|---|
| 457 | \relatesalso GF2mat |
|---|
| 458 | \brief GF(2) Identity matrix |
|---|
| 459 | */ |
|---|
| 460 | GF2mat gf2dense_eye(int m); |
|---|
| 461 | |
|---|
| 462 | /*! |
|---|
| 463 | \relatesalso GF2mat |
|---|
| 464 | \brief Multiplication X*Y' where X and Y are GF(2) matrices |
|---|
| 465 | */ |
|---|
| 466 | GF2mat mult_trans(const GF2mat &X, const GF2mat &Y); |
|---|
| 467 | |
|---|
| 468 | |
|---|
| 469 | // ---------------------------------------------------------------------- |
|---|
| 470 | // Inline implementations |
|---|
| 471 | // ---------------------------------------------------------------------- |
|---|
| 472 | |
|---|
| 473 | inline void GF2mat::addto_element(int i, int j, bin s) |
|---|
| 474 | { |
|---|
| 475 | it_assert_debug(i >= 0 && i < nrows, "GF2mat::addto_element()"); |
|---|
| 476 | it_assert_debug(j >= 0 && j < ncols, "GF2mat::addto_element()"); |
|---|
| 477 | if (s == 1) |
|---|
| 478 | data(i, (j >> shift_divisor)) ^= (1 << (j & rem_mask)); |
|---|
| 479 | } |
|---|
| 480 | |
|---|
| 481 | inline bin GF2mat::get(int i, int j) const |
|---|
| 482 | { |
|---|
| 483 | it_assert_debug(i >= 0 && i < nrows, "GF2mat::get_element()"); |
|---|
| 484 | it_assert_debug(j >= 0 && j < ncols, "GF2mat::get_element()"); |
|---|
| 485 | return (data(i, (j >> shift_divisor)) >> (j & rem_mask)) & 1; |
|---|
| 486 | } |
|---|
| 487 | |
|---|
| 488 | inline void GF2mat::set(int i, int j, bin s) |
|---|
| 489 | { |
|---|
| 490 | it_assert_debug(i >= 0 && i < nrows, "GF2mat::set_element()"); |
|---|
| 491 | it_assert_debug(j >= 0 && j < ncols, "GF2mat::set_element()"); |
|---|
| 492 | if (s == 1) // set bit to one |
|---|
| 493 | data(i, (j >> shift_divisor)) |= (1 << (j & rem_mask)); |
|---|
| 494 | else // set bit to zero |
|---|
| 495 | data(i, (j >> shift_divisor)) &= (~(1 << (j & rem_mask))); |
|---|
| 496 | } |
|---|
| 497 | |
|---|
| 498 | } // namespace itpp |
|---|
| 499 | |
|---|
| 500 | #endif // #ifndef GF2MAT_H |
|---|