parent
4b12aca941
commit
b541f59094
363 changed files with 0 additions and 100873 deletions
@ -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" "$@" |
@ -1 +0,0 @@ |
||||
apktool_2.3.0.jar |
Binary file not shown.
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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
|
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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
|
@ -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 |
@ -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
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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
|
@ -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
|
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
||||
|
@ -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 |
@ -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
|
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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
@ -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 |
@ -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 |
@ -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 |
@ -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 |
||||
|
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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
Loading…
Reference in new issue