Matrixmultiplikation



  • manni66 schrieb:

    so wie du es machst, ist es falsch.
    so ist es richtig: http://stackoverflow.com/questions/8767166/passing-a-2d-array-to-a-c-function

    Und schon wieder eine Schnapsnase mit geklautem Namen



  • Kinder, denkt euch mal 'n eigenen Namen aus. Ich benutze meinen schon seit Jahren...



  • Kann sein dass ich blöd bin aber keine Lösung funktioniert.
    Das Ziel ist

    void myFunction(double myArray)
    

    {
    ...
    }
    ..
    double anArray[10][10];
    ...
    myFunction(anArray)

    ohne Fehler zu rechnen.



  • Count_Omega schrieb:

    Kann sein dass ich blöd bin aber keine Lösung funktioniert.
    Das Ziel ist

    void myFunction(double myArray)
    

    {
    ...
    }
    ..
    double anArray[10][10];
    ...
    myFunction(anArray)

    ohne Fehler zu rechnen.

    Probier mal so:

    void myFunction(double (*myArray)[10])
    

    Das Herumreichen von 2D (und mehr D) Arrays ist ein bisschen doof in C++.
    Aber das kriegste schon hin.



  • Count_Omega schrieb:

    Sorry, aber was genau ist der Fehler bei der Übergabe(oder Nichtübergabe) der Arrays?

    Du übergibst das Element mit dem Index [1000][1000], das nicht einmal existiert.
    Dies ist ein einzelnes Element vom Typ int und kein Array.

    Bei der Multiplikation greifst du doch auch mit Ma[i][j] auf die Elemente zu.

    Nebenbei halte ich knappe 4 Megabyte für eine Matrix auf dem Stack etwas übertrieben.



  • Seht gut, danke. Scheint zu funktionieren. Der einzige verbliebene fehler ist

    Quelle1.cpp:32:34: error: invalid operands of types ‘int [1000]’ and ‘int [1000]’ to binary ‘operator*’
    Em[i][k] = Ma[i][j] * Mb[j][k];
    . Darf ich * bei arrays nich verwenden?



  • Count_Omega schrieb:

    Darf ich * bei arrays nich verwenden?

    Du musst zwischem dem Array (bzw. der Adresse eines (vom ersten) Element) und einem Element vom Array unterscheiden.

    Der * ist bei einem Array der Dereferenzierungsoperator.

    Wenn Ma oder Mb jeweils 2D-int-Arrays oder
    wenn Ma oder Mb Zeiger auf 1D-Zeiger_auf_int-Arrays sind, dann ist Ma[i][j] bzw. Mb[j][k] ein int.
    Und bei int ist * die Multiplikation.

    Demnach sind bei dir Ma und Mb keine 2D-Arrays.

    Zeige den ganzen Code!



  • [code="cpp"]
    #include <iostream>
    #define size 1000

    using namespace std;

    void matrixmult(*Ma[size][size], * Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb);

    int main(int argc, char **argv)

    {
    int z = 1000;
    int z1 = 1000;
    int z2 = 1000;

    int m1[1000][1000];
    int m2[1000][1000];
    matrixmult(*m1, *m2, z, z1, z2);
    }

    int ma[size][size];
    int mab[size][size];
    void matrixmult( *Ma[size][size], *Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb)
    {
    int Em[1000][1000] = { 0 };
    for (int i = 0; i< zeilenmc; ++i)
    {
    for (int j = 0; j < zeilenmb; ++j)
    {

    for (int k = 0; k < spaltenmc; ++k)
    {

    Em[i][k] = Ma[i][j] * Mb[j][k];
    }
    }

    }
    std::cout << Em[zeilenmc][spaltenmc] << endl;
    }



  • Count_Omega schrieb:

    #include <iostream>
    #define size 1000
    
    using namespace std;
    
    void matrixmult(*Ma[size][size], * Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb);
    
    int main(int argc, char **argv)
    
    {
    	int z = 1000;
    	int z1 = 1000;
    	int z2 = 1000;
    
    	int m1[1000][1000];
    	int m2[1000][1000];
    	matrixmult(*m1, *m2, z, z1, z2);
    }
    
    int ma[size][size];
    int mab[size][size];
    void matrixmult( *Ma[size][size],  *Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb)
    {
    	int Em[1000][1000] = { 0 };
    	for (int i = 0; i< zeilenmc; ++i)
    	{
    		for (int j = 0; j < zeilenmb; ++j)
    		{
    
    			for (int k = 0; k < spaltenmc; ++k)
    			{
    				
    				Em[i][k] = Ma[i][j] * Mb[j][k];
    			}
    		}
    
    	}
    	std::cout << Em[zeilenmc][spaltenmc] << endl;
    }
    
    // Die Funktion sollte so anfangen
    void matrixmult(int Ma[][size], int Mb[][size] ....
    // oder so
    void matrixmult(int (*Ma)[size], int (*Mb)[size] ...
    // aber nicht so
    void matrixmult( *Ma[size][size],  *Mb[size][size] ....
    ...
    // und sollte so aufgerufen werden
    matrixmult(m1, m2, ...
    // aber nicht so
    matrixmult(*m1, *m2, ...
    

    ausserdem sollte Em[i][k] = Ma[i][j] * Mb[j][k]; sinnigerweise Em[i][k] += (Ma[i][j] * Mb[j][k]); heissen.



  • Um. Welche Sprache?



  • Count_Omega schrieb:

    std::cout << Em[zeilenmc][spaltenmc] << endl;
    

    Das gibt das Element (und nur dieses eine Element) Em[1000][1000] des Arrays Em aus. (bei deinen Parametern)
    Nach deiner Definition existiert das Element aber gar nicht.



  • Ich habe den Code nochmals überprüft und jetzt kompiliert es. Beim Ausführen bekomme ich jedoch den error Speicherzugriffsfehler (Speicherabzug geschrieben).
    Dies liegt vermutlich an den Arrraygrenzen; wenn ich diese dynamisch festlegen will funktioniert es nicht.

    #include <iostream>
    #define size 100
    
    using namespace std;
    
    void matrixmult(int Ma[size][size],int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb);
    
    int main(int argc, char **argv)
    
    {
    	int z = 100;
    	int z1 = 100;
    	int z2 = 100;
    
    	int m1[100][100];
    	int m2[100][100];
    	matrixmult(m1, m2, z, z1, z2);
    }
    
    void matrixmult(int Ma[size][size], int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb)
    {
    	int Em[100][100] = { 0 };
    	for (int i = 0; i< zeilenmc; ++i)
    	{
    		for (int j = 0; j < zeilenmb; ++j)
    		{
    
    			for (int k = 0; k < spaltenmc; ++k)
    			{
    
    				Em[i][k] = Ma[i][j] * Mb[j][k];
    			}
    		}
    
    	}
    	std::cout << Em[zeilenmc][spaltenmc] << endl;
    }
    


  • Count_Omega schrieb:

    #include <iostream>
    #define size 100
    //?
    
    using namespace std;
    
    void matrixmult(int Ma[size][size],int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb);
    
    //int main(int argc, char **argv)
    int main()
    {
    	int z = 100;
    	int z1 = 100;
    	int z2 = 100;
    
    	int m1[100][100];
    	int m2[100][100];
    	matrixmult(m1, m2, z, z1, z2);
    }
    
    void matrixmult(int Ma[size][size], int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb)
    {
    	int Em[100][100] = { 0 };
    	for (int i = 0; i< zeilenmc; ++i)
    	{
    		for (int j = 0; j < zeilenmb; ++j)
    		{
    
    			for (int k = 0; k < spaltenmc; ++k)
    			{
    				
    				Em[i][k] = Ma[i][j] * Mb[j][k];
    //ist auch noch immer falsch.
    			}
    		}
    
    	}
    	std::cout << Em[zeilenmc][spaltenmc] << endl;
    }
    

    Beim Ausführen bekomme ich jedoch den Fehler Speicherzugriffsfehler (Speicherabzug geschrieben).

    DirkB schrieb:

    Count_Omega schrieb:

    std::cout << Em[zeilenmc][spaltenmc] << endl;
    

    Das gibt das Element (und nur dieses eine Element) Em[1000][1000] des Arrays Em aus. (bei deinen Parametern)
    Nach deiner Definition existiert das Element aber gar nicht.

    scheinst ein bisschen auf kriegsfuß mit lesen zu stehen?



  • ist es dann richtig mit

    ...
    Em[i][k] += Ma[i][j] * Mb[j][k];
    ...
    for (int l = 0; l > size; ++l)
    	{
    		for (int m = 0; m > size; ++m)
    		{
    			std::cout << Em[l][m] << endl;
    		}
    	}
    


  • Nein. Denn < und > solltest du besser nicht verwechseln (2x).

    Du kannst nicht einfach irgendwelche Zeichen wie *, +, <, =, > raten, sondern musst überlegen, welches jeweils passt! (ok, du kannst schon raten, aber dann ist es Glückssache, ob es richtig wird)



  • Hat sich erledigt, fuktioniert. Trotzdem vielen Dank. Code:

    #include <iostream>
    #define size 100
    
    using namespace std;
    
    void matrixmult(int Ma[size][size],int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb);
    
    int main(int argc, char **argv)
    
    {
    	int z = 100;
    	int z1 = 100;
    	int z2 = 100;
    
    	int m1[100][100];
    	int m2[100][100];
    	matrixmult(m1, m2, z, z1, z2);
    }
    
    void matrixmult(int Ma[size][size], int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb)
    {
    	int Em[100][100] = { 0 };
    	for (int i = 0; i< zeilenmc; ++i)
    	{
    		for (int j = 0; j < zeilenmb; ++j)
    		{
    
    			for (int k = 0; k < spaltenmc; ++k)
    			{
    
    				Em[i][k] = Ma[i][j] * Mb[j][k];
    			}
    		}
    
    	}
    	for (int l = 0; l < size; ++l)
    	{
    		for (int m = 0; m < size; ++m)
    		{
    			std::cout << Em[l][m] << endl;
    		}
    	}
    }
    

    Die Matrizen müssen noch gefüllt werden,aber das ist nebensächlich.



  • Count_Omega schrieb:

    Hat sich erledigt, fuktioniert.

    Em[i][k] = Ma[i][j] * Mb[j][k];
    

    Wetten nicht? Matrizenmultiplikation geht anders. 🙂



  • Ist eine zufallige Arrayfüllung so zulässsig?

    ...
    m1[size][size];
    srand((unsigned)time(NULL));
    
    	for (int i = 1; i < 100; i++)
    	{
    		for (int j = 1; i < 100; j++)
    		{
    			m1[i][j] = rand() % 100;
    
    		}
    	}
    


  • Es scheint zu funktionieren:

    #include <iostream>
    #include <ctime>
    #include <cstdlib>
    #define size 10
    
    using namespace std;
    
    void matrixmult(int Ma[size][size],int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb);
    
    int main(int argc, char **argv)
    
    {
    	int z = 10;
    	int z1 = 10;
    	int z2 = 10;
    
    	int m1[10][10];
    	int m2[10][10];
    
    	srand((unsigned)time(NULL));
    
    	for (int i = 1; i < 10; i++)
    	{
    		for (int j = 1; j < 10; j++)
    		{
    			m1[i][j] = rand() % 10;
    
    		}
    	}
    	srand((unsigned)time(NULL));
    	for (int i = 1; i < 10; i++)
    	{
    		for (int j = 1; j < 10; j++)
    		{
    			m2[i][j] = rand() % 10;
    
    		}
    	}
    
    	matrixmult(m1, m2, z, z1, z2);
    }
    
    void matrixmult(int Ma[size][size], int Mb[size][size], int zeilenmc, int spaltenmc, int zeilenmb)
    {
    	int Em[10][10] = { 0 };
    	for (int i = 0; i< zeilenmc; ++i)
    	{
    		for (int j = 0; j < zeilenmb; ++j)
    		{
    
    			for (int k = 0; k < spaltenmc; ++k)
    			{
    
    				Em[i][k] += Ma[i][j] * Mb[j][k];
    			}
    		}
    
    	}
    	std::cout << "Endmatrix: " << "[";
    	for (int l = 0; l < size; ++l)
    	{
    		for (int m = 0; m < size; ++m)
    		{
    			std::cout <<  Em[l][m] << " " ;
    		}
    	}
    	std::cout << "]" << endl;
    }
    

    Ist die Matrixfüllung wirklich zufällig?



  • Liest du eigentlich zu irgendeiner Funktion, die du benutzt, auch mal die Dokumentation?

    Preisfrage: wie oft soll man srand in einem Programm aufrufen?

    Versuch doch mal als ersten Test, irgendeine Matrix mit 1\mathbb{1} zu multiplizieren.

    (abgesehen davon, dass du hier im C++-Forum postest und du somit besser std::random_device und/oder std::mt19937 nutzen solltest - was hier aber aufgrund der anderen Dinge ziemlich irrelevant ist)


Anmelden zum Antworten