【问题标题】:How to use boost bisection?如何使用增强二分法?
【发布时间】:2011-11-23 16:44:53
【问题描述】:

昨天我遇到了另一个提升功能的问题,但幸运的是你们帮助我解决了这些问题。今天我需要知道如何正确使用二分函数。

所以这就是我认为它应该如何工作的方式,但似乎我也弄错了。好的,所以我想使用:

template <class F, class T, class Tol>
 std::pair<T, T> 
 bisect(
    F f, 
    T min, 
    T max, 
    Tol tol);

来自here,但我的问题在于宽容,因为我不知道如何正确设置。我试过了

double value = boost::math::tools::eps_tolerance<double>(0.00001);

找到二等分后如何返回值?结果应该是函数中的 std::pair 数字对,然后只计算 min+max/2 吗?

谢谢!

【问题讨论】:

    标签: c++ boost


    【解决方案1】:

    这是bisect 的使用示例。考虑解方程x^2 - 3x + 1 = 0

    struct TerminationCondition  {
      bool operator() (double min, double max)  {
        return abs(min - max) <= 0.000001;
      }
    };
    
    struct FunctionToApproximate  {
      double operator() (double x)  {
        return x*x - 3*x + 1;  // Replace with your function
      }
    };
    
    // ...
    using boost::math::tools::bisect;
    double from = 0;  // The solution must lie in the interval [from, to], additionally f(from) <= 0 && f(to) >= 0
    double to = 1;
    std::pair<double, double> result = bisect(FunctionToApproximate(), from, to, TerminationCondition());
    double root = (result.first + result.second) / 2;  // = 0.381966...
    

    编辑:或者,您可以通过以下方式将其与自定义函数一起使用:

    double myF(double x)  {
      return x*x*x;
    }
    
    double otherF(double x)  {
      return log(abs(x));
    }
    
    // ...
    std::pair<double, double> result1 = bisect(&myF, from, to, TerminationCondition());
    std::pair<double, double> result2 = bisect(&otherF, 0.1, 1.1, TerminationCondition());
    

    【讨论】:

    • 我假设我可以替换 FunctionToApproximate() 只要它只返回一个值就可以使用我想要使用的函数?还是我只是替换 return xxx 来调用另一个函数,例如 return Eval()
    • 第一个问题 - 您可以将 FunctionToApproximate 更改为可以使用一个双参数调用并返回双精度的任何内容。一种更简洁的方法是用您自己的函数替换 xxx 并保持 FunctionToApproximate 原样。对于第二个问题 - 您想将子句作为字符串输入还是将其硬编码为 C++ 表达式?
    • 对于第二个问题,基本上现在是子句字符串还是硬编码都无所谓。示例子句的目的只是为了测试二分函数是否正常工作。
    • 编辑了我的答案以反映您的测试表达。
    • 如果您确保您使用的各种函数都采用一个双精度参数并返回双精度,您可以摆脱 FunctionToApproximate 并将它们直接传递给 bisect。 bisect 接受具有满足此条件的重载 () 运算符的任何函数或类。编辑了我的帖子以反映这一点。
    【解决方案2】:

    请注意,bisect 也支持 lambda:

    using boost::math::tools::bisect;
    auto root = bisect
    (
        [](double x){return x;},
        -1.0, 1.0,
        [](double l, double r){return abs(l-r) < 1e-8;}
    );
    

    【讨论】:

      猜你喜欢
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 2011-05-27
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多