mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-10-31 23:57:10 -04:00
5ac886855d
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>
|