38#include "../expressions/lhsExpressionInterface.hpp"
39#include "../misc/exceptions.hpp"
40#include "../tapes/misc/tapeParameters.hpp"
41#include "../traits/gradientTraits.hpp"
42#include "data/dummy.hpp"
43#include "data/jacobian.hpp"
44#include "data/staticDummy.hpp"
67 template<
typename T_Type,
bool T_ActiveChecks = true>
76 using Tape =
typename Type::Tape;
78 using Real =
typename Type::Real;
94 if (inputs <= outputs) {
95 return EvaluationType::Forward;
97 return EvaluationType::Reverse;
140 template<
typename Jac,
bool keepState = true>
143 size_t const outputSize, Jac& jac,
145 size_t constexpr gradDim =
GT::dim;
149 tape.resizeAdjointVector();
150 tape.beginUseAdjointVector();
154 if (EvaluationType::Forward == evalType) {
155 for (
size_t j = 0; j < inputSize; j += gradDim) {
164 for (
size_t i = 0; i < outputSize; i += 1) {
165 for (
size_t curDim = 0; curDim < gradDim && j + curDim < inputSize; curDim += 1) {
166 jac(outputSize - i - 1, j + curDim) =
180 }
else if (EvaluationType::Reverse == evalType) {
181 for (
size_t i = 0; i < outputSize; i += gradDim) {
190 for (
size_t j = 0; j < inputSize; j += 1) {
191 for (
size_t curDim = 0; curDim < gradDim && i + curDim < outputSize; curDim += 1) {
204 CODI_EXCEPTION(
"Evaluation mode not implemented. Mode is: %d.", (
int)evalType);
208 tape.endUseAdjointVector();
217 template<
typename Jac>
219 size_t const inputSize,
Identifier const* output,
size_t const outputSize,
222 computeJacobian(Type::getTape(), start, end, input, inputSize, output, outputSize, jac, adjointsManagement);
243 template<
typename Hes,
typename Jac = DummyJacobian>
245 Identifier const* input,
size_t const inputSize,
246 Identifier const* output,
size_t const outputSize, Hes& hes,
249 if (EvaluationType::Forward == evalType) {
251 }
else if (EvaluationType::Reverse == evalType) {
254 CODI_EXCEPTION(
"Evaluation mode not implemented. Mode is: %d.", (
int)evalType);
269 template<
typename Hes,
typename Jac = DummyJacobian>
272 size_t const inputSize,
Identifier const* output,
273 size_t const outputSize, Hes& hes,
276 size_t constexpr gradDim1st = GT1st::dim;
278 size_t constexpr gradDim2nd = GT2nd::dim;
281 tape.revertPrimals(start);
283 for (
size_t j = 0; j < inputSize; j += gradDim2nd) {
284 setGradient2ndOnIdentifier(tape, j, input, inputSize,
typename GT2nd::Real(1.0));
287 for (
size_t k = j; k < inputSize; k += gradDim1st) {
288 setGradientOnIdentifier(tape, k, input, inputSize,
typename GT1st::Real(1.0));
290 tape.evaluateForward(start, end);
292 for (
size_t i = 0; i < outputSize; i += 1) {
293 for (
size_t vecPos1st = 0; vecPos1st < gradDim1st && k + vecPos1st < inputSize; vecPos1st += 1) {
294 for (
size_t vecPos2nd = 0; vecPos2nd < gradDim2nd && j + vecPos2nd < inputSize; vecPos2nd += 1) {
295 hes(i, j + vecPos2nd, k + vecPos1st) =
296 GT2nd::at(GT1st::at(tape.getGradient(output[i]), vecPos1st).gradient(), vecPos2nd);
297 hes(i, k + vecPos1st, j + vecPos2nd) = hes(i, j + vecPos2nd, k + vecPos1st);
302 for (
size_t vecPos = 0; vecPos < gradDim1st && k + vecPos < inputSize; vecPos += 1) {
303 jac(i, k + vecPos) = GT1st::at(tape.getGradient(output[i]), vecPos).value();
308 setGradientOnIdentifier(tape, k, input, inputSize,
typename GT1st::Real());
311 setGradient2ndOnIdentifier(tape, j, input, inputSize,
typename GT2nd::Real());
326 template<
typename Hes,
typename Jac = DummyJacobian>
329 size_t const inputSize,
Identifier const* output,
330 size_t const outputSize, Hes& hes,
333 size_t constexpr gradDim1st = GT1st::dim;
335 size_t constexpr gradDim2nd = GT2nd::dim;
338 tape.revertPrimals(start);
340 for (
size_t j = 0; j < inputSize; j += gradDim2nd) {
341 setGradient2ndOnIdentifier(tape, j, input, inputSize,
typename GT2nd::Real(1.0));
344 tape.evaluatePrimal(start, end);
346 for (
size_t i = 0; i < outputSize; i += gradDim1st) {
347 setGradientOnIdentifier(tape, i, output, outputSize,
typename GT1st::Real(1.0));
350 tape.evaluateKeepState(end, start);
352 for (
size_t k = 0; k < inputSize; k += 1) {
353 for (
size_t vecPos1st = 0; vecPos1st < gradDim1st && i + vecPos1st < outputSize; vecPos1st += 1) {
354 for (
size_t vecPos2nd = 0; vecPos2nd < gradDim2nd && j + vecPos2nd < inputSize; vecPos2nd += 1) {
355 hes(i + vecPos1st, j + vecPos2nd, k) =
356 GT2nd::at(GT1st::at(tape.gradient(input[k]), vecPos1st).gradient(), vecPos2nd);
361 for (
size_t vecPos1st = 0; vecPos1st < gradDim1st && i + vecPos1st < outputSize; vecPos1st += 1) {
362 jac(i + vecPos1st, k) = GT1st::at(tape.getGradient(input[k]), vecPos1st).value();
366 tape.gradient(input[k]) =
Gradient();
369 setGradientOnIdentifier(tape, i, output, outputSize,
typename GT1st::Real());
372 tape.clearAdjoints(end, start);
376 setGradient2ndOnIdentifier(tape, j, input, inputSize,
typename GT2nd::Real());
378 if (j + gradDim2nd < inputSize) {
379 tape.revertPrimals(start);
401 template<
typename Func,
typename VecIn,
typename VecOut,
typename Hes,
typename Jac = DummyJacobian>
405 if (EvaluationType::Forward == evalType) {
407 }
else if (EvaluationType::Reverse == evalType) {
410 CODI_EXCEPTION(
"Evaluation mode not implemented. Mode is: %d.", (
int)evalType);
427 template<
typename Func,
typename VecIn,
typename VecOut,
typename Hes,
typename Jac = DummyJacobian>
431 size_t constexpr gradDim1st = GT1st::dim;
433 size_t constexpr gradDim2nd = GT2nd::dim;
435 Tape& tape = Type::getTape();
437 for (
size_t j = 0; j < input.size(); j += gradDim2nd) {
438 setGradient2ndOnCoDiValue(j, input.data(), input.size(),
typename GT2nd::Real(1.0));
441 recordTape(func, input, output);
444 for (
size_t k = j; k < input.size(); k += gradDim1st) {
445 setGradientOnCoDiValue(tape, k, input.data(), input.size(),
typename GT1st::Real(1.0));
448 tape.evaluateForwardKeepState(tape.getZeroPosition(), tape.getPosition());
450 for (
size_t i = 0; i < output.size(); i += 1) {
451 for (
size_t vecPos1st = 0; vecPos1st < gradDim1st && k + vecPos1st < input.size(); vecPos1st += 1) {
452 for (
size_t vecPos2nd = 0; vecPos2nd < gradDim2nd && j + vecPos2nd < input.size(); vecPos2nd += 1) {
453 hes(i, j + vecPos2nd, k + vecPos1st) = GT2nd::at(
454 GT1st::at(tape.getGradient(output[i].getIdentifier()), vecPos1st).gradient(), vecPos2nd);
455 hes(i, k + vecPos1st, j + vecPos2nd) = hes(i, j + vecPos2nd, k + vecPos1st);
460 for (
size_t vecPos = 0; vecPos < gradDim1st && k + vecPos < input.size(); vecPos += 1) {
461 jac(i, k + vecPos) = GT1st::at(tape.getGradient(output[i].getIdentifier()), vecPos).value();
466 setGradientOnCoDiValue(tape, k, input.data(), input.size(),
typename GT1st::Real());
469 setGradient2ndOnCoDiValue(j, input.data(), input.size(),
typename GT2nd::Real());
488 template<
typename Func,
typename VecIn,
typename VecOut,
typename Hes,
typename Jac = DummyJacobian>
492 size_t constexpr gradDim1st = GT1st::dim;
494 size_t constexpr gradDim2nd = GT2nd::dim;
496 Tape& tape = Type::getTape();
498 for (
size_t j = 0; j < input.size(); j += gradDim2nd) {
499 setGradient2ndOnCoDiValue(j, input.data(), input.size(),
typename GT2nd::Real(1.0));
502 recordTape(func, input, output);
504 for (
size_t i = 0; i < output.size(); i += gradDim1st) {
505 setGradientOnCoDiValue(tape, i, output.data(), output.size(),
typename GT1st::Real(1.0));
508 tape.evaluateKeepState(tape.getPosition(), tape.getZeroPosition());
510 for (
size_t k = 0; k < input.size(); k += 1) {
511 for (
size_t vecPos1st = 0; vecPos1st < gradDim1st && i + vecPos1st < output.size(); vecPos1st += 1) {
512 for (
size_t vecPos2nd = 0; vecPos2nd < gradDim2nd && j + vecPos2nd < input.size(); vecPos2nd += 1) {
513 hes(i + vecPos1st, j + vecPos2nd, k) =
514 GT2nd::at(GT1st::at(tape.gradient(input[k].getIdentifier()), vecPos1st).gradient(), vecPos2nd);
519 for (
size_t vecPos1st = 0; vecPos1st < gradDim1st && i + vecPos1st < output.size(); vecPos1st += 1) {
520 jac(i + vecPos1st, k) = GT1st::at(tape.getGradient(input[k].getIdentifier()), vecPos1st).value();
524 tape.gradient(input[k].getIdentifier()) =
Gradient();
527 setGradientOnCoDiValue(tape, i, output.data(), output.size(),
typename GT1st::Real());
530 tape.clearAdjoints(tape.getPosition(), tape.getZeroPosition());
534 setGradient2ndOnCoDiValue(j, input.data(), input.size(),
typename GT2nd::Real());
550 Tape& tape,
size_t const pos, Identifier
const* identifiers,
size_t const size, T value,
552 size_t constexpr gradDim =
GT::dim;
554 for (
size_t curDim = 0; curDim < gradDim && pos + curDim < size; curDim += 1) {
556 GT::at(tape.gradient(identifiers[pos + curDim], adjointsManagement), curDim) = value;
563 static CODI_INLINE void setGradient2ndOnIdentifier(Tape& tape,
size_t const pos, Identifier
const* identifiers,
564 size_t const size, T value) {
566 size_t constexpr gradDim2nd = GT2nd::dim;
568 for (
size_t curDim = 0; curDim < gradDim2nd && pos + curDim < size; curDim += 1) {
570 GT2nd::at(tape.primal(identifiers[pos + curDim]).gradient(), curDim) = value;
581 static CODI_INLINE void setGradientOnCoDiValue(Tape& tape,
size_t const pos,
Type* identifiers,
size_t const size,
583 size_t constexpr gradDim =
GT::dim;
585 for (
size_t curDim = 0; curDim < gradDim && pos + curDim < size; curDim += 1) {
587 GT::at(tape.gradient(identifiers[pos + curDim].getIdentifier()), curDim) = value;
594 static CODI_INLINE void setGradient2ndOnCoDiValue(
size_t const pos,
Type* identifiers,
size_t const size,
597 size_t constexpr gradDim2nd = GT2nd::dim;
599 for (
size_t curDim = 0; curDim < gradDim2nd && pos + curDim < size; curDim += 1) {
601 GT2nd::at(identifiers[pos + curDim].value().gradient(), curDim) = value;
606 template<
typename Func,
typename VecIn,
typename VecOut>
607 static CODI_INLINE void recordTape(Func func, VecIn& input, VecOut& output) {
608 Tape& tape = Type::getTape();
610 for (
size_t curIn = 0; curIn < input.size(); curIn += 1) {
611 tape.registerInput(input[curIn]);
616 for (
size_t curOut = 0; curOut < output.size(); curOut += 1) {
617 tape.registerOutput(output[curOut]);
#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_ENABLE_CHECK(option, condition)
Definition macros.hpp:53
bool constexpr ReversalZeroesAdjoints
With a linear index management, control if adjoints are set to zero during reversal.
Definition config.h:289
DataExtraction< Type >::Identifier getIdentifier(Type const &v)
Extract the identifiers from a type of aggregated active types.
Definition realTraits.hpp:216
CoDiPack - Code Differentiation Package.
Definition codi.hpp:90
AdjointsManagement
Policies for management of the tape's interal adjoints.
Definition tapeParameters.hpp:98
@ Automatic
Manage internal adjoints automatically, including locking, bounds checking, and resizing.
@ Manual
Do not perform any bounds checking, locking, or resizing.
typename Tape::Gradient Gradient
See LhsExpressionInterface.
Definition activeTypeBase.hpp:79
Basic algorithms for tape evaluation in CoDiPack.
Definition algorithms.hpp:68
typename Type::Gradient Gradient
See LhsExpressionInterface.
Definition algorithms.hpp:80
T_Type Type
See Algorithms.
Definition algorithms.hpp:72
EvaluationType
Evaluation modes for the derivative computation.
Definition algorithms.hpp:85
typename Tape::Position Position
See LhsExpressionInterface.
Definition algorithms.hpp:77
static void computeHessianPrimalValueTapeForward(Tape &tape, Position const &start, Position const &end, Identifier const *input, size_t const inputSize, Identifier const *output, size_t const outputSize, Hes &hes, Jac &jac=StaticDummy< DummyJacobian >::dummy)
Forward version of the Hessian computation.
Definition algorithms.hpp:270
static void computeJacobian(Position const &start, Position const &end, Identifier const *input, size_t const inputSize, Identifier const *output, size_t const outputSize, Jac &jac, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Compute the Jacobian with multiple tape sweeps. This method uses the global tape for the Jacobian...
Definition algorithms.hpp:218
static bool constexpr ActiveChecks
See Algorithms.
Definition algorithms.hpp:74
static void computeHessian(Func func, VecIn &input, VecOut &output, Hes &hes, Jac &jac=StaticDummy< DummyJacobian >::dummy)
Compute the Hessian with multiple tape recordings and sweeps.
Definition algorithms.hpp:402
typename Type::Tape Tape
See LhsExpressionInterface.
Definition algorithms.hpp:76
GradientTraits::TraitsImplementation< Gradient > GT
Shortcut for traits of gradient.
Definition algorithms.hpp:82
typename Type::Identifier Identifier
See LhsExpressionInterface.
Definition algorithms.hpp:79
static void computeHessianForward(Func func, VecIn &input, VecOut &output, Hes &hes, Jac &jac=StaticDummy< DummyJacobian >::dummy)
Forward version of the Hessian computation with a function object.
Definition algorithms.hpp:428
static EvaluationType getEvaluationChoice(size_t const inputs, size_t const outputs)
Definition algorithms.hpp:93
typename Type::Real Real
See LhsExpressionInterface.
Definition algorithms.hpp:78
static void computeHessianPrimalValueTape(Tape &tape, Position const &start, Position const &end, Identifier const *input, size_t const inputSize, Identifier const *output, size_t const outputSize, Hes &hes, Jac &jac=StaticDummy< DummyJacobian >::dummy)
Compute the Hessian with multiple tape sweeps.
Definition algorithms.hpp:244
static void computeJacobian(Tape &tape, Position const &start, Position const &end, Identifier const *input, size_t const inputSize, Identifier const *output, size_t const outputSize, Jac &jac, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Compute the Jacobian with multiple tape sweeps.
Definition algorithms.hpp:141
static void computeHessianReverse(Func func, VecIn &input, VecOut &output, Hes &hes, Jac &jac=StaticDummy< DummyJacobian >::dummy)
Reverse version of the Hessian computation with a function object.
Definition algorithms.hpp:489
static void computeHessianPrimalValueTapeReverse(Tape &tape, Position const &start, Position const &end, Identifier const *input, size_t const inputSize, Identifier const *output, size_t const outputSize, Hes &hes, Jac &jac=StaticDummy< DummyJacobian >::dummy)
Reverse version of the Hessian computation.
Definition algorithms.hpp:327
Common traits for all types used as gradients.
Definition gradientTraits.hpp:64
static size_t constexpr dim
Number of dimensions this gradient value has.
Definition gradientTraits.hpp:70
static Real & at(Gradient &gradient, size_t dim)
Get the entry at the given index.
Definition gradientTraits.hpp:73
Gradient Real
The base value used in the gradient entries.
Definition gradientTraits.hpp:68
Static dummy objects for e.g. default reference arguments.
Definition staticDummy.hpp:42