forked from asavine/CompFinance
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AADNode.h
103 lines (77 loc) · 2.3 KB
/
AADNode.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
Written by Antoine Savine in 2018
This code is the strict IP of Antoine Savine
License to use and alter this code for personal and commercial applications
is freely granted to any person or company who purchased a copy of the book
Modern Computational Finance: AAD and Parallel Simulations
Antoine Savine
Wiley, 2018
As long as this comment is preserved at the top of the file
*/
#pragma once
// AAD implementation of chapter 10
// (With multi-dimensional additions of chapter 14)
// Implementation of Node = record on tape
// Unchanged for AADET of chapter 15
#include <exception>
using namespace std;
class Node
{
friend class Tape;
friend class Number;
friend auto setNumResultsForAAD(const bool, const size_t);
friend struct numResultsResetterForAAD;
// The adjoint(s)
// in single case, self held (chapter 10)
double mAdjoint = 0;
// in multi case, held separately and accessed by pointer (chapter 14)
double* pAdjoints;
// Data lives in separate memory
// the n derivatives to arguments,
double* pDerivatives;
// the n pointers to the adjoints of arguments
double** pAdjPtrs;
// Number of adjoints (results) to propagate, usually 1
// See chapter 14
static size_t numAdj;
// Number of childs (arguments)
const size_t n;
public:
Node(const size_t N = 0) : n(N) {}
// Access to adjoint(s)
// single
double& adjoint()
{
return mAdjoint;
}
// multi
double& adjoint(const size_t n) { return pAdjoints[n]; }
// Back-propagate adjoints to arguments adjoints
// Single case, chapter 10
void propagateOne()
{
// Nothing to propagate
if (!n || !mAdjoint) return;
for (size_t i = 0; i < n; ++i)
{
*(pAdjPtrs[i]) += pDerivatives[i] * mAdjoint;
}
}
// Multi case, chapter 14
void propagateAll()
{
// No adjoint to propagate
if (!n || all_of(pAdjoints, pAdjoints + numAdj,
[](const double& x) { return !x; }))
return;
for (size_t i = 0; i < n; ++i)
{
double *adjPtrs = pAdjPtrs[i], ders = pDerivatives[i];
// Vectorized!
for (size_t j = 0; j < numAdj; ++j)
{
adjPtrs[j] += ders * pAdjoints[j];
}
}
}
};