В вашем коде нет ничего плохого, формула конечных разностей работает просто отлично, а ошибка, которую вы получаете, заключается в численном вычислении элементов:
ошибки, сгенерированные вычислением a/b
, когда оба значения a
и b
очень и очень малы.
вычисление a-b
, когда a
и b
очень очень близки к тому, что MATLAB даст 0
.
Вот результат, когда k изменяется от 1 до 15:
Спасибо за проницательный комментарий @CrisLuengo!
, который показывает, что err
мгновенно падает почти до нуля, и снова повышается, когда h
становится 1e-9
(ситуация 1 происходит после этого). Наконец df
становится 0, когда h
становится 1e-14
(здесь происходит ситуация 2).
Я добавил несколько строк кода к вашей, чтобы показать это:
clc;
clear;
format long
syms f(x)
f(x) = tan(x);
h=1;
df = diff(f,x);
double(df(1));
x=1;
range=1:15;
[finitediff,err]=deal(zeros(size(range)));
for k=range
h=10^-k;
finitediff(k)=double((f(x+h)-f(x))/h);
err(k)=double(abs(finitediff(k)-df(1)));
end
figure(1)
subplot(1,2,1)
hold on
plot(err)
plot(err,'bx')
set(gca,'yscale','log')
title('err')
subplot(1,2,2)
hold on
ezplot(df)
axis([0.5 1.5 0 5])
plot(ones(size(range)),finitediff,'rx','MarkerSize',7)
for ii=range
text(1,finitediff(ii),['h=1e-' num2str(ii)])
end