![JAR search and dependency download from the Maven repository](/logo.png)
jscl.math.Matrix Maven / Gradle / Ivy
package jscl.math;
import jscl.math.function.Conjugate;
import jscl.math.function.Constant;
import jscl.math.function.Fraction;
import jscl.math.function.trigonometric.Cos;
import jscl.math.function.trigonometric.Sin;
import jscl.mathml.MathML;
import jscl.util.ArrayComparator;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;
public class Matrix extends Generic {
protected final Generic elements[][];
protected final int rows, cols;
public Matrix(Generic elements[][]) {
this.elements = elements;
rows = elements.length;
cols = elements.length > 0 ? elements[0].length : 0;
}
public Generic[][] elements() {
return elements;
}
public Matrix add(Matrix matrix) {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].add(matrix.elements[i][j]);
}
}
return m;
}
@Nonnull
public Generic add(@Nonnull Generic that) {
if (that instanceof Matrix) {
return add((Matrix) that);
} else {
return add(valueOf(that));
}
}
public Matrix subtract(Matrix matrix) {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].subtract(matrix.elements[i][j]);
}
}
return m;
}
@Nonnull
public Generic subtract(@Nonnull Generic that) {
if (that instanceof Matrix) {
return subtract((Matrix) that);
} else {
return subtract(valueOf(that));
}
}
public static boolean isMatrixProduct(@Nonnull Generic a, @Nonnull Generic b) {
return (a instanceof Matrix && b instanceof Matrix) ||
(a instanceof Matrix && b instanceof JsclVector) ||
(a instanceof JsclVector && b instanceof Matrix);
}
public Matrix multiply(Matrix matrix) {
if (cols != matrix.rows) {
throw new ArithmeticException("Unable to multiply matrix by matrix: number of columns of left matrix doesn't match number of rows of right matrix!");
}
Matrix m = (Matrix) newInstance(new Generic[rows][matrix.cols]);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < matrix.cols; j++) {
m.elements[i][j] = JsclInteger.valueOf(0);
for (int k = 0; k < cols; k++) {
m.elements[i][j] = m.elements[i][j].add(elements[i][k].multiply(matrix.elements[k][j]));
}
}
}
return m;
}
@Nonnull
public Generic multiply(@Nonnull Generic that) {
if (that instanceof Matrix) {
return multiply((Matrix) that);
} else if (that instanceof JsclVector) {
JsclVector v = (JsclVector) ((JsclVector) that).newInstance(new Generic[rows]);
JsclVector v2 = (JsclVector) that;
if (cols != v2.rows) {
throw new ArithmeticException("Unable to multiply matrix by vector: number of matrix columns doesn't match number of vector rows!");
}
for (int i = 0; i < rows; i++) {
v.elements[i] = JsclInteger.valueOf(0);
for (int k = 0; k < cols; k++) {
v.elements[i] = v.elements[i].add(elements[i][k].multiply(v2.elements[k]));
}
}
return v;
} else {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].multiply(that);
}
}
return m;
}
}
@Nonnull
public Generic divide(@Nonnull Generic that) throws NotDivisibleException {
if (that instanceof Matrix) {
return multiply(that.inverse());
} else if (that instanceof JsclVector) {
throw new ArithmeticException("Unable to divide matrix by vector: matrix could not be divided by vector!");
} else {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
try {
m.elements[i][j] = elements[i][j].divide(that);
} catch (NotDivisibleException e) {
m.elements[i][j] = new Fraction(elements[i][j], that).selfExpand();
}
}
}
return m;
}
}
public Generic gcd(@Nonnull Generic generic) {
return null;
}
@Nonnull
public Generic gcd() {
return null;
}
public Generic negate() {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].negate();
}
}
return m;
}
public int signum() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int c = elements[i][j].signum();
if (c < 0) return -1;
else if (c > 0) return 1;
}
}
return 0;
}
public int degree() {
return 0;
}
public Generic antiDerivative(@Nonnull Variable variable) throws NotIntegrableException {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].antiDerivative(variable);
}
}
return m;
}
public Generic derivative(@Nonnull Variable variable) {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].derivative(variable);
}
}
return m;
}
public Generic substitute(@Nonnull Variable variable, Generic generic) {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].substitute(variable, generic);
}
}
return m;
}
public Generic expand() {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].expand();
}
}
return m;
}
public Generic factorize() {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].factorize();
}
}
return m;
}
public Generic elementary() {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].elementary();
}
}
return m;
}
public Generic simplify() {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = elements[i][j].simplify();
}
}
return m;
}
public Generic numeric() {
return new NumericWrapper(this);
}
public Generic valueOf(Generic generic) {
if (generic instanceof Matrix || generic instanceof JsclVector) {
throw new ArithmeticException("Unable to create matrix: matrix of vectors and matrix of matrices are forbidden");
} else {
Matrix m = (Matrix) identity(rows, cols).multiply(generic);
return newInstance(m.elements);
}
}
public Generic[] sumValue() {
return new Generic[]{this};
}
public Generic[] productValue() throws NotProductException {
return new Generic[]{this};
}
public Power powerValue() throws NotPowerException {
return new Power(this, 1);
}
public Expression expressionValue() throws NotExpressionException {
throw new NotExpressionException();
}
public JsclInteger integerValue() throws NotIntegerException {
throw new NotIntegerException();
}
@Override
public boolean isInteger() {
return false;
}
public Variable variableValue() throws NotVariableException {
throw new NotVariableException();
}
public Variable[] variables() {
return null;
}
public boolean isPolynomial(@Nonnull Variable variable) {
return false;
}
public boolean isConstant(@Nonnull Variable variable) {
return false;
}
public Generic[] vectors() {
JsclVector v[] = new JsclVector[rows];
for (int i = 0; i < rows; i++) {
v[i] = new JsclVector(new Generic[cols]);
for (int j = 0; j < cols; j++) {
v[i].elements[j] = elements[i][j];
}
}
return v;
}
public Generic tensorProduct(Matrix matrix) {
Matrix m = (Matrix) newInstance(new Generic[rows * matrix.rows][cols * matrix.cols]);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
for (int k = 0; k < matrix.rows; k++) {
for (int l = 0; l < matrix.cols; l++) {
m.elements[i * matrix.rows + k][j * matrix.cols + l] = elements[i][j].multiply(matrix.elements[k][l]);
}
}
}
}
return m;
}
public Matrix transpose() {
Matrix m = (Matrix) newInstance(new Generic[cols][rows]);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[j][i] = elements[i][j];
}
}
return m;
}
public Generic trace() {
Generic s = JsclInteger.valueOf(0);
for (int i = 0; i < rows; i++) {
s = s.add(elements[i][i]);
}
return s;
}
public Generic inverse() {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < rows; j++) {
m.elements[i][j] = inverseElement(i, j);
}
}
return m.transpose().divide(determinant());
}
Generic inverseElement(int k, int l) {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < rows; j++) {
m.elements[i][j] = i == k ? JsclInteger.valueOf(j == l ? 1 : 0) : elements[i][j];
}
}
return m.determinant();
}
public Generic determinant() {
if (rows > 1) {
Generic a = JsclInteger.valueOf(0);
for (int i = 0; i < rows; i++) {
if (elements[i][0].signum() == 0) ;
else {
Matrix m = (Matrix) newInstance(new Generic[rows - 1][rows - 1]);
for (int j = 0; j < rows - 1; j++) {
for (int k = 0; k < rows - 1; k++) m.elements[j][k] = elements[j < i ? j : j + 1][k + 1];
}
if (i % 2 == 0) a = a.add(elements[i][0].multiply(m.determinant()));
else a = a.subtract(elements[i][0].multiply(m.determinant()));
}
}
return a;
} else if (rows > 0) return elements[0][0];
else return JsclInteger.valueOf(0);
}
public Generic conjugate() {
Matrix m = (Matrix) newInstance();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m.elements[i][j] = new Conjugate(elements[i][j]).selfExpand();
}
}
return m;
}
public int compareTo(Matrix matrix) {
return ArrayComparator.comparator.compare(vectors(), matrix.vectors());
}
public int compareTo(Generic generic) {
if (generic instanceof Matrix) {
return compareTo((Matrix) generic);
} else {
return compareTo(valueOf(generic));
}
}
public static Matrix identity(int dimension) {
return identity(dimension, dimension);
}
public static Matrix identity(int n, int p) {
Matrix m = new Matrix(new Generic[n][p]);
for (int i = 0; i < n; i++) {
for (int j = 0; j < p; j++) {
if (i == j) {
m.elements[i][j] = JsclInteger.valueOf(1);
} else {
m.elements[i][j] = JsclInteger.valueOf(0);
}
}
}
return m;
}
public static Matrix frame(JsclVector vector[]) {
Matrix m = new Matrix(new Generic[vector.length > 0 ? vector[0].rows : 0][vector.length]);
for (int i = 0; i < m.rows; i++) {
for (int j = 0; j < m.cols; j++) {
m.elements[i][j] = vector[j].elements[i];
}
}
return m;
}
public static Matrix rotation(int dimension, int plane, Generic angle) {
return rotation(dimension, plane, 2, angle);
}
public static Matrix rotation(int dimension, int axis1, int axis2, Generic angle) {
Matrix m = new Matrix(new Generic[dimension][dimension]);
for (int i = 0; i < m.rows; i++) {
for (int j = 0; j < m.cols; j++) {
if (i == axis1 && j == axis1) {
m.elements[i][j] = new Cos(angle).selfExpand();
} else if (i == axis1 && j == axis2) {
m.elements[i][j] = new Sin(angle).selfExpand().negate();
} else if (i == axis2 && j == axis1) {
m.elements[i][j] = new Sin(angle).selfExpand();
} else if (i == axis2 && j == axis2) {
m.elements[i][j] = new Cos(angle).selfExpand();
} else if (i == j) {
m.elements[i][j] = JsclInteger.valueOf(1);
} else {
m.elements[i][j] = JsclInteger.valueOf(0);
}
}
}
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(elements[i][j]).append(j < cols - 1 ? ", " : "");
}
result.append("]").append(i < rows - 1 ? ",\n" : "");
}
result.append("]");
return result.toString();
}
public String toJava() {
final StringBuilder result = new StringBuilder();
result.append("new Matrix(new Numeric[][] {");
for (int i = 0; i < rows; i++) {
result.append("{");
for (int j = 0; j < cols; j++) {
result.append(elements[i][j].toJava()).append(j < cols - 1 ? ", " : "");
}
result.append("}").append(i < rows - 1 ? ", " : "");
}
result.append("})");
return result.toString();
}
public void toMathML(MathML element, Object data) {
int exponent = data instanceof Integer ? (Integer) data : 1;
if (exponent == 1) bodyToMathML(element);
else {
MathML e1 = element.element("msup");
bodyToMathML(e1);
MathML e2 = element.element("mn");
e2.appendChild(element.text(String.valueOf(exponent)));
e1.appendChild(e2);
element.appendChild(e1);
}
}
@Nonnull
@Override
public Set extends Constant> getConstants() {
final Set result = new HashSet();
for (Generic[] element : elements) {
for (Generic generic : element) {
result.addAll(generic.getConstants());
}
}
return result;
}
protected void bodyToMathML(MathML e0) {
MathML e1 = e0.element("mfenced");
MathML e2 = e0.element("mtable");
for (int i = 0; i < rows; i++) {
MathML e3 = e0.element("mtr");
for (int j = 0; j < cols; j++) {
MathML e4 = e0.element("mtd");
elements[i][j].toMathML(e4, null);
e3.appendChild(e4);
}
e2.appendChild(e3);
}
e1.appendChild(e2);
e0.appendChild(e1);
}
@Nonnull
protected Generic newInstance() {
return newInstance(new Generic[rows][cols]);
}
@Nonnull
protected static Generic newInstance(Generic element[][]) {
return new Matrix(element);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy