Public Member Functions | Public Attributes | Private Member Functions | Private Attributes

chomp::homology::mmatrix< euclidom > Class Template Reference

A class for representing sparse matrices containing elements of the 'euclidom' type. More...

#include <chains.h>

List of all members.

Public Member Functions

 mmatrix ()
 The default constructor.
 mmatrix (const mmatrix< euclidom > &m)
 The copy constructor.
mmatrix< euclidom > & operator= (const mmatrix< euclidom > &s)
 The assignment operator.
 ~mmatrix ()
 The destructor of a matrix.
void define (int numrows, int numcols)
 Defines the number of rows and columns and increases the internal tables if necessary.
void identity (int size)
 Defines the matrix to be the identity of the given size.
void add (int row, int col, const euclidom &e)
 Adds a value to the given element of the matrix.
euclidom get (int row, int col) const
 Returns the value at the desired location of the matrix.
const chain< euclidom > & getrow (int n) const
 Returns a reference to the entire row stored as a chain.
const chain< euclidom > & getcol (int n) const
 Returns a reference to the entire column stored as a chain.
int getnrows () const
 Returns the number of rows in the matrix.
int getncols () const
 Returns the number of columns in the matrix.
void addrow (int dest, int source, const euclidom &e)
 Adds one row to another with a given coefficient.
void addcol (int dest, int source, const euclidom &e)
 Adds one column to another with a given coefficient.
void swaprows (int i, int j)
 Swaps two rows of the matrix.
void swapcols (int i, int j)
 Swaps two columns of the matrix.
void multiplyrow (int n, const euclidom &e)
 Multiplies the row by the given coefficient and updates columns.
void multiplycol (int n, const euclidom &e)
 Multiplies the column by the given coefficient and updates rows.
int findrow (int req_elements=1, int start=-1) const
 Finds a row containing at least the required number of nonzero elements, starting at the given row.
int findcol (int req_elements=1, int start=-1) const
 Finds a column containing at least the required number of nonzero elements, starting at the given column.
int reducerow (int n, int preferred)
 Reduces the given row of the matrix and updates its columns.
int reducecol (int n, int preferred)
 Reduces the given column of the matrix and updates its rows.
void simple_reductions (bool quiet=false)
 Runs some random simple reductions.
void simple_form (bool quiet=false)
 Transforms the matrix to a simple form (nearly SNF).
void invert (void)
 Inverts the matrix. Throws an error message on failure.
void multiply (const mmatrix< euclidom > &m1, const mmatrix< euclidom > &m2)
 Computes the product of the two given matrices.
void submatrix (const mmatrix< euclidom > &matr, const chain< euclidom > &domain, const chain< euclidom > &range)
 Extracts a submatrix from the given matrix.
outputstreamshow_hom_col (outputstream &out, int col, const chain< euclidom > &range, const char *txt=NULL) const
 Writes a column with only these coefficients which exist in 'range', and shows their positions in that chain.
std::ostream & show_hom_col (std::ostream &out, int col, const chain< euclidom > &range, const char *txt=NULL) const
 Writes a column with only these coefficients which exist in 'range', and shows their positions in that chain.
outputstreamshowrowscols (outputstream &out, chain< euclidom > *table, int tablen, int first=0, int howmany=0, const char *label=NULL) const
 Writes the matrix to an output stream by its rows or columns.
outputstreamshowrows (outputstream &out, int first=0, int howmany=0, const char *label="Row ") const
 Writes the matrix to an output stream by its rows.
std::ostream & showrows (std::ostream &out, int first=0, int howmany=0, const char *label="Row ") const
 Writes the matrix to an output stream by its rows.
outputstreamshowcols (outputstream &out, int first=0, int howmany=0, const char *label="Col ") const
 Writes the matrix to an output stream by its rows.
std::ostream & showcols (std::ostream &out, int first=0, int howmany=0, const char *label="Col ") const
 Writes the matrix to an output stream by its rows.
outputstreamshowmap (outputstream &out, const char *maplabel=NULL, const char *xlabel=NULL, const char *ylabel=NULL) const
 Writes the matrix as a linear map on generators.
std::ostream & showmap (std::ostream &out, const char *maplabel=NULL, const char *xlabel=NULL, const char *ylabel=NULL) const
 Writes the matrix as a linear map on generators.

Public Attributes

simplelist< mmatrix< euclidom > > dom_dom
 This is a list of matrices to be updated together with the changes to the columns or rows of the current matrix.
simplelist< mmatrix< euclidom > > dom_img
simplelist< mmatrix< euclidom > > img_dom
simplelist< mmatrix< euclidom > > img_img

Private Member Functions

int findrowcol (int req_elements, int start, int which) const
 An internal procedure for both findrow and findcol.
void increase (int numrows, int numcols)
 Increases tables to be enough to keep the given number of columns and rows.
void increaserows (int numrows)
 Increases tables to be enough to keep the given number of rows.
void increasecols (int numcols)
 Increases tables to be enough to keep the given number of columns.

Private Attributes

int nrows
 The number of rows in the matrix.
int ncols
 The number of columns in the matrix.
int allrows
 The number of allocated rows.
int allcols
 The number of allocated columns.
chain< euclidom > * rows
 The rows of the matrix.
chain< euclidom > * cols
 The columns of the matrix.

Detailed Description

template<class euclidom>
class chomp::homology::mmatrix< euclidom >

A class for representing sparse matrices containing elements of the 'euclidom' type.

This class has very specific functionality to be used mainly for the purpose of homology computation.

Definition at line 1293 of file chains.h.


Constructor & Destructor Documentation

template<class euclidom >
chomp::homology::mmatrix< euclidom >::mmatrix (  )  [inline]

The default constructor.

Definition at line 1498 of file chains.h.

                                  : nrows (0), ncols (0),
        allrows (0), allcols (0), rows (NULL), cols (NULL)
{
        return;
} /* mmatrix<euclidom>::mmatrix */

