2016-09-15 32 views
0

我们有一项任务要求我们估计exp(2)使用MacLaurin系列我已经花了一点时间尝试开发和运行,您可以在其中输入方程,您希望估计的价值x以及您希望获得的有效数字的数量。MacLaurin系列中diff(f,x,n)的问题

它非常适合于某些方程,即exp(x)sin(x),甚至exp(x) + 2x,但第二次我在一个更高的功率扔在x,说x^2返回0

例如,当我将该函数调用为:MacLaurin(x^2,2,1)时,它返回0这不是一个正确的答案。

下面是代码:

% Created by: DarkRiot43 
% Student #: 
% Date: Sept 12, 2016 
% Course: Numerical Analysis, MTH 510 

function [ ] = MacLaurin(func , valueOfx, sigfigs) 
%MACLAURIN Summary of this function goes here 
% Detailed explanation goes here 
%  inputs: func: a function 
%    sigfigs: the number of significant figures you would like 
%    to have the answer evaluated to. 
clc; 
syms f(x) x ; 
f(x) = func; 
presentApprox = 0; 
previousApprox = 0; 
n = 0; 
% Find the criterion for stopping the iteration as an double not a percent. 
Es = (0.5*10^(2-round(sigfigs)))/100; 

Ea =Es+1; % Ensures Ea is larger than Es to begin 

while Ea >= Es 
    %differentiate the n'th derivative of the equation f(x) w.r.t. x 
    beenDiff = diff(f(x),n); 
    presentApprox = previousApprox + (vpa(subs(beenDiff,x,0))* (((valueOfx)^n)/factorial(n))); %MacLaurin series structure used to evaluate. 
    n = n+1; %Counter incrementation 
    % Call to function approxError to determine approximate relative error. 
    Ea = approxError(presentApprox,previousApprox); 
    previousApprox = presentApprox; 
    f(x) = beenDiff;  
    % can be used to ensure proper iterating counting of the program 
    disp(n); 

    disp(f(x)); %shows the n'th derivative function 

    %check to see if in the approxError function there would have been a 
    %by zero error. if so I edit the value (999 was all i could think of? 
    % was thinking of using something else but didn't know what to use 
    if Ea == 999 
     break; 
    end 
end 
else 
    fprintf('\nStopping criterion used:\t'); 
    disp(Es*100) 


    fprintf('The estimate generated using MacLaurin Series of '); 
    disp(func); 
    fprintf('using the value x = %.3f is: \n\n',valueOfx); 
    fprintf('%7f',presentApprox); 
    fprintf('\nThis was done using %d iterations', n); 

    if Ea == 0 
     fprintf('\nCould not reach the requested stopping criterion.'); 

    end 


end 

function [Ea] = approxError(presentApprox,previousApprox) 
%Approximate relative error Function 
% inputs: 
% presentApprox: type double 
% previousApprox: type double 
% returns: 
% Ea: type double 
%  
% Uses two values to determine the approximate relative error w.r.t 
%  eachother 

    if presentApprox ~= 0 

     Ea = (presentApprox - previousApprox)/(presentApprox); 

    elseif presentApprox == 0 

     disp('Cannot determine the value with more precision as it would involve dividing by zero!'); 
     Ea = 999; 

    end 
end 

请问,如果我一直不清楚。

回答

0

代码有两处错误(除了我编辑的while循环结尾的语法错误)。第一个是f(x)= beenDiff的行。 beenDiff应该是第n个导数,所以如果你做这个任务,diff实际上变成了第(n!)个导数。删除行f(x)= beenDiff可以解决这个问题。

第二个问题是您的停止标准不好 - 如果任何衍生函数碰巧产生0,那么代码将会简单地停止,因为差异为零,而不管进一步的迭代是否会改变该值。对于像余弦这样的问题,这是一个问题。 (如果函数本身在x = 0时产生一个零,代码将拒绝运行,所以sin(x)根本不起作用)。

获得停止标准正确是一个相当大的挑战,因为您需要知道函数后面的导数的大小,以确保您不会获得更大的跳转。 (函数可以收敛,但不必在每次迭代时单调收敛)。

+0

谢谢戴夫, 我会研究这些问题。正如我想的那样,我似乎已经超出了我的想象。这就是说,这是一个很好的挑战,以获得我目前的位置。 – DarkRiot43