/* MOD2DENSE.H - Interface to module for handling dense mod2 matrices. */ /* Copyright (c) 1996, 2000, 2001 by Radford M. Neal * * Permission is granted for anyone to copy, use, modify, or distribute this * program and accompanying programs and documents for any purpose, provided * this copyright notice is retained and prominently displayed, along with * a note saying that the original programs are available from Radford Neal's * web page, and note is made of any changes made to the programs. The * programs and documents are distributed without any warranty, express or * implied. As the programs were written for research purposes only, they have * not been tested to the degree that would be advisable in any important * application. All use of these programs is entirely at the user's own risk. */ /* This module implements operations on matrices of mod2 elements (bits, with addition and multiplication being done modulo 2). The matrices are stored with consecutive bits of a column packed into words, and the procedures are implemented where possible using bit operations on these words. This is an appropriate representation when the matrices are dense (ie, 0s and 1s are about equally frequent). All procedures in this module display an error message on standard error and terminate the program if passed an invalid argument (indicative of a programming error), or if memory cannot be allocated. Errors from invalid contents of a file result in an error code being returned to the caller, with no message being printed by this module. */ /* PACKING OF BITS INTO WORDS. Bits are packed into 32-bit words, with the low-order bit coming first. */ typedef unsigned long mod2word; /* Data type that holds packed bits */ #define mod2_wordsize 32 /* Number of bits that fit in a mod2word. Can't be increased without changing intio module */ #define mod2_wordsize_shift 5 /* Amount to shift by to divide by wordsize */ #define mod2_wordsize_mask 0x1f /* What to and with to produce mod wordsize */ /* Extract the i'th bit of a mod2word. */ #define mod2_getbit(w,i) (((w)>>(i))&1) /* Make a word like w, but with the i'th bit set to 1 (if it wasn't already). */ #define mod2_setbit1(w,i) ((w)|(1<<(i))) /* Make a word like w, but with the i'th bit set to 0 (if it wasn't already). */ #define mod2_setbit0(w,i) ((w)&(~(1<<(i)))) /* STRUCTURE REPRESENTING A DENSE MATRIX. These structures are dynamically allocated using mod2dense_allocate (or by other procedures that call mod2dense_allocate). They should be freed with mod2dense_free when no longer required. Direct access to this structure should be avoided except in low-level routines. Use the macros and procedures defined below instead. */ typedef struct { int n_rows; /* Number of rows in the matrix */ int n_cols; /* Number of columns in the matrix */ int n_words; /* Number of words used to store a column of bits */ mod2word **col; /* Pointer to array of pointers to columns */ mod2word *bits; /* Pointer to storage block for bits in this matrix (pieces of this block are pointed to from col) */ } mod2dense; /* MACROS. */ #define mod2dense_rows(m) ((m)->n_rows) /* Get the number of rows or columns */ #define mod2dense_cols(m) ((m)->n_cols) /* in a matrix */ /* PROCEDURES. */ mod2dense *mod2dense_allocate (int, int); void mod2dense_free (mod2dense *); void mod2dense_clear (mod2dense *); void mod2dense_copy (mod2dense *, mod2dense *); void mod2dense_copyrows (mod2dense*, mod2dense *, int *); void mod2dense_copycols (mod2dense*, mod2dense *, int *); void mod2dense_print (FILE *, mod2dense *); int mod2dense_write (FILE *, mod2dense *); mod2dense *mod2dense_read (FILE *); int mod2dense_get (mod2dense *, int, int); void mod2dense_set (mod2dense *, int, int, int); int mod2dense_flip(mod2dense *, int, int); void mod2dense_transpose (mod2dense *, mod2dense *); void mod2dense_add (mod2dense *, mod2dense *, mod2dense *); void mod2dense_multiply (mod2dense *, mod2dense *, mod2dense *); int mod2dense_equal (mod2dense *, mod2dense *); int mod2dense_invert (mod2dense *, mod2dense *); int mod2dense_forcibly_invert (mod2dense *, mod2dense *, int *, int *); int mod2dense_invert_selected (mod2dense *, mod2dense *, int *, int *);