Matrix als Funktion programmieren



  • Hallo,

    ich möchte gerne eine Matrix mit variabler Größe und variablen Einträgen programmieren, auf die dann eine mathematische Funktion zugreifen kann und mit ihr rechnen kann. Google hat mich leider nicht weiter gebracht, weil ich nur Matrixdefinitionen in der main Funktion gefunden habe.

    In C sah der Code so aus (den habe ich von meinem Prof bekommen):

    typedef double *PVector;
    typedef double **PMatrix;
    
    PVector TVector_Create(int n){
    	return (PVector) calloc(n, sizeof(double));
    }
    
    PMatrix TMatrix_Create(int m, int n){
    	PMatrix  A;
    	int i;
    	A = (PMatrix) malloc(m * sizeof(PVector));
    	for ( i=0; i<m; i=i+1 )
    		A[i] = TVector_Create(n);
    	return A;
    }
    

    Jetzt möchte ich aber gerne für Vektoren

    vector<double>
    

    benutzen.
    Wie kann ich dann den Code für dir Matrix umschreiben?
    Mein Versuch war

    typedef double  **Matrix;
    Matrix NeueMatrix(int m, int n){
    	Matrix  A;
    	vector<double> y;
    	int i;
    	A = (Matrix) new(m * y.size());
    	for ( i=0; i<m; i=i+1 )
    		A[i] = vector<double> ;
    	return A;
    }
    

    Leider funktioniert das aber nicht. Liegt das an dem "new"?
    Kann mir vielleicht jemand einen Tip geben?
    Danke!



  • Am einfachsten baust du dir deine Matrix aus std::vector<std::vector<T>>.
    Am effizientesten machst du einfach nur einen std::vector<T> mit der Größe MxN und rechnest indexzugriffe um.

    typedef std::vector<std::vector<double> > Matrix;
    Matrix NeueMatrix(int m, int n)
    {
        Matrix  A(m);
        for (int i = 0; i < n; ++i)
            A[i].resize(m);
        return A;
    }
    

    Wäre in etwa die erste Lösung (was du versucht hast, aber total falsch, besorg dir ein C++ Buch !)

    Die zweite könnte so aussehen:

    typedef std::vector<double> Matrix;
    Matrix NeueMatrix(int m, int n)
    {
      return std::vector<double>(m * n);
    }
    


  • Upps, hab bei der ersten Lösung m/n 2x durcheinander gebracht, wirst aber leicht sehen was falsch ist. 😉



  • Super, danke. Das hat mir sehr geholfen!



  • Wenn du alles selbst programmieren willst statt fertige Bibliotheken zu benutzen könntest du templates einsetzen, um Matrizen und Vektoren zu realisieren. Über die Template Parameter kannst du sogar die Rechenregeln forcieren.

    template<typename T, unsigned int M, unsigned int N>
    class Matrix
    {
       std::vector<T> Elements_;
    
       // alternativ, falls vom Compiler unterstützt
       std::tr1::array<T, M*N> Elements_;
    
    public:
       Matrix() : Elements_( M * N )
       {
       }
    };
    

    analog dazu evtl.

    template<typename T, unsigned int M>
    class Vektor
    {
       std::vector<T> Elements_;
    public:
       Vektor() : Elements_( M )
       {
       }
    };
    

    und Rechenoperationen als freie Funktionen:

    template<typename T, typename U, unsigned int M, unsigned int N>
    Matrix<T,M,N> operator*( const Matrix<T,M,N>& m, const Vektor<U,N>& v )
    {
       Matrix<T,M,N> Result;
       ...
       return Result;
    }
    


  • DocShoe schrieb:

    Wenn du alles selbst programmieren willst statt fertige Bibliotheken zu benutzen könntest du templates einsetzen, um Matrizen und Vektoren zu realisieren. Über die Template Parameter kannst du sogar die Rechenregeln forcieren.

    Im Startpost steht variable Größe 🙂 Also wird ihm/ihr was Compiletime konstantes nicht wirklich nutzen. Findest du nicht auch? Ausserdem geht das. soweit ich das sehe, weit über den vorhandenen Kenntnisstand hinaus.

    @Himbeerchen wieviel Programmiererfahrung hast du denn? Ich würde mal vermuten, dass du noch nicht so viel in C++ gemacht hast. Da kann ich dir nur den Tipp geben: lass die Finger erstmal davon und hol dir etwas bereits fertiges. Es gibt so unglaublich viele Bibliotheken, da wirst du sicherlich was finden.

    Hier mal ein paar Beispiele:
    boost::ublas
    Eigen
    MTL
    Blitz++

    Die sollten auch alle wesentlich fixer sein als eure jetzige Konstruktion. Das sind natürlich externe Abhängigkeiten, da solltest du den Prof fragen ob und was erlaubt ist. Wenn bereits boost verwendet wird, kannst du ublas zum Beispiel ohne Aufwand nutzen(und wenn es ein Programm nur für dich ist, geht natürlich alles 🙂 ).



  • otze schrieb:

    DocShoe schrieb:

    Wenn du alles selbst programmieren willst statt fertige Bibliotheken zu benutzen könntest du templates einsetzen, um Matrizen und Vektoren zu realisieren. Über die Template Parameter kannst du sogar die Rechenregeln forcieren.

    Im Startpost steht variable Größe 🙂 Also wird ihm/ihr was Compiletime konstantes nicht wirklich nutzen. Findest du nicht auch?

    Nein, finde ich nicht. Ich habe variable Größe so aufgefasst, dass der Datentyp in der Lage sein soll, beliebige MxN Matrizen repräsentieren zu können. Iim Gegensatz zu statischen Implementationen, dir nur mit z.B. 3x3 Matrizen umgehen können.

    otze schrieb:

    Ausserdem geht das. soweit ich das sehe, weit über den vorhandenen Kenntnisstand hinaus.

    Vermutlich...


Anmelden zum Antworten