external folder

pull/960/head
George Hotz 5 years ago
parent 23c2d02682
commit 6abffe0ede
  1. 77
      external/apktool/apktool
  2. 1
      external/apktool/apktool.jar
  3. BIN
      external/apktool/apktool_2.3.0.jar
  4. 3
      external/azcopy/azcopy
  5. 1
      external/bin/MP4Box
  6. 1
      external/bin/apktool
  7. 1
      external/bin/azcopy
  8. 1
      external/bin/capnp
  9. 1
      external/bin/capnpc
  10. 1
      external/bin/capnpc-c
  11. 1
      external/bin/capnpc-c++
  12. 1
      external/bin/capnpc-capnp
  13. 1
      external/bin/capnpc-java
  14. 1
      external/bin/ffmpeg
  15. 1
      external/bin/ffprobe
  16. 1
      external/bin/flame
  17. 1
      external/bin/img2simg
  18. 1
      external/bin/ipfs
  19. 1
      external/bin/simg2img
  20. BIN
      external/capnp/bin/capnp
  21. 1
      external/capnp/bin/capnpc
  22. BIN
      external/capnp/bin/capnpc-c
  23. BIN
      external/capnp/bin/capnpc-c++
  24. BIN
      external/capnp/bin/capnpc-capnp
  25. BIN
      external/capnp/bin/capnpc-java
  26. 47
      external/capnp/build.sh
  27. 7
      external/cppad/build.txt
  28. 185
      external/cppad/include/cppad/base_require.hpp
  29. 216
      external/cppad/include/cppad/configure.hpp
  30. 60
      external/cppad/include/cppad/core/abort_recording.hpp
  31. 114
      external/cppad/include/cppad/core/abs.hpp
  32. 867
      external/cppad/include/cppad/core/abs_normal_fun.hpp
  33. 95
      external/cppad/include/cppad/core/acosh.hpp
  34. 291
      external/cppad/include/cppad/core/ad.hpp
  35. 140
      external/cppad/include/cppad/core/ad_assign.hpp
  36. 144
      external/cppad/include/cppad/core/ad_binary.hpp
  37. 167
      external/cppad/include/cppad/core/ad_ctor.hpp
  38. 712
      external/cppad/include/cppad/core/ad_fun.hpp
  39. 223
      external/cppad/include/cppad/core/ad_io.hpp
  40. 71
      external/cppad/include/cppad/core/ad_to_string.hpp
  41. 49
      external/cppad/include/cppad/core/ad_valued.hpp
  42. 97
      external/cppad/include/cppad/core/add.hpp
  43. 92
      external/cppad/include/cppad/core/add_eq.hpp
  44. 42
      external/cppad/include/cppad/core/arithmetic.hpp
  45. 96
      external/cppad/include/cppad/core/asinh.hpp
  46. 141
      external/cppad/include/cppad/core/atan2.hpp
  47. 96
      external/cppad/include/cppad/core/atanh.hpp
  48. 2423
      external/cppad/include/cppad/core/atomic_base.hpp
  49. 213
      external/cppad/include/cppad/core/azmul.hpp
  50. 384
      external/cppad/include/cppad/core/base_complex.hpp
  51. 281
      external/cppad/include/cppad/core/base_cond_exp.hpp
  52. 229
      external/cppad/include/cppad/core/base_double.hpp
  53. 230
      external/cppad/include/cppad/core/base_float.hpp
  54. 84
      external/cppad/include/cppad/core/base_hash.hpp
  55. 67
      external/cppad/include/cppad/core/base_limits.hpp
  56. 186
      external/cppad/include/cppad/core/base_std_math.hpp
  57. 65
      external/cppad/include/cppad/core/base_to_string.hpp
  58. 404
      external/cppad/include/cppad/core/bender_quad.hpp
  59. 243
      external/cppad/include/cppad/core/bool_fun.hpp
  60. 50
      external/cppad/include/cppad/core/bool_valued.hpp
  61. 259
      external/cppad/include/cppad/core/capacity_order.hpp
  62. 198
      external/cppad/include/cppad/core/check_for_nan.hpp
  63. 1058
      external/cppad/include/cppad/core/checkpoint.hpp
  64. 415
      external/cppad/include/cppad/core/compare.hpp
  65. 142
      external/cppad/include/cppad/core/compound_assign.hpp
  66. 354
      external/cppad/include/cppad/core/cond_exp.hpp
  67. 52
      external/cppad/include/cppad/core/convert.hpp
  68. 205
      external/cppad/include/cppad/core/cppad_assert.hpp
  69. 325
      external/cppad/include/cppad/core/define.hpp
  70. 332
      external/cppad/include/cppad/core/dependent.hpp
  71. 306
      external/cppad/include/cppad/core/discrete.hpp
  72. 101
      external/cppad/include/cppad/core/div.hpp
  73. 93
      external/cppad/include/cppad/core/div_eq.hpp
  74. 22
      external/cppad/include/cppad/core/drivers.hpp
  75. 60
      external/cppad/include/cppad/core/epsilon.hpp
  76. 119
      external/cppad/include/cppad/core/equal_op_seq.hpp
  77. 106
      external/cppad/include/cppad/core/erf.hpp
  78. 96
      external/cppad/include/cppad/core/expm1.hpp
  79. 302
      external/cppad/include/cppad/core/for_hes_sparsity.hpp
  80. 294
      external/cppad/include/cppad/core/for_jac_sparsity.hpp
  81. 164
      external/cppad/include/cppad/core/for_one.hpp
  82. 559
      external/cppad/include/cppad/core/for_sparse_hes.hpp
  83. 729
      external/cppad/include/cppad/core/for_sparse_jac.hpp
  84. 255
      external/cppad/include/cppad/core/for_two.hpp
  85. 432
      external/cppad/include/cppad/core/forward.hpp
  86. 210
      external/cppad/include/cppad/core/fun_check.hpp
  87. 488
      external/cppad/include/cppad/core/fun_construct.hpp
  88. 19
      external/cppad/include/cppad/core/fun_eval.hpp
  89. 51
      external/cppad/include/cppad/core/hash_code.hpp
  90. 214
      external/cppad/include/cppad/core/hessian.hpp
  91. 105
      external/cppad/include/cppad/core/identical.hpp
  92. 175
      external/cppad/include/cppad/core/independent.hpp
  93. 112
      external/cppad/include/cppad/core/integer.hpp
  94. 233
      external/cppad/include/cppad/core/jacobian.hpp
  95. 91
      external/cppad/include/cppad/core/log1p.hpp
  96. 337
      external/cppad/include/cppad/core/lu_ratio.hpp
  97. 102
      external/cppad/include/cppad/core/mul.hpp
  98. 102
      external/cppad/include/cppad/core/mul_eq.hpp
  99. 188
      external/cppad/include/cppad/core/near_equal_ext.hpp
  100. 129
      external/cppad/include/cppad/core/num_skip.hpp
  101. Some files were not shown because too many files have changed in this diff Show More

@ -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

1
external/bin/ipfs vendored

@ -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…
Cancel
Save