N*N Matrix Determinante berechnen

AsterixdGallier

Aktives Mitglied
Hallo ich versuche schon bestimmt 6-7 stunden ein programm zu schreiben, dass mir eine determinante von einer n*n matrix berechnet. 3*3 klappt schon gut auch 4*4 ging bereits. Allerding kriege ich N*N einfach nicht hin.
Mein Code bis jetzt:

Java:
public class Mathetool {

	public static void main(String[] args) 
	{
		int n = 5;
		
		double [][] matrix = new double[n][n];
		matrix [0][0] = 2;
		matrix [0][1] = 3;
		matrix [0][2] = 3;
		matrix [0][3] = -2;
		matrix [0][4] = 3;

		matrix [1][0] = 3;
		matrix [1][1] = -2;
		matrix [1][2] = 2;
		matrix [1][3] = 4;
		matrix [1][4] = 0;
		
		matrix [2][0] = -2;
		matrix [2][1] = 1;
		matrix [2][2] = 3;
		matrix [2][3] = 0;
		matrix [2][4] = 10;
		
		matrix [3][0] = 4;
		matrix [3][1] = 2;
		matrix [3][2] = 4;
		matrix [3][3] = 5;
		matrix [3][4] = 6;
		
		matrix [4][0] = 1;
		matrix [4][1] = 0;
		matrix [4][2] = 7;
		matrix [4][3] = 2;
		matrix [4][4] = 3;
		
		Mathetool matheTool = new Mathetool();
		matheTool.determinanteAll(n, matrix);
	}
	
	public double determinanteAll(int n, double[][] matrix)
	{
		if (n == 3)
		{
			calculateDeterminante3x3(n, matrix);
		}
		else
		{
			calculateNxN(n, matrix);
		}	
		return n;
	}
	
	public double calculateDeterminante3x3(int n, double[][] matrix)
	{
			double determinante = 0;
			double zwischenErgebnisAddition = 0;
			double zwischenErgebnisSubtrahtion = 0;
			double matrixElement = 1;
			double matrixElement2 = -1;
			int j = 2;
			int k = 0;
			for (int p = 0; p < n; p++)
			{
				matrixElement = 1;
				matrixElement2 = -1;
				for (int i = 0; i < n; i++)
				{
					matrixElement = matrix[k][i] * matrixElement; 
					matrixElement2 = matrix[k][j] * matrixElement2;
					j = j - 1;
					if (j == -1)
					{
						j = n-1;
					}
					k = (k + 1)%n;
				}
				zwischenErgebnisAddition = zwischenErgebnisAddition + matrixElement;
				zwischenErgebnisSubtrahtion = zwischenErgebnisSubtrahtion + matrixElement2;
				determinante = zwischenErgebnisAddition + zwischenErgebnisSubtrahtion;
				k = k + 1;
				System.out.println(determinante);
			}	
		return determinante;
	}
	
	public double calculateNxN(int n, double [][] matrix)
	{
		double[][] matrixHelp = new double [n-1][n-1];
		double wholeDeterminante = 0;
		double ergebnis = 0;
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				int l = 0;
				for (int k = 1; k < n; k++)
				{
					matrixHelp[(j%(n-1))][l] = matrix[(j+i)%n][k];
					l = l + 1;
				}
			}
//			wholeDeterminante = calculateDeterminante3x3(3, matrixHelp) * matrix[i][0];
//			if ((i%2)!=0)
//			{
//				wholeDeterminante = wholeDeterminante * -1;
//			}			
//			System.out.println(matrixHelp[0][n-2]);
			n--;
			
			
			if (n == 3)
			{
				calculateDeterminante3x3(n, matrixHelp);
			}
			else if (n > 3)
			{
				calculateNxN(n, matrixHelp);
			}
			
//			ergebnis = wholeDeterminante + ergebnis;
//			n = n - 1;
//			calculateNxN(n, matrixHelp);
		}
		return ergebnis;
	}
}
Vllt denke ich viel zu kompliziert..
Kann mir jemand weiterhelfen??
 
N

nillehammer

Gast
Fachlich blicke ich nicht so durch (Matrizen sind schon etwas länger her bei mir). Dein Code sieht mir aber nach rekursiven Aufrufen aus. Dort, wo Du rekursive Aufrufe machst, musst Du natürlich irgendwas mit dem Rückgabewert der aufgerufenen Methode anfangen.

Und grundsätzlich: Baue Deine Methoden so auf, dass es eine public Methode gibt, die nur einmal aufgerufen wird. Diese ruft dann die rekursiven privaten Methoden mit passenden Parametern auf. Die rekursiven privaten Methoden schreibst Du so, dass Du die Abbruchbedingung für die Rekursion inkl. return-Statement an den Anfang stellst. Danach kommen die rekursiven Aufrufe auch mit einem return-Statement versehen.

Nachfolgender Beispielcode zum einfachen Nachvollziehen:
Java:
// Der public-Teil, der ein einziges Mal aufgerufen wird und gleich den Parameter validiert
public static int fakultaet(final int value) {
  if (value < 1) {
    throw new IllegalArgumentException("Value darf nicht kleiner 1 sein!");
  }
  return berechneFakultaet(value);
}

// Der private Teil mit geeigneten Returnvalue und Parametern für rekursiven Aufruf. Validierung ist hier
// nicht nötig. Die Methode ist private. Der einzige der sie verwenden kann, bist Du selbst. Du solltest
// in der Lage sein, die Methode mit gültigen Werten aufzurufen.
private static int berechneFakultaet(final int value) {
  // Die Abbruchbedingung mit entspr. Returnstatement
  if (value == 1) {
    return value;
  }

  // Der rekursive Aufruf
  return value * berechneFakultaet(value -1);
}
 
S

SlaterB

Gast
im rekursiven Aufruf soll das n kleiner sein, daher grundsätzlich schon ein Weg der nicht in Endlosschleife enden soll,

umgesetzt aber natürlich noch nicht gut, in einer Schleife
> for (int i = 0; i < n; i++)
kann unmöglich das n verringert werden,
der Rückgabewert des Rekursionsaufruf wird nicht verwendet, das stimmt, einige Zeilen sind auch auskommentiert

es fehlt einfach ne Menge, was soll man da sagen?
andere könnten den Rest dazuprogrammieren, aber naja ;)

sortiere doch in Ruhe deine Gedanken,
schaue dir ein Beispiel für 4 bzw. die eingetippen Werte für 5x5 genau an, was ist nach der Herleitung
Determinante ? Wikipedia
nach Laplacescher Entwicklungssatz (richtig?) im einzelnen zu tun, auf Papier gerechnet?
wie ist das im Programm umzusetzen?

sicherlich kaum durch eine Schleife in der i mal n--; bis auf 0 ausgeführt wird,
der grundsätzliche Ablauf muss doch mal geklärt werden
 

AsterixdGallier

Aktives Mitglied
im rekursiven Aufruf soll das n kleiner sein, daher grundsätzlich schon ein Weg der nicht in Endlosschleife enden soll,

umgesetzt aber natürlich noch nicht gut, in einer Schleife
> for (int i = 0; i < n; i++)
kann unmöglich das n verringert werden,
der Rückgabewert des Rekursionsaufruf wird nicht verwendet, das stimmt, einige Zeilen sind auch auskommentiert

es fehlt einfach ne Menge, was soll man da sagen?
andere könnten den Rest dazuprogrammieren, aber naja ;)

sortiere doch in Ruhe deine Gedanken,
schaue dir ein Beispiel für 4 bzw. die eingetippen Werte für 5x5 genau an, was ist nach der Herleitung
Determinante ? Wikipedia
nach Laplacescher Entwicklungssatz (richtig?) im einzelnen zu tun, auf Papier gerechnet?
wie ist das im Programm umzusetzen?

sicherlich kaum durch eine Schleife in der i mal n--; bis auf 0 ausgeführt wird,
der grundsätzliche Ablauf muss doch mal geklärt werden

n wird doch weniger muss jawohl auch, aus 5x5 soll ja schließlich 4x4 und so weiter werden. was noch fehlt ist meiner meinung nach, dass man die unterdeterminanten multipliziert.
 

AsterixdGallier

Aktives Mitglied
Dieser Code haut sowohl für 3x3 als auch für 4x4 hin.
Eigentlich ist doch nxn von prinzip her mit 4x4 identisch.
da kann es doch nicht sein dass ich noch viel verändern muss:
Java:
public class Mathetool {

	public static void main(String[] args) 
	{
		int n = 4;
		
		double [][] matrix = new double[n][n];
		matrix [0][0] = 2;
		matrix [0][1] = 3;
		matrix [0][2] = 3;
		matrix [0][3] = -2;

		matrix [1][0] = 3;
		matrix [1][1] = -2;
		matrix [1][2] = 2;
		matrix [1][3] = 4;
		
		matrix [2][0] = -2;
		matrix [2][1] = 1;
		matrix [2][2] = 3;
		matrix [2][3] = 0;
		
		matrix [3][0] = 4;
		matrix [3][1] = 2;
		matrix [3][2] = 4;
		matrix [3][3] = 5;
		
		Mathetool matheTool = new Mathetool();
		matheTool.determinanteAll(n, matrix);
	}
	
	public double determinanteAll(int n, double[][] matrix)
	{
		if (n == 3)
			{
				calculateDeterminante3x3(n, matrix);
			}
		else
		{
				System.out.println(calculate4x4(n, matrix));
		}
			
		return n;
	}
	
	public double calculateDeterminante3x3(int n, double[][] matrix)
	{
			double determinante = 0;
			double zwischenErgebnisAddition = 0;
			double zwischenErgebnisSubtrahtion = 0;
			double matrixElement = 1;
			double matrixElement2 = -1;
			int j = 2;
			int k = 0;
			for (int p = 0; p < n; p++)
			{
				matrixElement = 1;
				matrixElement2 = -1;
				for (int i = 0; i < n; i++)
				{
					matrixElement = matrix[k][i] * matrixElement; 
//					System.out.println( matrix[k][i]);
					matrixElement2 = matrix[k][j] * matrixElement2;
					j = j - 1;
					if (j == -1)
					{
						j = n-1;
					}
					k = (k + 1)%n;
				}
				zwischenErgebnisAddition = zwischenErgebnisAddition + matrixElement;
//				System.out.println(zwischenErgebnisAddition);
				zwischenErgebnisSubtrahtion = zwischenErgebnisSubtrahtion + matrixElement2;
				determinante = zwischenErgebnisAddition + zwischenErgebnisSubtrahtion;
				k = k + 1;
			}	
//			System.out.println("Determinante: " + determinante);
		return determinante;
	}
	
	public double calculate4x4(int n, double [][] matrix)
	{
		double[][] matrixHelp = new double[4][3];
		double[][] matrixHelp3x3 = new double [3][3];
		double wholeDeterminante = 0;
		double ergebnis = 0;
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < n; j++)
			{
				int l = 0;
//				System.out.println("");
				for (int k = 1; k < n; k++)
				{
//						System.out.println(matrix[j][k]);
						matrixHelp3x3[(j)%3][l] = matrix[(j+i)%4][k];
//						System.out.println(matrixHelp[j][l]);
//						matrixHelp3x3[(j+i)%3][l] = matrixHelp[j][l];
//						System.out.println(matrixHelp3x3[0][2]);
//						System.out.println(matrixHelp3x3[2][2]);
//						matrixHelp[j][k-1] = matrix[((j+(i+1))%4)][k];
//						System.out.println(matrix[((j+(i+1))%4)][k]);
//						calculateDeterminante3x3(3, matrixHelp3x3);
//						System.out.println(matrixHelp3x3[0][0]);
						l = l + 1;
						
				}
			}
//			double determinante = 0;
//			for (int o = 0; o < n; o++)
//			{
//				determinante =  matrix[3][0] * calculateDeterminante3x3(3, matrixHelp3x3);
			wholeDeterminante = calculateDeterminante3x3(3, matrixHelp3x3) * matrix[i][0];
			if ((i%2)!=0)
			{
				wholeDeterminante = wholeDeterminante * -1;
			}
//			}
			
			ergebnis = wholeDeterminante + ergebnis;
//			System.out.println(matrixHelp3x3[2][0]);
//			System.out.println("");
		}
//		System.out.println(ergebnis);
//		calculateDeterminante3x3(3, matrixHelp3x3);
//		System.out.println(matrixHelp[3][2]);
//		calculateDeterminante3x3(n, matrixHelp);
		return ergebnis;
	}
}
habe es schon versucht allgemein zu halten
 
S

SlaterB

Gast
du brauchst mehrere 4x4-Determinanten, aber innerhalb des ersten Aufrufs muss n nie auf 3 sinken oder darunter,
dass jeder 4x4-Aufruf selber nach 3x3 geht, das erledigt schon die Rekursion, darum musst du dich im ersten Aufruf nicht kümmern,

die Multiplikation fehlt, in der Tat, aber was soll man da sagen? die Formel ist doch bekannt oder nachschlagbar,
der Rückgabewert des rekursiven Aufrufs muss mit irgendeinem Matrix-Wert multipliziert und dann addiert werden usw.,
das kannst du doch in Ruhe im Detail schaffen, was soll man von außen dazu sagen?
die richtige Codezeile könnte ich dir nur nennen wenn ich das ganze praktisch selber komplett programmiere

also schreibe dir mal sauber auf, wie 5x5 aufgeteilt wird, in wieviel Untermatrixen,
Untermethoden helfen auch, dann hast du vielleicht nicht so viele Schleifen,
der Hauptaufbau könnte so sein

Java:
calculate(n,matrix nn) { // 5
   int nKleiner // 4, einmal reicht, alles andere < n interessiert nicht
   double sum;   
   for ( 0-5) { // eine Schleife reicht
     matrix nknk // ohne Schleife durch Methodenaufruf einer Hilfsmethode (nicht Rekursion!) 
          // die aktuell benötigte Untermatrix bestimmten, in der Untermethode Doppelschleife oder so
     sum += ein Matrix-Wert * rekursiverAufruf(nKleiner,nknk);
   }
   return sum ;
}
die Unterscheidung ob 3x3-Methode aufzurufen ist könnte an den Anfang der calculate-Methode,
muss nicht beim rekursiven Aufruf sein,
dann funktioniert das auch falls die Methode initial mit 3 aufgerufen wird,

der int-Parameter könnte auch ganz weg, aus der Matrix kann man die Länge ja ablesen
 
Zuletzt bearbeitet von einem Moderator:

AsterixdGallier

Aktives Mitglied
In meinem letzten Code den ich gepostet habe wandle ich doch eine 4er Matrix in 4 3er Matritzen um. Und es funktioniert!
Wenn ich jetzt meine 5er Matrix in 4 4er umwandle, und diese 4 4er jeweils in 4 3er, müsste es doch klappen, und dem code müsste ich dann schon sehr nahe sein oder nicht?
 
S

SlaterB

Gast
oh ja, da habe ich mal ein Posting übersehen, das von 15:48 sieht zuversichtlich aus,

eine Frage besteht aktuell sonst nicht oder?
na dann spätestens jetzt an der nxn-Variante weiterarbeiten, falls das dein Ziel ist
 

AsterixdGallier

Aktives Mitglied
Hi ich bins nochmal habe den code weitergemacht, bzw verändert.

Java:
public class Mathetool {
	int zähl = 0;
	double result = 0;
	double multiplikator = 1;
	public static void main(String[] args) 
	{
		int n = 4;
		
		double [][] matrix = new double[n][n];
		matrix [0][0] = 1;
		matrix [0][1] = -2;
		matrix [0][2] = 2;
		matrix [0][3] = 3;
//		matrix [0][4] = 3;
//		matrix [0][5] = 11;

		matrix [1][0] = 4;
		matrix [1][1] = 3;
		matrix [1][2] = 1;
		matrix [1][3] = -1;
//		matrix [1][4] = 0;
//		matrix [1][5] = 6;
		
		matrix [2][0] = 5;
		matrix [2][1] = -1;
		matrix [2][2] = 1;
		matrix [2][3] = 2;
//		matrix [2][4] = 7;
//		matrix [2][5] = 1;
		
		matrix [3][0] = -1;
		matrix [3][1] = 0;
		matrix [3][2] = 0;
		matrix [3][3] = 1;
//		matrix [3][4] = 6;
//		matrix [3][5] = 5;
		
//		matrix [4][0] = 1;
//		matrix [4][1] = 10;
//		matrix [4][2] = 3;
//		matrix [4][3] = 4;
//		matrix [4][4] = 3;
//		matrix [4][5] = 10;
		
//		matrix [5][0] = 1;
//		matrix [5][1] = 12;
//		matrix [5][2] = 14;
//		matrix [5][3] = 1;
//		matrix [5][4] = 2;
//		matrix [5][5] = 6;
		
		Mathetool matheTool = new Mathetool();
		matheTool.determinanteAll(n, matrix);
	}
	
	public double determinanteAll(int n, double[][] matrix)
	{
		if (n == 3)
			{
				calculateDeterminante3x3(n, matrix);
			}
//		else if (n == 4)
//		{
//				System.out.println(calculate4x4(n, matrix));
//		}
		else if (n > 3)
		{
			macheNxNEineDimensionKleinerX(n, matrix);
//			System.out.println(result);
		}
			
		return n;
	}
	
	public double calculateDeterminante3x3(int n, double[][] matrix)
	{
			double determinante = 0;
			double zwischenErgebnisAddition = 0;
			double zwischenErgebnisSubtrahtion = 0;
			double matrixElement = 1;
			double matrixElement2 = -1;
			int j = 2;
			int k = 0;
			for (int p = 0; p < n; p++)
			{
				matrixElement = 1;
				matrixElement2 = -1;
				for (int i = 0; i < n; i++)
				{
					matrixElement = matrix[k][i] * matrixElement; 
//					System.out.println( matrix[k][i]);
					matrixElement2 = matrix[k][j] * matrixElement2;
					j = j - 1;
					if (j == -1)
					{
						j = n-1;
					}
					k = (k + 1)%n;
				}
				zwischenErgebnisAddition = zwischenErgebnisAddition + matrixElement;
//				System.out.println(zwischenErgebnisAddition);
				zwischenErgebnisSubtrahtion = zwischenErgebnisSubtrahtion + matrixElement2;
				determinante = zwischenErgebnisAddition + zwischenErgebnisSubtrahtion;
				k = k + 1;
			}	
//			System.out.println("Determinante: " + determinante);
		return determinante;
	}
	

	
	public void macheNxNEineDimensionKleinerX(int n, double [][] matrix) // Macht eine NxN-Matrix zu N (N-1)x(N-1) Matritzen.
	{
		double ergebnis = 0;
		double multiplikator = 2;
		double determinante = 0;
		double zwischenResult = 0;
		double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-2))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i)%n][k];
				}
			}
			if (n == 3)
			{
				zwischenResult = calculateDeterminante3x3(n, matrix);
//				computeResult (zwischenResult, 1.0);
			}
			else if (n > 3)
			{
				macheNxNEineDimensionKleinerX((n-1), matrixHelp);
			}
		}
		System.out.println(zwischenResult);
	}
	
//	public void computeResult (double determinante, double multiplicator)
//	{
//		result += determinante * multiplicator;
//	}
	}

Sorry für den ganzen auskommentierten kram.
er gibt mir jetzt von beliebigen matritzen alle ergebnisse der untermatritzen aus. also wenn man von 5x5 auf 4x4 auf 3x3 geht. kriege dann also bei einer 4x4 matrix 4 ergebnisse. Eine 4x4 ist ja das gleiche wie 4 3x3 matritzen. Es fehlt nur noch die multiplikation. ich muss die unterdeterminanten ja noch multiplizieren. weiß aber nicht wie das gehen soll, weil mein code rekursiv ist und der wert aus der matritze immer wieder überschrieben wird!
Bin glaube ich nicht mehr weit entfernt vom ziel hat jemand nen guten hinweis??
Er gibt jetzt aktuell 4, 0, -8, -4, 0 aus. (das sind die 4 ergebnisse von den 4 unterdeterminanten der 4x4 matrix) soweit richtig nur die letzte 0 ist überflüssig wie könnte ich die weglassen?
 
Zuletzt bearbeitet:
S

SlaterB

Gast
macheNxNEineDimensionKleinerX() muss wie calculateDeterminante3x3() einen double zurückgeben,

in der Schleife erhälst du von der einen oder der anderen Mehode einen double, dass ist die Determinante X der jeweiligen Untermatrix,
dieses X musst du ganz nach Formel mit aij multiplizieren, keine Ahnung ob du 'nach der 0-ten Spalte oder 0-ten Zeile entwickelst',
außerdem noch mit -1^(i+j) multiplizieren, auch eben ganz nach Formel, auf dem Papier siehst du ja welche Werte es im Beispiel sein müssen,
der Schleifen-Index spielt eine Rolle und die gewählte Spalte oder Zeile,

alle diese Produkte der Schleife noch aufaddieren, ganz nach Formel ( ;) ) und das ist der Rückgabewert der Methode macheNxNEineDimensionKleinerX(), das ist die entwickelte Determinante
 

AsterixdGallier

Aktives Mitglied
macheNxNEineDimensionKleinerX() muss wie calculateDeterminante3x3() einen double zurückgeben,

in der Schleife erhälst du von der einen oder der anderen Mehode einen double, dass ist die Determinante X der jeweiligen Untermatrix,
dieses X musst du ganz nach Formel mit aij multiplizieren, keine Ahnung ob du 'nach der 0-ten Spalte oder 0-ten Zeile entwickelst',
außerdem noch mit -1^(i+j) multiplizieren, auch eben ganz nach Formel, auf dem Papier siehst du ja welche Werte es im Beispiel sein müssen,
der Schleifen-Index spielt eine Rolle und die gewählte Spalte oder Zeile,

alle diese Produkte der Schleife noch aufaddieren, ganz nach Formel ( ;) ) und das ist der Rückgabewert der Methode macheNxNEineDimensionKleinerX(), das ist die entwickelte Determinante

danke, das es double werden muss ist mir klar, habe es nur noch nicht eingetragen.
das problem ist ich kriege den wert mit dem ich multiplizieren muss einfach nicht zu fassen.
ich weiß nicht wie ich den ansprechen soll. es müssten quasi die oberen werte der spalte sein, die ausgelassen wurde.
also irgendwie sowas wie matrix[0]. aber so bekomme ich sie leider nicht, weil die matrix durch die rekursion immer wieder mit der neuen kleineren überschrieben wird. und dann nimmt er halt von der kleineren matrix[0], er müsste aber dort nachwievor den von der ersten nehmen..
Man könnte als erste Frage formulieren, wie schaffe ich es dass mir die multiplikatoren einfach nur ausgegeben werden innerhalb meiner methode macheNxNEineDimensionKleinerX. dann brauch ich ja wie du schon gesagt hast nur noch multiplizieren nach der formel ich denke das kriege ich dann hin.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
du musst jede Stufe für sich betrachten

