Input Parameters
Output Parameters
Input Parameters
Output Parameters
Input Parameters
Output Parameters
On entry, | , |
or | , |
or | , |
or | , |
or | . |
(i) | To integrate to producing output at intervals of until a point is encountered where . The Jacobian is calculated numerically. |
(ii) | As (i) but with the Jacobian calculated analytically. |
(iii) | As (i) but with no intermediate output. |
(iv) | As (i) but with no termination on a root-finding condition. |
(v) | Integrating the equations as in (i) but with no intermediate output and no root-finding termination condition. |
Open in the MATLAB editor: d02ej_example
function d02ej_example fprintf('d02ej example results\n\n'); % For communication with save. global ykeep ncall xkeep; % Initialize variables and arrays. x = 0; xend = 10; y = [1; 0; 0]; tol = 0.001; relabs = 'Default'; ncall = 0; ykeep = zeros(1,length(y)); xkeep = zeros(1,1); disp('Case 1: calculating Jacobian internally,'); fprintf('intermediate output, root-finding\n\n'); for j = 3:4 tol = double(10)^(-j); disp(['Calculation with tol = ',num2str(tol)]); disp(' X Y(1) Y(2) Y(3)'); % output outputs intermediate values. [xOut, yOut, tolOut, ifail] = ... d02ej(... x, xend, y, @fcn,'d02ejy', tol, relabs, @output, @g); disp(' '); disp(['Root of Y(1)-0.9 = 0.0 at ',num2str(xOut)]); disp('Solution is' ); fprintf(' %8.4f %8.4f %8.4f\n\n', yOut); if (tol < 0.0) disp('Range too short for tol'); end end disp('Case 2: calculating Jacobian by pederv,'); fprintf('intermediate output, root-finding\n\n'); for j = 3:4 tol = double(10)^(-j); disp(['Calculation with tol = ',num2str(tol)]); disp(' X Y(1) Y(2) Y(3)'); % pederv evaluates Jacobian. [xOut, yOut, tolOut, ifail] = ... d02ej(... x, xend, y, @fcn, @pederv, tol, relabs, @output, @g); disp(' '); disp(['Root of Y(1)-0.9 = 0.0 at ',num2str(xOut)]); disp('Solution is' ); fprintf(' %8.4f %8.4f %8.4f\n\n', yOut); xOut1 = xOut; if (tol < 0.0) disp('Range too short for tol'); end % Store the x value for plotting. xOut1 = xOut; end disp('Case 3: calculating Jacobian internally,'); fprintf('no intermediate output, root-finding\n\n'); for j = 3:4 tol = double(10)^(-j); disp(['Calculation with tol = ',num2str(tol)]); [xOut, yOut, tolOut, ifail] = ... d02ej(... x, xend, y, @fcn, 'd02ejy', tol, relabs, 'd02ejx', @g); disp(' '); disp(['Root of Y(1)-0.9 = 0.0 at ',num2str(xOut)]); disp('Solution is' ); fprintf(' %8.4f %8.4f %8.4f\n\n', yOut); if (tol < 0.0) disp('Range too short for tol'); end end disp('Case 4: calculating Jacobian internally,'); fprintf('intermediate output, no root-finding\n\n'); for j = 3:4 tol = double(10)^(-j); disp(['Calculation with tol = ',num2str(tol)]); disp(' X Y(1) Y(2) Y(3)'); % save stores intermediate values in xkeep, ykeep, which are % plotted later (it also outputs them). [xOut, yOut, tolOut, ifail] = ... d02ej(... x, xend, y, @fcn, 'd02ejy', tol, relabs, @save, 'd02ejw'); disp(' '); if (tol < 0.0) disp('Range too short for tol'); end end disp('Case 5: calculating Jacobian internally,'); fprintf('no intermediate output, no root-finding (integrate to xend)\n\n'); for j = 3:4 tol = double(10)^(-j); disp(['Calculation with tol = ',num2str(tol)]); disp(' X Y(1) Y(2) Y(3)'); fprintf('%d %8.6f %8.6f %8.6f\n',x,y); [xOut, yOut, tolOut, ifail] = ... d02ej(... x, xend, y, @fcn, 'd02ejy', tol, relabs,'d02ejx', 'd02ejw'); fprintf('%2d %8.6f %8.6f %8.6f\n\n', xOut, yOut); if (tol < 0) disp('Range too short for tol'); end end % Plot results. nres = 0.5*length(xkeep); xplot = xkeep(nres+1:2*nres); yplot = ykeep(nres+1:2*nres, :); fig1 = figure; display_plot(xplot, yplot, xOut1); function xsolOut = save(xsol, y) % For communication with main routine. global ykeep ncall xkeep; % This version of the intermediate output routine stores the values % (so they can be plotted in the main routine). ncall = ncall+1; ykeep(ncall,:) = y; xkeep(ncall,:) = xsol; fprintf('%2d %8.6f %8.6f %8.6f\n', xsol, y); xsolOut = xsol + 2; function xsolOut = output(xsol, y) % Output intermediate values of solution. fprintf('%2d %8.6f %8.6f %8.6f\n', xsol, y); xsolOut = xsol + 2; function f = fcn(x, y) % Evaluate the derivatives. f = zeros(3,1); f(1) = -0.04*y(1) + 1.0d4*y(2)*y(3); f(2) = 0.04*y(1) - 1.0d4*y(2)*y(3) - 3.0d7*y(2)*y(2); f(3) = 3.0d7*y(2)*y(2); function result = g(x, y) % Evaluate g(x,y) when root-finding option is selected. result = y(1) - 0.9; function pw = pederv(x, y) % Evaluate the Jacobian. pw = zeros(3,3); pw(1,1) = -0.04d0; pw(1,2) = 1.0d4*y(3); pw(1,3) = 1.0d4*y(2); pw(2,1) = 0.04d0; pw(2,2) = -1.0d4*y(3) - 6.0d7*y(2); pw(2,3) = -1.0d4*y(2); pw(3,1) = 0.0d0; pw(3,2) = 6.0d7*y(2); pw(3,3) = 0.0d0; function display_plot(xplot, yplot, xOut1) % Formatting for title and axis labels. % Plot the three curves. plot(xplot, yplot(:,1), '-+', ... xplot, yplot(:,2), '--x', ... xplot, yplot(:,3), ':*'); set(gca, 'YLim', [-0.05 1.05]); % Mark the height=0 point. do_stem(xplot, yplot, xOut1); % Add title. title('ODE Solution: BDF Method with Root-finding'); % Label the x axis. xlabel('x'); % Label the y axis. ylabel('Solution (a,b,c)'); function do_stem(xplot, yplot, xOut1) % Find the x bin that xOut1 lies in. for i = 1:length(xplot) if xplot(i) > xOut1 break end end % Use linear interpolation to find the corresponding y values on the % two curves. dx = xplot(i)-xplot(i-1); ddx = xOut1-xplot(i-1); d1 = ddx/dx; f1 = yplot(i-1,2) + d1*(yplot(i,2)-yplot(i-1,2)); f2 = yplot(i-1,3) + d1*(yplot(i,3)-yplot(i-1,3)); % Plot the line from the x axis to the two y values. hold on stem([xOut1,xOut1],[f1,0],'k:s'); hold on stem([xOut1,xOut1],[f2,0],'k:s'); y = (abs(f1-f2)/2); text('Position',[xOut1-0.15,y],'String',['a = ',num2str(f1)],'Rotation',90);
d02ej example results Case 1: calculating Jacobian internally, intermediate output, root-finding Calculation with tol = 0.001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 2 0.941629 0.000027 0.058344 4 0.905507 0.000022 0.094470 Root of Y(1)-0.9 = 0.0 at 4.3767 Solution is 0.9000 0.0000 0.1000 Calculation with tol = 0.0001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 2 0.941608 0.000027 0.058365 4 0.905513 0.000022 0.094464 Root of Y(1)-0.9 = 0.0 at 4.3767 Solution is 0.9000 0.0000 0.1000 Case 2: calculating Jacobian by pederv, intermediate output, root-finding Calculation with tol = 0.001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 2 0.941629 0.000027 0.058344 4 0.905507 0.000022 0.094470 Root of Y(1)-0.9 = 0.0 at 4.3767 Solution is 0.9000 0.0000 0.1000 Calculation with tol = 0.0001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 2 0.941608 0.000027 0.058365 4 0.905513 0.000022 0.094464 Root of Y(1)-0.9 = 0.0 at 4.3767 Solution is 0.9000 0.0000 0.1000 Case 3: calculating Jacobian internally, no intermediate output, root-finding Calculation with tol = 0.001 Root of Y(1)-0.9 = 0.0 at 4.3767 Solution is 0.9000 0.0000 0.1000 Calculation with tol = 0.0001 Root of Y(1)-0.9 = 0.0 at 4.3767 Solution is 0.9000 0.0000 0.1000 Case 4: calculating Jacobian internally, intermediate output, no root-finding Calculation with tol = 0.001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 2 0.941629 0.000027 0.058344 4 0.905507 0.000022 0.094470 6 0.879302 0.000020 0.120678 8 0.858580 0.000018 0.141402 10 0.841361 0.000016 0.158623 Calculation with tol = 0.0001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 2 0.941608 0.000027 0.058365 4 0.905513 0.000022 0.094464 6 0.879261 0.000020 0.120720 8 0.858536 0.000018 0.141446 10 0.841357 0.000016 0.158627 Case 5: calculating Jacobian internally, no intermediate output, no root-finding (integrate to xend) Calculation with tol = 0.001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 10 0.841361 0.000016 0.158623 Calculation with tol = 0.0001 X Y(1) Y(2) Y(3) 0 1.000000 0.000000 0.000000 10 0.841357 0.000016 0.158627