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
		
			
				
	
	
		
			720 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			HTML
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			720 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			HTML
		
	
	
		
			Executable File
		
	
	
	
	
| <HTML><HEAD>
 | |
| 
 | |
| <TITLE> Sparse Modulo-2 Matrix Routines </TITLE>
 | |
| 
 | |
| </HEAD><BODY>
 | |
| 
 | |
| 
 | |
| <H1> Sparse 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 represented by doubly-linked lists of entries
 | |
| representing the elements in each row and column that are 1s, with
 | |
| other elements being assumed to be zero.  
 | |
| 
 | |
| <P>This is an appropriate representation when the matrices are sparse
 | |
| (ie, 0s are much more frequent that 1s).  Matrices in which 0s and 1s
 | |
| are about equally likely may be better handled with the <A
 | |
| HREF="mod2dense.html">dense 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. 
 | |
| 
 | |
| 
 | |
| <A NAME="rep"><H2>Representation of sparse matrices</H2></A>
 | |
| 
 | |
| <P>This module represents a non-zero element of a matrix (which must have
 | |
| the value 1, since these are modulo-2 matrices) by a node of type
 | |
| <TT>mod2entry</TT>, which contains the row and column of the element,
 | |
| pointers to the next non-zero elements above and below in its column
 | |
| and to the left and the right in its row, and two double-precision
 | |
| floating-point numbers called <B>pr</B> and <B>lr</B>, which are
 | |
| of no significance to this module, but which are used by the routines
 | |
| for <A HREF="decoding.html#prprp">decoding LDPC codes by probability
 | |
| propagation</A>.
 | |
| 
 | |
| <P>The <TT>mod2sparse</TT> type represents a matrix.  It records the
 | |
| number of rows and columns in the matrix, and contains arrays of
 | |
| pointers to the <TT>mod2entry</TT> structures for the first non-zero
 | |
| element in each row and the first non-zero element in each column.
 | |
| 
 | |
| <P>Matrices must be created by the <A
 | |
| HREF="#allocate"><TT>mod2sparse_allocate</TT></A> procedure, which
 | |
| returns a pointer to a <TT>mod2sparse</TT> structure.  When a matrix
 | |
| is no longer needed, the space it occupies can be freed with <A
 | |
| HREF="#free"><TT>mod2sparse_free</TT></A>.  Elements within a matrix,
 | |
| represented by <TT>mod2entry</TT> nodes, are allocated as needed, and
 | |
| if deleted, they will be reused for new elements within the same
 | |
| matrix.  The space they occupy is not reusable for other matrices or
 | |
| other purposes until the entire matrix is either freed, with <A
 | |
| HREF="#free"><TT>mod2sparse_free</TT></A>, or cleared to all zeros,
 | |
| with <A HREF="#clear"><TT>mod2sparse_clear</TT></A>, or used as
 | |
| the result matrix for copying or arithmetic operations.
 | |
| 
 | |
| 
 | |
| <P><B>Header files required</B>:
 | |
| <TT>mod2sparse.h</TT>
 | |
| 
 | |
| 
 | |
| <A NAME="dimension-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Dimension Macros</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <HR>The following macros take a pointer to a mod2sparse 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">mod2sparse_allocate</A>:
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2sparse_rows(m)   /* Returns the number of rows in m */
 | |
| 
 | |
| mod2sparse_cols(m)   /* Returns the number of columns in m */
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| 
 | |
| <A NAME="traversal-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Traversal Macros</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <HR>The following macros are used to move around a sparse matrix by
 | |
| following the pointers from one non-zero element to the next or
 | |
| previous non-zero element in the same row or column.  If such a
 | |
| movement takes one beyond the last or before first entry in a row or
 | |
| column, or if one tries to find the first or last non-zero entry in a
 | |
| row or column that has no non-zero entries, the entry returned will be
 | |
| a special one that can be identified using the
 | |
| <TT>mod2sparse_at_end</TT> macro.  If one is already at this special
 | |
| entry, moving further wraps one around to the first or last entry.
 | |
| 
 | |
| <P>The macros for finding the first or last entry in a row or column
 | |
