基于Ridders Method线性及二次多项式和三次样条插值的MATLAB实现

function root = ridders_method(func, left, right, tol, max_iter,interpolation_method)
    % func: 待求函数
    % a, b: 初始区间
    % tol: 允许误差
    % max_iter: 最大迭代次数
    %inter_mod: 插值方法
    
    f_left = feval(func, left);
    f_right = feval(func, right);
%判断端值
    if f_left * f_right > 0
        error('区间端点处的函数值符号必须相反。');
    end    
%开始迭代   
for k = 1:max_iter        

%计算区间中点和对应的函数值
        mid = (left + right) / 2;
        f_mid = feval(func, mid);       
        if strcmp(interpolation_method, 'line')
        %线性插值, 计算d处函数值和其位置
            d = mid + (mid - left) * sign(f_left - f_right) * f_mid / sqrt(f_mid^2 - f_left * f_right);  
        %二次多项式插值
        elseif strcmp(interpolation_method, 'polyfit')
            square = polyfit([left mid right],[f_left f_mid f_right],2);
            d = roots(square);%多项式的根
            d = d(imag(d) == 0);%保留实数根
            d = d(d >= left & d <= right);%保留在当前区间内的根
            %判断d是否为空
            if isempty(d)
                error('未找到实数解');
            end
            % 选择根使得与 c 更近
            [~, idx] = min(abs(d - mid));
            d = d(idx);
        elseif strcmp(interpolation_method, 'spline')
            spline_coeffs = spline([left, mid, right], [f_left, f_mid, f_right]);
            d = fzero(@(x) ppval(spline_coeffs, x), mid);
        else
            error('不是选定的插值方法');
        end
            
        fd = feval(func, d);%计算根(可能)在该函数的值
%判断是否找到根
            if fd == 0 || ((right - left)/2) < tol
                root = d;
                return;
            end
%更新端点
            if f_left * fd < 0
                right = d;
                f_right = fd;
            else
                left = d;
                f_left = fd;
            end        
%判断收敛条件
            if abs(right - left) < tol
               root = (left + right) / 2;
                return;
            end
end  
%若不满足其要求,并给出原因
    error('Ridders方法未在最大迭代次数内收敛。');
end

%复制到新脚本
% %%简单样例:
% % func: 待求解的函数句柄
% % a, b: 初始区间
% % tol: 允许误差
% %max_iter: 最大迭代次数
% %interpolation_method:插值方法
% func = @(x) x^2 - 2;
% a = 0;
% b = 2;
% tol = 1e-12;
% max_iter = 1000;
% interpolation_method = 'spline'; % 可以选择 'line', 'polyfit'(2次), 'spline'(三次样条)
%
% root = ridders_method(func, a, b, tol, max_iter, interpolation_method);
% disp(['Root: ', num2str(root)]);

实现代码如上

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值