user182078
user182078

Reputation: 63

Multiplying 3-dimensional arrays in Java

The problem is this: say you have a 3d array, Z (so int[][][] Z = new int[n][n][n]). What you are trying to do is print out a new 3d array, that is a multiplication of Z, X times.

Say you have

z[3][3][3] = {
                   {{3,3,3}{3,3,3}}
                   {{3,3,3}{3,3,3}}
                   {{3,3,3}{3,3,3}}
                  }

and x = 3 (user input)

The goal is to print out this:

Z[0]
Z[1]
XXXXXXX
Z[0]*Z[0]
Z[1]*Z[1]
XXXXXXX
Z[0]*Z[0]*Z[0]
Z[1]*Z[1]*Z[1]

Since this is a square (actually cube...) matrix, each printed out matrix will be the same dimensions. What I have so far is this:

   public static void main(String[] args) {
    Scanner getIt = new Scanner(System.in);
    System.out.println("Input 1 integer n: ");
    int n = getIt.nextInt();
    if (n > 0){
        final double M[][][] = new double[n][n][n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                for (int k = 0; k < n; k++)
                    M[i][j][k] = 3.0;
        System.out.println("Input 1 integer p: ");
        int p = getIt.nextInt();
        if(p > 0){
          for(int q = 1; q <= p; q++){
              for (int i = 0; i < n; i++){
                  for (int j = 0; j < n; j++){
                      for (int k = 0; k < n; k++){
                          System.out.printf("%f ", Math.pow(matrixMult(M[i], M[i])[j][k], q));
                      }
                      System.out.println("\n");
                  }

              }
              System.out.println("xxxxxxxxxxxxxxxxxxxxx");
          }
        }
        else{
            System.out.println("Woops, you entered a negative p.");
        }
    }
    else{
        System.out.println("Woops, you entered a negative n.");
    }
}

public static double[][] matrixMult(double a[][], double b[][]) {   
    int aRows = a.length; 
    int aCols = a[0].length; 
    int bCols = b[0].length;
    double[][] result = new double[aRows][bCols];   
    for(int i = 0; i < aRows; i++){ 
        for(int j = 0; j < bCols; j++){ 
            for(int k = 0; k < aCols; k++){ 
                result[i][j] += a[i][k] * b[k][j];      
                }
            }  
        }   
    return result;
}

Upvotes: 4

Views: 7043

Answers (1)

sarnold
sarnold

Reputation: 104050

Paulsm4's advice is dead-on -- you don't want to do the entire thing in just two functions. You should have the input array, user input, multiplication, and output, each in their own functions. You may find other opportunities to split apart your program as you're working on it -- I strongly recommend breaking your program down into functions as much as possible, especially because you can debug small pieces far more effectively than you can large pieces. (What's wrong with your current program? Input? Output? Calculation? Data storage sizes, as Adam noticed? It's difficult to tell, because you don't know which functions work perfectly and which are still buggy.)

I'd like to suggest a further change: don't put the else clauses of your tests so far away, if you can help it. Consider changing this:

int n = getIt.nextInt();
if (n > 0){
/* loop */
    System.out.println("Input 1 integer p: ");
    int p = getIt.nextInt();
    if(p > 0){
    /* loop loop loop */
    }
    else{
        System.out.println("Woops, you entered a negative p.");
    }
}
else{
    System.out.println("Woops, you entered a negative n.");
}

to this:

int n = getIt.nextInt();
if (n <= 0) {
    System.out.println("Woops, you entered a negative n.");
/* exit or recover */
}

System.out.println("Input 1 integer p: ");
int p = getIt.nextInt();
if (p <= 0) {
    System.out.println("Woops, you entered a negative p.");
/* exit or recover */
}

/* loop */

/* loop loop loop */

Writing the code this way will make maintenance far easier and will probably also make it easier to spot units that can be removed into their own routines. (Consider a function that takes a String prompt and Scanner in parameters and returns a number greater than zero -- it can prompt and re-prompt as necessary and the result will be exactly what your main code needs -- keeping it as clean as possible. This function is more obviously useful when the code is re-written in this fashion.)

As for the bug that brought you here, I think this is probably the culprit:

System.out.printf("%f ", Math.pow(matrixMult(M[i], M[i])[j][k], q));

You're calculating a lot here but not storing the results at all. Won't you need those results for further calculation?

Upvotes: 1

Related Questions