0

我们有一个任务要求我们exp(2)使用 MacLaurin 级数进行估计,我已经进一步尝试开发和运行,您可以在其中输入一个方程、x您希望估计的值以及您希望有多少个有效数字.

它适用于某些方程,即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

请问我是否有不清楚的地方。

4

1 回答 1

0

代码有几处错误(除了我编辑过的 while 循环末尾的语法错误)。第一个是 f(x) = benDiff 的行。benDiff 应该是第 n 个导数,因此如果您进行此分配,则 diff 实际上成为第 (n!) 个导数。删除 f(x)=beenDiff 行可以解决此问题。

第二个问题是您的停止标准不好 - 如果任何导数函数恰好产生 0,那么代码将简单地停止,因为差异为零,无论进一步的迭代是否会改变该值。对于余弦之类的东西,这是一个问题。(如果函数本身在 x=0 处产生零,则代码将拒绝运行,因此 sin(x) 根本不起作用)。

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

于 2016-09-15T07:22:45.437 回答