CoDiPack  3.0.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
computeExpression.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2025 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://scicomp.rptu.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://scicomp.rptu.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 <tuple>
38
39#include "../config.h"
40#include "../misc/macros.hpp"
41#include "../misc/tupleMemory.hpp"
42#include "../traits/computationTraits.hpp"
43#include "../traits/expressionTraits.hpp"
44#include "expressionInterface.hpp"
45#include "logic/compileTimeTraversalLogic.hpp"
46#include "logic/nodeInterface.hpp"
47#include "logic/traversalLogic.hpp"
48
50namespace codi {
51
61 template<typename T_Real>
63 public:
64
65 using Real = CODI_DD(T_Real, double);
66
70 template<typename... Args>
71 static CODI_INLINE Real primal(Args const&... args);
72
75 template<size_t argNumber, typename Tangent, typename... Args>
76 static CODI_INLINE auto applyTangent(Tangent const& tangent, Real const& result, Args const&... args);
77
80 template<size_t argNumber, typename Adjoint, typename... Args>
81 static CODI_INLINE auto applyAdjoint(Adjoint const& adjoint, Real const& result, Args const&... args);
82
84 static CODI_INLINE std::string getMathRep();
85 };
86
97 template<typename T_Real, typename T_Impl>
98 struct UnaryOperation : public ComputeOperation<T_Real> {
99 public:
100
101 using Real = CODI_DD(T_Real, double);
102
104 template<typename Arg>
105 static CODI_INLINE Real primal(Arg const& arg);
106
109 template<typename Tangent, typename Arg>
110 static CODI_INLINE auto applyTangentArg(Tangent const& tangent, Real const& result, Arg const& arg);
111
114 template<typename Adjoint, typename Arg>
115 static CODI_INLINE auto applyAdjointArg(Adjoint const& adjoint, Real const& result, Arg const& arg);
116
117 // Interface implementation
118
119 using Impl = CODI_DD(T_Impl, UnaryOperation);
120
124 template<size_t argNumber, typename Tangent, typename Arg>
125 static CODI_INLINE auto applyTangent(Tangent const& tangent, Real const& result, Arg const& arg) {
126 return Impl::applyTangentArg(tangent, result, arg);
127 }
128
132 template<size_t argNumber, typename Adjoint, typename Arg>
133 static CODI_INLINE auto applyAdjoint(Adjoint const& adjoint, Real const& result, Arg const& arg) {
134 return Impl::applyAdjointArg(adjoint, result, arg);
135 }
136 };
137
148 template<typename T_Real, typename T_Impl>
149 struct UnaryJacobianOperation : UnaryOperation<T_Real, T_Impl> {
150 public:
151
152 using Real = CODI_DD(T_Real, double);
153
155 template<typename Arg>
156 static CODI_INLINE Real primal(Arg const& arg);
157
159 template<typename Arg>
160 static CODI_INLINE auto gradient(Arg const& arg, Real const& result);
161
162 // Interface implementation
163
165
169 template<typename Tangent, typename Arg>
170 static CODI_INLINE auto applyTangentArg(Tangent const& tangent, Real const& result, Arg const& arg) {
171 return Impl::gradient(arg, result) * tangent;
172 }
173
177 template<typename Adjoint, typename Arg>
178 static CODI_INLINE Arg applyAdjointArg(Adjoint const& adjoint, Real const& result, Arg const& arg) {
179 return ComputationTraits::transpose(Impl::gradient(arg, result)) * adjoint;
180 }
181 };
182
196 template<typename T_Real, typename T_Impl>
197 struct BinaryOperation : public ComputeOperation<T_Real> {
198 public:
199
200 using Real = CODI_DD(T_Real, double);
201
203 template<typename ArgA, typename ArgB>
204 static CODI_INLINE Real primal(ArgA const& argA, ArgB const& argB);
205
208 template<typename Tangent, typename ArgA, typename ArgB>
209 static CODI_INLINE auto applyTangentArgA(Tangent const& tangent, Real const& result, ArgA const& argA,
210 ArgB const& argB);
211
214 template<typename Adjoint, typename ArgA, typename ArgB>
215 static CODI_INLINE auto applyAdjointArgA(Adjoint const& adjoint, Real const& result, ArgA const& argA,
216 ArgB const& argB);
217
220 template<typename Tangent, typename ArgA, typename ArgB>
221 static CODI_INLINE auto applyTangentArgB(Tangent const& tangent, Real const& result, ArgA const& argA,
222 ArgB const& argB);
223
226 template<typename Adjoint, typename ArgA, typename ArgB>
227 static CODI_INLINE auto applyAdjointArgB(Adjoint const& adjoint, Real const& result, ArgA const& argA,
228 ArgB const& argB);
229
230 // Interface implementation
231
232 using Impl = CODI_DD(T_Impl, BinaryOperation);
233
234#ifndef DOXYGEN_DISABLE
235 template<typename Func, bool derivB = false>
236 struct CallSwitchTangent {
237 public:
238 template<typename... Args>
239 CODI_INLINE static auto call(Args&&... args) {
240 return Impl::applyTangentArgA(std::forward<Args>(args)...);
241 }
242 };
243
244 template<typename Temp>
245 struct CallSwitchTangent<Temp, true> {
246 public:
247 template<typename... Args>
248 CODI_INLINE static auto call(Args&&... args) {
249 return Impl::applyTangentArgB(std::forward<Args>(args)...);
250 }
251 };
252
253 template<typename Func, bool derivB = false>
254 struct CallSwitchAdjoint {
255 public:
256 template<typename... Args>
257 CODI_INLINE static auto call(Args&&... args) {
258 return Impl::applyAdjointArgA(std::forward<Args>(args)...);
259 }
260 };
261
262 template<typename Temp>
263 struct CallSwitchAdjoint<Temp, true> {
264 public:
265 template<typename... Args>
266 CODI_INLINE static auto call(Args&&... args) {
267 return Impl::applyAdjointArgB(std::forward<Args>(args)...);
268 }
269 };
270#endif
271
275 template<size_t argNumber, typename Tangent, typename ArgA, typename ArgB>
276 static CODI_INLINE auto applyTangent(Tangent const& tangent, Real const& result, ArgA const& argA,
277 ArgB const& argB) {
278 return CallSwitchTangent < void, argNumber == 1 > ::call(tangent, result, argA, argB);
279 }
280
284 template<size_t argNumber, typename Adjoint, typename ArgA, typename ArgB>
285 static CODI_INLINE auto applyAdjoint(Adjoint const& adjoint, Real const& result, ArgA const& argA,
286 ArgB const& argB) {
287 return CallSwitchAdjoint < void, argNumber == 1 > ::call(adjoint, result, argA, argB);
288 }
289 };
290
301 template<typename T_Real, typename T_Impl>
302 struct BinaryJacobianOperation : public BinaryOperation<T_Real, T_Impl> {
303 public:
304
305 using Real = CODI_DD(T_Real, double);
306
308 template<typename ArgA, typename ArgB>
309 static CODI_INLINE Real primal(ArgA const& argA, ArgB const& argB);
310
312 template<typename ArgA, typename ArgB>
313 static CODI_INLINE auto gradientA(ArgA const& argA, ArgB const& argB, Real const& result);
314
316 template<typename ArgA, typename ArgB>
317 static CODI_INLINE auto gradientB(ArgA const& argA, ArgB const& argB, Real const& result);
318
319 // Interface implementation
320
322
326 template<typename Tangent, typename ArgA, typename ArgB>
327 static CODI_INLINE auto applyTangentArgA(Tangent const& tangent, Real const& result, ArgA const& argA,
328 ArgB const& argB) {
329 return Impl::gradientA(argA, argB, result) * tangent;
330 }
331
335 template<typename Adjoint, typename ArgA, typename ArgB>
336 static CODI_INLINE ArgA applyAdjointArgA(Adjoint const& adjoint, Real const& result, ArgA const& argA,
337 ArgB const& argB) {
338 return ComputationTraits::transpose(Impl::gradientA(argA, argB, result)) * adjoint;
339 }
340
344 template<typename Tangent, typename ArgA, typename ArgB>
345 static CODI_INLINE auto applyTangentArgB(Tangent const& tangent, Real const& result, ArgA const& argA,
346 ArgB const& argB) {
347 return Impl::gradientB(argA, argB, result) * tangent;
348 }
349
353 template<typename Adjoint, typename ArgA, typename ArgB>
354 static CODI_INLINE ArgB applyAdjointArgB(Adjoint const& adjoint, Real const& result, ArgA const& argA,
355 ArgB const& argB) {
356 return ComputationTraits::transpose(Impl::gradientB(argA, argB, result)) * adjoint;
357 }
358 };
359
369 template<typename T_Real, template<typename> class T_Operation, typename... T_ArgExprs>
371 : public ExpressionInterface<T_Real, ComputeExpression<T_Real, T_Operation, T_ArgExprs...> > {
372 public:
373 using Real = CODI_DD(T_Real, double);
374 template<typename T>
375 using Operation = CODI_DD(CODI_T(T_Operation<T>), CODI_T(ComputeOperation<T>));
376 using ArgExprs = std::tuple<T_ArgExprs...>;
377
378 using ArgReals = std::tuple<typename T_ArgExprs::Real...>;
380 std::tuple<typename T_ArgExprs::StoreAs...>;
381 using ArgStores = TupleMemory<typename T_ArgExprs::StoreAs...>;
382
384
386
390
393
394 /*******************************************************************************/
397
399 CODI_INLINE std::string getMathRep() const {
401 }
402
404 /*******************************************************************************/
407
410 typename T_ArgExprs::ADLogic...>::ADLogic;
411
413 CODI_INLINE Real const& getValue() const {
414 return result;
415 }
416
420 template<size_t argNumber, typename Tangent>
421 CODI_INLINE Real applyTangent(Tangent const& tangent) const {
422 return callTangent<argNumber>(tangent, result, args);
423 }
424
428 template<size_t argNumber, typename Adjoint>
429 CODI_INLINE auto applyAdjoint(Adjoint const& adjoint) const {
430 return callAdjoint<argNumber>(adjoint, result, args);
431 }
432
434 /*******************************************************************************/
437
438 static size_t constexpr LinkCount = std::tuple_size<ArgReals>::value;
439
441 template<size_t argNumber>
442 CODI_INLINE std::tuple_element_t<argNumber, ArgStoresTypes> const& getLink() const {
443 return args.template get<argNumber>();
444 }
445
446
447 private:
448
449 // Unpack helpers
450
451 template<size_t argNumber, typename EvalArg, typename Tuple, size_t... I>
452 static CODI_INLINE auto callAdjoint(EvalArg const& evalArg, Real const& result, Tuple t,
453 std::index_sequence<I...>) {
454 return Operation<Real>::template applyAdjoint<argNumber>(evalArg, result, t.template get<I>().getValue()...);
455 }
456
457 template<size_t argNumber, typename EvalArg, typename Tuple>
458 static CODI_INLINE auto callAdjoint(EvalArg const& evalArg, Real const& result, Tuple const& t) {
459 static constexpr auto size = std::tuple_size<ArgStoresTypes>::value;
460 return callAdjoint<argNumber>(evalArg, result, t, std::make_index_sequence<size>{});
461 }
462
463 template<size_t argNumber, typename EvalArg, typename Tuple, size_t... I>
464 static CODI_INLINE auto callTangent(EvalArg const& evalArg, Real const& result, Tuple t,
465 std::index_sequence<I...>) {
466 return Operation<Real>::template applyTangent<argNumber>(evalArg, result, t.template get<I>().getValue()...);
467 }
468
469 template<size_t argNumber, typename EvalArg, typename Tuple>
470 static CODI_INLINE auto callTangent(EvalArg const& evalArg, Real const& result, Tuple const& t) {
471 static constexpr auto size = std::tuple_size<ArgStoresTypes>::value;
472 return callTangent<argNumber>(evalArg, result, t, std::make_index_sequence<size>{});
473 }
474 };
475}
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:469
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:96
#define CODI_T(...)
Abbreviation for CODI_TEMPLATE.
Definition macros.hpp:116
ValidateADLogicImpl< Results... > ValidateADLogic
Validates if the AD logic of an arbitrary amount of expressions are the same or compatible....
Definition expressionTraits.hpp:119
CoDiPack - Code Differentiation Package.
Definition codi.hpp:94
inlineauto arg(ExpressionInterface< std::complex< Real >, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:75
Implements BinaryOperation for functions where the gradients can be computed and transposed.
Definition computeExpression.hpp:302
T_Impl Impl
See BinaryJacobianOperation.
Definition computeExpression.hpp:321
static inlineauto gradientA(ArgA const &argA, ArgB const &argB, Real const &result)
Compute .
static inlineReal primal(ArgA const &argA, ArgB const &argB)
static inlineauto applyTangentArgA(Tangent const &tangent, Real const &result, ArgA const &argA, ArgB const &argB)
Definition computeExpression.hpp:327
static inlineArgA applyAdjointArgA(Adjoint const &adjoint, Real const &result, ArgA const &argA, ArgB const &argB)
Definition computeExpression.hpp:336
static inlineauto applyTangentArgB(Tangent const &tangent, Real const &result, ArgA const &argA, ArgB const &argB)
Definition computeExpression.hpp:345
static inlineArgB applyAdjointArgB(Adjoint const &adjoint, Real const &result, ArgA const &argA, ArgB const &argB)
Definition computeExpression.hpp:354
static inlineauto gradientB(ArgA const &argA, ArgB const &argB, Real const &result)
Compute .
T_Real Real
See BinaryJacobianOperation.
Definition computeExpression.hpp:305
Implements ComputeOperation for two arguments.
Definition computeExpression.hpp:197
static inlineReal primal(ArgA const &argA, ArgB const &argB)
static inlineauto applyAdjoint(Adjoint const &adjoint, Real const &result, ArgA const &argA, ArgB const &argB)
Definition computeExpression.hpp:285
static inlineauto applyAdjointArgB(Adjoint const &adjoint, Real const &result, ArgA const &argA, ArgB const &argB)
static inlineauto applyTangentArgB(Tangent const &tangent, Real const &result, ArgA const &argA, ArgB const &argB)
T_Real Real
See BinaryOperation.
Definition computeExpression.hpp:200
static inlineauto applyTangent(Tangent const &tangent, Real const &result, ArgA const &argA, ArgB const &argB)
Definition computeExpression.hpp:276
T_Impl Impl
See BinaryOperation.
Definition computeExpression.hpp:232
static inlineauto applyTangentArgA(Tangent const &tangent, Real const &result, ArgA const &argA, ArgB const &argB)
static inlineauto applyAdjointArgA(Adjoint const &adjoint, Real const &result, ArgA const &argA, ArgB const &argB)
std::tuple< T_ArgExprs... > ArgExprs
Definition computeExpression.hpp:376
std::tuple< typename T_ArgExprs::StoreAs... > ArgStoresTypes
Definition computeExpression.hpp:379
InnerReal Real
Definition computeExpression.hpp:373
TupleMemory< typename T_ArgExprs::StoreAs... > ArgStores
Definition computeExpression.hpp:381
inlinestd::string getMathRep() const
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition computeExpression.hpp:399
ComputeExpression StoreAs
Definition computeExpression.hpp:408
inlineexplicit ComputeExpression(ExpressionInterface< typename T_ArgExprs::Real, T_ArgExprs > const &... args)
Constructor.
Definition computeExpression.hpp:388
static size_t constexpr LinkCount
Definition computeExpression.hpp:438
typename ExpressionTraits::ValidateADLogic< typename T_ArgExprs::ADLogic... >::ADLogic ADLogic
Definition computeExpression.hpp:409
inlinestd::tuple_element_t< argNumber, ArgStoresTypes > const & getLink() const
an expression.
Definition computeExpression.hpp:442
inlineReal applyTangent(Tangent const &tangent) const
Definition computeExpression.hpp:421
std::tuple< typename T_ArgExprs::Real... > ArgReals
Definition computeExpression.hpp:378
ArrayAccessOperation< T > Operation
Definition computeExpression.hpp:375
inlineReal const & getValue() const
Definition computeExpression.hpp:413
inlineauto applyAdjoint(Adjoint const &adjoint) const
Definition computeExpression.hpp:429
ArgStores args
Definition computeExpression.hpp:383
Interface for implementing the logic for a ComputeExpression.
Definition computeExpression.hpp:62
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
static inlineauto applyAdjoint(Adjoint const &adjoint, Real const &result, Args const &... args)
static inlineauto applyTangent(Tangent const &tangent, Real const &result, Args const &... args)
static inlineReal primal(Args const &... args)
T_Real Real
See ComputeOperation.
Definition computeExpression.hpp:65
inlineImpl const & cast() const
Cast to the implementation.
Definition expressionInterface.hpp:76
Tuple implementation which allows to force inline of the construction of the tuple.
Definition tupleMemory.hpp:92
Implements UnaryOperation for functions where the gradient can be computed and transposed.
Definition computeExpression.hpp:149
static inlineReal primal(Arg const &arg)
static inlineauto applyTangentArg(Tangent const &tangent, Real const &result, Arg const &arg)
Definition computeExpression.hpp:170
static inlineauto gradient(Arg const &arg, Real const &result)
Compute .
static inlineArg applyAdjointArg(Adjoint const &adjoint, Real const &result, Arg const &arg)
Definition computeExpression.hpp:178
T_Impl Impl
See UnaryOperation.
Definition computeExpression.hpp:164
T_Real Real
See UnaryJacobianOperation.
Definition computeExpression.hpp:152
Implements ComputeOperation for one argument.
Definition computeExpression.hpp:98
T_Impl Impl
See UnaryOperation.
Definition computeExpression.hpp:119
static inlineauto applyAdjointArg(Adjoint const &adjoint, Real const &result, Arg const &arg)
static inlineauto applyTangent(Tangent const &tangent, Real const &result, Arg const &arg)
Definition computeExpression.hpp:125
static inlineReal primal(Arg const &arg)
T_Real Real
See UnaryOperation.
Definition computeExpression.hpp:101
static inlineauto applyTangentArg(Tangent const &tangent, Real const &result, Arg const &arg)
static inlineauto applyAdjoint(Adjoint const &adjoint, Real const &result, Arg const &arg)
Definition computeExpression.hpp:133