Sie sind auf Seite 1von 24

AE470 Examples of Matlab refreshers Problem 1 The Taylor series expansion of sin(x) is x3 x5 x7 sin x = x ! + ! + ... 3! 5! 7!

! Write a code which uses that expression to compute the approximate value of sin(x) for a series of values of x between 0 and 2! . Find out how many terms are needed for a given value of x to achieve a certain level of precision (i.e., absolute error). Obtain a single graph that displays for 50 values of x, the number N of terms in the series for 5 values of the precision: 10-6, 10-8, 10-10, 10-12 and 10-14. Make sure to label the axes and to provide legends for the curves. Comment on your solution. Try for larger intervals (0 to 4! or 6! ): what happens to N for the high precision levels for large values of x?

()

Solution
% Program taylor_sin % xmax=2*pi; % maximum value of x num_x=100; % number of x values dx=xmax/num_x; % increment in x num_eps=5; % number of epsilon(tolerance of errors) epsilon=zeros(5,1); epsilon(1)=1.e-06; % specify epsilon values epsilon(2)=1.e-08; epsilon(3)=1.e-10; epsilon(4)=1.e-12; epsilon(5)=1.e-14; solution=zeros(num_x,2,num_eps); % prepare solution array to store the results % for k=1:num_eps % loop for precision values for i=1:num_x % loop for x values x=i*dx; % current x value partial_sum=x; % initial sum of talyor series N=1; % initial number of term = 1 NNfactorial=1; % initial factorial value while abs(partial_sum-sin(x)) > epsilon(k) % loop while the error > specified precision N=N+1; % add counter NNfactorial=NNfactorial*(2*N-2)*(2*N-1); % calculate factorial partial_sum=partial_sum+(-1)^(N-1)*x^(2*N-1)/NNfactorial; % add more term to taylor_series end solution(i,1,k)=x; % store current x value solution(i,2,k)=N; % store number of terms needed end end % % plot and add labels and legend % plot(solution(:,1,1),solution(:,2,1),'b',solution(:,1,2),solution(:,2,2),'r:',solution(:,1,3),solution(:,2,3),'g.',solution(:,1,4),solution(:,2,4),'m--',solution(:,1,5),solution(:,2,5),'c-') xlabel('x'); ylabel('N'); legend('epsilon=1.e-6','epsilon=1.e-8','epsilon=1.e-10','epsilon=1.e12','epsilon=1.e-14',0);

Comments about the results (1) As the value of x increases, the number of terms N required for convergence also increases (Figure 1). (2) For a given value of x, the higher the required precision, the higher the number of terms required for convergence. (3) When the value of x is too high at high level of precision, the significance of numerical approximation by series is lost due to the loss of effective digits associated with the ratio of very large numbers. (Figure 2)

Figure 1. Number of terms N needed for convergence as a function of x for various values of the convergence parameter epsilon ( x = 0 to 2! ).

Figure 2. Same as Figure 1 but for wider range of x ( x = 0 to 4! ).

Problem 2. The Taylor series expansion of log(1+x) = x - (1/2)x2 + (1/3)x3 - (1/4)x4 for -1<x<1 Write a Matlab code that uses this expression to compute the approximate value for N number of terms in the series. On a log-log plot, show the relative error as a function of N for x=-0.5 and x=0.5, for values of N ranging from 1 to 1000. Make sure to label the axes and to provide legends for the curves. Comment on your solution, i.e. describe and try to explain the trends noted with respect to changes in N.
% Program taylor_log % Nmax=1000; %maximum number of terms num_app=2; %number of values approximated approx=zeros(2,1); approx(1)=-0.5; approx(2)=0.5; solution=zeros(Nmax,2,num_app); % for k=1:num_app %error loop true=log(approx(k)+1); %calculates true value partial_sum=0; %resets partial sum variable for i=1:Nmax %term loop x=approx(k); %assigns local value partial_sum=partial_sum+(-1)^(i-1)*x^(i)/i; %runs taylor approx error=abs((true-partial_sum)/true); %calculates relative error solution(i,1,k)=i; solution(i,2,k)=error; end end loglog(solution(:,1,1),solution(:,2,1),'b',solution(:,1,2),solution(:,2,2 ),'r-') xlabel('Number of Terms'); ylabel('Relative Error'); legend('x=-0.5','x=0.5',2); title('Correlation Between Relative Error and the Number of Terms in the Taylor Expansion of log(1+x)');

