Multiplying two matrices in Java - java

I am currently developing a class to represent matrices, it represents any general mxn matrix. I have worked out addition and scalar multiplication but I am struggling to develop the multiplication of two matrices. The data of the matrix is held in a 2D array of doubles.
The method looks a little bit like this:
public Matrix multiply(Matrix A) {
////code
}
It will return the product matrix. This is multiplication on the right. So, if I called A.multiply(B) then it would return the matrix AB, with B on the right.
I don't yet need to worry about checking whether the multiplication is defined on the given matrices, I can assume that I will be given matrices of the correct dimensions.
Does anyone know of an easy algorithm, possibly even in pseudocode to carry out the multiplication process?

Mathematically the Product of Matrices A (l x m) and B (m x n) is defined as a Matrix C (l x n) consisting of the elements:
m
c_i_j = ∑ a_i_k * b_k_j
k=1
So if you're not too much up for speed you might be happy with the straight forward O(n^3) implementation:
for (int i=0; i<l; ++i)
for (int j=0; j<n; ++j)
for (int k=0; k<m; ++k)
c[i][j] += a[i][k] * b[k][j]
If instead you're up for speed you might want to check for other alternatives like Strassen algorithm (see: Strassen algorithm).
Nevertheless be warned - especially if you're multiplying small matrices on modern processor architectures speed heavily depends on matrix data and multiplication order arranged in a way to make best use of in cache lines.
I strongly doubt there will be any chance to influence this factor from withing a vm, so I'm not sure if this is to be taken into consideration.

Java. Matrix multiplication.
Here is the "code to carry out the multiplication process". Tested with matrices of different size.
public class Matrix {
/**
* Matrix multiplication method.
* #param m1 Multiplicand
* #param m2 Multiplier
* #return Product
*/
public static double[][] multiplyByMatrix(double[][] m1, double[][] m2) {
int m1ColLength = m1[0].length; // m1 columns length
int m2RowLength = m2.length; // m2 rows length
if (m1ColLength != m2RowLength) return null; // matrix multiplication is not possible
int mRRowLength = m1.length; // m result rows length
int mRColLength = m2[0].length; // m result columns length
double[][] mResult = new double[mRRowLength][mRColLength];
for (int i = 0; i < mRRowLength; i++) { // rows from m1
for (int j = 0; j < mRColLength; j++) { // columns from m2
for (int k = 0; k < m1ColLength; k++) { // columns from m1
mResult[i][j] += m1[i][k] * m2[k][j];
}
}
}
return mResult;
}
public static String toString(double[][] m) {
String result = "";
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
result += String.format("%11.2f", m[i][j]);
}
result += "\n";
}
return result;
}
public static void main(String[] args) {
// #1
double[][] multiplicand = new double[][]{
{3, -1, 2},
{2, 0, 1},
{1, 2, 1}
};
double[][] multiplier = new double[][]{
{2, -1, 1},
{0, -2, 3},
{3, 0, 1}
};
System.out.println("#1\n" + toString(multiplyByMatrix(multiplicand, multiplier)));
// #2
multiplicand = new double[][]{
{1, 2, 0},
{-1, 3, 1},
{2, -2, 1}
};
multiplier = new double[][]{
{2},
{-1},
{1}
};
System.out.println("#2\n" + toString(multiplyByMatrix(multiplicand, multiplier)));
// #3
multiplicand = new double[][]{
{1, 2, -1},
{0, 1, 0}
};
multiplier = new double[][]{
{1, 1, 0, 0},
{0, 2, 1, 1},
{1, 1, 2, 2}
};
System.out.println("#3\n" + toString(multiplyByMatrix(multiplicand, multiplier)));
}
}
Output:
#1
12.00 -1.00 2.00
7.00 -2.00 3.00
5.00 -5.00 8.00
#2
0.00
-4.00
7.00
#3
0.00 4.00 0.00 0.00
0.00 2.00 1.00 1.00

