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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • eclipse 安装svn插件 maven插件 web插件 erm插件

    eclipse 安装svn插件 maven插件 web插件 erm插件eclipse 安装svn插件 maven插件 web插件 erm插件

    2022年4月23日
    89
  • 深度图像基础知识(一)

    深度图像基础知识(一)深度图像(depthimage)也被称为距离影像(rangeimage),是指将从图像采集器到场景中各点的距离(深度)作为像素值的图像,它直接反映了景物可见表面的几何形状。深度图像经过坐标转换可以计算为点云数据,有规则及必要信息的点云数据也可以反算为深度图像数据。深度数据流所提供的图像帧中,每一个像素点代表的是在深度感应器的视野中,该特定的(x,y)坐标处物体到离摄像头平面最近的

    2022年4月25日
    40
  • linux 下vim的使用(学习必看!!重要)

    linux 下vim的使用(学习必看!!重要)vi与vimvi编辑器是所有Unix及Linux系统下标准的编辑器,他就相当于windows系统中的记事本一样,它的强大不逊色于任何最新的文本编辑器。他是我们使用Linux系统不能缺少的工具。由于对Unix及Linux系统的任何版本,vi编辑器是完全相同的,学会它后,您将在Linux的世界里畅行无阻。vim具有程序编辑的能力,可以以字体颜色辨别语法的正确性,方便程序设计;因为程序简单

    2025年6月10日
    7
  • es6删除数组指定元素_如何删除数组中的元素

    es6删除数组指定元素_如何删除数组中的元素arr.splice(arr.findIndex(item=&gt;item.id===id),1)//item只是参数可以写成i或者v都可以,//后面的额id是数组的id,是不能随便写的,如果你数组里面写的是id,这里就写id,如果数组里面写的是num,那这里就写num,//===后面的id是你想要删除的元素的id号,同理,如果你数组里面写的是num,那这里…

    2022年8月11日
    6
  • 最全的PHP后台管理系统源码「建议收藏」

    最全的PHP后台管理系统源码「建议收藏」一款PHP语言基于ThinkPhp6.x+Layui+MySQL等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可用于快速搭建前后端分离后台管理系统,本着简化开发、提升开发效率的初衷,框架自研了一套个性化的组件,实现了可插拔的组件式开发方式:单图上传、多图上传、下拉选择、开关按钮、单选按钮、多选按钮、图片裁剪等等一系列个性化、轻量级的组件,是一款真正意义上实现组件化开发的敏捷开发框架,框架已集成了完整的RBAC权限架构和常规基础模块,同时支持多

    2025年12月10日
    4
  • java实现异步调用

    java实现异步调用1、使用线程池的逻辑实现异步调用packagecom.ourlang.dataextract.controller;importcom.google.common.util.concurrent.ThreadFactoryBuilder;importcom.ourlang.dataextract.common.CommonResult;importcom.ourlang.dataextract.service.ISInPatientListService;importorg.apach

    2022年7月11日
    19

发表回复

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

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