wenn eine 5x5-Matrix in die Methode reinkommt, dann arbeitest du (per Schleife öfters) in Zeile 123-129 5x daran eine Untermatrix 4x4 Y zu erstellen,
zu dieser Untermatrix Y wird eine Unterdeterminante X berechnet (wie ist dir vollkommen egal, rekursiver Aufruf, fertig ist der Lack)
wenn dieser double-Wert X fertig da ist, bist du wieder dort wo die Untermatrix berechnet wurde,
bzw. in der aktuellen Betrachtung unter Auslassung der Rekursion die ganze Zeit in der 5x5er Bearbeitung,

dort wo du die Untermatrix Y 4x4 berechnet hast, und nun X von Unteraufrufen erhalten hast,
ist der Parameter matrix, die 5x5-Matrix, doch nach wie vor, die ganze Zeit vorhanden,
ganz simplel kannst du mit matrix[0] rechnen oder was immer nötig ist

-----

wenn der rekursive Aufruf für eine der 4x4-Matrixen selber zu einem kompletten macheNxNEineDimensionKleinerX()-Ablauf führt,
dann ist
1. die ursprüngliche 5x5-Matrix nicht nötig, der eigenständige Unter-Ablauf hat seine 4x4-Matrix als eigenen matrix-Parameter,
von dem wiederum 3x3 Untermatrixen Y berechnet und matrix[0] usw. abgefragt werden können
2. diese Unterberechnungen laufen auch völlig getrennt vom ersten und einzigen 5x5-Aufruf, der solange pausiert wird,
dessen Parameter, Schleifen usw. werden auf keine Weise gestört,
wenn ein Unteraufruf fertig ist geht dort alles in geordenten Bahnen mit den dortigen Variablen weiter

-> zusammen: es läuft alles
 
Zuletzt bearbeitet von einem Moderator:

AsterixdGallier

Aktives Mitglied
du musst jede Stufe für sich betrachten

wenn eine 5x5-Matrix in die Methode reinkommt, dann arbeitest du (per Schleife öfters) in Zeile 123-129 5x daran eine Untermatrix 4x4 Y zu erstellen,
zu dieser Untermatrix Y wird eine Unterdeterminante X berechnet (wie ist dir vollkommen egal, rekursiver Aufruf, fertig ist der Lack)
wenn dieser double-Wert X fertig da ist, bist du wieder dort wo die Untermatrix berechnet wurde,
bzw. in der aktuellen Betrachtung unter Auslassung der Rekursion die ganze Zeit in der 5x5er Bearbeitung,

ja aber ich glaube du vergisst, dass man zu der untermatrix Y nicht so einfach eine determinante berechnen kann. Aus Y müsste man jetzt wieder 3 3er Matritzen erstellen und diese mit matrix[0] von Y multiplizieren.
 
S

SlaterB

Gast
die Rekursion ist auf der Welt aus einem einzigen Grunde, nämlich um GENAU 'so einfach [.. etwas zu] berechnen'

du musst dir darum keine Gedanken machen, der rekursive Aufruf errechnet die Determinante und nur in der aktuellen Schicht muss alles klappen,

denke an eine Menschenkette für Wassereimer oder ein Navi auf dem Weg über tausend Kreuzungen,
jeder einzelne muss nur seine Arbeit korrekt machen, seinen Eimer in die richtige Richtung weiterreichen, an der aktuellen Kreuzung richtig abbiegen,
über vorherige oder spätere Stationen muss man nicht (gleichzeitig) nachdenken,
das funktioniert (bei geeigneten Aufbau) durch die Gesamtkonstruktion
 

AsterixdGallier

Aktives Mitglied
Hi gucke mal hier so siehts grade aus:

Java:
	public double macheNxNEineDimensionKleinerX(int n, double [][] matrix) // Macht eine NxN-Matrix zu N (N-1)x(N-1) Matritzen.
	{
		double ergebnis = 0;
		double multiplikator = 2;
		double determinante = 0;
		double zwischenResult = 0;
		double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-2))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i)%n][k];
				}
			}
			if (n == 3)
			{
				zwischenResult = calculateDeterminante3x3(n, matrix);
//				System.out.println(zwischenResult);
//				System.out.println(matrix[i][0]);
//				computeResult (zwischenResult, 1.0);
			}
			else if (n > 3)
			{
				zwischenResult = macheNxNEineDimensionKleinerX((n-1), matrixHelp);
//				zwischenResult = zwischenResult * matrix[i][0];
				System.out.println(matrix[i][0]*zwischenResult);
//				System.out.println(zwischenResult);
//				System.out.println(matrix[i][0]);
			}
			
//			System.out.println(zwischenResult * matrix[i][0]);
		}
		
//		for (int w = 0; w < n; w++)
//		{
//			System.out.println(matrix[w][0]);
//		}
//		System.out.println(zwischenResult);
		return zwischenResult;
	}
Wenn ich dort also um else if Zweig das ganze ausgebe kommen die richtig multiplizierten zwischenergebnisse raus. nur dort kann ich sie nicht weiterverwenden weil sie ja danach wieder überschrieben werden..
 
S

SlaterB

Gast
dass du in der Schleife unterscheidest habe ich schon früher als unnötig kompliziert genannt, aber ist zu behandeln
Java:
for { 
   ...  matrix erstellen

   double zwischenResult = 0; // erst hier deklarieren, macht weniger Probleme
   if (3er) {
       zwischenResult  = calc3er();
   } else {
       zwischenResult  = calcNer();
   }
   // hier die Unterdeterminante in zwischenResult fertig
}

kürzer wäre
Java:
for { 
   ...  matrix erstellen

   double zwischenResult = calcNer();
   // hier die Unterdeterminante in zwischenResult fertig
}
und erst im nächsten Rekursionsschritt, also zu Beginn der Methoe prüfen ob die Dimension 3 ist und dann erst auf calc3er() weiterleiten

----------

jedenfalls sorgt all das nur dafür, dass in der Schleife eine Unterdeterminante X berechnet wird, X = zwischenResult,

jetzt wie ich es gesagt habe und wie du teilweise schon eingebaut hast, jedes dieser X mit z.B. matrix[0] multiplizieren
und das ganze aufsummieren,
das ist doch eine einfache Aufgabe,
die Variable zwischenResult brauchst du nicht nach der Schleife, bzw. vielleicht schon, irgendeine Variable ja immer,
nimm meinetwegen zwischenResult zur Summierung,
aber dann speichere nicht die Unterdeterminanten X daran, sondern verwende eine separate Variable, das ist doch nun wirklich nicht schwer?

Java:
double zwischenResult = 0;
for { 
   ...  matrix erstellen

   double x = .. Unterderminante berechnen;

   zwischenResult += x * matrix[i][0];
}
// hier nun ist zwischenResult das richtige Endergebnis
 

AsterixdGallier

Aktives Mitglied
So funktinierts jetzt mal wieder für 4x4, aber nxn irgendwie nicht.. versteh nicht mehr warum..???:L

Java:
	public double macheNxNEineDimensionKleinerX(int n, double [][] matrix) // Macht eine NxN-Matrix zu N (N-1)x(N-1) Matritzen.
	{
		double ergebnis = 0;
		double multiplikator = 2;
		double determinante = 0;
		double zwischenResult = 0;
		double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-2))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i)%n][k];
				}
			}
			if (n == 3)
			{
				zwischenResult = calculateDeterminante3x3(n, matrix);
//				System.out.println(zwischenResult);
//				System.out.println(matrix[i][0]);
//				computeResult (zwischenResult, 1.0);
			}
			else if (n > 3)
			{
				zwischenResult = macheNxNEineDimensionKleinerX((n-1), matrixHelp);
				zwischenResult = zwischenResult * matrix[i][0];
//				System.out.println(zwischenResult);
				if ((i%2)!=0)
				{
					finale = finale - zwischenResult;
				}	
				else if (i%2==0)
				{
					finale = finale + zwischenResult;
				}

//				System.out.println(finale);
//				System.out.println(matrix[i][0]);
			}
			
//			System.out.println(zwischenResult * matrix[i][0]);
		}
		
//		for (int w = 0; w < n; w++)
//		{
//			System.out.println(matrix[w][0]);
//		}
		System.out.println(finale);
		return zwischenResult;
	}
 

AsterixdGallier

Aktives Mitglied
dass du in der Schleife unterscheidest habe ich schon früher als unnötig kompliziert genannt, aber ist zu behandeln
Java:
for { 
   ...  matrix erstellen

   double zwischenResult = 0; // erst hier deklarieren, macht weniger Probleme
   if (3er) {
       zwischenResult  = calc3er();
   } else {
       zwischenResult  = calcNer();
   }
   // hier die Unterdeterminante in zwischenResult fertig
}

kürzer wäre
Java:
for { 
   ...  matrix erstellen

   double zwischenResult = calcNer();
   // hier die Unterdeterminante in zwischenResult fertig
}
und erst im nächsten Rekursionsschritt, also zu Beginn der Methoe prüfen ob die Dimension 3 ist und dann erst auf calc3er() weiterleiten

----------

jedenfalls sorgt all das nur dafür, dass in der Schleife eine Unterdeterminante X berechnet wird, X = zwischenResult,

jetzt wie ich es gesagt habe und wie du teilweise schon eingebaut hast, jedes dieser X mit z.B. matrix[0] multiplizieren
und das ganze aufsummieren,
das ist doch eine einfache Aufgabe,
die Variable zwischenResult brauchst du nicht nach der Schleife, bzw. vielleicht schon, irgendeine Variable ja immer,
nimm meinetwegen zwischenResult zur Summierung,
aber dann speichere nicht die Unterdeterminanten X daran, sondern verwende eine separate Variable, das ist doch nun wirklich nicht schwer?

Java:
double zwischenResult = 0;
for { 
   ...  matrix erstellen

   double x = .. Unterderminante berechnen;

   zwischenResult += x * matrix[i][0];
}
// hier nun ist zwischenResult das richtige Endergebnis

habs jetzt erst gesehen, aber wieso funktniert der aktuelle code nicht für sachen größer als 4x4. der macht doch alles nach der formel und summiert es nach ein ander auf.
 

AsterixdGallier

Aktives Mitglied
Ich kriege einfach die berechnetetn untermatritzen nicht aus der methode raus nach oben hier:
Java:
	public double macheNxNEineDimensionKleinerX(int n, double [][] matrix) // Macht eine NxN-Matrix zu N (N-1)x(N-1) Matritzen.
	{
		double ergebnis = 0;
		double multiplikator = 2;
		double determinante = 0;
		double zwischenResult = 0;
		double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-2))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i)%n][k];
				}
			}
			if (n == 3)
			{
				zwischenResult = calculateDeterminante3x3(n, matrix);
//				System.out.println(zwischenResult);
//				System.out.println(matrix[i][0]);
//				computeResult (zwischenResult, 1.0);
			}
			else if (n > 3)
			{
				zwischenResult = macheNxNEineDimensionKleinerX((n-1), matrixHelp);
				zwischenResult = zwischenResult * matrix[i][0];
				System.out.println(zwischenResult);
//				System.out.println(zwischenResult);
//				System.out.println(matrix[i][0]);
			}
			
//			System.out.println(zwischenResult * matrix[i][0]);
		}
		
