C++ 微积分 - 求导 - 自动微分(Automatic Differentiation)
C++ 微积分 - 求导 - 自动微分(Automatic Differentiation)
flyfish
自动微分(Automatic Differentiation,简称 AD)是一种用于精确计算函数导数的技术。它结合了符号微分的准确性和数值微分的效率。自动微分的核心思想是利用计算图对函数进行分解,通过链式法则高效地计算导数,而无需进行符号运算或近似计算。自动微分能自动计算复杂函数的精确梯度。
C++ 微积分 - 求导 - 解析法(符号计算、符号微分)
C++ 微积分 - 求导 - 数值法
自动微分的基本概念
1 计算图:
自动微分将计算过程表示为一个有向无环图(DAG),其中节点表示变量或中间计算结果,边表示计算操作。通过这个图,可以追踪每个变量对输出的影响。
2 链式法则:
自动微分利用链式法则逐步计算导数。链式法则表示复合函数的导数为各个部分导数的乘积。
在计算图中,每个节点对输出的贡献可以通过链式法则从后往前累积计算。
3 前向模式和反向模式:
前向模式(Forward Mode):逐个变量进行传播计算,适用于输入变量较少的情况。
反向模式(Reverse Mode):从输出开始逐步传播导数,适用于输出变量较少的情况(如机器学习中的损失函数)。
自动微分提供精确的导数值,而不是近似值。与符号微分相比,自动微分在计算复杂函数时更高效。用户无需手动推导导数,可以直接获得函数的导数。
符号微分:处理复杂函数的导数推导可能非常复杂,容易导致表达式膨胀。
数值微分:容易受到舍入误差的影响,特别是在计算机浮点运算中。
自动微分的强大之处在于它可以自动地应用一系列简单的微积分规则来计算复杂函数的导数。通过重载运算符,Dual
结构体能够使用这些基本规则构建导数,而无需手动推导。
常见求导法则及其实现
1. 加法法则
对于两个函数 f ( x ) f(x) f(x) 和 g ( x ) g(x) g(x),有:
( f ( x ) + g ( x ) ) ′ = f ′ ( x ) + g ′ ( x ) (f(x) + g(x))' = f'(x) + g'(x) (f(x)+g(x))′=f′(x)+g′(x)实现: 在 Dual
结构体中,两个 Dual
对象相加时,值和导数分别相加。
Dual operator+(const Dual& other) const {return Dual(value + other.value, derivative + other.derivative);
}
2. 乘法法则
对于两个函数 f ( x ) f(x) f(x) 和 g ( x ) g(x) g(x),有:
( f ( x ) ⋅ g ( x ) ) ′ = f ′ ( x ) ⋅ g ( x ) + f ( x ) ⋅ g ′ ( x ) (f(x) \cdot g(x))' = f'(x) \cdot g(x) + f(x) \cdot g'(x) (f(x)⋅g(x))′=f′(x)⋅g(x)+f(x)⋅g′(x)实现: 在 Dual
结构体中,两个 Dual
对象相乘时,使用乘积法则计算导数。
Dual operator*(const Dual& other) const {return Dual(value * other.value, value * other.derivative + derivative * other.value);
}
3. 商法则
对于两个函数 f ( x ) f(x) f(x) 和 g ( x ) g(x) g(x),有:
( f ( x ) g ( x ) ) ′ = f ′ ( x ) ⋅ g ( x ) − f ( x ) ⋅ g ′ ( x ) ( g ( x ) ) 2 \left(\frac{f(x)}{g(x)}\right)' = \frac{f'(x) \cdot g(x) - f(x) \cdot g'(x)}{(g(x))^2} (g(x)f(x))′=(g(x))2f′(x)⋅g(x)−f(x)⋅g′(x)实现: 在 Dual
结构体中,两个 Dual
对象相除时,使用商法则计算导数。
Dual operator/(const Dual& other) const {return Dual(value / other.value, (derivative * other.value - value * other.derivative) / (other.value * other.value));
}
4. 链式法则
对于复合函数 f ( g ( x ) ) f(g(x)) f(g(x)),有:
( f ( g ( x ) ) ) ′ = f ′ ( g ( x ) ) ⋅ g ′ ( x ) (f(g(x)))' = f'(g(x)) \cdot g'(x) (f(g(x)))′=f′(g(x))⋅g′(x)
自动微分天然支持链式法则,因为每个操作都跟踪其导数,计算过程中自动应用链式法则。
使用基本规则计算复合函数的导数
展示如何使用这些基本规则计算复合函数 h ( x ) = ( x 2 + 1 ) ⋅ sin ( x ) h(x) = (x^2 + 1) \cdot \sin(x) h(x)=(x2+1)⋅sin(x) 的导数。
#include <iostream>
#include <cmath>const double M_PI = 3.1415;
// 双数结构体,用于实现前向模式自动微分
struct Dual {double value; // 函数值double derivative; // 导数值// 构造函数,初始化双数Dual(double v, double d) : value(v), derivative(d) {}// 重载加法运算符Dual operator+(const Dual& other) const {return Dual(value + other.value, derivative + other.derivative);}// 重载乘法运算符Dual operator*(const Dual& other) const {return Dual(value * other.value,value * other.derivative + derivative * other.value);}// 重载正弦函数friend Dual sin(const Dual& x) {return Dual(std::sin(x.value), std::cos(x.value) * x.derivative);}
};int main() {// 初始化 x 为一个双数,值为 π/4,导数为 1Dual x(M_PI / 4, 1.0);// 计算 h(x) = (x^2 + 1) * sin(x)Dual x_squared = x * x; // x^2Dual one(1.0, 0.0); // 常数 1Dual h = (x_squared + one) * sin(x);// 输出结果std::cout << "h(x) 的值为: " << h.value << std::endl;std::cout << "h(x) 的导数为: " << h.derivative << std::endl;return 0;
}
自动微分法:使用前向模式自动微分来处理更复杂的函数,包括加法、乘法、除法、指数和对数函数。
-
结构体
Dual
: -
value
表示函数的值。
derivative
表示导数的值。
支持常见的运算符重载(加、减、乘、除、取反)以便进行代数操作。 -
数学函数支持:
实现了exp
和log
函数,分别表示指数和对数函数的自动微分。 -
复杂函数计算:
compute_function
函数实现了一个复杂的函数 f ( x ) = x 2 + 2 x + e x f(x) = x^2 + 2x + e^x f(x)=x2+2x+ex,并使用自动微分来计算其值和导数。
#include <iostream>
#include <cmath>// Dual number structure for automatic differentiation
struct Dual {double value; // Function valuedouble derivative; // Derivative valueDual(double v, double d) : value(v), derivative(d) {}// Overload additionDual operator+(const Dual& other) const {return Dual(value + other.value, derivative + other.derivative);}// Overload subtractionDual operator-(const Dual& other) const {return Dual(value - other.value, derivative - other.derivative);}// Overload multiplicationDual operator*(const Dual& other) const {return Dual(value * other.value, value * other.derivative + derivative * other.value);}// Overload divisionDual operator/(const Dual& other) const {return Dual(value / other.value, (derivative * other.value - value * other.derivative) / (other.value * other.value));}// Overload unary minusDual operator-() const {return Dual(-value, -derivative);}
};// Exponential function
Dual exp(const Dual& x) {double exp_value = std::exp(x.value);return Dual(exp_value, exp_value * x.derivative);
}// Logarithm function
Dual log(const Dual& x) {return Dual(std::log(x.value), x.derivative / x.value);
}// Function to compute f(x) = x^2 + 2x + exp(x)
Dual compute_function(const Dual& x) {return x * x + Dual(2.0, 0.0) * x + exp(x);
}int main() {// Initialize x = 1.0 with derivative 1.0 (i.e., d(x)/dx = 1)Dual x(1.0, 1.0);// Compute the function and its derivativeDual result = compute_function(x);std::cout << "Function value at x = " << x.value << " is " << result.value << std::endl;std::cout << "Derivative at x = " << x.value << " is " << result.derivative << std::endl;return 0;
}
相关文章:
C++ 微积分 - 求导 - 自动微分(Automatic Differentiation)
C 微积分 - 求导 - 自动微分(Automatic Differentiation) flyfish 自动微分(Automatic Differentiation,简称 AD)是一种用于精确计算函数导数的技术。它结合了符号微分的准确性和数值微分的效率。自动微分的核心思想…...
面试题-每日5道
26.在 Queue 中 poll()和 remove()有什么区别? 相同点:都是删除第一个元素并返回。 不同点:如果没有元素poll()会返回null,而remove()会抛出NoSuchElementException异常 27.哪些集合类是线程安全的? Vector,Stock,Hashtable都是线程安全的&a…...

