C-Programm zur Matrizenmultiplikation

Neue Frage »

Nicocle Auf diesen Beitrag antworten »
C-Programm zur Matrizenmultiplikation
Hallo! Wink

Hab schon öfter gelesen, dass hier auch Leute sind, die sich mit Informatik auskennen..(ich gehör definitiv nicht dazu) unglücklich

Soll ein C-Programm schreiben, dass zwei Matrizen multipliziert..
Ich find programmieren schrecklich, hab das Programm da unten mehr oder weniger abgetippt und hab nicht wirklich Plan davon, was da geht.

Auf jeden Fall läuft das Gerät nicht so richtig. Wenn man Glück hat, schafft man es(bevor gar nix mehr geht und das Programm irgendso ne Fehlermeldung ausspuckt), die Elemente einzulesen. Multipliziert wird da gar nix und wenn doch, dann stimmen die Ergebnisse nicht. X(

Hab schon alles mögliche ausprobiert(..eigentlich ohne wirklich zu wissen, was ich da mache), aber bringt alles nichts traurig


#include <iostream>
using namespace std;

void main()

{
int m, n, i, j;
int k, l;

void MatMulti (double*, double*, double*, int, int, int);
double *pmatA, *pmatB, *pmatC;
cout<<"Dieses Programm multipliziert 2 Matrizen A und B miteinander.\n\n";

//Dimensionseingabe

cout<<"Bitte geben sie die Dimension m x n der Matrix A ein.\n\n m: \n";
cin>>m;
cout<<"\n n: \n";
cin>>n;
cout<<"Bitte geben sie die Dimension n x l der Matrix B ein.\n k: \n";
cin>>k;

if (k!=n)

{

cout<<"\nSpalten von A muessen die selbe Anzahl wie die Zeilen von B sein!Fehler\n";
return;
}

cout<<"\n l:\n";
cin>>l;

//Einlesen von Matrix A

pmatA=new double [m*n];

for (i=0; i<m; i++)
for (j=0; j<n; j++)

{
cout<<"\nEingabe von a" << i+1 <<","<< j+1 <<":";
cin>> *(pmatA + i*n+j);
}

//Einlesen von Matrix B
pmatB=new double [n*l];
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)

{
cout<<"\nEingabe von b"<< i+1 <<","<< j+1 <<":";
cin>>*(pmatB + i+n+j);

}

//Aufruf des Unterprogramms
pmatC=new double [m+1];
MatMulti(pmatA, pmatB, pmatC, m, n, 1);

//Ausgabe Matrix C

cout<<"\nDas Ergebnis der Matrizenmultiplikation ist folgende Matrix C: \n";

for (i=0; i<m; i++);
{
for (j=0; j<1; j++);
{
cout<< *(pmatC+i*l+j) << "\t\t";
}
cout<< "\n\n";

}

delete []pmatA;
delete []pmatB;
delete []pmatC;

cout << "\n\n!BITTE SELBER NOCHMAL NACHRECHNEN!\nKeine Garanie auf Fehlerfreiheit!\n";

}


}

void MatMulti(double* pmatA, double* pmatB, double *pmatC, int m,int n, int l)

{
int i, j, s;
double x=0;
for (i=0; i<m; i++)
{
for (j=0; j<l; j++)
{
for (s=0; s<n; s++)
{
x=x+* (pmatA+m*i+s) * * (pmatB+n*s+j);

}
*(pmatC+i*n+j)=x;
x=0;
}

}



}
Mazze Auf diesen Beitrag antworten »

*java code*

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
/**
	 * this.matrix is multiplied with mat, this.matrix will be changed with the result
	 * @param mat
	 */
	public void multMatrix(Matrix mat){
	if (n == mat.m){
		int[][] result= new int[m][mat.n];
			for(int i=0;i<=m-1;i++){
				for(int j=0;j<=mat.n-1;j++){
					for(int k=0;k<=n-1;k++){
						result[i][j]= result[i][j]+ matrix[i][k]*mat.matrix[k][j];
						
					}
				}
			}
			matrix= result;
		
	}
	else {
	System.out.println("Matritzen koennen nicht multipliziert werden");
	}
  }


Kleine erklärung dazu, das is mittels OOP geschrieben das heißt wenn du variablen, werte findest die nicht expliziet lokal definiert wurden, gehören diese zur Objektmatrix.

Hier die klasse dazu

code:
1:
2:
3:
4:
5:
public class Matrix {
	private int m,n; 
	private int[][] matrix;


Ich werd mir dein code gleichmal anschauen.
Nicocle Auf diesen Beitrag antworten »

Danke, das ist echt nett! smile

Dein java code sagt mir so gut wir gar nix..
Mazze Auf diesen Beitrag antworten »

Zitat:
pmatC=new double [m+1];


Eine Matrix multiplikation der Matrizen MxN und NxL liefert eine matrix
MxL

=>

pmatC=new double [m*1];

Da wird dir wohl öfter das array der MAtrix C übergelaufen sein.
Das heißt deine Ergebnismatrix ist zu klein
Vieleicht war das schon alles ich überprüf grad die Matmulti prozedur.


erklär mir mal bitte genau diesen zugriff, ist das ein arrayzugriff?

*(pmatA + i*n+j);

So wie es scheint funktioniert die matmulti richtig. Zumindets die testwerte die ich durchgegangen bin.

Kommt noch ne Fehlermeldung? Sollte eigentlich jetzt soweit alles funzen wenn du die C matrix verbessert hast.
Poff Auf diesen Beitrag antworten »
RE: C-Programm zur Matrizenmultiplikation
Zitat:
cin>>*(pmatB + i+n+j);


Matrix B wird falsch eingelesen

smile
Nicocle Auf diesen Beitrag antworten »

*(pmatA+i*n+j)

ist ein Arrayzugriff..glaub ich, oder ein Zeiger?

Puh..keine Ahnung!

das cin für Matrix B hab ich verbessert.

Die Ergebnismatrix hab ich jetzt so geschrieben:

pmatC= new double [m* l]


Krieg jetzt keine Fehlermeldung mehr, aber das Ergebnis stimmt immer noch nicht.

Als Ergebnis bekomm ich, egal welche Matrix eingelesen wird, irgendwas mit 1.7..e-irgendwas????
 
 
Mazze Auf diesen Beitrag antworten »

Zitat:
Puh..keine Ahnung!


Ehm, du solltest schon wissen mit was für Konstrukten du arbeitest,weil sonst ist die Wahrscheinlichkeit fehlerfrei zu programmieren gleich 0. Da ich noch nicht soviel ahnung in c hab aber weiß das arrays (statisch ) über mat[...] referenziert werden ,kann ich nicht so wirklich was mit dem ausdruck anfangen.

Spuckt der vieleicht die addresse des arrays (der stelle im speicher) aus?

Die Multiplikation ist richtig aber ich denke es wird sich um folgenden fehler handeln

Hauptprogramm.

Hier ist die variable matC definiert.
Initialisiert ist sie in c (soweit ich weiß) mit random werten

Unterprogram

Hier existiert auch eine matC, nämlich die die du Übergeben hast. Da ich in C mich nicht auskenne weiß ich nicht wie die pointer auf dieses Feld behandelt werden. Es kann sein das

a) C neuen Speicher für das objekt im Unterprogram reserviert und somit das matC im Unterprogram unabhängig vom matC im Hauptprogram ist. Dieser fall könnte deinen fehler erklären, um sicher zu gehen gib die ergebnis matrix zurück und schreibe sie nach matC im Hauptprogram (ergebnis typ void ändern)

b) Es wird lediglich der Pointer übergeben, eine änderung im Unterprogram würde eine änderung im hauptprogram nach sich ziehen.

edit

Ich denke fall a trifft zu, da du matC direkt ohne Pointerreferenzierung übergibst. Aber ich kenn halt die interne Arbeitsweise von C mit pointern in den speicher nicht.
Poff Auf diesen Beitrag antworten »
RE: C-Programm zur Matrizenmultiplikation
Zitat:
*(pmatC+i*n+j)=x;


diese Zuweisung aus der Multiplikationsroutine scheint mir falsch !!

verwirrt
Nicocle Auf diesen Beitrag antworten »

Zitat:

Ehm, du solltest schon wissen mit was für Konstrukten du arbeitest,weil sonst ist die Wahrscheinlichkeit fehlerfrei zu programmieren gleich 0.


