openpilot/external/cppad/include/cppad/core/print_for.hpp

220 lines
6.0 KiB
C++

# ifndef CPPAD_CORE_PRINT_FOR_HPP
# define CPPAD_CORE_PRINT_FOR_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
CppAD is distributed under multiple licenses. This distribution is under
the terms of the
Eclipse Public License Version 1.0.
A copy of this license is included in the COPYING file of this distribution.
Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
-------------------------------------------------------------------------- */
/*
$begin PrintFor$$
$spell
pos
var
VecAD
std
cout
const
$$
$section Printing AD Values During Forward Mode$$
$mindex print text output debug$$
$head Syntax$$
$icode%f%.Forward(0, %x%)
%$$
$codei%PrintFor(%before%, %var%)
%$$
$codei%PrintFor(%pos%, %before%, %var%, %after%)
%$$
$head Purpose$$
The $cref/zero order forward/forward_zero/$$ mode command
$codei%
%f%.Forward(0, %x%)
%$$
assigns the
$cref/independent variable/glossary/Tape/Independent Variable/$$ vector
equal to $icode x$$.
It then computes a value for all of the dependent variables in the
$cref/operation sequence/glossary/Operation/Sequence/$$ corresponding
to $icode f$$.
Putting a $code PrintFor$$ in the operation sequence will
cause the value of $icode var$$, corresponding to $icode x$$,
to be printed during zero order forward operations.
$head f.Forward(0, x)$$
The objects $icode f$$, $icode x$$, and the purpose
for this operation, are documented in $cref Forward$$.
$head pos$$
If present, the argument $icode pos$$ has one of the following prototypes
$codei%
const AD<%Base%>& %pos%
const VecAD<%Base%>::reference& %pos%
%$$
In this case
the text and $icode var$$ will be printed if and only if
$icode pos$$ is not greater than zero and a finite number.
$head before$$
The argument $icode before$$ has prototype
$codei%
const char* %before%
%$$
This text is written to $code std::cout$$ before $icode var$$.
$head var$$
The argument $icode var$$ has one of the following prototypes
$codei%
const AD<%Base%>& %var%
const VecAD<%Base%>::reference& %var%
%$$
The value of $icode var$$, that corresponds to $icode x$$,
is written to $code std::cout$$ during the execution of
$codei%
%f%.Forward(0, %x%)
%$$
Note that $icode var$$ may be a
$cref/variable/glossary/Variable/$$ or
$cref/parameter/glossary/Parameter/$$.
(A parameters value does not depend on the value of
the independent variable vector $icode x$$.)
$head after$$
The argument $icode after$$ has prototype
$codei%
const char* %after%
%$$
This text is written to $code std::cout$$ after $icode var$$.
$head Redirecting Output$$
You can redirect this output to any standard output stream; see the
$cref/s/forward_order/s/$$ in the forward mode documentation.
$head Discussion$$
This is helpful for understanding why tape evaluations
have trouble.
For example, if one of the operations in $icode f$$ is
$codei%log(%var%)%$$ and $icode%var% <= 0%$$,
the corresponding result will be $cref nan$$.
$head Alternative$$
The $cref ad_output$$ section describes the normal
printing of values; i.e., printing when the corresponding
code is executed.
$head Example$$
$children%
example/print_for/print_for.cpp%
example/general/print_for.cpp
%$$
The program
$cref print_for_cout.cpp$$
is an example and test that prints to standard output.
The output of this program
states the conditions for passing and failing the test.
The function
$cref print_for_string.cpp$$
is an example and test that prints to an standard string stream.
This function automatically check for correct output.
$end
------------------------------------------------------------------------------
*/
# include <cstring>
namespace CppAD {
template <class Base>
void PrintFor(const AD<Base>& pos,
const char *before, const AD<Base>& var, const char* after)
{ CPPAD_ASSERT_NARG_NRES(local::PriOp, 5, 0);
// check for case where we are not recording operations
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return;
CPPAD_ASSERT_KNOWN(
std::strlen(before) <= 1000 ,
"PrintFor: length of before is greater than 1000 characters"
);
CPPAD_ASSERT_KNOWN(
std::strlen(after) <= 1000 ,
"PrintFor: length of after is greater than 1000 characters"
);
addr_t ind0, ind1, ind2, ind3, ind4;
// ind[0] = base 2 representation of the value [Var(pos), Var(var)]
ind0 = 0;
// ind[1] = address for pos
if( Parameter(pos) )
ind1 = tape->Rec_.PutPar(pos.value_);
else
{ ind0 += 1;
ind1 = pos.taddr_;
}
// ind[2] = address of before
ind2 = tape->Rec_.PutTxt(before);
// ind[3] = address for var
if( Parameter(var) )
ind3 = tape->Rec_.PutPar(var.value_);
else
{ ind0 += 2;
ind3 = var.taddr_;
}
// ind[4] = address of after
ind4 = tape->Rec_.PutTxt(after);
// put the operator in the tape
tape->Rec_.PutArg(ind0, ind1, ind2, ind3, ind4);
tape->Rec_.PutOp(local::PriOp);
}
// Fold all other cases into the case above
template <class Base>
void PrintFor(const char* before, const AD<Base>& var)
{ PrintFor(AD<Base>(0), before, var, "" ); }
//
template <class Base>
void PrintFor(const char* before, const VecAD_reference<Base>& var)
{ PrintFor(AD<Base>(0), before, var.ADBase(), "" ); }
//
template <class Base>
void PrintFor(
const VecAD_reference<Base>& pos ,
const char *before ,
const VecAD_reference<Base>& var ,
const char *after )
{ PrintFor(pos.ADBase(), before, var.ADBase(), after); }
//
template <class Base>
void PrintFor(
const VecAD_reference<Base>& pos ,
const char *before ,
const AD<Base>& var ,
const char *after )
{ PrintFor(pos.ADBase(), before, var, after); }
//
template <class Base>
void PrintFor(
const AD<Base>& pos ,
const char *before ,
const VecAD_reference<Base>& var ,
const char *after )
{ PrintFor(pos, before, var.ADBase(), after); }
}
# endif