Initial Commit
This commit is contained in:
Executable
+719
@@ -0,0 +1,719 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user