CoDiPack  2.2.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
derivativeAccess.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2024 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://www.scicomp.uni-kl.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://www.scicomp.uni-kl.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <utility>
38
39#include "../config.h"
40#include "../expressions/lhsExpressionInterface.hpp"
41#include "../misc/binomial.hpp"
42#include "../misc/compileTimeLoop.hpp"
43#include "../misc/exceptions.hpp"
44#include "../misc/macros.hpp"
45#include "../traits/realTraits.hpp"
46
48namespace codi {
49
50#ifndef DOXYGEN_DISABLE
51
55 namespace DerivativeAccessImpl {
56 CODI_INLINE size_t constexpr maximumDerivatives(size_t selectionDepth, size_t order) {
57 return binomial(selectionDepth, order);
58 }
59
60 CODI_INLINE size_t constexpr maximumDerivativesPrimalBranch(size_t selectionDepth, size_t order) {
61 return binomial(selectionDepth - 1, order);
62 }
63
64 CODI_INLINE size_t constexpr isPrimalBranch(size_t selectionDepth, size_t order, size_t l) {
65 return l < maximumDerivativesPrimalBranch(selectionDepth, order);
66 }
67
68 template<typename Type, size_t selectionDepth, size_t order, size_t l>
69 struct CheckCompileTimeValues {
70 public:
71 CODI_STATIC_ASSERT(selectionDepth <= RealTraits::MaxDerivativeOrder<Type>(),
72 "Selection depth must not be higher than the maximum derivative order.");
73 CODI_STATIC_ASSERT(order <= selectionDepth, "Derivative order must not be higher than the selection depth.");
74 CODI_STATIC_ASSERT(l < maximumDerivatives(selectionDepth, order),
75 "Selected derivative must not be greater than the number of available derivatives for that"
76 "order.");
77
78 static bool constexpr isValid = true;
79 };
80
93 template<typename Type, bool constant, size_t selectionDepth, size_t order, size_t l,
94 bool primalBranch = isPrimalBranch(selectionDepth, order, l)>
95 struct SelectCompileTime;
96
98 template<typename T_Type, bool constant, size_t selectionDepth, size_t order, size_t l>
99 struct SelectCompileTime<T_Type, constant, selectionDepth, order, l, true> {
100 public:
101 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
102
103 using Inner = SelectCompileTime<typename Type::Real, constant, selectionDepth - 1, order, l>;
104 using ArgType = typename std::conditional<constant, Type const, Type>::type;
105 using RType = typename Inner::RType;
106
107 CODI_STATIC_ASSERT(CODI_T(CheckCompileTimeValues<Type, selectionDepth, order, l>::isValid),
108 "Checks inside of type.");
109
110 static RType& select(ArgType& value) {
111 return Inner::select(value.value());
112 }
113 };
114
116 template<typename T_Type, bool constant, size_t selectionDepth, size_t order, size_t l>
117 struct SelectCompileTime<T_Type, constant, selectionDepth, order, l, false> {
118 public:
119 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
120
121 using Inner = SelectCompileTime<typename Type::Gradient, constant, selectionDepth - 1, order - 1,
122 l - maximumDerivativesPrimalBranch(selectionDepth, order)>;
123 using ArgType = typename std::conditional<constant, Type const, Type>::type;
124 using RType = typename Inner::RType;
125
126 CODI_STATIC_ASSERT(CODI_T(CheckCompileTimeValues<Type, selectionDepth, order, l>::isValid),
127 "Checks inside of type.");
128
129 static RType& select(ArgType& value) {
130 return Inner::select(value.gradient());
131 }
132 };
133
135 template<typename Type, bool constant>
136 struct SelectCompileTime<Type, constant, 0, 0, 0, true> {
137 public:
138 using ArgType = typename std::conditional<constant, Type const, Type>::type;
139 using RType = ArgType;
140
141 static RType& select(ArgType& value) {
142 return value;
143 }
144 };
145
155 template<typename T_Type, bool constant, size_t T_selectionDepth>
156 struct SelectRunTime {
157 public:
158 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
159 static size_t constexpr selectionDepth = CODI_DD(T_selectionDepth, CODI_UNDEFINED_VALUE);
160
161 CODI_STATIC_ASSERT(CODI_T(std::is_same<typename Type::Real, typename Type::Gradient>::value),
162 "CoDiPack type needs to have the same real and gradient value for run time derivative "
163 "selection.");
164 CODI_STATIC_ASSERT(selectionDepth <= RealTraits::MaxDerivativeOrder<Type>(),
165 "Selection depth must not be higher than the maximum derivative order");
166
167 using Inner = SelectRunTime<typename Type::Real, constant, selectionDepth - 1>;
168 using ArgType = typename std::conditional<constant, Type const, Type>::type;
169 using RType = typename Inner::RType;
170
171 static RType& select(ArgType& v, size_t order, size_t l) {
172 size_t const maxDerivativesPrimalBranch = binomial(selectionDepth - 1, order);
173 if (l < maxDerivativesPrimalBranch) {
174 return Inner::select(v.value(), order, l);
175 } else {
176 return Inner::select(v.gradient(), order - 1, l - maxDerivativesPrimalBranch);
177 }
178 }
179 };
180
182 template<typename T_Type, bool constant>
183 struct SelectRunTime<T_Type, constant, 0> {
184 public:
185 using Type = CODI_DD(T_Type, double);
186 using ArgType = typename std::conditional<constant, Type const, Type>::type;
187 using RType = ArgType;
188
189 static RType& select(ArgType& v, size_t order, size_t l) {
190 CODI_UNUSED(order, l);
191 return v;
192 }
193 };
194 }
195#endif
196
266 template<typename T_Type>
268 public:
269
271 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
272
274 template<bool constant, size_t selectionDepth>
275 using SelectRunTime = DerivativeAccessImpl::SelectRunTime<Type, constant, selectionDepth>;
276
278 template<bool constant, size_t selectionDepth, size_t order, size_t l>
279 using SelectCompileTime = DerivativeAccessImpl::SelectCompileTime<Type, constant, selectionDepth, order, l>;
280
283 template<size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
284 static typename SelectRunTime<true, selectionDepth>::RType const& derivative(Type const& v, size_t order,
285 size_t l) {
286 checkRuntimeSelection<selectionDepth>(order, l);
287
289 }
290
293 template<size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
294 static typename SelectRunTime<false, selectionDepth>::RType& derivative(Type& v, size_t order, size_t l) {
295 checkRuntimeSelection<selectionDepth>(order, l);
296
298 }
299
301 template<typename Derivative, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
302 static void setAllDerivatives(Type& v, size_t order, Derivative const& d) {
303 size_t const maxDerivatives = binomial(selectionDepth, order);
304 for (size_t i = 0; i < maxDerivatives; i += 1) {
305 derivative<selectionDepth>(v, order, i) = d;
306 }
307 }
308
311 template<typename Derivative, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
312 static void setAllDerivativesForward(Type& v, size_t order, Derivative const& d) {
313 DerivativeAccess<typename Type::Real>::template setAllDerivatives<Derivative, selectionDepth - 1>(v.value(),
314 order, d);
315 }
316
319 template<typename Derivative, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
320 static void setAllDerivativesReverse(Type& v, size_t order, Derivative const& d) {
322 v.gradient(), order - 1, d);
323 }
324
327 template<size_t order, size_t l, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
330 }
331
334 template<size_t order, size_t l, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
337 }
338
340 template<size_t order, typename Derivative, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
341 static void setAllDerivatives(Type& v, Derivative const& d) {
342 CompileTimeLoop<DerivativeAccessImpl::maximumDerivatives(selectionDepth, order)>::eval(
343 CallSetDerivative<order, Derivative, selectionDepth>{}, v, d);
344 }
345
348 template<size_t order, typename Derivative, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
349 static void setAllDerivativesForward(Type& v, Derivative const& d) {
350 DerivativeAccess<typename Type::Real>::template setAllDerivatives<order, Derivative, selectionDepth - 1>(
351 v.value(), d);
352 }
353
356 template<size_t order, typename Derivative, size_t selectionDepth = RealTraits::MaxDerivativeOrder<Type>()>
357 static void setAllDerivativesReverse(Type& v, Derivative const& d) {
359 selectionDepth - 1>(v.gradient(), d);
360 }
361
362 private:
363
364 template<size_t selectionDepth>
365 static void checkRuntimeSelection(size_t order, size_t l) {
366 if (order > selectionDepth) {
367 CODI_EXCEPTION(
368 "The derivative order must be smaller or equal than the maximum possible derivative. order: %d, max "
369 "derivative: %d.",
370 order, selectionDepth);
371 }
372
373 size_t numberDerivatives = binomial(selectionDepth, order);
374 if (l >= numberDerivatives) {
375 CODI_EXCEPTION(
376 "The selected derivative must be smaller than the maximum number of derivatives. selected: %d, number "
377 "derivatives: %d.",
378 l, numberDerivatives);
379 }
380 }
381
382 template<size_t order, typename Derivative, size_t selectionDepth>
383 struct CallSetDerivative {
384 public:
385 template<size_t pos>
386 void operator()(std::integral_constant<size_t, pos>, Type& v, Derivative const& d) {
387 DerivativeAccess::derivative<order, pos - 1, selectionDepth>(v) = d;
388 }
389 };
390 };
391}
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition: config.h:457
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition: macros.hpp:94
#define CODI_UNDEFINED_VALUE
Used in interface declarations for variables that have to be defined in the specializations.
Definition: macros.hpp:117
#define CODI_STATIC_ASSERT(cond, message)
Static assert in CoDiPack.
Definition: macros.hpp:123
#define CODI_T(...)
Abbreviation for CODI_TEMPLATE.
Definition: macros.hpp:111
CoDiPack - Code Differentiation Package.
Definition: codi.hpp:90
void CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition: macros.hpp:46
size_t constexpr binomial(size_t n, size_t k)
Binomial coefficient computation.
Definition: binomial.hpp:56
Compile time loop evaluation.
Definition: compileTimeLoop.hpp:54
A helper class for the access of the various derivatives in higher order AD types.
Definition: derivativeAccess.hpp:267
static SelectCompileTime< false, selectionDepth, order, l >::RType & derivative(Type &v)
Definition: derivativeAccess.hpp:335
static void setAllDerivativesForward(Type &v, size_t order, Derivative const &d)
Definition: derivativeAccess.hpp:312
static void setAllDerivatives(Type &v, Derivative const &d)
Compile time set of all derivatives of the same order. .
Definition: derivativeAccess.hpp:341
static void setAllDerivativesReverse(Type &v, Derivative const &d)
Definition: derivativeAccess.hpp:357
static void setAllDerivativesForward(Type &v, Derivative const &d)
Definition: derivativeAccess.hpp:349
static SelectRunTime< true, selectionDepth >::RType const & derivative(Type const &v, size_t order, size_t l)
Definition: derivativeAccess.hpp:284
static SelectRunTime< false, selectionDepth >::RType & derivative(Type &v, size_t order, size_t l)
Definition: derivativeAccess.hpp:294
static void setAllDerivatives(Type &v, size_t order, Derivative const &d)
Run time set of all derivatives of the same order. .
Definition: derivativeAccess.hpp:302
static SelectCompileTime< true, selectionDepth, order, l >::RType const & derivative(Type const &v)
Definition: derivativeAccess.hpp:328
DerivativeAccessImpl::SelectRunTime< Type, constant, selectionDepth > SelectRunTime
Helper for the run time selection of derivatives.
Definition: derivativeAccess.hpp:275
static void setAllDerivativesReverse(Type &v, size_t order, Derivative const &d)
Definition: derivativeAccess.hpp:320
DerivativeAccessImpl::SelectCompileTime< Type, constant, selectionDepth, order, l > SelectCompileTime
Helper for the compile time selection of derivatives.
Definition: derivativeAccess.hpp:279
T_Type Type
See DerivativeAccess.
Definition: derivativeAccess.hpp:271