首页 > 其他分享 >优化原理 (1)高斯牛顿 线性

优化原理 (1)高斯牛顿 线性

时间:2024-07-18 13:09:09浏览次数:9  
标签:xi 高斯 int double inv 牛顿 线性 include sigma

 

 

 

 

/*
* Gauss-Newton iteration method
* author:Davidwang
* date  :2020.08.24
*/
#include <iostream>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <Eigen/Core>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;

void GN(const int, vector<double> &, vector<double> &, double &, double &, double &, double const);

int main(int argc, char **argv)
{
    double ar = 18.0, br = 2.0, cr = 1.0; // 真实参数值
    double ae = 2.0, be = 4.0, ce = 3.0;  // 估计参数值
    int N = 50;                           // 数据点
    double w_sigma = 1.0;                 // 噪声Sigma值
    double inv_sigma = 1.0 / w_sigma;     // 信息值
    cv::RNG rng;                          // OpenCV随机数产生器

    vector<double> x_data, y_data; // 生成真值数据
    for (int i = 0; i < N; i++)
    {
        double x = i / 100.0;
        x_data.push_back(x);
        y_data.push_back(ar * x + exp(br * x + cr) + rng.gaussian(w_sigma * w_sigma));
    }

    chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
    GN(N, x_data, y_data, ae, be, ce, inv_sigma);
    chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
    chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1);

    cout << "solve time cost = " << time_used.count() << " seconds. " << endl;
    cout << "estimated abc = " << ae << ", " << be << ", " << ce << endl;
    return 0;
}

///高斯牛顿法,N数据个数,x:X值,y:Y值,ae:a估计值,be:b估计值,ce:c估计值,inv_sigma:信息值(1/σ)
void GN(const int N, vector<double> &x, vector<double> &y, double &ae, double &be, double &ce, double const inv_sigma)
{
    int iterations = 50;           // 迭代次数
    double cost = 0, lastCost = 0; // 本次迭代的cost和上一次迭代的cost
    double xi, yi, error, e;

    for (int iter = 0; iter < iterations; iter++)
    {
        Matrix3d H = Matrix3d::Zero();
        Vector3d b = Vector3d::Zero();
        cost = 0;

        for (int i = 0; i < N; i++)
        {
            xi = x[i], yi = y[i];            // 第i个数据点
            e = ae * xi + exp(be * xi + ce); // 计算估计值
            error = yi - e;                  // 误差
            Vector3d J;                      // 雅可比矩阵
            J[0] = -xi;                      // de/da
            J[1] = -xi * exp(be * xi + ce);  // de/db
            J[2] = -exp(be * xi + ce);       // de/dd

            H += inv_sigma * inv_sigma * J * J.transpose(); //H = J^T * W^{-1} * J,inv_sigma 为信息值,本示例可以去掉
            b += -inv_sigma * inv_sigma * error * J;        //b= -W^{-1} * f(x)*J ,inv_sigma 为信息值,本示例可以去掉

            cost += error * error;

            cout << "The " << iter + 1 << " iteration, The " << i << " factor " << endl;
            cout << "THe Value, x: " << xi << ",y:" << yi << ",e:" << e << ",error:" << error << endl
                 << endl;
        }
        Vector3d dx = H.ldlt().solve(b); // 求解线性方程 HΔx=b
        if (isnan(dx[0]))
        {
            cout << "result is nan!" << endl;
            break;
        }

        if (iter > 0 && cost >= lastCost)
        {
            cout << "cost: " << cost << ">= last cost: " << lastCost << ", break." << endl;
            break;
        }

        ae += dx[0];
        be += dx[1];
        ce += dx[2];

        lastCost = cost;

        cout << "total cost: " << cost << ", \t\tupdate: " << dx.transpose() << "\t\testimated params: " << ae << "," << be << "," << ce << endl;
    }
}

  

 CMakeLists如下:

cmake_minimum_required(VERSION 2.8)
project(gaussNewton)

set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "-std=c++14 -O3")

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

# OpenCV
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

# Eigen
include_directories("/usr/include/eigen3")

add_executable(GN gaussNewton_GN.cpp)
target_link_libraries(GN ${OpenCV_LIBS})

  

 

标签:xi,高斯,int,double,inv,牛顿,线性,include,sigma
From: https://www.cnblogs.com/gooutlook/p/18309304

