├── Chapter1 ├── eval_exp_simple.m ├── eval_exp_tay.m ├── exp_tay.m ├── log_tay.m ├── plot_exp.m ├── plot_log.m ├── plot_sin.m ├── plot_sint.m ├── poly_even.m ├── poly_odd.m ├── polyeval.m ├── sin_tay.m ├── sint.m ├── sint_tay.m └── taylor_3d.m ├── Chapter3 ├── bisect.m ├── newton.m └── secant.m ├── Chapter4 ├── chebyshev_interp.m ├── divdif.m ├── interp.m └── ncs.m ├── Chapter5 ├── gaussint.m ├── simpson.m └── trapezoidal.m ├── Chapter6 ├── GEpivot.m ├── GS.m ├── Jacobi.m └── tridiag.m ├── Chapter7 ├── newton_sys.m └── power_method.m ├── Chapter8 ├── AB2.m ├── ODEBVP.m ├── euler_back.m ├── euler_for.m ├── eulersys.m └── trapezoidal.m ├── Chapter9 ├── Heat1.m ├── Heat2.m ├── Poisson.m └── Wave.m └── README.md /Chapter1/eval_exp_simple.m: -------------------------------------------------------------------------------- 1 | % TITLE: Evaluate Taylor polynomials for exp(x) about x = 0 2 | % 3 | % This evaluates several Taylor polynomials and their errors 4 | % for increasing degrees. The particular function being 5 | % approximated is exp(x) on [-b,b]. 6 | 7 | % Initialize 8 | b = input('Give the number b defining the interval [-b,b] '); 9 | h = b/10; 10 | x = -b:h:b; 11 | max_deg = 4; 12 | 13 | % Produce the Taylor coefficients for the function exp(x) when 14 | % expanded about the point a = 0. The coefficients are stored 15 | % in the array c, which will have length max_deg+1. 16 | c = ones(max_deg+1,1); 17 | fact = 1; 18 | for i = 1:max_deg 19 | fact = i*fact; 20 | c(i+1) = 1/fact; 21 | end 22 | 23 | % Calculate the Taylor polynomials 24 | p1 = polyeval(x,0,c,1); 25 | p2 = polyeval(x,0,c,2); 26 | p3 = polyeval(x,0,c,3); 27 | p4 = polyeval(x,0,c,4); 28 | 29 | % Calculate the errors in the Taylor polynomials 30 | true = exp(x); 31 | err1 = true-p1; 32 | err2 = true-p2; 33 | err3 = true-p3; 34 | err4 = true-p4; 35 | 36 | diary exp_taylor 37 | disp(' x exp(x) err1 err2 err3 err4') 38 | [x',true',err1',err2',err3',err4'] 39 | diary off 40 | -------------------------------------------------------------------------------- /Chapter1/eval_exp_tay.m: -------------------------------------------------------------------------------- 1 | % TITLE: Evaluate Taylor polynomials for exp(x) about x = 0 2 | % 3 | % This evaluates several Taylor polynomials and their errors 4 | % for increasing degrees. The particular function being 5 | % approximated is exp(x) on [-b,b]. 6 | 7 | % Initialize 8 | b = input('Give the number b defining the interval [-b,b] '); 9 | h = b/10; 10 | x = -b:h:b; 11 | max_deg = 4; 12 | 13 | % Produce the Taylor coefficients for the function exp(x) when 14 | % expanded about the point a = 0. The coefficients are stored 15 | % in the array c, which will have length max_deg+1. 16 | c = ones(max_deg+1,1); 17 | fact = 1; 18 | for i = 1:max_deg 19 | fact = i*fact; 20 | c(i+1) = 1/fact; 21 | end 22 | 23 | % Calculate the Taylor polynomials 24 | p1 = polyeval(x,0,c,1); 25 | p2 = polyeval(x,0,c,2); 26 | p3 = polyeval(x,0,c,3); 27 | p4 = polyeval(x,0,c,4); 28 | 29 | % Calculate the errors in the Taylor polynomials 30 | true = exp(x); 31 | err1 = true-p1; 32 | err2 = true-p2; 33 | err3 = true-p3; 34 | err4 = true-p4; 35 | 36 | diary exp_taylor 37 | disp(' x exp(x) err1 err2 err3 err4') 38 | for i=1:length(x) 39 | fprintf('%7.3f%10.3f%14.3e%14.3e%14.3e%14.3e\n',... 40 | x(i),true(i),err1(i),err2(i),err3(i),err4(i)) 41 | end 42 | diary off 43 | -------------------------------------------------------------------------------- /Chapter1/exp_tay.m: -------------------------------------------------------------------------------- 1 | function coeff=exp_tay(n); 2 | % 3 | % function coeff=exp_tay(n) 4 | % 5 | % Produce the Taylor coefficients for the function exp(x) 6 | % when expanded about the point a=0. The coefficients will 7 | % be returned in the array coeff, which will have length n+1. 8 | % 9 | coeff=ones(n+1,1); 10 | fact=1; 11 | for i=1:n 12 | fact=i*fact; 13 | coeff(i+1)=1/fact; 14 | end 15 | -------------------------------------------------------------------------------- /Chapter1/log_tay.m: -------------------------------------------------------------------------------- 1 | function coeff = log_tay(n); 2 | % 3 | % function coeff = log_tay(n) 4 | % 5 | % Produce the Taylor coefficients for the function log(x) 6 | % when expanded about the point a=1. The coefficients will 7 | % be returned in the array coeff, which will have length n+1. 8 | % 9 | coeff = zeros(n+1,1); 10 | sign = 1; 11 | for i=1:n 12 | coeff(i+1) = sign/i; 13 | sign = -sign; 14 | end 15 | -------------------------------------------------------------------------------- /Chapter1/plot_exp.m: -------------------------------------------------------------------------------- 1 | % TITLE: Plot Taylor polynomials for exp(x) about x = 0 2 | % 3 | % This plots several Taylor polynomials and their errors 4 | % for increasing degrees. The particular function being 5 | % approximated is exp(x) on [-b,b]. First we plot the 6 | % Taylor polynomials and then we plot the errors. 7 | % 8 | % Initialize 9 | b = input('Give the number b defining the interval [-b,b] '); 10 | h = b/100; 11 | x = -b:h:b; 12 | max_deg = 4; 13 | 14 | % Does the user want equal scaling? 15 | disp('The phrase "equal scaling" means the horizontal') 16 | disp('and vertical axes have the same unit length.') 17 | disp('Do you want equal scaling?') 18 | query = input('Give 0 for "no" and 1 for "yes". '); 19 | 20 | % Produce the Taylor coefficients for the function exp(x) when 21 | % expanded about the point a = 0. The coefficients are stored 22 | % in the array c, which will have length max_deg+1. 23 | c = ones(max_deg+1,1); 24 | fact = 1; 25 | for i = 1:max_deg 26 | fact = i*fact; 27 | c(i+1) = 1/fact; 28 | end 29 | 30 | % Calculate the Taylor polynomials 31 | p1 = polyeval(x,0,c,1); 32 | p2 = polyeval(x,0,c,2); 33 | p3 = polyeval(x,0,c,3); 34 | p4 = polyeval(x,0,c,4); 35 | 36 | % Calculate the errors in the Taylor polynomials 37 | true = exp(x); 38 | err1 = true-p1; 39 | err2 = true-p2; 40 | err3 = true-p3; 41 | err4 = true-p4; 42 | 43 | % Initialize for plotting the Taylor polynomials 44 | hold off 45 | clf 46 | m = min([min(p1),min(p2),min(p3),min(p4),min(true)]); 47 | if m > 0 48 | m = .9*m; 49 | else 50 | m = 1.1*m; 51 | end 52 | M = max([max(p1),max(p2),max(p3),max(p4),max(true)]); 53 | if M < 0 54 | M = .9*M; 55 | else 56 | M = 1.1*M; 57 | end 58 | axis([-b,b,m,M]) 59 | hold on 60 | 61 | % Plot the Taylor polynomials 62 | plot(x,true,'k',x,p1,'b:',x,p2,'g--',x,p3,'r-.'); 63 | title('Taylor approximations of e^x') 64 | plot([-b,b],[0,0]) 65 | plot([0 0 ],[m M/1.2]) 66 | if query == 1 67 | axis('equal') 68 | end 69 | legend('exp(x)','degree = 1','degree = 2','degree = 3',0) 70 | pause 71 | 72 | % print -deps exp2d.eps 73 | % print 74 | 75 | % Initialize for plotting the errors 76 | hold off 77 | clf 78 | m = min([min(err1),min(err2),min(err3),min(err4)]); 79 | if m > 0 80 | m = .9*m; 81 | else 82 | m = 1.1*m; 83 | end 84 | M = max([max(err1),max(err2),max(err3),max(err4)]); 85 | if M < 0 86 | M = .9*M; 87 | else 88 | M = 1.1*M; 89 | end 90 | axis([-b,b,m,M]) 91 | hold on 92 | 93 | % Plot the errors 94 | plot(x,err1,'b',x,err2,'g:',x,err3,'r--',x,err4,'c-.'); 95 | title('Errors in Taylor approximations of e^x') 96 | legend('degree = 1','degree = 2','degree = 3','degree = 4',0) 97 | hold off 98 | 99 | % print -deps experr2d.eps 100 | % pause 101 | % print 102 | -------------------------------------------------------------------------------- /Chapter1/plot_log.m: -------------------------------------------------------------------------------- 1 | % TITLE: Plot Taylor polynomials for log(x) about x = 1 2 | % 3 | % This plots several Taylor polynomials and their errors 4 | % for increasing degrees. The particular function being 5 | % approximated is log x and it is being expanded about 6 | % x = 1. The interval of approximation is [a,b] with 7 | % 0 < a < 1 and b > 1. First we plot the Taylor polynomials and 8 | % then we plot the errors. 9 | % 10 | % Initialize 11 | a = input('For the interval [a,b], give a with 0 < a < 1. '); 12 | b = input('Give b > 1 '); 13 | h = (b-a)/200; 14 | x = a:h:b; 15 | max_deg = 4; 16 | c = zeros(max_deg+1,1); 17 | sign = 1; 18 | for i = 1:max_deg 19 | c(i+1) = sign/i; 20 | sign = -sign; 21 | end 22 | 23 | % Calculate the Taylor polynomials 24 | p1 = polyeval(x,1,c,1); 25 | p2 = polyeval(x,1,c,2); 26 | p3 = polyeval(x,1,c,3); 27 | p4 = polyeval(x,1,c,4); 28 | 29 | % Calculate the errors in the Taylor polynomials 30 | true = log(x); 31 | err1 = true-p1; 32 | err2 = true-p2; 33 | err3 = true-p3; 34 | err4 = true-p4; 35 | 36 | % Initialize for plotting the Taylor polynomials 37 | hold off 38 | clf 39 | m = 1.1*min([min(p1),min(p2),min(p3),min(p4)]); 40 | M = 1.1*max([max(p1),max(p2),max(p3),max(p4)]); 41 | axis([a,b,m,M]) 42 | hold on 43 | 44 | % Plot the Taylor polynomials 45 | plot(x,true,x,p2,':',x,p3,'--',x,p4,'-.'); 46 | plot([0 b],[0 0]) 47 | plot([0 0],[m/1.1 M/1.1]) 48 | title('Taylor approximations of log(x)') 49 | text(b+3*h,0,'x') 50 | text(0,M,'y') 51 | axis('equal') 52 | legend('log(x)','degree = 2','degree = 3','degree = 4') 53 | pause 54 | 55 | % print -deps log2d.eps 56 | % print 57 | 58 | % Initialize for plotting the errors 59 | hold off 60 | clf 61 | m = 1.1*min([min(err1),min(err2),min(err3),min(err4)]); 62 | M = 1.1*max([max(err1),max(err2),max(err3),max(err4)]); 63 | axis([0,b,m,M]) 64 | hold on 65 | 66 | % Plot the errors 67 | plot(x,err1,x,err2,':',x,err3,'--',x,err4,'-.'); 68 | plot([0 b],[0 0]) 69 | plot([0 0],[m/1.2 M/1.2]) 70 | title('Errors in Taylor approximations of log(x)') 71 | text(b+3*h,0,'x') 72 | text(0,M+.05*max(M,abs(m)),'y') 73 | legend('degree = 1','degree = 2','degree = 3','degree = 4') 74 | 75 | % pause 76 | % print -deps logerr2d.eps 77 | % print 78 | -------------------------------------------------------------------------------- /Chapter1/plot_sin.m: -------------------------------------------------------------------------------- 1 | % TITLE: Plot Taylor polynomials for sin(x) about x = 0 2 | % 3 | % This plots several Taylor polynomials and their errors 4 | % for increasing degrees. The particular function being 5 | % approximated is sin(x) on [0,b], with x = 0 the point of 6 | % expansion for creating the Taylor polynomials. First 7 | % we plot the Taylor polynomials and then we plot the errors. 8 | % 9 | % Note that the Taylor polynomials in this case contain only 10 | % terms of odd degree. Such polynomials are called "odd 11 | % polynomials". 12 | % 13 | % Initialize 14 | b = input('Give the number b defining the interval [0,b] '); 15 | h = b/200; 16 | x = 0:h:b; 17 | max_deg = 7; 18 | 19 | % Produce the Taylor coefficients for the function sin(x) 20 | c = sin_tay(max_deg); 21 | 22 | % Calculate the Taylor polynomials 23 | p1 = poly_odd(x,c,1); 24 | p3 = poly_odd(x,c,3); 25 | p5 = poly_odd(x,c,5); 26 | p7 = poly_odd(x,c,7); 27 | 28 | % Calculate the errors in the Taylor polynomials 29 | true = sin(x); 30 | err1 = true-p1; 31 | err3 = true-p3; 32 | err5 = true-p5; 33 | err7 = true-p7; 34 | 35 | % Initialize for plotting the Taylor polynomials 36 | hold off 37 | clf 38 | m = 1.1*min([min(p1),min(p3),min(p5),min(p7)]); 39 | M = 1.1*max([max(p1),max(p3),max(p5),max(p7)]); 40 | axis([0,b,m,M]) 41 | hold on 42 | 43 | % Plot the Taylor polynomials 44 | plot(x,true,x,p1,':',x,p3,'--',x,p5,'-.'); 45 | title('Taylor approximations of sin(x)') 46 | plot([0,b],[0,0]) 47 | plot([0 0 ],[0 M/1.2]) 48 | axis('equal') 49 | legend('sin(x)','degree = 1','degree = 3','degree = 5') 50 | pause 51 | 52 | % print -deps sin2d.eps 53 | % print 54 | 55 | % Initialize for plotting the errors 56 | hold off 57 | clf 58 | m = 1.2*min([min(err1),min(err3),min(err5),min(err7)]); 59 | M = 1.2*max([max(err1),max(err3),max(err5),max(err7)]); 60 | axis([0,b,m,M]) 61 | hold on 62 | 63 | % Plot the errors 64 | plot(x,err1,x,err3,':',x,err5,'--',x,err7,'-.'); 65 | title('Errors in Taylor approximations of sin(x)') 66 | legend('degree = 1','degree = 3','degree = 5','degree = 7') 67 | hold off 68 | 69 | % print -deps sinerr2d.eps 70 | % pause 71 | % print 72 | -------------------------------------------------------------------------------- /Chapter1/plot_sint.m: -------------------------------------------------------------------------------- 1 | function ans = plot_sint_total 2 | 3 | % TITLE: Plot Taylor polynomials for the "sine integral" 4 | % about x = 0. 5 | % 6 | % This plots several Taylor polynomials and their errors 7 | % for increasing degrees. The particular function being 8 | % approximated is Sint(x) on [0,b], with x = 0 the point of 9 | % expansion for creating the Taylor polynomials. We plot the 10 | % Taylor polynomials for several degrees, which can be altered 11 | % by the user. Note that the function being plotted is symmetric 12 | % about x=0. 13 | % 14 | % The Taylor polynomials in this case contain only terms of even 15 | % degree. Such polynomials are called "even polynomials", and 16 | % they are symmetric about x=0. 17 | % 18 | % TO THE STUDENT: run this program for various input values of "b". 19 | % Also, change the values given in the vector "degree" given below, to 20 | % experiment with different degrees of Taylor polynomial approximations. 21 | % 22 | % Initialize 23 | b = input('Give the number b defining the interval [0,b] '); 24 | h = b/200; 25 | x = 0:h:b; 26 | max_degree = 20; 27 | % 28 | % Produce the Taylor coefficients for the "sine integral" function "sint". 29 | c = sint_tay(max_degree); 30 | % 31 | % Specify the four values of degree to be considered. They must all be even, 32 | % and they must be less than or equal to max_degree. 33 | degree=[2,4,6,8]; 34 | if max(degree) > max_degree 35 | fprintf('Some value of degree is greater than max_degree = %2.0f\n',... 36 | max_degree) 37 | return 38 | end 39 | % 40 | % Initialize the array to contain the polynomial values. Row #i is to 41 | % contain the values for the polynomial of degree=degree(i). 42 | p = zeros(4,length(x)); 43 | % 44 | % Calculate the Taylor polynomials 45 | for i=1:4 46 | p(i,:) = poly_even(x,c,degree(i)); 47 | end 48 | % 49 | % Initialize for plotting the Taylor polynomials 50 | hold off 51 | clf 52 | axis([0,b,0,1]) 53 | hold on 54 | % 55 | % Plot the Taylor polynomials 56 | plot(x,p(1,:),x,p(2,:),':',x,p(3,:),'--',x,p(4,:),'-.') 57 | plot([0,b],[0,0]) 58 | plot([0 0],[0 1]) 59 | title('Taylor approximations of Sint(x)') 60 | text(1.025*b,0,'x') 61 | text(0,1.03,'y') 62 | legend(strcat('degree = ',int2str(degree(1))),... 63 | strcat('degree = ',int2str(degree(2))),... 64 | strcat('degree = ',int2str(degree(3))),... 65 | strcat('degree = ',int2str(degree(4))),0) 66 | 67 | function coeff=sint_tay(n) 68 | % 69 | % function coeff = sint_tay(n) 70 | % 71 | % Evaluate the coefficients of the Taylor approximation of 72 | % degree n which approximates the "sine integral". The input 73 | % variable n must be an even integer. The output vector coeff 74 | % will have length m+1 where m=n/2. This is because only the 75 | % even ordered coefficients are nonzero, and this must be 76 | % considered in evaluating the associated Taylor polynomial. 77 | % 78 | m = double(int32(n/2)); 79 | if n ~= 2*m 80 | disp('Error in poly_even(x,coeff,n):') 81 | disp('The parameter n must be an even integer.') 82 | end 83 | % 84 | coeff = ones(m+1,1); 85 | sign = 1; 86 | fact = 1; 87 | % 88 | for i=2:m+1 89 | sign = -sign; 90 | d = 2*i-1; 91 | fact = fact*(d-1)*d; 92 | coeff(i) = sign/(fact*d); 93 | end 94 | 95 | function value = poly_even(x,coeff,n); 96 | % 97 | % function value = poly_even(x,coeff,n) 98 | % 99 | % Evaluate an "even" Taylor polynomial at the points 100 | % given in x, with n the degree of the polynomial. 101 | % The coefficients are to be given in coeff. It is 102 | % assumed that the numbers in coeff are are the non-zero 103 | % coefficients of the even-ordered terms in the polynomial. 104 | % The input parameter n must be an even integer. 105 | % 106 | m = double(int32(n/2)); 107 | if n ~= 2*m 108 | disp('Error in poly_even(x,coeff,n):') 109 | disp('The parameter n must be an even integer.') 110 | end 111 | % 112 | xsq = x.*x; 113 | value = coeff(m+1)*ones(size(x)); 114 | % 115 | for i = m:-1:1 116 | value = coeff(i) + xsq.*value; 117 | end 118 | -------------------------------------------------------------------------------- /Chapter1/poly_even.m: -------------------------------------------------------------------------------- 1 | function value = poly_even(x,coeff,n); 2 | % 3 | % function value = poly_even(x,coeff,n) 4 | % 5 | % Evaluate an "even" Taylor polynomial at the points 6 | % given in x, with n the degree of the polynomial. 7 | % The coefficients are to be given in coeff. It is 8 | % assumed that the numbers in coeff are are the non-zero 9 | % coefficients of the even-ordered terms in the polynomial. 10 | % The input parameter n must be an even integer. 11 | % 12 | m = ceil(n/2); 13 | if n ~= 2*m 14 | disp('Error in poly_even(x,coeff,n):') 15 | disp('The parameter n must be an even integer.') 16 | return 17 | end 18 | % 19 | xsq = x.*x; 20 | value = coeff(m+1)*ones(size(x)); 21 | % 22 | for i = m:-1:1 23 | value = coeff(i) + xsq.*value; 24 | end 25 | -------------------------------------------------------------------------------- /Chapter1/poly_odd.m: -------------------------------------------------------------------------------- 1 | function value=poly_odd(x,coeff,n); 2 | % 3 | % function value=poly_odd(x,coeff,n) 4 | % 5 | % Evaluate an "odd" Taylor polynomial at the points given in x, 6 | % with n the degree of the polynomial. The coefficients are to 7 | % be given in coeff. It is assumed that the numbers in coeff are 8 | % are the coefficients of the odd-ordered terms in the polynomial. 9 | % 10 | m=ceil(n/2); 11 | if n~=2*m-1 12 | 'Error in poly_odd: the degree n must be an odd integer.' 13 | return 14 | end 15 | xsq = x.*x; 16 | value=coeff(m)*ones(size(x)); 17 | for i=m-1:-1:1 18 | value = coeff(i) + xsq.*value; 19 | end 20 | value=x.*value; 21 | -------------------------------------------------------------------------------- /Chapter1/polyeval.m: -------------------------------------------------------------------------------- 1 | function value=polyeval(x,alpha,coeff,n); 2 | % 3 | % function value=polyeval(x,coeff,n) 4 | % 5 | % Evaluate a Taylor polynomial at the points given in x, with 6 | % alpha the point of expansion of the Taylor polynomial, and 7 | % with n the degree of the polynomial. The coefficients are to 8 | % be given in coeff; and it is assumed there are n+1 entries in 9 | % coeff with coeff(1) the constant term in the polynomial 10 | % 11 | value=coeff(n+1)*ones(size(x)); 12 | z=x-alpha; 13 | for i=n:-1:1 14 | value = coeff(i) + z.*value; 15 | end 16 | -------------------------------------------------------------------------------- /Chapter1/sin_tay.m: -------------------------------------------------------------------------------- 1 | function coeff=sin_tay(n) 2 | % 3 | % function coeff=sin_tay(n) 4 | % 5 | % Evaluate the coefficients of the Taylor approximation of 6 | % degree n which approximates the sine function. The input 7 | % variable n must be an odd integer. The output vector coeff 8 | % will have length m where n=2m-1. This is because only the 9 | % odd ordered coefficients are nonzero, and this must be 10 | % considered in evaluating the associated Taylor polynomial. 11 | % 12 | m = ceil(n/2); 13 | if n ~= 2*m-1 14 | 'Error in sin_tay(n): the variable n must be an odd integer.' 15 | end 16 | 17 | coeff=ones(m,1); 18 | sign = 1; 19 | fact = 1; 20 | 21 | for i=2:m 22 | sign = -sign; 23 | fact = fact*(2*i-2)*(2*i-1); 24 | coeff(i) = sign/fact; 25 | end 26 | -------------------------------------------------------------------------------- /Chapter1/sint.m: -------------------------------------------------------------------------------- 1 | function value = sint(x) 2 | % 3 | % This evaluates an approximation to 4 | % 5 | % 1 x 1 6 | % Sint(X) = - INTEGRAL - Sin(t)*dt 7 | % x 0 t 8 | % 9 | % For -1 .LE. x .LE. 1. the approximation is the 10 | % degree 8 Taylor polynomial for Sint(x). Its 11 | % maximum error is 5.0E-9, provided the computer 12 | % arithmetic allows an error of that size. 13 | % 14 | 15 | coeff = [1, -1/18, 1/600, -1/35280, 1/3265920]; 16 | degree = length(coeff)-1; 17 | 18 | u = x.*x; 19 | 20 | value = coeff(degree+1)*ones(size(x)); 21 | 22 | for j=degree:-1:1; 23 | value = coeff(j) + u.*value; 24 | end 25 | 26 | -------------------------------------------------------------------------------- /Chapter1/sint_tay.m: -------------------------------------------------------------------------------- 1 | function coeff=sint_tay(n) 2 | % 3 | % function coeff = sint_tay(n) 4 | % 5 | % Evaluate the coefficients of the Taylor approximation of 6 | % degree n which approximates the "sine integral". The input 7 | % variable n must be an even integer. The output vector coeff 8 | % will have length m+1 where m=n/2. This is because only the 9 | % even ordered coefficients are nonzero, and this must be 10 | % considered in evaluating the associated Taylor polynomial. 11 | % 12 | m = double(int32(n/2)); 13 | if n ~= 2*m 14 | disp('Error in poly_even(x,coeff,n):') 15 | disp('The parameter n must be an even integer.') 16 | return 17 | end 18 | % 19 | coeff = ones(m+1,1); 20 | sign = 1; 21 | fact = 1; 22 | % 23 | for i=2:m+1 24 | sign = -sign; 25 | d = 2*i-1; 26 | fact = fact*(d-1)*d; 27 | coeff(i) = sign/(fact*d); 28 | end 29 | -------------------------------------------------------------------------------- /Chapter1/taylor_3d.m: -------------------------------------------------------------------------------- 1 | % Title: Plot a 3D graph of variation in a Taylor series approximation 2 | % as the degree varies. This program is for log(x) about x=1. 3 | 4 | % This produces a surface plot to show the function values of a 5 | % Taylor polynomial approximation for increasing values of the 6 | % degree of the approximation. It also shows the values of the 7 | % errors for increasing degrees. 8 | 9 | % Initialize 10 | max_deg=10; % Set the maximum degree. 11 | c=log_tay(max_deg); % Call appropriate generator of Taylor coefficients. 12 | 13 | % Do the Taylor series calculation over [a,b]. 14 | a=.1; b=2; step=.01; 15 | x=a:step:b; % Generate values of independent variable. 16 | L=length(x); 17 | 18 | % Set up the z-values for the 3D-plot. 19 | z=zeros(max_deg+1,L); % Set up array z. 20 | alpha=1; % Point of expansion. 21 | for n=1:max_deg 22 | z(n,:)=polyeval(x,alpha,c,n); 23 | end 24 | z(max_deg+1,:)=log(x); %Set true values of function. 25 | 26 | % Set up xy-grid points 27 | y=1:max_deg+1; 28 | [X,Y]=meshgrid(x,y); 29 | 30 | % Plot the function values. 31 | mesh(X,Y,z),grid; 32 | title('Graphs of Taylor polynomial for log(x)') %Set title. 33 | xlabel('The variable x') 34 | ylabel('The degree n') 35 | pause 36 | 37 | % print 38 | % print -deps log3d.eps 39 | 40 | % Set up grid values and z-values for 3D-plotting of errors. 41 | y=1:max_deg; 42 | [X,Y]=meshgrid(x,y); 43 | true=log(x); 44 | err=zeros(max_deg,L); 45 | for n=1:max_deg 46 | err(n,:)=z(n,:)-true; 47 | end 48 | 49 | % Plot the error values. 50 | mesh(X,Y,err),grid; 51 | title('Errors in Taylor polynomial for log(x)') %Set title. 52 | xlabel('The variable x') 53 | ylabel('The degree n') 54 | 55 | %print 56 | %print -deps logerr3d.eps 57 | -------------------------------------------------------------------------------- /Chapter3/bisect.m: -------------------------------------------------------------------------------- 1 | function root=bisect(a0,b0,ep,max_iterate,index_f) 2 | % 3 | % function bisect(a0,b0,ep,max_iterate,index_f) 4 | % 5 | % This is the bisection method for solving an equation f(x)=0. 6 | % 7 | % The function f is defined below by the user. The function f is 8 | % to be continuous on the interval [a0,b0], and it is to be of 9 | % opposite signs at a0 and b0. The quantity ep is the error 10 | % tolerance. The routine guarantees this as an error bound 11 | % provided: (1) the restrictions on the initial interval are 12 | % correct, and (2) ep is not too small when the machine epsilon 13 | % is taken into account. Most of these conditions are not 14 | % checked in the program! The parameter max_iterate is an upper 15 | % limit on the number of iterates to be computed. 16 | % 17 | % For the given function f(x), an example of a calling sequence 18 | % might be the following: 19 | % root = bisect(1,1.5,1.0E-6,10,1) 20 | % The parameter index_f specifies the function to be used. 21 | % 22 | % The following will print out for each iteration the values of 23 | % count, a, b, c, f(c), (b-a)/2 24 | % with c the current iterate and (b-a)/2 the error bound for c. 25 | % The variable count is the index of the current interate. Tap 26 | % the carriage return to continue with the iteration. 27 | 28 | if a0 >= b0 29 | disp('a0 < b0 is not true. Stop!') 30 | return 31 | end 32 | 33 | format short e 34 | a = a0; b = b0; 35 | fa = f(a,index_f); fb = f(b,index_f); 36 | 37 | if sign(fa)*sign(fb) > 0 38 | disp('f(a0) and f(b0) are of the same sign. Stop!') 39 | return 40 | end 41 | 42 | c = (a+b)/2; 43 | it_count = 0; 44 | while b-c > ep & it_count < max_iterate 45 | it_count = it_count + 1; 46 | fc = f(c,index_f); 47 | % Internal print of bisection method. Tap the carriage 48 | % return key to continue the computation. 49 | iteration = [it_count a b c fc b-c] 50 | if sign(fb)*sign(fc) <= 0 51 | a = c; 52 | fa = fc; 53 | else 54 | b = c; 55 | fb = fc; 56 | end 57 | c = (a+b)/2; 58 | pause 59 | end 60 | 61 | format long 62 | root = c 63 | format short e 64 | error_bound = b-c 65 | format short 66 | it_count 67 | 68 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 69 | function value = f(x,index) 70 | 71 | % function to define equation for rootfinding problem. 72 | 73 | switch index 74 | case 1 75 | value = x.^6 - x - 1; 76 | case 2 77 | value = x - exp(-x); 78 | end 79 | 80 | -------------------------------------------------------------------------------- /Chapter3/newton.m: -------------------------------------------------------------------------------- 1 | function root = newton(x0,error_bd,max_iterate,index_f) 2 | % 3 | % function newton(x0,error_bd,max_iterate,index_f) 4 | % 5 | % This is Newton's method for solving an equation f(x) = 0. 6 | % 7 | % The functions f(x) and deriv_f(x) are given below. 8 | % The parameter error_bd is used in the error test for the 9 | % accuracy of each iterate. The parameter max_iterate 10 | % is an upper limit on the number of iterates to be 11 | % computed. An initial guess x0 must also be given. 12 | % 13 | % For the given function f(x), an example of a calling sequence 14 | % might be the following: 15 | % root = newton(1,1.0E-12,10,1) 16 | % The parameter index_f specifies the function to be used. 17 | % 18 | % The program prints the iteration values 19 | % iterate_number, x, f(x), deriv_f(x), error 20 | % The value of x is the most current initial guess, called 21 | % previous_iterate here, and it is updated with each iteration. 22 | % The value of error is 23 | % error = newly_computed_iterate - previous_iterate 24 | % and it is an estimated error for previous_iterate. 25 | % Tap the carriage return to continue with the iteration. 26 | 27 | format short e 28 | error = 1; 29 | it_count = 0; 30 | while abs(error) > error_bd & it_count <= max_iterate 31 | fx = f(x0,index_f); 32 | dfx = deriv_f(x0,index_f); 33 | if dfx == 0 34 | disp('The derivative is zero. Stop') 35 | return 36 | end 37 | x1 = x0 - fx/dfx; 38 | error = x1 - x0; 39 | % Internal print of newton method. Tap the carriage 40 | % return key to continue the computation. 41 | iteration = [it_count x0 fx dfx error] 42 | pause 43 | x0 = x1; 44 | it_count = it_count + 1; 45 | end 46 | 47 | if it_count > max_iterate 48 | disp('The number of iterates calculated exceeded') 49 | disp('max_iterate. An accurate root was not') 50 | disp('calculated.') 51 | else 52 | format long 53 | root = x1 54 | format short e 55 | error 56 | format short 57 | it_count 58 | end 59 | 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | function value = f(x,index) 62 | 63 | % function to define equation for rootfinding problem. 64 | 65 | switch index 66 | case 1 67 | value = x.^6 - x - 1; 68 | case 2 69 | value = x - exp(-x); 70 | end 71 | 72 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 73 | function value = deriv_f(x,index) 74 | 75 | % Derivative of function defining equation for rootfinding 76 | % problem. 77 | 78 | switch index 79 | case 1 80 | value = 6*x.^5 - 1; 81 | case 2 82 | value = 1 + exp(-x); 83 | end 84 | -------------------------------------------------------------------------------- /Chapter3/secant.m: -------------------------------------------------------------------------------- 1 | 2 | function root = secant(x0,x1,error_bd,max_iterate,index_f) 3 | % 4 | % function secant(x0,x1,error_bd,max_iterate,index_f) 5 | % 6 | % This implements the secant method for solving an 7 | % equation f(x) = 0. The function f(x) is given below. 8 | % 9 | % The parameter error_bd is used in the error test for the 10 | % accuracy of each iterate. The parameter max_iterate is an 11 | % upper limit on the number of iterates to be computed. Two 12 | % initial guesses, x0 and x1, must also be given. 13 | % 14 | % For the given function f(x), an example of a calling sequence 15 | % might be the following: 16 | % root = secant(x0,x1,1.0E-12,10,1) 17 | % The parameter index_f specifies the function to be used. 18 | % 19 | % The program prints the iteration values 20 | % iterate_number, x, f(x), error 21 | % The value of x is the most current initial guess, called 22 | % previous_iterate here, and it is updated with each iteration. 23 | % The value of error is 24 | % error = newly_computed_iterate - previous_iterate 25 | % and it is an estimated error for previous_iterate. 26 | % Tap the carriage return to continue with the iteration. 27 | 28 | format short e 29 | error = 1; 30 | fx0 = f(x0,index_f); 31 | it_count = 0; 32 | iteration = [it_count x0 fx0] 33 | while abs(error) > error_bd & it_count <= max_iterate 34 | it_count = it_count + 1; 35 | fx1 = f(x1,index_f); 36 | if fx1 - fx0 == 0 37 | disp('f(x1) = f(x0); Division by zero; Stop') 38 | return 39 | end 40 | x2 = x1 - fx1*(x1-x0)/(fx1-fx0); 41 | error = x2 - x1; 42 | % Internal print of secant method. Tap the carriage 43 | % return key to continue the computation. 44 | iteration = [it_count x1 fx1 error] 45 | pause 46 | x0 = x1; 47 | x1 = x2; 48 | fx0 = fx1; 49 | end 50 | 51 | if it_count > max_iterate 52 | disp('The number of iterates calculated exceeded') 53 | disp('max_iterate. An accurate root was not') 54 | disp('calculated.') 55 | else 56 | format long 57 | root = x2 58 | format short e 59 | error 60 | format short 61 | it_count 62 | end 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | function value = f(x,index) 66 | 67 | % function to define equation for rootfinding problem. 68 | 69 | switch index 70 | case 1 71 | value = x.^6 - x - 1; 72 | case 2 73 | value = x - exp(-x); 74 | end 75 | 76 | -------------------------------------------------------------------------------- /Chapter4/chebyshev_interp.m: -------------------------------------------------------------------------------- 1 | function [nodes, fcn_values, div_diff_fcn] = chebyshev_interp(n) 2 | 3 | % This creates an interpolant of order n to the function 4 | % fcn(x) on [-1,1], which is given below as a function 5 | % subprogram. The nodes are the Chebyshev zeroes of the 6 | % degree n+1 Chebyshev polynomial on [-1,1]. The program 7 | % gives two plots: first the true function and its 8 | % interpolant, and second, the error in the interpolation. 9 | 10 | % Create the nodes and associated divided differences. 11 | h = pi/(2*(n+1)); 12 | nodes = cos(h*[1:2:2*n+1]); 13 | fcn_values = fcn(nodes); 14 | div_diff_fcn = divdif(nodes,fcn_values); 15 | 16 | % Create the points at which the functions are to be 17 | % graphed. 18 | x_eval = -1:.002:1; 19 | true_fcn = fcn(x_eval); 20 | y_eval = interp(nodes,div_diff_fcn,x_eval); 21 | 22 | % Create the graph of the function and its interpolant. 23 | m = min([min(true_fcn),min(y_eval)]); 24 | if m > 0 25 | m = .9*m; 26 | else 27 | m = 1.1*m; 28 | end 29 | M = max([max(true_fcn),max(y_eval)]); 30 | if M < 0 31 | M = .9*M; 32 | else 33 | M = 1.1*M; 34 | end 35 | axis([-1.1,1.1,m,M]) 36 | hold on 37 | plot(x_eval,true_fcn,'r','LineWidth',1) 38 | plot(x_eval,y_eval,':') 39 | legend('True function','Interpolant',0) 40 | hold on 41 | plot(nodes,fcn_values,'.','MarkerSize',6) 42 | hold off 43 | 44 | pause 45 | clf 46 | 47 | % Create the window for the graph of the error. 48 | error = true_fcn - y_eval; 49 | M = max(error); 50 | if M < 0 51 | M = .9*M; 52 | else 53 | M = 1.1*M; 54 | end 55 | m = min(error); 56 | if m > 0 57 | m = .9*m; 58 | else 59 | m = 1.1*m; 60 | end 61 | axis([-1.1,1.1,m,M]) 62 | hold on 63 | 64 | % Create the graph of the error in the interpolant. 65 | plot(x_eval,error,'r','LineWidth',1) 66 | hold off 67 | 68 | % Print the maximum error. 69 | disp(['maximum error = ',num2str(max(abs(error)))]) 70 | 71 | function fval = fcn(x) 72 | 73 | fval = exp(x); 74 | 75 | function p_eval = interp(x_nodes,divdif_y,x_eval) 76 | % 77 | % This is a function 78 | % p_eval = interp(x_nodes,divdif_y,x_eval) 79 | % It calculates the Newton divided difference form of 80 | % the interpolation polynomial of degree m-1, where the 81 | % nodes are given in x_nodes, m is the length of x_nodes, 82 | % and the divided differences are given in divdif_y. The 83 | % points at which the interpolation is to be carried out 84 | % are given in x_eval; and on exit, p_eval contains the 85 | % corresponding values of the interpolation polynomial. 86 | % 87 | m = length(x_nodes); 88 | p_eval = divdif_y(m)*ones(size(x_eval)); 89 | for i=m-1:-1:1 90 | p_eval = divdif_y(i) + (x_eval - x_nodes(i)).*p_eval; 91 | end 92 | 93 | function divdif_y = divdif(x_nodes,y_values) 94 | % 95 | % This is a function 96 | % divdif_y = divdif(x_nodes,y_values) 97 | % It calculates the divided differences of the function 98 | % values given in the vector y_values, which are the values of 99 | % some function f(x) at the nodes given in x_nodes. On exit, 100 | % divdif_y(i) = f[x_1,...,x_i], i=1,...,m 101 | % with m the length of x_nodes. The input values x_nodes and 102 | % y_values are not changed by this program. 103 | % 104 | divdif_y = y_values; 105 | m = length(x_nodes); 106 | for i=2:m 107 | for j=m:-1:i 108 | divdif_y(j) = (divdif_y(j)-divdif_y(j-1)) ... 109 | /(x_nodes(j)-x_nodes(j-i+1)); 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /Chapter4/divdif.m: -------------------------------------------------------------------------------- 1 | function divdif_y = divdif(x_nodes,y_values) 2 | % 3 | % This is a function 4 | % divdif_y = divdif(x_nodes,y_values) 5 | % It calculates the divided differences of the function 6 | % values given in the vector y_values, which are the values of 7 | % some function f(x) at the nodes given in x_nodes. On exit, 8 | % divdif_y(i) = f[x_1,...,x_i], i=1,...,m 9 | % with m the length of x_nodes. The input values x_nodes and 10 | % y_values are not changed by this program. 11 | % 12 | divdif_y = y_values; 13 | m = length(x_nodes); 14 | for i=2:m 15 | for j=m:-1:i 16 | divdif_y(j) = (divdif_y(j)-divdif_y(j-1)) ... 17 | /(x_nodes(j)-x_nodes(j-i+1)); 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /Chapter4/interp.m: -------------------------------------------------------------------------------- 1 | function p_eval = interp(x_nodes,divdif_y,x_eval) 2 | % 3 | % This is a function 4 | % p_eval = interp(x_nodes,divdif_y,x_eval) 5 | % It calculates the Newton divided difference form of 6 | % the interpolation polynomial of degree m-1, where the 7 | % nodes are given in x_nodes, m is the length of x_nodes, 8 | % and the divided differences are given in divdif_y. The 9 | % points at which the interpolation is to be carried out 10 | % are given in x_eval; and on exit, p_eval contains the 11 | % corresponding values of the interpolation polynomial. 12 | % 13 | m = length(x_nodes); 14 | p_eval = divdif_y(m)*ones(size(x_eval)); 15 | for i=m-1:-1:1 16 | p_eval = divdif_y(i) + (x_eval - x_nodes(i)).*p_eval; 17 | end 18 | -------------------------------------------------------------------------------- /Chapter4/ncs.m: -------------------------------------------------------------------------------- 1 | function y_eval = ncs(x_nodes,y_nodes,x_eval) 2 | 3 | m=length(x_nodes); 4 | n=m-2; 5 | a=zeros(1,n); b=zeros(1,n); c=zeros(1,n); f=zeros(1,n); 6 | for i=1:n 7 | b(i)=(x_nodes(i+2)-x_nodes(i))/3; 8 | end 9 | for i=2:n 10 | a(i)=(x_nodes(i+1)-x_nodes(i))/6; 11 | end 12 | for i=1:n-1 13 | c(i)=(x_nodes(i+2)-x_nodes(i+1))/6; 14 | end 15 | for i=1:n 16 | f(i)=(y_nodes(i+2)-y_nodes(i+1))/(x_nodes(i+2)-x_nodes(i+1)) ... 17 | -(y_nodes(i+1)-y_nodes(i))/(x_nodes(i+1)-x_nodes(i)); 18 | end 19 | 20 | [soln, alpha, beta, ier] = tridiag(a,b,c,f,n,0); 21 | 22 | M=zeros(m); 23 | M(2:m-1)=soln; 24 | 25 | len_x=length(x_eval); 26 | for i=1:len_x 27 | x=x_eval(i); 28 | for j=2:m 29 | if x_nodes(j-1) <= x & x <= x_nodes(j) 30 | y_eval(i)=(M(j-1)*(x_nodes(j)-x)^3+M(j)*(x-x_nodes(j-1))^3)/(6*(x_nodes(j)-x_nodes(j-1))) ... 31 | +(y_nodes(j-1)*(x_nodes(j)-x)+y_nodes(j)*(x-x_nodes(j-1)))/(x_nodes(j)-x_nodes(j-1)) ... 32 | -(x_nodes(j)-x_nodes(j-1))*(M(j-1)*(x_nodes(j)-x)+M(j)*(x-x_nodes(j-1)))/6; 33 | end 34 | end 35 | end 36 | 37 | function [x, alpha, beta, ier] = tridiag(a,b,c,f,n,iflag) 38 | 39 | % function [x, alpha, beta, ier] = tridiag(a,b,c,f,n,iflag) 40 | % 41 | % Solve a tridiagonal linear system M*x=f 42 | % 43 | % INPUT: 44 | % The order of the linear system is given in n. 45 | % The subdiagonal, diagonal, and superdiagonal of M are given 46 | % by the arrays a,b,c, respectively. More precisely, 47 | % M(i,i-1) = a(i), i=2,...,n 48 | % M(i,i) = b(i), i=1,...,n 49 | % M(i,i+1) = c(i), i=1,...,n-1 50 | % iflag=0 means that the original matrix M is given as specified above. 51 | % iflag=1 means that the LU factorization of M is already known and is 52 | % stored in a,b,c. This will have been accomplished by a previous call 53 | % to this routine. In that case, the vectors alpha and beta should 54 | % have been substituted for a and b in the calling sequence. 55 | % 56 | % OUTPUT: 57 | % Upon exit, the LU factorization of M is already known and is stored 58 | % in alpha,beta,c. The solution x is given as well. 59 | % ier=0 means the program was completed satisfactorily. 60 | % ier=1 means that a zero pivot element was encountered and the 61 | % solution process was abandoned. 62 | 63 | a(1) = 0; 64 | if iflag == 0 65 | % Compute LU factorization of matrix M. 66 | for j=2:n 67 | if b(j-1) == 0 68 | ier = 1; 69 | return 70 | end 71 | a(j) = a(j)/b(j-1); 72 | b(j) = b(j) - a(j)*c(j-1); 73 | end 74 | if b(n) == 0 75 | ier = 1; 76 | return 77 | end 78 | end 79 | 80 | % Compute solution x to M*x = f. 81 | % Do forward substitution to solve lower triangular system. 82 | for j=2:n 83 | f(j) = f(j) - a(j)*f(j-1); 84 | end 85 | 86 | % Do backward substitution to solve upper triangular system. 87 | f(n) = f(n)/b(n); 88 | for j=n-1:-1:1 89 | f(j) = (f(j) - c(j)*f(j+1))/b(j); 90 | end 91 | 92 | % Set output variables. 93 | ier = 0; 94 | x = f; 95 | alpha = a; beta = b; 96 | -------------------------------------------------------------------------------- /Chapter5/gaussint.m: -------------------------------------------------------------------------------- 1 | function [val,bp,wf]=gaussint(a,b,n,index_f) 2 | 3 | % [val,bp,wf]=gaussint(fun,a,b,n) integrates 4 | % a function from a to b using an n-point 5 | % Gauss rule which is exact for a polynomial 6 | % of degree 2*n-1. Concepts on page 93 of 7 | % 'Methods of Numerical Integration' by 8 | % Philip Davis and Philip Rabinowitz yield 9 | % the base points and weight factors. 10 | % 11 | % a,b - integration limits 12 | % n - order of formula (default is 20) 13 | % val - value of the integral 14 | % bp,wf - Gauss base points and weight factors on [-1,1] 15 | % index_f - index of function to be integrated. 16 | 17 | if nargin < 4, n=20; end 18 | u=(1:n-1)./sqrt((2*(1:n-1)).^2-1); 19 | [vc,bp]=eig(diag(u,-1)+diag(u,1)); 20 | [bp,k]=sort(diag(bp)); 21 | wf=2*vc(1,k)'.^2; 22 | x=(a+b)/2+((b-a)/2)*bp; 23 | f=fcn(x,index_f)*(b-a)/2; 24 | val=wf(:)'*f(:); 25 | 26 | 27 | function f_value = fcn(x,index) 28 | % 29 | % This defines the integrand. 30 | 31 | switch index 32 | case 1 33 | f_value = exp(-x.^2); 34 | case 2 35 | f_value = 1 ./(1+x.^2); 36 | case 3 37 | f_value = 1 ./(2+sin(x)); 38 | case 4 39 | f_value = exp(cos(x)); 40 | end 41 | -------------------------------------------------------------------------------- /Chapter5/simpson.m: -------------------------------------------------------------------------------- 1 | function [integral,difference,ratio]=simpson(a,b,n0,index_f) 2 | % 3 | % function [integral,difference,ratio]=simpson(a,b,n0,index_f) 4 | % 5 | % This uses Simpson's rule with n subdivisions to integrate the function 6 | % f over the interval [a,b]. The values of n used are 7 | % n = n0,2*n0,4*n0,...,256*n0 8 | % The value of n0 MUST be nonzero. 9 | % The corresponding numerical integrals are returned in the vector 10 | % integral. The differences of successive numerical integrals are 11 | % returned in the vector difference: 12 | % difference(i) = integral(i)-integral(i-1), i=2,...,9 13 | % The entries in ratio give the rate of decrease in these 14 | % differences. 15 | % 16 | % In using this program, define the integrand using the 17 | % function given below. The parameter index_f allows the user 18 | % to do calculations with multiple integrands. 19 | 20 | % Initialize output vectors. 21 | integral = zeros(9,1); 22 | difference = zeros(9,1); 23 | ratio = zeros(9,1); 24 | 25 | % Initialize for Simpson integration. 26 | sumend = f(a,index_f) + f(b,index_f); 27 | sumodd = 0; 28 | sumeven = 0; 29 | 30 | % Initialize for case of n0 > 2. 31 | if(n0 > 2) 32 | h = (b-a)/n0; 33 | for i=2:2:n0-2 34 | sumeven = sumeven + f(a+i*h,index_f); 35 | end 36 | end 37 | 38 | % Calculate the numerical integrals, doing each 39 | % by appropriately modifying the preceding case. 40 | for i=1:9 41 | n = (n0)*(2^(i-1)); 42 | h = (b-a)/n; 43 | sumeven = sumeven + sumodd; 44 | sumodd = 0; 45 | for k=1:2:n-1 46 | sumodd = sumodd + f(a+k*h,index_f); 47 | end 48 | integral(i) = h*(sumend + 4*sumodd + 2*sumeven)/3; 49 | end 50 | 51 | % Calculate the differences of the successive 52 | % Simpson rule integrals and the ratio 53 | % of decrease in these differences. 54 | difference(2:9)=integral(2:9)-integral(1:8); 55 | ratio(3:9)=difference(2:8)./difference(3:9); 56 | 57 | function f_value = f(x,index) 58 | % 59 | % This defines the integrand. 60 | 61 | switch index 62 | case 1 63 | f_value = exp(-x.^2); 64 | case 2 65 | f_value = 1 ./(1+x.^2); 66 | case 3 67 | f_value = 1 ./(2+sin(x)); 68 | case 4 69 | f_value = exp(cos(x)); 70 | end 71 | -------------------------------------------------------------------------------- /Chapter5/trapezoidal.m: -------------------------------------------------------------------------------- 1 | function [integral,difference,ratio]=trapezoidal(a,b,n0,index_f) 2 | % 3 | % function [integral,difference,ratio]=trapezoidal(a,b,n0,index_f) 4 | % 5 | % This uses the trapezoidal rule with n subdivisions to 6 | % integrate the function f over the interval [a,b]. The 7 | % values of n used are 8 | % n = n0,2*n0,4*n0,...,256*n0 9 | % The corresponding numerical integrals are returned in the 10 | % vector integral. The differences of successive numerical 11 | % integrals are returned in the vector difference: 12 | % difference(i) = integral(i)-integral(i-1), i=2,...,9 13 | % The entries in ratio give the rate of decrease in these 14 | % differences. 15 | % 16 | % In using this program, define the integrand using the 17 | % function given below. The parameter index_f allows the user 18 | % to do calculations with multiple integrands. 19 | 20 | % Initialize output vectors. 21 | integral = zeros(9,1); 22 | difference = zeros(9,1); 23 | ratio = zeros(9,1); 24 | 25 | % Initialize for trapezoidal rule. 26 | sumend = (f(a,index_f) +f(b,index_f))/2; 27 | sum = 0; 28 | 29 | % Initialize for case of n0 > 2. 30 | if(n0 > 2) 31 | h = (b-a)/n0; 32 | for i=2:2:n0-2 33 | sum = sum + f(a+i*h,index_f); 34 | end 35 | end 36 | 37 | % Calculate the numerical integrals, doing each 38 | % by appropriately modifying the preceding case. 39 | for i=1:9 40 | n = n0*2^(i-1); 41 | h = (b-a)/n; 42 | for k=1:2:n-1 43 | sum = sum + f(a+k*h,index_f); 44 | end 45 | integral(i) = h*(sumend + sum); 46 | end 47 | 48 | % Calculate the differences of the successive 49 | % trapezoidal rule integrals and the ratio 50 | % of decrease in these differences. 51 | difference(2:9)=integral(2:9)-integral(1:8); 52 | ratio(3:9)=difference(2:8)./difference(3:9); 53 | 54 | function f_value = f(x,index) 55 | % 56 | % This defines the integrand. 57 | 58 | switch index 59 | case 1 60 | f_value = exp(-x.^2); 61 | case 2 62 | f_value = 1 ./(1+x.^2); 63 | case 3 64 | f_value = 1 ./(2+sin(x)); 65 | case 4 66 | f_value = exp(cos(x)); 67 | end 68 | -------------------------------------------------------------------------------- /Chapter6/GEpivot.m: -------------------------------------------------------------------------------- 1 | function [x,lu,piv] = GEpivot(A,b) 2 | % 3 | % function [x,lu,piv] = GEpivot(A,b) 4 | % 5 | % This program employs the Gaussian elimination method with partial 6 | % pivoting to solve the linear system Ax=b. 7 | % 8 | % Input 9 | % A: coefficient square matrix 10 | % b: right side column vector 11 | % 12 | % Output 13 | % x: solution vector 14 | % lu: a matrix whose upper triangular part is the upper 15 | % triangular matrix resulting from the Gaussian elimination 16 | % with partial pivoting, and whose strictly lower triangular 17 | % part stores the multipliers. In other words, it stores 18 | % the LU factorization of the matrix A with row permutations 19 | % determined by the pivoting vector piv. 20 | % piv: a pivoting vector recording the row permutations. 21 | 22 | % check the order of the matrix and the size of the vector 23 | [m,n] = size(A); 24 | if m ~= n 25 | error('The matrix is not square.') 26 | end 27 | m = length(b); 28 | if m ~= n 29 | error('The matrix and the vector do not match in size.') 30 | end 31 | 32 | % initialization of the pivoting vector 33 | piv = (1:n)'; 34 | 35 | % elimination step 36 | for k = 1:n-1 37 | % Find the maximal element in the pivot column, below the 38 | % pivot position, along with the index of that maximal element. 39 | 40 | [col_max index] = max(abs(A(k:n,k))); 41 | index = index + k-1; 42 | 43 | if index ~= k 44 | % Switch rows k and index, in columns k thru n. Do similarly 45 | % for the right-hand side b. 46 | 47 | tempA = A(k,k:n); 48 | A(k,k:n) = A(index,k:n); 49 | A(index,k:n) = tempA; 50 | 51 | tempb = b(k); 52 | b(k) = b(index); 53 | b(index) = tempb; 54 | 55 | temp = piv(k); 56 | piv(k) = piv(index); 57 | piv(index) = temp; 58 | end 59 | 60 | % Form the needed multipliers and store them into the pivot 61 | % column, below the diagonal. 62 | A(k+1:n,k) = A(k+1:n,k)/A(k,k); 63 | 64 | % Carry out the elimination step, first modifying the matrix, 65 | % and then modifying the right-hand side. 66 | for i = k+1:n 67 | A(i,k+1:n) = A(i,k+1:n) - A(i,k)*A(k,k+1:n); 68 | end 69 | b(k+1:n) = b(k+1:n) - A(k+1:n,k)*b(k); 70 | end 71 | 72 | % Solve the upper triangular linear system. 73 | x = zeros(n,1); 74 | x(n) = b(n)/A(n,n); 75 | for i = n-1:-1:1 76 | x(i)=(b(i)-A(i,i+1:n)*x(i+1:n))/A(i,i); 77 | end 78 | 79 | % Record the LU factorization with row permutation. 80 | lu = A; 81 | -------------------------------------------------------------------------------- /Chapter6/GS.m: -------------------------------------------------------------------------------- 1 | function [x, iflag, itnum] = GS(A,b,x0,delta,max_it) 2 | % 3 | % function [x, iflag, itnum] = GS(A,b,x0,delta,max_it) 4 | % 5 | % A program implementing the Gauss-Seidel iteration method to solve 6 | % the linear system Ax=b. 7 | % 8 | % Input 9 | % A: square coefficient matrix 10 | % b: right side vector 11 | % x0: initial guess 12 | % delta: error tolerance for the relative difference between 13 | % two consecutive iterates 14 | % max_it: maximum number of iterations to be allowed 15 | % 16 | % Output 17 | % x: numerical solution vector 18 | % iflag: 1 if a numerical solution satisfying the error 19 | % tolerance is found within max_it iterations 20 | % -1 if the program fails to produce a numerical 21 | % solution in max_it iterations 22 | % itnum: the number of iterations used to compute x 23 | % 24 | 25 | % initialization 26 | n = length(b); 27 | iflag = 1; 28 | k = 0; 29 | x = x0; 30 | % iteration 31 | while k < max_it 32 | k = k+1; 33 | x(1) = (b(1)-A(1,2:n)*x0(2:n))/A(1,1); 34 | for i = 2:n 35 | if i < n 36 | x(i) = (b(i)-A(i,1:i-1)*x(1:i-1) ... 37 | -A(i,i+1:n)*x0(i+1:n))/A(i,i); 38 | else 39 | x(n) = (b(n)-A(n,1:n-1)*x(1:n-1))/A(n,n); 40 | end 41 | end 42 | relerr = norm(x-x0,inf)/(norm(x,inf)+eps); 43 | x0 = x 44 | if relerr < delta 45 | break 46 | end 47 | end 48 | % 49 | itnum = k; 50 | if (itnum == max_it) 51 | iflag = -1 52 | end 53 | -------------------------------------------------------------------------------- /Chapter6/Jacobi.m: -------------------------------------------------------------------------------- 1 | function [x, iflag, itnum] = Jacobi(A,b,x0,delta,max_it) 2 | % 3 | % function [x, iflag, itnum] = Jacobi(A,b,x0,delta,max_it) 4 | % 5 | % A program implementing the Jacobi iteration method to solve 6 | % the linear system Ax=b. 7 | % 8 | % Input 9 | % A: square coefficient matrix 10 | % b: right side vector 11 | % x0: initial guess 12 | % delta: error tolerance for the relative difference between 13 | % two consecutive iterates 14 | % max_it: maximum number of iterations to be allowed 15 | % 16 | % Output 17 | % x: numerical solution vector 18 | % iflag: 1 if a numerical solution satisfying the error 19 | % tolerance is found within max_it iterations 20 | % -1 if the program fails to produce a numerical 21 | % solution in max_it iterations 22 | % itnum: the number of iterations used to compute x 23 | % 24 | 25 | % initialization 26 | n = length(b); 27 | iflag = 1; 28 | k = 0; 29 | % create a vector with diagonal elements of A 30 | diagA = diag(A); 31 | % modify A to make its diagonal elements zero 32 | A = A-diag(diag(A)); 33 | % iteration 34 | while k < max_it 35 | k = k+1; 36 | x = (b-A*x0)./diagA 37 | relerr = norm(x-x0,inf)/(norm(x,inf)+eps); 38 | x0 = x; 39 | if relerr < delta 40 | break 41 | end 42 | end 43 | % 44 | itnum = k; 45 | if (itnum == max_it) 46 | iflag = -1 47 | end 48 | -------------------------------------------------------------------------------- /Chapter6/tridiag.m: -------------------------------------------------------------------------------- 1 | function [x, alpha, beta, ier] = tridiag(a,b,c,f,n,iflag) 2 | 3 | % function [x, alpha, beta, ier] = tridiag(a,b,c,f,n,iflag) 4 | % 5 | % Solve a tridiagonal linear system M*x=f 6 | % 7 | % INPUT: 8 | % The order of the linear system is given in n. 9 | % The subdiagonal, diagonal, and superdiagonal of M are given 10 | % by the arrays a,b,c, respectively. More precisely, 11 | % M(i,i-1) = a(i), i=2,...,n 12 | % M(i,i) = b(i), i=1,...,n 13 | % M(i,i+1) = c(i), i=1,...,n-1 14 | % iflag=0 means that the original matrix M is given as specified above. 15 | % iflag=1 means that the LU factorization of M is already known and is 16 | % stored in a,b,c. This will have been accomplished by a previous call 17 | % to this routine. In that case, the vectors alpha and beta should 18 | % have been substituted for a and b in the calling sequence. 19 | % 20 | % OUTPUT: 21 | % Upon exit, the LU factorization of M is already known and is stored 22 | % in alpha,beta,c. The solution x is given as well. 23 | % ier=0 means the program was completed satisfactorily. 24 | % ier=1 means that a zero pivot element was encountered and the 25 | % solution process was abandoned. 26 | 27 | a(1) = 0; 28 | if iflag == 0 29 | % Compute LU factorization of matrix M. 30 | for j=2:n 31 | if b(j-1) == 0 32 | ier = 1; 33 | return 34 | end 35 | a(j) = a(j)/b(j-1); 36 | b(j) = b(j) - a(j)*c(j-1); 37 | end 38 | if b(n) == 0 39 | ier = 1; 40 | return 41 | end 42 | end 43 | 44 | % Compute solution x to M*x = f. 45 | % Do forward substitution to solve lower triangular system. 46 | for j=2:n 47 | f(j) = f(j) - a(j)*f(j-1); 48 | end 49 | 50 | % Do backward substitution to solve upper triangular system. 51 | f(n) = f(n)/b(n); 52 | for j=n-1:-1:1 53 | f(j) = (f(j) - c(j)*f(j+1))/b(j); 54 | end 55 | 56 | % Set output variables. 57 | ier = 0; 58 | x = f; 59 | alpha = a; beta = b; 60 | -------------------------------------------------------------------------------- /Chapter7/newton_sys.m: -------------------------------------------------------------------------------- 1 | function solution = newton_sys(x_init,err_tol,max_iterates) 2 | % 3 | % The calling sequence for newton_sys.m is 4 | % solution = newton_sys(x_init,err_tol,max_iterates) 5 | % This solves a pair of two nonlinear equations in two unknowns, 6 | % f(x) = 0 7 | % with f(x) a column vector of length 2. The definition of f(x) 8 | % is to be given below in the function named fsys; and you 9 | % also need to give the Jacobian matrix for f(x) in the 10 | % function named deriv_fsys. 11 | % 12 | % x_init is a vector of length 2, and it is an initial guess 13 | % at the solution. 14 | % 15 | % The parameters err_tol and max_iterates are upper limits on 16 | % the desired error in the solution and the maximum number of 17 | % iterates to be computed. 18 | % 19 | % Initialization. 20 | x0=zeros(2,1); 21 | for i=1:2 22 | x0(i) = x_init(i); 23 | end 24 | 25 | error = inf; 26 | it_count = 0; 27 | 28 | % Begin the main loop. 29 | while error > err_tol & it_count < max_iterates 30 | it_count = it_count + 1; 31 | rhs = fsys(x0); 32 | A = deriv_fsys(x0); 33 | delta = A\rhs; 34 | x1 = x0 - delta; 35 | error = norm(delta,inf); 36 | % The following statement is an internal print to show 37 | % the course of the iteration. It and the pause 38 | % statement following it can be commented out. 39 | [it_count x1' error] 40 | pause 41 | x0 = x1; 42 | end 43 | 44 | % Return with the solution. 45 | solution = x1; 46 | if it_count == max_iterates 47 | disp(' ') 48 | disp('*** Your answers may possibly not satisfy your error tolerance.') 49 | end 50 | 51 | %%%%%%%%%%% Definition of functions %%%%%%%%%%%%%%%%% 52 | function f_val = fsys(x) 53 | % 54 | % The equations being solved are 55 | % x(1)^2 + 4*x(2)^2 - 9 = 0 56 | % 18*x(2) - 14*x(1)^2 + 45 = 0 57 | % 58 | f_val = [x(1)^2+4*x(2)^2-9, 18*x(2)-14*x(1)^2+45]'; 59 | 60 | function df_val = deriv_fsys(x) 61 | % 62 | % This defines the Jacobian matrix for the function 63 | % given in fsys 64 | 65 | df_val = [2*x(1), 8*x(2); -28*x(1), 18]; 66 | -------------------------------------------------------------------------------- /Chapter7/power_method.m: -------------------------------------------------------------------------------- 1 | function [lambda, eigenvec, diff, ratio] = ... 2 | power_method(A,x_0,index,err_tol,max_iterates) 3 | % 4 | % The calling sequence for power_method.m is 5 | % 6 | % [lambda, eigenvec, diff, ratio] = power_method(A,x_0,index, ... 7 | % err_tol,max_iterates) 8 | % 9 | % It implements the power method for finding the eigenvalue of A 10 | % which is largest in magnitude. 11 | % 12 | % The vector x_0 is the user's initial guess at the eigenvector 13 | % corresponding to the eigenvalue of largest magnitude. If the user has 14 | % no idea of how to choose x_0, then we suggest using 15 | % x_0 = rand(n,1) 16 | % with n the order of A. DO NOT use x_0 = 0. 17 | % 18 | % The input parameter "index" is used to specify the method of 19 | % approximating the eigenvalue. With index=0, we generate a random 20 | % vector, call it v, and we use 21 | % lambda approximately (v'*w)/(v'*z) 22 | % with Az=w. For index in [1,n], we use 23 | % lambda approximately w(index)/z(index). 24 | % 25 | % The parameter err_tol is used in the error test. However, note 26 | % this test needs to be made more sophisticated. It uses 27 | % error approx lambda_present - lambda_previous 28 | % at each step of the iteration, and this is not an accurate 29 | % estimate for slowly convergent iterations. 30 | % 31 | % The output variables are: 32 | % lambda: A vector of the power method iterations for the 33 | % approximate eigenvalue of largest magnitude. 34 | % eigenvec: The corresponding normalized eigenvector. 35 | % diff: The differences of the successive values in lambda. 36 | % ratio: The ratios of the successive values in diff. 37 | % The values of diff and ratio are of use in examining 38 | % the rate of convergence of the power method. 39 | % 40 | % Initialization 41 | n = size(A,1); % Find the order of A. 42 | x_init = zeros(n,1); 43 | lambda = zeros(max_iterates,1); 44 | % 45 | % Define x_init and require it to be a column vector. 46 | for i=1:n 47 | x_init(i) = x_0(i); 48 | end 49 | % 50 | [max_x,i_max] = max(abs(x_init)); % Find the max element in abs(x_init). 51 | z = x_init/x_init(i_max); % Normalize the initial vector to have 52 | % an infinity norm of 1. 53 | if index == 0 % Generate special vector for 54 | spec_vec = rand(1,n); % approximate eigenvalue computation. 55 | end 56 | % 57 | format long 58 | error = inf; 59 | it_count = 0; 60 | % Main loop. 61 | while abs(error) > err_tol & it_count < max_iterates 62 | it_count = it_count + 1; 63 | w = A*z; 64 | [max_w,i_max] = max(abs(w)); 65 | if index == 0 % Calculate approximate eigenvalue. 66 | lambda(it_count) = (spec_vec*w)/(spec_vec*z); 67 | else 68 | lambda(it_count) = w(index)/z(index); 69 | end 70 | % 71 | if it_count > 1 72 | error = lambda(it_count) - lambda(it_count-1); 73 | end 74 | % 75 | z = w/w(i_max); % Save approximate eigenvector. 76 | end 77 | % 78 | if it_count == max_iterates 79 | disp(' ') 80 | disp('*** Your answers may possibly not satisfy your error tolerance.') 81 | end 82 | % 83 | % Setting of output variables. 84 | eigenvec = z; 85 | lambda = lambda(1:it_count); 86 | diff = zeros(it_count,1); 87 | ratio = zeros(it_count,1); 88 | diff(2:it_count) = lambda(2:it_count)-lambda(1:it_count-1); 89 | ratio(3:it_count) = diff(3:it_count)./diff(2:it_count-1); 90 | -------------------------------------------------------------------------------- /Chapter8/AB2.m: -------------------------------------------------------------------------------- 1 | function [x,y] = AB2(x0,y0,x_end,h,fcn) 2 | % 3 | % function [x,y]=AB2(x0,y0,x_end,h,fcn) 4 | % 5 | % Solve the initial value problem 6 | % y' = f(x,y), x0 <= x <= b, y(x0)=y0 7 | % Use Adams-Bashforth formula of order 2 with a stepsize of h. 8 | % Euler's method is used for the value y1. The user must 9 | % supply a program with some name, say deriv, and a first 10 | % line of the form 11 | % function ans=deriv(x,y) 12 | % A sample call would be 13 | % [t,z]=AB2(t0,z0,b,delta,'deriv') 14 | % 15 | % Output: 16 | % The routine AB2 will return two vectors, x and y. 17 | % The vector x will contain the node points 18 | % x(1)=x0, x(j)=x0+(j-1)*h, j=1,2,...,N 19 | % with 20 | % x(N) <= x_end-h, x(N)+h > x_end-h 21 | % The vector y will contain the estimates of the solution Y 22 | % at the node points in x. 23 | % 24 | n = fix((x_end-x0)/h)+1; 25 | x = linspace(x0,x0+(n-1)*h,n)'; 26 | y = zeros(n,1); 27 | y(1) = y0; 28 | ft1 = feval(fcn,x(1),y(1)); 29 | y(2) = y(1)+h*ft1; 30 | for i = 3:n 31 | ft2 = feval(fcn,x(i-1),y(i-1)); 32 | y(i) = y(i-1)+h*(3*ft2-ft1)/2; 33 | ft1 = ft2; 34 | end 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter8/ODEBVP.m: -------------------------------------------------------------------------------- 1 | function z = ODEBVP(p,q,r,a,b,ga,gb,N) 2 | % A program to solve the two point boundary value problem 3 | % y''=p(x)y'+q(x)y+r(x), a x_end 22 | % The vector y will contain the estimates of the solution Y 23 | % at the node points in x. 24 | % 25 | 26 | % Initialize. 27 | n = fix((x_end-x0)/h)+1; 28 | x = linspace(x0,x0+(n-1)*h,n)'; 29 | y = zeros(n,1); 30 | y(1) = y0; 31 | i = 2; 32 | % advancing 33 | while i <= n 34 | % 35 | % forward Euler estimate 36 | % 37 | yt1 = y(i-1)+h*feval(fcn,x(i-1),y(i-1)); 38 | % one-point iteration 39 | count = 0; 40 | diff = 1; 41 | while diff > tol & count < 10 42 | yt2 = y(i-1) + h*feval(fcn,x(i),yt1); 43 | diff = abs(yt2-yt1); 44 | yt1 = yt2; 45 | count = count +1; 46 | end 47 | if count >= 10 48 | disp('Not converging after 10 steps at x = ') 49 | fprintf('%5.2f\n', x(i)) 50 | end 51 | y(i) = yt2; 52 | i = i+1; 53 | end 54 | -------------------------------------------------------------------------------- /Chapter8/euler_for.m: -------------------------------------------------------------------------------- 1 | function [x,y] = euler_for(x0,y0,x_end,h,fcn) 2 | % 3 | % function [x,y]=euler_for(x0,y0,x_end,h,fcn) 4 | % 5 | % Solve the initial value problem 6 | % y' = f(x,y), x0 <= x <= b, y(x0)=y0 7 | % Use Euler's method with a stepsize of h. The user must 8 | % supply a program with some name, say deriv, and a first 9 | % line of the form 10 | % function ans=deriv(x,y) 11 | % A sample call would be 12 | % [t,z]=eulercls(t0,z0,b,delta,'deriv') 13 | % 14 | % Output: 15 | % The routine euler_for will return two vectors, x and y. 16 | % The vector x will contain the node points 17 | % x(1)=x0, x(j)=x0+(j-1)*h, j=1,2,...,N 18 | % with 19 | % x(N) <= x_end-h, x(N)+h > x_end-h 20 | % The vector y will contain the estimates of the solution Y 21 | % at the node points in x. 22 | % 23 | n = fix((x_end-x0)/h)+1; 24 | x = linspace(x0,x0+(n-1)*h,n)'; 25 | y = zeros(n,1); 26 | y(1) = y0; 27 | for i = 2:n 28 | y(i)=y(i-1)+h*feval(fcn,x(i-1),y(i-1)); 29 | end 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter8/eulersys.m: -------------------------------------------------------------------------------- 1 | function [x,y] = eulersys(x0,y0,x_end,h,fcn) 2 | % 3 | % function [x,y]=eulersys(x0,y0,x_end,h,fcn) 4 | % 5 | % Solve the initial value problem of a system 6 | % of first order equations 7 | % y' = f(x,y), x0 <= x <= b, y(x0)=y0 8 | % Use Euler's method with a stepsize of h. 9 | % The user must supply a program to compute the 10 | % right hand side function with some name, say 11 | % deriv, and a first line of the form 12 | % function ans=deriv(x,y) 13 | % A sample call would be 14 | % [t,z]=eulersys(t0,z0,b,delta,'deriv') 15 | % 16 | % The program automatically determines the 17 | % number of equations from the dimension of 18 | % the initial value vector y0. 19 | % 20 | % Output: 21 | % The routine eulersys will return a vector x 22 | % and matrix y. The vector x will contain the 23 | % node points in [x0,x_end]: 24 | % x(1)=x0, x(j)=x0+(j-1)*h, j=1,2,...,N 25 | % The matrix y is of size N by m, with m the 26 | % number of equations. The i-th row y(i,:) will 27 | % contain the estimates of the solution Y 28 | % at the node points in x(i). 29 | % 30 | m = length(y0); 31 | n = fix((x_end-x0)/h)+1; 32 | x = linspace(x0,x0+(n-1)*h,n)'; 33 | y = zeros(n,m); 34 | y(1,:) = y0; 35 | for i = 2:n 36 | y(i,:) = y(i-1,:) + h*feval(fcn,x(i-1),y(i-1,:)); 37 | end 38 | -------------------------------------------------------------------------------- /Chapter8/trapezoidal.m: -------------------------------------------------------------------------------- 1 | function [x,y]=trapezoidal(x0,y0,x_end,h,fcn,tol) 2 | % 3 | % function [x,y]=trapezoidal(x0,y0,x_end,h,fcn,tol) 4 | % 5 | % Solve the initial value problem 6 | % y' = f(x,y), x0 <= x <= b, y(x0)=y0 7 | % Use trapezoidal method with a stepsize of h. The user must 8 | % supply an m-file to define the derivative f, with some name, 9 | % say 'deriv.m', and a first line of the form 10 | % function ans=deriv(x,y) 11 | % tol is the user supplied bound on the difference between successive 12 | % values of the trapezoidal iteration. 13 | % A sample call would be 14 | % [t,z]=trapezoidal(t0,z0,b,delta,'deriv',1e-3) 15 | % 16 | % Output: 17 | % The routine trapezoidal will return two vectors, x and y. 18 | % The vector x will contain the node points 19 | % x(1)=x0, x(j)=x0+(j-1)*h, j=1,2,...,N 20 | % with 21 | % x(N) <= x_end, x(N)+h > x_end 22 | % The vector y will contain the estimates of the solution Y 23 | % at the node points in x. 24 | % 25 | 26 | % Initialize. 27 | n=fix((x_end-x0)/h)+1; 28 | x=linspace(x0,x0+(n-1)*h,n)'; 29 | y=zeros(n,1); 30 | y(1)=y0; 31 | i=2; 32 | % advancing 33 | while i<= n 34 | fyt=feval(fcn,x(i-1),y(i-1)); 35 | % 36 | % Euler estimate 37 | % 38 | yt1=y(i-1)+h*fyt; 39 | % trapezoidal iteration 40 | count=0; 41 | diff=1; 42 | while diff > tol & count < 10 43 | yt2=y(i-1) + h*(fyt+feval(fcn,x(i),yt1))/2; 44 | diff = abs(yt2-yt1); 45 | yt1=yt2; 46 | count = count +1; 47 | end 48 | if count >= 10 49 | disp('Not converging after 10 steps at x = ') 50 | fprintf('%5.2f\n', x(i)) 51 | end 52 | y(i) = yt2; 53 | i=i+1; 54 | end 55 | -------------------------------------------------------------------------------- /Chapter9/Heat1.m: -------------------------------------------------------------------------------- 1 | function U = Heat1(a,f,u0,g1,g2,L,T,nx,nt) 2 | 3 | % function U = Heat1(a,f,u0,g1,g2,L,T,nx,nt) 4 | % 5 | % The forward difference scheme for solving the initial-boundary value 6 | % problem of the heat equation u_t = a u_{xx} + f for x in [0,L], and 7 | % t in [0,T]. 8 | % Input 9 | % a: the coefficient of the u_{xx} term 10 | % f=f(x,t): the right hand side function 11 | % u0=u0(x): the initial value function 12 | % g1=g1(t): the boundary value function at x=0 13 | % g2=g2(t): the boundary value function at x=L 14 | % L: right end point of the spatial interval 15 | % T: right end point of the temporal interval 16 | % nx: the number of sub-intervals of [0,L] 17 | % nt: the number of sub-intervals of [0,T] 18 | % Output 19 | % U: the solution (u_{k,i}), k the time grid point index, 20 | % i the space grid point index 21 | 22 | % compute some parameters 23 | nx1 = nx+1; 24 | hx = L/nx; 25 | nt1 = nt+1; 26 | ht = T/nt; 27 | r = a*ht/(hx*hx) 28 | r1 = 1-2*r; 29 | 30 | % stability test 31 | if r > 0.5 32 | disp('The ratio is too big; the scheme is unstable!') 33 | end 34 | 35 | % generate grid point vectors 36 | xvec = hx*(0:nx); 37 | tvec = ht*(0:nt); 38 | 39 | % initialization 40 | U = zeros(nt1,nx1); 41 | U(1,:) = feval(u0,xvec(:)'); 42 | 43 | % time advancing 44 | U(2:nt1,1) = feval(g1,(1:nt)*ht); 45 | U(2:nt1,nx1) = feval(g2,(1:nt)*ht); 46 | for k = 1:nt 47 | U(k+1,2:nx) = r*(U(k,1:nx-1)+U(k,3:nx+1))+r1*U(k,2:nx) ... 48 | +ht*feval(f,xvec(2:nx),tvec(k)); 49 | end 50 | 51 | % plot the numerical solution 52 | surf(xvec,tvec,U) 53 | xlabel('x-axis') 54 | ylabel('t-axis') 55 | zlabel('The numerical solution') 56 | s1 = sprintf('h_t=%6.4f h_x=%6.4f',ht,hx) 57 | title(['Solution: ',s1]) 58 | -------------------------------------------------------------------------------- /Chapter9/Heat2.m: -------------------------------------------------------------------------------- 1 | function U = Heat2(D,f,u0,g1,g2,L,T,nx,nt) 2 | % 3 | % function U = Heat2(D,f,u0,g1,g2,L,T,nx,nt) 4 | % 5 | % The backward difference scheme for solving the initial-boundary value 6 | % problem of the heat equation u_t=D u_{xx}+f for x in [0,L], and 7 | % t in [0,T]. 8 | % Input 9 | % D: the coefficient of the u_{xx} term 10 | % f=f(x,t): the right hand side function 11 | % u0=u0(x): the initial value function 12 | % g1=g1(t): the boundary value function at x=0 13 | % g2=g2(t): the boundary value function at x=L 14 | % L: right end point of the spatial interval 15 | % T: right end point of the temporal interval 16 | % nx: the number of sub-intervals of [0,L] 17 | % nt: the number of sub-intervals of [0,T] 18 | % Output 19 | % U: the solution (u_{k,i}), k the time grid point index, 20 | % i the space grid point index 21 | 22 | % compute some parameters 23 | nx1 = nx+1; 24 | hx = L/nx; 25 | nt1 = nt+1; 26 | ht = T/nt; 27 | r = D*ht/(hx*hx) 28 | r1 = 1+2*r; 29 | % generate the grid points for x and t variables 30 | xvec = hx*(0:nx); 31 | tvec = ht*(0:nt); 32 | % generate the entries of the coefficient matrix for the linear 33 | % tridiagonal systems to be solved at each time level 34 | avec(2:nx-1) = -r; 35 | bvec(1:nx-1) = r1; 36 | cvec(1:nx-2) = -r; 37 | % define the dimensions of the unknown 38 | U = zeros(nt1,nx1); 39 | % the initial value 40 | U(1,:) = feval(u0,xvec(:)'); 41 | % compute the solution at t=ht; use the program tridiag.m to 42 | % factor and store A=LU and solve the system at t=ht 43 | U(2,1) = feval(g1,ht); 44 | U(2,nx1) = feval(g2,ht); 45 | fvec(1) = U(1,2)+ht*feval(f,xvec(2),tvec(2))+r*U(2,1); 46 | fvec(2:nx-2) = U(1,3:nx-1)+ht*feval(f,xvec(3:nx-1),tvec(2)); 47 | fvec(nx-1) = U(1,nx)+ht*feval(f,xvec(nx),tvec(2))+r*U(2,nx1); 48 | [U(2,2:nx),avec,bvec,ier]=tridiag(avec,bvec,cvec,fvec,nx-1,0); 49 | % compute the solution at the other time levels 50 | for k = 2:nt1 51 | U(k,1) = feval(g1,(k-1)*ht); 52 | U(k,nx1) = feval(g2,(k-1)*ht); 53 | fvec(1) = U(k-1,2)+ht*feval(f,xvec(2),tvec(k))+r*U(k,1); 54 | fvec(2:nx-2) = U(k-1,3:nx-1)+ht*feval(f,xvec(3:nx-1),tvec(k)); 55 | fvec(nx-1) = U(k-1,nx)+ht*feval(f,xvec(nx),tvec(k))+r*U(k,nx1); 56 | U(k,2:nx) = tridiag(avec,bvec,cvec,fvec,nx-1,1); 57 | end 58 | % plot the numerical solution 59 | surf(xvec,tvec,U) 60 | xlabel('x-axis') 61 | ylabel('t-axis') 62 | zlabel('The numerical solution') 63 | s1 = sprintf('h_t=%6.4f h_x=%6.4f',ht,hx) 64 | title(['Solution: ',s1]) 65 | -------------------------------------------------------------------------------- /Chapter9/Poisson.m: -------------------------------------------------------------------------------- 1 | function U = Poisson(f,g,n,tol,max_it) 2 | % 3 | % function U = Poisson(f,g,n,tol,max_it) 4 | % 5 | % The five point scheme for solving the Dirichlet BVP of the 6 | % Poisson equation on the unit square. 7 | % Input 8 | % f: the right hand side function 9 | % g: the Dirichlet boundary value function 10 | % n: the number of sub-intervals of [0,1] 11 | % tol: relative error tolerance of the iterative solution; 12 | % default value: 10^(-5) 13 | % max_it: maximal number of iterations allowed; 14 | % default value: 10,000 15 | % Output 16 | % U: the solution u_{ij}, i,j=1,...,n+1 17 | % 18 | % To use the program, the user must supply two m-files, say 19 | % 'f.m' and 'g.m', to define the right hand side function f of 20 | % the differential equation and the boundary value function g. 21 | % The user should also choose a positive integer n for the 22 | % number of subintervals of [0,1]. 23 | % A sample call would be 24 | % U = Poisson('f','g',n,1e-8,1000) 25 | % with 10^(-8) as the tolerance for the relative errors of the 26 | % iterative solution, and a maximal number of 1,000 iterations 27 | % is allowed for solving the finite difference system. 28 | % It is also possible to use 29 | % U = Poisson('f','g',n,1e-8) 30 | % then the maximal number of iterations is the default 31 | % value 10^4. If the default values 10^(-5) and 10^4 are 32 | % to be used for the iteration relative error tolerance and 33 | % maximal number of iterations, then one can simply use 34 | % U = Poisson('f','g',n) 35 | % if max_it, or max_it and tol, are not provided, use the 36 | % default values 37 | if nargin < 5 38 | max_it = 10000 39 | end 40 | if nargin < 4 41 | tol = 1e-5 42 | end 43 | % compute some parameters 44 | n1 = n+1; h = 1/n; 45 | toln = (h^2)*tol; 46 | h2 = h*h/4; 47 | Fr = zeros(n,n); 48 | for j = 2:n 49 | for i = 2:n 50 | Fr(i,j) = h2*feval(f,(i-1)*h,(j-1)*h); 51 | end 52 | end 53 | % initialization 54 | U = zeros(n1,n1); 55 | % specify boundary conditions 56 | for j = 1:n1 57 | U(1,j) = feval(g,0,(j-1)*h); 58 | U(n1,j) = feval(g,1,(j-1)*h); 59 | end 60 | for i = 1:n1 61 | U(i,1) = feval(g,(i-1)*h,0); 62 | U(i,n1) = feval(g,(i-1)*h,1); 63 | end 64 | % iteration 65 | rel_err = 1; 66 | itnum = 0; 67 | while ((rel_err > toln) & (itnum <= max_it)) 68 | err = 0; 69 | umax = 0; 70 | for j = 2:n 71 | for i = 2:n 72 | temp = (U(i+1,j)+U(i-1,j)+U(i,j+1)+U(i,j-1))/4-Fr(i,j); 73 | dif = abs(temp-U(i,j)); 74 | if (err <= dif) 75 | err = dif; 76 | end 77 | U(i,j) = temp; 78 | temp = abs(temp); 79 | if(umax <= temp) 80 | umax = temp; 81 | end 82 | end 83 | end 84 | itnum = itnum+1; 85 | rel_err = err/umax; 86 | end 87 | % plot the numerical solution 88 | X=(0:h:n*h)'; 89 | Y=X; 90 | surf(X,Y,U') 91 | xlabel('x-axis') 92 | ylabel('y-axis') 93 | zlabel('the numerical solution') 94 | title('Plot of the numerical solution') 95 | -------------------------------------------------------------------------------- /Chapter9/Wave.m: -------------------------------------------------------------------------------- 1 | function U = Wave(a,f,u0,v0,g1,g2,L,T,nx,nt) 2 | % 3 | % function U=Wave(a,f,u0,v0,g1,g2,L,T,nx,nt) 4 | % 5 | % The centered difference scheme for solving the initial-boundary value 6 | % problem of the wave equation u_{tt}=a u_{xx}+f for x in [0,L], and 7 | % t in [0,T]. 8 | % Input 9 | % a: the coefficient of the u_{xx} term 10 | % f=f(x,t): the right hand side function 11 | % u0=u0(x): the initial value function 12 | % v0=v0(x): the initial derivative value function 13 | % g1=g1(t): the boundary value function at x=0 14 | % g2=g2(t): the boundary value function at x=L 15 | % L: right end point of the spatial interval 16 | % T: right end point of the temporal interval 17 | % nx: the number of sub-intervals of [0,L] 18 | % nt: the number of sub-intervals of [0,T] 19 | % Output 20 | % U: the solution (u_{k,i}), k the time grid point index, 21 | % i the space grid point index 22 | 23 | % compute some parameters 24 | nx1 = nx+1; 25 | hx = L/nx; 26 | nt1 = nt+1; 27 | ht = T/nt; 28 | ht2 = ht*ht; 29 | r = a*ht*ht/(hx*hx) 30 | r1 = 2*(1-r); 31 | if r > 1 32 | disp('The ratio is too big; the scheme is unstable!') 33 | end 34 | % define the grid points 35 | xvec = hx*(0:nx); 36 | tvec = ht*(0:nt); 37 | % compute the solution at t=0 and ht using the initial values 38 | U = zeros(nt1,nx1); 39 | U(1,:) = feval(u0,xvec); 40 | U(2,1) = feval(g1,ht); 41 | U(2,2:nx) = 0.5*(r*(U(1,1:nx-1)+U(1,3:nx+1))+r1*U(1,2:nx) ... 42 | +ht2*feval(f,xvec(2:nx),tvec(1))) ... 43 | +ht*feval(v0,xvec(2:nx)); 44 | U(2,nx1) = feval(g2,ht); 45 | % compute the solution at the other times 46 | for k = 2:nt 47 | U(k+1,1) = feval(g1,k*ht); 48 | U(k+1,nx1) = feval(g2,k*ht); 49 | U(k+1,2:nx) = r*(U(k,1:nx-1)+U(k,3:nx+1))+r1*U(k,2:nx) ... 50 | -U(k-1,2:nx)+ht2*feval(f,xvec(2:nx),tvec(k)); 51 | end 52 | % plot the numerical solution 53 | surf(xvec,tvec,U) 54 | xlabel('x-axis') 55 | ylabel('t-axis') 56 | zlabel('The numerical solution') 57 | s1=sprintf('h_t=%6.4f h_x=%6.4f',ht,hx) 58 | title(['Solution: ',s1]) 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Numerical-Analysis-code 2 | 数值分析代码(Matlab版) 3 | --------------------------------------------------------------------------------