In this answer, I created a class named Matrix, and another class is known as MatrixOperations which defines the various operations that can be performed on matrices (except for row operations of course). But I will extract the code for multiplication from MatrixOperations. The full project can be found on my GitHub page here.
Below is the definition of the Matrix class.
package app.matrix;
import app.matrix.util.MatrixException;
public class Matrix {
private double[][] entries;
public void setEntries(double[][] entries) {
this.entries = entries;
}
private String name;
public double[][] getEntries() {
return entries;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public class Dimension {
private int rows;
private int columns;
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getColumns() {
return columns;
}
public void setColumns(int columns) {
this.columns = columns;
}
public Dimension(int rows, int columns) {
this.setRows(rows);
this.setColumns(columns);
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Dimension){
return (this.getColumns() == ((Dimension) obj).getColumns()) && (this.getRows() == ((Dimension) obj).getRows());
}
return false;
}
}
private Dimension dimension;
public Dimension getDimension() {
return dimension;
}
public void setDimension(Dimension dimension) {
this.dimension = dimension;
}
public Matrix(int dimension, String name) throws MatrixException {
if (dimension == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
else this.setEntries(new double[Math.abs(dimension)][Math.abs(dimension)]);
this.setDimension(new Dimension(dimension, dimension));
this.setName(name);
}
public Matrix(int dimensionH, int dimensionV, String name) throws MatrixException {
if (dimensionH == 0 || dimensionV == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
else this.setEntries(new double[Math.abs(dimensionH)][Math.abs(dimensionV)]);
this.setDimension(new Dimension(dimensionH, dimensionV));
this.setName(name);
}
private static final String OVERFLOW_ITEMS_MSG = "The values are too many for the matrix's specified dimensions";
private static final String ZERO_UNIT_DIMENSION = "Zero cannot be a value for a dimension";
public Matrix(int dimensionH, int dimensionV, String name, double... values) throws MatrixException {
if (dimensionH == 0 || dimensionV == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
else if (values.length > dimensionH * dimensionV) throw new MatrixException(Matrix.OVERFLOW_ITEMS_MSG);
else this.setEntries(new double[Math.abs(dimensionH)][Math.abs(dimensionV)]);
this.setDimension(new Dimension(dimensionH, dimensionV));
this.setName(name);
int iterator = 0;
int j;
for (int i = 0; i < dimensionH; i++) {
j = 0;
while (j < dimensionV) {
this.entries[i][j] = values[iterator];
j++;
iterator++;
}
}
}
public Matrix(Dimension dimension) throws MatrixException {
this(dimension.getRows(), dimension.getColumns(), null);
}
public static Matrix identityMatrix(int dim) throws MatrixException {
if (dim == 0) throw new MatrixException(ZERO_UNIT_DIMENSION);
double[] i = new double[dim * dim];
int constant = dim + 1;
for (int j = 0; j < i.length; j = j + constant) {
i[j] = 1.0;
}
return new Matrix(dim, dim, null, i);
}
public String toString() {
StringBuilder builder = new StringBuilder("Matrix \"" + (this.getName() == null ? "Null Matrix" : this.getName()) + "\": {\n");
for (int i = 0; i < this.getDimension().getRows(); i++) {
for (int j = 0; j < this.getDimension().getColumns(); j++) {
if (j == 0) builder.append("\t");
builder.append(this.entries[i][j]);
if (j != this.getDimension().getColumns() - 1)
builder.append(", ");
}
if (i != this.getDimension().getRows()) builder.append("\n");
}
builder.append("}");
return builder.toString();
}
public boolean isSquare() {
return this.getDimension().getColumns() == this.getDimension().getRows();
}
}
and here is the code method for matrix multiplication from MatrixOperations
public static Matrix multiply(Matrix matrix1, Matrix matrix2) throws MatrixException {
if (matrix1.getDimension().getColumns() != matrix2.getDimension().getRows())
throw new MatrixException(MATRIX_MULTIPLICATION_ERROR_MSG);
Matrix retVal = new Matrix(matrix1.getDimension().getRows(), matrix2.getDimension().getColumns(), matrix1.getName() + " x " + matrix2.getName());
for (int i = 0; i < matrix1.getDimension().getRows(); i++) {
for (int j = 0; j < matrix2.getDimension().getColumns(); j++) {
retVal.getEntries()[i][j] = sum(arrayProduct(matrix1.getEntries()[i], getColumnMatrix(matrix2, j)));
}
}
return retVal;
}
and below again are the codes for methods sum, arrayProduct, and getColumnMatrix
private static double sum(double... values) {
double sum = 0;
for (double value : values) {
sum += value;
}
return sum;
}
private static double[] arrayProduct(double[] arr1, double[] arr2) throws MatrixException {
if (arr1.length != arr2.length) throw new MatrixException("Array lengths must be the same");
double[] retVal = new double[arr1.length];
for (int i = 0; i < arr1.length; i++) {
retVal[i] = arr1[i] * arr2[i];
}
return retVal;
}
private static double[] getColumnMatrix(Matrix matrix, int col) {
double[] ret = new double[matrix.getDimension().getRows()];
for (int i = 0; i < matrix.getDimension().getRows(); i++) {
ret[i] = matrix.getEntries()[i][col];
}
return ret;
}

Try this code for multiple any dimensional array and print it. Think this is more simple and anyone can understand this.
public class Test {
public static void main(String[] args) {
int[][] array1 = {
{1, 4, -2},
{3, 5, -6},
{4, 5, 2}
};
int[][] array2 = {
{5, 2, 8, -1},
{3, 6, 4, 5},
{-2, 9, 7, -3}
};
Test test = new Test();
test.printArray(test.multiplication(array1, array2));
}
private int[][] multiplication(int[][] array1, int[][] array2) {
int r1, r2, c1, c2;
r1 = array1.length;
c1 = array1[0].length;
r2 = array2.length;
c2 = array2[0].length;
int[][] result;
if (c1 != r2) {
System.out.println("Error!");
result = new int[0][0];
} else {
result = new int[r1][c2];
for (int i = 0; i < r1; i++) { //2
for (int j = 0; j < c2; j++) { //4
for (int k = 0; k < c1; k++) {
result[i][j] += array1[i][k] * array2[k][j];
}
}
}
}
return result;
}
private void printArray(int[][] array) {
for (int[] arr : array) {
for (int element : arr) {
System.out.print(element + " ");
}
System.out.println();
}
}
}

Related

How to replace recursion in my code on Java?

This code calculates the number of permutations for four points by 3 (no repetitions).
Arranged with recursion, but this is awkward for me.
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(0,0, points);
}
static void p1(int nowPosition, int sizeArray, int[] points) {
if (nowPosition == POINTS_ON_LINE) {
System.out.println("Output:");
System.out.println(Arrays.toString(temp));
} else {
for(int i = sizeArray + 1; i <= TOTAL_POINTS; i++) {
temp[nowPosition] = points[i-1];
p1(nowPosition + 1, i, points);
}
}
}
}
Output:
no repetitions:
Output:
[1, 2, 3]
Output:
[1, 2, 4]
Output:
[1, 3, 4]
Output:
[2, 3, 4]
It is necessary to get rid of the recursive method call p1.
I tried to do so:
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(points);
}
static void p1(int[] points) {
int sizeArray = points.length;
for(int i = sizeArray + 1; i < TOTAL_POINTS; i++, sizeArray = i) {
int nowPosition = 0;
if(nowPosition == POINTS_ON_LINE) {
System.out.println("Output: " + Arrays.toString(temp));
} else {
temp[nowPosition] = points[i-1];
nowPosition++;
}
}
}
}
Result - Output on console - empty.
It didn't work for me.
How to replace recursion?
Method # 1 (thanks for the suggested option - #deadshot)
package com.company;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int base) {
int SIZE_ARRAY = arr.length;
List<Integer> indices = IntStream.range(0, base).boxed().collect(Collectors.toList());
for(Integer i : indices) {
System.out.println("- " + i);
}
if (base < SIZE_ARRAY) {
System.out.println("first");
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
boolean flag;
int i;
while (true) {
flag = false;
for (i = base - 1; i >= 0; i--)
if (indices.get(i) != i + SIZE_ARRAY - base) {
flag = true;
break;
}
if (!flag)
return;
indices.set(i, indices.get(i) + 1);
for (int j = i + 1; j < base; j++)
indices.set(j, indices.get(j - 1) + 1);
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
for(Integer x : indices) {
System.out.println("- " + x);
}
}
}
}
}
I have used python itertools.combinations code as reference to implement the method.
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int r) {
int n = arr.length, i;
int[] indices = new int[r];
for (i = 0; i < r; i++)
indices[i] = i;
if (r < n) {
for (int idx : indices)
temp[idx] = arr[idx];
System.out.println(Arrays.toString(temp));
boolean flag;
while (true) {
flag = false;
for (i = r - 1; i >= 0; i--)
if (indices[i] != i + n - r) {
flag = true;
break;
}
if (!flag)
return;
indices[i] += 1;
for (int j = i + 1; j < r; j++)
indices[j] = indices[j - 1] + 1;
for (i = 0; i < r; i++)
temp[i] = arr[indices[i]];
System.out.println(Arrays.toString(temp));
}
}
}
}

Java Integer Array Rotation (Left)

I have a simple rotation function which takes an array and a number to rotate the numbers left
e.g. [1,2,3,4,5] & 2 - output: [3,4,5,1,2].
I want to know the most efficient way of completing this function, whether it would be to convert the int array into a string a splice it or whether to copy the array or to convert to an List<Integer>.
If anyone wants additional information please ask!
my solution at the moment:
static int[] rotLeft(int[] a, int d) {
int lengthOfArray = a.length;
int[] temp = new int[lengthOfArray];
for(int i = 0; i < lengthOfArray; i++){
int newLocation = (i + (lengthOfArray - d)) % lengthOfArray;
temp[newLocation] = a[i];
}
return temp;
}
Simple way to do it with O(n) complexity is as below along with handling of valid shifts int[] arr: is an int array, n=length of an array, d=how many shifts required.
public int[] leftRotate(int[] arr, int n, int d) {
int rot = 0;
int[] marr = new int[n];
if (d < 0 || d == 0 || d>n) {
return arr;
}
else {
for (int i = 0; i < n; i++) {
if (i < n - d) {
marr[i] = arr[i + d];
} else {
marr[i] = arr[rot];
rot++;
}
}
return marr;
}
}
public void GetArray(int[] arr, int n, int d) {
int[] arr1 = leftRotate(arr, n, d);
for (int j : arr1) {
System.out.println(j);
}
}
public static void main(String args[]) {
int[] arr = { 1,2,3,4,5 };
int n = arr.length;
Test2 obj = new Test2();
obj.GetArray(arr, n, 2);
}
Why don't you try this one
void Rotate(int arr[], int d, int n)
{
for (int i = 0; i < d; i++)
leftRotatebyOne(arr, n);
}
void leftRotatebyOne(int arr[], int n)
{
int i, temp;
temp = arr[0];
for (i = 0; i < n - 1; i++)
arr[i] = arr[i + 1];
arr[i] = temp;
}
and to call this invoke method like below
int arr[] = { 1, 2, 3, 4, 5 };
Rotate(arr, 2, 5);

How to populate an array till its length with some specific values from another array?

I have a function
int[ ] fill(int[ ] arr, int k, int n) that returns an array with the length n and values consists of repetition of first k elements.
My code is:
class Repeat_block {
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 3;
int n = 10;
int arr[] = { 1, 2, 3, 5, 9, 12, -2, -1 };
System.out.println(Arrays.toString(fill(arr, k, n)));
}
public static int[] fill(int[] arr, int k, int n) {
int arr2[] = new int[n];
if (k == 0 || n <= 0) {
return null;
}
for (int i = 0; i < n; i++) {
if (i <k) {
arr2[i] = arr[i];
}
}
return arr2;
}
}
The function should return 1,2,3,1,2,3,1,2,3,1
but it's returning 1, 2, 3, 0, 0, 0, 0, 0, 0, 0 . I tried with so many ideas
but could not figure out to get the right logic. Anybody with some best ideas.
Once i == k, you need to reset it to 0. Hence you need to use two loop variables.
for (int i = 0, j = 0; i < n; i++, j++) {
if (j == k) {
j = 0;
}
arr2[i] = arr[j];
}
Replace your for-loop with:
for (int i = 0; i < n; i++) {
arr2[i] = arr[i % k]
}
Try this.
public static int[] fill(int[] arr, int k, int n) {
if (k == 0 || n <= 0) {
return null;
}
int[] ret = new int[n];
int counter = 0;
int value = 1;
while (counter < n) {
if (value > k) value = 1;
ret[counter] = value;
value++;
counter++;
}
return ret;
}
I thought it will be easy using streams and I am sure that it can be done much easier but here is my poor attempt:
import java.util.*;
import java.lang.*;
import java.util.stream.Collectors;
class Main
{
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 3;
int n = 10;
int arr[] = { 1, 2, 3, 5, 9, 12, -2, -1 };
fill(arr, k, n);
}
public static void fill(int[] arr, int k, int n) {
String elementsToCopy = Arrays.stream(arr)
.limit(k)
.mapToObj(String::valueOf)
.reduce((a,b) -> a.concat(",").concat(b))
.get();
List<String> resultInList = Collections.nCopies(n, elementsToCopy);
resultInList
.stream()
.collect(Collectors.toList());
System.out.println(resultInList
.toString()
.replace(" ", "")
.replace("[", "")
.substring(0, n+n-1));
}
}
Just for practice, I done that in Python3 :
def fill(arr,k,n):
c = math.ceil(n/k)
return (arr[0:k]*c)[0:n]

Vector Convolution - Calculating the Index of a Neighbour Element

I am trying to implement a convolution method taking two vectors: an image; and a kernel. My problem is that i don't know how to calculate the index of the image neighbour element when I "slide" the kernel over the image vector. For example, with two identical vectors {0, 1, 2, 3, 4, 5, 6, 7, 8} I would like to achieve the following result:
My code so far is as follows:
public int[] convolve(int[] image, int[] kernel)
{
int imageValue;
int kernelValue;
int outputValue;
int[] outputImage = new int[image.length()];
// loop through image
for(int i = 0; i < image.length(); i++)
{
outputValue = 0;
// loop through kernel
for(int j = 0; j < kernel.length(); j++)
{
neighbour = ?;
// discard out of bound neighbours
if (neighbour >= 0 && neighbour < imageSize)
{
imageValue = image[neighbour];
kernelValue = kernel[j];
outputValue += imageValue * kernelValue;
}
}
output[i] = outputValue;
}
return output;
}
As i + j - (kernel.length / 2) may be too short for an answer:
public class Convolution
{
public static void main(String[] args)
{
int image[] = { 0,1,2,3,4,5,6,7,8 };
int kernel[] = { 0,1,2,3,4,5,6,7,8 };
int output[] = convolve(image, kernel);
for (int i=0; i<image.length; i++)
{
System.out.printf(output[i]+" ");
}
}
public static int[] convolve(int[] image, int[] kernel)
{
int[] output = new int[image.length];
// loop through image
for(int i = 0; i < image.length; i++)
{
System.out.println("Compute output["+i+"]");
int outputValue = 0;
// loop through kernel
for(int j = 0; j < kernel.length; j++)
{
int neighbour = i + j - (kernel.length / 2);
// discard out of bound neighbours
if (neighbour >= 0 && neighbour < image.length)
{
int imageValue = image[neighbour];
int kernelValue = kernel[j];
outputValue += imageValue * kernelValue;
System.out.println("image["+neighbour+"] and kernel["+j+"]");
}
}
output[i] = outputValue;
}
return output;
}
}
Note that this only works properly when the kernel has an odd length. In fact, what you are doing there is to move the center of the kernel through the image space (this is where the kernel.length/2 comes from). For even length kernels, like 0 1 2 3, you would have to decide whether you wanted to include...
0 1 2 3 4 (image)
3 <- This line and/or ...
2 3
1 2 3
0 1 2 3
0 1 2 3
0 1 2
0 1
0 <- ... this line
Sounds to me like you want something like a slider:
static class Slider implements Iterable<List<Integer>> {
final List<Integer> kernel;
final int imageWidth;
final int center;
public Slider(int imageWidth, int kernelWidth) {
// Build my kernel offsets list.
this.kernel = new ArrayList<>(kernelWidth);
for (int i = 0; i < kernelWidth; i++) {
kernel.add(i, i);
}
// Which kernel cell is in the center.
center = kernelWidth / 2;
// Remember the image width.
this.imageWidth = imageWidth;
}
#Override
public Iterator<List<Integer>> iterator() {
return new Iterator<List<Integer>>() {
int x = 0;
#Override
public boolean hasNext() {
return x < imageWidth;
}
#Override
public List<Integer> next() {
List<Integer> slice = kernel.subList(Math.max(0, center - x), Math.min(kernel.size(), center - x + kernel.size()));
x += 1;
return slice;
}
};
}
}
public void test() {
List<Integer> image = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> kernel = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8);
// Keep track of image position.
int x = 0;
for (List<Integer> slice : new Slider(image.size(), kernel.size())) {
System.out.println(slice);
int outputValue = 0;
int imageValue = image.get(x++);
for (Integer o : slice) {
int kernelValue = kernel.get(o);
outputValue += imageValue * kernelValue;
}
System.out.println("outputValue=" + outputValue);
}
}