//		for (int w = 0; w < n; w++)
//		{
//			System.out.println(matrix[w][0]);
//		}
//		System.out.println(zwischenResult);
		return zwischenResult;
	}
ich müsste ja 4 werte zurück geben um sie oben dann alle zu multilpizieren, deswegen wollte ich das schon in der methode machen!
 
S

SlaterB

Gast
immer auf Papier ausrechnen, welche Untermatrixen Y zu einem Beispiel rauskommen,
welche Unterdeterminanten X dazu die Zwischenergebnisse sind,
welche Multiplikatoren dazu gehören (vielleicht irrst du dich mit matrix[0], vielleicht ist es matrix[0]),
einfach jeden einzelnen Schritt der Rechnungf kennen und nacheinander im Programmablauf abhaken

solange du selber nicht weißt was zu rechnen ist, ist es reiner Zufall ob du die richtigen oder falschen Formeln umsetzt

wenn du es aber weißt, ist es reiner Fleiß, das im Programm zu vergleichen und so den Fehler einzugrenzen

-----

ich selber kann im Moment nur feststellen, dass augenscheinlich alle Bestandteile vorhanden sind,
ob richtig oder falsch, dazu müsste ich alles selber genauso machen, angefangen mit Zurechtlegen einer Matrix und Ausrechnen auf Papier

-----

> ich müsste ja 4 werte zurück geben um sie oben dann alle zu multilpizieren, deswegen wollte ich das schon in der methode machen!

nein.., jeder Methodenaufruf gibt genau einen Wert zurück, klappt auch, aber das ist ne Nebendiskussion
 
Zuletzt bearbeitet von einem Moderator:

AsterixdGallier

Aktives Mitglied
immer auf Papier ausrechnen, welche Untermatrixen Y zu einem Beispiel rauskommen, welter Unterdeterminanten X dazu die Zwischenergebnisse sind, welche Multiplikatoren dazu gehören (vielleicht irrst du dich mit matrix[0], vielleicht ist es matrix[0]),
einfach jeden einzelnen Schritt der Rechnung, jeden Schriff kennen und nacheinander im Programmablauf abhaken

solange du selber nicht weißt was zu rechnen ist, ist es reiner Zufall ob du die richtigen oder falschen Formeln umsetzt

wenn du es aber weißt, ist es reiner Fleiß, das im Programm zu vergleichen und so den Fehler einzugrenzen

-----

ich selber kann im Moment nur feststellen, dass augenscheinlich alle Bestandteile vorhanden sind,
ob richtig oder falsch, dazu müsste ich alles selber genauso machen, angefangen mit Zurechtlegen einer Matrix und Ausrechnen auf Papier

-----

> ich müsste ja 4 werte zurück geben um sie oben dann alle zu multilpizieren, deswegen wollte ich das schon in der methode machen!

nein.., jeder Methodenaufruf gibt genau einen Wert zurück, klappt auch, aber das ist ne Nebendiskussion


danke meine untermatritzen sind richtig, und wie gesagt die ausgabe stimmt auch in der console. mein einziges problem ist es, die ausgegebenen werte zusammen zu rechnen und zurück zugeben.
Java:
public class Mathetool {
	int zähl = 0;
	double result = 0;
	double multiplikator = 1;
	double finale = 0;
	public static void main(String[] args) 
	{
		int n = 4;
		
		double [][] matrix = new double[n][n];
		matrix [0][0] = 1;
		matrix [0][1] = -2;
		matrix [0][2] = 2;
		matrix [0][3] = 3;
//		matrix [0][4] = 3;
//		matrix [0][5] = 11;

		matrix [1][0] = 4;
		matrix [1][1] = 3;
		matrix [1][2] = 1;
		matrix [1][3] = -1;
//		matrix [1][4] = 0;
//		matrix [1][5] = 6;
		
		matrix [2][0] = 5;
		matrix [2][1] = -1;
		matrix [2][2] = 1;
		matrix [2][3] = 2;
//		matrix [2][4] = 7;
//		matrix [2][5] = 1;
		
		matrix [3][0] = -1;
		matrix [3][1] = 0;
		matrix [3][2] = 0;
		matrix [3][3] = 1;
//		matrix [3][4] = 6;
//		matrix [3][5] = 5;
		
//		matrix [4][0] = 1;
//		matrix [4][1] = 10;
//		matrix [4][2] = 3;
//		matrix [4][3] = 4;
//		matrix [4][4] = 3;
//		matrix [4][5] = 10;
		
//		matrix [5][0] = 1;
//		matrix [5][1] = 12;
//		matrix [5][2] = 14;
//		matrix [5][3] = 1;
//		matrix [5][4] = 2;
//		matrix [5][5] = 6;
		
		Mathetool matheTool = new Mathetool();
		matheTool.determinanteAll(n, matrix);
	}
	
	public double determinanteAll(int n, double[][] matrix)
	{
		if (n == 3)
			{
				calculateDeterminante3x3(n, matrix);
			}
//		else if (n == 4)
//		{
//				System.out.println(calculate4x4(n, matrix));
//		}
		else if (n > 3)
		{
			macheNxNEineDimensionKleinerX(n, matrix);
//			System.out.println(result);
		}
			
		return n;
	}
	
	public double calculateDeterminante3x3(int n, double[][] matrix)
	{
			double determinante = 0;
			double zwischenErgebnisAddition = 0;
			double zwischenErgebnisSubtrahtion = 0;
			double matrixElement = 1;
			double matrixElement2 = -1;
			int j = 2;
			int k = 0;
			for (int p = 0; p < n; p++)
			{
				matrixElement = 1;
				matrixElement2 = -1;
				for (int i = 0; i < n; i++)
				{
					matrixElement = matrix[k][i] * matrixElement; 
//					System.out.println( matrix[k][i]);
					matrixElement2 = matrix[k][j] * matrixElement2;
					j = j - 1;
					if (j == -1)
					{
						j = n-1;
					}
					k = (k + 1)%n;
				}
				zwischenErgebnisAddition = zwischenErgebnisAddition + matrixElement;
//				System.out.println(zwischenErgebnisAddition);
				zwischenErgebnisSubtrahtion = zwischenErgebnisSubtrahtion + matrixElement2;
				determinante = zwischenErgebnisAddition + zwischenErgebnisSubtrahtion;
				k = k + 1;
			}	
//			System.out.println("Determinante: " + determinante);
		return determinante;
	}
	
//	public double calculate4x4(int n, double [][] matrix)
//	{
//		double[][] matrixHelp = new double[4][3];
//		double[][] matrixHelp3x3 = new double [3][3];
//		double wholeDeterminante = 0;
//		double ergebnis = 0;
//		for (int i = 0; i < 4; i++)
//		{
//			for (int j = 0; j < n; j++)
//			{
//				int l = 0;
//				for (int k = 1; k < n; k++)
//				{
//						matrixHelp3x3[(j)%3][l] = matrix[(j+i)%4][k];
//						l = l + 1;			
//				}
//			}
//			wholeDeterminante = calculateDeterminante3x3(3, matrixHelp3x3) * matrix[i][0];
//			if ((i%2)!=0)
//			{
//				wholeDeterminante = wholeDeterminante * -1;
//			}		
//			ergebnis = wholeDeterminante + ergebnis;
//		}
//		return ergebnis;
//	}
	
//	public void macheNxNEineDimensionKleiner(int n, double [][] matrix) // Macht eine NxN-Matrix zu N (N-1)x(N-1) Matritzen.
//	{
//		double[][] matrixHelp = new double[n][n-1];
//		for (int i = 0; i < n-1; i++)
//		{
//			for (int j = 0; j < n; j++)
//			{
//				for (int k = 0; k < n; k++)
//				{
//					matrixHelp[(j+(n-2))%(n)][((k+(n-2))%(n-1))] = matrix[(j+i)%n][k];
//				}
////				System.out.println(matrixHelp[4][3]);
//			}
//			
//			System.out.println(matrixHelp[4][0]);
//		}
//	}
	
	public double macheNxNEineDimensionKleinerX(int n, double [][] matrix) // Macht eine NxN-Matrix zu N (N-1)x(N-1) Matritzen.
	{
		double ergebnis = 0;
		double multiplikator = 2;
		double determinante = 0;
		double zwischenResult = 0;
		double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-2))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i)%n][k];
				}
			}
			if (n == 3)
			{
				zwischenResult = calculateDeterminante3x3(n, matrix);
//				System.out.println(zwischenResult);
//				System.out.println(matrix[i][0]);
//				computeResult (zwischenResult, 1.0);
			}
			else if (n > 3)
			{
				zwischenResult = macheNxNEineDimensionKleinerX((n-1), matrixHelp);
				zwischenResult = zwischenResult * matrix[i][0];
//				System.out.println(zwischenResult);			// DAS HIER IST RICHTIG!!! WIE KRIEGE ICH DIESE WERTE NACH OBEN (VON MIR AUS AUCH SCHON ZUM ERGEBNIS ADDIERT)
//				System.out.println(matrix[i][0]);			// AUCH DIE RICHIGEN FAKTOREN!!
			}
			
//			System.out.println(zwischenResult * matrix[i][0]);
		}
		
//		for (int w = 0; w < n; w++)
//		{
//			System.out.println(matrix[w][0]);
//		}
//		System.out.println(zwischenResult);				// HIER SIND DIE WERTE WIEDER FALSCH PLÖTZLICH, ES KOMMEN WIEDER DIE WERTE HERAUS BEVOR SIE MULTIPLIZIERT WURDEN
		return zwischenResult;
	}
	
//	public void computeResult (double determinante, double multiplicator)
//	{
//		result += determinante * multiplicator;
//	}
	}
Habe jetzt als Kommentar geschrieben was ich wo meine.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
hmm, das ist ja dann doch wieder der einfache Punkt, ich dachte den hättest du nach meinen letzten Erläuterungen richtig,
habe nicht genau genug geschaut,
in zwischenResult speicherst du immer nur den aktuellen Wert pro Schleifendurchlauf,

all diese Werte musst du addieren, das ist doch die sehr billig nach so komplexen anderen Themen?
definiere dir vor der Schleife eine weitere Variable, meinetwegen 'sum',
und in der Schleife einfach nur sum += zwischenResult;
schon hast du alle ZwischenResulte zusammen, was das Endergebnis ist?!
 

AsterixdGallier

Aktives Mitglied
hmm, das ist ja dann doch wieder der einfache Punkt, ich dachte den hättest du nach meinen letzten Erläuterungen richtig,
habe nicht genau genug geschaut,
in zwischenResult speicherst du immer nur den aktuellen Wert pro Schleifendurchlauf,

all diese Werte musst du addieren, das ist doch die sehr billig nach so komplexen anderen Themen?
definiere dir vor der Schleife eine weitere Variable, meinetwegen 'sum',
und in der Schleife einfach nur sum += zwischenResult;
schon hast du alle ZwischenResulte zusammen, was das Endergebnis ist?!

Jo danke das habe ich jetzt gemacht, und das klappt auch bei 4X4. Aber nicht mehr bei 5X5 :(
Habe wieder als Kommentar in den Code geschrieben.

Java:
	public double macheNxNEineDimensionKleinerX(int n, double [][] matrix) // Macht eine NxN-Matrix zu N (N-1)x(N-1) Matritzen.
	{
		double ergebnis = 0;
		double multiplikator = 2;
		double determinante = 0;
		double zwischenResult = 0;
		double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-2))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i)%n][k];
				}
			}
			if (n == 3)
			{
				zwischenResult = calculateDeterminante3x3(n, matrix);
//				System.out.println(zwischenResult);
//				System.out.println(matrix[i][0]);
//				computeResult (zwischenResult, 1.0);
			}
			else if (n > 3)
			{
				zwischenResult = macheNxNEineDimensionKleinerX((n-1), matrixHelp);
				zwischenResult = zwischenResult * matrix[i][0];
				if ((i%2)!=0)
				{
					finale = finale - zwischenResult;
				}	
				else if(i%2==0)
				{
					finale = finale + zwischenResult;
				}
			}
			
