Python | C++漂移扩散方程和无风险套利公式算法微分

2024-06-15 18:04

本文主要是介绍Python | C++漂移扩散方程和无风险套利公式算法微分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🎯要点

🎯漂移扩散方程计算微分 | 🎯期权无风险套利公式计算微分 | 🎯实现图结构算法微分 | 🎯实现简单正向和反向计算微分 | 🎯实现简单回归分类和生成对抗网络计算微分 | 🎯几何网格计算微分

🍇Python和C++计算微分正反向累积

算法微分在机器学习领域尤为重要。例如,它允许人们在神经网络中实现反向传播,而无需手动计算导数。

计算微分的基础是复合函数偏导数链式法则提供的微分分解。简单结构如:
y = f ( g ( h ( x ) ) ) = f ( g ( h ( w 0 ) ) ) = f ( g ( w 1 ) ) = f ( w 2 ) = w 3 w 0 = x w 1 = h ( w 0 ) w 2 = g ( w 1 ) w 3 = f ( w 2 ) = y \begin{aligned} y & =f(g(h(x)))=f\left(g\left(h\left(w_0\right)\right)\right)=f\left(g\left(w_1\right)\right)=f\left(w_2\right)=w_3 \\ w_0 & =x \\ w_1 & =h\left(w_0\right) \\ w_2 & =g\left(w_1\right) \\ w_3 & =f\left(w_2\right)=y \end{aligned} yw0w1w2w3=f(g(h(x)))=f(g(h(w0)))=f(g(w1))=f(w2)=w3=x=h(w0)=g(w1)=f(w2)=y
由链式法则得出:
∂ y ∂ x = ∂ y ∂ w 2 ∂ w 2 ∂ w 1 ∂ w 1 ∂ x = ∂ f ( w 2 ) ∂ w 2 ∂ g ( w 1 ) ∂ w 1 ∂ h ( w 0 ) ∂ x \frac{\partial y}{\partial x}=\frac{\partial y}{\partial w_2} \frac{\partial w_2}{\partial w_1} \frac{\partial w_1}{\partial x}=\frac{\partial f\left(w_2\right)}{\partial w_2} \frac{\partial g\left(w_1\right)}{\partial w_1} \frac{\partial h\left(w_0\right)}{\partial x} xy=w2yw1w2xw1=w2f(w2)w1g(w1)xh(w0)
通常,存在两种不同的计算微分模式:正向累积和反向累积。

正向累积指定从内到外遍历链式法则(即首先计算 ∂ w 1 / ∂ x \partial w_1 / \partial x w1/x,然后计算 ∂ w 2 / ∂ w 1 \partial w_2 / \partial w_1 w2/w1,最后计算 ∂ y / ∂ w 2 \partial y / \partial w_2 y/w2 ),而反向累积是从外到内的遍历(首先计算 ∂ y / ∂ w 2 \partial y / \partial w_2 y/w2,然后计算 ∂ w 2 / ∂ w 1 \partial w_2 / \partial w_1 w2/w1,最后计算 ∂ w 1 / ∂ x \partial w_1 / \partial x w1/x​)。更简洁地说,

正向累积计算递归关系: ∂ w i ∂ x = ∂ w i ∂ w i − 1 ∂ w i − 1 ∂ x \frac{\partial w_i}{\partial x}=\frac{\partial w_i}{\partial w_{i-1}} \frac{\partial w_{i-1}}{\partial x} xwi=wi1wixwi1 w 3 = y w_3=y w3=y

反向累积计算递归关系: ∂ y ∂ w i = ∂ y ∂ w i + 1 ∂ w i + 1 ∂ w i \frac{\partial y}{\partial w_i}=\frac{\partial y}{\partial w_{i+1}} \frac{\partial w_{i+1}}{\partial w_i} wiy=wi+1ywiwi+1 w 0 = x w_0=x w0=x

正向累积在一次传递中计算函数和导数(但每个仅针对一个独立变量)。相关方法调用期望表达式 Z 相对于变量 V 导出。该方法返回一对已求值的函数及其导数。该方法递归遍历表达式树,直到到达变量。如果请求相对于此变量的导数,则其导数为 1,否则为 0。然后求偏函数以及偏导数。

伪代码:

tuple<float,float> evaluateAndDerive(Expression Z, Variable V) {if isVariable(Z)if (Z = V) return {valueOf(Z), 1};else return {valueOf(Z), 0};else if (Z = A + B){a, a'} = evaluateAndDerive(A, V);{b, b'} = evaluateAndDerive(B, V);return {a + b, a' + b'};else if (Z = A - B){a, a'} = evaluateAndDerive(A, V);{b, b'} = evaluateAndDerive(B, V);return {a - b, a' - b'};else if (Z = A * B){a, a'} = evaluateAndDerive(A, V);{b, b'} = evaluateAndDerive(B, V);return {a * b, b * a' + a * b'};
}

Python实现正向累积:

class ValueAndPartial:def __init__(self, value, partial):self.value = valueself.partial = partialdef toList(self):return [self.value, self.partial]class Expression:def __add__(self, other):return Plus(self, other)def __mul__(self, other):return Multiply(self, other)class Variable(Expression):def __init__(self, value):self.value = valuedef evaluateAndDerive(self, variable):partial = 1 if self == variable else 0return ValueAndPartial(self.value, partial)class Plus(Expression):def __init__(self, expressionA, expressionB):self.expressionA = expressionAself.expressionB = expressionBdef evaluateAndDerive(self, variable):valueA, partialA = self.expressionA.evaluateAndDerive(variable).toList()valueB, partialB = self.expressionB.evaluateAndDerive(variable).toList()return ValueAndPartial(valueA + valueB, partialA + partialB)class Multiply(Expression):def __init__(self, expressionA, expressionB):self.expressionA = expressionAself.expressionB = expressionBdef evaluateAndDerive(self, variable):valueA, partialA = self.expressionA.evaluateAndDerive(variable).toList()valueB, partialB = self.expressionB.evaluateAndDerive(variable).toList()return ValueAndPartial(valueA * valueB, valueB * partialA + valueA * partialB)# Example: Finding the partials of z = x * (x + y) + y * y at (x, y) = (2, 3)
x = Variable(2)
y = Variable(3)
z = x * (x + y) + y * y
xPartial = z.evaluateAndDerive(x).partial
yPartial = z.evaluateAndDerive(y).partial
print("∂z/∂x =", xPartial)  # Output: ∂z/∂x = 7
print("∂z/∂y =", yPartial)  # Output: ∂z/∂y = 8

C++实现正向累积:

#include <iostream>
struct ValueAndPartial { float value, partial; };
struct Variable;
struct Expression {virtual ValueAndPartial evaluateAndDerive(Variable *variable) = 0;
};
struct Variable: public Expression {float value;Variable(float value): value(value) {}ValueAndPartial evaluateAndDerive(Variable *variable) {float partial = (this == variable) ? 1.0f : 0.0f;return {value, partial};}
};
struct Plus: public Expression {Expression *a, *b;Plus(Expression *a, Expression *b): a(a), b(b) {}ValueAndPartial evaluateAndDerive(Variable *variable) {auto [valueA, partialA] = a->evaluateAndDerive(variable);auto [valueB, partialB] = b->evaluateAndDerive(variable);return {valueA + valueB, partialA + partialB};}
};
struct Multiply: public Expression {Expression *a, *b;Multiply(Expression *a, Expression *b): a(a), b(b) {}ValueAndPartial evaluateAndDerive(Variable *variable) {auto [valueA, partialA] = a->evaluateAndDerive(variable);auto [valueB, partialB] = b->evaluateAndDerive(variable);return {valueA * valueB, valueB * partialA + valueA * partialB};}
};
int main () {// Example: Finding the partials of z = x * (x + y) + y * y at (x, y) = (2, 3)Variable x(2), y(3);Plus p1(&x, &y); Multiply m1(&x, &p1); Multiply m2(&y, &y); Plus z(&m1, &m2);float xPartial = z.evaluateAndDerive(&x).partial;float yPartial = z.evaluateAndDerive(&y).partial;std::cout << "∂z/∂x = " << xPartial << ", "<< "∂z/∂y = " << yPartial << std::endl;// Output: ∂z/∂x = 7, ∂z/∂y = 8return 0;
}

