![JAR search and dependency download from the Maven repository](/logo.png)
jscl.math.numeric.Matrix Maven / Gradle / Ivy
package jscl.math.numeric;
import jscl.math.NotDivisibleException;
import jscl.util.ArrayComparator;
import javax.annotation.Nonnull;
public class Matrix extends Numeric {
@Nonnull
private final Numeric m[][];
private final int rows, cols;
public Matrix(@Nonnull Numeric m[][]) {
this.m = m;
rows = m.length;
cols = m.length > 0 ? m[0].length : 0;
}
public Numeric[][] elements() {
return m;
}
public Matrix add(Matrix matrix) {
Matrix m = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.m[i][j] = this.m[i][j].add(matrix.m[i][j]);
}
}
return m;
}
@Nonnull
public Numeric add(@Nonnull Numeric that) {
if (that instanceof Matrix) {
return add((Matrix) that);
} else {
return add(valueOf(that));
}
}
public Matrix subtract(Matrix matrix) {
Matrix m = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.m[i][j] = this.m[i][j].subtract(matrix.m[i][j]);
}
}
return m;
}
@Nonnull
public Numeric subtract(@Nonnull Numeric that) {
if (that instanceof Matrix) {
return subtract((Matrix) that);
} else {
return subtract(valueOf(that));
}
}
public Matrix multiply(Matrix matrix) {
if (cols != matrix.rows) throw new ArithmeticException();
Matrix m = newInstance(new Numeric[rows][matrix.cols]);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < matrix.cols; j++) {
m.m[i][j] = Real.ZERO;
for (int k = 0; k < cols; k++) {
m.m[i][j] = m.m[i][j].add(this.m[i][k].multiply(matrix.m[k][j]));
}
}
}
return m;
}
@Nonnull
public Numeric multiply(@Nonnull Numeric that) {
if (that instanceof Matrix) {
return multiply((Matrix) that);
} else if (that instanceof Vector) {
Vector v = ((Vector) that).newInstance(new Numeric[rows]);
Vector v2 = (Vector) that;
if (cols != v2.n) throw new ArithmeticException();
for (int i = 0; i < rows; i++) {
v.element[i] = Real.ZERO;
for (int k = 0; k < cols; k++) {
v.element[i] = v.element[i].add(m[i][k].multiply(v2.element[k]));
}
}
return v;
} else {
Matrix m = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.m[i][j] = this.m[i][j].multiply(that);
}
}
return m;
}
}
@Nonnull
public Numeric divide(@Nonnull Numeric that) throws NotDivisibleException {
if (that instanceof Matrix) {
return multiply(that.inverse());
} else if (that instanceof Vector) {
throw new ArithmeticException();
} else {
Matrix m = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.m[i][j] = this.m[i][j].divide(that);
}
}
return m;
}
}
@Nonnull
public Numeric negate() {
Matrix m = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.m[i][j] = this.m[i][j].negate();
}
}
return m;
}
public int signum() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int c = m[i][j].signum();
if (c < 0) {
return -1;
} else if (c > 0) {
return 1;
}
}
}
return 0;
}
@Nonnull
public Numeric valueOf(@Nonnull Numeric numeric) {
if (numeric instanceof Matrix || numeric instanceof Vector) {
throw new ArithmeticException();
} else {
Matrix m = (Matrix) identity(rows, cols).multiply(numeric);
return newInstance(m.m);
}
}
public Numeric[] vectors() {
Vector v[] = new Vector[rows];
for (int i = 0; i < rows; i++) {
v[i] = new Vector(new Numeric[cols]);
for (int j = 0; j < cols; j++) {
v[i].element[j] = m[i][j];
}
}
return v;
}
public Numeric transpose() {
Matrix m = newInstance(new Numeric[cols][rows]);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.m[j][i] = this.m[i][j];
}
}
return m;
}
public Numeric trace() {
Numeric s = Real.ZERO;
for (int i = 0; i < rows; i++) {
s = s.add(m[i][i]);
}
return s;
}
@Nonnull
public Numeric inverse() {
Matrix m = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < rows; j++) {
m.m[i][j] = inverseElement(i, j);
}
}
return m.transpose().divide(determinant());
}
Numeric inverseElement(int k, int l) {
final Matrix result = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < rows; j++) {
if (i == k) {
result.m[i][j] = Real.valueOf(j == l ? 1 : 0);
} else {
result.m[i][j] = this.m[i][j];
}
}
}
return result.determinant();
}
public Numeric determinant() {
if (rows > 1) {
Numeric a = Real.ZERO;
for (int i = 0; i < rows; i++) {
if (m[i][0].signum() != 0) {
Matrix m = newInstance(new Numeric[rows - 1][rows - 1]);
for (int j = 0; j < rows - 1; j++) {
for (int k = 0; k < rows - 1; k++) m.m[j][k] = this.m[j < i ? j : j + 1][k + 1];
}
if (i % 2 == 0) {
a = a.add(this.m[i][0].multiply(m.determinant()));
} else {
a = a.subtract(this.m[i][0].multiply(m.determinant()));
}
}
}
return a;
} else if (rows > 0) return m[0][0];
else return Real.ZERO;
}
@Nonnull
public Numeric ln() {
throw new ArithmeticException();
}
@Nonnull
@Override
public Numeric lg() {
throw new ArithmeticException();
}
@Nonnull
public Numeric exp() {
throw new ArithmeticException();
}
public Numeric conjugate() {
Matrix m = newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.m[i][j] = this.m[i][j].conjugate();
}
}
return m;
}
public int compareTo(Matrix matrix) {
return ArrayComparator.comparator.compare(vectors(), matrix.vectors());
}
public int compareTo(Numeric numeric) {
if (numeric instanceof Matrix) {
return compareTo((Matrix) numeric);
} else {
return compareTo(valueOf(numeric));
}
}
public static Matrix identity(int dimension) {
return identity(dimension, dimension);
}
public static Matrix identity(int n, int p) {
Matrix m = new Matrix(new Numeric[n][p]);
for (int i = 0; i < n; i++) {
for (int j = 0; j < p; j++) {
if (i == j) {
m.m[i][j] = Real.ONE;
} else {
m.m[i][j] = Real.ZERO;
}
}
}
return m;
}
public String toString() {
final StringBuilder result = new StringBuilder();
result.append("{");
for (int i = 0; i < rows; i++) {
result.append("{");
for (int j = 0; j < cols; j++) {
result.append(m[i][j]).append(j < cols - 1 ? ", " : "");
}
result.append("}").append(i < rows - 1 ? ",\n" : "");
}
result.append("}");
return result.toString();
}
protected Matrix newInstance() {
return newInstance(new Numeric[rows][cols]);
}
protected Matrix newInstance(Numeric element[][]) {
return new Matrix(element);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy