自适应求积算法 MatLab版

在这里插入图片描述

%自适应simpson算法
clc
clear
close all;
syms x
f(x)=100/(x^2)*sin(10/x);%目标函数
a=1;b=3;%初始区间
TOL=1E-4;%误差容限
[s,fcount]=acsimpson1(f,a,b,TOL);

t = 1:0.001:3;
plot(t,f(t))
hold on
disp("自适应求积结果:")
result = vpa(s);
fprintf("result= %f",result);
% 画出f(x)图像
function [s,fcount]=acsimpson1(f,a,b,tol)
%此方法为自适应simpson方法求解定积分
%f为函数,a,b分别为积分区间,tol为精度
%s为积分值,fcount为计算函数值次数

%一下为准备输入数据
f = fcnchk(f,'vectorized');       %定义内联函数
h=b-a;             %步长
qu=[a a+h/2 b];    %三个节点
% qu(qu==0)=2^-1024; %避免计算函数值出现NAN的情况
y=feval(f,qu);     %计算函数节点处的值
s=y*[1 4 1]'*h/6;  %Simpson积分
fcount=0;          %定义初始计数器
tol=tol*10;        %调整精度

[s,fcount]=subsim(f,s,qu,y,fcount,tol); %递归函数
fcount=fcount+3;   %计数器加上准备输入数据的三次计算
end

%以下为递归函数
function [s,fcount]=subsim(f,s,qu,y,fcount,tol)
%以下为对qu二分,分别对两个小区间求出Simpson积分
h=(qu(end)-qu(1))/2;
quadd=[qu(1)+h/2 qu(2)+h/2];
quadd(quadd==0)=2^-1024; %避免计算函数值出现NAN的情况
yadd=feval(f,quadd);
scatter(quadd,yadd,"o")
hold on
subs=[y(1) yadd(1) y(2) yadd(2) y(3)].*[1 4 1 4 1]*h/6;
s1=sum(subs(1:3));    %左半区间
s2=sum(subs(3:end));  %右半区间
stemp=s1+s2;
fcount=fcount+2;

%每次递归一次,函数值运算次数增加2次
if abs(stemp-s)<tol
    s=s1+s2; %若满足精度,采用一次Romberg积分,返回函数值
else                      %若不满足,则继续二分
    tol=tol/2;
    [s1,fcount]=subsim(f,s1,[qu(1) qu(1)+h/2 qu(2)],[y(1) yadd(1) y(2)],fcount,tol);
    [s2,fcount]=subsim(f,s2,[qu(2) qu(2)+h/2 qu(end)],[y(2) yadd(2) y(3)],fcount,tol);
    s=s1+s2;              %将每个小区间的Romberg积分值相加            
    %fcount=fcount1+fcount2;   %将每个小区间的计数器相加
end

end
  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PANGOO OS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值