Comments about the results - The relative error decreases exponentially as the number of terms increases for Taylor expansions containing anywhere from 0 to approximately 48 terms. - Both functions oscillate due to the very nature of the Taylor expansion-being to seek numbers above and below the true value, converging closer and close each time. - Around 48 terms in the expansion, the error plateaus.

Problem 3 The Taylor series expansion of sinh(x) is


x 3 x5 x7 sinh( x ) = x + + + + .... 3! 5! 7!

Write a Matlab code which uses that expression to compute the approximate value of sinh(x) for a given value of x. Stop the series when the approximate value is within 0.001% of the exact value (obtained with sinh(x)). For a given value of x introduced interactively, output on the screen
x= exact value of sinh( x ) = approximate value of sinh(x ) = number of terms in approximation =

Then write a second version of your code that loops over N equally spaced values of x between xmin and xmax (with N, xmin and xmax introduced interactively by the user) and creates a plot with the number of terms in the approximation (to achieve 0.001% precision) as a function of x. Then run your code for xmin = 1.0 , xmax = 30.0 and N = 100. Comment on your solution. Solution The basic structure of the two codes is relatively self-explanatory. Here is the first code sinhcode1.m and a typical output
% Computes the Taylor series approximation of sinh(x) for a % user-introduced value of x within a given precision % TargetPrecision=0.001; % precision in percent MaxNumTerm=100; % maximum number of terms in Taylor series x=input(' Enter the value of the argument x = ') ExactValue=sinh(x); % exact value of sinh(x) PartialSum=0; % partial value of the series ICounter=0; % number of terms in the series while 100*abs(ExactValue-PartialSum)/ExactValue > TargetPrecision % check for % convergence ICounter=ICounter+1; % if no convergence, add one term to the series PartialSum=PartialSum+(x^(2*ICounter-1))/factorial(2*ICounter-1); if ICounter > MaxNumTerm % check for lack of convergence sprintf( ' No convergence achieved after %d terms for x=%d\n',ICounter,xx) break end end sprintf(' x = %15.10f\n',x) % output results as specified in assignment sprintf(' exact value of sinh(x) = %15.10f\n',ExactValue) sprintf(' approximate value of sinh(x) = %15.10f\n',PartialSum) sprintf(' number of terms in approximation = %d\n',ICounter)

>> sinhcode1 Enter the value of the argument x = ans = x = 10.5000000000

10.5

ans = exact value of sinh(x) = 18157.7513233551 ans = approximate value of sinh(x) = 18157.6986168544 ans = number of terms in approximation = 14 The second code sinhcode2.m just adds a loop (over the values of x) around the first one:
% AE 470 - Programming assignment # 1 - Problem 1 - Code 2 % Computes the Taylor series approximation of sinh(x) for a % user-introduced value of x within a given precision. % Plots the number of terms needed for convergence as a function % of x between xmin and xmax % TargetPrecision=0.001; % precision in percent MaxNumTerm=100; % maximum number of terms in Taylor series xmin=input(' Enter minimum value of the argument xmin = ') xmax=input(' Enter maximum value of the argument xmax = ') NumXValues=input(' Enter the number of x values NumXValues = ') x=linspace(xmin,xmax,NumXValues); % vector with equally spaced NumXValues values of argument x NumTerm=zeros(NumXValues,1); % vector with number of terms for convergence for k=1:NumXValues % loop over x values xx=x(k); ExactValue=sinh(xx); % exact value of sinh(x) PartialSum=0; % partial value of the series ICounter=0; % number of terms in the series while 100*abs(ExactValue-PartialSum)/ExactValue > TargetPrecision % check for %convergence ICounter=ICounter+1; % if no convergence, add one term to the series PartialSum=PartialSum+(xx^(2*ICounter-1))/factorial(2*ICounter-1); if ICounter > MaxNumTerm % check for lack of convergence sprintf('No convergence achieved after %d terms for x = %d\n',ICounter,xx) break end end NumTerm(k)=ICounter; % store the number of terms in vector NumTerm (for future % display) end plot(x,NumTerm,'b-o') % display results with solid blue line with circular symbols xlabel('x'); % label for x axis ylabel('Number of terms in Taylor series'); % label for y axis title(strcat('Precision = ',num2str(TargetPrecision,'%f'),' percent')); % title %for the plot

