Lösung Übungsblatt 5 Aufgabe 1: Positive Definitheit Zu zeigen: Beweis: Eine symmetrische Matrix A R N N ist genau dann positiv definit, wenn alle Eigenwerte von A positiv sind. A heißt positiv definit, wenn gilt: x T Ax > 0 x R N, x 0 Sei {v 1,..., v N } eine Orthogonalbasis aus Eigenvektoren von A mit entsprechenden Eigenwerten λ 1,..., λ N. Dann kann x geschrieben werden als x c i v i (x 0). x T Ax i1 T c i v i A c k v k i1 k1 c i v T i c k Av k i1 k1 }{{} λ k v k λ k c i c k v T i v k }{{} i1 k1 0 für i k i1 i1 λ i c 2 i v 2 i λ i x 2 i (1.1) Es gilt xi 2 > 0. Sei nun ein λ i < 0. Dann kann ein x so gewählt werden, dass (1.1) < 0 wird. Also muss jedes λ i > 0 sein, wenn (1.1) > 0 gelten soll für alle x 0. Folglich kann eine symmetrische, positiv definite Matrix ausschließlich positive Eigenwerte besitzen. bobbysteels@gmx.tm Seite 1 von 9 A. Bschorr, S. Flaischlen
Aufgabe 2: Spektralnorm a) Definitionen: A 2 : λ max (A T A) (Spektralnorm 1 ) (2.1) κ(a) : A A 1 (Kondition) (2.2) Gegeben sei eine orthogonale Matrix Q R N N, es gilt also Q T Q 1. Zu zeigen: Q 2 1 und κ 2 (Q) 1 Beweis: Q 2 λ max (1) 1 da alle Eigenwerte einer Einheitsmatrix 1 betragen. κ 2 (Q) Q 2 Q 1 2 λ max (1) λ max [(Q 1 ) T Q 1 ] λ max (1) λ max (QQ T ) λ max (1) λ max (1) λ max (1) 1 1 Mit λ max (B) max i λ i, wobei λ i die Eigenwerte von B sind. bobbysteels@gmx.tm Seite 2 von 9 A. Bschorr, S. Flaischlen
b) Gegeben sei folgende Matrix: A ( 7.2 0.4 4.6 7.2 ) Berechnung der Spektralnorm von A: Nach (2.1) werden die Eigenwerte von A T A benötigt: A T A ( 7.2 4.6 0.4 7.2 ( ) ( 7.2 0.4 4.6 7.2 7.2 2 + 4.6 2 7.2 0.4 4.6 7.2 7.2 0.4 4.6 7.2 0.4 2 + 7.2 2 ( 73 36 36 52 ) ) ) Es muss gelten: A T A λ 1 0 0 73 λ 36 36 52 λ (73 λ)(52 λ) 36 2 λ 2 125λ + 2500 λ 1,2 125 ± 15625 4 2500 2 125 ± 75 2 λ 1 25, λ 2 100 Somit ergibt sich für die Spektralnorm: A 2 λ max (A T A) max{25, 100} 100 10 bobbysteels@gmx.tm Seite 3 von 9 A. Bschorr, S. Flaischlen
Aufgabe 3: Tridiagonalsysteme C++ Quellcode: 1 /* 2 M4 Numerik fuer Physiker Sommersemester 2008 3 Uebungsblatt 5 - A.3 4 5 Titel : Tridiagonalsysteme 6 Datei : tridiag. cpp 7 Erstellt : 18.05.2008 8 Autoren : Alexander Bschorr, Stefan Flaischlen 9 */ 10 11 # include <iostream > 12 # include <iomanip > 13 # include <cmath > 14 15 using namespace std ; 16 17 // Anzahl der Reihen und Spalten global deklarieren : 18 int N_dim ; 19 20 // Funktionen deklarieren : 21 double ** Create_Matrix (); 22 void Display_Matrix ( double **, char ); 23 void Delete_Matrix ( double **) ; 24 void Delete_Vector ( double *); 25 void Display_Vector ( double *, char ); 26 void Display_Specials ( int ); 27 void Split_Matrix ( double **, double *, double *, 28 double *); 29 void Solve_Tridiag ( double *, double *, double *, 30 double *, double *); 31 void A_x_product ( double **, double *, double *); 32 bool Is_DiDom ( double **) ; 33 34 // -------------------------- Hauptfunktion ----------------------------- 35 int main () { 36 37 // Zeilen -/ Spaltenzahl festlegen ( dynamisch ): 38 N_dim 6; 39 40 // Vektoren dynamisch erzeugen : 41 double * v_a new double [ N_dim ]; 42 double * v_b new double [ N_dim ]; 43 double * v_c new double [ N_dim ]; 44 double * v_x new double [ N_dim ]; 45 double * v_y new double [ N_dim ]; 46 47 // Programmtitel ausgeben : 48 Display_Specials (0) ; 49 50 // Matrix A initalisieren : 51 double ** A Create_Matrix (); 52 53 for ( int i 0; i < N_dim ; i ++) { 54 A[ i][ i] 9; 55 } bobbysteels@gmx.tm Seite 4 von 9 A. Bschorr, S. Flaischlen
56 57 for ( int i 1; i < N_dim ; i ++) { 58 59 A[ i - 1][ i] i; 60 A[ i][ i - 1] N_dim - i; 61 62 // Vektor y initialisieren : 63 v_y [ i] 16; 64 } 65 66 v_y [0] 10; v_y [ N_dim - 1] 10; 67 68 Display_Matrix (A, A ); 69 70 // Ist A diagonal dominiert? 71 if (! Is_DiDom (A)) { 72 cerr << " Es liegt keine diagonale Dominanz vor!\ n" 73 << " A sollte pivotisiert werden.\ n"; 74 goto Handler ; 75 } 76 77 Display_Vector ( v_y, y ); 78 79 // Matrix in Vektoren aufteilen : 80 Split_Matrix (A, v_a, v_b, v_c ); 81 82 cout << "\ n\ n" << " A in Vektoren aufgeteilt " << "\ n"; 83 Display_Specials (1) ; 84 Display_Vector ( v_a, a ); 85 Display_Vector ( v_b, b ); 86 Display_Vector ( v_c, c ); 87 88 // System loesen : 89 Solve_Tridiag (v_a, v_b, v_c, v_y, v_x ); 90 91 cout << "\n\n" << " Loesungsvektor " << "\n"; 92 Display_Specials (1) ; 93 Display_Vector ( v_x, x ); 94 95 // Zur Kontrolle Produkt aus A und v_x berechnen : 96 A_x_product (A, v_x, v_y ); 97 98 cout << "\ n\ n" << " Kontrolle : y Ax berechnen " << "\ n"; 99 Display_Specials (1) ; 100 Display_Vector ( v_y, y ); 101 102 Handler : 103 104 // Speicher freigeben : 105 Delete_Matrix ( A); 106 Delete_Vector ( v_a ); 107 Delete_Vector ( v_b ); 108 Delete_Vector ( v_c ); 109 Delete_Vector ( v_x ); 110 Delete_Vector ( v_y ); 111 } bobbysteels@gmx.tm Seite 5 von 9 A. Bschorr, S. Flaischlen
112 113 // ---------- Funktion : Tridiagonale Matrix aufteilen -------------------- 114 void Split_Matrix ( double ** A, double * v_a, double * v_b, 115 double * v_c ) { 116 117 /* 118 Eingabe : Tridiagonale Matrix A und 3 Vektoren a, b und c. 119 Funktion : A auf a, b und c aufteilen. 120 */ 121 122 for ( int i 0; i < N_dim ; i ++) { 123 v_b [i] A[i][i]; 124 } 125 126 for ( int i 1; i < N_dim ; i ++) { 127 v_c [ i - 1] A[ i - 1][ i]; 128 v_a [i] A[i][i - 1]; 129 } 130 131 v_a [0] 0; v_c [ N_dim - 1] 0; 132 } 133 134 // ----------- Funktion : Tridiagonales System loesen --------------------- 135 void Solve_Tridiag ( double * v_a, double * v_b, double * v_c, 136 double * v_y, double * v_x ) { 137 138 /* 139 Eingabe : 3 Vektoren a, b und c aus einer tridiagonalen 140 Koeffizientenmatrix und ein Vektor y. 141 Funktion : Loesung mittels modifiziertem Gauss - Algorithmus 142 bestimmen und in Vektor x schreiben. 143 */ 144 145 double n_b ; 146 double n_d [ N_dim ]; 147 148 // System loesen : 149 n_d [0] v_c [0] / v_b [0]; 150 v_x [0] v_y [0] / v_b [0]; 151 152 for ( int i 1; i < N_dim ; i ++) { 153 n_b v_b [i] - n_d [i - 1] * v_a [i]; 154 n_d [i] v_c [i] / n_b ; 155 v_x [i] ( v_y [i] - v_x [i - 1] * v_a [i]) / n_b ; 156 } 157 158 // Rueckwaertseinsetzen : 159 for ( int i N_dim - 2; i > 0; i - -) { 160 v_x [i] - n_d [i] * v_x [i + 1]; 161 } 162 } bobbysteels@gmx.tm Seite 6 von 9 A. Bschorr, S. Flaischlen
163 164 // ---------------- Funktion : Matrix - Vektor - Produkt --------------------- 165 void A_x_product ( double ** A, double * x, double * y) { 166 167 /* 168 Eingabe : Matrix A und ein Vektor x. 169 Funktion : Multiplikation der Matrix A mit dem 170 Vektor x und Ausgabe im Array y. 171 */ 172 173 for ( int i 0; i < N_dim ; i ++) { 174 y[ i] 0; 175 for ( int k 0; k < N_dim ; k ++) { 176 y[ i] + A[ i][ k] * x[ k]; 177 } 178 } 179 } 180 181 // -------------- Funktion : Diagonale Dominanz pruefen ----------------- 182 bool Is_DiDom ( double ** A) { 183 184 /* 185 Eingabe : Tridiagonale Matrix A 186 Funktion : Prueft die diagonale Dominanz einer tridiagonalen 187 Matrix A. 188 */ 189 190 bool erg true ; 191 double tmp ; 192 193 for ( int i 0; i < N_dim ; i ++) { 194 tmp -fabs (A[i][i]); 195 for ( int k 0; k < N_dim ; k ++) { 196 tmp + fabs (A[i][k]); 197 } 198 if ( tmp > fabs (A[i][i])) { 199 erg false ; 200 break ; 201 } 202 } 203 return erg ; 204 } 205 206 // ----------------- Hilfsfunktion : Vektor ausgeben --------------------- 207 void Display_Vector ( double * sv, char vtitle ) { 208 209 /* 210 Eingabe : Vektor sv und Zeichen vtitle 211 Funktion : Ausgabe des Vektors. 212 */ 213 214 cout << " Vektor " << vtitle << ": [" 215 << setprecision (3) << sv [0]; 216 217 for ( int i 1; i< N_dim ; i ++) { 218 cout << ", " << setprecision (3) << sv[ i]; 219 } 220 221 cout << "]" << "\n"; 222 } bobbysteels@gmx.tm Seite 7 von 9 A. Bschorr, S. Flaischlen
223 224 // ----------------- Hilfsfunktion : Matrix ausgeben --------------------- 225 void Display_Matrix ( double ** sa, char mtitle ) { 226 227 cout << " Matrix " << mtitle << ": " << "\ n"; 228 229 for ( int i 0; i < N_dim ; i ++) { 230 cout << setw (11) << "[" 231 << setprecision (3) << sa[ i ][0]; 232 for ( int j 1; j < N_dim ; j ++) { 233 cout << " " << setprecision (3) << sa[ i][ j]; 234 } 235 cout << "]" << "\n"; 236 } 237 cout << "\n"; 238 } 239 240 // ------------ Hilfsfunktion : Matrix dynamisch erzeugen ---------------- 241 double ** Create_Matrix () { 242 243 double ** na new double *[ N_dim ]; 244 245 for ( int i 0; i < N_dim ; i ++) { 246 na[ i] new double [ N_dim ]; 247 na[ i ][0] 0; 248 } 249 250 return na; 251 } 252 253 // ----------------- Hilfsfunktion : Matrix loeschen --------------------- 254 void Delete_Matrix ( double ** sa) { 255 256 for ( int i 0; i < N_dim ; i ++) { 257 Delete_Vector ( sa[ i]); 258 delete sa; 259 } 260 } 261 262 // ----------------- Hilfsfunktion : Vektor loeschen --------------------- 263 void Delete_Vector ( double * sv) { 264 265 delete [] sv; 266 } 267 268 // ------------------ Hilfsfunktion : Titel, Linien ---------------------- 269 void Display_Specials ( int ntype ) { 270 271 int cwidth 60; 272 273 switch ( ntype ) { 274 case 0: 275 cout << setfill ( - ) << setw ( cwidth ) << "\n" << setfill ( ) 276 << setw (37) << " Tridiagonalsysteme " << "\ n" 277 << setfill ( - ) << setw ( cwidth + 1) << "\n\n" 278 << " Loesen des Tridiagonalsystems Ax y." << "\ n\ n\ n" 279 << " Eingabe " << "\n" 280 << setfill ( - ) << setw ( cwidth ) << "\n" << setfill ( ); 281 break ; 282 case 1: bobbysteels@gmx.tm Seite 8 von 9 A. Bschorr, S. Flaischlen
283 cout << setfill ( - ) << setw ( cwidth ) << "\n" << setfill ( ); 284 break ; 285 } 286 } Ausgabe: Tridiagonalsysteme Loesen des Tridiagonalsystems Ax y. Eingabe Matrix A: [9 1 0 0 0 0] [5 9 2 0 0 0] [0 4 9 3 0 0] [0 0 3 9 4 0] [0 0 0 2 9 5] [0 0 0 0 1 9] Vektor y: [10, 16, 16, 16, 16, 10] A in Vektoren aufgeteilt Vektor a: [0, 5, 4, 3, 2, 1] Vektor b: [9, 9, 9, 9, 9, 9] Vektor c: [1, 2, 3, 4, 5, 0] Loesungsvektor Vektor x: [1, 1, 1, 1, 1, 1] Kontrolle: y Ax berechnen Vektor y: [10, 16, 16, 16, 16, 10] bobbysteels@gmx.tm Seite 9 von 9 A. Bschorr, S. Flaischlen