| take as their arguments a pointer to the matrix (<TT>mod2sparse
 | |
| *</TT>) and a row or column index, starting at zero.  The other macros
 | |
| take as their arguments a pointer to an entry (<TT>mod2entry *</TT>)
 | |
| within some matrix.
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2sparse_first_in_row(m,i) /* Returns the first entry in row i of m */
 | |
| mod2sparse_first_in_col(m,j) /* Returns the first entry in column j of m */
 | |
| 
 | |
| mod2sparse_last_in_row(m,i)  /* Returns the last entry in row i of m */
 | |
| mod2sparse_last_in_col(m,j)  /* Returns the last entry in column j of m */
 | |
| 
 | |
| mod2sparse_next_in_row(e)    /* Returns the entry after e in its row */
 | |
| mod2sparse_next_in_col(e)    /* Returns the entry after e in its column */
 | |
| 
 | |
| mod2sparse_prev_in_row(e)    /* Returns the entry before e in its row */
 | |
| mod2sparse_prev_in_col(e)    /* Returns the entry before e in its col */
 | |
| 
 | |
| mod2sparse_row(e)            /* Returns the row index of entry e */
 | |
| mod2sparse_col(e)            /* Returns the column index of entry e */
 | |
| 
 | |
| mod2sparse_at_end(e)         /* Returns 1 if e is a special entry obtained 
 | |
|                                 by moving past the end, returns 0 otherwise */
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| 
 | |
| <A NAME="alloc-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Allocating and Freeing Sparse Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| 
 | |
| <A NAME="allocate"><HR><B>mod2sparse_allocate</B>: 
 | |
| Allocate space for a sparse module-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2sparse *mod2sparse_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.  The matrix will initially
 | |
| be all zero.  
 | |
| 
 | |
| <P>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>mod2sparse_free</TT></A> once it is no
 | |
| longer in use.
 | |
| 
 | |
| <P><A NAME="free"><HR><B>mod2sparse_free</B>: 
 | |
| Free the space occupied by a sparse module-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_free 
 | |
