数学:非线性方程的求解---(笔记+代码)

来源:互联网 发布:java断点下载 编辑:程序博客网 时间:2024/06/04 19:50

这里写图片描述
这里写图片描述
这里写图片描述

code:

/** *求解f(x) = x^4 - x - 2  *求解步骤 *1、对于给出的函数f(x),编写一个函数与之对应function() *2、使用给定的算法进行求解f(x) = 0 */Double function(Double x){    return pow(x,4) - x - 2;}/** *sign(x)符号函数,小于0返回0,否则返回1 */bool sign(Double x){    return x > 0;}Double dabs(Double x){    if(x < 0) x = -x;     return x;}/** *二分法的代码实现 *参数是区间(a,b),而且 *f(a)f(b) < 0 *我们可以不指定a,b,使用试探法进行 *自动的a,b赋值,但是这种方法并不保险 */Double binary_calcutateX(Double a,Double b){    if(function(a) * function(b) > 0) return 0;//不满足条件    if(function(a) == 0) return a;      if(function(b) == 0) return b;    Double x;    while(dabs(b - a) > ERR){        x = a+(b-a)/2;        if(sign(function(x)) == sign(function(a))){            a = x;        }        else{            b = x;        }    }    return a + (b-a)/2; }

这里写图片描述
这里写图片描述
code:

/** *不动点迭代法 *参数x0 *需要用到f(x)的变形x = h(x) = x^4 - 2 *或者x = h(x) = (x+1)^(1/4) *注意这个变换形式很重要 */Double h(Double x){     return pow(x,4) - 2;}Double h1(Double x){        return pow(x+2,1.0/4);}Double staticNode(Double x){//初始值不同时,会找到距离这个初始值最近的根    int k = 0;//记录迭代的次数     Double x1 = x;    while(dabs(function(x)) > ERR1 || dabs(x1 - x) > ERR2){        x = x1;        //x1 = h(x);                x1 = h1(x);         k += 1;    }    return x;}

这里写图片描述
应用和问题:
一般可以用来求一个数n的平方根a;
1、无法保证全局收敛性
2、要求f(x)在其根值附近有连续的2阶导数
3、每一次计算都要计算f’(x),计算量大,一般用在f’(x)确定的情况下
Code:

/** *牛顿迭代法 *参数:x0 *需要导函数ff *///f(x) = x^4 - x - 2的导函数Double ff(Double x){    return 4*pow(x,3) - 1;}Double niudun(Double x){    int k = 0;//记录迭代的次数    Double x1 = x;      while(dabs(function(x)) > ERR1 || dabs(x1 - x) > ERR2){        x = x1;             x1 = x - function(x)/ff(x);             k += 1;    }    return x;}

这里写图片描述
Code:

/** *平行弦法 *参数:x0 *需要导函数ff */Double parallel(Double x){    int k = 0;//记录迭代的次数    Double xx = ff(x);      Double x1 = x;      while(dabs(function(x)) > ERR1 || dabs(x1 - x) > ERR2){        x = x1;             x1 = x - function(x)/xx;                k += 1;    }    return x;}

这里写图片描述
这里写图片描述

Code:

/** *割线法 *参数:x0,x1 *!!!!!!这个代码对这个样例出现的死循环 */Double gexian(Double x0,Double x1){    int k = 0;//记录迭代的次数    Double x2 = x1;     while(dabs(function(x1)) > ERR1 || dabs(x1 - x0) > ERR2){        cout<<x0<<" "<<function(x0)<<endl;        cout<<x1<<" "<<function(x1)<<endl;        x2 = x1 - function(x1)/(function(x1) - function(x0));//注意除0错误        x0 = x1;        x1 = x2;            k += 1;    }    return x1;}

这里写图片描述

测试代码和头文件代码:
头文件head.h

#include<iostream>#include<stdio.h>#include<algorithm>#include<math.h>using namespace std;typedef long double Double;const Double ERR = 1e-4;const Double ERR1 = 1e-4;const Double ERR2 = 1e-4;

测试代码:

#include "head.h"int main(){    Double x5 = 0,x4 = 0,x3 = 0,x2 = 0,x1 = 0,a = 1.0,b = 1.5;    x1 = binary_calcutateX(a,b);    x2 = staticNode(b);    x3 = niudun(b);     x4 = parallel(b);       //x5 = gexian(a,b);     cout<<"x1 = "<<x1<<endl;    cout<<"f(x1) = "<<function(x1)<<endl;    cout<<"x2 = "<<x2<<endl;    cout<<"f(x2) = "<<function(x2)<<endl;    cout<<"x3 = "<<x3<<endl;    cout<<"f(x3) = "<<function(x3)<<endl;    cout<<"x4 = "<<x4<<endl;    cout<<"f(x4) = "<<function(x4)<<endl;    //cout<<"x5 = "<<x5<<endl;    //cout<<"f(x5) = "<<function(x5)<<endl;    return 0;}
原创粉丝点击