Package ch.akuhn.matrix

Source Code of ch.akuhn.matrix.Matrix

package ch.akuhn.matrix;

import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;

import ch.akuhn.matrix.Vector.Entry;
import ch.akuhn.util.Files;
import ch.akuhn.util.PrintOn;

/** Two-dimensional table of floating point numbers.
*<P>
* @author Adrian Kuhn
*
*/
public abstract class Matrix {

    public double add(int row, int column, double value) {
        return put(row, column, get(row, column) + value);
    }

    public Iterable<Vector> rows() {
      return vecs(/*isRow*/ true);
    }
   
    private Iterable<Vector> vecs(final boolean isRow) {
      return new Iterable<Vector>() {
      @Override
      public Iterator<Vector> iterator() {
        return new Iterator<Vector>() {

          private int count = 0;
         
          @Override
          public boolean hasNext() {
            return count < (isRow ? rowCount() : columnCount());
          }

          @Override
          public Vector next() {
            if (!hasNext()) throw new NoSuchElementException();
            return new Vec(count++, isRow);
          }

          @Override
          public void remove() {
            throw new UnsupportedOperationException();
          }
        };
      }
    };
    }
   
   
    public Iterable<Vector> columns() {
      return vecs(/*isRow*/ false);
    }

    public abstract int columnCount();

    public double density() {
        return (double) used() / elementCount();
    }
   
    public int elementCount() {
      return rowCount() * columnCount();
    }
   
    public abstract double get(int row, int column);

    public abstract double put(int row, int column, double value);

    public abstract int rowCount();

    public abstract int used();

    /** @see http://tedlab.mit.edu/~dr/svdlibc/SVD_F_ST.html */
    public void storeSparseOn(Appendable appendable) {
        // this stores the transposed matrix, but as we will transpose it again
        // when reading it, this can be done without loss of generality.
        PrintOn out = new PrintOn(appendable);
        out.print(this.columnCount()).space();
        out.print(this.rowCount()).space();
        out.print(this.used()).cr();
        for (Vector row: rows()) {
            out.print(row.used()).cr();
            for (Entry each: row.entries()) {
                out.print(each.index).space().print(each.value).space();
            }
            out.cr();
        }
        out.close();
    }

    public void storeSparseOn(String fname) {
        storeSparseOn(Files.openWrite(fname));
    }
   
    public Vector row(int row) {
      return new Vec(row, /*isRow*/ true);
    }
   
    public Vector column(int column) {
      return new Vec(column, /*isRow*/ false);
    }
   
    public double[][] asArray() {
    double[][] result = new double[rowCount()][columnCount()];
    for (int x = 0; x < result.length; x++) {
      for (int y = 0; y < result.length; y++) {
        result[x][y] = get(x,y);
      }
    }
    return result;
  }

  public static int indexOf(Vector vec) {
    return ((Vec) vec).index0;
  }

  private class Vec extends Vector {
   
    int index0;
      private boolean isRow;
     
      Vec(int n, boolean isRow) {
        this.isRow = isRow;
        this.index0 = n;
      }
     
    @Override
    public int size() {
      return isRow ? columnCount() : rowCount();
    }
     
    @Override
    public double put(int index, double value) {
      return isRow ? Matrix.this.put(this.index0, index, value)
          : Matrix.this.put(index, this.index0, value);
    }
     
    @Override
    public double get(int index) {
      return isRow ? Matrix.this.get(this.index0, index)
          : Matrix.this.get(index, this.index0);
    }

    @Override
    public boolean equals(Vector v, double epsilon) {
      throw new Error("Not yet implemented");
    }

    @Override
    public Vector times(double scalar) {
      throw new Error("Not yet implemented");
    }

    @Override
    public void apply(Function f) {
      throw new Error("Not yet implemented");
    }
   
    }

  /** Returns <code>y = Ax</code>.
   *
   */
  public Vector mult(Vector x) {
    assert x.size() == this.columnCount();
    Vector y = Vector.dense(this.rowCount());
    int i = 0; for (Vector row: rows()) y.put(i++, row.dot(x));
    return y;
  }
 
  /** Returns <code>y = (A^T)x</code>.
   *
   */
  public Vector transposeMultiply(Vector x) {
    assert x.size() == this.rowCount();
    Vector y = Vector.dense(this.columnCount());
    int i = 0; for (Vector row: rows()) row.scaleAndAddTo(x.get(i++), y);
    return y;
  }
 
  /** Returns <code>y = (A^T)Ax</code>.
   *<P>
   * Useful for doing singular decomposition using ARPACK's dsaupd routine.
   *
   */
  public Vector transposeNonTransposeMultiply(Vector x) {
    return this.transposeMultiply(this.mult(x));
  }

  public static Matrix from(int n, int m, double... values) {
    assert n * m == values.length;
    double[][] data = new double[n][];
    for (int i = 0; i < n; i++) data[i] = Arrays.copyOfRange(values, i*m, (i+1)*m);
    return new DenseMatrix(data);
  }

  public static Matrix dense(int n, int m) {
    return new DenseMatrix(n, m);
  }

  public boolean isSquare() {
    return columnCount() == rowCount();
  }

  public double[] asColumnMajorArray() {
    double[] data = new double[columnCount() * rowCount()];
    int n = columnCount();
    int i = 0;
    for (Vector row: rows()) {
      for (Entry each: row.entries()) {
        data[i + each.index * n] = each.value;
      }
      i++;
    }
    return data;
  }

  public static SparseMatrix sparse(int n, int m) {
    return new SparseMatrix(n, m);
  }
 
  public void apply(Function f) {
    f.apply(this.unwrap());
  }
 
  public double max() {
    return Util.max(this.unwrap(), Double.NaN);
  }
 
  public double min() {
    return Util.min(this.unwrap(), Double.NaN);
  }
 
  public double mean() {
    double[][] values = unwrap();
    return Util.sum(values) / Util.count(values);
  }
 
  public double[][] unwrap() {
    throw new IllegalStateException("cannot unwrap instance of " + this.getClass().getSimpleName());
  }

  public double[] rowwiseMean() {
    double[] mean = new double[rowCount()];
    int i = 0;
    for (Vector row: rows()) mean[i++] = row.mean();
    return mean;
  }

  public int[] getHistogram() {
    return Util.getHistogram(this.unwrap(), 100);
  }
 
}
TOP

Related Classes of ch.akuhn.matrix.Matrix

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.