problem bei einigen berechnungen



  • erstmal an alle ein großes hallllo 🙂 .

    so nun mein problem, ich füg mal schnell den quellcode ein:
    bis jetzt funktioniert alles so wie ich es mir vorstelle. nur leider rechnet mein gaussverfahren (steht weiter unten im code) noch falsch und ich find den fehler irgendwie gerade nicht 😕. kann mir da vielleicht jemand weiterhelfen?

    #include "stdafx.h"
    #include <stdio.h>
    #include <math.h>
    #include <iostream.h>
    #define max 10 
    
    void main()
    {
        int spalten_a, ispalten;   //spalten matrix a
        int zeilen_a;   //zeilen matrix a
        int spalten_b;   //spalten matrix b
        int zeilen_b;   //zeilen matrix b
    	int zeilen_vektor;   //zeilen vektor v
    	int i,j,k,l;       
        int matrixA[max][max]; //erste Matrix
        int matrixB[max][max]; //zweite Matrix
        int matrixC[max][max]; //ergebnis Matrix
    	int vektorU[max];	   //erster Vektor
    	int vektorV[max];      //zweiter Vektor
    	int vektorW[max];      //ergebnisvektor
    	char ende;
    
    	float matrixAg[max][max];
    	float vektorN[max];      // LGS ergebnis
    	float vektorX[max];    // gesuchte Nullstellen
    	int m;
    
        do
    	{
    // Eingabe der 2 Matrizen
    
    	while(1){
    
          /*  cout << "Gib die Dimensionen der Matrizen ein (min. 1, max. "<< max << " ):" << endl;
    		cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;*/
            cout << "Gib die Dimensionen der Matrizen ein:" << endl;
    		cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    		cout << "Wieviele Zeilen hat die Matrix A ?" << endl; 
    		cout << "Zeilen: ";
    		cin >> zeilen_a;
    		cout << "Wieviele Spalten hat die Matrix A ?" << endl;
    		cout << "Spalten: ";
    		cin >> spalten_a;
    		cout << "\nWieviele Zeilen hat die Matrix B ?" << endl;
    		cout << "Zeilen: ";
    		cin >> zeilen_b;
            cout << "Wieviele Spalten hat die Matrix B ?" << endl;
    		cout << "Spalten: ";
    		cin >> spalten_b;
    		ispalten = spalten_a;
    
    // mit dieser endlosschleife wird die eingabe solange wiederholte bis die matrizen den richtigen wert haben
    // also in diesem beispiel 3x3, weil define max 3.
    
         if(spalten_a==zeilen_b)
    		 break;
    
            else 
    			cout << "Die Matrizen lassen sich so nicht Multiplitzieren gib neue Werte ein !!!\n";
        }
    
    // wenn die matrizen den richtigen wert haben gehts hier weiter
        cout << "\nMatrix A hat das Format " << spalten_a << " x " << zeilen_a << endl;
        cout << "Matrix B hat das Format " << spalten_b << " x " << zeilen_b << endl;
        cout << "\nBelege die Matrix A mit " << spalten_a*zeilen_a << " Werten:" << endl;
    	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
    
    // Matrix A belegen
        for (i=0; i<zeilen_a; i++)
        {    
    		cout << "\nZeile " << i+1 << " = "; 
    
    		for (j=0; j<spalten_a; j++)
    
    			cin >> matrixA[i][j];
        } 
    
     // Matrix A zur kontrolle ausgeben
       cout << "\n\tMatrix A:";
    	for (i = 0; i < zeilen_a; i++)
        {    
    		  cout << "" << endl;
    
    		for (j=0; j<spalten_a; j++)
    
    			cout << "\t" <<matrixA[i][j];
    
        } 
    
    	cout << "\n\nBelege die Matrix B mit " << spalten_b*zeilen_b << " Werten:" << endl;
    	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
    
    // Matrix B belegen
        for (i = 0; i < zeilen_b; i++)
        {    
    		cout << "\nZeile " << i+1 << " = "; 
    
    		for (j=0; j<spalten_b; j++)
    
    			cin >> matrixB[i][j];
        } 
    
    // Matrix B zur kontrolle ausgeben
        cout << "\n\tMatrix B:";
    	for (i=0; i<zeilen_b; i++)
        {    
    		cout << "" << endl; 
    
    		for (j=0; j<spalten_b; j++)
    
    			cout << "\t" << matrixB[i][j];
    
        }
    
    	cout << "\n\n" << endl;
    	cout << "Berechnung (Mulitplikation mit Falk- Schema) der beiden Matrizen:" << endl;
    	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    
    // Matrix berechnen (multiplikation)
    
    for (k=0; k<zeilen_a; ++k) 
          for (l=0; l<spalten_b; ++l){
            int s = 0;
            for (int h=0; h<spalten_a; ++h)
              s = s + matrixA[k][h] * matrixB[h][l];
            matrixC[k][l] = s;
          }
    
    	for (k=0; k<zeilen_a; k++)
        {    
    		cout << endl; 
            for (l=0; l<spalten_b; l++)
                cout << "\t" << matrixC[k][l];
    
        }
    
    // Vektor-Multiplikation
    cout << "\n\nVektormultiplikation:" << endl;
    cout << "*********************" << endl;
    cout << "\nWieviele Zeilen haben die Vektoren?" << endl;
    cout << "Vektorzeilen: ";
    cin >> zeilen_vektor;
    
    // Vektor u belegen
    cout << "\nVektor u: "<<endl;
    for(i=0; i<zeilen_vektor; i++)
    {
    	cout << "Zeile " << i+1 << " = ";
    	cin >> vektorU[i];
    
    }
    
    // Vektor u zur Kontrolle ausgeben
    cout << endl;
    cout << "\n\tVektor u:";
    for(i=0;i<zeilen_vektor;i++)
    {
    	cout << "" << endl;
    	cout << "\t" <<vektorU[i];
    
    }
    
    // Vektor v belegen
    cout << endl << endl;
    cout << "Vektor v: "<<endl;
    for (j=0; j<zeilen_vektor; j++)
    {
    	cout << "Zeile " << j+1 << " = ";
    	cin >> vektorV[j];
    }
    
    // Vektor v zur Kontrolle ausgeben
    cout << "\n\tVektor v:";
    for(j=0;j<zeilen_vektor;j++)
    {
    	cout << "" << endl;
    	cout << "\t" <<vektorV[j];
    }
    cout << endl;
    // Vektor Multiplikation
    
    for(k=0;k<zeilen_vektor;k++)
    {
    	vektorW[k]=vektorU[k]*vektorV[k];
    }
    
    cout << "\nErgebnis: Vektor u * Vektor v"<<endl;
    cout << "============================="<<endl;
    
    cout << "\n\tVektor w:";
    for(l=0;l<zeilen_vektor;l++)
    {
    	cout << "\n" << endl;
    	cout << "\t" << vektorW[l];
    }
    
    cout << endl << endl;;
    
    // Gaussverfahren
    
    /*****************************************************/
    
    	float f;
    
    	// Eingabe von a und b ...
    
    	cout << "Gaussverfahren (in der Form A*x=b):" << endl;
    	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    	cout << "\nWieviele Zeilen hat die Matrix ?" << endl;
    	cout << "Zeilen: ";
    	cin >> zeilen_a;
    	cout << "Wieviele Spalten hat die Matrix ?" << endl;
    	cout << "Spalten: ";
    	cin >> spalten_a;
    	cout << "Matrix eingeben:" << endl;	
    // Matrix eingeben
        for (i=0; i<zeilen_a; i++)
        {    
    		cout << "\nZeile " << i+1 << " = "; 
    
    		for (j=0; j<spalten_a; j++)
    
    			cin >> matrixAg[i][j];
        } 
    
    // Matrix zur kontrolle ausgeben
       cout << "\n\tMatrix A:";
    	for (i = 0; i < zeilen_a; i++)
        {    
    		  cout << "" << endl;
    
    		for (j=0; j<spalten_a; j++)
    
    			cout << "\t" <<matrixAg[i][j];
    
        } 
    
    // Vektor n ausgeben
    cout << "\n\nVektor x:" << endl;
    for(i=0;i<zeilen_a /*zeilen_vektor*/ ;i++)
    {
    	cout << "x" << i+1 << " = ?" << endl;
    
    }
    
    // Vektor b belegen  (Ergebnisvektor)
    //cout << "\n\nWieviele Zeilen hat der Vektor ?" << endl;
    //cout << "Zeilen: ";
    //cin >> zeilen_vektor;
    cout << "\n\nVektor b (" << zeilen_a << " Zeilen):"<<endl;
    for(i=0; i<zeilen_a /*zeilen_vektor*/; i++)
    {
    	cout << "Zeile " << i+1 << " = ";
    	cin >> vektorN[i];
    
    }
    
    // Vektor b zur Kontrolle ausgeben
    cout << "\n\tVektor b:";
    for(i=0;i<zeilen_a /*zeilen_vektor*/ ;i++)
    {
    	cout << "" << endl;
    	cout << "\t" <<vektorN[i];
    
    }
    
    	//In Dreiecksform bringen:
    	cout << "\n\nBerechnung" << endl;
    	cout << "**********" << endl;
    
    	for (k = 0; k < zeilen_a; ++k)
    	for (l = k+1; l < zeilen_a; ++l) 
    	{
    		f = matrixAg[l][k]/matrixAg[k][k];
    
    		for (m = k; m<zeilen_a; ++m)
    			matrixAg[l][m] = matrixAg[l][m] - f*matrixAg[k][m];
    
    		vektorN[l] = vektorN[l] - f*vektorN[k];
    	}
    //Rückrechnung (x-Werte berechnen):
    for (k = zeilen_a-1; k>=0; --k) 
    {
    	float z = vektorN[k];
    
    	for (l=k+1; l<zeilen_a; ++l)
    	z = z - vektorX[l]*matrixAg[k][l];
    	vektorX[k] = z/matrixAg[k][k];
    }
    // Ausgabe von vektorX ...
    
    cout << endl;	
    for (l=0;l<zeilen_a;l++)	
    cout << "\t" << "x" << l+1 << " = " << vektorX[k] << endl;
    
    //}
    
    /*****************************************************/
    
    // Weiter?
    	  cout << "\nWeiter (j/n): ";
    	  cin >> ende;
    	  cout << "\n" << endl;
    	  }while(ende != 'n');
    
    }
    


  • erste Hilfe:

    Beschreib den Fehler (Was macht das Programm was es deiner Meinung nach nicht machen soll). "geht nich" ist keine Fehlerbeschreibung.



  • jo, stimmt.
    also bei der gaussberechnung sollen eigentlich unbekannte nullstellen berechnet werden. er berechnet auch irgendwas, aber dann doch das falsche. es kommen z.b. bei einer 4x4 matrix mit zugehörigen vektor 4 mal die selben (falschen) werte raus. ansonsten läuft das programm 🙂

    mfg



  • Hi,
    erstmal meckern:

    Warum ballerst du denn den ganzen Quellcode der Matrixmultiplikation vorweg, wenn der Fehler beim Gaussverfahren ist ?
    Unnötig viel Quellcode erschwert die Fehlersuche, erst recht für einen, der das alles nicht selbst programmiert hat, logisch ne?
    Quellcode lesen ist nicht gerade wie Bildzeitung lesen, wenn du verstehst was ich meine.

    Ansonsten scheint die Bildung der Dreiecksmatrix und die Rückrechnung ok zu sein, du brauchst eigentlich nur in der Zeile 301
    vektorX[k] durch vektorX[l] zu ersetzen, dann klappt das mit dem Gaußschen Algorithmus 😉

    Tipp: Debugger benutzen oder Inhalt der Variablen zwischendurch am besten in einer extra Funktion anzeigen lassen.

    Gruuuuuuhuuuß,
    p.

    Gruß, p.
    🙂



  • hi Nolbelt,

    Das ist falsch: for (m = k; m<zeilen_a; ++m)
    
    Das ist richtig: for (m = zeilen_a-1; m >= k; m--)
    

    vg tesu

    Hier noch ein Beispiel für einen Gaussalgo mit Pivotsuche und Zeilentausch. Die Dreieckszerlegung und Aufrechnung der Unbekannten xi wirds du im Code leicht finden. Pivot und Zeilentausch kannst du ja überspringen. Anstelle a(j,i) denkst du dir a[j][i]. (Es ist halt eine Methode aus einem Klassentemplate, das ich vor kurzem geschrieben habe. Es funktioniert fehlerfrei, ist allerdings noch nicht so optimal programmiert.)

    // Gauss with pivoting to solve Ax=r
    template <class T> bool matrix<T>::gsolver (matrix<T>& a, matrix<T>& r, matrix<T>& x)
    /*
     Solution of A*x=r by original Gauss algorithm with pivoting
     a - coefficient matrix, will be overwritten
     r - right side vector, will be overwritten
     x - resulting vector
    
     return
     true  - success
     false - singular matrix
    
     Further reading: Carl Friedrich Gauss: Disquisitiones arithmeticae. Hannover(1801).
    */
    
    { int i, j, k, p, n=a.ncols; T h, e = matrix<T>::getSingularLimit();
      for (i = 0; i<n; i++)
      {
         p = i;
         for (j = i+1; j<n;j++)                                      /* get pivot */
           if (fabs ( a ( p, i ) ) < fabs ( a ( j , i ) )) p = j;
         if (p != i)
         {                                                       /* exchange rows */
          for (k = i; k<n; k++)
          {
            h= a ( i, k ); a ( i, k )= a ( p, k ); a ( p, k )= h;
          }
          h = r ( i ); r ( i ) = r ( p ); r ( p ) = h;
         }
         for (j = i + 1; j<n;j++)
           if (e * fabs ( a ( j, i ) ) < fabs(a ( i, i )))
           { h = a ( j, i ) / a ( i, i ); r ( j ) = r ( j ) - h * r ( i );
             for (k = n-1; k >= i; k--) a ( j, k ) = a ( j, k ) - h * a ( i, k );
           }
            else {a.rank(i+1); return false;}                  /* singular matrix */
      }
      for (j = n-1; j>=0;j--)
       { h = T(0);
         for (i = j + 1; i < n; i++) h = h + a ( j, i ) * x(i);
         h = r ( j ) - h;
         if (e * fabs ( h ) < fabs( a ( j, j ) )) x(j) = h  / a ( j, j );
           else {a.rank(i+1); return false;}                   /* singular matrix */
       }
      a.rank(n); return true;
    }
    


  • @proggingmania
    stimmt schon. ich werds mir fürs nächste mal merken 😉
    der vergleich mit der bildzeitung ist gut 😃

    @tesuji
    danke für den code. ich werde ihn auch mal ausprobieren 🙂

    mfg


Anmelden zum Antworten