数值计算实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数值计算实验报告
姓名:XX
学号:XX
专业:XX
实验一
1.题目
x 5-3x 3+x-1=0在区间[-8,8]上。试分别用:①二分法②Newton 法③弦截法(割线法):双点弦法④Newton 下山法,求方程的根,精确到6位有效数字. 2.2.1二分法
(1)二分法
算法分析
设函数有根区间表示为[],a b 。将有根区间[],a b 用中点01
()2
x a b =+分成两半,
计算函数值()2a b f +。如果()02a b f +=,就得到方程组的实根*2
a b
x +=,否则检查0()f x 与()f a 是否同号,若同号,则说明所求的根*x 在0x 的右侧,这时令
101,a x b b ==;否则,根*x 在0x 的左侧,这时令110,a a b x ==,这样新的有根区
间[]11,a b 的长度为[],a b 之半。对压缩了的有根区间[]11,a b 又施以同样的方法……如此反复二分下去,即可得出一系列有根区间
[][][][]1122,,,,k k a b a b a b a b ⊃⊃⊃⊃⊃
其中,每个区间都是前一个区间的一半,因此二分k 次后的有根区间[],k k a b 的长
度为1
()2
k k k b a b a -=
- 可见,如果二分过程无限地下去,这些有根区间最终必收缩于一点*x ,该点显然就是所求的根。
取有根区间[],k k a b 的中点*1
()2
k k x a b =+作为根的近似值,此时的误差
*111
()()
22k k k k x x b a a b +-≤-=+
若事先给定的误差要求为ε,则只需*11
()2
k k x x a b ε+-≤+<便可以停止二分计
算。
(2)Newton 法
算法分析
对于非线性方程()0f x =,若已知根*x 的一个近似值k x (在这里是m ih +,将()f x 在k x 处展成一阶泰勒公式,忽略高次项,有()()()()k k k f x f x f x x x '≈+-。右端是直线方程,用这个直线方程来近似非线性方程()f x 。将非线性方程()0f x =的根
*x 代入*()0f x =,即
*()()()0k k k f x f x x x '+-≈
解得*()
()
k k k f x x x f x ≈-
' 这就是Newton 迭代公式。 在具体的应用中,写为:1()
()
k k k k f x x x f x +=-',则这样获得的1k x +即为按Newton 迭代法求得的近似解。
(3)弦截法 算法分析
由于Newton 迭代法有时收敛速度较慢,而且有时函数的一阶导数()f x '不易
求得或较为复杂,因此,改用两个端点都在变动的弦,即用差商11
()()
k k k k f x f x x x ----替
代Newton 迭代公式中的导数()f x ',从而导出
111()
()()()
k k k k k k k f x x x x x f x f x +--=---。这就是双点弦截法。
双点弦截法详细的计算步骤为:
1)选定初始值01,x x ,计算0()f x ,1()f x 。 2)按双点弦法迭代公式计算2x ,并求2()f x 。
3)判断:如果2(),f x εε<给定精度,则迭代停止;否则,用22(,())x f x 和11(,())x f x 分别代替1100(,())(,())x f x x f x 和重复2)和3)。
(4)牛顿下山法 算法分析
Newton 下山法是扩大初值范围的修正Newton 法。将Newton 迭代法的计算
结果1()
()
k k k k f x x x f x +=-'进行适当的加权平均作为新的改进值1k x +,即
11(1)k k k x x x λλ++=+-。从而化简可得Newton 下山法迭代公式
1()
()
k k k k f x x x f x λ
+=-' 其中,λ称为下山因子。在本实验中,选取1
4
λ=为下山因子。
2.源代码
#include "math.h" #include
typedef double D;
double f(D x);
double fnewton(D x);
void divide(D a1,D a2); void newton(D a1); void cord(D a1,D a2);
void newton2(D a1);
using namespace std;
double f(D x)
{
return pow(x,5)-6*pow(x,3)+x-1;
}
double fnewton(D x)
{
if((5*pow(x,4)-9*pow(x,2)+1)!=0)
return (pow(x,5)-3*pow(x,3)-1)/(5*pow(x,4)-9*pow(x,2)+1);
else
return 1;
}
void divide(D a1,D a2)
{
for(;fabs(fabs(a1)-fabs(a2))>=1e-6;)
{
if(f(a1)*f((a1+a2)/2)<0)
a2=(a1+a2)/2;
else
a1=(a1+a2)/2;
}
cout< } void newton(D a1) { for(;fabs(fabs(a1)-fabs(a1-fnewton(a1)))>=1e-6;) a1-=fnewton(a1); cout<<"Newton法求得的结果是:"< //return 0; } void cord(D a1,D a2) { int n=0; for(;fabs(f(a2-f(a2)*(a2-a1)/(f(a2)-f(a1)))-0)>=1e-6;n++) { if(n==50) break; else { if(f(a2-f(a2)*(a2-a1)/(f(a2)-f(a1)))*f(a1)>0||(f(a2)-f(a1))!=0) a1=a2-f(a2)*(a2-a1)/(f(a2)-f(a1)); else a2=a2-f(a2)*(a2-a1)/(f(a2)-f(a1)); } } if(n==50) cout<<"双点弦法求解失败!!"< else