mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-26 02:20:20 -04:00 
			
		
		
		
	git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6437 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
		
			
				
	
	
		
			488 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			HTML
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			488 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			HTML
		
	
	
		
			Executable File
		
	
	
	
	
| <HTML><HEAD>
 | |
| 
 | |
| <TITLE> Dense Modulo-2 Matrix Routines </TITLE>
 | |
| 
 | |
| </HEAD><BODY>
 | |
| 
 | |
| 
 | |
| <H1> Dense Modulo-2 Matrix Routines </H1>
 | |
| 
 | |
| <P>This module implements operations on matrices in which the elements
 | |
| are all 0 or 1, with addition and multiplication being done modulo 2.
 | |
| The matrices are stored with consecutive bits of a column packed into
 | |
| 32-bit words, and the procedures are implemented where possible using
 | |
| bit operations on these words.  
 | |
| 
 | |
| <P>This is an appropriate representation when the matrices are dense
 | |
| (ie, 0s and 1s are about equally frequent).  Matrices in which most
 | |
| elements are 0s may be better handled with the <A
 | |
| HREF="mod2sparse.html">sparse modulo-2 matrix routines</A>.  Matrices
 | |
| can be converted between these two formats using the <A
 | |
| HREF="mod2convert.html">module-2 matrix conversion routines</A>.
 | |
|   
 | |
| <P>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.
 | |
| 
 | |
| 
 | |
| <H2>Representation of dense matrices</H2>
 | |
| 
 | |
| <P>This module represents a matrix by a pointer to a structure of type
 | |
| <TT>mod2dense</TT>.  This structure records the number of rows and
 | |
| columns in the matrix, and contains an array of pointers to where the
 | |
| bits making up each column are stored.  These bits are packed 32 per
 | |
| word. When possible, bits in a column are manipulated 32 bits at a
 | |
| time, which operations such as adding one column to another much
 | |
| faster than the corresponding operations on rows.  The pointer
 | |
| structure also allows the columns of a matrix to easily be rearranged,
 | |
| which may be necessary when doing matrix inversion.
 | |
| 
 | |
| 
 | |
| <P><B>Header files required</B>:
 | |
| <TT>mod2dense.h</TT>
 | |
| 
 | |
| 
 | |
| <A NAME="dimension-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Dimension Macros</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <HR>The following macros take a pointer to a mod2dense structure as their
 | |
| argument, and return the number of rows or the number of columns in
 | |
| the matrix pointed to, which will have been fixed when the matrix was
 | |
| created with <A HREF="#allocate">mod2dense_allocate</A>:
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2dense_rows(m)   /* Returns the number of rows in m */
 | |
| 
 | |
| mod2dense_cols(m)   /* Returns the number of columns in m */
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| 
 | |
| <A NAME="alloc-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Allocating and Freeing Dense Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| 
 | |
| <A NAME="allocate"><HR><B>mod2dense_allocate</B>: 
 | |
| Allocate space for a dense module-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2dense *mod2dense_allocate 
 | |
