Matrixmult. Parallel mit split und merge

Objektorientierte Programmiersprache auf Basis einer virtuellen Maschine (https://www.oracle.com/java/)
Antworten
Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Matrixmult. Parallel mit split und merge

Beitrag von Zenerid » So Dez 03, 2017 7:58 am

Ich habe derzeit ein Problem, einen Algorithmus zu realisieren, und zwar würde ich gerne Matrizen parallel multiplizieren. So soll das ganze als Beispiel für eine 2x2 Matrix aussehen:
split.jpg
Die beiden Matrizen A und B sollen dabei also vorher in viele kleine 2x2 Matrizen gesplittet werden und dann sollen gemäß dem Bild die einzelnen Elemente der Ergebnismatrix C berechnet werden, was parallel ablaufen soll und am Ende soll auch die Ergebnismatrix, die ja aus vielen Untermatrizen besteht wieder "gemerged" werden, ganz nach dem Prinzip split und merge (Teile und Herrsche).
Ich bin bei der Implementierung aber auf ein Problem gestoßen und find den Fehler aber einfach nicht.

Code: Alles auswählen

public static Matrix parallelMult(final Matrix matA, final Matrix matB) {	
	Matrix[][] matASplit = split(matA);
	Matrix[][] matBSplit = split(matB);
	
	final int matASplitRows = matASplit.length;
	final int matBSplitCols = matBSplit[0].length;
	final int cpuCount = Runtime.getRuntime().availableProcessors();
	
	Matrix[][] matCSplit = new Matrix[matASplitRows][matBSplitCols];
	Matrix.initializeEmpty(matCSplit);
	
	BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(matASplitRows * matBSplitCols + 1);
	ThreadPoolExecutor threadpool = new ThreadPoolExecutor(cpuCount, cpuCount + 2, 10, TimeUnit.MINUTES, workQueue);
		
	for(int i = 0; i < matASplitRows; i++) {
		final int iF = i;
		for(int l = 0; l < matBSplitCols; l++) {
			final int lF = l;
			threadpool.execute(new Runnable() {    	
				int j, k;
				@Override
				public void run() {		        		
					for(j = 0; j < 2; j++) {
						for (k = 0; k < 2; k++) {		
							matCSplit[iF][lF].data[j][k] += matASplit[iF][lF].data[j][0] * matBSplit[iF][lF].data[0][k] + 
															  matASplit[iF][lF].data[j][1] * matBSplit[iF][lF].data[1][k];
						}		        			 
					}
				}
			});
		}
	}
	
	try {
		threadpool.shutdown();
		if(!threadpool.awaitTermination(200, TimeUnit.MILLISECONDS)) {
			threadpool.shutdownNow();
			threadpool.awaitTermination(200, TimeUnit.MILLISECONDS);
		}
	} catch(InterruptedException e) {
		e.printStackTrace();
	}
	
	return Matrix.merge(matCSplit);
}

private static Matrix[][] split(Matrix mat) {
	int currentRowIndex = 0;
	int currentColIndex = 0;
	int currentNewMatRow = 0;
	int currentNewMatCol = 0;

	final double splittedMatRows = Math.round(((double) mat.getNumberOfRows() / 2));
	final double splittedMatCols = Math.round(((double) mat.getNumberOfColumns() / 2));
	Matrix[][] splittedMatrix = new Matrix[(int) splittedMatRows][(int) splittedMatCols];
	
	double[][] newMatData;
	while(currentNewMatRow < splittedMatRows && currentRowIndex < (mat.getNumberOfRows() - 1)) {
		while(currentNewMatCol < splittedMatCols && currentColIndex < (mat.getNumberOfColumns() - 1)) {
			newMatData = new double[2][2];
			for(int j = 0; j < 2; j++) {
				for(int k = 0; k < 2; k++) {
					newMatData[j][k] = mat.data[j + currentRowIndex][k + currentColIndex];
				}
			}
			currentColIndex += 2;
			splittedMatrix[currentNewMatRow][currentNewMatCol++] = new Matrix(newMatData);
		}
		
		currentColIndex = 0;
		currentRowIndex += 2;
		currentNewMatRow++;
		currentNewMatCol = 0;
	}
	
	return splittedMatrix;	
}

private static Matrix merge(Matrix[][] matToMerge) {	
	final int splittedMatRows = matToMerge.length;
	final int splittedMatCols = matToMerge[0].length;
	
	final int mergedMatRows = splittedMatRows * 2;
	final int mergedMatCols = splittedMatCols * 2;
	
	double[][] mergedMatrix = new double[mergedMatRows][mergedMatCols];
	for(int i = 0; i < splittedMatRows; i++) {
		for(int j = 0; j < splittedMatCols; j++) {
			
			for(int k = 0; k < 2; k++) {
				for(int l = 0; l < 2; l++) {
					mergedMatrix[k + i][j + l] = matToMerge[i][j].data[k][l];
				}
			}
		}
	}
	return new Matrix(mergedMatrix);		
}

Das hier ist ein Junit Test, der leider nur für den ersten Testfall ein grün gibt. Die anderen beiden sind rot, bzw. nur der este, da jUnit ja beim ersten fehlgeschlagenem Test in einer Methode ja aufhört. bzw. abbricht.

Code: Alles auswählen

@Test
public final void testParallelMult() throws IllegalArgumentException {
	Matrix matA;
	Matrix matB;
	Matrix resultMat;
	Matrix expectedResultMat;
	
	matA = new Matrix(new double[][] {{1,2},{3,4}});
	matB = new Matrix(new double[][] {{2,3},{4,5}});
	expectedResultMat = new Matrix(new double[][] {{10,13},{22,29}});
	
	resultMat = Matrix.parallelMult(matA, matB);
	assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
	
	matA = new Matrix(new double[][] {{1,2},{3,4}});
	matB = new Matrix(new double[][] {{2,3,4},{5,6,7}});	
	expectedResultMat = new Matrix(new double[][] {{12,15,18},{26,33,40}});
	
	resultMat = Matrix.parallelMult(matA, matB);
	assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
	
	matA = new Matrix(new double[][] {{1,2},{3,4},{5,6}});
	matB = new Matrix(new double[][] {{2,3},{4,5}});
	expectedResultMat = new Matrix(new double[][] {{10,13},{22,29},{34,45}});
}
Da ihr vielleicht so das ganze auch ganz einfach zum laufen bringen könnt, hier mal meine Klasse Matrix, mit den entsprechend benötigten Methoden. Ich hoffe mal, dass es so passt, die ganze Klasse wäre mittlerweile ein wenig zu umfangreich. :D

Code: Alles auswählen

public class Matrix {
	private final int rows;
	private final int columns;
	private double data[][];
	
	public Matrix(double matrix[][]) {
		this.data = matrix;
		this.rows = matrix.length;
		this.columns = matrix[0].length;
	}

	@Override
	public boolean equals(Object other) {
		if(other == null) return false;
		if(other == this) return true;
		
		int i, j;
	    final Matrix otherMatrix = (Matrix) other;
		final int otherMatrixRows = otherMatrix.rows;
		final int otherMatrixColumns = otherMatrix.columns;
		
		if(this.getNumberOfRows() != otherMatrixRows || this.getNumberOfColumns() != otherMatrixColumns) 
			return false;
		
		for(i = 0; i < otherMatrixRows; i++) {
			for(j = 0; j < otherMatrixColumns; j++) {
				if(this.data[i][j] != otherMatrix.data[i][j])
					return false;
			}
		}
		
		return true;
	}
	
	@Override
	public String toString() {
		int i, j;
		String matWrapper = "";
		String retString = "";
		final String minusAColumn = "------------";
		
		for(i = 0; i < this.getNumberOfColumns(); i++)
			matWrapper += minusAColumn;
		matWrapper += "-";
		
		retString += matWrapper + "\n";
		
		for(i = 0; i < this.getNumberOfRows(); i++) {			
			for(j = 0; j < this.getNumberOfColumns(); j++) {
				retString += String.format("| %10.0f", this.data[i][j]); // 10.2f
			}
			retString += "|\n";
		}
		
		retString += matWrapper + "\n";
		return retString;
	}
	
	
	public static Matrix parallelMult(final Matrix matA, final Matrix matB) {	
		Matrix[][] matASplit = split(matA);
	    Matrix[][] matBSplit = split(matB);
	    
	    final int matASplitRows = matASplit.length;
	    final int matBSplitCols = matBSplit[0].length;
		final int cpuCount = Runtime.getRuntime().availableProcessors();
		
	    Matrix[][] matCSplit = new Matrix[matASplitRows][matBSplitCols];
	    Matrix.initializeEmpty(matCSplit);
	    
		BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(matASplitRows * matBSplitCols + 1);
		ThreadPoolExecutor threadpool = new ThreadPoolExecutor(cpuCount, cpuCount + 2, 10, TimeUnit.MINUTES, workQueue);
		    
	    for(int i = 0; i < matASplitRows; i++) {
	    	final int iF = i;
	    	for(int l = 0; l < matBSplitCols; l++) {
	    		final int lF = l;
			    threadpool.execute(new Runnable() {    	
			    	int j, k;
		            @Override
		            public void run() {		        		
		        		for(j = 0; j < 2; j++) {
		        			for (k = 0; k < 2; k++) {		
			        			matCSplit[iF][lF].data[j][k] += matASplit[iF][lF].data[j][0] * matBSplit[iF][lF].data[0][k] + 
			        											  matASplit[iF][lF].data[j][1] * matBSplit[iF][lF].data[1][k];
		        			}		        			 
		        		}
		            }
		        });
	    	}
	    }
	    
		try {
			threadpool.shutdown();
			if(!threadpool.awaitTermination(200, TimeUnit.MILLISECONDS)) {
				threadpool.shutdownNow();
				threadpool.awaitTermination(200, TimeUnit.MILLISECONDS);
			}
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
		
		return Matrix.merge(matCSplit);
	}
	
	private static Matrix[][] split(Matrix mat) {
		int currentRowIndex = 0;
		int currentColIndex = 0;
		int currentNewMatRow = 0;
		int currentNewMatCol = 0;
	
		final double splittedMatRows = Math.round(((double) mat.getNumberOfRows() / 2));
		final double splittedMatCols = Math.round(((double) mat.getNumberOfColumns() / 2));
		Matrix[][] splittedMatrix = new Matrix[(int) splittedMatRows][(int) splittedMatCols];
		
		double[][] newMatData;
		while(currentNewMatRow < splittedMatRows && currentRowIndex < (mat.getNumberOfRows() - 1)) {
			while(currentNewMatCol < splittedMatCols && currentColIndex < (mat.getNumberOfColumns() - 1)) {
				newMatData = new double[2][2];
				for(int j = 0; j < 2; j++) {
					for(int k = 0; k < 2; k++) {
						newMatData[j][k] = mat.data[j + currentRowIndex][k + currentColIndex];
					}
				}
				currentColIndex += 2;
				splittedMatrix[currentNewMatRow][currentNewMatCol++] = new Matrix(newMatData);
			}
			
			currentColIndex = 0;
			currentRowIndex += 2;
			currentNewMatRow++;
			currentNewMatCol = 0;
		}
		
		return splittedMatrix;	
	}
	
	private static Matrix merge(Matrix[][] matToMerge) {	
		final int splittedMatRows = matToMerge.length;
		final int splittedMatCols = matToMerge[0].length;
		
		final int mergedMatRows = splittedMatRows * 2;
		final int mergedMatCols = splittedMatCols * 2;
		
		double[][] mergedMatrix = new double[mergedMatRows][mergedMatCols];
		for(int i = 0; i < splittedMatRows; i++) {
			for(int j = 0; j < splittedMatCols; j++) {
				
				for(int k = 0; k < 2; k++) {
					for(int l = 0; l < 2; l++) {
						mergedMatrix[k + i][j + l] = matToMerge[i][j].data[k][l];
					}
				}
			}
		}
		return new Matrix(mergedMatrix);		
	}
}
So könnt ihr auch meinen kleinen einzelnen Test laufen lassen. Ich hoffe wirklich, dass mir hier jemand helfen kann. Ich suche jetzt mittlerweile schon sehr lange nach dem Fehler aber ich finde ihn einfach nicht. Ich hoffe jemand kann helfen.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Matrixmult. Parallel mit split und merge

Beitrag von nufan » So Dez 03, 2017 6:24 pm

Hallo Zenerid :)

Ich schaue mir dein Problem gerne an, allerdings ist dein Code unvollständig und nicht kompilierbar. Ich hab versucht die fehlenden Teile nachzubauen und lande sofort bei einer ArrayIndexOutOfBoundsException in der run()-Methode.

Der wesentliche Unterschied zwischen dem ersten und dem zweiten Testcase ist die Dimensionierung der Matrizen. Du musst beachten, dass die Matrizen A und B eine unterschiedliche Größe haben (daher auch eine unterschiedliche Anzahl an Split-Matrizen). Entweder erlaubst du nur die Multiplikation von korrekt dimensionierten Matrizen oder du ergänzt die kleinere Matrix.

Von solchen Konstrukten würde ich dir auch abraten:

Code: Alles auswählen

final double splittedMatRows = Math.round(((double) mat.getNumberOfRows() / 2));
Floating Point Abweichungen können zu schwer zu findenden Fehlern führen. Eine sicherere Lösung im ganzzahligen Bereich:

Code: Alles auswählen

final int splittedMatRows = mat.getNumberOfRows() / 2 + mat.getNumberOfRows() % 2;

Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Re: Matrixmult. Parallel mit split und merge

Beitrag von Zenerid » Mo Dez 04, 2017 6:31 am

Hallo nufan,

vielen Dank schon einmal für deine Antwort! Ich muss wohl vielmals um Entschuldigung bitten, weil ich das ganze eigentlich noch einmal testen hätte müssen, bevor ich da etwas rauskopiere und zusammenfüge. Ist wie schon gesagt nicht die ganze Matrix Klasse. :oops:

Hier jetzt aber mal getestet:

Code: Alles auswählen

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Matrix {
   private final int rows;
   private final int columns;
   private double data[][];
   
   public Matrix(double matrix[][]) {
      this.data = matrix;
      this.rows = matrix.length;
      this.columns = matrix[0].length;
   }

   @Override
   public boolean equals(Object other) {
      if(other == null) return false;
      if(other == this) return true;
      
      int i, j;
      final Matrix otherMatrix = (Matrix) other;
      final int otherMatrixRows = otherMatrix.rows;
      final int otherMatrixColumns = otherMatrix.columns;
      
      if(this.getNumberOfRows() != otherMatrixRows || this.getNumberOfColumns() != otherMatrixColumns)
         return false;
      
      for(i = 0; i < otherMatrixRows; i++) {
         for(j = 0; j < otherMatrixColumns; j++) {
            if(this.data[i][j] != otherMatrix.data[i][j])
               return false;
         }
      }
      
      return true;
   }
   
   @Override
   public String toString() {
      int i, j;
      String matWrapper = "";
      String retString = "";
      final String minusAColumn = "------------";
      
      for(i = 0; i < this.getNumberOfColumns(); i++)
         matWrapper += minusAColumn;
      matWrapper += "-";
      
      retString += matWrapper + "\n";
      
      for(i = 0; i < this.getNumberOfRows(); i++) {         
         for(j = 0; j < this.getNumberOfColumns(); j++) {
            retString += String.format("| %10.0f", this.data[i][j]); // 10.2f
         }
         retString += "|\n";
      }
      
      retString += matWrapper + "\n";
      return retString;
   }
   
	private static void initializeEmpty(Matrix[][] mat) {
		double[][] newMatData = new double[2][2];
		
		for(int i = 0; i < mat.length; i++) {
    		for(int j = 0; j < mat[0].length; j++) {
    			mat[i][j] = new Matrix(newMatData);
    		}
        }
	}
   
	public int getNumberOfRows() {
		return rows;
	}

	public int getNumberOfColumns() {
		return columns;
	}
   
   public static Matrix parallelMult(final Matrix matA, final Matrix matB) {   
      final Matrix[][] matASplit = split(matA);
      final Matrix[][] matBSplit = split(matB);
      
      final int matASplitRows = matASplit.length;
      final int matBSplitCols = matBSplit[0].length;
      final int cpuCount = Runtime.getRuntime().availableProcessors();
  
      final Matrix[][] matCSplit = new Matrix[matASplitRows][matBSplitCols];
      Matrix.initializeEmpty(matCSplit);
      
      BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(matASplitRows * matBSplitCols + 1);
      ThreadPoolExecutor threadpool = new ThreadPoolExecutor(cpuCount, cpuCount + 2, 10, TimeUnit.MINUTES, workQueue);
         
       for(int i = 0; i < matASplitRows; i++) {
          final int iF = i;
          for(int l = 0; l < matBSplitCols; l++) {
             final int lF = l;
             threadpool.execute(new Runnable() {       
                int j, k;
                  public void run() {                    
                    for(j = 0; j < 2; j++) {
                       for (k = 0; k < 2; k++) {      
                          matCSplit[iF][lF].data[j][k] += matASplit[iF][lF].data[j][0] * matBSplit[iF][lF].data[0][k] +
                                                    matASplit[iF][lF].data[j][1] * matBSplit[iF][lF].data[1][k];
                       }                       
                    }
                  }
              });
          }
       }
      
      try {
         threadpool.shutdown();
         if(!threadpool.awaitTermination(200, TimeUnit.MILLISECONDS)) {
            threadpool.shutdownNow();
            threadpool.awaitTermination(200, TimeUnit.MILLISECONDS);
         }
      } catch(InterruptedException e) {
         e.printStackTrace();
      }
      
      return Matrix.merge(matCSplit);
   }
   
   private static Matrix[][] split(Matrix mat) {
      int currentRowIndex = 0;
      int currentColIndex = 0;
      int currentNewMatRow = 0;
      int currentNewMatCol = 0;
   
      final double splittedMatRows = Math.round(((double) mat.getNumberOfRows() / 2));
      final double splittedMatCols = Math.round(((double) mat.getNumberOfColumns() / 2));
      Matrix[][] splittedMatrix = new Matrix[(int) splittedMatRows][(int) splittedMatCols];
      
      double[][] newMatData;
      while(currentNewMatRow < splittedMatRows && currentRowIndex < (mat.getNumberOfRows() - 1)) {
         while(currentNewMatCol < splittedMatCols && currentColIndex < (mat.getNumberOfColumns() - 1)) {
            newMatData = new double[2][2];
            for(int j = 0; j < 2; j++) {
               for(int k = 0; k < 2; k++) {
                  newMatData[j][k] = mat.data[j + currentRowIndex][k + currentColIndex];
               }
            }
            currentColIndex += 2;
            splittedMatrix[currentNewMatRow][currentNewMatCol++] = new Matrix(newMatData);
         }
         
         currentColIndex = 0;
         currentRowIndex += 2;
         currentNewMatRow++;
         currentNewMatCol = 0;
      }
      
      return splittedMatrix;   
   }
   
   private static Matrix merge(Matrix[][] matToMerge) {   
      final int splittedMatRows = matToMerge.length;
      final int splittedMatCols = matToMerge[0].length;
      
      final int mergedMatRows = splittedMatRows * 2;
      final int mergedMatCols = splittedMatCols * 2;
      
      double[][] mergedMatrix = new double[mergedMatRows][mergedMatCols];
      for(int i = 0; i < splittedMatRows; i++) {
         for(int j = 0; j < splittedMatCols; j++) {
            
            for(int k = 0; k < 2; k++) {
               for(int l = 0; l < 2; l++) {
                  mergedMatrix[k + i][j + l] = matToMerge[i][j].data[k][l];
               }
            }
         }
      }
      return new Matrix(mergedMatrix);      
   }
}
An dem Test hat sich sonst so eigentlich nichts geändert, außer das ich noch ein paar größere Matrizen hinzugefügt habe, daher hier noch einmal die Testklasse.

Code: Alles auswählen

import org.junit.Test;
import static org.junit.Assert.*;

public class MatrixTests {
	@Test
	public final void testParallelMult() throws IllegalArgumentException {
		Matrix matA;
		Matrix matB;
		Matrix resultMat;
		Matrix expectedResultMat;
		
		matA = new Matrix(new double[][] {{1,2},{3,4}});
		matB = new Matrix(new double[][] {{2,3},{4,5}});
		expectedResultMat = new Matrix(new double[][] {{10,13},{22,29}});
		
		resultMat = Matrix.parallelMult(matA, matB);
		assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
		
		matA = new Matrix(new double[][] {{1,2},{3,4}});
		matB = new Matrix(new double[][] {{2,3,4},{5,6,7}});	
		expectedResultMat = new Matrix(new double[][] {{12,15,18},{26,33,40}});
		
		resultMat = Matrix.parallelMult(matA, matB);
		assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
		
		matA = new Matrix(new double[][] {{1,2},{3,4},{5,6}});
		matB = new Matrix(new double[][] {{2,3},{4,5}});
		expectedResultMat = new Matrix(new double[][] {{10,13},{22,29},{34,45}});
		
		resultMat = Matrix.parallelMult(matA, matB);
		assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
		
		matA = new Matrix(new double[][] {{1,2,3},{4,5,6},{7,8,9}});
		matB = new Matrix(new double[][] {{2,3,4},{5,6,7},{8,9,10}});
		expectedResultMat = new Matrix(new double[][] {{36,42,48},{81,96,111},{126,150,174}});
		
		resultMat = Matrix.parallelMult(matA, matB);
		assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
			
//		matA = new Matrix(new double[][] {{1,2,3,4},{5,6,7,8},{9,10,11,12}});
//		matB = new Matrix(new double[][] {{2,3,4,5},{6,7,8,9},{10,11,12,13},{14,15,16,17}});
//		expectedResultMat = new Matrix(new double[][] {{100,110,120,130},{228,254,280,306},{356,398,440,482}});
//		
//		resultMat = Matrix.parallelMult(matA, matB);
//		assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
		
//		matA = new Matrix(new double[][] {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}});
//		matB = new Matrix(new double[][] {{2,3,4,5},{6,7,8,9},{10,11,12,13},{14,15,16,17}});
//		expectedResultMat = new Matrix(new double[][] {{100,110,120,130},{228,254,280,306},{356,398,440,482},{484,542,600,658}});
//		
//		resultMat = Matrix.parallelMult(matA, matB);
//		assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
		
//		matA = new Matrix(new double[][] {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}});
//		matB = new Matrix(new double[][] {{2,3,4,5,6},{7,8,9,10,11},{12,13,14,15,16},{17,18,19,20,21},{22,23,24,25,26}});
//		expectedResultMat = new Matrix(new double[][] {{230,245,260,275,290},{530,570,610,650,690},{830,895,960,1025,1090},{1130,1220,1310,1400,1490},{1430,1545,1660,1775,1890}});
//		
//		resultMat = Matrix.parallelMult(matA, matB);
//		assertTrue("Wrong result!\nExpected:\n" + expectedResultMat.toString() + "Got:\n" + resultMat.toString(), expectedResultMat.equals(resultMat));
	}
}
Die beiden sollten dann nur noch im selben Package liegen und dann sollte es wenigstens so schon einmal laufen. Eigentlich soll das ganze auch für Matrizen laufen, die ungleiche Zeilen und Spalten haben aber ich glaube, dasss ich mir da selbst in's Bein geschossen habe, weil ja die Methoden static sind. Jetzt weiß ich nicht, wie ich die korrekte Anzahl an Zeilen und Spalten berechnen soll, was ja auch dann nachher zu einer NullPointerException führt. Ich stecke gerade daher fast komplett fest.

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Matrixmult. Parallel mit split und merge

Beitrag von nufan » Di Dez 05, 2017 4:08 pm

Du hast in einer Matrix weniger Split-Matrizen, weil du auch weniger Zellen zum Multiplizieren hast. Diesen Fall musst du über eine Überprüfung der Dimensionen entsprechend abfangen. Das machst du hier nicht:

Code: Alles auswählen

matCSplit[iF][lF].data[j][k] += matASplit[iF][lF].data[j][0] * matBSplit[iF][lF].data[0][k] +
        matASplit[iF][lF].data[j][1] * matBSplit[iF][lF].data[1][k];
Du verwendest für alle Matrizen die gleichen Indizes, ohne die unterschiedlichen Größen von A und B zu berücksichtigen.

Ich würde dir raten dein Schema mal mit kleinen Matrizen händisch durchzurechnen.

Antworten