mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-04 05:50:31 -05:00 
			
		
		
		
	
		
			
	
	
		
			488 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
		
		
			
		
	
	
			488 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| 
								 | 
							
								<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>
							 |