STM32卡死、跑飞如何调试确定问题
目录 前言 一、程序跑飞原因 二、调试工具 2.1Registers工具 2.2 Memory工具 2.3 Disassembly工具 2.4 Call Stack工具 三、找到程序跑飞位置 方式一、 方式二、 前言 我们初学STM32的时候代码难免会出现疏忽,导致程序跑飞,不再正常运行&#…...

代理模式和Spring MVC
Spring是一个分层的轻量级的开源Java框架。核心是IOC(Inverse of Control 控制反转)和AOP(Aspect Oriented Programming 面向切面编程) AOP 面向切面 AOP (Aspect Orient Programming),直译过来就是 面向切面编程,AOP 是一种编程思想&#x…...

深入理解Vue slot的原理
文章目录 前言为什么需要插槽作用域插槽插槽的原理总结 前言 插槽是Vue中一个重要的特性,它有很多种用法:默认插槽、具名插槽、作用域插槽。尤其作用域插槽,还有一堆特性,比如解构prop,解构prop的时候还可以进行属性名…...
git fetch作用与用法
目录 git fetch作用 git fetch用法 git fetch作用 git fetch 命令在 Git 版本控制系统中扮演着重要的角色。其主要作用是从远程仓库获取最新版本的项目文件,但不会自动合并或修改你当前的工作。这意味着,使用 git fetch 后,你需要手动合并…...