//			System.out.println(zwischenResult * matrix[i][0]);
		}
		
//		for (int w = 0; w < n; w++)
//		{
//			System.out.println(matrix[w][0]);
//		}
		System.out.println(finale);				// HIER GIBT ES MIR JETZT 5 WERTE AUS. DER LETZTE DAVON IST BEI EINER 4X4-MATRIX DAS RICHTIGE ENDERGEBNIS. BEI 5X5 KLAPPT ES ALLERDINGS SCHON WIEDER NICHT MEHR!! :(
		return zwischenResult;
	}
 
S

SlaterB

Gast
welche Ausgaben zu welchem Aufruf gehören ist nicht ganz leicht festzustellen wenn sie ineinander geschachtelt sind,
da muss man evtl. das Logging aufbohren, mit Leerzeichen einrücken oder sonstigen Prefixen verschiedene Ebenen markieren,
zu Beginn der Methode einen definieren, in allen System.out.println() einfügen

abgesehen davon gilt genau das vorherige, kenne die Papierrechnung, vergleiche die Ergebnisse, neues kann ich nicht sagen,

wenn du aus irgendeinem Grund mit dem Vergleich nicht weiterkommst,
könntest du zumindest mir das Leben leichter machen, indem du dein 5x5-Matrix-Beispiel soweit verständlich hinschreibst,
wie es dir möglich und hier praktikabel ist, welche 4x4 Untermatrixen kommen raus, welche Unterdeterminanten sind dafür die richtigen Ergebnisse, was davon konntest du schon im Programm bestätigen,

wie sieht die letzte Formelzeile aus
5x5-det = 45 -24 + 66 - 34 + 9 = ?
oder was genau?
 
Zuletzt bearbeitet von einem Moderator:

Fant

Bekanntes Mitglied
Mal was zum grundsätzlichen Aufbau..

Du solltest dir eine Methode
Code:
private double[][] unterMatrix(double[][] Matrix, int zeile, int spalte)
schreiben, die nichts weiter macht, als die entsprechende Untermatrix beim Streichen der Spalte spalte und der Zeile zeile zurückzugeben. Dann wird dein ganzer Code schon sehr viel übersichtlicher. Die Rekursive Berechnung der Determinante lässt sich dann in ~5? Zeilen aufschreiben.

Außerdem solltest du dir überlegen, was denn passiert, wenn eine 2x2 oder eine 1x1-Matrix eingegeben wird. Lass deine Rekursion doch einfach bis n=1 laufen. Die Determinante ist dann einfach der einzige Eintrag dieser Matrix.

Wenn du unbedingt (aus Performance-Gründen?) die 3x3-Matrix direkt berechnen willst, dann ist es hier m.M. nach wesentlich schöner und vermutlich auch schneller, wenn du direkt mit der Regel von Sarrus arbeitest.

Code:
private double det3x3Matrix(double[][] matrix) {
    return matrix[0][0]*matrix[1][1]*matrix[2][2]
          + matrix[0][1]*matrix[1][2]*matrix[2][0]
          + matrix[0][2]*matrix[1][0]*matrix[2][1]
          - matrix[0][2]*matrix[1][1]*matrix[2][0]
          - matrix[0][1]*matrix[1][0]*matrix[2][2]
          - matrix[0][0]*matrix[1][2]*matrix[2][1];
}

Ich hoffe ich hab jetzt nicht die Indizes durcheinandergewürfelt ;) Hier weiß jedoch jeder, der den Code sieht, sofort, was denn eigentlich berechnet werden soll.
 
Zuletzt bearbeitet:

AsterixdGallier

Aktives Mitglied
welche Ausgaben zu welchem Aufruf gehören ist nicht ganz leicht festzustellen wenn sie ineinander geschachtelt sind,
da muss man evtl. das Logging aufbohren, mit Leerzeichen einrücken oder sonstigen Prefixen verschiedene Ebenen markieren,
zu Beginn der Methode einen definieren, in allen System.out.println() einfügen

abgesehen davon gilt genau das vorherige, kenne die Papierrechnung, vergleiche die Ergebnisse, neues kann ich nicht sagen,
wenn du aus irgendeinem Grund mit dem Vergleich nicht weiterkommst,
könntest du zumindest mir das Leben leichter machen, in dem du dein 5x5-Matrix-Beispiel soweit verständlich hinschreibst,
wie es dir möglich und hier praktikabel ist, welche 4x4 Untermatrixen kommen raus, welche Unterdeterminanten sind dafür die richtigen Ergebnisse, was davon konntest du schon im Programm bestätigen,

wie sieht die letzte Formelzeile aus
5x5-det = 45 -24 + 66 - 34 + 9 = ?
oder was genau?

Naja die 5X5-Matritzen:
Java:
		matrix [0][0] = 1;
		matrix [0][1] = -2;
		matrix [0][2] = 2;
		matrix [0][3] = 3;
		matrix [0][4] = 3;

		matrix [1][0] = 4;
		matrix [1][1] = 3;
		matrix [1][2] = 1;
		matrix [1][3] = -1;
		matrix [1][4] = 0;
		
		matrix [2][0] = 5;
		matrix [2][1] = -1;
		matrix [2][2] = 1;
		matrix [2][3] = 2;
		matrix [2][4] = 7;
		
		matrix [3][0] = -1;
		matrix [3][1] = 0;
		matrix [3][2] = 0;
		matrix [3][3] = 1;
		matrix [3][4] = 6;
		
		matrix [4][0] = 1;
		matrix [4][1] = 10;
		matrix [4][2] = 3;
		matrix [4][3] = 4;
		matrix [4][4] = 3;

Dann berechnet er halt die dazugehörigen 4x4 Matritzen, das sind dann 4 Stück:



1:
[3.0, 1.0, -1.0, 0.0], [-1.0, 1.0, 2.0, 7.0], [0.0, 0.0, 1.0, 6.0], [10.0, 3.0, 4.0, 3.0]

Die hat jetzt 4 3x3-Matritzen:
1:
[1.0, 2.0, 7.0], [0.0, 1.0, 6.0], [3.0, 4.0, 3.0]

2:
[0.0, 1.0, 6.0], [3.0, 4.0, 3.0], [1.0, -1.0, 0.0]

3:
[3.0, 4.0, 3.0], [1.0, -1.0, 0.0], [1.0, 2.0, 7.0]

4:
[1.0, -1.0, 0.0], [1.0, 2.0, 7.0], [0.0, 1.0, 6.0]




2:
[-1.0, 1.0, 2.0, 7.0], [0.0, 0.0, 1.0, 6.0], [10.0, 3.0, 4.0, 3.0], [-2.0, 2.0, 3.0, 3.0]

Wieder 4 3x3:

1:
[0.0, 1.0, 6.0], [3.0, 4.0, 3.0], [2.0, 3.0, 3.0]

2:
[3.0, 4.0, 3.0], [2.0, 3.0, 3.0], [1.0, 2.0, 7.0]

3:
[2.0, 3.0, 3.0], [1.0, 2.0, 7.0], [0.0, 1.0, 6.0]

4:
[1.0, 2.0, 7.0], [0.0, 1.0, 6.0], [3.0, 4.0, 3.0]




3:
[0.0, 0.0, 1.0, 6.0], [10.0, 3.0, 4.0, 3.0], [-2.0, 2.0, 3.0, 3.0], [3.0, 1.0, -1.0, 0.0]

Wieder 4 3x3:

1:
[3.0, 4.0, 3.0], [2.0, 3.0, 3.0], [1.0, -1.0, 0.0]

2:
[2.0, 3.0, 3.0], [1.0, -1.0, 0.0], [0.0, 1.0, 6.0]

3:
[1.0, -1.0, 0.0], [0.0, 1.0, 6.0], [3.0, 4.0, 3.0]

4:
[0.0, 1.0, 6.0], [3.0, 4.0, 3.0], [2.0, 3.0, 3.0]




4:
[10.0, 3.0, 4.0, 3.0], [-2.0, 2.0, 3.0, 3.0], [3.0, 1.0, -1.0, 0.0], [-1.0, 1.0, 2.0, 7.0]

Wieder 4 3X3:

1:
[2.0, 3.0, 3.0], [1.0, -1.0, 0.0], [1.0, 2.0, 7.0]

2:
[1.0, -1.0, 0.0], [1.0, 2.0, 7.0], [3.0, 4.0, 3.0]

3:
[1.0, 2.0, 7.0], [3.0, 4.0, 3.0], [2.0, 3.0, 3.0]

4:
[3.0, 4.0, 3.0], [2.0, 3.0, 3.0], [1.0, -1.0, 0.0]


Die sehen meiner Meinung nach doch richtig aus oder?
 
S

SlaterB

Gast
was sind die Ergebnisse, die Unterdeterminaten dazu?
was das Programm dann meint kann ich schon nachschauen,
aber aus welchen Grund glaubst du bzw. weißt du hoffentlich recht sicher, dass das Programm falsch rechnet,
welche Zahl weicht ab?

die Matrixen sind gut zu wissen, noch wichtiger wären aber die simplen Einzelzahlen, die Determinanten
 

AsterixdGallier

Aktives Mitglied
Mal was zum grundsätzlichen Aufbau..

Du solltest dir eine Methode
Code:
private double[][] unterMatrix(double[][] Matrix, int zeile, int spalte)
schreiben, die nichts weiter macht, als die entsprechende Untermatrix beim Streichen der Spalte spalte und der Zeile zeile zurückzugeben. Dann wird dein ganzer Code schon sehr viel übersichtlicher. Die Rekursive Berechnung der Determinante lässt sich dann in ~5? Zeilen aufschreiben.

Außerdem solltest du dir überlegen, was denn passiert, wenn eine 2x2 oder eine 1x1-Matrix eingegeben wird. Lass deine Rekursion doch einfach bis n=1 laufen. Die Determinante ist dann einfach der einzige Eintrag dieser Matrix.

Wenn du unbedingt (aus Performance-Gründen?) die 3x3-Matrix direkt berechnen willst, dann ist es hier m.M. nach wesentlich schöner und vermutlich auch schneller, wenn du direkt mit der Regel von Sarrus arbeitest.

Code:
private double det3x3Matrix(double[][] matrix) {
    return matrix[0][0]*matrix[1][1]*matrix[2][2]
          + matrix[0][1]*matrix[1][2]*matrix[2][0]
          + matrix[0][2]*matrix[1][0]*matrix[2][1]
          - matrix[0][2]*matrix[1][1]*matrix[2][0]
          - matrix[0][1]*matrix[1][0]*matrix[2][2]
          - matrix[0][0]*matrix[1][2]*matrix[2][1];
}

Ich hoffe ich hab jetzt nicht die Indizes durcheinandergewürfelt ;) Hier weiß jedoch jeder, der den Code sieht, sofort, was denn eigentlich berechnet werden soll.

