All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.sandia.cognition.math.matrix.mtj.SparseRowMatrix Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * File:                SparseRowMatrix.java
 * Authors:             Kevin R. Dixon
 * Company:             Sandia National Laboratories
 * Project:             Cognitive Foundry
 *
 * Copyright February 21, 2006, Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
 * or on behalf of the U.S. Government. Export of this program may require a
 * license from the United States Government. See CopyrightHistory.txt for
 * complete details.
 *
 */

package gov.sandia.cognition.math.matrix.mtj;

import gov.sandia.cognition.annotation.CodeReview;
import gov.sandia.cognition.math.matrix.Matrix;
import gov.sandia.cognition.math.matrix.MatrixEntry;
import gov.sandia.cognition.math.matrix.MatrixFactory;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import no.uib.cipr.matrix.sparse.FlexCompRowMatrix;

/**
 * A sparse matrix, represented as a collection of sparse row vectors. 
 * Generally, this is the fastest sparse matrix for premultiplying against
 * a vector.
 * 
 * @author Kevin R. Dixon
 * @since 1.0
 */
@CodeReview(
    reviewer="Justin Basilico",
    date="2006-07-27",
    changesNeeded=false,
    comments="Looks good."
)
public class SparseRowMatrix
    extends AbstractSparseMatrix
{

    /**
     * Creates a new empty instance of SparseRowMatrix.
     * 
     * @param numRows Number of rows in the matrix.
     * @param numColumns Number of columns in the matrix.
     */
    protected SparseRowMatrix(
        int numRows,
        int numColumns )
    {
        this( new no.uib.cipr.matrix.sparse.FlexCompRowMatrix(
            numRows, numColumns ) );

        if (numRows < 0)
        {
            throw new IllegalArgumentException( "Num rows must be >= 0" );
        }
        if (numColumns < 0)
        {
            throw new IllegalArgumentException( "Num columns must be >= 0" );
        }

    }

    /**
     * Copy constructor for SparseRowMatrix matrices
     * 
     * @param matrix Matrix from which to copy the internal MTJ matrix.
     */
    protected SparseRowMatrix(
        SparseRowMatrix matrix )
    {
        this( (FlexCompRowMatrix) matrix.getInternalMatrix().copy() );
    }

    /**
     * Copy constructor for general matrices, copies over nonzero values.
     * 
     * @param matrix Matrix from which to copy the nonzero elements into this.
     */
    protected SparseRowMatrix(
        Matrix matrix )
    {
        this( matrix.getNumRows(), matrix.getNumColumns() );

        for (MatrixEntry e : matrix)
        {
            double value = e.getValue();

            if (value != 0.0)
            {
                this.setElement( e.getRowIndex(), e.getColumnIndex(), value );
            }
        }
    }

    /**
     * Creates a SparseRowMatrix based on the appropriate MTJ matrix,
     * does NOT create a copy of internalMatrix.
     * 
     * @param internalMatrix New internal matrix for this, no copy made.
     */
    protected SparseRowMatrix(
        FlexCompRowMatrix internalMatrix )
    {
        super( internalMatrix );
    }

    @Override
    public FlexCompRowMatrix getInternalMatrix()
    {
        return (FlexCompRowMatrix) super.getInternalMatrix();
    }

    public SparseColumnMatrix transpose()
    {
        SparseColumnMatrix result = new SparseColumnMatrix(
            this.getNumColumns(), this.getNumRows() );
        this.transposeInto( result );
        return result;
    }

    public SparseRowMatrix times(
        final AbstractMTJMatrix matrix )
    {
        int returnRows = this.getNumRows();
        int returnColumns = matrix.getNumColumns();

        SparseRowMatrix result = new SparseRowMatrix(
            returnRows, returnColumns );

        this.timesInto( matrix, result );
        return result;

    }

    public SparseRowMatrix getSubMatrix(
        int minRow,
        int maxRow,
        int minColumn,
        int maxColumn )
    {

        if (minRow > maxRow)
        {
            throw new IllegalArgumentException( "minRow > maxRow" );
        }
        if (minColumn > maxColumn)
        {
            throw new IllegalArgumentException( "minColumn > maxColumn" );
        }
        int numRows = maxRow - minRow + 1;
        int numColumns = maxColumn - minColumn + 1;
        SparseRowMatrix submatrix = new SparseRowMatrix( numRows, numColumns );
        this.getSubMatrixInto(
            minRow, maxRow, minColumn, maxColumn, submatrix );
        return submatrix;
    }

    /**
     * Gets the specified row of the matrix, using MTJ's internal routine
     * to speed things up.
     *
     * @param rowIndex Zero-based row index.
     * @return SparseVector with the same dimensions as this has columns.
     */
    @Override
    public SparseVector getRow(
        int rowIndex )
    {
        return new SparseVector( this.getInternalMatrix().getRow( rowIndex ) );
    }

    /**
     * Sets the specified row of the matrix using rowVector, using MTJ's
     * internal routine to speed things up.
     *
     * @param rowIndex Zero-based row index.
     * @param rowVector SparseVector containing the elements to replace in 
     *        this.
     */
    public void setRow(
        int rowIndex,
        SparseVector rowVector )
    {
        this.getInternalMatrix().setRow(
            rowIndex, rowVector.getInternalVector() );
    }

    public void compact()
    {
        this.getInternalMatrix().compact();
    }

    @Override
    public int getEntryCount()
    {
        final FlexCompRowMatrix m = this.getInternalMatrix();
        final int rowCount = this.getNumRows();
        int result = 0;
        for (int i = 0; i < rowCount; i++)
        {
            result += m.getRow(i).getUsed();
        }
        return result;
    }

    /**
     * Custom deserialization is needed.
     *
     * @param in The ObjectInputStream to deserialize from.
     * @throws java.io.IOException If there is an error with the stream.
     * @throws java.lang.ClassNotFoundException If a class used by this one 
     *         cannot be found.
     */
    private void readObject(
        ObjectInputStream in )
        throws IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        int numRows = in.readInt();
        int numCols = in.readInt();
        this.setInternalMatrix( new FlexCompRowMatrix( numRows, numCols ) );

        for (int i = 0; i < numRows; i++)
        {
            SparseVector row = (SparseVector) in.readObject();
            this.setRow( i, row );
        }

        this.compact();

    }


    /**
     * Custom serialization is needed.
     *
     * @param out The ObjectOutputStream to write this object to.
     * @throws java.io.IOException If there is an error writing to the stream.
     */
    private void writeObject(
        ObjectOutputStream out )
        throws IOException
    {

        this.compact();

        out.defaultWriteObject();

        int numRows = this.getNumRows();
        int numCols = this.getNumColumns();
        out.writeInt( numRows );
        out.writeInt( numCols );
        for (int i = 0; i < numRows; i++)
        {
            out.writeObject( this.getRow( i ) );
        }
    }

    @Override
    public MatrixFactory getMatrixFactory()
    {
        return SparseMatrixFactoryMTJ.INSTANCE;
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy