From 9562d8615ac2c7d35a076a7947ea59adb52c4b68 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Sun, 3 Dec 2017 18:04:52 +0100 Subject: [PATCH] Implemented matrix multiplication --- src/zutil/math/MatrixMath.java | 144 ++++++++++++++++++++-------- test/zutil/math/MatrixMathTest.java | 34 +++++-- 2 files changed, 132 insertions(+), 46 deletions(-) diff --git a/src/zutil/math/MatrixMath.java b/src/zutil/math/MatrixMath.java index a6694c5..ce39dbf 100755 --- a/src/zutil/math/MatrixMath.java +++ b/src/zutil/math/MatrixMath.java @@ -13,60 +13,61 @@ public class MatrixMath { * Scalar addition, every element in the matrix will * be added by the provided number * - * @return same reference as matrix with the resulting addition + * @return a new matrix with the result */ public static double[][] add(double[][] matrix, double num){ + double[][] result = new double[matrix.length][matrix[0].length]; + for (int y=0; y < matrix.length; ++y) { for (int x=0; x < matrix[y].length; ++x){ - matrix[y][x] = matrix[y][x] + num; + result[y][x] = matrix[y][x] + num; } } - return matrix; + return result; } /** * Scalar subtraction, every element in the matrix will * be subtracted by the provided number * - * @return same reference as matrix with the resulting subtraction + * @return a new matrix with the result */ public static double[][] subtract(double[][] matrix, double num){ + double[][] result = new double[matrix.length][matrix[0].length]; + for (int y=0; y < matrix.length; ++y) { for (int x=0; x < matrix[y].length; ++x){ - matrix[y][x] = matrix[y][x] - num; + result[y][x] = matrix[y][x] - num; } } - return matrix; + return result; } /** * Scalar multiplication, every element in the matrix will * be multiplied by the provided number * - * @return same reference as matrix with the resulting multiplication + * @return a new matrix with the result */ public static double[][] multiply(double[][] matrix, double num){ + double[][] result = new double[matrix.length][matrix[0].length]; + for (int y=0; y < matrix.length; ++y) { for (int x=0; x < matrix[y].length; ++x){ - matrix[y][x] = matrix[y][x] * num; + result[y][x] = matrix[y][x] * num; } } - return matrix; + return result; } /** * Scalar division, every element in the matrix will * be multiplied by the provided number * - * @return same reference as matrix with the resulting division + * @return a new matrix with the result */ public static double[][] divide(double[][] matrix, double num){ - for (int y=0; y < matrix.length; ++y) { - for (int x=0; x < matrix[y].length; ++x){ - matrix[y][x] = matrix[y][x] / num; - } - } - return matrix; + return multiply(matrix, 1/num); } /*********************************************************************** @@ -77,59 +78,122 @@ public class MatrixMath { * Element addition, each element in matrix1 will be * added with the corresponding element in matrix2. * - * @return same reference as matrix1 with the resulting addition + * @return a new matrix with the result */ public static double[][] add(double[][] matrix1, double[][] matrix2){ + elementalPreCheck(matrix1, matrix2); + double[][] result = new double[matrix1.length][matrix1[0].length]; + for (int y=0; y < matrix1.length; ++y) { for (int x=0; x < matrix1[y].length; ++x){ - matrix1[y][x] = matrix1[y][x] + matrix2[y][x]; + result[y][x] = matrix1[y][x] + matrix2[y][x]; } } - return matrix1; + return result; } /** * Element subtraction, each element in matrix1 will be * subtracted with the corresponding element in matrix2. * - * @return same reference as matrix1 with the resulting subtraction + * @return a new matrix with the result */ public static double[][] subtract(double[][] matrix1, double[][] matrix2){ + elementalPreCheck(matrix1, matrix2); + double[][] result = new double[matrix1.length][matrix1[0].length]; + for (int y=0; y < matrix1.length; ++y) { for (int x=0; x < matrix1[y].length; ++x){ - matrix1[y][x] = matrix1[y][x] - matrix2[y][x]; + result[y][x] = matrix1[y][x] - matrix2[y][x]; } } - return matrix1; + return result; } + private static void elementalPreCheck(double[][] matrix1, double[][] matrix2) { + if (matrix1.length != matrix2.length || matrix1[0].length != matrix2[0].length) + throw new IllegalArgumentException("Matrices need to be of same dimension: " + + "matrix1 " + matrix1.length + "x" + matrix1[0].length + ", " + + "matrix2 " + matrix2.length + "x" + matrix2[0].length + ", "); + } + + /*********************************************************************** + * Vector + **********************************************************************/ + + /** + * Matrix Vector multiplication, each element column in the matrix will be + * multiplied with the corresponding element row in the vector. + * + * @return a new vector with the result + */ + public static double[] multiply(double[][] matrix, double[] vector){ + vectorPreCheck(matrix, vector); + double[] result = new double[matrix.length]; + + for (int y=0; y < matrix.length; ++y) { + for (int x=0; x < matrix[y].length; ++x){ + result[y] += matrix[y][x] * vector[x]; + } + } + return result; + } + + /** + * Matrix Vector division, each element column in the matrix will be + * divided with the corresponding element row in the vector. + * + * @return a new vector with the result + */ + public static double[] divide(double[][] matrix, double[] vector){ + vectorPreCheck(matrix, vector); + double[] result = new double[matrix.length]; + + for (int y=0; y < matrix.length; ++y) { + for (int x=0; x < matrix[y].length; ++x){ + result[y] += matrix[y][x] / vector[x]; + } + } + return result; + } + + private static void vectorPreCheck(double[][] matrix, double[] vector) { + if (matrix[0].length != vector.length) + throw new IllegalArgumentException("Matrix columns need to have same length as vector length: " + + "matrix " + matrix.length + "x" + matrix[0].length + ", " + + "vector " + vector.length + "x1"); + } + + /*********************************************************************** + * Matrix + **********************************************************************/ + /** * Element multiplication, each element in matrix1 will be * multiplied with the corresponding element in matrix2. * - * @return same reference as matrix1 with the resulting multiplication + * @return a new matrix with the result */ public static double[][] multiply(double[][] matrix1, double[][] matrix2){ - for (int y=0; y < matrix1.length; ++y) { - for (int x=0; x < matrix1[y].length; ++x){ - matrix1[y][x] = matrix1[y][x] * matrix2[y][x]; + matrixPreCheck(matrix1, matrix2); + double[][] result = new double[matrix1.length][matrix2[0].length]; + + for (int y=0; y < result.length; ++y) { + for (int x=0; x < result[y].length; ++x){ + + for (int i=0; i