feat: 前向自动微分纯头文件库

This commit is contained in:
mayge
2026-04-01 02:39:40 +08:00
parent 2ff32f5c89
commit 58aedec43c
10 changed files with 180 additions and 0 deletions

38
include/forwardad.hpp Normal file
View File

@@ -0,0 +1,38 @@
/*前向自动微分的声明部分*/
#pragma once
#include <iostream>
#include <vector>
#include <functional>
#include "dual.hpp"
#include "types/common.hpp"
namespace forwardad{
template <typename Func, typename... Args>
Result diff(const Func& f, Args... args) {
Result res;
constexpr size_t N = sizeof...(Args);
res.gradient.resize(N);
// 1. 计算函数值(所有导数为 0
Dual value_res = f(Dual((double)args, 0.0)...);
res.value = value_res.value;
// 2. 对每个输入变量求偏导seed 依次设为 1
double args_arr[] = { (double)args... };
[&]<size_t... Is>(std::index_sequence<Is...>) {
([&]() {
// 创建 Dual 输入,第 Is 个变量导数=1其余=0
Dual inputs[N];
for (size_t j = 0; j < N; ++j)
inputs[j] = Dual(args_arr[j], j == Is ? 1.0 : 0.0);
// 用内层 index_sequence 展开所有 N 个参数传给 f
res.gradient[Is] = [&]<size_t... Js>(std::index_sequence<Js...>) {
return f(inputs[Js]...).deriv;
}(std::make_index_sequence<N>{});
}(), ...);
}(std::make_index_sequence<N>{});
return res;
}
} // namespace forwardad