LM算法代码_快速排序算法代码

LM算法代码_快速排序算法代码LM算法+推导+C++代码实践一、算法推导二、代码实践参考一、算法推导二、代码实践#include<Eigen/Dense>#include<Eigen/Sparse>#include<iostream>#include<iomanip>#include<math.h>usingnamespacestd;usingnamespaceEigen;constdoubleDERIV_STEP=1

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

LM算法+推导+C++代码实践

一、算法推导

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、代码实践

#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <iostream>
#include <iomanip>
#include <math.h>

using namespace std;
using namespace Eigen;

const double DERIV_STEP = 1e-5;
const int MAX_ITER = 100;

#define max(a,b) (((a)>(b))?(a):(b))

double func(const VectorXd& input, const VectorXd& output, const VectorXd& params, double objIndex)
{ 
   
	// obj = A * sin(Bx) + C * cos(D*x) - F
	double x1 = params(0);
	double x2 = params(1);
	double x3 = params(2);
	double x4 = params(3);

	double t = input(objIndex);
	double f = output(objIndex);

	return x1 * sin(x2 * t) + x3 * cos(x4 * t) - f;
}

//return vector make up of func() element.
VectorXd objF(const VectorXd& input, const VectorXd& output, const VectorXd& params)
{ 
   
	VectorXd obj(input.rows());
	for (int i = 0; i < input.rows(); i++)
		obj(i) = func(input, output, params, i);

	return obj;
}

//F = (f ^t * f)/2
double Func(const VectorXd& obj)
{ 
   
	//平方和,所有误差的平方和
	return obj.squaredNorm() / 2;
}

double Deriv(const VectorXd& input, const VectorXd& output, int objIndex, const VectorXd& params,
	int paraIndex)
{ 
   
	VectorXd para1 = params;
	VectorXd para2 = params;

	para1(paraIndex) -= DERIV_STEP;
	para2(paraIndex) += DERIV_STEP;

	double obj1 = func(input, output, para1, objIndex);
	double obj2 = func(input, output, para2, objIndex);

	return (obj2 - obj1) / (2 * DERIV_STEP);
}

MatrixXd Jacobin(const VectorXd& input, const VectorXd& output, const VectorXd& params)
{ 
   
	int rowNum = input.rows();
	int colNum = params.rows();

	MatrixXd Jac(rowNum, colNum);

	for (int i = 0; i < rowNum; i++)
	{ 
   
		for (int j = 0; j < colNum; j++)
		{ 
   
			Jac(i, j) = Deriv(input, output, i, params, j);
		}
	}
	return Jac;
}
double maxMatrixDiagonale(const MatrixXd& Hessian)
{ 
   
	int max = 0;
	for (int i = 0; i < Hessian.rows(); i++)
	{ 
   
		if (Hessian(i, i) > max)
			max = Hessian(i, i);
	}

	return max;
}
//L(h) = F(x) + h^t*J^t*f + h^t*J^t*J*h/2
//deltaL = h^t * (u * h - g)/2
double linerDeltaL(const VectorXd& step, const VectorXd& gradient, const double u)
{ 
   
	double L = step.transpose() * (u * step - gradient);
	return L;
}