The output of the code is shown in Figure 1.

Figure 1. x-dependence of the number of terms needed to achieve convergence (within 0.001%) in the Taylor series expansion of sinh(x). As apparent there, an increasing number of terms are needed to capture sinh(x) accurately as x increases, although that increases in less than linear.

Problem 4. Write a simple Matlab code that, given an integer number N between 1 and 100, computes the ratio
=1 . q( N ) = iN ! i3 i =1

! i2

Output the result on the screen as User input N = Computed ratio q(N) = Key Matlab commands: input, for, sprintf Solution Code HW1_Problem1_solution.m
% This code will, given an integer number N between 1 and 100, % compute the ratio of the sum of the squares and the sum of the cubes % of the summation index "i" from 1 to N % % % % % % % ============Definition of Variables============ N = upper limit of summation i = summation index num = numerator of ratio den = denominator of ratio q = value of ratio, q(N) =============================================== % Request upper limit of summation, N % % % % run program only if N is between 1 and 100 initialize numerator for-loop to compute numerator total sum of squares over index i

N=input('Enter N: '); if (N>=1 & N<=100) num=0; for i=1:N num=num+i^2; end den=0; for i=1:N den=den+i^3; end q = num/den;

% initialize denominator % for-loop to compute denominator % total sum of cubes over index i % compute ratio, q(N)

fprintf('User input N = %i\n',N); % Repeat to user the N they entered fprintf('Computed ratio q(N) = %f\n',q); % Show the result of the calculation of q(N) else fprintf('Number is not between 1 and 100...Program stopping') end

Screen output >> HW1_Problem1_solution Enter N: 36 User input N = 36 Computed ratio q(N) = 0.036537 >> HW1_Problem1_solution Enter N: 47 User input N = 47

Computed ratio q(N) = 0.028073

Problem 5. As you probably know, the Fibonacci numbers Pi ( i = 1,2,...) are obtained by starting with 0 and 1, and then adding the last two numbers to obtain the next one. 0 1 1 2 3 5 8 13 21 34 Display the first 50 numbers on the screen and plot the ratio of two successive numbers ( Pi +1 / Pi ) for i = 2,...,50 and show graphically that it tends to a limit (sometimes referred to as the Golden Ratio). Key Matlab command: plot, title Solution Code HW1_Problem2_solution.m
% % % % This code will display the first 50 Fibonacci numbers on the screen and plot the ratio of two successive numbers (Pi+1 / Pi) for i = 2,...,50 and will show graphically that it tends to a limit (sometimes referred to as the Golden Ratio).

% ============Definition of Variables============ % i = index for Fibonacci number % ii = auxillary array for plotting % P(i) = Fibonacci number % ratio = (Pi+1 / Pi)= Fibonacci number ratio % =============================================== NumTerms=50; % number of terms in Fibonacci number series P = zeros(1,NumTerms); % initialize row matrix to contain first 50 Fibonacci numbers P(1)=0; % first element is zero P(2)=1; % second element is one for i=3:NumTerms % for-loop to find the rest of the Fibonacci numbers P(i)=P(i-1)+P(i-2); end fprintf('First %i Fibonacci numbers are: \n',NumTerms) for i=1:NumTerms % display first NumTerms numbers on the screen fprintf('P(%i)= %i\n',i,P(i)) end for i=2:NumTerms-1 % for-loop to compute ratio (Pi+1 / Pi) ratio(i) = P(i+1)/P(i); end ii = linspace(2,NumTerms,NumTerms-1); % create linear array for x-axis with same number of elements as ratio(i) plot(ii,ratio) % create plot, title, and axes title('Aaron Shinn - Fibonacci numbers - Plot of P(i+1)/P(i) versus i') xlabel('i') ylabel('P(i+1)/P(i)')

Screen output
>> HW1_Problem2_solution First 50 Fibonacci numbers are: P(1)= 0 P(2)= 1 P(3)= 1 P(4)= 2 P(5)= 3 P(6)= 5 P(7)= 8 P(8)= 13 P(9)= 21

P(10)= P(11)= P(12)= P(13)= P(14)= P(15)= P(16)= P(17)= P(18)= P(19)= P(20)= P(21)= P(22)= P(23)= P(24)= P(25)= P(26)= P(27)= P(28)= P(29)= P(30)= P(31)= P(32)= P(33)= P(34)= P(35)= P(36)= P(37)= P(38)= P(39)= P(40)= P(41)= P(42)= P(43)= P(44)= P(45)= P(46)= P(47)= P(48)= P(49)= P(50)=

34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2.971215e+09 4.807527e+09 7.778742e+09

The ratio of successive Fibonacci numbers is shown in the figure below, showing how quickly it converges to a value close to 1.6.

Ratio of successive Fibonacci numbers.

Problem 6. Create an array A( N , N ) where N being a user-defined integer between 1 and 20 (and introduced interactively), with

A( i , j) = i 2 + j . Compute and output on the screen the N eigenvalues of the matrix A.


Key Matlab commands: zeros, eig Solution Code HW1-Problem3_solution.m
% % % % % % % % % % This code will Create an array A(N,N) where N is a user-defined integer between 1 and 20 (and introduced interactively), with A(i,j)=sqrt(i^2+j) Compute and output on the screen the N eigenvalues of the matrix A. ============Definition of Variables============ N = user-defined integer between 1 and 20 i,j = indices for row and column A(i,j) = main array E = array containing the N eigenvalues of A(i,j) ===============================================

N=input('Enter N: '); % Request user-defined integer between 1 and 20 A=zeros(N,N); % initialize A if (N>=1 & N<=20) % run program only if N is between 1 and 20 for i=1:N for j=1:N A(i,j)=sqrt(i^2+j); end end E = eig(A); % compute eigenvalues of matrix A fprintf('The eigenvalues of A are: \n'); for i=1:N fprintf('E(%i)= %22.18f\n',i,E(i)) % print eigenvalues of matrix A end else fprintf('Number is not between 1 and 20...Program stopping') end

Screen output HW1_Problem3_solution Enter N: 13 The eigenvalues of A are: E(1)= 101.165320332260606051 E(2)= -3.851620710479454868 E(3)= -0.134296357411982342 E(4)= -0.007695587884377023 E(5)= -0.000406693293250423 E(6)= -0.000016839339392271 E(7)= -0.000000520079546231 E(8)= -0.000000011730021393 E(9)= -0.000000000189293712 E(10)= -0.000000000002119122 E(11)= -0.000000000000013340 E(12)= -0.000000000000001762 E(13)=

0.000000000000000168

Problem 7. Write a Matlab code that uses a Monte-Carlo method to compute the value of ! . Consider the figure made of a quarter circle (of radius 1) inscribed in a square (of size 1). The ratio of the area of region A to that of the square is given by ! / 4 . Using a random number generator, pick randomly N points within the square (defined by 0 ! x ! 1 and 0 ! y ! 1) and compute the number of times P the points fall into region A. Then plot the probability of successful hits (i.e., P/N) as a function of N for N = 1 to 10,000. Normalize your y-axis by ! / 4 and comment on your solution. Key Matlab command: rand, if Solution Code HW1_Poblem4_solution.m
% % % % % % % % % % % % % % % % %

Write a Matlab code that uses a Monte-Carlo method to compute the value of pi. Using a random number generator pick randomly N points within the square (defined by 0<=x<=1 and 0<=y<=1) and compute the number of times P the points fall into region A. Then plot the probability of successful hits (i.e., P/N) as a function of N for N = 1 to 10,000. Normalize your y-axis by pi/4. ============Definition of Variables============ N_total = maximum number of random points N = current number of random points x,y = random coordinates d = distance to random point from origin P = hit counter for hits inside circle probability = P/N N_values = values of N from 1 to N_total norm_probability = normalized probability ===============================================

