Chain Matrix Multiplication : Multiply Algorithm not working - java

I have implemented a chain matrix multiplication. Although I get correct chain order, but while doing actual multiplication, the given multiply algorithm is not working properly. My Java Code:-
package algopackage;
import java.util.ArrayList;
import java.util.List;
public class ChainMatrixMultiplication {
static int s[][];
static int x[][];
static int y[][];
public ChainMatrixMultiplication() {
}
static void chainMatrixMultiplication(int[] p) {
boolean isFirst = false;
int n = p.length-1;
int m[][] = new int[n][n];
s = new int[n][n];
for (int c = 0; c < n; c++)
m[c][c] = 0;
for (int counter = 1; counter < n; counter++) {
for (int i = 0;i < n; i++) {
isFirst = false;
int j = i + counter;
for (int k = i; k < j && j < n; k++) {
int result = m[i][k] + m[k+1][j] + p[i] * p[k+1] * p[j+1];
if (!isFirst) {
m[i][j] = result;
s[i][j] = k;
isFirst = true;
} else if (m[i][j] > result) {
m[i][j] = result;
s[i][j] = k;
}
}
}
}
}
static int[][] matrixMultiply(List<Matrix> matrices, int s[][], int i ,int j) {
if (i ==j) return matrices.get(i).getMatrix();
else {
int k = s[i][j];
x = matrixMultiply(matrices, s, i, k);
y = matrixMultiply(matrices, s, k+1, j);
return mult(x,y);
}
}
static int[][] mult(int[][] x, int[][] y) {
int [][] result = new int[x.length][y[0].length];
/* Loop through each and get product, then sum up and store the value */
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < y[0].length; j++) {
for (int k = 0; k < x[0].length; k++) {
result[i][j] += x[i][k] * y[k][j];
}
}
}
return result;
}
public static void main(String[] args) {
int p[] = {5,4,6,2};
List<Matrix> matrices = new ArrayList<Matrix>();
Matrix m1 = new Matrix(5,4);
int arr[] = {1,2,40,2,3,29,10,21,11,120,23,90,24,12,11,1,11,45,23,21};
m1.addElementsToMatrix(5, 4, arr);
Matrix m2 = new Matrix(4,6);
int arr1[] = {1,1,1,2,3,12,12,3,10,12,12,29,22,11,22,11,11,11,13,1,2,12,4,2};
m2.addElementsToMatrix(4, 6, arr1);
Matrix m3 = new Matrix(6,2);
int arr2[] = {1,1,12,3,22,11,13,1,2,12,12,12};
m3.addElementsToMatrix(6, 2, arr2);
matrices.add(m1);
matrices.add(m2);
matrices.add(m3);
chainMatrixMultiplication(p);
matrixMultiply(matrices,s,0,2);
}
}
class Matrix {
private final int[][] matrix;
public Matrix(int rows, int cols) {
this.matrix = new int[rows][cols];
}
public void addElementsToMatrix(int rows, int cols, int[] arr) {
int counter = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = arr[counter++];
}
}
}
public int[][] getMatrix() {
return matrix;
}
}
In the above code matrixMultiply() function is throwing exception. Exception is caused as matrices are not being multiplied as expected. As recursion is not behaving as expected. I am missing something in this code. Any help will be appreciated.Thanks!

