Вопрос

Im trying to make a method in java that multiplies two matrices using integers as arguments to tell where in the matrices Im working, and recursively "slice up" the matrices to smaller parts and multiply them together from here using the so called Divide and Conquer (it is a school task to do so, allthough it sure is a hard way to multiply two matrices!). Unsurprisingly, after my code have finished running, the matrice does not show what I would expect. In my main method, I have 3 matrices of size n*n (n=2, 4, 8, 16...), so they are squares. Im multiplying matrice A and B into matrice D. My main method is inside matrix class. This is how my code looks now:

public class indexMult {
matrix mat = new matrix();


public void calc(int Ay, int Ax, int By, int Bx, int Dy, int Dx, int size){

    System.out.println(Ay +" "+ Ax +" "+ By +" "+ Bx +" "+ Dy +" "+ Dx +" "+ size);
    if(size==2){

        mat.D[Dy][Dx] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy+1][Dx] = mat.A[Ay+1][Ax] * mat.B[By][Bx] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy][Dx+1] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx+1];
        mat.D[Dy+1][Dx+1] = mat.A[Ay+1][Ax] * mat.B[By][Bx+1] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];


    }else{

        size = size/2;  
        for(int i=0; i<size; i++){
            for(int j=0; j<size; j++){

                calc(i, j, i, j, i, j, size);
                calc(i, size+j, i, size+j, i, size+j, size);
                calc(size+i, j, size+i, j, size+i, j, size);
                calc(size+i, size+j, size+i, size+j, size+i, size+j, size);

            }   
        }           
    }
}               

}

This method changes matrice D directly. To make it easier, Im using 2 in every spot in matrice A and B. There is also an issue in the way I have formulated my code, as the results are not right - but I have not come to this issue yet. My issue at this point is that no matter what I set n to, D only fills 5x5. If I use n as 4 or 2, I get an Array Index Out of Bounds Exception (because Im obviously trying to fill a 4x4 matrice with 5x5 data). But thats not what I want my code to do! The idea behind my code is to divide the n in n*n (int size) by 2, and from here do a recursive call with each quarter of the matrice until the size is 2x2 and I can solve that part. Im probably lacking a piece to add together the quarter matrices, but Im not that far yet - Im having trouble filling the whole matrice as it stops after 5x5. Are anyone able to spot the error??

EDIT:

With help from answer bellow, and some fixies myself, this change seems to work - not only for my issue, but to actually calculate what I need! :))

calc(Ay, Ax, By, Bx, Dy, Dx, size);
        calc(Ay, Ax+size, By+size, Bx, Dy, Dx, size);

        calc(Ay, Ax, By, Bx+size, Dy, Dx+size, size);
        calc(Ay, Ax+size, By+size, Bx+size, Dy, Dx+size, size);

        calc(Ay+size, Ax, By, Bx, Dy+size, Dx, size);
        calc(Ay+size, Ax+size, By+size, Bx, Dy+size, Dx, size);

        calc(Ay+size, Ax, By, Bx+size, Dy+size, Dx+size, size);
        calc(Ay+size, Ax+size, By+size, Bx+size, Dy+size, Dx+size, size);
Это было полезно?

Решение

Probably something along these lines would work:

public class indexMult {
matrix mat = new matrix();


public void calc(int Ay, int Ax, int By, int Bx, int Dy, int Dx, int size){

    System.out.println(Ay +" "+ Ax +" "+ By +" "+ Bx +" "+ Dy +" "+ Dx +" "+ size);
    if(size==2){

        mat.D[Dy][Dx] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy+1][Dx] = mat.A[Ay+1][Ax] * mat.B[By][Bx] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy][Dx+1] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx+1];
        mat.D[Dy+1][Dx+1] = mat.A[Ay+1][Ax] * mat.B[By][Bx+1] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];


    }else{

        size = size/2;  
        calc(Ay, Ax, By, Bx, Dy, Dx, size);
        calc(Ay, Ax+size, By, Bx+size, Dy, Dx+size, size);
        calc(Ay+size, Ax, By+size, Bx, Dy+size, Dx, size);
        calc(Ay+size, Ax+size, By+size, Bx+size, Dy+size, Dx+size, size);
    }
}

I have just replaced the loop with recursion to simply just recursion.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top