尝试在cpp scritp中模仿Python中的fsolve函数来实现简单函数

2024-05-15 04:10:30 发布

您现在位置:Python中文网/ 问答频道 /正文

首先,我是C++新手。TBH我觉得很难“习惯”,但上周我一直试图“翻译”一个脚本从Python到C++由于计算时间的要求。p>

我遇到的一个问题是简单1D函数的根查找:

首先是Python中的简单MWE: 试图求解ax^2+bx+c=0:

def f(x,a,b,c):
   return a*x**2+b*x+c
optimize.fsolve(f,-1.0e2,args=(1,1,-1))

它将返回-1.6180.618,具体取决于起始点的猜测符号

< >,在C++中,我在网上搜索的内容有点复杂,使用了GSL Root finding库。

对于简单的非多元函数,它就像一个符咒,但当第二阶出现时, 当您简化搜索“快速”解决方案时,添加端点似乎是一个问题:

#include <stdio.h>
#include <math.h>
#include <functional>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <gsl/gsl_math.h>
#include <gsl/gsl_interp2d.h>
#include <gsl/gsl_spline2d.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_roots.h>


struct my_f_params { double a; double b; double c; };

double
my_f (double x, void * p)
  {
    struct my_f_params * params = (struct my_f_params *)p;
    double a = (params->a);
    double b = (params->b);
    double c = (params->c);

    return  (a * x + b) * x + c;
  }

double root (struct my_f_params prms, double r)
{
  int status;
  int iter = 0, max_iter = 50;
  const gsl_root_fsolver_type *T;
  gsl_root_fsolver *s;
  double x_lo= -5e0, x_hi=11e0;
  gsl_function F;
   

  F.function = &my_f;
  F.params = &prms;

  T = gsl_root_fsolver_falsepos;
  s = gsl_root_fsolver_alloc (T);
  gsl_root_fsolver_set (s, &F, x_lo, x_hi);




  do
    {
      iter++;
      gsl_set_error_handler_off();
      status = gsl_root_fsolver_iterate (s);
      r = gsl_root_fsolver_root (s);
      x_lo = gsl_root_fsolver_x_lower (s);
      x_hi = gsl_root_fsolver_x_upper (s);
      status = gsl_root_test_interval (x_lo, x_hi,
                                       0, 0.001);
    printf("%f  %f\n",x_lo,x_hi);
    }
  while (status == GSL_CONTINUE && iter < max_iter);


  return r;
}
int main(int argc, char const *argv[])
{
   struct my_f_params params = {1, 1, -1};
   printf("root of x2+x1-1=0 %f\n",  root(params,1.25));
  return 0;
}

现在,如果起始x_lo , x_hi覆盖了2个解积分,它不会继续寻找最接近的积分,给出错误

gsl: falsepos.c:74: ERROR: endpoints do not straddle y=0
Default GSL error handler invoked.
Aborted (core dumped)

在我发布之前,我已经尝试过谷歌的很多东西

真的非常感谢您的时间,一切都很感激


Tags: loreturnincludemystatusrootparamshi
1条回答
网友
1楼 · 发布于 2024-05-15 04:10:30

你需要的是研究这个类似的问题,并很好地解释如何使它工作error in GSL - root finding。 为了提供帮助,您可以使用https://www.desmos.com/calculator/zuaqvcvpbz查看函数,并可以如下设置初始值: 双x_lo=0.0,x_hi=1.0; 在您的实现中使其运行; 添加此代码将有助于找到x_lo和x_hi的适当值:

gsl_set_error_handler_off(); // this turns off error reporting
int check = gsl_root_fsolver_set(s, &F, x_lo, x_hi);
if (check == GSL_EINVAL) {// this is the error code you got
    do {
        x_lo += 0.1;  // it would be appropriate to check the sign in both 
        x_hi -= 0.1;  // cases, to make sure interval is adjusted properly
        check = gsl_root_fsolver_set(s, &F, x_lo, x_hi);
    } while (check != 0);
}

相关问题 更多 >

    热门问题