I'm not sure of the correctness of your code, but looking at the matrix multiplication output when you multiply matrix of dimension a*b and c*d after you multiply, you get a matrix of dimension a*d there by changing
for (int k = 0; k < x[0].length; k++) {
to
for (int k = 0; k < y[0].length; k++) {
should resolve the problem.

This:
x = matrixMultiply(matrices, s, i, k); // call A
y = matrixMultiply(matrices, s, k+1, j); // call B
return mult(x,y);
looks like it should multiply the result of call A by the result of call B. But in general, it doesn't.
x is not local, call B will usually overwrite it, except when call B immediately hits the base case.
This sort of thing tends to happen when you pass data around "to the side", not as function parameter or function return value. It is not reasonable to avoid that kind of data flow all the time, but you should avoid it here, especially since it's not even what you wanted.

Related

How can I print out the result matrix in my java code?

Create a basics.Matrix class (using a two-dimensional array of real numbers as a matrix) that has the following operations: construct an M × N zero matrix, construct an M × N matrix using an M × N array, create an N × N dimensional unit matrix ( the result matrix should be a return value), the matrix transposed resp. calculating the sum and difference of two matrices, representing the matrix as a string (use java.lang.StringBuilder to generate the text).
Also create a main program (Main.java) that tests these operations!
My problem is in my basicsMatrixMain.java code, that I do not know how can I print out thre results I get from difference or transpone. Can anybody help me to solve it ?
public class basicsMatrix {
private final int N;
private final int M;
private final double[][] matrix;
public basicsMatrix(int M, int N) {
this.N = N;
this.M = M;
matrix = new double[M][N];
}
public basicsMatrix(double[][] matrix) {
M = matrix.length;
N = matrix[0].length;
this.matrix = new double[N][M];
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
this.matrix[i][j] = matrix[i][j];
}
public void transzponalas(double[][] matrix1){
double[][] transpose = new double[M][N];
for(int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
transpose[j][i] = matrix1[i][j];
}
}
}
public void add(double[][] matrix1,double[][] matrix2){
double[][] osszeadas = new double[N][M];
for(int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
osszeadas[i][j] = (matrix1[i][j] + matrix2[i][j]);
}
}
}
public void difference(int matrix1[][], int matrix2[][]){
double[][] kivonas = new double[N][M];
for(int i = 0; i <= N; i++){
for(int j = 0; j <= M; j++){
kivonas[i][j] = matrix1[i][j] - matrix2[i][j];
}
}
}
public String matrixtostring(double[][] matrix1){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
sb.append(matrix1);
}
}
return sb.toString();
}
}
public class basicsMatrixMain {
public static void main(String[] args) {
int N = 2;
int M = 3;
double[][] matrix1 = { {2, 3, 4}, {5, 2, 3} };
double[][] matrix2 = { {-4, 5, 3}, {5, 6, 3} };
System.out.println("\n");
System.out.print("Difference:");
for(int i = 0; i <= N; i++){
for(int j = 0; j <= M; j++){
System.out.println();
}
}
}
}
You have defined a lot of functions in basicsMatrix that you can use here.
However there are some changes that you need to make. In your add, difference and transpose methods, you define something but you never save the result. I would recommend something like this:
public double[][] transzponalas(double[][] matrix1){
double[][] transpose = new double[M][N];
for(int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
transpose[j][i] = matrix1[i][j];
}
}
return transpose;
}
public double[][] add(double[][] matrix1,double[][] matrix2){
double[][] osszeadas = new double[N][M];
for(int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
osszeadas[i][j] = (matrix1[i][j] + matrix2[i][j]);
}
}
return osszeadas;
}
public double[][] difference(int matrix1[][], int matrix2[][]){
double[][] kivonas = new double[N][M];
for(int i = 0; i <= N; i++){
for(int j = 0; j <= M; j++){
kivonas[i][j] = matrix1[i][j] - matrix2[i][j];
}
}
return kivonas;
}
All these functions now return a matrix that you can print out.
Now you just print you matrices. Something like this should work.
System.out.println(matrixtostring(transzponalas(matrix1)));
System.out.println(matrixtostring(add(matrix1,matrix2)));
System.out.println(matrixtostring(difference(matrix1,matrix2)));
Looking at the question description.
"Create a basics.Matrix class (using a two-dimensional array of real numbers as a matrix) that has the following operations: construct an M × N zero matrix, construct an M × N matrix using an M × N array, create an N × N dimensional unit matrix ( the result matrix should be a return value), the matrix transposed resp. calculating the sum and difference of two matrices, representing the matrix as a string (use java.lang.StringBuilder to generate the text).
Also create a main program (Main.java) that tests these operations!"
I suspect that you are supposed to create a class that calls functions on itself. In other words the basicsMatrix will become your matrix.
For example, the transzponalas method would become
public void transzponalas(){
double[][] transpose = new double[M][N];
for(int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
transpose[j][i] = this.matrix[i][j];
}
}
int tmp = this.M
this.M = this.N
this.N = tmp
this.matrix = transpose;
}
This way, you change the matrix that is inside your basicsMatrix. You should make sure that you understand the assignment correctly.