template<class euclidom >
chomp::homology::mmatrix< euclidom >::mmatrix ( const mmatrix< euclidom > &  m  )  [inline]

The copy constructor.

Added by Marcin Zelawski and fixed by Pawel Pilarczyk.

Definition at line 1532 of file chains.h.

References chomp::homology::mmatrix< euclidom >::allcols, chomp::homology::mmatrix< euclidom >::allrows, chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::ncols, chomp::homology::mmatrix< euclidom >::nrows, and chomp::homology::mmatrix< euclidom >::rows.

{
        nrows = m.nrows; 
        ncols = m.ncols;
        allrows = m.allrows;
        allcols = m.allcols;

        rows = NULL;
        cols = NULL;
        if (m. allrows > 0)
        {
                chain<euclidom> *newrows = new chain<euclidom> [m. allrows];
                if (!newrows)
                        throw "Not enough memory for matrix rows.";
                for (int i = 0; i < m. allrows; ++ i)
                        newrows [i] = m. rows [i];
                rows = newrows;
        }

        if (m. allcols > 0)
        {
                chain<euclidom> *newcols = new chain<euclidom> [m. allcols];
                if (!newcols)
                        throw "Not enough memory for matrix columns.";
                for (int i = 0; i < m.allcols; ++ i)
                        newcols [i] = m. cols [i];
                cols = newcols;
        }
} /* mmatrix<euclidom>::mmatrix */

template<class euclidom >
chomp::homology::mmatrix< euclidom >::~mmatrix (  )  [inline]

The destructor of a matrix.

Definition at line 1505 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, and chomp::homology::mmatrix< euclidom >::rows.

{
        if (rows)
                delete [] rows;
        if (cols)
                delete [] cols;
        return;
} /* mmatrix<euclidom>::~mmatrix */


Member Function Documentation

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::add ( int  row,
int  col,
const euclidom &  e 
) [inline]

Adds a value to the given element of the matrix.

Definition at line 1619 of file chains.h.

References chomp::homology::mmatrix< euclidom >::allcols, chomp::homology::mmatrix< euclidom >::allrows, chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::increasecols(), chomp::homology::mmatrix< euclidom >::increaserows(), chomp::homology::mmatrix< euclidom >::ncols, chomp::homology::mmatrix< euclidom >::nrows, and chomp::homology::mmatrix< euclidom >::rows.

Referenced by chomp::homology::mmatrix< euclidom >::addcol(), chomp::homology::mmatrix< euclidom >::addrow(), chomp::homology::mmatrix< euclidom >::identity(), chomp::homology::mmatrix< euclidom >::multiply(), and chomp::homology::mmatrix< euclidom >::submatrix().

{
        if (row < 0)
                throw "Incorrect row number.";
        if (col < 0)
                throw "Incorrect column number.";
        if (row >= nrows)
        {
                if (row >= allrows)
                        increaserows (row + row / 2 + 1);
                nrows = row + 1;
        }
        if (col >= ncols)
        {
                if (col >= allcols)
                        increasecols (col + col / 2 + 1);
                ncols = col + 1;
        }
        if (e == 0)
                return;
        cols [col]. add (row, e);
        rows [row]. add (col, e);
        return;
} /* mmatrix<euclidom>::add */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::addcol ( int  dest,
int  source,
const euclidom &  e 
) [inline]

Adds one column to another with a given coefficient.

Updates all the matrices which are linked to this one.

Definition at line 1723 of file chains.h.

References chomp::homology::mmatrix< euclidom >::add(), chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::dom_dom, chomp::homology::mmatrix< euclidom >::dom_img, chomp::homology::mmatrix< euclidom >::ncols, and chomp::homology::mmatrix< euclidom >::rows.

Referenced by chomp::homology::mmatrix< euclidom >::reducerow().

{
        // check if the parameters are not out of range
        if ((dest < 0) || (dest >= ncols) || (source < 0) ||
                (source >= ncols))
                throw "Trying to add columns out of range.";

        // add this column
        cols [dest]. add (cols [source], e, dest, rows);

        // update the other matrices
        mmatrix<euclidom> *m;
        while ((m = dom_dom. take ()) != NULL)
                if (m -> cols)
                        m -> cols [dest]. add (m -> cols [source], e,
                                dest, m -> rows);

        while ((m = dom_img. take ()) != NULL)
                if (m -> rows)
                        m -> rows [source]. add (m -> rows [dest], -e,
                                source, m -> cols);

        return;
} /* mmatrix<euclidom>::addcol */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::addrow ( int  dest,
int  source,
const euclidom &  e 
) [inline]

Adds one row to another with a given coefficient.

Updates all the matrices which are linked to this one.

Definition at line 1696 of file chains.h.

References chomp::homology::mmatrix< euclidom >::add(), chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::img_dom, chomp::homology::mmatrix< euclidom >::img_img, chomp::homology::mmatrix< euclidom >::nrows, and chomp::homology::mmatrix< euclidom >::rows.

Referenced by chomp::homology::mmatrix< euclidom >::invert(), and chomp::homology::mmatrix< euclidom >::reducecol().

{
        // check if the parameters are not out of range
        if ((dest < 0) || (dest >= nrows) || (source < 0) ||
                (source >= nrows))
                throw "Trying to add rows out of range.";

        // add this row
        rows [dest]. add (rows [source], e, dest, cols);

        // update the other matrices
        mmatrix<euclidom> *m;
        while ((m = img_img. take ()) != NULL)
                if (m -> rows)
                        m -> rows [dest]. add (m -> rows [source], e,
                                dest, m -> cols);

        while ((m = img_dom. take ()) != NULL)
                if (m -> cols)
                        m -> cols [source]. add (m -> cols [dest], -e,
                                source, m -> rows);

        return;
} /* mmatrix<euclidom>::addrow */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::define ( int  numrows,
int  numcols 
) [inline]

