考研数学:用割线法求方程的近似解
1. 割线法原理
割线法也叫弦截法,是一种用于求解方程\(f(x)=0\)的迭代数值方法。
基本思想:利用过函数\(y = f(x)\)上两点的割线来逼近函数的零点。
与切线法(牛顿迭代法)不同,割线法不需要计算函数的导数,而是通过函数在两个不同点的值来构造割线,然后求出割线与\(x\)轴的交点作为新的近似解。
2. 割线法的迭代公式推导
设\(x_{n - 1}\)和\(x_{n}\)是已经得到的两个近似解,函数\(y = f(x)\)对应的函数值为\(f(x_{n - 1})\)和\(f(x_{n})\)。
过点\((x_{n - 1},f(x_{n - 1}))\)和\((x_{n},f(x_{n}))\)的割线方程为\(y - f(x_{n})=\frac{f(x_{n}) - f(x_{n - 1})}{x_{n}-x_{n - 1}}(x - x_{n})\)。
令\(y = 0\),解得割线与\(x\)轴交点的横坐标\(x_{n + 1}=x_{n}-\frac{f(x_{n})(x_{n}-x_{n - 1})}{f(x_{n}) - f(x_{n - 1})}\),这就是割线法的迭代公式。
例如,用割线法求方程\(x^{3}-x - 1 = 0\)的近似解。
先选取两个初始值\(x_{0}=1\),\(x_{1}=2\)。
第一次迭代:
根据迭代公式\(x_{n + 1}=x_{n}-\frac{f(x_{n})(x_{n}-x_{n - 1})}{f(x_{n}) - f(x_{n - 1})}\),这里\(n = 1\)。
首先计算\(f(x_{0})=f(1)=1^{3}-1 - 1=-1\),\(f(x_{1})=f(2)=2^{3}-2 - 1 = 5\)。
代入迭代公式可得\(x_{2}=2-\frac{5\times(2 - 1)}{5 - (-1)}=2-\frac{5}{6}=\frac{7}{6}\approx1.167\)。
第二次迭代:
此时\(n = 2\),\(x_{n - 1}=x_{1}=2\),\(x_{n}=x_{2}=\frac{7}{6}\)。
\(f(x_{2})=(\frac{7}{6})^{3}-\frac{7}{6}-1=\frac{343}{216}-\frac{7}{6}-1=\frac{343 - 252 - 216}{216}=-\frac{125}{216}\)。
代入迭代公式可得\(x_{3}=\frac{7}{6}-\frac{(-\frac{125}{216})\times(\frac{7}{6}-2)}{(-\frac{125}{216}) - 5}\)
先计算分子\((-\frac{125}{216})\times(\frac{7}{6}-2)=(-\frac{125}{216})\times(-\frac{5}{6})=\frac{625}{1296}\)。
分母\((-\frac{125}{216}) - 5=-\frac{125 + 1080}{216}=-\frac{1105}{216}\)。
则\(x_{3}=\frac{7}{6}-\frac{\frac{625}{1296}}{-\frac{1105}{216}}=\frac{7}{6}+\frac{625}{1296}\times\frac{216}{1105}=\frac{7}{6}+\frac{625\times216}{1296\times1105}\approx1.318\)。
继续迭代,直到满足精度要求,如\(\vert x_{n + 1}-x_{n}\vert<\varepsilon\)(\(\varepsilon\)为给定的精度)。
用C++求解方程 \(f(x) =x^{3}-x - 1 = 0\)
#include <iostream>
#include <cmath>
using namespace std;
// 定义要求解的方程
double equation(double x) {
return x * x * x - x - 1;
}
// 割线法:利用两个初始值构造割线,求出割线与 x 轴交点作为新的近似解,然后不断更新两个用于构造割线的值,直至满足精度条件。
double secantMethod(double x0, double x1, double tolerance) {
double x2;
do {
x2 = x1 - equation(x1) * (x1 - x0) / (equation(x1) - equation(x0));
if (fabs(x2 - x1) < tolerance)
break;
x0 = x1;
x1 = x2;
} while (true);
return x2;
}
可以使用以下方式调用割线法函数:
int main() {
double x0 = 1; // 第一个初始值
double x1 = 2; // 第二个初始值
double tolerance = 0.0001; // 精度要求
double root = secantMethod(x0, x1, tolerance);
cout << "割线法求得的近似根为: " << root << endl;
return 0;
}