GaussJordan elimination Algorithm Java

I have some trouble with my Gauss Jordan elimination method. It looks a bit oversimplified but on paper it should work. It sets the pivot to 1 considering that in case of 0 it must perform a swap. Then it subtracts that row times the value conindex of the remaing rows with the same index number of the pivot column.
I use these methods in my final algorithm.
Row multiplication:
public static double[] rowMul(double[] row, double scalar) {
BigDecimal[] temp = new BigDecimal[row.length];
BigDecimal s = new BigDecimal(scalar);
double[] newrow = new double[row.length];
for (int i = 0; i < row.length; i++) {
temp[i] = new BigDecimal(row[i]).multiply(s);
newrow[i] = temp[i].doubleValue();
}
return newrow;
}
Dividing rows:
public static double[] rowDiv(double[] row, double divisor) {
BigDecimal[] temp = new BigDecimal[row.length];
BigDecimal s = new BigDecimal(divisor);
double[] newrow = new double[row.length];
for (int i = 0; i < row.length; i++) {
temp[i] = new BigDecimal(row[i]).divide(s);
newrow[i] = temp[i].doubleValue();
}
return newrow;
}
Row subtraction:
public static double[] subtractRow(double[] mat1, double[] mat2) {
double[] c = new double[mat1.length];
for (int i = 0; i < mat1.length; i++) {
c[i] = mat1[i] - mat2[i];
}
return c;
}
Pivot check and row swap:
public static boolean checkPivot(double[][] mat, int row) {
if (mat[row][row] == 0) {
return true;
} else {
return false;
}
}
// Keeps track of the number of swaps performed to secure a finite solution.
private static int swapcount = 0;
// Mind giving the index value. So row starting from 0 up instead of 1!
public static double[][] swapRow(double[][] mat, int row) {
swapcount++;
if (swapcount >= mat.length - row) {
System.out.println("no possible combinations.");
swapcount = 0;
return mat;
}
double[] temp = mat[row];
for (int i = row; i < mat.length - 1; i++) {
mat[i] = mat[i + 1];
}
mat[mat.length - 1] = temp;
if (checkPivot(mat, row) == true) {
mat = swapRow(mat, row);
}
swapcount = 0;
return mat;
}
And then my final Gauss Jordan Algorithm:
public static double[][] gaussJordan(double[][] matrix) {
double[][] mat = matrix;
int m = mat.length;
for (int i = 0; i < m; i++) {
if (checkPivot(mat, i) == true) {
mat = swapRow(mat, i);
}
mat[i] = rowDiv(mat[i], mat[i][i]);
for (int j = 0; j < m; j++) {
if (j == i) {
j++;
} else {
mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i]));
}
}
}
return mat;
}
How ever if I give it this matrix to compute.
private static double[][] elim = {
{-20,-10,10,-10},
{ 0, 10,-5, 10},
{-10, 10,15, 20}
};
It somehow skips the middle column of the square 3 x 3 matrix on the left and returns.
1.0 0.375 0.0 0.625
0.0 1.75 0.0 2.25
0.0 1.5 1.0 2.5
The expected outcome is:
1.0 0.0 0.0 0.14286
0.0 1.0 0.0 1.28571
0.0 0.0 1.0 0.57143
Can somebody help me with finding that what I must have overlooked. I just hope its nothing to obvious! I thank you for your trouble.
mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i]));
seems wrong. With it new value of mat[j][i] is mat[j][i] - (mat[i][i] * mat[j][i]) which is != 0.
I think it should be
mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i] / mat[i][i]));
With it new value of mat[j][i] is mat[j][i] - (mat[i][i] * mat[j][i] / mat[i][i]) which is in fact 0.
Also:
if (mat[row][row] == 0) {
This is risky with doubles. I would advise something like Math.abs(mat[row][row]) < 1e-9
I hope that helps.

Categories

Resources