N_total=10000; % total number of random points x = rand(1,N_total); % pick N_total random x-points within the square y = rand(1,N_total); % pick N_total random y-points within the square for N=1:N_total d(N)=sqrt(x(N)^2 + y(N)^2); % create array with distances to all random points end for N=1:N_total P=0; for i=1:N if (d(i)<=1) P=P+1; end end probability(N) = P/N; end % % % % % loop thru all values of random points initialize hit counter loop thru all N distances to all N random points if true then random point is inside circle counter for number of successful hits

% create array containing probability for current N % end loop thru all values of random points

N_values = [1:N_total]; % set-up x-axis array with values of N from 1 to N_total norm_probability = (probability)./(pi/4); % set-up y-axis by normalizing probability by pi/4 plot(N_values,norm_probability,b-,linewidth,2) % plot normalized probability versus N title('Aaron Shinn - Normalized Probability of Successful Hits vs. N') %set

title xlabel('N'),ylabel('Normalized Probability')

% set-up axis titles

As shown in the figure above, the Monte-Carlo approximation of ! quickly converges: after 2000 attempts, the probability of falling into the quarter circle approaches !/4. The figure below shows the initial phase of the convergence process.

Problem 8. Create a data file (called mydata.dat) with 14 data points (characterized by ( x ,y) coordinates with 0 ! x ! 10 and !5 " y " 10 . Create these data points by hand using your favorite editor (the simplest way is to use that available in Matlab to create .m files). Then write a code that (i) open the data file, (ii) read the 14 data points, (iii) uses the command polyfit to find the 4 coefficients of the 3rd-order polynomial fit that best passes among the 14 points. Output the 4 coefficients on the screen (indicating on your screen display which one corresponds to the cubic term, the quadratic term ). Then plot the 14 points (as symbols) and the polynomial fit (as solid curve). Key Matlab commands: load, polyfit, polyval, linspace Solution code
% Least square polynomial fit of 14 data points (stored in file 'prog5.dat') % % This code computes and displays the 3rd-order polynomial fit for 14 data % points stored in a file 'prog5.daa' % % read from file 'prog5.dat' % XYarray=load('prog5.dat'); NumPoints=size(XYarray,1) % number of data points % % Use polyfit command to compute the four coefficients of the 3rd order % polynomial fit Coeff=polyfit(XYarray(:,1),XYarray(:,2),3); fprintf(' Coefficients of 3rd order polynomial fit: P(1)*x^3+p(2)*x^2+P(3)*x+P(4) \n') fprintf(' P(1) = %d \n',Coeff(1)) fprintf(' P(2) = %d \n',Coeff(2)) fprintf(' P(3) = %d \n',Coeff(3)) fprintf(' P(4) = %d \n',Coeff(4)) % % display the data points and the polynomial fir using command polyval xx=linspace(min(XYarray(:,1)),max(XYarray(:,1)),100); % set 100 points for polynomial display yy=polyval(Coeff,xx); % compute y-values plot(XYarray(:,1),XYarray(:,2),'ro',xx,yy,'b-','linewidth',2) xlabel('x'); ylabel('y'); title('Philippe Geubelle - 3rd order polynomial fit of 14 data points');

Data points (File prog5.dat) 0.0 0.3 1.2 2.5 2.9 3.2 3.9 5.6 6.5 7.0 7.5 10.0 8.0 5.0 -1.0 -1.5 -1.4 -0.2 1.3 2.4 2.8 3.1

8.0 3.0 8.7 2.8 9.2 2.5 Screen output


prog5 NumPoints = 14 Coefficients of 3rd order polynomial fit P(1)*x^3+p(2)*x^2+P(3)*x+P(4) P(1) = -9.140170e-02 P(2) = 1.574714e+00 P(3) = -7.632546e+00 P(4) = 1.038157e+01

Resulting plot

3rd-order polynomial fit (solid curve) of 14 data points (shown as symbols).

Problem 9. The Taylor series expansion for cos(x) is x2 x4 x6 cos( x) = 1 ! + ! + ... 2! 4! 6! For 50 values of x equally spaced between x = 0 and x = ! / 4 , compute the number of terms N(x) needed in the Taylor series expansion to achieve a precision of 10!6 . Plot N(x) versus x and comment on your solution. Solution Code
% Taylor series expansion of cos(x) % % This code computes the number of terms N(x) needed in the Taylor % series expansion of cos(x) to achieve a given precision. % Then plot N(x) versus x. % NumXValues=50; % number of X values (equally spaced between 0 and pi/4) XValues=linspace(0,pi/4,NumXValues); % vector of X values between 0 and Pi/4 NumTerms=zeros(NumXValues,1); % solution vector with N(x) Tolerance=1.e-06; % Tolerance for i=1:NumXValues % loop over X values X=XValues(i); % current value of X CosExact=cos(X); % exact value of cos(X) SumCos=1; % Initiate Taylor series expansion at X NumTerms(i)=1; % Initiate N(x) to 1 while abs(CosExact-SumCos)>Tolerance NumTerms(i)=NumTerms(i)+1; % increment N(x) jaux=NumTerms(i)-1; % auxiliary index SumCos=SumCos+(-1)^(jaux)*(X^(2*jaux))/factorial(2*jaux); % add term to Taylor series expansion end end plot(XValues,NumTerms,'b-o','linewidth',2) % plot N(x) versus x title(' Philippe Geubelle - Taylor series expansion of cos(x)'); xlabel('X'); ylabel('N(X)');

The variation of N(x) is shown in the figure below, showing that, as x increases, the number of terms needed in the Taylor series expansion to achieve the prescribed precision increases from 1 (at x=0) to 5 (for x approaching !/4).

Variation of N(x) versus x for the Taylor series expansion of cos(x).

Problem 10. The central difference approximation of the first derivative f '( x) of a function f ( x) is f ( x + !x) " f ( x " !x) f '( x) = + O !x 2 , 2!x where !x is a small increment in x. Write a Matlab code that computes f '( 0.5) for

( )

f ( x) = sin( x) and g'(1) for g( x) = exp x 2 . A function call should be used whenever the

( )

function f or g is to be evaluated. Let us define the relative error as f 'exact ( a) # f 'numer ( a ,"x) . ! ( "x; a) = 100* f 'exact ( a) Plot on a log-log plot the !x dependence of ! ( "x; a) for the two requested derivatives for

10!8 " x " 100 . Does the slope correspond to your expectation? What happens when !x becomes very small?
Key Matlab commands: logspace, loglog, function. Solution Here is the code prog7.m for the second function g(x).
% Central difference approximation of first derivative % % This code computes the central difference approximation of the first derivative % f'(x)=(f(x+dx)-f(x-dx))/2dx % and investigates the dependence of the numerical approximation on dx % LogdxMin=-8; LogdxMax=0; NumdxValues=50; % number of dx values (equally spaced on log scale between 10^LogdxMin % and 10^LogdxMax) dxValues=logspace(LogdxMin,LogdxMax,NumdxValues); % create dx values fperror=zeros(NumdxValues,1); % solution vector with relative error on derivative xvalue=1.0; % value of x at which the derivative is to be computed fpexact=2*xvalue*exp(xvalue^2); % exact value of the derivative of sin(x) for i=1:NumdxValues % loop over X values dx=dxValues(i); % current value of X fpnumer=(func7(xvalue+dx)-func7(xvalue-dx))/(2*dx); % central difference approximation of derivative fperror(i)=100*abs((fpnumer-fpexact)/fpexact); % error end loglog(dxValues,fperror,'b-o','linewidth',2) % log-log plot of error versus dx title(' Philippe Geubelle - Central difference approximation of first derivative'); xlabel('dx'); ylabel('relative error (in %)'); grid on;

The associated subroutine func7.m is as follows:


function ff=func7(x) % function subroutine that computes the function used in problem 7 ff=exp(x^2);

The two graphs are shown below.

Central difference approximation of f(0.5) where f(x)=sin(x).

Central difference approximation of g(1) where g(x)=exp(x^2). In both cases, the slope of the error curve is 2, indicating that the central difference approximation of the first derivative is of second order (i.e., decreasing dx by a factor of 2 decreases the error on the derivative by a factor of 4). When the value of dx becomes very small (less than 10^-5), the numerical solution suffers from round-off errors, as the approximation of the derivative is obtained by the ratio of two very small numbers.

Das könnte Ihnen auch gefallen