求解非线性方程组的牛顿法c语言,牛顿下山法求解非线性方程(组)(C实现)...
1、算法描述
(1)符号说明与基本假设
对于非线性方程组:
(1)
引入向量:
可将(1)式改写为
(2)
通常考虑方程(2)只有唯一解的情形。
(2)牛顿下山算法
引入下山因子λ,产生一下计算格式:
下山因子λ一般依次取1、1/2、1/4、1/8、……
其中
计算步骤为:
2、C语言实现
newton.h头文件:
#ifndef __NEWTON_H__
#define __NEWTON_H__
// 牛顿下山法求解非线性方程(组)
int newton( double** X0
, int n
, double lmada
, double eps_x
, double eps_f
, void (*f)( double** X, int n)
, void (*df)(double** X, int n)
);
#endif
newton.c文件
#include "newton.h"
#include
#include
// 计算矩阵的逆
static int inverse( double** dfX, int n )
{
int i, j,k, p;
double maxV, tmp;
double* A = *dfX;
double* T = (double*)malloc(sizeof(double) * n * n);
double* tArr = (double*)malloc(sizeof(double) * n);
int row_size = sizeof(double) * n;
memset( T, 0, sizeof(double)*n*n);
for ( i = 0; i < n; ++i )
{
T[i*n+i] = 1.0;
}
for ( j = 0; j < n; ++j )
{
p = j;
tmp = A[j*n+j];
maxV = (tmp>=0)?(tmp):(-tmp);
for ( i = j +1; i < n; ++i )
{
tmp = A[i*n+j];
if ( tmp < 0 ) tmp = -tmp;
if ( maxV < tmp )
{
p = i;
maxV = tmp;
}
}
if ( maxV < 1e-20 )
{
return -1;
}
if ( j != p )
{
memcpy( tArr, A+j*n, row_size);
memcpy( A+j*n, A+p*n, row_size);
memcpy( A+p*n, tArr, row_size);
memcpy( tArr, T+j*n, row_size);
memcpy( T+j*n, T+p*n, row_size);
memcpy( T+p*n, tArr, row_size);
}
tmp = A[j*n+j];
for ( i = j; i < n; ++i ) A[j*n+i] /= tmp;
for ( i = 0; i < n; ++i ) T[j*n+i] /= tmp;
for ( i = 0; i < n; ++i )
{
if ( i != j )
{
tmp = A[i*n+j];
for ( k = j; k < n; ++k )
A[i*n+k] -= tmp * A[j*n+k];
for ( k = 0; k < n; ++k )
T[i*n+k] -= tmp * T[j*n+k];
}
}
}
memcpy( A, T, row_size * n );
free( T );
free( tArr );
return 0;
}
// 计算步长dx
static void calc_dx( double** dx
, double* df
, double* dfx
, double lamda
, int n
)
{
int i, j;
double* x = *dx;
memset( x, 0, sizeof(double) * n);
for ( i = 0; i < n; ++i )
{
for ( j = 0; j < n; ++j )
{
x[i] += -lamda * df[j] * dfx[i*n+j];
}
}
}
// 计算向量的无穷范数
static double norm_inf( double* A, int n )
{
int i;
double t = A[0];
double ret = t;
if ( t < 0 )
{
ret = -t;
}
for ( i = 1; i < n; ++i )
{
t = A[i];
if ( t < 0 ) t = -t;
if ( ret < t ) ret = t;
}
return ret;
}
// 牛顿下山法求解非线性方程组,求解成功返回0,失败返回-1
int newton ( double** X0 // 迭代起始点
, int n // 方程组维数
, double lamda // 起始下山因子
, double eps_x // 阈值
, double eps_f // 阈值
, void (*f)( double** X, int n) // 带求解非线性方程组函数
, void (*df)(double** X, int n) // 带求解非线性方程组的导函数(Jacobi矩阵)
)
{
int i, ret = 0;
int row_size = sizeof(double) * n;
double* X = *X0;
double* dx = (double*)malloc( row_size );
double* fX = (double*)malloc( row_size );
double* dfX = (double*)malloc( n * row_size );
double max_f, max_f1;
memcpy( fX, X, row_size );
f ( &fX, n );
for ( ;; )
{
memcpy( dfX, X, row_size);
df( &dfX, n );
ret = inverse( &dfX, n ); // 计算逆
if ( ret < 0 ) // Jacobi矩阵不可逆
{
goto end;
}
calc_dx( &dx, fX, dfX, lamda, n); // 计算步长
max_f = norm_inf( fX, n );
for ( i = 0; i < n; ++i )
{
X[i] += dx[i];
}
memcpy( fX, X, row_size);
f( &fX, n );
max_f1 = norm_inf( fX, n );
if ( max_f1 < max_f )
{
if ( norm_inf( dx, n ) < eps_x )
{
break;
}
else
{
continue;
}
}
else
{
if ( max_f1 < eps_f )
{
break;
}
else
{
lamda /= 2.0;
}
}
}
end:
free( dx );
free( fX );
free( dfX);
return ret;
}
3、测试
考虑用牛顿下山法求解以下非线性方程组:
求解以上方程的主程序:
#include
#include
#include
#include
#include "newton.h"
#define MATH_E 2.7182818285
#define MATH_PI 3.1415926536
void f( double** X, int n )
{
assert( n == 3 );
double* A = *X;
double x = A[0];
double y = A[1];
double z = A[2];
A[0] = 3*x-cos(y*z)-0.5;
A[1] = x*x-81*(y+0.1)*(y+0.1)+sin(z)+1.06;
A[2] = pow( MATH_E, -x*y)+20*z + 10*MATH_PI/3.0-1;
}
void df( double** X, int n )
{
assert( n == 3 );
double* A = *X;
double x = A[0];
double y = A[1];
double z = A[2];
A[0] = 3.0;
A[1] = z * sin(y*z);
A[2] = y * sin(y*z);
A[3] = 2*x;
A[4] = -162.0*(y+0.1);
A[5] = cos(z);
A[6] = -y * pow( MATH_E, -x*y);
A[7] = -x * pow( MATH_E, -x*y);
A[8] = 20.0;
}
int main()
{
int n = 3;
double* X = (double*)malloc(sizeof(double)*n);
X[0] = 1.0;
X[1] = 1.0;
X[2] = 1.0;
double eps_x = 1e-14;
double eps_f = eps_x;
double lamda = 1.0;
newton( &X, n, lamda, eps_x, eps_f, f, df);
printf("%f\t%f\t%f", X[0], X[1], X[2]);
free( X );
return 1;
}
计算结果:
x = 0.500000
y = -0.000000
z = -0.523599
求解非线性方程组的牛顿法c语言,牛顿下山法求解非线性方程(组)(C实现)...相关推荐
- 牛顿下山法求解非线性方程(组)(C实现)
1.算法描述 (1)符号说明与基本假设 对于非线性方程组: (1) 引入向量: 可将(1) ...
- 5 matlab详解牛顿下山法求解复杂函数代数方程和超越方程
5.1 题目 5.2 问题背景 在工程和科学技术中,许多问题常归结为求解函数方程: f(x) = 0 如何求方程 f(x) = 0 的根是一个古老的数学问题,5 次以上的代数方程和超越方程一般没有求根 ...
- matlab中牛顿下山法实例,非线性方程的数值解法牛顿下山法matlab
非线性方程的数值解法牛顿下山法matlab 1 非线性方程的数值解法 --计算物理实验作业九 陈万 物理学2013级 130******** ● 题目: 用下列方法求0133=--=x x f(x)在 ...
- matlab中牛顿下山法实例,非线性方程的数值解法牛顿下山法matlab.docx
非线性方程的数值解法牛顿下山法matlab.docx 1 非线性方程的数值解法 --计算物理实验作业九 陈万 物理学2013级 13020011006 题目: 用下列方法求 在 附近的根.根的准确 ...
- Matlab学习手记——非线性方程组求解:牛顿下山法
功能:牛顿下山法求解非线性方程组. 牛顿下山法 function [x, n] = NonLinearEquations_NewtonDown(x0, err) %{ 函数功能:牛顿下山法求解非线性方 ...
- 迭代法求解非线性方程组(含python代码)
1. 迭代法求解非线性方程组的原理 参考西安交大数值分析教材 2. 迭代法求解非线性方程组的计算过程 牛顿法求解非线性方程组的计算过程如下 弦割法与牛顿法类似,弦割法将牛顿法中的偏导数 ...
- 牛顿法和牛顿下山法求极值的理解
泰勒展开 先创建一个不太方便求解的方程sinx=−0.01ex\sin x=-0.01e^xsinx=−0.01ex,并用matlab画出来y=sinx+0.01exy=\sin x+0.01e^ ...
- MATLAB之牛顿下山法
MATLAB之牛顿下山法 算法原理 matlab程序 算法原理 上一篇博客,我介绍了牛顿法迭代法,接下来我就们接着讲解一下什么是牛顿下山法. 一.迭代公式 在牛顿迭代过程中,若满足单调性|f(x(k+ ...
- python牛顿法解非线性方程组_matlab实现牛顿迭代法求解非线性方程组.pdf
matlab实现牛顿迭代法求解非线性方程组.pdf matlab 实现牛顿迭代法求解非线性方程组实现牛顿迭代法求解非线性方程组 已知非线性方程组如下 3*x1-cosx2*x3-1/20 x12-81 ...
最新文章
- 关于C语言中的malloc和free函数的用法
- 偏见与人类大脑结构有关
- 转在同一个sql语句中如何写不同条件的count数量
- c++析构相关-待看
- 关于OSPF用反掩码
- java 循环 基本类型
- 去除utf8文件的bom标记
- g++: internal compiler error: Killed (program cc1plus)Please submit a full bug report,内存不足问题解决
- 创世纪游戏、黄金分割比
- 从备用类型总盗用steal page
- android客户端与服务器端的搭建,android客户端与服务器端的搭建.ppt
- 高中英语语法(002)-否定
- 2022-2028年中国工业互联网预测性维护(PdM)行业市场调查及未来前景预测报告
- mysql中的int(11)到底代表什么意思?
- 从头来过教你PHP脚本语言(先导篇)
- [BZOJ 3653]谈笑风生
- redhat 复制文件夹及子文件夹_linux如何复制文件夹和移动文件夹
- 【注意力模型】Harmonious Attention Network for Person Re-Identification
- 学习感悟-如何养成良好的编程习惯
- ABAP: 循环加和查询