pycharm如何查看git历史版本变更信息
通过名字查看不同版本 查看版本不同地方...
【2.2 python中的变量】
2.2 python中的变量 在Python中,变量是存储数据值的容器。Python是一种动态类型语言,这意味着你不需要在声明变量时指定变量的类型;Python会根据你赋给变量的值自动确定其类型。下面我将详细介绍Python中的变量,包括保留字&#…...
Python软体中找出一组字符串的最长公共前缀:算法与实现
Python软体中找出一组字符串的最长公共前缀:算法与实现 在处理字符串数据时,寻找多个字符串之间的共同特征是一个常见的需求。特别是在文件名、URL、或其他文本数据中,找到最长公共前缀(Longest Common Prefix, LCP)可以帮助我们进行更高效的搜索和分类。本文将详细介绍如…...
git lfs使用(huggingface下载大模型文件)-教程记录
写的比较清楚的教程,用于之后有需求时查找用: https://blog.csdn.net/flyingluohaipeng/article/details/130788293...

1. 什么是操作系统
文章目录 1.1 从功能上来看操作系统1.2 硬件资源 1.1 从功能上来看操作系统 对用户来说,操作系统是一个控制软件,可以用来管理应用程序,它可以限制不同的程序来占用的资源。对内部的软件来说,操作系统是一个管理外设和分配资源的…...

数据科学 - 数据预处理 (数据清洗,结构化数据)
1. 前言 数据清洗与结构化数据在数据分析和机器学习项目中扮演着至关重要的角色。随着大数据时代的到来,数据的质量、准确性和可用性成为决定项目成功与否的关键因素。 数据清洗提高数据质量,保证数据集的一致性;促进数据分析与挖掘…...

基于SpringBoot+Vue的校车调度管理系统(带1w+文档)
基于SpringBootVue的校车调度管理系统(带1w文档) 基于SpringBootVue的校车调度管理系统(带1w文档) 如今,因为无线网相关技术的快速,尤其是在网上进行资源的上传下载、搜索查询等技术,以及信息处理和语言开发技术的进步,同时编程语…...

基于改进拥挤距离的多模态多目标优化差分进化(MMODE-ICD)求解无人机三维路径规划(MATLAB代码)
一、无人机多目标优化模型 无人机三维路径规划是无人机在执行任务过程中的非常关键的环节,无人机三维路径规划的主要目的是在满足任务需求和自主飞行约束的基础上,计算出发点和目标点之间的最佳航路。 1.1路径成本 无人机三维路径规划的首要目标是寻找…...

opencascade AIS_Trihedron源码学习 绘制三轴坐标系
opencascade AIS_Trihedron 前言 //! 创建一个可选择的三轴坐标系 //! 该三轴坐标系包括一个原点,三个轴线和三个标签。 //! 标签的默认文本为 “X”, “Y”, “Z”。 //! 可以更改原点和任意轴线的颜色,箭头和标签的颜色也可以改变。 //! 可视化呈现可…...

【C++】C++应用案例-通讯录管理系统
目录 一、整体介绍 1.1、需求和目标 1.2、整体功能描述 二、页面及功能描述 2.1 主菜单 2.2 添加联系人菜单 2.3 显示联系人菜单 2.4 修改联系人菜单 2.5 退出功能 三、流程设计 3.1 主流程 3.2 添加操作流程 3.3 显示联系人操作流程 3.4 修改联系人操作流程 四…...
使用Python自动批量提取增值税发票信息并导出为Excel文件
要批量提取增值税发票的关键信息并将其导出为 Excel 文件,可以使用 Python 脚本结合 pdfplumber(用于解析 PDF 内容)、pandas(用于处理数据并导出 Excel)等库来实现。以下是实现这一目标的详细步骤。 1. 环境设置 首…...

vitis (eclipse) 的Indexer不能搜索、不能跳转到函数和变量定义和声明不能打开调用层次的解决方法
在使用vitis(2021.1) 过程中,有一个非常方便实用的功能,就是在函数或变量等源代码上通过右键菜单或快捷键F3、F4、CtrlAltH,也可以按住Ctrl键然后鼠标停留在函数名或变量名上,点击出现的链接,可以跳转到函数或变量的定…...

最佳HR软件指南:11款高效管理工具
文章介绍了11款人力资源管理工具:Moka、友人才、北森HRSaaS、同鑫eHR、i人事、红海eHR、BambooHR、Skuad、Hibob、OrangeHRM、Verint。 在选择人力资源管理软件时,选错不仅浪费时间和金钱,还会影响团队的工作效率和员工满意度。本文总结了11款…...
家长为孩子出国留学择校的四个步骤
如何为孩子选择最好的学校?无论您是选择公立或私立学校还是在家上学,无论您是否支付学费,都必须仔细规划。在为孩子选择学校的过程中,以下部分有供您考虑的问题。 写下对你来说最重要的五件事 在考虑选择学校时,您可…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...