数值计算——求解非线性方程组
2017-04-30 22:49
281 查看
数值计算——求解非线性方程组
上一篇是求解的非线性方程,但是并不能简单的扩展到n维的情况下。下面是使用牛顿法和割线法求解非线性方程组:1、牛顿法
需要求方程组的雅克比矩阵,即对每个变量求偏导:算法:
代码:
package com.kexin.lab7; import com.kexin.lab3.*; /** * 牛顿法求解非线性方程组 * @author KeXin * */ public class Newton { static final double tol = 0.00001; /** * 返回函数值的取反,这里处理的函数是: * (x1+3)(x2^3-7)+18=0 * sin(x2*e^x1-1)=0 * @param x * @return */ public static double[] Function(double[] x){ double[]result = new double[2]; double x1 = x[0]; double x2 = x[1]; //书上例题测试 // result[0] = -(x1+2*x2-2); // result[1] = -(Math.pow(x1, 2)+4*Math.pow(x2, 2)-4); //实验题目 result[0] = -((x1+3)*(Math.pow(x2, 3)-7)+18); result[1] = -(Math.sin((x2*Math.pow(Math.E, x1)-1))); return result; } /** * 返回上面函数对应的Jacobi矩阵 * @param x * @return */ public static double[][] FunctionJ(double[] x){ double[][] result = new double[2][2]; double x1 = x[0]; double x2 = x[1]; //书上例题测试 // result[0][0] = 1; // result[0][1] = 2; // result[1][0] = 2*x1; // result[1][1] = 8*x2; //实验题目 result[0][0] = Math.pow(x2, 3)-7; result[0][1] = (3*x1+9)*Math.pow(x2, 2); double e = Math.E; double temp = Math.cos((x2*Math.pow(e, x1)-1))*Math.pow(e, x1); result[1][0] = x2*temp; result[1][1] = temp; return result; } public static double[] NewtonF(double[]x0){ double[] f ; double[][] j ; double[] s; double r; double[] x = {0,1}; int time = 0; while(true){ time++; f = Function(x0); if(Math.abs(f[0])<tol&&Math.abs(f[1])<tol){ break; } j = FunctionJ(x0); DieDai.PrintArray("x", x0); DieDai.PrintArray("-F", f); DieDai.Print2DArray("J", j); s = DieDai.SOR(j, f,0.2); DieDai.PrintArray("s", s); r = Math.sqrt((Math.pow(x[0]-x0[0], 2)+Math.pow(x[1]-x0[1],2))); System.out.println("r:"+r); x0 = AddFunction(x0, s); } System.out.println("time = "+time); return x0; } public static void main(String[] args) { //定义初值x0 // double[] x0 = {1,2}; //书上例题测试 double[] x0 = {-0.5,1.4}; //实验题目 double[] result = NewtonF(x0); DieDai.PrintArray("result", result); DieDai.PrintArray("-F", Function(result)); } /** * 转置行矩阵 * * @param a * @return */ public static double[][] Transposition1(double[] a) { int len = a.length; double[][] result = new double[len][1]; for (int i = 0; i < len; i++) { result[i][0] = a[i]; } return result; } /** * 一维数组矩阵加法 * @param x1 * @param x2 * @return */ public static double[] AddFunction(double[]x1,double[]x2){ int row = x1.length; double[] result = new double[row]; for(int i = 0;i<row;i++){ result[i] = x1[i]+x2[i]; } return result; } }
2、割线法
割线法是牛顿法的变形之一,牛顿法是使用导数即割线逼近正确解,而割线法则是选择两点的连线即曲线的割线逼近正确解:代码:
broyden.m
function [time,x,f] = broyden() x = [-0.5;1.4] B=[1,2;2,6]; i = 0 time = 0 while i<1 time = time + 1 f=caculatef(x); s=inv(B)*f; s=-s; x=x+s; y=caculatef(x)-f; B=B+inv((s'*s))*(y-B*s)*s'; if s(1,1)^2+s(2,1)^2<0.00001 i=2 end end end
Caculatef.m:
function [f] = caculatef(x) f(1,1)=(x(1,1)+3)*(x(2,1)^3-7)+18; f(2,1)=sin(x(2,1)*exp(x(1,1))-1); end
相关文章推荐
- 数值计算-线性方程组求解(2)-追赶法解三对角矩阵-MATLAB实现
- 数值计算线性方程组求解实现
- 数值计算-线性方程组求解(0)
- 数值计算——一维非线性方程求解
- 数值计算方程求解实现
- Matlab 数值计算----二分法求非线性方程组
- [数值计算]1,线性方程的三角分解法求解
- 数值计算方法:二分法求解方程的根(伪代码 python c/c++)
- 数值计算一阶常微分方程求解实现
- Matlab 数值计算----迭代法计算非线性方程组在指定区间的根
- 数值计算-线性方程组求解(1)-LU分解-MATLAB实现
- 数值计算 && 实验8 && Gauss-Seidel迭代法求解线性方程组
- 数值计算方法 求解初值问题(伪代码 c/c++ python)
- PHP中字符串类型与数值类型混合计算
- 读取txt文档中的数值,有一定的协议,读取后求和,并计算出平均值
- 开源Math.NET基础数学类库使用(06)数值分析之线性方程组直接求解
- GreenPlum常用数值计算函数
- css中数值计算
- 计算方法实验二实验报告 非线性方程求根
- 二分法求解超大项的斐波那契数列数值