Matrixpointer



  • Hallo zusammen!
    Mein Problem ist dass ich viele schlimme Sachen mit einer Matrix machen muss. Dafür erstelle ich mir ein Pointerarry wobei jeder Pointer wieder auf ein double Array zeigt.
    Ich habe dafür eine allozierungsfunktion geschrieben. Ich habe aus meinem Buch den Befehl malloc dafür verwendet. Ich nehme auch gerne new wenn mir jemand erklärt wie^^ Bei mir hat das irgendwie nicht geklappt.

    Das Programm kompiliert ohne Fehler. Leider gibt es einen Fehler beim Aufrufen meiner Matrix_malloc() Funktion.

    "Eine nicht behandelte Ausnahme des Typs "System.NullReferenceException" ist in Jacobi.exe aufgetreten.

    Zusätzliche Informationen: Object reference not set to an instance of an object."

    Dabei zeigt er auf diese Zeile:

    if(!(*tmp = (double *) malloc(n*sizeof(double*)))){
    

    Die gesamte Funktion sieht so aus:

    double** m_alloc(int n) {
    	unsigned int j;
    	double** tmp;
    	if(!(*tmp = (double *) malloc(n*sizeof(double*)))){ 
    		return NULL;
    	}
    	for (j = 0; j < n; ++j) {
    		if(!(tmp[j] = (double *) malloc(n*sizeof(double)))){
    			return NULL;
    		}
    	}
    	return tmp;
    }
    

    Ich freue mich sehr über jede Hilfe und Verbesserung!


  • Mod

    *tmp ist eine Dereferenzierung eines uninitialisierten Zeigers. Das hättest du mit der Fehlermeldung auch leicht gogglen können.

    Deinen Code...kann ich nicht verbessern. Das ist zu schlimm. Schmeiß weg, lern die Sprache die du benutzen möchtest, mach's neu.



  • tut mir leid für den grausamen Code 😃
    Wir müssen für Numerik einige Sachen implementieren und unser vorheriges Programm hatten wir in C zum laufen bekommen.
    Das nächste machen wir in c++, leider ist das ein wenig anders mit den Pointern.
    Um mir großes Wissen über c++ anzueignen ist jetzt leider nicht die Zeit. Erst in den Weihnachtszeit (Vorlesungsfrei).
    Im Mathestudium hat man einiges um die Ohren, so dass man nicht dazu kommt Zeit anderweitig zu investieren.

    Ich würde mich trotzdem gerne an eurem Wissen bereichern wenn ihr so nett seid 🙂
    Wenn dieser Code so schlecht ist, dann würde ich mich über eine alternative bzw. korrekte implementierung eines Pointerarrays mit den gewünschten Eigenschaften freuen 🙂

    LG
    Sunflower



  • Das ist aber nicht C++.



  • Sunflower schrieb:

    Mein Problem ist dass ich viele schlimme Sachen mit einer Matrix machen muss.

    Und zwar?

    Sunflower schrieb:

    Ich freue mich sehr über jede Hilfe und Verbesserung!

    Verwende Kapselung. Verwende einen eigenen Typen als Matrix-Abstraktion. Zeigerfrickeleien sind doch fehleranfällig.

    #include <vector>
    #include <cassert>
    
    class matrix
    {
      std::vector<double> coeffs_;
      int rows_, cols_;
    
      typedef std::vector<double>::size_type size_type;
    
      size_type indexof(int i, int j) const {
        assert( 0<=i && i<rows_ );
        assert( 0<=j && j<cols_ );
        return size_type(i)*cols_ + j; // row major
      }
    
    public:
      matrix();
      matrix(int r, int c, double default_value=0);
    
      void reset(int r, int c, double default_value=0);
    
      int rows() const {return rows_;}
      int cols() const {return cols_;}
    
      double  operator()(int i, int j) const {return coeffs_[indexof(i,j)];}
      double& operator()(int i, int j)       {return coeffs_[indexof(i,j)];}
    };
    
    :::
    
    int main()
    {
      matrix m (5,5,0.0);
      for (int i=0; i<5; ++i)
        m(i,i) = 42;
    
      return 0;
    }
    

    u.s.w.



  • Danke Krümelkacker!
    Dein Beitrag hat geholfen dass ich wieder bisschen etwas zu Klassen verstanden habe.

    Zur anderen Frage
    Ich muss im einzelnen Householdertransformationen, Givens Rotationen, Sigular Value Decomposition und am Ende noch Jacobi, Gauß Seidel und SOR implementieren.
    Insgesammt muss ich die Matrix also auf Tridiagonalgestalt, Bidiagonalgestallt bringen und später aufspalten um interative Verfahren darauf anzuwenden.
    Also insgesamt nur aufwendig, nicht besonders schwer. (Außer HH)
    Nur zuvor hatten wir es in C und da war es mit den Pointern nach einiger Zeit doch etwas zu hässlich und dann wollte ich mich an c++ trauen.

    LG



  • Sunflower schrieb:

    Zur anderen Frage
    Ich muss im einzelnen Householdertransformationen, Givens Rotationen, Sigular Value Decomposition und am Ende noch Jacobi, Gauß Seidel und SOR implementieren.
    Insgesammt muss ich die Matrix also auf Tridiagonalgestalt, Bidiagonalgestallt bringen und später aufspalten um interative Verfahren darauf anzuwenden.
    Also insgesamt nur aufwendig, nicht besonders schwer. (Außer HH)
    Nur zuvor hatten wir es in C und da war es mit den Pointern nach einiger Zeit doch etwas zu hässlich und dann wollte ich mich an c++ trauen.

    Tu das.

    Was war noch gleich die Frage?



  • Die Frage wurde dank Krümelkacker beantwortet, danke 🙂
    Ich hab mich ein bisschen den Container "vector" eingelesen und ein wenig in obj. Programmierung. Jetzt hab ich garkeine Pointer mehr!
    Das ist herrlich.

    LG



  • Sunflower schrieb:

    Ich muss im einzelnen Householdertransformationen, Givens Rotationen, Sigular Value Decomposition und am Ende noch Jacobi, Gauß Seidel und SOR implementieren.

    Autsch. Musst Du das? Glaub'ich nicht. Selbst in meinem dicken Numerikbuch, welches ich für zwei Semester (Numerik I und Numerik II) verwendet habe, steht nicht drin, wie sie SVD berechnet werden kann, sondern nur dass es sie gibt (mit Beweis). Der einzige Hinweis zu den Berechnungen war "Das würde den Rahmen dieses Buches sprengen". SVD berechnen ist schwarze Magie. So'was implementiert man einfach nicht selbst. Man benutzt fertige Bibliotheken wie z.B. Eigen, welche die Arbeit mit Matrizen und Vektoren unter C++ ähnlich einfach macht wie unter Matlab zum Beispiel...

    Sunflower schrieb:

    Insgesammt muss ich die Matrix also auf Tridiagonalgestalt, Bidiagonalgestallt bringen und später aufspalten um interative Verfahren darauf anzuwenden.
    Also insgesamt nur aufwendig, nicht besonders schwer. (Außer HH)

    Wenn Du mit HH Householder meinst: HH ist noch mit das einfachste von dem, was Du alles aufgezählt hast.



  • SVD´s berechnen ist einfacher als HH implementieren

    Wenn man es natürlich genau nimmt dann kann man eine SVD nicht berechnen weil es keinen exakten algorithmus gibt um die Eigenwerte zu bestimmen.
    Aber es gibt eine Möglichkeit sich super stabil an die Eigenwerte anzunähern.
    Dann muss man einfach die Eigenvektoren zu den Eigenwerten bestimmen woraus man dann eine Orthogonale symmetrische Matrix V aus Eigenvektoren zusammensetzten kann und eine Matrix D mit Eigenwerten auf der Diagonalen. Dann fehlt nur noch U und das ist mit 2 bekannten Matritzen einfach zu berechnen.

    Gruß
    Sunflower



  • Ich weiß nicht genau was du damit meinst das HH das einfachste davon wäre. Ich habe zwar Gauß Seidel und SOR noch nicht implementiert, aber ich denke wenn ich SOR hab dann kommt Gauß Seidel von selber.
    Givens ist wirklich einfach. Aber HH ist da noch am Fehleranfälligsten. Die normale HH funktioniert bei mir auch.
    Nur die HH die meine Tridiagonalgestallt aus meiner Matrix erzeugen soll um anschließend mit Givens die Nebendiagonalen systematisch zu elemenieren funktioniert bei mir nicht. Der Algorithmus ist bei alles Verfahren einfach. Nur bei der Implementierung scheitert es. Warum hab ich bis jetzt nicht herausgefunden. Aber ich hab ja noch 2 Wochen.

    LG
    Sunflower


Anmelden zum Antworten