【Android】非线性方程的求解寻根

目录

前言:

一、Apache-commons-math3介绍

二、具体简单实例

2.1 导入函数类

2.2 定义函数接口

2.3 使用求解器

2.3.1 布伦特法(Brent)

2.3.2 米勒(Muller)法

2.3.3 Newton-Raphson法 


前言:

        最近在Android app实时显示数据上遇到了个问题,就是获取的数据需要进行转换。这里的转换公式为双指数函数,反函数不好转化出一个式子,需要实现非线性方程的求解寻根。

        以往完成这个操作,我是在matlab定义函数式用fslove求解来完成这件事情,我在思考是否可以在Android app上实现这一点。经过一些调研,的确是可以的,可以使用Apache-commons-math3来实现。

一、Apache-commons-math3介绍

        Apache-commons-math3是java的一种科学计算库,平日里接触数学计算更多是在matlab或者python上实现,在Android Java上实现的相关资料比较少。这里简要简要介绍一下apache-commons-math3,大致了解它能够做些什么,详细的使用可以去研究官方文档。

        math3可以支持的功能如下所示:

  • 支持常用的矩阵操作,例如矩阵转置、求逆以及加减乘除等
  • 支持矩阵分解操作,例如LU分解、QR分解、奇异值分解、特征值分解等
  • 可以实现一些数理统计的方法,例如t检验、卡方检验等等
  • 可以实现一些基本的数值方法,例如插值、曲线拟合、积分、最小二乘、线性回归等等
  • 可以实现非线性方程组的求解寻根。

        其中矩阵的运算是可以应用到多个场景,例如线性方程组求解、图像处理、信号处理以及机器学习和数据分析等;信号处理方面,常见的如傅里叶变换以及滤波处理;对于机器学习和数据分析,常见的特征矩阵被用于存储数据特征,线性代数中的运算方法常应用于模型训练和预测。

二、具体实例

        以上apache-commons-math3有很多的功能,这里我只讲述非线性方程组求解的实例。实现双指数单变量函数的求解寻根。

2.1 导入函数类

import org.apache.commons.math3.analysis.UnivariateFunction;   //单变量实数类
import org.apache.commons.math3.analysis.solvers.BrentSolver;   //布伦特法
import org.apache.commons.math3.analysis.solvers.MullerSolver;  //米勒(Muller)法
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; //处理函数微分的类
import org.apache.commons.math3.analysis.solvers.NewtonRaphsonSolver;//Newton-Raphson法
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;//函数类
import org.apache.commons.math3.exception.DimensionMismatchException;

2.2 定义函数接口

        这里我们先进行初始化,这里是使用了单变量实函数类UnivariateFunction,对应方法布伦特法和米勒法。函数较为复杂,双指数函数:3323 * exp(-5.647 * x) + 239.2 * exp(-0.5883 * x) - data。注:data为实时获取的数据。

UnivariateFunction function = new UnivariateFunction() {
@Override
	public double value(double x) {
    //data为实时获取的数据
	return (3323 * Math.exp(-5.647 * x) + 239.2 * Math.exp(-0.5883 * x) - data); 
	}
};

2.3 使用求解器

        这里讲述一些我应用实践的求解器,求解函数方程的根。

2.3.1 布伦特法(Brent)

/*初始化求解器*/
/*布伦特法(混合寻根算法,结合了平方法、分割法和逆二次插值法)
* */
BrentSolver brentSolver = new BrentSolver(1e-9);

/*求根*/
/*迭代次数、函数以及最小值和最大值*/
/*0.5ms*/
double res = brentSolver.solve(500,function,-5,8);

2.3.2 米勒(Muller)法

/*初始化求解器*/
/*米勒法*/
MullerSolver mullerSolver = new MullerSolver(1e-9);

/*求根*/
/*迭代次数、函数以及最小值和最大值*/
double res = mullerSolver.solve(500,function,-10,10);

2.3.3 Newton-Raphson法 

//需要用到微分
//定义函数
UnivariateDifferentiableFunction function = new UnivariateDifferentiableFunction() {
	@Override
	public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
		double x = t.getValue();
		double result = (3323 * Math.exp(-5.647 * x) + 239.2 * Math.exp(-0.5883 * x) - data);
		//返回函数值以及一阶导数
		return new DerivativeStructure(1,1,0,result);
	}

	@Override
	public double value(double x) {
		return (3323 * Math.exp(-5.647 * x) + 239.2 * Math.exp(-0.5883 * x) - resistence);
	}
};
NewtonRaphsonSolver newtonRaphsonSolver = new NewtonRaphsonSolver(1e-9);
//迭代次数、函数以及初始值
double res = newtonRaphsonSolver.solve(500,function,0);

你可能感兴趣的:(Java,数值计算,Android,java,数值计算)