Meinst du sowas?
Java:
	public double[][] unterMatrix(double[][] matrix, int zeile, int spalte)
	{
		{
		double[][] matrixHelp = new double[zeile][spalte];
		for (int i = 0; i < spalte; i++)
		{
			for (int j = 0; j < zeile; j++)
			{
				for (int k = 0; k < zeile; k++)
				{
					matrixHelp[(j+(spalte-1))%(zeile)][((k+(spalte-1))%(spalte))] = matrix[(j+i)%zeile][k];
				}
//				System.out.println(matrixHelp[4][3]);
			}
			
//			System.out.println(matrixHelp[4][0]);
		}
		return matrixHelp;
	}
In wie weit hilft mir das jetzt weiter. Jetzt kriege ich immer EINE unter Matrix zu einer anderen, aber eben immer nur eine. Brauche ja alle
 
S

SlaterB

Gast
wie kann der Hinweis zu einer anderen 3x3-Berechnung oder Einführung einer Untermethode (hatte ich auch mal versucht zu erwähnen) die Anzahl der Unter-Matrixen ändern?
nicht immer so viel hineininterpretieren

der Hinweis von Fant scheint wichtig, bis ich genauer reinschauen könnte würde es noch etwas dauern
 

AsterixdGallier

Aktives Mitglied
was sind die Ergebnisse, die Unterdeterminaten dazu?
was das Programm dann meint kann ich schon nachschauen,
aber aus welchen Grund glaubst du bzw. weißt du hoffentlich recht sicher, dass das Programm falsch rechnet,
welche Zahl weicht ab?

die Matrixen sind gut zu wissen, noch wichtiger wären aber die simplen Einzelzahlen, die Determinanten
Die unterdeterminanten habe ich bei 5x5 noch nicht gecheckt, weil sie bei 4x4 geklappt haben und ich keinen grund wüsste warum sie bei 5x5 nicht hinhauen soltlen. habe einfach auf: Berechnung von Determinanten meine matrix eingegeben und das ergebnis von den berechnungen verglichen leider weicht es ab..
 
S

SlaterB

Gast
> weil sie bei 4x4 geklappt haben und ich keinen grund wüsste warum sie bei 5x5 nicht hinhauen soltlen

sowas ist immer gefährlich, 4x4 ist gerademal eine Stufe über 3x3, welches schon Sonderbehandlung hat,
eine echte Rekursion sollte schon ein paar Ebenen hindurch getestet werden, 5x5 komplett geprüft wäre ein gutes Beispiel
(also testen wolltest du es ja natürlich, das ist das wichtigste, aber wäre auch gut die Zwischenschritte selber zu kennen)

wie steht es darum dass 5 Untermatrixen nötig sind? aber sollte in dem Programm ja auch so funktionieren,
na ich kann vorerst nicht mehr als solche schlauen Sätze sagen, nicht wirklich helfen, später dann vielleicht genauer reinschauen
 

Fant

Bekanntes Mitglied
danke meine untermatritzen sind richtig

Bist du dir sicher? Du hast da komische Zeilenpermutationen drin. Das ist in jedem Fall fehleranfällig und hat eventuell einen Vorzeichenfehler in deinen Berechnungen zur Folge.


Bei meinem Hinweis mit der Methode zu Berechnung der Untermatrix meinte ich, dass jeweils die Spalte mit dem Index spalte und die Zeile mit dem Index zeile gelöscht werden soll.

Für A = [(1,2,3),(4,5,6),(7,8,9)] soll dann etwa der Aufruf unterMatrix(A,0,0) das Array [(5,6),(8,9)] zurückliefern. Der Aufruf unterMatrix(A,1,2) liefert [(1,2),(7,8)] usw..


Und jetzt nimm dir einfach mal ein Blatt Papier, schreib eine beliebige 5x5-Matrix auf und überlege dir, wie (nur) der erste Schritt bei der Berechnung der Determinante (nach Laplace) aussieht. Dann schreibt sich die Rekursion nahezu von selbst...
 

AsterixdGallier

Aktives Mitglied
Bist du dir sicher? Du hast da komische Zeilenpermutationen drin. Das ist in jedem Fall fehleranfällig und hat eventuell einen Vorzeichenfehler in deinen Berechnungen zur Folge.


Bei meinem Hinweis mit der Methode zu Berechnung der Untermatrix meinte ich, dass jeweils die Spalte mit dem Index spalte und die Zeile mit dem Index zeile gelöscht werden soll.

Für A = [(1,2,3),(4,5,6),(7,8,9)] soll dann etwa der Aufruf unterMatrix(A,0,0) das Array [(5,6),(8,9)] zurückliefern. Der Aufruf unterMatrix(A,1,2) liefert [(1,2),(7,8)] usw..


Und jetzt nimm dir einfach mal ein Blatt Papier, schreib eine beliebige 5x5-Matrix auf und überlege dir, wie (nur) der erste Schritt bei der Berechnung der Determinante (nach Laplace) aussieht. Dann schreibt sich die Rekursion nahezu von selbst...

hi habe jetzt einen code gemacht wo ich die gewünschte spalte auslassen kann, zeile wird meiner meinung nach für nxn nicht benötigt oder?

Java:
	public double[][] unterMatrix(double[][] matrix,int n, int spalte, int zeile)
	{
	double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n-1; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-spalte))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i+(spalte+2))%n][k];
				}
			}
		}
	return matrixHelp;
	}
 
S

SlaterB

Gast
ich schau jetzt etwas nach, zwei sofort auffällige Punkte:
du gibst finale aus, aber finale nicht zurück, sondern zwischenergebnis,
da kann sich der Aufrufer (z.B. die höhere Ebene für 5x5) ja über einen falschen Wert freuen..

für n== 3 rechnest du in der Schleife x-mal dasselbe aus,
es reicht doch das EINMAL vor der Schleife zu machen und fertig

und noch ein dritter Punkt: ein Instanzattribut finale ist ja vollkommen verrückt,
damit addierst du ja die Zwischenwerte über mehrere Ebenen zusammen?!

jeder Methodendurchlauf von macheNxNEineDimensionKleinerX() sollte für sich in lokalen Variablen ohne Einflüsse von außen,
fertige korrekte Ergebnisse gewünschter rekursiver Aufrufe abgesehen, arbeiten..,
das ist ja noch ein sehr bedenklicher Fehler, wie kann man sowas einbauen? eine Variable die von verschiedensten Schleifen im gesamten Programm bearbeitet wird

hier vorerst neuer Code,
da du noch nichtmal das erhoffte Endergebnis gepostet hast, weiß ich nicht ob richtig, 1486 kommt raus,
für die Webseite muss ich die 5x5-Matrix auch erst noch mühevoll die Zahlen extrahieren,
den Punkt hast du dir gespart

Java:
public double macheNxNEineDimensionKleinerX(int n, double[][] matrix)
    {
        if (n == 3)
        {
            return calculateDeterminante3x3(n, matrix);
        }

        double ergebnis = 0;
        double multiplikator = 2;
        double determinante = 0;
        double[][] matrixHelp = new double[n - 1][n - 1];
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                for (int k = 0; k < n; k++)
                {
                    matrixHelp[(j + (n - 2)) % (n - 1)][((k + (n - 2)) % (n - 1))] = matrix[(j + i) % n][k];
                }
            }

            double zwischenResult = macheNxNEineDimensionKleinerX(n - 1, matrixHelp);
            zwischenResult = zwischenResult * matrix[i][0];
            if ((i % 2) != 0)
            {
                ergebnis = ergebnis - zwischenResult;
            }
            else
            {
                ergebnis = ergebnis + zwischenResult;
            }

        }
        System.out.println("n: " + n + " -> " + ergebnis);
        return ergebnis;
    }
 

AsterixdGallier

Aktives Mitglied
So ich habe jetzt neuen hoffentlich übersichtlicheren code gemacht.

Java:
	else if (n > 3)
		{
			double finale2 = 0;
			double zr = 0;
			for (int r = 0; r < n; r++)
			{
				double[][] a = unterMatrix(matrix, n,r,0);
				zr = matrix[r][0]*calculateDeterminante3x3(n-1, a);
				if ((r%2)!=0)
					{
					finale2 = finale2 - zr;
					}	
				else
				{
					finale2 = finale2 + zr;
				}
				
			}
			System.out.println(finale2);
		}
Java:
	public double[][] unterMatrix(double[][] matrix,int n, int spalte, int zeile)
	{
	double[][] matrixHelp = new double[n-1][n-1];
		for (int i = 0; i < n-1; i++)
		{
			for (int j = 0; j < n; j++)
			{
				for (int k = 0; k < n; k++)
				{
					matrixHelp[(j+(n-spalte))%(n-1)][((k+(n-2))%(n-1))] = matrix[(j+i+(spalte+2))%n][k];
				}
			}
		}
	return matrixHelp;
	}
4x4 klappt mal wieder.
5x5 kommt -2840 raus, sollte aber laut internet 1610.
habe jetzt diese methode die die gewünschte spalte rauslässt und das passiert halt mit jeder einmal und wird dann mit multipliziert.
 

Fant

Bekanntes Mitglied
Die Zeilenpermutationen sind immer noch drin. Hast du das bei deinen Berechnungen berücksichtigt?

Auch versteh ich nicht so wirklich, was deine Methode da macht. Du durchläufst da defintiv eine Schleife mehr durch, als nötig wär. Bei großen Matrizen wird das tödlich ... bei n=10 hast du so schon tausend Schleifendurchläufe statt hundert, bei n=1000 sind es 1 Mrd. statt einer Million ... da wird einem schnell schwindelig *g*

Wenn du bei einer nxn Matrix nur eine Spalte streichst, dann bekommst du eine nx(n-1) Matrix. Du willst aber doch wieder eine quadratische Matrix haben. Wenn du aber immer nach der ersten Zeile entwickeln willst, dann musst du das natürlich nicht extra als Argument übergeben. Allerdings ist der Mehraufwand bei der Implementierung so verschwindend gering, dass du dich fragen solltest, ob du aus so ein nützliches Extra wirklich verzichten willst?

Mein Vorschläg wäre da einfach so etwas:

Code:
public static double[][] unterMatrix(double [][] matrix, int zeile, int spalte) {
        double [][] unterMatrix = new double[matrix.length-1][matrix.length-1];
        int zeilenOffset=0, spaltenOffset=0;

        for(int z=0; z<unterMatrix.length; z++){
            spaltenOffset=0;
            if(zeile==z) zeilenOffset=1;
            for(int sp=0; sp<unterMatrix.length; sp++){
                if(spalte==sp) spaltenOffset=1;
                unterMatrix[z][sp]= matrix[z+zeilenOffset][sp+spaltenOffset];
            }
        }
        return unterMatrix;
}

Ganz naiv angegangen. Da hast du auch nicht diese störenden Permutationen drin.
 

Fant

Bekanntes Mitglied
Zu deinem Code-Schnipsel:

Du weißt doch gar nicht, ob a eine 3x3-Matrix ist, rufst aber trotzdem die Methode zur Berechnung der Determinante einer 3x3-Matrix auf. Das kann doch gar nicht funktionieren, wenn du die det einer 5x5-Matrix berechnen willst und in a dann jeweils eine 4x4-Matrix steckt!
 
Zuletzt bearbeitet:
S

SlaterB

Gast
da haben wir ja alle einen schönen verwurschtelten Thread zustande gebracht, nun kann man mit Einzeltipps kaum mehr was erreichen,

ich habe hier jetzt eine Version, die 1610 berechnet,
ich erinnere an mein vorheriges Posting, vielleicht übersehen, besonders die finale-Variable war falsch,
und darüber hinaus war dann noch ein Fehler falsche Untermatrixen, Zeilen-Ordnung seltsam

für 4x4 aus spielte die Reihenfolge der Zeilen in 3x3-Matrixen keine so große Rolle, es kam auch mit Vertauschung dasselbe raus,
bei 5x5 sind richtige 4x4er aber schon wichtig, mit der neuen Untermethode kommen richtige raus, insgesamt 1610

Java:
class Mathetool
{
    int zähl = 0;
    double result = 0;
    double multiplikator = 1;

    public static void main(String[] args)
    {
        int n = 5;

         double[][] matrix = new double[n][n];
         matrix[0][0] = 1;
         matrix[0][1] = -2;
         matrix[0][2] = 2;
         matrix[0][3] = 3;
         matrix[0][4] = 3;
         // matrix [0][5] = 11;
        
         matrix[1][0] = 4;
         matrix[1][1] = 3;
         matrix[1][2] = 1;
         matrix[1][3] = -1;
         matrix[1][4] = 0;
         // matrix [1][5] = 6;
        
         matrix[2][0] = 5;
         matrix[2][1] = -1;
         matrix[2][2] = 1;
         matrix[2][3] = 2;
         matrix[2][4] = 7;
         // matrix [2][5] = 1;
        
         matrix[3][0] = -1;
         matrix[3][1] = 0;
         matrix[3][2] = 0;
         matrix[3][3] = 1;
         matrix[3][4] = 6;
         // matrix [3][5] = 5;
        
         matrix[4][0] = 1;
         matrix[4][1] = 10;
         matrix[4][2] = 3;
         matrix[4][3] = 4;
         matrix[4][4] = 3;
        // matrix [4][5] = 10;

        // matrix [5][0] = 1;
        // matrix [5][1] = 12;
        // matrix [5][2] = 14;
        // matrix [5][3] = 1;
        // matrix [5][4] = 2;
        // matrix [5][5] = 6;

// so kann man auch kürzer definieren:
//        double[][] matrix =
//            {
//                {3, 1, -1, 0},
//                {-1, 1, 2, 7},
//                {0, 0, 1, 6},
//                {10, 3, 4, 3}};


        Mathetool matheTool = new Mathetool();
        matheTool.determinanteAll(n, matrix);
    }

    public double determinanteAll(int n, double[][] matrix)
    {
        if (n == 3)
        {
            return calculateDeterminante3x3(n, matrix);
        }
        if (n > 3)
        {
            return macheNxNEineDimensionKleinerX(n, matrix);
        }
        throw new RuntimeException();
    }

    public double calculateDeterminante3x3(int n, double[][] matrix)
    {
        double determinante = 0;
        double zwischenErgebnisAddition = 0;
        double zwischenErgebnisSubtrahtion = 0;
        double matrixElement = 1;
        double matrixElement2 = -1;
        int j = 2;
        int k = 0;
        for (int p = 0; p < n; p++)
        {
            matrixElement = 1;
            matrixElement2 = -1;
            for (int i = 0; i < n; i++)
            {
                matrixElement = matrix[k][i] * matrixElement;
                // System.out.println( matrix[k][i]);
                matrixElement2 = matrix[k][j] * matrixElement2;
                j = j - 1;
                if (j == -1)
                {
                    j = n - 1;
                }
                k = (k + 1) % n;
            }
            zwischenErgebnisAddition = zwischenErgebnisAddition + matrixElement;
            // System.out.println(zwischenErgebnisAddition);
            zwischenErgebnisSubtrahtion = zwischenErgebnisSubtrahtion + matrixElement2;
            determinante = zwischenErgebnisAddition + zwischenErgebnisSubtrahtion;
            k = k + 1;
        }
        // System.out.println("Determinante: " + determinante);
        return determinante;
    }


    public double macheNxNEineDimensionKleinerX(int n, double[][] matrix)
    {
        int kk = 3;
        if (n == 3)
        {
            return calculateDeterminante3x3(n, matrix);
        }

        double ergebnis = 0;
        double multiplikator = 2;
        double determinante = 0;
        double[][] matrixHelp = new double[n - 1][n - 1];
        for (int i = 0; i < n; i++)
        {
            matrixHelp = unterMatrix(matrix, i, 0);
            // for (int j = 0; j < n; j++)
            // {
            // for (int k = 0; k < n; k++)
            // {
            // matrixHelp[(j + (n - 2)) % (n - 1)][((k + (n - 2)) % (n - 1))] = matrix[(j
            // + i) % n][k];
            // }
            // }
            double zwischenResult = macheNxNEineDimensionKleinerX(n - 1, matrixHelp);
            double fac = matrix[i][0];
            zwischenResult = zwischenResult * fac;

            if ((i % 2) != 0)
            {
                ergebnis = ergebnis - zwischenResult;
            }
            else
            {
                ergebnis = ergebnis + zwischenResult;
            }

        }
        System.out.println("n: " + n + " -> " + ergebnis);
        return ergebnis;
    }

    public static double[][] unterMatrix(double[][] matrix, int zeile, int spalte)
    {
        double[][] unterMatrix = new double[matrix.length - 1][matrix.length - 1];
        int zeilenOffset = 0, spaltenOffset = 0;

        for (int z = 0; z < unterMatrix.length; z++)
        {
            spaltenOffset = 0;
            if (zeile == z) zeilenOffset = 1;
            for (int sp = 0; sp < unterMatrix.length; sp++)
            {
                if (spalte == sp) spaltenOffset = 1;
                unterMatrix[z][sp] = matrix[z + zeilenOffset][sp + spaltenOffset];
            }
        }
        return unterMatrix;
    }
}
 

Fant

Bekanntes Mitglied
Und nur mal zum Vergleich, wie kurz und übersichtlich der Code wird, wenn du auf das gesonderte Berechnen der Determinanten von 3x3-Matrizen und sonstigen Schnick-Schnack verzichtest

Java:
public static double[][] unterMatrix(double [][] matrix, int zeile, int spalte) {
    double [][] unterMatrix = new double[matrix.length-1][matrix.length-1];
    int zeilenOffset=0, spaltenOffset=0;

    for(int z=0; z<unterMatrix.length; z++){
        spaltenOffset=0;
        if(zeile==z) zeilenOffset=1;
        for(int sp=0; sp<unterMatrix.length; sp++){
            if(spalte==sp) spaltenOffset=1;
            unterMatrix[z][sp]= matrix[z+zeilenOffset][sp+spaltenOffset];
        }
    }
    return unterMatrix;
}

public static double determinant(double[][] matrix) {
    if(matrix.length==1) return matrix[0][0];
    else {
        double determinant = 0;
        for(int i=0; i<matrix.length; i++) {
            determinant += (i%2==0?1:-1)*matrix[i][0]*determinant(unterMatrix(matrix,i,0));
        }
        return determinant;
    }
}

...und dann funktioniert er sogar auch für 2x2- und 1x1-Matrizen ;)
 

AsterixdGallier

Aktives Mitglied
Zu deinem Code-Schnipsel:

Du weißt doch gar nicht, ob a eine 3x3-Matrix ist, rufst aber trotzdem die Methode zur Berechnung der Determinante einer 3x3-Matrix auf. Das kann doch gar nicht funktionieren, wenn du die det einer 5x5-Matrix berechnen willst und in a dann jeweils eine 4x4-Matrix steckt!

habe ich auch gerade gemerkt das war ziemlich dämlich von mir..
 

AsterixdGallier

Aktives Mitglied
da haben wir ja alle einen schönen verwurschtelten Thread zustande gebracht, nun kann man mit Einzeltipps kaum mehr was erreichen,

ich habe hier jetzt eine Version, die 1610 berechnet,
ich erinnere an mein vorheriges Posting, vielleicht übersehen, besonders die finale-Variable war falsch,
und darüber hinaus war dann noch ein Fehler falsche Untermatrixen, Zeilen-Ordnung seltsam

für 4x4 aus spielte die Reihenfolge der Zeilen in 3x3-Matrixen keine so große Rolle, es kam auch mit Vertauschung dasselbe raus,
bei 5x5 sind richtige 4x4er aber schon wichtig, mit der neuen Untermethode kommen richtige raus, insgesamt 1610

Java:
class Mathetool
{
    int zähl = 0;
    double result = 0;
    double multiplikator = 1;

    public static void main(String[] args)
    {
        int n = 5;

         double[][] matrix = new double[n][n];
         matrix[0][0] = 1;
         matrix[0][1] = -2;
         matrix[0][2] = 2;
         matrix[0][3] = 3;
         matrix[0][4] = 3;
         // matrix [0][5] = 11;
        
         matrix[1][0] = 4;
         matrix[1][1] = 3;
         matrix[1][2] = 1;
         matrix[1][3] = -1;
         matrix[1][4] = 0;
         // matrix [1][5] = 6;
        
         matrix[2][0] = 5;
         matrix[2][1] = -1;
         matrix[2][2] = 1;
         matrix[2][3] = 2;
         matrix[2][4] = 7;
         // matrix [2][5] = 1;
        
         matrix[3][0] = -1;
         matrix[3][1] = 0;
         matrix[3][2] = 0;
         matrix[3][3] = 1;
         matrix[3][4] = 6;
         // matrix [3][5] = 5;
        
         matrix[4][0] = 1;
         matrix[4][1] = 10;
         matrix[4][2] = 3;
         matrix[4][3] = 4;
         matrix[4][4] = 3;
        // matrix [4][5] = 10;

        // matrix [5][0] = 1;
        // matrix [5][1] = 12;
        // matrix [5][2] = 14;
        // matrix [5][3] = 1;
        // matrix [5][4] = 2;
        // matrix [5][5] = 6;

// so kann man auch kürzer definieren:
//        double[][] matrix =
//            {
//                {3, 1, -1, 0},
//                {-1, 1, 2, 7},
//                {0, 0, 1, 6},
//                {10, 3, 4, 3}};


        Mathetool matheTool = new Mathetool();
        matheTool.determinanteAll(n, matrix);
    }

    public double determinanteAll(int n, double[][] matrix)
    {
        if (n == 3)
        {
            return calculateDeterminante3x3(n, matrix);
        }
        if (n > 3)
        {
            return macheNxNEineDimensionKleinerX(n, matrix);
        }
        throw new RuntimeException();
    }

    public double calculateDeterminante3x3(int n, double[][] matrix)
    {
        double determinante = 0;
        double zwischenErgebnisAddition = 0;
        double zwischenErgebnisSubtrahtion = 0;
        double matrixElement = 1;
        double matrixElement2 = -1;
        int j = 2;
        int k = 0;
        for (int p = 0; p < n; p++)
        {
            matrixElement = 1;
            matrixElement2 = -1;
            for (int i = 0; i < n; i++)
            {
                matrixElement = matrix[k][i] * matrixElement;
                // System.out.println( matrix[k][i]);
                matrixElement2 = matrix[k][j] * matrixElement2;
                j = j - 1;
                if (j == -1)
                {
                    j = n - 1;
                }
                k = (k + 1) % n;
            }
            zwischenErgebnisAddition = zwischenErgebnisAddition + matrixElement;
            // System.out.println(zwischenErgebnisAddition);
            zwischenErgebnisSubtrahtion = zwischenErgebnisSubtrahtion + matrixElement2;
            determinante = zwischenErgebnisAddition + zwischenErgebnisSubtrahtion;
            k = k + 1;
        }
        // System.out.println("Determinante: " + determinante);
        return determinante;
    }


