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 <stdlib.h>
#include <string.h>// 计算矩阵的逆
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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>#include "newton.h"
#define  MATH_E   2.7182818285
#define  MATH_PI  3.1415926536void 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实现)相关推荐

  1. 求解非线性方程组的牛顿法c语言,牛顿下山法求解非线性方程(组)(C实现)...

    1.算法描述 (1)符号说明与基本假设 对于非线性方程组:                                                        (1) 引入向量: 可将(1) ...

  2. matlab中牛顿下山法实例,非线性方程的数值解法牛顿下山法matlab

    非线性方程的数值解法牛顿下山法matlab 1 非线性方程的数值解法 --计算物理实验作业九 陈万 物理学2013级 130******** ● 题目: 用下列方法求0133=--=x x f(x)在 ...

  3. matlab中牛顿下山法实例,非线性方程的数值解法牛顿下山法matlab.docx

    非线性方程的数值解法牛顿下山法matlab.docx 1 非线性方程的数值解法 --计算物理实验作业九 陈万 物理学2013级 13020011006  题目: 用下列方法求 在 附近的根.根的准确 ...

  4. 5 matlab详解牛顿下山法求解复杂函数代数方程和超越方程

    5.1 题目 5.2 问题背景 在工程和科学技术中,许多问题常归结为求解函数方程: f(x) = 0 如何求方程 f(x) = 0 的根是一个古老的数学问题,5 次以上的代数方程和超越方程一般没有求根 ...

  5. Matlab学习手记——非线性方程组求解:牛顿下山法

    功能:牛顿下山法求解非线性方程组. 牛顿下山法 function [x, n] = NonLinearEquations_NewtonDown(x0, err) %{ 函数功能:牛顿下山法求解非线性方 ...

  6. 非线性方程的数值解法:牛顿法及牛顿下山法(含Matlab程序)

    牛顿法及牛顿下山法 简介:牛顿迭代法是求解单变量非线性方程f(x)=0中最实用的方法,该方法在单根附近二阶收敛.但应用时要选用较好的初值x0近似才能保证迭代收敛.为克服这一缺点,可使用牛顿下山法.下面 ...

  7. matlab 牛顿法 初值,非线性方程的数值解法:牛顿法及牛顿下山法(含Matlab程序)...

    牛顿法及牛顿下山法 简介:牛顿迭代法是求解单变量非线性方程f(x)=0中最实用的方法,该方法在单根附近二阶收敛.但应用时要选用较好的初值x0近似才能保证迭代收敛.为克服这一缺点,可使用牛顿下山法.下面 ...

  8. 利用牛顿公式求解方程的根并且实现牛顿下山法

    实验要求 a. 实现牛顿公式,并分别找到收敛和发散的例子 算法介绍 牛顿公式原理如下图: 为了防止牛顿迭代发散并且加速迭代速度,所以我们在这里引入一个新的方法-- 牛顿下山法: 根据牛顿公式原理以及牛 ...

  9. matlab实现牛顿下山法

    说起牛顿下山法,首先要提牛顿法,牛顿法是求解非线性方程的一个重要方法,具体可以点击牛顿法:虽然牛顿法作为一个二阶的迭代收敛方法,但是其对于函数和初始点的要求都比较高,而牛顿下山法则是有效降低这些要求的 ...

最新文章

  1. 嵌入式Linux操作系统学习规划,学习嵌入式开发需要哪些知识?
  2. 高并发编程-Thread_正确关闭线程的三种方式
  3. RHEL 6.3使用CentOS yum源 (redhat yum安装失败)
  4. 数据库事务的四大特性以及事务的隔离级别详解
  5. 计算机考试如何添加打印机,如何添加网络打印机?
  6. 正交矩阵和Gram-Schmidt正交化
  7. 消息队列(MQ)比较
  8. 区块链底层架构概览:第一原则框架
  9. 逻辑机房(LDC)是什么
  10. MATLAB图像的频域低通滤波(灰度图像滤波+彩色图像滤波)
  11. 招投标概念及注意事项
  12. 小米4充不了电处理办法(图文)小米4不能充电的维修教程
  13. 黑苹果开启——HiDPI 技术
  14. 用js实现背景颜色改变
  15. 分布式系统的知识点-架构设计
  16. 二叉树、平衡二叉树、红黑树、B-树、B+树、B*树、T树之间的详解和比较
  17. 如何连接苹果电脑打印服务器
  18. mysql基于SSM框架的众筹平台设计 毕业设计源码211755
  19. python计算点到面的距离
  20. Mysql登录报错:Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)

热门文章

  1. 敏捷方法 - 极限编程与工程实践
  2. mySQL 2502 2503错误
  3. 细数 GameFi 模型发展 ,未来仍可期?
  4. asp.net core ABP模板本地化设置
  5. Linux/Unix关机、重启(shutdown\reboot\halt\init)等命令
  6. java泛型 方法返回值带有泛型 <T>
  7. 1. Python和Java、PHP、C、C#、C++等其他语言的对比?
  8. 浅析新媒体运营工作内容
  9. 给深度学习模型构建数据迭代器
  10. TensorFlow-SSD测试代码梳理