remove unused stuff from external

albatross
George Hotz 2020-02-10 08:20:42 -07:00
parent 4b12aca941
commit b541f59094
363 changed files with 0 additions and 100873 deletions

View File

@ -1,77 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This script is a wrapper for smali.jar, so you can simply call "smali",
# instead of java -jar smali.jar. It is heavily based on the "dx" script
# from the Android SDK
# Set up prog to be the path of this script, including following symlinks,
# and set up progdir to be the fully-qualified pathname of its directory.
prog="$0"
while [ -h "${prog}" ]; do
newProg=`/bin/ls -ld "${prog}"`
newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
if expr "x${newProg}" : 'x/' >/dev/null; then
prog="${newProg}"
else
progdir=`dirname "${prog}"`
prog="${progdir}/${newProg}"
fi
done
oldwd=`pwd`
progdir=`dirname "${prog}"`
cd "${progdir}"
progdir=`pwd`
prog="${progdir}"/`basename "${prog}"`
cd "${oldwd}"
jarfile=apktool.jar
libdir="$progdir"
if [ ! -r "$libdir/$jarfile" ]
then
echo `basename "$prog"`": can't find $jarfile"
exit 1
fi
javaOpts=""
# If you want DX to have more memory when executing, uncomment the following
# line and adjust the value accordingly. Use "java -X" for a list of options
# you can pass here.
#
javaOpts="-Xmx512M -Dfile.encoding=utf-8"
# Alternatively, this will extract any parameter "-Jxxx" from the command line
# and pass them to Java (instead of to dx). This makes it possible for you to
# add a command-line parameter such as "-JXmx256M" in your ant scripts, for
# example.
while expr "x$1" : 'x-J' >/dev/null; do
opt=`expr "$1" : '-J\(.*\)'`
javaOpts="${javaOpts} -${opt}"
shift
done
if [ "$OSTYPE" = "cygwin" ] ; then
jarpath=`cygpath -w "$libdir/$jarfile"`
else
jarpath="$libdir/$jarfile"
fi
# add current location to path for aapt
PATH=$PATH:`pwd`;
export PATH;
exec java $javaOpts -jar "$jarpath" "$@"

View File

@ -1 +0,0 @@
apktool_2.3.0.jar

Binary file not shown.

View File

@ -1,7 +0,0 @@
wget 'http://www.coin-or.org/download/source/CppAD/cppad-20170816.epl.tgz'
tar xvf cppad-20170816.epl.tgz
cd cppad-20170816/
mkdir build
cd build
cmake -D cppad_prefix="$HOME/one/external/cppad" ..
make install

View File

@ -1,185 +0,0 @@
// $Id: base_require.hpp 3845 2016-11-19 01:50:47Z bradbell $
# ifndef CPPAD_BASE_REQUIRE_HPP
# define CPPAD_BASE_REQUIRE_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 base_require$$
$spell
azmul
ostream
alloc
eps
std
Lt
Le
Eq
Ge
Gt
cppad.hpp
namespace
optimizations
bool
const
CppAD
enum
Lt
Le
Eq
Ge
Gt
inline
Op
std
CondExp
$$
$section AD<Base> Requirements for a CppAD Base Type$$
$head Syntax$$
$code # include <cppad/base_require.hpp>$$
$head Purpose$$
This section lists the requirements for the type
$icode Base$$ so that the type $codei%AD<%Base%>%$$ can be used.
$head API Warning$$
Defining a CppAD $icode Base$$ type is an advanced use of CppAD.
This part of the CppAD API changes with time. The most common change
is adding more requirements.
Search for $code base_require$$ in the
current $cref whats_new$$ section for these changes.
$head Standard Base Types$$
In the case where $icode Base$$ is
$code float$$,
$code double$$,
$code std::complex<float>$$,
$code std::complex<double>$$,
or $codei%AD<%Other%>%$$,
these requirements are provided by including the file
$code cppad/cppad.hpp$$.
$head Include Order$$
If you are linking a non-standard base type to CppAD,
you must first include the file $code cppad/base_require.hpp$$,
then provide the specifications below,
and then include the file $code cppad/cppad.hpp$$.
$head Numeric Type$$
The type $icode Base$$ must support all the operations for a
$cref NumericType$$.
$head Output Operator$$
The type $icode Base$$ must support the syntax
$codei%
%os% << %x%
%$$
where $icode os$$ is an $code std::ostream&$$
and $icode x$$ is a $code const base_alloc&$$.
For example, see
$cref/base_alloc/base_alloc.hpp/Output Operator/$$.
$head Integer$$
The type $icode Base$$ must support the syntax
$codei%
%i% = CppAD::Integer(%x%)
%$$
which converts $icode x$$ to an $code int$$.
The argument $icode x$$ has prototype
$codei%
const %Base%& %x%
%$$
and the return value $icode i$$ has prototype
$codei%
int %i%
%$$
$subhead Suggestion$$
In many cases, the $icode Base$$ version of the $code Integer$$ function
can be defined by
$codei%
namespace CppAD {
inline int Integer(const %Base%& x)
{ return static_cast<int>(x); }
}
%$$
For example, see
$cref/base_float/base_float.hpp/Integer/$$ and
$cref/base_alloc/base_alloc.hpp/Integer/$$.
$head Absolute Zero, azmul$$
The type $icode Base$$ must support the syntax
$codei%
%z% = azmul(%x%, %y%)
%$$
see; $cref azmul$$.
The following preprocessor macro invocation suffices
(for most $icode Base$$ types):
$codei%
namespace CppAD {
CPPAD_AZMUL(%Base%)
}
%$$
where the macro is defined by
$srccode%cpp% */
# define CPPAD_AZMUL(Base) \
inline Base azmul(const Base& x, const Base& y) \
{ Base zero(0.0); \
if( x == zero ) \
return zero; \
return x * y; \
}
/* %$$
$childtable%
omh/base_require/base_member.omh%
cppad/core/base_cond_exp.hpp%
omh/base_require/base_identical.omh%
omh/base_require/base_ordered.omh%
cppad/core/base_std_math.hpp%
cppad/core/base_limits.hpp%
cppad/core/base_to_string.hpp%
cppad/core/base_hash.hpp%
omh/base_require/base_example.omh
%$$
$end
*/
// definitions that must come before base implementations
# include <cppad/utility/error_handler.hpp>
# include <cppad/core/define.hpp>
# include <cppad/core/cppad_assert.hpp>
# include <cppad/local/declare_ad.hpp>
// grouping documentation by feature
# include <cppad/core/base_cond_exp.hpp>
# include <cppad/core/base_std_math.hpp>
# include <cppad/core/base_limits.hpp>
# include <cppad/core/base_to_string.hpp>
# include <cppad/core/base_hash.hpp>
// must define template class numeric_limits before the base cases
# include <cppad/core/numeric_limits.hpp>
# include <cppad/core/epsilon.hpp> // deprecated
// base cases that come with CppAD
# include <cppad/core/base_float.hpp>
# include <cppad/core/base_double.hpp>
# include <cppad/core/base_complex.hpp>
// deprecated base type
# include <cppad/core/zdouble.hpp>
# endif

View File

@ -1,216 +0,0 @@
# ifndef CPPAD_CONFIGURE_HPP
# define CPPAD_CONFIGURE_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.
-------------------------------------------------------------------------- */
/*!
\file configure.hpp
Replacement for config.h so that all preprocessor symbols begin with CPPAD_
*/
/*!
\def CPPAD_COMPILER_IS_GNUCXX
is the compiler a variant of g++
*/
# define CPPAD_COMPILER_IS_GNUCXX 1
/*!
\def CPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS
This macro is only used to document the pragmas that disables the
follow warnings:
\li C4100
unreferenced formal parameter.
\li C4127
conditional expression is constant.
*/
# define CPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS 1
# if _MSC_VER
# pragma warning( disable : 4100 )
# pragma warning( disable : 4127 )
# endif
# undef CPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS
/*!
\def CPPAD_USE_CPLUSPLUS_2011
Should CppAD use C++11 features. This will be true if the current
compiler flags request C++11 features and the install procedure
determined that all the necessary features are avaiable.
*/
# if _MSC_VER
# define CPPAD_USE_CPLUSPLUS_2011 0
# else //
# if __cplusplus >= 201100
# define CPPAD_USE_CPLUSPLUS_2011 0
# else //
# define CPPAD_USE_CPLUSPLUS_2011 0
# endif //
# endif //
/*!
\def CPPAD_PACKAGE_STRING
cppad-yyyymmdd as a C string where yyyy is year, mm is month, and dd is day.
*/
# define CPPAD_PACKAGE_STRING "cppad-20170816"
/*!
def CPPAD_HAS_ADOLC
Was a adolc_prefix specified on the cmake command line.
*/
# define CPPAD_HAS_ADOLC 0
/*!
def CPPAD_HAS_COLPACK
Was a colpack_prefix specified on the cmake command line.
*/
# define CPPAD_HAS_COLPACK 0
/*!
def CPPAD_HAS_EIGEN
Was a eigen_prefix specified on the cmake command line.
*/
# define CPPAD_HAS_EIGEN 0
/*!
def CPPAD_HAS_IPOPT
Was a ipopt_prefix specified on the cmake command line.
*/
# define CPPAD_HAS_IPOPT 0
/*!
\def CPPAD_DEPRECATED
This symbol is not currently being used.
*/
# define CPPAD_DEPRECATED 0
/*!
\def CPPAD_BOOSTVECTOR
If this symbol is one, and _MSC_VER is not defined,
we are using boost vector for CPPAD_TESTVECTOR.
It this symbol is zero,
we are not using boost vector for CPPAD_TESTVECTOR.
*/
# define CPPAD_BOOSTVECTOR 0
/*!
\def CPPAD_CPPADVECTOR
If this symbol is one,
we are using CppAD vector for CPPAD_TESTVECTOR.
It this symbol is zero,
we are not using CppAD vector for CPPAD_TESTVECTOR.
*/
# define CPPAD_CPPADVECTOR 1
/*!
\def CPPAD_STDVECTOR
If this symbol is one,
we are using standard vector for CPPAD_TESTVECTOR.
It this symbol is zero,
we are not using standard vector for CPPAD_TESTVECTOR.
*/
# define CPPAD_STDVECTOR 0
/*!
\def CPPAD_EIGENVECTOR
If this symbol is one,
we are using Eigen vector for CPPAD_TESTVECTOR.
If this symbol is zero,
we are not using Eigen vector for CPPAD_TESTVECTOR.
*/
# define CPPAD_EIGENVECTOR 0
/*!
\def CPPAD_HAS_GETTIMEOFDAY
If this symbol is one, and _MSC_VER is not defined,
this system supports the gettimeofday funcgtion.
Otherwise, this smybol should be zero.
*/
# define CPPAD_HAS_GETTIMEOFDAY 1
/*!
\def CPPAD_SIZE_T_NOT_UNSIGNED_INT
If this symbol is zero, the type size_t is the same as the type unsigned int,
otherwise this symbol is one.
*/
# define CPPAD_SIZE_T_NOT_UNSIGNED_INT 1
/*!
\def CPPAD_TAPE_ADDR_TYPE
Is the type used to store address on the tape. If not size_t, then
<code>sizeof(CPPAD_TAPE_ADDR_TYPE) <= sizeof( size_t )</code>
to conserve memory.
This type must support \c std::numeric_limits,
the \c <= operator,
and conversion to \c size_t.
Make sure that the type chosen returns true for is_pod<CPPAD_TAPE_ADDR_TYPE>
in pod_vector.hpp.
This type is later defined as \c addr_t in the CppAD namespace.
*/
# define CPPAD_TAPE_ADDR_TYPE unsigned int
/*!
\def CPPAD_TAPE_ID_TYPE
Is the type used to store tape identifiers. If not size_t, then
<code>sizeof(CPPAD_TAPE_ID_TYPE) <= sizeof( size_t )</code>
to conserve memory.
This type must support \c std::numeric_limits,
the \c <= operator,
and conversion to \c size_t.
Make sure that the type chosen returns true for is_pod<CPPAD_TAPE_ID_TYPE>
in pod_vector.hpp.
This type is later defined as \c tape_id_t in the CppAD namespace.
*/
# define CPPAD_TAPE_ID_TYPE unsigned int
/*!
\def CPPAD_MAX_NUM_THREADS
Specifies the maximum number of threads that CppAD can support
(must be greater than or equal four).
The user may define CPPAD_MAX_NUM_THREADS before including any of the CppAD
header files. If it is not yet defined,
*/
# ifndef CPPAD_MAX_NUM_THREADS
# define CPPAD_MAX_NUM_THREADS 48
# endif
/*!
\def CPPAD_HAS_MKSTEMP
It true, mkstemp works in C++ on this system.
*/
# define CPPAD_HAS_MKSTEMP 1
/*!
\def CPPAD_HAS_TMPNAM_S
It true, tmpnam_s works in C++ on this system.
*/
# define CPPAD_HAS_TMPNAM_S 0
// ---------------------------------------------------------------------------
// defines that only depend on values above
// ---------------------------------------------------------------------------
/*!
\def CPPAD_NULL
This preprocessor symbol is used for a null pointer.
If it is not yet defined,
it is defined when cppad/core/define.hpp is included.
*/
# ifndef CPPAD_NULL
# if CPPAD_USE_CPLUSPLUS_2011
# define CPPAD_NULL nullptr
# else
# define CPPAD_NULL 0
# endif
# endif
# endif

View File

@ -1,60 +0,0 @@
# ifndef CPPAD_CORE_ABORT_RECORDING_HPP
# define CPPAD_CORE_ABORT_RECORDING_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 abort_recording$$
$spell
$$
$section Abort Recording of an Operation Sequence$$
$mindex tape$$
$head Syntax$$
$codei%AD<%Base%>::abort_recording()%$$
$head Purpose$$
Sometimes it is necessary to abort the recording of an operation sequence
that started with a call of the form
$codei%
Independent(%x%)
%$$
If such a recording is currently in progress,
$code abort_recording$$ will stop the recording and delete the
corresponding information.
Otherwise, $code abort_recording$$ has no effect.
$children%
example/general/abort_recording.cpp
%$$
$head Example$$
The file
$cref abort_recording.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
----------------------------------------------------------------------------
*/
namespace CppAD {
template <typename Base>
void AD<Base>::abort_recording(void)
{ local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape != CPPAD_NULL )
AD<Base>::tape_manage(tape_manage_delete);
}
}
# endif

View File

@ -1,114 +0,0 @@
# ifndef CPPAD_CORE_ABS_HPP
# define CPPAD_CORE_ABS_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 abs$$
$spell
fabs
Vec
std
faq
Taylor
Cpp
namespace
const
abs
$$
$section AD Absolute Value Functions: abs, fabs$$
$head Syntax$$
$icode%y% = abs(%x%)
%$$
$icode%y% = fabs(%x%)%$$
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head Atomic$$
In the case where $icode x$$ is an AD type,
this is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$head Complex Types$$
The functions $code abs$$ and $icode fabs$$
are not defined for the base types
$code std::complex<float>$$ or $code std::complex<double>$$
because the complex $code abs$$ function is not complex differentiable
(see $cref/complex types faq/Faq/Complex Types/$$).
$head Derivative$$
CppAD defines the derivative of the $code abs$$ function is
the $cref sign$$ function; i.e.,
$latex \[
{\rm abs}^{(1)} ( x ) = {\rm sign} (x ) =
\left\{ \begin{array}{rl}
+1 & {\rm if} \; x > 0 \\
0 & {\rm if} \; x = 0 \\
-1 & {\rm if} \; x < 0
\end{array} \right.
\] $$
The result for $icode%x% == 0%$$ used to be a directional derivative.
$head Example$$
$children%
example/general/fabs.cpp
%$$
The file
$cref fabs.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <class Base>
AD<Base> AD<Base>::abs_me (void) const
{
AD<Base> result;
result.value_ = abs(value_);
CPPAD_ASSERT_UNKNOWN( Parameter(result) );
if( Variable(*this) )
{ // add this operation to the tape
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AbsOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AbsOp) == 1 );
local::ADTape<Base> *tape = tape_this();
// corresponding operand address
tape->Rec_.PutArg(taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::AbsOp);
// make result a variable
result.tape_id_ = tape->id_;
}
return result;
}
template <class Base>
inline AD<Base> abs(const AD<Base> &x)
{ return x.abs_me(); }
template <class Base>
inline AD<Base> abs(const VecAD_reference<Base> &x)
{ return x.ADBase().abs_me(); }
} // END CppAD namespace
# endif

View File

@ -1,867 +0,0 @@
# ifndef CPPAD_CORE_ABS_NORMAL_FUN_HPP
# define CPPAD_CORE_ABS_NORMAL_FUN_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 abs_normal_fun$$
$spell
const
$$
$section Create An Abs-normal Representation of a Function$$
$head Syntax$$
$icode%f%.abs_normal_fun(%g%, %a%)%$$
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%>& %f%
%$$
It represents a function $latex f : \B{R}^n \rightarrow \B{R}^m$$.
We assume that the only non-smooth terms in the representation are
absolute value functions and use $latex s \in \B{Z}_+$$
to represent the number of these terms.
It is effectively $code const$$, except that some internal state
that is not relevant to the user; see
$cref/const ADFun/wish_list/const ADFun/$$.
$subhead n$$
We use $icode n$$ to denote the dimension of the domain space for $icode f$$.
$subhead m$$
We use $icode m$$ to denote the dimension of the range space for $icode f$$.
$subhead s$$
We use $icode s$$ to denote the number of absolute value terms in $icode f$$.
$head a$$
The object $icode a$$ has prototype
$codei%
ADFun<%Base%> %a%
%$$
The initial function representation in $icode a$$ is lost.
Upon return it represents the result of the absolute terms
$latex a : \B{R}^n \rightarrow \B{R}^s$$; see $latex a(x)$$ defined below.
Note that $icode a$$ is constructed by copying $icode f$$
and then changing the dependent variables. There may
be many calculations in this representation that are not necessary
and can be removed using
$codei%
%a%.optimize()
%$$
This optimization is not done automatically by $code abs_normal_fun$$
because it may take a significant amount of time.
$subhead zeta$$
Let $latex \zeta_0 ( x )$$
denote the argument for the first absolute value term in $latex f(x)$$,
$latex \zeta_1 ( x , |\zeta_0 (x)| )$$ for the second term, and so on.
$subhead a(x)$$
For $latex i = 0 , \ldots , {s-1}$$ define
$latex \[
a_i (x)
=
| \zeta_i ( x , a_0 (x) , \ldots , a_{i-1} (x ) ) |
\] $$
This defines $latex a : \B{R}^n \rightarrow \B{R}^s$$.
$head g$$
The object $icode g$$ has prototype
$codei%
ADFun<%Base%> %g%
%$$
The initial function representation in $icode g$$ is lost.
Upon return it represents the smooth function
$latex g : \B{R}^{n + s} \rightarrow \B{R}^{m + s}$$ is defined by
$latex \[
g( x , u )
=
\left[ \begin{array}{c} y(x, u) \\ z(x, u) \end{array} \right]
\] $$
were $latex y(x, u)$$ and $latex z(x, u)$$ are defined below.
$subhead z(x, u)$$
Define the smooth function
$latex z : \B{R}^{n + s} \rightarrow \B{R}^s$$ by
$latex \[
z_i ( x , u ) = \zeta_i ( x , u_0 , \ldots , u_{i-1} )
\] $$
Note that the partial of $latex z_i$$ with respect to $latex u_j$$ is zero
for $latex j \geq i$$.
$subhead y(x, u)$$
There is a smooth function
$latex y : \B{R}^{n + s} \rightarrow \B{R}^m$$
such that $latex y( x , u ) = f(x)$$ whenever $latex u = a(x)$$.
$head Affine Approximation$$
We define the affine approximations
$latex \[
\begin{array}{rcl}
y[ \hat{x} ]( x , u )
& = &
y ( \hat{x}, a( \hat{x} ) )
+ \partial_x y ( \hat{x}, a( \hat{x} ) ) ( x - \hat{x} )
+ \partial_u y ( \hat{x}, a( \hat{x} ) ) ( u - a( \hat{x} ) )
\\
z[ \hat{x} ]( x , u )
& = &
z ( \hat{x}, a( \hat{x} ) )
+ \partial_x z ( \hat{x}, a( \hat{x} ) ) ( x - \hat{x} )
+ \partial_u z ( \hat{x}, a( \hat{x} ) ) ( u - a( \hat{x} ) )
\end{array}
\] $$
It follows that
$latex \[
\begin{array}{rcl}
y( x , u )
& = &
y[ \hat{x} ]( x , u ) + o ( x - \hat{x}, u - a( \hat{x} ) )
\\
z( x , u )
& = &
z[ \hat{x} ]( x , u ) + o ( x - \hat{x}, u - a( \hat{x} ) )
\end{array}
\] $$
$head Abs-normal Approximation$$
$subhead Approximating a(x)$$
The function $latex a(x)$$ is not smooth, but it is equal to
$latex | z(x, u) |$$ when $latex u = a(x)$$.
Furthermore
$latex \[
z[ \hat{x} ]( x , u )
=
z ( \hat{x}, a( \hat{x} ) )
+ \partial_x z ( \hat{x}, a( \hat{x} ) ) ( x - \hat{x} )
+ \partial_u z ( \hat{x}, a( \hat{x} ) ) ( u - a( \hat{x} ) )
\] $$
The partial of $latex z_i$$ with respect to $latex u_j$$ is zero
for $latex j \geq i$$. It follows that
$latex \[
z_i [ \hat{x} ]( x , u )
=
z_i ( \hat{x}, a( \hat{x} ) )
+ \partial_x z_i ( \hat{x}, a( \hat{x} ) ) ( x - \hat{x} )
+ \sum_{j < i} \partial_{u(j)}
z_i ( \hat{x}, a( \hat{x} ) ) ( u_j - a_j ( \hat{x} ) )
\] $$
Considering the case $latex i = 0$$ we define
$latex \[
a_0 [ \hat{x} ]( x )
=
| z_0 [ \hat{x} ]( x , u ) |
=
\left|
z_0 ( \hat{x}, a( \hat{x} ) )
+ \partial_x z_0 ( \hat{x}, a( \hat{x} ) ) ( x - \hat{x} )
\right|
\] $$
It follows that
$latex \[
a_0 (x) = a_0 [ \hat{x} ]( x ) + o ( x - \hat{x} )
\] $$
In general, we define $latex a_i [ \hat{x} ]$$ using
$latex a_j [ \hat{x} ]$$ for $latex j < i$$ as follows:
$latex \[
a_i [ \hat{x} ]( x )
=
\left |
z_i ( \hat{x}, a( \hat{x} ) )
+ \partial_x z_i ( \hat{x}, a( \hat{x} ) ) ( x - \hat{x} )
+ \sum_{j < i} \partial_{u(j)}
z_i ( \hat{x}, a( \hat{x} ) )
( a_j [ \hat{x} ] ( x ) - a_j ( \hat{x} ) )
\right|
\] $$
It follows that
$latex \[
a (x) = a[ \hat{x} ]( x ) + o ( x - \hat{x} )
\] $$
Note that in the case where $latex z(x, u)$$ and $latex y(x, u)$$ are
affine,
$latex \[
a[ \hat{x} ]( x ) = a( x )
\] $$
$subhead Approximating f(x)$$
$latex \[
f(x)
=
y ( x , a(x ) )
=
y [ \hat{x} ] ( x , a[ \hat{x} ] ( x ) )
+ o( \Delta x )
\] $$
$head Correspondence to Literature$$
Using the notation
$latex Z = \partial_x z(\hat{x}, \hat{u})$$,
$latex L = \partial_u z(\hat{x}, \hat{u})$$,
$latex J = \partial_x y(\hat{x}, \hat{u})$$,
$latex Y = \partial_u y(\hat{x}, \hat{u})$$,
the approximation for $latex z$$ and $latex y$$ are
$latex \[
\begin{array}{rcl}
z[ \hat{x} ]( x , u )
& = &
z ( \hat{x}, a( \hat{x} ) ) + Z ( x - \hat{x} ) + L ( u - a( \hat{x} ) )
\\
y[ \hat{x} ]( x , u )
& = &
y ( \hat{x}, a( \hat{x} ) ) + J ( x - \hat{x} ) + Y ( u - a( \hat{x} ) )
\end{array}
\] $$
Moving the terms with $latex \hat{x}$$ together, we have
$latex \[
\begin{array}{rcl}
z[ \hat{x} ]( x , u )
& = &
z ( \hat{x}, a( \hat{x} ) ) - Z \hat{x} - L a( \hat{x} ) + Z x + L u
\\
y[ \hat{x} ]( x , u )
& = &
y ( \hat{x}, a( \hat{x} ) ) - J \hat{x} - Y a( \hat{x} ) + J x + Y u
\end{array}
\] $$
Using the notation
$latex c = z ( \hat{x}, \hat{u} ) - Z \hat{x} - L \hat{u}$$,
$latex b = y ( \hat{x}, \hat{u} ) - J \hat{x} - Y \hat{u}$$,
we have
$latex \[
\begin{array}{rcl}
z[ \hat{x} ]( x , u ) & = & c + Z x + L u
\\
y[ \hat{x} ]( x , u ) & = & b + J x + Y u
\end{array}
\] $$
Considering the affine case, where the approximations are exact,
and choosing $latex u = a(x) = |z(x, u)|$$, we obtain
$latex \[
\begin{array}{rcl}
z( x , a(x ) ) & = & c + Z x + L |z( x , a(x ) )|
\\
y( x , a(x ) ) & = & b + J x + Y |z( x , a(x ) )|
\end{array}
\] $$
This is Equation (2) of the
$cref/reference/abs_normal/Reference/$$.
$children%example/abs_normal/get_started.cpp
%$$
$head Example$$
The file $cref abs_get_started.cpp$$ contains
an example and test using this operation.
$end
-------------------------------------------------------------------------------
*/
/*!
file abs_normal_fun.hpp
Create an abs-normal representation of a function
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Create an abs-normal representation of an ADFun object.
\tparam Base
base type for this abs-normal form and for the function beging represented;
i.e., f.
\param f
is the function that this object will represent in abs-normal form.
This is effectively const except that the play back state play_
is used.
*/
# define NOT_YET_COMPILING 0
template <class Base>
void ADFun<Base>::abs_normal_fun(ADFun<Base>& g, ADFun<Base>& a)
{ using namespace local;
// -----------------------------------------------------------------------
// Forward sweep to determine number of absolute value operations in f
// -----------------------------------------------------------------------
// The argument and result index in f for each absolute value operator
CppAD::vector<addr_t> f_abs_arg;
CppAD::vector<size_t> f_abs_res;
//
OpCode op; // this operator
const addr_t* arg = CPPAD_NULL; // arguments for this operator
size_t i_op; // index of this operator
size_t i_var; // variable index for this operator
play_.forward_start(op, arg, i_op, i_var);
CPPAD_ASSERT_UNKNOWN( op == BeginOp );
//
bool more_operators = true;
while( more_operators )
{
// next op
play_.forward_next(op, arg, i_op, i_var);
switch( op )
{ // absolute value operator
case AbsOp:
CPPAD_ASSERT_NARG_NRES(op, 1, 1);
f_abs_arg.push_back( arg[0] );
f_abs_res.push_back( i_var );
break;
case CSumOp:
// CSumOp has a variable number of arguments
play_.forward_csum(op, arg, i_op, i_var);
break;
case CSkipOp:
// CSkip has a variable number of arguments
play_.forward_cskip(op, arg, i_op, i_var);
break;
case EndOp:
more_operators = false;
break;
default:
break;
}
}
// ------------------------------------------------------------------------
// Forward sweep to create new recording
// ------------------------------------------------------------------------
// recorder for new operation sequence
recorder<Base> rec;
//
// number of variables in both operation sequences
// (the AbsOp operators are replace by InvOp operators)
const size_t num_var = play_.num_var_rec();
//
// mapping from old variable index to new variable index
CPPAD_ASSERT_UNKNOWN(
std::numeric_limits<addr_t>::max() >= num_var
);
CppAD::vector<addr_t> f2g_var(num_var);
for(i_var = 0; i_var < num_var; i_var++)
f2g_var[i_var] = addr_t( num_var ); // invalid (should not be used)
//
// record the independent variables in f
play_.forward_start(op, arg, i_op, i_var);
CPPAD_ASSERT_UNKNOWN( op == BeginOp );
more_operators = true;
while( more_operators )
{ switch( op )
{
// phantom variable
case BeginOp:
CPPAD_ASSERT_NARG_NRES(op, 1, 1);
CPPAD_ASSERT_UNKNOWN( arg[0] == 0 );
rec.PutArg(0);
f2g_var[i_var] = rec.PutOp(op);
break;
// independent variables
case InvOp:
CPPAD_ASSERT_NARG_NRES(op, 0, 1);
f2g_var[i_var] = rec.PutOp(op);
break;
// end of independent variables
default:
more_operators = false;
break;
}
if( more_operators )
play_.forward_next(op, arg, i_op, i_var);
}
// add one for the phantom variable
CPPAD_ASSERT_UNKNOWN( 1 + Domain() == i_var );
//
// record the independent variables corresponding AbsOp results
size_t index_abs;
for(index_abs = 0; index_abs < f_abs_res.size(); index_abs++)
f2g_var[ f_abs_res[index_abs] ] = rec.PutOp(InvOp);
//
// used to hold new argument vector
addr_t new_arg[6];
//
// Parameters in recording of f
const Base* f_parameter = play_.GetPar();
//
// now loop through the rest of the
more_operators = true;
index_abs = 0;
while( more_operators )
{ addr_t mask; // temporary used in some switch cases
switch( op )
{
// check setting of f_abs_arg and f_abs_res;
case AbsOp:
CPPAD_ASSERT_NARG_NRES(op, 1, 1);
CPPAD_ASSERT_UNKNOWN( f_abs_arg[index_abs] == arg[0] );
CPPAD_ASSERT_UNKNOWN( f_abs_res[index_abs] == i_var );
CPPAD_ASSERT_UNKNOWN( f2g_var[i_var] > 0 );
++index_abs;
break;
// These operators come at beginning of take and are handled above
case InvOp:
CPPAD_ASSERT_UNKNOWN(false);
break;
// ---------------------------------------------------------------
// Unary operators, argument a parameter, one result
case ParOp:
CPPAD_ASSERT_NARG_NRES(op, 1, 1);
new_arg[0] = rec.PutPar( f_parameter[ arg[0] ] );
rec.PutArg( new_arg[0] );
f2g_var[i_var] = rec.PutOp(op);
break;
// --------------------------------------------------------------
// Unary operators, argument a variable, one result
// (excluding the absolute value operator AbsOp)
case AcosOp:
case AcoshOp:
case AsinOp:
case AsinhOp:
case AtanOp:
case AtanhOp:
case CosOp:
case CoshOp:
case ExpOp:
case Expm1Op:
case LogOp:
case Log1pOp:
case SignOp:
case SinOp:
case SinhOp:
case SqrtOp:
case TanOp:
case TanhOp:
// some of these operators have an auxillary result; e.g.,
// sine and cosine are computed togeather.
CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 || NumRes(op) == 2 );
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );
new_arg[0] = f2g_var[ arg[0] ];
rec.PutArg( new_arg[0] );
f2g_var[i_var] = rec.PutOp( op );
break;
case ErfOp:
CPPAD_ASSERT_NARG_NRES(op, 3, 5);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );
// Error function is a special case
// second argument is always the parameter 0
// third argument is always the parameter 2 / sqrt(pi)
rec.PutArg( rec.PutPar( Base(0.0) ) );
rec.PutArg( rec.PutPar(
Base( 1.0 / std::sqrt( std::atan(1.0) ) )
) );
f2g_var[i_var] = rec.PutOp(op);
break;
// --------------------------------------------------------------
// Binary operators, left variable, right parameter, one result
case SubvpOp:
case DivvpOp:
case PowvpOp:
case ZmulvpOp:
CPPAD_ASSERT_NARG_NRES(op, 2, 1);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );
new_arg[0] = f2g_var[ arg[0] ];
new_arg[1] = rec.PutPar( f_parameter[ arg[1] ] );
rec.PutArg( new_arg[0], new_arg[1] );
f2g_var[i_var] = rec.PutOp(op);
break;
// ---------------------------------------------------
// Binary operators, left index, right variable, one result
case DisOp:
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );
new_arg[0] = arg[0];
new_arg[1] = f2g_var[ arg[1] ];
rec.PutArg( new_arg[0], new_arg[1] );
f2g_var[i_var] = rec.PutOp(op);
break;
// --------------------------------------------------------------
// Binary operators, left parameter, right variable, one result
case AddpvOp:
case SubpvOp:
case MulpvOp:
case DivpvOp:
case PowpvOp:
case ZmulpvOp:
CPPAD_ASSERT_NARG_NRES(op, 2, 1);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );
new_arg[0] = rec.PutPar( f_parameter[ arg[0] ] );
new_arg[1] = f2g_var[ arg[1] ];
rec.PutArg( new_arg[0], new_arg[1] );
f2g_var[i_var] = rec.PutOp(op);
break;
// --------------------------------------------------------------
// Binary operators, left and right variables, one result
case AddvvOp:
case SubvvOp:
case MulvvOp:
case DivvvOp:
case ZmulvvOp:
CPPAD_ASSERT_NARG_NRES(op, 2, 1);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );
new_arg[0] = f2g_var[ arg[0] ];
new_arg[1] = f2g_var[ arg[1] ];
rec.PutArg( new_arg[0], new_arg[1] );
f2g_var[i_var] = rec.PutOp(op);
break;
// ---------------------------------------------------
// Conditional expression operators
case CExpOp:
CPPAD_ASSERT_NARG_NRES(op, 6, 1);
new_arg[0] = arg[0];
new_arg[1] = arg[1];
mask = 1;
for(size_t i = 2; i < 6; i++)
{ if( arg[1] & mask )
{ CPPAD_ASSERT_UNKNOWN( size_t(f2g_var[arg[i]]) < num_var );
new_arg[i] = f2g_var[ arg[i] ];
}
else
new_arg[i] = rec.PutPar( f_parameter[ arg[i] ] );
mask = mask << 1;
}
rec.PutArg(
new_arg[0] ,
new_arg[1] ,
new_arg[2] ,
new_arg[3] ,
new_arg[4] ,
new_arg[5]
);
f2g_var[i_var] = rec.PutOp(op);
break;
// --------------------------------------------------
// Operators with no arguments and no results
case EndOp:
CPPAD_ASSERT_NARG_NRES(op, 0, 0);
rec.PutOp(op);
more_operators = false;
break;
// ---------------------------------------------------
// Operations with two arguments and no results
case LepvOp:
case LtpvOp:
case EqpvOp:
case NepvOp:
CPPAD_ASSERT_NARG_NRES(op, 2, 0);
new_arg[0] = rec.PutPar( f_parameter[ arg[0] ] );
new_arg[1] = f2g_var[ arg[1] ];
rec.PutArg(new_arg[0], new_arg[1]);
rec.PutOp(op);
break;
//
case LevpOp:
case LtvpOp:
CPPAD_ASSERT_NARG_NRES(op, 2, 0);
new_arg[0] = f2g_var[ arg[0] ];
new_arg[1] = rec.PutPar( f_parameter[ arg[1] ] );
rec.PutArg(new_arg[0], new_arg[1]);
rec.PutOp(op);
break;
//
case LevvOp:
case LtvvOp:
case EqvvOp:
case NevvOp:
CPPAD_ASSERT_NARG_NRES(op, 2, 0);
new_arg[0] = f2g_var[ arg[0] ];
new_arg[1] = f2g_var[ arg[1] ];
rec.PutArg(new_arg[0], new_arg[1]);
rec.PutOp(op);
break;
// ---------------------------------------------------
// print forward operator
case PriOp:
CPPAD_ASSERT_NARG_NRES(op, 5, 0);
//
// arg[0]
new_arg[0] = arg[0];
//
// arg[1]
if( arg[0] & 1 )
{
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );
new_arg[1] = f2g_var[ arg[1] ];
}
else
{ new_arg[1] = rec.PutPar( f_parameter[ arg[1] ] );
}
//
// arg[3]
if( arg[0] & 2 )
{
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[3] ] ) < num_var );
new_arg[3] = f2g_var[ arg[3] ];
}
else
{ new_arg[3] = rec.PutPar( f_parameter[ arg[3] ] );
}
new_arg[2] = rec.PutTxt( play_.GetTxt( arg[2] ) );
new_arg[4] = rec.PutTxt( play_.GetTxt( arg[4] ) );
//
rec.PutArg(
new_arg[0] ,
new_arg[1] ,
new_arg[2] ,
new_arg[3] ,
new_arg[4]
);
// no result
rec.PutOp(op);
break;
// ---------------------------------------------------
// VecAD operators
// Load using a parameter index
case LdpOp:
CPPAD_ASSERT_NARG_NRES(op, 3, 1);
new_arg[0] = arg[0];
new_arg[1] = arg[1];
new_arg[2] = arg[2];
rec.PutArg(
new_arg[0],
new_arg[1],
new_arg[2]
);
f2g_var[i_var] = rec.PutLoadOp(op);
break;
// Load using a variable index
case LdvOp:
CPPAD_ASSERT_NARG_NRES(op, 3, 1);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );
new_arg[0] = arg[0];
new_arg[1] = f2g_var[ arg[1] ];
new_arg[2] = arg[2];
rec.PutArg(
new_arg[0],
new_arg[1],
new_arg[2]
);
f2g_var[i_var] = rec.PutLoadOp(op);
break;
// Store a parameter using a parameter index
case StppOp:
CPPAD_ASSERT_NARG_NRES(op, 3, 0);
new_arg[0] = arg[0];
new_arg[1] = rec.PutPar( f_parameter[ arg[1] ] );
new_arg[2] = rec.PutPar( f_parameter[ arg[2] ] );
rec.PutArg(
new_arg[0],
new_arg[1],
new_arg[2]
);
rec.PutOp(op);
break;
// Store a parameter using a variable index
case StvpOp:
CPPAD_ASSERT_NARG_NRES(op, 3, 0);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );
new_arg[0] = arg[0];
new_arg[1] = f2g_var[ arg[1] ];
new_arg[2] = rec.PutPar( f_parameter[ arg[2] ] );
rec.PutArg(
new_arg[0],
new_arg[1],
new_arg[2]
);
rec.PutOp(op);
break;
// Store a variable using a parameter index
case StpvOp:
CPPAD_ASSERT_NARG_NRES(op, 3, 0);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[2] ] ) < num_var );
new_arg[0] = arg[0];
new_arg[1] = rec.PutPar( f_parameter[ arg[1] ] );
new_arg[2] = f2g_var[ arg[2] ];
rec.PutArg(
new_arg[0],
new_arg[1],
new_arg[2]
);
rec.PutOp(op);
break;
// Store a variable using a variable index
case StvvOp:
CPPAD_ASSERT_NARG_NRES(op, 3, 0);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[2] ] ) < num_var );
new_arg[0] = arg[0];
new_arg[1] = f2g_var[ arg[1] ];
new_arg[2] = f2g_var[ arg[2] ];
rec.PutArg(
new_arg[0],
new_arg[1],
new_arg[2]
);
break;
// -----------------------------------------------------------
// user atomic function call operators
case UserOp:
CPPAD_ASSERT_NARG_NRES(op, 4, 0);
// atomic_index, user_old, user_n, user_m
rec.PutArg(arg[0], arg[1], arg[2], arg[3]);
rec.PutOp(UserOp);
break;
case UsrapOp:
CPPAD_ASSERT_NARG_NRES(op, 1, 0);
new_arg[0] = rec.PutPar( f_parameter[ arg[0] ] );
rec.PutArg(new_arg[0]);
rec.PutOp(UsrapOp);
break;
case UsravOp:
CPPAD_ASSERT_NARG_NRES(op, 1, 0);
CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[arg[0]] ) < num_var );
new_arg[0] = f2g_var[ arg[0] ];
rec.PutArg(new_arg[0]);
rec.PutOp(UsravOp);
break;
case UsrrpOp:
CPPAD_ASSERT_NARG_NRES(op, 1, 0);
new_arg[0] = rec.PutPar( f_parameter[ arg[0] ] );
rec.PutArg(new_arg[0]);
rec.PutOp(UsrrpOp);
break;
case UsrrvOp:
CPPAD_ASSERT_NARG_NRES(op, 0, 1);
f2g_var[i_var] = rec.PutOp(UsrrvOp);
break;
// ---------------------------------------------------
// all cases should be handled above
default:
CPPAD_ASSERT_UNKNOWN(false);
}
if( more_operators )
play_.forward_next(op, arg, i_op, i_var);
}
// Check a few expected results
CPPAD_ASSERT_UNKNOWN( rec.num_op_rec() == play_.num_op_rec() );
CPPAD_ASSERT_UNKNOWN( rec.num_var_rec() == play_.num_var_rec() );
CPPAD_ASSERT_UNKNOWN( rec.num_load_op_rec() == play_.num_load_op_rec() );
// -----------------------------------------------------------------------
// Use rec to create the function g
// -----------------------------------------------------------------------
// number of variables in the recording
g.num_var_tape_ = rec.num_var_rec();
// dimension cskip_op vector to number of operators
g.cskip_op_.erase();
g.cskip_op_.extend( rec.num_op_rec() );
// independent variables in g: (x, u)
size_t s = f_abs_res.size();
size_t n = Domain();
g.ind_taddr_.resize(n + s);
// (x, u)
for(size_t j = 0; j < n; j++)
{ g.ind_taddr_[j] = f2g_var[ ind_taddr_[j] ];
CPPAD_ASSERT_UNKNOWN( g.ind_taddr_[j] == j + 1 );
}
for(size_t j = 0; j < s; j++)
{ g.ind_taddr_[n + j] = f2g_var[ f_abs_res[j] ];
CPPAD_ASSERT_UNKNOWN( g.ind_taddr_[n + j] == n + j + 1 );
}
// dependent variable in g: (y, z)
CPPAD_ASSERT_UNKNOWN( s == f_abs_arg.size() );
size_t m = Range();
g.dep_taddr_.resize(m + s);
for(size_t i = 0; i < m; i++)
{ g.dep_taddr_[i] = f2g_var[ dep_taddr_[i] ];
CPPAD_ASSERT_UNKNOWN( g.dep_taddr_[i] < num_var );
}
for(size_t i = 0; i < s; i++)
{ g.dep_taddr_[m + i] = f2g_var[ f_abs_arg[i] ];
CPPAD_ASSERT_UNKNOWN( g.dep_taddr_[m + i] < num_var );
}
// which dependent variables are parameters
g.dep_parameter_.resize(m + s);
for(size_t i = 0; i < m; i++)
g.dep_parameter_[i] = dep_parameter_[i];
for(size_t i = 0; i < s; i++)
g.dep_parameter_[m + i] = false;
// free memory allocated for sparse Jacobian calculation
// (the resutls are no longer valid)
g.for_jac_sparse_pack_.resize(0, 0);
g.for_jac_sparse_set_.resize(0, 0);
// free taylor coefficient memory
g.taylor_.free();
g.num_order_taylor_ = 0;
g.cap_order_taylor_ = 0;
// Transferring the recording swaps its vectors so do this last
// replace the recording in g (this ADFun object)
g.play_.get(rec);
// ------------------------------------------------------------------------
// Create the function a
// ------------------------------------------------------------------------
// start with a copy of f
a = *this;
// dependent variables in a(x)
CPPAD_ASSERT_UNKNOWN( s == f_abs_arg.size() );
a.dep_taddr_.resize(s);
for(size_t i = 0; i < s; i++)
{ a.dep_taddr_[i] = f_abs_res[i];
CPPAD_ASSERT_UNKNOWN( a.dep_taddr_[i] < num_var );
}
// free memory allocated for sparse Jacobian calculation
// (the resutls are no longer valid)
a.for_jac_sparse_pack_.resize(0, 0);
a.for_jac_sparse_set_.resize(0, 0);
// free taylor coefficient memory
a.taylor_.free();
a.num_order_taylor_ = 0;
a.cap_order_taylor_ = 0;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,95 +0,0 @@
# ifndef CPPAD_CORE_ACOSH_HPP
# define CPPAD_CORE_ACOSH_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 acosh$$
$spell
acosh
const
Vec
std
cmath
CppAD
$$
$section The Inverse Hyperbolic Cosine Function: acosh$$
$head Syntax$$
$icode%y% = acosh(%x%)%$$
$head Description$$
The inverse hyperbolic cosine function is defined by
$icode%x% == cosh(%y%)%$$.
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head CPPAD_USE_CPLUSPLUS_2011$$
$subhead true$$
If this preprocessor symbol is true ($code 1$$),
and $icode x$$ is an AD type,
this is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$subhead false$$
If this preprocessor symbol is false ($code 0$$),
CppAD uses the representation
$latex \[
\R{acosh} (x) = \log \left( x + \sqrt{ x^2 - 1 } \right)
\] $$
to compute this function.
$head Example$$
$children%
example/general/acosh.cpp
%$$
The file
$cref acosh.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
# include <cppad/configure.hpp>
# if ! CPPAD_USE_CPLUSPLUS_2011
// BEGIN CppAD namespace
namespace CppAD {
template <class Type>
Type acosh_template(const Type &x)
{ return CppAD::log( x + CppAD::sqrt( x * x - Type(1) ) );
}
inline float acosh(const float &x)
{ return acosh_template(x); }
inline double acosh(const double &x)
{ return acosh_template(x); }
template <class Base>
inline AD<Base> acosh(const AD<Base> &x)
{ return acosh_template(x); }
template <class Base>
inline AD<Base> acosh(const VecAD_reference<Base> &x)
{ return acosh_template( x.ADBase() ); }
} // END CppAD namespace
# endif // CPPAD_USE_CPLUSPLUS_2011
# endif // CPPAD_ACOSH_INCLUDED

View File

@ -1,291 +0,0 @@
# ifndef CPPAD_CORE_AD_HPP
# define CPPAD_CORE_AD_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.
-------------------------------------------------------------------------- */
// simple AD operations that must be defined for AD as well as base class
# include <cppad/core/ordered.hpp>
# include <cppad/core/identical.hpp>
// define the template classes that are used by the AD template class
# include <cppad/local/op_code.hpp>
# include <cppad/local/recorder.hpp>
# include <cppad/local/player.hpp>
# include <cppad/local/ad_tape.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
typedef enum {
tape_manage_new,
tape_manage_delete,
tape_manage_clear
} tape_manage_job;
template <class Base>
class AD {
private :
// -----------------------------------------------------------------------
// value_ corresponding to this object
Base value_;
// Tape identifier corresponding to taddr
tape_id_t tape_id_;
// taddr_ in tape for this variable
addr_t taddr_;
// -----------------------------------------------------------------------
// enable use of AD<Base> in parallel mode
template <class Type>
friend void parallel_ad(void);
// template friend functions where template parameter is not bound
template <class VectorAD>
friend void Independent(VectorAD &x, size_t abort_op_index);
// one argument functions
friend bool Parameter <Base>
(const AD<Base> &u);
friend bool Parameter <Base>
(const VecAD<Base> &u);
friend bool Variable <Base>
(const AD<Base> &u);
friend bool Variable <Base>
(const VecAD<Base> &u);
friend int Integer <Base>
(const AD<Base> &u);
friend AD Var2Par <Base>
(const AD<Base> &u);
// power function
friend AD pow <Base>
(const AD<Base> &x, const AD<Base> &y);
// azmul function
friend AD azmul <Base>
(const AD<Base> &x, const AD<Base> &y);
// order determining functions, see ordered.hpp
friend bool GreaterThanZero <Base> (const AD<Base> &x);
friend bool GreaterThanOrZero <Base> (const AD<Base> &x);
friend bool LessThanZero <Base> (const AD<Base> &x);
friend bool LessThanOrZero <Base> (const AD<Base> &x);
friend bool abs_geq <Base>
(const AD<Base>& x, const AD<Base>& y);
// The identical property functions, see identical.hpp
friend bool IdenticalPar <Base> (const AD<Base> &x);
friend bool IdenticalZero <Base> (const AD<Base> &x);
friend bool IdenticalOne <Base> (const AD<Base> &x);
friend bool IdenticalEqualPar <Base>
(const AD<Base> &x, const AD<Base> &y);
// EqualOpSeq function
friend bool EqualOpSeq <Base>
(const AD<Base> &u, const AD<Base> &v);
// NearEqual function
friend bool NearEqual <Base> (
const AD<Base> &x, const AD<Base> &y, const Base &r, const Base &a);
friend bool NearEqual <Base> (
const Base &x, const AD<Base> &y, const Base &r, const Base &a);
friend bool NearEqual <Base> (
const AD<Base> &x, const Base &y, const Base &r, const Base &a);
// CondExp function
friend AD<Base> CondExpOp <Base> (
enum CompareOp cop ,
const AD<Base> &left ,
const AD<Base> &right ,
const AD<Base> &trueCase ,
const AD<Base> &falseCase
);
// classes
friend class local::ADTape<Base>;
friend class ADFun<Base>;
friend class atomic_base<Base>;
friend class discrete<Base>;
friend class VecAD<Base>;
friend class VecAD_reference<Base>;
// arithematic binary operators
friend AD<Base> operator + <Base>
(const AD<Base> &left, const AD<Base> &right);
friend AD<Base> operator - <Base>
(const AD<Base> &left, const AD<Base> &right);
friend AD<Base> operator * <Base>
(const AD<Base> &left, const AD<Base> &right);
friend AD<Base> operator / <Base>
(const AD<Base> &left, const AD<Base> &right);
// comparison operators
friend bool operator < <Base>
(const AD<Base> &left, const AD<Base> &right);
friend bool operator <= <Base>
(const AD<Base> &left, const AD<Base> &right);
friend bool operator > <Base>
(const AD<Base> &left, const AD<Base> &right);
friend bool operator >= <Base>
(const AD<Base> &left, const AD<Base> &right);
friend bool operator == <Base>
(const AD<Base> &left, const AD<Base> &right);
friend bool operator != <Base>
(const AD<Base> &left, const AD<Base> &right);
// input operator
friend std::istream& operator >> <Base>
(std::istream &is, AD<Base> &x);
// output operations
friend std::ostream& operator << <Base>
(std::ostream &os, const AD<Base> &x);
friend void PrintFor <Base> (
const AD<Base>& flag ,
const char* before ,
const AD<Base>& var ,
const char* after
);
public:
// type of value
typedef Base value_type;
// implicit default constructor
inline AD(void);
// use default implicit copy constructor and assignment operator
// inline AD(const AD &x);
// inline AD& operator=(const AD &x);
// implicit construction and assingment from base type
inline AD(const Base &b);
inline AD& operator=(const Base &b);
// implicit contructor and assignment from VecAD<Base>::reference
inline AD(const VecAD_reference<Base> &x);
inline AD& operator=(const VecAD_reference<Base> &x);
// explicit construction from some other type (depricated)
template <class T> inline explicit AD(const T &t);
// assignment from some other type
template <class T> inline AD& operator=(const T &right);
// base type corresponding to an AD object
friend Base Value <Base> (const AD<Base> &x);
// compound assignment operators
inline AD& operator += (const AD &right);
inline AD& operator -= (const AD &right);
inline AD& operator *= (const AD &right);
inline AD& operator /= (const AD &right);
// unary operators
inline AD operator +(void) const;
inline AD operator -(void) const;
// destructor
~AD(void)
{ }
// interface so these functions need not be friends
inline AD abs_me(void) const;
inline AD acos_me(void) const;
inline AD asin_me(void) const;
inline AD atan_me(void) const;
inline AD cos_me(void) const;
inline AD cosh_me(void) const;
inline AD exp_me(void) const;
inline AD fabs_me(void) const;
inline AD log_me(void) const;
inline AD sin_me(void) const;
inline AD sign_me(void) const;
inline AD sinh_me(void) const;
inline AD sqrt_me(void) const;
inline AD tan_me(void) const;
inline AD tanh_me(void) const;
# if CPPAD_USE_CPLUSPLUS_2011
inline AD erf_me(void) const;
inline AD asinh_me(void) const;
inline AD acosh_me(void) const;
inline AD atanh_me(void) const;
inline AD expm1_me(void) const;
inline AD log1p_me(void) const;
# endif
// ----------------------------------------------------------
// static public member functions
// abort current AD<Base> recording
static void abort_recording(void);
// set the maximum number of OpenMP threads (deprecated)
static void omp_max_thread(size_t number);
// These functions declared public so can be accessed by user through
// a macro interface and are not intended for direct use.
// The macro interface is documented in bool_fun.hpp.
// Developer documentation for these fucntions is in bool_fun.hpp
static inline bool UnaryBool(
bool FunName(const Base &x),
const AD<Base> &x
);
static inline bool BinaryBool(
bool FunName(const Base &x, const Base &y),
const AD<Base> &x , const AD<Base> &y
);
private:
//
// Make this variable a parameter
//
void make_parameter(void)
{ CPPAD_ASSERT_UNKNOWN( Variable(*this) ); // currently a var
tape_id_ = 0;
}
//
// Make this parameter a new variable
//
void make_variable(tape_id_t id, addr_t taddr)
{ CPPAD_ASSERT_UNKNOWN( Parameter(*this) ); // currently a par
CPPAD_ASSERT_UNKNOWN( taddr > 0 ); // sure valid taddr
taddr_ = taddr;
tape_id_ = id;
}
// ---------------------------------------------------------------
// tape linking functions
//
// not static
inline local::ADTape<Base>* tape_this(void) const;
//
// static
inline static tape_id_t** tape_id_handle(size_t thread);
inline static tape_id_t* tape_id_ptr(size_t thread);
inline static local::ADTape<Base>** tape_handle(size_t thread);
static local::ADTape<Base>* tape_manage(tape_manage_job job);
inline static local::ADTape<Base>* tape_ptr(void);
inline static local::ADTape<Base>* tape_ptr(tape_id_t tape_id);
};
// ---------------------------------------------------------------------------
} // END_CPPAD_NAMESPACE
// tape linking private functions
# include <cppad/core/tape_link.hpp>
// operations that expect the AD template class to be defined
# endif

View File

@ -1,140 +0,0 @@
# ifndef CPPAD_CORE_AD_ASSIGN_HPP
# define CPPAD_CORE_AD_ASSIGN_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 ad_assign$$
$spell
Vec
const
$$
$section AD Assignment Operator$$
$mindex assign Base VecAD$$
$head Syntax$$
$icode%y% = %x%$$
$head Purpose$$
Assigns the value in $icode x$$ to the object $icode y$$.
In either case,
$head x$$
The argument $icode x$$ has prototype
$codei%
const %Type% &%x%
%$$
where $icode Type$$ is
$codei%VecAD<%Base%>::reference%$$,
$codei%AD<%Base%>%$$,
$icode Base$$,
or any type that has an implicit constructor of the form
$icode%Base%(%x%)%$$.
$head y$$
The target $icode y$$ has prototype
$codei%
AD<%Base%> %y%
%$$
$head Example$$
$children%
example/general/ad_assign.cpp
%$$
The file $cref ad_assign.cpp$$ contain examples and tests of these operations.
It test returns true if it succeeds and false otherwise.
$end
------------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file ad_assign.hpp
AD<Base> constructors and and copy operations.
*/
/*!
\page AD_default_assign
Use default assignment operator
because they may be optimized better than the code below:
\code
template <class Base>
inline AD<Base>& AD<Base>::operator=(const AD<Base> &right)
{ value_ = right.value_;
tape_id_ = right.tape_id_;
taddr_ = right.taddr_;
return *this;
}
\endcode
*/
/*!
Assignment to Base type value.
\tparam Base
Base type for this AD object.
\param b
is the Base type value being assignment to this AD object.
The tape identifier will be an invalid tape identifier,
so this object is initially a parameter.
*/
template <class Base>
inline AD<Base>& AD<Base>::operator=(const Base &b)
{ value_ = b;
tape_id_ = 0;
// check that this is a parameter
CPPAD_ASSERT_UNKNOWN( Parameter(*this) );
return *this;
}
/*!
Assignment to an ADVec<Base> element drops the vector information.
\tparam Base
Base type for this AD object.
*/
template <class Base>
inline AD<Base>& AD<Base>::operator=(const VecAD_reference<Base> &x)
{ return *this = x.ADBase(); }
/*!
Assignment from any other type, converts to Base type, and then uses assignment
from Base type.
\tparam Base
Base type for this AD object.
\tparam T
is the the type that is being assigned to AD<Base>.
There must be an assignment for Base from Type.
\param t
is the object that is being assigned to an AD<Base> object.
*/
template <class Base>
template <class T>
inline AD<Base>& AD<Base>::operator=(const T &t)
{ return *this = Base(t); }
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,144 +0,0 @@
# ifndef CPPAD_CORE_AD_BINARY_HPP
# define CPPAD_CORE_AD_BINARY_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 ad_binary$$
$spell
Op
VecAD
const
$$
$section AD Binary Arithmetic Operators$$
$mindex + add plus - subtract minus * multiply times / divide$$
$head Syntax$$
$icode%z% = %x% %Op% %y%$$
$head Purpose$$
Performs arithmetic operations where either $icode x$$ or $icode y$$
has type
$codei%AD<%Base%>%$$ or
$cref%VecAD<Base>::reference%VecAD%VecAD<Base>::reference%$$.
$head Op$$
The operator $icode Op$$ is one of the following
$table
$bold Op$$ $cnext $bold Meaning$$ $rnext
$code +$$ $cnext $icode z$$ is $icode x$$ plus $icode y$$ $rnext
$code -$$ $cnext $icode z$$ is $icode x$$ minus $icode y$$ $rnext
$code *$$ $cnext $icode z$$ is $icode x$$ times $icode y$$ $rnext
$code /$$ $cnext $icode z$$ is $icode x$$ divided by $icode y$$
$tend
$head Base$$
The type $icode Base$$ is determined by the operand that
has type $codei%AD<%Base%>%$$ or $codei%VecAD<%Base%>::reference%$$.
$head x$$
The operand $icode x$$ has the following prototype
$codei%
const %Type% &%x%
%$$
where $icode Type$$ is
$codei%VecAD<%Base%>::reference%$$,
$codei%AD<%Base%>%$$,
$icode Base$$, or
$code double$$.
$head y$$
The operand $icode y$$ has the following prototype
$codei%
const %Type% &%y%
%$$
where $icode Type$$ is
$codei%VecAD<%Base%>::reference%$$,
$codei%AD<%Base%>%$$,
$icode Base$$, or
$code double$$.
$head z$$
The result $icode z$$ has the following prototype
$codei%
%Type% %z%
%$$
where $icode Type$$ is
$codei%AD<%Base%>%$$.
$head Operation Sequence$$
This is an $cref/atomic/glossary/Operation/Atomic/$$
$cref/AD of Base/glossary/AD of Base/$$ operation
and hence it is part of the current
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$children%
example/general/add.cpp%
example/general/sub.cpp%
example/general/mul.cpp%
example/general/div.cpp
%$$
$head Example$$
The following files contain examples and tests of these functions.
Each test returns true if it succeeds and false otherwise.
$table
$rref add.cpp$$
$rref sub.cpp$$
$rref mul.cpp$$
$rref div.cpp$$
$tend
$head Derivative$$
If $latex f$$ and $latex g$$ are
$cref/Base functions/glossary/Base Function/$$
$subhead Addition$$
$latex \[
\D{[ f(x) + g(x) ]}{x} = \D{f(x)}{x} + \D{g(x)}{x}
\] $$
$subhead Subtraction$$
$latex \[
\D{[ f(x) - g(x) ]}{x} = \D{f(x)}{x} - \D{g(x)}{x}
\] $$
$subhead Multiplication$$
$latex \[
\D{[ f(x) * g(x) ]}{x} = g(x) * \D{f(x)}{x} + f(x) * \D{g(x)}{x}
\] $$
$subhead Division$$
$latex \[
\D{[ f(x) / g(x) ]}{x} =
[1/g(x)] * \D{f(x)}{x} - [f(x)/g(x)^2] * \D{g(x)}{x}
\] $$
$end
-----------------------------------------------------------------------------
*/
# include <cppad/core/add.hpp>
# include <cppad/core/sub.hpp>
# include <cppad/core/mul.hpp>
# include <cppad/core/div.hpp>
# endif

View File

@ -1,167 +0,0 @@
# ifndef CPPAD_CORE_AD_CTOR_HPP
# define CPPAD_CORE_AD_CTOR_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 ad_ctor$$
$spell
cppad
ctor
initializes
Vec
const
$$
$section AD Constructors $$
$mindex convert Base VecAD$$
$head Syntax$$
$codei%AD<%Base%> %y%()
%$$
$codei%AD<%Base%> %y%(%x%)
%$$
$head Purpose$$
creates a new $codei%AD<%Base%>%$$ object $icode y$$
and initializes its value as equal to $icode x$$.
$head x$$
$subhead implicit$$
There is an implicit constructor where $icode x$$ has one of the following
prototypes:
$codei%
const %Base%& %x%
const VecAD<%Base%>& %x%
%$$
$subhead explicit$$
There is an explicit constructor where $icode x$$ has prototype
$codei%
const %Type%& %x%
%$$
for any type that has an explicit constructor of the form
$icode%Base%(%x%)%$$.
$head y$$
The target $icode y$$ has prototype
$codei%
AD<%Base%> %y%
%$$
$head Example$$
$children%
example/general/ad_ctor.cpp
%$$
The files $cref ad_ctor.cpp$$ contain examples and tests of these operations.
It test returns true if it succeeds and false otherwise.
$end
------------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file ad_ctor.hpp
AD<Base> constructors and and copy operations.
*/
/*!
\page AD_default_ctor
Use default copy constructor
because they may be optimized better than the code below:
\code
template <class Base>
inline AD<Base>::AD(const AD &x)
{
value_ = x.value_;
tape_id_ = x.tape_id_;
taddr_ = x.taddr_;
return;
}
\endcode
*/
/*!
Default Constructor.
\tparam Base
Base type for this AD object.
*/
template <class Base>
inline AD<Base>::AD(void)
: value_()
, tape_id_(0)
, taddr_(0)
{ }
/*!
Constructor from Base type.
\tparam Base
Base type for this AD object.
\param b
is the Base type value corresponding to this AD object.
The tape identifier will be an invalid tape identifier,
so this object is initially a parameter.
*/
template <class Base>
inline AD<Base>::AD(const Base &b)
: value_(b)
, tape_id_(0)
, taddr_(0)
{ // check that this is a parameter
CPPAD_ASSERT_UNKNOWN( Parameter(*this) );
}
/*!
Constructor from an ADVec<Base> element drops the vector information.
\tparam Base
Base type for this AD object.
*/
template <class Base>
inline AD<Base>::AD(const VecAD_reference<Base> &x)
{ *this = x.ADBase(); }
/*!
Constructor from any other type, converts to Base type, and uses constructor
from Base type.
\tparam Base
Base type for this AD object.
\tparam T
is the the type that is being converted to AD<Base>.
There must be a constructor for Base from Type.
\param t
is the object that is being converted from T to AD<Base>.
*/
template <class Base>
template <class T>
inline AD<Base>::AD(const T &t)
: value_(Base(t))
, tape_id_(0)
, taddr_(0)
{ }
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,712 +0,0 @@
# ifndef CPPAD_CORE_AD_FUN_HPP
# define CPPAD_CORE_AD_FUN_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 ADFun$$
$spell
xk
Ind
bool
taylor_
sizeof
const
std
ind_taddr_
dep_taddr_
$$
$spell
$$
$section ADFun Objects$$
$head Purpose$$
An AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$
is stored in an $code ADFun$$ object by its $cref FunConstruct$$.
The $code ADFun$$ object can then be used to calculate function values,
derivative values, and other values related to the corresponding function.
$childtable%
omh/adfun.omh%
cppad/core/optimize.hpp%
example/abs_normal/abs_normal.omh%
cppad/core/fun_check.hpp%
cppad/core/check_for_nan.hpp
%$$
$end
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file ad_fun.hpp
File used to define the ADFun<Base> class.
*/
/*!
Class used to hold function objects
\tparam Base
A function object has a recording of <tt>AD<Base></tt> operations.
It does it calculations using \c Base operations.
*/
template <class Base>
class ADFun {
// ------------------------------------------------------------
// Private member variables
private:
/// Has this ADFun object been optmized
bool has_been_optimized_;
/// Check for nan's and report message to user (default value is true).
bool check_for_nan_;
/// If zero, ignoring comparison operators. Otherwise is the
/// compare change count at which to store the operator index.
size_t compare_change_count_;
/// If compare_change_count_ is zero, compare_change_number_ is also zero.
/// Otherwise, it is set to the number of comparison operations that had a
/// different result during the subsequent zero order forward.
size_t compare_change_number_;
/// If compare_change_count is zero, compare_change_op_index_ is also
/// zero. Otherwise it is the operator index for the comparison operator
//// that corresponded to the number changing from count-1 to count.
size_t compare_change_op_index_;
/// number of orders stored in taylor_
size_t num_order_taylor_;
/// maximum number of orders that will fit in taylor_
size_t cap_order_taylor_;
/// number of directions stored in taylor_
size_t num_direction_taylor_;
/// number of variables in the recording (play_)
size_t num_var_tape_;
/// tape address for the independent variables
CppAD::vector<size_t> ind_taddr_;
/// tape address and parameter flag for the dependent variables
CppAD::vector<size_t> dep_taddr_;
/// which dependent variables are actually parameters
CppAD::vector<bool> dep_parameter_;
/// results of the forward mode calculations
local::pod_vector<Base> taylor_;
/// which operations can be conditionally skipped
/// Set during forward pass of order zero
local::pod_vector<bool> cskip_op_;
/// Variable on the tape corresponding to each vecad load operation
/// (if zero, the operation corresponds to a parameter).
local::pod_vector<addr_t> load_op_;
/// the operation sequence corresponding to this object
local::player<Base> play_;
/// Packed results of the forward mode Jacobian sparsity calculations.
/// for_jac_sparse_pack_.n_set() != 0 implies other sparsity results
/// are empty
local::sparse_pack for_jac_sparse_pack_;
/// Set results of the forward mode Jacobian sparsity calculations
/// for_jac_sparse_set_.n_set() != 0 implies for_sparse_pack_ is empty.
local::sparse_list for_jac_sparse_set_;
// ------------------------------------------------------------
// Private member functions
/// change the operation sequence corresponding to this object
template <typename ADvector>
void Dependent(local::ADTape<Base> *tape, const ADvector &y);
// ------------------------------------------------------------
// vector of bool version of ForSparseJac
// (see doxygen in for_sparse_jac.hpp)
template <class VectorSet>
void ForSparseJacCase(
bool set_type ,
bool transpose ,
bool dependency,
size_t q ,
const VectorSet& r ,
VectorSet& s
);
// vector of std::set<size_t> version of ForSparseJac
// (see doxygen in for_sparse_jac.hpp)
template <class VectorSet>
void ForSparseJacCase(
const std::set<size_t>& set_type ,
bool transpose ,
bool dependency,
size_t q ,
const VectorSet& r ,
VectorSet& s
);
// ------------------------------------------------------------
// vector of bool version of RevSparseJac
// (see doxygen in rev_sparse_jac.hpp)
template <class VectorSet>
void RevSparseJacCase(
bool set_type ,
bool transpose ,
bool dependency,
size_t p ,
const VectorSet& s ,
VectorSet& r
);
// vector of std::set<size_t> version of RevSparseJac
// (see doxygen in rev_sparse_jac.hpp)
template <class VectorSet>
void RevSparseJacCase(
const std::set<size_t>& set_type ,
bool transpose ,
bool dependency,
size_t p ,
const VectorSet& s ,
VectorSet& r
);
// ------------------------------------------------------------
// vector of bool version of ForSparseHes
// (see doxygen in rev_sparse_hes.hpp)
template <class VectorSet>
void ForSparseHesCase(
bool set_type ,
const VectorSet& r ,
const VectorSet& s ,
VectorSet& h
);
// vector of std::set<size_t> version of ForSparseHes
// (see doxygen in rev_sparse_hes.hpp)
template <class VectorSet>
void ForSparseHesCase(
const std::set<size_t>& set_type ,
const VectorSet& r ,
const VectorSet& s ,
VectorSet& h
);
// ------------------------------------------------------------
// vector of bool version of RevSparseHes
// (see doxygen in rev_sparse_hes.hpp)
template <class VectorSet>
void RevSparseHesCase(
bool set_type ,
bool transpose ,
size_t q ,
const VectorSet& s ,
VectorSet& h
);
// vector of std::set<size_t> version of RevSparseHes
// (see doxygen in rev_sparse_hes.hpp)
template <class VectorSet>
void RevSparseHesCase(
const std::set<size_t>& set_type ,
bool transpose ,
size_t q ,
const VectorSet& s ,
VectorSet& h
);
// ------------------------------------------------------------
// Forward mode version of SparseJacobian
// (see doxygen in sparse_jacobian.hpp)
template <class VectorBase, class VectorSet, class VectorSize>
size_t SparseJacobianFor(
const VectorBase& x ,
VectorSet& p_transpose ,
const VectorSize& row ,
const VectorSize& col ,
VectorBase& jac ,
sparse_jacobian_work& work
);
// Reverse mode version of SparseJacobian
// (see doxygen in sparse_jacobian.hpp)
template <class VectorBase, class VectorSet, class VectorSize>
size_t SparseJacobianRev(
const VectorBase& x ,
VectorSet& p ,
const VectorSize& row ,
const VectorSize& col ,
VectorBase& jac ,
sparse_jacobian_work& work
);
// ------------------------------------------------------------
// combined sparse_list and sparse_pack version of
// SparseHessian (see doxygen in sparse_hessian.hpp)
template <class VectorBase, class VectorSet, class VectorSize>
size_t SparseHessianCompute(
const VectorBase& x ,
const VectorBase& w ,
VectorSet& sparsity ,
const VectorSize& row ,
const VectorSize& col ,
VectorBase& hes ,
sparse_hessian_work& work
);
// ------------------------------------------------------------
public:
/// copy constructor
ADFun(const ADFun& g)
: num_var_tape_(0)
{ CppAD::ErrorHandler::Call(
true,
__LINE__,
__FILE__,
"ADFun(const ADFun& g)",
"Attempting to use the ADFun<Base> copy constructor.\n"
"Perhaps you are passing an ADFun<Base> object "
"by value instead of by reference."
);
}
/// default constructor
ADFun(void);
// assignment operator
// (see doxygen in fun_construct.hpp)
void operator=(const ADFun& f);
/// sequence constructor
template <typename ADvector>
ADFun(const ADvector &x, const ADvector &y);
/// destructor
~ADFun(void)
{ }
/// set value of check_for_nan_
void check_for_nan(bool value)
{ check_for_nan_ = value; }
bool check_for_nan(void) const
{ return check_for_nan_; }
/// assign a new operation sequence
template <typename ADvector>
void Dependent(const ADvector &x, const ADvector &y);
/// forward mode user API, one order multiple directions.
template <typename VectorBase>
VectorBase Forward(size_t q, size_t r, const VectorBase& x);
/// forward mode user API, multiple directions one order.
template <typename VectorBase>
VectorBase Forward(size_t q,
const VectorBase& x, std::ostream& s = std::cout
);
/// reverse mode sweep
template <typename VectorBase>
VectorBase Reverse(size_t p, const VectorBase &v);
// ---------------------------------------------------------------------
// Jacobian sparsity
template <typename VectorSet>
VectorSet ForSparseJac(
size_t q, const VectorSet &r, bool transpose = false,
bool dependency = false
);
template <typename VectorSet>
VectorSet RevSparseJac(
size_t q, const VectorSet &s, bool transpose = false,
bool dependency = false
);
// ---------------------------------------------------------------------
template <typename SizeVector, typename BaseVector>
size_t sparse_jac_for(
size_t group_max ,
const BaseVector& x ,
sparse_rcv<SizeVector, BaseVector>& subset ,
const sparse_rc<SizeVector>& pattern ,
const std::string& coloring ,
sparse_jac_work& work
);
template <typename SizeVector, typename BaseVector>
size_t sparse_jac_rev(
const BaseVector& x ,
sparse_rcv<SizeVector, BaseVector>& subset ,
const sparse_rc<SizeVector>& pattern ,
const std::string& coloring ,
sparse_jac_work& work
);
template <typename SizeVector, typename BaseVector>
size_t sparse_hes(
const BaseVector& x ,
const BaseVector& w ,
sparse_rcv<SizeVector, BaseVector>& subset ,
const sparse_rc<SizeVector>& pattern ,
const std::string& coloring ,
sparse_hes_work& work
);
// ---------------------------------------------------------------------
template <typename SizeVector>
void for_jac_sparsity(
const sparse_rc<SizeVector>& pattern_in ,
bool transpose ,
bool dependency ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out
);
template <typename SizeVector>
void rev_jac_sparsity(
const sparse_rc<SizeVector>& pattern_in ,
bool transpose ,
bool dependency ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out
);
template <typename BoolVector, typename SizeVector>
void rev_hes_sparsity(
const BoolVector& select_range ,
bool transpose ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out
);
template <typename BoolVector, typename SizeVector>
void for_hes_sparsity(
const BoolVector& select_domain ,
const BoolVector& select_range ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out
);
// ---------------------------------------------------------------------
// forward mode Hessian sparsity
// (see doxygen documentation in rev_sparse_hes.hpp)
template <typename VectorSet>
VectorSet ForSparseHes(
const VectorSet &r, const VectorSet &s
);
// internal set sparsity version of ForSparseHes
// (used by checkpoint functions only)
void ForSparseHesCheckpoint(
vector<bool>& r ,
vector<bool>& s ,
local::sparse_list& h
);
// reverse mode Hessian sparsity
// (see doxygen documentation in rev_sparse_hes.hpp)
template <typename VectorSet>
VectorSet RevSparseHes(
size_t q, const VectorSet &s, bool transpose = false
);
// internal set sparsity version of RevSparseHes
// (used by checkpoint functions only)
void RevSparseHesCheckpoint(
size_t q ,
vector<bool>& s ,
bool transpose ,
local::sparse_list& h
);
// internal set sparsity version of RevSparseJac
// (used by checkpoint functions only)
void RevSparseJacCheckpoint(
size_t q ,
const local::sparse_list& r ,
bool transpose ,
bool dependency ,
local::sparse_list& s
);
// internal set sparsity version of RevSparseJac
// (used by checkpoint functions only)
void ForSparseJacCheckpoint(
size_t q ,
const local::sparse_list& r ,
bool transpose ,
bool dependency ,
local::sparse_list& s
);
/// amount of memory used for boolean Jacobain sparsity pattern
size_t size_forward_bool(void) const
{ return for_jac_sparse_pack_.memory(); }
/// free memory used for Jacobain sparsity pattern
void size_forward_bool(size_t zero)
{ CPPAD_ASSERT_KNOWN(
zero == 0,
"size_forward_bool: argument not equal to zero"
);
for_jac_sparse_pack_.resize(0, 0);
}
/// amount of memory used for vector of set Jacobain sparsity pattern
size_t size_forward_set(void) const
{ return for_jac_sparse_set_.memory(); }
/// free memory used for Jacobain sparsity pattern
void size_forward_set(size_t zero)
{ CPPAD_ASSERT_KNOWN(
zero == 0,
"size_forward_bool: argument not equal to zero"
);
for_jac_sparse_set_.resize(0, 0);
}
/// number of operators in the operation sequence
size_t size_op(void) const
{ return play_.num_op_rec(); }
/// number of operator arguments in the operation sequence
size_t size_op_arg(void) const
{ return play_.num_op_arg_rec(); }
/// amount of memory required for the operation sequence
size_t size_op_seq(void) const
{ return play_.Memory(); }
/// number of parameters in the operation sequence
size_t size_par(void) const
{ return play_.num_par_rec(); }
/// number taylor coefficient orders calculated
size_t size_order(void) const
{ return num_order_taylor_; }
/// number taylor coefficient directions calculated
size_t size_direction(void) const
{ return num_direction_taylor_; }
/// number of characters in the operation sequence
size_t size_text(void) const
{ return play_.num_text_rec(); }
/// number of variables in opertion sequence
size_t size_var(void) const
{ return num_var_tape_; }
/// number of VecAD indices in the operation sequence
size_t size_VecAD(void) const
{ return play_.num_vec_ind_rec(); }
/// set number of orders currently allocated (user API)
void capacity_order(size_t c);
/// set number of orders and directions currently allocated
void capacity_order(size_t c, size_t r);
/// number of variables in conditional expressions that can be skipped
size_t number_skip(void);
/// number of independent variables
size_t Domain(void) const
{ return ind_taddr_.size(); }
/// number of dependent variables
size_t Range(void) const
{ return dep_taddr_.size(); }
/// is variable a parameter
bool Parameter(size_t i)
{ CPPAD_ASSERT_KNOWN(
i < dep_taddr_.size(),
"Argument to Parameter is >= dimension of range space"
);
return dep_parameter_[i];
}
/// Deprecated: number of comparison operations that changed
/// for the previous zero order forward (than when function was recorded)
size_t CompareChange(void) const
{ return compare_change_number_; }
/// count as which to store operator index
void compare_change_count(size_t count)
{ compare_change_count_ = count;
compare_change_number_ = 0;
compare_change_op_index_ = 0;
}
/// number of comparison operations that changed
size_t compare_change_number(void) const
{ return compare_change_number_; }
/// operator index for the count-th comparison change
size_t compare_change_op_index(void) const
{ if( has_been_optimized_ )
return 0;
return compare_change_op_index_;
}
/// calculate entire Jacobian
template <typename VectorBase>
VectorBase Jacobian(const VectorBase &x);
/// calculate Hessian for one component of f
template <typename VectorBase>
VectorBase Hessian(const VectorBase &x, const VectorBase &w);
template <typename VectorBase>
VectorBase Hessian(const VectorBase &x, size_t i);
/// forward mode calculation of partial w.r.t one domain component
template <typename VectorBase>
VectorBase ForOne(
const VectorBase &x ,
size_t j );
/// reverse mode calculation of derivative of one range component
template <typename VectorBase>
VectorBase RevOne(
const VectorBase &x ,
size_t i );
/// forward mode calculation of a subset of second order partials
template <typename VectorBase, typename VectorSize_t>
VectorBase ForTwo(
const VectorBase &x ,
const VectorSize_t &J ,
const VectorSize_t &K );
/// reverse mode calculation of a subset of second order partials
template <typename VectorBase, typename VectorSize_t>
VectorBase RevTwo(
const VectorBase &x ,
const VectorSize_t &I ,
const VectorSize_t &J );
/// calculate sparse Jacobians
template <typename VectorBase>
VectorBase SparseJacobian(
const VectorBase &x
);
template <typename VectorBase, typename VectorSet>
VectorBase SparseJacobian(
const VectorBase &x ,
const VectorSet &p
);
template <class VectorBase, class VectorSet, class VectorSize>
size_t SparseJacobianForward(
const VectorBase& x ,
const VectorSet& p ,
const VectorSize& r ,
const VectorSize& c ,
VectorBase& jac ,
sparse_jacobian_work& work
);
template <class VectorBase, class VectorSet, class VectorSize>
size_t SparseJacobianReverse(
const VectorBase& x ,
const VectorSet& p ,
const VectorSize& r ,
const VectorSize& c ,
VectorBase& jac ,
sparse_jacobian_work& work
);
/// calculate sparse Hessians
template <typename VectorBase>
VectorBase SparseHessian(
const VectorBase& x ,
const VectorBase& w
);
template <typename VectorBase, typename VectorBool>
VectorBase SparseHessian(
const VectorBase& x ,
const VectorBase& w ,
const VectorBool& p
);
template <class VectorBase, class VectorSet, class VectorSize>
size_t SparseHessian(
const VectorBase& x ,
const VectorBase& w ,
const VectorSet& p ,
const VectorSize& r ,
const VectorSize& c ,
VectorBase& hes ,
sparse_hessian_work& work
);
// Optimize the tape
// (see doxygen documentation in optimize.hpp)
void optimize( const std::string& options = "" );
// create abs-normal representation of the function f(x)
void abs_normal_fun( ADFun& g, ADFun& a );
// ------------------- Deprecated -----------------------------
/// deprecated: assign a new operation sequence
template <typename ADvector>
void Dependent(const ADvector &y);
/// Deprecated: number of variables in opertion sequence
size_t Size(void) const
{ return num_var_tape_; }
/// Deprecated: # taylor_ coefficients currently stored
/// (per variable,direction)
size_t Order(void) const
{ return num_order_taylor_ - 1; }
/// Deprecated: amount of memory for this object
/// Note that an approximation is used for the std::set<size_t> memory
size_t Memory(void) const
{ size_t pervar = cap_order_taylor_ * sizeof(Base)
+ for_jac_sparse_pack_.memory()
+ for_jac_sparse_set_.memory();
size_t total = num_var_tape_ * pervar + play_.Memory();
return total;
}
/// Deprecated: # taylor_ coefficient orderss stored
/// (per variable,direction)
size_t taylor_size(void) const
{ return num_order_taylor_; }
/// Deprecated: Does this AD operation sequence use
/// VecAD<Base>::reference operands
bool use_VecAD(void) const
{ return play_.num_vec_ind_rec() > 0; }
/// Deprecated: # taylor_ coefficient orders calculated
/// (per variable,direction)
size_t size_taylor(void) const
{ return num_order_taylor_; }
/// Deprecated: set number of orders currently allocated
/// (per variable,direction)
void capacity_taylor(size_t per_var);
};
// ---------------------------------------------------------------------------
} // END_CPPAD_NAMESPACE
// non-user interfaces
# include <cppad/local/forward0sweep.hpp>
# include <cppad/local/forward1sweep.hpp>
# include <cppad/local/forward2sweep.hpp>
# include <cppad/local/reverse_sweep.hpp>
# include <cppad/local/for_jac_sweep.hpp>
# include <cppad/local/rev_jac_sweep.hpp>
# include <cppad/local/rev_hes_sweep.hpp>
# include <cppad/local/for_hes_sweep.hpp>
// user interfaces
# include <cppad/core/parallel_ad.hpp>
# include <cppad/core/independent.hpp>
# include <cppad/core/dependent.hpp>
# include <cppad/core/fun_construct.hpp>
# include <cppad/core/abort_recording.hpp>
# include <cppad/core/fun_eval.hpp>
# include <cppad/core/drivers.hpp>
# include <cppad/core/fun_check.hpp>
# include <cppad/core/omp_max_thread.hpp>
# include <cppad/core/optimize.hpp>
# include <cppad/core/abs_normal_fun.hpp>
# endif

View File

@ -1,223 +0,0 @@
# ifndef CPPAD_CORE_AD_IO_HPP
# define CPPAD_CORE_AD_IO_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 ad_input$$
$spell
VecAD
std
istream
const
$$
$section AD Output Stream Operator$$
$mindex >> input write$$
$head Syntax$$
$icode%is% >> %x%$$
$head Purpose$$
Sets $icode x$$ to a $cref/parameter/glossary/Parameter/$$
with value $icode b$$ corresponding to
$codei%
%is% >> %b%
%$$
where $icode b$$ is a $icode Base$$ object.
It is assumed that this $icode Base$$ input operation returns
a reference to $icode is$$.
$head is$$
The operand $icode is$$ has prototype
$codei%
std::istream& %is%
%$$
$head x$$
The operand $icode x$$ has one of the following prototypes
$codei%
AD<%Base%>& %x%
%$$
$head Result$$
The result of this operation can be used as a reference to $icode is$$.
For example, if the operand $icode y$$ has prototype
$codei%
AD<%Base%> %y%
%$$
then the syntax
$codei%
%is% >> %x% >> %y%
%$$
will first read the $icode Base$$ value of $icode x$$ from $icode is$$,
and then read the $icode Base$$ value to $icode y$$.
$head Operation Sequence$$
The result of this operation is not an
$cref/AD of Base/glossary/AD of Base/$$ object.
Thus it will not be recorded as part of an
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$children%
example/general/ad_input.cpp
%$$
The file
$cref ad_input.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
------------------------------------------------------------------------------
$begin ad_output$$
$spell
VecAD
std
ostream
const
$$
$section AD Output Stream Operator$$
$mindex <<$$
$head Syntax$$
$icode%os% << %x%$$
$head Purpose$$
Writes the $icode Base$$ value, corresponding to $icode x$$,
to the output stream $icode os$$.
$head Assumption$$
If $icode b$$ is a $icode Base$$ object,
$codei%
%os% << %b%
%$$
returns a reference to $icode os$$.
$head os$$
The operand $icode os$$ has prototype
$codei%
std::ostream& %os%
%$$
$head x$$
The operand $icode x$$ has one of the following prototypes
$codei%
const AD<%Base%>& %x%
const VecAD<%Base%>::reference& %x%
%$$
$head Result$$
The result of this operation can be used as a reference to $icode os$$.
For example, if the operand $icode y$$ has prototype
$codei%
AD<%Base%> %y%
%$$
then the syntax
$codei%
%os% << %x% << %y%
%$$
will output the value corresponding to $icode x$$
followed by the value corresponding to $icode y$$.
$head Operation Sequence$$
The result of this operation is not an
$cref/AD of Base/glossary/AD of Base/$$ object.
Thus it will not be recorded as part of an
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$children%
example/general/ad_output.cpp
%$$
The file
$cref ad_output.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
------------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file ad_io.hpp
AD<Base> input and ouput stream operators.
*/
// ---------------------------------------------------------------------------
/*!
Read an AD<Base> object from an input stream.
\tparam Base
Base type for the AD object.
\param is [in,out]
Is the input stream from which that value is read.
\param x [out]
is the object that is being set to a value.
Upone return, x.value_ is read from the input stream
and x.tape_is_ is zero; i.e., x is a parameter.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
std::istream& operator >> (std::istream& is, AD<Base>& x)
{ // like assignment to a base type value
x.tape_id_ = 0;
CPPAD_ASSERT_UNKNOWN( Parameter(x) );
return (is >> x.value_);
}
// ---------------------------------------------------------------------------
/*!
Write an AD<Base> object to an output stream.
\tparam Base
Base type for the AD object.
\param os [in,out]
Is the output stream to which that value is written.
\param x
is the object that is being written to the output stream.
This is equivalent to writing x.value_ to the output stream.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
std::ostream& operator << (std::ostream &os, const AD<Base> &x)
{ return (os << x.value_); }
// ---------------------------------------------------------------------------
/*!
Write a VecAD_reference<Base> object to an output stream.
\tparam Base
Base type for the VecAD_reference object.
\param os [in,out]
Is the output stream to which that value is written.
\param x
is the element of the VecAD object that is being written to the output stream.
This is equivalent to writing the corresponing Base value to the stream.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
std::ostream& operator << (std::ostream &os, const VecAD_reference<Base> &x)
{ return (os << x.ADBase()); }
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,71 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_AD_TO_STRING_HPP
# define CPPAD_CORE_AD_TO_STRING_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 ad_to_string$$
$spell
const
std
$$
$section Convert An AD or Base Type to String$$
$head Syntax$$
$icode%s% = to_string(%value%)%$$.
$head See Also$$
$cref to_string$$, $cref base_to_string$$
$head value$$
The argument $icode value$$ has prototype
$codei%
const AD<%Base%>& %value%
const %Base%& %value%
%$$
where $icode Base$$ is a type that supports the
$cref base_to_string$$ type requirement.
$head s$$
The return value has prototype
$codei%
std::string %s%
%$$
and contains a representation of the specified $icode value$$.
If $icode value$$ is an AD type,
the result has the same precision as for the $icode Base$$ type.
$head Example$$
The file $cref to_string.cpp$$
includes an example and test of $code to_string$$ with AD types.
It returns true if it succeeds and false otherwise.
$end
*/
# include <cppad/utility/to_string.hpp>
# include <cppad/core/ad.hpp>
namespace CppAD {
// Template definition is in cppad/utility/to_string.hpp.
// Partial specialzation for AD<Base> types
template<class Base>
struct to_string_struct< CppAD::AD<Base> >
{ std::string operator()(const CppAD::AD<Base>& value)
{ to_string_struct<Base> ts;
return ts( Value( Var2Par( value ) ) ); }
};
}
# endif

View File

@ -1,49 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_AD_VALUED_HPP
# define CPPAD_CORE_AD_VALUED_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 ADValued$$
$spell
$$
$section AD Valued Operations and Functions$$
$comment atomic.omh includes atomic_base.omh which atomic_base.hpp$$
$childtable%
cppad/core/arithmetic.hpp%
cppad/core/standard_math.hpp%
cppad/core/cond_exp.hpp%
cppad/core/discrete.hpp%
cppad/core/numeric_limits.hpp%
omh/atomic.omh
%$$
$end
*/
// include MathOther.h after CondExp.h because some MathOther.h routines use
// CondExp.h and CondExp.h is not sufficently declared in Declare.h
# include <cppad/core/arithmetic.hpp>
# include <cppad/core/standard_math.hpp>
# include <cppad/core/azmul.hpp>
# include <cppad/core/cond_exp.hpp>
# include <cppad/core/discrete.hpp>
# include <cppad/core/atomic_base.hpp>
# include <cppad/core/checkpoint.hpp>
# include <cppad/core/old_atomic.hpp>
# endif

View File

@ -1,97 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_ADD_HPP
# define CPPAD_CORE_ADD_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 CppAD namespace
namespace CppAD {
template <class Base>
AD<Base> operator + (const AD<Base> &left , const AD<Base> &right)
{
// compute the Base part of this AD object
AD<Base> result;
result.value_ = left.value_ + right.value_;
CPPAD_ASSERT_UNKNOWN( Parameter(result) );
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return result;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_left = left.tape_id_ == tape_id;
bool var_right = right.tape_id_ == tape_id;
if( var_left )
{ if( var_right )
{ // result = variable + variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddvvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(left.taddr_, right.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::AddvvOp);
// make result a variable
result.tape_id_ = tape_id;
}
else if( IdenticalZero(right.value_) )
{ // result = variable + 0
result.make_variable(left.tape_id_, left.taddr_);
}
else
{ // result = variable + parameter
// = parameter + variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(p, left.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::AddpvOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
else if( var_right )
{ if( IdenticalZero(left.value_) )
{ // result = 0 + variable
result.make_variable(right.tape_id_, right.taddr_);
}
else
{ // result = parameter + variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(left.value_);
tape->Rec_.PutArg(p, right.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::AddpvOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(+)
} // END CppAD namespace
# endif

View File

@ -1,92 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_ADD_EQ_HPP
# define CPPAD_CORE_ADD_EQ_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 CppAD namespace
namespace CppAD {
template <class Base>
AD<Base>& AD<Base>::operator += (const AD<Base> &right)
{
// compute the Base part
Base left;
left = value_;
value_ += right.value_;
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return *this;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_left = tape_id_ == tape_id;
bool var_right = right.tape_id_ == tape_id;
if( var_left )
{ if( var_right )
{ // this = variable + variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddvvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(taddr_, right.taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::AddvvOp);
// make this a variable
CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );
}
else if( ! IdenticalZero( right.value_ ) )
{ // this = variable + parameter
// = parameter + variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(p, taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::AddpvOp);
// make this a variable
CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );
}
}
else if( var_right )
{ if( IdenticalZero(left) )
{ // this = 0 + right
make_variable(right.tape_id_, right.taddr_);
}
else
{ // this = parameter + variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(left);
tape->Rec_.PutArg(p, right.taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::AddpvOp);
// make this a variable
tape_id_ = tape_id;
}
}
return *this;
}
CPPAD_FOLD_ASSIGNMENT_OPERATOR(+=)
} // END CppAD namespace
# endif

View File

@ -1,42 +0,0 @@
# ifndef CPPAD_CORE_ARITHMETIC_HPP
# define CPPAD_CORE_ARITHMETIC_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 Arithmetic$$
$spell
Op
const
$$
$section AD Arithmetic Operators and Compound Assignments$$
$childtable%
cppad/core/unary_plus.hpp%
cppad/core/unary_minus.hpp%
cppad/core/ad_binary.hpp%
cppad/core/compound_assign.hpp
%$$
$end
-------------------------------------------------------------------------------
*/
# include <cppad/core/unary_plus.hpp>
# include <cppad/core/unary_minus.hpp>
# include <cppad/core/ad_binary.hpp>
# include <cppad/core/compound_assign.hpp>
# endif

View File

@ -1,96 +0,0 @@
# ifndef CPPAD_CORE_ASINH_HPP
# define CPPAD_CORE_ASINH_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 asinh$$
$spell
asinh
const
Vec
std
cmath
CppAD
$$
$section The Inverse Hyperbolic Sine Function: asinh$$
$head Syntax$$
$icode%y% = asinh(%x%)%$$
$head Description$$
The inverse hyperbolic sine function is defined by
$icode%x% == sinh(%y%)%$$.
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head CPPAD_USE_CPLUSPLUS_2011$$
$subhead true$$
If this preprocessor symbol is true ($code 1$$),
and $icode x$$ is an AD type,
this is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$subhead false$$
If this preprocessor symbol is false ($code 0$$),
CppAD uses the representation
$latex \[
\R{asinh} (x) = \log \left( x + \sqrt{ 1 + x^2 } \right)
\] $$
to compute this function.
$head Example$$
$children%
example/general/asinh.cpp
%$$
The file
$cref asinh.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
# include <cppad/configure.hpp>
# if ! CPPAD_USE_CPLUSPLUS_2011
// BEGIN CppAD namespace
namespace CppAD {
template <class Type>
Type asinh_template(const Type &x)
{ return CppAD::log( x + CppAD::sqrt( Type(1) + x * x ) );
}
inline float asinh(const float &x)
{ return asinh_template(x); }
inline double asinh(const double &x)
{ return asinh_template(x); }
template <class Base>
inline AD<Base> asinh(const AD<Base> &x)
{ return asinh_template(x); }
template <class Base>
inline AD<Base> asinh(const VecAD_reference<Base> &x)
{ return asinh_template( x.ADBase() ); }
} // END CppAD namespace
# endif // CPPAD_USE_CPLUSPLUS_2011
# endif // CPPAD_ASINH_INCLUDED

View File

@ -1,141 +0,0 @@
# ifndef CPPAD_CORE_ATAN2_HPP
# define CPPAD_CORE_ATAN2_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 atan2$$
$spell
Vec
CppAD
namespace
std
atan
const
$$
$section AD Two Argument Inverse Tangent Function$$
$mindex tan atan2$$
$head Syntax$$
$icode%theta% = atan2(%y%, %x%)%$$
$head Purpose$$
Determines an angle $latex \theta \in [ - \pi , + \pi ]$$
such that
$latex \[
\begin{array}{rcl}
\sin ( \theta ) & = & y / \sqrt{ x^2 + y^2 } \\
\cos ( \theta ) & = & x / \sqrt{ x^2 + y^2 }
\end{array}
\] $$
$head y$$
The argument $icode y$$ has one of the following prototypes
$codei%
const AD<%Base%> &%y%
const VecAD<%Base%>::reference &%y%
%$$
$head x$$
The argument $icode x$$ has one of the following prototypes
$codei%
const AD<%Base%> &%x%
const VecAD<%Base%>::reference &%x%
%$$
$head theta$$
The result $icode theta$$ has prototype
$codei%
AD<%Base%> %theta%
%$$
$head Operation Sequence$$
The AD of $icode Base$$
operation sequence used to calculate $icode theta$$ is
$cref/independent/glossary/Operation/Independent/$$
of $icode x$$ and $icode y$$.
$head Example$$
$children%
example/general/atan2.cpp
%$$
The file
$cref atan2.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN CppAD namespace
inline float atan2(float x, float y)
{ return std::atan2(x, y); }
inline double atan2(double x, double y)
{ return std::atan2(x, y); }
// The code below is used as an example by the CondExp documentation.
// BEGIN CondExp
template <class Base>
AD<Base> atan2 (const AD<Base> &y, const AD<Base> &x)
{ AD<Base> alpha;
AD<Base> beta;
AD<Base> theta;
AD<Base> zero(0.);
AD<Base> pi2(2. * atan(1.));
AD<Base> pi(2. * pi2);
AD<Base> ax = fabs(x);
AD<Base> ay = fabs(y);
// if( ax > ay )
// theta = atan(ay / ax);
// else theta = pi2 - atan(ax / ay);
alpha = atan(ay / ax);
beta = pi2 - atan(ax / ay);
theta = CondExpGt(ax, ay, alpha, beta); // use of CondExp
// if( x <= 0 )
// theta = pi - theta;
theta = CondExpLe(x, zero, pi - theta, theta); // use of CondExp
// if( y <= 0 )
// theta = - theta;
theta = CondExpLe(y, zero, -theta, theta); // use of CondExp
return theta;
}
// END CondExp
template <class Base>
inline AD<Base> atan2 (const VecAD_reference<Base> &y, const AD<Base> &x)
{ return atan2( y.ADBase() , x ); }
template <class Base>
inline AD<Base> atan2 (const AD<Base> &y, const VecAD_reference<Base> &x)
{ return atan2( y , x.ADBase() ); }
template <class Base>
inline AD<Base> atan2
(const VecAD_reference<Base> &y, const VecAD_reference<Base> &x)
{ return atan2( y.ADBase() , x.ADBase() ); }
} // END CppAD namespace
# endif

View File

@ -1,96 +0,0 @@
# ifndef CPPAD_CORE_ATANH_HPP
# define CPPAD_CORE_ATANH_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 atanh$$
$spell
atanh
const
Vec
std
cmath
CppAD
tanh
$$
$section The Inverse Hyperbolic Tangent Function: atanh$$
$head Syntax$$
$icode%y% = atanh(%x%)%$$
$head Description$$
The inverse hyperbolic tangent function is defined by
$icode%x% == tanh(%y%)%$$.
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head CPPAD_USE_CPLUSPLUS_2011$$
$subhead true$$
If this preprocessor symbol is true ($code 1$$),
and $icode x$$ is an AD type,
this is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$subhead false$$
If this preprocessor symbol is false ($code 0$$),
CppAD uses the representation
$latex \[
\R{atanh} (x) = \frac{1}{2} \log \left( \frac{1 + x}{1 - x} \right)
\] $$
to compute this function.
$head Example$$
$children%
example/general/atanh.cpp
%$$
The file
$cref atanh.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
# include <cppad/configure.hpp>
# if ! CPPAD_USE_CPLUSPLUS_2011
// BEGIN CppAD namespace
namespace CppAD {
template <class Type>
Type atanh_template(const Type &x)
{ return CppAD::log( (Type(1) + x) / (Type(1) - x) ) / Type(2);
}
inline float atanh(const float &x)
{ return atanh_template(x); }
inline double atanh(const double &x)
{ return atanh_template(x); }
template <class Base>
inline AD<Base> atanh(const AD<Base> &x)
{ return atanh_template(x); }
template <class Base>
inline AD<Base> atanh(const VecAD_reference<Base> &x)
{ return atanh_template( x.ADBase() ); }
} // END CppAD namespace
# endif // CPPAD_USE_CPLUSPLUS_2011
# endif // CPPAD_ATANH_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,213 +0,0 @@
# ifndef CPPAD_CORE_AZMUL_HPP
# define CPPAD_CORE_AZMUL_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 azmul$$
$spell
azmul
const
namespace
Vec
$$
$section Absolute Zero Multiplication$$
$head Syntax$$
$icode%z% = azmul(%x%, %y%)%$$
$head Purpose$$
Evaluates multiplication with an absolute zero
for any of the possible types listed below.
The result is given by
$latex \[
z = \left\{ \begin{array}{ll}
0 & {\rm if} \; x = 0 \\
x \cdot y & {\rm otherwise}
\end{array} \right.
\] $$
Note if $icode x$$ is zero and $icode y$$ is infinity,
ieee multiplication would result in not a number whereas
$icode z$$ would be zero.
$head Base$$
If $icode Base$$ satisfies the
$cref/base type requirements/base_require/$$
and arguments $icode x$$, $icode y$$ have prototypes
$codei%
const %Base%& %x%
const %Base%& %y%
%$$
then the result $icode z$$ has prototype
$codei%
%Base% %z%
%$$
$head AD<Base>$$
If the arguments $icode x$$, $icode y$$ have prototype
$codei%
const AD<%Base%>& %x%
const AD<%Base%>& %y%
%$$
then the result $icode z$$ has prototype
$codei%
AD<%Base%> %z%
%$$
$head VecAD<Base>$$
If the arguments $icode x$$, $icode y$$ have prototype
$codei%
const VecAD<%Base%>::reference& %x%
const VecAD<%Base%>::reference& %y%
%$$
then the result $icode z$$ has prototype
$codei%
AD<%Base%> %z%
%$$
$head Example$$
$children%
example/general/azmul.cpp
%$$
The file
$cref azmul.cpp$$
is an examples and tests of this function.
It returns true if it succeeds and false otherwise.
$end
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
// ==========================================================================
// case where x and y are AD<Base> -------------------------------------------
template <class Base> AD<Base>
azmul(const AD<Base>& x, const AD<Base>& y)
{
// compute the Base part
AD<Base> result;
result.value_ = azmul(x.value_, y.value_);
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return result;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_x = x.tape_id_ == tape_id;
bool var_y = y.tape_id_ == tape_id;
if( var_x )
{ if( var_y )
{ // result = azmul(variable, variable)
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ZmulvvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::ZmulvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(x.taddr_, y.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::ZmulvvOp);
// make result a variable
result.tape_id_ = tape_id;
}
else if( IdenticalZero( y.value_ ) )
{ // result = variable * 0
}
else if( IdenticalOne( y.value_ ) )
{ // result = variable * 1
result.make_variable(x.tape_id_, x.taddr_);
}
else
{ // result = zmul(variable, parameter)
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ZmulvpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::ZmulvpOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(y.value_);
tape->Rec_.PutArg(x.taddr_, p);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::ZmulvpOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
else if( var_y )
{ if( IdenticalZero(x.value_) )
{ // result = 0 * variable
}
else if( IdenticalOne( x.value_ ) )
{ // result = 1 * variable
result.make_variable(y.tape_id_, y.taddr_);
}
else
{ // result = zmul(parameter, variable)
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ZmulpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::ZmulpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(x.value_);
tape->Rec_.PutArg(p, y.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::ZmulpvOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
return result;
}
// =========================================================================
// Fold operations into case above
// -------------------------------------------------------------------------
// Operations with VecAD_reference<Base> and AD<Base> only
template <class Base> AD<Base>
azmul(const AD<Base>& x, const VecAD_reference<Base>& y)
{ return azmul(x, y.ADBase()); }
template <class Base> AD<Base>
azmul(const VecAD_reference<Base>& x, const VecAD_reference<Base>& y)
{ return azmul(x.ADBase(), y.ADBase()); }
template <class Base> AD<Base>
azmul(const VecAD_reference<Base>& x, const AD<Base>& y)
{ return azmul(x.ADBase(), y); }
// -------------------------------------------------------------------------
// Operations with Base
template <class Base> AD<Base>
azmul(const Base& x, const AD<Base>& y)
{ return azmul(AD<Base>(x), y); }
template <class Base> AD<Base>
azmul(const Base& x, const VecAD_reference<Base>& y)
{ return azmul(AD<Base>(x), y.ADBase()); }
template <class Base> AD<Base>
azmul(const AD<Base>& x, const Base& y)
{ return azmul(x, AD<Base>(y)); }
template <class Base> AD<Base>
azmul(const VecAD_reference<Base>& x, const Base& y)
{ return azmul(x.ADBase(), AD<Base>(y)); }
// ==========================================================================
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,384 +0,0 @@
# ifndef CPPAD_CORE_BASE_COMPLEX_HPP
# define CPPAD_CORE_BASE_COMPLEX_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.
-------------------------------------------------------------------------- */
# include <cppad/configure.hpp>
# include <limits>
# include <complex>
// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
# include <cppad/utility/thread_alloc.hpp>
/*
$begin base_complex.hpp$$
$spell
azmul
expm1
atanh
acosh
asinh
endif
eps
abs_geq
Rel
Lt Le Eq Ge Gt
imag
gcc
isnan
cppad.hpp
sqrt
exp
cos
std
const
CppAD
Op
inline
enum
undef
acos
asin
atan
erf
Cond
namespace
bool
$$
$section Enable use of AD<Base> where Base is std::complex<double>$$
$children%example/general/complex_poly.cpp
%$$
$head Example$$
The file $cref complex_poly.cpp$$ contains an example use of
$code std::complex<double>$$ type for a CppAD $icode Base$$ type.
It returns true if it succeeds and false otherwise.
$head Include Order$$
This file is included before $code <cppad/cppad.hpp>$$
so it is necessary to define the error handler
in addition to including
$cref/base_require.hpp/base_require/Include Order/$$
$srccode%cpp% */
# include <limits>
# include <complex>
# include <cppad/base_require.hpp>
# include <cppad/core/cppad_assert.hpp>
/* %$$
$head CondExpOp$$
The type $code std::complex<double>$$ does not supports the
$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
$cref/not ordered/base_cond_exp/CondExpTemplate/Not Ordered/$$.
Hence its $code CondExpOp$$ function is defined by
$srccode%cpp% */
namespace CppAD {
inline std::complex<double> CondExpOp(
enum CppAD::CompareOp cop ,
const std::complex<double> &left ,
const std::complex<double> &right ,
const std::complex<double> &trueCase ,
const std::complex<double> &falseCase )
{ CppAD::ErrorHandler::Call(
true , __LINE__ , __FILE__ ,
"std::complex<float> CondExpOp(...)",
"Error: cannot use CondExp with a complex type"
);
return std::complex<double>(0);
}
}
/* %$$
$head CondExpRel$$
The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
$srccode%cpp% */
namespace CppAD {
CPPAD_COND_EXP_REL( std::complex<double> )
}
/* %$$
used $code CondExpOp$$ above to
define $codei%CondExp%Rel%$$ for $code std::complex<double>$$ arguments
and $icode%Rel%$$ equal to
$code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, and $code Gt$$.
$head EqualOpSeq$$
Complex numbers do not carry operation sequence information.
Thus they are equal in this sense if and only if there values are equal.
$srccode%cpp% */
namespace CppAD {
inline bool EqualOpSeq(
const std::complex<double> &x ,
const std::complex<double> &y )
{ return x == y;
}
}
/* %$$
$head Identical$$
Complex numbers do not carry operation sequence information.
Thus they are all parameters so the identical functions just check values.
$srccode%cpp% */
namespace CppAD {
inline bool IdenticalPar(const std::complex<double> &x)
{ return true; }
inline bool IdenticalZero(const std::complex<double> &x)
{ return (x == std::complex<double>(0., 0.) ); }
inline bool IdenticalOne(const std::complex<double> &x)
{ return (x == std::complex<double>(1., 0.) ); }
inline bool IdenticalEqualPar(
const std::complex<double> &x, const std::complex<double> &y)
{ return (x == y); }
}
/* %$$
$head Ordered$$
Complex types do not support comparison operators,
$srccode%cpp% */
# undef CPPAD_USER_MACRO
# define CPPAD_USER_MACRO(Fun) \
inline bool Fun(const std::complex<double>& x) \
{ CppAD::ErrorHandler::Call( \
true , __LINE__ , __FILE__ , \
#Fun"(x)", \
"Error: cannot use " #Fun " with x complex<double> " \
); \
return false; \
}
namespace CppAD {
CPPAD_USER_MACRO(LessThanZero)
CPPAD_USER_MACRO(LessThanOrZero)
CPPAD_USER_MACRO(GreaterThanOrZero)
CPPAD_USER_MACRO(GreaterThanZero)
inline bool abs_geq(
const std::complex<double>& x ,
const std::complex<double>& y )
{ return std::abs(x) >= std::abs(y); }
}
/* %$$
$head Integer$$
The implementation of this function must agree
with the CppAD user specifications for complex arguments to the
$cref/Integer/Integer/x/Complex Types/$$ function:
$srccode%cpp% */
namespace CppAD {
inline int Integer(const std::complex<double> &x)
{ return static_cast<int>( x.real() ); }
}
/* %$$
$head azmul$$
$srccode%cpp% */
namespace CppAD {
CPPAD_AZMUL( std::complex<double> )
}
/* %$$
$head isnan$$
The gcc 4.1.1 complier defines the function
$codei%
int std::complex<double>::isnan( std::complex<double> %z% )
%$$
(which is not specified in the C++ 1998 standard ISO/IEC 14882).
This causes an ambiguity between the function above and the CppAD
$cref/isnan/nan/$$ template function.
We avoid this ambiguity by defining a non-template version of
this function in the CppAD namespace.
$srccode%cpp% */
namespace CppAD {
inline bool isnan(const std::complex<double>& z)
{ return (z != z);
}
}
/* %$$
$head Valid Unary Math$$
The following macro invocations define the standard unary
math functions that are valid with complex arguments and are
required to use $code AD< std::complex<double> >$$.
$srccode%cpp% */
namespace CppAD {
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cos)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cosh)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, exp)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, log)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sin)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sinh)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sqrt)
}
/* %$$
$head Invalid Unary Math$$
The following macro definition and invocations define the standard unary
math functions that are invalid with complex arguments and are
required to use $code AD< std::complex<double> >$$.
$srccode%cpp% */
# undef CPPAD_USER_MACRO
# define CPPAD_USER_MACRO(Fun) \
inline std::complex<double> Fun(const std::complex<double>& x) \
{ CppAD::ErrorHandler::Call( \
true , __LINE__ , __FILE__ , \
#Fun"(x)", \
"Error: cannot use " #Fun " with x complex<double> " \
); \
return std::complex<double>(0); \
}
namespace CppAD {
CPPAD_USER_MACRO(abs)
CPPAD_USER_MACRO(fabs)
CPPAD_USER_MACRO(acos)
CPPAD_USER_MACRO(asin)
CPPAD_USER_MACRO(atan)
CPPAD_USER_MACRO(sign)
# if CPPAD_USE_CPLUSPLUS_2011
CPPAD_USER_MACRO(erf)
CPPAD_USER_MACRO(asinh)
CPPAD_USER_MACRO(acosh)
CPPAD_USER_MACRO(atanh)
CPPAD_USER_MACRO(expm1)
CPPAD_USER_MACRO(log1p)
# endif
}
/* %$$
$head pow $$
The following defines a $code CppAD::pow$$ function that
is required to use $code AD< std::complex<double> >$$:
$srccode%cpp% */
namespace CppAD {
inline std::complex<double> pow(
const std::complex<double> &x ,
const std::complex<double> &y )
{ return std::pow(x, y); }
}
/* %$$
$head numeric_limits$$
The following defines the CppAD $cref numeric_limits$$
for the type $code std::complex<double>$$:
$srccode%cpp% */
namespace CppAD {
CPPAD_NUMERIC_LIMITS(double, std::complex<double>)
}
/* %$$
$head to_string$$
The following defines the function CppAD $cref to_string$$
for the type $code std::complex<double>$$:
$srccode%cpp% */
namespace CppAD {
CPPAD_TO_STRING(std::complex<double>)
}
/* %$$
$end
*/
# undef CPPAD_USER_MACRO_ONE
# define CPPAD_USER_MACRO_ONE(Fun) \
inline bool Fun(const std::complex<float>& x) \
{ CppAD::ErrorHandler::Call( \
true , __LINE__ , __FILE__ , \
#Fun"(x)", \
"Error: cannot use " #Fun " with x complex<float> " \
); \
return false; \
}
# undef CPPAD_USER_MACRO_TWO
# define CPPAD_USER_MACRO_TWO(Fun) \
inline std::complex<float> Fun(const std::complex<float>& x) \
{ CppAD::ErrorHandler::Call( \
true , __LINE__ , __FILE__ , \
#Fun"(x)", \
"Error: cannot use " #Fun " with x complex<float> " \
); \
return std::complex<float>(0); \
}
namespace CppAD {
// CondExpOp ------------------------------------------------------
inline std::complex<float> CondExpOp(
enum CppAD::CompareOp cop ,
const std::complex<float> &left ,
const std::complex<float> &right ,
const std::complex<float> &trueCase ,
const std::complex<float> &falseCase )
{ CppAD::ErrorHandler::Call(
true , __LINE__ , __FILE__ ,
"std::complex<float> CondExpOp(...)",
"Error: cannot use CondExp with a complex type"
);
return std::complex<float>(0);
}
// CondExpRel --------------------------------------------------------
CPPAD_COND_EXP_REL( std::complex<float> )
// EqualOpSeq -----------------------------------------------------
inline bool EqualOpSeq(
const std::complex<float> &x ,
const std::complex<float> &y )
{ return x == y;
}
// Identical ------------------------------------------------------
inline bool IdenticalPar(const std::complex<float> &x)
{ return true; }
inline bool IdenticalZero(const std::complex<float> &x)
{ return (x == std::complex<float>(0., 0.) ); }
inline bool IdenticalOne(const std::complex<float> &x)
{ return (x == std::complex<float>(1., 0.) ); }
inline bool IdenticalEqualPar(
const std::complex<float> &x, const std::complex<float> &y)
{ return (x == y); }
// Ordered --------------------------------------------------------
CPPAD_USER_MACRO_ONE(LessThanZero)
CPPAD_USER_MACRO_ONE(LessThanOrZero)
CPPAD_USER_MACRO_ONE(GreaterThanOrZero)
CPPAD_USER_MACRO_ONE(GreaterThanZero)
inline bool abs_geq(
const std::complex<float>& x ,
const std::complex<float>& y )
{ return std::abs(x) >= std::abs(y); }
// Integer ------------------------------------------------------
inline int Integer(const std::complex<float> &x)
{ return static_cast<int>( x.real() ); }
// isnan -------------------------------------------------------------
inline bool isnan(const std::complex<float>& z)
{ return (z != z);
}
// Valid standard math functions --------------------------------
CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cos)
CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cosh)
CPPAD_STANDARD_MATH_UNARY(std::complex<float>, exp)
CPPAD_STANDARD_MATH_UNARY(std::complex<float>, log)
CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sin)
CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sinh)
CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sqrt)
// Invalid standrd math functions -------------------------------
CPPAD_USER_MACRO_TWO(abs)
CPPAD_USER_MACRO_TWO(acos)
CPPAD_USER_MACRO_TWO(asin)
CPPAD_USER_MACRO_TWO(atan)
CPPAD_USER_MACRO_TWO(sign)
// The pow function
inline std::complex<float> pow(
const std::complex<float> &x ,
const std::complex<float> &y )
{ return std::pow(x, y); }
// numeric_limits -------------------------------------------------
CPPAD_NUMERIC_LIMITS(float, std::complex<float>)
// to_string -------------------------------------------------
CPPAD_TO_STRING(std::complex<float>)
}
// undefine macros only used by this file
# undef CPPAD_USER_MACRO
# undef CPPAD_USER_MACRO_ONE
# undef CPPAD_USER_MACRO_TWO
# endif

View File

@ -1,281 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_BASE_COND_EXP_HPP
# define CPPAD_CORE_BASE_COND_EXP_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 base_cond_exp$$
$spell
alloc
Rel
hpp
enum
namespace
Op
Lt
Le
Eq
Ge
Gt
Ne
cond
exp
const
adolc
CppAD
inline
$$
$section Base Type Requirements for Conditional Expressions$$
$mindex CondExp require CPPAD_COND_EXP_REL$$
$head Purpose$$
These definitions are required by the user's code to support the
$codei%AD<%Base%>%$$ type for $cref CondExp$$ operations:
$head CompareOp$$
The following $code enum$$ type is used in the specifications below:
$codep
namespace CppAD {
// The conditional expression operator enum type
enum CompareOp
{ CompareLt, // less than
CompareLe, // less than or equal
CompareEq, // equal
CompareGe, // greater than or equal
CompareGt, // greater than
CompareNe // not equal
};
}
$$
$head CondExpTemplate$$
The type $icode Base$$ must support the syntax
$codei%
%result% = CppAD::CondExpOp(
%cop%, %left%, %right%, %exp_if_true%, %exp_if_false%
)
%$$
which computes implements the corresponding $cref CondExp$$
function when the result has prototype
$codei%
%Base% %result%
%$$
The argument $icode cop$$ has prototype
$codei%
enum CppAD::CompareOp %cop%
%$$
The other arguments have the prototype
$codei%
const %Base%& %left%
const %Base%& %right%
const %Base%& %exp_if_true%
const %Base%& %exp_if_false%
%$$
$subhead Ordered Type$$
If $icode Base$$ is a relatively simple type
that supports
$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators
its $code CondExpOp$$ function can be defined by
$codei%
namespace CppAD {
inline %Base% CondExpOp(
enum CppAD::CompareOp cop ,
const %Base% &left ,
const %Base% &right ,
const %Base% &exp_if_true ,
const %Base% &exp_if_false )
{ return CondExpTemplate(
cop, left, right, trueCase, falseCase);
}
}
%$$
For example, see
$cref/double CondExpOp/base_alloc.hpp/CondExpOp/$$.
For an example of and implementation of $code CondExpOp$$ with
a more involved $icode Base$$ type see
$cref/adolc CondExpOp/base_adolc.hpp/CondExpOp/$$.
$subhead Not Ordered$$
If the type $icode Base$$ does not support ordering,
the $code CondExpOp$$ function does not make sense.
In this case one might (but need not) define $code CondExpOp$$ as follows:
$codei%
namespace CppAD {
inline %Base% CondExpOp(
enum CompareOp cop ,
const %Base% &left ,
const %Base% &right ,
const %Base% &exp_if_true ,
const %Base% &exp_if_false )
{ // attempt to use CondExp with a %Base% argument
assert(0);
return %Base%(0);
}
}
%$$
For example, see
$cref/complex CondExpOp/base_complex.hpp/CondExpOp/$$.
$head CondExpRel$$
The macro invocation
$codei%
CPPAD_COND_EXP_REL(%Base%)
%$$
uses $code CondExpOp$$ above to define the following functions
$codei%
CondExpLt(%left%, %right%, %exp_if_true%, %exp_if_false%)
CondExpLe(%left%, %right%, %exp_if_true%, %exp_if_false%)
CondExpEq(%left%, %right%, %exp_if_true%, %exp_if_false%)
CondExpGe(%left%, %right%, %exp_if_true%, %exp_if_false%)
CondExpGt(%left%, %right%, %exp_if_true%, %exp_if_false%)
%$$
where the arguments have type $icode Base$$.
This should be done inside of the CppAD namespace.
For example, see
$cref/base_alloc/base_alloc.hpp/CondExpRel/$$.
$end
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file base_cond_exp.hpp
CondExp operations that aid in meeting Base type requirements.
*/
/*!
\def CPPAD_COND_EXP_BASE_REL(Type, Rel, Op)
This macro defines the operation
\verbatim
CondExpRel(left, right, exp_if_true, exp_if_false)
\endverbatim
The argument \c Type is the \c Base type for this base require operation.
The argument \c Rel is one of \c Lt, \c Le, \c Eq, \c Ge, \c Gt.
The argument \c Op is the corresponding \c CompareOp value.
*/
# define CPPAD_COND_EXP_BASE_REL(Type, Rel, Op) \
inline Type CondExp##Rel( \
const Type& left , \
const Type& right , \
const Type& exp_if_true , \
const Type& exp_if_false ) \
{ return CondExpOp(Op, left, right, exp_if_true, exp_if_false); \
}
/*!
\def CPPAD_COND_EXP_REL(Type)
The macro defines the operations
\verbatim
CondExpLt(left, right, exp_if_true, exp_if_false)
CondExpLe(left, right, exp_if_true, exp_if_false)
CondExpEq(left, right, exp_if_true, exp_if_false)
CondExpGe(left, right, exp_if_true, exp_if_false)
CondExpGt(left, right, exp_if_true, exp_if_false)
\endverbatim
The argument \c Type is the \c Base type for this base require operation.
*/
# define CPPAD_COND_EXP_REL(Type) \
CPPAD_COND_EXP_BASE_REL(Type, Lt, CompareLt) \
CPPAD_COND_EXP_BASE_REL(Type, Le, CompareLe) \
CPPAD_COND_EXP_BASE_REL(Type, Eq, CompareEq) \
CPPAD_COND_EXP_BASE_REL(Type, Ge, CompareGe) \
CPPAD_COND_EXP_BASE_REL(Type, Gt, CompareGt)
/*!
Template function to implement Conditional Expressions for simple types
that have comparision operators.
\tparam CompareType
is the type of the left and right operands to the comparision operator.
\tparam ResultType
is the type of the result, which is the same as \c CompareType except
during forward and reverse mode sparese calculations.
\param cop
specifices which comparision to use; i.e.,
$code <$$,
$code <=$$,
$code ==$$,
$code >=$$,
$code >$$, or
$code !=$$.
\param left
is the left operand to the comparision operator.
\param right
is the right operand to the comparision operator.
\param exp_if_true
is the return value is the comparision results in true.
\param exp_if_false
is the return value is the comparision results in false.
\return
see \c exp_if_true and \c exp_if_false above.
*/
template <class CompareType, class ResultType>
ResultType CondExpTemplate(
enum CompareOp cop ,
const CompareType& left ,
const CompareType& right ,
const ResultType& exp_if_true ,
const ResultType& exp_if_false )
{ ResultType returnValue;
switch( cop )
{
case CompareLt:
if( left < right )
returnValue = exp_if_true;
else returnValue = exp_if_false;
break;
case CompareLe:
if( left <= right )
returnValue = exp_if_true;
else returnValue = exp_if_false;
break;
case CompareEq:
if( left == right )
returnValue = exp_if_true;
else returnValue = exp_if_false;
break;
case CompareGe:
if( left >= right )
returnValue = exp_if_true;
else returnValue = exp_if_false;
break;
case CompareGt:
if( left > right )
returnValue = exp_if_true;
else returnValue = exp_if_false;
break;
default:
CPPAD_ASSERT_UNKNOWN(0);
returnValue = exp_if_true;
}
return returnValue;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,229 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_BASE_DOUBLE_HPP
# define CPPAD_CORE_BASE_DOUBLE_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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.
-------------------------------------------------------------------------- */
# include <cppad/configure.hpp>
# include <limits>
/*
$begin base_double.hpp$$
$spell
namespaces
cppad
hpp
azmul
expm1
atanh
acosh
asinh
erf
endif
abs_geq
acos
asin
atan
cos
sqrt
tanh
std
fabs
bool
Lt Le Eq Ge Gt
Rel
CppAD
CondExpOp
namespace
inline
enum
const
exp
const
$$
$section Enable use of AD<Base> where Base is double$$
$head CondExpOp$$
The type $code double$$ is a relatively simple type that supports
$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
$cref/ordered type/base_cond_exp/CondExpTemplate/Ordered Type/$$.
Hence its $code CondExpOp$$ function is defined by
$srccode%cpp% */
namespace CppAD {
inline double CondExpOp(
enum CompareOp cop ,
const double& left ,
const double& right ,
const double& exp_if_true ,
const double& exp_if_false )
{ return CondExpTemplate(cop, left, right, exp_if_true, exp_if_false);
}
}
/* %$$
$head CondExpRel$$
The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
$srccode%cpp% */
namespace CppAD {
CPPAD_COND_EXP_REL(double)
}
/* %$$
uses $code CondExpOp$$ above to
define $codei%CondExp%Rel%$$ for $code double$$ arguments
and $icode%Rel%$$ equal to
$code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, and $code Gt$$.
$head EqualOpSeq$$
The type $code double$$ is simple (in this respect) and so we define
$srccode%cpp% */
namespace CppAD {
inline bool EqualOpSeq(const double& x, const double& y)
{ return x == y; }
}
/* %$$
$head Identical$$
The type $code double$$ is simple (in this respect) and so we define
$srccode%cpp% */
namespace CppAD {
inline bool IdenticalPar(const double& x)
{ return true; }
inline bool IdenticalZero(const double& x)
{ return (x == 0.); }
inline bool IdenticalOne(const double& x)
{ return (x == 1.); }
inline bool IdenticalEqualPar(const double& x, const double& y)
{ return (x == y); }
}
/* %$$
$head Integer$$
$srccode%cpp% */
namespace CppAD {
inline int Integer(const double& x)
{ return static_cast<int>(x); }
}
/* %$$
$head azmul$$
$srccode%cpp% */
namespace CppAD {
CPPAD_AZMUL( double )
}
/* %$$
$head Ordered$$
The $code double$$ type supports ordered comparisons
$srccode%cpp% */
namespace CppAD {
inline bool GreaterThanZero(const double& x)
{ return x > 0.; }
inline bool GreaterThanOrZero(const double& x)
{ return x >= 0.; }
inline bool LessThanZero(const double& x)
{ return x < 0.; }
inline bool LessThanOrZero(const double& x)
{ return x <= 0.; }
inline bool abs_geq(const double& x, const double& y)
{ return std::fabs(x) >= std::fabs(y); }
}
/* %$$
$head Unary Standard Math$$
The following macro invocations import the $code double$$ versions of
the unary standard math functions into the $code CppAD$$ namespace.
Importing avoids ambiguity errors when using both the
$code CppAD$$ and $code std$$ namespaces.
Note this also defines the $cref/float/base_float.hpp/Unary Standard Math/$$
versions of these functions.
$srccode%cpp% */
namespace CppAD {
using std::acos;
using std::asin;
using std::atan;
using std::cos;
using std::cosh;
using std::exp;
using std::fabs;
using std::log;
using std::log10;
using std::sin;
using std::sinh;
using std::sqrt;
using std::tan;
using std::tanh;
# if CPPAD_USE_CPLUSPLUS_2011
using std::erf;
using std::asinh;
using std::acosh;
using std::atanh;
using std::expm1;
using std::log1p;
# endif
}
/* %$$
The absolute value function is special because its $code std$$ name is
$code fabs$$
$srccode%cpp% */
namespace CppAD {
inline double abs(const double& x)
{ return std::fabs(x); }
}
/* %$$
$head sign$$
The following defines the $code CppAD::sign$$ function that
is required to use $code AD<double>$$:
$srccode%cpp% */
namespace CppAD {
inline double sign(const double& x)
{ if( x > 0. )
return 1.;
if( x == 0. )
return 0.;
return -1.;
}
}
/* %$$
$head pow$$
The following defines a $code CppAD::pow$$ function that
is required to use $code AD<double>$$.
As with the unary standard math functions,
this has the exact same signature as $code std::pow$$,
so use it instead of defining another function.
$srccode%cpp% */
namespace CppAD {
using std::pow;
}
/* %$$
$head numeric_limits$$
The following defines the CppAD $cref numeric_limits$$
for the type $code double$$:
$srccode%cpp% */
namespace CppAD {
CPPAD_NUMERIC_LIMITS(double, double)
}
/* %$$
$head to_string$$
There is no need to define $code to_string$$ for $code double$$
because it is defined by including $code cppad/utility/to_string.hpp$$;
see $cref to_string$$.
See $cref/base_complex.hpp/base_complex.hpp/to_string/$$ for an example where
it is necessary to define $code to_string$$ for a $icode Base$$ type.
$end
*/
# endif

View File

@ -1,230 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_BASE_FLOAT_HPP
# define CPPAD_CORE_BASE_FLOAT_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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.
-------------------------------------------------------------------------- */
# include <cppad/configure.hpp>
# include <limits>
/*
$begin base_float.hpp$$
$spell
namespaces
cppad
hpp
azmul
expm1
atanh
acosh
asinh
erf
endif
abs_geq
acos
asin
atan
cos
sqrt
tanh
std
fabs
bool
Lt Le Eq Ge Gt
Rel
CppAD
CondExpOp
namespace
inline
enum
const
exp
const
$$
$section Enable use of AD<Base> where Base is float$$
$head CondExpOp$$
The type $code float$$ is a relatively simple type that supports
$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
$cref/ordered type/base_cond_exp/CondExpTemplate/Ordered Type/$$.
Hence its $code CondExpOp$$ function is defined by
$srccode%cpp% */
namespace CppAD {
inline float CondExpOp(
enum CompareOp cop ,
const float& left ,
const float& right ,
const float& exp_if_true ,
const float& exp_if_false )
{ return CondExpTemplate(cop, left, right, exp_if_true, exp_if_false);
}
}
/* %$$
$head CondExpRel$$
The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
$srccode%cpp% */
namespace CppAD {
CPPAD_COND_EXP_REL(float)
}
/* %$$
uses $code CondExpOp$$ above to
define $codei%CondExp%Rel%$$ for $code float$$ arguments
and $icode%Rel%$$ equal to
$code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, and $code Gt$$.
$head EqualOpSeq$$
The type $code float$$ is simple (in this respect) and so we define
$srccode%cpp% */
namespace CppAD {
inline bool EqualOpSeq(const float& x, const float& y)
{ return x == y; }
}
/* %$$
$head Identical$$
The type $code float$$ is simple (in this respect) and so we define
$srccode%cpp% */
namespace CppAD {
inline bool IdenticalPar(const float& x)
{ return true; }
inline bool IdenticalZero(const float& x)
{ return (x == 0.f); }
inline bool IdenticalOne(const float& x)
{ return (x == 1.f); }
inline bool IdenticalEqualPar(const float& x, const float& y)
{ return (x == y); }
}
/* %$$
$head Integer$$
$srccode%cpp% */
namespace CppAD {
inline int Integer(const float& x)
{ return static_cast<int>(x); }
}
/* %$$
$head azmul$$
$srccode%cpp% */
namespace CppAD {
CPPAD_AZMUL( float )
}
/* %$$
$head Ordered$$
The $code float$$ type supports ordered comparisons
$srccode%cpp% */
namespace CppAD {
inline bool GreaterThanZero(const float& x)
{ return x > 0.f; }
inline bool GreaterThanOrZero(const float& x)
{ return x >= 0.f; }
inline bool LessThanZero(const float& x)
{ return x < 0.f; }
inline bool LessThanOrZero(const float& x)
{ return x <= 0.f; }
inline bool abs_geq(const float& x, const float& y)
{ return std::fabs(x) >= std::fabs(y); }
}
/* %$$
$head Unary Standard Math$$
The following macro invocations import the $code float$$ versions of
the unary standard math functions into the $code CppAD$$ namespace.
Importing avoids ambiguity errors when using both the
$code CppAD$$ and $code std$$ namespaces.
Note this also defines the $cref/double/base_double.hpp/Unary Standard Math/$$
versions of these functions.
$srccode%cpp% */
namespace CppAD {
using std::acos;
using std::asin;
using std::atan;
using std::cos;
using std::cosh;
using std::exp;
using std::fabs;
using std::log;
using std::log10;
using std::sin;
using std::sinh;
using std::sqrt;
using std::tan;
using std::tanh;
# if CPPAD_USE_CPLUSPLUS_2011
using std::erf;
using std::asinh;
using std::acosh;
using std::atanh;
using std::expm1;
using std::log1p;
# endif
}
/* %$$
The absolute value function is special because its $code std$$ name is
$code fabs$$
$srccode%cpp% */
namespace CppAD {
inline float abs(const float& x)
{ return std::fabs(x); }
}
/* %$$
$head sign$$
The following defines the $code CppAD::sign$$ function that
is required to use $code AD<float>$$:
$srccode%cpp% */
namespace CppAD {
inline float sign(const float& x)
{ if( x > 0.f )
return 1.f;
if( x == 0.f )
return 0.f;
return -1.f;
}
}
/* %$$
$head pow$$
The following defines a $code CppAD::pow$$ function that
is required to use $code AD<float>$$.
As with the unary standard math functions,
this has the exact same signature as $code std::pow$$,
so use it instead of defining another function.
$srccode%cpp% */
namespace CppAD {
using std::pow;
}
/* %$$
$head numeric_limits$$
The following defines the CppAD $cref numeric_limits$$
for the type $code float$$:
$srccode%cpp% */
namespace CppAD {
CPPAD_NUMERIC_LIMITS(float, float)
}
/* %$$
$head to_string$$
There is no need to define $code to_string$$ for $code float$$
because it is defined by including $code cppad/utility/to_string.hpp$$;
see $cref to_string$$.
See $cref/base_complex.hpp/base_complex.hpp/to_string/$$ for an example where
it is necessary to define $code to_string$$ for a $icode Base$$ type.
$end
*/
# endif

View File

@ -1,84 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_BASE_HASH_HPP
# define CPPAD_CORE_BASE_HASH_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 base_hash$$
$spell
alloc
Cpp
adouble
valgrind
const
inline
$$
$section Base Type Requirements for Hash Coding Values$$
$head Syntax$$
$icode%code% = hash_code(%x%)%$$
$head Purpose$$
CppAD uses a table of $icode Base$$ type values when recording
$codei%AD<%Base%>%$$ operations.
A hashing function is used to reduce number of values stored in this table;
for example, it is not necessary to store the value 3.0 every
time it is used as a $cref/parameter/parvar/$$.
$head Default$$
The default hashing function works with the set of bits that correspond
to a $icode Base$$ value.
In most cases this works well, but in some cases
it does not. For example, in the
$cref base_adolc.hpp$$ case, an $code adouble$$ value can have
fields that are not initialized and $code valgrind$$ reported an error
when these are used to form the hash code.
$head x$$
This argument has prototype
$codei%
const %Base%& %x
%$$
It is the value we are forming a hash code for.
$head code$$
The return value $icode code$$ has prototype
$codei%
unsigned short %code%
%$$
It is the hash code corresponding to $icode x$$. This intention is the
commonly used values will have different hash codes.
The hash code must satisfy
$codei%
%code% < CPPAD_HASH_TABLE_SIZE
%$$
so that it is a valid index into the hash code table.
$head inline$$
If you define this function, it should declare it to be $code inline$$,
so that you do not get multiple definitions from different compilation units.
$head Example$$
See the $code base_alloc$$ $cref/hash_code/base_alloc.hpp/hash_code/$$
and the $code adouble$$ $cref/hash_code/base_adolc.hpp/hash_code/$$.
$end
*/
/*!
\def CPPAD_HASH_TABLE_SIZE
the codes retruned by hash_code are between zero and CPPAD_HASH_TABLE_SIZE
minus one.
*/
# define CPPAD_HASH_TABLE_SIZE 10000
# endif

View File

@ -1,67 +0,0 @@
# ifndef CPPAD_CORE_BASE_LIMITS_HPP
# define CPPAD_CORE_BASE_LIMITS_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 base_limits$$
$spell
std
namespace
CppAD
$$
$section Base Type Requirements for Numeric Limits$$
$head CppAD::numeric_limits$$
A specialization for
$cref/CppAD::numeric_limits/numeric_limits/$$
must be defined in order to use the type $codei%AD<%Base%>%$$.
CppAD does not use a specialization of
$codei%std::numeric_limits<%Base%>%$$.
Since C++11, using a specialization of
$codei%std::numeric_limits<%Base%>%$$
would require that $icode Base$$ be a literal type.
$head CPPAD_NUMERIC_LIMITS$$
In most cases, this macro can be used to define the specialization where
the numeric limits for the type $icode Base$$
are the same as the standard numeric limits for the type $icode Other$$.
For most $icode Base$$ types,
there is a choice of $icode Other$$,
for which the following preprocessor macro invocation suffices:
$codei%
namespace CppAD {
CPPAD_NUMERIC_LIMITS(%Other%, %Base%)
}
%$$
where the macro is defined by
$srccode%cpp% */
# define CPPAD_NUMERIC_LIMITS(Other, Base) \
template <> class numeric_limits<Base>\
{\
public:\
static Base min(void) \
{ return static_cast<Base>( std::numeric_limits<Other>::min() ); }\
static Base max(void) \
{ return static_cast<Base>( std::numeric_limits<Other>::max() ); }\
static Base epsilon(void) \
{ return static_cast<Base>( std::numeric_limits<Other>::epsilon() ); }\
static Base quiet_NaN(void) \
{ return static_cast<Base>( std::numeric_limits<Other>::quiet_NaN() ); }\
static const int digits10 = std::numeric_limits<Other>::digits10;\
};
/* %$$
$end
*/
# endif

View File

@ -1,186 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_BASE_STD_MATH_HPP
# define CPPAD_CORE_BASE_STD_MATH_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 base_std_math$$
$spell
expm1
atanh
acosh
asinh
inline
fabs
isnan
alloc
std
acos
asin
atan
cos
exp
sqrt
const
CppAD
namespace
erf
$$
$section Base Type Requirements for Standard Math Functions$$
$head Purpose$$
These definitions are required for the user's code to use the type
$codei%AD<%Base%>%$$:
$head Unary Standard Math$$
The type $icode Base$$ must support the following functions
unary standard math functions (in the CppAD namespace):
$table
$bold Syntax$$ $cnext $bold Result$$
$rnext
$icode%y% = abs(%x%)%$$ $cnext absolute value $rnext
$icode%y% = acos(%x%)%$$ $cnext inverse cosine $rnext
$icode%y% = asin(%x%)%$$ $cnext inverse sine $rnext
$icode%y% = atan(%x%)%$$ $cnext inverse tangent $rnext
$icode%y% = cos(%x%)%$$ $cnext cosine $rnext
$icode%y% = cosh(%x%)%$$ $cnext hyperbolic cosine $rnext
$icode%y% = exp(%x%)%$$ $cnext exponential $rnext
$icode%y% = fabs(%x%)%$$ $cnext absolute value $rnext
$icode%y% = log(%x%)%$$ $cnext natural logarithm $rnext
$icode%y% = sin(%x%)%$$ $cnext sine $rnext
$icode%y% = sinh(%x%)%$$ $cnext hyperbolic sine $rnext
$icode%y% = sqrt(%x%)%$$ $cnext square root $rnext
$icode%y% = tan(%x%)%$$ $cnext tangent
$tend
where the arguments and return value have the prototypes
$codei%
const %Base%& %x%
%Base% %y%
%$$
For example,
$cref/base_alloc/base_alloc.hpp/Unary Standard Math/$$,
$head CPPAD_STANDARD_MATH_UNARY$$
The macro invocation, within the CppAD namespace,
$codei%
CPPAD_STANDARD_MATH_UNARY(%Base%, %Fun%)
%$$
defines the syntax
$codei%
%y% = CppAD::%Fun%(%x%)
%$$
This macro uses the functions $codei%std::%Fun%$$ which
must be defined and have the same prototype as $codei%CppAD::%Fun%$$.
For example,
$cref/float/base_float.hpp/Unary Standard Math/$$.
$head erf, asinh, acosh, atanh, expm1, log1p$$
If this preprocessor symbol
$code CPPAD_USE_CPLUSPLUS_2011$$ is true ($code 1$$),
when compiling for c++11, the type
$code double$$ is supported for the functions listed below.
In this case, the type $icode Base$$ must also support these functions:
$table
$bold Syntax$$ $cnext $bold Result$$
$rnext
$icode%y% = erf(%x%)%$$ $cnext error function $rnext
$icode%y% = asinh(%x%)%$$ $cnext inverse hyperbolic sin $rnext
$icode%y% = acosh(%x%)%$$ $cnext inverse hyperbolic cosine $rnext
$icode%y% = atanh(%x%)%$$ $cnext inverse hyperbolic tangent $rnext
$icode%y% = expm1(%x%)%$$ $cnext exponential of x minus one $rnext
$icode%y% = log1p(%x%)%$$ $cnext logarithm of one plus x
$tend
where the arguments and return value have the prototypes
$codei%
const %Base%& %x%
%Base% %y%
%$$
$head sign$$
The type $icode Base$$ must support the syntax
$codei%
%y% = CppAD::sign(%x%)
%$$
which computes
$latex \[
y = \left\{ \begin{array}{ll}
+1 & {\rm if} \; x > 0 \\
0 & {\rm if} \; x = 0 \\
-1 & {\rm if} \; x < 0
\end{array} \right.
\] $$
where $icode x$$ and $icode y$$ have the same prototype as above.
For example, see
$cref/base_alloc/base_alloc.hpp/sign/$$.
Note that, if ordered comparisons are not defined for the type $icode Base$$,
the $code code sign$$ function should generate an assert if it is used; see
$cref/complex invalid unary math/base_complex.hpp/Invalid Unary Math/$$.
$head pow$$
The type $icode Base$$ must support the syntax
$codei%
%z% = CppAD::pow(%x%, %y%)
%$$
which computes $latex z = x^y$$.
The arguments $icode x$$ and $icode y$$ have prototypes
$codei%
const %Base%& %x%
const %Base%& %y%
%$$
and the return value $icode z$$ has prototype
$codei%
%Base% %z%
%$$
For example, see
$cref/base_alloc/base_alloc.hpp/pow/$$.
$head isnan$$
If $icode Base$$ defines the $code isnan$$ function,
you may also have to provide a definition in the CppAD namespace
(to avoid a function ambiguity).
For example, see
$cref/base_complex/base_complex.hpp/isnan/$$.
$end
-------------------------------------------------------------------------------
*/
# include <cmath>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file base_std_math.hpp
Defintions that aid meeting Base type requirements for standard math functions.
*/
/*!
\def CPPAD_STANDARD_MATH_UNARY(Type, Fun)
This macro defines the function
\verbatim
y = CppAD:Fun(x)
\endverbatim
where the argument \c x and return value \c y have type \c Type
using the corresponding function <code>std::Fun</code>.
*/
# define CPPAD_STANDARD_MATH_UNARY(Type, Fun) \
inline Type Fun(const Type& x) \
{ return std::Fun(x); }
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,65 +0,0 @@
# ifndef CPPAD_CORE_BASE_TO_STRING_HPP
# define CPPAD_CORE_BASE_TO_STRING_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 base_to_string$$
$spell
std
namespace
CppAD
struct
const
stringstream
setprecision
str
$$
$section Extending to_string To Another Floating Point Type$$
$head Base Requirement$$
If the function $cref to_string$$ is used by an
$cref/AD type above Base/glossary/AD Type Above Base/$$,
A specialization for the template structure
$code CppAD::to_string_struct$$ must be defined.
$head CPPAD_TO_STRING$$
For most $icode Base$$ types,
the following can be used to define the specialization:
$codei%
namespace CppAD {
CPPAD_TO_STRING(%Base%)
}
%$$
Note that the $code CPPAD_TO_STRING$$ macro assumes that the
$cref base_limits$$ and $cref base_std_math$$ have already been defined
for this type.
This macro is defined as follows:
$srccode%cpp% */
# define CPPAD_TO_STRING(Base) \
template <> struct to_string_struct<Base>\
{ std::string operator()(const Base& value) \
{ std::stringstream os;\
int n_digits = 1 + CppAD::numeric_limits<Base>::digits10; \
os << std::setprecision(n_digits);\
os << value;\
return os.str();\
}\
};
/* %$$
$end
------------------------------------------------------------------------------
*/
// make sure to_string has been included
# include <cppad/utility/to_string.hpp>
# endif

View File

@ -1,404 +0,0 @@
# ifndef CPPAD_CORE_BENDER_QUAD_HPP
# define CPPAD_CORE_BENDER_QUAD_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 BenderQuad$$
$spell
cppad.hpp
BAvector
gx
gxx
CppAD
Fy
dy
Jacobian
ADvector
const
dg
ddg
$$
$section Computing Jacobian and Hessian of Bender's Reduced Objective$$
$mindex BenderQuad$$
$head Syntax$$
$codei%
# include <cppad/cppad.hpp>
BenderQuad(%x%, %y%, %fun%, %g%, %gx%, %gxx%)%$$
$head See Also$$
$cref opt_val_hes$$
$head Problem$$
The type $cref/ADvector/BenderQuad/ADvector/$$ cannot be determined
form the arguments above
(currently the type $icode ADvector$$ must be
$codei%CPPAD_TESTVECTOR(%Base%)%$$.)
This will be corrected in the future by requiring $icode Fun$$
to define $icode%Fun%::vector_type%$$ which will specify the
type $icode ADvector$$.
$head Purpose$$
We are given the optimization problem
$latex \[
\begin{array}{rcl}
{\rm minimize} & F(x, y) & {\rm w.r.t.} \; (x, y) \in \B{R}^n \times \B{R}^m
\end{array}
\] $$
that is convex with respect to $latex y$$.
In addition, we are given a set of equations $latex H(x, y)$$
such that
$latex \[
H[ x , Y(x) ] = 0 \;\; \Rightarrow \;\; F_y [ x , Y(x) ] = 0
\] $$
(In fact, it is often the case that $latex H(x, y) = F_y (x, y)$$.)
Furthermore, it is easy to calculate a Newton step for these equations; i.e.,
$latex \[
dy = - [ \partial_y H(x, y)]^{-1} H(x, y)
\] $$
The purpose of this routine is to compute the
value, Jacobian, and Hessian of the reduced objective function
$latex \[
G(x) = F[ x , Y(x) ]
\] $$
Note that if only the value and Jacobian are needed, they can be
computed more quickly using the relations
$latex \[
G^{(1)} (x) = \partial_x F [x, Y(x) ]
\] $$
$head x$$
The $code BenderQuad$$ argument $icode x$$ has prototype
$codei%
const %BAvector% &%x%
%$$
(see $cref/BAvector/BenderQuad/BAvector/$$ below)
and its size must be equal to $icode n$$.
It specifies the point at which we evaluating
the reduced objective function and its derivatives.
$head y$$
The $code BenderQuad$$ argument $icode y$$ has prototype
$codei%
const %BAvector% &%y%
%$$
and its size must be equal to $icode m$$.
It must be equal to $latex Y(x)$$; i.e.,
it must solve the problem in $latex y$$ for this given value of $latex x$$
$latex \[
\begin{array}{rcl}
{\rm minimize} & F(x, y) & {\rm w.r.t.} \; y \in \B{R}^m
\end{array}
\] $$
$head fun$$
The $code BenderQuad$$ object $icode fun$$
must support the member functions listed below.
The $codei%AD<%Base%>%$$ arguments will be variables for
a tape created by a call to $cref Independent$$ from $code BenderQuad$$
(hence they can not be combined with variables corresponding to a
different tape).
$subhead fun.f$$
The $code BenderQuad$$ argument $icode fun$$ supports the syntax
$codei%
%f% = %fun%.f(%x%, %y%)
%$$
The $icode%fun%.f%$$ argument $icode x$$ has prototype
$codei%
const %ADvector% &%x%
%$$
(see $cref/ADvector/BenderQuad/ADvector/$$ below)
and its size must be equal to $icode n$$.
The $icode%fun%.f%$$ argument $icode y$$ has prototype
$codei%
const %ADvector% &%y%
%$$
and its size must be equal to $icode m$$.
The $icode%fun%.f%$$ result $icode f$$ has prototype
$codei%
%ADvector% %f%
%$$
and its size must be equal to one.
The value of $icode f$$ is
$latex \[
f = F(x, y)
\] $$.
$subhead fun.h$$
The $code BenderQuad$$ argument $icode fun$$ supports the syntax
$codei%
%h% = %fun%.h(%x%, %y%)
%$$
The $icode%fun%.h%$$ argument $icode x$$ has prototype
$codei%
const %ADvector% &%x%
%$$
and its size must be equal to $icode n$$.
The $icode%fun%.h%$$ argument $icode y$$ has prototype
$codei%
const %BAvector% &%y%
%$$
and its size must be equal to $icode m$$.
The $icode%fun%.h%$$ result $icode h$$ has prototype
$codei%
%ADvector% %h%
%$$
and its size must be equal to $icode m$$.
The value of $icode h$$ is
$latex \[
h = H(x, y)
\] $$.
$subhead fun.dy$$
The $code BenderQuad$$ argument $icode fun$$ supports the syntax
$codei%
%dy% = %fun%.dy(%x%, %y%, %h%)
%x%
%$$
The $icode%fun%.dy%$$ argument $icode x$$ has prototype
$codei%
const %BAvector% &%x%
%$$
and its size must be equal to $icode n$$.
Its value will be exactly equal to the $code BenderQuad$$ argument
$icode x$$ and values depending on it can be stored as private objects
in $icode f$$ and need not be recalculated.
$codei%
%y%
%$$
The $icode%fun%.dy%$$ argument $icode y$$ has prototype
$codei%
const %BAvector% &%y%
%$$
and its size must be equal to $icode m$$.
Its value will be exactly equal to the $code BenderQuad$$ argument
$icode y$$ and values depending on it can be stored as private objects
in $icode f$$ and need not be recalculated.
$codei%
%h%
%$$
The $icode%fun%.dy%$$ argument $icode h$$ has prototype
$codei%
const %ADvector% &%h%
%$$
and its size must be equal to $icode m$$.
$codei%
%dy%
%$$
The $icode%fun%.dy%$$ result $icode dy$$ has prototype
$codei%
%ADvector% %dy%
%$$
and its size must be equal to $icode m$$.
The return value $icode dy$$ is given by
$latex \[
dy = - [ \partial_y H (x , y) ]^{-1} h
\] $$
Note that if $icode h$$ is equal to $latex H(x, y)$$,
$latex dy$$ is the Newton step for finding a zero
of $latex H(x, y)$$ with respect to $latex y$$;
i.e.,
$latex y + dy$$ is an approximate solution for the equation
$latex H (x, y + dy) = 0$$.
$head g$$
The argument $icode g$$ has prototype
$codei%
%BAvector% &%g%
%$$
and has size one.
The input value of its element does not matter.
On output,
it contains the value of $latex G (x)$$; i.e.,
$latex \[
g[0] = G (x)
\] $$
$head gx$$
The argument $icode gx$$ has prototype
$codei%
%BAvector% &%gx%
%$$
and has size $latex n $$.
The input values of its elements do not matter.
On output,
it contains the Jacobian of $latex G (x)$$; i.e.,
for $latex j = 0 , \ldots , n-1$$,
$latex \[
gx[ j ] = G^{(1)} (x)_j
\] $$
$head gxx$$
The argument $icode gx$$ has prototype
$codei%
%BAvector% &%gxx%
%$$
and has size $latex n \times n$$.
The input values of its elements do not matter.
On output,
it contains the Hessian of $latex G (x)$$; i.e.,
for $latex i = 0 , \ldots , n-1$$, and
$latex j = 0 , \ldots , n-1$$,
$latex \[
gxx[ i * n + j ] = G^{(2)} (x)_{i,j}
\] $$
$head BAvector$$
The type $icode BAvector$$ must be a
$cref SimpleVector$$ class.
We use $icode Base$$ to refer to the type of the elements of
$icode BAvector$$; i.e.,
$codei%
%BAvector%::value_type
%$$
$head ADvector$$
The type $icode ADvector$$ must be a
$cref SimpleVector$$ class with elements of type
$codei%AD<%Base%>%$$; i.e.,
$codei%
%ADvector%::value_type
%$$
must be the same type as
$codei%
AD< %BAvector%::value_type >
%$$.
$head Example$$
$children%
example/general/bender_quad.cpp
%$$
The file
$cref bender_quad.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN CppAD namespace
template <class BAvector, class Fun>
void BenderQuad(
const BAvector &x ,
const BAvector &y ,
Fun fun ,
BAvector &g ,
BAvector &gx ,
BAvector &gxx )
{ // determine the base type
typedef typename BAvector::value_type Base;
// check that BAvector is a SimpleVector class
CheckSimpleVector<Base, BAvector>();
// declare the ADvector type
typedef CPPAD_TESTVECTOR(AD<Base>) ADvector;
// size of the x and y spaces
size_t n = size_t(x.size());
size_t m = size_t(y.size());
// check the size of gx and gxx
CPPAD_ASSERT_KNOWN(
g.size() == 1,
"BenderQuad: size of the vector g is not equal to 1"
);
CPPAD_ASSERT_KNOWN(
size_t(gx.size()) == n,
"BenderQuad: size of the vector gx is not equal to n"
);
CPPAD_ASSERT_KNOWN(
size_t(gxx.size()) == n * n,
"BenderQuad: size of the vector gxx is not equal to n * n"
);
// some temporary indices
size_t i, j;
// variable versions x
ADvector vx(n);
for(j = 0; j < n; j++)
vx[j] = x[j];
// declare the independent variables
Independent(vx);
// evaluate h = H(x, y)
ADvector h(m);
h = fun.h(vx, y);
// evaluate dy (x) = Newton step as a function of x through h only
ADvector dy(m);
dy = fun.dy(x, y, h);
// variable version of y
ADvector vy(m);
for(j = 0; j < m; j++)
vy[j] = y[j] + dy[j];
// evaluate G~ (x) = F [ x , y + dy(x) ]
ADvector gtilde(1);
gtilde = fun.f(vx, vy);
// AD function object that corresponds to G~ (x)
// We will make heavy use of this tape, so optimize it
ADFun<Base> Gtilde;
Gtilde.Dependent(vx, gtilde);
Gtilde.optimize();
// value of G(x)
g = Gtilde.Forward(0, x);
// initial forward direction vector as zero
BAvector dx(n);
for(j = 0; j < n; j++)
dx[j] = Base(0.0);
// weight, first and second order derivative values
BAvector dg(1), w(1), ddw(2 * n);
w[0] = 1.;
// Jacobian and Hessian of G(x) is equal Jacobian and Hessian of Gtilde
for(j = 0; j < n; j++)
{ // compute partials in x[j] direction
dx[j] = Base(1.0);
dg = Gtilde.Forward(1, dx);
gx[j] = dg[0];
// restore the dx vector to zero
dx[j] = Base(0.0);
// compute second partials w.r.t x[j] and x[l] for l = 1, n
ddw = Gtilde.Reverse(2, w);
for(i = 0; i < n; i++)
gxx[ i * n + j ] = ddw[ i * 2 + 1 ];
}
return;
}
} // END CppAD namespace
# endif

View File

@ -1,243 +0,0 @@
# ifndef CPPAD_CORE_BOOL_FUN_HPP
# define CPPAD_CORE_BOOL_FUN_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 BoolFun$$
$spell
namespace
bool
CppAD
const
$$
$section AD Boolean Functions$$
$mindex bool CPPAD_BOOL_UNARY CPPAD_BOOL_BINARY$$
$head Syntax$$
$codei%CPPAD_BOOL_UNARY(%Base%, %unary_name%)
%$$
$icode%b% = %unary_name%(%u%)
%$$
$icode%b% = %unary_name%(%x%)
%$$
$codei%CPPAD_BOOL_BINARY(%Base%, %binary_name%)
%$$
$icode%b% = %binary_name%(%u%, %v%)
%$$
$icode%b% = %binary_name%(%x%, %y%)%$$
$head Purpose$$
Create a $code bool$$ valued function that has $codei%AD<%Base%>%$$ arguments.
$head unary_name$$
This is the name of the $code bool$$ valued function with one argument
(as it is used in the source code).
The user must provide a version of $icode unary_name$$ where
the argument has type $icode Base$$.
CppAD uses this to create a version of $icode unary_name$$ where the
argument has type $codei%AD<%Base%>%$$.
$head u$$
The argument $icode u$$ has prototype
$codei%
const %Base% &%u%
%$$
It is the value at which the user provided version of $icode unary_name$$
is to be evaluated.
It is also used for the first argument to the
user provided version of $icode binary_name$$.
$head x$$
The argument $icode x$$ has prototype
$codei%
const AD<%Base%> &%x%
%$$
It is the value at which the CppAD provided version of $icode unary_name$$
is to be evaluated.
It is also used for the first argument to the
CppAD provided version of $icode binary_name$$.
$head b$$
The result $icode b$$ has prototype
$codei%
bool %b%
%$$
$head Create Unary$$
The preprocessor macro invocation
$codei%
CPPAD_BOOL_UNARY(%Base%, %unary_name%)
%$$
defines the version of $icode unary_name$$ with a $codei%AD<%Base%>%$$
argument.
This can with in a namespace
(not the $code CppAD$$ namespace)
but must be outside of any routine.
$head binary_name$$
This is the name of the $code bool$$ valued function with two arguments
(as it is used in the source code).
The user must provide a version of $icode binary_name$$ where
the arguments have type $icode Base$$.
CppAD uses this to create a version of $icode binary_name$$ where the
arguments have type $codei%AD<%Base%>%$$.
$head v$$
The argument $icode v$$ has prototype
$codei%
const %Base% &%v%
%$$
It is the second argument to
the user provided version of $icode binary_name$$.
$head y$$
The argument $icode x$$ has prototype
$codei%
const AD<%Base%> &%y%
%$$
It is the second argument to
the CppAD provided version of $icode binary_name$$.
$head Create Binary$$
The preprocessor macro invocation
$codei%
CPPAD_BOOL_BINARY(%Base%, %binary_name%)
%$$
defines the version of $icode binary_name$$ with $codei%AD<%Base%>%$$
arguments.
This can with in a namespace
(not the $code CppAD$$ namespace)
but must be outside of any routine.
$head Operation Sequence$$
The result of this operation is not an
$cref/AD of Base/glossary/AD of Base/$$ object.
Thus it will not be recorded as part of an
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$children%
example/general/bool_fun.cpp
%$$
The file
$cref bool_fun.cpp$$
contains an example and test of these operations.
It returns true if it succeeds and false otherwise.
$head Deprecated 2007-07-31$$
The preprocessor symbols $code CppADCreateUnaryBool$$
and $code CppADCreateBinaryBool$$ are defined to be the same as
$code CPPAD_BOOL_UNARY$$ and $code CPPAD_BOOL_BINARY$$ respectively
(but their use is deprecated).
$end
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file bool_fun.hpp
Routines and macros that implement functions from AD<Base> to bool.
*/
/*!
Macro that defines a unary function <tt>bool F(AD<Base> x)</tt>
using <tt>bool F(Base x)</tt>.
\param Base
base for the AD type of arguments to this unary bool valued function.
\param unary_name
name of this unary function; i.e., \c F.
*/
# define CPPAD_BOOL_UNARY(Base, unary_name) \
inline bool unary_name (const CppAD::AD<Base> &x) \
{ \
return CppAD::AD<Base>::UnaryBool(unary_name, x); \
}
/*!
Deprecated name for CPPAD_BOOL_UNARY
*/
# define CppADCreateUnaryBool CPPAD_BOOL_UNARY
/*!
Link a function name, and AD value pair to function call with base argument
and bool retrun value.
\param FunName
is the name of the function that we are linking.
\param x
is the argument where we are evaluating the function.
*/
template <class Base>
inline bool AD<Base>::UnaryBool(
bool FunName(const Base &x),
const AD<Base> &x
)
{
return FunName(x.value_);
}
/*!
Macro that defines a binary function <tt>bool F(AD<Base> x, AD<Base> y)</tt>
using <tt>bool F(Base x, Base y)</tt>.
\param Base
base for the AD type of arguments to this binary bool valued function.
\param binary_name
name of this binary function; i.e., \c F.
*/
# define CPPAD_BOOL_BINARY(Base, binary_name) \
inline bool binary_name ( \
const CppAD::AD<Base> &x, const CppAD::AD<Base> &y) \
{ \
return CppAD::AD<Base>::BinaryBool(binary_name, x, y); \
}
/*!
Deprecated name for CPPAD_BOOL_BINARY
*/
# define CppADCreateBinaryBool CPPAD_BOOL_BINARY
/*!
Link a function name, and two AD values to function call with base arguments
and bool retrun value.
\param FunName
is the name of the function that we are linking.
\param x
is the first argument where we are evaluating the function at.
\param y
is the second argument where we are evaluating the function at.
*/
template <class Base>
inline bool AD<Base>::BinaryBool(
bool FunName(const Base &x, const Base &y),
const AD<Base> &x, const AD<Base> &y
)
{
return FunName(x.value_, y.value_);
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,50 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_BOOL_VALUED_HPP
# define CPPAD_CORE_BOOL_VALUED_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 BoolValued$$
$spell
Bool
$$
$section Bool Valued Operations and Functions with AD Arguments$$
$children%
cppad/core/compare.hpp%
cppad/core/near_equal_ext.hpp%
cppad/core/bool_fun.hpp%
cppad/core/par_var.hpp%
cppad/core/equal_op_seq.hpp
%$$
$table
$rref Compare$$
$rref NearEqualExt$$
$rref BoolFun$$
$rref ParVar$$
$rref EqualOpSeq$$
$tend
$end
*/
# include <cppad/core/compare.hpp>
# include <cppad/core/near_equal_ext.hpp>
# include <cppad/core/bool_fun.hpp>
# include <cppad/core/par_var.hpp>
# include <cppad/core/equal_op_seq.hpp>
# endif

View File

@ -1,259 +0,0 @@
# ifndef CPPAD_CORE_CAPACITY_ORDER_HPP
# define CPPAD_CORE_CAPACITY_ORDER_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 capacity_order$$
$spell
var
taylor_
xq
yq
$$
$section Controlling Taylor Coefficients Memory Allocation$$
$mindex Forward capacity_order control$$
$head Syntax$$
$icode%f%.capacity_order(%c%)%$$
$subhead See Also$$
$cref seq_property$$
$head Purpose$$
The Taylor coefficients calculated by $cref Forward$$ mode calculations
are retained in an $cref ADFun$$ object for subsequent use during
$cref Reverse$$ mode and higher order Forward mode calculations.
For example, a call to $cref/Forward/forward_order/$$ with the syntax
$codei%
%yq% = %f%.Forward(%q%, %xq%)
%$$
where $icode%q% > 0%$$ and $code%xq%.size() == %f%.Domain()%$$,
uses the lower order Taylor coefficients and
computes the $th q$$ order Taylor coefficients for all
the variables in the operation sequence corresponding to $icode f$$.
The $code capacity_order$$ operation allows you to control that
amount of memory that is retained by an AD function object
(to hold $code Forward$$ results for subsequent calculations).
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
$head c$$
The argument $icode c$$ has prototype
$codei%
size_t %c%
%$$
It specifies the number of Taylor coefficient orders that are allocated
in the AD operation sequence corresponding to $icode f$$.
$subhead Pre-Allocating Memory$$
If you plan to make calls to $code Forward$$ with the maximum value of
$icode q$$ equal to $icode Q$$,
it should be faster to pre-allocate memory for these calls using
$codei%
%f%.capacity_order(%c%)
%$$
with $icode c$$ equal to $latex Q + 1$$.
If you do no do this, $code Forward$$ will automatically allocate memory
and will copy the results to a larger buffer, when necessary.
$pre
$$
Note that each call to $cref Dependent$$ frees the old memory
connected to the function object and sets the corresponding
taylor capacity to zero.
$subhead Freeing Memory$$
If you no longer need the Taylor coefficients of order $icode q$$
and higher (that are stored in $icode f$$),
you can reduce the memory allocated to $icode f$$ using
$codei%
%f%.capacity_order(%c%)
%$$
with $icode c$$ equal to $icode q$$.
Note that, if $cref ta_hold_memory$$ is true, this memory is not actually
returned to the system, but rather held for future use by the same thread.
$head Original State$$
If $icode f$$ is $cref/constructed/FunConstruct/$$ with the syntax
$codei%
ADFun<%Base%> %f%(%x%, %y%)
%$$,
there is an implicit call to $cref forward_zero$$ with $icode xq$$ equal to
the value of the
$cref/independent variables/glossary/Tape/Independent Variable/$$
when the AD operation sequence was recorded.
This corresponds to $icode%c% == 1%$$.
$children%
example/general/capacity_order.cpp
%$$
$head Example$$
The file
$cref capacity_order.cpp$$
contains an example and test of these operations.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file capacity_order.hpp
Control of number of orders allocated.
\}
*/
/*!
Control of number of orders and directions allocated.
\tparam Base
The type used during the forward mode computations; i.e., the corresponding
recording of operations used the type AD<Base>.
\param c
is the number of orders to allocate memory for.
If <code>c == 0</code> then \c r must also be zero.
In this case num_order_taylor_, cap_order_taylor_, and num_direction_taylor_
are all set to zero.
In addition, taylor_.free() is called.
\param r
is the number of directions to allocate memory for.
If <code>c == 1</code> then \c r must also be one.
In all cases, it must hold that
<code>
r == num_direction_taylor_ || num_order_taylor <= 1
</code>
Upon return, num_direction_taylor_ is equal to r.
\par num_order_taylor_
The output value of num_order_taylor_ is the mininumum of its input
value and c. This minimum is the number of orders that are copied to the
new taylor coefficient buffer.
\par num_direction_taylor_
The output value of num_direction_taylor_ is equal to \c r.
*/
template <typename Base>
void ADFun<Base>::capacity_order(size_t c, size_t r)
{ // temporary indices
size_t i, k, ell;
if( (c == cap_order_taylor_) & (r == num_direction_taylor_) )
return;
if( c == 0 )
{ CPPAD_ASSERT_UNKNOWN( r == 0 );
taylor_.free();
num_order_taylor_ = 0;
cap_order_taylor_ = 0;
num_direction_taylor_ = r;
return;
}
CPPAD_ASSERT_UNKNOWN(r==num_direction_taylor_ || num_order_taylor_<=1);
// Allocate new taylor with requested number of orders and directions
size_t new_len = ( (c-1)*r + 1 ) * num_var_tape_;
local::pod_vector<Base> new_taylor;
new_taylor.extend(new_len);
// number of orders to copy
size_t p = std::min(num_order_taylor_, c);
if( p > 0 )
{
// old order capacity
size_t C = cap_order_taylor_;
// old number of directions
size_t R = num_direction_taylor_;
// copy the old data into the new matrix
CPPAD_ASSERT_UNKNOWN( p == 1 || r == R );
for(i = 0; i < num_var_tape_; i++)
{ // copy zero order
size_t old_index = ((C-1) * R + 1) * i + 0;
size_t new_index = ((c-1) * r + 1) * i + 0;
new_taylor[ new_index ] = taylor_[ old_index ];
// copy higher orders
for(k = 1; k < p; k++)
{ for(ell = 0; ell < R; ell++)
{ old_index = ((C-1) * R + 1) * i + (k-1) * R + ell + 1;
new_index = ((c-1) * r + 1) * i + (k-1) * r + ell + 1;
new_taylor[ new_index ] = taylor_[ old_index ];
}
}
}
}
// replace taylor_ by new_taylor
taylor_.swap(new_taylor);
cap_order_taylor_ = c;
num_order_taylor_ = p;
num_direction_taylor_ = r;
// note that the destructor for new_taylor will free the old taylor memory
return;
}
/*!
User API control of number of orders allocated.
\tparam Base
The type used during the forward mode computations; i.e., the corresponding
recording of operations used the type AD<Base>.
\param c
is the number of orders to allocate memory for.
If <code>c == 0</code>,
num_order_taylor_, cap_order_taylor_, and num_direction_taylor_
are all set to zero.
In addition, taylor_.free() is called.
\par num_order_taylor_
The output value of num_order_taylor_ is the mininumum of its input
value and c. This minimum is the number of orders that are copied to the
new taylor coefficient buffer.
\par num_direction_taylor_
If \c is zero (one), \c num_direction_taylor_ is set to zero (one).
Otherwise, if \c num_direction_taylor_ is zero, it is set to one.
Othwerwise, \c num_direction_taylor_ is not modified.
*/
template <typename Base>
void ADFun<Base>::capacity_order(size_t c)
{ size_t r;
if( (c == 0) | (c == 1) )
{ r = c;
capacity_order(c, r);
return;
}
r = num_direction_taylor_;
if( r == 0 )
r = 1;
capacity_order(c, r);
return;
}
} // END CppAD namespace
# endif

View File

@ -1,198 +0,0 @@
# ifndef CPPAD_CORE_CHECK_FOR_NAN_HPP
# define CPPAD_CORE_CHECK_FOR_NAN_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 check_for_nan$$
$spell
std
vec
Cpp
const
bool
newline
$$
$section Check an ADFun Object For Nan Results$$
$head Syntax$$
$icode%f%.check_for_nan(%b%)
%$$
$icode%b% = %f%.check_for_nan()
%$$
$codei%get_check_for_nan(%vec%, %file%)
%$$
$head Debugging$$
If $code NDEBUG$$ is not defined, and
the result of a $cref/forward/forward_order/$$ or $cref/reverse/reverse_any/$$
calculation contains a $cref nan$$,
CppAD can halt with an error message.
$head f$$
For the syntax where $icode b$$ is an argument,
$icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
(see $codei%ADFun<%Base%>%$$ $cref/constructor/FunConstruct/$$).
For the syntax where $icode b$$ is the result,
$icode f$$ has prototype
$codei%
const ADFun<%Base%> %f%
%$$
$head b$$
This argument or result has prototype
$codei%
bool %b%
%$$
Future calls to $icode%f%.Forward%$$ will (will not) check for $code nan$$.
depending on if $icode b$$ is true (false).
$head Default$$
The value for this setting after construction of $icode f$$) is true.
The value of this setting is not affected by calling
$cref Dependent$$ for this function object.
$head Error Message$$
If this error is detected during zero order forward mode,
the values of the independent variables that resulted in the $code nan$$
are written to a temporary binary file.
This is so that you can run the original source code with those values
to see what is causing the $code nan$$.
$subhead vector_size$$
The error message with contain the text
$codei%vector_size = %vector_size%$$ followed the newline character
$code '\n'$$.
The value of $icode vector_size$$ is the number of elements
in the independent vector.
$subhead file_name$$
The error message with contain the text
$codei%file_name = %file_name%$$ followed the newline character
$code '\n'$$.
The value of $icode file_name$$ is the name of the temporary file
that contains the dependent variable values.
$subhead index$$
The error message will contain the text
$codei%index = %index%$$ followed by the newline character $code '\n'$$.
The value of $icode index$$ is the lowest dependent variable index
that has the value $code nan$$.
$head get_check_for_nan$$
This routine can be used to get the independent variable
values that result in a $code nan$$.
$subhead vec$$
This argument has prototype
$codei%
CppAD::vector<%Base%>& %vec%
%$$
It size must be equal to the corresponding value of
$cref/vector_size/check_for_nan/Error Message/vector_size/$$
in the corresponding error message.
The input value of its elements does not matter.
Upon return, it will contain the values for the independent variables,
in the corresponding call to $cref Independent$$,
that resulted in the $code nan$$.
(Note that the call to $code Independent$$ uses an vector with elements
of type $codei%AD<%Base%>%$$ and $icode vec$$ has elements of type
$icode Base$$.)
$subhead file$$
This argument has prototype
$codei%
const std::string& %file%
%$$
It must be the value of
$cref/file_name/check_for_nan/Error Message/file_name/$$
in the corresponding error message.
$head Example$$
$children%
example/general/check_for_nan.cpp
%$$
The file
$cref check_for_nan.cpp$$
contains an example and test of these operations.
It returns true if it succeeds and false otherwise.
$end
*/
# include <cppad/utility/vector.hpp>
# include <cppad/configure.hpp>
# include <fstream>
# if CPPAD_HAS_MKSTEMP
# include <stdlib.h>
# include <unistd.h>
# else
# if CPPAD_HAS_TMPNAM_S
# include <stdio.h>
# else
# include <stdlib.h>
# endif
# endif
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
template <class Base>
void put_check_for_nan(const CppAD::vector<Base>& vec, std::string& file_name)
{
size_t char_size = sizeof(Base) * vec.size();
const char* char_ptr = reinterpret_cast<const char*>( vec.data() );
# if CPPAD_HAS_MKSTEMP
char pattern[] = "/tmp/fileXXXXXX";
int fd = mkstemp(pattern);
file_name = pattern;
write(fd, char_ptr, char_size);
close(fd);
# else
# if CPPAD_HAS_TMPNAM_S
std::vector<char> name(L_tmpnam_s);
if( tmpnam_s( name.data(), L_tmpnam_s ) != 0 )
{ CPPAD_ASSERT_KNOWN(
false,
"Cannot create a temporary file name"
);
}
file_name = name.data();
# else
file_name = tmpnam( CPPAD_NULL );
# endif
std::fstream file_out(file_name.c_str(), std::ios::out|std::ios::binary );
file_out.write(char_ptr, char_size);
file_out.close();
# endif
return;
}
template <class Base>
void get_check_for_nan(CppAD::vector<Base>& vec, const std::string& file_name)
{ //
size_t n = vec.size();
size_t char_size = sizeof(Base) * n;
char* char_ptr = reinterpret_cast<char*>( vec.data() );
//
std::fstream file_in(file_name.c_str(), std::ios::in|std::ios::binary );
file_in.read(char_ptr, char_size);
//
return;
}
} // END_CPPAD_NAMESPACE
# endif

File diff suppressed because it is too large Load Diff

View File

@ -1,415 +0,0 @@
# ifndef CPPAD_CORE_COMPARE_HPP
# define CPPAD_CORE_COMPARE_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 Compare$$
$spell
cos
Op
bool
const
$$
$section AD Binary Comparison Operators$$
$mindex compare < <= > >= == !=$$
$head Syntax$$
$icode%b% = %x% %Op% %y%$$
$head Purpose$$
Compares two operands where one of the operands is an
$codei%AD<%Base%>%$$ object.
The comparison has the same interpretation as for
the $icode Base$$ type.
$head Op$$
The operator $icode Op$$ is one of the following:
$table
$bold Op$$ $pre $$ $cnext $bold Meaning$$ $rnext
$code <$$ $cnext is $icode x$$ less than $icode y$$ $rnext
$code <=$$ $cnext is $icode x$$ less than or equal $icode y$$ $rnext
$code >$$ $cnext is $icode x$$ greater than $icode y$$ $rnext
$code >=$$ $cnext is $icode x$$ greater than or equal $icode y$$ $rnext
$code ==$$ $cnext is $icode x$$ equal to $icode y$$ $rnext
$code !=$$ $cnext is $icode x$$ not equal to $icode y$$
$tend
$head x$$
The operand $icode x$$ has prototype
$codei%
const %Type% &%x%
%$$
where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
$head y$$
The operand $icode y$$ has prototype
$codei%
const %Type% &%y%
%$$
where $icode Type$$ is $codei%AD<%Base%>%$$, $icode Base$$, or $code int$$.
$head b$$
The result $icode b$$ has type
$codei%
bool %b%
%$$
$head Operation Sequence$$
The result of this operation is a $code bool$$ value
(not an $cref/AD of Base/glossary/AD of Base/$$ object).
Thus it will not be recorded as part of an
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$pre
$$
For example, suppose
$icode x$$ and $icode y$$ are $codei%AD<%Base%>%$$ objects,
the tape corresponding to $codei%AD<%Base%>%$$ is recording,
$icode b$$ is true,
and the subsequent code is
$codei%
if( %b% )
%y% = cos(%x%);
else %y% = sin(%x%);
%$$
only the assignment $icode%y% = cos(%x%)%$$ is recorded on the tape
(if $icode x$$ is a $cref/parameter/glossary/Parameter/$$,
nothing is recorded).
The $cref CompareChange$$ function can yield
some information about changes in comparison operation results.
You can use $cref CondExp$$ to obtain comparison operations
that depends on the
$cref/independent variable/glossary/Tape/Independent Variable/$$
values with out re-taping the AD sequence of operations.
$head Assumptions$$
If one of the $icode Op$$ operators listed above
is used with an $codei%AD<%Base%>%$$ object,
it is assumed that the same operator is supported by the base type
$icode Base$$.
$head Example$$
$children%
example/general/compare.cpp
%$$
The file
$cref compare.cpp$$
contains an example and test of these operations.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
// -------------------------------- < --------------------------
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool operator < (const AD<Base> &left , const AD<Base> &right)
{ bool result = (left.value_ < right.value_);
bool var_left = Variable(left);
bool var_right = Variable(right);
local::ADTape<Base> *tape = CPPAD_NULL;
if( var_left )
{ tape = left.tape_this();
if( var_right )
{ if( result )
{ tape->Rec_.PutOp(local::LtvvOp);
tape->Rec_.PutArg(left.taddr_, right.taddr_);
}
else
{ tape->Rec_.PutOp(local::LevvOp);
tape->Rec_.PutArg(right.taddr_, left.taddr_);
}
}
else
{ addr_t arg1 = tape->Rec_.PutPar(right.value_);
if( result )
{ tape->Rec_.PutOp(local::LtvpOp);
tape->Rec_.PutArg(left.taddr_, arg1);
}
else
{ tape->Rec_.PutOp(local::LepvOp);
tape->Rec_.PutArg(arg1, left.taddr_);
}
}
}
else if ( var_right )
{ tape = right.tape_this();
addr_t arg0 = tape->Rec_.PutPar(left.value_);
if( result )
{ tape->Rec_.PutOp(local::LtpvOp);
tape->Rec_.PutArg(arg0, right.taddr_);
}
else
{ tape->Rec_.PutOp(local::LevpOp);
tape->Rec_.PutArg(right.taddr_, arg0);
}
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<)
// -------------------------------- <= -------------------------
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool operator <= (const AD<Base> &left , const AD<Base> &right)
{ bool result = (left.value_ <= right.value_);
bool var_left = Variable(left);
bool var_right = Variable(right);
local::ADTape<Base> *tape = CPPAD_NULL;
if( var_left )
{ tape = left.tape_this();
if( var_right )
{ if( result )
{ tape->Rec_.PutOp(local::LevvOp);
tape->Rec_.PutArg(left.taddr_, right.taddr_);
}
else
{ tape->Rec_.PutOp(local::LtvvOp);
tape->Rec_.PutArg(right.taddr_, left.taddr_);
}
}
else
{ addr_t arg1 = tape->Rec_.PutPar(right.value_);
if( result )
{ tape->Rec_.PutOp(local::LevpOp);
tape->Rec_.PutArg(left.taddr_, arg1);
}
else
{ tape->Rec_.PutOp(local::LtpvOp);
tape->Rec_.PutArg(arg1, left.taddr_);
}
}
}
else if ( var_right )
{ tape = right.tape_this();
addr_t arg0 = tape->Rec_.PutPar(left.value_);
if( result )
{ tape->Rec_.PutOp(local::LepvOp);
tape->Rec_.PutArg(arg0, right.taddr_);
}
else
{ tape->Rec_.PutOp(local::LtvpOp);
tape->Rec_.PutArg(right.taddr_, arg0);
}
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<=)
// -------------------------------- > --------------------------
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool operator > (const AD<Base> &left , const AD<Base> &right)
{ bool result = (left.value_ > right.value_);
bool var_left = Variable(left);
bool var_right = Variable(right);
local::ADTape<Base> *tape = CPPAD_NULL;
if( var_left )
{ tape = left.tape_this();
if( var_right )
{ if( result )
{ tape->Rec_.PutOp(local::LtvvOp);
tape->Rec_.PutArg(right.taddr_, left.taddr_);
}
else
{ tape->Rec_.PutOp(local::LevvOp);
tape->Rec_.PutArg(left.taddr_, right.taddr_);
}
}
else
{ addr_t arg1 = tape->Rec_.PutPar(right.value_);
if( result )
{ tape->Rec_.PutOp(local::LtpvOp);
tape->Rec_.PutArg(arg1, left.taddr_);
}
else
{ tape->Rec_.PutOp(local::LevpOp);
tape->Rec_.PutArg(left.taddr_, arg1);
}
}
}
else if ( var_right )
{ tape = right.tape_this();
addr_t arg0 = tape->Rec_.PutPar(left.value_);
if( result )
{ tape->Rec_.PutOp(local::LtvpOp);
tape->Rec_.PutArg(right.taddr_, arg0);
}
else
{ tape->Rec_.PutOp(local::LepvOp);
tape->Rec_.PutArg(arg0, right.taddr_);
}
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>)
// -------------------------------- >= -------------------------
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool operator >= (const AD<Base> &left , const AD<Base> &right)
{ bool result = (left.value_ >= right.value_);
bool var_left = Variable(left);
bool var_right = Variable(right);
local::ADTape<Base> *tape = CPPAD_NULL;
if( var_left )
{ tape = left.tape_this();
if( var_right )
{ if( result )
{ tape->Rec_.PutOp(local::LevvOp);
tape->Rec_.PutArg(right.taddr_, left.taddr_);
}
else
{ tape->Rec_.PutOp(local::LtvvOp);
tape->Rec_.PutArg(left.taddr_, right.taddr_);
}
}
else
{ addr_t arg1 = tape->Rec_.PutPar(right.value_);
if( result )
{ tape->Rec_.PutOp(local::LepvOp);
tape->Rec_.PutArg(arg1, left.taddr_);
}
else
{ tape->Rec_.PutOp(local::LtvpOp);
tape->Rec_.PutArg(left.taddr_, arg1);
}
}
}
else if ( var_right )
{ tape = right.tape_this();
addr_t arg0 = tape->Rec_.PutPar(left.value_);
if( result )
{ tape->Rec_.PutOp(local::LevpOp);
tape->Rec_.PutArg(right.taddr_, arg0);
}
else
{ tape->Rec_.PutOp(local::LtpvOp);
tape->Rec_.PutArg(arg0, right.taddr_);
}
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>=)
// -------------------------------- == -------------------------
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool operator == (const AD<Base> &left , const AD<Base> &right)
{ bool result = (left.value_ == right.value_);
bool var_left = Variable(left);
bool var_right = Variable(right);
local::ADTape<Base> *tape = CPPAD_NULL;
if( var_left )
{ tape = left.tape_this();
if( var_right )
{ tape->Rec_.PutArg(left.taddr_, right.taddr_);
if( result )
tape->Rec_.PutOp(local::EqvvOp);
else
tape->Rec_.PutOp(local::NevvOp);
}
else
{ addr_t arg1 = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(arg1, left.taddr_);
if( result )
tape->Rec_.PutOp(local::EqpvOp);
else
tape->Rec_.PutOp(local::NepvOp);
}
}
else if ( var_right )
{ tape = right.tape_this();
addr_t arg0 = tape->Rec_.PutPar(left.value_);
tape->Rec_.PutArg(arg0, right.taddr_);
if( result )
tape->Rec_.PutOp(local::EqpvOp);
else
tape->Rec_.PutOp(local::NepvOp);
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(==)
// -------------------------------- != -------------------------
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool operator != (const AD<Base> &left , const AD<Base> &right)
{ bool result = (left.value_ != right.value_);
bool var_left = Variable(left);
bool var_right = Variable(right);
local::ADTape<Base> *tape = CPPAD_NULL;
if( var_left )
{ tape = left.tape_this();
if( var_right )
{ tape->Rec_.PutArg(left.taddr_, right.taddr_);
if( result )
tape->Rec_.PutOp(local::NevvOp);
else
tape->Rec_.PutOp(local::EqvvOp);
}
else
{ addr_t arg1 = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(arg1, left.taddr_);
if( result )
tape->Rec_.PutOp(local::NepvOp);
else
tape->Rec_.PutOp(local::EqpvOp);
}
}
else if ( var_right )
{ tape = right.tape_this();
addr_t arg0 = tape->Rec_.PutPar(left.value_);
tape->Rec_.PutArg(arg0, right.taddr_);
if( result )
tape->Rec_.PutOp(local::NepvOp);
else
tape->Rec_.PutOp(local::EqpvOp);
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(!=)
} // END CppAD namespace
# endif

View File

@ -1,142 +0,0 @@
# ifndef CPPAD_CORE_COMPOUND_ASSIGN_HPP
# define CPPAD_CORE_COMPOUND_ASSIGN_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 compound_assign$$
$spell
Op
VecAD
const
$$
$section AD Compound Assignment Operators$$
$mindex + add plus - subtract minus * multiply times / divide multiple$$
$head Syntax$$
$icode%x% %Op% %y%$$
$head Purpose$$
Performs compound assignment operations
where either $icode x$$ has type
$codei%AD<%Base%>%$$.
$head Op$$
The operator $icode Op$$ is one of the following
$table
$bold Op$$ $cnext $bold Meaning$$ $rnext
$code +=$$ $cnext $icode x$$ is assigned $icode x$$ plus $icode y$$ $rnext
$code -=$$ $cnext $icode x$$ is assigned $icode x$$ minus $icode y$$ $rnext
$code *=$$ $cnext $icode x$$ is assigned $icode x$$ times $icode y$$ $rnext
$code /=$$ $cnext $icode x$$ is assigned $icode x$$ divided by $icode y$$
$tend
$head Base$$
The type $icode Base$$ is determined by the operand $icode x$$.
$head x$$
The operand $icode x$$ has the following prototype
$codei%
AD<%Base%> &%x%
%$$
$head y$$
The operand $icode y$$ has the following prototype
$codei%
const %Type% &%y%
%$$
where $icode Type$$ is
$codei%VecAD<%Base%>::reference%$$,
$codei%AD<%Base%>%$$,
$icode Base$$, or
$code double$$.
$head Result$$
The result of this assignment
can be used as a reference to $icode x$$.
For example, if $icode z$$ has the following type
$codei%
AD<%Base%> %z%
%$$
then the syntax
$codei%
%z% = %x% += %y%
%$$
will compute $icode x$$ plus $icode y$$
and then assign this value to both $icode x$$ and $icode z$$.
$head Operation Sequence$$
This is an $cref/atomic/glossary/Operation/Atomic/$$
$cref/AD of Base/glossary/AD of Base/$$ operation
and hence it is part of the current
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$children%
example/general/add_eq.cpp%
example/general/sub_eq.cpp%
example/general/mul_eq.cpp%
example/general/div_eq.cpp
%$$
$head Example$$
The following files contain examples and tests of these functions.
Each test returns true if it succeeds and false otherwise.
$table
$rref AddEq.cpp$$
$rref sub_eq.cpp$$
$rref mul_eq.cpp$$
$rref div_eq.cpp$$
$tend
$head Derivative$$
If $latex f$$ and $latex g$$ are
$cref/Base functions/glossary/Base Function/$$
$subhead Addition$$
$latex \[
\D{[ f(x) + g(x) ]}{x} = \D{f(x)}{x} + \D{g(x)}{x}
\] $$
$subhead Subtraction$$
$latex \[
\D{[ f(x) - g(x) ]}{x} = \D{f(x)}{x} - \D{g(x)}{x}
\] $$
$subhead Multiplication$$
$latex \[
\D{[ f(x) * g(x) ]}{x} = g(x) * \D{f(x)}{x} + f(x) * \D{g(x)}{x}
\] $$
$subhead Division$$
$latex \[
\D{[ f(x) / g(x) ]}{x} =
[1/g(x)] * \D{f(x)}{x} - [f(x)/g(x)^2] * \D{g(x)}{x}
\] $$
$end
-----------------------------------------------------------------------------
*/
# include <cppad/core/add_eq.hpp>
# include <cppad/core/sub_eq.hpp>
# include <cppad/core/mul_eq.hpp>
# include <cppad/core/div_eq.hpp>
# endif

View File

@ -1,354 +0,0 @@
# ifndef CPPAD_CORE_COND_EXP_HPP
# define CPPAD_CORE_COND_EXP_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 CondExp$$
$spell
Atan2
CondExp
Taylor
std
Cpp
namespace
inline
const
abs
Rel
bool
Lt
Le
Eq
Ge
Gt
$$
$section AD Conditional Expressions$$
$mindex assign$$
$head Syntax$$
$icode%result% = CondExp%Rel%(%left%, %right%, %if_true%, %if_false%)%$$
$head Purpose$$
Record,
as part of an AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$,
the conditional result
$codei%
if( %left% %Cop% %right% )
%result% = %if_true%
else %result% = %if_false%
%$$
The relational $icode Rel$$ and comparison operator $icode Cop$$
above have the following correspondence:
$codei%
%Rel% Lt Le Eq Ge Gt
%Cop% < <= == >= >
%$$
If $icode f$$ is the $cref ADFun$$ object corresponding to the
AD operation sequence,
the assignment choice for $icode result$$
in an AD conditional expression is made each time
$cref/f.Forward/Forward/$$ is used to evaluate the zero order Taylor
coefficients with new values for the
$cref/independent variables/glossary/Tape/Independent Variable/$$.
This is in contrast to the $cref/AD comparison operators/Compare/$$
which are boolean valued and not included in the AD operation sequence.
$head Rel$$
In the syntax above, the relation $icode Rel$$ represents one of the following
two characters: $code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, $code Gt$$.
As in the table above,
$icode Rel$$ determines which comparison operator $icode Cop$$ is used
when comparing $icode left$$ and $icode right$$.
$head Type$$
These functions are defined in the CppAD namespace for arguments of
$icode Type$$ is $code float$$ , $code double$$, or any type of the form
$codei%AD<%Base%>%$$.
(Note that all four arguments must have the same type.)
$head left$$
The argument $icode left$$ has prototype
$codei%
const %Type%& %left%
%$$
It specifies the value for the left side of the comparison operator.
$head right$$
The argument $icode right$$ has prototype
$codei%
const %Type%& %right%
%$$
It specifies the value for the right side of the comparison operator.
$head if_true$$
The argument $icode if_true$$ has prototype
$codei%
const %Type%& %if_true%
%$$
It specifies the return value if the result of the comparison is true.
$head if_false$$
The argument $icode if_false$$ has prototype
$codei%
const %Type%& %if_false%
%$$
It specifies the return value if the result of the comparison is false.
$head result$$
The $icode result$$ has prototype
$codei%
%Type%& %if_false%
%$$
$head Optimize$$
The $cref optimize$$ method will optimize conditional expressions
in the following way:
During $cref/zero order forward mode/forward_zero/$$,
once the value of the $icode left$$ and $icode right$$ have been determined,
it is known if the true or false case is required.
From this point on, values corresponding to the case that is not required
are not computed.
This optimization is done for the rest of zero order forward mode
as well as forward and reverse derivatives calculations.
$head Deprecate 2005-08-07$$
Previous versions of CppAD used
$codei%
CondExp(%flag%, %if_true%, %if_false%)
%$$
for the same meaning as
$codei%
CondExpGt(%flag%, %Type%(0), %if_true%, %if_false%)
%$$
Use of $code CondExp$$ is deprecated, but continues to be supported.
$head Operation Sequence$$
This is an AD of $icode Base$$
$cref/atomic operation/glossary/Operation/Atomic/$$
and hence is part of the current
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$head Test$$
$children%
example/general/cond_exp.cpp
%$$
The file
$cref cond_exp.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$head Atan2$$
The following implementation of the
AD $cref atan2$$ function is a more complex
example of using conditional expressions:
$code
$srcfile%cppad/core/atan2.hpp%0%BEGIN CondExp%// END CondExp%$$
$$
$end
-------------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
AD<Base> CondExpOp(
enum CompareOp cop ,
const AD<Base> &left ,
const AD<Base> &right ,
const AD<Base> &if_true ,
const AD<Base> &if_false )
{
AD<Base> returnValue;
CPPAD_ASSERT_UNKNOWN( Parameter(returnValue) );
// check first case where do not need to tape
if( IdenticalPar(left) & IdenticalPar(right) )
{ switch( cop )
{
case CompareLt:
if( left.value_ < right.value_ )
returnValue = if_true;
else returnValue = if_false;
break;
case CompareLe:
if( left.value_ <= right.value_ )
returnValue = if_true;
else returnValue = if_false;
break;
case CompareEq:
if( left.value_ == right.value_ )
returnValue = if_true;
else returnValue = if_false;
break;
case CompareGe:
if( left.value_ >= right.value_ )
returnValue = if_true;
else returnValue = if_false;
break;
case CompareGt:
if( left.value_ > right.value_ )
returnValue = if_true;
else returnValue = if_false;
break;
default:
CPPAD_ASSERT_UNKNOWN(0);
returnValue = if_true;
}
return returnValue;
}
// must use CondExp incase Base is an AD type and recording
returnValue.value_ = CondExpOp(cop,
left.value_, right.value_, if_true.value_, if_false.value_);
local::ADTape<Base> *tape = CPPAD_NULL;
if( Variable(left) )
tape = left.tape_this();
if( Variable(right) )
tape = right.tape_this();
if( Variable(if_true) )
tape = if_true.tape_this();
if( Variable(if_false) )
tape = if_false.tape_this();
// add this operation to the tape
if( tape != CPPAD_NULL )
tape->RecordCondExp(cop,
returnValue, left, right, if_true, if_false);
return returnValue;
}
// --- RecordCondExp(cop, returnValue, left, right, if_true, if_false) -----
/// All these operations are done in \c Rec_, so we should move this
/// routine to <tt>recorder<Base></tt>.
template <class Base>
void local::ADTape<Base>::RecordCondExp(
enum CompareOp cop ,
AD<Base> &returnValue ,
const AD<Base> &left ,
const AD<Base> &right ,
const AD<Base> &if_true ,
const AD<Base> &if_false )
{ addr_t ind0, ind1, ind2, ind3, ind4, ind5;
addr_t returnValue_taddr;
// taddr_ of this variable
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
returnValue_taddr = Rec_.PutOp(CExpOp);
// ind[0] = cop
ind0 = addr_t( cop );
// ind[1] = base 2 represenation of the value
// [Var(left), Var(right), Var(if_true), Var(if_false)]
ind1 = 0;
// Make sure returnValue is in the list of variables and set its taddr
if( Parameter(returnValue) )
returnValue.make_variable(id_, returnValue_taddr );
else returnValue.taddr_ = returnValue_taddr;
// ind[2] = left address
if( Parameter(left) )
ind2 = Rec_.PutPar(left.value_);
else
{ ind1 += 1;
ind2 = left.taddr_;
}
// ind[3] = right address
if( Parameter(right) )
ind3 = Rec_.PutPar(right.value_);
else
{ ind1 += 2;
ind3 = right.taddr_;
}
// ind[4] = if_true address
if( Parameter(if_true) )
ind4 = Rec_.PutPar(if_true.value_);
else
{ ind1 += 4;
ind4 = if_true.taddr_;
}
// ind[5] = if_false address
if( Parameter(if_false) )
ind5 = Rec_.PutPar(if_false.value_);
else
{ ind1 += 8;
ind5 = if_false.taddr_;
}
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( ind1 > 0 );
Rec_.PutArg(ind0, ind1, ind2, ind3, ind4, ind5);
// check that returnValue is a dependent variable
CPPAD_ASSERT_UNKNOWN( Variable(returnValue) );
}
// ------------ CondExpOp(left, right, if_true, if_false) ----------------
# define CPPAD_COND_EXP(Name) \
template <class Base> \
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION \
AD<Base> CondExp##Name( \
const AD<Base> &left , \
const AD<Base> &right , \
const AD<Base> &if_true , \
const AD<Base> &if_false ) \
{ \
return CondExpOp(Compare##Name, \
left, right, if_true, if_false); \
}
// AD<Base>
CPPAD_COND_EXP(Lt)
CPPAD_COND_EXP(Le)
CPPAD_COND_EXP(Eq)
CPPAD_COND_EXP(Ge)
CPPAD_COND_EXP(Gt)
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
AD<Base> CondExp(
const AD<Base> &flag ,
const AD<Base> &if_true ,
const AD<Base> &if_false )
{
return CondExpOp(CompareGt, flag, AD<Base>(0), if_true, if_false);
}
# undef CPPAD_COND_EXP
} // END CppAD namespace
# endif

View File

@ -1,52 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_CONVERT_HPP
# define CPPAD_CORE_CONVERT_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 Convert$$
$spell
$$
$section Conversion and I/O of AD Objects$$
$mindex convert from$$
$children%
cppad/core/value.hpp%
cppad/core/integer.hpp%
cppad/core/ad_to_string.hpp%
cppad/core/ad_io.hpp%
cppad/core/print_for.hpp%
cppad/core/var2par.hpp
%$$
$table
$rref Value$$
$rref Integer$$
$rref ad_output$$
$rref PrintFor$$
$rref Var2Par$$
$tend
$end
*/
# include <cppad/core/value.hpp>
# include <cppad/core/integer.hpp>
# include <cppad/core/ad_to_string.hpp>
# include <cppad/core/ad_io.hpp>
# include <cppad/core/print_for.hpp>
# include <cppad/core/var2par.hpp>
# endif

View File

@ -1,205 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_CPPAD_ASSERT_HPP
# define CPPAD_CORE_CPPAD_ASSERT_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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.
-------------------------------------------------------------------------- */
/*!
\file cppad_assert.hpp
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
*/
/*
-------------------------------------------------------------------------------
$begin cppad_assert$$
$spell
CppAD
exp
const
bool
$$
$section CppAD Assertions During Execution$$
$mindex assert macro CPPAD_ASSERT_KNOWN CPPAD_ASSERT_UNKNOWN$$
$head Syntax$$
$codei%CPPAD_ASSERT_KNOWN(%exp%, %msg%)
%$$
$codei%CPPAD_ASSERT_UNKNOWN(%exp%)%$$
$head Purpose$$
These CppAD macros are used to detect and report errors.
They are documented here because they correspond to the C++
source code that the error is reported at.
$head NDEBUG$$
If the preprocessor symbol
$cref/NDEBUG/Faq/Speed/NDEBUG/$$ is defined,
these macros do nothing; i.e., they are optimized out.
$head Restriction$$
The CppAD user should not uses these macros.
You can however write your own macros that do not begin with $code CPPAD$$
and that call the $cref/CppAD error handler/ErrorHandler/$$.
$head Known$$
The $code CPPAD_ASSERT_KNOWN$$ macro is used to check for an error
with a known cause.
For example, many CppAD routines uses these macros
to make sure their arguments conform to their specifications.
$head Unknown$$
The $code CPPAD_ASSERT_UNKNOWN$$ macro is used to check that the
CppAD internal data structures conform as expected.
If this is not the case, CppAD does not know why the error has
occurred; for example, the user may have written past the end
of an allocated array.
$head Exp$$
The argument $icode exp$$ is a C++ source code expression
that results in a $code bool$$ value that should be true.
If it is false, an error has occurred.
This expression may be execute any number of times
(including zero times) so it must have not side effects.
$head Msg$$
The argument $icode msg$$ has prototype
$codei%
const char *%msg%
%$$
and contains a $code '\0'$$ terminated character string.
This string is a description of the error
corresponding to $icode exp$$ being false.
$head Error Handler$$
These macros use the
$cref/CppAD error handler/ErrorHandler/$$ to report errors.
This error handler can be replaced by the user.
$end
------------------------------------------------------------------------------
*/
# include <cassert>
# include <iostream>
# include <cppad/utility/error_handler.hpp>
/*!
\def CPPAD_ASSERT_KNOWN(exp, msg)
Check that \a exp is true, if not print \a msg and terminate execution.
The C++ expression \a exp is expected to be true.
If it is false,
the CppAD use has made an error that is described by \a msg.
If the preprocessor symbol \a NDEBUG is not defined,
and \a exp is false,
this macro will report the source code line number at
which this expected result occurred.
In addition, it will print the specified error message \a msg.
*/
# ifdef NDEBUG
# define CPPAD_ASSERT_KNOWN(exp, msg) // do nothing
# else
# define CPPAD_ASSERT_KNOWN(exp, msg) \
{ if( ! ( exp ) ) \
CppAD::ErrorHandler::Call( \
true , \
__LINE__ , \
__FILE__ , \
#exp , \
msg ); \
}
# endif
/*!
\def CPPAD_ASSERT_UNKNOWN(exp)
Check that \a exp is true, if not terminate execution.
The C++ expression \a exp is expected to be true.
If it is false,
CppAD has detected an error but does not know the cause of the error.
If the preprocessor symbol \a NDEBUG is not defined,
and \a exp is false,
this macro will report the source code line number at
which this expected result occurred.
*/
# ifdef NDEBUG
# define CPPAD_ASSERT_UNKNOWN(exp) // do nothing
# else
# define CPPAD_ASSERT_UNKNOWN(exp) \
{ if( ! ( exp ) ) \
CppAD::ErrorHandler::Call( \
false , \
__LINE__ , \
__FILE__ , \
#exp , \
"" ); \
}
# endif
/*!
\def CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res)
Check that operator \a op has the specified number of of arguments and results.
If \a NDEBUG is not defined and either the number of arguments
or the number of results are not as expected,
execution is terminated and the source code line number is reported.
*/
# define CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res) \
CPPAD_ASSERT_UNKNOWN( NumArg(op) == n_arg ) \
CPPAD_ASSERT_UNKNOWN( NumRes(op) == n_res )
/*!
\def CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
Check that the first call to a routine is not during parallel execution mode.
If \c NDEBUG is defined, this macro has no effect
(not even the definition of (\c assert_first_call).
Otherwise, the variable
\code
static bool assert_first_call
\endcode
is defined and if the first call is executed in parallel mode,
execution is terminated and the source code line number is reported.
*/
# ifdef NDEBUG
# define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
# else
# define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL \
static bool assert_first_call = true; \
if( assert_first_call ) \
{ CPPAD_ASSERT_KNOWN( \
! (CppAD::thread_alloc::in_parallel() ), \
"In parallel mode and parallel_setup has not been called." \
); \
assert_first_call = false; \
}
# endif
/*!
\def CPPAD_ASSERT_ARG_BEFORE_RESULT
Check that operator arguments come before result.
If \c NDEBUG is defined, this macro has no effect,
otherwise it calls the function assert_arg_before_result.
*/
# ifdef NDEBUG
# define CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, result)
# else
# define CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, result) \
assert_arg_before_result(op, arg, result)
# endif
# endif

View File

@ -1,325 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_DEFINE_HPP
# define CPPAD_CORE_DEFINE_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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.
-------------------------------------------------------------------------- */
/*!
\file define.hpp
Define processor symbols and macros that are used by CppAD.
*/
// ----------------------------------------------------------------------------
/*!
\def CPPAD_OP_CODE_TYPE
Is the type used to store enum OpCode values. If not the same as OpCode, then
<code>sizeof(CPPAD_OP_CODE_TYPE) <= sizeof( enum OpCode )</code>
to conserve memory.
This type must support \c std::numeric_limits,
the \c <= operator,
and conversion to \c size_t.
Make sure that the type chosen returns true for is_pod<CPPAD_OP_CODE_TYPE>
in pod_vector.hpp.
*/
# define CPPAD_OP_CODE_TYPE unsigned char
// ----------------------------------------------------------------------------
/*!
\def CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
A version of the inline command that works with MC compiler.
Microsoft Visual C++ version 9.0 generates a warning if a template
function is declared as a friend
(this was not a problem for version 7.0).
The warning identifier is
\verbatim
warning C4396
\endverbatim
and it contains the text
\verbatim
the inline specifier cannot be used when a friend declaration refers
to a specialization of a function template
\endverbatim
This happens even if the function is not a specialization.
This macro is defined as empty for Microsoft compilers.
*/
# ifdef _MSC_VER
# define CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
# else
# define CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION inline
# endif
// ----------------------------------------------------------------------------
/*!
\def CPPAD_LIB_EXPORT
Special macro for exporting windows DLL symbols; see
https://cmake.org/Wiki/BuildingWinDLL
*/
# ifdef _MSC_VER
# ifdef cppad_lib_EXPORTS
# define CPPAD_LIB_EXPORT __declspec(dllexport)
# else
# define CPPAD_LIB_EXPORT __declspec(dllimport)
# endif // cppad_lib_EXPORTS
# else // _MSC_VER
# define CPPAD_LIB_EXPORT
# endif
// ============================================================================
/*!
\def CPPAD_FOLD_ASSIGNMENT_OPERATOR(Op)
Declares automatic coercion for certain AD assignment operations.
This macro assumes that the operator
\verbatim
left Op right
\endverbatim
is defined for the case where left and right have type AD<Base>.
It uses this case to define the cases where
left has type AD<Base> and right has type
VecAD_reference<Base>,
Base, or
double.
The argument right is const and call by reference.
This macro converts the operands to AD<Base> and then
uses the definition of the same operation for that case.
*/
# define CPPAD_FOLD_ASSIGNMENT_OPERATOR(Op) \
/* ----------------------------------------------------------------*/ \
template <class Base> \
inline AD<Base>& operator Op \
(AD<Base> &left, double right) \
{ return left Op AD<Base>(right); } \
\
template <class Base> \
inline AD<Base>& operator Op \
(AD<Base> &left, const Base &right) \
{ return left Op AD<Base>(right); } \
\
inline AD<double>& operator Op \
(AD<double> &left, const double &right) \
{ return left Op AD<double>(right); } \
\
template <class Base> \
inline AD<Base>& operator Op \
(AD<Base> &left, const VecAD_reference<Base> &right) \
{ return left Op right.ADBase(); }
// =====================================================================
/*!
\def CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op)
Declares automatic coercion for certain binary operations with AD result.
This macro assumes that the operator
\verbatim
left Op right
\endverbatim
is defined for the case where left and right
and the result of the operation all
have type AD<Base>.
It uses this case to define the cases either left
or right has type VecAD_reference<Base> or AD<Base>
and the type of the other operand is one of the following:
VecAD_reference<Base>, AD<Base>, Base, double.
All of the arguments are const and call by reference.
This macro converts the operands to AD<Base> and then
uses the definition of the same operation for that case.
*/
# define CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op) \
/* ----------------------------------------------------------------*/ \
/* Operations with VecAD_reference<Base> and AD<Base> only*/ \
\
template <class Base> \
inline AD<Base> operator Op \
(const AD<Base> &left, const VecAD_reference<Base> &right) \
{ return left Op right.ADBase(); } \
\
template <class Base> \
inline AD<Base> operator Op \
(const VecAD_reference<Base> &left, const VecAD_reference<Base> &right)\
{ return left.ADBase() Op right.ADBase(); } \
\
template <class Base> \
inline AD<Base> operator Op \
(const VecAD_reference<Base> &left, const AD<Base> &right) \
{ return left.ADBase() Op right; } \
/* ----------------------------------------------------------------*/ \
/* Operations Base */ \
\
template <class Base> \
inline AD<Base> operator Op \
(const Base &left, const AD<Base> &right) \
{ return AD<Base>(left) Op right; } \
\
template <class Base> \
inline AD<Base> operator Op \
(const Base &left, const VecAD_reference<Base> &right) \
{ return AD<Base>(left) Op right.ADBase(); } \
\
template <class Base> \
inline AD<Base> operator Op \
(const AD<Base> &left, const Base &right) \
{ return left Op AD<Base>(right); } \
\
template <class Base> \
inline AD<Base> operator Op \
(const VecAD_reference<Base> &left, const Base &right) \
{ return left.ADBase() Op AD<Base>(right); } \
\
/* ----------------------------------------------------------------*/ \
/* Operations double */ \
\
template <class Base> \
inline AD<Base> operator Op \
(const double &left, const AD<Base> &right) \
{ return AD<Base>(left) Op right; } \
\
template <class Base> \
inline AD<Base> operator Op \
(const double &left, const VecAD_reference<Base> &right) \
{ return AD<Base>(left) Op right.ADBase(); } \
\
template <class Base> \
inline AD<Base> operator Op \
(const AD<Base> &left, const double &right) \
{ return left Op AD<Base>(right); } \
\
template <class Base> \
inline AD<Base> operator Op \
(const VecAD_reference<Base> &left, const double &right) \
{ return left.ADBase() Op AD<Base>(right); } \
/* ----------------------------------------------------------------*/ \
/* Special case to avoid ambuigity when Base is double */ \
\
inline AD<double> operator Op \
(const double &left, const AD<double> &right) \
{ return AD<double>(left) Op right; } \
\
inline AD<double> operator Op \
(const double &left, const VecAD_reference<double> &right) \
{ return AD<double>(left) Op right.ADBase(); } \
\
inline AD<double> operator Op \
(const AD<double> &left, const double &right) \
{ return left Op AD<double>(right); } \
\
inline AD<double> operator Op \
(const VecAD_reference<double> &left, const double &right) \
{ return left.ADBase() Op AD<double>(right); }
// =======================================================================
/*!
\def CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op)
Declares automatic coercion for certain binary operations with bool result.
This macro assumes that the operator
\verbatim
left Op right
\endverbatim
is defined for the case where left and right
have type AD<Base> and the result has type bool.
It uses this case to define the cases either left
or right has type
VecAD_reference<Base> or AD<Base>
and the type of the other operand is one of the following:
VecAD_reference<Base>, AD<Base>, Base, double.
All of the arguments are const and call by reference.
This macro converts the operands to AD<Base> and then
uses the definition of the same operation for that case.
*/
# define CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op) \
/* ----------------------------------------------------------------*/ \
/* Operations with VecAD_reference<Base> and AD<Base> only*/ \
\
template <class Base> \
inline bool operator Op \
(const AD<Base> &left, const VecAD_reference<Base> &right) \
{ return left Op right.ADBase(); } \
\
template <class Base> \
inline bool operator Op \
(const VecAD_reference<Base> &left, const VecAD_reference<Base> &right)\
{ return left.ADBase() Op right.ADBase(); } \
\
template <class Base> \
inline bool operator Op \
(const VecAD_reference<Base> &left, const AD<Base> &right) \
{ return left.ADBase() Op right; } \
/* ----------------------------------------------------------------*/ \
/* Operations Base */ \
\
template <class Base> \
inline bool operator Op \
(const Base &left, const AD<Base> &right) \
{ return AD<Base>(left) Op right; } \
\
template <class Base> \
inline bool operator Op \
(const Base &left, const VecAD_reference<Base> &right) \
{ return AD<Base>(left) Op right.ADBase(); } \
\
template <class Base> \
inline bool operator Op \
(const AD<Base> &left, const Base &right) \
{ return left Op AD<Base>(right); } \
\
template <class Base> \
inline bool operator Op \
(const VecAD_reference<Base> &left, const Base &right) \
{ return left.ADBase() Op AD<Base>(right); } \
\
/* ----------------------------------------------------------------*/ \
/* Operations double */ \
\
template <class Base> \
inline bool operator Op \
(const double &left, const AD<Base> &right) \
{ return AD<Base>(left) Op right; } \
\
template <class Base> \
inline bool operator Op \
(const double &left, const VecAD_reference<Base> &right) \
{ return AD<Base>(left) Op right.ADBase(); } \
\
template <class Base> \
inline bool operator Op \
(const AD<Base> &left, const double &right) \
{ return left Op AD<Base>(right); } \
\
template <class Base> \
inline bool operator Op \
(const VecAD_reference<Base> &left, const double &right) \
{ return left.ADBase() Op AD<Base>(right); } \
/* ----------------------------------------------------------------*/ \
/* Special case to avoid ambuigity when Base is double */ \
\
inline bool operator Op \
(const double &left, const AD<double> &right) \
{ return AD<double>(left) Op right; } \
\
inline bool operator Op \
(const double &left, const VecAD_reference<double> &right) \
{ return AD<double>(left) Op right.ADBase(); } \
\
inline bool operator Op \
(const AD<double> &left, const double &right) \
{ return left Op AD<double>(right); } \
\
inline bool operator Op \
(const VecAD_reference<double> &left, const double &right) \
{ return left.ADBase() Op AD<double>(right); }
# endif

View File

@ -1,332 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_DEPENDENT_HPP
# define CPPAD_CORE_DEPENDENT_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 Dependent$$
$spell
alloc
num
taylor_
ADvector
const
$$
$spell
$$
$section Stop Recording and Store Operation Sequence$$
$mindex ADFun tape Dependent$$
$head Syntax$$
$icode%f%.Dependent(%x%, %y%)%$$
$head Purpose$$
Stop recording and the AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$
that started with the call
$codei%
Independent(%x%)
%$$
and store the operation sequence in $icode f$$.
The operation sequence defines an
$cref/AD function/glossary/AD Function/$$
$latex \[
F : B^n \rightarrow B^m
\] $$
where $latex B$$ is the space corresponding to objects of type $icode Base$$.
The value $latex n$$ is the dimension of the
$cref/domain/seq_property/Domain/$$ space for the operation sequence.
The value $latex m$$ is the dimension of the
$cref/range/seq_property/Range/$$ space for the operation sequence
(which is determined by the size of $icode y$$).
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
The AD of $icode Base$$ operation sequence is stored in $icode f$$; i.e.,
it becomes the operation sequence corresponding to $icode f$$.
If a previous operation sequence was stored in $icode f$$,
it is deleted.
$head x$$
The argument $icode x$$
must be the vector argument in a previous call to
$cref Independent$$.
Neither its size, or any of its values, are allowed to change
between calling
$codei%
Independent(%x%)
%$$
and
$codei%
%f%.Dependent(%x%, %y%)
%$$.
$head y$$
The vector $icode y$$ has prototype
$codei%
const %ADvector% &%y%
%$$
(see $cref/ADvector/FunConstruct/$$ below).
The length of $icode y$$ must be greater than zero
and is the dimension of the range space for $icode f$$.
$head ADvector$$
The type $icode ADvector$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$codei%AD<%Base%>%$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head Taping$$
The tape,
that was created when $codei%Independent(%x%)%$$ was called,
will stop recording.
The AD operation sequence will be transferred from
the tape to the object $icode f$$ and the tape will then be deleted.
$head Forward$$
No $cref Forward$$ calculation is preformed during this operation.
Thus, directly after this operation,
$codei%
%f%.size_order()
%$$
is zero (see $cref size_order$$).
$head Parallel Mode$$
The call to $code Independent$$,
and the corresponding call to
$codei%
ADFun<%Base%> %f%( %x%, %y%)
%$$
or
$codei%
%f%.Dependent( %x%, %y%)
%$$
or $cref abort_recording$$,
must be preformed by the same thread; i.e.,
$cref/thread_alloc::thread_num/ta_thread_num/$$ must be the same.
$head Example$$
The file
$cref fun_check.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
/*!
\file dependent.hpp
Different versions of Dependent function.
*/
/*!
Determine the \c tape corresponding to this exeuction thread and then use
<code>Dependent(tape, y)</code> to store this tapes recording in a function.
\param y [in]
The dependent variable vector for the corresponding function.
*/
template <typename Base>
template <typename ADvector>
void ADFun<Base>::Dependent(const ADvector &y)
{ local::ADTape<Base>* tape = AD<Base>::tape_ptr();
CPPAD_ASSERT_KNOWN(
tape != CPPAD_NULL,
"Can't store current operation sequence in this ADFun object"
"\nbecause there is no active tape (for this thread)."
);
// code above just determines the tape and checks for errors
Dependent(tape, y);
}
/*!
Determine the \c tape corresponding to this exeuction thread and then use
<code>Dependent(tape, y)</code> to store this tapes recording in a function.
\param x [in]
The independent variable vector for this tape. This informaiton is
also stored in the tape so a check is done to make sure it is correct
(if NDEBUG is not defined).
\param y [in]
The dependent variable vector for the corresponding function.
*/
template <typename Base>
template <typename ADvector>
void ADFun<Base>::Dependent(const ADvector &x, const ADvector &y)
{
CPPAD_ASSERT_KNOWN(
x.size() > 0,
"Dependent: independent variable vector has size zero."
);
CPPAD_ASSERT_KNOWN(
Variable(x[0]),
"Dependent: independent variable vector has been changed."
);
local::ADTape<Base> *tape = AD<Base>::tape_ptr(x[0].tape_id_);
CPPAD_ASSERT_KNOWN(
tape->size_independent_ == size_t( x.size() ),
"Dependent: independent variable vector has been changed."
);
# ifndef NDEBUG
size_t i, j;
for(j = 0; j < size_t(x.size()); j++)
{ CPPAD_ASSERT_KNOWN(
size_t(x[j].taddr_) == (j+1),
"ADFun<Base>: independent variable vector has been changed."
);
CPPAD_ASSERT_KNOWN(
x[j].tape_id_ == x[0].tape_id_,
"ADFun<Base>: independent variable vector has been changed."
);
}
for(i = 0; i < size_t(y.size()); i++)
{ CPPAD_ASSERT_KNOWN(
CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) ,
"ADFun<Base>: dependent vector contains a variable for"
"\na different tape (thread) than the independent variables."
);
}
# endif
// code above just determines the tape and checks for errors
Dependent(tape, y);
}
/*!
Replace the floationg point operations sequence for this function object.
\param tape
is a tape that contains the new floating point operation sequence
for this function.
After this operation, all memory allocated for this tape is deleted.
\param y
The dependent variable vector for the function being stored in this object.
\par
All of the private member data in ad_fun.hpp is set to correspond to the
new tape except for check_for_nan_.
*/
template <typename Base>
template <typename ADvector>
void ADFun<Base>::Dependent(local::ADTape<Base> *tape, const ADvector &y)
{
size_t m = y.size();
size_t n = tape->size_independent_;
size_t i, j;
size_t y_taddr;
// check ADvector is Simple Vector class with AD<Base> elements
CheckSimpleVector< AD<Base>, ADvector>();
CPPAD_ASSERT_KNOWN(
y.size() > 0,
"ADFun operation sequence dependent variable size is zero size"
);
// ---------------------------------------------------------------------
// Begin setting ad_fun.hpp private member data
// ---------------------------------------------------------------------
// dep_parameter_, dep_taddr_
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ParOp) == 1 );
dep_parameter_.resize(m);
dep_taddr_.resize(m);
for(i = 0; i < m; i++)
{ dep_parameter_[i] = CppAD::Parameter(y[i]);
if( dep_parameter_[i] )
{ // make a tape copy of dependent variables that are parameters,
y_taddr = tape->RecordParOp( y[i].value_ );
}
else y_taddr = y[i].taddr_;
CPPAD_ASSERT_UNKNOWN( y_taddr > 0 );
dep_taddr_[i] = y_taddr;
}
// put an EndOp at the end of the tape
tape->Rec_.PutOp(local::EndOp);
// some size_t values in ad_fun.hpp
has_been_optimized_ = false;
compare_change_count_ = 1;
compare_change_number_ = 0;
compare_change_op_index_ = 0;
num_order_taylor_ = 0;
num_direction_taylor_ = 0;
cap_order_taylor_ = 0;
// num_var_tape_
// Now that all the variables are in the tape, we can set this value.
num_var_tape_ = tape->Rec_.num_var_rec();
// taylor_
taylor_.erase();
// cskip_op_
cskip_op_.erase();
cskip_op_.extend( tape->Rec_.num_op_rec() );
// load_op_
load_op_.erase();
load_op_.extend( tape->Rec_.num_load_op_rec() );
// play_
// Now that each dependent variable has a place in the tape,
// and there is a EndOp at the end of the tape, we can transfer the
// recording to the player and and erase the tape.
play_.get(tape->Rec_);
// ind_taddr_
// Note that play_ has been set, we can use it to check operators
ind_taddr_.resize(n);
CPPAD_ASSERT_UNKNOWN( n < num_var_tape_);
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == local::InvOp );
ind_taddr_[j] = j+1;
}
// for_jac_sparse_pack_, for_jac_sparse_set_
for_jac_sparse_pack_.resize(0, 0);
for_jac_sparse_set_.resize(0,0);
// ---------------------------------------------------------------------
// End set ad_fun.hpp private member data
// ---------------------------------------------------------------------
// now we can delete the tape
AD<Base>::tape_manage(tape_manage_delete);
// total number of varables in this recording
CPPAD_ASSERT_UNKNOWN( num_var_tape_ == play_.num_var_rec() );
// used to determine if there is an operation sequence in *this
CPPAD_ASSERT_UNKNOWN( num_var_tape_ > 0 );
}
} // END CppAD namespace
# endif

View File

@ -1,306 +0,0 @@
# ifndef CPPAD_CORE_DISCRETE_HPP
# define CPPAD_CORE_DISCRETE_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 Discrete$$
$spell
retaping
namespace
std
Eq
Cpp
const
inline
Geq
$$
$section Discrete AD Functions$$
$mindex CPPAD_DISCRETE_FUNCTION$$
$head Syntax$$
$codei%CPPAD_DISCRETE_FUNCTION(%Base%, %name%)
%$$
$icode%y% = %name%(%x%)
%$$
$icode%ay% = %name%(%ax%)
%$$
$head Purpose$$
Record the evaluation of a discrete function as part
of an $codei%AD<%Base%>%$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
The value of a discrete function can depend on the
$cref/independent variables/glossary/Tape/Independent Variable/$$,
but its derivative is identically zero.
For example, suppose that the integer part of
a $cref/variable/glossary/Variable/$$ $icode x$$ is the
index into an array of values.
$head Base$$
This is the
$cref/base type/base_require/$$
corresponding to the operations sequence;
i.e., use of the $icode name$$ with arguments of type
$codei%AD<%Base%>%$$ can be recorded in an operation sequence.
$head name$$
This is the name of the function (as it is used in the source code).
The user must provide a version of $icode name$$
where the argument has type $icode Base$$.
CppAD uses this to create a version of $icode name$$
where the argument has type $codei%AD<%Base%>%$$.
$head x$$
The argument $icode x$$ has prototype
$codei%
const %Base%& %x%
%$$
It is the value at which the user provided version of $icode name$$
is to be evaluated.
$head y$$
The result $icode y$$ has prototype
$codei%
%Base% %y%
%$$
It is the return value for the user provided version of $icode name$$.
$head ax$$
The argument $icode ax$$ has prototype
$codei%
const AD<%Base%>& %ax%
%$$
It is the value at which the CppAD provided version of $icode name$$
is to be evaluated.
$head ay$$
The result $icode ay$$ has prototype
$codei%
AD<%Base%> %ay%
%$$
It is the return value for the CppAD provided version of $icode name$$.
$head Create AD Version$$
The preprocessor macro invocation
$codei%
CPPAD_DISCRETE_FUNCTION(%Base%, %name%)
%$$
defines the $codei%AD<%Base%>%$$ version of $icode name$$.
This can be with in a namespace (not the $code CppAD$$ namespace)
but must be outside of any routine.
$head Operation Sequence$$
This is an AD of $icode Base$$
$cref/atomic operation/glossary/Operation/Atomic/$$
and hence is part of the current
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Derivatives$$
During a zero order $cref Forward$$ operation,
an $cref ADFun$$ object will compute the value of $icode name$$
using the user provided $icode Base$$ version of this routine.
All the derivatives of $icode name$$ will be evaluated as zero.
$head Parallel Mode$$
The first call to
$codei%
%ay% = %name%(%ax%)
%$$
must not be in $cref/parallel/ta_in_parallel/$$ execution mode.
$head Example$$
$children%
example/general/tape_index.cpp%
example/general/interp_onetape.cpp%
example/general/interp_retape.cpp
%$$
The file
$cref tape_index.cpp$$
contains an example and test that uses a discrete function
to vary an array index during $cref Forward$$ mode calculations.
The file
$cref interp_onetape.cpp$$
contains an example and test that uses discrete
functions to avoid retaping a calculation that requires interpolation.
(The file
$cref interp_retape.cpp$$
shows how interpolation can be done with retaping.)
$head CppADCreateDiscrete Deprecated 2007-07-28$$
The preprocessor symbol $code CppADCreateDiscrete$$
is defined to be the same as $code CPPAD_DISCRETE_FUNCTION$$
but its use is deprecated.
$end
------------------------------------------------------------------------------
*/
# include <vector>
# include <cppad/core/cppad_assert.hpp>
// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
# include <cppad/utility/thread_alloc.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file discrete.hpp
user define discrete functions
*/
/*!
\def CPPAD_DISCRETE_FUNCTION(Base, name)
Defines the function <code>name(ax, ay)</code>
where \c ax and \c ay are vectors with <code>AD<Base></code> elements.
\par Base
is the base type for the discrete function.
\par name
is the name of the user defined function that corresponding to this operation.
*/
# define CPPAD_DISCRETE_FUNCTION(Base, name) \
inline CppAD::AD<Base> name (const CppAD::AD<Base>& ax) \
{ \
static CppAD::discrete<Base> fun(#name, name); \
\
return fun.ad(ax); \
}
# define CppADCreateDiscrete CPPAD_DISCRETE_FUNCTION
/*
Class that acutally implemnets the <code>ay = name(ax)</code> call.
A new discrete function is generated for ech time the user invokes
the CPPAD_DISCRETE_FUNCTION macro; see static object in that macro.
*/
template <class Base>
class discrete {
/// parallel_ad needs to call List to initialize static
template <class Type>
friend void parallel_ad(void);
/// type for the user routine that computes function values
typedef Base (*F) (const Base& x);
private:
/// name of this user defined function
const std::string name_;
/// user's implementation of the function for Base operations
const F f_;
/// index of this objec in the vector of all objects for this class
const size_t index_;
/*!
List of all objects in this class.
If we use CppAD::vector for this vector, it will appear that
there is a memory leak because this list is not distroyed before
thread_alloc::free_available(thread) is called by the testing routines.
*/
static std::vector<discrete *>& List(void)
{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
static std::vector<discrete *> list;
return list;
}
public:
/*!
Constructor called for each invocation of CPPAD_DISCRETE_FUNCTION.
Put this object in the list of all objects for this class and set
the constant private data name_, f_, and index_.
\param Name
is the user's name for this discrete function.
\param f
user routine that implements this function for \c Base class.
\par
This constructor can ont be used in parallel mode because it changes
the static object \c List.
*/
discrete(const char* Name, F f) :
name_(Name)
, f_(f)
, index_( List().size() )
{
CPPAD_ASSERT_KNOWN(
! thread_alloc::in_parallel() ,
"discrete: First call the function *Name is in parallel mode."
);
List().push_back(this);
}
/*!
Implement the user call to <code>ay = name(ax)</code>.
\param ax
is the argument for this call.
\return
the return value is called \c ay above.
*/
AD<Base> ad(const AD<Base> &ax) const
{ AD<Base> ay;
ay.value_ = f_(ax.value_);
if( Variable(ax) )
{ local::ADTape<Base> *tape = ax.tape_this();
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DisOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DisOp) == 2 );
// put operand addresses in the tape
CPPAD_ASSERT_KNOWN(
std::numeric_limits<addr_t>::max() >= index_,
"discrete: cppad_tape_addr_type maximum not large enough"
);
tape->Rec_.PutArg(addr_t(index_), ax.taddr_);
// put operator in the tape
ay.taddr_ = tape->Rec_.PutOp(local::DisOp);
// make result a variable
ay.tape_id_ = tape->id_;
CPPAD_ASSERT_UNKNOWN( Variable(ay) );
}
return ay;
}
/// Name corresponding to a discrete object
static const char* name(size_t index)
{ return List()[index]->name_.c_str(); }
/*!
Link from forward mode sweep to users routine
\param index
index for this function in the list of all discrete object
\param x
argument value at which to evaluate this function
*/
static Base eval(size_t index, const Base& x)
{
CPPAD_ASSERT_UNKNOWN(index < List().size() );
return List()[index]->f_(x);
}
};
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,101 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_DIV_HPP
# define CPPAD_CORE_DIV_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 CppAD namespace
namespace CppAD {
template <class Base>
AD<Base> operator / (const AD<Base> &left , const AD<Base> &right)
{
// compute the Base part
AD<Base> result;
result.value_ = left.value_ / right.value_;
CPPAD_ASSERT_UNKNOWN( Parameter(result) );
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return result;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_left = left.tape_id_ == tape_id;
bool var_right = right.tape_id_ == tape_id;
if( var_left )
{ if( var_right )
{ // result = variable / variable
CPPAD_ASSERT_KNOWN(
left.tape_id_ == right.tape_id_,
"Dividing AD objects that are"
" variables on different tapes."
);
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(left.taddr_, right.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::DivvvOp);
// make result a variable
result.tape_id_ = tape_id;
}
else if( IdenticalOne(right.value_) )
{ // result = variable / 1
result.make_variable(left.tape_id_, left.taddr_);
}
else
{ // result = variable / parameter
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvpOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(left.taddr_, p);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::DivvpOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
else if( var_right )
{ if( IdenticalZero(left.value_) )
{ // result = 0 / variable
}
else
{ // result = parameter / variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(left.value_);
tape->Rec_.PutArg(p, right.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::DivpvOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(/)
} // END CppAD namespace
# endif

View File

@ -1,93 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_DIV_EQ_HPP
# define CPPAD_CORE_DIV_EQ_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 CppAD namespace
namespace CppAD {
template <class Base>
AD<Base>& AD<Base>::operator /= (const AD<Base> &right)
{
// compute the Base part
Base left;
left = value_;
value_ /= right.value_;
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return *this;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_left = tape_id_ == tape_id;
bool var_right = right.tape_id_ == tape_id;
if( var_left )
{ if( var_right )
{ // this = variable / variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(taddr_, right.taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::DivvvOp);
// make this a variable
CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );
}
else if( IdenticalOne( right.value_ ) )
{ // this = variable * 1
}
else
{ // this = variable / parameter
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvpOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(taddr_, p);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::DivvpOp);
// make this a variable
CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );
}
}
else if( var_right )
{ if( IdenticalZero(left) )
{ // this = 0 / variable
}
else
{ // this = parameter / variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(left);
tape->Rec_.PutArg(p, right.taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::DivpvOp);
// make this a variable
tape_id_ = tape_id;
}
}
return *this;
}
CPPAD_FOLD_ASSIGNMENT_OPERATOR(/=)
} // END CppAD namespace
# endif

View File

@ -1,22 +0,0 @@
# ifndef CPPAD_CORE_DRIVERS_HPP
# define CPPAD_CORE_DRIVERS_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.
-------------------------------------------------------------------------- */
# include <cppad/core/jacobian.hpp>
# include <cppad/core/hessian.hpp>
# include <cppad/core/for_one.hpp>
# include <cppad/core/rev_one.hpp>
# include <cppad/core/for_two.hpp>
# include <cppad/core/rev_two.hpp>
# endif

View File

@ -1,60 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_EPSILON_HPP
# define CPPAD_CORE_EPSILON_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 epsilon$$
$spell
std
eps
CppAD
namespace
const
$$
$section Machine Epsilon For AD Types$$
$head Deprecated 2012-06-17$$
This routine has been deprecated.
You should use the $cref numeric_limits$$ $code epsilon$$ instead.
$head Syntax$$
$icode%eps% = epsilon<%Float%>()%$$
$head Purpose$$
Obtain the value of machine epsilon corresponding
to the type $icode%Float%$$.
$head Float$$
this type can either be $codei%AD<%Base%>%$$,
or it can be $icode Base$$ for any $codei%AD<%Base%>%$$ type.
$head eps$$
The result $icode eps$$ has prototype
$codei%
%Float% eps
%$$
$end
------------------------------------------------------------------------------
*/
namespace CppAD {
template <class Type>
inline Type epsilon(void)
{ return Type ( numeric_limits<Type>::epsilon() ); }
}
# endif

View File

@ -1,119 +0,0 @@
# ifndef CPPAD_CORE_EQUAL_OP_SEQ_HPP
# define CPPAD_CORE_EQUAL_OP_SEQ_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 EqualOpSeq$$
$spell
Op
const
bool
$$
$section Check if Two Value are Identically Equal$$
$mindex EqualOpSeq operation sequence$$
$head Syntax$$
$icode%b% = EqualOpSeq(%x%, %y%)%$$
$head Purpose$$
Determine if two $icode x$$ and $icode y$$ are identically equal; i.e.,
not only is $icode%x% == %y%$$ true, but
if they are $cref/variables/glossary/Variable/$$,
they correspond have the same
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Motivation$$
Sometimes it is useful to cache information
and only recalculate when a function's arguments change.
In the case of AD variables,
it may be important not only when the argument values are equal,
but when they are related to the
$cref/independent variables/glossary/Tape/Independent Variable/$$
by the same operation sequence.
After the assignment
$codei%
%y% = %x%
%$$
these two AD objects would not only have equal values,
but would also correspond to the same operation sequence.
$head x$$
The argument $icode x$$ has prototype
$codei%
const AD<%Base%> &%x%
%$$
$head y$$
The argument $icode y$$ has prototype
$codei%
const AD<%Base%> &%y%
%$$
$head b$$
The result $icode b$$ has prototype
$codei%
bool %b%
%$$
The result is true if and only if one of the following cases holds:
$list number$$
Both $icode x$$ and $icode y$$ are variables
and correspond to the same operation sequence.
$lnext
Both $icode x$$ and $icode y$$ are parameters,
$icode Base$$ is an AD type,
and $codei%EqualOpSeq( Value(%x%) , Value(%y%) )%$$ is true.
$lnext
Both $icode x$$ and $icode y$$ are parameters,
$icode Base$$ is not an AD type,
and $icode%x% == %y%%$$ is true.
$lend
$head Example$$
$children%
example/general/equal_op_seq.cpp
%$$
The file
$cref equal_op_seq.cpp$$
contains an example and test of $code EqualOpSeq$$.
It returns true if it succeeds and false otherwise.
$end
------------------------------------------------------------------------------
*/
namespace CppAD {
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool EqualOpSeq(const AD<Base> &x, const AD<Base> &y)
{
if( Parameter(x) )
{ if( Parameter(y) )
return EqualOpSeq(x.value_, y.value_);
else return false;
}
else if( Parameter(y) )
return false;
return (x.taddr_ == y.taddr_);
}
}
# endif

View File

@ -1,106 +0,0 @@
# ifndef CPPAD_CORE_ERF_HPP
# define CPPAD_CORE_ERF_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 erf$$
$spell
erf
const
Vec
std
cmath
CppAD
Vedder
$$
$section The Error Function$$
$head Syntax$$
$icode%y% = erf(%x%)%$$
$head Description$$
Returns the value of the error function which is defined by
$latex \[
{\rm erf} (x) = \frac{2}{ \sqrt{\pi} } \int_0^x \exp( - t * t ) \; {\bf d} t
\] $$
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head CPPAD_USE_CPLUSPLUS_2011$$
$subhead true$$
If this preprocessor symbol is true ($code 1$$),
and $icode x$$ is an AD type,
this is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$subhead false$$
If this preprocessor symbol is false ($code 0$$),
CppAD uses a fast approximation (few numerical operations)
with relative error bound $latex 4 \times 10^{-4}$$; see
Vedder, J.D.,
$icode Simple approximations for the error function and its inverse$$,
American Journal of Physics,
v 55,
n 8,
1987,
p 762-3.
$head Example$$
$children%
example/general/erf.cpp
%$$
The file
$cref erf.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
# include <cppad/configure.hpp>
# if ! CPPAD_USE_CPLUSPLUS_2011
// BEGIN CppAD namespace
namespace CppAD {
template <class Type>
Type erf_template(const Type &x)
{ using CppAD::exp;
const Type a = static_cast<Type>(993./880.);
const Type b = static_cast<Type>(89./880.);
return tanh( (a + b * x * x) * x );
}
inline float erf(const float &x)
{ return erf_template(x); }
inline double erf(const double &x)
{ return erf_template(x); }
template <class Base>
inline AD<Base> erf(const AD<Base> &x)
{ return erf_template(x); }
template <class Base>
inline AD<Base> erf(const VecAD_reference<Base> &x)
{ return erf_template( x.ADBase() ); }
} // END CppAD namespace
# endif // CPPAD_USE_CPLUSPLUS_2011
# endif // CPPAD_ERF_INCLUDED

View File

@ -1,96 +0,0 @@
# ifndef CPPAD_CORE_EXPM1_HPP
# define CPPAD_CORE_EXPM1_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 expm1$$
$spell
exp
expm1
const
Vec
std
cmath
CppAD
$$
$section The Exponential Function Minus One: expm1$$
$head Syntax$$
$icode%y% = expm1(%x%)%$$
$head Description$$
Returns the value of the exponential function minus one which is defined
by $icode%y% == exp(%x%) - 1%$$.
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head CPPAD_USE_CPLUSPLUS_2011$$
$subhead true$$
If this preprocessor symbol is true ($code 1$$),
and $icode x$$ is an AD type,
this is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$subhead false$$
If this preprocessor symbol is false ($code 0$$),
CppAD uses the representation
$latex \[
\R{expm1} (x) = \exp(x) - 1
\] $$
to compute this function.
$head Example$$
$children%
example/general/expm1.cpp
%$$
The file
$cref expm1.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
# include <cppad/configure.hpp>
# if ! CPPAD_USE_CPLUSPLUS_2011
// BEGIN CppAD namespace
namespace CppAD {
template <class Type>
Type expm1_template(const Type &x)
{ return CppAD::exp(x) - Type(1);
}
inline float expm1(const float &x)
{ return expm1_template(x); }
inline double expm1(const double &x)
{ return expm1_template(x); }
template <class Base>
inline AD<Base> expm1(const AD<Base> &x)
{ return expm1_template(x); }
template <class Base>
inline AD<Base> expm1(const VecAD_reference<Base> &x)
{ return expm1_template( x.ADBase() ); }
} // END CppAD namespace
# endif // CPPAD_USE_CPLUSPLUS_2011
# endif // CPPAD_EXPM1_INCLUDED

View File

@ -1,302 +0,0 @@
# ifndef CPPAD_CORE_FOR_HES_SPARSITY_HPP
# define CPPAD_CORE_FOR_HES_SPARSITY_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 for_hes_sparsity$$
$spell
Andrea Walther
Jacobian
Hessian
jac
hes
bool
const
rc
cpp
$$
$section Forward Mode Hessian Sparsity Patterns$$
$head Syntax$$
$icode%f%.for_hes_sparsity(
%select_domain%, %select_range%, %internal_bool%, %pattern_out%
)%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to
the operation sequence stored in $icode f$$.
Fix a diagonal matrix $latex D \in \B{R}^{n \times n}$$,
a vector $latex s \in \B{R}^m$$ and define the function
$latex \[
H(x) = D ( s^\R{T} F )^{(2)} ( x ) D
\] $$
Given the sparsity for $latex D$$ and $latex s$$,
$code for_hes_sparsity$$ computes a sparsity pattern for $latex H(x)$$.
$head x$$
Note that the sparsity pattern $latex H(x)$$ corresponds to the
operation sequence stored in $icode f$$ and does not depend on
the argument $icode x$$.
$head BoolVector$$
The type $icode BoolVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code bool$$.
$head SizeVector$$
The type $icode SizeVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
$head select_domain$$
The argument $icode diagonal$$ has prototype
$codei%
const %BoolVector%& %select_domain%
%$$
It has size $latex n$$ and specifies which components of the diagonal of
$latex D$$ are non-zero; i.e., $icode%select_domain%[%j%]%$$ is true
if and only if $latex D_{j,j}$$ is possibly non-zero.
$head select_range$$
The argument $icode select_range$$ has prototype
$codei%
const %BoolVector%& %select_range%
%$$
It has size $latex m$$ and specifies which components of the vector
$latex s$$ are non-zero; i.e., $icode%select_range%[%i%]%$$ is true
if and only if $latex s_i$$ is possibly non-zero.
$head internal_bool$$
If this is true, calculations are done with sets represented by a vector
of boolean values. Otherwise, a vector of sets of integers is used.
$head pattern_out$$
This argument has prototype
$codei%
sparse_rc<%SizeVector%>& %pattern_out%
%$$
This input value of $icode pattern_out$$ does not matter.
Upon return $icode pattern_out$$ is a sparsity pattern for $latex H(x)$$.
$head Sparsity for Entire Hessian$$
Suppose that $latex R$$ is the $latex n \times n$$ identity matrix.
In this case, $icode pattern_out$$ is a sparsity pattern for
$latex (s^\R{T} F) F^{(2)} ( x )$$.
$head Algorithm$$
See Algorithm II in
$italic Computing sparse Hessians with automatic differentiation$$
by Andrea Walther.
Note that $icode s$$ provides the information so that
'dead ends' are not included in the sparsity pattern.
$head Example$$
$children%
example/sparse/for_hes_sparsity.cpp
%$$
The file $cref for_hes_sparsity.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/core/ad_fun.hpp>
# include <cppad/local/sparse_internal.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Forward Hessian sparsity patterns.
\tparam Base
is the base type for this recording.
\tparam BoolVector
is the simple vector with elements of type bool that is used for
sparsity for the vector s.
\tparam SizeVector
is the simple vector with elements of type size_t that is used for
row, column index sparsity patterns.
\param select_domain
is a sparsity pattern for for the diagonal of D.
\param select_range
is a sparsity pattern for for s.
\param internal_bool
If this is true, calculations are done with sets represented by a vector
of boolean values. Otherwise, a vector of standard sets is used.
\param pattern_out
The return value is a sparsity pattern for H(x) where
\f[
H(x) = D * F^{(1)} (x) * D
\f]
Here F is the function corresponding to the operation sequence
and x is any argument value.
*/
template <class Base>
template <class BoolVector, class SizeVector>
void ADFun<Base>::for_hes_sparsity(
const BoolVector& select_domain ,
const BoolVector& select_range ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out )
{ size_t n = Domain();
size_t m = Range();
//
CPPAD_ASSERT_KNOWN(
size_t( select_domain.size() ) == n,
"for_hes_sparsity: size of select_domain is not equal to "
"number of independent variables"
);
CPPAD_ASSERT_KNOWN(
size_t( select_range.size() ) == m,
"for_hes_sparsity: size of select_range is not equal to "
"number of dependent variables"
);
// do not need transpose or depenency
bool transpose = false;
bool dependency = false;
//
sparse_rc<SizeVector> pattern_tmp;
if( internal_bool )
{ // forward Jacobian sparsity pattern for independent variables
local::sparse_pack internal_for_jac;
internal_for_jac.resize(num_var_tape_, n + 1 );
for(size_t j = 0; j < n; j++) if( select_domain[j] )
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < n + 1 );
internal_for_jac.add_element( ind_taddr_[j] , ind_taddr_[j] );
}
// forward Jacobian sparsity for all variables on tape
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
internal_for_jac
);
// reverse Jacobian sparsity pattern for select_range
local::sparse_pack internal_rev_jac;
internal_rev_jac.resize(num_var_tape_, 1);
for(size_t i = 0; i < m; i++) if( select_range[i] )
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
internal_rev_jac.add_element( dep_taddr_[i] , 0 );
}
// reverse Jacobian sparsity for all variables on tape
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
internal_rev_jac
);
// internal vector of sets that will hold Hessian
local::sparse_pack internal_for_hes;
internal_for_hes.resize(n + 1, n + 1);
//
// compute forward Hessian sparsity pattern
local::ForHesSweep(
n,
num_var_tape_,
&play_,
internal_for_jac,
internal_rev_jac,
internal_for_hes
);
//
// put the result in pattern_tmp
get_internal_sparsity(
transpose, ind_taddr_, internal_for_hes, pattern_tmp
);
}
else
{ // forward Jacobian sparsity pattern for independent variables
// (corresponds to D)
local::sparse_list internal_for_jac;
internal_for_jac.resize(num_var_tape_, n + 1 );
for(size_t j = 0; j < n; j++) if( select_domain[j] )
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < n + 1 );
internal_for_jac.add_element( ind_taddr_[j] , ind_taddr_[j] );
}
// forward Jacobian sparsity for all variables on tape
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
internal_for_jac
);
// reverse Jacobian sparsity pattern for select_range
// (corresponds to s)
local::sparse_list internal_rev_jac;
internal_rev_jac.resize(num_var_tape_, 1);
for(size_t i = 0; i < m; i++) if( select_range[i] )
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
internal_rev_jac.add_element( dep_taddr_[i] , 0 );
}
// reverse Jacobian sparsity for all variables on tape
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
internal_rev_jac
);
// internal vector of sets that will hold Hessian
local::sparse_list internal_for_hes;
internal_for_hes.resize(n + 1, n + 1);
//
// compute forward Hessian sparsity pattern
local::ForHesSweep(
n,
num_var_tape_,
&play_,
internal_for_jac,
internal_rev_jac,
internal_for_hes
);
//
// put the result in pattern_tmp
get_internal_sparsity(
transpose, ind_taddr_, internal_for_hes, pattern_tmp
);
}
// subtract 1 from all column values
CPPAD_ASSERT_UNKNOWN( pattern_tmp.nr() == n );
CPPAD_ASSERT_UNKNOWN( pattern_tmp.nc() == n + 1 );
const SizeVector& row( pattern_tmp.row() );
const SizeVector& col( pattern_tmp.col() );
size_t nr = n;
size_t nc = n;
size_t nnz = pattern_tmp.nnz();
pattern_out.resize(nr, nc, nnz);
for(size_t k = 0; k < nnz; k++)
{ CPPAD_ASSERT_UNKNOWN( 0 < col[k] );
pattern_out.set(k, row[k], col[k] - 1);
}
return;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,294 +0,0 @@
# ifndef CPPAD_CORE_FOR_JAC_SPARSITY_HPP
# define CPPAD_CORE_FOR_JAC_SPARSITY_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 for_jac_sparsity$$
$spell
Jacobian
jac
bool
const
rc
cpp
$$
$section Forward Mode Jacobian Sparsity Patterns$$
$head Syntax$$
$icode%f%.for_jac_sparsity(
%pattern_in%, %transpose%, %dependency%, %internal_bool%, %pattern_out%
)%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to
the operation sequence stored in $icode f$$.
Fix $latex R \in \B{R}^{n \times \ell}$$ and define the function
$latex \[
J(x) = F^{(1)} ( x ) * R
\] $$
Given the $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$,
$code for_jac_sparsity$$ computes a sparsity pattern for $latex J(x)$$.
$head x$$
Note that the sparsity pattern $latex J(x)$$ corresponds to the
operation sequence stored in $icode f$$ and does not depend on
the argument $icode x$$.
(The operation sequence may contain
$cref CondExp$$ and $cref VecAD$$ operations.)
$head SizeVector$$
The type $icode SizeVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
The $cref ADFun$$ object $icode f$$ is not $code const$$.
After a call to $code for_jac_sparsity$$, a sparsity pattern
for each of the variables in the operation sequence
is held in $icode f$$ for possible later use during
reverse Hessian sparsity calculations.
$subhead size_forward_bool$$
After $code for_jac_sparsity$$, if $icode k$$ is a $code size_t$$ object,
$codei%
%k% = %f%.size_forward_bool()
%$$
sets $icode k$$ to the amount of memory (in unsigned character units)
used to store the
$cref/boolean vector/glossary/Sparsity Pattern/Boolean Vector/$$
sparsity patterns.
If $icode internal_bool$$ if false, $icode k$$ will be zero.
Otherwise it will be non-zero.
If you do not need this information for $cref RevSparseHes$$
calculations, it can be deleted
(and the corresponding memory freed) using
$codei%
%f%.size_forward_bool(0)
%$$
after which $icode%f%.size_forward_bool()%$$ will return zero.
$subhead size_forward_set$$
After $code for_jac_sparsity$$, if $icode k$$ is a $code size_t$$ object,
$codei%
%k% = %f%.size_forward_set()
%$$
sets $icode k$$ to the amount of memory (in unsigned character units)
used to store the
$cref/vector of sets/glossary/Sparsity Pattern/Vector of Sets/$$
sparsity patterns.
If $icode internal_bool$$ if true, $icode k$$ will be zero.
Otherwise it will be non-zero.
If you do not need this information for future $cref rev_hes_sparsity$$
calculations, it can be deleted
(and the corresponding memory freed) using
$codei%
%f%.size_forward_set(0)
%$$
after which $icode%f%.size_forward_set()%$$ will return zero.
$head pattern_in$$
The argument $icode pattern_in$$ has prototype
$codei%
const sparse_rc<%SizeVector%>& %pattern_in%
%$$
see $cref sparse_rc$$.
If $icode transpose$$ it is false (true),
$icode pattern_in$$ is a sparsity pattern for $latex R$$ ($latex R^\R{T}$$).
$head transpose$$
This argument has prototype
$codei%
bool %transpose%
%$$
See $cref/pattern_in/for_jac_sparsity/pattern_in/$$ above and
$cref/pattern_out/for_jac_sparsity/pattern_out/$$ below.
$head dependency$$
This argument has prototype
$codei%
bool %dependency%
%$$
see $cref/pattern_out/for_jac_sparsity/pattern_out/$$ below.
$head internal_bool$$
If this is true, calculations are done with sets represented by a vector
of boolean values. Otherwise, a vector of sets of integers is used.
$head pattern_out$$
This argument has prototype
$codei%
sparse_rc<%SizeVector%>& %pattern_out%
%$$
This input value of $icode pattern_out$$ does not matter.
If $icode transpose$$ it is false (true),
upon return $icode pattern_out$$ is a sparsity pattern for
$latex J(x)$$ ($latex J(x)^\R{T}$$).
If $icode dependency$$ is true, $icode pattern_out$$ is a
$cref/dependency pattern/dependency.cpp/Dependency Pattern/$$
instead of sparsity pattern.
$head Sparsity for Entire Jacobian$$
Suppose that
$latex R$$ is the $latex n \times n$$ identity matrix.
In this case, $icode pattern_out$$ is a sparsity pattern for
$latex F^{(1)} ( x )$$ ( $latex F^{(1)} (x)^\R{T}$$ )
if $icode transpose$$ is false (true).
$head Example$$
$children%
example/sparse/for_jac_sparsity.cpp
%$$
The file
$cref for_jac_sparsity.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/core/ad_fun.hpp>
# include <cppad/local/sparse_internal.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Forward Jacobian sparsity patterns.
\tparam Base
is the base type for this recording.
\tparam SizeVector
is the simple vector with elements of type size_t that is used for
row, column index sparsity patterns.
\param pattern_in
is the sparsity pattern for for R or R^T depending on transpose.
\param transpose
Is the input and returned sparsity pattern transposed.
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\param internal_bool
If this is true, calculations are done with sets represented by a vector
of boolean values. Othewise, a vector of standard sets is used.
\param pattern_out
The value of transpose is false (true),
the return value is a sparsity pattern for J(x) ( J(x)^T ) where
\f[
J(x) = F^{(1)} (x) * R
\f]
Here F is the function corresponding to the operation sequence
and x is any argument value.
*/
template <class Base>
template <class SizeVector>
void ADFun<Base>::for_jac_sparsity(
const sparse_rc<SizeVector>& pattern_in ,
bool transpose ,
bool dependency ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out )
{ // number or rows, columns, and non-zeros in pattern_in
size_t nr_in = pattern_in.nr();
size_t nc_in = pattern_in.nc();
//
size_t n = nr_in;
size_t ell = nc_in;
if( transpose )
std::swap(n, ell);
//
CPPAD_ASSERT_KNOWN(
n == Domain() ,
"for_jac_sparsity: number rows in R "
"is not equal number of independent variables."
);
bool zero_empty = true;
bool input_empty = true;
if( internal_bool )
{ // allocate memory for bool sparsity calculation
// (sparsity pattern is emtpy after a resize)
for_jac_sparse_pack_.resize(num_var_tape_, ell);
for_jac_sparse_set_.resize(0, 0);
//
// set sparsity patttern for independent variables
local::set_internal_sparsity(
zero_empty ,
input_empty ,
transpose ,
ind_taddr_ ,
for_jac_sparse_pack_ ,
pattern_in
);
// compute sparsity for other variables
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
for_jac_sparse_pack_
);
// set the output pattern
local::get_internal_sparsity(
transpose, dep_taddr_, for_jac_sparse_pack_, pattern_out
);
}
else
{
// allocate memory for set sparsity calculation
// (sparsity pattern is emtpy after a resize)
for_jac_sparse_set_.resize(num_var_tape_, ell);
for_jac_sparse_pack_.resize(0, 0);
//
// set sparsity patttern for independent variables
local::set_internal_sparsity(
zero_empty ,
input_empty ,
transpose ,
ind_taddr_ ,
for_jac_sparse_set_ ,
pattern_in
);
// compute sparsity for other variables
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
for_jac_sparse_set_
);
// get the ouput pattern
local::get_internal_sparsity(
transpose, dep_taddr_, for_jac_sparse_set_, pattern_out
);
}
return;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,164 +0,0 @@
# ifndef CPPAD_CORE_FOR_ONE_HPP
# define CPPAD_CORE_FOR_ONE_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 ForOne$$
$spell
dy
typename
Taylor
const
$$
$section First Order Partial Derivative: Driver Routine$$
$mindex easy$$
$head Syntax$$
$icode%dy% = %f%.ForOne(%x%, %j%)%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
The syntax above sets $icode dy$$ to the
partial of $latex F$$ with respect to $latex x_j$$; i.e.,
$latex \[
dy
= \D{F}{ x_j } (x)
= \left[
\D{ F_0 }{ x_j } (x) , \cdots , \D{ F_{m-1} }{ x_j } (x)
\right]
\] $$
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/ForOne Uses Forward/ForOne/ForOne Uses Forward/$$ below).
$head x$$
The argument $icode x$$ has prototype
$codei%
const %Vector% &%x%
%$$
(see $cref/Vector/ForOne/Vector/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies
that point at which to evaluate the partial derivative.
$head j$$
The argument $icode j$$ has prototype
$codei%
size_t %j%
%$$
an is less than $icode n$$,
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies the component of $icode F$$
for which we are computing the partial derivative.
$head dy$$
The result $icode dy$$ has prototype
$codei%
%Vector% %dy%
%$$
(see $cref/Vector/ForOne/Vector/$$ below)
and its size is $latex m$$, the dimension of the
$cref/range/seq_property/Range/$$ space for $icode f$$.
The value of $icode dy$$ is the partial of $latex F$$ with respect to
$latex x_j$$ evaluated at $icode x$$; i.e.,
for $latex i = 0 , \ldots , m - 1$$
$latex \[.
dy[i] = \D{ F_i }{ x_j } ( x )
\] $$
$head Vector$$
The type $icode Vector$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$icode Base$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head ForOne Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code ForOne$$,
the zero order Taylor coefficients correspond to
$icode%f%.Forward(0,%x%)%$$
and the other coefficients are unspecified.
$head Example$$
$children%
example/general/for_one.cpp
%$$
The routine
$cref/ForOne/for_one.cpp/$$ is both an example and test.
It returns $code true$$, if it succeeds and $code false$$ otherwise.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <typename Base>
template <typename Vector>
Vector ADFun<Base>::ForOne(const Vector &x, size_t j)
{ size_t j1;
size_t n = Domain();
size_t m = Range();
// check Vector is Simple Vector class with Base type elements
CheckSimpleVector<Base, Vector>();
CPPAD_ASSERT_KNOWN(
x.size() == n,
"ForOne: Length of x not equal domain dimension for f"
);
CPPAD_ASSERT_KNOWN(
j < n,
"ForOne: the index j is not less than domain dimension for f"
);
// point at which we are evaluating the second partials
Forward(0, x);
// direction in which are are taking the derivative
Vector dx(n);
for(j1 = 0; j1 < n; j1++)
dx[j1] = Base(0.0);
dx[j] = Base(1.0);
// dimension the return value
Vector dy(m);
// compute the return value
dy = Forward(1, dx);
return dy;
}
} // END CppAD namespace
# endif

View File

@ -1,559 +0,0 @@
# ifndef CPPAD_CORE_FOR_SPARSE_HES_HPP
# define CPPAD_CORE_FOR_SPARSE_HES_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 ForSparseHes$$
$spell
Andrea Walther
std
VecAD
Jacobian
Jac
Hessian
Hes
const
Bool
Dep
proportional
var
cpp
$$
$section Hessian Sparsity Pattern: Forward Mode$$
$head Syntax$$
$icode%h% = %f%.ForSparseHes(%r%, %s%)
%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
we define
$latex \[
\begin{array}{rcl}
H(x)
& = & \partial_x \left[ \partial_u S \cdot F[ x + R \cdot u ] \right]_{u=0}
\\
& = & R^\R{T} \cdot (S \cdot F)^{(2)} ( x ) \cdot R
\end{array}
\] $$
Where $latex R \in \B{R}^{n \times n}$$ is a diagonal matrix
and $latex S \in \B{R}^{1 \times m}$$ is a row vector.
Given a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the diagonal of $latex R$$ and the vector $latex S$$,
$code ForSparseHes$$ returns a sparsity pattern for the $latex H(x)$$.
$head f$$
The object $icode f$$ has prototype
$codei%
const ADFun<%Base%> %f%
%$$
$head x$$
If the operation sequence in $icode f$$ is
$cref/independent/glossary/Operation/Independent/$$ of
the independent variables in $latex x \in B^n$$,
the sparsity pattern is valid for all values of
(even if it has $cref CondExp$$ or $cref VecAD$$ operations).
$head r$$
The argument $icode r$$ has prototype
$codei%
const %VectorSet%& %r%
%$$
(see $cref/VectorSet/ForSparseHes/VectorSet/$$ below)
If it has elements of type $code bool$$,
its size is $latex n$$.
If it has elements of type $code std::set<size_t>$$,
its size is one and all the elements of $icode%s%[0]%$$
are between zero and $latex n - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the diagonal of $latex R$$.
The fewer non-zero elements in this sparsity pattern,
the faster the calculation should be and the more sparse
$latex H(x)$$ should be.
$head s$$
The argument $icode s$$ has prototype
$codei%
const %VectorSet%& %s%
%$$
(see $cref/VectorSet/ForSparseHes/VectorSet/$$ below)
If it has elements of type $code bool$$,
its size is $latex m$$.
If it has elements of type $code std::set<size_t>$$,
its size is one and all the elements of $icode%s%[0]%$$
are between zero and $latex m - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the vector $icode S$$.
The fewer non-zero elements in this sparsity pattern,
the faster the calculation should be and the more sparse
$latex H(x)$$ should be.
$head h$$
The result $icode h$$ has prototype
$codei%
%VectorSet%& %h%
%$$
(see $cref/VectorSet/ForSparseHes/VectorSet/$$ below).
If $icode h$$ has elements of type $code bool$$,
its size is $latex n * n$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex n$$ and all the set elements are between
zero and $icode%n%-1%$$ inclusive.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex H(x)$$.
$head VectorSet$$
The type $icode VectorSet$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code bool$$ or $code std::set<size_t>$$;
see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion
of the difference.
The type of the elements of
$cref/VectorSet/ForSparseHes/VectorSet/$$ must be the
same as the type of the elements of $icode r$$.
$head Algorithm$$
See Algorithm II in
$italic Computing sparse Hessians with automatic differentiation$$
by Andrea Walther.
Note that $icode s$$ provides the information so that
'dead ends' are not included in the sparsity pattern.
$head Example$$
$children%
example/sparse/for_sparse_hes.cpp
%$$
The file
$cref for_sparse_hes.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <algorithm>
# include <cppad/local/pod_vector.hpp>
# include <cppad/local/std_set.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file for_sparse_hes.hpp
Forward mode Hessian sparsity patterns.
*/
// ===========================================================================
// ForSparseHesCase
/*!
Private helper function for ForSparseHes(q, s) bool sparsity.
All of the description in the public member function ForSparseHes(q, s)
applies.
\param set_type
is a \c bool value. This argument is used to dispatch to the proper source
code depending on the vlaue of \c VectorSet::value_type.
\param r
See \c ForSparseHes(r, s).
\param s
See \c ForSparseHes(r, s).
\param h
is the return value for the corresponging call to \c ForSparseJac(q, s).
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::ForSparseHesCase(
bool set_type ,
const VectorSet& r ,
const VectorSet& s ,
VectorSet& h )
{ size_t n = Domain();
size_t m = Range();
//
// check Vector is Simple VectorSet class with bool elements
CheckSimpleVector<bool, VectorSet>();
//
CPPAD_ASSERT_KNOWN(
size_t(r.size()) == n,
"ForSparseHes: size of r is not equal to\n"
"domain dimension for ADFun object."
);
CPPAD_ASSERT_KNOWN(
size_t(s.size()) == m,
"ForSparseHes: size of s is not equal to\n"
"range dimension for ADFun object."
);
//
// sparsity pattern corresponding to r
local::sparse_pack for_jac_pattern;
for_jac_pattern.resize(num_var_tape_, n + 1);
for(size_t i = 0; i < n; i++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 );
// ind_taddr_[i] is operator taddr for i-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
//
if( r[i] )
for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] );
}
// compute forward Jacobiain sparsity pattern
bool dependency = false;
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
for_jac_pattern
);
// sparsity pattern correspnding to s
local::sparse_pack rev_jac_pattern;
rev_jac_pattern.resize(num_var_tape_, 1);
for(size_t i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
if( s[i] )
rev_jac_pattern.add_element( dep_taddr_[i], 0);
}
// compute reverse sparsity pattern for dependency analysis
// (note that we are only want non-zero derivatives not true dependency)
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
rev_jac_pattern
);
// vector of sets that will hold the forward Hessain values
local::sparse_pack for_hes_pattern;
for_hes_pattern.resize(n+1, n+1);
//
// compute the Hessian sparsity patterns
local::ForHesSweep(
n,
num_var_tape_,
&play_,
for_jac_pattern,
rev_jac_pattern,
for_hes_pattern
);
// initialize return values corresponding to independent variables
h.resize(n * n);
for(size_t i = 0; i < n; i++)
{ for(size_t j = 0; j < n; j++)
h[ i * n + j ] = false;
}
// copy to result pattern
CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );
for(size_t i = 0; i < n; i++)
{ // ind_taddr_[i] is operator taddr for i-th independent variable
CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
// extract the result from for_hes_pattern
local::sparse_pack::const_iterator itr(for_hes_pattern, ind_taddr_[i] );
size_t j = *itr;
while( j < for_hes_pattern.end() )
{ CPPAD_ASSERT_UNKNOWN( 0 < j )
h[ i * n + (j-1) ] = true;
j = *(++itr);
}
}
}
/*!
Private helper function for ForSparseHes(q, s) set sparsity.
All of the description in the public member function ForSparseHes(q, s)
applies.
\param set_type
is a \c std::set<size_t> value.
This argument is used to dispatch to the proper source
code depending on the vlaue of \c VectorSet::value_type.
\param r
See \c ForSparseHes(r, s).
\param s
See \c ForSparseHes(q, s).
\param h
is the return value for the corresponging call to \c ForSparseJac(q, s).
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::ForSparseHesCase(
const std::set<size_t>& set_type ,
const VectorSet& r ,
const VectorSet& s ,
VectorSet& h )
{ size_t n = Domain();
# ifndef NDEBUG
size_t m = Range();
# endif
std::set<size_t>::const_iterator itr_1;
//
// check VectorSet is Simple Vector class with sets for elements
CheckSimpleVector<std::set<size_t>, VectorSet>(
local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()
);
CPPAD_ASSERT_KNOWN(
r.size() == 1,
"ForSparseHes: size of s is not equal to one."
);
CPPAD_ASSERT_KNOWN(
s.size() == 1,
"ForSparseHes: size of s is not equal to one."
);
//
// sparsity pattern corresponding to r
local::sparse_list for_jac_pattern;
for_jac_pattern.resize(num_var_tape_, n + 1);
itr_1 = r[0].begin();
while( itr_1 != r[0].end() )
{ size_t i = *itr_1++;
CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 );
// ind_taddr_[i] is operator taddr for i-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
//
for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] );
}
// compute forward Jacobiain sparsity pattern
bool dependency = false;
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
for_jac_pattern
);
// sparsity pattern correspnding to s
local::sparse_list rev_jac_pattern;
rev_jac_pattern.resize(num_var_tape_, 1);
itr_1 = s[0].begin();
while( itr_1 != s[0].end() )
{ size_t i = *itr_1++;
CPPAD_ASSERT_KNOWN(
i < m,
"ForSparseHes: an element of the set s[0] has value "
"greater than or equal m"
);
CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
rev_jac_pattern.add_element( dep_taddr_[i], 0);
}
//
// compute reverse sparsity pattern for dependency analysis
// (note that we are only want non-zero derivatives not true dependency)
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
rev_jac_pattern
);
//
// vector of sets that will hold reverse Hessain values
local::sparse_list for_hes_pattern;
for_hes_pattern.resize(n+1, n+1);
//
// compute the Hessian sparsity patterns
local::ForHesSweep(
n,
num_var_tape_,
&play_,
for_jac_pattern,
rev_jac_pattern,
for_hes_pattern
);
// return values corresponding to independent variables
// j is index corresponding to reverse mode partial
h.resize(n);
CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );
for(size_t i = 0; i < n; i++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
// extract the result from for_hes_pattern
local::sparse_list::const_iterator itr_2(for_hes_pattern, ind_taddr_[i] );
size_t j = *itr_2;
while( j < for_hes_pattern.end() )
{ CPPAD_ASSERT_UNKNOWN( 0 < j )
h[i].insert(j-1);
j = *(++itr_2);
}
}
}
// ===========================================================================
// ForSparseHes
/*!
User API for Hessian sparsity patterns using reverse mode.
The C++ source code corresponding to this operation is
\verbatim
h = f.ForSparseHes(q, r)
\endverbatim
\tparam Base
is the base type for this recording.
\tparam VectorSet
is a simple vector with elements of type \c bool
or \c std::set<size_t>.
\param r
is a vector with size \c n that specifies the sparsity pattern
for the diagonal of the matrix \f$ R \f$,
where \c n is the number of independent variables
corresponding to the operation sequence stored in \a play.
\param s
is a vector with size \c m that specifies the sparsity pattern
for the vector \f$ S \f$,
where \c m is the number of dependent variables
corresponding to the operation sequence stored in \a play.
\return
The return vector is a sparsity pattern for \f$ H(x) \f$
\f[
H(x) = R^T ( S * F)^{(2)} (x) R
\f]
where \f$ F \f$ is the function corresponding to the operation sequence
and \a x is any argument value.
*/
template <class Base>
template <class VectorSet>
VectorSet ADFun<Base>::ForSparseHes(
const VectorSet& r, const VectorSet& s
)
{ VectorSet h;
typedef typename VectorSet::value_type Set_type;
// Should check to make sure q is same as in previous call to
// forward sparse Jacobian.
ForSparseHesCase(
Set_type() ,
r ,
s ,
h
);
return h;
}
// ===========================================================================
// ForSparseHesCheckpoint
/*!
Hessian sparsity patterns calculation used by checkpoint functions.
\tparam Base
is the base type for this recording.
\param r
is a vector with size n that specifies the sparsity pattern
for the diagonal of \f$ R \f$,
where n is the number of independent variables
corresponding to the operation sequence stored in play_.
\param s
is a vector with size m that specifies the sparsity pattern
for the vector \f$ S \f$,
where m is the number of dependent variables
corresponding to the operation sequence stored in play_.
\param h
The input size and elements of h do not matter.
On output, h is the sparsity pattern for the matrix \f$ H(x) R \f$.
\par Assumptions
The forward jacobian sparsity pattern must be currently stored
in this ADFUN object.
*/
// The checkpoint class is not yet using forward sparse Hessians.
# ifdef CPPAD_NOT_DEFINED
template <class Base>
void ADFun<Base>::ForSparseHesCheckpoint(
vector<bool>& r ,
vector<bool>& s ,
local::sparse_list& h )
{
size_t n = Domain();
size_t m = Range();
// checkpoint functions should get this right
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 );
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == 0 );
CPPAD_ASSERT_UNKNOWN( s.size() == m );
// Array that holds the reverse Jacobiain dependcy flags.
// Initialize as true for dependent variables, flase for others.
local::pod_vector<bool> RevJac;
RevJac.extend(num_var_tape_);
for(size_t i = 0; i < num_var_tape_; i++)
RevJac[i] = false;
for(size_t i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ )
RevJac[ dep_taddr_[i] ] = s[i];
}
// holds forward Hessian sparsity pattern for all variables
local::sparse_list for_hes_pattern;
for_hes_pattern.resize(n+1, n+1);
// compute Hessian sparsity pattern for all variables
local::ForHesSweep(
n,
num_var_tape_,
&play_,
for_jac_sparse_set_,
RevJac.data(),
for_hes_pattern
);
// dimension the return value
if( transpose )
h.resize(n, n);
else
h.resize(n, n);
// j is index corresponding to reverse mode partial
for(size_t j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
// extract the result from for_hes_pattern
CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == q );
local::sparse_list::const_iterator itr(for_hes_pattern, .j + 1);
size_t i = *itr;
while( i < q )
{ if( transpose )
h.add_element(j, i);
else h.add_element(i, j);
i = *(++itr);
}
}
}
# endif
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,729 +0,0 @@
# ifndef CPPAD_CORE_FOR_SPARSE_JAC_HPP
# define CPPAD_CORE_FOR_SPARSE_JAC_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 ForSparseJac$$
$spell
std
var
Jacobian
Jac
const
Bool
proportional
VecAD
CondExpRel
optimizer
cpp
$$
$section Jacobian Sparsity Pattern: Forward Mode$$
$head Syntax$$
$icode%s% = %f%.ForSparseJac(%q%, %r%)
%$$
$icode%s% = %f%.ForSparseJac(%q%, %r%, %transpose%, %dependency%)%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
For a fixed $latex n \times q$$ matrix $latex R$$,
the Jacobian of $latex F[ x + R * u ]$$
with respect to $latex u$$ at $latex u = 0$$ is
$latex \[
S(x) = F^{(1)} ( x ) * R
\] $$
Given a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for $latex R$$,
$code ForSparseJac$$ returns a sparsity pattern for the $latex S(x)$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$.
After a call to $code ForSparseJac$$, the sparsity pattern
for each of the variables in the operation sequence
is held in $icode f$$ (for possible later use by $cref RevSparseHes$$).
These sparsity patterns are stored with elements of type $code bool$$
or elements of type $code std::set<size_t>$$
(see $cref/VectorSet/ForSparseJac/VectorSet/$$ below).
$subhead size_forward_bool$$
After $code ForSparseJac$$, if $icode k$$ is a $code size_t$$ object,
$codei%
%k% = %f%.size_forward_bool()
%$$
sets $icode k$$ to the amount of memory (in unsigned character units)
used to store the sparsity pattern with elements of type $code bool$$
in the function object $icode f$$.
If the sparsity patterns for the previous $code ForSparseJac$$ used
elements of type $code bool$$,
the return value for $code size_forward_bool$$ will be non-zero.
Otherwise, its return value will be zero.
This sparsity pattern is stored for use by $cref RevSparseHes$$ and
when it is not longer needed, it can be deleted
(and the corresponding memory freed) using
$codei%
%f%.size_forward_bool(0)
%$$
After this call, $icode%f%.size_forward_bool()%$$ will return zero.
$subhead size_forward_set$$
After $code ForSparseJac$$, if $icode k$$ is a $code size_t$$ object,
$codei%
%k% = %f%.size_forward_set()
%$$
sets $icode k$$ to the amount of memory (in unsigned character units)
used to store the
$cref/vector of sets/glossary/Sparsity Pattern/Vector of Sets/$$
sparsity patterns.
If the sparsity patterns for this operation use elements of type $code bool$$,
the return value for $code size_forward_set$$ will be zero.
Otherwise, its return value will be non-zero.
This sparsity pattern is stored for use by $cref RevSparseHes$$ and
when it is not longer needed, it can be deleted
(and the corresponding memory freed) using
$codei%
%f%.size_forward_set(0)
%$$
After this call, $icode%f%.size_forward_set()%$$ will return zero.
$head x$$
If the operation sequence in $icode f$$ is
$cref/independent/glossary/Operation/Independent/$$ of
the independent variables in $latex x \in B^n$$,
the sparsity pattern is valid for all values of
(even if it has $cref CondExp$$ or $cref VecAD$$ operations).
$head q$$
The argument $icode q$$ has prototype
$codei%
size_t %q%
%$$
It specifies the number of columns in
$latex R \in B^{n \times q}$$ and the Jacobian
$latex S(x) \in B^{m \times q}$$.
$head transpose$$
The argument $icode transpose$$ has prototype
$codei%
bool %transpose%
%$$
The default value $code false$$ is used when $icode transpose$$ is not present.
$head dependency$$
The argument $icode dependency$$ has prototype
$codei%
bool %dependency%
%$$
If $icode dependency$$ is true,
the $cref/dependency pattern/dependency.cpp/Dependency Pattern/$$
(instead of sparsity pattern) is computed.
$head r$$
The argument $icode r$$ has prototype
$codei%
const %VectorSet%& %r%
%$$
see $cref/VectorSet/ForSparseJac/VectorSet/$$ below.
$subhead transpose false$$
If $icode r$$ has elements of type $code bool$$,
its size is $latex n * q$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex n$$ and all the set elements must be between
zero and $icode%q%-1%$$ inclusive.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex R \in B^{n \times q}$$.
$subhead transpose true$$
If $icode r$$ has elements of type $code bool$$,
its size is $latex q * n$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex q$$ and all the set elements must be between
zero and $icode%n%-1%$$ inclusive.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex R^\R{T} \in B^{q \times n}$$.
$head s$$
The return value $icode s$$ has prototype
$codei%
%VectorSet% %s%
%$$
see $cref/VectorSet/ForSparseJac/VectorSet/$$ below.
$subhead transpose false$$
If $icode s$$ has elements of type $code bool$$,
its size is $latex m * q$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex m$$ and all its set elements are between
zero and $icode%q%-1%$$ inclusive.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex S(x) \in B^{m \times q}$$.
$subhead transpose true$$
If $icode s$$ has elements of type $code bool$$,
its size is $latex q * m$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex q$$ and all its set elements are between
zero and $icode%m%-1%$$ inclusive.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex S(x)^\R{T} \in B^{q \times m}$$.
$head VectorSet$$
The type $icode VectorSet$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code bool$$ or $code std::set<size_t>$$;
see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion
of the difference.
$head Entire Sparsity Pattern$$
Suppose that $latex q = n$$ and
$latex R$$ is the $latex n \times n$$ identity matrix.
In this case,
the corresponding value for $icode s$$ is a
sparsity pattern for the Jacobian $latex S(x) = F^{(1)} ( x )$$.
$head Example$$
$children%
example/sparse/for_sparse_jac.cpp
%$$
The file
$cref for_sparse_jac.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
The file
$cref/sparsity_sub.cpp/sparsity_sub.cpp/ForSparseJac/$$
contains an example and test of using $code ForSparseJac$$
to compute the sparsity pattern for a subset of the Jacobian.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/local/std_set.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file for_sparse_jac.hpp
Forward mode Jacobian sparsity patterns.
*/
// ---------------------------------------------------------------------------
/*!
Private helper function for ForSparseJac(q, r) boolean sparsity patterns.
All of the description in the public member function ForSparseJac(q, r)
applies.
\param set_type
is a \c bool value. This argument is used to dispatch to the proper source
code depending on the value of \c VectorSet::value_type.
\param transpose
See \c ForSparseJac(q, r, transpose, dependency).
\param dependency
See \c ForSparseJac(q, r, transpose, dependency).
\param q
See \c ForSparseJac(q, r, transpose, dependency).
\param r
See \c ForSparseJac(q, r, transpose, dependency).
\param s
is the return value for the corresponding call to \c ForSparseJac(q, r).
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::ForSparseJacCase(
bool set_type ,
bool transpose ,
bool dependency ,
size_t q ,
const VectorSet& r ,
VectorSet& s )
{ size_t m = Range();
size_t n = Domain();
// check VectorSet is Simple Vector class with bool elements
CheckSimpleVector<bool, VectorSet>();
// dimension size of result vector
s.resize( m * q );
// temporary indices
size_t i, j;
//
CPPAD_ASSERT_KNOWN(
q > 0,
"ForSparseJac: q is not greater than zero"
);
CPPAD_ASSERT_KNOWN(
size_t(r.size()) == n * q,
"ForSparseJac: size of r is not equal to\n"
"q times domain dimension for ADFun object."
);
//
// allocate memory for the requested sparsity calculation result
for_jac_sparse_pack_.resize(num_var_tape_, q);
// set values corresponding to independent variables
for(i = 0; i < n; i++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < num_var_tape_ );
// ind_taddr_[i] is operator taddr for i-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
// set bits that are true
if( transpose )
{ for(j = 0; j < q; j++) if( r[ j * n + i ] )
for_jac_sparse_pack_.add_element( ind_taddr_[i], j);
}
else
{ for(j = 0; j < q; j++) if( r[ i * q + j ] )
for_jac_sparse_pack_.add_element( ind_taddr_[i], j);
}
}
// evaluate the sparsity patterns
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
for_jac_sparse_pack_
);
// return values corresponding to dependent variables
CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m * q );
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
// extract the result from for_jac_sparse_pack_
if( transpose )
{ for(j = 0; j < q; j++)
s[ j * m + i ] = false;
}
else
{ for(j = 0; j < q; j++)
s[ i * q + j ] = false;
}
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.end() == q );
local::sparse_pack::const_iterator itr(for_jac_sparse_pack_, dep_taddr_[i] );
j = *itr;
while( j < q )
{ if( transpose )
s[j * m + i] = true;
else s[i * q + j] = true;
j = *(++itr);
}
}
}
// ---------------------------------------------------------------------------
/*!
Private helper function for \c ForSparseJac(q, r) set sparsity.
All of the description in the public member function \c ForSparseJac(q, r)
applies.
\param set_type
is a \c std::set<size_t> object.
This argument is used to dispatch to the proper source
code depending on the value of \c VectorSet::value_type.
\param transpose
See \c ForSparseJac(q, r, transpose, dependency).
\param dependency
See \c ForSparseJac(q, r, transpose, dependency).
\param q
See \c ForSparseJac(q, r, transpose, dependency).
\param r
See \c ForSparseJac(q, r, transpose, dependency).
\param s
is the return value for the corresponding call to \c ForSparseJac(q, r).
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::ForSparseJacCase(
const std::set<size_t>& set_type ,
bool transpose ,
bool dependency ,
size_t q ,
const VectorSet& r ,
VectorSet& s )
{ size_t m = Range();
size_t n = Domain();
// check VectorSet is Simple Vector class with sets for elements
CheckSimpleVector<std::set<size_t>, VectorSet>(
local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()
);
// dimension size of result vector
if( transpose )
s.resize(q);
else s.resize( m );
// temporary indices
size_t i, j;
std::set<size_t>::const_iterator itr_1;
//
CPPAD_ASSERT_KNOWN(
q > 0,
"ForSparseJac: q is not greater than zero"
);
CPPAD_ASSERT_KNOWN(
size_t(r.size()) == n || transpose,
"ForSparseJac: size of r is not equal to n and transpose is false."
);
CPPAD_ASSERT_KNOWN(
size_t(r.size()) == q || ! transpose,
"ForSparseJac: size of r is not equal to q and transpose is true."
);
//
// allocate memory for the requested sparsity calculation
for_jac_sparse_set_.resize(num_var_tape_, q);
// set values corresponding to independent variables
if( transpose )
{ for(i = 0; i < q; i++)
{ // add the elements that are present
itr_1 = r[i].begin();
while( itr_1 != r[i].end() )
{ j = *itr_1++;
CPPAD_ASSERT_KNOWN(
j < n,
"ForSparseJac: transpose is true and element of the set\n"
"r[j] has value greater than or equal n."
);
CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
// operator for j-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
for_jac_sparse_set_.add_element( ind_taddr_[j], i);
}
}
}
else
{ for(i = 0; i < n; i++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < num_var_tape_ );
// ind_taddr_[i] is operator taddr for i-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
// add the elements that are present
itr_1 = r[i].begin();
while( itr_1 != r[i].end() )
{ j = *itr_1++;
CPPAD_ASSERT_KNOWN(
j < q,
"ForSparseJac: an element of the set r[i] "
"has value greater than or equal q."
);
for_jac_sparse_set_.add_element( ind_taddr_[i], j);
}
}
}
// evaluate the sparsity patterns
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
for_jac_sparse_set_
);
// return values corresponding to dependent variables
CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m || transpose );
CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || ! transpose );
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
// extract results from for_jac_sparse_set_
// and add corresponding elements to sets in s
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end() == q );
local::sparse_list::const_iterator itr_2(for_jac_sparse_set_, dep_taddr_[i] );
j = *itr_2;
while( j < q )
{ if( transpose )
s[j].insert(i);
else s[i].insert(j);
j = *(++itr_2);
}
}
}
// ---------------------------------------------------------------------------
/*!
User API for Jacobian sparsity patterns using forward mode.
The C++ source code corresponding to this operation is
\verbatim
s = f.ForSparseJac(q, r, transpose, dependency)
\endverbatim
\tparam Base
is the base type for this recording.
\tparam VectorSet
is a simple vector with elements of type \c bool
or \c std::set<size_t>.
\param q
is the number of columns in the matrix \f$ R \f$.
\param r
is a sparsity pattern for the matrix \f$ R \f$.
\param transpose
are sparsity patterns for \f$ R \f$ and \f$ S(x) \f$ transposed.
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\return
The value of \c transpose is false (true),
the return value is a sparsity pattern for \f$ S(x) \f$ (\f$ S(x)^T \f$) where
\f[
S(x) = F^{(1)} (x) * R
\f]
where \f$ F \f$ is the function corresponding to the operation sequence
and \a x is any argument value.
If \c VectorSet::value_type is \c bool,
the return value has size \f$ m * q \f$ (\f$ q * m \f$).
where \c m is the number of dependent variables
corresponding to the operation sequence stored in \c f.
If \c VectorSet::value_type is \c std::set<size_t>,
the return value has size \f$ m \f$ ( \f$ q \f$ )
and with all its elements between zero and
\f$ q - 1 \f$ ( \f$ m - 1 \f$).
\par Side Effects
If \c VectorSet::value_type is \c bool,
the forward sparsity pattern for all of the variables on the
tape is stored in \c for_jac_sparse_pack__.
In this case
\verbatim
for_jac_sparse_pack_.n_set() == num_var_tape_
for_jac_sparse_pack_.end() == q
for_jac_sparse_set_.n_set() == 0
for_jac_sparse_set_.end() == 0
\endverbatim
\n
\n
If \c VectorSet::value_type is \c std::set<size_t>,
the forward sparsity pattern for all of the variables on the
tape is stored in \c for_jac_sparse_set__.
In this case
\verbatim
for_jac_sparse_set_.n_set() == num_var_tape_
for_jac_sparse_set_.end() == q
for_jac_sparse_pack_.n_set() == 0
for_jac_sparse_pack_.end() == 0
\endverbatim
*/
template <class Base>
template <class VectorSet>
VectorSet ADFun<Base>::ForSparseJac(
size_t q ,
const VectorSet& r ,
bool transpose ,
bool dependency )
{ VectorSet s;
typedef typename VectorSet::value_type Set_type;
// free all memory currently in sparsity patterns
for_jac_sparse_pack_.resize(0, 0);
for_jac_sparse_set_.resize(0, 0);
ForSparseJacCase(
Set_type() ,
transpose ,
dependency ,
q ,
r ,
s
);
return s;
}
// ===========================================================================
// ForSparseJacCheckpoint
/*!
Forward mode Jacobian sparsity calculation used by checkpoint functions.
\tparam Base
is the base type for this recording.
\param transpose
is true (false) s is equal to \f$ S(x) \f$ (\f$ S(x)^T \f$)
where
\f[
S(x) = F^{(1)} (x) * R
\f]
where \f$ F \f$ is the function corresponding to the operation sequence
and \f$ x \f$ is any argument value.
\param q
is the number of columns in the matrix \f$ R \f$.
\param r
is a sparsity pattern for the matrix \f$ R \f$.
\param transpose
are the sparsity patterns for \f$ R \f$ and \f$ S(x) \f$ transposed.
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\param s
The input size and elements of s do not matter.
On output, s is the sparsity pattern for the matrix \f$ S(x) \f$
or \f$ S(x)^T \f$ depending on transpose.
\par Side Effects
If \c VectorSet::value_type is \c bool,
the forward sparsity pattern for all of the variables on the
tape is stored in \c for_jac_sparse_pack__.
In this case
\verbatim
for_jac_sparse_pack_.n_set() == num_var_tape_
for_jac_sparse_pack_.end() == q
for_jac_sparse_set_.n_set() == 0
for_jac_sparse_set_.end() == 0
\endverbatim
\n
\n
If \c VectorSet::value_type is \c std::set<size_t>,
the forward sparsity pattern for all of the variables on the
tape is stored in \c for_jac_sparse_set__.
In this case
\verbatim
for_jac_sparse_set_.n_set() == num_var_tape_
for_jac_sparse_set_.end() == q
for_jac_sparse_pack_.n_set() == 0
for_jac_sparse_pack_.end() == 0
\endverbatim
*/
template <class Base>
void ADFun<Base>::ForSparseJacCheckpoint(
size_t q ,
const local::sparse_list& r ,
bool transpose ,
bool dependency ,
local::sparse_list& s )
{ size_t n = Domain();
size_t m = Range();
# ifndef NDEBUG
if( transpose )
{ CPPAD_ASSERT_UNKNOWN( r.n_set() == q );
CPPAD_ASSERT_UNKNOWN( r.end() == n );
}
else
{ CPPAD_ASSERT_UNKNOWN( r.n_set() == n );
CPPAD_ASSERT_UNKNOWN( r.end() == q );
}
for(size_t j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
}
# endif
// free all memory currently in sparsity patterns
for_jac_sparse_pack_.resize(0, 0);
for_jac_sparse_set_.resize(0, 0);
// allocate new sparsity pattern
for_jac_sparse_set_.resize(num_var_tape_, q);
// set sparsity pattern for dependent variables
if( transpose )
{ for(size_t i = 0; i < q; i++)
{ local::sparse_list::const_iterator itr(r, i);
size_t j = *itr;
while( j < n )
{ for_jac_sparse_set_.add_element( ind_taddr_[j], i );
j = *(++itr);
}
}
}
else
{ for(size_t j = 0; j < n; j++)
{ local::sparse_list::const_iterator itr(r, j);
size_t i = *itr;
while( i < q )
{ for_jac_sparse_set_.add_element( ind_taddr_[j], i );
i = *(++itr);
}
}
}
// evaluate the sparsity pattern for all variables
local::ForJacSweep(
dependency,
n,
num_var_tape_,
&play_,
for_jac_sparse_set_
);
// dimension the return value
if( transpose )
s.resize(q, m);
else
s.resize(m, q);
// return values corresponding to dependent variables
for(size_t i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
// extract the result from for_jac_sparse_set_
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end() == q );
local::sparse_list::const_iterator itr(for_jac_sparse_set_, dep_taddr_[i] );
size_t j = *itr;
while( j < q )
{ if( transpose )
s.add_element(j, i);
else
s.add_element(i, j);
j = *(++itr);
}
}
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,255 +0,0 @@
# ifndef CPPAD_CORE_FOR_TWO_HPP
# define CPPAD_CORE_FOR_TWO_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 ForTwo$$
$spell
ddy
typename
Taylor
const
$$
$section Forward Mode Second Partial Derivative Driver$$
$mindex order easy$$
$head Syntax$$
$icode%ddy% = %f%.ForTwo(%x%, %j%, %k%)%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
The syntax above sets
$latex \[
ddy [ i * p + \ell ]
=
\DD{ F_i }{ x_{j[ \ell ]} }{ x_{k[ \ell ]} } (x)
\] $$
for $latex i = 0 , \ldots , m-1$$
and $latex \ell = 0 , \ldots , p$$,
where $latex p$$ is the size of the vectors $icode j$$ and $icode k$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/ForTwo Uses Forward/ForTwo/ForTwo Uses Forward/$$ below).
$head x$$
The argument $icode x$$ has prototype
$codei%
const %VectorBase% &%x%
%$$
(see $cref/VectorBase/ForTwo/VectorBase/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies
that point at which to evaluate the partial derivatives listed above.
$head j$$
The argument $icode j$$ has prototype
$codei%
const %VectorSize_t% &%j%
%$$
(see $cref/VectorSize_t/ForTwo/VectorSize_t/$$ below)
We use $icode p$$ to denote the size of the vector $icode j$$.
All of the indices in $icode j$$
must be less than $icode n$$; i.e.,
for $latex \ell = 0 , \ldots , p-1$$, $latex j[ \ell ] < n$$.
$head k$$
The argument $icode k$$ has prototype
$codei%
const %VectorSize_t% &%k%
%$$
(see $cref/VectorSize_t/ForTwo/VectorSize_t/$$ below)
and its size must be equal to $icode p$$,
the size of the vector $icode j$$.
All of the indices in $icode k$$
must be less than $icode n$$; i.e.,
for $latex \ell = 0 , \ldots , p-1$$, $latex k[ \ell ] < n$$.
$head ddy$$
The result $icode ddy$$ has prototype
$codei%
%VectorBase% %ddy%
%$$
(see $cref/VectorBase/ForTwo/VectorBase/$$ below)
and its size is $latex m * p$$.
It contains the requested partial derivatives; to be specific,
for $latex i = 0 , \ldots , m - 1 $$
and $latex \ell = 0 , \ldots , p - 1$$
$latex \[
ddy [ i * p + \ell ]
=
\DD{ F_i }{ x_{j[ \ell ]} }{ x_{k[ \ell ]} } (x)
\] $$
$head VectorBase$$
The type $icode VectorBase$$ must be a $cref SimpleVector$$ class with
$cref/elements of type Base/SimpleVector/Elements of Specified Type/$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head VectorSize_t$$
The type $icode VectorSize_t$$ must be a $cref SimpleVector$$ class with
$cref/elements of type size_t/SimpleVector/Elements of Specified Type/$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head ForTwo Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code ForTwo$$,
the zero order Taylor coefficients correspond to
$icode%f%.Forward(0, %x%)%$$
and the other coefficients are unspecified.
$head Examples$$
$children%
example/general/for_two.cpp
%$$
The routine
$cref/ForTwo/for_two.cpp/$$ is both an example and test.
It returns $code true$$, if it succeeds and $code false$$ otherwise.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <typename Base>
template <typename VectorBase, typename VectorSize_t>
VectorBase ADFun<Base>::ForTwo(
const VectorBase &x,
const VectorSize_t &j,
const VectorSize_t &k)
{ size_t i;
size_t j1;
size_t k1;
size_t l;
size_t n = Domain();
size_t m = Range();
size_t p = j.size();
// check VectorBase is Simple Vector class with Base type elements
CheckSimpleVector<Base, VectorBase>();
// check VectorSize_t is Simple Vector class with size_t elements
CheckSimpleVector<size_t, VectorSize_t>();
CPPAD_ASSERT_KNOWN(
x.size() == n,
"ForTwo: Length of x not equal domain dimension for f."
);
CPPAD_ASSERT_KNOWN(
j.size() == k.size(),
"ForTwo: Lenght of the j and k vectors are not equal."
);
// point at which we are evaluating the second partials
Forward(0, x);
// dimension the return value
VectorBase ddy(m * p);
// allocate memory to hold all possible diagonal Taylor coefficients
// (for large sparse cases, this is not efficient)
VectorBase D(m * n);
// boolean flag for which diagonal coefficients are computed
CppAD::vector<bool> c(n);
for(j1 = 0; j1 < n; j1++)
c[j1] = false;
// direction vector in argument space
VectorBase dx(n);
for(j1 = 0; j1 < n; j1++)
dx[j1] = Base(0.0);
// result vector in range space
VectorBase dy(m);
// compute the diagonal coefficients that are needed
for(l = 0; l < p; l++)
{ j1 = j[l];
k1 = k[l];
CPPAD_ASSERT_KNOWN(
j1 < n,
"ForTwo: an element of j not less than domain dimension for f."
);
CPPAD_ASSERT_KNOWN(
k1 < n,
"ForTwo: an element of k not less than domain dimension for f."
);
size_t count = 2;
while(count)
{ count--;
if( ! c[j1] )
{ // diagonal term in j1 direction
c[j1] = true;
dx[j1] = Base(1.0);
Forward(1, dx);
dx[j1] = Base(0.0);
dy = Forward(2, dx);
for(i = 0; i < m; i++)
D[i * n + j1 ] = dy[i];
}
j1 = k1;
}
}
// compute all the requested cross partials
for(l = 0; l < p; l++)
{ j1 = j[l];
k1 = k[l];
if( j1 == k1 )
{ for(i = 0; i < m; i++)
ddy[i * p + l] = Base(2.0) * D[i * n + j1];
}
else
{
// cross term in j1 and k1 directions
dx[j1] = Base(1.0);
dx[k1] = Base(1.0);
Forward(1, dx);
dx[j1] = Base(0.0);
dx[k1] = Base(0.0);
dy = Forward(2, dx);
// place result in return value
for(i = 0; i < m; i++)
ddy[i * p + l] = dy[i] - D[i*n+j1] - D[i*n+k1];
}
}
return ddy;
}
} // END CppAD namespace
# endif

View File

@ -1,432 +0,0 @@
# ifndef CPPAD_CORE_FORWARD_HPP
# define CPPAD_CORE_FORWARD_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.
-------------------------------------------------------------------------- */
// documened after Forward but included here so easy to see
# include <cppad/core/capacity_order.hpp>
# include <cppad/core/num_skip.hpp>
# include <cppad/core/check_for_nan.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file forward.hpp
User interface to forward mode computations.
*/
/*!
Multiple orders, one direction, forward mode Taylor coefficieints.
\tparam Base
The type used during the forward mode computations; i.e., the corresponding
recording of operations used the type AD<Base>.
\tparam VectorBase
is a Simple Vector class with eleements of type Base.
\param q
is the hightest order for this forward mode computation; i.e.,
after this calculation there will be <code>q+1</code>
Taylor coefficients per variable.
\param xq
contains Taylor coefficients for the independent variables.
The size of xq must either be n or <code>(q+1)*n</code>,
We define <code>p = q + 1 - xq.size()/n</code>.
For <code>j = 0 , ... , n-1</code>,
<code>k = p, ... , q</code>, are
<code>xq[ (q+1-p)*j + k - p ]</code>
is the k-th order coefficient for the j-th independent variable.
\param s
Is the stream where output corresponding to PriOp operations will written.
\return
contains Taylor coefficients for the dependent variables.
The size of the return value y is <code>m*(q+1-p)</code>.
For <code>i = 0, ... , m-1</code>,
<code>k = p, ..., q</code>,
<code>y[(q+1-p)*i + (k-p)]</code>
is the k-th order coefficient for the i-th dependent variable.
\par taylor_
The Taylor coefficients up to order p-1 are inputs
and the coefficents from order p through q are outputs.
Let <code>N = num_var_tape_</code>, and
<code>C = cap_order_taylor_</code>.
Note that for
<code>i = 1 , ..., N-1</code>,
<code>k = 0 , ..., q</code>,
<code>taylor_[ C*i + k ]</code>
is the k-th order cofficent,
for the i-th varaible on the tape.
(The first independent variable has index one on the tape
and there is no variable with index zero.)
*/
template <typename Base>
template <typename VectorBase>
VectorBase ADFun<Base>::Forward(
size_t q ,
const VectorBase& xq ,
std::ostream& s )
{ // temporary indices
size_t i, j, k;
// number of independent variables
size_t n = ind_taddr_.size();
// number of dependent variables
size_t m = dep_taddr_.size();
// check Vector is Simple Vector class with Base type elements
CheckSimpleVector<Base, VectorBase>();
CPPAD_ASSERT_KNOWN(
size_t(xq.size()) == n || size_t(xq.size()) == n*(q+1),
"Forward(q, xq): xq.size() is not equal n or n*(q+1)"
);
// lowest order we are computing
size_t p = q + 1 - size_t(xq.size()) / n;
CPPAD_ASSERT_UNKNOWN( p == 0 || p == q );
CPPAD_ASSERT_KNOWN(
q <= num_order_taylor_ || p == 0,
"Forward(q, xq): Number of Taylor coefficient orders stored in this"
" ADFun\nis less than q and xq.size() != n*(q+1)."
);
CPPAD_ASSERT_KNOWN(
p <= 1 || num_direction_taylor_ == 1,
"Forward(q, xq): computing order q >= 2"
" and number of directions is not one."
"\nMust use Forward(q, r, xq) for this case"
);
// does taylor_ need more orders or fewer directions
if( (cap_order_taylor_ <= q) | (num_direction_taylor_ != 1) )
{ if( p == 0 )
{ // no need to copy old values during capacity_order
num_order_taylor_ = 0;
}
else num_order_taylor_ = q;
size_t c = std::max(q + 1, cap_order_taylor_);
size_t r = 1;
capacity_order(c, r);
}
CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ > q );
CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 1 );
// short hand notation for order capacity
size_t C = cap_order_taylor_;
// The optimizer may skip a step that does not affect dependent variables.
// Initilaizing zero order coefficients avoids following valgrind warning:
// "Conditional jump or move depends on uninitialised value(s)".
for(j = 0; j < num_var_tape_; j++)
{ for(k = p; k <= q; k++)
taylor_[C * j + k] = CppAD::numeric_limits<Base>::quiet_NaN();
}
// set Taylor coefficients for independent variables
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
if( p == q )
taylor_[ C * ind_taddr_[j] + q] = xq[j];
else
{ for(k = 0; k <= q; k++)
taylor_[ C * ind_taddr_[j] + k] = xq[ (q+1)*j + k];
}
}
// evaluate the derivatives
CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
CPPAD_ASSERT_UNKNOWN( load_op_.size() == play_.num_load_op_rec() );
if( q == 0 )
{ local::forward0sweep(s, true,
n, num_var_tape_, &play_, C,
taylor_.data(), cskip_op_.data(), load_op_,
compare_change_count_,
compare_change_number_,
compare_change_op_index_
);
}
else
{ local::forward1sweep(s, true, p, q,
n, num_var_tape_, &play_, C,
taylor_.data(), cskip_op_.data(), load_op_,
compare_change_count_,
compare_change_number_,
compare_change_op_index_
);
}
// return Taylor coefficients for dependent variables
VectorBase yq;
if( p == q )
{ yq.resize(m);
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
yq[i] = taylor_[ C * dep_taddr_[i] + q];
}
}
else
{ yq.resize(m * (q+1) );
for(i = 0; i < m; i++)
{ for(k = 0; k <= q; k++)
yq[ (q+1) * i + k] =
taylor_[ C * dep_taddr_[i] + k ];
}
}
# ifndef NDEBUG
if( check_for_nan_ )
{ bool ok = true;
size_t index = m;
if( p == 0 )
{ for(i = 0; i < m; i++)
{ // Visual Studio 2012, CppAD required in front of isnan ?
if( CppAD::isnan( yq[ (q+1) * i + 0 ] ) )
{ ok = false;
if( index == m )
index = i;
}
}
}
if( ! ok )
{ CPPAD_ASSERT_UNKNOWN( index < m );
//
CppAD::vector<Base> x0(n);
for(j = 0; j < n; j++)
x0[j] = taylor_[ C * ind_taddr_[j] + 0 ];
std::string file_name;
put_check_for_nan(x0, file_name);
std::stringstream ss;
ss <<
"yq = f.Forward(q, xq): a zero order Taylor coefficient is nan.\n"
"Corresponding independent variables vector was written "
"to binary a file.\n"
"vector_size = " << n << "\n" <<
"file_name = " << file_name << "\n" <<
"index = " << index << "\n";
// ss.str() returns a string object with a copy of the current
// contents in the stream buffer.
std::string msg_str = ss.str();
// msg_str.c_str() returns a pointer to the c-string
// representation of the string object's value.
const char* msg_char_star = msg_str.c_str();
ErrorHandler::Call(
true,
__LINE__,
__FILE__,
"if( CppAD::isnan( yq[ (q+1) * index + 0 ] )",
msg_char_star
);
}
CPPAD_ASSERT_KNOWN(ok,
"with the value nan."
);
if( 0 < q )
{ for(i = 0; i < m; i++)
{ for(k = p; k <= q; k++)
{ // Studio 2012, CppAD required in front of isnan ?
ok &= ! CppAD::isnan( yq[ (q+1-p)*i + k-p ] );
}
}
}
CPPAD_ASSERT_KNOWN(ok,
"yq = f.Forward(q, xq): has a non-zero order Taylor coefficient\n"
"with the value nan (but zero order coefficients are not nan)."
);
}
# endif
// now we have q + 1 taylor_ coefficient orders per variable
num_order_taylor_ = q + 1;
return yq;
}
/*!
One order, multiple directions, forward mode Taylor coefficieints.
\tparam Base
The type used during the forward mode computations; i.e., the corresponding
recording of operations used the type AD<Base>.
\tparam VectorBase
is a Simple Vector class with eleements of type Base.
\param q
is the order for this forward mode computation,
<code>q > 0</code>.
There must be at least <code>q</code> Taylor coefficients
per variable before this call.
After this call there will be <code>q+1</code>
Taylor coefficients per variable.
\param r
is the number of directions for this calculation.
If <code>q != 1</code>, \c r must be the same as in the previous
call to Forward where \c q was equal to one.
\param xq
contains Taylor coefficients for the independent variables.
The size of xq must either be <code>r*n</code>,
For <code>j = 0 , ... , n-1</code>,
<code>ell = 0, ... , r-1</code>,
<code>xq[ ( r*j + ell ]</code>
is the q-th order coefficient for the j-th independent variable
and the ell-th direction.
\return
contains Taylor coefficients for the dependent variables.
The size of the return value \c y is <code>r*m</code>.
For <code>i = 0, ... , m-1</code>,
<code>ell = 0, ... , r-1</code>,
<code>y[ r*i + ell ]</code>
is the q-th order coefficient for the i-th dependent variable
and the ell-th direction.
\par taylor_
The Taylor coefficients up to order <code>q-1</code> are inputs
and the coefficents of order \c q are outputs.
Let <code>N = num_var_tape_</code>, and
<code>C = cap_order_taylor_</code>.
Note that for
<code>i = 1 , ..., N-1</code>,
<code>taylor_[ (C-1)*r*i + i + 0 ]</code>
is the zero order cofficent,
for the i-th varaible, and all directions.
For <code>i = 1 , ..., N-1</code>,
<code>k = 1 , ..., q</code>,
<code>ell = 0 , ..., r-1</code>,
<code>taylor_[ (C-1)*r*i + i + (k-1)*r + ell + 1 ]</code>
is the k-th order cofficent,
for the i-th varaible, and ell-th direction.
(The first independent variable has index one on the tape
and there is no variable with index zero.)
*/
template <typename Base>
template <typename VectorBase>
VectorBase ADFun<Base>::Forward(
size_t q ,
size_t r ,
const VectorBase& xq )
{ // temporary indices
size_t i, j, ell;
// number of independent variables
size_t n = ind_taddr_.size();
// number of dependent variables
size_t m = dep_taddr_.size();
// check Vector is Simple Vector class with Base type elements
CheckSimpleVector<Base, VectorBase>();
CPPAD_ASSERT_KNOWN( q > 0, "Forward(q, r, xq): q == 0" );
CPPAD_ASSERT_KNOWN(
size_t(xq.size()) == r * n,
"Forward(q, r, xq): xq.size() is not equal r * n"
);
CPPAD_ASSERT_KNOWN(
q <= num_order_taylor_ ,
"Forward(q, r, xq): Number of Taylor coefficient orders stored in"
" this ADFun is less than q"
);
CPPAD_ASSERT_KNOWN(
q == 1 || num_direction_taylor_ == r ,
"Forward(q, r, xq): q > 1 and number of Taylor directions r"
" is not same as previous Forward(1, r, xq)"
);
// does taylor_ need more orders or new number of directions
if( cap_order_taylor_ <= q || num_direction_taylor_ != r )
{ if( num_direction_taylor_ != r )
num_order_taylor_ = 1;
size_t c = std::max(q + 1, cap_order_taylor_);
capacity_order(c, r);
}
CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ > q );
CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r )
// short hand notation for order capacity
size_t c = cap_order_taylor_;
// set Taylor coefficients for independent variables
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
for(ell = 0; ell < r; ell++)
{ size_t index = ((c-1)*r + 1)*ind_taddr_[j] + (q-1)*r + ell + 1;
taylor_[ index ] = xq[ r * j + ell ];
}
}
// evaluate the derivatives
CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
CPPAD_ASSERT_UNKNOWN( load_op_.size() == play_.num_load_op_rec() );
local::forward2sweep(
q,
r,
n,
num_var_tape_,
&play_,
c,
taylor_.data(),
cskip_op_.data(),
load_op_
);
// return Taylor coefficients for dependent variables
VectorBase yq;
yq.resize(r * m);
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
for(ell = 0; ell < r; ell++)
{ size_t index = ((c-1)*r + 1)*dep_taddr_[i] + (q-1)*r + ell + 1;
yq[ r * i + ell ] = taylor_[ index ];
}
}
# ifndef NDEBUG
if( check_for_nan_ )
{ bool ok = true;
for(i = 0; i < m; i++)
{ for(ell = 0; ell < r; ell++)
{ // Studio 2012, CppAD required in front of isnan ?
ok &= ! CppAD::isnan( yq[ r * i + ell ] );
}
}
CPPAD_ASSERT_KNOWN(ok,
"yq = f.Forward(q, r, xq): has a non-zero order Taylor coefficient\n"
"with the value nan (but zero order coefficients are not nan)."
);
}
# endif
// now we have q + 1 taylor_ coefficient orders per variable
num_order_taylor_ = q + 1;
return yq;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,210 +0,0 @@
# ifndef CPPAD_CORE_FUN_CHECK_HPP
# define CPPAD_CORE_FUN_CHECK_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 FunCheck$$
$spell
exp
bool
const
Taylor
$$
$section Check an ADFun Sequence of Operations$$
$head Syntax$$
$icode%ok% = FunCheck(%f%, %g%, %x%, %r%, %a%)%$$
$pre
$$
$bold See Also$$
$cref CompareChange$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
We use $latex G : B^n \rightarrow B^m$$ to denote the
function corresponding to the C++ function object $icode g$$.
This routine check if
$latex \[
F(x) = G(x)
\]$$
If $latex F(x) \neq G(x)$$, the
$cref/operation sequence/glossary/Operation/Sequence/$$
corresponding to $icode f$$ does not represents the algorithm used
by $icode g$$ to calculate values for $latex G$$
(see $cref/Discussion/FunCheck/Discussion/$$ below).
$head f$$
The $code FunCheck$$ argument $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/Forward/FunCheck/FunCheck Uses Forward/$$ below).
$head g$$
The $code FunCheck$$ argument $icode g$$ has prototype
$codei%
%Fun% &%g%
%$$
($icode Fun$$ is defined the properties of $icode g$$).
The C++ function object $icode g$$ supports the syntax
$codei%
%y% = %g%(%x%)
%$$
which computes $latex y = G(x)$$.
$subhead x$$
The $icode g$$ argument $icode x$$ has prototype
$codei%
const %Vector% &%x%
%$$
(see $cref/Vector/FunCheck/Vector/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
$head y$$
The $icode g$$ result $icode y$$ has prototype
$codei%
%Vector% %y%
%$$
and its value is $latex G(x)$$.
The size of $icode y$$
is equal to $icode m$$, the dimension of the
$cref/range/seq_property/Range/$$ space for $icode f$$.
$head x$$
The $code FunCheck$$ argument $icode x$$ has prototype
$codei%
const %Vector% &%x%
%$$
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
This specifies that point at which to compare the values
calculated by $icode f$$ and $icode G$$.
$head r$$
The $code FunCheck$$ argument $icode r$$ has prototype
$codei%
const %Base% &%r%
%$$
It specifies the relative error the element by element
comparison of the value of $latex F(x)$$ and $latex G(x)$$.
$head a$$
The $code FunCheck$$ argument $icode a$$ has prototype
$codei%
const %Base% &%a%
%$$
It specifies the absolute error the element by element
comparison of the value of $latex F(x)$$ and $latex G(x)$$.
$head ok$$
The $code FunCheck$$ result $icode ok$$ has prototype
$codei%
bool %ok%
%$$
It is true, if for $latex i = 0 , \ldots , m-1$$
either the relative error bound is satisfied
$latex \[
| F_i (x) - G_i (x) |
\leq
r ( | F_i (x) | + | G_i (x) | )
\] $$
or the absolute error bound is satisfied
$latex \[
| F_i (x) - G_i (x) | \leq a
\] $$
It is false if for some $latex (i, j)$$ neither
of these bounds is satisfied.
$head Vector$$
The type $icode Vector$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$icode Base$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head FunCheck Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After $code FunCheck$$,
the previous calls to $cref Forward$$ are undefined.
$head Discussion$$
Suppose that the algorithm corresponding to $icode g$$ contains
$codei%
if( %x% >= 0 )
%y% = exp(%x%)
else %y% = exp(-%x%)
%$$
where $icode x$$ and $icode y$$ are $codei%AD<double>%$$ objects.
It follows that the
AD of $code double$$ $cref/operation sequence/glossary/Operation/Sequence/$$
depends on the value of $icode x$$.
If the sequence of operations stored in $icode f$$ corresponds to
$icode g$$ with $latex x \geq 0$$,
the function values computed using $icode f$$ when $latex x < 0$$
will not agree with the function values computed by $latex g$$.
This is because the operation sequence corresponding to $icode g$$ changed
(and hence the object $icode f$$ does not represent the function
$latex G$$ for this value of $icode x$$).
In this case, you probably want to re-tape the calculations
performed by $icode g$$ with the
$cref/independent variables/glossary/Tape/Independent Variable/$$
equal to the values in $icode x$$
(so AD operation sequence properly represents the algorithm
for this value of independent variables).
$head Example$$
$children%
example/general/fun_check.cpp
%$$
The file
$cref fun_check.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
---------------------------------------------------------------------------
*/
namespace CppAD {
template <class Base, class Fun, class Vector>
bool FunCheck(
ADFun<Base> &f ,
Fun &g ,
const Vector &x ,
const Base &r ,
const Base &a )
{ bool ok = true;
size_t m = f.Range();
Vector yf = f.Forward(0, x);
Vector yg = g(x);
size_t i;
for(i = 0; i < m; i++)
ok &= NearEqual(yf[i], yg[i], r, a);
return ok;
}
}
# endif

View File

@ -1,488 +0,0 @@
# ifndef CPPAD_CORE_FUN_CONSTRUCT_HPP
# define CPPAD_CORE_FUN_CONSTRUCT_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 FunConstruct$$
$spell
alloc
num
Jac
bool
taylor
var
ADvector
const
Jacobian
$$
$spell
$$
$section Construct an ADFun Object and Stop Recording$$
$mindex tape$$
$head Syntax$$
$codei%ADFun<%Base%> %f%, %g%
%$$
$codei%ADFun<%Base%> %f%(%x%, %y%)
%$$
$icode%g% = %f%
%$$
$head Purpose$$
The $codei%AD<%Base%>%$$ object $icode f$$ can
store an AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
It can then be used to calculate derivatives of the corresponding
$cref/AD function/glossary/AD Function/$$
$latex \[
F : B^n \rightarrow B^m
\] $$
where $latex B$$ is the space corresponding to objects of type $icode Base$$.
$head x$$
If the argument $icode x$$ is present, it has prototype
$codei%
const %VectorAD% &%x%
%$$
It must be the vector argument in the previous call to
$cref Independent$$.
Neither its size, or any of its values, are allowed to change
between calling
$codei%
Independent(%x%)
%$$
and
$codei%
ADFun<%Base%> %f%(%x%, %y%)
%$$
$head y$$
If the argument $icode y$$ is present, it has prototype
$codei%
const %VectorAD% &%y%
%$$
The sequence of operations that map $icode x$$
to $icode y$$ are stored in the ADFun object $icode f$$.
$head VectorAD$$
The type $icode VectorAD$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$codei%AD<%Base%>%$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head Default Constructor$$
The default constructor
$codei%
ADFun<%Base%> %f%
%$$
creates an
$codei%AD<%Base%>%$$ object with no corresponding operation sequence; i.e.,
$codei%
%f%.size_var()
%$$
returns the value zero (see $cref/size_var/seq_property/size_var/$$).
$head Sequence Constructor$$
The sequence constructor
$codei%
ADFun<%Base%> %f%(%x%, %y%)
%$$
creates the $codei%AD<%Base%>%$$ object $icode f$$,
stops the recording of AD of $icode Base$$ operations
corresponding to the call
$codei%
Independent(%x%)
%$$
and stores the corresponding operation sequence in the object $icode f$$.
It then stores the zero order Taylor coefficients
(corresponding to the value of $icode x$$) in $icode f$$.
This is equivalent to the following steps using the default constructor:
$list number$$
Create $icode f$$ with the default constructor
$codei%
ADFun<%Base%> %f%;
%$$
$lnext
Stop the tape and storing the operation sequence using
$codei%
%f%.Dependent(%x%, %y%);
%$$
(see $cref Dependent$$).
$lnext
Calculate the zero order Taylor coefficients for all
the variables in the operation sequence using
$codei%
%f%.Forward(%p%, %x_p%)
%$$
with $icode p$$ equal to zero and the elements of $icode x_p$$
equal to the corresponding elements of $icode x$$
(see $cref Forward$$).
$lend
$head Copy Constructor$$
It is an error to attempt to use the $codei%ADFun<%Base%>%$$ copy constructor;
i.e., the following syntax is not allowed:
$codei%
ADFun<%Base%> %g%(%f%)
%$$
where $icode f$$ is an $codei%ADFun<%Base%>%$$ object.
Use its $cref/default constructor/FunConstruct/Default Constructor/$$ instead
and its assignment operator.
$head Assignment Operator$$
The $codei%ADFun<%Base%>%$$ assignment operation
$codei%
%g% = %f%
%$$
makes a copy of the operation sequence currently stored in $icode f$$
in the object $icode g$$.
The object $icode f$$ is not affected by this operation and
can be $code const$$.
All of information (state) stored in $icode f$$ is copied to $icode g$$
and any information originally in $icode g$$ is lost.
$subhead Taylor Coefficients$$
The Taylor coefficient information currently stored in $icode f$$
(computed by $cref/f.Forward/Forward/$$) is
copied to $icode g$$.
Hence, directly after this operation
$codei%
%g%.size_order() == %f%.size_order()
%$$
$subhead Sparsity Patterns$$
The forward Jacobian sparsity pattern currently stored in $icode f$$
(computed by $cref/f.ForSparseJac/ForSparseJac/$$) is
copied to $icode g$$.
Hence, directly after this operation
$codei%
%g%.size_forward_bool() == %f%.size_forward_bool()
%g%.size_forward_set() == %f%.size_forward_set()
%$$
$head Parallel Mode$$
The call to $code Independent$$,
and the corresponding call to
$codei%
ADFun<%Base%> %f%( %x%, %y%)
%$$
or
$codei%
%f%.Dependent( %x%, %y%)
%$$
or $cref abort_recording$$,
must be preformed by the same thread; i.e.,
$cref/thread_alloc::thread_num/ta_thread_num/$$ must be the same.
$head Example$$
$subhead Sequence Constructor$$
The file
$cref independent.cpp$$
contains an example and test of the sequence constructor.
It returns true if it succeeds and false otherwise.
$subhead Default Constructor$$
The files
$cref fun_check.cpp$$
and
$cref hes_lagrangian.cpp$$
contain an examples and tests using the default constructor.
They return true if they succeed and false otherwise.
$children%
example/general/fun_assign.cpp
%$$
$subhead Assignment Operator$$
The file
$cref fun_assign.cpp$$
contains an example and test of the $codei%ADFun<%Base%>%$$
assignment operator.
It returns true if it succeeds and false otherwise.
$end
----------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file fun_construct.hpp
ADFun function constructors and assignment operator.
*/
/*!
ADFun default constructor
The C++ syntax for this operation is
\verbatim
ADFun<Base> f
\endverbatim
An empty ADFun object is created.
The Dependent member function,
or the ADFun<Base> assingment operator,
can then be used to put an operation sequence in this ADFun object.
\tparam Base
is the base for the recording that can be stored in this ADFun object;
i.e., operation sequences that were recorded using the type \c AD<Base>.
*/
template <typename Base>
ADFun<Base>::ADFun(void) :
has_been_optimized_(false),
check_for_nan_(true) ,
compare_change_count_(1),
compare_change_number_(0),
compare_change_op_index_(0),
num_var_tape_(0)
{ }
/*!
ADFun assignment operator
The C++ syntax for this operation is
\verbatim
g = f
\endverbatim
where \c g and \c f are ADFun<Base> ADFun objects.
A copy of the the operation sequence currently stored in \c f
is placed in this ADFun object (called \c g above).
Any information currently stored in this ADFun object is lost.
\tparam Base
is the base for the recording that can be stored in this ADFun object;
i.e., operation sequences that were recorded using the type \c AD<Base>.
\param f
ADFun object containing the operation sequence to be copied.
*/
template <typename Base>
void ADFun<Base>::operator=(const ADFun<Base>& f)
{ size_t m = f.Range();
size_t n = f.Domain();
size_t i;
// go through member variables in ad_fun.hpp order
//
// size_t objects
has_been_optimized_ = f.has_been_optimized_;
check_for_nan_ = f.check_for_nan_;
compare_change_count_ = f.compare_change_count_;
compare_change_number_ = f.compare_change_number_;
compare_change_op_index_ = f.compare_change_op_index_;
num_order_taylor_ = f.num_order_taylor_;
cap_order_taylor_ = f.cap_order_taylor_;
num_direction_taylor_ = f.num_direction_taylor_;
num_var_tape_ = f.num_var_tape_;
//
// CppAD::vector objects
ind_taddr_.resize(n);
ind_taddr_ = f.ind_taddr_;
dep_taddr_.resize(m);
dep_taddr_ = f.dep_taddr_;
dep_parameter_.resize(m);
dep_parameter_ = f.dep_parameter_;
//
// pod_vector objects
taylor_ = f.taylor_;
cskip_op_ = f.cskip_op_;
load_op_ = f.load_op_;
//
// player
play_ = f.play_;
//
// sparse_pack
for_jac_sparse_pack_.resize(0, 0);
size_t n_set = f.for_jac_sparse_pack_.n_set();
size_t end = f.for_jac_sparse_pack_.end();
if( n_set > 0 )
{ CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ );
CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_set_.n_set() == 0 );
for_jac_sparse_pack_.resize(n_set, end);
for(i = 0; i < num_var_tape_ ; i++)
{ for_jac_sparse_pack_.assignment(
i ,
i ,
f.for_jac_sparse_pack_
);
}
}
//
// sparse_set
for_jac_sparse_set_.resize(0, 0);
n_set = f.for_jac_sparse_set_.n_set();
end = f.for_jac_sparse_set_.end();
if( n_set > 0 )
{ CPPAD_ASSERT_UNKNOWN( n_set == num_var_tape_ );
CPPAD_ASSERT_UNKNOWN( f.for_jac_sparse_pack_.n_set() == 0 );
for_jac_sparse_set_.resize(n_set, end);
for(i = 0; i < num_var_tape_; i++)
{ for_jac_sparse_set_.assignment(
i ,
i ,
f.for_jac_sparse_set_
);
}
}
}
/*!
ADFun constructor from an operation sequence.
The C++ syntax for this operation is
\verbatim
ADFun<Base> f(x, y)
\endverbatim
The operation sequence that started with the previous call
\c Independent(x), and that ends with this operation, is stored
in this \c ADFun<Base> object \c f.
\tparam Base
is the base for the recording that will be stored in the object \c f;
i.e., the operations were recorded using the type \c AD<Base>.
\tparam VectorAD
is a simple vector class with elements of typea \c AD<Base>.
\param x
is the independent variable vector for this ADFun object.
The domain dimension of this object will be the size of \a x.
\param y
is the dependent variable vector for this ADFun object.
The range dimension of this object will be the size of \a y.
\par Taylor Coefficients
A zero order forward mode sweep is done,
and if NDEBUG is not defined the resulting values for the
depenedent variables are checked against the values in \a y.
Thus, the zero order Taylor coefficients
corresponding to the value of the \a x vector
are stored in this ADFun object.
*/
template <typename Base>
template <typename VectorAD>
ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y)
{
CPPAD_ASSERT_KNOWN(
x.size() > 0,
"ADFun<Base>: independent variable vector has size zero."
);
CPPAD_ASSERT_KNOWN(
Variable(x[0]),
"ADFun<Base>: independent variable vector has been changed."
);
local::ADTape<Base>* tape = AD<Base>::tape_ptr(x[0].tape_id_);
CPPAD_ASSERT_KNOWN(
tape->size_independent_ == size_t ( x.size() ),
"ADFun<Base>: independent variable vector has been changed."
);
size_t j, n = x.size();
# ifndef NDEBUG
size_t i, m = y.size();
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_KNOWN(
size_t(x[j].taddr_) == (j+1),
"ADFun<Base>: independent variable vector has been changed."
);
CPPAD_ASSERT_KNOWN(
x[j].tape_id_ == x[0].tape_id_,
"ADFun<Base>: independent variable vector has been changed."
);
}
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_KNOWN(
CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) ,
"ADFun<Base>: dependent vector contains variables for"
"\na different tape than the independent variables."
);
}
# endif
// stop the tape and store the operation sequence
Dependent(tape, y);
// ad_fun.hpp member values not set by dependent
check_for_nan_ = true;
// allocate memory for one zero order taylor_ coefficient
CPPAD_ASSERT_UNKNOWN( num_order_taylor_ == 0 );
CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 0 );
size_t c = 1;
size_t r = 1;
capacity_order(c, r);
CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ == c );
CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r );
// set zero order coefficients corresponding to indpendent variables
CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() );
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == (j+1) );
taylor_[ ind_taddr_[j] ] = x[j].value_;
}
// use independent variable values to fill in values for others
CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
CPPAD_ASSERT_UNKNOWN( load_op_.size() == play_.num_load_op_rec() );
local::forward0sweep(std::cout, false,
n, num_var_tape_, &play_, cap_order_taylor_, taylor_.data(),
cskip_op_.data(), load_op_,
compare_change_count_,
compare_change_number_,
compare_change_op_index_
);
CPPAD_ASSERT_UNKNOWN( compare_change_count_ == 1 );
CPPAD_ASSERT_UNKNOWN( compare_change_number_ == 0 );
CPPAD_ASSERT_UNKNOWN( compare_change_op_index_ == 0 );
// now set the number of orders stored
num_order_taylor_ = 1;
# ifndef NDEBUG
// on MS Visual Studio 2012, CppAD required in front of isnan ?
for(i = 0; i < m; i++)
if( taylor_[dep_taddr_[i]] != y[i].value_ || CppAD::isnan( y[i].value_ ) )
{ using std::endl;
std::ostringstream buf;
buf << "A dependent variable value is not equal to "
<< "its tape evaluation value," << endl
<< "perhaps it is nan." << endl
<< "Dependent variable value = "
<< y[i].value_ << endl
<< "Tape evaluation value = "
<< taylor_[dep_taddr_[i]] << endl
<< "Difference = "
<< y[i].value_ - taylor_[dep_taddr_[i]] << endl
;
// buf.str() returns a string object with a copy of the current
// contents in the stream buffer.
std::string msg_str = buf.str();
// msg_str.c_str() returns a pointer to the c-string
// representation of the string object's value.
const char* msg_char_star = msg_str.c_str();
CPPAD_ASSERT_KNOWN(
0,
msg_char_star
);
}
# endif
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,19 +0,0 @@
# ifndef CPPAD_CORE_FUN_EVAL_HPP
# define CPPAD_CORE_FUN_EVAL_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.
-------------------------------------------------------------------------- */
# include <cppad/core/forward.hpp>
# include <cppad/core/reverse.hpp>
# include <cppad/core/sparse.hpp>
# endif

View File

@ -1,51 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_HASH_CODE_HPP
# define CPPAD_CORE_HASH_CODE_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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.
-------------------------------------------------------------------------- */
/*!
\file core/hash_code.hpp
CppAD hashing utility.
*/
# include <cppad/local/hash_code.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
General purpose hash code for an arbitrary value.
\tparam Value
is the type of the argument being hash coded.
It should be a plain old data class; i.e.,
the values included in the equality operator in the object and
not pointed to by the object.
\param value
the value that we are generating a hash code for.
All of the fields in value should have been set before the hash code
is computed (otherwise undefined values are used).
\return
is a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1.
\par Checked Assertions
\li \c std::numeric_limits<unsigned short>::max() >= CPPAD_HASH_TABLE_SIZE
\li \c sizeof(value) is even
\li \c sizeof(unsigned short) == 2
*/
template <class Value>
unsigned short hash_code(const Value& value)
{ return local::local_hash_code(value); }
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,214 +0,0 @@
# ifndef CPPAD_CORE_HESSIAN_HPP
# define CPPAD_CORE_HESSIAN_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 Hessian$$
$spell
hes
typename
Taylor
HesLuDet
const
$$
$section Hessian: Easy Driver$$
$mindex second derivative$$
$head Syntax$$
$icode%hes% = %f%.Hessian(%x%, %w%)
%$$
$icode%hes% = %f%.Hessian(%x%, %l%)
%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
The syntax above sets $icode hes$$ to the Hessian
The syntax above sets $icode h$$ to the Hessian
$latex \[
hes = \dpow{2}{x} \sum_{i=1}^m w_i F_i (x)
\] $$
The routine $cref sparse_hessian$$ may be faster in the case
where the Hessian is sparse.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/Hessian Uses Forward/Hessian/Hessian Uses Forward/$$ below).
$head x$$
The argument $icode x$$ has prototype
$codei%
const %Vector% &%x%
%$$
(see $cref/Vector/Hessian/Vector/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies
that point at which to evaluate the Hessian.
$head l$$
If the argument $icode l$$ is present, it has prototype
$codei%
size_t %l%
%$$
and is less than $icode m$$, the dimension of the
$cref/range/seq_property/Range/$$ space for $icode f$$.
It specifies the component of $icode F$$
for which we are evaluating the Hessian.
To be specific, in the case where the argument $icode l$$ is present,
$latex \[
w_i = \left\{ \begin{array}{ll}
1 & i = l \\
0 & {\rm otherwise}
\end{array} \right.
\] $$
$head w$$
If the argument $icode w$$ is present, it has prototype
$codei%
const %Vector% &%w%
%$$
and size $latex m$$.
It specifies the value of $latex w_i$$ in the expression
for $icode h$$.
$head hes$$
The result $icode hes$$ has prototype
$codei%
%Vector% %hes%
%$$
(see $cref/Vector/Hessian/Vector/$$ below)
and its size is $latex n * n$$.
For $latex j = 0 , \ldots , n - 1 $$
and $latex \ell = 0 , \ldots , n - 1$$
$latex \[
hes [ j * n + \ell ] = \DD{ w^{\rm T} F }{ x_j }{ x_\ell } ( x )
\] $$
$head Vector$$
The type $icode Vector$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$icode Base$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head Hessian Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code Hessian$$,
the zero order Taylor coefficients correspond to
$icode%f%.Forward(0, %x%)%$$
and the other coefficients are unspecified.
$head Example$$
$children%
example/general/hessian.cpp%
example/general/hes_lagrangian.cpp
%$$
The routines
$cref hessian.cpp$$ and
$cref hes_lagrangian.cpp$$
are examples and tests of $code Hessian$$.
They return $code true$$, if they succeed and $code false$$ otherwise.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <typename Base>
template <typename Vector>
Vector ADFun<Base>::Hessian(const Vector &x, size_t l)
{ size_t i, m = Range();
CPPAD_ASSERT_KNOWN(
l < m,
"Hessian: index i is not less than range dimension for f"
);
Vector w(m);
for(i = 0; i < m; i++)
w[i] = Base(0.0);
w[l] = Base(1.0);
return Hessian(x, w);
}
template <typename Base>
template <typename Vector>
Vector ADFun<Base>::Hessian(const Vector &x, const Vector &w)
{ size_t j;
size_t k;
size_t n = Domain();
// check Vector is Simple Vector class with Base type elements
CheckSimpleVector<Base, Vector>();
CPPAD_ASSERT_KNOWN(
size_t(x.size()) == n,
"Hessian: length of x not equal domain dimension for f"
);
CPPAD_ASSERT_KNOWN(
size_t(w.size()) == Range(),
"Hessian: length of w not equal range dimension for f"
);
// point at which we are evaluating the Hessian
Forward(0, x);
// define the return value
Vector hes(n * n);
// direction vector for calls to forward
Vector u(n);
for(j = 0; j < n; j++)
u[j] = Base(0.0);
// location for return values from Reverse
Vector ddw(n * 2);
// loop over forward directions
for(j = 0; j < n; j++)
{ // evaluate partials of entire function w.r.t. j-th coordinate
u[j] = Base(1.0);
Forward(1, u);
u[j] = Base(0.0);
// evaluate derivative of partial corresponding to F_i
ddw = Reverse(2, w);
// return desired components
for(k = 0; k < n; k++)
hes[k * n + j] = ddw[k * 2 + 1];
}
return hes;
}
} // END CppAD namespace
# endif

View File

@ -1,105 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_IDENTICAL_HPP
# define CPPAD_CORE_IDENTICAL_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.
-------------------------------------------------------------------------- */
# include <cppad/core/define.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file identical.hpp
Check if certain properties is true for any possible AD tape play back.
*/
// ---------------------------------------------------------------------------
/*!
Determine if an AD<Base> object is a parameter, and could never have
a different value during any tape playback.
An AD<Base> object \c x is identically a parameter if and only if
all of the objects in the following chain are parameters:
\code
x , x.value , x.value.value , ...
\endcode
In such a case, the value of the object will always be the same
no matter what the independent variable values are at any level.
\param x
values that we are checking for identically a pamameter.
\return
returns true iff \c x is identically a parameter.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool IdenticalPar(const AD<Base> &x)
{ return Parameter(x) && IdenticalPar(x.value_); }
// Zero ==============================================================
/*!
Determine if an AD<Base> is equal to zero,
and must be equal zero during any tape playback.
\param x
object that we are checking.
\return
returns true if and only if
\c x is equals zero and is identically a parameter \ref CppAD::IdenticalPar.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool IdenticalZero(const AD<Base> &x)
{ return Parameter(x) && IdenticalZero(x.value_); }
// One ==============================================================
/*!
Determine if an AD<Base> is equal to one,
and must be equal one during any tape playback.
\param x
object that we are checking.
\return
returns true if and only if
\c x is equals one and is identically a parameter \ref CppAD::IdenticalPar.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool IdenticalOne(const AD<Base> &x)
{ return Parameter(x) && IdenticalOne(x.value_); }
// Equal ===================================================================
/*!
Determine if two AD<Base> objects are equal,
and must be equal during any tape playback.
\param x
first of two objects we are checking for equal.
\param y
second of two objects we are checking for equal.
\return
returns true if and only if
the arguments are equal and both identically parameters \ref CppAD::IdenticalPar.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool IdenticalEqualPar
(const AD<Base> &x, const AD<Base> &y)
{ bool parameter;
parameter = ( Parameter(x) & Parameter(y) );
return parameter && IdenticalEqualPar(x.value_, y.value_);
}
// ==========================================================================
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,175 +0,0 @@
# ifndef CPPAD_CORE_INDEPENDENT_HPP
# define CPPAD_CORE_INDEPENDENT_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 Independent$$
$spell
op
alloc
num
Cpp
bool
const
var
typename
$$
$section Declare Independent Variables and Start Recording$$
$head Syntax$$
$codei%Independent(%x%)
%$$
$codei%Independent(%x%, %abort_op_index%)
%$$
$head Purpose$$
Start recording
$cref/AD of Base/glossary/AD of Base/$$ operations
with $icode x$$ as the independent variable vector.
Once the
$cref/operation sequence/glossary/Operation/Sequence/$$ is completed,
it must be transferred to a function object; see below.
$head Start Recording$$
An operation sequence recording is started by the commands
$codei%
Independent(%x%)
Independent(%x%, %abort_op_index%)
%$$
$head Stop Recording$$
The recording is stopped,
and the operation sequence is transferred to the AD function object $icode f$$,
using either the $cref/function constructor/FunConstruct/$$
$codei%
ADFun<%Base%> %f%(%x%, %y%)
%$$
or the $cref/dependent variable specifier/Dependent/$$
$codei%
%f%.Dependent(%x%, %y%)
%$$
The only other way to stop a recording is using
$cref abort_recording$$.
Between when the recording is started and when it stopped,
we refer to the elements of $icode x$$,
and the values that depend on the elements of $icode x$$,
as $codei%AD<%Base%>%$$ variables.
$head x$$
The vector $icode x$$ has prototype
$codei%
%VectorAD% &%x%
%$$
(see $icode VectorAD$$ below).
The size of the vector $icode x$$, must be greater than zero,
and is the number of independent variables for this
AD operation sequence.
$head abort_op_index$$
It specifies the operator index at which the execution is be aborted
by calling the CppAD $cref/error handler/ErrorHandler/$$.
When this error handler leads to an assert, the user
can inspect the call stack to see the source code corresponding to
this operator index; see
$cref/purpose/compare_change/op_index/Purpose/$$.
No abort will occur if $icode abort_op_index$$ is zero,
of if $cref/NDEBUG/Faq/Speed/NDEBUG/$$ is defined.
$head VectorAD$$
The type $icode VectorAD$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$codei%AD<%Base%>%$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head Parallel Mode$$
Each thread can have one, and only one, active recording.
A call to $code Independent$$ starts the recording for the current thread.
The recording must be stopped by a corresponding call to
$codei%
ADFun<%Base%> %f%( %x%, %y%)
%$$
or
$codei%
%f%.Dependent( %x%, %y%)
%$$
or $cref abort_recording$$
preformed by the same thread; i.e.,
$cref/thread_alloc::thread_num/ta_thread_num/$$ must be the same.
$head Example$$
$children%
example/general/independent.cpp
%$$
The file
$cref independent.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/local/independent.hpp>
/*!
\file core/independent.hpp
Declare the independent variables
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Declaration of independent variables.
\tparam VectorAD
This is simple vector type with elements of type AD<Base>.
\param x
Vector of the independent variablerd.
\param abort_op_index
operator index at which execution will be aborted (during the recording
of operations). The value zero corresponds to not aborting (will not match).
*/
template <typename VectorAD>
inline void Independent(VectorAD &x, size_t abort_op_index)
{ typedef typename VectorAD::value_type ADBase;
typedef typename ADBase::value_type Base;
CPPAD_ASSERT_KNOWN(
ADBase::tape_ptr() == CPPAD_NULL,
"Independent: cannot create a new tape because\n"
"a previous tape is still active (for this thread).\n"
"AD<Base>::abort_recording() would abort this previous recording."
);
local::ADTape<Base>* tape = ADBase::tape_manage(tape_manage_new);
tape->Independent(x, abort_op_index);
}
/*!
Declaration of independent variables without abort option.
\tparam VectorAD
This is simple vector type with elements of type AD<Base>.
\param x
Vector of the independent variablerd.
*/
template <typename VectorAD>
inline void Independent(VectorAD &x)
{ size_t abort_op_index = 0;
Independent(x, abort_op_index);
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,112 +0,0 @@
# ifndef CPPAD_CORE_INTEGER_HPP
# define CPPAD_CORE_INTEGER_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 Integer$$
$spell
std
VecAD
CppAD
namespace
const
bool
$$
$section Convert From AD to Integer$$
$head Syntax$$
$icode%i% = Integer(%x%)%$$
$head Purpose$$
Converts from an AD type to the corresponding integer value.
$head i$$
The result $icode i$$ has prototype
$codei%
int %i%
%$$
$head x$$
$subhead Real Types$$
If the argument $icode x$$ has either of the following prototypes:
$codei%
const float %% &%x%
const double %% &%x%
%$$
the fractional part is dropped to form the integer value.
For example, if $icode x$$ is 1.5, $icode i$$ is 1.
In general, if $latex x \geq 0$$, $icode i$$ is the
greatest integer less than or equal $icode x$$.
If $latex x \leq 0$$, $icode i$$ is the
smallest integer greater than or equal $icode x$$.
$subhead Complex Types$$
If the argument $icode x$$ has either of the following prototypes:
$codei%
const std::complex<float> %% &%x%
const std::complex<double> %% &%x%
%$$
The result $icode i$$ is given by
$codei%
%i% = Integer(%x%.real())
%$$
$subhead AD Types$$
If the argument $icode x$$ has either of the following prototypes:
$codei%
const AD<%Base%> &%x%
const VecAD<%Base%>::reference &%x%
%$$
$icode Base$$ must support the $code Integer$$ function and
the conversion has the same meaning as for $icode Base$$.
$head Operation Sequence$$
The result of this operation is not an
$cref/AD of Base/glossary/AD of Base/$$ object.
Thus it will not be recorded as part of an
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$children%
example/general/integer.cpp
%$$
The file
$cref integer.cpp$$
contains an example and test of this operation.
$end
------------------------------------------------------------------------------
*/
namespace CppAD {
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
int Integer(const AD<Base> &x)
{ return Integer(x.value_); }
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
int Integer(const VecAD_reference<Base> &x)
{ return Integer( x.ADBase() ); }
}
# endif

View File

@ -1,233 +0,0 @@
# ifndef CPPAD_CORE_JACOBIAN_HPP
# define CPPAD_CORE_JACOBIAN_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 Jacobian$$
$spell
jac
typename
Taylor
Jacobian
DetLu
const
$$
$section Jacobian: Driver Routine$$
$mindex Jacobian first derivative$$
$head Syntax$$
$icode%jac% = %f%.Jacobian(%x%)%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
The syntax above sets $icode jac$$ to the
Jacobian of $icode F$$ evaluated at $icode x$$; i.e.,
$latex \[
jac = F^{(1)} (x)
\] $$
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/Forward or Reverse/Jacobian/Forward or Reverse/$$ below).
$head x$$
The argument $icode x$$ has prototype
$codei%
const %Vector% &%x%
%$$
(see $cref/Vector/Jacobian/Vector/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies
that point at which to evaluate the Jacobian.
$head jac$$
The result $icode jac$$ has prototype
$codei%
%Vector% %jac%
%$$
(see $cref/Vector/Jacobian/Vector/$$ below)
and its size is $latex m * n$$; i.e., the product of the
$cref/domain/seq_property/Domain/$$
and
$cref/range/seq_property/Range/$$
dimensions for $icode f$$.
For $latex i = 0 , \ldots , m - 1 $$
and $latex j = 0 , \ldots , n - 1$$
$latex \[.
jac[ i * n + j ] = \D{ F_i }{ x_j } ( x )
\] $$
$head Vector$$
The type $icode Vector$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$icode Base$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head Forward or Reverse$$
This will use order zero Forward mode and either
order one Forward or order one Reverse to compute the Jacobian
(depending on which it estimates will require less work).
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code Jacobian$$,
the zero order Taylor coefficients correspond to
$icode%f%.Forward(0, %x%)%$$
and the other coefficients are unspecified.
$head Example$$
$children%
example/general/jacobian.cpp
%$$
The routine
$cref/Jacobian/jacobian.cpp/$$ is both an example and test.
It returns $code true$$, if it succeeds and $code false$$ otherwise.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <typename Base, typename Vector>
void JacobianFor(ADFun<Base> &f, const Vector &x, Vector &jac)
{ size_t i;
size_t j;
size_t n = f.Domain();
size_t m = f.Range();
// check Vector is Simple Vector class with Base type elements
CheckSimpleVector<Base, Vector>();
CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == f.Domain() );
CPPAD_ASSERT_UNKNOWN( size_t(jac.size()) == f.Range() * f.Domain() );
// argument and result for forward mode calculations
Vector u(n);
Vector v(m);
// initialize all the components
for(j = 0; j < n; j++)
u[j] = Base(0.0);
// loop through the different coordinate directions
for(j = 0; j < n; j++)
{ // set u to the j-th coordinate direction
u[j] = Base(1.0);
// compute the partial of f w.r.t. this coordinate direction
v = f.Forward(1, u);
// reset u to vector of all zeros
u[j] = Base(0.0);
// return the result
for(i = 0; i < m; i++)
jac[ i * n + j ] = v[i];
}
}
template <typename Base, typename Vector>
void JacobianRev(ADFun<Base> &f, const Vector &x, Vector &jac)
{ size_t i;
size_t j;
size_t n = f.Domain();
size_t m = f.Range();
CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == f.Domain() );
CPPAD_ASSERT_UNKNOWN( size_t(jac.size()) == f.Range() * f.Domain() );
// argument and result for reverse mode calculations
Vector u(n);
Vector v(m);
// initialize all the components
for(i = 0; i < m; i++)
v[i] = Base(0.0);
// loop through the different coordinate directions
for(i = 0; i < m; i++)
{ if( f.Parameter(i) )
{ // return zero for this component of f
for(j = 0; j < n; j++)
jac[ i * n + j ] = Base(0.0);
}
else
{
// set v to the i-th coordinate direction
v[i] = Base(1.0);
// compute the derivative of this component of f
u = f.Reverse(1, v);
// reset v to vector of all zeros
v[i] = Base(0.0);
// return the result
for(j = 0; j < n; j++)
jac[ i * n + j ] = u[j];
}
}
}
template <typename Base>
template <typename Vector>
Vector ADFun<Base>::Jacobian(const Vector &x)
{ size_t i;
size_t n = Domain();
size_t m = Range();
CPPAD_ASSERT_KNOWN(
size_t(x.size()) == n,
"Jacobian: length of x not equal domain dimension for F"
);
// point at which we are evaluating the Jacobian
Forward(0, x);
// work factor for forward mode
size_t workForward = n;
// work factor for reverse mode
size_t workReverse = 0;
for(i = 0; i < m; i++)
{ if( ! Parameter(i) )
++workReverse;
}
// choose the method with the least work
Vector jac( n * m );
if( workForward <= workReverse )
JacobianFor(*this, x, jac);
else JacobianRev(*this, x, jac);
return jac;
}
} // END CppAD namespace
# endif

View File

@ -1,91 +0,0 @@
# ifndef CPPAD_CORE_LOG1P_HPP
# define CPPAD_CORE_LOG1P_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 log1p$$
$spell
CppAD
$$
$section The Logarithm of One Plus Argument: log1p$$
$head Syntax$$
$icode%y% = log1p(%x%)%$$
$head Description$$
Returns the value of the logarithm of one plus argument which is defined
by $icode%y% == log(1 + %x%)%$$.
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head CPPAD_USE_CPLUSPLUS_2011$$
$subhead true$$
If this preprocessor symbol is true ($code 1$$),
and $icode x$$ is an AD type,
this is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$subhead false$$
If this preprocessor symbol is false ($code 0$$),
CppAD uses the representation
$latex \[
\R{log1p} (x) = \log(1 + x)
\] $$
to compute this function.
$head Example$$
$children%
example/general/log1p.cpp
%$$
The file
$cref log1p.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
# include <cppad/configure.hpp>
# if ! CPPAD_USE_CPLUSPLUS_2011
// BEGIN CppAD namespace
namespace CppAD {
template <class Type>
Type log1p_template(const Type &x)
{ return CppAD::log(Type(1) + x);
}
inline float log1p(const float &x)
{ return log1p_template(x); }
inline double log1p(const double &x)
{ return log1p_template(x); }
template <class Base>
inline AD<Base> log1p(const AD<Base> &x)
{ return log1p_template(x); }
template <class Base>
inline AD<Base> log1p(const VecAD_reference<Base> &x)
{ return log1p_template( x.ADBase() ); }
} // END CppAD namespace
# endif // CPPAD_USE_CPLUSPLUS_2011
# endif // CPPAD_LOG1P_INCLUDED

View File

@ -1,337 +0,0 @@
# ifndef CPPAD_CORE_LU_RATIO_HPP
# define CPPAD_CORE_LU_RATIO_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 LuRatio$$
$spell
cppad.hpp
xk
Cpp
Lu
bool
const
ip
jp
std
ADvector
$$
$section LU Factorization of A Square Matrix and Stability Calculation$$
$mindex LuRatio linear equation solve$$
$head Syntax$$
$code# include <cppad/cppad.hpp>$$
$pre
$$
$icode%sign% = LuRatio(%ip%, %jp%, %LU%, %ratio%)%$$
$head Description$$
Computes an LU factorization of the matrix $icode A$$
where $icode A$$ is a square matrix.
A measure of the numerical stability called $icode ratio$$ is calculated.
This ratio is useful when the results of $code LuRatio$$ are
used as part of an $cref ADFun$$ object.
$head Include$$
This routine is designed to be used with AD objects and
requires the $code cppad/cppad.hpp$$ file to be included.
$head Matrix Storage$$
All matrices are stored in row major order.
To be specific, if $latex Y$$ is a vector
that contains a $latex p$$ by $latex q$$ matrix,
the size of $latex Y$$ must be equal to $latex p * q $$ and for
$latex i = 0 , \ldots , p-1$$,
$latex j = 0 , \ldots , q-1$$,
$latex \[
Y_{i,j} = Y[ i * q + j ]
\] $$
$head sign$$
The return value $icode sign$$ has prototype
$codei%
int %sign%
%$$
If $icode A$$ is invertible, $icode sign$$ is plus or minus one
and is the sign of the permutation corresponding to the row ordering
$icode ip$$ and column ordering $icode jp$$.
If $icode A$$ is not invertible, $icode sign$$ is zero.
$head ip$$
The argument $icode ip$$ has prototype
$codei%
%SizeVector% &%ip%
%$$
(see description of $cref/SizeVector/LuFactor/SizeVector/$$ below).
The size of $icode ip$$ is referred to as $icode n$$ in the
specifications below.
The input value of the elements of $icode ip$$ does not matter.
The output value of the elements of $icode ip$$ determine
the order of the rows in the permuted matrix.
$head jp$$
The argument $icode jp$$ has prototype
$codei%
%SizeVector% &%jp%
%$$
(see description of $cref/SizeVector/LuFactor/SizeVector/$$ below).
The size of $icode jp$$ must be equal to $icode n$$.
The input value of the elements of $icode jp$$ does not matter.
The output value of the elements of $icode jp$$ determine
the order of the columns in the permuted matrix.
$head LU$$
The argument $icode LU$$ has the prototype
$codei%
%ADvector% &%LU%
%$$
and the size of $icode LU$$ must equal $latex n * n$$
(see description of $cref/ADvector/LuRatio/ADvector/$$ below).
$subhead A$$
We define $icode A$$ as the matrix corresponding to the input
value of $icode LU$$.
$subhead P$$
We define the permuted matrix $icode P$$ in terms of $icode A$$ by
$codei%
%P%(%i%, %j%) = %A%[ %ip%[%i%] * %n% + %jp%[%j%] ]
%$$
$subhead L$$
We define the lower triangular matrix $icode L$$ in terms of the
output value of $icode LU$$.
The matrix $icode L$$ is zero above the diagonal
and the rest of the elements are defined by
$codei%
%L%(%i%, %j%) = %LU%[ %ip%[%i%] * %n% + %jp%[%j%] ]
%$$
for $latex i = 0 , \ldots , n-1$$ and $latex j = 0 , \ldots , i$$.
$subhead U$$
We define the upper triangular matrix $icode U$$ in terms of the
output value of $icode LU$$.
The matrix $icode U$$ is zero below the diagonal,
one on the diagonal,
and the rest of the elements are defined by
$codei%
%U%(%i%, %j%) = %LU%[ %ip%[%i%] * %n% + %jp%[%j%] ]
%$$
for $latex i = 0 , \ldots , n-2$$ and $latex j = i+1 , \ldots , n-1$$.
$subhead Factor$$
If the return value $icode sign$$ is non-zero,
$codei%
%L% * %U% = %P%
%$$
If the return value of $icode sign$$ is zero,
the contents of $icode L$$ and $icode U$$ are not defined.
$subhead Determinant$$
If the return value $icode sign$$ is zero,
the determinant of $icode A$$ is zero.
If $icode sign$$ is non-zero,
using the output value of $icode LU$$
the determinant of the matrix $icode A$$ is equal to
$codei%
%sign% * %LU%[%ip%[0], %jp%[0]] * %...% * %LU%[%ip%[%n%-1], %jp%[%n%-1]]
%$$
$head ratio$$
The argument $icode ratio$$ has prototype
$codei%
AD<%Base%> &%ratio%
%$$
On input, the value of $icode ratio$$ does not matter.
On output it is a measure of how good the choice of pivots is.
For $latex p = 0 , \ldots , n-1$$,
the $th p$$ pivot element is the element of maximum absolute value of a
$latex (n-p) \times (n-p)$$ sub-matrix.
The ratio of each element of sub-matrix divided by the pivot element
is computed.
The return value of $icode ratio$$ is the maximum absolute value of
such ratios over with respect to all elements and all the pivots.
$subhead Purpose$$
Suppose that the execution of a call to $code LuRatio$$
is recorded in the $codei%ADFun<%Base%>%$$ object $icode F$$.
Then a call to $cref Forward$$ of the form
$codei%
%F%.Forward(%k%, %xk%)
%$$
with $icode k$$ equal to zero will revaluate this Lu factorization
with the same pivots and a new value for $icode A$$.
In this case, the resulting $icode ratio$$ may not be one.
If $icode ratio$$ is too large (the meaning of too large is up to you),
the current pivots do not yield a stable LU factorization of $icode A$$.
A better choice for the pivots (for this value of $icode A$$)
will be made if you recreate the $code ADFun$$ object
starting with the $cref Independent$$ variable values
that correspond to the vector $icode xk$$.
$head SizeVector$$
The type $icode SizeVector$$ must be a $cref SimpleVector$$ class with
$cref/elements of type size_t/SimpleVector/Elements of Specified Type/$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head ADvector$$
The type $icode ADvector$$ must be a
$cref/simple vector class/SimpleVector/$$ with elements of type
$codei%AD<%Base%>%$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head Example$$
$children%
example/general/lu_ratio.cpp
%$$
The file $cref lu_ratio.cpp$$
contains an example and test of using $code LuRatio$$.
It returns true if it succeeds and false otherwise.
$end
--------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN CppAD namespace
// Lines different from the code in cppad/lu_factor.hpp end with //
template <class SizeVector, class ADvector, class Base> //
int LuRatio(SizeVector &ip, SizeVector &jp, ADvector &LU, AD<Base> &ratio) //
{
typedef ADvector FloatVector; //
typedef AD<Base> Float; //
// check numeric type specifications
CheckNumericType<Float>();
// check simple vector class specifications
CheckSimpleVector<Float, FloatVector>();
CheckSimpleVector<size_t, SizeVector>();
size_t i, j; // some temporary indices
const Float zero( 0 ); // the value zero as a Float object
size_t imax; // row index of maximum element
size_t jmax; // column indx of maximum element
Float emax; // maximum absolute value
size_t p; // count pivots
int sign; // sign of the permutation
Float etmp; // temporary element
Float pivot; // pivot element
// -------------------------------------------------------
size_t n = size_t(ip.size());
CPPAD_ASSERT_KNOWN(
size_t(jp.size()) == n,
"Error in LuFactor: jp must have size equal to n"
);
CPPAD_ASSERT_KNOWN(
size_t(LU.size()) == n * n,
"Error in LuFactor: LU must have size equal to n * m"
);
// -------------------------------------------------------
// initialize row and column order in matrix not yet pivoted
for(i = 0; i < n; i++)
{ ip[i] = i;
jp[i] = i;
}
// initialize the sign of the permutation
sign = 1;
// initialize the ratio //
ratio = Float(1); //
// ---------------------------------------------------------
// Reduce the matrix P to L * U using n pivots
for(p = 0; p < n; p++)
{ // determine row and column corresponding to element of
// maximum absolute value in remaining part of P
imax = jmax = n;
emax = zero;
for(i = p; i < n; i++)
{ for(j = p; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN(
(ip[i] < n) & (jp[j] < n)
);
etmp = LU[ ip[i] * n + jp[j] ];
// check if maximum absolute value so far
if( AbsGeq (etmp, emax) )
{ imax = i;
jmax = j;
emax = etmp;
}
}
}
for(i = p; i < n; i++) //
{ for(j = p; j < n; j++) //
{ etmp = fabs(LU[ ip[i] * n + jp[j] ] / emax); //
ratio = //
CondExpGt(etmp, ratio, etmp, ratio); //
} //
} //
CPPAD_ASSERT_KNOWN(
(imax < n) & (jmax < n) ,
"AbsGeq must return true when second argument is zero"
);
if( imax != p )
{ // switch rows so max absolute element is in row p
i = ip[p];
ip[p] = ip[imax];
ip[imax] = i;
sign = -sign;
}
if( jmax != p )
{ // switch columns so max absolute element is in column p
j = jp[p];
jp[p] = jp[jmax];
jp[jmax] = j;
sign = -sign;
}
// pivot using the max absolute element
pivot = LU[ ip[p] * n + jp[p] ];
// check for determinant equal to zero
if( pivot == zero )
{ // abort the mission
return 0;
}
// Reduce U by the elementary transformations that maps
// LU( ip[p], jp[p] ) to one. Only need transform elements
// above the diagonal in U and LU( ip[p] , jp[p] ) is
// corresponding value below diagonal in L.
for(j = p+1; j < n; j++)
LU[ ip[p] * n + jp[j] ] /= pivot;
// Reduce U by the elementary transformations that maps
// LU( ip[i], jp[p] ) to zero. Only need transform elements
// above the diagonal in U and LU( ip[i], jp[p] ) is
// corresponding value below diagonal in L.
for(i = p+1; i < n; i++ )
{ etmp = LU[ ip[i] * n + jp[p] ];
for(j = p+1; j < n; j++)
{ LU[ ip[i] * n + jp[j] ] -=
etmp * LU[ ip[p] * n + jp[j] ];
}
}
}
return sign;
}
} // END CppAD namespace
# endif

View File

@ -1,102 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_MUL_HPP
# define CPPAD_CORE_MUL_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 CppAD namespace
namespace CppAD {
template <class Base>
AD<Base> operator * (const AD<Base> &left , const AD<Base> &right)
{
// compute the Base part
AD<Base> result;
result.value_ = left.value_ * right.value_;
CPPAD_ASSERT_UNKNOWN( Parameter(result) );
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return result;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_left = left.tape_id_ == tape_id;
bool var_right = right.tape_id_ == tape_id;
if( var_left )
{ if( var_right )
{ // result = variable * variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulvvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(left.taddr_, right.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::MulvvOp);
// make result a variable
result.tape_id_ = tape_id;
}
else if( IdenticalZero(right.value_) )
{ // result = variable * 0
}
else if( IdenticalOne(right.value_) )
{ // result = variable * 1
result.make_variable(left.tape_id_, left.taddr_);
}
else
{ // result = variable * parameter
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(p, left.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::MulpvOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
else if( var_right )
{ if( IdenticalZero(left.value_) )
{ // result = 0 * variable
}
else if( IdenticalOne(left.value_) )
{ // result = 1 * variable
result.make_variable(right.tape_id_, right.taddr_);
}
else
{ // result = parameter * variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(left.value_);
tape->Rec_.PutArg(p, right.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::MulpvOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
return result;
}
// convert other cases into the case above
CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(*)
} // END CppAD namespace
# endif

View File

@ -1,102 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_MUL_EQ_HPP
# define CPPAD_CORE_MUL_EQ_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 CppAD namespace
namespace CppAD {
template <class Base>
AD<Base>& AD<Base>::operator *= (const AD<Base> &right)
{
// compute the Base part
Base left;
left = value_;
value_ *= right.value_;
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return *this;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_left = tape_id_ == tape_id;
bool var_right = right.tape_id_ == tape_id;
if( var_left )
{ if( var_right )
{ // this = variable * variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulvvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(taddr_, right.taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::MulvvOp);
// make this a variable
CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );
}
else if( IdenticalOne( right.value_ ) )
{ // this = variable * 1
}
else if( IdenticalZero( right.value_ ) )
{ // this = variable * 0
make_parameter();
}
else
{ // this = variable * parameter
// = parameter * variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(right.value_);
tape->Rec_.PutArg(p, taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::MulpvOp);
// make this a variable
CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );
}
}
else if( var_right )
{ if( IdenticalZero(left) )
{ // this = 0 * right
}
else if( IdenticalOne(left) )
{ // this = 1 * right
make_variable(right.tape_id_, right.taddr_);
}
else
{ // this = parameter * variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(left);
tape->Rec_.PutArg(p, right.taddr_);
// put operator in the tape
taddr_ = tape->Rec_.PutOp(local::MulpvOp);
// make this a variable
tape_id_ = tape_id;
}
}
return *this;
}
CPPAD_FOLD_ASSIGNMENT_OPERATOR(*=)
} // END CppAD namespace
# endif

View File

@ -1,188 +0,0 @@
# ifndef CPPAD_CORE_NEAR_EQUAL_EXT_HPP
# define CPPAD_CORE_NEAR_EQUAL_EXT_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 NearEqualExt$$
$spell
cout
endl
Microsoft
std
Cpp
namespace
const
bool
$$
$section Compare AD and Base Objects for Nearly Equal$$
$mindex NearEqual with$$
$head Syntax$$
$icode%b% = NearEqual(%x%, %y%, %r%, %a%)%$$
$head Purpose$$
The routine $cref NearEqual$$ determines if two objects of
the same type are nearly.
This routine is extended to the case where one object can have type
$icode Type$$ while the other can have type
$codei%AD<%Type%>%$$ or
$codei%AD< std::complex<%Type%> >%$$.
$head x$$
The arguments $icode x$$
has one of the following possible prototypes:
$codei%
const %Type% &%x%
const AD<%Type%> &%x%
const AD< std::complex<%Type%> > &%x%
%$$
$head y$$
The arguments $icode y$$
has one of the following possible prototypes:
$codei%
const %Type% &%y%
const AD<%Type%> &%y%
const AD< std::complex<%Type%> > &%x%
%$$
$head r$$
The relative error criteria $icode r$$ has prototype
$codei%
const %Type% &%r%
%$$
It must be greater than or equal to zero.
The relative error condition is defined as:
$latex \[
\frac{ | x - y | } { |x| + |y| } \leq r
\] $$
$head a$$
The absolute error criteria $icode a$$ has prototype
$codei%
const %Type% &%a%
%$$
It must be greater than or equal to zero.
The absolute error condition is defined as:
$latex \[
| x - y | \leq a
\] $$
$head b$$
The return value $icode b$$ has prototype
$codei%
bool %b%
%$$
If either $icode x$$ or $icode y$$ is infinite or not a number,
the return value is false.
Otherwise, if either the relative or absolute error
condition (defined above) is satisfied, the return value is true.
Otherwise, the return value is false.
$head Type$$
The type $icode Type$$ must be a
$cref NumericType$$.
The routine $cref CheckNumericType$$ will generate
an error message if this is not the case.
If $icode a$$ and $icode b$$ have type $icode Type$$,
the following operation must be defined
$table
$bold Operation$$ $cnext
$bold Description$$ $rnext
$icode%a% <= %b%$$ $cnext
less that or equal operator (returns a $code bool$$ object)
$tend
$head Operation Sequence$$
The result of this operation is not an
$cref/AD of Base/glossary/AD of Base/$$ object.
Thus it will not be recorded as part of an
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$children%
example/general/near_equal_ext.cpp
%$$
The file $cref near_equal_ext.cpp$$ contains an example
and test of this extension of $cref NearEqual$$.
It return true if it succeeds and false otherwise.
$end
*/
// BEGIN CppAD namespace
namespace CppAD {
// ------------------------------------------------------------------------
// fold into base type and then use <cppad/near_equal.hpp>
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(
const AD<Base> &x, const AD<Base> &y, const Base &r, const Base &a)
{ return NearEqual(x.value_, y.value_, r, a);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(
const Base &x, const AD<Base> &y, const Base &r, const Base &a)
{ return NearEqual(x, y.value_, r, a);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(
const AD<Base> &x, const Base &y, const Base &r, const Base &a)
{ return NearEqual(x.value_, y, r, a);
}
// fold into AD type and then use cases above
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(
const VecAD_reference<Base> &x, const VecAD_reference<Base> &y,
const Base &r, const Base &a)
{ return NearEqual(x.ADBase(), y.ADBase(), r, a);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(const VecAD_reference<Base> &x, const AD<Base> &y,
const Base &r, const Base &a)
{ return NearEqual(x.ADBase(), y, r, a);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(const VecAD_reference<Base> &x, const Base &y,
const Base &r, const Base &a)
{ return NearEqual(x.ADBase(), y, r, a);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(const AD<Base> &x, const VecAD_reference<Base> &y,
const Base &r, const Base &a)
{ return NearEqual(x, y.ADBase(), r, a);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool NearEqual(const Base &x, const VecAD_reference<Base> &y,
const Base &r, const Base &a)
{ return NearEqual(x, y.ADBase(), r, a);
}
} // END CppAD namespace
# endif

View File

@ -1,129 +0,0 @@
# ifndef CPPAD_CORE_NUM_SKIP_HPP
# define CPPAD_CORE_NUM_SKIP_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 number_skip$$
$spell
optimizer
var
taylor_
$$
$section Number of Variables that Can be Skipped$$
$mindex number_skip$$
$head Syntax$$
$icode%n% = %f%.number_skip()%$$
$subhead See Also$$
$cref seq_property$$
$head Purpose$$
The $cref/conditional expressions/CondExp/$$ use either the
$cref/if_true/CondExp/$$ or $cref/if_false/CondExp/$$.
Hence, some terms only need to be evaluated
depending on the value of the comparison in the conditional expression.
The $cref optimize$$ option is capable of detecting some of these
case and determining variables that can be skipped.
This routine returns the number such variables.
$head n$$
The return value $icode n$$ has type $code size_t$$
is the number of variables that the optimizer has determined can be skipped
(given the independent variable values specified by the previous call to
$cref/f.Forward/Forward/$$ for order zero).
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
$children%
example/general/number_skip.cpp
%$$
$head Example$$
The file $cref number_skip.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
// This routine is not const because it runs through the operations sequence
// 2DO: compute this value during zero order forward operations.
template <typename Base>
size_t ADFun<Base>::number_skip(void)
{ // must pass through operation sequence to map operations to variables
local::OpCode op;
size_t i_op;
size_t i_var;
const addr_t* arg;
// information defined by forward_user
size_t user_old=0, user_m=0, user_n=0, user_i=0, user_j=0;
local::enum_user_state user_state;
// number of variables skipped
size_t num_var_skip = 0;
// start playback
user_state = local::start_user;
play_.forward_start(op, arg, i_op, i_var);
CPPAD_ASSERT_UNKNOWN(op == local::BeginOp)
while(op != local::EndOp)
{ // next op
play_.forward_next(op, arg, i_op, i_var);
//
if( op == local::UserOp )
{ // skip only appears at front or back UserOp of user atomic call
bool skip_call = cskip_op_[i_op];
CPPAD_ASSERT_UNKNOWN( user_state == local::start_user );
play_.forward_user(
op, user_state, user_old, user_m, user_n, user_i, user_j
);
CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );
size_t num_op = user_m + user_n + 1;
for(size_t i = 0; i < num_op; i++)
{ play_.forward_next(op, arg, i_op, i_var);
play_.forward_user(
op, user_state, user_old, user_m, user_n, user_i, user_j
);
if( skip_call )
num_var_skip += NumRes(op);
}
CPPAD_ASSERT_UNKNOWN( user_state == local::start_user );
}
else
{ if( op == local::CSumOp)
play_.forward_csum(op, arg, i_op, i_var);
else if (op == local::CSkipOp)
play_.forward_cskip(op, arg, i_op, i_var);
//
if( cskip_op_[i_op] )
num_var_skip += NumRes(op);
}
}
return num_var_skip;
}
} // END CppAD namespace
# endif

View File

@ -1,214 +0,0 @@
# ifndef CPPAD_CORE_NUMERIC_LIMITS_HPP
# define CPPAD_CORE_NUMERIC_LIMITS_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 numeric_limits$$
$spell
std
eps
CppAD
namespace
const
$$
$section Numeric Limits For an AD and Base Types$$
$head Syntax$$
$icode%eps% = numeric_limits<%Float%>::epsilon()
%$$
$icode%min% = numeric_limits<%Float%>::min()
%$$
$icode%max% = numeric_limits<%Float%>::max()
%$$
$icode%nan% = numeric_limits<%Float%>::quiet_NaN()
%$$
$codei%numeric_limits<%Float%>::digits10%$$
$head CppAD::numeric_limits$$
These functions and have the prototype
$codei%
static %Float% CppAD::numeric_limits<%Float%>::%fun%(%void%)
%$$
where $icode fun$$ is
$code epsilon$$, $code min$$, $code max$$, and $code quiet_NaN$$.
(Note that $code digits10$$ is member variable and not a function.)
$head std::numeric_limits$$
CppAD does not use a specialization of $code std::numeric_limits$$
because this would be to restrictive.
The C++ standard specifies that Non-fundamental standard
types, such as
$cref/std::complex<double>/base_complex.hpp/$$ shall not have specializations
of $code std::numeric_limits$$; see Section 18.2 of
ISO/IEC 14882:1998(E).
In addition, since C++11, a only literal types can have a specialization
of $code std::numeric_limits$$.
$head Float$$
These functions are defined for all $codei%AD<%Base%>%$$,
and for all corresponding $icode Base$$ types;
see $icode Base$$ type $cref base_limits$$.
$head epsilon$$
The result $icode eps$$ is equal to machine epsilon and has prototype
$codei%
%Float% %eps%
%$$
The file $cref num_limits.cpp$$
tests the value $icode eps$$ by checking that the following are true
$codei%
1 != 1 + %eps%
1 == 1 + %eps% / 2
%$$
where all the values, and calculations, are done with the precision
corresponding to $icode Float$$.
$head min$$
The result $icode min$$ is equal to
the minimum positive normalized value and has prototype
$codei%
%Float% %min%
%$$
The file $cref num_limits.cpp$$
tests the value $icode min$$ by checking that the following are true
$codei%
abs( ((%min% / 100) * 100) / %min% - 1 ) > 3 * %eps%
abs( ((%min% * 100) / 100) / %min% - 1 ) < 3 * %eps%
%$$
where all the values, and calculations, are done with the precision
corresponding to $icode Float$$.
$head max$$
The result $icode max$$ is equal to
the maximum finite value and has prototype
$codei%
%Float% %max%
%$$
The file $cref num_limits.cpp$$
tests the value $icode max$$ by checking that the following are true
$codei%
abs( ((%max% * 100) / 100) / %max% - 1 ) > 3 * %eps%
abs( ((%max% / 100) * 100) / %max% - 1 ) < 3 * %eps%
%$$
where all the values, and calculations, are done with the precision
corresponding to $icode Float$$.
$head quiet_NaN$$
The result $icode nan$$ is not a number and has prototype
$codei%
%Float% %nan%
%$$
The file $cref num_limits.cpp$$
tests the value $icode nan$$ by checking that the following is true
$codei%
%nan% != %nan%
%$$
$head digits10$$
The member variable $code digits10$$ has prototype
$codei%
static const int numeric_limits<%Float%>::digits10
%$$
It is the number of decimal digits that can be represented by a
$icode Float$$ value. A number with this many decimal digits can be
converted to $icode Float$$ and back to a string,
without change due to rounding or overflow.
$head Example$$
$children%
example/general/num_limits.cpp
%$$
The file
$cref num_limits.cpp$$
contains an example and test of these functions.
$end
------------------------------------------------------------------------------
*/
# include <iostream>
# include <cppad/configure.hpp>
# include <cppad/core/define.hpp>
# include <cppad/core/cppad_assert.hpp>
# include <cppad/local/declare_ad.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file numeric_limits.hpp
File that defines CppAD numeric_limits for AD types
*/
/// All tthese defaults correspond to errors
template <class Float>
class numeric_limits {
public:
/// machine epsilon
static Float epsilon(void)
{ CPPAD_ASSERT_KNOWN(
false,
"numeric_limits<Float>::epsilon() is not specialized for this Float"
);
return Float(0);
}
/// minimum positive normalized value
static Float min(void)
{ CPPAD_ASSERT_KNOWN(
false,
"numeric_limits<Float>::min() is not specialized for this Float"
);
return Float(0);
}
/// maximum finite value
static Float max(void)
{ CPPAD_ASSERT_KNOWN(
false,
"numeric_limits<Float>::max() is not specialized for this Float"
);
return Float(0);
}
/// not a number
static Float quiet_NaN(void)
{ CPPAD_ASSERT_KNOWN(
false,
"numeric_limits<Float>::quiet_NaN() is not specialized for this Float"
);
return Float(0);
}
/// number of decimal digits
static const int digits10 = -1;
};
/// Partial specialization that defines limits for for all AD types
template <class Base>
class numeric_limits< AD<Base> > {
public:
/// machine epsilon
static AD<Base> epsilon(void)
{ return AD<Base>( numeric_limits<Base>::epsilon() ); }
/// minimum positive normalized value
static AD<Base> min(void)
{ return AD<Base>( numeric_limits<Base>::min() ); }
/// maximum finite value
static AD<Base> max(void)
{ return AD<Base>( numeric_limits<Base>::max() ); }
/// not a number
static AD<Base> quiet_NaN(void)
{ return AD<Base>( numeric_limits<Base>::quiet_NaN() ); }
/// number of decimal digits
static const int digits10 = numeric_limits<Base>::digits10;
};
} // END_CPPAD_NAMESPACE
# endif

File diff suppressed because it is too large Load Diff

View File

@ -1,95 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_OMP_MAX_THREAD_HPP
# define CPPAD_CORE_OMP_MAX_THREAD_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 omp_max_thread$$
$spell
alloc
num
omp
OpenMp
CppAD
$$
$section OpenMP Parallel Setup$$
$mindex omp_max_thread$$
$head Deprecated 2011-06-23$$
Use $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$
to set the number of threads.
$head Syntax$$
$codei%AD<%Base%>::omp_max_thread(%number%)
%$$
$head Purpose$$
By default, for each $codei%AD<%Base%>%$$ class there is only one
tape that records $cref/AD of Base/glossary/AD of Base/$$ operations.
This tape is a global variable and hence it cannot be used
by multiple OpenMP threads at the same time.
The $code omp_max_thread$$ function is used to set the
maximum number of OpenMP threads that can be active.
In this case, there is a different tape corresponding to each
$codei%AD<%Base%>%$$ class and thread pair.
$head number$$
The argument $icode number$$ has prototype
$codei%
size_t %number%
%$$
It must be greater than zero and specifies the maximum number of
OpenMp threads that will be active at one time.
$head Independent$$
Each call to $cref/Independent(x)/Independent/$$
creates a new $cref/active/glossary/Tape/Active/$$ tape.
All of the operations with the corresponding variables
must be preformed by the same OpenMP thread.
This includes the corresponding call to
$cref/f.Dependent(x,y)/Dependent/$$ or the
$cref/ADFun f(x, y)/FunConstruct/Sequence Constructor/$$
during which the tape stops recording and the variables
become parameters.
$head Restriction$$
No tapes can be
$cref/active/glossary/Tape/Active/$$ when this function is called.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <class Base>
void AD<Base>::omp_max_thread(size_t number)
{
# ifdef _OPENMP
thread_alloc::parallel_setup(
number, omp_alloc::in_parallel, omp_alloc::get_thread_num
);
# else
CPPAD_ASSERT_KNOWN(
number == 1,
"omp_max_thread: number > 1 and _OPENMP is not defined"
);
# endif
parallel_ad<Base>();
}
} // END CppAD namespace
# endif

View File

@ -1,524 +0,0 @@
# ifndef CPPAD_CORE_OPT_VAL_HES_HPP
# define CPPAD_CORE_OPT_VAL_HES_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 opt_val_hes$$
$spell
hes
sy
Jacobian
hes
signdet
jac
Bradley
const
CppAD
$$
$section Jacobian and Hessian of Optimal Values$$
$mindex opt_val_hes$$
$head Syntax$$
$icode%signdet% = opt_val_hes(%x%, %y%, %fun%, %jac%, %hes%)%$$
$head See Also$$
$cref BenderQuad$$
$head Reference$$
Algorithmic differentiation of implicit functions and optimal values,
Bradley M. Bell and James V. Burke, Advances in Automatic Differentiation,
2008, Springer.
$head Purpose$$
We are given a function
$latex S : \B{R}^n \times \B{R}^m \rightarrow \B{R}^\ell$$
and we define $latex F : \B{R}^n \times \B{R}^m \rightarrow \B{R}$$
and $latex V : \B{R}^n \rightarrow \B{R} $$ by
$latex \[
\begin{array}{rcl}
F(x, y) & = & \sum_{k=0}^{\ell-1} S_k ( x , y)
\\
V(x) & = & F [ x , Y(x) ]
\\
0 & = & \partial_y F [x , Y(x) ]
\end{array}
\] $$
We wish to compute the Jacobian
and possibly also the Hessian, of $latex V (x)$$.
$head BaseVector$$
The type $icode BaseVector$$ must be a
$cref SimpleVector$$ class.
We use $icode Base$$ to refer to the type of the elements of
$icode BaseVector$$; i.e.,
$codei%
%BaseVector%::value_type
%$$
$head x$$
The argument $icode x$$ has prototype
$codei%
const %BaseVector%& %x%
%$$
and its size must be equal to $icode n$$.
It specifies the point at which we evaluating
the Jacobian $latex V^{(1)} (x)$$
(and possibly the Hessian $latex V^{(2)} (x)$$).
$head y$$
The argument $icode y$$ has prototype
$codei%
const %BaseVector%& %y%
%$$
and its size must be equal to $icode m$$.
It must be equal to $latex Y(x)$$; i.e.,
it must solve the implicit equation
$latex \[
0 = \partial_y F ( x , y)
\] $$
$head Fun$$
The argument $icode fun$$ is an object of type $icode Fun$$
which must support the member functions listed below.
CppAD will may be recording operations of the type $codei%AD<%Base%>%$$
when these member functions are called.
These member functions must not stop such a recording; e.g.,
they must not call $cref/AD<Base>::abort_recording/abort_recording/$$.
$subhead Fun::ad_vector$$
The type $icode%Fun%::ad_vector%$$ must be a
$cref SimpleVector$$ class with elements of type $codei%AD<%Base%>%$$; i.e.
$codei%
%Fun%::ad_vector::value_type
%$$
is equal to $codei%AD<%Base%>%$$.
$subhead fun.ell$$
The type $icode Fun$$ must support the syntax
$codei%
%ell% = %fun%.ell()
%$$
where $icode ell$$ has prototype
$codei%
size_t %ell%
%$$
and is the value of $latex \ell$$; i.e.,
the number of terms in the summation.
$pre
$$
One can choose $icode ell$$ equal to one, and have
$latex S(x,y)$$ the same as $latex F(x, y)$$.
Each of the functions $latex S_k (x , y)$$,
(in the summation defining $latex F(x, y)$$)
is differentiated separately using AD.
For very large problems, breaking $latex F(x, y)$$ into the sum
of separate simpler functions may reduce the amount of memory necessary for
algorithmic differentiation and there by speed up the process.
$subhead fun.s$$
The type $icode Fun$$ must support the syntax
$codei%
%s_k% = %fun%.s(%k%, %x%, %y%)
%$$
The $icode%fun%.s%$$ argument $icode k$$ has prototype
$codei%
size_t %k%
%$$
and is between zero and $icode%ell% - 1%$$.
The argument $icode x$$ to $icode%fun%.s%$$ has prototype
$codei%
const %Fun%::ad_vector& %x%
%$$
and its size must be equal to $icode n$$.
The argument $icode y$$ to $icode%fun%.s%$$ has prototype
$codei%
const %Fun%::ad_vector& %y%
%$$
and its size must be equal to $icode m$$.
The $icode%fun%.s%$$ result $icode s_k$$ has prototype
$codei%
AD<%Base%> %s_k%
%$$
and its value must be given by $latex s_k = S_k ( x , y )$$.
$subhead fun.sy$$
The type $icode Fun$$ must support the syntax
$codei%
%sy_k% = %fun%.sy(%k%, %x%, %y%)
%$$
The argument $icode k$$ to $icode%fun%.sy%$$ has prototype
$codei%
size_t %k%
%$$
The argument $icode x$$ to $icode%fun%.sy%$$ has prototype
$codei%
const %Fun%::ad_vector& %x%
%$$
and its size must be equal to $icode n$$.
The argument $icode y$$ to $icode%fun%.sy%$$ has prototype
$codei%
const %Fun%::ad_vector& %y%
%$$
and its size must be equal to $icode m$$.
The $icode%fun%.sy%$$ result $icode sy_k$$ has prototype
$codei%
%Fun%::ad_vector %sy_k%
%$$
its size must be equal to $icode m$$,
and its value must be given by $latex sy_k = \partial_y S_k ( x , y )$$.
$head jac$$
The argument $icode jac$$ has prototype
$codei%
%BaseVector%& %jac%
%$$
and has size $icode n$$ or zero.
The input values of its elements do not matter.
If it has size zero, it is not affected. Otherwise, on output
it contains the Jacobian of $latex V (x)$$; i.e.,
for $latex j = 0 , \ldots , n-1$$,
$latex \[
jac[ j ] = V^{(1)} (x)_j
\] $$
where $icode x$$ is the first argument to $code opt_val_hes$$.
$head hes$$
The argument $icode hes$$ has prototype
$codei%
%BaseVector%& %hes%
%$$
and has size $icode%n% * %n%$$ or zero.
The input values of its elements do not matter.
If it has size zero, it is not affected. Otherwise, on output
it contains the Hessian of $latex V (x)$$; i.e.,
for $latex i = 0 , \ldots , n-1$$, and
$latex j = 0 , \ldots , n-1$$,
$latex \[
hes[ i * n + j ] = V^{(2)} (x)_{i,j}
\] $$
$head signdet$$
If $icode%hes%$$ has size zero, $icode signdet$$ is not defined.
Otherwise
the return value $icode signdet$$ is the sign of the determinant for
$latex \partial_{yy}^2 F(x , y) $$.
If it is zero, then the matrix is singular and
the Hessian is not computed ($icode hes$$ is not changed).
$head Example$$
$children%
example/general/opt_val_hes.cpp
%$$
The file
$cref opt_val_hes.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file opt_val_hes.hpp
\brief Computing Jabobians and Hessians of Optimal Values
*/
/*!
Computing Jabobians and Hessians of Optimal Values
We are given a function
\f$ S : {\rm R}^n \times {\rm R}^m \rightarrow {\rm R}^\ell \f$
and we define \f$ F : {\rm R}^n \times {\rm R}^m \rightarrow {\rm R} \f$
and \f$ V : {\rm R}^n \rightarrow {\rm R} \f$ by
\f[
\begin{array}{rcl}
F(x, y) & = & \sum_{k=0}^{\ell-1} S_k ( x , y)
\\
V(x) & = & F [ x , Y(x) ]
\\
0 & = & \partial_y F [x , Y(x) ]
\end{array}
\f]
We wish to compute the Jacobian
and possibly also the Hessian, of \f$ V (x) \f$.
\tparam BaseVector
The type \c BaseVector must be a SimpleVector class.
We use \c Base to refer to the type of the elements of
\c BaseVector; i.e.,
<tt>BaseVector::value_type</tt>.
\param x
is a vector with size \c n.
It specifies the point at which we evaluating
the Jacobian \f$ V^{(1)} (x) \f$
(and possibly the Hessian \f$ V^{(2)} (x) \f$).
\param y
is a vector with size \c m.
It must be equal to \f$ Y(x) \f$; i.e.,
it must solve the implicit equation
\f[
0 = \partial_y F ( x , y)
\f]
\param fun
The argument \c fun is an object of type \c Fun
wich must support the member functions listed below.
CppAD will may be recording operations of the type \c AD<Base>
when these member functions are called.
These member functions must not stop such a recording; e.g.,
they must not call \c AD<Base>::abort_recording.
\par Fun::ad_vector</tt>
The type <tt>Fun::ad_vector</tt> must be a
SimpleVector class with elements of type \c AD<Base>; i.e.
<tt>Fun::ad_vector::value_type</tt>
is equal to \c AD<Base>.
\par fun.ell
the type \c Fun must support the syntax
\verbatim
ell = fun.ell()
\endverbatim
where \c ell is a \c size_t value that is set to \f$ \ell \f$; i.e.,
the number of terms in the summation.
\par fun.s
The type \c Fun must support the syntax
\verbatim
s_k = fun.s(k, x, y)
\endverbatim
The argument \c k has prototype <tt>size_t k</tt>.
The argument \c x has prototype <tt>const Fun::ad_vector& x</tt>
and its size must be equal to \c n.
The argument \c y has prototype <tt>const Fun::ad_vector& y</tt>
and its size must be equal to \c m.
The return value \c s_k has prototype \c AD<Base> s_k
and its value must be given by \f$ s_k = S_k ( x , y ) \f$.
\par fun.sy
The type \c Fun must support the syntax
\verbatim
sy_k = fun.sy(k, x, y)
\endverbatim
The argument \c k has prototype <tt>size_t k</tt>.
The argument \c x has prototype <tt>const Fun::ad_vector& x</tt>
and its size must be equal to \c n.
The argument \c y has prototype <tt>const Fun::ad_vector& y</tt>
and its size must be equal to \c m.
The return value \c sy_k has prototype <tt>Fun::ad_vector& sy_k</tt>,
its size is \c m
and its value must be given by \f$ sy_k = \partial_y S_k ( x , y ) \f$.
\param jac
is a vector with size \c n or zero.
The input values of its elements do not matter.
If it has size zero, it is not affected. Otherwise, on output
it contains the Jacobian of \f$ V (x) \f$; i.e.,
for \f$ j = 0 , \ldots , n-1 \f$,
\f[
jac[ j ] = V^{(1)} (x)_j
\f] $$
where \c x is the first argument to \c opt_val_hes.
\param hes
is a vector with size <tt>n * n</tt> or zero.
The input values of its elements do not matter.
If it has size zero, it is not affected. Otherwise, on output
it contains the Hessian of \f$ V (x) \f$; i.e.,
for \f$ i = 0 , \ldots , n-1 \f$, and
\f$ j = 0 , \ldots , n-1 \f$,
\f[
hes[ i * n + j ] = V^{(2)} (x)_{i,j}
\f]
\return
If <tt>hes.size() == 0</tt>, the return value is not defined.
Otherwise,
the return value is the sign of the determinant for
\f$ \partial_{yy}^2 F(x , y) \f$$.
If it is zero, then the matrix is singular and \c hes is not set
to its specified value.
*/
template <class BaseVector, class Fun>
int opt_val_hes(
const BaseVector& x ,
const BaseVector& y ,
Fun fun ,
BaseVector& jac ,
BaseVector& hes )
{ // determine the base type
typedef typename BaseVector::value_type Base;
// check that BaseVector is a SimpleVector class with Base elements
CheckSimpleVector<Base, BaseVector>();
// determine the AD vector type
typedef typename Fun::ad_vector ad_vector;
// check that ad_vector is a SimpleVector class with AD<Base> elements
CheckSimpleVector< AD<Base> , ad_vector >();
// size of the x and y spaces
size_t n = size_t(x.size());
size_t m = size_t(y.size());
// number of terms in the summation
size_t ell = fun.ell();
// check size of return values
CPPAD_ASSERT_KNOWN(
size_t(jac.size()) == n || jac.size() == 0,
"opt_val_hes: size of the vector jac is not equal to n or zero"
);
CPPAD_ASSERT_KNOWN(
size_t(hes.size()) == n * n || hes.size() == 0,
"opt_val_hes: size of the vector hes is not equal to n * n or zero"
);
// some temporary indices
size_t i, j, k;
// AD version of S_k(x, y)
ad_vector s_k(1);
// ADFun version of S_k(x, y)
ADFun<Base> S_k;
// AD version of x
ad_vector a_x(n);
// AD version of y
ad_vector a_y(n);
if( jac.size() > 0 )
{ // this is the easy part, computing the V^{(1)} (x) which is equal
// to \partial_x F (x, y) (see Thoerem 2 of the reference).
// copy x and y to AD version
for(j = 0; j < n; j++)
a_x[j] = x[j];
for(j = 0; j < m; j++)
a_y[j] = y[j];
// initialize summation
for(j = 0; j < n; j++)
jac[j] = Base(0.);
// add in \partial_x S_k (x, y)
for(k = 0; k < ell; k++)
{ // start recording
Independent(a_x);
// record
s_k[0] = fun.s(k, a_x, a_y);
// stop recording and store in S_k
S_k.Dependent(a_x, s_k);
// compute partial of S_k with respect to x
BaseVector jac_k = S_k.Jacobian(x);
// add \partial_x S_k (x, y) to jac
for(j = 0; j < n; j++)
jac[j] += jac_k[j];
}
}
// check if we are done
if( hes.size() == 0 )
return 0;
/*
In this case, we need to compute the Hessian. Using Theorem 1 of the
reference:
Y^{(1)}(x) = - F_yy (x, y)^{-1} F_yx (x, y)
Using Theorem 2 of the reference:
V^{(2)}(x) = F_xx (x, y) + F_xy (x, y) Y^{(1)}(x)
*/
// Base and AD version of xy
BaseVector xy(n + m);
ad_vector a_xy(n + m);
for(j = 0; j < n; j++)
a_xy[j] = xy[j] = x[j];
for(j = 0; j < m; j++)
a_xy[n+j] = xy[n+j] = y[j];
// Initialization summation for Hessian of F
size_t nm_sq = (n + m) * (n + m);
BaseVector F_hes(nm_sq);
for(j = 0; j < nm_sq; j++)
F_hes[j] = Base(0.);
BaseVector hes_k(nm_sq);
// add in Hessian of S_k to hes
for(k = 0; k < ell; k++)
{ // start recording
Independent(a_xy);
// split out x
for(j = 0; j < n; j++)
a_x[j] = a_xy[j];
// split out y
for(j = 0; j < m; j++)
a_y[j] = a_xy[n+j];
// record
s_k[0] = fun.s(k, a_x, a_y);
// stop recording and store in S_k
S_k.Dependent(a_xy, s_k);
// when computing the Hessian it pays to optimize the tape
S_k.optimize();
// compute Hessian of S_k
hes_k = S_k.Hessian(xy, 0);
// add \partial_x S_k (x, y) to jac
for(j = 0; j < nm_sq; j++)
F_hes[j] += hes_k[j];
}
// Extract F_yx
BaseVector F_yx(m * n);
for(i = 0; i < m; i++)
{ for(j = 0; j < n; j++)
F_yx[i * n + j] = F_hes[ (i+n)*(n+m) + j ];
}
// Extract F_yy
BaseVector F_yy(n * m);
for(i = 0; i < m; i++)
{ for(j = 0; j < m; j++)
F_yy[i * m + j] = F_hes[ (i+n)*(n+m) + j + n ];
}
// compute - Y^{(1)}(x) = F_yy (x, y)^{-1} F_yx (x, y)
BaseVector neg_Y_x(m * n);
Base logdet;
int signdet = CppAD::LuSolve(m, n, F_yy, F_yx, neg_Y_x, logdet);
if( signdet == 0 )
return signdet;
// compute hes = F_xx (x, y) + F_xy (x, y) Y^{(1)}(x)
for(i = 0; i < n; i++)
{ for(j = 0; j < n; j++)
{ hes[i * n + j] = F_hes[ i*(n+m) + j ];
for(k = 0; k < m; k++)
hes[i*n+j] -= F_hes[i*(n+m) + k+n] * neg_Y_x[k*n+j];
}
}
return signdet;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,298 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_OPTIMIZE_HPP
# define CPPAD_CORE_OPTIMIZE_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 optimize$$
$spell
enum
jac
bool
Taylor
CppAD
cppad
std
const
onetape
op
$$
$section Optimize an ADFun Object Tape$$
$mindex sequence operations speed memory NDEBUG$$
$head Syntax$$
$icode%f%.optimize()
%$$
$icode%f%.optimize(%options%)
%$$
$head Purpose$$
The operation sequence corresponding to an $cref ADFun$$ object can
be very large and involve many operations; see the
size functions in $cref seq_property$$.
The $icode%f%.optimize%$$ procedure reduces the number of operations,
and thereby the time and the memory, required to
compute function and derivative values.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
$head options$$
This argument has prototype
$codei%
const std::string& %options%
%$$
The default for $icode options$$ is the empty string.
If it is present, it must consist of one or more of the options below
separated by a single space character.
$subhead no_conditional_skip$$
The $code optimize$$ function can create conditional skip operators
to improve the speed of conditional expressions; see
$cref/optimize/CondExp/Optimize/$$.
If the sub-string $code no_conditional_skip$$ appears in $icode options$$,
conditional skip operations are not be generated.
This may make the optimize routine use significantly less memory
and take less time to optimize $icode f$$.
If conditional skip operations are generated,
it may save a significant amount of time when
using $icode f$$ for $cref forward$$ or $cref reverse$$ mode calculations;
see $cref number_skip$$.
$subhead no_compare_op$$
If the sub-string $code no_compare_op$$ appears in $icode options$$,
comparison operators will be removed from the optimized function.
These operators are necessary for the
$cref compare_change$$ functions to be meaningful.
On the other hand, they are not necessary, and take extra time,
when the compare_change functions are not used.
$subhead no_print_for_op$$
If the sub-string $code no_compare_op$$ appears in $icode options$$,
$cref PrintFor$$ operations will be removed form the optimized function.
These operators are useful for reporting problems evaluating derivatives
at independent variable values different from those used to record a function.
$head Examples$$
$children%
example/optimize/forward_active.cpp
%example/optimize/reverse_active.cpp
%example/optimize/compare_op.cpp
%example/optimize/print_for.cpp
%example/optimize/conditional_skip.cpp
%example/optimize/nest_conditional.cpp
%example/optimize/cumulative_sum.cpp
%$$
$table
$cref/forward_active.cpp/optimize_forward_active.cpp/$$ $cnext
$title optimize_forward_active.cpp$$
$rnext
$cref/reverse_active.cpp/optimize_reverse_active.cpp/$$ $cnext
$title optimize_reverse_active.cpp$$
$rnext
$cref/compare_op.cpp/optimize_compare_op.cpp/$$ $cnext
$title optimize_compare_op.cpp$$
$rnext
$cref/print_for_op.cpp/optimize_print_for.cpp/$$ $cnext
$title optimize_print_for.cpp$$
$rnext
$cref/conditional_skip.cpp/optimize_conditional_skip.cpp/$$ $cnext
$title optimize_conditional_skip.cpp$$
$rnext
$cref/nest_conditional.cpp/optimize_nest_conditional.cpp/$$ $cnext
$title optimize_nest_conditional.cpp$$
$rnext
$cref/cumulative_sum.cpp/optimize_cumulative_sum.cpp/$$ $cnext
$title optimize_cumulative_sum.cpp$$
$tend
$head Efficiency$$
If a $cref/zero order forward/forward_zero/$$ calculation is done during
the construction of $icode f$$, it will require more memory
and time than required after the optimization procedure.
In addition, it will need to be redone.
For this reason, it is more efficient to use
$codei%
ADFun<%Base%> %f%;
%f%.Dependent(%x%, %y%);
%f%.optimize();
%$$
instead of
$codei%
ADFun<%Base%> %f%(%x%, %y%)
%f%.optimize();
%$$
See the discussion about
$cref/sequence constructors/FunConstruct/Sequence Constructor/$$.
$head Speed Testing$$
You can run the CppAD $cref/speed/speed_main/$$ tests and see
the corresponding changes in number of variables and execution time.
Note that there is an interaction between using
$cref/optimize/speed_main/Global Options/optimize/$$ and
$cref/onetape/speed_main/Global Options/onetape/$$.
If $icode onetape$$ is true and $icode optimize$$ is true,
the optimized tape will be reused many times.
If $icode onetape$$ is false and $icode optimize$$ is true,
the tape will be re-optimized for each test.
$head Atomic Functions$$
There are some subtitle issue with optimized $cref atomic$$ functions
$latex v = g(u)$$:
$subhead rev_sparse_jac$$
The $cref atomic_rev_sparse_jac$$ function is be used to determine
which components of $icode u$$ affect the dependent variables of $icode f$$.
For each atomic operation, the current
$cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ setting is used
to determine if $code pack_sparsity_enum$$, $code bool_sparsity_enum$$,
or $code set_sparsity_enum$$ is used to determine dependency relations
between argument and result variables.
$subhead nan$$
If $icode%u%[%i%]%$$ does not affect the value of
the dependent variables for $icode f$$,
the value of $icode%u%[%i%]%$$ is set to $cref nan$$.
$head Checking Optimization$$
If $cref/NDEBUG/Faq/Speed/NDEBUG/$$ is not defined,
and $cref/f.size_order()/size_order/$$ is greater than zero,
a $cref forward_zero$$ calculation is done using the optimized version
of $icode f$$ and the results are checked to see that they are
the same as before.
If they are not the same, the
$cref ErrorHandler$$ is called with a known error message
related to $icode%f%.optimize()%$$.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/local/optimize/optimize_run.hpp>
/*!
\file optimize.hpp
Optimize a player object operation sequence
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Optimize a player object operation sequence
The operation sequence for this object is replaced by one with fewer operations
but the same funcition and derivative values.
\tparam Base
base type for the operator; i.e., this operation was recorded
using AD<Base> and computations by this routine are done using type
\a Base.
\param options
\li
If the sub-string "no_conditional_skip" appears,
conditional skip operations will not be generated.
This may make the optimize routine use significantly less memory
and take significantly less time.
\li
If the sub-string "no_compare_op" appears,
then comparison operators will be removed from the optimized tape.
These operators are necessary for the compare_change function to be
be meaningful in the resulting recording.
On the other hand, they are not necessary and take extra time
when compare_change is not used.
*/
template <class Base>
void ADFun<Base>::optimize(const std::string& options)
{ // place to store the optimized version of the recording
local::recorder<Base> rec;
// number of independent variables
size_t n = ind_taddr_.size();
# ifndef NDEBUG
size_t i, j, m = dep_taddr_.size();
CppAD::vector<Base> x(n), y(m), check(m);
Base max_taylor(0);
bool check_zero_order = num_order_taylor_ > 0;
if( check_zero_order )
{ // zero order coefficients for independent vars
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == local::InvOp );
CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j+1 );
x[j] = taylor_[ ind_taddr_[j] * cap_order_taylor_ + 0];
}
// zero order coefficients for dependent vars
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
y[i] = taylor_[ dep_taddr_[i] * cap_order_taylor_ + 0];
}
// maximum zero order coefficient not counting BeginOp at beginning
// (which is correpsonds to uninitialized memory).
for(i = 1; i < num_var_tape_; i++)
{ if( abs_geq(taylor_[i*cap_order_taylor_+0] , max_taylor) )
max_taylor = taylor_[i*cap_order_taylor_+0];
}
}
# endif
// create the optimized recording
local::optimize::optimize_run<Base>(options, n, dep_taddr_, &play_, &rec);
// number of variables in the recording
num_var_tape_ = rec.num_var_rec();
// now replace the recording
play_.get(rec);
// set flag so this function knows it has been optimized
has_been_optimized_ = true;
// free memory allocated for sparse Jacobian calculation
// (the results are no longer valid)
for_jac_sparse_pack_.resize(0, 0);
for_jac_sparse_set_.resize(0,0);
// free old Taylor coefficient memory
taylor_.free();
num_order_taylor_ = 0;
cap_order_taylor_ = 0;
// resize and initilaize conditional skip vector
// (must use player size because it now has the recoreder information)
cskip_op_.erase();
cskip_op_.extend( play_.num_op_rec() );
# ifndef NDEBUG
if( check_zero_order )
{
// zero order forward calculation using new operation sequence
check = Forward(0, x);
// check results
Base eps = 10. * CppAD::numeric_limits<Base>::epsilon();
for(i = 0; i < m; i++) CPPAD_ASSERT_KNOWN(
abs_geq( eps * max_taylor , check[i] - y[i] ) ,
"Error during check of f.optimize()."
);
// Erase memory that this calculation was done so NDEBUG gives
// same final state for this object (from users perspective)
num_order_taylor_ = 0;
}
# endif
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,102 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_ORDERED_HPP
# define CPPAD_CORE_ORDERED_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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.
-------------------------------------------------------------------------- */
# include <cppad/core/define.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file ordered.hpp
Check and AD values ordering properties relative to zero.
*/
// GreaterThanZero ============================================================
/*!
Check if an AD<Base> is greater than zero.
\param x
value we are checking.
\return
returns true iff the \c x is greater than zero.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool GreaterThanZero(const AD<Base> &x)
{ return GreaterThanZero(x.value_); }
// GreaterThanOrZero =========================================================
/*!
Check if an AD<Base> is greater than or equal zero.
\param x
value we are checking.
\return
returns true iff the \c x is greater than or equal zero.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool GreaterThanOrZero(const AD<Base> &x)
{ return GreaterThanOrZero(x.value_); }
// LessThanZero ============================================================
/*!
Check if an AD<Base> is less than zero.
\param x
value we are checking.
\return
returns true iff the \c x is less than zero.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool LessThanZero(const AD<Base> &x)
{ return LessThanZero(x.value_); }
// LessThanOrZero =========================================================
/*!
Check if an AD<Base> is less than or equal zero.
\param x
value we are checking.
\return
returns true iff the \c x is less than or equal zero.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool LessThanOrZero(const AD<Base> &x)
{ return LessThanOrZero(x.value_); }
// abs_geq =========================================================
/*!
Check if absolute value of one AD<Base> is greater or equal another.
\param x
value we are checking if it is greater than or equal other.
\param y
value we are checking if it is less than other.
\return
returns true iff the absolute value of \c x is greater than or equal
absolute value of \c y.
*/
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool abs_geq(const AD<Base>& x, const AD<Base>& y)
{ return abs_geq(x.value_, y.value_); }
// ============================================================================
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,118 +0,0 @@
# ifndef CPPAD_CORE_PAR_VAR_HPP
# define CPPAD_CORE_PAR_VAR_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 ParVar$$
$spell
VecAD
const
bool
$$
$section Is an AD Object a Parameter or Variable$$
$head Syntax$$
$icode%b% = Parameter(%x%)%$$
$pre
$$
$icode%b% = Variable(%x%)%$$
$head Purpose$$
Determine if $icode x$$ is a
$cref/parameter/glossary/Parameter/$$ or
$cref/variable/glossary/Variable/$$.
$head x$$
The argument $icode x$$ has prototype
$codei%
const AD<%Base%> &%x%
const VecAD<%Base%> &%x%
%$$
$head b$$
The return value $icode b$$ has prototype
$codei%
bool %b%
%$$
The return value for $code Parameter$$ ($code Variable$$)
is true if and only if $icode x$$ is a parameter (variable).
Note that a $cref/VecAD<Base>/VecAD/$$ object
is a variable if any element of the vector depends on the independent
variables.
$head Operation Sequence$$
The result of this operation is not an
$cref/AD of Base/glossary/AD of Base/$$ object.
Thus it will not be recorded as part of an
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$children%
example/general/par_var.cpp
%$$
The file
$cref par_var.cpp$$
contains an example and test of these functions.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
namespace CppAD {
// Parameter
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool Parameter(const AD<Base> &x)
{ if( x.tape_id_ == 0 )
return true;
size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);
return x.tape_id_ != *AD<Base>::tape_id_ptr(thread);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool Parameter(const VecAD<Base> &x)
{ if( x.tape_id_ == 0 )
return true;
size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);
return x.tape_id_ != *AD<Base>::tape_id_ptr(thread);
}
// Variable
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool Variable(const AD<Base> &x)
{ if( x.tape_id_ == 0 )
return false;
size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);
return x.tape_id_ == *AD<Base>::tape_id_ptr(thread);
}
template <class Base>
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool Variable(const VecAD<Base> &x)
{ if( x.tape_id_ == 0 )
return false;
size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);
return x.tape_id_ == *AD<Base>::tape_id_ptr(thread);
}
}
// END CppAD namespace
# endif

View File

@ -1,118 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_PARALLEL_AD_HPP
# define CPPAD_CORE_PARALLEL_AD_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 parallel_ad$$
$spell
CppAD
num
std
$$
$section Enable AD Calculations During Parallel Mode$$
$head Syntax$$
$codei%parallel_ad<%Base%>()%$$
$head Purpose$$
The function
$codei%parallel_ad<%Base%>()%$$
must be called before any $codei%AD<%Base>%$$ objects are used
in $cref/parallel/ta_in_parallel/$$ mode.
In addition, if this routine is called after one is done using
parallel mode, it will free extra memory used to keep track of
the multiple $codei%AD<%Base%>%$$ tapes required for parallel execution.
$head Discussion$$
By default, for each $codei%AD<%Base%>%$$ class there is only one
tape that records $cref/AD of Base/glossary/AD of Base/$$ operations.
This tape is a global variable and hence it cannot be used
by multiple threads at the same time.
The $cref/parallel_setup/ta_parallel_setup/$$ function informs CppAD of the
maximum number of threads that can be active in parallel mode.
This routine does extra setup
(and teardown) for the particular $icode Base$$ type.
$head CheckSimpleVector$$
This routine has the side effect of calling the routines
$codei%
CheckSimpleVector< %Type%, CppAD::vector<%Type%> >()
%$$
where $icode Type$$ is $icode Base$$ and $codei%AD<%Base%>%$$.
$head Example$$
The files
$cref team_openmp.cpp$$,
$cref team_bthread.cpp$$, and
$cref team_pthread.cpp$$,
contain examples and tests that implement this function.
$head Restriction$$
This routine cannot be called in parallel mode or while
there is a tape recording $codei%AD<%Base%>%$$ operations.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/local/std_set.hpp>
// BEGIN CppAD namespace
namespace CppAD {
/*!
Enable parallel execution mode with <code>AD<Base></code> by initializing
static variables that my be used.
*/
template <class Base>
void parallel_ad(void)
{ CPPAD_ASSERT_KNOWN(
! thread_alloc::in_parallel() ,
"parallel_ad must be called before entering parallel execution mode."
);
CPPAD_ASSERT_KNOWN(
AD<Base>::tape_ptr() == CPPAD_NULL ,
"parallel_ad cannot be called while a tape recording is in progress"
);
// ensure statics in following functions are initialized
elapsed_seconds();
ErrorHandler::Current();
local::NumArg(local::BeginOp);
local::NumRes(local::BeginOp);
local::one_element_std_set<size_t>();
local::two_element_std_set<size_t>();
// the sparse_pack class has member functions with static data
local::sparse_pack sp;
sp.resize(1, 1); // so can call add_element
sp.add_element(0, 0); // has static data
sp.clear(0); // has static data
sp.is_element(0, 0); // has static data
local::sparse_pack::const_iterator itr(sp, 0); // has static data
++itr; // has static data
// statics that depend on the value of Base
AD<Base>::tape_id_handle(0);
AD<Base>::tape_handle(0);
AD<Base>::tape_manage(tape_manage_clear);
discrete<Base>::List();
CheckSimpleVector< Base, CppAD::vector<Base> >();
CheckSimpleVector< AD<Base>, CppAD::vector< AD<Base> > >();
}
} // END CppAD namespace
# endif

View File

@ -1,257 +0,0 @@
# ifndef CPPAD_CORE_POW_HPP
# define CPPAD_CORE_POW_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 pow$$
$spell
Vec
std
namespace
CppAD
const
$$
$section The AD Power Function$$
$mindex pow exponent$$
$head Syntax$$
$icode%z% = pow(%x%, %y%)%$$
$head See Also$$
$cref pow_int$$
$head Purpose$$
Determines the value of the power function which is defined by
$latex \[
{\rm pow} (x, y) = x^y
\] $$
This version of the $code pow$$ function may use
logarithms and exponentiation to compute derivatives.
This will not work if $icode x$$ is less than or equal zero.
If the value of $icode y$$ is an integer,
the $cref pow_int$$ function is used to compute this value
using only multiplication (and division if $icode y$$ is negative).
(This will work even if $icode x$$ is less than or equal zero.)
$head x$$
The argument $icode x$$ has one of the following prototypes
$codei%
const %Base%& %x%
const AD<%Base%>& %x%
const VecAD<%Base%>::reference& %x%
%$$
$head y$$
The argument $icode y$$ has one of the following prototypes
$codei%
const %Base%& %y%
const AD<%Base%>& %y%
const VecAD<%Base%>::reference& %y%
%$$
$head z$$
If both $icode x$$ and $icode y$$ are $icode Base$$ objects,
the result $icode z$$ is also a $icode Base$$ object.
Otherwise, it has prototype
$codei%
AD<%Base%> %z%
%$$
$head Operation Sequence$$
This is an AD of $icode Base$$
$cref/atomic operation/glossary/Operation/Atomic/$$
and hence is part of the current
AD of $icode Base$$
$cref/operation sequence/glossary/Operation/Sequence/$$.
$head Example$$
$children%
example/general/pow.cpp
%$$
The file
$cref pow.cpp$$
is an examples and tests of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
// case where x and y are AD<Base> -----------------------------------------
template <class Base> AD<Base>
pow(const AD<Base>& x, const AD<Base>& y)
{
// compute the Base part
AD<Base> result;
result.value_ = pow(x.value_, y.value_);
CPPAD_ASSERT_UNKNOWN( Parameter(result) );
// check if there is a recording in progress
local::ADTape<Base>* tape = AD<Base>::tape_ptr();
if( tape == CPPAD_NULL )
return result;
tape_id_t tape_id = tape->id_;
// tape_id cannot match the default value for tape_id_; i.e., 0
CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
bool var_x = x.tape_id_ == tape_id;
bool var_y = y.tape_id_ == tape_id;
if( var_x )
{ if( var_y )
{ // result = variable^variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowvvOp) == 3 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowvvOp) == 2 );
// put operand addresses in tape
tape->Rec_.PutArg(x.taddr_, y.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::PowvvOp);
// make result a variable
result.tape_id_ = tape_id;
}
else if( IdenticalZero( y.value_ ) )
{ // result = variable^0
}
else
{ // result = variable^parameter
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowvpOp) == 3 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowvpOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(y.value_);
tape->Rec_.PutArg(x.taddr_, p);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::PowvpOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
else if( var_y )
{ if( IdenticalZero(x.value_) )
{ // result = 0^variable
}
else
{ // result = parameter^variable
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowpvOp) == 3 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowpvOp) == 2 );
// put operand addresses in tape
addr_t p = tape->Rec_.PutPar(x.value_);
tape->Rec_.PutArg(p, y.taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::PowpvOp);
// make result a variable
result.tape_id_ = tape_id;
}
}
return result;
}
// =========================================================================
// Fold operations in same way as CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op)
// -------------------------------------------------------------------------
// Operations with VecAD_reference<Base> and AD<Base> only
template <class Base> AD<Base>
pow(const AD<Base>& x, const VecAD_reference<Base>& y)
{ return pow(x, y.ADBase()); }
template <class Base> AD<Base>
pow(const VecAD_reference<Base>& x, const VecAD_reference<Base>& y)
{ return pow(x.ADBase(), y.ADBase()); }
template <class Base> AD<Base>
pow(const VecAD_reference<Base>& x, const AD<Base>& y)
{ return pow(x.ADBase(), y); }
// -------------------------------------------------------------------------
// Operations with Base
template <class Base> AD<Base>
pow(const Base& x, const AD<Base>& y)
{ return pow(AD<Base>(x), y); }
template <class Base> AD<Base>
pow(const Base& x, const VecAD_reference<Base>& y)
{ return pow(AD<Base>(x), y.ADBase()); }
template <class Base> AD<Base>
pow(const AD<Base>& x, const Base& y)
{ return pow(x, AD<Base>(y)); }
template <class Base> AD<Base>
pow(const VecAD_reference<Base>& x, const Base& y)
{ return pow(x.ADBase(), AD<Base>(y)); }
// -------------------------------------------------------------------------
// Operations with double
template <class Base> AD<Base>
pow(const double& x, const AD<Base>& y)
{ return pow(AD<Base>(x), y); }
template <class Base> AD<Base>
pow(const double& x, const VecAD_reference<Base>& y)
{ return pow(AD<Base>(x), y.ADBase()); }
template <class Base> AD<Base>
pow(const AD<Base>& x, const double& y)
{ return pow(x, AD<Base>(y)); }
template <class Base> AD<Base>
pow(const VecAD_reference<Base>& x, const double& y)
{ return pow(x.ADBase(), AD<Base>(y)); }
// -------------------------------------------------------------------------
// Special case to avoid ambuigity when Base is double
inline AD<double>
pow(const double& x, const AD<double>& y)
{ return pow(AD<double>(x), y); }
inline AD<double>
pow(const double& x, const VecAD_reference<double>& y)
{ return pow(AD<double>(x), y.ADBase()); }
inline AD<double>
pow(const AD<double>& x, const double& y)
{ return pow(x, AD<double>(y)); }
inline AD<double>
pow(const VecAD_reference<double>& x, const double& y)
{ return pow(x.ADBase(), AD<double>(y)); }
// =========================================================================
// Fold operations for the cases where x is an int,
// but let cppad/utility/pow_int.hpp handle the cases where y is an int.
// -------------------------------------------------------------------------
template <class Base> AD<Base> pow
(const int& x, const VecAD_reference<Base>& y)
{ return pow(AD<Base>(x), y.ADBase()); }
template <class Base> AD<Base> pow
(const int& x, const AD<Base>& y)
{ return pow(AD<Base>(x), y); }
} // END CppAD namespace
# endif

View File

@ -1,219 +0,0 @@
# 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

View File

@ -1,251 +0,0 @@
# ifndef CPPAD_CORE_REV_HES_SPARSITY_HPP
# define CPPAD_CORE_REV_HES_SPARSITY_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 rev_hes_sparsity$$
$spell
Jacobian
Hessian
jac
hes
bool
const
rc
cpp
$$
$section Reverse Mode Hessian Sparsity Patterns$$
$head Syntax$$
$icode%f%.rev_hes_sparsity(
%select_range%, %transpose%, %internal_bool%, %pattern_out%
)%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to
the operation sequence stored in $icode f$$.
Fix $latex R \in \B{R}^{n \times \ell}$$, $latex s \in \B{R}^m$$
and define the function
$latex \[
H(x) = ( s^\R{T} F )^{(2)} ( x ) R
\] $$
Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$
and for the vector $latex s$$,
$code rev_hes_sparsity$$ computes a sparsity pattern for $latex H(x)$$.
$head x$$
Note that the sparsity pattern $latex H(x)$$ corresponds to the
operation sequence stored in $icode f$$ and does not depend on
the argument $icode x$$.
$head BoolVector$$
The type $icode BoolVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code bool$$.
$head SizeVector$$
The type $icode SizeVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
$head R$$
The sparsity pattern for the matrix $latex R$$ is specified by
$cref/pattern_in/for_jac_sparsity/pattern_in/$$ in the previous call
$codei%
%f%.for_jac_sparsity(
%pattern_in%, %transpose%, %dependency%, %internal_bool%, %pattern_out%
)%$$
$head select_range$$
The argument $icode select_range$$ has prototype
$codei%
const %BoolVector%& %select_range%
%$$
It has size $latex m$$ and specifies which components of the vector
$latex s$$ are non-zero; i.e., $icode%select_range%[%i%]%$$ is true
if and only if $latex s_i$$ is possibly non-zero.
$head transpose$$
This argument has prototype
$codei%
bool %transpose%
%$$
See $cref/pattern_out/rev_hes_sparsity/pattern_out/$$ below.
$head internal_bool$$
If this is true, calculations are done with sets represented by a vector
of boolean values. Otherwise, a vector of sets of integers is used.
This must be the same as in the previous call to
$icode%f%.for_jac_sparsity%$$.
$head pattern_out$$
This argument has prototype
$codei%
sparse_rc<%SizeVector%>& %pattern_out%
%$$
This input value of $icode pattern_out$$ does not matter.
If $icode transpose$$ it is false (true),
upon return $icode pattern_out$$ is a sparsity pattern for
$latex H(x)$$ ($latex H(x)^\R{T}$$).
$head Sparsity for Entire Hessian$$
Suppose that $latex R$$ is the $latex n \times n$$ identity matrix.
In this case, $icode pattern_out$$ is a sparsity pattern for
$latex (s^\R{T} F) F^{(2)} ( x )$$.
$head Example$$
$children%
example/sparse/rev_hes_sparsity.cpp
%$$
The file
$cref rev_hes_sparsity.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/core/ad_fun.hpp>
# include <cppad/local/sparse_internal.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Reverse Hessian sparsity patterns.
\tparam Base
is the base type for this recording.
\tparam BoolVector
is the simple vector with elements of type bool that is used for
sparsity for the vector s.
\tparam SizeVector
is the simple vector with elements of type size_t that is used for
row, column index sparsity patterns.
\param select_range
is a sparsity pattern for for s.
\param transpose
Is the returned sparsity pattern transposed.
\param internal_bool
If this is true, calculations are done with sets represented by a vector
of boolean values. Otherwise, a vector of standard sets is used.
\param pattern_out
The value of transpose is false (true),
the return value is a sparsity pattern for H(x) ( H(x)^T ) where
\f[
H(x) = R * F^{(1)} (x)
\f]
Here F is the function corresponding to the operation sequence
and x is any argument value.
*/
template <class Base>
template <class BoolVector, class SizeVector>
void ADFun<Base>::rev_hes_sparsity(
const BoolVector& select_range ,
bool transpose ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out )
{ size_t n = Domain();
size_t m = Range();
//
CPPAD_ASSERT_KNOWN(
size_t( select_range.size() ) == m,
"rev_hes_sparsity: size of select_range is not equal to "
"number of dependent variables"
);
//
// vector that holds reverse Jacobian sparsity flag
local::pod_vector<bool> rev_jac_pattern;
rev_jac_pattern.extend(num_var_tape_);
for(size_t i = 0; i < num_var_tape_; i++)
rev_jac_pattern[i] = false;
//
// initialize rev_jac_pattern for dependent variables
for(size_t i = 0; i < m; i++)
rev_jac_pattern[ dep_taddr_[i] ] = select_range[i];
//
//
if( internal_bool )
{ CPPAD_ASSERT_KNOWN(
for_jac_sparse_pack_.n_set() > 0,
"rev_hes_sparsity: previous call to for_jac_sparsity did not "
"use bool for interanl sparsity patterns."
);
// column dimension of internal sparstiy pattern
size_t ell = for_jac_sparse_pack_.end();
//
// allocate memory for bool sparsity calculation
// (sparsity pattern is emtpy after a resize)
local::sparse_pack internal_hes;
internal_hes.resize(num_var_tape_, ell);
//
// compute the Hessian sparsity pattern
local::RevHesSweep(
n,
num_var_tape_,
&play_,
for_jac_sparse_pack_,
rev_jac_pattern.data(),
internal_hes
);
// get sparstiy pattern for independent variables
local::get_internal_sparsity(
transpose, ind_taddr_, internal_hes, pattern_out
);
}
else
{ CPPAD_ASSERT_KNOWN(
for_jac_sparse_set_.n_set() > 0,
"rev_hes_sparsity: previous call to for_jac_sparsity did not "
"use bool for interanl sparsity patterns."
);
// column dimension of internal sparstiy pattern
size_t ell = for_jac_sparse_set_.end();
//
// allocate memory for bool sparsity calculation
// (sparsity pattern is emtpy after a resize)
local::sparse_list internal_hes;
internal_hes.resize(num_var_tape_, ell);
//
// compute the Hessian sparsity pattern
local::RevHesSweep(
n,
num_var_tape_,
&play_,
for_jac_sparse_set_,
rev_jac_pattern.data(),
internal_hes
);
// get sparstiy pattern for independent variables
local::get_internal_sparsity(
transpose, ind_taddr_, internal_hes, pattern_out
);
}
return;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,251 +0,0 @@
# ifndef CPPAD_CORE_REV_JAC_SPARSITY_HPP
# define CPPAD_CORE_REV_JAC_SPARSITY_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 rev_jac_sparsity$$
$spell
Jacobian
jac
bool
const
rc
cpp
$$
$section Reverse Mode Jacobian Sparsity Patterns$$
$head Syntax$$
$icode%f%.rev_jac_sparsity(
%pattern_in%, %transpose%, %dependency%, %internal_bool%, %pattern_out%
)%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to
the operation sequence stored in $icode f$$.
Fix $latex R \in \B{R}^{\ell \times m}$$ and define the function
$latex \[
J(x) = R * F^{(1)} ( x )
\] $$
Given the $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$,
$code rev_jac_sparsity$$ computes a sparsity pattern for $latex J(x)$$.
$head x$$
Note that the sparsity pattern $latex J(x)$$ corresponds to the
operation sequence stored in $icode f$$ and does not depend on
the argument $icode x$$.
(The operation sequence may contain
$cref CondExp$$ and $cref VecAD$$ operations.)
$head SizeVector$$
The type $icode SizeVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
$head pattern_in$$
The argument $icode pattern_in$$ has prototype
$codei%
const sparse_rc<%SizeVector%>& %pattern_in%
%$$
see $cref sparse_rc$$.
If $icode transpose$$ it is false (true),
$icode pattern_in$$ is a sparsity pattern for $latex R$$ ($latex R^\R{T}$$).
$head transpose$$
This argument has prototype
$codei%
bool %transpose%
%$$
See $cref/pattern_in/rev_jac_sparsity/pattern_in/$$ above and
$cref/pattern_out/rev_jac_sparsity/pattern_out/$$ below.
$head dependency$$
This argument has prototype
$codei%
bool %dependency%
%$$
see $cref/pattern_out/rev_jac_sparsity/pattern_out/$$ below.
$head internal_bool$$
If this is true, calculations are done with sets represented by a vector
of boolean values. Otherwise, a vector of sets of integers is used.
$head pattern_out$$
This argument has prototype
$codei%
sparse_rc<%SizeVector%>& %pattern_out%
%$$
This input value of $icode pattern_out$$ does not matter.
If $icode transpose$$ it is false (true),
upon return $icode pattern_out$$ is a sparsity pattern for
$latex J(x)$$ ($latex J(x)^\R{T}$$).
If $icode dependency$$ is true, $icode pattern_out$$ is a
$cref/dependency pattern/dependency.cpp/Dependency Pattern/$$
instead of sparsity pattern.
$head Sparsity for Entire Jacobian$$
Suppose that
$latex R$$ is the $latex m \times m$$ identity matrix.
In this case, $icode pattern_out$$ is a sparsity pattern for
$latex F^{(1)} ( x )$$ ( $latex F^{(1)} (x)^\R{T}$$ )
if $icode transpose$$ is false (true).
$head Example$$
$children%
example/sparse/rev_jac_sparsity.cpp
%$$
The file
$cref rev_jac_sparsity.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/core/ad_fun.hpp>
# include <cppad/local/sparse_internal.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Reverse Jacobian sparsity patterns.
\tparam Base
is the base type for this recording.
\tparam SizeVector
is the simple vector with elements of type size_t that is used for
row, column index sparsity patterns.
\param pattern_in
is the sparsity pattern for for R or R^T depending on transpose.
\param transpose
Is the input and returned sparsity pattern transposed.
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\param internal_bool
If this is true, calculations are done with sets represented by a vector
of boolean values. Otherwise, a vector of standard sets is used.
\param pattern_out
The value of transpose is false (true),
the return value is a sparsity pattern for J(x) ( J(x)^T ) where
\f[
J(x) = R * F^{(1)} (x)
\f]
Here F is the function corresponding to the operation sequence
and x is any argument value.
*/
template <class Base>
template <class SizeVector>
void ADFun<Base>::rev_jac_sparsity(
const sparse_rc<SizeVector>& pattern_in ,
bool transpose ,
bool dependency ,
bool internal_bool ,
sparse_rc<SizeVector>& pattern_out )
{ // number or rows, columns, and non-zeros in pattern_in
size_t nr_in = pattern_in.nr();
size_t nc_in = pattern_in.nc();
//
size_t ell = nr_in;
size_t m = nc_in;
if( transpose )
std::swap(ell, m);
//
CPPAD_ASSERT_KNOWN(
m == Range() ,
"rev_jac_sparsity: number columns in R "
"is not equal number of dependent variables."
);
// number of independent variables
size_t n = Domain();
//
bool zero_empty = true;
bool input_empty = true;
if( internal_bool )
{ // allocate memory for bool sparsity calculation
// (sparsity pattern is emtpy after a resize)
local::sparse_pack internal_jac;
internal_jac.resize(num_var_tape_, ell);
//
// set sparsity patttern for dependent variables
local::set_internal_sparsity(
zero_empty ,
input_empty ,
! transpose ,
dep_taddr_ ,
internal_jac ,
pattern_in
);
// compute sparsity for other variables
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
internal_jac
);
// get sparstiy pattern for independent variables
local::get_internal_sparsity(
! transpose, ind_taddr_, internal_jac, pattern_out
);
}
else
{ // allocate memory for bool sparsity calculation
// (sparsity pattern is emtpy after a resize)
local::sparse_list internal_jac;
internal_jac.resize(num_var_tape_, ell);
//
// set sparsity patttern for dependent variables
local::set_internal_sparsity(
zero_empty ,
input_empty ,
! transpose ,
dep_taddr_ ,
internal_jac ,
pattern_in
);
// compute sparsity for other variables
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
internal_jac
);
// get sparstiy pattern for independent variables
local::get_internal_sparsity(
! transpose, ind_taddr_, internal_jac, pattern_out
);
}
return;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,162 +0,0 @@
# ifndef CPPAD_CORE_REV_ONE_HPP
# define CPPAD_CORE_REV_ONE_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 RevOne$$
$spell
dw
Taylor
const
$$
$section First Order Derivative: Driver Routine$$
$mindex derivative easy$$
$head Syntax$$
$icode%dw% = %f%.RevOne(%x%, %i%)%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
The syntax above sets $icode dw$$ to the
derivative of $latex F_i$$ with respect to $latex x$$; i.e.,
$latex \[
dw =
F_i^{(1)} (x)
= \left[
\D{ F_i }{ x_0 } (x) , \cdots , \D{ F_i }{ x_{n-1} } (x)
\right]
\] $$
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/RevOne Uses Forward/RevOne/RevOne Uses Forward/$$ below).
$head x$$
The argument $icode x$$ has prototype
$codei%
const %Vector% &%x%
%$$
(see $cref/Vector/RevOne/Vector/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies
that point at which to evaluate the derivative.
$head i$$
The index $icode i$$ has prototype
$codei%
size_t %i%
%$$
and is less than $latex m$$, the dimension of the
$cref/range/seq_property/Range/$$ space for $icode f$$.
It specifies the
component of $latex F$$ that we are computing the derivative of.
$head dw$$
The result $icode dw$$ has prototype
$codei%
%Vector% %dw%
%$$
(see $cref/Vector/RevOne/Vector/$$ below)
and its size is $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
The value of $icode dw$$ is the derivative of $latex F_i$$
evaluated at $icode x$$; i.e.,
for $latex j = 0 , \ldots , n - 1 $$
$latex \[.
dw[ j ] = \D{ F_i }{ x_j } ( x )
\] $$
$head Vector$$
The type $icode Vector$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$icode Base$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head RevOne Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code RevOne$$,
the zero order Taylor coefficients correspond to
$icode%f%.Forward(0, %x%)%$$
and the other coefficients are unspecified.
$head Example$$
$children%
example/general/rev_one.cpp
%$$
The routine
$cref/RevOne/rev_one.cpp/$$ is both an example and test.
It returns $code true$$, if it succeeds and $code false$$ otherwise.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <typename Base>
template <typename Vector>
Vector ADFun<Base>::RevOne(const Vector &x, size_t i)
{ size_t i1;
size_t n = Domain();
size_t m = Range();
// check Vector is Simple Vector class with Base type elements
CheckSimpleVector<Base, Vector>();
CPPAD_ASSERT_KNOWN(
x.size() == n,
"RevOne: Length of x not equal domain dimension for f"
);
CPPAD_ASSERT_KNOWN(
i < m,
"RevOne: the index i is not less than range dimension for f"
);
// point at which we are evaluating the derivative
Forward(0, x);
// component which are are taking the derivative of
Vector w(m);
for(i1 = 0; i1 < m; i1++)
w[i1] = 0.;
w[i] = Base(1.0);
// dimension the return value
Vector dw(n);
// compute the return value
dw = Reverse(1, w);
return dw;
}
} // END CppAD namespace
# endif

View File

@ -1,621 +0,0 @@
# ifndef CPPAD_CORE_REV_SPARSE_HES_HPP
# define CPPAD_CORE_REV_SPARSE_HES_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 RevSparseHes$$
$spell
std
VecAD
Jacobian
Jac
Hessian
Hes
const
Bool
Dep
proportional
var
cpp
$$
$section Hessian Sparsity Pattern: Reverse Mode$$
$head Syntax$$
$icode%h% = %f%.RevSparseHes(%q%, %s%)
%$$
$icode%h% = %f%.RevSparseHes(%q%, %s%, %transpose%)%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
For a fixed matrix $latex R \in \B{R}^{n \times q}$$
and a fixed vector $latex S \in \B{R}^{1 \times m}$$,
we define
$latex \[
\begin{array}{rcl}
H(x)
& = & \partial_x \left[ \partial_u S * F[ x + R * u ] \right]_{u=0}
\\
& = & R^\R{T} * (S * F)^{(2)} ( x )
\\
H(x)^\R{T}
& = & (S * F)^{(2)} ( x ) * R
\end{array}
\] $$
Given a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex R$$ and the vector $latex S$$,
$code RevSparseHes$$ returns a sparsity pattern for the $latex H(x)$$.
$head f$$
The object $icode f$$ has prototype
$codei%
const ADFun<%Base%> %f%
%$$
$head x$$
If the operation sequence in $icode f$$ is
$cref/independent/glossary/Operation/Independent/$$ of
the independent variables in $latex x \in B^n$$,
the sparsity pattern is valid for all values of
(even if it has $cref CondExp$$ or $cref VecAD$$ operations).
$head q$$
The argument $icode q$$ has prototype
$codei%
size_t %q%
%$$
It specifies the number of columns in $latex R \in \B{R}^{n \times q}$$
and the number of rows in $latex H(x) \in \B{R}^{q \times n}$$.
It must be the same value as in the previous $cref ForSparseJac$$ call
$codei%
%f%.ForSparseJac(%q%, %r%, %r_transpose%)
%$$
Note that if $icode r_transpose$$ is true, $icode r$$ in the call above
corresponding to $latex R^\R{T} \in \B{R}^{q \times n}$$
$head transpose$$
The argument $icode transpose$$ has prototype
$codei%
bool %transpose%
%$$
The default value $code false$$ is used when $icode transpose$$ is not present.
$head r$$
The matrix $latex R$$ is specified by the previous call
$codei%
%f%.ForSparseJac(%q%, %r%, %transpose%)
%$$
see $cref/r/ForSparseJac/r/$$.
The type of the elements of
$cref/VectorSet/RevSparseHes/VectorSet/$$ must be the
same as the type of the elements of $icode r$$.
$head s$$
The argument $icode s$$ has prototype
$codei%
const %VectorSet%& %s%
%$$
(see $cref/VectorSet/RevSparseHes/VectorSet/$$ below)
If it has elements of type $code bool$$,
its size is $latex m$$.
If it has elements of type $code std::set<size_t>$$,
its size is one and all the elements of $icode%s%[0]%$$
are between zero and $latex m - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the vector $icode S$$.
$head h$$
The result $icode h$$ has prototype
$codei%
%VectorSet%& %h%
%$$
(see $cref/VectorSet/RevSparseHes/VectorSet/$$ below).
$subhead transpose false$$
If $icode h$$ has elements of type $code bool$$,
its size is $latex q * n$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex q$$ and all the set elements are between
zero and $icode%n%-1%$$ inclusive.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex H(x)$$.
$subhead transpose true$$
If $icode h$$ has elements of type $code bool$$,
its size is $latex n * q$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex n$$ and all the set elements are between
zero and $icode%q%-1%$$ inclusive.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex H(x)^\R{T}$$.
$head VectorSet$$
The type $icode VectorSet$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code bool$$ or $code std::set<size_t>$$;
see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion
of the difference.
The type of the elements of
$cref/VectorSet/RevSparseHes/VectorSet/$$ must be the
same as the type of the elements of $icode r$$.
$head Entire Sparsity Pattern$$
Suppose that $latex q = n$$ and
$latex R \in \B{R}^{n \times n}$$ is the $latex n \times n$$ identity matrix.
Further suppose that the $latex S$$ is the $th k$$
$cref/elementary vector/glossary/Elementary Vector/$$; i.e.
$latex \[
S_j = \left\{ \begin{array}{ll}
1 & {\rm if} \; j = k
\\
0 & {\rm otherwise}
\end{array} \right.
\] $$
In this case,
the corresponding value $icode h$$ is a
sparsity pattern for the Hessian matrix
$latex F_k^{(2)} (x) \in \B{R}^{n \times n}$$.
$head Example$$
$children%
example/sparse/rev_sparse_hes.cpp
%example/sparse/sparsity_sub.cpp
%$$
The file
$cref rev_sparse_hes.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
The file
$cref/sparsity_sub.cpp/sparsity_sub.cpp/RevSparseHes/$$
contains an example and test of using $code RevSparseHes$$
to compute the sparsity pattern for a subset of the Hessian.
$end
-----------------------------------------------------------------------------
*/
# include <algorithm>
# include <cppad/local/pod_vector.hpp>
# include <cppad/local/std_set.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file rev_sparse_hes.hpp
Reverse mode Hessian sparsity patterns.
*/
// ===========================================================================
// RevSparseHesCase
/*!
Private helper function for RevSparseHes(q, s) bool sparsity.
All of the description in the public member function RevSparseHes(q, s)
applies.
\param set_type
is a \c bool value. This argument is used to dispatch to the proper source
code depending on the vlaue of \c VectorSet::value_type.
\param transpose
See \c RevSparseHes(q, s).
\param q
See \c RevSparseHes(q, s).
\param s
See \c RevSparseHes(q, s).
\param h
is the return value for the corresponging call to \c RevSparseJac(q, s).
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::RevSparseHesCase(
bool set_type ,
bool transpose ,
size_t q ,
const VectorSet& s ,
VectorSet& h )
{ size_t n = Domain();
size_t m = Range();
//
h.resize(q * n );
CPPAD_ASSERT_KNOWN(
for_jac_sparse_pack_.n_set() > 0,
"RevSparseHes: previous stored call to ForSparseJac did not "
"use bool for the elements of r."
);
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == 0 );
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == num_var_tape_ );
//
// temporary indices
size_t i, j;
// check Vector is Simple VectorSet class with bool elements
CheckSimpleVector<bool, VectorSet>();
CPPAD_ASSERT_KNOWN(
q == for_jac_sparse_pack_.end(),
"RevSparseHes: q is not equal to its value\n"
"in the previous call to ForSparseJac with this ADFun object."
);
CPPAD_ASSERT_KNOWN(
size_t(s.size()) == m,
"RevSparseHes: size of s is not equal to\n"
"range dimension for ADFun object."
);
// Array that will hold reverse Jacobian dependency flag.
// Initialize as true for the dependent variables.
local::pod_vector<bool> RevJac;
RevJac.extend(num_var_tape_);
for(i = 0; i < num_var_tape_; i++)
RevJac[i] = false;
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
RevJac[ dep_taddr_[i] ] = s[i];
}
// vector of sets that will hold reverse Hessain values
local::sparse_pack rev_hes_pattern;
rev_hes_pattern.resize(num_var_tape_, q);
// compute the Hessian sparsity patterns
local::RevHesSweep(
n,
num_var_tape_,
&play_,
for_jac_sparse_pack_,
RevJac.data(),
rev_hes_pattern
);
// return values corresponding to independent variables
CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n * q );
for(j = 0; j < n; j++)
{ for(i = 0; i < q; i++)
{ if( transpose )
h[ j * q + i ] = false;
else h[ i * n + j ] = false;
}
}
// j is index corresponding to reverse mode partial
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
// extract the result from rev_hes_pattern
CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q );
local::sparse_pack::const_iterator itr(rev_hes_pattern, j + 1);
i = *itr;
while( i < q )
{ if( transpose )
h[ j * q + i ] = true;
else h[ i * n + j ] = true;
i = *(++itr);
}
}
}
/*!
Private helper function for RevSparseHes(q, s) set sparsity.
All of the description in the public member function RevSparseHes(q, s)
applies.
\param set_type
is a \c std::set<size_t> value.
This argument is used to dispatch to the proper source
code depending on the vlaue of \c VectorSet::value_type.
\param transpose
See \c RevSparseHes(q, s).
\param q
See \c RevSparseHes(q, s).
\param s
See \c RevSparseHes(q, s).
\param h
is the return value for the corresponging call to \c RevSparseJac(q, s).
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::RevSparseHesCase(
const std::set<size_t>& set_type ,
bool transpose ,
size_t q ,
const VectorSet& s ,
VectorSet& h )
{ size_t n = Domain();
# ifndef NDEBUG
size_t m = Range();
# endif
//
if( transpose )
h.resize(n);
else h.resize(q);
CPPAD_ASSERT_KNOWN(
for_jac_sparse_set_.n_set() > 0,
"RevSparseHes: previous stored call to ForSparseJac did not "
"use std::set<size_t> for the elements of r."
);
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 );
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == num_var_tape_ );
//
// temporary indices
size_t i, j;
std::set<size_t>::const_iterator itr_1;
// check VectorSet is Simple Vector class with sets for elements
CheckSimpleVector<std::set<size_t>, VectorSet>(
local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()
);
CPPAD_ASSERT_KNOWN(
q == for_jac_sparse_set_.end(),
"RevSparseHes: q is not equal to its value\n"
"in the previous call to ForSparseJac with this ADFun object."
);
CPPAD_ASSERT_KNOWN(
s.size() == 1,
"RevSparseHes: size of s is not equal to one."
);
// Array that will hold reverse Jacobian dependency flag.
// Initialize as true for the dependent variables.
local::pod_vector<bool> RevJac;
RevJac.extend(num_var_tape_);
for(i = 0; i < num_var_tape_; i++)
RevJac[i] = false;
itr_1 = s[0].begin();
while( itr_1 != s[0].end() )
{ i = *itr_1++;
CPPAD_ASSERT_KNOWN(
i < m,
"RevSparseHes: an element of the set s[0] has value "
"greater than or equal m"
);
CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
RevJac[ dep_taddr_[i] ] = true;
}
// vector of sets that will hold reverse Hessain values
local::sparse_list rev_hes_pattern;
rev_hes_pattern.resize(num_var_tape_, q);
// compute the Hessian sparsity patterns
local::RevHesSweep(
n,
num_var_tape_,
&play_,
for_jac_sparse_set_,
RevJac.data(),
rev_hes_pattern
);
// return values corresponding to independent variables
// j is index corresponding to reverse mode partial
CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == q || transpose );
CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n || ! transpose );
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
// extract the result from rev_hes_pattern
// and add corresponding elements to result sets in h
CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q );
local::sparse_list::const_iterator itr_2(rev_hes_pattern, j+1);
i = *itr_2;
while( i < q )
{ if( transpose )
h[j].insert(i);
else h[i].insert(j);
i = *(++itr_2);
}
}
}
// ===========================================================================
// RevSparseHes
/*!
User API for Hessian sparsity patterns using reverse mode.
The C++ source code corresponding to this operation is
\verbatim
h = f.RevSparseHes(q, r)
\endverbatim
\tparam Base
is the base type for this recording.
\tparam VectorSet
is a simple vector with elements of type \c bool
or \c std::set<size_t>.
\param transpose
is true (false) if \c is is equal to \f$ H(x) \f$ (\f$ H(x)^T \f$)
where
\f[
H(x) = R^T (S * F)^{(2)} (x)
\f]
where \f$ F \f$ is the function corresponding to the operation sequence
and \a x is any argument value.
\param q
is the value of \a q in the
by the previous call of the form
\verbatim
f.ForSparseJac(q, r, packed)
\endverbatim
The value \c r in this call is a sparsity pattern for the matrix \f$ R \f$.
The type of the element of \c r for the previous call to \c ForSparseJac
must be the same as the type of the elements of \c s.
\param s
is a vector with size \c m that specifies the sparsity pattern
for the vector \f$ S \f$,
where \c m is the number of dependent variables
corresponding to the operation sequence stored in \a play.
\return
If \c transpose is false (true),
the return vector is a sparsity pattern for \f$ H(x) \f$ (\f$ H(x)^T \f$).
\f[
H(x) = R^T ( S * F)^{(2)} (x)
\f]
where \f$ F \f$ is the function corresponding to the operation sequence
and \a x is any argument value.
*/
template <class Base>
template <class VectorSet>
VectorSet ADFun<Base>::RevSparseHes(
size_t q, const VectorSet& s, bool transpose
)
{ VectorSet h;
typedef typename VectorSet::value_type Set_type;
// Should check to make sure q is same as in previous call to
// forward sparse Jacobian.
RevSparseHesCase(
Set_type() ,
transpose ,
q ,
s ,
h
);
return h;
}
// ===========================================================================
// RevSparseHesCheckpoint
/*!
Hessian sparsity patterns calculation used by checkpoint functions.
\tparam Base
is the base type for this recording.
\param transpose
is true (false) h is equal to \f$ H(x) \f$ (\f$ H(x)^T \f$)
where
\f[
H(x) = R^T (S * F)^{(2)} (x)
\f]
where \f$ F \f$ is the function corresponding to the operation sequence
and \f$ x \f$ is any argument value.
\param q
is the value of q in the by the previous call of the form
\verbatim
f.ForSparseJac(q, r)
\endverbatim
The value r in this call is a sparsity pattern for the matrix \f$ R \f$.
\param s
is a vector with size m that specifies the sparsity pattern
for the vector \f$ S \f$,
where m is the number of dependent variables
corresponding to the operation sequence stored in play_.
\param h
The input size and elements of h do not matter.
On output, h is the sparsity pattern for the matrix \f$ H(x) \f$
or \f$ H(x)^T \f$ depending on transpose.
\par Assumptions
The forward jacobian sparsity pattern must be currently stored
in this ADFUN object.
*/
template <class Base>
void ADFun<Base>::RevSparseHesCheckpoint(
size_t q ,
vector<bool>& s ,
bool transpose ,
local::sparse_list& h )
{ size_t n = Domain();
size_t m = Range();
// checkpoint functions should get this right
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 );
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == num_var_tape_ );
CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end() == q );
CPPAD_ASSERT_UNKNOWN( s.size() == m );
// Array that holds the reverse Jacobiain dependcy flags.
// Initialize as true for dependent variables, flase for others.
local::pod_vector<bool> RevJac;
RevJac.extend(num_var_tape_);
for(size_t i = 0; i < num_var_tape_; i++)
RevJac[i] = false;
for(size_t i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ )
RevJac[ dep_taddr_[i] ] = s[i];
}
// holds reverse Hessian sparsity pattern for all variables
local::sparse_list rev_hes_pattern;
rev_hes_pattern.resize(num_var_tape_, q);
// compute Hessian sparsity pattern for all variables
local::RevHesSweep(
n,
num_var_tape_,
&play_,
for_jac_sparse_set_,
RevJac.data(),
rev_hes_pattern
);
// dimension the return value
if( transpose )
h.resize(n, q);
else
h.resize(q, n);
// j is index corresponding to reverse mode partial
for(size_t j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
// extract the result from rev_hes_pattern
CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q );
local::sparse_list::const_iterator itr(rev_hes_pattern, j + 1);
size_t i = *itr;
while( i < q )
{ if( transpose )
h.add_element(j, i);
else h.add_element(i, j);
i = *(++itr);
}
}
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,626 +0,0 @@
# ifndef CPPAD_CORE_REV_SPARSE_JAC_HPP
# define CPPAD_CORE_REV_SPARSE_JAC_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 RevSparseJac$$
$spell
optimizer
nz
CondExpRel
std
VecAD
var
Jacobian
Jac
const
Bool
Dep
proportional
$$
$section Jacobian Sparsity Pattern: Reverse Mode$$
$mindex RevSparseJac sparse$$
$head Syntax$$
$icode%s% = %f%.RevSparseJac(%q%, %r%)
%$$
$icode%s% = %f%.RevSparseJac(%q%, %r%, %transpose%, %dependency%)%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
For a fixed matrix $latex R \in B^{q \times m}$$,
the Jacobian of $latex R * F( x )$$
with respect to $latex x$$ is
$latex \[
S(x) = R * F^{(1)} ( x )
\] $$
Given a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for $latex R$$,
$code RevSparseJac$$ returns a sparsity pattern for the $latex S(x)$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
$head x$$
If the operation sequence in $icode f$$ is
$cref/independent/glossary/Operation/Independent/$$ of
the independent variables in $latex x \in B^n$$,
the sparsity pattern is valid for all values of
(even if it has $cref CondExp$$ or $cref VecAD$$ operations).
$head q$$
The argument $icode q$$ has prototype
$codei%
size_t %q%
%$$
It specifies the number of rows in
$latex R \in B^{q \times m}$$ and the
Jacobian $latex S(x) \in B^{q \times n}$$.
$head transpose$$
The argument $icode transpose$$ has prototype
$codei%
bool %transpose%
%$$
The default value $code false$$ is used when $icode transpose$$ is not present.
$head dependency$$
The argument $icode dependency$$ has prototype
$codei%
bool %dependency%
%$$
If $icode dependency$$ is true,
the $cref/dependency pattern/dependency.cpp/Dependency Pattern/$$
(instead of sparsity pattern) is computed.
$head r$$
The argument $icode s$$ has prototype
$codei%
const %VectorSet%& %r%
%$$
see $cref/VectorSet/RevSparseJac/VectorSet/$$ below.
$subhead transpose false$$
If $icode r$$ has elements of type $code bool$$,
its size is $latex q * m$$.
If it has elements of type $code std::set<size_t>$$,
its size is $icode q$$ and all its set elements are between
zero and $latex m - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex R \in B^{q \times m}$$.
$subhead transpose true$$
If $icode r$$ has elements of type $code bool$$,
its size is $latex m * q$$.
If it has elements of type $code std::set<size_t>$$,
its size is $icode m$$ and all its set elements are between
zero and $latex q - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex R^\R{T} \in B^{m \times q}$$.
$head s$$
The return value $icode s$$ has prototype
$codei%
%VectorSet% %s%
%$$
see $cref/VectorSet/RevSparseJac/VectorSet/$$ below.
$subhead transpose false$$
If it has elements of type $code bool$$,
its size is $latex q * n$$.
If it has elements of type $code std::set<size_t>$$,
its size is $icode q$$ and all its set elements are between
zero and $latex n - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex S(x) \in {q \times n}$$.
$subhead transpose true$$
If it has elements of type $code bool$$,
its size is $latex n * q$$.
If it has elements of type $code std::set<size_t>$$,
its size is $icode n$$ and all its set elements are between
zero and $latex q - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the matrix $latex S(x)^\R{T} \in {n \times q}$$.
$head VectorSet$$
The type $icode VectorSet$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code bool$$ or $code std::set<size_t>$$;
see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion
of the difference.
$head Entire Sparsity Pattern$$
Suppose that $latex q = m$$ and
$latex R$$ is the $latex m \times m$$ identity matrix.
In this case,
the corresponding value for $icode s$$ is a
sparsity pattern for the Jacobian $latex S(x) = F^{(1)} ( x )$$.
$head Example$$
$children%
example/sparse/rev_sparse_jac.cpp
%$$
The file
$cref rev_sparse_jac.cpp$$
contains an example and test of this operation.
It returns true if it succeeds and false otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/local/std_set.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file rev_sparse_jac.hpp
Reverse mode Jacobian sparsity patterns.
*/
// =========================================================================
// RevSparseJacCase
/*!
Private helper function for RevSparseJac(q, r, transpose) boolean sparsity.
All of the description in the public member function
\c RevSparseJac(q, r, transpose) apply.
\param set_type
is a \c bool value.
This argument is used to dispatch to the proper source code
depending on the value of \c VectorSet::value_type.
\param transpose
See \c RevSparseJac(q, r, transpose, dependency)
\param dependency
See \c RevSparseJac(q, r, transpose, dependency)
\param q
See \c RevSparseJac(q, r, transpose, dependency)
\param r
See \c RevSparseJac(q, r, transpose, dependency)
\param s
is the return value for the corresponding call to
RevSparseJac(q, r, transpose).
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::RevSparseJacCase(
bool set_type ,
bool transpose ,
bool dependency ,
size_t q ,
const VectorSet& r ,
VectorSet& s )
{ size_t n = Domain();
size_t m = Range();
// dimension of the result vector
s.resize( q * n );
// temporary indices
size_t i, j;
// check VectorSet is Simple Vector class with bool elements
CheckSimpleVector<bool, VectorSet>();
//
CPPAD_ASSERT_KNOWN(
q > 0,
"RevSparseJac: q is not greater than zero"
);
CPPAD_ASSERT_KNOWN(
size_t(r.size()) == q * m,
"RevSparseJac: size of r is not equal to\n"
"q times range dimension for ADFun object."
);
//
// vector of sets that will hold the results
local::sparse_pack var_sparsity;
var_sparsity.resize(num_var_tape_, q);
// The sparsity pattern corresponding to the dependent variables
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
if( transpose )
{ for(j = 0; j < q; j++) if( r[ i * q + j ] )
var_sparsity.add_element( dep_taddr_[i], j );
}
else
{ for(j = 0; j < q; j++) if( r[ j * m + i ] )
var_sparsity.add_element( dep_taddr_[i], j );
}
}
// evaluate the sparsity patterns
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
var_sparsity
);
// return values corresponding to dependent variables
CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q * n );
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
// extract the result from var_sparsity
if( transpose )
{ for(i = 0; i < q; i++)
s[ j * q + i ] = false;
}
else
{ for(i = 0; i < q; i++)
s[ i * n + j ] = false;
}
CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );
local::sparse_pack::const_iterator itr(var_sparsity, j+1);
i = *itr;
while( i < q )
{ if( transpose )
s[ j * q + i ] = true;
else s[ i * n + j ] = true;
i = *(++itr);
}
}
}
/*!
Private helper function for RevSparseJac(q, r, transpose) set sparsity
All of the description in the public member function
\c RevSparseJac(q, r, transpose) apply.
\param set_type
is a \c std::set<size_t> object.
This argument is used to dispatch to the proper source code
depending on the value of \c VectorSet::value_type.
\param transpose
See \c RevSparseJac(q, r, transpose, dependency)
\param dependency
See \c RevSparseJac(q, r, transpose, dependency)
\param q
See \c RevSparseJac(q, r, transpose, dependency)
\param r
See \c RevSparseJac(q, r, transpose, dependency)
\param s
is the return value for the corresponding call to RevSparseJac(q, r, transpose)
*/
template <class Base>
template <class VectorSet>
void ADFun<Base>::RevSparseJacCase(
const std::set<size_t>& set_type ,
bool transpose ,
bool dependency ,
size_t q ,
const VectorSet& r ,
VectorSet& s )
{ // dimension of the result vector
if( transpose )
s.resize( Domain() );
else s.resize( q );
// temporary indices
size_t i, j;
std::set<size_t>::const_iterator itr_1;
// check VectorSet is Simple Vector class with sets for elements
CheckSimpleVector<std::set<size_t>, VectorSet>(
local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()
);
// domain dimensions for F
size_t n = ind_taddr_.size();
size_t m = dep_taddr_.size();
CPPAD_ASSERT_KNOWN(
q > 0,
"RevSparseJac: q is not greater than zero"
);
CPPAD_ASSERT_KNOWN(
size_t(r.size()) == q || transpose,
"RevSparseJac: size of r is not equal to q and transpose is false."
);
CPPAD_ASSERT_KNOWN(
size_t(r.size()) == m || ! transpose,
"RevSparseJac: size of r is not equal to m and transpose is true."
);
// vector of lists that will hold the results
local::sparse_list var_sparsity;
var_sparsity.resize(num_var_tape_, q);
// The sparsity pattern corresponding to the dependent variables
if( transpose )
{ for(i = 0; i < m; i++)
{ itr_1 = r[i].begin();
while(itr_1 != r[i].end())
{ j = *itr_1++;
CPPAD_ASSERT_KNOWN(
j < q,
"RevSparseJac: transpose is true and element of the set\n"
"r[i] has value greater than or equal q."
);
CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
var_sparsity.add_element( dep_taddr_[i], j );
}
}
}
else
{ for(i = 0; i < q; i++)
{ itr_1 = r[i].begin();
while(itr_1 != r[i].end())
{ j = *itr_1++;
CPPAD_ASSERT_KNOWN(
j < m,
"RevSparseJac: transpose is false and element of the set\n"
"r[i] has value greater than or equal range dimension."
);
CPPAD_ASSERT_UNKNOWN( dep_taddr_[j] < num_var_tape_ );
var_sparsity.add_element( dep_taddr_[j], i );
}
}
}
// evaluate the sparsity patterns
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
var_sparsity
);
// return values corresponding to dependent variables
CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || transpose );
CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == n || ! transpose );
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );
local::sparse_list::const_iterator itr_2(var_sparsity, j+1);
i = *itr_2;
while( i < q )
{ if( transpose )
s[j].insert(i);
else s[i].insert(j);
i = *(++itr_2);
}
}
}
// =========================================================================
// RevSparseJac
/*!
User API for Jacobian sparsity patterns using reverse mode.
The C++ source code corresponding to this operation is
\verbatim
s = f.RevSparseJac(q, r, transpose, dependency)
\endverbatim
\tparam Base
is the base type for this recording.
\tparam VectorSet
is a simple vector with elements of type \c bool.
or \c std::set<size_t>.
\param q
is the number of rows in the matrix \f$ R \f$.
\param r
is a sparsity pattern for the matrix \f$ R \f$.
\param transpose
are the sparsity patterns for \f$ R \f$ and \f$ S(x) \f$ transposed.
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\return
If \c transpose is false (true), the return value is a sparsity pattern
for \f$ S(x) \f$ (\f$ S(x)^T \f$) where
\f[
S(x) = R * F^{(1)} (x)
\f]
and \f$ F \f$ is the function corresponding to the operation sequence
and \a x is any argument value.
If \c VectorSet::value_type is \c bool,
the return value has size \f$ q * n \f$ ( \f$ n * q \f$).
If \c VectorSet::value_type is \c std::set<size_t>,
the return value has size \f$ q \f$ ( \f$ n \f$)
and with all its elements between zero and \f$ n - 1 \f$ (\f$ q - 1 \f$).
*/
template <class Base>
template <class VectorSet>
VectorSet ADFun<Base>::RevSparseJac(
size_t q ,
const VectorSet& r ,
bool transpose ,
bool dependency )
{
VectorSet s;
typedef typename VectorSet::value_type Set_type;
RevSparseJacCase(
Set_type() ,
transpose ,
dependency ,
q ,
r ,
s
);
return s;
}
// ===========================================================================
// RevSparseJacCheckpoint
/*!
Reverse mode Jacobian sparsity calculation used by checkpoint functions.
\tparam Base
is the base type for this recording.
\param transpose
is true (false) s is equal to \f$ S(x) \f$ (\f$ S(x)^T \f$)
where
\f[
S(x) = R * F^{(1)} (x)
\f]
where \f$ F \f$ is the function corresponding to the operation sequence
and \f$ x \f$ is any argument value.
\param q
is the number of rows in the matrix \f$ R \f$.
\param r
is a sparsity pattern for the matrix \f$ R \f$.
\param transpose
are the sparsity patterns for \f$ R \f$ and \f$ S(x) \f$ transposed.
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\param s
The input size and elements of s do not matter.
On output, s is the sparsity pattern for the matrix \f$ S(x) \f$
or \f$ S(x)^T \f$ depending on transpose.
*/
template <class Base>
void ADFun<Base>::RevSparseJacCheckpoint(
size_t q ,
const local::sparse_list& r ,
bool transpose ,
bool dependency ,
local::sparse_list& s )
{ size_t n = Domain();
size_t m = Range();
# ifndef NDEBUG
if( transpose )
{ CPPAD_ASSERT_UNKNOWN( r.n_set() == m );
CPPAD_ASSERT_UNKNOWN( r.end() == q );
}
else
{ CPPAD_ASSERT_UNKNOWN( r.n_set() == q );
CPPAD_ASSERT_UNKNOWN( r.end() == m );
}
for(size_t i = 0; i < m; i++)
CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
# endif
// holds reverse Jacobian sparsity pattern for all variables
local::sparse_list var_sparsity;
var_sparsity.resize(num_var_tape_, q);
// set sparsity pattern for dependent variables
if( transpose )
{ for(size_t i = 0; i < m; i++)
{ local::sparse_list::const_iterator itr(r, i);
size_t j = *itr;
while( j < q )
{ var_sparsity.add_element( dep_taddr_[i], j );
j = *(++itr);
}
}
}
else
{ for(size_t j = 0; j < q; j++)
{ local::sparse_list::const_iterator itr(r, j);
size_t i = *itr;
while( i < m )
{ var_sparsity.add_element( dep_taddr_[i], j );
i = *(++itr);
}
}
}
// evaluate the sparsity pattern for all variables
local::RevJacSweep(
dependency,
n,
num_var_tape_,
&play_,
var_sparsity
);
// dimension the return value
if( transpose )
s.resize(n, m);
else
s.resize(m, n);
// return values corresponding to independent variables
for(size_t j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
// ind_taddr_[j] is operator taddr for j-th independent variable
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
// extract the result from var_sparsity
CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );
local::sparse_list::const_iterator itr(var_sparsity, j+1);
size_t i = *itr;
while( i < q )
{ if( transpose )
s.add_element(j, i);
else
s.add_element(i, j);
i = *(++itr);
}
}
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,235 +0,0 @@
# ifndef CPPAD_CORE_REV_TWO_HPP
# define CPPAD_CORE_REV_TWO_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 RevTwo$$
$spell
ddw
typename
Taylor
const
$$
$section Reverse Mode Second Partial Derivative Driver$$
$mindex order easy$$
$head Syntax$$
$icode%ddw% = %f%.RevTwo(%x%, %i%, %j%)%$$
$head Purpose$$
We use $latex F : B^n \rightarrow B^m$$ to denote the
$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$.
The syntax above sets
$latex \[
ddw [ k * p + \ell ]
=
\DD{ F_{i[ \ell ]} }{ x_{j[ \ell ]} }{ x_k } (x)
\] $$
for $latex k = 0 , \ldots , n-1$$
and $latex \ell = 0 , \ldots , p$$,
where $latex p$$ is the size of the vectors $icode i$$ and $icode j$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/RevTwo Uses Forward/RevTwo/RevTwo Uses Forward/$$ below).
$head x$$
The argument $icode x$$ has prototype
$codei%
const %VectorBase% &%x%
%$$
(see $cref/VectorBase/RevTwo/VectorBase/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies
that point at which to evaluate the partial derivatives listed above.
$head i$$
The argument $icode i$$ has prototype
$codei%
const %VectorSize_t% &%i%
%$$
(see $cref/VectorSize_t/RevTwo/VectorSize_t/$$ below)
We use $icode p$$ to denote the size of the vector $icode i$$.
All of the indices in $icode i$$
must be less than $icode m$$, the dimension of the
$cref/range/seq_property/Range/$$ space for $icode f$$; i.e.,
for $latex \ell = 0 , \ldots , p-1$$, $latex i[ \ell ] < m$$.
$head j$$
The argument $icode j$$ has prototype
$codei%
const %VectorSize_t% &%j%
%$$
(see $cref/VectorSize_t/RevTwo/VectorSize_t/$$ below)
and its size must be equal to $icode p$$,
the size of the vector $icode i$$.
All of the indices in $icode j$$
must be less than $icode n$$; i.e.,
for $latex \ell = 0 , \ldots , p-1$$, $latex j[ \ell ] < n$$.
$head ddw$$
The result $icode ddw$$ has prototype
$codei%
%VectorBase% %ddw%
%$$
(see $cref/VectorBase/RevTwo/VectorBase/$$ below)
and its size is $latex n * p$$.
It contains the requested partial derivatives; to be specific,
for $latex k = 0 , \ldots , n - 1 $$
and $latex \ell = 0 , \ldots , p - 1$$
$latex \[
ddw [ k * p + \ell ]
=
\DD{ F_{i[ \ell ]} }{ x_{j[ \ell ]} }{ x_k } (x)
\] $$
$head VectorBase$$
The type $icode VectorBase$$ must be a $cref SimpleVector$$ class with
$cref/elements of type Base/SimpleVector/Elements of Specified Type/$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head VectorSize_t$$
The type $icode VectorSize_t$$ must be a $cref SimpleVector$$ class with
$cref/elements of type size_t/SimpleVector/Elements of Specified Type/$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head RevTwo Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code RevTwo$$,
the zero order Taylor coefficients correspond to
$icode%f%.Forward(0, %x%)%$$
and the other coefficients are unspecified.
$head Examples$$
$children%
example/general/rev_two.cpp
%$$
The routine
$cref/RevTwo/rev_two.cpp/$$ is both an example and test.
It returns $code true$$, if it succeeds and $code false$$ otherwise.
$end
-----------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <typename Base>
template <typename VectorBase, typename VectorSize_t>
VectorBase ADFun<Base>::RevTwo(
const VectorBase &x,
const VectorSize_t &i,
const VectorSize_t &j)
{ size_t i1;
size_t j1;
size_t k;
size_t l;
size_t n = Domain();
size_t m = Range();
size_t p = i.size();
// check VectorBase is Simple Vector class with Base elements
CheckSimpleVector<Base, VectorBase>();
// check VectorSize_t is Simple Vector class with size_t elements
CheckSimpleVector<size_t, VectorSize_t>();
CPPAD_ASSERT_KNOWN(
x.size() == n,
"RevTwo: Length of x not equal domain dimension for f."
);
CPPAD_ASSERT_KNOWN(
i.size() == j.size(),
"RevTwo: Lenght of the i and j vectors are not equal."
);
// point at which we are evaluating the second partials
Forward(0, x);
// dimension the return value
VectorBase ddw(n * p);
// direction vector in argument space
VectorBase dx(n);
for(j1 = 0; j1 < n; j1++)
dx[j1] = Base(0.0);
// direction vector in range space
VectorBase w(m);
for(i1 = 0; i1 < m; i1++)
w[i1] = Base(0.0);
// place to hold the results of a reverse calculation
VectorBase r(n * 2);
// check the indices in i and j
for(l = 0; l < p; l++)
{ i1 = i[l];
j1 = j[l];
CPPAD_ASSERT_KNOWN(
i1 < m,
"RevTwo: an eleemnt of i not less than range dimension for f."
);
CPPAD_ASSERT_KNOWN(
j1 < n,
"RevTwo: an element of j not less than domain dimension for f."
);
}
// loop over all forward directions
for(j1 = 0; j1 < n; j1++)
{ // first order forward mode calculation done
bool first_done = false;
for(l = 0; l < p; l++) if( j[l] == j1 )
{ if( ! first_done )
{ first_done = true;
// first order forward mode in j1 direction
dx[j1] = Base(1.0);
Forward(1, dx);
dx[j1] = Base(0.0);
}
// execute a reverse in this component direction
i1 = i[l];
w[i1] = Base(1.0);
r = Reverse(2, w);
w[i1] = Base(0.0);
// place the reverse result in return value
for(k = 0; k < n; k++)
ddw[k * p + l] = r[k * 2 + 1];
}
}
return ddw;
}
} // END CppAD namespace
# endif

View File

@ -1,209 +0,0 @@
// $Id$
# ifndef CPPAD_CORE_REVERSE_HPP
# define CPPAD_CORE_REVERSE_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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.
-------------------------------------------------------------------------- */
# include <algorithm>
# include <cppad/local/pod_vector.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file reverse.hpp
Compute derivatives using reverse mode.
*/
/*!
Use reverse mode to compute derivative of forward mode Taylor coefficients.
The function
\f$ X : {\rm R} \times {\rm R}^{n \times q} \rightarrow {\rm R} \f$
is defined by
\f[
X(t , u) = \sum_{k=0}^{q-1} u^{(k)} t^k
\f]
The function
\f$ Y : {\rm R} \times {\rm R}^{n \times q} \rightarrow {\rm R} \f$
is defined by
\f[
Y(t , u) = F[ X(t, u) ]
\f]
The function
\f$ W : {\rm R}^{n \times q} \rightarrow {\rm R} \f$ is defined by
\f[
W(u) = \sum_{k=0}^{q-1} ( w^{(k)} )^{\rm T}
\frac{1}{k !} \frac{ \partial^k } { t^k } Y(0, u)
\f]
\tparam Base
base type for the operator; i.e., this operation sequence was recorded
using AD< \a Base > and computations by this routine are done using type
\a Base.
\tparam VectorBase
is a Simple Vector class with elements of type \a Base.
\param q
is the number of the number of Taylor coefficients that are being
differentiated (per variable).
\param w
is the weighting for each of the Taylor coefficients corresponding
to dependent variables.
If the argument \a w has size <tt>m * q </tt>,
for \f$ k = 0 , \ldots , q-1 \f$ and \f$ i = 0, \ldots , m-1 \f$,
\f[
w_i^{(k)} = w [ i * q + k ]
\f]
If the argument \a w has size \c m ,
for \f$ k = 0 , \ldots , q-1 \f$ and \f$ i = 0, \ldots , m-1 \f$,
\f[
w_i^{(k)} = \left\{ \begin{array}{ll}
w [ i ] & {\rm if} \; k = q-1
\\
0 & {\rm otherwise}
\end{array} \right.
\f]
\return
Is a vector \f$ dw \f$ such that
for \f$ j = 0 , \ldots , n-1 \f$ and
\f$ k = 0 , \ldots , q-1 \f$
\f[
dw[ j * q + k ] = W^{(1)} ( x )_{j,k}
\f]
where the matrix \f$ x \f$ is the value for \f$ u \f$
that corresponding to the forward mode Taylor coefficients
for the independent variables as specified by previous calls to Forward.
*/
template <typename Base>
template <typename VectorBase>
VectorBase ADFun<Base>::Reverse(size_t q, const VectorBase &w)
{ // constants
const Base zero(0);
// temporary indices
size_t i, j, k;
// number of independent variables
size_t n = ind_taddr_.size();
// number of dependent variables
size_t m = dep_taddr_.size();
local::pod_vector<Base> Partial;
Partial.extend(num_var_tape_ * q);
// update maximum memory requirement
// memoryMax = std::max( memoryMax,
// Memory() + num_var_tape_ * q * sizeof(Base)
// );
// check VectorBase is Simple Vector class with Base type elements
CheckSimpleVector<Base, VectorBase>();
CPPAD_ASSERT_KNOWN(
size_t(w.size()) == m || size_t(w.size()) == (m * q),
"Argument w to Reverse does not have length equal to\n"
"the dimension of the range for the corresponding ADFun."
);
CPPAD_ASSERT_KNOWN(
q > 0,
"The first argument to Reverse must be greater than zero."
);
CPPAD_ASSERT_KNOWN(
num_order_taylor_ >= q,
"Less that q taylor_ coefficients are currently stored"
" in this ADFun object."
);
// special case where multiple forward directions have been computed,
// but we are only using the one direction zero order results
if( (q == 1) & (num_direction_taylor_ > 1) )
{ num_order_taylor_ = 1; // number of orders to copy
size_t c = cap_order_taylor_; // keep the same capacity setting
size_t r = 1; // only keep one direction
capacity_order(c, r);
}
CPPAD_ASSERT_KNOWN(
num_direction_taylor_ == 1,
"Reverse mode for Forward(q, r, xq) with more than one direction"
"\n(r > 1) is not yet supported for q > 1."
);
// initialize entire Partial matrix to zero
for(i = 0; i < num_var_tape_; i++)
for(j = 0; j < q; j++)
Partial[i * q + j] = zero;
// set the dependent variable direction
// (use += because two dependent variables can point to same location)
for(i = 0; i < m; i++)
{ CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
if( size_t(w.size()) == m )
Partial[dep_taddr_[i] * q + q - 1] += w[i];
else
{ for(k = 0; k < q; k++)
// ? should use += here, first make test to demonstrate bug
Partial[ dep_taddr_[i] * q + k ] = w[i * q + k ];
}
}
// evaluate the derivatives
CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
CPPAD_ASSERT_UNKNOWN( load_op_.size() == play_.num_load_op_rec() );
local::ReverseSweep(
q - 1,
n,
num_var_tape_,
&play_,
cap_order_taylor_,
taylor_.data(),
q,
Partial.data(),
cskip_op_.data(),
load_op_
);
// return the derivative values
VectorBase value(n * q);
for(j = 0; j < n; j++)
{ CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );
// independent variable taddr equals its operator taddr
CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );
// by the Reverse Identity Theorem
// partial of y^{(k)} w.r.t. u^{(0)} is equal to
// partial of y^{(q-1)} w.r.t. u^{(q - 1 - k)}
if( size_t(w.size()) == m )
{ for(k = 0; k < q; k++)
value[j * q + k ] =
Partial[ind_taddr_[j] * q + q - 1 - k];
}
else
{ for(k = 0; k < q; k++)
value[j * q + k ] =
Partial[ind_taddr_[j] * q + k];
}
}
CPPAD_ASSERT_KNOWN( ! ( hasnan(value) && check_for_nan_ ) ,
"dw = f.Reverse(q, w): has a nan,\n"
"but none of its Taylor coefficents are nan."
);
return value;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,103 +0,0 @@
# ifndef CPPAD_CORE_SIGN_HPP
# define CPPAD_CORE_SIGN_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 sign$$
$spell
CppAD
Dirac
$$
$section The Sign: sign$$
$head Syntax$$
$icode%y% = sign(%x%)%$$
$head Description$$
Evaluates the $code sign$$ function which is defined by
$latex \[
{\rm sign} (x) =
\left\{ \begin{array}{rl}
+1 & {\rm if} \; x > 0 \\
0 & {\rm if} \; x = 0 \\
-1 & {\rm if} \; x < 0
\end{array} \right.
\] $$
$head x, y$$
See the $cref/possible types/unary_standard_math/Possible Types/$$
for a unary standard math function.
$head Atomic$$
This is an $cref/atomic operation/glossary/Operation/Atomic/$$.
$head Derivative$$
CppAD computes the derivative of the $code sign$$ function as zero for all
argument values $icode x$$.
The correct mathematical derivative is different and
is given by
$latex \[
{\rm sign}^{(1)} (x) = 2 \delta (x)
\] $$
where $latex \delta (x)$$ is the Dirac Delta function.
$head Example$$
$children%
example/general/sign.cpp
%$$
The file
$cref sign.cpp$$
contains an example and test of this function.
It returns true if it succeeds and false otherwise.
$end
-------------------------------------------------------------------------------
*/
// BEGIN CppAD namespace
namespace CppAD {
template <class Base>
AD<Base> AD<Base>::sign_me (void) const
{
AD<Base> result;
result.value_ = sign(value_);
CPPAD_ASSERT_UNKNOWN( Parameter(result) );
if( Variable(*this) )
{ // add this operation to the tape
CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SignOp) == 1 );
CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SignOp) == 1 );
local::ADTape<Base> *tape = tape_this();
// corresponding operand address
tape->Rec_.PutArg(taddr_);
// put operator in the tape
result.taddr_ = tape->Rec_.PutOp(local::SignOp);
// make result a variable
result.tape_id_ = tape->id_;
}
return result;
}
template <class Base>
inline AD<Base> sign(const AD<Base> &x)
{ return x.sign_me(); }
template <class Base>
inline AD<Base> sign(const VecAD_reference<Base> &x)
{ return x.ADBase().sign_me(); }
} // END CppAD namespace
# endif

View File

@ -1,31 +0,0 @@
# ifndef CPPAD_CORE_SPARSE_HPP
# define CPPAD_CORE_SPARSE_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.
-------------------------------------------------------------------------- */
# include <cppad/core/for_jac_sparsity.hpp>
# include <cppad/core/rev_jac_sparsity.hpp>
# include <cppad/core/rev_hes_sparsity.hpp>
# include <cppad/core/for_hes_sparsity.hpp>
//
# include <cppad/core/for_sparse_jac.hpp>
# include <cppad/core/rev_sparse_jac.hpp>
# include <cppad/core/rev_sparse_hes.hpp>
# include <cppad/core/for_sparse_hes.hpp>
//
# include <cppad/core/sparse_jac.hpp>
# include <cppad/core/sparse_hes.hpp>
//
# include <cppad/core/sparse_jacobian.hpp>
# include <cppad/core/sparse_hessian.hpp>
# endif

View File

@ -1,540 +0,0 @@
# ifndef CPPAD_CORE_SPARSE_HES_HPP
# define CPPAD_CORE_SPARSE_HES_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 sparse_hes$$
$spell
const
Taylor
rc
rcv
nr
nc
hes
std
cppad
colpack
cmake
Jacobian
$$
$section Computing Sparse Hessians$$
$head Syntax$$
$icode%n_sweep% = %f%.sparse_hes(
%x%, %w%, %subset%, %pattern%, %coloring%, %work%
)%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
function corresponding to $icode f$$.
Here $icode n$$ is the $cref/domain/seq_property/Domain/$$ size,
and $icode m$$ is the $cref/range/seq_property/Range/$$ size, or $icode f$$.
The syntax above takes advantage of sparsity when computing the Hessian
$latex \[
H(x) = \dpow{2}{x} \sum_{i=0}^{m-1} w_i F_i (x)
\] $$
In the sparse case, this should be faster and take less memory than
$cref Hessian$$.
The matrix element $latex H_{i,j} (x)$$ is the second partial of
$latex w^\R{T} F (x)$$ with respect to $latex x_i$$ and $latex x_j$$.
$head SizeVector$$
The type $icode SizeVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head BaseVector$$
The type $icode BaseVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head f$$
This object has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the Taylor coefficients stored in $icode f$$ are affected
by this operation; see
$cref/uses forward/sparse_hes/Uses Forward/$$ below.
$head x$$
This argument has prototype
$codei%
const %BaseVector%& %x%
%$$
and its size is $icode n$$.
It specifies the point at which to evaluate the Hessian
$latex H(x)$$.
$head w$$
This argument has prototype
$codei%
const %BaseVector%& %w%
%$$
and its size is $icode m$$.
It specifies the weight for each of the components of $latex F(x)$$;
i.e. $latex w_i$$ is the weight for $latex F_i (x)$$.
$head subset$$
This argument has prototype
$codei%
sparse_rcv<%SizeVector%, %BaseVector%>& %subset%
%$$
Its row size and column size is $icode n$$; i.e.,
$icode%subset%.nr() == %n%$$ and $icode%subset%.nc() == %n%$$.
It specifies which elements of the Hessian are computed.
$list number$$
The input value of its value vector
$icode%subset%.val()%$$ does not matter.
Upon return it contains the value of the corresponding elements
of the Hessian.
$lnext
All of the row, column pairs in $icode subset$$ must also appear in
$icode pattern$$; i.e., they must be possibly non-zero.
$lnext
The Hessian is symmetric, so one has a choice as to which off diagonal
elements to put in $icode subset$$.
It will probably be more efficient if one makes this choice so that
the there are more entries in each non-zero column of $icode subset$$;
see $cref/n_sweep/sparse_hes/n_sweep/$$ below.
$lend
$head pattern$$
This argument has prototype
$codei%
const sparse_rc<%SizeVector%>& %pattern%
%$$
Its row size and column size is $icode n$$; i.e.,
$icode%pattern%.nr() == %n%$$ and $icode%pattern%.nc() == %n%$$.
It is a sparsity pattern for the Hessian $latex H(x)$$.
If the $th i$$ row ($th j$$ column) does not appear in $icode subset$$,
the $th i$$ row ($th j$$ column) of $icode pattern$$ does not matter
and need not be computed.
This argument is not used (and need not satisfy any conditions),
when $cref/work/sparse_hes/work/$$ is non-empty.
$subhead subset$$
If the $th i$$ row and $th i$$ column do not appear in $icode subset$$,
the $th i$$ row and column of $icode pattern$$ do not matter.
In this case the $th i-th$$ row and column may have no entries in
$icode pattern$$ even though they are possibly non-zero in $latex H(x)$$.
(This can be used to reduce the amount of computation required to find
$icode pattern$$.)
$head coloring$$
The coloring algorithm determines which rows and columns
can be computed during the same sweep.
This field has prototype
$codei%
const std::string& %coloring%
%$$
This value only matters when work is empty; i.e.,
after the $icode work$$ constructor or $icode%work%.clear()%$$.
$subhead cppad.symmetric$$
This coloring takes advantage of the fact that the Hessian matrix
is symmetric when find a coloring that requires fewer
$cref/sweeps/sparse_hes/n_sweep/$$.
$subhead cppad.general$$
This is the same as the sparse Jacobian
$cref/cppad/sparse_jac/coloring/cppad/$$ method
which does not take advantage of symmetry.
$subhead colpack.symmetric$$
If $cref colpack_prefix$$ was specified on the
$cref/cmake command/cmake/CMake Command/$$ line,
you can set $icode coloring$$ to $code colpack.symmetric$$.
This also takes advantage of the fact that the Hessian matrix is symmetric.
$subhead colpack.general$$
If $cref colpack_prefix$$ was specified on the
$cref/cmake command/cmake/CMake Command/$$ line,
you can set $icode coloring$$ to $code colpack.general$$.
This is the same as the sparse Jacobian
$cref/colpack/sparse_jac/coloring/colpack/$$ method
which does not take advantage of symmetry.
$subhead colpack.star Deprecated 2017-06-01$$
The $code colpack.star$$ method is deprecated.
It is the same as the $code colpack.symmetric$$ method
which should be used instead.
$head work$$
This argument has prototype
$codei%
sparse_hes_work& %work%
%$$
We refer to its initial value,
and its value after $icode%work%.clear()%$$, as empty.
If it is empty, information is stored in $icode work$$.
This can be used to reduce computation when
a future call is for the same object $icode f$$,
and the same subset of the Hessian.
If either of these values change, use $icode%work%.clear()%$$ to
empty this structure.
$head n_sweep$$
The return value $icode n_sweep$$ has prototype
$codei%
size_t %n_sweep%
%$$
It is the number of first order forward sweeps
used to compute the requested Hessian values.
Each first forward sweep is followed by a second order reverse sweep
so it is also the number of reverse sweeps.
It is also the number of colors determined by the coloring method
mentioned above.
This is proportional to the total computational work,
not counting the zero order forward sweep,
or combining multiple columns and rows into a single sweep.
$head Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code sparse_hes$$
the zero order coefficients correspond to
$codei%
%f%.Forward(0, %x%)
%$$
All the other forward mode coefficients are unspecified.
$head Example$$
$children%
example/sparse/sparse_hes.cpp
%$$
The files $cref sparse_hes.cpp$$
is an example and test of $code sparse_hes$$.
It returns $code true$$, if it succeeds, and $code false$$ otherwise.
$head Subset Hessian$$
The routine
$cref sparse_sub_hes.cpp$$
is an example and test that compute a subset of a sparse Hessian.
It returns $code true$$, for success, and $code false$$ otherwise.
$end
*/
# include <cppad/core/cppad_assert.hpp>
# include <cppad/local/sparse_internal.hpp>
# include <cppad/local/color_general.hpp>
# include <cppad/local/color_symmetric.hpp>
/*!
\file sparse_hes.hpp
Sparse Hessian calculation routines.
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Class used to hold information used by Sparse Hessian routine in this file,
so it does not need to be recomputed every time.
*/
class sparse_hes_work {
public:
/// row and column indicies for return values
/// (some may be reflected by symmetric coloring algorithms)
CppAD::vector<size_t> row;
CppAD::vector<size_t> col;
/// indices that sort the row and col arrays by color
CppAD::vector<size_t> order;
/// results of the coloring algorithm
CppAD::vector<size_t> color;
/// constructor
sparse_hes_work(void)
{ }
/// inform CppAD that this information needs to be recomputed
void clear(void)
{
row.clear();
col.clear();
order.clear();
color.clear();
}
};
// ----------------------------------------------------------------------------
/*!
Calculate sparse Hessians using forward mode
\tparam Base
the base type for the recording that is stored in the ADFun object.
\tparam SizeVector
a simple vector class with elements of type size_t.
\tparam BaseVector
a simple vector class with elements of type Base.
\param x
a vector of length n, the number of independent variables in f
(this ADFun object).
\param w
a vector of length m, the number of dependent variables in f
(this ADFun object).
\param subset
specifices the subset of the sparsity pattern where the Hessian is evaluated.
subset.nr() == n,
subset.nc() == n.
\param pattern
is a sparsity pattern for the Hessian of w^T * f;
pattern.nr() == n,
pattern.nc() == n,
where m is number of dependent variables in f.
\param coloring
determines which coloring algorithm is used.
This must be cppad.symmetric, cppad.general, colpack.symmetic,
or colpack.star.
\param work
this structure must be empty, or contain the information stored
by a previous call to sparse_hes.
The previous call must be for the same ADFun object f
and the same subset.
\return
This is the number of first order forward
(and second order reverse) sweeps used to compute thhe Hessian.
*/
template <class Base>
template <class SizeVector, class BaseVector>
size_t ADFun<Base>::sparse_hes(
const BaseVector& x ,
const BaseVector& w ,
sparse_rcv<SizeVector , BaseVector>& subset ,
const sparse_rc<SizeVector>& pattern ,
const std::string& coloring ,
sparse_hes_work& work )
{ size_t n = Domain();
//
CPPAD_ASSERT_KNOWN(
subset.nr() == n,
"sparse_hes: subset.nr() not equal domain dimension for f"
);
CPPAD_ASSERT_KNOWN(
subset.nc() == n,
"sparse_hes: subset.nc() not equal domain dimension for f"
);
CPPAD_ASSERT_KNOWN(
size_t( x.size() ) == n,
"sparse_hes: x.size() not equal domain dimension for f"
);
CPPAD_ASSERT_KNOWN(
size_t( w.size() ) == Range(),
"sparse_hes: w.size() not equal range dimension for f"
);
//
// work information
vector<size_t>& row(work.row);
vector<size_t>& col(work.col);
vector<size_t>& color(work.color);
vector<size_t>& order(work.order);
//
// subset information
const SizeVector& subset_row( subset.row() );
const SizeVector& subset_col( subset.col() );
//
// point at which we are evaluationg the Hessian
Forward(0, x);
//
// number of elements in the subset
size_t K = subset.nnz();
//
// check for case were there is nothing to do
// (except for call to Forward(0, x)
if( K == 0 )
return 0;
//
# ifndef NDEBUG
if( color.size() != 0 )
{ CPPAD_ASSERT_KNOWN(
color.size() == n,
"sparse_hes: work is non-empty and conditions have changed"
);
CPPAD_ASSERT_KNOWN(
row.size() == K,
"sparse_hes: work is non-empty and conditions have changed"
);
CPPAD_ASSERT_KNOWN(
col.size() == K,
"sparse_hes: work is non-empty and conditions have changed"
);
//
for(size_t k = 0; k < K; k++)
{ bool ok = row[k] == subset_row[k] && col[k] == subset_col[k];
ok |= row[k] == subset_col[k] && col[k] == subset_row[k];
CPPAD_ASSERT_KNOWN(
ok,
"sparse_hes: work is non-empty and conditions have changed"
);
}
}
# endif
//
// check for case where input work is empty
if( color.size() == 0 )
{ // compute work color and order vectors
CPPAD_ASSERT_KNOWN(
pattern.nr() == n,
"sparse_hes: pattern.nr() not equal domain dimension for f"
);
CPPAD_ASSERT_KNOWN(
pattern.nc() == n,
"sparse_hes: pattern.nc() not equal domain dimension for f"
);
//
// initialize work row, col to be same as subset row, col
row.resize(K);
col.resize(K);
// cannot assign vectors becasue may be of different types
// (SizeVector and CppAD::vector<size_t>)
for(size_t k = 0; k < K; k++)
{ row[k] = subset_row[k];
col[k] = subset_col[k];
}
//
// convert pattern to an internal version of its transpose
vector<size_t> internal_index(n);
for(size_t j = 0; j < n; j++)
internal_index[j] = j;
bool transpose = true;
bool zero_empty = false;
bool input_empty = true;
local::sparse_list internal_pattern;
internal_pattern.resize(n, n);
local::set_internal_sparsity(zero_empty, input_empty,
transpose, internal_index, internal_pattern, pattern
);
//
// execute coloring algorithm
// (we are using transpose becasue coloring groups rows, not columns)
color.resize(n);
if( coloring == "cppad.general" )
local::color_general_cppad(internal_pattern, col, row, color);
else if( coloring == "cppad.symmetric" )
local::color_symmetric_cppad(internal_pattern, col, row, color);
else if( coloring == "colpack.general" )
{
# if CPPAD_HAS_COLPACK
local::color_general_colpack(internal_pattern, col, row, color);
# else
CPPAD_ASSERT_KNOWN(
false,
"sparse_hes: coloring = colpack.star "
"and colpack_prefix not in cmake command line."
);
# endif
}
else if(
coloring == "colpack.symmetric" ||
coloring == "colpack.star"
)
{
# if CPPAD_HAS_COLPACK
local::color_symmetric_colpack(internal_pattern, col, row, color);
# else
CPPAD_ASSERT_KNOWN(
false,
"sparse_hes: coloring = colpack.symmetic or colpack.star "
"and colpack_prefix not in cmake command line."
);
# endif
}
else CPPAD_ASSERT_KNOWN(
false,
"sparse_hes: coloring is not valid."
);
//
// put sorting indices in color order
SizeVector key(K);
order.resize(K);
for(size_t k = 0; k < K; k++)
key[k] = color[ col[k] ];
index_sort(key, order);
}
// Base versions of zero and one
Base one(1.0);
Base zero(0.0);
//
size_t n_color = 1;
for(size_t j = 0; j < n; j++) if( color[j] < n )
n_color = std::max(n_color, color[j] + 1);
//
// initialize the return Hessian values as zero
for(size_t k = 0; k < K; k++)
subset.set(k, zero);
//
// direction vector for calls to first order forward
BaseVector dx(n);
//
// return values for calls to second order reverse
BaseVector ddw(2 * n);
//
// loop over colors
size_t k = 0;
for(size_t ell = 0; ell < n_color; ell++)
if( k == K )
{ // kludge because colpack returns colors that are not used
// (it does not know about the subset corresponding to row, col)
CPPAD_ASSERT_UNKNOWN(
coloring == "colpack.general" ||
coloring == "colpack.symmetric" ||
coloring == "colpack.star"
);
}
else if( color[ col[ order[k] ] ] != ell )
{ // kludge because colpack returns colors that are not used
// (it does not know about the subset corresponding to row, col)
CPPAD_ASSERT_UNKNOWN(
coloring == "colpack.general" ||
coloring == "colpack.symmetic" ||
coloring == "colpack.star"
);
}
else
{ CPPAD_ASSERT_UNKNOWN( color[ col[ order[k] ] ] == ell );
//
// combine all columns with this color
for(size_t j = 0; j < n; j++)
{ dx[j] = zero;
if( color[j] == ell )
dx[j] = one;
}
// call forward mode for all these rows at once
Forward(1, dx);
//
// evaluate derivative of w^T * F'(x) * dx
ddw = Reverse(2, w);
//
// set the corresponding components of the result
while( k < K && color[ col[order[k]] ] == ell )
{ size_t index = row[ order[k] ] * 2 + 1;
subset.set(order[k], ddw[index] );
k++;
}
}
// check that all the required entries have been set
CPPAD_ASSERT_UNKNOWN( k == K );
return n_color;
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,861 +0,0 @@
# ifndef CPPAD_CORE_SPARSE_HESSIAN_HPP
# define CPPAD_CORE_SPARSE_HESSIAN_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 sparse_hessian$$
$spell
jacobian
recomputed
CppAD
valarray
std
Bool
hes
const
Taylor
cppad
cmake
colpack
$$
$section Sparse Hessian$$
$head Syntax$$
$icode%hes% = %f%.SparseHessian(%x%, %w%)
%hes% = %f%.SparseHessian(%x%, %w%, %p%)
%n_sweep% = %f%.SparseHessian(%x%, %w%, %p%, %row%, %col%, %hes%, %work%)
%$$
$head Purpose$$
We use $latex n$$ for the $cref/domain/seq_property/Domain/$$ size,
and $latex m$$ for the $cref/range/seq_property/Range/$$ size of $icode f$$.
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ do denote the
$cref/AD function/glossary/AD Function/$$
corresponding to $icode f$$.
The syntax above sets $icode hes$$ to the Hessian
$latex \[
H(x) = \dpow{2}{x} \sum_{i=1}^m w_i F_i (x)
\] $$
This routine takes advantage of the sparsity of the Hessian
in order to reduce the amount of computation necessary.
If $icode row$$ and $icode col$$ are present, it also takes
advantage of the reduced set of elements of the Hessian that
need to be computed.
One can use speed tests (e.g. $cref speed_test$$)
to verify that results are computed faster
than when using the routine $cref Hessian$$.
$head f$$
The object $icode f$$ has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the $cref ADFun$$ object $icode f$$ is not $code const$$
(see $cref/Uses Forward/sparse_hessian/Uses Forward/$$ below).
$head x$$
The argument $icode x$$ has prototype
$codei%
const %VectorBase%& %x%
%$$
(see $cref/VectorBase/sparse_hessian/VectorBase/$$ below)
and its size
must be equal to $icode n$$, the dimension of the
$cref/domain/seq_property/Domain/$$ space for $icode f$$.
It specifies
that point at which to evaluate the Hessian.
$head w$$
The argument $icode w$$ has prototype
$codei%
const %VectorBase%& %w%
%$$
and size $latex m$$.
It specifies the value of $latex w_i$$ in the expression
for $icode hes$$.
The more components of $latex w$$ that are identically zero,
the more sparse the resulting Hessian may be (and hence the more efficient
the calculation of $icode hes$$ may be).
$head p$$
The argument $icode p$$ is optional and has prototype
$codei%
const %VectorSet%& %p%
%$$
(see $cref/VectorSet/sparse_hessian/VectorSet/$$ below)
If it has elements of type $code bool$$,
its size is $latex n * n$$.
If it has elements of type $code std::set<size_t>$$,
its size is $latex n$$ and all its set elements are between
zero and $latex n - 1$$.
It specifies a
$cref/sparsity pattern/glossary/Sparsity Pattern/$$
for the Hessian $latex H(x)$$.
$subhead Purpose$$
If this sparsity pattern does not change between calls to
$codei SparseHessian$$, it should be faster to calculate $icode p$$ once and
pass this argument to $codei SparseHessian$$.
If you specify $icode p$$, CppAD will use the same
type of sparsity representation
(vectors of $code bool$$ or vectors of $code std::set<size_t>$$)
for its internal calculations.
Otherwise, the representation
for the internal calculations is unspecified.
$subhead work$$
If you specify $icode work$$ in the calling sequence,
it is not necessary to keep the sparsity pattern; see the heading
$cref/p/sparse_hessian/work/p/$$ under the $icode work$$ description.
$subhead Column Subset$$
If the arguments $icode row$$ and $icode col$$ are present,
and $cref/color_method/sparse_hessian/work/color_method/$$ is
$code cppad.general$$ or $code cppad.symmetric$$,
it is not necessary to compute the entire sparsity pattern.
Only the following subset of column values will matter:
$codei%
{ %col%[%k%] : %k% = 0 , %...% , %K%-1 }
%$$.
$head row, col$$
The arguments $icode row$$ and $icode col$$ are optional and have prototype
$codei%
const %VectorSize%& %row%
const %VectorSize%& %col%
%$$
(see $cref/VectorSize/sparse_hessian/VectorSize/$$ below).
They specify which rows and columns of $latex H (x)$$ are
returned and in what order.
We use $latex K$$ to denote the value $icode%hes%.size()%$$
which must also equal the size of $icode row$$ and $icode col$$.
Furthermore,
for $latex k = 0 , \ldots , K-1$$, it must hold that
$latex row[k] < n$$ and $latex col[k] < n$$.
In addition,
all of the $latex (row[k], col[k])$$ pairs must correspond to a true value
in the sparsity pattern $icode p$$.
$head hes$$
The result $icode hes$$ has prototype
$codei%
%VectorBase% %hes%
%$$
In the case where $icode row$$ and $icode col$$ are not present,
the size of $icode hes$$ is $latex n * n$$ and
its size is $latex n * n$$.
In this case, for $latex i = 0 , \ldots , n - 1 $$
and $latex ell = 0 , \ldots , n - 1$$
$latex \[
hes [ j * n + \ell ] = \DD{ w^{\rm T} F }{ x_j }{ x_\ell } ( x )
\] $$
$pre
$$
In the case where the arguments $icode row$$ and $icode col$$ are present,
we use $latex K$$ to denote the size of $icode hes$$.
The input value of its elements does not matter.
Upon return, for $latex k = 0 , \ldots , K - 1$$,
$latex \[
hes [ k ] = \DD{ w^{\rm T} F }{ x_j }{ x_\ell } (x)
\; , \;
\; {\rm where} \;
j = row[k]
\; {\rm and } \;
\ell = col[k]
\] $$
$head work$$
If this argument is present, it has prototype
$codei%
sparse_hessian_work& %work%
%$$
This object can only be used with the routines $code SparseHessian$$.
During its the first use, information is stored in $icode work$$.
This is used to reduce the work done by future calls to $code SparseHessian$$
with the same $icode f$$, $icode p$$, $icode row$$, and $icode col$$.
If a future call is made where any of these values have changed,
you must first call $icode%work%.clear()%$$
to inform CppAD that this information needs to be recomputed.
$subhead color_method$$
The coloring algorithm determines which rows and columns
can be computed during the same sweep.
This field has prototype
$codei%
std::string %work%.color_method
%$$
This value only matters on the first call to $code sparse_hessian$$ that
follows the $icode work$$ constructor or a call to
$icode%work%.clear()%$$.
$codei%
"cppad.symmetric"
%$$
This is the default coloring method (after a constructor or $code clear()$$).
It takes advantage of the fact that the Hessian matrix
is symmetric to find a coloring that requires fewer
$cref/sweeps/sparse_hessian/n_sweep/$$.
$codei%
"cppad.general"
%$$
This is the same as the $code "cppad"$$ method for the
$cref/sparse_jacobian/sparse_jacobian/work/color_method/$$ calculation.
$codei%
"colpack.symmetric"
%$$
This method requires that
$cref colpack_prefix$$ was specified on the
$cref/cmake command/cmake/CMake Command/$$ line.
It also takes advantage of the fact that the Hessian matrix is symmetric.
$codei%
"colpack.general"
%$$
This is the same as the $code "colpack"$$ method for the
$cref/sparse_jacobian/sparse_jacobian/work/color_method/$$ calculation.
$subhead colpack.star Deprecated 2017-06-01$$
The $code colpack.star$$ method is deprecated.
It is the same as the $code colpack.symmetric$$
which should be used instead.
$subhead p$$
If $icode work$$ is present, and it is not the first call after
its construction or a clear,
the sparsity pattern $icode p$$ is not used.
This enables one to free the sparsity pattern
and still compute corresponding sparse Hessians.
$head n_sweep$$
The return value $icode n_sweep$$ has prototype
$codei%
size_t %n_sweep%
%$$
It is the number of first order forward sweeps
used to compute the requested Hessian values.
Each first forward sweep is followed by a second order reverse sweep
so it is also the number of reverse sweeps.
This is proportional to the total work that $code SparseHessian$$ does,
not counting the zero order forward sweep,
or the work to combine multiple columns into a single
forward-reverse sweep pair.
$head VectorBase$$
The type $icode VectorBase$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$icode Base$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head VectorSet$$
The type $icode VectorSet$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code bool$$ or $code std::set<size_t>$$;
see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion
of the difference.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$subhead Restrictions$$
If $icode VectorSet$$ has elements of $code std::set<size_t>$$,
then $icode%p%[%i%]%$$ must return a reference (not a copy) to the
corresponding set.
According to section 26.3.2.3 of the 1998 C++ standard,
$code std::valarray< std::set<size_t> >$$ does not satisfy
this condition.
$head VectorSize$$
The type $icode VectorSize$$ must be a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
The routine $cref CheckSimpleVector$$ will generate an error message
if this is not the case.
$head Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to any of the sparse Hessian routines,
the zero order Taylor coefficients correspond to
$icode%f%.Forward(0, %x%)%$$
and the other coefficients are unspecified.
$children%
example/sparse/sparse_hessian.cpp%
example/sparse/sub_sparse_hes.cpp%
example/sparse/sparse_sub_hes.cpp
%$$
$head Example$$
The routine
$cref sparse_hessian.cpp$$
is examples and tests of $code sparse_hessian$$.
It return $code true$$, if it succeeds and $code false$$ otherwise.
$head Subset Hessian$$
The routine
$cref sub_sparse_hes.cpp$$
is an example and test that compute a sparse Hessian
for a subset of the variables.
It returns $code true$$, for success, and $code false$$ otherwise.
$end
-----------------------------------------------------------------------------
*/
# include <cppad/local/std_set.hpp>
# include <cppad/local/color_general.hpp>
# include <cppad/local/color_symmetric.hpp>
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
\file sparse_hessian.hpp
Sparse Hessian driver routine and helper functions.
*/
// ===========================================================================
/*!
class used by SparseHessian to hold information
so it does not need to be recomputed.
*/
class sparse_hessian_work {
public:
/// Coloring method: "cppad", or "colpack"
/// (this field is set by user)
std::string color_method;
/// row and column indicies for return values
/// (some may be reflected by star coloring algorithm)
CppAD::vector<size_t> row;
CppAD::vector<size_t> col;
/// indices that sort the user row and col arrays by color
CppAD::vector<size_t> order;
/// results of the coloring algorithm
CppAD::vector<size_t> color;
/// constructor
sparse_hessian_work(void) : color_method("cppad.symmetric")
{ }
/// inform CppAD that this information needs to be recomputed
void clear(void)
{ color_method = "cppad.symmetric";
row.clear();
col.clear();
order.clear();
color.clear();
}
};
// ===========================================================================
/*!
Private helper function that does computation for all Sparse Hessian cases.
\tparam Base
is the base type for the recording that is stored in this ADFun<Base object.
\tparam VectorBase
is a simple vector class with elements of type \a Base.
\tparam VectorSet
is a simple vector class with elements of type
\c bool or \c std::set<size_t>.
\tparam VectorSize
is sparse_pack or sparse_list.
\param x [in]
is a vector specifing the point at which to compute the Hessian.
\param w [in]
is the weighting vector that defines a scalar valued function by
a weighted sum of the components of the vector valued function
$latex F(x)$$.
\param sparsity [in]
is the sparsity pattern for the Hessian that we are calculating.
\param user_row [in]
is the vector of row indices for the returned Hessian values.
\param user_col [in]
is the vector of columns indices for the returned Hessian values.
It must have the same size as user_row.
\param hes [out]
is the vector of Hessian values.
It must have the same size as user_row.
The return value <code>hes[k]</code> is the second partial of
\f$ w^{\rm T} F(x)\f$ with respect to the
<code>row[k]</code> and <code>col[k]</code> component of \f$ x\f$.
\param work
This structure contains information that is computed by \c SparseHessianCompute.
If the sparsity pattern, \c row vector, or \c col vectors
are not the same between calls to \c SparseHessianCompute,
\c work.clear() must be called to reinitialize \c work.
\return
Is the number of first order forward sweeps used to compute the
requested Hessian values.
(This is also equal to the number of second order reverse sweeps.)
The total work, not counting the zero order
forward sweep, or the time to combine computations, is proportional to this
return value.
*/
template<class Base>
template <class VectorBase, class VectorSet, class VectorSize>
size_t ADFun<Base>::SparseHessianCompute(
const VectorBase& x ,
const VectorBase& w ,
VectorSet& sparsity ,
const VectorSize& user_row ,
const VectorSize& user_col ,
VectorBase& hes ,
sparse_hessian_work& work )
{
using CppAD::vectorBool;
size_t i, k, ell;
CppAD::vector<size_t>& row(work.row);
CppAD::vector<size_t>& col(work.col);
CppAD::vector<size_t>& color(work.color);
CppAD::vector<size_t>& order(work.order);
size_t n = Domain();
// some values
const Base zero(0);
const Base one(1);
// check VectorBase is Simple Vector class with Base type elements
CheckSimpleVector<Base, VectorBase>();
// number of components of Hessian that are required
size_t K = hes.size();
CPPAD_ASSERT_UNKNOWN( size_t( user_row.size() ) == K );
CPPAD_ASSERT_UNKNOWN( size_t( user_col.size() ) == K );
CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n );
CPPAD_ASSERT_UNKNOWN( color.size() == 0 || color.size() == n );
CPPAD_ASSERT_UNKNOWN( row.size() == 0 || row.size() == K );
CPPAD_ASSERT_UNKNOWN( col.size() == 0 || col.size() == K );
// Point at which we are evaluating the Hessian
Forward(0, x);
// check for case where nothing (except Forward above) to do
if( K == 0 )
return 0;
// Rows of the Hessian (i below) correspond to the forward mode index
// and columns (j below) correspond to the reverse mode index.
if( color.size() == 0 )
{
CPPAD_ASSERT_UNKNOWN( sparsity.n_set() == n );
CPPAD_ASSERT_UNKNOWN( sparsity.end() == n );
// copy user rwo and col to work space
row.resize(K);
col.resize(K);
for(k = 0; k < K; k++)
{ row[k] = user_row[k];
col[k] = user_col[k];
}
// execute coloring algorithm
color.resize(n);
if( work.color_method == "cppad.general" )
local::color_general_cppad(sparsity, row, col, color);
else if( work.color_method == "cppad.symmetric" )
local::color_symmetric_cppad(sparsity, row, col, color);
else if( work.color_method == "colpack.general" )
{
# if CPPAD_HAS_COLPACK
local::color_general_colpack(sparsity, row, col, color);
# else
CPPAD_ASSERT_KNOWN(
false,
"SparseHessian: work.color_method = colpack.general "
"and colpack_prefix missing from cmake command line."
);
# endif
}
else if(
work.color_method == "colpack.symmetric" ||
work.color_method == "colpack.star"
)
{
# if CPPAD_HAS_COLPACK
local::color_symmetric_colpack(sparsity, row, col, color);
# else
CPPAD_ASSERT_KNOWN(
false,
"SparseHessian: work.color_method is "
"colpack.symmetric or colpack.star\n"
"and colpack_prefix missing from cmake command line."
);
# endif
}
else
{ CPPAD_ASSERT_KNOWN(
false,
"SparseHessian: work.color_method is not valid."
);
}
// put sorting indices in color order
VectorSize key(K);
order.resize(K);
for(k = 0; k < K; k++)
key[k] = color[ row[k] ];
index_sort(key, order);
}
size_t n_color = 1;
for(ell = 0; ell < n; ell++) if( color[ell] < n )
n_color = std::max(n_color, color[ell] + 1);
// direction vector for calls to forward (rows of the Hessian)
VectorBase u(n);
// location for return values from reverse (columns of the Hessian)
VectorBase ddw(2 * n);
// initialize the return value
for(k = 0; k < K; k++)
hes[k] = zero;
// loop over colors
# ifndef NDEBUG
const std::string& coloring = work.color_method;
# endif
k = 0;
for(ell = 0; ell < n_color; ell++)
if( k == K )
{ // kludge because colpack returns colors that are not used
// (it does not know about the subset corresponding to row, col)
CPPAD_ASSERT_UNKNOWN(
coloring == "colpack.general" ||
coloring == "colpack.symmetic" ||
coloring == "colpack.star"
);
}
else if( color[ row[ order[k] ] ] != ell )
{ // kludge because colpack returns colors that are not used
// (it does not know about the subset corresponding to row, col)
CPPAD_ASSERT_UNKNOWN(
coloring == "colpack.general" ||
coloring == "colpack.symmetic" ||
coloring == "colpack.star"
);
}
else
{ CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell );
// combine all rows with this color
for(i = 0; i < n; i++)
{ u[i] = zero;
if( color[i] == ell )
u[i] = one;
}
// call forward mode for all these rows at once
Forward(1, u);
// evaluate derivative of w^T * F'(x) * u
ddw = Reverse(2, w);
// set the corresponding components of the result
while( k < K && color[ row[ order[k] ] ] == ell )
{ hes[ order[k] ] = ddw[ col[ order[k] ] * 2 + 1 ];
k++;
}
}
return n_color;
}
// ===========================================================================
// Public Member Functions
// ===========================================================================
/*!
Compute user specified subset of a sparse Hessian.
The C++ source code corresponding to this operation is
\verbatim
SparceHessian(x, w, p, row, col, hes, work)
\endverbatim
\tparam Base
is the base type for the recording that is stored in this ADFun<Base object.
\tparam VectorBase
is a simple vector class with elements of type \a Base.
\tparam VectorSet
is a simple vector class with elements of type
\c bool or \c std::set<size_t>.
\tparam VectorSize
is a simple vector class with elements of type \c size_t.
\param x [in]
is a vector specifing the point at which to compute the Hessian.
\param w [in]
is the weighting vector that defines a scalar valued function by
a weighted sum of the components of the vector valued function
$latex F(x)$$.
\param p [in]
is the sparsity pattern for the Hessian that we are calculating.
\param row [in]
is the vector of row indices for the returned Hessian values.
\param col [in]
is the vector of columns indices for the returned Hessian values.
It must have the same size are r.
\param hes [out]
is the vector of Hessian values.
It must have the same size are r.
The return value <code>hes[k]</code> is the second partial of
\f$ w^{\rm T} F(x)\f$ with respect to the
<code>row[k]</code> and <code>col[k]</code> component of \f$ x\f$.
\param work
This structure contains information that is computed by \c SparseHessianCompute.
If the sparsity pattern, \c row vector, or \c col vectors
are not the same between calls to \c SparseHessian,
\c work.clear() must be called to reinitialize \c work.
\return
Is the number of first order forward sweeps used to compute the
requested Hessian values.
(This is also equal to the number of second order reverse sweeps.)
The total work, not counting the zero order
forward sweep, or the time to combine computations, is proportional to this
return value.
*/
template<class Base>
template <class VectorBase, class VectorSet, class VectorSize>
size_t ADFun<Base>::SparseHessian(
const VectorBase& x ,
const VectorBase& w ,
const VectorSet& p ,
const VectorSize& row ,
const VectorSize& col ,
VectorBase& hes ,
sparse_hessian_work& work )
{
size_t n = Domain();
size_t K = hes.size();
# ifndef NDEBUG
size_t k;
CPPAD_ASSERT_KNOWN(
size_t(x.size()) == n ,
"SparseHessian: size of x not equal domain dimension for f."
);
CPPAD_ASSERT_KNOWN(
size_t(row.size()) == K && size_t(col.size()) == K ,
"SparseHessian: either r or c does not have the same size as ehs."
);
CPPAD_ASSERT_KNOWN(
work.color.size() == 0 || work.color.size() == n,
"SparseHessian: invalid value in work."
);
for(k = 0; k < K; k++)
{ CPPAD_ASSERT_KNOWN(
row[k] < n,
"SparseHessian: invalid value in r."
);
CPPAD_ASSERT_KNOWN(
col[k] < n,
"SparseHessian: invalid value in c."
);
}
if( work.color.size() != 0 )
for(size_t j = 0; j < n; j++) CPPAD_ASSERT_KNOWN(
work.color[j] <= n,
"SparseHessian: invalid value in work."
);
# endif
// check for case where there is nothing to compute
size_t n_sweep = 0;
if( K == 0 )
return n_sweep;
typedef typename VectorSet::value_type Set_type;
typedef typename local::internal_sparsity<Set_type>::pattern_type Pattern_type;
Pattern_type s;
if( work.color.size() == 0 )
{ bool transpose = false;
const char* error_msg = "SparseHessian: sparsity pattern"
" does not have proper row or column dimension";
sparsity_user2internal(s, p, n, n, transpose, error_msg);
}
n_sweep = SparseHessianCompute(x, w, s, row, col, hes, work);
return n_sweep;
}
/*!
Compute a sparse Hessian.
The C++ source code coresponding to this operation is
\verbatim
hes = SparseHessian(x, w, p)
\endverbatim
\tparam Base
is the base type for the recording that is stored in this
ADFun<Base object.
\tparam VectorBase
is a simple vector class with elements of the \a Base.
\tparam VectorSet
is a simple vector class with elements of type
\c bool or \c std::set<size_t>.
\param x [in]
is a vector specifing the point at which to compute the Hessian.
\param w [in]
The Hessian is computed for a weighted sum of the components
of the function corresponding to this ADFun<Base> object.
The argument \a w specifies the weights for each component.
It must have size equal to the range dimension for this ADFun<Base> object.
\param p [in]
is a sparsity pattern for the Hessian.
\return
Will be a vector of size \c n * n containing the Hessian of
at the point specified by \a x
(where \c n is the domain dimension for this ADFun<Base> object).
*/
template <class Base>
template <class VectorBase, class VectorSet>
VectorBase ADFun<Base>::SparseHessian(
const VectorBase& x, const VectorBase& w, const VectorSet& p
)
{ size_t i, j, k;
size_t n = Domain();
VectorBase hes(n * n);
CPPAD_ASSERT_KNOWN(
size_t(x.size()) == n,
"SparseHessian: size of x not equal domain size for f."
);
typedef typename VectorSet::value_type Set_type;
typedef typename local::internal_sparsity<Set_type>::pattern_type Pattern_type;
// initialize the return value as zero
Base zero(0);
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
hes[i * n + j] = zero;
// arguments to SparseHessianCompute
Pattern_type s;
CppAD::vector<size_t> row;
CppAD::vector<size_t> col;
sparse_hessian_work work;
bool transpose = false;
const char* error_msg = "SparseHessian: sparsity pattern"
" does not have proper row or column dimension";
sparsity_user2internal(s, p, n, n, transpose, error_msg);
k = 0;
for(i = 0; i < n; i++)
{ typename Pattern_type::const_iterator itr(s, i);
j = *itr;
while( j != s.end() )
{ row.push_back(i);
col.push_back(j);
k++;
j = *(++itr);
}
}
size_t K = k;
VectorBase H(K);
// now we have folded this into the following case
SparseHessianCompute(x, w, s, row, col, H, work);
// now set the non-zero return values
for(k = 0; k < K; k++)
hes[ row[k] * n + col[k] ] = H[k];
return hes;
}
/*!
Compute a sparse Hessian
The C++ source code coresponding to this operation is
\verbatim
hes = SparseHessian(x, w)
\endverbatim
\tparam Base
is the base type for the recording that is stored in this
ADFun<Base object.
\tparam VectorBase
is a simple vector class with elements of the \a Base.
\param x [in]
is a vector specifing the point at which to compute the Hessian.
\param w [in]
The Hessian is computed for a weighted sum of the components
of the function corresponding to this ADFun<Base> object.
The argument \a w specifies the weights for each component.
It must have size equal to the range dimension for this ADFun<Base> object.
\return
Will be a vector of size \c n * n containing the Hessian of
at the point specified by \a x
(where \c n is the domain dimension for this ADFun<Base> object).
*/
template <class Base>
template <class VectorBase>
VectorBase ADFun<Base>::SparseHessian(const VectorBase &x, const VectorBase &w)
{ size_t i, j, k;
typedef CppAD::vectorBool VectorBool;
size_t m = Range();
size_t n = Domain();
// determine the sparsity pattern p for Hessian of w^T F
VectorBool r(n * n);
for(j = 0; j < n; j++)
{ for(k = 0; k < n; k++)
r[j * n + k] = false;
r[j * n + j] = true;
}
ForSparseJac(n, r);
//
VectorBool s(m);
for(i = 0; i < m; i++)
s[i] = w[i] != 0;
VectorBool p = RevSparseHes(n, s);
// compute sparse Hessian
return SparseHessian(x, w, p);
}
} // END_CPPAD_NAMESPACE
# endif

View File

@ -1,623 +0,0 @@
# ifndef CPPAD_CORE_SPARSE_JAC_HPP
# define CPPAD_CORE_SPARSE_JAC_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 sparse_jac$$
$spell
Jacobian
Jacobians
const
jac
Taylor
rc
rcv
nr
nc
std
Cppad
Colpack
cmake
$$
$section Computing Sparse Jacobians$$
$head Syntax$$
$icode%n_sweep% = %f%.sparse_jac_for(
%group_max%, %x%, %subset%, %pattern%, %coloring%, %work%
)
%$$
$icode%n_sweep% = %f%.sparse_jac_rev(
%x%, %subset%, %pattern%, %coloring%, %work%
)%$$
$head Purpose$$
We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the
function corresponding to $icode f$$.
Here $icode n$$ is the $cref/domain/seq_property/Domain/$$ size,
and $icode m$$ is the $cref/range/seq_property/Range/$$ size, or $icode f$$.
The syntax above takes advantage of sparsity when computing the Jacobian
$latex \[
J(x) = F^{(1)} (x)
\] $$
In the sparse case, this should be faster and take less memory than
$cref Jacobian$$.
We use the notation $latex J_{i,j} (x)$$ to denote the partial of
$latex F_i (x)$$ with respect to $latex x_j$$.
$head SizeVector$$
The type $icode SizeVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head BaseVector$$
The type $icode BaseVector$$ is a $cref SimpleVector$$ class with
$cref/elements of type/SimpleVector/Elements of Specified Type/$$
$code size_t$$.
$head sparse_jac_for$$
This function uses first order forward mode sweeps $cref forward_one$$
to compute multiple columns of the Jacobian at the same time.
$head sparse_jac_rev$$
This uses function first order reverse mode sweeps $cref reverse_one$$
to compute multiple rows of the Jacobian at the same time.
$head f$$
This object has prototype
$codei%
ADFun<%Base%> %f%
%$$
Note that the Taylor coefficients stored in $icode f$$ are affected
by this operation; see
$cref/uses forward/sparse_jac/Uses Forward/$$ below.
$head group_max$$
This argument has prototype
$codei%
size_t %group_max%
%$$
and must be greater than zero.
It specifies the maximum number of colors to group during
a single forward sweep.
If a single color is in a group,
a single direction for of first order forward mode
$cref forward_one$$ is used for each color.
If multiple colors are in a group,
the multiple direction for of first order forward mode
$cref forward_dir$$ is used with one direction for each color.
This uses separate memory for each direction (more memory),
but my be significantly faster.
$head x$$
This argument has prototype
$codei%
const %BaseVector%& %x%
%$$
and its size is $icode n$$.
It specifies the point at which to evaluate the Jacobian
$latex J(x)$$.
$head subset$$
This argument has prototype
$codei%
sparse_rcv<%SizeVector%, %BaseVector%>& %subset%
%$$
Its row size is $icode%subset%.nr() == %m%$$,
and its column size is $icode%subset%.nc() == %n%$$.
It specifies which elements of the Jacobian are computed.
The input value of its value vector
$icode%subset%.val()%$$ does not matter.
Upon return it contains the value of the corresponding elements
of the Jacobian.
All of the row, column pairs in $icode subset$$ must also appear in
$icode pattern$$; i.e., they must be possibly non-zero.
$head pattern$$
This argument has prototype
$codei%
const sparse_rc<%SizeVector%>& %pattern%
%$$
Its row size is $icode%pattern%.nr() == %m%$$,
and its column size is $icode%pattern%.nc() == %n%$$.
It is a sparsity pattern for the Jacobian $latex J(x)$$.
This argument is not used (and need not satisfy any conditions),
when $cref/work/sparse_jac/work/$$ is non-empty.
$head coloring$$
The coloring algorithm determines which rows (reverse) or columns (forward)
can be computed during the same sweep.
This field has prototype
$codei%
const std::string& %coloring%
%$$
This value only matters when work is empty; i.e.,
after the $icode work$$ constructor or $icode%work%.clear()%$$.
$subhead cppad$$
This uses a general purpose coloring algorithm written for Cppad.
$subhead colpack$$
If $cref colpack_prefix$$ is specified on the
$cref/cmake command/cmake/CMake Command/$$ line,
you can set $icode coloring$$ to $code colpack$$.
This uses a general purpose coloring algorithm that is part of Colpack.
$head work$$
This argument has prototype
$codei%
sparse_jac_work& %work%
%$$
We refer to its initial value,
and its value after $icode%work%.clear()%$$, as empty.
If it is empty, information is stored in $icode work$$.
This can be used to reduce computation when
a future call is for the same object $icode f$$,
the same member function $code sparse_jac_for$$ or $code sparse_jac_rev$$,
and the same subset of the Jacobian.
If any of these values change, use $icode%work%.clear()%$$ to
empty this structure.
$head n_sweep$$
The return value $icode n_sweep$$ has prototype
$codei%
size_t %n_sweep%
%$$
If $code sparse_jac_for$$ ($code sparse_jac_rev$$) is used,
$icode n_sweep$$ is the number of first order forward (reverse) sweeps
used to compute the requested Jacobian values.
It is also the number of colors determined by the coloring method
mentioned above.
This is proportional to the total computational work,
not counting the zero order forward sweep,
or combining multiple columns (rows) into a single sweep.
$head Uses Forward$$
After each call to $cref Forward$$,
the object $icode f$$ contains the corresponding
$cref/Taylor coefficients/glossary/Taylor Coefficient/$$.
After a call to $code sparse_jac_forward$$ or $code sparse_jac_rev$$,
the zero order coefficients correspond to
$codei%
%f%.Forward(0, %x%)
%$$
All the other forward mode coefficients are unspecified.
$head Example$$
$children%
example/sparse/sparse_jac_for.cpp%
example/sparse/sparse_jac_rev.cpp
%$$
The files $cref sparse_jac_for.cpp$$ and $cref sparse_jac_rev.cpp$$
are examples and tests of $code sparse_jac_for$$ and $code sparse_jac_rev$$.
They return $code true$$, if they succeed, and $code false$$ otherwise.
$end
*/
# include <cppad/core/cppad_assert.hpp>
# include <cppad/local/sparse_internal.hpp>
# include <cppad/local/color_general.hpp>
# include <cppad/utility/vector.hpp>
/*!
\file sparse_jac.hpp
Sparse Jacobian calculation routines.
*/
namespace CppAD { // BEGIN_CPPAD_NAMESPACE
/*!
Class used to hold information used by Sparse Jacobian routines in this file,
so they do not need to be recomputed every time.
*/
class sparse_jac_work {
public:
/// indices that sort the user row and col arrays by color
CppAD::vector<size_t> order;
/// results of the coloring algorithm
CppAD::vector<size_t> color;
//
/// constructor
sparse_jac_work(void)
{ }
/// reset work to empty.
/// This informs CppAD that color and order need to be recomputed
void clear(void)
{ order.clear();
color.clear();
}
};
// ----------------------------------------------------------------------------
/*!
Calculate sparse Jacobains using forward mode
\tparam Base
the base type for the recording that is stored in the ADFun object.
\tparam SizeVector
a simple vector class with elements of type size_t.
\tparam BaseVector
a simple vector class with elements of type Base.
\param group_max
specifies the maximum number of colors to group during a single forward sweep.
This must be greater than zero and group_max = 1 minimizes memory usage.
\param x
a vector of length n, the number of independent variables in f
(this ADFun object).
\param subset
specifices the subset of the sparsity pattern where the Jacobian is evaluated.
subset.nr() == m,
subset.nc() == n.
\param pattern
is a sparsity pattern for the Jacobian of f;
pattern.nr() == m,
pattern.nc() == n,
where m is number of dependent variables in f.
\param coloring
determines which coloring algorithm is used.
This must be cppad or colpack.
\param work
this structure must be empty, or contain the information stored
by a previous call to sparse_jac_for.
The previous call must be for the same ADFun object f
and the same subset.
\return
This is the number of first order forward sweeps used to compute
the Jacobian.
*/
template <class Base>
template <class SizeVector, class BaseVector>
size_t ADFun<Base>::sparse_jac_for(
size_t group_max ,
const BaseVector& x ,
sparse_rcv<SizeVector, BaseVector>& subset ,
const sparse_rc<SizeVector>& pattern ,
const std::string& coloring ,
sparse_jac_work& work )
{ size_t m = Range();
size_t n = Domain();
//
CPPAD_ASSERT_KNOWN(
subset.nr() == m,
"sparse_jac_for: subset.nr() not equal range dimension for f"
);
CPPAD_ASSERT_KNOWN(
subset.nc() == n,
"sparse_jac_for: subset.nc() not equal domain dimension for f"
);
//
// row and column vectors in subset
const SizeVector& row( subset.row() );
const SizeVector& col( subset.col() );
//
vector<size_t>& color(work.color);
vector<size_t>& order(work.order);
CPPAD_ASSERT_KNOWN(
color.size() == 0 || color.size() == n,
"sparse_jac_for: work is non-empty and conditions have changed"
);
//
// point at which we are evaluationg the Jacobian
Forward(0, x);
//
// number of elements in the subset
size_t K = subset.nnz();
//
// check for case were there is nothing to do
// (except for call to Forward(0, x)
if( K == 0 )
return 0;
//
// check for case where input work is empty
if( color.size() == 0 )
{ // compute work color and order vectors
CPPAD_ASSERT_KNOWN(
pattern.nr() == m,
"sparse_jac_for: pattern.nr() not equal range dimension for f"
);
CPPAD_ASSERT_KNOWN(
pattern.nc() == n,
"sparse_jac_for: pattern.nc() not equal domain dimension for f"
);
//
// convert pattern to an internal version of its transpose
vector<size_t> internal_index(n);
for(size_t j = 0; j < n; j++)
internal_index[j] = j;
bool transpose = true;
bool zero_empty = false;
bool input_empty = true;
local::sparse_list pattern_transpose;
pattern_transpose.resize(n, m);
local::set_internal_sparsity(zero_empty, input_empty,
transpose, internal_index, pattern_transpose, pattern
);
//
// execute coloring algorithm
// (we are using transpose because coloring groups rows, not columns).
color.resize(n);
if( coloring == "cppad" )
local::color_general_cppad(pattern_transpose, col, row, color);
else if( coloring == "colpack" )
{
# if CPPAD_HAS_COLPACK
local::color_general_colpack(pattern_transpose, col, row, color);
# else
CPPAD_ASSERT_KNOWN(
false,
"sparse_jac_for: coloring = colpack "
"and colpack_prefix missing from cmake command line."
);
# endif
}
else CPPAD_ASSERT_KNOWN(
false,
"sparse_jac_for: coloring is not valid."
);
//
// put sorting indices in color order
SizeVector key(K);
order.resize(K);
for(size_t k = 0; k < K; k++)
key[k] = color[ col[k] ];
index_sort(key, order);
}
// Base versions of zero and one
Base one(1.0);
Base zero(0.0);
//
size_t n_color = 1;
for(size_t j = 0; j < n; j++) if( color[j] < n )
n_color = std::max(n_color, color[j] + 1);
//
// initialize the return Jacobian values as zero
for(size_t k = 0; k < K; k++)
subset.set(k, zero);
//
// index in subset
size_t k = 0;
// number of colors computed so far
size_t color_count = 0;
//
while( color_count < n_color )
{ // number of colors that will be in this group
size_t group_size = std::min(group_max, n_color - color_count);
//
// forward mode values for independent and dependent variables
BaseVector dx(n * group_size), dy(m * group_size);
//
// set dx
for(size_t ell = 0; ell < group_size; ell++)
{ // combine all columns with this color
for(size_t j = 0; j < n; j++)
{ dx[j * group_size + ell] = zero;
if( color[j] == ell + color_count )
dx[j * group_size + ell] = one;
}
}
if( group_size == 1 )
dy = Forward(1, dx);
else
dy = Forward(1, group_size, dx);
//
// store results in subset
for(size_t ell = 0; ell < group_size; ell++)
{ // color with index ell + color_count is in this group
while(k < K && color[ col[ order[k] ] ] == ell + color_count )
{ // subset element with index order[k] is included in this color
size_t r = row[ order[k] ];
subset.set( order[k], dy[ r * group_size + ell ] );
++k;
}
}
// advance color count
color_count += group_size;
}
CPPAD_ASSERT_UNKNOWN( color_count == n_color );
//
return n_color;
}
// ----------------------------------------------------------------------------
/*!
Calculate sparse Jacobains using reverse mode
\tparam Base
the base type for the recording that is stored in the ADFun object.
\tparam SizeVector
a simple vector class with elements of type size_t.
\tparam BaseVector
a simple vector class with elements of type Base.
\param x
a vector of length n, the number of independent variables in f
(this ADFun object).
\param subset
specifices the subset of the sparsity pattern where the Jacobian is evaluated.
subset.nr() == m,
subset.nc() == n.
\param pattern
is a sparsity pattern for the Jacobian of f;
pattern.nr() == m,
pattern.nc() == n,
where m is number of dependent variables in f.
\param coloring
determines which coloring algorithm is used.
This must be cppad or colpack.
\param work
this structure must be empty, or contain the information stored
by a previous call to sparse_jac_rev.
The previous call must be for the same ADFun object f
and the same subset.
\return
This is the number of first order reverse sweeps used to compute
the Jacobian.
*/
template <class Base>
template <class SizeVector, class BaseVector>
size_t ADFun<Base>::sparse_jac_rev(
const BaseVector& x ,
sparse_rcv<SizeVector, BaseVector>& subset ,
const sparse_rc<SizeVector>& pattern ,
const std::string& coloring ,
sparse_jac_work& work )
{ size_t m = Range();
size_t n = Domain();
//
CPPAD_ASSERT_KNOWN(
subset.nr() == m,
"sparse_jac_rev: subset.nr() not equal range dimension for f"
);
CPPAD_ASSERT_KNOWN(
subset.nc() == n,
"sparse_jac_rev: subset.nc() not equal domain dimension for f"
);
//
// row and column vectors in subset
const SizeVector& row( subset.row() );
const SizeVector& col( subset.col() );
//
vector<size_t>& color(work.color);
vector<size_t>& order(work.order);
CPPAD_ASSERT_KNOWN(
color.size() == 0 || color.size() == m,
"sparse_jac_rev: work is non-empty and conditions have changed"
);
//
// point at which we are evaluationg the Jacobian
Forward(0, x);
//
// number of elements in the subset
size_t K = subset.nnz();
//
// check for case were there is nothing to do
// (except for call to Forward(0, x)
if( K == 0 )
return 0;
//
// check for case where input work is empty
if( color.size() == 0 )
{ // compute work color and order vectors
CPPAD_ASSERT_KNOWN(
pattern.nr() == m,
"sparse_jac_rev: pattern.nr() not equal range dimension for f"
);
CPPAD_ASSERT_KNOWN(
pattern.nc() == n,
"sparse_jac_rev: pattern.nc() not equal domain dimension for f"
);
//
// convert pattern to an internal version
vector<size_t> internal_index(m);
for(size_t i = 0; i < m; i++)
internal_index[i] = i;
bool transpose = false;
bool zero_empty = false;
bool input_empty = true;
local::sparse_list internal_pattern;
internal_pattern.resize(m, n);
local::set_internal_sparsity(zero_empty, input_empty,
transpose, internal_index, internal_pattern, pattern
);
//
// execute coloring algorithm
color.resize(m);
if( coloring == "cppad" )
local::color_general_cppad(internal_pattern, row, col, color);
else if( coloring == "colpack" )
{
# if CPPAD_HAS_COLPACK
local::color_general_colpack(internal_pattern, row, col, color);
# else
CPPAD_ASSERT_KNOWN(
false,
"sparse_jac_rev: coloring = colpack "
"and colpack_prefix missing from cmake command line."
);
# endif
}
else CPPAD_ASSERT_KNOWN(
false,
"sparse_jac_rev: coloring is not valid."
);
//
// put sorting indices in color order
SizeVector key(K);
order.resize(K);
for(size_t k = 0; k < K; k++)
key[k] = color[ row[k] ];
index_sort(key, order);
}
// Base versions of zero and one
Base one(1.0);
Base zero(0.0);
//
size_t n_color = 1;
for(size_t i = 0; i < m; i++) if( color[i] < m )
n_color = std::max(n_color, color[i] + 1);
//
// initialize the return Jacobian values as zero
for(size_t k = 0; k < K; k++)
subset.set(k, zero);
//
// weighting vector and return values for calls to Reverse
BaseVector w(m), dw(n);
//
// loop over colors
size_t k = 0;
for(size_t ell = 0; ell < n_color; ell++)
if( k == K )
{ // kludge because colpack returns colors that are not used
// (it does not know about the subset corresponding to row, col)
CPPAD_ASSERT_UNKNOWN( coloring == "colpack" );
}
else if( color[ row[ order[k] ] ] != ell )
{ // kludge because colpack returns colors that are not used
// (it does not know about the subset corresponding to row, col)
CPPAD_ASSERT_UNKNOWN( coloring == "colpack" );
}
else
{ CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell );
//
// combine all rows with this color
for(size_t i = 0; i < m; i++)
{ w[i] = zero;
if( color[i] == ell )
w[i] = one;
}
// call reverse mode for all these rows at once
dw = Reverse(1, w);
//
// set the corresponding components of the result
while( k < K && color[ row[order[k]] ] == ell )
{ subset.set(order[k], dw[col[order[k]]] );
k++;
}
}
return n_color;
}
} // END_CPPAD_NAMESPACE
# endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More