Java implement cross correlation 2d image

enter image description here
Can i implement the cross-correlation in the same way as the convolution?
I want to implement the formula in as in the picture, where Li the kernel in 4 different direction filters; Ci is the magnitude map for direction i. So what I did is to find the cross-correlation in the four directions separately and add them up. I learned that the cross correlation can be the same as convolution in image line sharping; s as the result should be stroke line of an image but what I actually get are discrete points. I am not sure if I implemented the formula correctly. Please help
private static void sharpTheLine(){
int[][] cC_0= crossCorrelation(KERNEL_0,CMap_0);
int[][] cC_45=crossCorrelation(KERNEL_45,CMap_45);
int[][] cC_90=crossCorrelation(KERNEL_90,CMap_90);
int[][] cC_135=crossCorrelation(KERNEL_135,CMap_135);
//generate S
for(int i=0; i<imageWidth; i++){
for(int j =0; j<imageHight; j++) {
SMap[i][j] = cC_0[i][j]+cC_45[i][j]+cC_90[i][j]+cC_135[i][j];
}
}
}
private static int[][] crossCorrelation(int [][] kernel,int[][] CMapVal){
int horizontalWalk = imageWidth - K_R;
int verticalWalk = imageHight - K_C;
int res[][]=new int[imageWidth][imageHight];
for (int i = 0; i < horizontalWalk; i++) {
for (int j = 0; j < verticalWalk; j++) {
int sample[][] = new int[K_R][K_C];
for (int k = i; k < K_R + i; k++) {
for (int m = j; m < K_C + j; m++) {
sample[k - i][m - j] = CMapVal[k][m];
OnePixelConvolution(sample, i, j, kernel, res);
}
}
}
}
return res;
}
private static void OnePixelConvolution(int[][] sample, int x, int y, int [][]kernel, int [][] res) {
int resrgb = 0;
for (int i = 0; i < K_R; i++) {
for (int j = 0; j < K_C; j++) {
resrgb = resrgb + sample[i][j] * kernel[i][j];
}
}
res[x][y] = resrgb;
}

My matrix doesn’t change when I try to perform scalar multiplication

we're supposed to multiply every element in the matrix by a number, in this case "k". not sure what i'm doing wrong but it wont work. HELP! i have edited and added the whole project so far.
public class Matrix {
private int r;//rows
private int c;//columns
private int[][] neo; //2D array
public static void main(String[] args) {
Matrix m1 = new Matrix(3,4);
Matrix m2 = new Matrix(3,4);
System.out.println(m2);
try {
Matrix m3 = m1.multiply(m2);
} catch (Exception e) {
e.printStackTrace();
}
m2.scaleMult(k);
}//main
public Matrix(int row, int column) {
r = row;
c = column;
neo = new int[r][c];
for(int i = 0; i < neo.length; i++) {
for (int j = 0; j < neo[i].length; j++) {
neo[i][j] = (int) (1 + Math.random() * 100);
}//forLoop
}//forLoop
System.out.println(Arrays.toString(neo));
}//Matrix
public Matrix copyMatrix(Matrix m) {
Matrix copy = new Matrix(m.r, m.c);
for (int i = 0; i < r; i++) {
System.arraycopy(this.neo[i], 0, copy.neo[i], 0, this.neo[i].length);
}//forLoop
return copy;
}//copyMatrix
public void scaleMult(int k){
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
this.neo[i][j] * k;
}//scaleMult
public boolean equals(Matrix m2) {
if (this.r != m2.r || this.c != m2.c) {
return false;
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (this.neo[i][j] != m2.neo[i][j]) {
return false;
}
}
}
return true;
}//equalsMethod
public Matrix multiply(Matrix m2) throws Exception {
if (this.c != m2.r) {
throw new RuntimeException();
}//if
Matrix m3 = new Matrix(this.r, m2.c);
for (int i = 0; i < this.r; i++) {
for (int j = 0; j < m2.c; j++) {
m3.neo[i][j] = 0;
for (int k = 0; k < this.c; k++) {
m3.neo[i][j] += this.neo[i][k] * m2.neo[k][j];
}//forK
}//forJ
}//forI
return m3;
}//multiplyMethod
}//class
Change your scaleMult method to this and it should work:
public void scaleMult(int k) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
this.neo[i][j] *= k;
// you forgot to assign the value, basically we multiply neo[i][j] by k and make neo[i][j] receive that value
// making this.neo[i][j] = this.neo[i][j] *k; would work as well
}
}
}//scaleMult
Also, based on the example you provided on your main method, your code will launch an exception on the multiply method, because as you specified, you can only multiply two matrixes if one's columns amount is equal to the other's row amount. Other than that, I would advise on creating a new class just for your main method.
If your question is multiply a matrix by a number, then here is a very simple example.
public static void main(String []args){
int[][] a = {{1,2,3},{4,5,6}};
int[][] b=new int[2][3];
int i,j,k=2;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
b[i][j]=a[i][j]*k;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
System.out.println(b[i][j]);
}
There must be some array variable on left which should be assigned the multiplied value.
Do this helped? If not, please post your complete code.

How do we rotate a tetris piece counter clockwise?

I looked at the algorithm here for clockwise rotation, but I can't do it the other way around. So basically, for clockwise rotation, you need to multiply the transpose to a rotation matrix, but how do you do the same thing the other way around?
Here's my code:
public class rotation2 {
public static int [][] multiplyMatrix(int [][] m1) {
int [][] m2 = {{0,0,0,1},
{0,0,1,0},
{0,1,0,0},
{1,0,0,0}};
int[][] result = new int[4][4];
// multiply
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
for (int k=0; k<4; k++)
result[i][j] += m1[i][k] * m2[k][j];
return result;
}
public static int [][] multiplyMatrix2(int [][] m2) {
int [][] m1 = {{0,0,0,1},
{0,0,1,0},
{0,-1,0,0},
{-1,0,0,0}};
int[][] result = new int[4][4];
// multiply
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
for (int k=0; k<4; k++)
result[i][j] += m1[i][k] * m2[k][j];
return result;
}
public static void printArray(int [][] array) {
for(int row = 0; row < array.length; row++) {
for(int col = 0; col < array[row].length; col++) {
if (array[row][col] > 0) {
System.out.printf("1");
} else {
System.out.printf("0");
}
}
System.out.printf("\n");
}
}
public static int [][] transpose(int [][] m1) {
int m = 4;
int n = 4;
int c = 0;
int d = 0;
int[][] transpose = new int [n][m];
for ( c = 0 ; c < m ; c++ ) {
for ( d = 0 ; d < n ; d++ ) {
transpose[d][c] = m1[c][d];
}
}
return transpose;
}
public static void main(String[] args) {
int [][] m1 = {{1,0,0,0},
{1,0,0,0},
{1,1,0,0},
{0,0,0,0}};
int [][] transpose = transpose(m1);
printArray(transpose);
transpose = multiplyMatrix(transpose);
printArray(transpose);
int [][] transpose2 = transpose(m1);
printArray(transpose2);
transpose2 = multiplyMatrix(transpose2);
printArray(transpose2);
}
}
You don't transpose for counter clock rotation, right?
What you have to do is to (1) transpose the matrix, and (2) inverse the rows (clockwise) or columns (counter-clockwise), respectively.
You can just use a double-for-loop to set the new values for the individual cells, doing both steps at the same time. In code, this might look like this:
public static int[][] rotate(int[][] m, boolean left) {
int rows = m.length, cols = m[0].length;
int[][] m2 = new int[cols][rows]; // swap rows and cols
for (int r = 0; r < rows; r++)
for (int c = 0; c < cols; c++)
if (left) // rotate left
m2[c][r] = m[r][cols - c - 1];
else // rotate right
m2[c][r] = m[rows - r - 1][c];
return m2;
}
For more information and alternative approaches, take a look at the answers to this related question.

Sorting with 2D Arrays

I need help with sorting Random numbers into a 2D array. I have to generate 50 random numbers into a column of the array, then sort the numbers in order (ascending or descending). This is what I have so far and am so lost. Please Help.
UPDATED VERSION
public static void main(String[] args)
{
int rows = 2;
int columns = 50;
int[][] anArray = new int[rows][columns];
Random rand = new Random();
for (int i = 0; i < anArray.length; i++)
{
for (int j = 0; j < anArray[0].length; j++)
{
int n = rand.nextInt(100);
anArray[i][j] = n;
}
}
int []temp;
for (int i=0;i<anArray.length;i++)
{
for (int j=0;j<anArray.length-i;j++ )
{
if (anArray[i][j]>anArray[i][j+1])
{
temp =anArray[j];
anArray[j+1]=anArray[j];
anArray[j+1]=temp;
}
}
}
for (int i = 0; i < anArray.length; i++)
{
for (int j=0;j<anArray.length-i;j++ )
{
System.out.println(anArray[i][j]);
}
}
}
}
You can sort 2D arrays on their initial element using a custom Comparator:
Arrays.sort(anArray, new Comparator<int[]>() {
public int compare(int[] lhs, int[] rhs) {
return lhs[0]-rhs[0];
}
});
First of all, you need nested for loops in order to properly insert the random numbers into the two dimensional array. I have also updated my response to show how the sorting should be done. Hope this helps!
EDITED TO SATISFY REQUIREMENTS MENTIONED IN COMMENT BELOW.
import java.util.Arrays;
import java.util.Random;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
int rows = 2;
int columns = 50;
int[][] anArray = new int[rows][columns];
Random rand = new Random();
//initialize the first row only
for (int j = 0; j < anArray[0].length; j++)
{
int n = rand.nextInt(100);
anArray[0][j] = n;
}
System.out.println("-----------Before the Sort----------------");
for (int i = 0; i < anArray.length; i++)
{
for (int j = 0; j < anArray[0].length; j++)
{
System.out.print(anArray[i][j] + ", "); //format any way you want
}
System.out.println(); //to make each row print on a new line.
}
anArray = mySort(anArray);
System.out.println("-----------After the Sort----------------");
for (int i = 0; i < anArray.length; i++)
{
for (int j = 0; j < anArray[0].length; j++)
{
System.out.print(anArray[i][j] + ", "); //format any way you want
}
System.out.println(); //to make each row print on a new line.
}
}
private static int[][] mySort(int[][] anArray) {
int [][] result = new int[anArray.length][anArray[0].length];
int thisRow[] = getRow(anArray, 0);
Arrays.sort(thisRow);
for(int j = 0; j < thisRow.length; j++){
result[0][j] = anArray[0][j];
result[1][j] = thisRow[j];
}
return result;
}
private static int[] getRow(int[][] anArray, int row) {
int thisRow[] = new int[anArray[row].length];
for(int j = 0; j < anArray[row].length; j++){
thisRow[j] = anArray[row][j];
}
return thisRow;
}
}
You can sort by considering the 2D array 1D. Let's consider a 3x4 array.
1st element's index is 0, 2nd is 1, 3rd is 2, 4th is 3, 5th is 4, etc.
General formula to convert from a 1D index to a 2D:
row_index = _1D_index % nRows;
col_index = _1D_index % nCols;
For example the 5th element has the 1D index of 4, to get the row: 4 % 3 = 1, to get the col, 4 % 4 = 0, so your element is at 1,0. What's the point of all this? Now you can just make a function
int GetAt(int index)
{
return array[index % nRows][index % nCols];
}
and something along the lines of:
void Swap(int index1, int index2)
{
int r1 = index1 % nRows;
int c1 = index1 % nCols;
int r2 = index2 % nRows;
int c2 = index2 % nCols;
int temp = array[r1][c1];
array[r1][c1] = array[r2][c2];
array[r2][c2] = temp;
}
And sort the array as if it was one dimensional :)

Categories