Ja, da hast du recht! Hab in Informatik etwas geschludert(und das ist noch ziemlich positiv ausgedrückt) smile

Also, ich versuch jetzt mal die Ergebnismatrix zurück ins Hauptprogramm zu schreiben..irgendwie, und sag ganz laut: DANKE!!!

Zitat:
Original von Poff
Zitat:
*(pmatC+i*n+j)=x;


diese Zuweisung aus der Multiplikationsroutine scheint mir falsch !!

verwirrt


verwirrt
mathemaduenn Auf diesen Beitrag antworten »

Hallo Nicole

>>MatMulti(pmatA, pmatB, pmatC, m, n, 1);
Da sollte wohl statt der 1 ein l stehen sonst wird's nichts.
Das Feld wird in jedem Fall an die Funktion richtig übergeben.

Gruß mathemaduenn
Poff Auf diesen Beitrag antworten »

Zitat:
Original von Nicocle
*(pmatA+i*n+j)
...


@Nicocle und Mazze


... ist die Referenzierung auf ein Arrayelement.

'pmatA' ist der Zeiger vom Typ double und

*pmatA die Referenz auf das 0. Element vom Typ double


so müsste es sein ....




Zitat:
Also, ich versuch jetzt mal die Ergebnismatrix zurück ins Hauptprogramm zu schreiben..irgendwie, und sag ganz laut: DANKE!!!



halt Stopp, du brauchst nichts zurück ins Hauptprg. zu schreiben,
sondern wenigstens diese Zuweisung in Ordnung zu bringen,

oder aber, du gibst mal versuchsweise die 'x' se so wie sie
errechnet werden direkt aus ohne sie später aus der C-Matrix zu
entnehmen, dann kannst du zumindest sehen ob die Glieder
richtig berechnet werden ....


smile
Nicocle Auf diesen Beitrag antworten »

ich flipp aus: es funzt! 8)

#include <iostream>
using namespace std;
void main ()
{
int m,n,i,j;
int l;
void MatMulti(double*, double*, double*, int, int, int);
double *pmatA, *pmatB, *pmatC;
cout<<"Dieses Programm multipliziert zwei Matrizen A und B.\n";

//Dimensionseingabe

cout<<"Bitte geben sie die Dimension m x n der Matrix A ein.\n m:\n";
cin>>m;
cout<<"n:\n";
cin>>n;
cout<<"Bitte geben sie die Dimension n x l der Matrix B ein. \n l:\n";
cin>>l;

if (l!=n)
{
cout<<"\nSpalten von A muessen selbe Anzahl wie Zeilen von B sein!\n";
return;
}
cout<<"l:\n";
cin>>l;

//Einlesen von Matrix A

pmatA=new double [m*n];
for (i=0;i<m;i++)
for(j=0;j<n;j++)
{
cout<<"\nEingabe von a"<<i+1<<","<<j+1<<":";
cin>>*(pmatA+i*n+j);
}

//Einlesen von Matrix B

pmatB=new double [n*l];
for (i=0;i<m;i++)
for (j=0;j<n;j++)
{
cout<<"\nEingabe von b"<<i+1<<","<<j+1<<":";
cin>>*(pmatB+i*n+j);
}

//Aufruf des Unterprogramm

pmatC=new double [m*l];
MatMulti(pmatA, pmatB, pmatC, m, n, l);

//Ausgab Matrix C

cout<<"\nDas Ergebnis der Matrizenmultiplikation ist folgende Matrix C:\n";
for (i=0;i<m;i++)
{
for(j=0;j<l;j++)
{
cout<<*(pmatC+i*l+j)<<"\t\t";
}
cout<<"\n\n";
}
delete []pmatA;
delete []pmatB;
delete []pmatC;

cout<<"\n\nBITTE SELBER NOCHMAL NACHRECHNEN\n";
}

void MatMulti(double* pmatA, double* pmatB, double* pmatC, int m, int n,int l)
{
int i,j,s;
double x=0;
for (i=0;i<m;i++)
{
for (j=0;j<l;j++)
{
for (s=0;s<n;s++)
{
x=x+*(pmatA+m*i+s) * * (pmatB+n*s+j);
}
*(pmatC+i*n+j)=x;
x=0;

}
}
}

Prost
Poff Auf diesen Beitrag antworten »

Zitat:
Original von Nicocle
ich flipp aus: es funzt! 8)
...


dass es läuft will ich nicht bestreiten, dass es richtig FUNZT
hingegen schon . Augenzwinkern



Zitat:
//Einlesen von Matrix B
pmatB=new double [n*l];
for (i=0;i<m;i++)
for (j=0;j<n;j++)
{
cout<<"\nEingabe von b"<<i+1<<","<<j+1<<":";
cin>>*(pmatB+i*n+j);
}


so ist z.B. nachwievor das Einlesen der Matrix B falsch !!

erstens ist es eine n*l Matrix, wird aber als m*n Matrix 'eingelesen'
und dies zudem noch ANDERS organisiert als die Matrix in A !!

Dieser 'Organisationsbruch' müsste zwar nicht zwingend zum
Fehler führen, weil entsprechende Berücksichtigung bei der
Multiplikationsprozedur das ja wieder ausgleichen könnte.
[ Damit liesen sich gut einige Leute irreführen und ärgern,
der Übersicht dient das natürlich in keinem Falle ]



Die Multiplikation kann ebenfalls nicht durchgehend stimmen,
dieweil als Resultat eine m*l Matrix enstehen müsste, allein die
Zuweisungsoperation

Zitat:
*(pmatC+i*n+j)=x;
x=0;

ein solches Feld aber nicht abdeckt. :-oo

sollte wegen unterschiedlicher Deutungen von 'n' bei A und B eine
m*n Resultatmatrix enstehen, so wäre wiederum das C-Array mit

Zitat:
pmatC=new double [m*l];

falsch deklariert ...




Weitere Fehler scheinen vorhanden z.B. bei der Dimensionsabfrage
von Matrix B

Zitat:
if (l!=n)
{
cout<<"\nSpalten von A muessen selbe Anzahl wie Zeilen von B sein!\n";
return;
}

das ist falsch,
es sei denn Matrix B wird Zeilen-Spalten vertauscht zu A organisiert
abgerufen ??

Normalerweise gäbs da nur die Spaltenanzahl 'l' von B einzulesen,
dieweil die Zeilenzahl mit den Spalten 'n' der A Matrix überein-
zustimmen hat ....


ist verschiedenes unausgegorenes Kleinzeug's versteckt in
dem Programm . Augenzwinkern


smile
Sir Dragonslayer Auf diesen Beitrag antworten »

Das hab ich mal in Modula-3 gemacht. unglücklich
Scheiß uralt Pascal-Akzent Sprachen.
Nebenbei die Multiplikation selbst ist doch gerade mal 4 Zeilen lang.
Der Rest ist doch trivial (dieses Wort ist bei Mathematikern eine Krankheit). Big Laugh
Schreib die Lösung aber nicht her, sind ja schon genug da.
Nicocle Auf diesen Beitrag antworten »

Zitat:
Zitat:
//Einlesen von Matrix B
pmatB=new double [n*l];
for (i=0;i<m;i++)
for (j=0;j<n;j++)
{
cout<<"\nEingabe von b"<<i+1<<","<<j+1<<":";
cin>>*(pmatB+i*n+j);
}


so ist z.B. nachwievor das Einlesen der Matrix B falsch !!


ja..das hab ich verbessert.

Zitat:
Dieser 'Organisationsbruch'


versteh ich nicht verwirrt wieso anders organisiert?!

Zitat:
Die Multiplikation kann ebenfalls nicht durchgehend stimmen,
dieweil als Resultat eine m*l Matrix enstehen müsste, allein die
Zuweisungsoperation

Zitat:
*(pmatC+i*n+j)=x;
x=0;

ein solches Feld aber nicht abdeckt. :-oo


ich hab das n gegen l getauscht... verwirrt

Zitat:
Weitere Fehler scheinen vorhanden z.B. bei der Dimensionsabfrage
von Matrix B


hab ich ebenfalls verbessert, indem ich noch ne Variable k(für Spalten von B) eingeführt hab und dann: if (k!=n) cout.. return;

weiß jetzt aber nicht, wie(oder ob) ich das k bei der Multiplikation berücksichtigen muss verwirrt

Es stimmt bei einer [mxn] * [kxl] Multiplikation, wobei natürlich n gleich k ist, nur die erste Zeile im Ergebnis. X(

Wenn quadratische Matrizen multipliziert werden, stimmt das Ergebnis ganz.

verwirrt
Poff Auf diesen Beitrag antworten »

Zitat:
Original von Nicocle
ich flipp aus: es funzt! 8) ???

#include <iostream>
using namespace std;
void main ()
{
int m,n,i,j;
int l;
void MatMulti(double*, double*, double*, int, int, int);
double *pmatA, *pmatB, *pmatC;
cout<<"Dieses Programm multipliziert zwei Matrizen A und B.\n";

//Dimensionseingabe

cout<<"Bitte geben sie die Dimension m x n der Matrix A ein.\n m:\n";
cin>>m;
cout<<"n:\n";
cin>>n;
cout<<"Bitte geben sie die Dimension n x l der Matrix B ein. \n n:\n";
int dummy;
cin>>dummy;
cout<<"l:\n";
cin >>l;
if (dummy!=n)

{
cout<<"\nSpalten von A muessen selbe Anzahl wie Zeilen von B sein!\n";
return;
}
cout<<"n:\n";
cin>>dummy;


//Einlesen von Matrix A

pmatA=new double [m*n];
for (i=0;i<m;i++)
for(j=0;j<n;j++)
{
cout<<"\nEingabe von a"<<i+1<<","<<j+1<<":";
cin>>*(pmatA+i*n+j);
}

//Einlesen von Matrix B

pmatB=new double [n*l];
for (i=0;i<n;i++)
for (j=0;j<l;j++)
{
cout<<"\nEingabe von b"<<i+1<<","<<j+1<<":";
cin>>*(pmatB+i*l+j);
}

//Aufruf des Unterprogramm

pmatC=new double [m*l];
MatMulti(pmatA, pmatB, pmatC, m, n, l);

//Ausgab Matrix C

cout<<"\nDas Ergebnis der Matrizenmultiplikation ist folgende Matrix C:\n";
for (i=0;i<m;i++)
{
for(j=0;j<l;j++)
{
cout<<*(pmatC+i*l+j)<<"\t\t";
}
cout<<"\n\n";
}
delete []pmatA;
delete []pmatB;
delete []pmatC;

cout<<"\n\nBITTE SELBER NOCHMAL NACHRECHNEN\n";
}

void MatMulti(double* pmatA, double* pmatB, double* pmatC, int m, int n,int l)
{
int i,j,s;
double x=0;
for (i=0;i<m;i++)
{
for (j=0;j<l;j++)
{
for (s=0;s<n;s++)
{
x=x+*(pmatA+n*i+s) * * (pmatB+l*s+j);
}
*(pmatC+i*l+j)=x;
x=0;

}
}
}

Prost hoffentlich
Nicocle Auf diesen Beitrag antworten »

Hi Poff!
Tut mir leid, dass ich jetzt erst antworte!
Es funktioniert endlich.. Prost

Danke für deine Hilfe! Mit Zunge
Poff Auf diesen Beitrag antworten »

So erhofft und auch schon vermutet auf GRUND der ausgebliebenen
Meckerpost ... *gg*
...


Das war ja nun C++ und nicht C und deswegen solltest du falls
weitere Aufgaben dieser Art anstehen, dir vor Augen führen dass
über 'Typdeklarationen' auch mehrdimensionale Strukturen-Arrays
möglich sind. Dies fördert die Übersicht und auch das Verständnis
für solche Probleme nicht gering.


Ich weiß nicht wie's gemacht wird, bin mir aber zu 99.99%
sicher dass es geht. In blanko C gehts evtl nicht, weil wenn ich
nicht irre Array's im üblichen Sinne nicht direkt zur Verfügung
stehen, sondern nur über Zeiger realisierbar sind und dann gings
eben nur über Zeiger auf Datentyp oder so ... oder garnicht.


Jedenfalls ist die Definition 'mehrdimensionaler Felder' für
solche Dinge ideal und auch der Mühe wert.


smile
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »