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