Defines the number of rows and columns and increases the internal tables if necessary.

Useful for creating large zero matrices.

Definition at line 1515 of file chains.h.

References chomp::homology::mmatrix< euclidom >::increase(), chomp::homology::mmatrix< euclidom >::ncols, and chomp::homology::mmatrix< euclidom >::nrows.

Referenced by chomp::homology::mmatrix< euclidom >::multiply().

{
        // verify that no nonzero entry will be thrown away
        if ((nrows > numrows) || (ncols > numcols))
                throw "Trying to define a matrix smaller than it really is";

        // increase the size of the matrix to fit the defined one
        increase (numrows, numcols);

        // set the number of rows and the number of columns as requested
        nrows = numrows;
        ncols = numcols;

        return;
} /* mmatrix<euclidom>::define */

template<class euclidom >
int chomp::homology::mmatrix< euclidom >::findcol ( int  req_elements = 1,
int  start = -1 
) const [inline]

Finds a column containing at least the required number of nonzero elements, starting at the given column.

If 'req_elements' is set to -1 then looks for a zero column. Returns the number of the column satisfying the desired property, or -1 if not found.

Definition at line 1911 of file chains.h.

References chomp::homology::mmatrix< euclidom >::findrowcol().

Referenced by chomp::homology::mmatrix< euclidom >::simple_form().

{
        return findrowcol (req_elements, start, 0);
} /* mmatrix<euclidom>::findcol */

template<class euclidom >
int chomp::homology::mmatrix< euclidom >::findrow ( int  req_elements = 1,
int  start = -1 
) const [inline]

Finds a row containing at least the required number of nonzero elements, starting at the given row.

If 'req_elements' is set to -1 then looks for a zero row. Returns the number of the row satisfying the desired property, or -1 if not found.

Definition at line 1905 of file chains.h.

References chomp::homology::mmatrix< euclidom >::findrowcol().

Referenced by chomp::homology::mmatrix< euclidom >::simple_form().

{
        return findrowcol (req_elements, start, 1);
} /* mmatrix<euclidom>::findrow */

template<class euclidom >
int chomp::homology::mmatrix< euclidom >::findrowcol ( int  req_elements,
int  start,
int  which 
) const [inline, private]

An internal procedure for both findrow and findcol.

Definition at line 1836 of file chains.h.

Referenced by chomp::homology::mmatrix< euclidom >::findcol(), and chomp::homology::mmatrix< euclidom >::findrow().

        : row = 1, col = 0
{
        // start at the starting point
        int i = start;
        int random_i = -1;

        // set loop to none
        int loopcounter = 0;

        // if a random start is requested, initialize it and set loop to 1
        if (start < 0)
        {
                i = random_i = std::rand () % (which ? nrows : ncols);
                loopcounter = 1;
        }

        // select some candidates
        int candidate = -1;
        int candidates_left = 3;

        // if the table has one of its dimensions trivial, return the result
        if (which ? !ncols : !nrows)
                return (((req_elements > 0) ||
                        (i >= (which ? nrows : ncols))) ? -1 : i);

        // while the current position has not gone beyond the table
        while (i < (which ? nrows : ncols))
        {
                // if there is an appropriate row/column, return its number
                int l = (which ? rows : cols) [i]. size ();
                if ((req_elements >= 0) && (l >= req_elements))
                        return i;
                else if ((req_elements < 0) && !l)
                {
                        if (!candidates_left || !(which ? rows : cols) [i].
                                contains_non_invertible ())
                                return i;
                        else
                        {
                                candidate = i;
                                -- candidates_left;
                                if (start < 0)
                                {
                                        random_i = std::rand () %
                                                (which ? nrows : ncols);
                                        i = random_i - 1;
                                        loopcounter = 1;
                                }
                        }
                }

                // otherwise increase the counter and rewind to 0 if needed
                if (++ i >= (which ? nrows : ncols))
                        if (loopcounter --)
                                i = 0;

                // if the searching was started at a random position,
                // finish earlier
                if ((random_i >= 0) && !loopcounter && (i >= random_i))
                        break;
        }

        // if not found, return the recent candidate (or -1 if none)
        return candidate;
} /* mmatrix<euclidom>::findrowcol */

template<class euclidom >
euclidom chomp::homology::mmatrix< euclidom >::get ( int  row,
int  col 
) const [inline]

Returns the value at the desired location of the matrix.

If 'row' or 'col' is set to -1, gets the first element in it or returns 0 if the colum/row is empty.

Definition at line 1646 of file chains.h.

Referenced by chomp::homology::mmatrix< euclidom >::multiply().

{
        if ((row >= nrows) || (col >= ncols))
        {
                euclidom zero;
                zero = 0;
                return zero;
        }
        if (row >= 0)
                return rows [row]. getcoefficient (col);
        else if (col >= 0)
                return cols [col]. getcoefficient (row);
        else
        {
                euclidom zero;
                zero = 0;
                return zero;
        }
} /* mmatrix<euclidom>::get */

template<class euclidom >
const chain< euclidom > & chomp::homology::mmatrix< euclidom >::getcol ( int  n  )  const [inline]

Returns a reference to the entire column stored as a chain.

Definition at line 1676 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, and chomp::homology::mmatrix< euclidom >::ncols.

{
        if ((n < 0) || (n >= ncols))
                throw "Incorrect column number.";
        return cols [n];
} /* mmatrix<euclidom>::getcol */

template<class euclidom >
int chomp::homology::mmatrix< euclidom >::getncols (  )  const [inline]

Returns the number of columns in the matrix.

Definition at line 1690 of file chains.h.

References chomp::homology::mmatrix< euclidom >::ncols.

{
        return ncols;
} /* mmatrix<euclidom>::getncols */

template<class euclidom >
int chomp::homology::mmatrix< euclidom >::getnrows (  )  const [inline]

Returns the number of rows in the matrix.

Definition at line 1684 of file chains.h.

References chomp::homology::mmatrix< euclidom >::nrows.

{
        return nrows;
} /* mmatrix<euclidom>::getnrows */

template<class euclidom >
const chain< euclidom > & chomp::homology::mmatrix< euclidom >::getrow ( int  n  )  const [inline]

Returns a reference to the entire row stored as a chain.

Definition at line 1668 of file chains.h.

References chomp::homology::mmatrix< euclidom >::nrows, and chomp::homology::mmatrix< euclidom >::rows.

{
        if ((n < 0) || (n >= nrows))
                throw "Incorrect row number.";
        return rows [n];
} /* mmatrix<euclidom>::getrow */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::identity ( int  size  )  [inline]

Defines the matrix to be the identity of the given size.

Definition at line 1603 of file chains.h.

References chomp::homology::mmatrix< euclidom >::add(), chomp::homology::mmatrix< euclidom >::increase(), chomp::homology::mmatrix< euclidom >::ncols, and chomp::homology::mmatrix< euclidom >::nrows.

Referenced by chomp::homology::mmatrix< euclidom >::invert().

{
        if (!nrows && !ncols)
                increase (size, size);
        else if ((size > nrows) || (size > ncols))
                size = (nrows < ncols) ? nrows : ncols;
        for (int i = 0; i < size; ++ i)
        {
                euclidom one;
                one = 1;
                add (i, i, one);
        }
        return;
} /* mmatrix<euclidom>::identity */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::increase ( int  numrows,
int  numcols 
) [inline, private]

Increases tables to be enough to keep the given number of columns and rows.

This function does not set 'nrows' and 'ncols'.

Definition at line 2382 of file chains.h.

References chomp::homology::mmatrix< euclidom >::increasecols(), and chomp::homology::mmatrix< euclidom >::increaserows().

Referenced by chomp::homology::mmatrix< euclidom >::define(), and chomp::homology::mmatrix< euclidom >::identity().

{
        increaserows (numrows);
        increasecols (numcols);
        return;
} /* mmatrix<euclidom>::increase */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::increasecols ( int  numcols  )  [inline, private]

Increases tables to be enough to keep the given number of columns.

Definition at line 2407 of file chains.h.

References chomp::homology::mmatrix< euclidom >::allcols, chomp::homology::mmatrix< euclidom >::cols, and chomp::homology::mmatrix< euclidom >::ncols.

Referenced by chomp::homology::mmatrix< euclidom >::add(), and chomp::homology::mmatrix< euclidom >::increase().

{
        if (allcols >= numcols)
                return;
        chain<euclidom> *newcols = new chain<euclidom> [numcols];
        if (!newcols)
                throw "Not enough memory for matrix columns.";
        for (int i = 0; i < ncols; ++ i)
                newcols [i]. take (cols [i]);
        if (cols)
                delete [] cols;
        cols = newcols;
        allcols = numcols;

        return;
} /* mmatrix<euclidom>::increasecols */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::increaserows ( int  numrows  )  [inline, private]

Increases tables to be enough to keep the given number of rows.

Definition at line 2390 of file chains.h.

References chomp::homology::mmatrix< euclidom >::allrows, chomp::homology::mmatrix< euclidom >::nrows, and chomp::homology::mmatrix< euclidom >::rows.

Referenced by chomp::homology::mmatrix< euclidom >::add(), and chomp::homology::mmatrix< euclidom >::increase().

{
        if (allrows >= numrows)
                return;
        chain<euclidom> *newrows = new chain<euclidom> [numrows];
        if (!newrows)
                throw "Not enough memory for matrix rows.";
        for (int i = 0; i < nrows; ++ i)
                newrows [i]. take (rows [i]);
        if (rows)
                delete [] rows;
        rows = newrows;
        allrows = numrows;
        return;
} /* mmatrix<euclidom>::increaserows */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::invert ( void   )  [inline]

Inverts the matrix. Throws an error message on failure.

Definition at line 2212 of file chains.h.

References chomp::homology::mmatrix< euclidom >::addrow(), chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::identity(), chomp::homology::mmatrix< euclidom >::multiplyrow(), chomp::homology::mmatrix< euclidom >::ncols, chomp::homology::mmatrix< euclidom >::nrows, chomp::homology::mmatrix< euclidom >::rows, and chomp::homology::mmatrix< euclidom >::swaprows().

{
        // check if the matrix is square
        if (nrows != ncols)
                throw "Trying to invert a non-square matrix.";

        // if the matrix is trivial, nothing needs to be done
        if (!nrows)
                return;

        // create the identity matrix of the appropriate size
        mmatrix<euclidom> m;
        m. identity (ncols);
        
        // transform the matrix to the identity
        // by row operations (swapping and adding)
        // and apply the same operations to the matrix 'm'
        for (int col = 0; col < ncols; ++ col)
        {
                // find an invertible element in the column
                int len = cols [col]. size ();
                if (len <= 0)
                {
                        throw "Matrix inverting: Zero column found.";
                }
                int chosen = 0;
                while ((chosen < len) &&
                        ((cols [col]. num (chosen) < col) ||
                        (cols [col]. coef (chosen). delta () != 1)))
                {
                        ++ chosen;
                }
                if (chosen >= len)
                {
                        throw "Matrix inverting: "
                                "No invertible element in a column.";
                }

                // make the leading entry equal 1 in the chosen row
                euclidom invcoef;
                invcoef = 1;
                invcoef = invcoef / cols [col]. coef (chosen);
                m. multiplyrow (cols [col]. num (chosen), invcoef);
                multiplyrow (cols [col]. num (chosen), invcoef);

                // move the chosen row to the diagonal position
                m. swaprows (col, cols [col]. num (chosen));
                swaprows (col, cols [col]. num (chosen));

                // zero the column below and above the chosen entry
                invcoef = -1;
                for (int i = 0; i < len; ++ i)
                {
                        if (cols [col]. num (i) == col)
                                continue;
                        euclidom coef = invcoef * cols [col]. coef (i);
                        m. addrow (cols [col]. num (i), col, coef);
                        addrow (cols [col]. num (i), col, coef);
                        -- i;
                        -- len;
                }
        }

        // take the matrix 'm' as the result
        for (int i = 0; i < ncols; ++ i)
        {
                cols [i]. take (m. cols [i]);
                rows [i]. take (m. rows [i]);
        }

        return;
} /* mmatrix<euclidom>::invert */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::multiply ( const mmatrix< euclidom > &  m1,
const mmatrix< euclidom > &  m2 
) [inline]

Computes the product of the two given matrices.

The matrix is replaced with the product.

Definition at line 2286 of file chains.h.

References chomp::homology::mmatrix< euclidom >::add(), chomp::homology::mmatrix< euclidom >::define(), chomp::homology::mmatrix< euclidom >::get(), chomp::homology::mmatrix< euclidom >::ncols, and chomp::homology::mmatrix< euclidom >::nrows.

Referenced by chomp::homology::mmatrix< euclidom >::multiplycol(), and chomp::homology::mmatrix< euclidom >::multiplyrow().

{
        if (m1. ncols != m2. nrows)
                throw "Trying to multiply matrices of wrong sizes.";
        int K = m1. ncols;
        define (m1. nrows, m2. ncols);
        for (int i = 0; i < nrows; ++ i)
        {
                for (int j = 0; j < ncols; ++ j)
                {
                        euclidom e;
                        e = 0;
                        for (int k = 0; k < K; ++ k)
                                e += m1. get (i, k) * m2. get (k, j);
                        add (i, j, e);
                }
        }
        return;
} /* mmatrix<euclidom>::multiply */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::multiplycol ( int  n,
const euclidom &  e 
) [inline]

Multiplies the column by the given coefficient and updates rows.

Definition at line 1820 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::multiply(), and chomp::homology::mmatrix< euclidom >::rows.

{
        // retrieve the row
        chain<euclidom> &thecol = cols [n];

        // multiply the row
        thecol. multiply (e);

        // multiply the corresponding entries in all the rows
        for (int i = 0; i < thecol. size (); ++ i)
                rows [thecol. num (i)]. multiply (e, n);

        return;
} /* mmatrix<euclidom>::multiplycol */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::multiplyrow ( int  n,
const euclidom &  e 
) [inline]

Multiplies the row by the given coefficient and updates columns.

Definition at line 1804 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::multiply(), and chomp::homology::mmatrix< euclidom >::rows.

Referenced by chomp::homology::mmatrix< euclidom >::invert().

{
        // retrieve the row
        chain<euclidom> &therow = rows [n];

        // multiply the row
        therow. multiply (e);

        // multiply the corresponding entries in all the columns
        for (int i = 0; i < therow. size (); ++ i)
                cols [therow. num (i)]. multiply (e, n);

        return;
} /* mmatrix<euclidom>::multiplyrow */

template<class euclidom >
mmatrix< euclidom > & chomp::homology::mmatrix< euclidom >::operator= ( const mmatrix< euclidom > &  s  )  [inline]

The assignment operator.

Added by Marcin Zelawski and fixed by Pawel Pilarczyk.

Definition at line 1564 of file chains.h.

{
        // first release allocated tables if any
        if (rows)
                delete [] rows;
        if (cols)
                delete [] cols;

        nrows = m. nrows; 
        ncols = m. ncols;
        allrows = m. allrows;
        allcols = m. allcols;

        rows = NULL;
        cols = NULL;
        if (m. allrows > 0)
        {
                chain<euclidom> *newrows = new chain<euclidom> [m. allrows];
                if (!newrows)
                        throw "Not enough memory for matrix rows.";
                for (int i = 0; i < m. allrows; ++ i)
                        newrows [i] = m. rows [i];
                rows = newrows;
        }

        if (m. allcols > 0)
        {
                chain<euclidom> *newcols = new chain<euclidom> [m. allcols];
                if (!newcols)
                        throw "Not enough memory for matrix columns.";
                for (int i = 0; i < m.allcols; ++ i)
                        newcols [i] = m. cols [i];
                cols = newcols;
        }

        return *this;
} /* mmatrix<euclidom>::operator = */

template<class euclidom >
int chomp::homology::mmatrix< euclidom >::reducecol ( int  n,
int  preferred 
) [inline]

Reduces the given column of the matrix and updates its rows.

A preferred number of a row to leave is given. Returns the number of the row to be reduced next, or -1 if done.

Definition at line 1969 of file chains.h.

References chomp::homology::mmatrix< euclidom >::addrow(), chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::ncols, and chomp::homology::mmatrix< euclidom >::rows.

Referenced by chomp::homology::mmatrix< euclidom >::simple_form(), and chomp::homology::mmatrix< euclidom >::simple_reductions().

{
        if (n >= ncols)
                throw "Trying to reduce a column out of range.";

        int the_other = -1;

        // repeat until the column contains at most one nonzero entry
        int len;
        while ((len = cols [n]. size ()) > 1)
        {
                // copy the column to a local structure
                chain<euclidom> local (cols [n]);

                // find the best element in this column
                int best_i = local. findbest (rows);

                // find the number of the preferred element in the row
                int preferred_i = (preferred < 0) ? -1 :
                        local. findnumber (preferred);

                // check if the element in the preferred column
                // is equally good as the one already chosen
                if ((preferred_i >= 0) &&
                        (local. coef (preferred_i). delta () ==
                        local. coef (best_i). delta ()))
                        best_i = preferred_i;

                // remember the row number containing this element
                the_other = local. num (best_i);

                // for each row
                for (int i = 0; i < len; ++ i)
                {
                        // if this row is the chosen one, do nothing
                        if (i == best_i)
                                continue;

                        // compute the quotient of two elements
                        euclidom quotient = local. coef (i) /
                                local. coef (best_i);

                        // subtract the chosen row from the other one
                        addrow (local. num (i), local. num (best_i),
                                -quotient);
                }
        }

        return the_other;
} /* mmatrix<euclidom>::reducecol */

template<class euclidom >
int chomp::homology::mmatrix< euclidom >::reducerow ( int  n,
int  preferred 
) [inline]

Reduces the given row of the matrix and updates its columns.

A preferred number of a column to leave is given. Returns the number of the column to be reduced next, or -1 if done.

Definition at line 1917 of file chains.h.

References chomp::homology::mmatrix< euclidom >::addcol(), chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::nrows, and chomp::homology::mmatrix< euclidom >::rows.

Referenced by chomp::homology::mmatrix< euclidom >::simple_form().

{
        if (n >= nrows)
                throw "Trying to reduce a row out of range.";

        int the_other = -1;

        // repeat until the row contains at most one nonzero entry
        int len;
        while ((len = rows [n]. size ()) > 1)
        {
                // copy the row to a local structure
                chain<euclidom> local (rows [n]);

                // find the best element in this row
                int best_i = local. findbest (cols);

                // find the number of the preferred element in the row
                int preferred_i = (preferred < 0) ? -1 :
                        local. findnumber (preferred);

                // check if the element in the preferred column
                // is equally good as the one already chosen
                if ((preferred_i >= 0) &&
                        (local. coef (preferred_i). delta () ==
                        local. coef (best_i). delta ()))
                        best_i = preferred_i;

                // remember the column number containing this element
                the_other = local. num (best_i);

                // for each column
                for (int i = 0; i < len; ++ i)
                {
                        // if this column is the chosen one, do nothing
                        if (i == best_i)
                                continue;

                        // compute the quotient of two elements
                        euclidom quotient = local. coef (i) /
                                local. coef (best_i);

                        // subtract the chosen column from the other one
                        addcol (local. num (i), local. num (best_i),
                                -quotient);
                }
        }

        return the_other;
} /* mmatrix<euclidom>::reducerow */

template<class euclidom >
outputstream & chomp::homology::mmatrix< euclidom >::show_hom_col ( outputstream out,
int  col,
const chain< euclidom > &  range,
const char *  txt = NULL 
) const [inline]

Writes a column with only these coefficients which exist in 'range', and shows their positions in that chain.

Definition at line 2326 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols.

Referenced by chomp::homology::mmatrix< euclidom >::show_hom_col().

{
        // keep current position in 'range'
        int j = 0;

        // remember if this is the first displayed element
        int first = 1;

        // go through the column of the matrix
        for (int i = 0; i < cols [col]. size (); ++ i)
        {
                // find the current element in the range
                while ((j < range. size ()) &&
                        (range. num (j) < cols [col]. num (i)))
                {
                        ++ j;
                }

                // if this element was found in the range, display it
                if ((j < range. size ()) &&
                        (range. num (j) == cols [col]. num (i)))
                {
                        if (first)
                                first = 0;
                        else
                                out << " + ";
                        if (-cols [col]. coef (i) == 1)
                                out << "-";
                        else if (cols [col]. coef (i) != 1)
                                out << cols [col]. coef (i) << " * ";
                        if (txt)
                                out << txt;
                        out << (j + 1);
                }
        }

        // if nothing was shown, display 0
        if (first)
                out << 0;

        return out;
} /* mmatrix<euclidom>::show_hom_col */

template<class euclidom >
std::ostream & chomp::homology::mmatrix< euclidom >::show_hom_col ( std::ostream &  out,
int  col,
const chain< euclidom > &  range,
const char *  txt = NULL 
) const [inline]

Writes a column with only these coefficients which exist in 'range', and shows their positions in that chain.

Definition at line 2371 of file chains.h.

References chomp::homology::mmatrix< euclidom >::show_hom_col().

{
        outputstream tout (out);
        show_hom_col (tout, col, range, txt);
        return out;
} /* mmatrix<euclidom>::show_hom_col */

template<class euclidom >
std::ostream & chomp::homology::mmatrix< euclidom >::showcols ( std::ostream &  out,
int  first = 0,
int  howmany = 0,
const char *  label = "Col " 
) const [inline]

Writes the matrix to an output stream by its rows.

Definition at line 2060 of file chains.h.

References chomp::homology::mmatrix< euclidom >::showcols().

{
        outputstream tout (out);
        showcols (tout, first, howmany, label);
        return out;
} /* mmatrix<euclidom>::showcols */

template<class euclidom >
outputstream & chomp::homology::mmatrix< euclidom >::showcols ( outputstream out,
int  first = 0,
int  howmany = 0,
const char *  label = "Col " 
) const [inline]

Writes the matrix to an output stream by its rows.

Definition at line 2053 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::ncols, and chomp::homology::mmatrix< euclidom >::showrowscols().

Referenced by chomp::homology::mmatrix< euclidom >::showcols().

{
        return showrowscols (out, cols, ncols, first, howmany, label);
} /* mmatrix<euclidom>::showcols */

template<class euclidom >
std::ostream & chomp::homology::mmatrix< euclidom >::showmap ( std::ostream &  out,
const char *  maplabel = NULL,
const char *  xlabel = NULL,
const char *  ylabel = NULL 
) const [inline]

Writes the matrix as a linear map on generators.

Definition at line 2089 of file chains.h.

References chomp::homology::mmatrix< euclidom >::showmap().

{
        outputstream tout (out);
        showmap (tout, maplabel, xlabel, ylabel);
        return out;
} /* mmatrix<euclidom>::showmap */

template<class euclidom >
outputstream & chomp::homology::mmatrix< euclidom >::showmap ( outputstream out,
const char *  maplabel = NULL,
const char *  xlabel = NULL,
const char *  ylabel = NULL 
) const [inline]

Writes the matrix as a linear map on generators.

Definition at line 2069 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, and chomp::homology::mmatrix< euclidom >::ncols.

Referenced by chomp::homology::mmatrix< euclidom >::showmap().

{
        if (ncols <= 0)
        {
                if (maplabel && (maplabel [0] == '\t'))
                        out << "\t0\n";
                else
                        out << "0\n";
        }
        for (int i = 0; i < ncols; ++ i)
        {
                out << (maplabel ? maplabel : "f") << " (" <<
                        (xlabel ? xlabel : "") << (i + 1) << ") = ";
                cols [i]. show (out, ylabel) << '\n';
        }
        return out;
} /* mmatrix<euclidom>::showmap */

template<class euclidom >
std::ostream & chomp::homology::mmatrix< euclidom >::showrows ( std::ostream &  out,
int  first = 0,
int  howmany = 0,
const char *  label = "Row " 
) const [inline]

Writes the matrix to an output stream by its rows.

Definition at line 2044 of file chains.h.

References chomp::homology::mmatrix< euclidom >::showrows().

{
        outputstream tout (out);
        showrows (tout, first, howmany, label);
        return out;
} /* mmatrix<euclidom>::showrows */

template<class euclidom >
outputstream & chomp::homology::mmatrix< euclidom >::showrows ( outputstream out,
int  first = 0,
int  howmany = 0,
const char *  label = "Row " 
) const [inline]

Writes the matrix to an output stream by its rows.

Definition at line 2037 of file chains.h.

References chomp::homology::mmatrix< euclidom >::nrows, chomp::homology::mmatrix< euclidom >::rows, and chomp::homology::mmatrix< euclidom >::showrowscols().

Referenced by chomp::homology::mmatrix< euclidom >::showrows().

{
        return showrowscols (out, rows, nrows, first, howmany, label);
} /* mmatrix<euclidom>::showrows */

template<class euclidom >
outputstream & chomp::homology::mmatrix< euclidom >::showrowscols ( outputstream out,
chain< euclidom > *  table,
int  tablen,
int  first = 0,
int  howmany = 0,
const char *  label = NULL 
) const [inline]

Writes the matrix to an output stream by its rows or columns.

Definition at line 2021 of file chains.h.

Referenced by chomp::homology::mmatrix< euclidom >::showcols(), and chomp::homology::mmatrix< euclidom >::showrows().

{
        if ((first < 0) || (first >= tablen))
                first = 0;
        if ((howmany <= 0) || (first + howmany > tablen))
                howmany = tablen - first;
        for (int i = 0; i < howmany; ++ i)
                out << (label ? label : "") << (first + i + 1) << ": " <<
                        table [first + i] << '\n';
        out << '\n';
        return out;
} /* matrix<euclidom>::showrowscols */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::simple_form ( bool  quiet = false  )  [inline]

Transforms the matrix to a simple form (nearly SNF).

Definition at line 2153 of file chains.h.

References chomp::homology::mmatrix< euclidom >::findcol(), chomp::homology::mmatrix< euclidom >::findrow(), chomp::homology::mmatrix< euclidom >::ncols, chomp::homology::mmatrix< euclidom >::nrows, chomp::homology::mmatrix< euclidom >::reducecol(), chomp::homology::mmatrix< euclidom >::reducerow(), chomp::homology::scon, chomp::homology::mmatrix< euclidom >::simple_reductions(), and chomp::homology::sout.

{
        // if the matrix has no rows or columns, it is already in simple form
        if (!nrows || !ncols)
                return;

        // make some random simple reductions before proceeding
        simple_reductions (quiet);

        // prepare a counter
        long count = 0;

        // prepare variables for chosen row and column numbers
        int row, col, prev_row, prev_col;

        // find a row or a column with at least two nonzero entries
        row = -1;
        col = findcol (2);
        prev_row = -1, prev_col = -1;
        if (col < 0)
                row = findrow (2);

        // repeat while such a row or a column can be found
        while ((row >= 0) || (col >= 0))
        {
                // reduce rows and columns until a single entry remains
                while ((row >= 0) || (col >= 0))
                        if (row >= 0)
                        {
                                col = reducerow (row, prev_col);
                                prev_row = row;
                                row = -1;
                        }
                        else if (col >= 0)
                        {
                                row = reducecol (col, prev_row);
                                prev_col = col;
                                col = -1;
                        }

                // update the counter and display it if requested to
                ++ count;
                if (!quiet && !(count % 373))
                        scon << std::setw (12) << count <<
                                "\b\b\b\b\b\b\b\b\b\b\b\b";

                // find another row or column with at least 2 nonzero entries
                col = findcol (2);
                if (col < 0)
                        row = findrow (2);
        }

        if (!quiet)
                sout << " " << count << " reductions made. ";

        return;
} /* mmatrix<euclidom>::simple_form */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::simple_reductions ( bool  quiet = false  )  [inline]

Runs some random simple reductions.

It is recommended to run this function before running the 'simple_form' procedure.

Definition at line 2098 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::ncols, chomp::homology::mmatrix< euclidom >::nrows, chomp::homology::mmatrix< euclidom >::reducecol(), chomp::homology::mmatrix< euclidom >::rows, chomp::homology::scon, and chomp::homology::sout.

Referenced by chomp::homology::mmatrix< euclidom >::simple_form().

