Matrix Vektor Multiplikation



  • Hallo,
    ich mache grade eine Hausarbeit bei dem ich ein Vektor und eine Matrix aus einer Textdatei einlesen und dann durch eine externe Funktion Multiplizieren soll. Das einlesen und Multiplizieren habe ich hinbekommen aber bekomme es nicht hin mit einer Funktion (ob intern oder extern).

    #include <iostream>
    #include <fstream>
    int main(){
    
        double *b=NULL,*a1=NULL;
        int n,m,dim,zeile,spalte;
        char in1[20],in2[20];
        
        
        //Vektor einlesen und auf b speichern
        std::ifstream myfile1;
        std::cout<<"Geben Sie die Textdatei fuer den Vektor ein"<<std::endl;
        std::cin>>in1;
        myfile1.open(in1);
        myfile1>>dim;
        b=new double[dim];
            for(n=0;n<dim;n++){
                myfile1>>b[n];
            }
                for(n=0;n<dim;n++){
                    std::cout<<b[n]<<std::endl;
                }
    
        //Matrix ablesen und auf A speichern
        std::ifstream myfile2;
        std::cout<<"Geben Sie die Textdatei fuer die Matriz ein"<<std::endl;
        std::cin>>in2;
        myfile2.open(in2);
        myfile2>>zeile>>spalte;
        a1= new double[zeile*spalte];
            for (n=0;n<zeile;n++){
                for (m=0;m<spalte;m++){
                    myfile2>>a1[m+n*spalte];
                }
            }
                for (n=0;n<zeile;n++){
                    for (m=0;m<spalte;m++){
                        std::cout<<a1[m+n*spalte]<<"\t";
                    }
                    std::cout<<""<<std::endl;
                }
                    double A[zeile][spalte];
                    for (n=0;n<zeile;n++){
                        for (m=0;m<spalte;m++){
                            A[n][m]=a1[m+n*spalte];  
                        }
                    }    
    
    
        //Vektor Matrix Multiplikation
        double c[spalte];
        for (n=0;n<zeile;n++){
            for (m=0;m<spalte;m++){
                c[n]=c[n]+(A[n][m]*b[m]);
            }
            std::cout<<c[n]<<std::endl;
        }
    
    
        myfile1.close();
        myfile2.close();
        free(b);
        free(a1);
        return 0;
    }
    
    

    Die jeweiligen Textdateien für den Vektor und die Matrix waren
    Vektor.txt:

    4
    1
    2
    1
    2

    Matrix.txt:
    3
    4
    1.1 1.2 1.3 1.4 2.1 2.2 2.3 2.4 3.1 3.2 3.3 3.4



  • @Asoaso Warum nutzt du nicht std::vector(oder std:array) ?

    Das ist irgendwie in den 1990er stehen geblieben.



  • Keine Ahnung 🙂 Fange erst an mit C++ und laut den Arbeitsblättern sollen wie das nutzen


  • Gesperrt

    @DirkB sagte in Matrix Vektor Multiplikation:

    Warum nutzt du nicht std::vector(oder std:array) ?

    Also, schöner fände ich so eine Struktur:

    #include <string>
    #include <vector>
    #include <sstream>
    #include <iostream>
    #include <iomanip>
    #include <variant>
    #include <cmath>
    
    struct Value
    {
        double value = 0.0;
    };
    
    using Row = std::vector<Value>;
    using Matrix = std::vector<std::vector<Value>>;
    
    struct System
    {
        Matrix coefficients;
        Row constant_terms;
    };
    
    double round_to(double value, double precision = 0.01)
    {
        return std::round(value / precision) * precision;
    }
    
    std::ostream &operator<<(std::ostream &out, const Value &v)
    {
        out << std::setw(6) << std::setfill(' ') << round_to(v.value);
        return out;
    }
    
    std::ostream &operator<<(std::ostream &out, const Matrix &matrix)
    {
        out << "Matrix: (" << matrix.size() << " x " << matrix[0].size() << ")\n";
        for (auto &row : matrix)
        {
            for (auto &value : row)
            {
                out << value;
            }
            out << '\n';
        }
        return out << '\n';
    }
    
    std::ostream &operator<<(std::ostream &out, const Row &row)
    {
        out << "Matrix: (1 x " << row.size() << ")\n";
        for (size_t i = 0; i < row.size(); i++)
        {
            out << "     " << (char)('a' + i);
        }
        out << '\n';
        for (auto &value : row)
        {
            out << value;
        }
        out << '\n';
        return out << '\n';
    }
    
    void printSystem(const System &system)
    {
        std::cout << system.coefficients;
        std::cout << system.constant_terms;
    }
    
    int main()
    {
    }
    


  • @Asoaso Hi, wenn es eine Aufgabe ist, ist es häufig hilfreich auch die genaue Aufgabenstellung zu posten. Dann sehen wir, worrauf es ankommt.

    Normalerweise nutzt man kein newund delete mehr, erst recht nicht als Anfänger. Manuelle Speicherverwaltung ist eins der fehleranfälligsten Themen und die Sachen sind heute so hinter Container gekapselt, dass man das zu Beginn nicht benötigt. Irgendwann ist es sinnvoll für C++ Programmierer auch das zu lernen, aber erst für Fortgeschrittene.

    Aber, für den Aufbau, den dein Lehrer gewählt hast, kannst du ja nichts.

    Mit new und delete komme ich auch direkt zu dem ersten Problem in deinem Code: Zu jedem new gehört ein delete kein free. freenutzt man um mit malloc reservierten Speicher wieder freizugeben. Das sollte man nicht miteinander mischen. free würde z.B. keinen Destruktor einer Klasse aufrufen, so dass Klassen, die auf dem "freien" Speicher alloziert worden sind, nicht richtig aufgeräumt würden.
    Zu new[] gehört übrigens ein delete[].

    Das Einlesen der Matrix machst du in einen eindimensionales Array. Das finde ich gut, und das ist der Weg, den ich auch empfehlen würde. Warum kopierst du das in ein 2 dim array um?

    Welchen Compiler nutzt du? double A[zeile][spalte]; kompiliert z.B. bei mir nicht, da der Speicher eigentlich schon zur Compiletime feststehen muss, zeile und spalte aber erst zur Compiletime feststehen.

    Deine eigentliche Frage war, wie man das ganze in Funktionen auslagern kann. Hast du da schon was probiert? Wenn ja, was?
    Der alte C weg für Funktionen die ein Array entgegen nehmen, wäre den Pointer auf das erste Element und die Länge des Arrays zu übergeben.
    Einen std::vector oder std::array könntest du einfach als const reference übergeben.
    Man könnte auch einen Pointer auf das erste Element und einen Pointer auf das Element nach dem Array übergeben und passend iterieren. Das wäre im Prinzip das Konzept der Iteratoren in C++.


  • Gesperrt

    @Schlangenmensch sagte in Matrix Vektor Multiplikation:

    bei mir nicht, da der Speicher eigentlich schon zur Compiletime feststehen muss, zeile und spalte aber erst zur Compiletime feststehen.

    Du meinst wohl zur Runtime beim zweiten. 😉



  • @omggg offensichtlich


  • Gesperrt

    Ich bin Autist. Deshalb übersehe ich auch "Selbstverständlichkeiten" nicht. 😊


Anmelden zum Antworten