    public double macheNxNEineDimensionKleinerX(int n, double[][] matrix)
    {
        int kk = 3;
        if (n == 3)
        {
            return calculateDeterminante3x3(n, matrix);
        }

        double ergebnis = 0;
        double multiplikator = 2;
        double determinante = 0;
        double[][] matrixHelp = new double[n - 1][n - 1];
        for (int i = 0; i < n; i++)
        {
            matrixHelp = unterMatrix(matrix, i, 0);
            // for (int j = 0; j < n; j++)
            // {
            // for (int k = 0; k < n; k++)
            // {
            // matrixHelp[(j + (n - 2)) % (n - 1)][((k + (n - 2)) % (n - 1))] = matrix[(j
            // + i) % n][k];
            // }
            // }
            double zwischenResult = macheNxNEineDimensionKleinerX(n - 1, matrixHelp);
            double fac = matrix[i][0];
            zwischenResult = zwischenResult * fac;

            if ((i % 2) != 0)
            {
                ergebnis = ergebnis - zwischenResult;
            }
            else
            {
                ergebnis = ergebnis + zwischenResult;
            }

        }
        System.out.println("n: " + n + " -> " + ergebnis);
        return ergebnis;
    }

    public static double[][] unterMatrix(double[][] matrix, int zeile, int spalte)
    {
        double[][] unterMatrix = new double[matrix.length - 1][matrix.length - 1];
        int zeilenOffset = 0, spaltenOffset = 0;

        for (int z = 0; z < unterMatrix.length; z++)
        {
            spaltenOffset = 0;
            if (zeile == z) zeilenOffset = 1;
            for (int sp = 0; sp < unterMatrix.length; sp++)
            {
                if (spalte == sp) spaltenOffset = 1;
                unterMatrix[z][sp] = matrix[z + zeilenOffset][sp + spaltenOffset];
            }
        }
        return unterMatrix;
    }
}

tatsache vielen dank den werd ich mir jetzt erstmal genau ansehen.
 
S

SlaterB

Gast
Und nur mal zum Vergleich, wie kurz und übersichtlich der Code wird, wenn du auf das gesonderte Berechnen der Determinanten von 3x3-Matrizen und sonstigen Schnick-Schnack verzichtest
die separate Methode kann man haben oder nicht haben, hat auf die Hauptmethoden wenig Einfluss,
je nach Umsetzung und Code-Stil nur eine Zeile Aufruf

den Rest hast du auch deutlich verkürzt, aber das hat ja nix mit 3x3 zu tun sondern allein dieselbe Methode viel kürzer ohne Variablen-Deklarationen, if/else Unterschied usw. ;)
 
S

SlaterB

Gast
na wenn das nicht direkt sichtbar ist..,
die Ausgabe gibt jede errechnete Determinante bis auf die 3er,
also zuerst die 5 4er in Reihenfolge, dann die 5er
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Determinante berechnen von einer Matrix Java Basics - Anfänger-Themen 3
I matrix aufgabe Java Basics - Anfänger-Themen 22
L Zweidimensionaler Array; n x m - Matrix überprüfuen Java Basics - Anfänger-Themen 35
C Matrix mit Array ausgeben Java Basics - Anfänger-Themen 6
idontknow707 Matrix nach z.B. Variable durchsuchen Java Basics - Anfänger-Themen 4
F Adjunkte Matrix erstellen Java Basics - Anfänger-Themen 3
M Matrix Java Basics - Anfänger-Themen 3
F Matrix Multiplikation Java Basics - Anfänger-Themen 3
B Dünn besetzte Matrix Java Basics - Anfänger-Themen 7
Al3xand3r01 Matrix, Nachbarelemente Java Basics - Anfänger-Themen 16
E Rückwärtsmultiplikation einer invertierten matrix Java Basics - Anfänger-Themen 2
U Dreiecks-Matrix mit Array Java Basics - Anfänger-Themen 3
Z Matrix Klasse mit Mehrdimensionalen Array (Addition, Multiplikation, to String) Java Basics - Anfänger-Themen 57
E 2D Array - char durch die Matrix "wandern" lassen Java Basics - Anfänger-Themen 7
M Matrix auf 4 Elemente untersuchen mit offenen Enden Java Basics - Anfänger-Themen 8
B Diskrete Faltung (Matrix) Randfälle Java Basics - Anfänger-Themen 8
M Matrix Elemente vergleichen Java Basics - Anfänger-Themen 11
N Quadratische Matrix inkl Summe Java Basics - Anfänger-Themen 8
J Methoden Moving a n integer matrix Java Basics - Anfänger-Themen 3
D Methoden Matrix Multiplikation Java Basics - Anfänger-Themen 27
O Matrix, Vektor Java Basics - Anfänger-Themen 9
H 2D Array, Symmetrische Matrix Java Basics - Anfänger-Themen 12
S Matrix spaltenweise befüllen Java Basics - Anfänger-Themen 1
T Zufällige Matrix in neue Matrix schreiben Java Basics - Anfänger-Themen 6
C Matrix-Werte werden nicht wie erwartet ausgegeben Java Basics - Anfänger-Themen 7
C Matrix erstellen Spaltensumme, Zeilensumme, Diagonale Java Basics - Anfänger-Themen 1
S Methoden Transponierte Matrix Java Basics - Anfänger-Themen 3
N Vererbung Submatrix mit Verweis auf Matrix erstellen Java Basics - Anfänger-Themen 9
J Matrix erstellen Java Java Basics - Anfänger-Themen 7
B Transponiertes Matrix Java Basics - Anfänger-Themen 12
J Überprüfen, ob eine 2D Matrix ein Baum ist Java Basics - Anfänger-Themen 5
C Matrix transponieren - Hilfe Java Basics - Anfänger-Themen 1
D Ausgabe einer Matrix mit System.out.println Java Basics - Anfänger-Themen 6
T Art 4 Felder Matrix Memory Java Basics - Anfänger-Themen 2
U Ist diese Methode zur Matrix Vektor Multiplikation korrekt ? Java Basics - Anfänger-Themen 5
L Matrix(Array) minimieren... Java Basics - Anfänger-Themen 9
E Matrix mit Vektor multiplizieren Java Basics - Anfänger-Themen 7
S eingegebene Matrix anzeigen Java Basics - Anfänger-Themen 4
J Matrix für Schachbrett Java Basics - Anfänger-Themen 6
G tga Datei lesen und in eine matrix umwandeln Java Basics - Anfänger-Themen 1
G Bilddaten in Matrix umwandeln Java Basics - Anfänger-Themen 1
T Eine String Matrix erstellen die eine boolean Funtion verwendet Java Basics - Anfänger-Themen 10
O Matrix Multiplizieren Java Basics - Anfänger-Themen 4
S LWJGL - Matrix vom Matrixstack laden Java Basics - Anfänger-Themen 3
T Matrix auf Symmetrie überprüfen Java Basics - Anfänger-Themen 6
V Matrix Transponieren Java Basics - Anfänger-Themen 3
V Methoden Matrix als 1D Array mit Werten füllen Java Basics - Anfänger-Themen 12
W Zweidimensionale Arrays als Matrix ausgeben Java Basics - Anfänger-Themen 8
R Matrix-Vektor-Multiplikation Java Basics - Anfänger-Themen 13
O Matrix ordnen Java Basics - Anfänger-Themen 4
M Symmetrische Matrix Java Basics - Anfänger-Themen 2
W Methoden Rang von einer Matrix mit Gauss Java Basics - Anfänger-Themen 0
U Matrix Subtrahieren Java Basics - Anfänger-Themen 12
E Input/Output convert string to two dimensional char and output = matrix Java Basics - Anfänger-Themen 2
A daten vom 1d array in 2d matrix speichern Java Basics - Anfänger-Themen 3
I Matrix überprüfen Java Basics - Anfänger-Themen 8
Z Matrix mit Vektor multiplizieren Java Basics - Anfänger-Themen 13
K Methoden Einlesen einer unbegrenzten Matrix über Konsole Java Basics - Anfänger-Themen 6
O Einlesen einer Matrix von der Console Java Basics - Anfänger-Themen 18
N Matrix/Vektoren Java Basics - Anfänger-Themen 3
N Matrix Java Basics - Anfänger-Themen 14
T Methode, die eine 2 dimensionale Matrix kopiert. Java Basics - Anfänger-Themen 16
J Matrix Java Java Basics - Anfänger-Themen 3
D 2 mehrdimensionale Matrix einlesen Java Basics - Anfänger-Themen 2
K Quadratische Matrix um 90° drehen Java Basics - Anfänger-Themen 5
C Programm zur Berechnung der Spur einer Matrix Java Basics - Anfänger-Themen 4
B Zeilenumbruch (zweidim. Matrix) Java Basics - Anfänger-Themen 2
O Java Matrix mal Matrix über while Schleife... Java Basics - Anfänger-Themen 10
O Transponieren einer Matrix per While-Schleife Java Basics - Anfänger-Themen 3
M Matrix - Probelm Java Basics - Anfänger-Themen 7
O 2D Matrix befüllen mit geraden Zahlen!? Java Basics - Anfänger-Themen 14
J Java Matrix befüllen Java Basics - Anfänger-Themen 5
M Matrix Matrix Multiplikation Java Basics - Anfänger-Themen 6
F Matrix Java Basics - Anfänger-Themen 11
E Array als Matrix Java Basics - Anfänger-Themen 21
G OOP Parameter Matrix Java Basics - Anfänger-Themen 2
N Matrix Klasse Java Basics - Anfänger-Themen 4
B Maske an eine Matrix anpassen Java Basics - Anfänger-Themen 5
W Matrix übergeben Java Basics - Anfänger-Themen 7
T Matrix transponieren Java Basics - Anfänger-Themen 17
W Eine Methode schreiben, ob eine Matrix eine Diagonalmatrix ist.? Java Basics - Anfänger-Themen 3
M String Datei in Float-Matrix umwandeln Java Basics - Anfänger-Themen 8
D Problem: Werte eine Matrix vergleichen! Java Basics - Anfänger-Themen 5
B Matrix Java Basics - Anfänger-Themen 2
Semox Matrix multiplizieren Java Basics - Anfänger-Themen 4
N Matrix an toString Java Basics - Anfänger-Themen 7
C Diagonale in einem NxN Matrix Java Basics - Anfänger-Themen 6
F Einträgen von Matrix zu sotieren Java Basics - Anfänger-Themen 2
D JUnit auf Matrix anwenden Java Basics - Anfänger-Themen 5
J Spezielle Matrix ausgeben ! Java Basics - Anfänger-Themen 8
S Problem bei Matrix Addition Java Basics - Anfänger-Themen 5
F matrix werte übergeben Java Basics - Anfänger-Themen 5
M Hauptdiagonale Matrix berechnen Java Basics - Anfänger-Themen 6
M Klassenerstellung für Matrix mit Rechenopperationen Java Basics - Anfänger-Themen 42
D Matrix .bat datei erstellen und öffnen Java Basics - Anfänger-Themen 2
J Matrix ausgeben Java Basics - Anfänger-Themen 9
N Matrix Matrix Produkt Java Basics - Anfänger-Themen 7
N prüfe ob etwas in einer Matrix steht... Java Basics - Anfänger-Themen 14
L rechtecke zeichnen anhand von matrix Java Basics - Anfänger-Themen 27
J Matrix aus Datei einlesen mit StreamTokenizer Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben