Einführung in die Numerik Sommersemester 2011 Übungsblatt Matlab-Zentralübung Musterlösung Lösung 1 (Givens-Rotationen für Wilkinson Matrix) a) function [Q,R] = qr_givens (A) % [Q,R] = qr_givens(a) berechnet die QR Zerlegung einer % rechteckigen Matrix A. Die Matrix R i s t die % gesuchte oberen Dreiecksmatrix, Q i s t eine orthogonale % Matrix. % Groesse von A ermitteln n = size (A, 1); m = size (A, 2); % Q i n i t i a l i s i e r e n Q = eye(n ) ; % Schleife ueber die Spalten von A for k = 1:m % Schleife ueber die Zeilen von A bis zur Diagonale for i = n: 1:k+1 % I nitialisierung der Givens Rotation G = speye(n ) ; % i s t eine Drehung notwig? if (A( i, k) ~= 0) % Berechnung von sin, cos und r r = sqrt (A( i 1,k).^2 + A( i, k ).^2); s = A( i, k)/ r ; c = A( i 1,k)/ r ; % Aufstellen der Givens Rotation G( i 1,i 1) = c ; G( i, i ) = c ; G( i 1, i ) = s ; G( i, i 1) = s ; % Update von A A = G A; % Update von Q Q = G Q; %Q 1
% Rueckgabe definieren Q = Q ; R = A; b) function [W, b ] = my_wilk(n) % Erzeugt die Wilkinson Matrix der % Groesse nxn und die rechte Seite % b mit b( i )=(i 1)/n, b(n)=1. b = zeros(n, 1); W = eye(n ) ; W( :, n) = ones (n, 1); for i = 1:n W( i, [ 1 : i 1]) = ones (1, i 1); b( i ) = ( i 1)/n ; b(n) = 1; c) clear all ; close all ; % maximale Anzahl von Iterationen kmax = 50; % I nitialisierung der Fehlervektoren n = zeros(kmax, 1 ) ; error = zeros(kmax, 1 ) ; errorqr = zeros(kmax, 1 ) ; for i = 1:kmax n( i ) = i ; x = zeros(n( i ), 1); % Angabe der exakten Loesung exact = 1/n( i ) ones (n( i ), 1); exact (n( i )) = 1/n( i ) ; % Definition der Matrix und der rechten Seite [W, b ] = my_wilk(n( i ) ) ; % Berechnen der LU Zerlegung A = my_lu(w) ; % Ermittlung der unteren Dreiecksmatrix L L = eye(n( i )) + tril (A, 1); % Ermittlung der oberen Dreiecksmatrix U U = triu (A, 0 ) ; % Vorwaertssubstitution x = s o l v e l t r i (L, b ) ; % Rueckwaertssubstitution x = solveutri (U, x ) ; 2
% Berechnung des relativen Fehlers error ( i ) = norm(x exact )/norm( exact ) ; % Berechnen der QR Zerlegung [Q,R] = qr_givens (W) ; % Berechnung der rechten Seite x = Q b ; % Rueckwaertssubstitution x = solveutri (R, x ) ; % Berechnung des relativen Fehlers errorqr ( i ) = norm(x exact )/norm( exact ) ; % grafische Ausgabe des Fehlers in Abhaengigkeit von n semilogy (n, error, n, errorqr, LineWidth,3); set (gca, FontSize,14); leg ( LU, QR,2); xlabel ( n ) ; ylabel ( Fehler ) ; Dies ergibt die folge Ausgabe: 10 2 10 4 LU QR 10 6 10 8 Fehler 10 10 10 12 10 14 10 16 10 18 0 10 20 30 40 50 n Im Gegensatz zu der LU-Zerlegung, bei der κ(u) κ(a) auftreten kann, gilt für die QR-Zerlegung stets κ(r) = κ(a). Damit ist die Rückwärtssubstitution gut konditioniert und verstärt eventuelle Rundungsfehler nicht so stark wie die LU- Zerlegung. Lösung 2 (Halbwertszeit & Normalengleichung) Man schreibt die Gesetzmäßigkeit um durch Logarithmieren: ln(y(t)) = ln(y(0))+αt 3
Man erhält das folge lineare Gleichungssystem: 1 1.5 ln(25.9) 1 4.0 [ ] 1 6.5 ln(y(0)) ln(22.7) = 1 9.0 α ln(20.3) ln(17.7) 1 11.5 ln(15.6) Mit Matlab berechnet man dann die Halbwertszeit wie folgt: % Gleichungssystem aufstellen >> A = [1 1.5; 1 4.0; 1 6.5; 1 9.0; 1 11.5]; >> b = [25.9; 22.7; 20.3; 17.7; 15.6]; >> logb = log(b); % Lösen der Normalengleichung >> x = (A *A)\(A *log(b)) x = 3.3299-0.0505 % Berechnung des Anfangsgewichts y_0 >> y_0 = exp(x(1)) y_0 = 27.9363 % Berechnung von alpha >> alpha = x(2) alpha = -0.0505 % Berechnung der Halbwertszeit: >> t_halb = (log(y_0/2)-log(y_0))/alpha % Alternativ: Berechnung der Halbwertszeit, falls log in der passen basis (hier e): >> t_halb = -log(2) / alpha t_halb = 13.7230 % log. loesung des ausgleichsproblems tausgleich = linspace(0,12,1200); ylogausgleich = log(y_0) + alpha.*tausgleich; yausgleich = y_0 * exp(alpha.*tausgleich); 4
figure(1); % log. plot plot(a(:,2),logb, x,tausgleich,ylogausgleich); xlabel( t ); ylabel( ln(y) ); figure(2) % normaler plot plot(a(:,2),b, x,tausgleich,yausgleich); xlabel( t ); ylabel( y ); ln(y) 3.5 3.4 3.3 3.2 3.1 3 2.9 2.8 2.7 0 2 4 6 8 10 12 Zeit y 28 26 24 22 20 18 16 14 0 2 4 6 8 10 12 Zeit Abbildung 1: Links: Lösung des linearen Ausgleichsproblems. Rechts: Rücktransformation auf die ursprüngliche exponentielle Problemstellung. Lösung 3 (Nichtlineares Ausgleichsproblem) a) function [ x, k ] = gauss_newton ( t, b, Ft, dft, x0, maxit, tol ) x = x0 ; for k = 1: maxit % compute local Jacobian Jac = feval (dft, t, x ) ; % compute system matrix of normal equation given by DF^T DF M = Jac Jac ; % compute right hand side DF^T F r = Jac eval (Ft ) ; % solve normal equation of linearized problem dx = M\r ; % compute update x = x + dx ; % stop i f requested accuracy is achieved if norm(dx)/norm(x0) < tol 5
break ; b) function Jac = dft(t, x) F1 = i n l i n e ( exp( (x_2.^2 + x_3^2). t ). sinh (x_3.^2. t )/x_3^2,... x_1, x_2, x_3, t ) ; F2 = i n l i n e ( 2 x_2. t. x_1. exp( (x_2.^2 + x_3^2). t ). sinh (x_3.^2. t )/x_3^2,. x_1, x_2, x_3, t ) ; F3 = i n l i n e ( 2 x_3. t. x_1. exp( (x_2.^2 + x_3^2). t ). sinh (x_3.^2. t )/x_3^2 + 2 x_1, x_2, x_3, t ) ; m = length ( t ) ; n = length (x ) ; Jac = zeros (m, n ) ; Jac ( :, 1) = F1(x (1), x (2), x (3), t ) ; Jac ( :, 2) = F2(x (1), x (2), x (3), t ) ; Jac ( :, 3) = F3(x (1), x (2), x (3), t ) ; % set i n i t i a l value x0 = [ 80; 0.055; 0. 2 1 ; ] ; % choose tolerance tol = 1e 10; % measurements t = [ 6 12 18 24 30 36 42 48 54 60 66 72 78 84 90 96 102 108 114 120... 126 132 138 144 150 156 162 168 174 1 8 0] ; b = [24.19 35.34 43.43 42.63 49.92 51.53 57.39 59.56 55.60 51.91... 58.27 62.99 52.99 53.83 59.37 62.35 61.84 61.62 49.64 57.81... 54.79 50.38 43.85 45.16 46.72 40.68 35.14 45.47 42.40 5 5.21] ; %csvwrite ( Messdaten. txt, [ t, b ]) % write data to tabulator spaced f i l e %dlmwrite ( Messdaten. txt, [ t, b ], \ t ) % read data from tabulator spaced f i l e % not needed i f t %f i l e i n p u t = dlmread ( Messdaten. txt, \ t ) ; % check i f f i l e io worked correctly %filecheck = max( abs ( f i leinput (:,1) t ) + abs ( f i l e i n put (:,2) b )) % function phi ( t, x) phit = x(1) exp( (x(2)^2 + x(3)^2) tvec ). sinh (x(3)^2 tvec )/x(3)^2 ; % function F( t, x) Ft = x(1) exp( (x(2)^2 + x(3)^2) t ). sinh (x(3)^2 t )/x(3)^2 b ; % discret times for plot tvec = linspace (6, 180, 200); hold of f ; for k = 1:6 % gauss_newton step [ x, k ] = gauss_newton ( t, b, Ft, @dft, x0, k, tol ) %evaluate phit fvec = eval ( phit ) ; 6
plot ( tvec, fvec, linewidth, 2); hold on ; text(182+k, fvec (), num2str(k ), f ontsize, 12); plot ( t, b, r+, linewidth, 2, markersize, 12); set (gca, f ontsize, 12); 80 70 60 2 50 40 3 4 5 6 30 20 1 10 0 20 40 60 80 100 120 140 160 180 7