| ( int n_rows,    /* Number of rows in matrix */
 | |
|   int n_cols     /* Number of columns in matrix */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Allocates space for a matrix with the given number of rows and
 | |
| columns, and returns a pointer to it.  If there is not enough memory
 | |
| available, a message is displayed on standard error and the program is
 | |
| terminated.  The matrix should be freed with <A
 | |
| HREF="#free"><TT>mod2dense_free</TT></A> once it is no longer in use.
 | |
| 
 | |
| <P><A NAME="free"><HR><B>mod2dense_free</B>: 
 | |
| Free the space occupied by a dense module-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_free 
 | |
| ( mod2dense *m   /* Pointer to matrix to free */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Frees the space occupied by the matrix for re-use.  The pointer passed
 | |
| should no longer be used.
 | |
| 
 | |
| 
 | |
| <A NAME="copy-clear-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Copying and Clearing Dense Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="clear"><HR><B>mod2dense_clear</B>: 
 | |
| Set all elements of a matrix to zero.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_clear
 | |
| ( mod2dense *m   /* Pointer to matrix to clear */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Sets all of the elements of the matrix passed to 0.
 | |
| 
 | |
| <P><A NAME="copy"><HR><B>mod2dense_copy</B>: 
 | |
| Copy the contents of one matrix to another.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_copy
 | |
| ( mod2dense *m   /* Pointer to matrix to copy from */
 | |
|   mod2dense *r   /* Pointer to matrix to receive data */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Copies the contents of the first matrix passed, <B>m</B>, to the
 | |
| second matrix passed, <B>r</B>, which must already have been
 | |
| allocated, and must have at least as many rows and columns as the
 | |
| first.  If <B>r</B> is larger than <B>m</B>, its elements that have
 | |
| row or column indexes greater than the dimension of <B>m</B> are set
 | |
| to zeros.
 | |
| 
 | |
| 
 | |
| <P><A NAME="copyrows"><HR><B>mod2dense_copyrows</B>: 
 | |
| Copy selected rows from one matrix to another.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_copyrows
 | |
| ( mod2dense *m,   /* Pointer to matrix to copy columns from */
 | |
|   mod2dense *r,   /* Pointer to matrix in which to store data */
 | |
|   int *rows       /* Indexes of rows, numbered from 0 */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Copies selected rows of the first matrix, <B>m</B>, to the second
 | |
| matrix, <B>r</B>, which must already have been allocated, and which
 | |
| must have at least as many columns as <B>m</B>.  The indexes of the
 | |
| rows to copy are given in order as an array of length the same as
 | |
| the number of rows in <B>r</B>; duplicates are allowed.  Row
 | |
| indexes start at 0.  These rows are copied to <B>r</B>, with the
 | |
| row indexed by the first entry in <B>rows</B> going to the first
 | |
| row of <B>r</B>, and so forth.  If <B>r</B> has more columns than
 | |
| <B>m</B>, the extra entries in each row are set to zeros.
 | |
| 
 | |
| 
 | |
| <P><A NAME="copycols"><HR><B>mod2dense_copycols</B>: 
 | |
| Copy selected columns from one matrix to another.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_copycols
 | |
| ( mod2dense *m,   /* Pointer to matrix to copy columns from */
 | |
|   mod2dense *r,   /* Pointer to matrix in which to store data */
 | |
|   int *cols       /* Indexes of columns, numbered from 0 */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Copies selected columns of the first matrix, <B>m</B>, to the second
 | |
| matrix, <B>r</B>, which must already have been allocated, and which
 | |
| must have at least as many rows as <B>m</B>.  The indexes of the
 | |
| columns to copy are given in order as an array of length the same as
 | |
| the number of columns in <B>r</B>; duplicates are allowed.  Column
 | |
| indexes start at 0.  These columns are copied to <B>r</B>, with the
 | |
| column indexed by the first entry in <B>cols</B> going to the first
 | |
| column of <B>r</B>, and so forth.  If <B>r</B> has more rows than
 | |
| <B>m</B>, the extra entries in each column are set to zeros.
 | |
| 
 | |
| 
 | |
| <A NAME="input-output-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Input and Output of Dense Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="print"><HR><B>mod2dense_print</B>: 
 | |
| Print a dense modulo-2 matrix in human-readable form.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_print
 | |
| ( FILE *f,       /* File to print to */
 | |
|   mod2dense *m   /* Pointer to matrix to print */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| The matrix is printed on standard output as "0" and "1" characters,
 | |
| each preceded by a space, with one line of "0"s and "1"s for each row
 | |
| of the matrix.
 | |
| 
 | |
| <P><A NAME="write"><HR><B>mod2dense_write</B>: 
 | |
| Write a dense modulo-2 matrix to a file in machine-readable format.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2dense_write
 | |
| ( FILE *f,       /* File to write data to */
 | |
|   mod2dense *m   /* Pointer to matrix write out */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Writes a machine-readable representation the dense matrix <B>m</B> to
 | |
| the file <B>f</B>.  The file should have been opened in binary mode
 | |
| (with a "b" in the mode passed to fopen).  The contents written will
 | |
| not be text, and will not be human-readable.  Other binary data may
 | |
| precede or follow the data for the matrix written.  
 | |
| 
 | |
| <P>The data written to the file consists of the number of rows and the
 | |
| number of columns, followed by the bits in each column, packed into
 | |
| 32-bit words.  The data should be readable by <A
 | |
| HREF="#read"><TT>mod2dense_read</TT></A> even on a machine with a
 | |
| different byte-ordering.
 | |
| 
 | |
| <P>The value returned by <TT>mod2dense_write</TT> is one if the
 | |
| operation was successful, zero if an error of some sort occurred.
 | |
| 
 | |
| <P><A NAME="read"><HR><B>mod2dense_read</B>: 
 | |
| Read a dense modulo-2 matrix from a file.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2dense *mod2dense_read
 | |
| ( FILE *f,       /* File to read data from */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Reads a dense modulo-2 matrix from the file <B>f</B>.  This file
 | |
| should have been opened in binary mode (with a "b" in the mode passed
 | |
| to fopen).  The contents of the file at the point when
 | |
| <TT>mod2dense_read</TT> is called should have been written by <A
 | |
| HREF="#write"><TT>mod2dense_write</TT></A>.  Other binary data may
 | |
| precede or follow this data.
 | |
| 
 | |
| <P>The value returned is a pointer to the matrix read, for which space
 | |
| will have been allocated by <TT>mod2dense_read</TT>, or zero if an
 | |
| error occurred (either an error reading the file, or data not in the
 | |
| right format).
 | |
| 
 | |
| 
 | |
| <A NAME="elementary-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Elementary Operations on Dense Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="get"><HR><B>mod2dense_get</B>: 
 | |
| Get an element of a dense modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2dense_get  
 | |
| ( mod2dense *m,   /* Pointer to matrix to get element from */
 | |
|   int row,        /* Row of element (indexed from zero) */
 | |
|   int col         /* Column of element (indexed from zero) */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Returns the value (0 or 1) of the element in the given row and column
 | |
| of the matrix <B>m</B>.
 | |
| 
 | |
| <P><A NAME="set"><HR><B>mod2dense_set</B>: 
 | |
| Set an element of a dense modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_set
 | |
| ( mod2dense *m,   /* Pointer to matrix to get element from */
 | |
|   int row,        /* Row of element (indexed from zero) */
 | |
|   int col,        /* Column of element (indexed from zero) */
 | |
|   int value       /* New value of element (0 or 1) */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Set the element in the given row and column of the matrix <B>m</B> to
 | |
| the specified value.
 | |
| 
 | |
| <P><A NAME="flip"><HR><B>mod2dense_flip</B>: 
 | |
| Flip an element of a dense modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2dense_flip
 | |
| ( mod2dense *m,   /* Pointer to matrix to get element from */
 | |
|   int row,        /* Row of element (indexed from zero) */
 | |
|   int col         /* Column of element (indexed from zero) */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Flips the value of the element in the given row and column of the 
 | |
| matrix <B>m</B>, changing it to 0 if it was 1, and to 1 if it was 0.
 | |
| Returns the new value of this element.
 | |
| 
 | |
| 
 | |
| <A NAME="arith-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Dense Modulo-2 Matrix Arithmetic and Comparison</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="transpose"><HR><B>mod2dense_transpose</B>: 
 | |
| Compute the transpose of a dense modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_transpose
 | |
| ( mod2dense *m,   /* Matrix to compute transpose of */
 | |
|   mod2dense *r    /* Result of transpose operation */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Stores the transpose of its first argument, <B>m</B>, in the matrix
 | |
| pointed to by its second argument, <B>r</B>, which must already have
 | |
| been allocated, and which must have as many rows as <B>m</B> has
 | |
| columns, and as many columns as <B>m</B> has rows.  The two matrices
 | |
| <B>m</B> and <B>r</B> must not be the same (ie, the two pointers
 | |
| passed must be different).
 | |
| 
 | |
| <P><A NAME="add"><HR><B>mod2dense_add</B>: 
 | |
| Add two dense modulo-2 matrices.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_add
 | |
| ( mod2dense *m1,  /* Left operand of add */
 | |
|   mod2dense *m2,  /* Right operand of add */
 | |
|   mod2dense *r    /* Place to store result of add */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Adds matrices <B>m1</B> and <B>m2</B>, storing the result in the
 | |
| matrix pointed to by <B>r</B>.  All three matrices must have the same
 | |
| numbers of rows and columns.  It is permissible for <B>r</B> to be the
 | |
| same as <B>m1</B> and/or <B>m2</B>.  Neither of the first two matrices is
 | |
| changed by this procedure (unless they are the same as <B>r</B>).
 | |
| 
 | |
| 
 | |
| <P><A NAME="multiply"><HR><B>mod2dense_multiply</B>: 
 | |
| Multiply two dense modulo-2 matrices.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2dense_multiply 
 | |
| ( mod2dense *m1,  /* Left operand of multiply */
 | |
|   mod2dense *m2,  /* Right operand of multiply */
 | |
|   mod2dense *r    /* Place to store result of multiply */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Does a matrix multiplication of <B>m1</B> by <B>m2</B>, and stores the
 | |
| result in the matrix pointed to by <B>r</B>.  The matrices must have
 | |
| compatible numbers of rows and columns.  Neither of the first two
 | |
| matrices is changed by this procedure.  The result matrix, <B>r</B>,
 | |
| must not be the same as either <B>m1</B> or <B>m2</B>.
 | |
| 
 | |
| <P>The algorithm used runs faster if <B>m2</B> contains mostly 0s, but
 | |
| it is also appropriate for matrices with many 1s.
 | |
| 
 | |
| <P><A NAME="equal"><HR><B>mod2dense_equal</B>: 
 | |
| Check whether two dense modulo-2 matrices are equal.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2dense_equal
 | |
| ( mod2dense *m1, /* Pointers to the two matrices */
 | |
|   mod2dense *m2  /*   to compare                 */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Returns one if every element of <B>m1</B> is equal to the
 | |
| corresponding element of <B>m2</B>, and otherwise returns zero.  The
 | |
| two matrices must have the same number of rows and the same number of
 | |
| columns.
 | |
| 
 | |
| <A NAME="invert-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Dense Modulo-2 Matrix Inversion</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="invert"><HR><B>mod2dense_invert</B>: 
 | |
| Invert a dense modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2dense_invert
 | |
| ( mod2dense *m,   /* Matrix to find inverse of (destroyed) */
 | |
|   mod2dense *r    /* Place to store the inverse */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| <P>Inverts the first matrix passed, <B>m</B>, and stores its inverse in
 | |
| the second matrix, <B>r</B>.  The contents of <B>m</B> are destroyed
 | |
| by this operation, though it remains a valid matrix for storing into
 | |
| later.  The matrix <B>m</B> must have the same number of rows as
 | |
| columns.  The matrix <B>r</B> must already have been allocated, and
 | |
| must have the same number of rows and columns as <B>m</B>.  The
 | |
| two matrices passed must not be the same.
 | |
| 
 | |
| <P>The value returned is one if the inversion was successful and zero
 | |
| if the matrix turned out to be singular (in which case the contents of
 | |
| both the original matrix and the result matrix will be garbage).
 | |
| 
 | |
| <P>The algorithm used is based on inverting M by transforming the equation
 | |
| MI = M to the equation MR = I using column operations, at which point R 
 | |
| is the inverse of M.  The representation of matrices used allows easy
 | |
| swapping of columns as needed by fiddling pointers.
 | |
| 
 | |
| <P><A NAME="forcibly_invert"><HR><B>mod2dense_forcibly_invert</B>: 
 | |
| Forcibly invert a matrix by changing bits if necessary.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2dense_forcibly_invert
 | |
| ( mod2dense *m,   /* Matrix to find inverse of (destroyed) */
 | |
|   mod2dense *r,   /* Place to store the inverse */
 | |
|   int *a_row,     /* Place to store row indexes of altered elements */
 | |
|   int *a_col      /* Place to store column indexes of altered elements */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| <P>Inverts the first matrix passed, <B>m</B>, and stores its inverse
 | |
| in the second matrix, <B>r</B>, proceeding with the inversion even if
 | |
| <B>m</B> is singular, by changing some elements as necessary.  The
 | |
| contents of <B>m</B> are destroyed by this operation, though it
 | |
| remains a valid matrix for storing into later.  The matrix <B>m</B>
 | |
| must have the same number of rows as columns.  The matrix <B>r</B>
 | |
| must already have been allocated, and must have the same number of
 | |
| rows and columns as <B>m</B>.  The two matrices passed must not be the
 | |
| same.
 | |
| 
 | |
| <P>The value returned is the number of elements of <B>m</B> that had
 | |
| to be changed to make inversion possible (zero, if the original matrix
 | |
| was non-singular).  The row and column indexes of the elements of the
 | |
| original matrix that were changed are stored in the arrays passed as
 | |
| the last two elements.  These arrays must have as many elements as the
 | |
| dimension of the matrix.  (This is so even if it is known that fewer
 | |
| elements than this will be changed, as these arrays are also used as
 | |
| temporary storage by this routine.)
 | |
| 
 | |
| <P>See <A HREF="#invert"><TT>mod2dense_invert</TT></A> for the algorithm used.
 | |
| 
 | |
| <P><A NAME="invert_selected"><HR><B>mod2dense_invert_selected</B>: 
 | |
| Invert a matrix with columns selected from a bigger matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2dense_invert_selected 
 | |
| ( mod2dense *m,   /* Matrix from which a submatrix is inverted (destroyed) */
 | |
|   mod2dense *r,   /* Place to store the inverse */
 | |
|   int *rows,      /* Place to store indexes of rows used and not used */
 | |
|   int *cols       /* Place to store indexes of columns used and not used */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| <P>Inverts a matrix obtained by selecting certain columns from the
 | |
| first matrix passed, <B>m</B>, which must have at least as many
 | |
| columns as rows.  The second matrix passed, <B>r</B>, must already
 | |
| exist, and must have the same number of rows and columns as <B>m</B>.
 | |
| The result of inverting the sub-matrix of <B>m</B> is stored in the
 | |
| corresponding columns of <B>r</B>, with the other columns being set to
 | |
| garbage (or zero, see below).  Normally, one would extract just the
 | |
| relevant columns afterwards using <A
 | |
| HREF="#copycols"><TT>mod2dense_copycols</TT></A>.)  The contents of
 | |
| <B>m</B> are destroyed (though it remains a valid matrix for storing
 | |
| into later.  The two matrices passed must not be the same.
 | |
| 
 | |
| <P>The indexes of the columns selected are stored, in order, in the last
 | |
| argument, <B>cols</B>, followed by the columns not selected (in
 | |
| arbitrary order).  The argument <B>rows</B> is set to the indexes of
 | |
| the rows used, which will be simply the indexes from zero up if the
 | |
| matrix is invertible, and will otherwise give an ordering that allows
 | |
| the inversion to proceed as far as possible.
 | |
| 
 | |
| <P>The value returned is zero if an invertible matrix was found, and
 | |
| is otherwise the number of columns/rows that are redundant (ie, the
 | |
| amount by which matrix falls short of being of full rank).  If
 | |
| inversion fails, partial results are stored in the columns and rows of
 | |
| <B>r</B> identified by the initial portions of <B>cols</B> and
 | |
| <B>rows</B>, such that if these rows and columns were extracted in
 | |
| their new order, they would constitute the inverse of the
 | |
| corresponding re-ordered submatrix of <B>m</B>.  The remaining portion
 | |
| of <B>cols</B> up to the number of rows in <B>m</B> will contain
 | |
| indexes of columns of <B>r</B> that are selected arbitrarily; these
 | |
| columns will, however, be set to contain all zeros.
 | |
| 
 | |
| <P>Note that when the first matrix is square, and non-singular, the
 | |
| result is NOT in general the same as that obtained by calling <A
 | |
| HREF="#invert"></TT>mod2dense_invert</TT></A>, since that procedure
 | |
| orders the columns of the inverse so that it applies to the original
 | |
| ordering of the columns of the first matrix.
 | |
| 
 | |
| <P>See <A HREF="#invert"><TT>mod2dense_invert</TT></A> for the algorithm used.
 | |
| 
 | |
| <HR>
 | |
| 
 | |
| <A HREF="index.html">Back to index for LDPC software</A>
 | |
| 
 | |
| </BODY></HTML>
 |