反向累积需要两次传递:在正向传递中,首先评估函数并缓存部分结果。在反向传递中,计算偏导数并反向传播先前导出的值。相应的方法调用期望表达式 Z 被导出,并以父表达式的导出值为种子。对于顶部表达式 Z 相对于 Z 导出,这是 1。该方法递归遍历表达式树,直到到达变量并将当前种子值添加到导数表达式。

伪代码:

void derive(Expression Z, float seed) {if isVariable(Z)partialDerivativeOf(Z) += seed;else if (Z = A + B)derive(A, seed);derive(B, seed);else if (Z = A - B)derive(A, seed);derive(B, -seed);else if (Z = A * B)derive(A, valueOf(B) * seed);derive(B, valueOf(A) * seed);
}

Python实现反向累积:

class Expression:def __add__(self, other):return Plus(self, other)def __mul__(self, other):return Multiply(self, other)class Variable(Expression):def __init__(self, value):self.value = valueself.partial = 0def evaluate(self):passdef derive(self, seed):self.partial += seedclass Plus(Expression):def __init__(self, expressionA, expressionB):self.expressionA = expressionAself.expressionB = expressionBself.value = Nonedef evaluate(self):self.expressionA.evaluate()self.expressionB.evaluate()self.value = self.expressionA.value + self.expressionB.valuedef derive(self, seed):self.expressionA.derive(seed)self.expressionB.derive(seed)class Multiply(Expression):def __init__(self, expressionA, expressionB):self.expressionA = expressionAself.expressionB = expressionBself.value = Nonedef evaluate(self):self.expressionA.evaluate()self.expressionB.evaluate()self.value = self.expressionA.value * self.expressionB.valuedef derive(self, seed):self.expressionA.derive(self.expressionB.value * seed)self.expressionB.derive(self.expressionA.value * seed)# Example: Finding the partials of z = x * (x + y) + y * y at (x, y) = (2, 3)
x = Variable(2)
y = Variable(3)
z = x * (x + y) + y * y
z.evaluate()
print("z =", z.value)        # Output: z = 19
z.derive(1)
print("∂z/∂x =", x.partial)  # Output: ∂z/∂x = 7
print("∂z/∂y =", y.partial)  # Output: ∂z/∂y = 8

C++实现反向累积:

#include <iostream>
struct Expression {float value;virtual void evaluate() = 0;virtual void derive(float seed) = 0;
};
struct Variable: public Expression {float partial;Variable(float _value) {value = _value;partial = 0;}void evaluate() {}void derive(float seed) {partial += seed;}
};
struct Plus: public Expression {Expression *a, *b;Plus(Expression *a, Expression *b): a(a), b(b) {}void evaluate() {a->evaluate();b->evaluate();value = a->value + b->value;}void derive(float seed) {a->derive(seed);b->derive(seed);}
};
struct Multiply: public Expression {Expression *a, *b;Multiply(Expression *a, Expression *b): a(a), b(b) {}void evaluate() {a->evaluate();b->evaluate();value = a->value * b->value;}void derive(float seed) {a->derive(b->value * seed);b->derive(a->value * seed);}
};
int main () {// Example: Finding the partials of z = x * (x + y) + y * y at (x, y) = (2, 3)Variable x(2), y(3);Plus p1(&x, &y); Multiply m1(&x, &p1); Multiply m2(&y, &y); Plus z(&m1, &m2);z.evaluate();std::cout << "z = " << z.value << std::endl;// Output: z = 19z.derive(1);std::cout << "∂z/∂x = " << x.partial << ", "<< "∂z/∂y = " << y.partial << std::endl;// Output: ∂z/∂x = 7, ∂z/∂y = 8return 0;
}

👉参阅一:计算思维

👉参阅二:亚图跨际

这篇关于Python | C++漂移扩散方程和无风险套利公式算法微分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1064176

相关文章

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

Python极速搭建局域网文件共享服务器完整指南

《Python极速搭建局域网文件共享服务器完整指南》在办公室或家庭局域网中快速共享文件时,许多人会选择第三方工具或云存储服务,但这些方案往往存在隐私泄露风险或需要复杂配置,下面我们就来看看如何使用Py... 目录一、android基础版:HTTP文件共享的魔法命令1. 一行代码启动HTTP服务器2. 关键参

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali