
edu.jas.vector.GenMatrix Maven / Gradle / Ivy
The newest version!
/*
* $Id: GenMatrix.java 4125 2012-08-19 19:05:22Z kredel $
*/
package edu.jas.vector;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import edu.jas.kern.PrettyPrint;
import edu.jas.structure.AlgebraElem;
import edu.jas.structure.RingElem;
/**
* GenMatrix implements a generic matrix algebra over RingElem entries. Matrix
* has n columns and m rows over C.
* @author Heinz Kredel
*/
public class GenMatrix> implements AlgebraElem, C> {
private static final Logger logger = Logger.getLogger(GenMatrix.class);
public final GenMatrixRing ring;
public final ArrayList> matrix;
private int hashValue = 0;
/**
* Constructor for zero GenMatrix.
* @param r matrix ring
*/
public GenMatrix(GenMatrixRing r) {
this(r, r.getZERO().matrix);
}
/**
* Constructor for GenMatrix.
* @param r matrix ring
* @param m matrix
*/
public GenMatrix(GenMatrixRing r, List> m) {
ring = r;
matrix = new ArrayList>(r.rows);
for (List row : m) {
ArrayList nr = new ArrayList(row);
matrix.add(nr);
}
logger.info(ring.rows + " x " + ring.cols + " matrix constructed");
}
/**
* Constructor for GenMatrix.
* @param r matrix ring
* @param m matrix
*/
public GenMatrix(GenMatrixRing r, ArrayList> m) {
if (r == null || m == null) {
throw new IllegalArgumentException("Empty r or m not allowed, r = " + r + ", m = " + m);
}
ring = r;
matrix = new ArrayList>(m);
logger.info(ring.rows + " x " + ring.cols + " matrix constructed");
}
/**
* Get element at row i, column j.
* @param i row index.
* @param j column index.
* @return this(i,j).
*/
public C get(int i, int j) {
return matrix.get(i).get(j);
}
/**
* Set element at row i, column j. Mutates this matrix.
* @param i row index.
* @param j column index.
* @param el element to set.
*/
public void setMutate(int i, int j, C el) {
ArrayList ri = matrix.get(i);
ri.set(j, el);
hashValue = 0; // invalidate
}
/**
* Set element at row i, column j.
* @param i row index.
* @param j column index.
* @param el element to set.
* @return new matrix m, with m(i,j) == el.
*/
public GenMatrix set(int i, int j, C el) {
GenMatrix mat = this.copy();
mat.setMutate(i, j, el);
return mat;
}
/**
* Get the String representation as RingElem.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuffer s = new StringBuffer();
boolean firstRow = true;
s.append("[\n");
for (List val : matrix) {
if (firstRow) {
firstRow = false;
} else {
s.append(",\n");
}
boolean first = true;
s.append("[ ");
for (C c : val) {
if (first) {
first = false;
} else {
s.append(", ");
}
s.append(c.toString());
}
s.append(" ]");
}
s.append(" ] ");
if (!PrettyPrint.isTrue()) {
s.append(":: " + ring.toString());
s.append("\n");
}
return s.toString();
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this Element.
* @see edu.jas.structure.Element#toScript()
*/
//JAVA6only: @Override
public String toScript() {
// Python case
StringBuffer s = new StringBuffer();
boolean firstRow = true;
s.append("( ");
for (List val : matrix) {
if (firstRow) {
firstRow = false;
} else {
s.append(", ");
}
boolean first = true;
s.append("( ");
for (C c : val) {
if (first) {
first = false;
} else {
s.append(", ");
}
s.append(c.toScript());
}
s.append(" )");
}
s.append(" ) ");
return s.toString();
}
/**
* Get a scripting compatible string representation of the factory.
* @return script compatible representation for this ElemFactory.
* @see edu.jas.structure.Element#toScriptFactory()
*/
//JAVA6only: @Override
public String toScriptFactory() {
// Python case
return factory().toScript();
}
/**
* Get the corresponding element factory.
* @return factory for this Element.
* @see edu.jas.structure.Element#factory()
*/
public GenMatrixRing factory() {
return ring;
}
/**
* clone method.
* @see java.lang.Object#clone()
*/
@Override
@SuppressWarnings("unchecked")
public GenMatrix copy() {
//return ring.copy(this);
ArrayList> m = new ArrayList>(ring.rows);
ArrayList v;
for (ArrayList val : matrix) {
v = (ArrayList) val.clone();
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Test if this is equal to a zero matrix.
*/
public boolean isZERO() {
for (List row : matrix) {
for (C elem : row) {
if (!elem.isZERO()) {
return false;
}
}
}
return true;
}
/**
* Test if this is one.
* @return true if this is 1, else false.
*/
public boolean isONE() {
int i = 0;
for (List row : matrix) {
int j = 0;
for (C elem : row) {
if (i == j) {
if (!elem.isONE()) {
return false;
}
} else if (!elem.isZERO()) {
return false;
}
j++;
}
i++;
}
return true;
}
/**
* Comparison with any other object.
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object other) {
if (!(other instanceof GenMatrix)) {
return false;
}
GenMatrix om = (GenMatrix) other;
if (!ring.equals(om.ring)) {
return false;
}
if (!matrix.equals(om.matrix)) {
return false;
}
return true;
}
/**
* Hash code for this GenMatrix.
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
if (hashValue == 0) {
hashValue = 37 * matrix.hashCode() + ring.hashCode();
if (hashValue == 0) {
hashValue = 1;
}
}
return hashValue;
}
/**
* compareTo, lexicogaphical comparison.
* @param b other
* @return 1 if (this < b), 0 if (this == b) or -1 if (this > b).
*/
//JAVA6only: @Override
public int compareTo(GenMatrix b) {
if (!ring.equals(b.ring)) {
return -1;
}
ArrayList> om = b.matrix;
int i = 0;
for (ArrayList val : matrix) {
ArrayList ov = om.get(i++);
int j = 0;
for (C c : val) {
int s = c.compareTo(ov.get(j++));
if (s != 0) {
return s;
}
}
}
return 0;
}
/**
* Test if this is a unit. I.e. there exists x with this.multiply(x).isONE()
* == true. Tests if all diagonal elements are units and all other elements
* are zero.
* @return true if this is a unit, else false.
*/
public boolean isUnit() {
int i = 0;
for (ArrayList val : matrix) {
int j = 0;
for (C el : val) {
if (i == j) {
if (!el.isUnit()) {
return false;
}
} else {
if (!el.isZERO()) {
return false;
}
}
j++;
}
i++;
}
return true;
}
/**
* sign of matrix.
* @return 1 if (this < 0), 0 if (this == 0) or -1 if (this > 0).
*/
public int signum() {
return compareTo(ring.getZERO());
}
/**
* Sum of matrices.
* @return this+b
*/
public GenMatrix sum(GenMatrix b) {
ArrayList> om = b.matrix;
ArrayList> m = new ArrayList>(ring.rows);
int i = 0;
for (ArrayList val : matrix) {
ArrayList ov = om.get(i++);
ArrayList v = new ArrayList(ring.cols);
int j = 0;
for (C c : val) {
C e = c.sum(ov.get(j++));
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Difference of matrices.
* @return this-b
*/
public GenMatrix subtract(GenMatrix b) {
ArrayList> om = b.matrix;
ArrayList> m = new ArrayList>(ring.rows);
int i = 0;
for (ArrayList val : matrix) {
ArrayList ov = om.get(i++);
ArrayList v = new ArrayList(ring.cols);
int j = 0;
for (C c : val) {
C e = c.subtract(ov.get(j++));
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Negative of this matrix.
* @return -this
*/
public GenMatrix negate() {
ArrayList> m = new ArrayList>(ring.rows);
//int i = 0;
for (ArrayList val : matrix) {
ArrayList v = new ArrayList(ring.cols);
for (C c : val) {
C e = c.negate();
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Absolute value of this matrix.
* @return abs(this)
*/
public GenMatrix abs() {
if (signum() < 0) {
return negate();
}
return this;
}
/**
* Product of this matrix with scalar.
* @return this*s
*/
public GenMatrix scalarMultiply(C s) {
ArrayList> m = new ArrayList>(ring.rows);
//int i = 0;
for (ArrayList val : matrix) {
ArrayList v = new ArrayList(ring.cols);
for (C c : val) {
C e = c.multiply(s);
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Left product of this matrix with scalar.
* @return s*this
*/
public GenMatrix leftScalarMultiply(C s) {
ArrayList> m = new ArrayList>(ring.rows);
//int i = 0;
for (ArrayList val : matrix) {
ArrayList v = new ArrayList(ring.cols);
for (C c : val) {
C e = s.multiply(c);
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Linear compination of this matrix with scalar multiple of other matrix.
* @return this*s+b*t
*/
public GenMatrix linearCombination(C s, GenMatrix b, C t) {
ArrayList> om = b.matrix;
ArrayList> m = new ArrayList>(ring.rows);
int i = 0;
for (ArrayList val : matrix) {
ArrayList ov = om.get(i++);
ArrayList v = new ArrayList(ring.cols);
int j = 0;
for (C c : val) {
C c1 = c.multiply(s);
C c2 = ov.get(j++).multiply(t);
C e = c1.sum(c2);
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Linear combination of this matrix with scalar multiple of other matrix.
* @return this+b*t
*/
public GenMatrix linearCombination(GenMatrix b, C t) {
ArrayList> om = b.matrix;
ArrayList> m = new ArrayList>(ring.rows);
int i = 0;
for (ArrayList val : matrix) {
ArrayList ov = om.get(i++);
ArrayList v = new ArrayList(ring.cols);
int j = 0;
for (C c : val) {
C c2 = ov.get(j++).multiply(t);
C e = c.sum(c2);
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Left linear combination of this matrix with scalar multiple of other
* matrix.
* @return this+t*b
*/
public GenMatrix linearCombination(C t, GenMatrix b) {
ArrayList> om = b.matrix;
ArrayList> m = new ArrayList>(ring.rows);
int i = 0;
for (ArrayList val : matrix) {
ArrayList ov = om.get(i++);
ArrayList v = new ArrayList(ring.cols);
int j = 0;
for (C c : val) {
C c2 = t.multiply(ov.get(j++));
C e = c.sum(c2);
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* left linear compination of this matrix with scalar multiple of other
* matrix.
* @return s*this+t*b
*/
public GenMatrix leftLinearCombination(C s, C t, GenMatrix b) {
ArrayList> om = b.matrix;
ArrayList> m = new ArrayList>(ring.rows);
int i = 0;
for (ArrayList val : matrix) {
ArrayList ov = om.get(i++);
ArrayList v = new ArrayList(ring.cols);
int j = 0;
for (C c : val) {
C c1 = s.multiply(c);
C c2 = t.multiply(ov.get(j++));
C e = c1.sum(c2);
v.add(e);
}
m.add(v);
}
return new GenMatrix(ring, m);
}
/**
* Transposed matrix.
* @return transpose(this)
*/
public GenMatrix transpose(GenMatrixRing tr) {
GenMatrix t = tr.getZERO().copy();
ArrayList> m = t.matrix;
int i = 0;
for (ArrayList val : matrix) {
int j = 0;
for (C c : val) {
(m.get(j)).set(i, c); //A[j,i] = A[i,j]
j++;
}
i++;
}
// return new GenMatrix(tr,m);
return t;
}
/**
* Multiply this with S.
* @param S
* @return this * S.
*/
public GenMatrix multiply(GenMatrix S) {
int na = ring.blocksize;
int nb = ring.blocksize;
//System.out.println("#blocks = " + (matrix.size()/na) + ", na = " + na
// + " SeqMultBlockTrans");
ArrayList> m = matrix;
//ArrayList> s = S.matrix;
GenMatrixRing tr = S.ring.transpose();
GenMatrix T = S.transpose(tr);
ArrayList> t = T.matrix;
//System.out.println("T = " + T);
GenMatrixRing pr = ring.product(S.ring);
GenMatrix P = pr.getZERO().copy();
ArrayList> p = P.matrix;
//System.out.println("P = " + P);
for (int ii = 0; ii < m.size(); ii += na) {
for (int jj = 0; jj < t.size(); jj += nb) {
for (int i = ii; i < Math.min((ii + na), m.size()); i++) {
ArrayList Ai = m.get(i); //A[i];
for (int j = jj; j < Math.min((jj + nb), t.size()); j++) {
ArrayList Bj = t.get(j); //B[j];
C c = ring.coFac.getZERO();
for (int k = 0; k < Bj.size(); k++) {
c = c.sum(Ai.get(k).multiply(Bj.get(k)));
// c += Ai[k] * Bj[k];
}
(p.get(i)).set(j, c); // C[i][j] = c;
}
}
}
}
return new GenMatrix(pr, p);
}
/**
* Multiply this with S. Simple unblocked algorithm.
* @param S
* @return this * S.
*/
public GenMatrix multiplySimple(GenMatrix S) {
ArrayList> m = matrix;
ArrayList> B = S.matrix;
GenMatrixRing pr = ring.product(S.ring);
GenMatrix P = pr.getZERO().copy();
ArrayList> p = P.matrix;
for (int i = 0; i < pr.rows; i++) {
ArrayList Ai = m.get(i); //A[i];
for (int j = 0; j < pr.cols; j++) {
C c = ring.coFac.getZERO();
for (int k = 0; k < S.ring.rows; k++) {
c = c.sum(Ai.get(k).multiply(B.get(k).get(j)));
// c += A[i][k] * B[k][j];
}
(p.get(i)).set(j, c); // C[i][j] = c;
}
}
return new GenMatrix(pr, p);
}
/**
* Divide this by S.
* @param S
* @return this / S.
*/
public GenMatrix divide(GenMatrix S) {
throw new UnsupportedOperationException("divide not yet implemented");
}
/**
* Remainder after division of this by S.
* @param S
* @return this - (this / S) * S.
*/
public GenMatrix remainder(GenMatrix S) {
throw new UnsupportedOperationException("remainder not implemented");
}
/**
* Inverse of this.
* @return x with this * x = 1, if it exists.
*/
public GenMatrix inverse() {
throw new UnsupportedOperationException("inverse not yet implemented");
}
/**
* Greatest common divisor.
* @param b other element.
* @return gcd(this,b).
*/
public GenMatrix gcd(GenMatrix b) {
throw new UnsupportedOperationException("gcd not implemented");
}
/**
* Extended greatest common divisor.
* @param b other element.
* @return [ gcd(this,b), c1, c2 ] with c1*this + c2*b = gcd(this,b).
*/
public GenMatrix[] egcd(GenMatrix b) {
throw new UnsupportedOperationException("egcd not implemented");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy