查找黑盒函数的第一个根,或同一函数的任何负值

2023-12-11

我有一个黑盒函数 f(x) 和 x 的一系列值。 我需要找到 f(x) = 0 时 x 的最小值。

我知道对于 x 范围的开始,f(x) > 0,如果我有一个 f(x)

我知道 f(x) 是连续的,并且对于所讨论的范围应该只有 0,1 或 2 个根,但它可能有一个局部最小值。

f(x) 的计算量有点大,我必须经常找到这个第一个根。

我正在考虑某种具有一定程度随机性的爬山以避免任何局部最小值,但是你怎么知道是否没有小于零的最小值或者你还没有找到它呢?我认为该函数不应有超过两个最小值点,但我不能完全确定这一点足以依赖它。

如果有帮助的话,本例中的 x 代表时间,f(x) 代表当时船舶与轨道上的物体(月球/行星)之间的距离。我需要第一个点,它们彼此之间有一定的距离。


我的方法听起来相当复杂,但最终该方法的计算时间将远远小于距离计算(评估你的f(x))。此外,现有库中已经编写了很多它的实现。

那么我会做什么:

  • 近似f(x)与切比雪夫多项式
  • 找到该多项式的实根
  • 如果找到任何根,请使用这些根作为更精确的寻根器中的初始估计(如果需要)

给定函数的性质(平滑、连续、否则表现良好)以及有 0,1 或 2 个根的信息,通过 3 次评估就可以找到一个好的切比雪夫多项式f(x).

然后求切比雪夫系数伴生矩阵的特征值;这些对应于切比雪夫多项式的根。

如果全部都是虚数,则根为 0。 如果存在一些实数根,请检查两个是否相等(您所说的“罕见”情况)。 否则,所有实特征值都是根;其中最低的一个是你所寻找的根。

然后使用Newton-Raphson 进行细化(如有必要,或使用更好的切比雪夫多项式)。的衍生物f可以使用中心差来近似

f'(x) = ( f(x+h)-f(h-x) ) /2/h     (for small h)

我在 Matlab/Octave 中实现了 Chebychev 例程(如下所示)。像这样使用:

R = FindRealRoots(@f, x_min, x_max, 5, true,true);

with [x_min,x_max]你的范围在x, 5用于查找多项式的点数(越高,越准确。等于所需的函数计算量),以及最后一个true将绘制实际函数及其切比雪夫近似值的图(主要用于测试目的)。

现在,实施:

% FINDREALROOTS     Find approximations to all real roots of any function 
%                   on an interval [a, b].
%
% USAGE:
%    Roots = FindRealRoots(funfcn, a, b, n, vectorized, make_plot)
%
% FINDREALROOTS() approximates all the real roots of the function 'funfcn' 
% in the interval [a,b]. It does so by finding the roots of an [n]-th degree 
% Chebyshev polynomial approximation, via the eignevalues of the associated 
% companion matrix. 
%
% When the argument [vectorized] is [true], FINDREALROOTS() will evaluate 
% the function 'funfcn' at all [n] required points in the interval 
% simultaneously. Otherwise, it will use ARRAFUN() to calculate the [n] 
% function values one-by-one. [vectorized] defaults to [false]. 
%
% When the argument [make_plot] is true, FINDREALROOTS() plots the 
% original function and the Chebyshev approximation, and shows any roots on
% the given interval. Also [make_plot] defaults to [false]. 
%
% All [Roots] (if any) will be sorted.
% 
% First version 26th May 2007 by Stephen Morris, 
% Nightingale-EOS Ltd., St. Asaph, Wales.
%
% Modified 14/Nov (Rody Oldenhuis)
%
% See also roots, eig.

function Roots = FindRealRoots(funfcn, a, b, n, vectorized, make_plot)

    % parse input and initialize.
    inarg = nargin; 
    if n <= 2, n = 3; end                    % Minimum [n] is 3:    
    if (inarg < 5), vectorized = false; end  % default: function isn't vectorized
    if (inarg < 6), make_plot = false; end   % default: don't make plot

    % some convenient variables
    bma = (b-a)/2;  bpa = (b+a)/2;  Roots = [];

    % Obtain the Chebyshev coefficients for the function
    %
    % Based on the routine given in Numerical Recipes (3rd) section 5.8;
    % calculates the Chebyshev coefficients necessary to approximate some
    % function over the interval [a,b]

    % initialize 
    c = zeros(1,n);  k=(1:n)';  y = cos(pi*((1:n)-1/2)/n); 
    % evaluate function on Chebychev nodes
    if vectorized
        f = feval(funfcn,(y*bma)+bpa);
    else
        f = arrayfun(@(x) feval(funfcn,x),(y*bma)+bpa);
    end

    % compute the coefficients
    for j=1:n, c(j)=(f(:).'*(cos((pi*(j-1))*((k-0.5)/n))))*(2-(j==1))/n; end       

    % coefficients may be [NaN] if [inf]
    % ??? TODO - it is of course possible for c(n) to be zero...
    if any(~isfinite(c(:))) || (c(n) == 0), return; end

    % Define [A] as the Frobenius-Chebyshev companion matrix. This is based
    % on the form given by J.P. Boyd, Appl. Num. Math. 56 pp.1077-1091 (2006).
    one = ones(n-3,1);
    A = diag([one/2; 0],-1) + diag([1; one/2],+1);
    A(end, :) = -c(1:n-1)/2/c(n);
    A(end,end-1) = A(end,end-1) + 0.5;

    % Now we have the companion matrix, we can find its eigenvalues using the
    % MATLAB built-in function. We're only interested in the real elements of
    % the matrix:
    eigvals = eig(A);  realvals = eigvals(imag(eigvals)==0);

    % if there aren't any real roots, return
    if isempty(realvals), return; end

    % Of course these are the roots scaled to the canonical interval [-1,1]. We
    % need to map them back onto the interval [a, b]; we widen the interval just
    % a tiny bit to make sure that we don't miss any that are right on the 
    % boundaries.
    rangevals = nonzeros(realvals(abs(realvals) <= 1+1e-5));

    % also sort the roots
    Roots = sort(rangevals*bma + bpa);

    % As a sanity check we'll plot out the original function and its Chebyshev
    % approximation: if they don't match then we know to call the routine again
    % with a larger 'n'.
    if make_plot
        % simple grid
        grid = linspace(a,b, max(25,n));
        % evaluate function
        if vectorized
            fungrid = feval(funfcn, grid);
        else
            fungrid = arrayfun(@(x) feval(funfcn,x), grid);
        end        
        % corresponding Chebychev-grid (more complicated but essentially the same)
        y = (2.*grid-a-b)./(b-a); d = zeros(1,length(grid)); dd = d;
        for j = length(c):-1:2, sv=d; d=(2*y.*d)-dd+c(j); dd=sv; end, chebgrid=(y.*d)-dd+c(1);
        % Now make plot
        figure(1), clf,  hold on
        plot(grid, fungrid ,'color' , 'r');
        line(grid, chebgrid,'color' , 'b'); 
        line(grid, zeros(1,length(grid)), 'linestyle','--')
        legend('function', 'interpolation')
    end % make plot

end % FindRealRoots
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找黑盒函数的第一个根,或同一函数的任何负值 的相关文章

  • 用于基本要素匹配的最坏情况 NlogN 算法

    查找两个相同大小数组的元素之间的唯一映射 https stackoverflow com questions 4411940 find the unique mapping between elements of two same size
  • StackOverflowError 计算 BigInteger 的阶乘?

    我正在尝试编写一个Java程序来计算大数的阶乘 它似乎BigInteger无法容纳这么大的数量 下面是我编写的 简单的 代码 public static BigInteger getFactorial BigInteger num if n
  • 对矩阵进行舍入,保留行和列总计

    想要 以保留行和列总计的方式对矩阵进行舍入的 伪 代码 问题从向量开始 X and Y of 非负整数 with Sum X Sum Y 想要圆X Y Sum X 同时保留行和列总计 这是婚姻问题的一种 Xa需要进行一定次数的握手 拨打该号
  • 为什么《破解编码面试》这个例子的时间复杂度是O(k c^k)?

    该问题来自 破解编码面试 第 6 版 问题 V1 11 以下代码打印长度为 k 的所有字符串 其中字符 是按排序顺序排列的 它通过生成所有长度的字符串来做到这一点 k 然后检查每个是否已排序 什么是运行时间 package QVI 11 P
  • 数组中最远的相等元素

    假设你有一个未排序的数组 你如何找到两个相等的元素 使它们成为数组中最远的元素 例如8 7 3 4 7 5 3 9 3 7 9 0ans 将是7 9 7 1 8 我想到了以下几点 initialise max 0 using hashing
  • 用于计算三角函数、对数或类似函数的算法。仅限加减法

    我正在修复 Ascota 170 古董机械可编程计算机 它已经开始工作了 现在我正在寻找一种算法来展示其功能 例如计算三角或对数表 或类似的东西 不幸的是 从数学运算来看 计算机只能进行整数的加减法 从 1E12到1E12的55个寄存器 甚
  • 如何在单向链表(一次遍历中)中从尾部获取第 n 个节点?

    所以我在一次考试中得到了这个问题 如何从单链表的尾部获取第 n 个节点 每个节点都有一个值和一个下一个 指向下一个值的指针 我们得到这个 getNodeFromTail Node head int x 所以我的做法是通过遍历一次来求出列表的
  • 运行时间为 O(n) 且就地排序的排序算法

    有没有运行时间为O n 并且还分类到位 在某些情况下 最好的情况是 O n 但这可能是因为项目集合已经排序 你正在看 O nlogn 一些较好的平均值 话虽如此 排序算法的 Wiki 还是相当不错的 有一个表格比较了流行的算法 说明了它们的
  • 神经网络的层和神经元

    我想更多地了解神经网络 我正在开发一个 C 程序来制作神经网络 但我坚持使用反向传播算法 很抱歉没有提供一些工作代码 我知道有很多库可以用多种语言创建神经网络 但我更喜欢自己制作一个 关键是我不知道要实现特定目标 例如模式识别或函数近似或其
  • 素数生成器算法

    我一直在尝试解决素数生成算法的SPOJ问题 这是问题 彼得想为他的密码系统生成一些素数 帮助 他 你的任务是生成两个给定之间的所有素数 数字 Input 输入以单行中测试用例的数量 t 开始 t Output 对于每个测试用例 打印所有素数
  • 简单的排名算法

    我需要创建一个民意调查 按照项目的好坏顺序创建一个排名列表 我打算向每个用户展示两个项目 让他们选择一个他们认为更好的项目 然后多次重复这个过程 它有点类似于您在社交网络电影 我应该如何根据收到的答案对项目进行排名 看着那 这ELO国际象棋
  • 检查有效的 IMEI

    有人知道如何检查有效的 IMEI 吗 我找到了一个可以检查此页面的功能 http www dotnetfunda com articles article597 imeivalidator in vbnet aspx http www do
  • 分而治之算法找到两个有序元素之间的最大差异

    给定一个整数数组 arr 找出任意两个元素之间的差异 使得较大的元素出现在 arr 中较小的数字之后 Max Difference Max arr x arr y x gt y 例子 如果数组是 2 3 10 6 4 8 1 7 那么返回值
  • 如何求两个地点的经纬度距离?

    我有一组位置的纬度和经度 怎么找distance从集合中的一个位置到另一个位置 有公式吗 半正矢公式假定地球是球形的 然而 地球的形状更为复杂 扁球体模型会给出更好的结果 如果需要这样的精度 你应该更好地使用文森特逆公式 See http
  • Python 旅行商贪婪算法 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 因此 我为旅行推销员问题创建了一种排序 并按 x 坐标和 y 坐标进行排序 我正在尝试实施贪婪搜索 但无法做到 此外 每
  • heapq.nlargest 的时间复杂度是多少?

    我在看演讲者说 获得t列表中最大的元素n元素可以在O t n 这怎么可能 我的理解是创建堆将是O n 但是复杂度是多少nlargest本身就是O n t or O t 实际的算法是什么 在这种情况下 说话者是错误的 实际成本是O n log
  • 重写修改后的 goto 语义的算法

    我有一大堆使用旧的自行设计的脚本语言编写的遗留代码 我们将它们编译 翻译成 javascript 该语言有条件跳转 跳转到标签 与普通 goto 语句的区别在于 不可能向后跳转 该语言中没有嵌套的 if 语句或循环 由于 javascrip
  • 我可以在元标记中使用 HTML 字符实体吗?

    我有一个有两种语言的网站 英语和中文 在使用 UTF 8 字符集的英文主页中 我有 例如 这出现在搜索结果中 我想将其更改为 在哪里 20013 25991 是 中文 的 ISO 实体 搜索结果中会显示为 中文 吗 我无法将 中文 直接粘贴
  • 颜色逻辑算法

    我们正在构建一个体育应用程序 并希望将团队颜色融入到应用程序的各个部分 现在 每个团队都可以使用几种不同的颜色来表示 我想做的是执行检查以验证两个团队颜色是否在彼此一定的范围内 这样我就不会显示两个相似的颜色 因此 如果团队 1 的主要团队
  • 使用什么算法来确定使系统达到“零”状态所需的最小操作数?

    这是一种更通用的问题 不是特定于语言的 有关要使用的想法和算法的更多信息 系统如下 它登记朋友群体之间的小额贷款 Alice and Bill要去吃午饭 比尔的卡坏了 所以爱丽丝支付了他的餐费 10 美元 第二天Bill and Charl

随机推荐