Kapitel 21 - Zur Rechnung mit Matrizen

Werbung
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 2x0  20

    
3 4x1  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
Herunterladen