C++正在查找函数的根
C++ Finding root of the function
我被要求找到以下函数的根
sin((a*x / (1 + pow(x, 2))) + 1) * atan(b*x - 1 / 2) + exp(-c*x) * atan(x)
对于两组值
a=10
、b=2
和c=0
a=4.5
、b=2.8
和c=1
但我还没有得到开始和结束的值,在这些值中我需要找到根。我该怎么办?
注意:atan()表示tan的逆函数
代码片段:
double f(double x, double a, double b, double c)
{
return sin((a*x / (1 + pow(x, 2))) + 1) * atan(b*x - 1 / 2) + exp(-c*x) * atan(x);
}
double RootFinder(double f(double, double, double, double), double a, double b, double c, double left, double right, double precision)
{
double f_left = f(left, a, b, c), now = left + precision, f_right = f(now, a, b, c);
while (f_left * f_right > 0 && now < right)
{
f_left = f_right;
now += precision;
f_right = now;
}
return now - precision / 2;
}
函数的实现中有一个错误。
atan(b*x - 1 / 2)
术语1 / 2
进行整数除法并计算为0,这可能不是您想要的。通常,在使用双变量进行算术时,请使用双文本。pow()
函数确实将(double, int)
作为其重载之一,所以您在这方面做得很好。它也有一个(double, double)
重载,但如果你的指数实际上是一个整数,那么你就不想要它了。
这里有一个最简单的根查找方法的简单实现——平分方法(我后来注意到OP使用了平分标记,完美)。
#include <iostream>
#include <cmath>
#include <random>
double f(const double x, const double a, const double b, const double c)
{
return sin((a*x / (1.0 + pow(x, 2))) + 1.0) * atan(b*x - 1.0 / 2.0) + exp(-c*x) * atan(x);
}
double BisectionMethod(
double f(double, double, double, double),
const double a, const double b, const double c,
const std::random_device::result_type entropy)
{
std::mt19937 gen(entropy);
static const auto lower_bound = -1.0;
static const auto upper_bound = 1.0;
std::uniform_real_distribution<> dis(lower_bound, upper_bound);
auto pos_pt = dis(gen);
auto neg_pt = dis(gen);
while (f(pos_pt, a, b, c) < 0.0)
pos_pt = dis(gen);
while (f(neg_pt, a, b, c) > 0.0)
neg_pt = dis(gen);
static const auto about_zero_mag = 1E-8;
for (;;)
{
const auto mid_pt = (pos_pt + neg_pt)/2.0;
const auto f_mid_pt = f(mid_pt, a, b, c);
if (fabs(f_mid_pt) < about_zero_mag)
return mid_pt;
if (f_mid_pt >= 0.0)
pos_pt = mid_pt;
else
neg_pt = mid_pt;
}
}
int main()
{
double a, b, c;
std::random_device rd;
static const auto entropy = rd();
a =10, b = 2.0, c = 0.0;
const auto root1 = BisectionMethod(f, a, b, c, entropy);
std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
std::cout << "Found root: (" << root1 << ", " << f(root1, a, b, c) << ")" << std::endl;
a =4.5, b = 2.8, c = 1.0;
const auto root2 = BisectionMethod(f, a, b, c, entropy);
std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
std::cout << "Found root: (" << root2 << ", " << f(root2, a, b, c) << ")" << std::endl;
}
输出:
g++ -O3 -std=c++11 -Wall -Wextra -pedantic main.cpp -o root && ./root
a = 10, b = 2, c = 0
Found root: (0.143042, -2.12425e-09)
a = 4.5, b = 2.8, c = 1
Found root: (0.136172, 5.81247e-09)
输出将随每次运行而变化,因为这使用了RNG。从视觉上看,输出看起来是正确的。
代码假设根由-1.0和1.0限定,这在您的情况下是正确的。如果您希望它更通用,那么您需要添加用于处理溢出和检查nan的逻辑。如果根不在-1.0和1.0之间,它将永远循环。尽管如此,它还是解决了这个问题中的具体问题,并为更一般的事情开辟了一个开端。
还要注意,您的函数有多个根,而给定的代码只找到一个根。
编辑:清理代码。将entropy
作为参数添加到BisectionMethod()
中,使其具有可重复性,这在我们讨论数值方法时似乎是可取的。
相关文章:
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 一个函数,用于查找字符串1包含字符串2 c++的次数
- 用于在 C++ 中使用 while 循环查找下一个素数的简单函数
- C++ 函数,用于查找传入的 N 个数字的平均值、总和、最小值和最大值
- 使用用户定义的函数查找数字的幂时出现问题
- 如何处理具有不同类的成员函数的函数查找表?
- 如果我们没有在 C++ 中传递大小变量,则通过函数查找数组的大小
- 使用用户定义的函数查找完美数时出现浮点异常错误
- 使用 lambda 函数查找 std::unordered_map 中的最小值
- 重载函数查找轮廓的实例与参数列表不匹配
- 使用C++中的割线函数查找根
- JNA 程序函数查找失败
- 通过 C 加加号中的函数查找中位数
- 试图通过函数查找数组的最大值和最小值,其中数组值由用户输入
- xlC模板函数问题的静态函数查找
- 使用线程函数查找 2D 数组中的最大条目
- 如何在cpp中使用std::regex_replace()函数查找和替换
- 数组函数查找最大值
- 使用' stdio.h '函数查找模板和名称
- CPP字符串构造函数查找并附加空字符