| ( mod2sparse *m   /* Pointer to matrix to free */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Frees the space occupied by the matrix for re-use.  The pointer passed
 | |
| should not be used afterward.  Note that space for the individual matrix
 | |
| elements (but not the matrix as a whole) is also freed when <A
 | |
| HREF="#clear"><TT>mod2sparse_clear</TT></A> is called, or the matrix
 | |
| is used as the destination for other operations.
 | |
| 
 | |
| 
 | |
| <A NAME="copy-clear-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Copying and Clearing Sparse Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="clear"><HR><B>mod2sparse_clear</B>: 
 | |
| Set all elements of a matrix to zero.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_clear
 | |
| ( mod2sparse *m   /* Pointer to matrix to clear */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Sets all of the elements of the matrix passed to 0.  The space occupied
 | |
| by the previous non-zero elements is freed for use in other matrices, or
 | |
| other purposes.  The matrix itself is not freed, however.  To do that,
 | |
| use <A HREF="#free"><TT>mod2sparse_free</TT></A>.
 | |
| 
 | |
| 
 | |
| <P><A NAME="copy"><HR><B>mod2sparse_copy</B>: 
 | |
| Copy the contents of one matrix to another.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_copy
 | |
| ( mod2sparse *m   /* Pointer to matrix to copy from */
 | |
|   mod2sparse *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>The space occupied by the previous non-zero entries of <B>r</B> is
 | |
| freed for general use (which may include being reused immediately for
 | |
| the copies of the entries in <B>m</B>).
 | |
| 
 | |
| 
 | |
| <P><A NAME="copyrows"><HR><B>mod2sparse_copyrows</B>: 
 | |
| Copy selected rows from one matrix to another.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_copyrows
 | |
| ( mod2sparse *m,  /* Pointer to matrix to copy rows from */
 | |
|   mod2sparse *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>The space occupied by the previous non-zero entries of <B>r</B> is
 | |
| freed for general use (which may include being reused immediately for
 | |
| the copies of the entries in <B>m</B>).
 | |
| 
 | |
| 
 | |
| <P><A NAME="copycols"><HR><B>mod2sparse_copycols</B>: 
 | |
| Copy selected columns from one matrix to another.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_copycols
 | |
| ( mod2sparse *m,  /* Pointer to matrix to copy columns from */
 | |
|   mod2sparse *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.
 | |
| 
 | |
| <P>The space occupied by the previous non-zero entries of <B>r</B> is
 | |
| freed for general use (which may include being reused immediately for
 | |
| the copies of the entries in <B>m</B>).
 | |
| 
 | |
| 
 | |
| <A NAME="input-output-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Input and Output of Sparse Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="print"><HR><B>mod2sparse_print</B>: 
 | |
| Print a sparse modulo-2 matrix in human-readable form.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_print
 | |
| ( FILE *f,        /* File to print to */
 | |
|   mod2sparse *m   /* Pointer to matrix to print */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| The matrix is printed on standard output with one line of output per row,
 | |
| of the form
 | |
| <BLOCKQUOTE><PRE>
 | |
| <I>row</I>: <I>col col col ...</I>
 | |
| </PRE></BLOCKQUOTE>
 | |
| where <I>row</I> is the index of the row, and the <I>col</I> entries are 
 | |
| the indexes of columns that are non-zero in that row.  Row and column
 | |
| indexes start at zero.  Rows with no entries are printed with no column
 | |
| indexes after the colon.  The number of columns is not indicated in the output. 
 | |
| 
 | |
| <P><A NAME="write"><HR><B>mod2sparse_write</B>: 
 | |
| Write a sparse modulo-2 matrix to a file in machine-readable format.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2sparse_write
 | |
| ( FILE *f,        /* File to write data to */
 | |
|   mod2sparse *m   /* Pointer to matrix write out */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Writes a machine-readable representation the sparse 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 starts with the number of rows and the
 | |
| number of columns.  Following this are negative integers giving row
 | |
| indexes (starting at 1), which apply until the next row index, and
 | |
| positive integers giving column indexes (starting at 1) for a non-zero
 | |
| entry in the matrix.  The data should be readable by <A
 | |
| HREF="#read"><TT>mod2sparse_read</TT></A> even on a machine with a
 | |
| different byte-ordering.
 | |
| 
 | |
| <P>The value returned by <TT>mod2sparse_write</TT> is one if the
 | |
| operation was successful, zero if an error of some sort occurred.
 | |
| 
 | |
| <P><A NAME="read"><HR><B>mod2sparse_read</B>: 
 | |
| Read a sparse modulo-2 matrix from a file.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2sparse *mod2sparse_read
 | |
| ( FILE *f,        /* File to read data from */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Reads a sparse 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>mod2sparse_read</TT> is called should have been written by <A
 | |
| HREF="#write"><TT>mod2sparse_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>mod2sparse_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 Sparse Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="find"><HR><B>mod2sparse_find</B>: 
 | |
| Look for an entry at a given row and column.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2entry *mod2sparse_find
 | |
| ( mod2sparse *m,  /* Matrix in which to look for entry */
 | |
|   int row,        /* Row index (from 0) */
 | |
|   int col         /* Column index (from 0) */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Looks for an entry at the given row and column in the matrix <B>m</B>,
 | |
| representing a non-zero element (ie, one with value 1).  Returns a
 | |
| pointer to this entry if it exists, or zero (a null pointer) if it 
 | |
| does not exist (ie, if that element of the matrix has value 0).
 | |
| 
 | |
| <P>The search strategy is to first look at the end of the row and the
 | |
| end of the column.  The entry might be found at one of these two
 | |
| places, or it might be determinable from these end entries that no
 | |
| entry exists at the given row and column.  Otherwise, searches are
 | |
| done from the start of the row and the start of the column, in
 | |
| parallel, until an entry with the given row and column are found, or
 | |
| until it can be determined that such an entry does not exist.
 | |
| Searching in parallel ensures that the operation will be fast if
 | |
| either the row is sparse or the column is sparse.
 | |
| 
 | |
| <P><A NAME="insert"><HR><B>mod2sparse_insert</B>: 
 | |
| Insert an entry at a given row and column.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| mod2entry *mod2sparse_insert
 | |
| ( mod2sparse *m,  /* Matrix in which to insert an entry */
 | |
|   int row,        /* Row index (from 0) */
 | |
|   int col         /* Column index (from 0) */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Adds a new entry (representing an element with value 1) at the given
 | |
| row and column position in the matrix <B>m</B>.  If such an entry
 | |
| already exists, nothing is done (this is not considered to be an
 | |
| error).  The new (or existing) entry is returned as the value of
 | |
| this procedure.
 | |
| 
 | |
| <P>The search strategy is to first look at the end of the row for an
 | |
| existing entry or for the place where the new entry belongs.  If this
 | |
| fails, the row is searched from the beginning.  If an existing entry
 | |
| is found, it is returned.  Otherwise, a new entry is created, it is
 | |
| inserted in its correct place in the row, and it is inserted in its
 | |
| correct place in its column, once again by first looking at the end,
 | |
| and then if required searching from the beginning.  
 | |
| 
 | |
| <P>The effect of this strategy is that a sparse matrix can be efficiently
 | |
| created by either adding entries in increasing order by row and column or in
 | |
| decreasing order by row and column.
 | |
| 
 | |
| <P><A NAME="delete"><HR><B>mod2sparse_delete</B>: 
 | |
| Delete an entry from a sparse modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_delete
 | |
| ( mod2sparse *m,  /* Matrix in which to delete an entry */
 | |
|   mod2entry *e    /* Entry to delete - MUST be in m */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Deletes the entry <B>e</B> from the sparse matrix <B>m</B>, which
 | |
| effectively sets to zero the element of the matrix that this entry
 | |
| corresponded to.  The entry is freed for future use in the same
 | |
| matrix, but not (immediately, at least) for use in other matrices, or
 | |
| generally.  The pointer to this entry should not be used again once
 | |
| it is deleted.
 | |
| 
 | |
| <P>The time required for this operation does not depend on how many
 | |
| entries are currently in the matrix.
 | |
| 
 | |
| <P><B>Warning:</B> It is an error if <B>e</B> is not an entry of
 | |
| <B>m</B>.  This error is not currently diagnosed, but doing this may
 | |
| cause serious problems, as it may lead later to entries for <B>m</B>
 | |
| being erroneously freed when the matrix to which <B>e</B> properly
 | |
| belongs is freed.
 | |
| 
 | |
| <A NAME="arith-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Sparse Modulo-2 Matrix Arithmetic and Comparison</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="transpose"><HR><B>mod2sparse_transpose</B>: 
 | |
| Compute the transpose of a sparse modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_transpose
 | |
| ( mod2sparse *m,  /* Matrix to compute transpose of */
 | |
|   mod2sparse *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>The space occupied by the previous non-zero entries of <B>r</B> is
 | |
| freed for general use.
 | |
| 
 | |
| <P><A NAME="add"><HR><B>mod2sparse_add</B>: 
 | |
| Add two sparse modulo-2 matrices.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_add
 | |
| ( mod2sparse *m1, /* Left operand of add */
 | |
|   mod2sparse *m2, /* Right operand of add */
 | |
|   mod2sparse *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>The space occupied by the previous non-zero entries of <B>r</B> is
 | |
| freed for general use.
 | |
| 
 | |
| 
 | |
| <P><A NAME="multiply"><HR><B>mod2sparse_multiply</B>: 
 | |
| Multiply two sparse modulo-2 matrices.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_multiply 
 | |
| ( mod2sparse *m1, /* Left operand of multiply */
 | |
|   mod2sparse *m2, /* Right operand of multiply */
 | |
|   mod2sparse *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 space occupied by the previous non-zero entries of <B>r</B> is
 | |
| freed for general use.
 | |
| 
 | |
| <P><A NAME="mulvec"><HR><B>mod2sparse_mulvec</B>: 
 | |
| Multiply a vector by a sparse modulo-2 matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_mulvec
 | |
| ( mod2sparse *m,  /* Pointer to matrix to multiply by, M rows, N columns */
 | |
|   char *u,        /* Pointer to unpacked vector to multiply, N long */
 | |
|   char *v         /* Pointer to unpacked result vector, M long */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Multiplies the vector <B>u</B> on the left by the sparse modulo-2
 | |
| matrix <B>m</B>, storing the result in <B>v</B>.  Both <B>u</B> and
 | |
| <B>v</B> are modulo-2 vectors, but are stored unpacked, with one bit
 | |
| per char.  Any non-zero value in <B>u</B> is equivalent to '1'.  
 | |
| The vectors <B>u</B> and <B>v</B> must not overlap.
 | |
| 
 | |
| <P><A NAME="equal"><HR><B>mod2sparse_equal</B>: 
 | |
| Check whether two sparse modulo-2 matrices are equal.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2sparse_equal
 | |
| ( mod2sparse *m1, /* Pointers to the two matrices */
 | |
|   mod2sparse *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="row-col-ops-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>Row/Column Operations on Sparse Modulo-2 Matrices</BIG>
 | |
| </CENTER></A>
 | |
| 
 | |
| <A NAME="count_row"><HR><B>mod2sparse_count_row</B>: 
 | |
| Count the number of 1s in a row of a sparse matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2sparse_count_row
 | |
| ( mod2sparse *m,  /* Pointer to matrix */
 | |
|   int row         /* Index of row to count (from 0) */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Returns the number of 1s in the given row of the matrix, by counting
 | |
| the number of entries in that row.  
 | |
| 
 | |
| <P><A NAME="count_col"><HR><B>mod2sparse_count_col</B>: 
 | |
| Count the number of 1s in a column of a sparse matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2sparse_count_col
 | |
| ( mod2sparse *m,  /* Pointer to matrix */
 | |
|   int col         /* Index of column to count (from 0) */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Returns the number of 1s in the given column of the matrix, by counting
 | |
| the number of entries in that column.  
 | |
| 
 | |
| <P><A NAME="add_row"><HR><B>mod2sparse_add_row</B>: 
 | |
| Add a row to a row of a sparse matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_add_row
 | |
| ( mod2sparse *m1, /* Matrix containing row to add to */
 | |
|   int row1,       /* Index in this matrix of row to add to */
 | |
|   mod2sparse *m2, /* Matrix containing row to add from */
 | |
|   int row2        /* Index in this matrix of row to add from */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Modifies the row with index <B>row1</B> in the matrix <B>m1</B> by
 | |
| adding to that row the row with index <B>row2</B> in the matrix
 | |
| <B>m2</B>.  The matrix <B>m1</B> must have at least as many columns as
 | |
| <B>m2</B>.  This operation is performed by inserting entries into the
 | |
| row of <B>m1</B> at positions where they exist in the row of <B>m2</B>
 | |
| but not in the row of <B>m1</B>, and deleting entries in the row of
 | |
| <B>m1</B> that exist in the same position in the row of <B>m2</B>.
 | |
| The matrix <B>m2</B> is not modified.
 | |
| 
 | |
| <P><A NAME="add_col"><HR><B>mod2sparse_add_col</B>: 
 | |
| Add a column to a column of a sparse matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| void mod2sparse_add_col
 | |
| ( mod2sparse *m1, /* Matrix containing column to add to */
 | |
|   int col1,       /* Index in this matrix of col to add to */
 | |
|   mod2sparse *m2, /* Matrix containing column to add from */
 | |
|   int col2        /* Index in this matrix of column to add from */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| Modifies the column with index <B>col1</B> in the matrix <B>m1</B> by
 | |
| adding to that column the column with index <B>col2</B> in the matrix
 | |
| <B>m2</B>.  The matrix <B>m1</B> must have at least as many rows as
 | |
| <B>m2</B>.  This operation is performed by inserting entries into the
 | |
| column of <B>m1</B> at positions where they exist in the column of
 | |
| <B>m2</B> but not in the column of <B>m1</B>, and deleting entries in
 | |
| the column of <B>m1</B> that exist in the same position in the column
 | |
| of <B>m2</B>.  The matrix <B>m2</B> is not modified.
 | |
| 
 | |
| 
 | |
| <A NAME="lu-decomp-sec">
 | |
| <P><HR>
 | |
| <CENTER><BIG>LU Decomposition of Sparse Modulo-2 Matrices</BIG></CENTER>
 | |
| </A>
 | |
| 
 | |
| <A NAME="decomp"><HR><B>mod2sparse_decomp</B>: 
 | |
| Find an LU decomposition of a sparse modulo-2 (sub-)matrix.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2sparse_decomp
 | |
| ( mod2sparse *A,      /* Matrix to find LU decomposition within, M by N */
 | |
|   int K,              /* Size of sub-matrix to find LU decomposition of */
 | |
|   mod2sparse *L,      /* Matrix in which L is stored, M by K */
 | |
|   mod2sparse *U,      /* Matrix in which U is stored, K by N */
 | |
|   int *rows,          /* Array where row indexes are stored, M long */
 | |
|   int *cols,          /* Array where column indexes are stored, N long */
 | |
|   mod2sparse_strategy strategy, /* Strategy to follow in picking rows/columns */
 | |
|   int abandon_number, /* Number of columns to abandon at some point */
 | |
|   int abandon_when    /* When to abandon these columns */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| <P>Takes as input a matrix, <B>A</B>, having <I>M</I> rows and
 | |
| <I>N</I> columns, and an integer <I>K</I>.  Finds an LU decomposition
 | |
| of a <I>K</I> by <I>K</I> sub-matrix of <B>A</B>.  The decomposition
 | |
| is stored in the matrix <B>L</B>, with <I>M</I> rows and <I>K</I>
 | |
| columns, and the matrix <B>U</B>, with <I>K</I> rows and <I>N</I>
 | |
| columns.  The product of <B>L</B> and <B>U</B> will be equal to the
 | |
| <I>K</I> by <I>K</I> submatrix of <B>A</B> obtained by taking only
 | |
| rows and columns that are given in the first <I>K</I> elements of the
 | |
| <B>rows</B> and <B>cols</B> arrays, which are set by this procedure,
 | |
| with this sub-matrix distributed over the original <I>M</I> rows and
 | |
| <I>N</I> columns.  Furthermore, the ordering of the row and column
 | |
| indexes in these arrays will be set so that if the rows of <B>L</B>
 | |
| and the columns of <B>U</B> were rearranged in this order, <B>L</B>
 | |
| would be lower triangular, with zeros in rows past row <I>K</I>, and
 | |
| <B>U</B> would be upper triangular, with zeros in columns past column
 | |
| <I>K</I>.  The <B>rows</B> array is <I>M</I> long, and the <B>cols</B>
 | |
| array is <I>N</I> long.  The elements in both arrays after the first
 | |
| <I>K</I> contain the indexes of the rows and columns not selected to
 | |
| be part of the sub-matrix of <B>A</B>, in arbitrary order.
 | |
| 
 | |
| <P>The rows and columns of <B>A</B> are selected in order to try to
 | |
| make the LU decomposition as sparse as possible, using the strategy
 | |
| identified by the <B>strategy</B>, <B>abandon_number</B>, and
 | |
| <B>abandon_when</B> parameters.  The possible strategies are
 | |
| <TT>Mod2sparse_first</TT>, <TT>Mod2sparse_mincol</TT>, and
 | |
| <TT>Mod2sparse_minprod</TT>.  If <B>abandon_number</B> is greater than
 | |
| zero, it is possible that the matrix will appear to have linearly
 | |
| dependent rows when it actually does not.  See the <A
 | |
| HREF="sparse-LU.html">discussion of sparse LU decomposition
 | |
| methods</A> for details about these strategies.
 | |
| 
 | |
| <P>If <B>A</B> is not of rank <I>K</I> or more, <B>L</B> will contain
 | |
| some number less than <I>K</I> of non-zero columns, and <B>U</B> will
 | |
| contain an equal number of non-zero rows.  The entries in the
 | |
| <B>rows</B> and <B>cols</B> arrays for the extra zero rows or columns
 | |
| will be arbitrary (but valid).  The number of extra zero columns is
 | |
| returned as the value of this procedure (hence a return value of zero
 | |
| indicates that a <I>K</I> by <I>K</I> sub-matrix of full rank was
 | |
| found).
 | |
| 
 | |
| <P>The matrix <B>A</B> is not altered.  The previous contents of 
 | |
| <B>L</B> and <B>U</B> are cleared. 
 | |
| 
 | |
| <P><A NAME="forward_sub"><HR><B>mod2sparse_forward_sub</B>: 
 | |
| Solve a lower-triangular system by forward substitution.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2sparse_forward_sub
 | |
| ( mod2sparse *L,  /* Matrix that is lower triangular after reordering */
 | |
|   int *rows,      /* Array of indexes (from 0) of rows for new order */
 | |
|   char *x,        /* Vector on right of equation, also reordered */
 | |
|   char *y         /* Place to store solution */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| <P>Solves the system of equations <B>Ly</B>=<B>x</B> for <B>y</B> by
 | |
| forward substitution, based on <B>L</B> being lower triangular after
 | |
| its rows are reordered according to the given index array.  The
 | |
| vectors <B>x</B> and <B>y</B> are stored unpacked, one bit per
 | |
| character.  If <B>L</B> is <I>M</I> by <I>K</I>, then <B>x</B> should
 | |
| be <I>M</I> long, but only the <I>K</I> bits indexed by <B>rows</B>
 | |
| are looked at.  The solution vector, <B>y</B>, must be <I>K</I> long.
 | |
| Only <I>K</I> rows of <B>L</B> are used, as also determined by the
 | |
| <I>K</I> indexes in the <B>rows</B> argument.  If <B>rows</B> is null,
 | |
| the first <I>K</I> rows of <B>L</B> and the first <I>K</I> elements of
 | |
| <B>x</B> are used.
 | |
| 
 | |
| <P>If the matrix <B>L</B> does not have 1s on its diagonal (after row
 | |
| rearrangement), there may be no solution, depending on what <B>x</B>
 | |
| is.  If no solution exists, this procedure returns zero, otherwise it
 | |
| returns one.  Any arbitrary bits in the solution are set to zero.
 | |
| 
 | |
| <P><A NAME="backward_sub"><HR><B>mod2sparse_backward_sub</B>: 
 | |
| Solve an upper-triangular system by backward substitution.</A>
 | |
| 
 | |
| <BLOCKQUOTE><PRE>
 | |
| int mod2sparse_backward_sub
 | |
| ( mod2sparse *U,  /* Matrix that is upper triangular after reordering */
 | |
|   int *cols,      /* Array of indexes (from 0) of columns for new order */
 | |
|   char *y,        /* Vector on right of equation */
 | |
|   char *z         /* Place to store solution, also reordered */
 | |
| )
 | |
| </PRE></BLOCKQUOTE>
 | |
| 
 | |
| <P>Solves <B>Uz</B>=<B>y</B> for <B>z</B> by backward substitution,
 | |
| based on <B>U</B> being upper triangular after its columns are
 | |
| reordered according to the given index array.  The vectors <B>y</B>
 | |
| and <B>z</B> are stored unpacked, one bit per character.  If <B>U</B>
 | |
| is <I>K</I> by <I>N</I>, then the solution vector, <I>z</I>, should be
 | |
| <I>N</I> long, but only the <I>K</I> bits indexed by <B>cols</B> are
 | |
| set.  The vector <B>y</B> must be <I>K</I> long.  Only <I>K</I> columns
 | |
| of <B>U</B> are used, as also determined by the <I>K</I> indexes in
 | |
| the <B>cols</B> argument.  The other columns of <B>U</B> must be zero
 | |
| (this is not checked, but is necessary for the method used to work).
 | |
| If <B>cols</B> is null, the first <I>K</I> columns of <B>U</B> and the
 | |
| first <I>K</I> elements of <B>z</B> are used.
 | |
| 
 | |
| <P>If the  matrix <B>U</B> does  not  have 1s  on its diagonal  (after
 | |
| column rearrangement) there  may be no  solution, depending on what  y
 | |
| is.  If no solution exists, this procedure  returns zero, otherwise it
 | |
| returns one.  Any arbitrary bits in the solution are set to zero.
 | |
| 
 | |
| <HR>
 | |
| 
 | |
| <A HREF="index.html">Back to index for LDPC software</A>
 | |
| 
 | |
| </BODY></HTML>
 |