05 Ceres

文章目录

    • 05 Ceres
      • 5.0 仿函数
      • 5.1 Ceres 简介
      • 5.2 代码示例

05 Ceres

5.0 仿函数

简单来说,仿函数就是重载了 () 操作符的类,可以实现类似函数调用的过程,所以叫做仿函数。

struct MyPlus
{int operator()(const int &a , const int &b) const{return a + b;}
};int main()
{MyPlus a;cout << MyPlus()(1,2) << endl;  //1、通过产生临时对象调用重载运算符cout << a.operator()(1,2) << endl;  //2、通过对象显示调用重载运算符cout << a(1,2) << endl;   //3、通过对象类似函数调用 隐示地调用重载运算符return 0;
}

其次,关于构造函数和仿函数的调用:

  • 构造函数无返回值,而 operator() 是可以有返回值的;
  • 构造函数是声明对象,而仿函数则需要声明好的对象进行调用。
  • 构造函数和仿函数在形式上是可以相同的,但用法和目的不同。

例如

#include <iostream>// 定义一个带有构造函数的仿函数类
class MyFunctor {
public:// 构造函数,接受一个整数参数MyFunctor(int config) : config_(config) { }// 仿函数的函数调用运算符,接受两个整数并返回它们的和,加上构造函数参数int operator()(int a, int b) {return a + b + config_;}private:int config_;
};int main() {// 创建一个带有构造函数参数的仿函数对象MyFunctor addWithConfig(10);// 使用仿函数对象调用它int result = addWithConfig(3, 4);std::cout << "Result: " << result << std::endl;return 0;
}

构造函数和仿函数可以是相同的(接收同样的参数)

#include <iostream>// 定义一个类,同时拥有构造函数和仿函数
class MyFunction {
public:// 构造函数,用于对象的初始化MyFunction(int initialValue) : value(initialValue) {std::cout << "Constructor called. Value: " << value << std::endl;}// 仿函数的函数调用运算符,用于执行特定的操作int operator()(int x) {std::cout << "Function called with argument: " << x << std::endl;return value + x;}private:int value;
};int main() {// 创建一个对象并调用构造函数MyFunction obj1(10);// 使用仿函数的方式调用对象int result = obj1(5);std::cout << "Result: " << result << std::endl;return 0;
}

5.1 Ceres 简介

Ceres 可以解决带有约束条件的非线性最小二乘问题,数学表达如下:

min ⁡ x 1 2 ∑ i ρ i ( ∥ f i ( x i 1 , … , x i k ) ∥ 2 ) s . t . l j ⩽ x j ⩽ u j . \min_{x}\quad\frac12\sum_{\mathrm{i}}\rho_{\mathrm{i}}\left(\|f_{\mathrm{i}}\left(x_{\mathrm{i}1},\ldots,x_{\mathrm{i}\mathrm{k}}\right.)\|^2\right) \\ \mathrm{s.t.~}l_j\leqslant x_j\leqslant u_j. xmin21iρi(fi(xi1,,xik)2)s.t. ljxjuj.

其中

  • ρ i ( ∥ f i ( x i 1 , … , x i k ) ∥ 2 ) \rho_{\mathrm{i}}\left(\|f_{\mathrm{i}}\left(x_{\mathrm{i}1},\ldots,x_{\mathrm{i}\mathrm{k}}\right.)\|^2\right) ρi(fi(xi1,,xik)2) 为残差块;

  • f ( ⋅ ) f(\cdot) f() 为代价函数,也即误差项;

  • ρ ( ⋅ ) \rho(\cdot) ρ() 是核函数(也称损失函数),它属于标量函数,为了减小异常值对非线性优化的影响,一般就取恒等函数(如 “ ρ ( x ) = x \rho(x)=x ρ(x)=x”);

  • l j , u j l_j, u_j lj,uj x j x_j xj 的上下界。

特殊情况:当损失函数 ρ i = x \rho_i=x ρi=x,$l_j=- \infty , u_j=\infty $,那么得到了一个常见的非线性优化函数:

min ⁡ x 1 2 ∑ i ( ∥ f i ( x i 1 , … , x i k ) ∥ 2 ) \min_{x}\quad\frac12\sum_{\mathrm{i}}\left(\|f_{\mathrm{i}}\left(x_{\mathrm{i}1},\ldots,x_{\mathrm{i}\mathrm{k}}\right.)\|^2\right) xmin21i(fi(xi1,,xik)2)

Ceres 求解的一般步骤

  • 定义Cost Function模型,即代价函数 f ( ⋅ ) f(\cdot) f()。也就是我们要寻找的最优目标,这里我们用到了仿函数或称为拟函数(functor)。做法是写一个类,然后在仿函数中重载()运算符。

  • 使用定义的代价函数构建待求解的优化问题。即调用AddResidualBlock将误差项,添加到目标函数中。由于优化需要梯度,我们有几种选择: ① 使用ceres自动求导(Auto Diff)② 使用数值求导(Numeric Diff)3)自行推导解析形式,提供给ceres。

  • 配置求解器参数并求解问题。配置项options比较丰富,可以查看options的定义。

5.2 代码示例

拟合函数 y = exp ⁡ ( a x 2 + b x + c ) y=\exp(ax^2+bx+c) y=exp(ax2+bx+c),自动求导。

/***********************************************************                                          *
* Time: 2023/8/29
* Author: xiaocong
* Function: Ceres
***********************************************************/#include <iostream>
#include <ceres/ceres.h>const int N = 100;                 // 数据点个数using namespace std;// 定义代价函数即 f()
// 仿函数
class CurveFittingCost
{
public:// 构造函数CurveFittingCost(double x, double y) : _x(x), _y(y) {}// 计算残差template <typename T>bool operator()(const T* const abc,     // 待优化变量,三维T* residual) const                  // 残差{residual[0] = T(_y) - ceres::exp(abc[0] * T(_x) * T(_x) + abc[1] * T(_x) + abc[2]);  // y-exp(ax^2+bx+c)return true;}private:const double _x, _y;
};int main()
{double ar = 1.0, br = 2.0, cr = 1.0;         // 真实参数值double abc[3] = { 0,0,0 };                   // 初始估计值// 生成数据vector<double> x_data, y_data;for (int i = 0; i < N; i++){double xi = i / 100.0;                                     // [0~1]double sigma = 0.02 * (rand() % 1000) / 1000.0 - 0.01;     // 随机噪声,[-0.01, 0.01]double yi = exp(ar * xi * xi + br * xi + cr) + sigma;x_data.push_back(xi);y_data.push_back(yi);}// 构建最小二乘问题ceres::Problem problem;for (int i = 0;i < N;i++)    // 添加残差块{// 使用自动求导,模板参数:误差类型,输出维度1,输入维度3,维数要与前面 class 中一致problem.AddResidualBlock(new ceres::AutoDiffCostFunction<CurveFittingCost, 1, 3>(new CurveFittingCost(x_data[i], y_data[i])), nullptr, abc);}// 配置求解器ceres::Solver::Options options;options.linear_solver_type = ceres::DENSE_QR;       // 求解增量方程,QR 分解options.minimizer_progress_to_stdout = true;        // 输出到coutceres::Solver::Summary summary;                     // 优化信息ceres::Solve(options, &problem, &summary);          // 开始优化// 输出结果cout << summary.BriefReport() << endl;cout << "estimated a,b,c = ";for (auto a : abc)cout << a << " ";cout << endl;return 0;
}

结果

estimated a,b,c = 0.999313 2.00098 0.999658

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/187378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (146)-- 算法导论12.2 1题

一、用go语言&#xff0c;假设一棵二叉搜索树中的结点在1到 1000 之间&#xff0c;现在想要查找数值为 363 的结点。下面序列中哪个不是查找过的序列? a.2&#xff0c;252&#xff0c;401&#xff0c;398&#xff0c;330&#xff0c;344&#xff0c;397&#xff0c;363。 b.9…

ps 透明印章制作

ps 透明印章制作 1、打开不透明印章2、抠出红色印章3、新建图层4、填充红色印章到新图层5、导出透明印章 1、打开不透明印章 打开ps软件&#xff0c;菜单栏选择 文件-打开 选择本地不透明印章 打开 2、抠出红色印章 ps菜单栏 选择 选择-色彩范围 点击色彩范围 色彩范围窗口 取…

内网协议区别

今天面试的时候被面试官问到内网隧道技术中的协议有什么区别&#xff0c;平时只注重使用不注重原理&#xff0c;学习记录 2023-11-30 网络层&#xff1a;IPV6 隧道、ICMP 隧道、GRE 隧道 传输层&#xff1a;TCP 隧道、UDP 隧道、常规端口转发 应用层&#xff1a;SSH 隧道、HTTP…

基于B/S架构的医院一体化电子病历编辑器源码

电子病历在线制作、管理和使用的一体化电子病历解决方案&#xff0c;通过一体化的设计&#xff0c;提供对住院病人的电子病历书写、保存、修改、打印等功能。电子病历系统将临床医护需要的诊疗资料以符合临床思维的方法展示。建立以病人为中心&#xff0c;以临床诊疗信息为主线…

使用 SDKMAN 管理多版本本地 Java 环境---Centos8 Windows

文章目录 windows 安装centos8 安装卸载sdkman使用 windows 安装 SDKMAN是一个 jdk 多版本管理工具&#xff0c;类似于 nodejs 中的 nvm。可以在本地存在多个 java 环境&#xff0c;快速切换功能&#xff0c;同时&#xff0c;他不止于 java sdk&#xff0c;还有maven、tomcat等…

算法:双指针

数组分块 题型特点&#xff1a;给一个数组&#xff0c;在某个规则下将数组划分成几个区间 解决&#xff1a;双指针&#xff08;数组中利用下标充当指针&#xff09; 283 移动0 定义两个指针 dest指针&#xff08;已处理区间内非0元素的最后一个位置&#xff09;cur指针&#…

Memcached最新2023年面试题,高级面试题及附答案解析

文章目录 01、Memcached是什么&#xff0c;有什么作用&#xff1f;02、Memcached的多线程是什么&#xff1f;如何使用它们&#xff1f;03、Memcached与Redis的区别&#xff1f;04、如果缓存数据在导出导入之间过期了&#xff0c;怎么处理这些数据呢&#xff1f;05、如何实现集群…

mysql中字符串截取与拆分

按分隔符把字符串拆成多行 引言截取字符串一、left(str,length)二、right(str,length)三、截取特定长度的字符串四、按分隔符截取 分割字符串一、分割成多列二、分割成多行 总结 引言 截取和拆分字符串在编程生涯中是普遍存在的&#xff0c;在sql中也不例外&#xff0c;下面就…

树与二叉树堆:经典OJ题集

目录 查找值为x的结点&#xff1a; 思路分析&#xff1a; 单值二叉树&#xff1a; 示例&#xff1a; 思路分析&#xff1a; 相同的树&#xff1a; 示例&#xff1a; 思路分析&#xff1a; 二叉树的前序遍历&#xff1a;——使用前序遍历把结点元素放入数组中 题…

塑料注塑件自动化光学测量蓝光自动化三维检测解决方案-CASAIM-IS(2ND)

一、背景介绍 在塑料制品的生产过程中&#xff0c;注塑件的质量对于产品的整体质量和性能至关重要。然而&#xff0c;通过使用三坐标、卡尺、千分尺等量具&#xff0c;对工件进行单点或人工检测其加工精度&#xff0c;对复杂形位公差检测目前比较难取得数据&#xff0c;无法快…

SpringSecurity6怎么用

SpringSecurity依赖 <!--SpringSecurity起步依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency> jwt依赖 <!--jwt令牌--> <depend…

WordPress文章防复制代码

通过下面的JS代码&#xff0c;可以有效地防止别人直接复制拷贝你的文章&#xff0c;用frame标签引用你的文章时&#xff0c;会自动跳转到文章正常链接&#xff0c;同时禁止右键菜单。 使用方法一&#xff1a; 打开当前主题头部模 板header.php找到&#xff1a;<?php wp_h…

力扣11题 盛最多水的容器 双指针算法

11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明 你不能倾斜容器. 示…

React Native环境搭建及Hello World

写这篇博客的目的就是想说,react native 挺简单,但是大部分初级前端会被环境搭建给难住,从而放弃. 环境搭建 环境搭建其实说简单也挺简单的,有经验的前端直接翻看react native中文文档就行,直接按上面来肯定没错 以下以安卓开发,windows配置环境为例,来演示一遍 首先 电脑…

架构的模式

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容&#x1f4e2;文章总结&#x1f4e5;博主目标 &#x1f50a;博主介绍 &#x1f31f;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作…

自定义BeanPostProcessor之XssBeanPostProcessor

什么是BeanPostProcessor BeanPostProcessor是Spring框架中的一个重要的扩展点&#xff0c;它允许开发者在Bean初始化前后对Bean进行自定义处理。Spring中有很多内置的BeanPostProcessor&#xff0c;如AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcess…

NX二次开发UF_MTX2_identity 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_MTX2_identity Defined in: uf_mtx.h void UF_MTX2_identity(double identity_mtx [ 4 ] ) overview 概述 Returns a 2 x 2 identity matrix. 返回一个2 x 2的单位矩阵。 UFUN…

【目标检测】进行实时检测计数时,在摄像头窗口显示实时计数个数

这里我是用我本地训练的基于yolov8环境的竹签计数模型&#xff0c;在打开摄像头窗口增加了实时计数显示的代码&#xff0c;可以直接运行&#xff0c;大家可以根据此代码进行修改&#xff0c;其底层原理时将检测出来的目标的个数显示了出来。 该项目链接&#xff1a;【目标检测…

怎样搭建好Google关键词广告账号结构

搭建好Google关键词广告账号结构对于实现广告效果的最大化至关重要。本文小编将为您提供一些关于如何搭建好Google关键词广告账号结构的建议和步骤。 1、设定目标和策略 在开始搭建广告账号结构之前&#xff0c;首先需要明确您的广告目标和策略。您想要增加网站流量还是提高转…

周报:css相关扩展知识

目录 1. 扩展知识&#xff1a;浮动盒子的排列位置 浮动盒子常见排列特点&#xff1a; 浮动盒子扩展特点&#xff1a; 2.扩展知识:行高的取值 line-height常见取值&#xff1a; 行高的取值的方式&#xff1a; 两个方式的区别&#xff1a; 3.扩展知识&#xff1a;body背景…