相关文章

  • 母函数与高斯和
    前置知识:单位根(为了偷懒,基本将所有的\(\omega\)都写成了\(w\))CP1我们很经常遇到的一个问题是\(xy~mod~n\)的求解,母函数在处理这样的一些问题时会有效(更优先的是寻求\(xy\)的性质或者利用带余除法)例1设\(p>2\)是素数,\(p\nmidabcd\),满足\(\{\frac{ra}p\}+\{\frac......
  • 优化原理 (1)高斯牛顿 线性
          增量方程   #include<iostream>#include<Eigen/Core>#include<Eigen/Dense>#include<Eigen/Geometry>#include"sophus/se3.hpp"#include"sophus/so3.hpp"intmain(void){//优化变量为李代数se(3)的平移向......
  • 高等代数 第三章 线性空间
    知识复习向量的线性关系我们先从方程入手把它写成向量的形式,分别用\(\alpha_i,\beta\)表示上面的列向量,那么方程等价于\(\sumx_i\alpha_i=\beta\)如果考虑齐次方程,那么$\sumx_i\alpha_i=0$,\(0\)肯定是一个解,但是我们想知道的是有没有非平凡的解,也就是说有没有一组不......
  • Halcon的学习笔记(一)——非线性字符识别
    Halcon非线性模式的字符识别(ocr_cd_print_polar_trans.hdev例程分析)Halcon的学习笔记(一)——非线性字符识别项目上需要对非线性模式的字符进行识别,halcon中包含的例程,我搜了一下,网上对于该例程的解析比较少,因此自己便记录了一下自己的学习例程,也算自己的学习笔记。1.什......
  • 【数学】高斯消元
    1.算法简介高斯消元法(Gauss–Jordanelimination)是求解线性方程组的经典算法。例如求解下列方程组:\(\begin{cases}2x+9y-5z=10\\4x+20y+z=24\\x-2y+3z=8\end{cases}\)形式化的,高斯消元可用于求解类似于\(\begin{cases}a_{1,1}x_1+a_{1,2}x_2+\dots+a_{1,n}x_n=b......
  • 基于FPGA的MSK调制解调系统verilog开发,包含testbench,同步模块,高斯信道模拟模块,误
    1.算法仿真效果本程序系统是《m基于FPGA的MSK调制解调系统verilog开发,并带FPGA误码检测模块和matlab仿真程序》的的升级。 升级前原文链接 增加了完整的AWGN信道模型的FPGA实现,可以在testbench里面设置SNR,分析不同SNR对应的FPGA误码率情况。 vivado2019.2仿真结果如下(......
  • R语言贝叶斯MCMC:用rstan建立线性回归模型分析汽车数据和可视化诊断|附代码数据
    全文链接 http://tecdat.cn/?p=23255最近我们被客户要求撰写关于rstan的研究报告,包括一些图形和统计输出。本文将谈论Stan以及如何在R中使用rstan创建Stan模型尽管Stan提供了使用其编程语言的文档和带有例子的用户指南,但对于初学者来说,这可能是很难理解的。StanStan是一种用......
  • 电工电子实验——集成运算放大器的非线性应用
    正弦波形产生电路实验目的加深理解RC桥式正弦振荡器的工作原理。学习并掌握RC桥式正弦振荡器的设计方法和步骤。掌握RC桥式正弦振荡器的调试方法。主要仪器设备及软件硬件:硬件:双踪示波器、函数信号发生器、直流稳压电源、交流毫伏表、实验箱、万用表、阻容元件及导线......
  • 机器学习实战笔记4线性回归
    线性回归首先看一下线性回归方程,就是用代码来编写方程1.numpy正规方程线性回归importnumpyasnpimportpandasaspddf=pd.DataFrame({'years':[1,2,3,4,5,6],'salary':[4000,4250,4500,4750,5000,5250]})df生成dfm=len(df)m输出:6x1=df......
  • 华为高斯数据库openGauss_5.0.2 企业版部署学习
    系统环境欧拉系统官方下载链接openEuler-22.03-LTS-SP4-x86_64-dvd.iso https://mirrors.tuna.tsinghua.edu.cn/openeuler/openEuler-22.03-LTS-SP4/ISO/x86_64/openEuler-22.03-LTS-SP4-x86_64-dvd.iso openEuler下载|openEulerISO镜像|openEuler社区官网 数据库安......