计算三角方程解的快速方法c ++
Fast way to calculate solution of a triangular equation c++
用 c++ 计算下面等式中 x 的最快方法是什么?
sin (a x) + b sin (c x)== d * x + e
我不需要非常精确的 x 值。 0.001 的近似值是可以接受的。我也知道解决方案的间隔 [x_0,x_1].
我知道牛顿法,但是因为我要模拟一个系统,我需要解一千次,我不知道如何给出第一个解
我假设您正在寻找 数值 解决方案,给定已知参数 a
、b
、c
、d
、e
。可以通过这种脏迭代找到近似解。
但不保证所有参数值都收敛。
唯一的方法是给出解的解析上限和下限,并使用二分根查找进行迭代。
#include<numeric>
#include<iostream>
#include<cmath>
using std::cout;
int main(){
auto a = 1.1;
auto b = 1.2;
auto c = 0.9;
auto d = 0.1;
auto e = 0.1;
auto N = 1000;
auto x = 0.;
for(int n = 0; n != N; ++n)
x = 0.999*x + 0.001*(sin(a*x) + b*sin(c*x) - e)/d;
cout << sin(a*x) + b*sin(c*x) << " == " << d*x + e << '\n';
cout << "solution is x = " << x << '\n';
}
(为简单起见,这是 C++11)
您可以将等式重新表述为
sin (a x) + b sin (c x) - d * x - e == 0
现在,这是一个寻根问题。这是 root finding algorithms 的列表。
牛顿法非常快速且易于实施,因为您的方程的导数可以解析计算。
#include <array>
#include <iostream>
#include <cmath>
template <typename T> double func(const T ¶meter, const double x) {
const auto a = parameter[0];
const auto b = parameter[1];
const auto c = parameter[2];
const auto d = parameter[3];
const auto e = parameter[4];
return sin(a * x) + b * sin(c * x) - (d * x + e);
}
template <typename T> double derivative(const T ¶meter, const double x) {
const auto a = parameter[0];
const auto b = parameter[1];
const auto c = parameter[2];
const auto d = parameter[3];
return a * cos(a * x) + b * c * cos(c * x) - d;
}
template <typename T> double solve(const T ¶meter) {
double x = 0.0;
const double eps = 1e-9;
while (fabs(func(parameter, x)) > eps) {
x = x - func(parameter, x) / derivative(parameter, x);
}
return x;
}
int main() {
const std::array<double, 5> parameter{1.1, 1.2, 0.9, 0.1, 0.1};
const auto x = solve(parameter);
std::cout << "solution is x=" << x << " f(x)=" << func(parameter, x) << '\n';
}
从 double
到 float
以加快速度,如果您希望的精度允许的话。
用 c++ 计算下面等式中 x 的最快方法是什么?
sin (a x) + b sin (c x)== d * x + e
我不需要非常精确的 x 值。 0.001 的近似值是可以接受的。我也知道解决方案的间隔 [x_0,x_1].
我知道牛顿法,但是因为我要模拟一个系统,我需要解一千次,我不知道如何给出第一个解
我假设您正在寻找 数值 解决方案,给定已知参数 a
、b
、c
、d
、e
。可以通过这种脏迭代找到近似解。
但不保证所有参数值都收敛。
唯一的方法是给出解的解析上限和下限,并使用二分根查找进行迭代。
#include<numeric>
#include<iostream>
#include<cmath>
using std::cout;
int main(){
auto a = 1.1;
auto b = 1.2;
auto c = 0.9;
auto d = 0.1;
auto e = 0.1;
auto N = 1000;
auto x = 0.;
for(int n = 0; n != N; ++n)
x = 0.999*x + 0.001*(sin(a*x) + b*sin(c*x) - e)/d;
cout << sin(a*x) + b*sin(c*x) << " == " << d*x + e << '\n';
cout << "solution is x = " << x << '\n';
}
(为简单起见,这是 C++11)
您可以将等式重新表述为
sin (a x) + b sin (c x) - d * x - e == 0
现在,这是一个寻根问题。这是 root finding algorithms 的列表。
牛顿法非常快速且易于实施,因为您的方程的导数可以解析计算。
#include <array>
#include <iostream>
#include <cmath>
template <typename T> double func(const T ¶meter, const double x) {
const auto a = parameter[0];
const auto b = parameter[1];
const auto c = parameter[2];
const auto d = parameter[3];
const auto e = parameter[4];
return sin(a * x) + b * sin(c * x) - (d * x + e);
}
template <typename T> double derivative(const T ¶meter, const double x) {
const auto a = parameter[0];
const auto b = parameter[1];
const auto c = parameter[2];
const auto d = parameter[3];
return a * cos(a * x) + b * c * cos(c * x) - d;
}
template <typename T> double solve(const T ¶meter) {
double x = 0.0;
const double eps = 1e-9;
while (fabs(func(parameter, x)) > eps) {
x = x - func(parameter, x) / derivative(parameter, x);
}
return x;
}
int main() {
const std::array<double, 5> parameter{1.1, 1.2, 0.9, 0.1, 0.1};
const auto x = solve(parameter);
std::cout << "solution is x=" << x << " f(x)=" << func(parameter, x) << '\n';
}
从 double
到 float
以加快速度,如果您希望的精度允许的话。