{
        // if the matrix has no rows or no columns,
        // simple reductions make no sense
        if (!nrows || !ncols)
                return;

        // prepare counters
        long countreduced = 0;
        long count = 4 * ((nrows > ncols) ? ncols : nrows);

        // prepare quazi-random numbers
        int nr = std::rand () % nrows;
        int nr_count = 0;
        int nr_add = 0;

        // try quazi-random reductions
        while (count --)
        {
                // try a simple reduction
                if ((rows [nr]. size () == 1) &&
                        (rows [nr]. coef (0). delta () == 1) &&
                        (cols [rows [nr]. num (0)]. size () > 1))
                {
                        ++ countreduced;
                        reducecol (rows [nr]. num (0), -1);
                }

                // try a new semi-random position
                if (nr_count)
                        -- nr_count;
                else
                {
                        nr_add = ((std::rand () >> 2) + 171) % nrows;
                        if (nr_add < 1)
                                nr_add = 1;
                        nr_count = 100;
                }
                nr += nr_add;
                if (nr >= nrows)
                        nr -= nrows;

                // display a counter
                if (!quiet && !(count % 373))
                        scon << std::setw (12) << count <<
                                "\b\b\b\b\b\b\b\b\b\b\b\b";
        }

        if (!quiet)
                sout << countreduced << " +";

        return;
} /* mmatrix<euclidom>::simple_reductions */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::submatrix ( const mmatrix< euclidom > &  matr,
const chain< euclidom > &  domain,
const chain< euclidom > &  range 
) [inline]

Extracts a submatrix from the given matrix.

Uses the positions in the 'domain' and 'range' chains as the column and row numbers for the coefficients in the new matrix.

Definition at line 2308 of file chains.h.

References chomp::homology::mmatrix< euclidom >::add().

{
        for (int i = 0; i < domain. size (); ++ i)
        {
                for (int j = 0; j < range. size (); ++ j)
                {
                        euclidom e = matr. get (domain. num (i),
                                range. num (j));
                        if (!(e == 0))
                                add (i, j, e);
                }
        }

        return;
} /* mmatrix<euclidom>::submatrix */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::swapcols ( int  i,
int  j 
) [inline]

Swaps two columns of the matrix.

Definition at line 1777 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::dom_dom, chomp::homology::mmatrix< euclidom >::dom_img, chomp::homology::mmatrix< euclidom >::ncols, chomp::homology::mmatrix< euclidom >::nrows, chomp::homology::mmatrix< euclidom >::rows, and chomp::multiwork::swap().

{
        // in the trivial case nothing needs to be done
        if (i == j)
                return;

        // check if the parameters are not out of range
        if ((i < 0) || (i >= ncols) || (j < 0) || (j >= ncols))
                throw "Trying to swap cols out of range.";

        // swap the columns
        cols [i]. swap (cols [j], i, j, rows);

        // update the other matrices
        mmatrix<euclidom> *m;
        while ((m = dom_dom. take ()) != NULL)
                if ((m -> cols) && (m -> ncols))
                        m -> cols [i]. swap (m -> cols [j], i, j, m -> rows);

        while ((m = dom_img. take ()) != NULL)
                if ((m -> rows) && (m -> nrows))
                        m -> rows [i]. swap (m -> rows [j], i, j, m -> cols);

        return;
} /* mmatrix<euclidom>::swapcols */

template<class euclidom >
void chomp::homology::mmatrix< euclidom >::swaprows ( int  i,
int  j 
) [inline]

Swaps two rows of the matrix.

Definition at line 1750 of file chains.h.

References chomp::homology::mmatrix< euclidom >::cols, chomp::homology::mmatrix< euclidom >::img_dom, chomp::homology::mmatrix< euclidom >::img_img, chomp::homology::mmatrix< euclidom >::ncols, chomp::homology::mmatrix< euclidom >::nrows, chomp::homology::mmatrix< euclidom >::rows, and chomp::multiwork::swap().

Referenced by chomp::homology::mmatrix< euclidom >::invert().

{
        // in the trivial case nothing needs to be done
        if (i == j)
                return;

        // check if the parameters are not out of range
        if ((i < 0) || (i >= nrows) || (j < 0) || (j >= nrows))
                throw "Trying to swap rows out of range.";

        // swap the rows
        rows [i]. swap (rows [j], i, j, cols);

        // update the other matrices
        mmatrix<euclidom> *m;
        while ((m = img_img. take ()) != NULL)
                if ((m -> rows) && (m -> nrows))
                        m -> rows [i]. swap (m -> rows [j], i, j, m -> cols);

        while ((m = img_dom. take ()) != NULL)
                if ((m -> cols) && (m -> ncols))
                        m -> cols [i]. swap (m -> cols [j], i, j, m -> rows);

        return;
} /* mmatrix<euclidom>::swaprows */


Member Data Documentation

template<class euclidom>
int chomp::homology::mmatrix< euclidom >::allcols [private]
template<class euclidom>
int chomp::homology::mmatrix< euclidom >::allrows [private]
template<class euclidom>
chain<euclidom>* chomp::homology::mmatrix< euclidom >::cols [private]
template<class euclidom>
simplelist<mmatrix<euclidom> > chomp::homology::mmatrix< euclidom >::dom_dom

This is a list of matrices to be updated together with the changes to the columns or rows of the current matrix.

These matrices may have these spaces as their domains or ranges (codomains, images). For instance, "dom_img" is a list of matrices such that the domain of the current matrix is the image of each of them.

Definition at line 1405 of file chains.h.

Referenced by chomp::homology::mmatrix< euclidom >::addcol(), and chomp::homology::mmatrix< euclidom >::swapcols().

template<class euclidom>
simplelist<mmatrix<euclidom> > chomp::homology::mmatrix< euclidom >::dom_img
template<class euclidom>
simplelist<mmatrix<euclidom> > chomp::homology::mmatrix< euclidom >::img_dom
template<class euclidom>
simplelist<mmatrix<euclidom> > chomp::homology::mmatrix< euclidom >::img_img
template<class euclidom>
int chomp::homology::mmatrix< euclidom >::ncols [private]
template<class euclidom>
int chomp::homology::mmatrix< euclidom >::nrows [private]
template<class euclidom>
chain<euclidom>* chomp::homology::mmatrix< euclidom >::rows [private]

The documentation for this class was generated from the following file: