01.07.2000 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure II Prof. Dr. Gisbert Dittrich Universität Dortmund, Lehrstuhl Informatik 1 [email protected] Prof. Dr. G. Dittrich 01.07.2000 Gliederung • Vektoren und Matrizen als ADTs • Deren Implementierungen • Lösung linearer Gleichungssysteme • Gaußsches Eliminationsverfahren Version 0 – Entwurf – Implementierung • Gauß mit Pivotisierung • Matrixinvertierung • Literatur: B.H. Flowers: An Introduction to Numerical Methods in C++, p. 188ff, Oxford University Press, 2000 EINI II Kap. 21: Zur Rechnung mit Matrizen 21-2 Prof. Dr. G. Dittrich 01.07.2000 Vektoren als ADT • Hier: Reellwertige Vektoren (+ Matrizen) • Vektoren haben: • Größe (Dimension) • Operationen • Erzeugen • Entfernen • Einlesen • Auslesen • Operationen i.e.S: – Projektion auf Komponente : [ ] – Addition: += – Multiplikation mit Skalar: *= - Zuweisung: = - Subtraktion: -= - Skalarmultiplikation EINI II Kap. 21: Zur Rechnung mit Matrizen 21-3 Prof. Dr. G. Dittrich 01.07.2000 Matrizen als ADT • Matrizen haben: • Größe: Anzahl Reihen und Anzahl Spalten • Operationen • Erzeugen • Entfernen • Einlesen • Auslesen • Operationen i.e.S: – Projektion auf Zeile : [ ] – Addition: += – Multiplikation mit Skalar: *= – Invertierung - Zuweisung: = - Subtraktion: -= - Matrixmultiplikation EINI II Kap. 21: Zur Rechnung mit Matrizen 21-4 Prof. Dr. G. Dittrich 01.07.2000 Error-Funktion: Implementierung void error (char*); void error (char* errmsg) { cerr << "An unexpected error has occured!" << endl; cerr << "reason: " << errmsg; cerr << "\n\nProgram execution" << "terminated!" << endl; exit(-1); } Anmerkung: cerr Fehler-Output-Stream EINI II Kap. 21: Zur Rechnung mit Matrizen 21-5 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung class Vector { friend class matrix; // allows access to private attributes of matrix private: int size; double * vec; int range (int); // dimension of the vector public: Vector (int); // constructor: constructs vector // with given dimension Vector ( const double*, int); // ..+ init w. field Vector ( const Vector&); // Copy-constructor ~Vector(); EINI II Kap. 21: Zur Rechnung mit Matrizen 21-6 Prof. Dr. G. Dittrich 01.07.2000 Anmerkungen friend: • Schlüsselwort. • Durch friend bezeichnete Funktionen oder Klassen haben auch Zugriff auf die private members, obwohl: • Durch friend bezeichnete Funktionen oder Klassen sind nicht member der Klasse. EINI II Kap. 21: Zur Rechnung mit Matrizen 21-7 Prof. Dr. G. Dittrich 01.07.2000 Anmerkungen &: Referenz • Alternativer Name für ein Objekt • X& bedeutet Referenz auf X int ii = 1; pp: int& rr = ii; rr++; // ii wird um 1 // inkrementiert int* pp = &rr // pp zeigt auf ii &ii ii: rr: 1 Hauptanwendung: • Angabe von Argumenten und Rückgabewerten von Funktionen • Insbesondere: für überladene Operatoren (s.u.) EINI II Kap. 21: Zur Rechnung mit Matrizen 21-8 Prof. Dr. G. Dittrich 01.07.2000 Anmerkungen const vor Zeiger oder Referenz • macht zugehöriges Objekt (jedoch nicht Zeiger oder Referenz) zur Konstanten. Unser Beispiel: Vector ( const Vector&); • [ Zeiger zur Konstante zu machen erreicht man durch *const] EINI II Kap. 21: Zur Rechnung mit Matrizen 21-9 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung class Vector // Fortsetzung {.... public: double& operator[] (int i) { return vec[range(i)];} Vector& operator=(const Vector&); // assignment Vector& operator+=(const Vector&);// add-assignment Vector& operator-=(const Vector&);//minus-assignmnt Vector& operator*=(double); // mult by double int getsize() {return size;} ...... }; EINI II Kap. 21: Zur Rechnung mit Matrizen 21-10 Prof. Dr. G. Dittrich 01.07.2000 Anmerkungen operator: • Schlüsselwort. • Beschreibt Spezifikation der Überladung von Operationen über Objekten der (neuen) Klasse: – arithmetische – andere (z. B. Einlesen , auslesen) • Infixnotation weiter verwendbar EINI II Kap. 21: Zur Rechnung mit Matrizen 21-11 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung class Vector // Fortsetzung {.... public: friend Vector operator* (double, const Vector&); friend double scalar (const Vector&, const Vector&); // scalar product friend Vector operator* (const matrix&, const Vector&); friend Vector operator* (const Vector&, const matrix&); friend ostream& operator<< (ostream&, const Vector&); friend istream& operator>> (istream&, Vector&); }; EINI II Kap. 21: Zur Rechnung mit Matrizen 21-12 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector::Vector (int n) { size=n; vec = new double [size]; if (!vec) error ("allocation failure in ¬ // ¬: carriage return Vector::Vector(int)!"); for (int i=0; i<size; ++i) vec[i]=0; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-13 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector::Vector (const double *a, int n) { size=n; vec = new double [size]; if (!vec) error ("allocation failure in ¬ Vector::Vector(double*, int)!"); for (int i=0; i<size; ++i) vec[i]=a[i]; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-14 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector::Vector (const Vector &v) { size=v.size; vec = new double [size]; if (!vec) error ("allocation failure in ¬ Vector::Vector(Vector&)!"); for (int i=0; i<size; ++i) vec[i]=v.vec[i]; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-15 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector::~Vector () {delete vec;} inline int Vector::range (int i) {return (i <0 || i>= size) ? ¬ (error ¬ ("error in range-function in class vector"), -1) ¬ : i; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-16 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector& Vector::operator= (const Vector &v) { if (size != v.size) error ("diff size in vector& ¬ vector::op=(const vector&)!"); for (int i=0; i<size; ++i) vec[i]=v.vec[i]; return *this; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-17 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector& Vector::operator+= (const Vector &v) { if (size != v.size) error ("diff size in vector& ¬ vector::op+=(const vector&)!"); for (int i=0; i<size; ++i) vec[i]+=v.vec[i]; return *this; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-18 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector& Vector::operator-= (const Vector &v) { if (size != v.size) error ("diff size in vector& ¬ vector::op-=(const vector&)!"); for (int i=0; i<size; ++i) vec[i]-=v.vec[i]; return *this; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-19 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung Vector& Vector::operator*=(double x) { for (int i=0; i< size; ++i) vec[i]*=x; return *this; } Vector operator* (double d, const Vector &v) { Vector vd=v; vd *= d; return vd; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-20 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung double scalar (const Vector &u, const Vector &v) { double t=0; int n=u.size; if (u.size != v.size) error ("error in function scalar ¬ in class Vector"); for (int i=0; i<n; ++i) t += u.vec[i]*v.vec[i]; return t; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-21 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung istream& operator>>(istream &s, Vector &v) { int n=v.size; cout << "enter " << n << " elements:\n"; for (int i=0; i<n; ++i) { cout << "v [" << i << "] = "; s >> v.vec[i]; } return s; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-22 Prof. Dr. G. Dittrich 01.07.2000 Vektoren: Implementierung ostream& operator<<(ostream &s, const Vector &v) { int n=v.size; cout << "( "; for (int i=0; i<n; ++i) s << v.vec[i] << " | "; s << " )" << "\n"; return s; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-23 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung class matrix { private: int numrows; int numcols; Vector **mat; int range(int); // how many rows? // how many columns? // row range check public: matrix (int, int);// constr: rectangular matrix matrix (int); // constr: square matrix matrix (const matrix&); // constr: rectang. matrix ~matrix(); // destructor EINI II Kap. 21: Zur Rechnung mit Matrizen 21-24 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung class matrix // Fortsetzung { ...... public: ..... int getsize(); // def. for square matrix only! void swap(int a, int b); matrix transpose(); Vector& operator[] (int i) { return *mat[range(i)];} matrix& operator=(const matrix&); friend Vector operator* (const matrix&, const Vector&); friend Vector operator* (const Vector&, const matrix&); friend ostream& operator<< (ostream&,const matrix&); friend istream& operator>> (istream&, matrix&); EINI II Kap. 21: Zur Rechnung mit Matrizen }; 21-25 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung matrix::matrix (int nrows, int ncols) { numrows=nrows; numcols=ncols; mat=new Vector* [numrows]; if (!mat) error ("row alloc failure in ¬ matrix::matrix(int, int)"); for (int i=0; i<numrows; ++i) { mat[i] = new Vector (numcols); if (!mat[i]) error ("col alloc failure in ¬ matrix::matrix(int, int)"); } } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-26 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung matrix::matrix (int n) { numrows=numcols=n; mat=new Vector* [numrows]; if (!mat) error ("row alloc failure in ¬ matrix::matrix(int)"); for (int i=0; i<numrows; ++i) { mat[i] = new Vector (numcols); if (!mat[i]) error ("col alloc failure in ¬ matrix::matrix(int)"); } } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-27 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung matrix::matrix (const matrix &m) { numrows=m.numrows; numcols=m.numcols; mat=new Vector* [numrows]; if (!mat) error ("row alloc failure in ¬ matrix::matrix(matrix&)"); for (int i=0; i<numrows; ++i) { mat[i] = new Vector (numcols); if (!mat[i]) error ("col alloc failure in ¬ matrix::matrix(matrix&)"); } for (int i=0; i<numrows; ++i) *mat[i]=*m.mat[i]; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-28 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung matrix::~matrix() { for (int i=numrows; i>0; --i) delete mat[i-1]; delete mat; } int matrix::range (int i) { return (i<0 || i>=numrows) ? ¬ (error ("matrix row index out of range!"), -1): i; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-29 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung int matrix::getsize() { if (numrows != numcols) {error ("getsize() requires square matrix"); } return numrows; } void matrix::swap(int i, int j) { Vector *tmp = mat[range(i)]; mat[i]=mat[range(j)]; mat[j]=tmp; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-30 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung matrix matrix::transpose() { int p=numrows, q=numcols; matrix mt(q,p); // create transposed matrix for (int i=0; i<q; ++i) { for (int j=0; j<p; ++j) mt.mat[i]->vec[j] = mat[j]->vec[i]; } return mt; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-31 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung matrix& matrix::operator=(const matrix &m) { if (m.numrows != numrows || m.numcols != numcols) error ("diff sizes in matrix& ¬ matrix::operator=(const matrix &m)!"); for (int i=0; i<numrows; ++i) *mat[i] = *m.mat[i]; return *this; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-32 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung Vector operator* (const matrix &m, const Vector &v) { int nr=m.numrows; if (m.numcols != v.size) error ("diff sizes in ¬ vector op*(const matrix&, const vector&)!"); Vector u(nr); for (int i=0; i < nr; ++i) u[i] = scalar(*m.mat[i], v); return u; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-33 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung Vector operator* (const Vector &v, const matrix &m) { int nr=m.numrows, nc = m.numcols; if (v.size != nr) error ("diff sizes in ¬ vector op* (const vector&, const matrix&)!"); Vector u(nc); for (int i=0; i < nc; ++i) { double t=0; for (int j=0; j < nr; ++j) t += v.vec[j] * m.mat[j]->vec[i]; u.vec[i] = t; } return u; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-34 Prof. Dr. G. Dittrich 01.07.2000 Matrizen: Implementierung ostream& operator<< (ostream &s, const matrix &m) { int nr=m.numrows; for (int i=0; i<nr; ++i) s << *m.mat[i]; return s; } istream& operator>> (istream &s, matrix &m) { int nr=m.numrows; cout << "\nenter " << nr << " row vectors\n\n"; for (int i=0; i<nr; ++i) { cout << "enter row vector " << i << "\n"; s >> *m.mat[i]; } return s; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-35 Prof. Dr. G. Dittrich 01.07.2000 Beispiel #include <iostream.h> #include "error.cpp" #include "vector.cpp" #include "matrix.cpp" EINI II Kap. 21: Zur Rechnung mit Matrizen 21-36 Prof. Dr. G. Dittrich 01.07.2000 Beispiel int main() { int nr, nc; cout << "Enter number of rows of the matrix: "; cin >> nr; cout << "Enter number of columns of the matrix: "; cin >> nc; matrix m(nr,nc); Vector x(nc), b(nc); cout << "\nEnter matrix m\n"; cin >> m; cout << "Enter vector "; cin >> b; x = m*b; cout <<x; // x = b*m; cout << x ; return 0; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-37 Prof. Dr. G. Dittrich 01.07.2000 Beispiel: Ausgabe Enter Enter Enter enter enter v [0] enter v [0] enter v [0] Enter v [0] ( 4 | ( 8 | number of rows of number of columns matrix m 3 row vectors row vector 0 = 1 v [1] row vector 1 = 4 v [1] row vector 2 = 7 v [1] vector = 1 v [1] 10 | 16 | ) 10 | 12 | ) the matrix: 3 of the matrix: 3 enter = 2 enter = 5 enter = 8 enter = 0 3 elements: v [2] 3 elements: v [2] 3 elements: v [2] 3 elements: v [2] = 3 = 6 = 9 = 1 [Umbruch geändert GD] EINI II Kap. 21: Zur Rechnung mit Matrizen 21-38 Prof. Dr. G. Dittrich 01.07.2000 Anwendung: Gauß Ziel: • Gauß‘sche Elimination zur Gleichungslösung Idee: • Trianguläre Darstellung des Gleichungssystems, • Dann rückwärts ausrechnen. EINI II Kap. 21: Zur Rechnung mit Matrizen 21-39 Prof. Dr. G. Dittrich 01.07.2000 Anwendung: Gauß Beispiel: in Matrixdarstellung: 5 2x0 20 3 4x1 26 5x0 + 2x1 = 20 3x0 + 4x1 = 26 Triangulation: „ Ziehe (3/5)x Zeile 1 von Zeile 2 ab“ 5x0 + 2x1 = 20 (14/5)x1 = 14 Rechne „von unten nach oben“ die Lösung aus: x1 = 5 Einsetzen von x1 in die vorherige (hier erste) Zeile: 5x0 + 2*5 = 20 x0 = 2 EINI II Kap. 21: Zur Rechnung mit Matrizen 21-40 Prof. Dr. G. Dittrich 01.07.2000 Gauß-Elimination: Implementierung const double gauss0_toosmall=3.0E-7; void triangulate(matrix &a, Vector &b) // make matrix an upper triangular { int n=a.getsize(); for (int i=0; i<n-1; i++) { double diag = a[i][i]; if (fabs(diag) < gauss0_toosmall) // fabs means absolute value error ("diagonal too small in triangulate()"); for (int j=i+1; j<n; j++) { double mult=a[j][i]/diag; a[j]-= mult * a[i]; b[j]-= mult * b[i]; }} EINI II Kap. 21: Zur Rechnung mit Matrizen 21-41 } Prof. Dr. G. Dittrich 01.07.2000 Gauß-Elimination: Implementierung void backsubst(matrix &a, Vector &x, Vector &b) // given triangulated a, solve for x given b { int n = a.getsize(); for (int i=n-1; i>=0; i--) { double diag = a[i][i]; if (fabs(diag) < gauss0_toosmall) // to avoid division by zero error ("diagonal too small in backsubst()"); x[i]=(b[i]-scalar(a[i], x))/diag; }} void gauss0 (matrix &m, Vector &x, Vector &b) { triangulate(m,b); backsubst(m, x, b); } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-42 Prof. Dr. G. Dittrich 01.07.2000 Main: Implementierung int main() { int n; cout << "Enter number of variables" << " of the equation system: ";cin >> n; matrix m(n);Vector x(n), b(n); cout << "\nEnter matrix m\n"; cin >> m; matrix m1=m; cout << "\nEnter Vector b\n";cin >> b; gauss0 (m,x,b); cout << "Solution Vector x is:\n";cout << x; cout << "\n\nNow, the verification: " << endl; Vector u = m1*x; cout << "\nproduct vector is: " << u; return 0; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-43 Prof. Dr. G. Dittrich 01.07.2000 Gauß-Elimination; Ausgabe für Beispiel Enter number of variables of the equation system: 2 Enter matrix m enter 2 row vectors enter row vector 0 enter 2 elements: v [0] = 5 v [1] = 2 enter row vector 1 enter 2 elements: v [0] = 3 v [1] = 4 Enter Vector b enter 2 elements: v [0] = 20 v [1] = 26 Solution Vector x is: ( 2 | 5 | ) Now, the verification: product vector is: ( 20 | 26 | ) EINI II Kap. 21: Zur Rechnung mit Matrizen 21-44 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung 5x0 + 2x1 = 20 (14/5)x1 = 14 Vertausche Gleichungen: (14/5)x1 = 14 5x0 + 2x1 = 20 Gauß-Elimination versagt, da a00 = 0, obwohl das Gleichungssystem lösbar ist (s. o.!). Lösung: Versuche „Teilen durch 0“ möglichst zu vermeiden. Passiert durch „Pivotisierung“. EINI II Kap. 21: Zur Rechnung mit Matrizen 21-45 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung Am Beispiel: 3x0 + 4x1 = 26 5x0 + 2x1 = 20 Suche zum zu betrachtenden Diagonalelement (zu Beginn a00) größten Koeffizienten in der Spalte (aber nur darunter). Vertausche die aktuelle mit der/einer Zeile, die größten solchen Koeffizienten aufweist. 5x0 + 2x1 = 20 3x0 + 4x1 = 26 Führe hierfür Triangulation durch. (Dadurch wird immer durch größtmöglichen Koeffizienten geteilt) EINI II Kap. 21: Zur Rechnung mit Matrizen 21-46 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung: Implementierung double pivot (matrix &a, Vector &b, int i) { // row i to have largest element from lower col i as //diag int n=a.getsize(); int j=i; // row variable double t=0; for (int k=i; k<n; ++k) // find max elem { double aki=fabs(a[k][i]); if (aki > t) { t=aki; j=k; }} if (j>i) // swap equations { a.swap(i,j); // swap matrix rows b.swap(i,j); } // swap indices return a[i][i]; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-47 Prof. Dr. G. Dittrich 01.07.2000 Gauß-Elimination: Implementierung void triangulate(matrix &a, Vector &b)//Wiederholung // make matrix an upper triangular { int n=a.getsize(); for (int i=0; i<n-1; i++) { double diag = a[i][i]; if (fabs(diag) < gauss0_toosmall) // fabs means absolute value error ("diagonal too small in triangulate()"); for (int j=i+1; j<n; j++) { double mult=a[j][i]/diag; a[j]-= mult * a[i]; b[j]-= mult * b[i]; } }} EINI II Kap. 21: Zur Rechnung mit Matrizen 21-48 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung: Implementierung void triangulate(matrix &a, Vector &b) // with pivoting { int n=a.getsize(); for (int i=0; i<n-1; ++i) { double diag = pivot (a,b,i); if (fabs(diag) < gauss0_toosmall) // to avoid division by zero error ("zero determinant!"); for (int j=i+1; j<n; ++j) { double mult=a[j][i]/diag; for (int k=i+1; k<n; ++k) a[j][k]-=mult*a[i][k]; b[j]-=mult*b[i]; } }} EINI II Kap. 21: Zur Rechnung mit Matrizen 21-49 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung: Implementierung double dotprod (Vector &u, Vector &v, int k1, int k2) {// sum u[i]*v[i], i=k1...k2 double sum=0; for (int i=k1; i<=k2; ++i) sum+=u[i]*v[i]; return sum; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-50 Prof. Dr. G. Dittrich 01.07.2000 Gauß-Elimination: Implementierung Wiedhlg void backsubst(matrix &a, Vector &x, Vector &b) { int n = a.getsize(); for (int i=n-1; i>=0; i--) { double diag = a[i][i]; // ....... x[i]=(b[i]-scalar(a[i], x))/diag; }} void gauss0 (matrix &m, Vector &x, Vector &b) { triangulate(m,b); backsubst(m, x, b); } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-51 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung: Implementierung void backsubst(matrix &a, Vector &x, Vector &b) { int n = a.getsize(); for (int i=n-1; i>=0; i--) { double diag = a[i][i]; x[i]=(b[i]-dotprod(a[i],x,i+1,n-1))/diag; }} void gauss (matrix &m, Vector &x, Vector &b) { triangulate(m,b); backsubst(m, x, b); } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-52 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung: Implementierung int main() { int n; cout << "Enter number of variables << " of the equation system: ";cin >> n; matrix m(n); Vector x(n), b(n); cout << "\nEnter matrix m\n"; cin >> m; matrix m1=m; cout << "\nEnter Vector b\n"; cin >> b; gauss (m,x,b); cout << "Solution Vector x is:\n"; cout << x; cout << "\n\nNow, the verification: " << endl; Vector u = m1*x; cout << "\nproduct vector is: " << u; return 0; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-53 Prof. Dr. G. Dittrich 01.07.2000 Gauß mit Pivotisierung: Implementierung Ausgabe: Enter number of variables of the equation system: 3 Enter matrix m enter 3 row vectors enter row vector 0 enter 3 elements: v [0] = 3 v [1] = 5 v [2] = 1 enter row vector 1 enter 3 elements: v [0] = 2 v [1] = 4 v [2] = 5 enter row vector 2 enter 3 elements: v [0] = 1 v [1] = 2 v [2] = 2 Enter Vector b enter 3 elements: v [0] = 4 v [1] = -9 v [2] = -3 Solution Vector x is: ( -1 | 2 | -3 | ) Now, the verification: product vector is: ( 4|-9|-3|) EINI II Kap. 21: Zur Rechnung mit Matrizen 21-54 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Multiplikation: Implementierung Ergänzung um Matrix-Multiplikation in: class Vector {.... friend matrix operator* ¬ (const matrix&, const matrix&); .....} class matrix {.... friend matrix operator* ¬ (const matrix&, const matrix&); .....} EINI II Kap. 21: Zur Rechnung mit Matrizen 21-55 Prof. Dr. G. Dittrich 01.07.2000 Matrix -Multiplikation: Implementierung matrix operator* (const matrix &m1, const matrix &m2) // caution: friend-declaration in "matrix" and // "Vector" necessary. { int r,c; if (m1.numcols != m2.numrows) error ("Dimensions of the two matrices ¬ don't fit in ¬ operator* (const matrix &m1, const matrix &m2)"); r=m1.numrows; c=m2.numcols; // dimension of the result-matrix; ..... } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-56 Prof. Dr. G. Dittrich 01.07.2000 Matrix -Multiplikation: Implementierung matrix operator* (const matrix &m1, const matrix &m2) // Fortsetzung {...... matrix mult(r,c); for (int i=0; i < r; ++i) {for (int k =0;k<c;++k) { double t=0; for (int j=0; j < m1.numcols; ++j) t += m1.mat[i]->vec[j] * m2.mat[j]->vec[k]; mult.mat[i]->vec[k] = t; }} return mult; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-57 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Multiplikation: main int main() { int r1,c1,r2,c2; cout << "Enter number of rows: "; cin >> cout << "Enter number of cols: "; cin >> matrix m1(r1,c1); cin >> m1; cout << "Enter number of rows: "; cin >> cout << "Enter number of cols: "; cin >> matrix m2(r2,c2); cin >> m2; matrix mult (r1,c2); mult=m1*m2; cout << "\nErgebnis der Multiplikation:" cout << m1 <<endl; cout << "\n*\n"; cout cout << "\n=\n"; cout << mult; cout << "\n Transponierte Matrix:\n"; cout << m1.transpose(); return 0; } EINI II Kap. 21: Zur Rechnung mit Matrizen r1; c1; r2; c2; << endl; << m2; 21-58 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Multiplikation: Ausgabe Enter enter enter v [0] enter v [0] Enter enter enter v [0] enter v [0] number of rows: 2 2 row vectors row vector 0 = 1 v [1] row vector 1 = 1 v [1] number of rows: 2 2 row vectors row vector 0 = 1 v [1] row vector 1 = 1 v [1] Enter number of cols: 2 enter 2 elements: = 2 enter 2 elements: = 2 Enter number of cols: 2 enter 2 elements: = 1 enter 2 elements: = 1 EINI II Kap. 21: Zur Rechnung mit Matrizen 21-59 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Multiplikation: Ausgabe // Fortsetzung Ergebnis der Multiplikation: ( 1 | 2 | ) ( 1 | 2 | ) * ( 1 | 1 | ) ( 1 | 1 | ) = ( 3 | 3 | ) ( 3 | 3 | ) Transponierte Matrix: ( 1 | 1 | ) ( 2 | 2 | ) EINI II Kap. 21: Zur Rechnung mit Matrizen 21-60 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Invertierung: Implementierung Ergänzung zu Gauss: matrix identity (int n) { matrix m(n); // initialized to zero for (int i=0; i<n; ++i) m[i][i]=1; return m; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-61 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Invertierung: Implementierung matrix invert (const matrix& m) { int n=m.numcols; matrix m2=m; matrix e=identity(n); matrix result(n); Vector x(n); for (int r=0; r<n;++r) { gauss (m2,x,*e.mat[r]); // Gauss changes m2 *result.mat[r]=x; // columnvectors are included // as rows. Therefore "transpose" below ! m2=m; } result=result.transpose(); return result; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-62 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Invertierung: Implementierung matrix invert (const matrix& m) int main() { int n; cout << "Enter number of rows of matrix to invert: "; cin >> n; matrix m(n), m1(n); Vector x(n); cout << "\nEnter matrix m\n"; cin >> m; cout << "inverse matrix:" << endl;; cout << invert (m) << endl; m1=invert (m); m1= m*m1; cout << m1; return 0; } EINI II Kap. 21: Zur Rechnung mit Matrizen 21-63 Prof. Dr. G. Dittrich 01.07.2000 Matrix-Invertierung: Ausgabe Enter number of rows of matrix to invert: 3 Enter matrix m enter 3 row vectors enter row vector 0 enter 3 elements: v [0] = 3 v [1] = 5 v [2] = 1 enter row vector 1 enter 3 elements: v [0] = 2 v [1] = 4 v [2] = 5 enter row vector 2 enter 3 elements: v [0] = 1 v [1] = 2 v [2] = 2 inverse matrix: ( 2 | 8 | -21 | ) ( -1 | -5 | 13 | ) ( 0 | 1 | -2 | Matrix mal Inverse: ( 1 | 3.10862e-15 | -8.88178e-16 | ) ( 0 | 1 | -4.44089e-15 | ) ( 0 | 8.88178e-16 | 1 | ) EINI II Kap. 21: Zur Rechnung mit Matrizen ) 21-64