parent
23c2d02682
commit
6abffe0ede
578 changed files with 140675 additions and 0 deletions
@ -0,0 +1,77 @@ |
||||
#!/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" "$@" |
@ -0,0 +1 @@ |
||||
apktool_2.3.0.jar |
Binary file not shown.
@ -0,0 +1,3 @@ |
||||
version https://git-lfs.github.com/spec/v1 |
||||
oid sha256:b7d08710ae4c0bbdc73184453b4d40da979fa3b0abbdb4e974980f9250730127 |
||||
size 18914367 |
@ -0,0 +1 @@ |
||||
../gpac/bin/MP4Box |
@ -0,0 +1 @@ |
||||
../apktool/apktool |
@ -0,0 +1 @@ |
||||
../azcopy/azcopy |
@ -0,0 +1 @@ |
||||
../capnp/bin/capnp |
@ -0,0 +1 @@ |
||||
../capnp/bin/capnpc |
@ -0,0 +1 @@ |
||||
../capnp/bin/capnpc-c |
@ -0,0 +1 @@ |
||||
../capnp/bin/capnpc-c++ |
@ -0,0 +1 @@ |
||||
../capnp/bin/capnpc-capnp |
@ -0,0 +1 @@ |
||||
../capnp/bin/capnpc-java |
@ -0,0 +1 @@ |
||||
../ffmpeg/bin/ffmpeg |
@ -0,0 +1 @@ |
||||
../ffmpeg/bin/ffprobe |
@ -0,0 +1 @@ |
||||
../pyflame/flame.sh |
@ -0,0 +1 @@ |
||||
../simg2img/img2simg |
@ -0,0 +1 @@ |
||||
../ipfs/ipfs |
@ -0,0 +1 @@ |
||||
../simg2img/simg2img |
Binary file not shown.
@ -0,0 +1 @@ |
||||
capnp |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,47 @@ |
||||
set -e |
||||
echo "Installing capnp" |
||||
|
||||
ONE=${HOME}/one |
||||
VERSION=0.6.1 |
||||
wget https://capnproto.org/capnproto-c++-${VERSION}.tar.gz |
||||
tar xvf capnproto-c++-${VERSION}.tar.gz |
||||
cd capnproto-c++-${VERSION} |
||||
CXXFLAGS="-fPIC" ./configure --prefix=${ONE}/external/capnp |
||||
make -j9 |
||||
|
||||
# manually build binaries statically |
||||
g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnp src/capnp/compiler/module-loader.o src/capnp/compiler/capnp.o ./.libs/libcapnpc.a ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread |
||||
|
||||
g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-c++ src/capnp/compiler/capnpc-c++.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread |
||||
|
||||
g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-capnp src/capnp/compiler/capnpc-capnp.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread |
||||
|
||||
|
||||
make -j4 install |
||||
|
||||
# -------- |
||||
echo "Installing c-capnp" |
||||
|
||||
git clone git@github.com:commaai/c-capnproto.git |
||||
cd c-capnproto |
||||
git submodule update --init --recursive |
||||
autoreconf -f -i -s |
||||
CFLAGS="-fPIC" ./configure --prefix=${ONE}/external/capnp |
||||
make -j4 |
||||
|
||||
# manually build binaries statically |
||||
gcc -fPIC -o .libs/capnpc-c compiler/capnpc-c.o compiler/schema.capnp.o compiler/str.o ./.libs/libcapnp_c.a -Wl,-rpath -Wl,${ONE}/external/capnp/lib |
||||
|
||||
make install |
||||
|
||||
# -------- |
||||
echo "Installing java-capnp" |
||||
|
||||
git clone https://github.com/dwrensha/capnproto-java.git |
||||
cd capnproto-java |
||||
git reset --hard 2c43bd712fb218da0eabdf241a750b9c05903e8e |
||||
g++ compiler/src/main/cpp/capnpc-java.c++ -std=c++11 -pthread -I${ONE}/external/capnp/include -L${ONE}/external/capnp/lib -l:libcapnp.a -l:libkj.a -pthread -lpthread -o capnpc-java |
||||
cp capnpc-java ${ONE}/external/capnp/bin/ |
||||
|
||||
rm -rf capnproto-c++-${VERSION}.tar.gz |
||||
rm -rf capnproto-c++-${VERSION} |
@ -0,0 +1,7 @@ |
||||
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 |
@ -0,0 +1,185 @@ |
||||
// $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 |
@ -0,0 +1,216 @@ |
||||
# 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 |
@ -0,0 +1,60 @@ |
||||
# 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 |
@ -0,0 +1,114 @@ |
||||
# 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 |
@ -0,0 +1,867 @@ |
||||
# 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 |
@ -0,0 +1,95 @@ |
||||
# 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
|
@ -0,0 +1,291 @@ |
||||
# 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 |
@ -0,0 +1,140 @@ |
||||
# 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 |
@ -0,0 +1,144 @@ |
||||
# 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 |
@ -0,0 +1,167 @@ |
||||
# 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 |
@ -0,0 +1,712 @@ |
||||
# 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 |
@ -0,0 +1,223 @@ |
||||
# 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 |
@ -0,0 +1,71 @@ |
||||
// $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 |
@ -0,0 +1,49 @@ |
||||
// $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 |
@ -0,0 +1,97 @@ |
||||
// $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 |
@ -0,0 +1,92 @@ |
||||
// $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 |
@ -0,0 +1,42 @@ |
||||
# 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 |
@ -0,0 +1,96 @@ |
||||
# 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
|
@ -0,0 +1,141 @@ |
||||
# 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 |
@ -0,0 +1,96 @@ |
||||
# 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
@ -0,0 +1,213 @@ |
||||
# 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 |
@ -0,0 +1,384 @@ |
||||
# 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 |
@ -0,0 +1,281 @@ |
||||
// $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 |
@ -0,0 +1,229 @@ |
||||
// $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 |
@ -0,0 +1,230 @@ |
||||
// $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 |
@ -0,0 +1,84 @@ |
||||
// $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 |
@ -0,0 +1,67 @@ |
||||
# 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 |
@ -0,0 +1,186 @@ |
||||
// $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 |
@ -0,0 +1,65 @@ |
||||
# 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 |
@ -0,0 +1,404 @@ |
||||
# 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 |
@ -0,0 +1,243 @@ |
||||
# 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 |
@ -0,0 +1,50 @@ |
||||
// $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 |
@ -0,0 +1,259 @@ |
||||
# 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 |
@ -0,0 +1,198 @@ |
||||
# 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
@ -0,0 +1,415 @@ |
||||
# 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 |
@ -0,0 +1,142 @@ |
||||
# 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 |
@ -0,0 +1,354 @@ |
||||
# 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 |
@ -0,0 +1,52 @@ |
||||
// $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 |
@ -0,0 +1,205 @@ |
||||
// $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 |
@ -0,0 +1,325 @@ |
||||
// $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 |
@ -0,0 +1,332 @@ |
||||
// $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 |
@ -0,0 +1,306 @@ |
||||
# 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 |
@ -0,0 +1,101 @@ |
||||
// $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 |
@ -0,0 +1,93 @@ |
||||
// $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 |
@ -0,0 +1,22 @@ |
||||
# 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 |
@ -0,0 +1,60 @@ |
||||
// $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 |
@ -0,0 +1,119 @@ |
||||
# 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 |
@ -0,0 +1,106 @@ |
||||
# 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
|
@ -0,0 +1,96 @@ |
||||
# 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
|
@ -0,0 +1,302 @@ |
||||
# 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 |
@ -0,0 +1,294 @@ |
||||
# 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 |
@ -0,0 +1,164 @@ |
||||
# 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 |
@ -0,0 +1,559 @@ |
||||
# 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 |
@ -0,0 +1,729 @@ |
||||
# 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 |
@ -0,0 +1,255 @@ |
||||
# 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 |
@ -0,0 +1,432 @@ |
||||
# 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 |
@ -0,0 +1,210 @@ |
||||
# 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 |
@ -0,0 +1,488 @@ |
||||
# 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 |
@ -0,0 +1,19 @@ |
||||
# 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 |
@ -0,0 +1,51 @@ |
||||
// $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 |
@ -0,0 +1,214 @@ |
||||
# 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 |
@ -0,0 +1,105 @@ |
||||
// $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 |
@ -0,0 +1,175 @@ |
||||
# 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 |
@ -0,0 +1,112 @@ |
||||
# 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 |
||||
|
@ -0,0 +1,233 @@ |
||||
# 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 |
@ -0,0 +1,91 @@ |
||||
# 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
|
@ -0,0 +1,337 @@ |
||||
# 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 |
@ -0,0 +1,102 @@ |
||||
// $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 |
@ -0,0 +1,102 @@ |
||||
// $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 |
@ -0,0 +1,188 @@ |
||||
# 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 |
@ -0,0 +1,129 @@ |
||||
# 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 |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue