01.07.2000 universität dortmund, lehrstuhl informatik 1 [email protected] eini ii...
TRANSCRIPT
01.07.2000
Universität Dortmund, Lehrstuhl Informatik [email protected]
EINI IIEinführung in die Informatik
für Naturwissenschaftler und Ingenieure II
Prof. Dr. Gisbert Dittrich
21-2
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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
21-3
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren als ADT
• Hier: Reellwertige Vektoren (+ Matrizen)• Vektoren haben: • Größe (Dimension)
• Operationen• Erzeugen • Entfernen • Einlesen • Auslesen• Operationen i.e.S:
– Projektion auf Komponente : [ ] - Zuweisung: =– Addition: += - Subtraktion: -= – Multiplikation mit Skalar: *= - Skalarmultiplikation
21-4
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen als ADT
• Matrizen haben: • Größe: Anzahl Reihen und Anzahl Spalten
• Operationen• Erzeugen • Entfernen • Einlesen • Auslesen• Operationen i.e.S:
– Projektion auf Zeile : [ ] - Zuweisung: =– Addition: += - Subtraktion: -= – Multiplikation mit Skalar: *= - Matrixmultiplikation– Invertierung
21-5
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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
21-6
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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();
21-7
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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.
21-8
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Anmerkungen
&: Referenz• Alternativer Name für ein Objekt• X& bedeutet Referenz auf Xint ii = 1;
int& rr = ii;
rr++; // ii wird um 1
// inkrementiert
int* pp = &rr
// pp zeigt auf ii
Hauptanwendung: • Angabe von Argumenten und Rückgabewerten von Funktionen• Insbesondere: für überladene Operatoren (s.u.)
1ii:rr:
&iipp:
21-9
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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]
21-10
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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;}
......
};
21-11
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Anmerkungen
operator:• Schlüsselwort. • Beschreibt Spezifikation der Überladung von Operationen über Objekten der (neuen) Klasse:
– arithmetische – andere (z. B. Einlesen , auslesen)
• Infixnotation weiter verwendbar
21-12
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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&);
};
21-13
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector::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;
}
21-14
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector::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];
}
21-15
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector::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];
}
21-16
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector::~Vector () {delete vec;}
inline int Vector::range (int i)
{return (i <0 || i>= size) ? ¬
(error ¬
("error in range-function in class vector"), -1) ¬
: i;
}
21-17
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector& 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;
}
21-18
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector& 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;
}
21-19
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector& 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;
}
21-20
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: ImplementierungVector& 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;
}
21-21
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: Implementierungdouble 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;
}
21-22
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: Implementierungistream& 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;
}
21-23
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Vektoren: Implementierungostream& 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;
}
21-24
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierung
class matrix {
private:
int numrows; // how many rows?
int numcols; // how many columns?
Vector **mat;
int range(int); // row range check
public:
matrix (int, int);// constr: rectangular matrix
matrix (int); // constr: square matrix
matrix (const matrix&); // constr: rectang. matrix
~matrix(); // destructor
21-25
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungclass 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&);
};
21-26
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungmatrix::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)");
}
}
21-27
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungmatrix::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)");
}
}
21-28
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungmatrix::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];
}
21-29
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungmatrix::~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;
}
21-30
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungint 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;
}
21-31
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungmatrix 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;
}
21-32
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungmatrix& 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;
}
21-33
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: ImplementierungVector 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;
}
21-34
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: ImplementierungVector 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;
}
21-35
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrizen: Implementierungostream& 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;
}
21-36
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Beispiel
#include <iostream.h>
#include "error.cpp"
#include "vector.cpp"
#include "matrix.cpp"
21-37
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Beispielint 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;
}
21-38
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Beispiel: AusgabeEnter number of rows of the matrix: 3
Enter number of columns of the matrix: 3
Enter matrix m
enter 3 row vectors
enter row vector 0 enter 3 elements:
v [0] = 1 v [1] = 2 v [2] = 3
enter row vector 1 enter 3 elements:
v [0] = 4 v [1] = 5 v [2] = 6
enter row vector 2 enter 3 elements:
v [0] = 7 v [1] = 8 v [2] = 9
Enter vector enter 3 elements:
v [0] = 1 v [1] = 0 v [2] = 1
( 4 | 10 | 16 | )
( 8 | 10 | 12 | ) [Umbruch geändert GD]
21-39
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Anwendung: Gauß
Ziel: • Gauß‘sche Elimination zur Gleichungslösung
Idee: • Trianguläre Darstellung des Gleichungssystems, • Dann rückwärts ausrechnen.
21-40
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Anwendung: Gauß
Beispiel: 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
in Matrixdarstellung:
5 2
3 4
⎛
⎝ ⎜
⎞
⎠ ⎟
x0
x1
⎛
⎝ ⎜
⎞
⎠ ⎟ =
20
26
⎛
⎝ ⎜
⎞
⎠ ⎟
21-41
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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];
}}
}
21-42
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß-Elimination: Implementierungvoid 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);
}
21-43
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Main: Implementierungint 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;
}
21-44
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß-Elimination; Ausgabe für BeispielEnter 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 | )
21-45
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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“.
21-46
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß mit PivotisierungAm 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)
21-47
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß mit Pivotisierung: Implementierungdouble 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];
}
21-48
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß-Elimination: Implementierungvoid 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];
}
}}
21-49
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß mit Pivotisierung: Implementierungvoid 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];
}
}}
21-50
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß mit Pivotisierung: Implementierungdouble 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;
}
21-51
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß-Elimination: Implementierung Wiedhlgvoid 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);
}
21-52
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß mit Pivotisierung: Implementierungvoid 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);
}
21-53
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Gauß mit Pivotisierung: Implementierungint 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;
}
21-54
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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|)
21-55
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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&);
.....}
21-56
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrix -Multiplikation: Implementierungmatrix 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;
.....
}
21-57
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrix -Multiplikation: Implementierungmatrix 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;
}
21-58
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrix-Multiplikation: mainint main()
{ int r1,c1,r2,c2;
cout << "Enter number of rows: "; cin >> r1;
cout << "Enter number of cols: "; cin >> c1;
matrix m1(r1,c1); cin >> m1;
cout << "Enter number of rows: "; cin >> r2;
cout << "Enter number of cols: "; cin >> c2;
matrix m2(r2,c2); cin >> m2;
matrix mult (r1,c2); mult=m1*m2;
cout << "\nErgebnis der Multiplikation:" << endl;
cout << m1 <<endl; cout << "\n*\n"; cout << m2;
cout << "\n=\n"; cout << mult;
cout << "\n Transponierte Matrix:\n";
cout << m1.transpose(); return 0; }
21-59
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrix-Multiplikation: AusgabeEnter number of rows: 2 Enter number of cols: 2
enter 2 row vectors
enter row vector 0 enter 2 elements:
v [0] = 1 v [1] = 2
enter row vector 1 enter 2 elements:
v [0] = 1 v [1] = 2
Enter number of rows: 2 Enter number of cols: 2
enter 2 row vectors
enter row vector 0 enter 2 elements:
v [0] = 1 v [1] = 1
enter row vector 1 enter 2 elements:
v [0] = 1 v [1] = 1
21-60
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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 | )
21-61
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
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;
}
21-62
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrix-Invertierung: Implementierungmatrix 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;
}
21-63
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrix-Invertierung: Implementierungmatrix 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;
}
21-64
Prof. Dr. G. Dittrich01.07.2000
EINI II Kap. 21: Zur Rechnung mit Matrizen
Matrix-Invertierung: AusgabeEnter 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 | )