void levenMar(const VectorXd& input, const VectorXd& output, VectorXd& params)
{ 
   
	int errNum = input.rows();      //error num
	int paraNum = params.rows();    //parameter num

	//initial parameter 
	VectorXd obj = objF(input, output, params);     //得到误差
	MatrixXd Jac = Jacobin(input, output, params);  //得到雅可比矩阵
	MatrixXd A = Jac.transpose() * Jac;             //Hessian矩阵,此处为4x4的矩阵
	VectorXd gradient = Jac.transpose() * obj;      //gradient

	//initial parameter tao v epsilon1 epsilon2
	double tao = 1e-3;
	long long v = 2;
	double eps1 = 1e-12, eps2 = 1e-12;
	double u = tao * maxMatrixDiagonale(A);   //找到雅可比矩阵对角线上最大的值,并乘tao
	bool found = gradient.norm() <= eps1;     //判断是否小于阈值,小于这个阈值,即可退出。
	if (found) return;

	double last_sum = 0;
	int iterCnt = 0;

	while (iterCnt < MAX_ITER)
	{ 
   
		VectorXd obj = objF(input, output, params);

		MatrixXd Jac = Jacobin(input, output, params);  //jacobin
		MatrixXd A = Jac.transpose() * Jac;             //Hessian
		VectorXd gradient = Jac.transpose() * obj;      //gradient

		if (gradient.norm() <= eps1)
		{ 
   
			cout << "stop g(x) = 0 for a local minimizer optimizer." << endl;
			break;
		}

		cout << "A: " << endl << A << endl;

		VectorXd step = (A + u * MatrixXd::Identity(paraNum, paraNum)).inverse() * gradient; //negtive Hlm.

		cout << "step: " << endl << step << endl;

		if (step.norm() <= eps2 * (params.norm() + eps2))
		{ 
   
			cout << "stop because change in x is small" << endl;
			break;
		}

		VectorXd paramsNew(params.rows());
		paramsNew = params - step; //h_lm = -step;

		//compute f(x)
		obj = objF(input, output, params);

		//compute f(x_new)
		VectorXd obj_new = objF(input, output, paramsNew);

		double deltaF = Func(obj) - Func(obj_new);
		double deltaL = linerDeltaL(-1 * step, gradient, u);

		double roi = deltaF / deltaL;
		cout << "roi is : " << roi << endl;
		if (roi > 0)
		{ 
   
			params = paramsNew;
			u *= max(1.0 / 3.0, 1 - pow(2 * roi - 1, 3));
			v = 2;
		}
		else
		{ 
   
			u = u * v;
			v = v * 2;
		}
		cout << "u = " << u << " v = " << v << endl;

		iterCnt++;
		cout << "Iterator " << iterCnt << " times, result is :" << endl << endl;
	}
}
int main(int argc, char* argv[])
{ 
   
	// obj = A * sin(Bx) + C * cos(D*x) - F
	//there are 4 parameter: A, B, C, D.
	int num_params = 4;

	//generate random data using these parameter
	int total_data = 100;

	VectorXd input(total_data);
	VectorXd output(total_data);

	double A = 5, B = 1, C = 10, D = 2;
	//load observation data
	for (int i = 0; i < total_data; i++)
	{ 
   
		//generate a random variable [-10 10]
		double x = 20.0 * ((rand() % 1000) / 1000.0) - 10.0;
		double deltaY = 2.0 * (rand() % 1000) / 1000.0;
		double y = A * sin(B*x) + C * cos(D*x) + deltaY;

		input(i) = x;
		output(i) = y;
	}

	//gauss the parameters
	VectorXd params_gaussNewton(num_params);
	//init gauss
	params_gaussNewton << 3.6, 1.3, 7.2, 1.7;

	VectorXd params_levenMar = params_gaussNewton;

	levenMar(input, output, params_levenMar);
	cout << "Levenberg-Marquardt parameter: " << endl << params_levenMar << endl << endl << endl;

}

参考

1:https://zhuanlan.zhihu.com/p/136143299
2:https://blog.csdn.net/stihy/article/details/52737723
3:参考文献:A Brief Description of the
Levenberg-Marquardt Algorithm Implemened

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188418.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【WPF】Toolkit(一个项目)的要点总结

    【WPF】Toolkit(一个项目)的要点总结架构相关1.插件式开发:MEF具体怎么使用可参考百度+Demo(密码:k8ck)2.备份机制(项目特有功能)待续3.镜像机制(项目特有功能)待续4.分模块记录日志(转)非常完善的Log4net详细说明UI相关1.多语言读取系统的显示语言(displayLanguage),显示语言的定义是:假如你的系统现在是中文的,

    2022年10月2日
    0
  • 允许跨域访问_vue浏览器清空跳转记录

    允许跨域访问_vue浏览器清空跳转记录from http://www.cnblogs.com/fengyuqing/p/javascript_xmlhttp.html在非IE下,使用XMLHttpRequest不能跨域访问,除非要访问的网页设置为允许跨域访问。将网页设置为允许跨域访问的方法如下: JavaResponse.AddHeader(“Access-Control

    2022年10月1日
    0
  • dll和so的区别_dllor

    dll和so的区别_dllor动态链接,在可执行文件装载时或运行时,由操作系统的装载程序加载库。大多数操作系统将解析外部引用(比如库)作为加载过程的一部分。在这些系统上,可执行文件包含一个叫做importdirecto

    2022年9月2日
    2
  • 保存rtsp视频流

    保存rtsp视频流将视频流保存为.avi格式的本地文件importcv2cap=cv2.VideoCapture(“rtsp://103.229.215.117:1554/s?dev=b80fd652-5097-401c-b187-b439365bd9be&sup=dev116&supip=103.229.215.117&support=8000&ch=1&typ…

    2022年10月17日
    1
  • python tkinter窗口美化_jquery进度条插件

    python tkinter窗口美化_jquery进度条插件前言在我们进行自动化测试的时候,用例往往是成百上千,执行的时间是几十分钟或者是小时级别。有时,我们在调试那么多用例的时候,不知道执行到什么程度了,而pytest-sugar插件能很好解决我们的痛点。

    2022年7月30日
    2
  • linux 安装 mysql简单教程

    linux 安装 mysql简单教程首先明确大体步骤为3步1.下载数据库的压缩包或二进制包,可以在linux用wget或yum下载,也可以外网下载再传到linux2.配置数据库的环境和路径3.登陆数据库修改一.我这里是用wgethttps://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz下…

    2022年6月6日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号