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款…...
家长为孩子出国留学择校的四个步骤
如何为孩子选择最好的学校?无论您是选择公立或私立学校还是在家上学,无论您是否支付学费,都必须仔细规划。在为孩子选择学校的过程中,以下部分有供您考虑的问题。 写下对你来说最重要的五件事 在考虑选择学校时,您可…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...

Canal环境搭建并实现和ES数据同步
作者:田超凡 日期:2025年6月7日 Canal安装,启动端口11111、8082: 安装canal-deployer服务端: https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...

2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...