diff --git a/.gitignore b/.gitignore index ba8f29b2..3d9965aa 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,10 @@ subprojects/kinsol-*/ subprojects/CLI11-*/ subprojects/openssl-*/ subprojects/tomlplusplus-*/ +subprojects/CppAD-*/ +subprojects/mimalloc-*/ +subprojects/unordered_dense*/ + *.fbundle *.wraplock diff --git a/benchmarks/SingleZoneSolver/main.cpp b/benchmarks/SingleZoneSolver/main.cpp new file mode 100644 index 00000000..72edb819 --- /dev/null +++ b/benchmarks/SingleZoneSolver/main.cpp @@ -0,0 +1,159 @@ +// ReSharper disable CppUnusedIncludeDirective +#include +#include +#include +#include +#include + +#include "gridfire/gridfire.h" +#include // Required for parallel_setup + +#include "fourdst/composition/composition.h" +#include "fourdst/logging/logging.h" +#include "fourdst/atomic/species.h" +#include "fourdst/composition/utils.h" + +#include "quill/Logger.h" +#include "quill/Backend.h" + +#include + +#include "gridfire/reaction/reaclib.h" +#include "gridfire/utils/gf_omp.h" + +gridfire::NetIn init(const double temp, const double rho, const double tMax) { + std::setlocale(LC_ALL, ""); + quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); + logger->set_log_level(quill::LogLevel::TraceL2); + + using namespace gridfire; + const std::vector X = {0.7081145999999999, 2.94e-5, 0.276, 0.003, 0.0011, 9.62e-3, 1.62e-3, 5.16e-4}; + const std::vector symbols = {"H-1", "He-3", "He-4", "C-12", "N-14", "O-16", "Ne-20", "Mg-24"}; + + + const fourdst::composition::Composition composition = fourdst::composition::buildCompositionFromMassFractions(symbols, X); + + NetIn netIn; + netIn.composition = composition; + netIn.temperature = temp; + netIn.density = rho; + netIn.energy = 0; + + netIn.tMax = tMax; + netIn.dt0 = 1e-12; + + return netIn; +} + + +int main() { + GF_PAR_INIT() + using namespace gridfire; + + constexpr size_t breaks = 1; + constexpr double temp = 1.5e7; + constexpr double rho = 1.5e2; + constexpr double tMax = 3.1536e+16/breaks; + + const NetIn netIn = init(temp, rho, tMax); + + policy::MainSequencePolicy stellarPolicy(netIn.composition); + const policy::ConstructionResults construct = stellarPolicy.construct(); + std::println("Sandbox Engine Stack: {}", stellarPolicy); + std::println("Scratch Blob State: {}", *construct.scratch_blob); + + + constexpr size_t runs = 10; + auto startTime = std::chrono::high_resolution_clock::now(); + + // arrays to store timings + std::array, runs> setup_times; + std::array, runs> eval_times; + std::array serial_results; + for (size_t i = 0; i < runs; ++i) { + auto start_setup_time = std::chrono::high_resolution_clock::now(); + solver::PointSolverContext solverCtx(*construct.scratch_blob); + solverCtx.set_stdout_logging(false); + solver::PointSolver solver(construct.engine); + auto end_setup_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration setup_elapsed = end_setup_time - start_setup_time; + setup_times[i] = setup_elapsed; + + auto start_eval_time = std::chrono::high_resolution_clock::now(); + const NetOut netOut = solver.evaluate(solverCtx, netIn); + auto end_eval_time = std::chrono::high_resolution_clock::now(); + serial_results[i] = netOut; + std::chrono::duration eval_elapsed = end_eval_time - start_eval_time; + eval_times[i] = eval_elapsed; + } + auto endTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = endTime - startTime; + std::println(""); + + // Summarize serial timings + double total_setup_time = 0.0; + double total_eval_time = 0.0; + for (size_t i = 0; i < runs; ++i) { + total_setup_time += setup_times[i].count(); + total_eval_time += eval_times[i].count(); + } + std::println("Average Setup Time over {} runs: {:.6f} seconds", runs, total_setup_time / runs); + std::println("Average Evaluation Time over {} runs: {:.6f} seconds", runs, total_eval_time / runs); + std::println("Total Time for {} runs: {:.6f} seconds", runs, elapsed.count()); + + + std::array parallelResults; + std::array, runs> setupTimes; + std::array, runs> evalTimes; + std::array, runs> workspaces; + for (size_t i = 0; i < runs; ++i) { + workspaces[i] = construct.scratch_blob->clone_structure(); + } + + + // Parallel runs + startTime = std::chrono::high_resolution_clock::now(); + + GF_OMP(parallel for, for (size_t i = 0; i < runs; ++i)) { + auto start_setup_time = std::chrono::high_resolution_clock::now(); + solver::PointSolverContext solverCtx(*construct.scratch_blob); + solverCtx.set_stdout_logging(false); + solver::PointSolver solver(construct.engine); + auto end_setup_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration setup_elapsed = end_setup_time - start_setup_time; + setupTimes[i] = setup_elapsed; + auto start_eval_time = std::chrono::high_resolution_clock::now(); + parallelResults[i] = solver.evaluate(solverCtx, netIn); + auto end_eval_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration eval_elapsed = end_eval_time - start_eval_time; + evalTimes[i] = eval_elapsed; + } + endTime = std::chrono::high_resolution_clock::now(); + elapsed = endTime - startTime; + std::println(""); + + // Summarize parallel timings + total_setup_time = 0.0; + total_eval_time = 0.0; + for (size_t i = 0; i < runs; ++i) { + total_setup_time += setupTimes[i].count(); + total_eval_time += evalTimes[i].count(); + } + + std::println("Average Parallel Setup Time over {} runs: {:.6f} seconds", runs, total_setup_time / runs); + std::println("Average Parallel Evaluation Time over {} runs: {:.6f} seconds", runs, total_eval_time / runs); + std::println("Total Parallel Time for {} runs: {:.6f} seconds", runs, elapsed.count()); + + std::println("========== Summary =========="); + std::println("Serial Runs:"); + std::println(" Average Setup Time: {:.6f} seconds", total_setup_time / runs); + std::println(" Average Evaluation Time: {:.6f} seconds", total_eval_time / runs); + std::println("Parallel Runs:"); + std::println(" Average Setup Time: {:.6f} seconds", total_setup_time / runs); + std::println(" Average Evaluation Time: {:.6f} seconds", total_eval_time / runs); + std::println("Difference:"); + std::println(" Setup Time Difference: {:.6f} seconds", (total_setup_time / runs) - (total_setup_time / runs)); + std::println(" Evaluation Time Difference: {:.6f} seconds", (total_eval_time / runs) - (total_eval_time / runs)); + std::println(" Setup Time Fractional Difference: {:.2f}%", ((total_setup_time / runs) - (total_setup_time / runs)) / (total_setup_time / runs) * 100.0); + std::println(" Evaluation Time Fractional Difference: {:.2f}%", ((total_eval_time / runs) - (total_eval_time / runs)) / (total_eval_time / runs) * 100.0); +} \ No newline at end of file diff --git a/benchmarks/SingleZoneSolver/meson.build b/benchmarks/SingleZoneSolver/meson.build new file mode 100644 index 00000000..68c2aa8e --- /dev/null +++ b/benchmarks/SingleZoneSolver/meson.build @@ -0,0 +1,5 @@ +executable( + 'gf_bench_single_zone_parallel', + 'main.cpp', + dependencies: [gridfire_dep], +) diff --git a/benchmarks/meson.build b/benchmarks/meson.build new file mode 100644 index 00000000..52a7e63b --- /dev/null +++ b/benchmarks/meson.build @@ -0,0 +1,3 @@ +if get_option('build_benchmarks') + subdir('SingleZoneSolver') +endif \ No newline at end of file diff --git a/build-check/CPPC/meson.build b/build-check/CPPC/meson.build index 070401de..743ebc36 100644 --- a/build-check/CPPC/meson.build +++ b/build-check/CPPC/meson.build @@ -33,5 +33,18 @@ else endif if get_option('openmp_support') - add_project_arguments('-DGRIDFIRE_USE_OPENMP', language: 'cpp') + add_project_arguments('-DGF_USE_OPENMP', language: 'cpp') +endif + +if get_option('asan') and get_option('buildtype') != 'debug' and get_option('buildtype') != 'debugoptimized' + error('AddressSanitizer (ASan) can only be enabled for debug or debugoptimized builds') +endif + +if get_option('asan') and (get_option('buildtype') == 'debugoptimized' or get_option('buildtype') == 'debug') + message('enabling AddressSanitizer (ASan) support') + add_project_arguments('-fsanitize=address,undefined', language: 'cpp') + add_project_arguments('-fno-omit-frame-pointer', language: 'cpp') + + add_project_link_arguments('-fsanitize=address,undefined', language: 'cpp') + add_project_link_arguments('-fno-omit-frame-pointer', language: 'cpp') endif diff --git a/build-check/FC/meson.build b/build-check/FC/meson.build index 5d1cc40e..6366845d 100644 --- a/build-check/FC/meson.build +++ b/build-check/FC/meson.build @@ -1,5 +1,10 @@ if get_option('build_fortran') - add_languages('fortran', native: true) + found_fortran = add_languages('fortran') + if not found_fortran + error('Fortran compiler not found, but build_fortran option is enabled.') + else + message('Fortran compiler found.') + endif message('Found FORTRAN compiler: ' + meson.get_compiler('fortran').get_id()) message('Fortran standard set to: ' + get_option('fortran_std')) message('Building fortran module (gridfire_mod.mod)') diff --git a/build-config/cppad/COPYING b/build-config/cppad/COPYING deleted file mode 100644 index bfb3d7bb..00000000 --- a/build-config/cppad/COPYING +++ /dev/null @@ -1,11 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------ diff --git a/build-config/cppad/include/cppad/CMakeLists.txt b/build-config/cppad/include/cppad/CMakeLists.txt deleted file mode 100644 index 7c5e6f3e..00000000 --- a/build-config/cppad/include/cppad/CMakeLists.txt +++ /dev/null @@ -1,184 +0,0 @@ -# ----------------------------------------------------------------------------- -# CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell -# -# CppAD is distributed under the terms of the -# Eclipse Public License Version 2.0. -# -# This Source Code may also be made available under the following -# Secondary License when the conditions for such availability set forth -# in the Eclipse Public License, Version 2.0 are satisfied: -# GNU General Public License, Version 2.0 or later. -# ----------------------------------------------------------------------------- -# Configure the CppAD include file directory -# ----------------------------------------------------------------------------- -# check_match -MACRO(check_match match_variable match_constant output_variable) - STRING(COMPARE EQUAL ${${match_variable}} ${match_constant} match_flag ) - IF( match_flag ) - SET(${output_variable} 1) - ELSE( match_flag ) - SET(${output_variable} 0) - ENDIF( match_flag ) - print_variable(${output_variable}) -ENDMACRO(check_match) -# ----------------------------------------------------------------------------- -# compiler_has_conversion_warn -SET( clang_or_gnu 0 ) -IF( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) - SET(clang_or_gnu 1) -ENDIF( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) -IF( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) - SET(clang_or_gnu 1) -ENDIF( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) -IF( clang_or_gnu ) - SET(backup "${cppad_cxx_flags}") - SET(cppad_cxx_flags "${backup} -Wfloat-conversion -Wconversion -Werror") - # - SET(source "int main(void) { return 0; }") - run_source_test("${source}" compiler_has_conversion_warn ) - # - SET(cppad_cxx_flags "${backup}") -ELSE( clang_or_gnu ) - SET( compiler_has_conversion_warn 0 ) -ENDIF( clang_or_gnu ) -# ----------------------------------------------------------------------------- -# cppad_boostvector, cppad_cppadvector, cppad_eigenvector, cppad_stdvector -# -check_match(cppad_testvector boost cppad_boostvector) -check_match(cppad_testvector cppad cppad_cppadvector) -check_match(cppad_testvector eigen cppad_eigenvector) -check_match(cppad_testvector std cppad_stdvector) -IF( NOT cppad_boostvector ) -IF( NOT cppad_cppadvector ) -IF( NOT cppad_eigenvector ) -IF( NOT cppad_stdvector ) -MESSAGE(FATAL_ERROR -"cppad_testvector not one of following: boost, cppad, eigen, std." -"This should have been found earlier, please report this as a bug." -) -ENDIF( NOT cppad_stdvector ) -ENDIF( NOT cppad_eigenvector ) -ENDIF( NOT cppad_cppadvector ) -ENDIF( NOT cppad_boostvector ) - -IF( cppad_boostvector ) - # FIND_PACKAGE(Boost) done by ../CMakeLists.txt - IF( NOT Boost_FOUND ) - MESSAGE(FATAL_ERROR -"cppad_testvector == boost but cannot find boost include files" - ) - ENDIF( NOT Boost_FOUND ) -ENDIF( cppad_boostvector ) -# -IF( cppad_eigenvector ) - IF( NOT include_eigen ) - MESSAGE(FATAL_ERROR -"cppad_testvector == eigen but eigen_prefix is not specified" - ) - ENDIF( NOT include_eigen ) -ENDIF( cppad_eigenvector ) -# -print_variable(cppad_cplusplus_201100_ok) -# ----------------------------------------------------------------------------- -# cppad_has_gettimeofday -# -SET(source " -# include -int main(void) -{ struct timeval time; - gettimeofday(&time, 0); - return 0; -}" -) -run_source_test("${source}" cppad_has_gettimeofday) -# ----------------------------------------------------------------------------- -# cppad_tape_addr_type, cppad_tape_id_type -# -FOREACH(cmake_var cppad_tape_id_type cppad_tape_addr_type ) - SET(source " -# include -int main(void) -{ bool is_unsigned = ! std::numeric_limits<${${cmake_var}}>::is_signed; - return int(! is_unsigned); -} -" - ) - run_source_test("${source}" ${cmake_var}_is_unsigned) - IF( ${cmake_var}_is_unsigned STREQUAL 0 ) - MESSAGE(STATUS -"Warning: using a signed ${cmake_var} is for CppAD developers only !" - ) - ENDIF( ${cmake_var}_is_unsigned STREQUAL 0 ) -ENDFOREACH( cmake_var ) -# ----------------------------------------------------------------------------- -# check that cppad_max_num_threads is >= 4 -# -SET(CMAKE_REQUIRED_DERINITIONS "") -SET(CMAKE_REQUIRED_INCLUDES "") -SET(CMAKE_REQUIRED_LIBRARIES "") -SET(CMAKE_REQUIRED_FLAGS "") -SET(source " -int main(void) -{ const char* number = \"${cppad_max_num_threads}\"; - int value = 0; - while( *number == ' ' ) - number++; - while( '0' <= *number && *number <= '9' ) - { value = 10 * value + (int)(*number - '0'); - number++; - } - while( *number == ' ' ) - number++; - if( *number != char(0) ) - return 1; - if( value < 4 ) - return 1; - return 0; -} -" ) -# Using CHECK_CXX_SOURCE_RUNS directly (instead of run_source_test). -IF( DEFINED cppad_max_num_threads_is_integer_ge_4 ) - MESSAGE( ERROR - "cppad_max_num_threads_is_integer_ge_4 is defined before expected" - ) -ENDIF( DEFINED cppad_max_num_threads_is_integer_ge_4 ) -CHECK_CXX_SOURCE_RUNS("${source}" cppad_max_num_threads_is_integer_ge_4 ) -IF( NOT cppad_max_num_threads_is_integer_ge_4 ) - MESSAGE(FATAL_ERROR - "cppad_max_num_threads is not an integer greater than or equal 4" - ) -ENDIF( NOT cppad_max_num_threads_is_integer_ge_4 ) -# ----------------------------------------------------------------------------- -# cppad_has_mkstemp -# -SET(source " -# include -# include -int main(void) -{ - char pattern[] = \"/tmp/fileXXXXXX\"; - int fd = mkstemp(pattern); - return 0; -} -" ) -run_source_test("${source}" cppad_has_mkstemp ) -# ----------------------------------------------------------------------------- -# cppad_has_tmpname_s -# -SET(source " -# include -int main(void) -{ char filename[L_tmpnam_s ]; - if( tmpnam_s(filename, L_tmpnam_s ) != 0 ) - return 1; - return 0; -} -" ) -run_source_test("${source}" cppad_has_tmpnam_s ) -# ----------------------------------------------------------------------------- -# configure.hpp -CONFIGURE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/configure.hpp.in - ${CMAKE_CURRENT_SOURCE_DIR}/configure.hpp -) -# ----------------------------------------------------------------------------- diff --git a/build-config/cppad/include/cppad/base_require.hpp b/build-config/cppad/include/cppad/base_require.hpp deleted file mode 100644 index af54fad7..00000000 --- a/build-config/cppad/include/cppad/base_require.hpp +++ /dev/null @@ -1,177 +0,0 @@ -# ifndef CPPAD_BASE_REQUIRE_HPP -# define CPPAD_BASE_REQUIRE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin base_require$$ -$spell - azmul - ostream - alloc - eps - std - cppad.hpp - namespace - bool - const - CppAD - enum - inline - Op - std - CondExp -$$ - -$section AD Requirements for a CppAD Base Type$$ - -$head Syntax$$ -$code # include $$ - -$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$$, -$code std::complex$$, -or $codei%AD<%Other%>%$$, -these requirements are provided by including the file -$code cppad/cppad.hpp$$. -In the documentation, The notation $latex \B{R}$$ denotes -the field corresponding to the base type. -Multiplication must be commutative for this field, -but it need not be the reals; e.g., the complex numbers. - -$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(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% - include/cppad/core/base_cond_exp.hpp% - omh/base_require/base_identical.omh% - omh/base_require/base_ordered.omh% - 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% - omh/base_require/base_example.omh -%$$ - -$end -*/ - -// definitions that must come before base implementations -# include -# include -# include -# include - -// grouping documentation by feature -# include -# include -# include -# include -# include - -// must define template class numeric_limits before the base cases -# include -# include // deprecated - -// base cases that come with CppAD -# include -# include -# include - -// deprecated base type -# include - -# endif diff --git a/build-config/cppad/include/cppad/configure.hpp b/build-config/cppad/include/cppad/configure.hpp deleted file mode 100644 index 028064ec..00000000 --- a/build-config/cppad/include/cppad/configure.hpp +++ /dev/null @@ -1,238 +0,0 @@ -# ifndef CPPAD_CONFIGURE_HPP -# define CPPAD_CONFIGURE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/*! -$begin configure.hpp$$ -$spell - noexcept - pragmas - unreferenced - CppAD - cppad - yyyymmdd - yyyy - mm - dd - adolc - cmake - colpack - eigen - ipopt - gettimeofday - namespace - mkstemp - tmpnam - nullptr - sizeof - std - hpp - addr -$$ - -$section Preprocessor Symbols Set By CMake Command$$ - -$head CPPAD_COMPILER_HAS_CONVERSION_WARN$$ -is the compiler a variant of g++ and has conversion warnings -$srccode%hpp% */ -# define CPPAD_COMPILER_HAS_CONVERSION_WARN 0 -/* %$$ - -$head CPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS$$ -This macro is only used to document the pragmas that disables the -follow warnings: - -$subhead C4100$$ -unreferenced formal parameter. - -$subhead C4127$$ -conditional expression is constant. - -$srccode%hpp% */ -# 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 -/* %$$ - -$head CPPAD_USE_CPLUSPLUS_2011$$ -Deprecated 2020-12-03: -Should CppAD use C++11 features. This is always 1 (for true). -$srccode%hpp% */ -# define CPPAD_USE_CPLUSPLUS_2011 1 -/* %$$ - -$head CPPAD_PACKAGE_STRING$$ -cppad-yyyymmdd as a C string where yyyy is year, mm is month, and dd is day. -$srccode%hpp% */ -# define CPPAD_PACKAGE_STRING "cppad-20210000.8" -/* %$$ - -$head CPPAD_HAS_ADOLC$$ -Was include_adolc=true on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_ADOLC 0 -/* %$$ - -$head CPPAD_HAS_COLPACK$$ -Was a colpack_prefix specified on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_COLPACK 0 -/* %$$ - -$head CPPAD_HAS_EIGEN$$ -Was include_eigen=true on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_EIGEN 0 -/* %$$ - -$head CPPAD_HAS_IPOPT$$ -Was include_ipopt=true on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_IPOPT 0 -/* %$$ - -$head CPPAD_DEPRECATED$$ -This symbol is not currently being used. -$srccode%hpp% */ -# define CPPAD_DEPRECATED -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_BOOSTVECTOR 0 -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_CPPADVECTOR 1 -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_STDVECTOR 0 -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_EIGENVECTOR 0 -/* %$$ - -$head CPPAD_HAS_GETTIMEOFDAY$$ -If this symbol is one, and _MSC_VER is not defined, -this system supports the gettimeofday function. -Otherwise, this symbol should be zero. -$srccode%hpp% */ -# define CPPAD_HAS_GETTIMEOFDAY 1 -/* %$$ - -$head CPPAD_TAPE_ADDR_TYPE$$ -Is the type used to store address on the tape. If not size_t, then -sizeof(CPPAD_TAPE_ADDR_TYPE) <= sizeof( size_t ) -to conserve memory. -This type must support std::numeric_limits, -the <= operator, -and conversion to size_t. -Make sure that the type chosen returns true for is_pod -in pod_vector.hpp. -This type is later defined as addr_t in the CppAD namespace. -$srccode%hpp% */ -# define CPPAD_TAPE_ADDR_TYPE unsigned int -/* %$$ - -$head CPPAD_TAPE_ID_TYPE$$ -Is the type used to store tape identifiers. If not size_t, then -sizeof(CPPAD_TAPE_ID_TYPE) <= sizeof( size_t ) -to conserve memory. -This type must support std::numeric_limits, -the <= operator, -and conversion to size_t. -Make sure that the type chosen returns true for is_pod -in pod_vector.hpp. -This type is later defined as tape_id_t in the CppAD namespace. -$srccode%hpp% */ -# define CPPAD_TAPE_ID_TYPE unsigned int -/* %$$ - -$head 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, -$srccode%hpp% */ -# ifndef CPPAD_MAX_NUM_THREADS -# define CPPAD_MAX_NUM_THREADS 48 -# endif -/* %$$ - -$head CPPAD_HAS_MKSTEMP$$ -It true, mkstemp works in C++ on this system. -$srccode%hpp% */ -# define CPPAD_HAS_MKSTEMP 1 -/* %$$ - -$head CPPAD_HAS_TMPNAM_S$$ -It true, tmpnam_s works in C++ on this system. -$srccode%hpp% */ -# define CPPAD_HAS_TMPNAM_S 0 -/* %$$ - -$head CPPAD_NULL$$ -Deprecated 2020-12-03: -This preprocessor symbol was used for a null pointer before c++11. -Replace it by $code nullptr$$. - -$head CPPAD_NOEXCEPT$$ -Deprecated 2020-12-03: -This preprocessor symbol was used for no exception before c++11, -replace it by $code noexcept$$. - -$subhead CPPAD_NDEBUG_NOEXCEPT$$ -This preprocessor symbol is -$code noexcept$$ when C++11 is available and $code NDEBUG$$ is defined. -Otherwise it is empty. - - -$end -*/ -// ------------------------------------------------- -# define CPPAD_NULL nullptr -# define CPPAD_NOEXCEPT noexcept -// -# ifdef NDEBUG -# define CPPAD_NDEBUG_NOEXCEPT noexcept -# else -# define CPPAD_NDEBUG_NOEXCEPT -# endif -// ------------------------------------------------- - -# endif diff --git a/build-config/cppad/include/cppad/configure.hpp.in b/build-config/cppad/include/cppad/configure.hpp.in deleted file mode 100644 index 718e42cb..00000000 --- a/build-config/cppad/include/cppad/configure.hpp.in +++ /dev/null @@ -1,238 +0,0 @@ -# ifndef CPPAD_CONFIGURE_HPP -# define CPPAD_CONFIGURE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/*! -$begin configure.hpp$$ -$spell - noexcept - pragmas - unreferenced - CppAD - cppad - yyyymmdd - yyyy - mm - dd - adolc - cmake - colpack - eigen - ipopt - gettimeofday - namespace - mkstemp - tmpnam - nullptr - sizeof - std - hpp - addr -$$ - -$section Preprocessor Symbols Set By CMake Command$$ - -$head CPPAD_COMPILER_HAS_CONVERSION_WARN$$ -is the compiler a variant of g++ and has conversion warnings -$srccode%hpp% */ -# define CPPAD_COMPILER_HAS_CONVERSION_WARN @compiler_has_conversion_warn@ -/* %$$ - -$head CPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS$$ -This macro is only used to document the pragmas that disables the -follow warnings: - -$subhead C4100$$ -unreferenced formal parameter. - -$subhead C4127$$ -conditional expression is constant. - -$srccode%hpp% */ -# 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 -/* %$$ - -$head CPPAD_USE_CPLUSPLUS_2011$$ -Deprecated 2020-12-03: -Should CppAD use C++11 features. This is always 1 (for true). -$srccode%hpp% */ -# define CPPAD_USE_CPLUSPLUS_2011 1 -/* %$$ - -$head CPPAD_PACKAGE_STRING$$ -cppad-yyyymmdd as a C string where yyyy is year, mm is month, and dd is day. -$srccode%hpp% */ -# define CPPAD_PACKAGE_STRING "cppad-@cppad_version@" -/* %$$ - -$head CPPAD_HAS_ADOLC$$ -Was include_adolc=true on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_ADOLC @cppad_has_adolc@ -/* %$$ - -$head CPPAD_HAS_COLPACK$$ -Was a colpack_prefix specified on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_COLPACK @cppad_has_colpack@ -/* %$$ - -$head CPPAD_HAS_EIGEN$$ -Was include_eigen=true on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_EIGEN @cppad_has_eigen@ -/* %$$ - -$head CPPAD_HAS_IPOPT$$ -Was include_ipopt=true on the cmake command line. -$srccode%hpp% */ -# define CPPAD_HAS_IPOPT @cppad_has_ipopt@ -/* %$$ - -$head CPPAD_DEPRECATED$$ -This symbol is not currently being used. -$srccode%hpp% */ -# define CPPAD_DEPRECATED @cppad_deprecated_01@ -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_BOOSTVECTOR @cppad_boostvector@ -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_CPPADVECTOR @cppad_cppadvector@ -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_STDVECTOR @cppad_stdvector@ -/* %$$ - -$head 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. -$srccode%hpp% */ -# define CPPAD_EIGENVECTOR @cppad_eigenvector@ -/* %$$ - -$head CPPAD_HAS_GETTIMEOFDAY$$ -If this symbol is one, and _MSC_VER is not defined, -this system supports the gettimeofday function. -Otherwise, this symbol should be zero. -$srccode%hpp% */ -# define CPPAD_HAS_GETTIMEOFDAY @cppad_has_gettimeofday@ -/* %$$ - -$head CPPAD_TAPE_ADDR_TYPE$$ -Is the type used to store address on the tape. If not size_t, then -sizeof(CPPAD_TAPE_ADDR_TYPE) <= sizeof( size_t ) -to conserve memory. -This type must support std::numeric_limits, -the <= operator, -and conversion to size_t. -Make sure that the type chosen returns true for is_pod -in pod_vector.hpp. -This type is later defined as addr_t in the CppAD namespace. -$srccode%hpp% */ -# define CPPAD_TAPE_ADDR_TYPE @cppad_tape_addr_type@ -/* %$$ - -$head CPPAD_TAPE_ID_TYPE$$ -Is the type used to store tape identifiers. If not size_t, then -sizeof(CPPAD_TAPE_ID_TYPE) <= sizeof( size_t ) -to conserve memory. -This type must support std::numeric_limits, -the <= operator, -and conversion to size_t. -Make sure that the type chosen returns true for is_pod -in pod_vector.hpp. -This type is later defined as tape_id_t in the CppAD namespace. -$srccode%hpp% */ -# define CPPAD_TAPE_ID_TYPE @cppad_tape_id_type@ -/* %$$ - -$head 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, -$srccode%hpp% */ -# ifndef CPPAD_MAX_NUM_THREADS -# define CPPAD_MAX_NUM_THREADS @cppad_max_num_threads@ -# endif -/* %$$ - -$head CPPAD_HAS_MKSTEMP$$ -It true, mkstemp works in C++ on this system. -$srccode%hpp% */ -# define CPPAD_HAS_MKSTEMP @cppad_has_mkstemp@ -/* %$$ - -$head CPPAD_HAS_TMPNAM_S$$ -It true, tmpnam_s works in C++ on this system. -$srccode%hpp% */ -# define CPPAD_HAS_TMPNAM_S @cppad_has_tmpnam_s@ -/* %$$ - -$head CPPAD_NULL$$ -Deprecated 2020-12-03: -This preprocessor symbol was used for a null pointer before c++11. -Replace it by $code nullptr$$. - -$head CPPAD_NOEXCEPT$$ -Deprecated 2020-12-03: -This preprocessor symbol was used for no exception before c++11, -replace it by $code noexcept$$. - -$subhead CPPAD_NDEBUG_NOEXCEPT$$ -This preprocessor symbol is -$code noexcept$$ when C++11 is available and $code NDEBUG$$ is defined. -Otherwise it is empty. - - -$end -*/ -// ------------------------------------------------- -# define CPPAD_NULL nullptr -# define CPPAD_NOEXCEPT noexcept -// -# ifdef NDEBUG -# define CPPAD_NDEBUG_NOEXCEPT noexcept -# else -# define CPPAD_NDEBUG_NOEXCEPT -# endif -// ------------------------------------------------- - -# endif diff --git a/build-config/cppad/include/cppad/core/abort_recording.hpp b/build-config/cppad/include/cppad/core/abort_recording.hpp deleted file mode 100644 index 09c3a1f8..00000000 --- a/build-config/cppad/include/cppad/core/abort_recording.hpp +++ /dev/null @@ -1,58 +0,0 @@ -# ifndef CPPAD_CORE_ABORT_RECORDING_HPP -# define CPPAD_CORE_ABORT_RECORDING_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin abort_recording$$ -$spell -$$ - -$section Abort Recording of an Operation Sequence$$ - - -$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. - -$end ----------------------------------------------------------------------------- -*/ - - -namespace CppAD { - template - void AD::abort_recording(void) - { local::ADTape* tape = AD::tape_ptr(); - if( tape != nullptr ) - AD::tape_manage(delete_tape_manage); - } -} - -# endif diff --git a/build-config/cppad/include/cppad/core/abs.hpp b/build-config/cppad/include/cppad/core/abs.hpp deleted file mode 100644 index f25d6e87..00000000 --- a/build-config/cppad/include/cppad/core/abs.hpp +++ /dev/null @@ -1,132 +0,0 @@ -# ifndef CPPAD_CORE_ABS_HPP -# define CPPAD_CORE_ABS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$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$$ or $code std::complex$$ -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. - -$end -------------------------------------------------------------------------------- -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD AD::abs_me (void) const -{ - AD result; - result.value_ = abs(value_); - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - - // check if operand is a constant parameter - if( tape_id_ != tape->id_ ) - return result; - - if(ad_type_ == dynamic_enum) - { // dynamic paramter argument - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::abs_dyn, taddr_ - ); - result.tape_id_ = tape_id_; - result.ad_type_ = dynamic_enum; - } - else - { // variable argument - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AbsOp) == 1 ); - - // 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_; - result.ad_type_ = variable_enum; - } - return result; -} - -template -AD abs(const AD &x) -{ return x.abs_me(); } - -template -AD abs(const VecAD_reference &x) -{ return x.ADBase().abs_me(); } - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/abs_normal_fun.hpp b/build-config/cppad/include/cppad/core/abs_normal_fun.hpp deleted file mode 100644 index c5a124b7..00000000 --- a/build-config/cppad/include/cppad/core/abs_normal_fun.hpp +++ /dev/null @@ -1,959 +0,0 @@ -# ifndef CPPAD_CORE_ABS_NORMAL_FUN_HPP -# define CPPAD_CORE_ABS_NORMAL_FUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-21 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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% - const 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. - -$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( x - \hat{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/example_abs_normal/Reference/$$. - -$children%example/abs_normal/abs_normal.omh -%$$ -$head Example$$ -The file $cref abs_get_started.cpp$$ contains -an example and test using this operation. -The section $cref example_abs_normal$$ -has a links to all the abs normal examples. - -$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. -*/ - -# ifndef NDEBUG -# define CPPAD_J_PAR_EQUAL_REC j_par = (size_t) rec -# else -# define CPPAD_J_PAR_EQUAL_REC rec -# endif - -template -void ADFun::abs_normal_fun(ADFun& g, ADFun& a) const -{ 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 f_abs_arg; - CppAD::vector f_abs_res; - // - OpCode op; // this operator - const addr_t* arg = nullptr; // arguments for this operator - size_t i_var; // variable index for this operator - local::play::const_sequential_iterator itr = play_.begin(); - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); - // - bool more_operators = true; - while( op != EndOp ) - { - // next op - (++itr).op_info(op, arg, 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; - - default: - break; - } - } - // ------------------------------------------------------------------------ - // Forward sweep to create new recording - // ------------------------------------------------------------------------ - // dynamic parameter information in player - const pod_vector& dyn_par_is( play_.dyn_par_is() ); - const pod_vector& dyn_par_op( play_.dyn_par_op() ); - const pod_vector& dyn_par_arg( play_.dyn_par_arg() ); - // - // recorder for new operation sequence - recorder rec; - // - // number of parameters in both operation sequences - size_t num_par = play_.num_par_rec(); - // - // number of independent dynamic parameters - size_t num_dynamic_ind = play_.num_dynamic_par(); - rec.set_num_dynamic_ind(num_dynamic_ind); - // - // set all parameter to be exactly the same in rec as in play - size_t i_dyn = 0; // dynamic parameter index - size_t i_arg = 0; // dynamic parameter operator argument index - for(size_t i_par = 0; i_par < num_par; ++i_par) - { -# ifndef NDEBUG - size_t j_par = 0; -# endif - // value of this parameter - Base par = play_.GetPar(i_par); - if( ! dyn_par_is[i_par] ) - CPPAD_J_PAR_EQUAL_REC.put_con_par(par); - else - { // operator for this dynamic parameter - op_code_dyn op_dyn = op_code_dyn( dyn_par_op[i_dyn] ); - CPPAD_ASSERT_KNOWN( - op_dyn != local::atom_dyn, - "abs_normal_fun: not yet implemented for " - "atomic dynamic parameter functions" - ); - // - // number of arguments for this dynamic parameter - size_t n_arg = num_arg_dyn(op_dyn); - // - switch(n_arg) - { case 0: - CPPAD_J_PAR_EQUAL_REC.put_dyn_par(par, op_dyn); - break; - - case 1: - CPPAD_J_PAR_EQUAL_REC.put_dyn_par(par, op_dyn, - dyn_par_arg[i_arg + 0] - ); - break; - - case 2: - CPPAD_J_PAR_EQUAL_REC.put_dyn_par(par, op_dyn, - dyn_par_arg[i_arg + 0] , - dyn_par_arg[i_arg + 1] - ); - break; - - case 5: - CPPAD_J_PAR_EQUAL_REC.put_dyn_cond_exp(par, - CompareOp( dyn_par_arg[i_arg + 0] ) , - dyn_par_arg[i_arg + 1] , - dyn_par_arg[i_arg + 2] , - dyn_par_arg[i_arg + 3] , - dyn_par_arg[i_arg + 4] - ); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - ++i_dyn; - i_arg += n_arg; - } - CPPAD_ASSERT_UNKNOWN( j_par == i_par ); - } - // - // 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( - size_t( (std::numeric_limits::max)() ) >= num_var - ); - CppAD::vector 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 - itr = play_.begin(); - itr.op_info(op, arg, 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 ) - (++itr).op_info(op, arg, 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]; - // - // 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] = arg[0]; // parameter - 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: - case ErfcOp: - 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( arg[1] ); // parameter - rec.PutArg( arg[2] ); // parameter - f2g_var[i_var] = rec.PutOp(op); - break; - // -------------------------------------------------------------- - // Binary operators, left variable, right parameter, one result - case SubvpOp: - case DivvpOp: - case PowvpOp: - case ZmulvpOp: -# ifndef NDEBUG - if( op == PowvpOp ) - { CPPAD_ASSERT_NARG_NRES(op, 2, 3); - } - else - { CPPAD_ASSERT_NARG_NRES(op, 2, 1); - } -# endif - CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var ); - new_arg[0] = f2g_var[ arg[0] ]; - new_arg[1] = arg[1]; // parameter - 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: -# ifndef NDEBUG - if( op == PowpvOp ) - { CPPAD_ASSERT_NARG_NRES(op, 2, 3); - } - else - { CPPAD_ASSERT_NARG_NRES(op, 2, 1); - } -# endif - CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var ); - new_arg[0] = arg[0]; // parameter - 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 PowvvOp: - case ZmulvvOp: -# ifndef NDEBUG - if( op == PowvvOp ) - { CPPAD_ASSERT_NARG_NRES(op, 2, 3); - } - else - { CPPAD_ASSERT_NARG_NRES(op, 2, 1); - } -# endif - 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] = arg[i]; // parameter - 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] = arg[0]; // parameter - 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] = arg[1]; // parameter - 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] = arg[1]; // parameter - } - // - // 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] = arg[3]; // parameter - } - new_arg[2] = rec.PutTxt( play_.GetTxt(size_t(arg[2])) ); - new_arg[4] = rec.PutTxt( play_.GetTxt(size_t(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]; // parameter - 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] = arg[1]; // parameter - new_arg[2] = arg[2]; // parameter - 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] = arg[2]; // parameter - 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] = arg[1]; // parameter - 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; - - // ----------------------------------------------------------- - // atomic function call operators - - case AFunOp: - CPPAD_ASSERT_NARG_NRES(op, 4, 0); - // atom_index, atom_old, atom_n, atom_m - rec.PutArg(arg[0], arg[1], arg[2], arg[3]); - rec.PutOp(AFunOp); - break; - - case FunapOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - new_arg[0] = arg[0]; // parameter - rec.PutArg(new_arg[0]); - rec.PutOp(FunapOp); - break; - - case FunavOp: - 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(FunavOp); - break; - - case FunrpOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - new_arg[0] = arg[0]; // parameter - rec.PutArg(new_arg[0]); - rec.PutOp(FunrpOp); - break; - - case FunrvOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - f2g_var[i_var] = rec.PutOp(FunrvOp); - break; - // --------------------------------------------------- - - // all cases should be handled above - default: - CPPAD_ASSERT_UNKNOWN(false); - } - if( more_operators ) - (++itr).op_info(op, arg, 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_var_load_rec() == play_.num_var_load_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_.resize( 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] = size_t( 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] = size_t( 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] = size_t( 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] = size_t( 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_.clear(); - 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_recording(rec, n + s); - - // resize subgraph_info_ - g.subgraph_info_.resize( - g.ind_taddr_.size(), // n_ind - g.dep_taddr_.size(), // n_dep - g.play_.num_op_rec(), // n_op - g.play_.num_var_rec() // n_var - ); - - // ------------------------------------------------------------------------ - // 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_.clear(); - a.num_order_taylor_ = 0; - a.cap_order_taylor_ = 0; -} - -// preprocessor symbols that are local to this file -# undef CPPAD_J_PAR_EQUAL_REC - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/ad.hpp b/build-config/cppad/include/cppad/core/ad.hpp deleted file mode 100644 index 99acdabb..00000000 --- a/build-config/cppad/include/cppad/core/ad.hpp +++ /dev/null @@ -1,311 +0,0 @@ -# ifndef CPPAD_CORE_AD_HPP -# define CPPAD_CORE_AD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// simple AD operations that must be defined for AD as well as base class -# include -# include - -// define the template classes that are used by the AD template class -# include -# include -# include -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -// tape_manage_enum -typedef enum { - new_tape_manage, - delete_tape_manage -} -tape_manage_enum; - -template -class AD { -private : - // ----------------------------------------------------------------------- - // Base type value for this object - Base value_; - // - // tape for this object - tape_id_t tape_id_; - // - // tape address for this object - // (when tape_id is current tape for AD) - addr_t taddr_; - // - // sub-type for this object - // (when tape_id is current tape for AD) - ad_type_enum ad_type_; - // ----------------------------------------------------------------------- - - // enable use of AD in parallel mode - template - friend void parallel_ad(void); - - // template friend functions where template parameter is not bound - template - friend void Independent( - ADVector& x , - size_t abort_op_index , - bool record_compare , - ADVector& dynamic - ); - - // one argument functions - friend bool Constant (const AD &u); - friend bool Constant (const VecAD &u); - // - friend bool Dynamic (const AD &u); - friend bool Dynamic (const VecAD &u); - // - friend bool Parameter (const AD &u); - friend bool Parameter (const VecAD &u); - // - friend bool Variable (const AD &u); - friend bool Variable (const VecAD &u); - // - friend int Integer (const AD &u); - friend AD Var2Par (const AD &u); - // - friend unsigned short hash_code (const AD &u); - // - // power function - friend AD pow - (const AD &x, const AD &y); - - // azmul function - friend AD azmul - (const AD &x, const AD &y); - - // order determining functions, see ordered.hpp - friend bool GreaterThanZero (const AD &x); - friend bool GreaterThanOrZero (const AD &x); - friend bool LessThanZero (const AD &x); - friend bool LessThanOrZero (const AD &x); - friend bool abs_geq - (const AD& x, const AD& y); - - // The identical property functions, see identical.hpp - friend bool IdenticalCon (const AD &x); - friend bool IdenticalZero (const AD &x); - friend bool IdenticalOne (const AD &x); - friend bool IdenticalEqualCon - (const AD &x, const AD &y); - - // EqualOpSeq function - friend bool EqualOpSeq - (const AD &u, const AD &v); - - // NearEqual function - friend bool NearEqual ( - const AD &x, const AD &y, const Base &r, const Base &a); - - friend bool NearEqual ( - const Base &x, const AD &y, const Base &r, const Base &a); - - friend bool NearEqual ( - const AD &x, const Base &y, const Base &r, const Base &a); - - // CondExp function - friend AD CondExpOp ( - enum CompareOp cop , - const AD &left , - const AD &right , - const AD &trueCase , - const AD &falseCase - ); - - // classes - friend class local::ADTape; - friend class local::recorder; - friend class ADFun; - friend class atomic_base; - friend class atomic_three; - friend class discrete; - friend class VecAD; - friend class VecAD_reference; - - // arithematic binary operators - friend AD operator + - (const AD &left, const AD &right); - friend AD operator - - (const AD &left, const AD &right); - friend AD operator * - (const AD &left, const AD &right); - friend AD operator / - (const AD &left, const AD &right); - - // comparison operators - friend bool operator < - (const AD &left, const AD &right); - friend bool operator <= - (const AD &left, const AD &right); - friend bool operator > - (const AD &left, const AD &right); - friend bool operator >= - (const AD &left, const AD &right); - friend bool operator == - (const AD &left, const AD &right); - friend bool operator != - (const AD &left, const AD &right); - - // input operator - friend std::istream& operator >> - (std::istream &is, AD &x); - - // output operations - friend std::ostream& operator << - (std::ostream &os, const AD &x); - friend void PrintFor ( - const AD& flag , - const char* before , - const AD& var , - const char* after - ); -public: - // type of value - typedef Base value_type; - - // implicit default constructor - AD(void); - - // destructor - ~AD(void) { } - - // use default implicit copy constructor - // AD(const AD &x); - -# ifdef CPPAD_FOR_TMB - // TMB would rather have implicit construction from double, - // CppAD uses default constructor and assignment to double instead. - AD(const double &d); -# else - // implicit construction from base type - AD(const Base &b); -# endif - - // implicit contructor from VecAD::reference - AD(const VecAD_reference &x); - - // explicit construction from some other type (depricated) - template explicit AD(const T &t); - - // conversion from AD to Base type - friend Base Value (const AD &x); - - // use default assignment operator - // AD& operator=(const AD &x); - - // assingment from base type - AD& operator=(const Base &b); - - // assignment from VecAD::reference - AD& operator=(const VecAD_reference &x); - - // assignment from some other type - template AD& operator=(const T &right); - - // compound assignment operators - AD& operator += (const AD &right); - AD& operator -= (const AD &right); - AD& operator *= (const AD &right); - AD& operator /= (const AD &right); - - // unary operators - AD operator +(void) const; - AD operator -(void) const; - - // interface so these functions need not be friends - AD abs_me(void) const; - AD acos_me(void) const; - AD asin_me(void) const; - AD atan_me(void) const; - AD cos_me(void) const; - AD cosh_me(void) const; - AD exp_me(void) const; - AD fabs_me(void) const; - AD log_me(void) const; - AD sin_me(void) const; - AD sign_me(void) const; - AD sinh_me(void) const; - AD sqrt_me(void) const; - AD tan_me(void) const; - AD tanh_me(void) const; - AD asinh_me(void) const; - AD acosh_me(void) const; - AD atanh_me(void) const; - AD erf_me(bool complemnet) const; - AD expm1_me(void) const; - AD log1p_me(void) const; - - // ---------------------------------------------------------- - // static public member functions - - // abort current AD 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 bool UnaryBool( - bool FunName(const Base &x), - const AD &x - ); - static bool BinaryBool( - bool FunName(const Base &x, const Base &y), - const AD &x , const AD &y - ); - -private: - // ----------------------------------------------------------------- - // 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 - - tape_id_ = id; - taddr_ = taddr; - ad_type_ = variable_enum; - } - // --------------------------------------------------------------- - // tape linking functions - // - // not static - local::ADTape* tape_this(void) const; - // - // static - static tape_id_t* tape_id_ptr(size_t thread); - static local::ADTape** tape_handle(size_t thread); - static local::ADTape* tape_manage(tape_manage_enum job); - static local::ADTape* tape_ptr(void); - static local::ADTape* tape_ptr(tape_id_t tape_id); -}; -// --------------------------------------------------------------------------- - -} // END_CPPAD_NAMESPACE - -// tape linking private functions -# include - -// operations that expect the AD template class to be defined - - -# endif diff --git a/build-config/cppad/include/cppad/core/ad_assign.hpp b/build-config/cppad/include/cppad/core/ad_assign.hpp deleted file mode 100644 index 7da1c79b..00000000 --- a/build-config/cppad/include/cppad/core/ad_assign.hpp +++ /dev/null @@ -1,144 +0,0 @@ -# ifndef CPPAD_CORE_AD_ASSIGN_HPP -# define CPPAD_CORE_AD_ASSIGN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------------- - -$begin ad_assign$$ -$spell - Vec - const -$$ - - -$section AD Assignment Operator$$ - -$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 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 -AD& AD::operator=(const AD &right) -{ value_ = right.value_; - tape_id_ = right.tape_id_; - taddr_ = right.taddr_; - ad_type_ = right.ad_type_; - - 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 -AD& AD::operator=(const Base &b) -{ value_ = b; - tape_id_ = 0; - // - CPPAD_ASSERT_UNKNOWN( ! ( Variable(*this) | Dynamic(*this) ) ); - return *this; -} - -/*! -Assignment to an ADVec element drops the vector information. - -\tparam Base -Base type for this AD object. -*/ -template -AD& AD::operator=(const VecAD_reference &x) -{ *this = x.ADBase(); - CPPAD_ASSERT_UNKNOWN( ! Dynamic(*this) ); - return *this; -} - -/*! -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. -There must be an assignment for Base from Type. - -\param t -is the object that is being assigned to an AD object. -*/ -template -template -AD& AD::operator=(const T &t) -{ *this = Base(t); - CPPAD_ASSERT_UNKNOWN( ! ( Variable(*this) | Dynamic(*this) ) ); - return *this; -} - - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/ad_binary.hpp b/build-config/cppad/include/cppad/core/ad_binary.hpp deleted file mode 100644 index e7c73218..00000000 --- a/build-config/cppad/include/cppad/core/ad_binary.hpp +++ /dev/null @@ -1,143 +0,0 @@ -# ifndef CPPAD_CORE_AD_BINARY_HPP -# define CPPAD_CORE_AD_BINARY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$begin ad_binary$$ -$spell - Op - VecAD - const -$$ - -$section AD Binary Arithmetic Operators$$ - - - - - - - -$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::reference%VecAD%VecAD::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_base/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 -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/ad_ctor.hpp b/build-config/cppad/include/cppad/core/ad_ctor.hpp deleted file mode 100644 index 27506f36..00000000 --- a/build-config/cppad/include/cppad/core/ad_ctor.hpp +++ /dev/null @@ -1,199 +0,0 @@ -# ifndef CPPAD_CORE_AD_CTOR_HPP -# define CPPAD_CORE_AD_CTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------------- - -$begin ad_ctor$$ -$spell - cppad - ctor - initializes - Vec - const -$$ - - -$section AD Constructors $$ - -$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 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 -AD::AD(const AD &x) -{ - value_ = x.value_; - tape_id_ = x.tape_id_; - taddr_ = x.taddr_; - ad_type_ = x.ad_type_; - - return; -} -\endcode -*/ - -/*! -Default Constructor. - -\tparam Base -Base type for this AD object. -*/ -template -AD::AD(void) -: value_() -, tape_id_(0) -, taddr_(0) -, ad_type_(constant_enum) -{ } - -// -------------------------------------------------------------------------- -# ifdef CPPAD_FOR_TMB -/*! -Constructor from double. - -\param d -is value corresponding to this AD object. -The tape identifier will be an invalid tape identifier, -so this object is initially a parameter. - -\par CPPAD_FOR_TMB -This constructor is defined when CPPAD_FOR_TMB is defined. -*/ -template -AD::AD(const double &d) -: value_( Base(d) ) -, tape_id_(0) -, taddr_(0) -, ad_type_(constant_enum) -{ // check that this is a parameter - CPPAD_ASSERT_UNKNOWN( Parameter(*this) ); -} -// -------------------------------------------------------------------------- -# else -// -------------------------------------------------------------------------- -/*! -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. - -\par CPPAD_FOR_TMB -This constructor is defined when CPPAD_FOR_TMB is not defined. -*/ -template -AD::AD(const Base &b) -: value_(b) -, tape_id_(0) -, taddr_(0) -, ad_type_(constant_enum) -{ // check that this is a parameter - CPPAD_ASSERT_UNKNOWN( Parameter(*this) ); -} -# endif -// -------------------------------------------------------------------------- - -/*! -Constructor from an ADVec element drops the vector information. - -\tparam Base -Base type for this AD object. -*/ -template -AD::AD(const VecAD_reference &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. -There must be a constructor for Base from Type. - -\param t -is the object that is being converted from T to AD. -*/ -template -template -AD::AD(const T &t) -: value_(Base(t)) -, tape_id_(0) -, taddr_(0) -, ad_type_(constant_enum) -{ } - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/ad_fun.hpp b/build-config/cppad/include/cppad/core/ad_fun.hpp deleted file mode 100644 index 6dd5885a..00000000 --- a/build-config/cppad/include/cppad/core/ad_fun.hpp +++ /dev/null @@ -1,876 +0,0 @@ -# ifndef CPPAD_CORE_AD_FUN_HPP -# define CPPAD_CORE_AD_FUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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% - include/cppad/core/optimize.hpp% - include/cppad/core/fun_check.hpp% - include/cppad/core/check_for_nan.hpp -%$$ - -$end -*/ -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file ad_fun.hpp -File used to define the ADFun class. -*/ - -/*! -Class used to hold function objects - -\tparam Base -A function object has a recording of AD operations. -It does it calculations using Base operations. -*/ - - -template -class ADFun { - // ADFun must be a friend of ADFun< AD > for base2ad to work. - template friend class ADFun; -private: - // ------------------------------------------------------------ - // Private member variables - // ------------------------------------------------------------ - - /// name of this function (so far only json operations use this value) - std::string function_name_; - - /// Did the previous optimzation exceed the collision limit - bool exceed_collision_limit_; - - /// 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 - local::pod_vector ind_taddr_; - - /// tape address and parameter flag for the dependent variables - local::pod_vector dep_taddr_; - - /// which dependent variables are actually parameters - local::pod_vector dep_parameter_; - - /// which operations can be conditionally skipped - /// Set during forward pass of order zero - local::pod_vector cskip_op_; - - /// Variable on the tape corresponding to each vecad load operation - /// (if zero, the operation corresponds to a parameter). - local::pod_vector load_op2var_; - - /// results of the forward mode calculations - local::pod_vector_maybe taylor_; - - /// used for subgraph reverse mode calculations. - /// Declared here to avoid reallocation for each call to subgraph_reverse. - /// Not in subgraph_info_ because it depends on Base. - local::pod_vector_maybe subgraph_partial_; - - /// the operation sequence corresponding to this object - local::player play_; - - /// subgraph information for this object - local::subgraph::subgraph_info subgraph_info_; - - /// 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_setvec 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_setvec for_jac_sparse_set_; - - - // ------------------------------------------------------------ - // Private member functions - // ------------------------------------------------------------ - - /// change the operation sequence corresponding to this object - template - void Dependent(local::ADTape *tape, const ADvector &y); - - // vector of bool version of ForSparseJac - // (doxygen in cppad/core/for_sparse_jac.hpp) - template - void ForSparseJacCase( - bool set_type , - bool transpose , - bool dependency, - size_t q , - const SetVector& r , - SetVector& s - ); - - // vector of std::set version of ForSparseJac - // (doxygen in cppad/core/for_sparse_jac.hpp) - template - void ForSparseJacCase( - const std::set& set_type , - bool transpose , - bool dependency, - size_t q , - const SetVector& r , - SetVector& s - ); - - // vector of bool version of RevSparseJac - // (doxygen in cppad/core/rev_sparse_jac.hpp) - template - void RevSparseJacCase( - bool set_type , - bool transpose , - bool dependency, - size_t p , - const SetVector& s , - SetVector& r - ); - - // vector of std::set version of RevSparseJac - // (doxygen in cppad/core/rev_sparse_jac.hpp) - template - void RevSparseJacCase( - const std::set& set_type , - bool transpose , - bool dependency, - size_t p , - const SetVector& s , - SetVector& r - ); - - // vector of bool version of ForSparseHes - // (doxygen in cppad/core/for_sparse_hes.hpp) - template - void ForSparseHesCase( - bool set_type , - const SetVector& r , - const SetVector& s , - SetVector& h - ); - - // vector of std::set version of ForSparseHes - // (doxygen in cppad/core/for_sparse_hes.hpp) - template - void ForSparseHesCase( - const std::set& set_type , - const SetVector& r , - const SetVector& s , - SetVector& h - ); - - // vector of bool version of RevSparseHes - // (doxygen in cppad/core/rev_sparse_hes.hpp) - template - void RevSparseHesCase( - bool set_type , - bool transpose , - size_t q , - const SetVector& s , - SetVector& h - ); - - // vector of std::set version of RevSparseHes - // (doxygen in cppad/core/rev_sparse_hes.hpp) - template - void RevSparseHesCase( - const std::set& set_type , - bool transpose , - size_t q , - const SetVector& s , - SetVector& h - ); - - // Forward mode version of SparseJacobian - // (doxygen in cppad/core/sparse_jacobian.hpp) - template - size_t SparseJacobianFor( - const BaseVector& x , - SetVector& p_transpose , - const SizeVector& row , - const SizeVector& col , - BaseVector& jac , - sparse_jacobian_work& work - ); - - // Reverse mode version of SparseJacobian - // (doxygen in cppad/core/sparse_jacobian.hpp) - template - size_t SparseJacobianRev( - const BaseVector& x , - SetVector& p , - const SizeVector& row , - const SizeVector& col , - BaseVector& jac , - sparse_jacobian_work& work - ); - - // combined sparse_list and sparse_pack version of SparseHessian - // (doxygen in cppad/core/sparse_hessian.hpp) - template - size_t SparseHessianCompute( - const BaseVector& x , - const BaseVector& w , - SetVector& sparsity , - const SizeVector& row , - const SizeVector& col , - BaseVector& hes , - sparse_hessian_work& work - ); - -public: - /// default constructor - ADFun(void); - - /// copy constructor - ADFun(const ADFun& g) = delete; - - // assignment operator - // (doxygen in cppad/core/fun_construct.hpp) - void operator=(const ADFun& f); - - // swap - void swap(ADFun& f); - - // move semenatics copy - ADFun(ADFun&& f); - - // move semantics assignment - void operator=(ADFun&& f); - - // create from Json or C++ AD graph - void from_json(const std::string& json); - void from_graph(const cpp_graph& graph_obj); - void from_graph( - const cpp_graph& graph_obj , - const vector& dyn2var , - const vector& var2dyn - ); - - // create a Json or C++ AD graph - std::string to_json(void); - void to_graph(cpp_graph& graph_obj); - - // create ADFun< AD > from this ADFun - // (doxygen in cppad/core/base2ad.hpp) - ADFun< AD, RecBase > base2ad(void) const; - - /// sequence constructor - template - ADFun(const ADvector &x, const ADvector &y); - - /// destructor - ~ADFun(void); - - /// set check_for_nan - void check_for_nan(bool value); - - /// get check_for_nan - bool check_for_nan(void) const; - - /// assign a new operation sequence - template - void Dependent(const ADvector &x, const ADvector &y); - - /// new_dynamic user API - template - void new_dynamic(const BaseVector& dynamic); - - /// forward mode user API, one order multiple directions. - template - BaseVector Forward(size_t q, size_t r, const BaseVector& x); - - /// forward mode user API, multiple orders one direction. - template - BaseVector Forward( - size_t q, const BaseVector& xq, std::ostream& s = std::cout - ); - - /// reverse mode sweep - template - BaseVector Reverse(size_t p, const BaseVector &v); - - // forward Jacobian sparsity pattern - // (doxygen in cppad/core/for_sparse_jac.hpp) - template - SetVector ForSparseJac( - size_t q, const SetVector &r, bool transpose = false, - bool dependency = false - ); - - // reverse Jacobian sparsity pattern - // (doxygen in cppad/core/rev_sparse_jac.hpp) - template - SetVector RevSparseJac( - size_t q, const SetVector &s, bool transpose = false, - bool dependency = false - ); - - // subgraph_reverse: select domain - // (doxygen in cppad/core/subgraph_reverse.hpp) - template - void subgraph_reverse( - const BoolVector& select_domain - ); - - // subgraph_reverse: compute derivative - // (doxygen in cppad/core/subgraph_reverse.hpp) - template - void subgraph_reverse_helper( - size_t q , - size_t ell , - SizeVector& col , - BaseVector& dw - ); - - // subgraph_reverse: compute derivative - // (doxygen in cppad/core/subgraph_reverse.hpp) - template - void subgraph_reverse( - size_t q , - size_t ell , - SizeVector& col , - BaseVector& dw - ); - - // subgraph_jac_rev: compute Jacobian - // (doxygen in cppad/core/subgraph_jac_rev.hpp) - template - void subgraph_jac_rev( - const BaseVector& x , - sparse_rcv& subset - ); - - // subgraph_jac_rev: compute Jacobian - // (doxygen missing in cppad/core/subgraph_jac_rev.hpp) - template - void subgraph_jac_rev( - const BoolVector& select_domain , - const BoolVector& select_range , - const BaseVector& x , - sparse_rcv& matrix_out - ); - - - // compute sparse Jacobian using forward mode - // (doxygen in cppad/core/sparse_jac.hpp) - template - size_t sparse_jac_for( - size_t group_max , - const BaseVector& x , - sparse_rcv& subset , - const sparse_rc& pattern , - const std::string& coloring , - sparse_jac_work& work - ); - - // compute sparse Jacobian using reverse mode - // (doxygen in cppad/core/sparse_jac.hpp) - template - size_t sparse_jac_rev( - const BaseVector& x , - sparse_rcv& subset , - const sparse_rc& pattern , - const std::string& coloring , - sparse_jac_work& work - ); - - // compute sparse Hessian - // (doxygen in cppad/core/sparse_hes.hpp) - template - size_t sparse_hes( - const BaseVector& x , - const BaseVector& w , - sparse_rcv& subset , - const sparse_rc& pattern , - const std::string& coloring , - sparse_hes_work& work - ); - - // compute sparsity pattern using subgraphs - // (doxygen in cppad/core/subgraph_sparsity.hpp) - template - void subgraph_sparsity( - const BoolVector& select_domain , - const BoolVector& select_range , - bool transpose , - sparse_rc& pattern_out - ); - - - // forward mode Jacobian sparsity pattern - // (doxygen in cppad/core/for_jac_sparsity.hpp) - template - void for_jac_sparsity( - const sparse_rc& pattern_in , - bool transpose , - bool dependency , - bool internal_bool , - sparse_rc& pattern_out - ); - - // reverse mode Jacobian sparsity pattern - // (doxygen in cppad/core/for_jac_sparsity.hpp) - template - void rev_jac_sparsity( - const sparse_rc& pattern_in , - bool transpose , - bool dependency , - bool internal_bool , - sparse_rc& pattern_out - ); - - // reverse mode Hessian sparsity pattern - // (doxygen in cppad/core/rev_hes_sparsity.hpp) - template - void rev_hes_sparsity( - const BoolVector& select_range , - bool transpose , - bool internal_bool , - sparse_rc& pattern_out - ); - - // forward mode Hessian sparsity pattern - // (doxygen in cppad/core/for_hes_sparsity.hpp) - template - void for_hes_sparsity( - const BoolVector& select_domain , - const BoolVector& select_range , - bool internal_bool , - sparse_rc& pattern_out - ); - - // forward mode Hessian sparsity pattern - // (see doxygen in cppad/core/for_sparse_hes.hpp) - template - SetVector ForSparseHes( - const SetVector &r, const SetVector &s - ); - - // internal set sparsity version of ForSparseHes - // (used by checkpoint functions only) - void ForSparseHesCheckpoint( - vector& r , - vector& s , - local::sparse::list_setvec& h - ); - - // reverse mode Hessian sparsity pattern - // (see doxygen in cppad/core/rev_sparse_hes.hpp) - template - SetVector RevSparseHes( - size_t q, const SetVector &s, bool transpose = false - ); - - // internal set sparsity version of RevSparseHes - // (doxygen in cppad/core/rev_sparse_hes.hpp) - // (used by checkpoint functions only) - void RevSparseHesCheckpoint( - size_t q , - vector& s , - bool transpose , - local::sparse::list_setvec& h - ); - - // internal set sparsity version of RevSparseJac - // (doxygen in cppad/core/rev_sparse_jac.hpp) - // (used by checkpoint functions only) - void RevSparseJacCheckpoint( - size_t q , - const local::sparse::list_setvec& r , - bool transpose , - bool dependency , - local::sparse::list_setvec& s - ); - - // internal set sparsity version of RevSparseJac - // (doxygen in cppad/core/for_sparse_jac.hpp) - // (used by checkpoint functions only) - void ForSparseJacCheckpoint( - size_t q , - const local::sparse::list_setvec& r , - bool transpose , - bool dependency , - local::sparse::list_setvec& s - ); - - /// did previous optimization exceed the collision limit - bool exceed_collision_limit(void) const - { return exceed_collision_limit_; } - - /// 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_.size_op_seq(); } - - /// amount of memory currently allocated for random access - /// of the operation sequence - size_t size_random(void) const - { return play_.size_random(); } - - /// number of parameters in the operation sequence - size_t size_par(void) const - { return play_.num_par_rec(); } - - /// number of independent dynamic parameters - size_t size_dyn_ind(void) const - { return play_.num_dynamic_ind(); } - - /// number of dynamic parameters - size_t size_dyn_par(void) const - { return play_.num_dynamic_par(); } - - /// number of dynamic parameters arguments - size_t size_dyn_arg(void) const - { return play_.num_dynamic_arg(); } - - /// 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_var_vecad_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 - BaseVector Jacobian(const BaseVector &x); - - /// calculate Hessian for one component of f - template - BaseVector Hessian(const BaseVector &x, const BaseVector &w); - template - BaseVector Hessian(const BaseVector &x, size_t i); - - /// forward mode calculation of partial w.r.t one domain component - template - BaseVector ForOne( - const BaseVector &x , - size_t j ); - - /// reverse mode calculation of derivative of one range component - template - BaseVector RevOne( - const BaseVector &x , - size_t i ); - - /// forward mode calculation of a subset of second order partials - template - BaseVector ForTwo( - const BaseVector &x , - const SizeVector_t &J , - const SizeVector_t &K ); - - /// reverse mode calculation of a subset of second order partials - template - BaseVector RevTwo( - const BaseVector &x , - const SizeVector_t &I , - const SizeVector_t &J ); - - /// calculate sparse Jacobians - template - BaseVector SparseJacobian( - const BaseVector &x - ); - template - BaseVector SparseJacobian( - const BaseVector &x , - const SetVector &p - ); - template - size_t SparseJacobianForward( - const BaseVector& x , - const SetVector& p , - const SizeVector& r , - const SizeVector& c , - BaseVector& jac , - sparse_jacobian_work& work - ); - template - size_t SparseJacobianReverse( - const BaseVector& x , - const SetVector& p , - const SizeVector& r , - const SizeVector& c , - BaseVector& jac , - sparse_jacobian_work& work - ); - - /// calculate sparse Hessians - template - BaseVector SparseHessian( - const BaseVector& x , - const BaseVector& w - ); - template - BaseVector SparseHessian( - const BaseVector& x , - const BaseVector& w , - const BoolVector& p - ); - template - size_t SparseHessian( - const BaseVector& x , - const BaseVector& w , - const SetVector& p , - const SizeVector& r , - const SizeVector& c , - BaseVector& 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 ) const; - - // clear all subgraph information - void clear_subgraph(void); - // ------------------- Deprecated ----------------------------- - - /// deprecated: assign a new operation sequence - template - 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 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; - total += play_.size_op_seq(); - total += play_.size_random(); - total += subgraph_info_.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::reference operands - bool use_VecAD(void) const - { return play_.num_var_vecad_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 -# include -# include -# include -# include -# include -# include -# include -# include -# include - -// user interfaces -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/ad_io.hpp b/build-config/cppad/include/cppad/core/ad_io.hpp deleted file mode 100644 index 4ac757ab..00000000 --- a/build-config/cppad/include/cppad/core/ad_io.hpp +++ /dev/null @@ -1,220 +0,0 @@ -# ifndef CPPAD_CORE_AD_IO_HPP -# define CPPAD_CORE_AD_IO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin ad_input$$ -$spell - VecAD - std - istream - const -$$ - - -$section AD Input Stream Operator$$ - -$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. - -$end ------------------------------------------------------------------------------- -$begin ad_output$$ -$spell - VecAD - std - ostream - const -$$ - - -$section AD Output Stream Operator$$ - -$head Syntax$$ -$icode%os% << %x%$$ - -$head See Also$$ -$cref PrintFor$$ - -$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. - -$end ------------------------------------------------------------------------------- -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file ad_io.hpp -AD input and ouput stream operators. -*/ -// --------------------------------------------------------------------------- -/*! -Read an AD 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 -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -std::istream& operator >> (std::istream& is, AD& x) -{ // like assignment to a base type value - x.tape_id_ = 0; - CPPAD_ASSERT_UNKNOWN( Parameter(x) ); - return (is >> x.value_); -} -// --------------------------------------------------------------------------- -/*! -Write an AD 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 -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -std::ostream& operator << (std::ostream &os, const AD &x) -{ return (os << x.value_); } -// --------------------------------------------------------------------------- -/*! -Write a VecAD_reference 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 -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -std::ostream& operator << (std::ostream &os, const VecAD_reference &x) -{ return (os << x.ADBase()); } - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/ad_to_string.hpp b/build-config/cppad/include/cppad/core/ad_to_string.hpp deleted file mode 100644 index 71c669f7..00000000 --- a/build-config/cppad/include/cppad/core/ad_to_string.hpp +++ /dev/null @@ -1,70 +0,0 @@ -# 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 the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$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. - -$end -*/ -# include -# include - -namespace CppAD { - - // Template definition is in cppad/utility/to_string.hpp. - // Partial specialzation for AD types - template - struct to_string_struct< CppAD::AD > - { std::string operator()(const CppAD::AD& value) - { to_string_struct ts; - return ts( Value( Var2Par( value ) ) ); } - }; - -} - -# endif diff --git a/build-config/cppad/include/cppad/core/ad_type.hpp b/build-config/cppad/include/cppad/core/ad_type.hpp deleted file mode 100644 index 4b1194c4..00000000 --- a/build-config/cppad/include/cppad/core/ad_type.hpp +++ /dev/null @@ -1,59 +0,0 @@ -# ifndef CPPAD_CORE_AD_TYPE_HPP -# define CPPAD_CORE_AD_TYPE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/* -$begin ad_type_enum$$ -$spell - enum - typedef - CppAD - namespace -$$ - -$section Type of AD an Object$$ - -$head User API$$ -The values $code constant_enum$$, $code dynamic_enum$$ and -$code variable_enum$$ are in the user API; see -$cref/ad_type/atomic_three/ad_type/$$ for $code atomic_three$$ functions. - -$head typedef$$ -This typedef is in the $code CppAD$$ namespace: -$srccode%hpp% */ - typedef enum { - constant_enum, // constant parameter - dynamic_enum, // dynamic parameter - variable_enum, // variable - number_ad_type_enum // number of valid values for type_ad_enum - } ad_type_enum; -/* %$$ - -$head is_pod$$ -The following informs $cref is_pod$$ that this is plain old data. -$srccode%hpp% */ - namespace local { - template <> inline bool - is_pod(void) { return true; } - } -/* %$$ -$end -*/ - -} // END_CPPAD_NAMESPACE - - -# endif diff --git a/build-config/cppad/include/cppad/core/ad_valued.hpp b/build-config/cppad/include/cppad/core/ad_valued.hpp deleted file mode 100644 index 5db4344a..00000000 --- a/build-config/cppad/include/cppad/core/ad_valued.hpp +++ /dev/null @@ -1,50 +0,0 @@ -# ifndef CPPAD_CORE_AD_VALUED_HPP -# define CPPAD_CORE_AD_VALUED_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin ADValued$$ -$spell -$$ - - -$section AD Valued Operations and Functions$$ - -$comment atomic.omh includes atomic_two.hpp$$ -$childtable% - include/cppad/core/arithmetic.hpp% - include/cppad/core/standard_math.hpp% - include/cppad/core/cond_exp.hpp% - include/cppad/core/discrete/user.omh% - include/cppad/core/numeric_limits.hpp% - include/cppad/core/atomic/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 -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/add.hpp b/build-config/cppad/include/cppad/core/add.hpp deleted file mode 100644 index 9b41670f..00000000 --- a/build-config/cppad/include/cppad/core/add.hpp +++ /dev/null @@ -1,131 +0,0 @@ -# ifndef CPPAD_CORE_ADD_HPP -# define CPPAD_CORE_ADD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD operator + (const AD &left , const AD &right) -{ - // compute the Base part of this AD object - AD result; - result.value_ = left.value_ + right.value_; - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "Add: AD variables or dynamic parameters on different threads." - ); - 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; - result.ad_type_ = variable_enum; - } - else if( (! dyn_right) & 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 = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( var_right ) - { if( (! dyn_left) & 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 = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter result - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::add_dyn, arg0, arg1 - ); - result.tape_id_ = tape_id; - result.ad_type_ = dynamic_enum; - } - return result; -} - -// convert other cases into the case above -CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(+) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/add_eq.hpp b/build-config/cppad/include/cppad/core/add_eq.hpp deleted file mode 100644 index eb96b0b4..00000000 --- a/build-config/cppad/include/cppad/core/add_eq.hpp +++ /dev/null @@ -1,128 +0,0 @@ -# ifndef CPPAD_CORE_ADD_EQ_HPP -# define CPPAD_CORE_ADD_EQ_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD& AD::operator += (const AD &right) -{ - // compute the Base part - Base left; - left = value_; - value_ += right.value_; - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "+= : AD variables or dynamic parameters on different threads." - ); - 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); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - else if( dyn_right | (! 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 = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - tape->Rec_.PutArg(p, taddr_); - // put operator in the tape - taddr_ = tape->Rec_.PutOp(local::AddpvOp); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - } - else if( var_right ) - { if( (! dyn_left) & 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 = taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(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; - ad_type_ = variable_enum; - } - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter results - taddr_ = tape->Rec_.put_dyn_par( - value_, local::add_dyn, arg0, arg1 - ); - tape_id_ = tape_id; - ad_type_ = dynamic_enum; - } - return *this; -} - -CPPAD_FOLD_ASSIGNMENT_OPERATOR(+=) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/arithmetic.hpp b/build-config/cppad/include/cppad/core/arithmetic.hpp deleted file mode 100644 index 40484071..00000000 --- a/build-config/cppad/include/cppad/core/arithmetic.hpp +++ /dev/null @@ -1,42 +0,0 @@ -# ifndef CPPAD_CORE_ARITHMETIC_HPP -# define CPPAD_CORE_ARITHMETIC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$begin Arithmetic$$ -$spell - Op - const -$$ - - - -$section AD Arithmetic Operators and Compound Assignments$$ - -$childtable% - include/cppad/core/unary_plus.hpp% - include/cppad/core/unary_minus.hpp% - include/cppad/core/ad_binary.hpp% - include/cppad/core/compound_assign.hpp -%$$ - -$end -------------------------------------------------------------------------------- -*/ -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/atan2.hpp b/build-config/cppad/include/cppad/core/atan2.hpp deleted file mode 100644 index d975d7b6..00000000 --- a/build-config/cppad/include/cppad/core/atan2.hpp +++ /dev/null @@ -1,152 +0,0 @@ -# ifndef CPPAD_CORE_ATAN2_HPP -# define CPPAD_CORE_ATAN2_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-21 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$begin atan2$$ -$spell - Vec - CppAD - namespace - std - atan - const -$$ - - -$section AD Two Argument Inverse Tangent Function$$ - -$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. - -$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 -AD atan2 (const AD &y, const AD &x) -{ // - // zero, pi2, pi - AD zero(0.); - AD pi2(2. * atan(1.)); - AD pi(2. * pi2); - // - // abs_x, abs_y - // Not using fabs because its derivative is zero at zero - AD abs_x = CondExpGe(x, zero, x, -x); - AD abs_y = CondExpGe(y, zero, y, -y); - // - // first - // This is the result for first quadrant: x >= 0 , y >= 0 - AD alpha = atan(abs_y / abs_x); - AD beta = pi2 - atan(abs_x / abs_y); - AD first = CondExpGt(abs_x, abs_y, alpha, beta); - // - // second - // This is the result for second quadrant: x <= 0 , y >= 0 - AD second = pi - first; - // - // third - // This is the result for third quadrant: x <= 0 , y <= 0 - AD third = - pi + first; - // - // fourth - // This is the result for fourth quadrant: x >= 0 , y <= 0 - AD fourth = - first; - // - // alpha - // This is the result for x >= 0 - alpha = CondExpGe(y, zero, first, fourth); - // - // beta - // This is the result for x <= 0 - beta = CondExpGe(y, zero, second, third); - // - // - AD result = CondExpGe(x, zero, alpha, beta); - return result; -} -// END CondExp - -template -AD atan2 (const VecAD_reference &y, const AD &x) -{ return atan2( y.ADBase() , x ); } - -template -AD atan2 (const AD &y, const VecAD_reference &x) -{ return atan2( y , x.ADBase() ); } - -template -AD atan2 -(const VecAD_reference &y, const VecAD_reference &x) -{ return atan2( y.ADBase() , x.ADBase() ); } - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/atomic.omh b/build-config/cppad/include/cppad/core/atomic/atomic.omh deleted file mode 100644 index 30dc4b19..00000000 --- a/build-config/cppad/include/cppad/core/atomic/atomic.omh +++ /dev/null @@ -1,26 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin atomic$$ - -$section Atomic AD Functions$$ - -$childtable% - include/cppad/core/atomic/atomic_three.hpp% - include/cppad/core/chkpoint_two/chkpoint_two.hpp -%$$ - -$head Deprecated Atomic Function$$ -$cref atomic_one$$, -$cref atomic_two$$, -$cref chkpoint_one$$. - -$end diff --git a/build-config/cppad/include/cppad/core/atomic/atomic_one.hpp b/build-config/cppad/include/cppad/core/atomic/atomic_one.hpp deleted file mode 100644 index 9b0bd155..00000000 --- a/build-config/cppad/include/cppad/core/atomic/atomic_one.hpp +++ /dev/null @@ -1,1058 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_ATOMIC_ONE_HPP -# define CPPAD_CORE_ATOMIC_ATOMIC_ONE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_one$$ -$spell - hes - std - Jacobian - jac - Tvector - afun - vx - vy - bool - namespace - CppAD - const - Taylor - tx - ty - px - py -$$ - -$section Defining Atomic Functions: First Generation$$ - -$head Deprecated 2013-05-27$$ -Using $code CPPAD_USER_ATOMIC$$ has been deprecated. -Use $cref atomic_three$$ instead. - -$head Syntax Function$$ -$codei%CPPAD_USER_ATOMIC(%afun%, %Tvector%, %Base%, - %forward%, %reverse%, %for_jac_sparse%, %rev_jac_sparse%, %rev_hes_sparse% -) -%$$ - -$subhead Use Function$$ -$icode%afun%(%id%, %ax%, %ay%) -%$$ - -$subhead Callback Routines$$ -$icode%ok% = %forward%(%id%, %k%, %n%, %m%, %vx%, %vy%, %tx%, %ty%) -%$$ -$icode%ok% = %reverse%(%id%, %k%, %n%, %m%, %tx%, %ty%, %px%, %py%) -%$$ -$icode%ok% = %for_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%) -%$$ -$icode%ok% = %rev_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%) -%$$ -$icode%ok% = %rev_hes_sparse%(%id%, %n%, %m%, %q%, %r%, %s%, %t%, %u%, %v%) -%$$ - -$subhead Free Static Memory$$ -$codei%user_atomic<%Base%>::clear()%$$ - -$head Purpose$$ -In some cases, the user knows how to compute the derivative -of a function -$latex \[ - y = f(x) \; {\rm where} \; f : \B{R}^n \rightarrow \B{R}^m -\] $$ -more efficiently than by coding it using $codei%AD<%Base%>%$$ -$cref/atomic_base/glossary/Operation/Atomic/$$ operations -and letting CppAD do the rest. -In this case, $code CPPAD_USER_ATOMIC$$ can be used -add the user code for $latex f(x)$$, and its derivatives, -to the set of $codei%AD<%Base%>%$$ atomic operations. -$pre - -$$ -Another possible purpose is to reduce the size of the tape. - -$head Partial Implementation$$ -The routines -$cref/forward/atomic_one/forward/$$, -$cref/reverse/atomic_one/reverse/$$, -$cref/for_jac_sparse/atomic_one/for_jac_sparse/$$, -$cref/rev_jac_sparse/atomic_one/rev_jac_sparse/$$, and -$cref/rev_hes_sparse/atomic_one/rev_hes_sparse/$$, -must be defined by the user. -The $icode forward$$ the routine, -for the case $icode%k% = 0%$$, must be implemented. -Functions with the correct prototype, -that just return $code false$$, -can be used for the other cases -(unless they are required by your calculations). -For example, you need not implement -$icode forward$$ for the case $icode%k% == 2%$$ until you require -forward mode calculation of second derivatives. - -$head CPPAD_USER_ATOMIC$$ -The macro -$codei% -CPPAD_USER_ATOMIC(%afun%, %Tvector%, %Base%, - %forward%, %reverse%, %for_jac_sparse%, %rev_jac_sparse%, %rev_hes_sparse% -) -%$$ -defines the $codei%AD<%Base%>%$$ routine $icode afun$$. -This macro can be placed within a namespace -(not the $code CppAD$$ namespace) -but must be outside of any routine. - -$subhead Tvector$$ -The macro argument $icode Tvector$$ must be a -$cref/simple vector template class/SimpleVector/$$. -It determines the type of vectors used as arguments to the routine -$icode afun$$. - -$subhead Base$$ -The macro argument $icode Base$$ specifies the -$cref/base type/base_require/$$ -corresponding to $codei%AD<%Base>%$$ operation sequences. -Calling the routine $icode afun$$ will add the operator defined -by this macro to an $codei%AD<%Base>%$$ operation sequence. - -$head ok$$ -For all routines documented below, -the return value $icode ok$$ has prototype -$codei% - bool %ok% -%$$ -If it is $code true$$, the corresponding evaluation succeeded, -otherwise it failed. - -$head id$$ -For all routines documented below, -the argument $icode id$$ has prototype -$codei% - size_t %id% -%$$ -Its value in all other calls is the same as in the corresponding -call to $icode afun$$. -It can be used to store and retrieve extra information about -a specific call to $icode afun$$. - -$head k$$ -For all routines documented below, the argument $icode k$$ has prototype -$codei% - size_t %k% -%$$ -The value $icode%k%$$ is the order of the Taylor coefficient that -we are evaluating ($cref/forward/atomic_one/forward/$$) -or taking the derivative of ($cref/reverse/atomic_one/reverse/$$). - -$head n$$ -For all routines documented below, -the argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ -It is the size of the vector $icode ax$$ in the corresponding call to -$icode%afun%(%id%, %ax%, %ay%)%$$; i.e., -the dimension of the domain space for $latex y = f(x)$$. - -$head m$$ -For all routines documented below, the argument $icode m$$ has prototype -$codei% - size_t %m% -%$$ -It is the size of the vector $icode ay$$ in the corresponding call to -$icode%afun%(%id%, %ax%, %ay%)%$$; i.e., -the dimension of the range space for $latex y = f(x)$$. - -$head tx$$ -For all routines documented below, -the argument $icode tx$$ has prototype -$codei% - const CppAD::vector<%Base%>& %tx% -%$$ -and $icode%tx%.size() >= (%k% + 1) * %n%$$. -For $latex j = 0 , \ldots , n-1$$ and $latex \ell = 0 , \ldots , k$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - x_j^\ell & = & tx [ j * ( k + 1 ) + \ell ] - \\ - X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^k t^k -\end{array} -\] $$ -If $icode%tx%.size() > (%k% + 1) * %n%$$, -the other components of $icode tx$$ are not specified and should not be used. -Note that superscripts represent an index for $latex x_j^\ell$$ -and an exponent for $latex t^\ell$$. -Also note that the Taylor coefficients for $latex X(t)$$ correspond -to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - x_j^\ell = \frac{1}{ \ell ! } X_j^{(\ell)} (0) -\] $$ - -$head ty$$ -In calls to $cref/forward/atomic_one/forward/$$, -the argument $icode ty$$ has prototype -$codei% - CppAD::vector<%Base%>& %ty% -%$$ -while in calls to $cref/reverse/atomic_one/reverse/$$ it has prototype -$codei% - const CppAD::vector<%Base%>& %ty% -%$$ -For all calls, $icode%tx%.size() >= (%k% + 1) * %m%$$. -For $latex i = 0 , \ldots , m-1$$ and $latex \ell = 0 , \ldots , k$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - y_i^\ell & = & ty [ i * ( k + 1 ) + \ell ] - \\ - Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^k t^k + o ( t^k ) -\end{array} -\] $$ -where $latex o( t^k ) / t^k \rightarrow 0$$ as $latex t \rightarrow 0$$. -If $icode%ty%.size() > (%k% + 1) * %m%$$, -the other components of $icode ty$$ are not specified and should not be used. -Note that superscripts represent an index for $latex y_j^\ell$$ -and an exponent for $latex t^\ell$$. -Also note that the Taylor coefficients for $latex Y(t)$$ correspond -to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - y_j^\ell = \frac{1}{ \ell ! } Y_j^{(\ell)} (0) -\] $$ - -$subhead forward$$ -In the case of $icode forward$$, -for $latex i = 0 , \ldots , m-1$$, $latex ty[ i *( k + 1) + k ]$$ is an output -and all the other components of $icode ty$$ are inputs. - -$subhead reverse$$ -In the case of $icode reverse$$, -all the components of $icode ty$$ are inputs. - -$head afun$$ -The macro argument $icode afun$$, -is the name of the AD function corresponding to this atomic -operation (as it is used in the source code). -CppAD uses the other functions, -where the arguments are vectors with elements of type $icode Base$$, -to implement the function -$codei% - %afun%(%id%, %ax%, %ay%) -%$$ -where the argument are vectors with elements of type $codei%AD<%Base%>%$$. - -$subhead ax$$ -The $icode afun$$ argument $icode ax$$ has prototype -$codei% - const %Tvector%< AD<%Base%> >& %ax% -%$$ -It is the argument vector $latex x \in \B{R}^n$$ -at which the $codei%AD<%Base%>%$$ version of -$latex y = f(x)$$ is to be evaluated. -The dimension of the domain space for $latex y = f (x)$$ -is specified by $cref/n/atomic_one/n/$$ $codei%= %ax%.size()%$$, -which must be greater than zero. - -$subhead ay$$ -The $icode afun$$ result $icode ay$$ has prototype -$codei% - %Tvector%< AD<%Base%> >& %ay% -%$$ -The input values of its elements -are not specified (must not matter). -Upon return, it is the $codei%AD<%Base%>%$$ version of the -result vector $latex y = f(x)$$. -The dimension of the range space for $latex y = f (x)$$ -is specified by $cref/m/atomic_one/m/$$ $codei%= %ay%.size()%$$, -which must be greater than zero. - -$subhead Parallel Mode$$ -The first call to -$codei% - %afun%(%id%, %ax%, %ay%) -%$$ -must not be in $cref/parallel/ta_in_parallel/$$ mode. -In addition, the -$cref/atomic_one clear/atomic_one/clear/$$ -routine cannot be called while in parallel mode. - -$head forward$$ -The macro argument $icode forward$$ is a -user defined function -$codei% - %ok% = %forward%(%id%, %k%, %n%, %m%, %vx%, %vy%, %tx%, %ty%) -%$$ -that computes results during a $cref/forward/Forward/$$ mode sweep. -For this call, we are given the Taylor coefficients in $icode tx$$ -form order zero through $icode k$$, -and the Taylor coefficients in $icode ty$$ with order less than $icode k$$. -The $icode forward$$ routine computes the -$icode k$$ order Taylor coefficients for $latex y$$ using the definition -$latex Y(t) = f[ X(t) ]$$. -For example, for $latex i = 0 , \ldots , m-1$$, -$latex \[ -\begin{array}{rcl} -y_i^0 & = & Y(0) - = f_i ( x^0 ) -\\ -y_i^1 & = & Y^{(1)} ( 0 ) - = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 ) - = f_i^{(1)} ( x^0 ) x^1 -\\ -y_i^2 -& = & \frac{1}{2 !} Y^{(2)} (0) -\\ -& = & \frac{1}{2} X^{(1)} (0)^\R{T} f_i^{(2)} ( x^0 ) X^{(1)} ( 0 ) - + \frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 ) -\\ -& = & \frac{1}{2} (x^1)^\R{T} f_i^{(2)} ( x^0 ) x^1 - + f_i^{(1)} ( x^0 ) x^2 -\end{array} -\] $$ -Then, for $latex i = 0 , \ldots , m-1$$, it sets -$latex \[ - ty [ i * (k + 1) + k ] = y_i^k -\] $$ -The other components of $icode ty$$ must be left unchanged. - -$subhead Usage$$ -This routine is used, -with $icode%vx%.size() > 0%$$ and $icode%k% == 0%$$, -by calls to $icode afun$$. -It is used, -with $icode%vx%.size() = 0%$$ and -$icode k$$ equal to the order of the derivative begin computed, -by calls to $cref/forward/forward_order/$$. - -$subhead vx$$ -The $icode forward$$ argument $icode vx$$ has prototype -$codei% - const CppAD::vector& %vx% -%$$ -The case $icode%vx%.size() > 0%$$ occurs -once for each call to $icode afun$$, -during the call, -and before any of the other callbacks corresponding to that call. -Hence such a call can be used to cache information attached to -the corresponding $icode id$$ -(such as the elements of $icode vx$$). -If $icode%vx%.size() > 0%$$ then -$icode%k% == 0%$$, -$icode%vx%.size() >= %n%$$, and -for $latex j = 0 , \ldots , n-1$$, -$icode%vx%[%j%]%$$ is true if and only if -$icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$. -$pre - -$$ -If $icode%vx%.size() == 0%$$, -then $icode%vy%.size() == 0%$$ and neither of these vectors -should be used. - -$subhead vy$$ -The $icode forward$$ argument $icode vy$$ has prototype -$codei% - CppAD::vector& %vy% -%$$ -If $icode%vy%.size() == 0%$$, it should not be used. -Otherwise, -$icode%k% == 0%$$ and $icode%vy%.size() >= %m%$$. -The input values of the elements of $icode vy$$ -are not specified (must not matter). -Upon return, for $latex j = 0 , \ldots , m-1$$, -$icode%vy%[%i%]%$$ is true if and only if -$icode%ay%[%j%]%$$ is a variable. -(CppAD uses $icode vy$$ to reduce the necessary computations.) - -$head reverse$$ -The macro argument $icode reverse$$ -is a user defined function -$codei% - %ok% = %reverse%(%id%, %k%, %n%, %m%, %tx%, %ty%, %px%, %py%) -%$$ -that computes results during a $cref/reverse/Reverse/$$ mode sweep. -The input value of the vectors $icode tx$$ and $icode ty$$ -contain Taylor coefficient, up to order $icode k$$, -for $latex X(t)$$ and $latex Y(t)$$ respectively. -We use the $latex \{ x_j^\ell \}$$ and $latex \{ y_i^\ell \}$$ -to denote these Taylor coefficients where the implicit range indices are -$latex i = 0 , \ldots , m-1$$, -$latex j = 0 , \ldots , n-1$$, -$latex \ell = 0 , \ldots , k$$. -Using the calculations done by $cref/forward/atomic_one/forward/$$, -the Taylor coefficients $latex \{ y_i^\ell \}$$ are a function of the Taylor -coefficients for $latex \{ x_j^\ell \}$$; i.e., given $latex y = f(x)$$ -we define the function -$latex F : \B{R}^{n \times (k+1)} \rightarrow \B{R}^{m \times (k+1)}$$ by -$latex \[ -y_i^\ell = F_i^\ell ( \{ x_j^\ell \} ) -\] $$ -We use $latex G : \B{R}^{m \times (k+1)} \rightarrow \B{R}$$ -to denote an arbitrary scalar valued function of the Taylor coefficients for -$latex Y(t)$$ and write $latex z = G( \{ y_i^\ell \} )$$. -The $code reverse$$ routine -is given the derivative of $latex z$$ with respect to -$latex \{ y_i^\ell \}$$ and computes its derivative with respect -to $latex \{ x_j^\ell \}$$. - -$subhead Usage$$ -This routine is used, -with $icode%k% + 1%$$ equal to the order of the derivative being calculated, -by calls to $cref/reverse/reverse_any/$$. - -$subhead py$$ -The $icode reverse$$ argument $icode py$$ has prototype -$codei% - const CppAD::vector<%Base%>& %py% -%$$ -and $icode%py%.size() >= (%k% + 1) * %m%$$. -For $latex i = 0 , \ldots , m-1$$ and $latex \ell = 0 , \ldots , k$$, -$latex \[ - py[ i * (k + 1 ) + \ell ] = \partial G / \partial y_i^\ell -\] $$ -If $icode%py%.size() > (%k% + 1) * %m%$$, -the other components of $icode py$$ are not specified and should not be used. - -$subhead px$$ -We define the function -$latex \[ -H ( \{ x_j^\ell \} ) = G[ F( \{ x_j^\ell \} ) ] -\] $$ -The $icode reverse$$ argument $icode px$$ has prototype -$codei% - CppAD::vector<%Base%>& %px% -%$$ -and $icode%px%.size() >= (%k% + 1) * %n%$$. -The input values of the elements of $icode px$$ -are not specified (must not matter). -Upon return, -for $latex j = 0 , \ldots , n-1$$ and $latex p = 0 , \ldots , k$$, -$latex \[ -\begin{array}{rcl} -px [ j * (k + 1) + p ] & = & \partial H / \partial x_j^p -\\ -& = & -( \partial G / \partial \{ y_i^\ell \} ) - ( \partial \{ y_i^\ell \} / \partial x_j^p ) -\\ -& = & -\sum_{i=0}^{m-1} \sum_{\ell=0}^k -( \partial G / \partial y_i^\ell ) ( \partial y_i^\ell / \partial x_j^p ) -\\ -& = & -\sum_{i=0}^{m-1} \sum_{\ell=p}^k -py[ i * (k + 1 ) + \ell ] ( \partial F_i^\ell / \partial x_j^p ) -\end{array} -\] $$ -Note that we have used the fact that for $latex \ell < p$$, -$latex \partial F_i^\ell / \partial x_j^p = 0$$. -If $icode%px%.size() > (%k% + 1) * %n%$$, -the other components of $icode px$$ are not specified and should not be used. - -$head for_jac_sparse$$ -The macro argument $icode for_jac_sparse$$ -is a user defined function -$codei% - %ok% = %for_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%) -%$$ -that is used to compute results during a forward Jacobian sparsity sweep. -For a fixed $latex n \times q$$ matrix $latex R$$, -the Jacobian of $latex f( x + R * u)$$ with respect to $latex u \in \B{R}^q$$ is -$latex \[ - S(x) = f^{(1)} (x) * R -\] $$ -Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$, -$icode for_jac_sparse$$ computes a sparsity pattern for $latex S(x)$$. - -$subhead Usage$$ -This routine is used by calls to $cref ForSparseJac$$. - -$subhead q$$ -The $icode for_jac_sparse$$ argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of columns in -$latex R \in \B{R}^{n \times q}$$ and the Jacobian -$latex S(x) \in \B{R}^{m \times q}$$. - -$subhead r$$ -The $icode for_jac_sparse$$ argument $icode r$$ has prototype -$codei% - const CppAD::vector< std::set >& %r% -%$$ -and $icode%r%.size() >= %n%$$. -For $latex j = 0 , \ldots , n-1$$, -all the elements of $icode%r%[%j%]%$$ are between -zero and $icode%q%-1%$$ inclusive. -This specifies a sparsity pattern for the matrix $latex R$$. - -$subhead s$$ -The $icode for_jac_sparse$$ return value $icode s$$ has prototype -$codei% - CppAD::vector< std::set >& %s% -%$$ -and $icode%s%.size() >= %m%%$$. -The input values of its sets -are not specified (must not matter). Upon return -for $latex i = 0 , \ldots , m-1$$, -all the elements of $icode%s%[%i%]%$$ are between -zero and $icode%q%-1%$$ inclusive. -This represents a sparsity pattern for the matrix $latex S(x)$$. - -$head rev_jac_sparse$$ -The macro argument $icode rev_jac_sparse$$ -is a user defined function -$codei% - %ok% = %rev_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%) -%$$ -that is used to compute results during a reverse Jacobian sparsity sweep. -For a fixed $latex q \times m$$ matrix $latex S$$, -the Jacobian of $latex S * f( x )$$ with respect to $latex x \in \B{R}^n$$ is -$latex \[ - R(x) = S * f^{(1)} (x) -\] $$ -Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex S$$, -$icode rev_jac_sparse$$ computes a sparsity pattern for $latex R(x)$$. - -$subhead Usage$$ -This routine is used by calls to $cref RevSparseJac$$ -and to $cref optimize$$. - - -$subhead q$$ -The $icode rev_jac_sparse$$ argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of rows in -$latex S \in \B{R}^{q \times m}$$ and the Jacobian -$latex R(x) \in \B{R}^{q \times n}$$. - -$subhead s$$ -The $icode rev_jac_sparse$$ argument $icode s$$ has prototype -$codei% - const CppAD::vector< std::set >& %s% -%$$ -and $icode%s%.size() >= %m%$$. -For $latex i = 0 , \ldots , m-1$$, -all the elements of $icode%s%[%i%]%$$ -are between zero and $icode%q%-1%$$ inclusive. -This specifies a sparsity pattern for the matrix $latex S^\R{T}$$. - -$subhead r$$ -The $icode rev_jac_sparse$$ return value $icode r$$ has prototype -$codei% - CppAD::vector< std::set >& %r% -%$$ -and $icode%r%.size() >= %n%$$. -The input values of its sets -are not specified (must not matter). -Upon return for $latex j = 0 , \ldots , n-1$$, -all the elements of $icode%r%[%j%]%$$ -are between zero and $icode%q%-1%$$ inclusive. -This represents a sparsity pattern for the matrix $latex R(x)^\R{T}$$. - -$head rev_hes_sparse$$ -The macro argument $icode rev_hes_sparse$$ -is a user defined function -$codei% - %ok% = %rev_hes_sparse%(%id%, %n%, %m%, %q%, %r%, %s%, %t%, %u%, %v%) -%$$ -There is an unspecified scalar valued function -$latex g : \B{R}^m \rightarrow \B{R}$$. -Given a sparsity pattern for $latex R$$ -and information about the function $latex z = g(y)$$, -this routine computes the sparsity pattern for -$latex \[ - V(x) = (g \circ f)^{(2)}( x ) R -\] $$ - -$subhead Usage$$ -This routine is used by calls to $cref RevSparseHes$$. - -$subhead q$$ -The $icode rev_hes_sparse$$ argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of columns in the sparsity patterns. - -$subhead r$$ -The $icode rev_hes_sparse$$ argument $icode r$$ has prototype -$codei% - const CppAD::vector< std::set >& %r% -%$$ -and $icode%r%.size() >= %n%$$. -For $latex j = 0 , \ldots , n-1$$, -all the elements of $icode%r%[%j%]%$$ are between -zero and $icode%q%-1%$$ inclusive. -This specifies a sparsity pattern for the matrix $latex R \in \B{R}^{n \times q}$$. - -$subhead s$$ -The $icode rev_hes_sparse$$ argument $icode s$$ has prototype -$codei% - const CppAD::vector& %s% -%$$ -and $icode%s%.size() >= %m%$$. -This specifies a sparsity pattern for the matrix -$latex S(x) = g^{(1)} (y) \in \B{R}^{1 \times m}$$. - -$subhead t$$ -The $icode rev_hes_sparse$$ argument $icode t$$ has prototype -$codei% - CppAD::vector& %t% -%$$ -and $icode%t%.size() >= %n%$$. -The input values of its elements -are not specified (must not matter). -Upon return it represents a sparsity pattern for the matrix -$latex T(x) \in \B{R}^{1 \times n}$$ defined by -$latex \[ -T(x) = (g \circ f)^{(1)} (x) = S(x) * f^{(1)} (x) -\] $$ - -$subhead u$$ -The $icode rev_hes_sparse$$ argument $icode u$$ has prototype -$codei% - const CppAD::vector< std::set >& %u% -%$$ -and $icode%u%.size() >= %m%$$. -For $latex i = 0 , \ldots , m-1$$, -all the elements of $icode%u%[%i%]%$$ -are between zero and $icode%q%-1%$$ inclusive. -This specifies a sparsity pattern -for the matrix $latex U(x) \in \B{R}^{m \times q}$$ defined by -$latex \[ -\begin{array}{rcl} -U(x) -& = & -\partial_u \{ \partial_y g[ y + f^{(1)} (x) R u ] \}_{u=0} -\\ -& = & -\partial_u \{ g^{(1)} [ y + f^{(1)} (x) R u ] \}_{u=0} -\\ -& = & -g^{(2)} (y) f^{(1)} (x) R -\end{array} -\] $$ - -$subhead v$$ -The $icode rev_hes_sparse$$ argument $icode v$$ has prototype -$codei% - CppAD::vector< std::set >& %v% -%$$ -and $icode%v%.size() >= %n%$$. -The input values of its elements -are not specified (must not matter). -Upon return, for $latex j = 0, \ldots , n-1$$, -all the elements of $icode%v%[%j%]%$$ -are between zero and $icode%q%-1%$$ inclusive. -This represents a sparsity pattern for the matrix -$latex V(x) \in \B{R}^{n \times q}$$ defined by -$latex \[ -\begin{array}{rcl} -V(x) -& = & -\partial_u [ \partial_x (g \circ f) ( x + R u ) ]_{u=0} -\\ -& = & -\partial_u [ (g \circ f)^{(1)}( x + R u ) ]_{u=0} -\\ -& = & -(g \circ f)^{(2)}( x ) R -\\ -& = & -f^{(1)} (x)^\R{T} g^{(2)} ( y ) f^{(1)} (x) R -+ -\sum_{i=1}^m [ g^{(1)} (y) ]_i \; f_i^{(2)} (x) R -\\ -& = & -f^{(1)} (x)^\R{T} U(x) -+ -\sum_{i=1}^m S(x)_i \; f_i^{(2)} (x) R -\end{array} -\] $$ - -$head clear$$ -User atomic functions hold onto static work space in order to -increase speed by avoiding system memory allocation calls. -The function call $codei% - user_atomic<%Base%>::clear() -%$$ -makes to work space $cref/available/ta_available/$$ to -for other uses by the same thread. -This should be called when you are done using the -atomic functions for a specific value of $icode Base$$. - -$subhead Restriction$$ -The atomic function $code clear$$ routine cannot be called -while in $cref/parallel/ta_in_parallel/$$ execution mode. - -$end ------------------------------------------------------------------------------- -*/ -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic_one.hpp -user defined atomic operations. -*/ - -/*! -\def CPPAD_USER_ATOMIC(afun, Tvector, - forward, reverse, for_jac_sparse, rev_jac_sparse, rev_hes_sparse -) -Defines the function afun(id, ax, ay) -where id is ax and ay are vectors with AD elements. - -\par Tvector -the Simple Vector template class for this function. - -\par Base -the base type for the atomic operation. - -\par afun -name of the CppAD defined function that corresponding to this operation. -Note that afun, preceeded by a pound sign, -is a version of afun with quotes arround it. - -\par forward -name of the user defined function that computes corresponding -results during forward mode. - -\par reverse -name of the user defined function that computes corresponding -results during reverse mode. - -\par for_jac_sparse -name of the user defined routine that computes corresponding -results during forward mode jacobian sparsity sweeps. - -\par rev_jac_sparse -name of the user defined routine that computes corresponding -results during reverse mode jacobian sparsity sweeps. - -\par rev_hes_sparse -name of the user defined routine that computes corresponding -results during reverse mode Hessian sparsity sweeps. - -\par memory allocation -Note that atomic_one is used as a static object, so its objects -do note get deallocated until the program terminates. -*/ -# define CPPAD_USER_ATOMIC( \ - afun , \ - Tvector , \ - Base , \ - forward , \ - reverse , \ - for_jac_sparse , \ - rev_jac_sparse , \ - rev_hes_sparse \ -) \ -inline void afun ( \ - size_t id , \ - const Tvector< CppAD::AD >& ax , \ - Tvector< CppAD::AD >& ay \ -) \ -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; \ - static CppAD::atomic_one fun( \ - #afun , \ - forward , \ - reverse , \ - for_jac_sparse , \ - rev_jac_sparse , \ - rev_hes_sparse \ - ); \ - fun(id, ax, ay); \ -} - -/// link so that user_atomic::clear() still works -template class user_atomic : public atomic_base { -}; - -/*! -Class that actually implements the afun(id, ax, ay) calls. - -A new atomic_one object is generated each time the user invokes -the CPPAD_USER_ATOMIC macro; see static object in that macro. -*/ -template -class atomic_one : public atomic_base { -public: - /// disable atomic_one::clear(void) - static void clear(void) - { CPPAD_ASSERT_KNOWN( - false, - "Depreacted API uses user_atomic::clear()" - ); - } - /// type for user routine that computes forward mode results - typedef bool (*F) ( - size_t id , - size_t k , - size_t n , - size_t m , - const vector& vx , - vector& vy , - const vector& tx , - vector& ty - ); - /// type for user routine that computes reverse mode results - typedef bool (*R) ( - size_t id , - size_t k , - size_t n , - size_t m , - const vector& tx , - const vector& ty , - vector& px , - const vector& py - ); - /// type for user routine that computes forward mode Jacobian sparsity - typedef bool (*FJS) ( - size_t id , - size_t n , - size_t m , - size_t q , - const vector< std::set >& r , - vector< std::set >& s - ); - /// type for user routine that computes reverse mode Jacobian sparsity - typedef bool (*RJS) ( - size_t id , - size_t n , - size_t m , - size_t q , - vector< std::set >& r , - const vector< std::set >& s - ); - /// type for user routine that computes reverse mode Hessian sparsity - typedef bool (*RHS) ( - size_t id , - size_t n , - size_t m , - size_t q , - const vector< std::set >& r , - const vector& s , - vector& t , - const vector< std::set >& u , - vector< std::set >& v - ); -private: - /// id value corresponding to next virtual callback - size_t id_; - /// user's implementation of forward mode - const F f_; - /// user's implementation of reverse mode - const R r_; - /// user's implementation of forward jacobian sparsity calculations - const FJS fjs_; - /// user's implementation of reverse jacobian sparsity calculations - const RJS rjs_; - /// user's implementation of reverse Hessian sparsity calculations - const RHS rhs_; - -public: - /*! - Constructor called for each invocation of CPPAD_USER_ATOMIC. - - Put this object in the list of all objects for this class and set - the constant private data f_, r_, fjs_, rjs_, rhs_. - - \param afun - is the user's name for the AD version of this atomic operation. - - \param f - user routine that does forward mode calculations for this operation. - - \param r - user routine that does reverse mode calculations for this operation. - - \param fjs - user routine that does forward Jacobian sparsity calculations. - - \param rjs - user routine that does reverse Jacobian sparsity calculations. - - \param rhs - user routine that does reverse Hessian sparsity calculations. - - \par - This constructor can not be used in parallel mode because - atomic_base has this restriction. - */ - atomic_one(const char* afun, F f, R r, FJS fjs, RJS rjs, RHS rhs) : - atomic_base(afun) // name = afun - , f_(f) - , r_(r) - , fjs_(fjs) - , rjs_(rjs) - , rhs_(rhs) - { this->option( atomic_base::set_sparsity_enum ); - } - /*! - Implement the user call to afun(id, ax, ay). - - \tparam ADVector - A simple vector class with elements of type AD. - - \param id - extra information vector that is just passed through by CppAD, - and possibly used by user's routines. - - \param ax - is the argument vector for this call, - ax.size() determines the number of arguments. - - \param ay - is the result vector for this call, - ay.size() determines the number of results. - */ - template - void operator()(size_t id, const ADVector& ax, ADVector& ay) - { // call atomic_base function object - this->atomic_base::operator()(ax, ay, id); - return; - } - /*! - Store id for next virtual function callback - - \param id - id value corresponding to next virtual callback - */ - virtual void set_old(size_t id) - { id_ = id; } - /*! - Link from atomic_one to forward mode - - \copydetails atomic_base::forward - */ - virtual bool forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector& tx , - vector& ty ) - { CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 ); - size_t n = tx.size() / (q+1); - size_t m = ty.size() / (q+1); - size_t i, j, k, ell; - - vector x(n * (q+1)); - vector y(m * (q+1)); - vector empty; - - // atomic_one interface can only handel one order at a time - // so must just throuh hoops to get multiple orders at one time. - bool ok = true; - for(k = p; k <= q; k++) - { for(j = 0; j < n; j++) - for(ell = 0; ell <= k; ell++) - x[ j * (k+1) + ell ] = tx[ j * (q+1) + ell ]; - for(i = 0; i < m; i++) - for(ell = 0; ell < k; ell++) - y[ i * (k+1) + ell ] = ty[ i * (q+1) + ell ]; - if( k == 0 ) - ok &= f_(id_, k, n, m, vx, vy, x, y); - else - ok &= f_(id_, k, n, m, empty, empty, x, y); - for(i = 0; i < m; i++) - ty[ i * (q+1) + k ] = y[ i * (k+1) + k]; - } - return ok; - } - /*! - Link from atomic_one to reverse mode - - \copydetails atomic_base::reverse - */ - virtual bool reverse( - size_t q , - const vector& tx , - const vector& ty , - vector& px , - const vector& py ) - { CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 ); - size_t n = tx.size() / (q+1); - size_t m = ty.size() / (q+1); - bool ok = r_(id_, q, n, m, tx, ty, px, py); - return ok; - } - /*! - Link from forward Jacobian sparsity sweep to atomic_one - - \copydetails atomic_base::for_sparse_jac - */ - virtual bool for_sparse_jac( - size_t q , - const vector< std::set >& r , - vector< std::set >& s , - const vector& x ) - { size_t n = r.size(); - size_t m = s.size(); - bool ok = fjs_(id_, n, m, q, r, s); - return ok; - } - - /*! - Link from reverse Jacobian sparsity sweep to atomic_one. - - \copydetails atomic_base::rev_sparse_jac - */ - virtual bool rev_sparse_jac( - size_t q , - const vector< std::set >& rt , - vector< std::set >& st , - const vector& x ) - { size_t n = st.size(); - size_t m = rt.size(); - bool ok = rjs_(id_, n, m, q, st, rt); - return ok; - } - /*! - Link from reverse Hessian sparsity sweep to atomic_one - - \copydetails atomic_base::rev_sparse_hes - */ - virtual bool rev_sparse_hes( - const vector& vx, - const vector& s , - vector& t , - size_t q , - const vector< std::set >& r , - const vector< std::set >& u , - vector< std::set >& v , - const vector& x ) - { size_t m = u.size(); - size_t n = v.size(); - CPPAD_ASSERT_UNKNOWN( r.size() == n ); - CPPAD_ASSERT_UNKNOWN( s.size() == m ); - CPPAD_ASSERT_UNKNOWN( t.size() == n ); - // - // old interface used id instead of vx - bool ok = rhs_(id_, n, m, q, r, s, t, u, v); - return ok; - } -}; - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/atomic_three.hpp b/build-config/cppad/include/cppad/core/atomic/atomic_three.hpp deleted file mode 100644 index 1afae080..00000000 --- a/build-config/cppad/include/cppad/core/atomic/atomic_three.hpp +++ /dev/null @@ -1,486 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_ATOMIC_THREE_HPP -# define CPPAD_CORE_ATOMIC_ATOMIC_THREE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three$$ -$spell - taylor - ctor - afun - arg - jac - hes - CppAD - enum - mul - hpp - const -$$ - -$section Defining Atomic Functions: Third Generation$$ - -$head Syntax$$ - -$subhead Define Class$$ -$codei%class %atomic_user% : public CppAD::atomic_three<%Base%> { - %...% -};%$$ - -$subhead Construct Atomic Function$$ -$icode%atomic_user% %afun%(%ctor_arg_list%)%$$ - -$subhead Use Atomic Function$$ -$icode%afun%(%ax%, %ay%)%$$ - -$subhead Class Member Callbacks$$ -$icode%ok% = %afun%.for_type( - %parameter_x%, %type_x%, %type_y% -) -%ok% = %afun%.forward( - %parameter_x%, %type_x%, - %need_y%, %order_low%, %order_up%, %taylor_x%, %taylor_y% -) -%ok% = %afun%.reverse( - %parameter_x%, %type_x%, - %order_up%, %taylor_x%, %taylor_y%, %partial_x%, %partial_y% -) -%ok% = %afun%.jac_sparsity( - %parameter_x%, %type_x%, %dependency%, %select_x% %select_y%, %pattern_out% -) -%ok% = %afun%.hes_sparsity( - %parameter_x%, %type_x%, %select_x% %select_y%, %pattern_out% -) -%ok% = %afun%.rev_depend( - %parameter_x%, %type_x%, %depend_x%, %depend_y% -)%$$ - -$head See Also$$ -$cref chkpoint_two$$, $cref atomic_two$$ - -$head Purpose$$ - -$subhead Speed$$ -In some cases, it is possible to compute derivatives of a function -$latex \[ - y = g(x) \; {\rm where} \; g : \B{R}^n \rightarrow \B{R}^m -\] $$ -more efficiently than by coding it using $codei%AD<%Base%>%$$ -$cref/atomic/glossary/Operation/Atomic/$$ operations -and letting CppAD do the rest. -The class $codei%atomic_three%<%Base%>%$$ is used to -create a new atomic operation corresponding to a function $latex g(x)$$ -where the user specifies how to compute the derivatives -and sparsity patterns for $latex g(x)$$. - -$subhead Reduce Memory$$ -If the function $latex g(x)$$ is many times during the recording -of an $cref ADFun$$ object, -using an atomic version of $latex g(x)$$ removed the need for repeated -copies of the corresponding $codei%AD<%Base%>%$$ operations and variables -in the recording. - -$head ad_type$$ -The type $code CppAD::ad_type_enum$$ -is used to specify if an AD object is a -$cref/constant parameter/glossary/Parameter/Constant/$$ -$cref/dynamic parameter/glossary/Parameter/Dynamic/$$ -or $cref/variable/glossary/Variable/$$. -It has the following possible values: -$center -$table -$icode ad_type_enum$$ $pre $$ $cnext Meaning $rnext -$code constant_enum$$ $pre $$ $cnext constant parameter $rnext -$code dynamic_enum$$ $pre $$ $cnext dynamic parameter $rnext -$code variable_enum$$ $pre $$ $cnext variable -$tend -$$ -In addition, -$code constant_enum < dynamic_enum < variable_enum$$. - -$head Virtual Functions$$ -The $cref/callback functions/atomic_three/Syntax/Class Member Callbacks/$$ -are implemented by defining the virtual functions in the -$icode atomic_user$$ class. -These functions compute derivatives, -sparsity patterns, and dependency relations. -Each virtual function has a default implementation -that returns $icode%ok% == false%$$. -The $cref/for_type/atomic_three_for_type/$$ -and $cref/forward/atomic_three_forward/$$ function -(for the case $icode%order_up% == 0%$$) must be implemented. -Otherwise, only those functions and orders -required by the your calculations need to be implemented. -For example, -$icode forward$$ for the case $icode%order_up% == 2%$$ can just return -$icode%ok% == false%$$ unless you require -forward mode calculation of second derivatives. - -$head Base$$ -This is the type of the elements of -$cref/ax/atomic_three_afun/ax/$$ and $cref/ay/atomic_three_afun/ay/$$ -in the corresponding $icode%afun%(%ax%, %ay%)%$$ call. - -$head parameter_x$$ -All the virtual functions include this argument which has prototype -$codei% - const CppAD::vector<%Base%> %parameter_x% -%$$ -Its size is equal to $icode%n% = %ax%.size()%$$ -in corresponding $icode%afun%(%ax%, %ay%)%$$ call. - -$subhead Constant$$ -For $icode%j% =0,%...%,%n%-1%$$, -if $icode%ax%[%j%]%$$ is a $cref/constant/con_dyn_var/Constant/$$ parameter, -$codei% - %parameter_x%[%j%] == %ax%[%j%] -%$$ - -$subhead Dynamic$$ -If $icode%ax%[%j%]%$$ is a $cref/dynamic/con_dyn_var/Dynamic/$$ parameter, -$icode%parameter_x%[%j%]%$$ value of $icode%ax%[%j%]%$$ corresponding to the -previous call to $cref new_dynamic$$ for the corresponding function object. - -$subhead Variable$$ -If $icode%ax%[%j%]%$$ is a variable, -the value of $icode%parameter_x%[%j%]%$$ is not specified. -See the -$cref/atomic_three_mat_mul.hpp/atomic_three_mat_mul.hpp/Purpose/parameter_x/$$ -for an example using $icode parameter_x$$. - -$head type_x$$ -All the virtual functions include this argument. -Its size is equal to $icode%n% = %ax%.size()%$$ -in corresponding $icode%afun%(%ax%, %ay%)%$$ call. -For $icode%j% =0,%...%,%n%-1%$$, -if $icode%ax%[%j%]%$$ is a constant parameter, -$codei% - %type_x%[%j%] == CppAD::constant_enum -%$$ -if $icode%ax%[%j%]%$$ is a dynamic parameter, -$codei% - %type_x%[%j%] == CppAD::dynamic_enum -%$$ -if $icode%ax%[%j%]%$$ is a variable, -$codei% - %type_x%[%j%] == CppAD::variable_enum -%$$ -See the -$cref/atomic_three_mat_mul.hpp/atomic_three_mat_mul.hpp/Purpose/type_x/$$ -for an example using $icode type_x$$. - - -$childtable%include/cppad/core/atomic/three_ctor.hpp - %include/cppad/core/atomic/three_afun.hpp - %include/cppad/core/atomic/three_for_type.hpp - %include/cppad/core/atomic/three_forward.hpp - %include/cppad/core/atomic/three_reverse.hpp - %include/cppad/core/atomic/three_jac_sparsity.hpp - %include/cppad/core/atomic/three_hes_sparsity.hpp - %include/cppad/core/atomic/three_rev_depend.hpp -%$$ - -$end -------------------------------------------------------------------------------- -$begin atomic_three_example$$ - -$section Example Defining Atomic Functions: Third Generation$$ - -$childtable%example/atomic_three/get_started.cpp - %example/atomic_three/norm_sq.cpp - %example/atomic_three/tangent.cpp - %example/atomic_three/base2ad.cpp - %example/atomic_three/reciprocal.cpp - %example/atomic_three/mat_mul.cpp -%$$ - -$end -------------------------------------------------------------------------------- -*/ - -# include -# include -# include - -// needed before one can use in_parallel -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic_three.hpp -Base class for atomic function operations. -*/ - -template -class atomic_three { -// =================================================================== -private: - // ------------------------------------------------------ - // constants - // - /// index of this object in lcal::atomic_index - /// (set by constructor and not changed; i.e., effectively const) - size_t index_; - // - // ----------------------------------------------------- - // - /// temporary work space used by member functions, declared here to avoid - // memory allocation/deallocation for each usage - struct work_struct { - vector type_x; - vector type_y; - // - vector taylor_x; - vector taylor_y; - // - vector< AD > ataylor_x; - vector< AD > ataylor_y; - // - sparse_rc< vector > pattern; - }; - // Use pointers, to avoid false sharing between threads. - // Not using: vector work_; - // so that deprecated atomic examples do not result in a memory leak. - work_struct* work_[CPPAD_MAX_NUM_THREADS]; - // ----------------------------------------------------- -public: - // ===================================================================== - // In User API - // ===================================================================== - // - // --------------------------------------------------------------------- - // ctor: doxygen in atomic/three_ctor.hpp - atomic_three(void); - atomic_three(const std::string& name); - - // ------------------------------------------------------------------------ - // operator(): see doxygen in atomic_three/afun.hpp - template - void operator()( - const ADVector& ax , - ADVector& ay - ); - // ------------------------------------------------------------------------ - // type: doxygen in atomic/three_for_type.hpp - virtual bool for_type( - const vector& parameter_x , - const vector& type_x , - vector& type_y - ); - // ------------------------------------------------------------------------ - // type: doxygen in atomic/three_rev_depend.hpp - virtual bool rev_depend( - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y - ); - // ------------------------------------------------------------------------ - // forward: see docygen in atomic/three_forward.hpp - virtual bool forward( - const vector& parameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector& taylor_x , - vector& taylor_y - ); - virtual bool forward( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector< AD >& ataylor_x , - vector< AD >& ataylor_y - ); - // ------------------------------------------------------------------------ - // reverse: see docygen in atomic/three_reverse.hpp - virtual bool reverse( - const vector& parameter_x , - const vector& type_x , - size_t order_up , - const vector& taylor_x , - const vector& taylor_y , - vector& partial_x , - const vector& partial_y - ); - virtual bool reverse( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t order_up , - const vector< AD >& ataylor_x , - const vector< AD >& ataylor_y , - vector< AD >& apartial_x , - const vector< AD >& apartial_y - ); - // ------------------------------------------------------------ - // jac_sparsity: see doxygen in atomic/three_jac_sparsity.hpp - virtual bool jac_sparsity( - const vector& parameter_x , - const vector& type_x , - bool dependency , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out - ); - template - bool for_jac_sparsity( - bool dependency , - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity - ); - template - bool rev_jac_sparsity( - bool dependency , - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity - ); - // ------------------------------------------------------------ - // hes_sparsity: see doxygen in atomic/three_jac_sparsity.hpp - virtual bool hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out - ); - template - bool for_hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - size_t np1 , - size_t numvar , - const InternalSparsity& rev_jac_sparsity , - InternalSparsity& for_sparsity - ); - template - bool rev_hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - const InternalSparsity& for_jac_pattern , - bool* rev_jac_flag , - InternalSparsity& hes_sparsity - ); - - // ===================================================================== - // Not in User API - // ===================================================================== - - /// Name corresponding to a atomic_three object - const std::string atomic_name(void) const - { bool set_null = false; - size_t type = 0; // set to avoid warning - std::string name; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index_, type, &name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 3 ); - return name; - } - /// destructor informs CppAD that this atomic function with this index - /// has dropped out of scope by setting its pointer to null - virtual ~atomic_three(void) - { // change object pointer to null, but leave name for error reporting - bool set_null = true; - size_t type = 0; // set to avoid warning - std::string* name = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index_, type, name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 3 ); - // - // free temporary work memory - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++) - free_work(thread); - } - /// allocates work_ for a specified thread - void allocate_work(size_t thread) - { if( work_[thread] == nullptr ) - { // allocate the raw memory - size_t min_bytes = sizeof(work_struct); - size_t num_bytes; - void* v_ptr = thread_alloc::get_memory(min_bytes, num_bytes); - // save in work_ - work_[thread] = reinterpret_cast( v_ptr ); - // call constructor - new( work_[thread] ) work_struct; - } - return; - } - /// frees work_ for a specified thread - void free_work(size_t thread) - { if( work_[thread] != nullptr ) - { // call destructor - work_[thread]->~work_struct(); - // return memory to avialable pool for this thread - thread_alloc::return_memory( - reinterpret_cast(work_[thread]) - ); - // mark this thread as not allocated - work_[thread] = nullptr; - } - return; - } - /// atomic_three function object corresponding to a certain index - static atomic_three* class_object(size_t index) - { bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index, type, name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 3 ); - return reinterpret_cast( v_ptr ); - } - /// atomic_three function name corresponding to a certain index - static const std::string class_name(size_t index) - { bool set_null = false; - size_t type = 0; // set to avoid warning - std::string name; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index, type, &name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 3 ); - return name; - } - - /*! - Set value of id (used by deprecated atomic_one class) - - This function is called just before calling any of the virtual function - and has the corresponding id of the corresponding virtual call. - */ - virtual void set_old(size_t id) - { } -// --------------------------------------------------------------------------- -}; -} // END_CPPAD_NAMESPACE - -// member functions -# include -# include -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/atomic_two.hpp b/build-config/cppad/include/cppad/core/atomic/atomic_two.hpp deleted file mode 100644 index 13418999..00000000 --- a/build-config/cppad/include/cppad/core/atomic/atomic_two.hpp +++ /dev/null @@ -1,613 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_ATOMIC_TWO_HPP -# define CPPAD_CORE_ATOMIC_ATOMIC_TWO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two$$ -$spell - ctor - afun - arg - vx - vy - tx - ty - px - py - jac - hes - CppAD - checkpointing -$$ - -$section Defining Atomic Functions: Second Generation$$ - -$head Deprecated 2019-01-01$$ -Using the $code atomic_base$$ class has been deprecated. -Use $cref atomic_three$$ instead. - - -$head Syntax$$ - -$codei% -%atomic_user% %afun%(%ctor_arg_list%) -%afun%(%ax%, %ay%) -%ok% = %afun%.forward(%p%, %q%, %vx%, %vy%, %tx%, %ty%) -%ok% = %afun%.reverse(%q%, %tx%, %ty%, %px%, %py%) -%ok% = %afun%.for_sparse_jac(%q%, %r%, %s%, %x%) -%ok% = %afun%.rev_sparse_jac(%q%, %r%, %s%, %x%) -%ok% = %afun%.for_sparse_hes(%vx%, %r%, %s%, %h%, %x%) -%ok% = %afun%.rev_sparse_hes(%vx%, %s%, %t%, %q%, %r%, %u%, %v%, %x%) -atomic_base<%Base%>::clear()%$$ - -$head See Also$$ -$cref/checkpoint/chkpoint_one/$$ - -$head Purpose$$ - -$subhead Speed$$ -In some cases, the user knows how to compute derivatives of a function -$latex \[ - y = f(x) \; {\rm where} \; f : \B{R}^n \rightarrow \B{R}^m -\] $$ -more efficiently than by coding it using $codei%AD<%Base%>%$$ -$cref/atomic_base/glossary/Operation/Atomic/$$ operations -and letting CppAD do the rest. -In this case $codei%atomic_base%<%Base%>%$$ can use -the user code for $latex f(x)$$, and its derivatives, -as $codei%AD<%Base%>%$$ atomic operations. - -$subhead Reduce Memory$$ -If the function $latex f(x)$$ is used often, -using an atomic version of $latex f(x)$$ remove the need for repeated -copies of the corresponding $codei%AD<%Base%>%$$ operations. - -$head Virtual Functions$$ -User defined derivatives are implemented by defining the -following virtual functions in the $icode atomic_base$$ class: -$cref/forward/atomic_two_forward/$$, -$cref/reverse/atomic_two_reverse/$$, -$cref/for_sparse_jac/atomic_two_for_sparse_jac/$$, -$cref/rev_sparse_jac/atomic_two_rev_sparse_jac/$$, and -$cref/rev_sparse_hes/atomic_two_rev_sparse_hes/$$. -These virtual functions have a default implementation -that returns $icode%ok% == false%$$. -The $code forward$$ function, -for the case $icode%q% == 0%$$, must be implemented. -Otherwise, only those functions -required by the your calculations need to be implemented. -For example, -$icode forward$$ for the case $icode%q% == 2%$$ can just return -$icode%ok% == false%$$ unless you require -forward mode calculation of second derivatives. - -$head Examples$$ -See $cref atomic_two_example$$. - -$childtable% - include/cppad/core/atomic/two_ctor.hpp% - include/cppad/core/atomic/two_option.hpp% - include/cppad/core/atomic/two_afun.hpp% - include/cppad/core/atomic/two_forward.hpp% - include/cppad/core/atomic/two_reverse.hpp% - include/cppad/core/atomic/two_for_sparse_jac.hpp% - include/cppad/core/atomic/two_rev_sparse_jac.hpp% - include/cppad/core/atomic/two_for_sparse_hes.hpp% - include/cppad/core/atomic/two_rev_sparse_hes.hpp% - include/cppad/core/atomic/two_clear.hpp -%$$ - -$end -------------------------------------------------------------------------------- -$begin atomic_two_example$$ - -$section Example Defining Atomic Functions: Second Generation$$ - -$head Getting Started$$ -that shows the minimal amount of information required to create -a user defined atomic operation. - -$head Scalar Function$$ -where the user provides the code for computing derivatives. -This example is simple because the domain and range are scalars. - -$head Vector Range$$ -where the user provides the code for computing derivatives. -This example is more complex because the range has two components. - -$head Hessian Sparsity Patterns$$ -where the user provides the code for computing Hessian sparsity patterns. - -$childtable% - example/atomic_two/eigen_mat_mul.cpp% - example/atomic_two/eigen_mat_inv.cpp% - example/atomic_two/eigen_cholesky.cpp -%$$ - -$end -------------------------------------------------------------------------------- -*/ - -# include -# include -# include -# include - -// needed before one can use in_parallel -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic_two.hpp -Base class for atomic function operations. -*/ - -template -class atomic_base { -// =================================================================== -public: - enum option_enum { - pack_sparsity_enum , - bool_sparsity_enum , - set_sparsity_enum - }; -private: - // ------------------------------------------------------ - // constants - // - /// index of this object in local::atomic_index - /// (set by constructor and not changed; i.e., effectively const) - size_t index_; - // - // ----------------------------------------------------- - // variables - // - /// sparsity pattern this object is currently using - /// (set by constructor and option member functions) - option_enum sparsity_; - // - /// temporary work space used by member functions, declared here to avoid - // memory allocation/deallocation for each usage - struct work_struct { - vector vx; - vector vy; - // - vector tx; - vector ty; - // - vector< AD > atx; - vector< AD > aty; - // - vector bool_t; - // - vectorBool pack_h; - vectorBool pack_r; - vectorBool pack_s; - vectorBool pack_u; - // - vector bool_h; - vector bool_r; - vector bool_s; - vector bool_u; - // - vector< std::set > set_h; - vector< std::set > set_r; - vector< std::set > set_s; - vector< std::set > set_u; - }; - // Use pointers, to avoid false sharing between threads. - // Not using: vector work_; - // so that deprecated atomic examples do not result in a memory leak. - work_struct* work_[CPPAD_MAX_NUM_THREADS]; -public: - // ===================================================================== - // In User API - // ===================================================================== - // - // --------------------------------------------------------------------- - // ctor: doxygen in atomic_base/ctor.hpp - atomic_base(void); - atomic_base( - const std::string& name, - option_enum sparsity = bool_sparsity_enum - ); - - // option: see doxygen in atomic_base/option.hpp - void option(enum option_enum option_value); - - // operator(): see doxygen in atomic_base/afun.hpp - template - void operator()( - const ADVector& ax , - ADVector& ay , - size_t id = 0 - ); - - // ------------------------------------------------------------------------ - // base_two version of forward - virtual bool forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector& tx , - vector& ty - ); - virtual bool forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector< AD >& atx , - vector< AD >& aty - ); - // base_three version of forward - bool forward( - size_t order_low , - size_t order_up , - const vector& type_x , - vector& type_y , - const vector& taylor_x , - vector& taylor_y - ); - bool forward( - size_t order_low , - size_t order_up , - const vector& type_x , - vector& type_y , - const vector< AD >& ataylor_x , - vector< AD >& ataylor_y - ); - // ------------------------------------------------------------------------ - // reverse: see doxygen in atomic_base/reverse.hpp - virtual bool reverse( - size_t q , - const vector& tx , - const vector& ty , - vector& px , - const vector& py - ); - virtual bool reverse( - size_t q , - const vector< AD >& atx , - const vector< AD >& aty , - vector< AD >& apx , - const vector< AD >& apy - ); - - // ------------------------------------------------------------ - // for_sparse_jac: see doxygen in atomic_base/for_sparse_jac.hpp - virtual bool for_sparse_jac( - size_t q , - const vector< std::set >& r , - vector< std::set >& s , - const vector& x - ); - virtual bool for_sparse_jac( - size_t q , - const vector& r , - vector& s , - const vector& x - ); - virtual bool for_sparse_jac( - size_t q , - const vectorBool& r , - vectorBool& s , - const vector& x - ); - template - bool for_sparse_jac( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity - ); - // deprecated versions - virtual bool for_sparse_jac( - size_t q , - const vector< std::set >& r , - vector< std::set >& s - ); - virtual bool for_sparse_jac( - size_t q , - const vector& r , - vector& s - ); - virtual bool for_sparse_jac( - size_t q , - const vectorBool& r , - vectorBool& s - ); - // ------------------------------------------------------------ - // rev_sparse_jac: see doxygen in atomic_base/rev_sparse_jac.hpp - virtual bool rev_sparse_jac( - size_t q , - const vector< std::set >& rt , - vector< std::set >& st , - const vector& x - ); - virtual bool rev_sparse_jac( - size_t q , - const vector& rt , - vector& st , - const vector& x - ); - virtual bool rev_sparse_jac( - size_t q , - const vectorBool& rt , - vectorBool& st , - const vector& x - ); - template - bool rev_sparse_jac( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity - ); - // deprecated versions - virtual bool rev_sparse_jac( - size_t q , - const vector< std::set >& rt , - vector< std::set >& st - ); - virtual bool rev_sparse_jac( - size_t q , - const vector& rt , - vector& st - ); - virtual bool rev_sparse_jac( - size_t q , - const vectorBool& rt , - vectorBool& st - ); - // ------------------------------------------------------------ - // for_sparse_hes: see doxygen in atomic_base/for_sparse_hes.hpp - virtual bool for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector< std::set >& h , - const vector& x - ); - virtual bool for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector& h , - const vector& x - ); - virtual bool for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vectorBool& h , - const vector& x - ); - template - bool for_sparse_hes( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - size_t np1 , - size_t numvar , - const InternalSparsity& rev_jac_sparsity , - InternalSparsity& for_sparsity - ); - // deprecated versions - virtual bool for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector< std::set >& h - ); - virtual bool for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector& h - ); - virtual bool for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vectorBool& h - ); - // ------------------------------------------------------------ - // rev_sparse_hes: see doxygen in atomic_base/rev_sparse_hes.hpp - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector< std::set >& r , - const vector< std::set >& u , - vector< std::set >& v , - const vector& x - ); - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector& r , - const vector& u , - vector& v , - const vector& x - ); - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vectorBool& r , - const vectorBool& u , - vectorBool& v , - const vector& x - ); - template - bool rev_sparse_hes( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - const InternalSparsity& for_jac_sparsity , - bool* rev_jac_flag , - InternalSparsity& rev_hes_sparsity - ); - // deprecated - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector< std::set >& r , - const vector< std::set >& u , - vector< std::set >& v - ); - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector& r , - const vector& u , - vector& v - ); - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vectorBool& r , - const vectorBool& u , - vectorBool& v - ); - // ------------------------------------------------------------ - // atomic_three like interface for reverse dependency analysis - bool rev_depend( - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y - ); - // ------------------------------------------------------------ - // clear: see doxygen in atomic_base/clear.hpp - static void clear(void); - - // ===================================================================== - // Not in User API - // ===================================================================== - - /// current sparsity setting - option_enum sparsity(void) const - { return sparsity_; } - - /// Name corresponding to a atomic_base object - const std::string atomic_name(void) const - { bool set_null = false; - size_t type = 0; // set to avoid warning - std::string name; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index_, type, &name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 2 ); - return name; - } - /// destructor informs CppAD that this atomic function with this index - /// has dropped out of scope by setting its pointer to null - virtual ~atomic_base(void) - { // change object pointer to null, but leave name for error reporting - bool set_null = true; - size_t type = 0; // set to avoid warning - std::string* name = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index_, type, name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 2 ); - // - // free temporary work memory - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++) - free_work(thread); - } - /// allocates work_ for a specified thread - void allocate_work(size_t thread) - { if( work_[thread] == nullptr ) - { // allocate the raw memory - size_t min_bytes = sizeof(work_struct); - size_t num_bytes; - void* v_ptr = thread_alloc::get_memory(min_bytes, num_bytes); - // save in work_ - work_[thread] = reinterpret_cast( v_ptr ); - // call constructor - new( work_[thread] ) work_struct; - } - return; - } - /// frees work_ for a specified thread - void free_work(size_t thread) - { if( work_[thread] != nullptr ) - { // call destructor - work_[thread]->~work_struct(); - // return memory to avialable pool for this thread - thread_alloc::return_memory( - reinterpret_cast(work_[thread]) - ); - // mark this thread as not allocated - work_[thread] = nullptr; - } - return; - } - /// atomic_base function object corresponding to a certain index - static atomic_base* class_object(size_t index) - { bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index, type, name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 2 ); - return reinterpret_cast( v_ptr ); - } - /// atomic_base function name corresponding to a certain index - static const std::string class_name(size_t index) - { bool set_null = false; - size_t type = 0; // set to avoid warning - std::string name; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, index, type, &name, v_ptr); - CPPAD_ASSERT_UNKNOWN( type == 2 ); - return name; - } - - /*! - Set value of id (used by deprecated atomic_one class) - - This function is called just before calling any of the virtual function - and has the corresponding id of the corresponding virtual call. - */ - virtual void set_old(size_t id) - { } -// --------------------------------------------------------------------------- -}; -} // END_CPPAD_NAMESPACE - -// functitons implemented in cppad/core/atomic_base files -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_afun.hpp b/build-config/cppad/include/cppad/core/atomic/three_afun.hpp deleted file mode 100644 index 2e468105..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_afun.hpp +++ /dev/null @@ -1,248 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_AFUN_HPP -# define CPPAD_CORE_ATOMIC_THREE_AFUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_afun$$ - -$spell - sq - mul - afun - const - CppAD - mat_mul.cpp -$$ - -$section Using AD Version of an Atomic Function$$ - -$head Syntax$$ -$icode%afun%(%ax%, %ay%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Purpose$$ -Given $icode ax$$, this call computes the corresponding value of $icode ay$$. -If $codei%AD<%Base%>%$$ operations are being recorded, -it enters the computation as an atomic operation in the recording; -see $cref/start recording/Independent/Start Recording/$$. - -$head Base$$ -This is the $icode Base$$ type of the elements of $icode ax$$ and $icode ay$$ -in the call to the $icode afun$$ atomic operation. -To be specific, the elements of $icode ax$$ and $icode ay$$ have type -$codei%AD%<%Base%>%$$. - -$head ADVector$$ -The type $icode ADVector$$ must be a -$cref/simple vector class/SimpleVector/$$ with elements of type -$codei%AD<%Base%>%$$. - -$head afun$$ -is a $cref/atomic_user/atomic_three_ctor/atomic_user/$$ object -and this $icode afun$$ function call is implemented by the -$cref/atomic_three/atomic_three_ctor/atomic_three/$$ class. - -$head ax$$ -This argument has prototype -$codei% - const %ADVector%& %ax% -%$$ -and size must be equal to $icode n$$. -It specifies vector $latex x \in \B{R}^n$$ -at which an $codei%AD<%Base%>%$$ version of -$latex y = g(x)$$ is to be evaluated; see -$cref/Base/atomic_three_ctor/atomic_three/Base/$$. - -$head ay$$ -This argument has prototype -$codei% - %ADVector%& %ay% -%$$ -and size must be equal to $icode m$$. -The input values of its elements -are not specified (must not matter). -Upon return, it is an $codei%AD<%Base%>%$$ version of -$latex y = g(x)$$. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_afun.hpp -Implement user call to an atomic_three function. -*/ - -/*! -Implement the user call to afun(ax, ay) - -\tparam ADVector -A simple vector class with elements of type AD. - -\param ax -is the argument vector for this call, -ax.size() determines the number of arguments. - -\param ay -is the result vector for this call, -ay.size() determines the number of results. -*/ -// BEGIN_PROTOTYPE -template -template -void atomic_three::operator()( - const ADVector& ax , - ADVector& ay ) -// END_PROTOTYPE -{ - - size_t n = ax.size(); - size_t m = ay.size(); -# ifndef NDEBUG - bool ok = true; - std::string msg = "atomic_three: " + atomic_name() + ".eval: "; - if( (n == 0) | (m == 0) ) - { msg += "ax.size() or ay.size() is zero"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - vector& taylor_x = work_[thread]->taylor_x; - vector& taylor_y = work_[thread]->taylor_y; - vector& type_x = work_[thread]->type_x; - vector& type_y = work_[thread]->type_y; - // - type_x.resize(n); - taylor_x.resize(n); - // - type_y.resize(m); - taylor_y.resize(m); - // - // Determine tape corresponding to variables in ax - tape_id_t tape_id = 0; - local::ADTape* tape = nullptr; - for(size_t j = 0; j < n; j++) - { taylor_x[j] = ax[j].value_; - if( Constant( ax[j] ) ) - type_x[j] = constant_enum; - else - { type_x[j] = ax[j].ad_type_; - if( tape_id == 0 ) - { tape = ax[j].tape_this(); - tape_id = ax[j].tape_id_; - CPPAD_ASSERT_UNKNOWN( tape != nullptr ); - } -# ifndef NDEBUG - if( Dynamic( ax[j] ) ) - { CPPAD_ASSERT_UNKNOWN( type_x[j] == dynamic_enum ); - } - else - { CPPAD_ASSERT_UNKNOWN( Variable( ax[j] ) ); - CPPAD_ASSERT_UNKNOWN( type_x[j] == variable_enum ); - } - if( tape_id != ax[j].tape_id_ ) - { msg += atomic_name() + - ": ax contains non-constant values from different threads."; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } -# endif - } - } - // Use zero order forward mode to compute all the components of y - size_t need_y = size_t(variable_enum) + 1; - size_t order_low = 0; - size_t order_up = 0; - CPPAD_ASSERT_UNKNOWN( need_y > size_t(variable_enum) ); -# ifdef NDEBUG - forward(taylor_x, type_x, need_y, order_low, order_up, taylor_x, taylor_y); - for(size_t j = 0; j < n; ++j) - if( type_x[j] == variable_enum ) - taylor_x[j] = CppAD::numeric_limits::quiet_NaN(); - for_type(taylor_x, type_x, type_y); -# else - ok &= forward( - taylor_x, type_x, need_y, order_low, order_up, taylor_x, taylor_y - ); - for(size_t j = 0; j < n; ++j) - if( type_x[j] == variable_enum ) - taylor_x[j] = CppAD::numeric_limits::quiet_NaN(); - ok &= for_type(taylor_x, type_x, type_y); - if( ! ok ) - { msg += atomic_name() + ": ok is false for " - "type or zero order forward mode calculation."; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } -# endif - bool record_dynamic = false; - bool record_variable = false; - // - // set ay to be vector of constant parameters with correct value - for(size_t i = 0; i < m; i++) - { // pass back values - ay[i].value_ = taylor_y[i]; - - // initialize entire vector as constants - ay[i].tape_id_ = 0; - ay[i].taddr_ = 0; - - // we need to record this operation if - // any of the elemnts of ay are dynamics or variables, - record_dynamic |= type_y[i] == dynamic_enum; - record_variable |= type_y[i] == variable_enum; - } -# ifndef NDEBUG - if( (record_dynamic || record_variable) && tape == nullptr ) - { msg += - "all elements of x are constants but y contains a non-constant"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - if( record_dynamic) - { tape->Rec_.put_dyn_atomic(tape_id, index_, type_x, type_y, ax, ay); - } - // case where result contains a variable - if( record_variable ) - { tape->Rec_.put_var_atomic(tape_id, index_, type_x, type_y, ax, ay); - } -# ifndef NDEBUG - for(size_t i = 0; i < m; ++i) switch( type_y[i] ) - { // - case constant_enum: - CPPAD_ASSERT_UNKNOWN( Constant( ay[i] ) ); - break; - // - case dynamic_enum: - CPPAD_ASSERT_UNKNOWN( Dynamic( ay[i] ) ); - break; - // - case variable_enum: - CPPAD_ASSERT_UNKNOWN( Variable( ay[i] ) ); - break; - // - default: - CPPAD_ASSERT_KNOWN( false, - "atomic_three: for_type: type_y[i]: is not a valid type" - ); - break; - } -# endif - return; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_ctor.hpp b/build-config/cppad/include/cppad/core/atomic/three_ctor.hpp deleted file mode 100644 index 46672063..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_ctor.hpp +++ /dev/null @@ -1,165 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_CTOR_HPP -# define CPPAD_CORE_ATOMIC_THREE_CTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_ctor$$ -$spell - enum - sq - std - afun - arg - CppAD - bool - ctor - const - mat_mul_xam.cpp - hpp -$$ - -$section Atomic Function Constructor$$ - -$head Syntax$$ -$codei%class %atomic_user% : public CppAD::atomic_three<%Base%> { -public: - %atomic_user%(%ctor_arg_list%) : CppAD::atomic_three<%Base%>(%name%) - %...% -}; -%$$ -$icode%atomic_user afun%(%ctor_arg_list%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head atomic_user$$ - -$subhead ctor_arg_list$$ -Is a list of arguments for the $icode atomic_user$$ constructor. - -$subhead afun$$ -The object $icode afun$$ must stay in scope for as long -as the corresponding atomic function is used. -This includes use by any $cref/ADFun/ADFun/$$ that -has this $icode atomic_user$$ operation in its -$cref/operation sequence/glossary/Operation/Sequence/$$. - -$subhead Implementation$$ -The user defined $icode atomic_user$$ class is a publicly derived class of -$codei%atomic_three<%Base%>%$$. -It should be declared as follows: -$codei% - class %atomic_user% : public CppAD::atomic_three<%Base%> { - public: - %atomic_user%(%ctor_arg_list%) : atomic_three<%Base%>(%name%) - %...% - }; -%$$ -where $icode ...$$ -denotes the rest of the implementation of the derived class. -This includes completing the constructor and -all the virtual functions that have their -$code atomic_three$$ implementations replaced by -$icode atomic_user$$ implementations. - -$head atomic_three$$ - -$subhead Restrictions$$ -The $code atomic_three$$ constructor and destructor cannot be called in -$cref/parallel/ta_in_parallel/$$ mode. - -$subhead Base$$ -The template parameter determines the -$cref/Base/atomic_three_afun/Base/$$ -type for this $codei%AD<%Base%>%$$ atomic operation. - -$subhead name$$ -This $code atomic_three$$ constructor argument has the following prototype -$codei% - const std::string& %name% -%$$ -It is the name for this atomic function and is used for error reporting. -The suggested value for $icode name$$ is $icode afun$$ or $icode atomic_user$$, -i.e., the name of the corresponding atomic object or class. - -$head Example$$ - -$subhead Define Constructor$$ -The following is an example of a atomic function constructor definition: -$cref%get_started.cpp%atomic_three_get_started.cpp%Constructor%$$. - -$subhead Use Constructor$$ -The following is an example using a atomic function constructor: -$cref%get_started.cpp - %atomic_three_get_started.cpp - %Use Atomic Function%Constructor -%$$. - -$end -------------------------------------------------------------------------------- -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_ctor.hpp -Constructors for atomic_three class. -*/ - -/*! -Base class for atomic_atomic functions. - -\tparam Base -This class is used for defining an AD atomic operation y = g(x). - -\par -make sure user does not invoke the default constructor -*/ -template -atomic_three::atomic_three(void) -{ CPPAD_ASSERT_KNOWN(false, - "Attempt to use the atomic_three default constructor" - ); -} -/*! -Constructor - -\param name -name used for error reporting -*/ -// BEGIN_PROTOTYPE -template -atomic_three::atomic_three(const std::string& name ) -// END_PROTOTYPE -{ CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "atomic_three: constructor cannot be called in parallel mode." - ); - // - // atomic_index - bool set_null = false; - size_t index = 0; - size_t type = 3; - std::string copy_name = name; - void* copy_this = reinterpret_cast( this ); - index_ = local::atomic_index( - set_null, index, type, ©_name, copy_this - ); - // initialize work pointers as null; - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++) - work_[thread] = nullptr; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_for_type.hpp b/build-config/cppad/include/cppad/core/atomic/three_for_type.hpp deleted file mode 100644 index cb1cc31e..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_for_type.hpp +++ /dev/null @@ -1,117 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_FOR_TYPE_HPP -# define CPPAD_CORE_ATOMIC_THREE_FOR_TYPE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_for_type$$ -$spell - afun - enum - cpp -$$ - -$section Atomic Function Forward Type Calculation$$ - -$head Syntax$$ -$icode%ok% = %afun%.for_type(%parameter_x%, %type_x%, %type_y%)%$$ - -$subhead Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Dependency Analysis$$ -This calculation is sometimes referred to as a forward dependency analysis. - -$head Usage$$ -This syntax and prototype are used by -$codei% - %afun%(%ax%, %ay%) -%$$ -where $cref/afun/atomic_three_ctor/atomic_user/afun/$$ -is a user defined atomic function. - -$head Implementation$$ -This virtual function must be defined by the -$cref/atomic_user/atomic_three_ctor/atomic_user/$$ class. - -$head Base$$ -See $cref/Base/atomic_three/Base/$$. - -$head parameter_x$$ -See $cref/parameter_x/atomic_three/parameter_x/$$. - -$head type_x$$ -See $cref/type_x/atomic_three/type_x/$$. - -$head type_y$$ -This vector has size equal to the number of results for this atomic function; -i.e. $icode%m%=%ay%.size()%$$. -The input values of the elements of $icode type_y$$ -are not specified (must not matter). -Upon return, for $latex i = 0 , \ldots , m-1$$, -$icode%type_y%[%i%]%$$ is set to one of the following values: -$list number$$ -It is $code constant_enum$$ if $icode%ay%[%i%]%$$ only depends on -the arguments that are constants. -$lnext -It is $code dynamic_enum$$ if $icode%ay%[%i%]%$$ depends on -a dynamic parameter and does not depend on any variables. -$lnext -It is $code variable_enum$$ if $icode%ay%[%i%]%$$ depends on -a variable. -$lend - -$head ok$$ -If this calculation succeeded, $icode ok$$ is true. -Otherwise, it is false. - -$head Example$$ -The following is an example of a atomic function $code for_type$$ definition: -$cref%get_started.cpp%atomic_three_get_started.cpp%for_type%$$. - - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_for_type.hpp -Third generation atomic type computation. -*/ -/*! -Link from atomic_three to type calculation - -\param parameter_x [in] -is the value of the parameters in the corresponding function call -afun(ax, ay). - -\param type_x [in] -specifies which components of x are -constants, dynamics, and variables - -\param type_y [out] -specifies which components of y are -constants, dynamics, and variables -*/ -// BEGIN_PROTOTYPE -template -bool atomic_three::for_type( - const vector& parameter_x , - const vector& type_x , - vector& type_y ) -// END_PROTOTYPE -{ return false; } - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_forward.hpp b/build-config/cppad/include/cppad/core/atomic/three_forward.hpp deleted file mode 100644 index f35654bb..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_forward.hpp +++ /dev/null @@ -1,346 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_FORWARD_HPP -# define CPPAD_CORE_ATOMIC_THREE_FORWARD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_forward$$ -$spell - taylor - ataylor - af - afun - enum - CppAD - aparameter -$$ - -$section Atomic Function Forward Mode$$ - -$head Base$$ -This syntax and prototype are used by -$cref/afun(ax, ay)/atomic_three_afun/$$; see -$cref/Base/atomic_three_afun/Base/$$. -They are also used by -$icode%f%.Forward%$$ and $icode%f%.new_dynamic%$$ -where $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -and $icode afun$$ is used during the recording of $icode f$$. - -$subhead Syntax$$ -$icode%ok% = %afun%.forward( - %parameter_x%, %type_x%, - %need_y%, %order_low%, %order_up%, %type_x%, %taylor_x%, %taylor_y% -)%$$ - -$subhead Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE_BASE%// END_PROTOTYPE_BASE%1 -%$$ - -$head AD$$ -This syntax and prototype are used by -$icode%af%.Forward%$$ and $icode%af%.new_dynamic%$$ -where $icode af$$ has prototype -$codei% - ADFun< AD<%Base%> , %Base% > %af% -%$$ -and $icode afun$$ is used in $icode af$$ (see $cref base2ad$$). - -$subhead Syntax$$ -$icode%ok% = %afun%.forward( - %parameter_x%, %type_x%, - %need_y%, %order_low%, %order_up%, %type_x%, %ataylor_x%, %ataylor_y% -)%$$ - -$subhead Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE_AD_BASE%// END_PROTOTYPE_AD_BASE%1 -%$$ - -$head Implementation$$ -The $icode taylor_x$$, $icode taylor_y$$ version of this function -must be defined by the -$cref/atomic_user/atomic_three_ctor/atomic_user/$$ class. -It can just return $icode%ok% == false%$$ -(and not compute anything) for values -of $icode%order_up%$$ that are greater than those used by your -$cref/forward/Forward/$$ mode calculations -(order zero must be implemented). - -$head parameter_x$$ -See $cref/parameter_x/atomic_three/parameter_x/$$. - -$head aparameter_x$$ -The specifications for $icode aparameter_x$$ -is the same as for $cref/parameter_x/atomic_three/parameter_x/$$ -(only the type of $icode ataylor_x$$ is different). - -$head type_x$$ -See $cref/type_x/atomic_three/type_x/$$. - -$head need_y$$ -One can ignore this argument and compute all the $icode taylor_y$$ -Taylor coefficient. -Often, this is not necessary and $icode need_y$$ is used to specify this. -The value $cref/type_y/atomic_three_for_type/type_y/$$ is used -to determine which coefficients are necessary as follows: - -$subhead Constant Parameters$$ -If $icode%need_y% == size_t(constant_enum)%$$, -then only the taylor coefficients -for $latex Y_i (t)$$ where $icode%type_y%[%i%] == constant_enum%$$ -are necessary. -This is the case during a $cref from_json$$ operation. - -$subhead Dynamic Parameters$$ -If $icode%need_y% == size_t(dynamic_enum)%$$, -then only the taylor coefficients -for $latex Y_i (t)$$ where $icode%type_y%[%i%] == dynamic_enum%$$ -are necessary. -This is the case during an $cref new_dynamic$$ operation. - -$subhead Variables$$ -If $icode%need_y% == size_t(variable_enum)%$$, -If $codei%ad_type_enum(%need_y%)% == variable_enum%$$, -then only the taylor coefficients -for $latex Y_i (t)$$ where $icode%type_y%[%i%] == variable_enum%$$ -are necessary. -This is the case during a $cref/f.Forward/Forward/$$ operation. -T - -$subhead All$$ -If $icode%need_y > size_t(variable_enum)%$$, -then the taylor coefficients for all $latex Y_i (t)$$ are necessary. -This is the case during an $icode%afun%(%ax%, %ay%)%$$ operation. - - -$head order_low$$ -This argument -specifies the lowest order Taylor coefficient that we are computing. - -$subhead p$$ -We sometimes use the notation $icode%p% = %order_low%$$ below. - -$head order_up$$ -This argument -specifies the highest order Taylor coefficient that we are computing -($icode%order_low% <= %order_up%$$). - -$subhead q$$ -We sometimes use the notation $icode%q% = %order_up%$$ below. - -$head taylor_x$$ -The size of $icode taylor_x$$ is $codei%(%q%+1)*%n%$$. -For $latex j = 0 , \ldots , n-1$$ and $latex k = 0 , \ldots , q$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - x_j^k & = & \R{taylor\_x} [ j * ( q + 1 ) + k ] - \\ - X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^q t^q -\end{array} -\] $$ -Note that superscripts represent an index for $latex x_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex X(t)$$ correspond -to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - x_j^k = \frac{1}{ k ! } X_j^{(k)} (0) -\] $$ - -$subhead parameters$$ -If the $th j$$ component of $icode x$$ corresponds to a parameter, -$codei% - %type_x%[%j%] < CppAD::variable_enum -%$$ -In this case, -the $th j$$ component of $icode parameter_x$$ is equal to $latex x_j^0$$; -i.e., -$codei% - %parameter_x%[%j%] == %taylor_x%[ %j% * ( %q% + 1 ) + 0 ] -%$$ -Furthermore, for $icode%k% > 0%$$, -$codei% - %taylor_x%[ %j% * ( %q% + 1 ) + %k% ] == 0 -%$$ - -$head ataylor_x$$ -The specifications for $icode ataylor_x$$ is the same as for $icode taylor_x$$ -(only the type of $icode ataylor_x$$ is different). - -$head taylor_y$$ -The size of $icode taylor_y$$ is $codei%(%q%+1)*%m%$$. -Upon return, -For $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , q$$, -$latex \[ -\begin{array}{rcl} - Y_i (t) & = & g_i [ X(t) ] - \\ - Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q ) - \\ - \R{taylor\_y} [ i * ( q + 1 ) + k ] & = & y_i^k -\end{array} -\] $$ -where $latex o( t^q ) / t^q \rightarrow 0$$ as $latex t \rightarrow 0$$. -Note that superscripts represent an index for $latex y_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex Y(t)$$ correspond -to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0) -\] $$ -If $latex p > 0$$, -for $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , p-1$$, -the input of $icode taylor_y$$ satisfies -$latex \[ - \R{taylor\_y} [ i * ( q + 1 ) + k ] = y_i^k -\]$$ -These values do not need to be recalculated -and can be used during the computation of the higher order coefficients. - -$head ataylor_y$$ -The specifications for $icode ataylor_y$$ is the same as for $icode taylor_y$$ -(only the type of $icode ataylor_y$$ is different). - -$head ok$$ -If this calculation succeeded, $icode ok$$ is true. -Otherwise, it is false. - -$head Discussion$$ -For example, suppose that $icode%order_up% == 2%$$, -and you know how to compute the function $latex g(x)$$, -its first derivative $latex f^{(1)} (x)$$, -and it component wise Hessian $latex g_i^{(2)} (x)$$. -Then you can compute $icode taylor_x$$ using the following formulas: -$latex \[ -\begin{array}{rcl} -y_i^0 & = & Y(0) - = g_i ( x^0 ) -\\ -y_i^1 & = & Y^{(1)} ( 0 ) - = g_i^{(1)} ( x^0 ) X^{(1)} ( 0 ) - = g_i^{(1)} ( x^0 ) x^1 -\\ -y_i^2 -& = & \frac{1}{2 !} Y^{(2)} (0) -\\ -& = & \frac{1}{2} X^{(1)} (0)^\R{T} g_i^{(2)} ( x^0 ) X^{(1)} ( 0 ) - + \frac{1}{2} g_i^{(1)} ( x^0 ) X^{(2)} ( 0 ) -\\ -& = & \frac{1}{2} (x^1)^\R{T} g_i^{(2)} ( x^0 ) x^1 - + g_i^{(1)} ( x^0 ) x^2 -\end{array} -\] $$ -For $latex i = 0 , \ldots , m-1$$, and $latex k = 0 , 1 , 2$$, -$latex \[ - \R{taylor\_y} [ i * (q + 1) + k ] = y_i^k -\] $$ - -$children% - example/atomic_three/forward.cpp% - example/atomic_three/dynamic.cpp -%$$ -$head Examples$$ -The files -$cref atomic_three_forward.cpp$$ and $cref atomic_three_dynamic.cpp$$ -contain examples and tests that uses this routine. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_forward.hpp -Third generation atomic forward mode. -*/ -/*! -Link from atomic_three to forward mode - -\param parameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param need_y [in] -specifies which components of taylor_y are needed, - -\param order_low [in] -lowerest order for this forward mode calculation. - -\param order_up [in] -highest order for this forward mode calculation. - -\param taylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param taylor_y [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for atomic_three -*/ -// BEGIN_PROTOTYPE_BASE -template -bool atomic_three::forward( - const vector& parameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector& taylor_x , - vector& taylor_y ) -// END_PROTOTYPE_BASE -{ return false; } - -/*! -Link from atomic_three to forward mode - -\param aparameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param need_y [in] -specifies which components of taylor_y are needed, - -\param order_low [in] -lowerest order for this forward mode calculation. - -\param order_up [in] -highest order for this forward mode calculation. - -\param ataylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param ataylor_y [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for base_three -*/ -// BEGIN_PROTOTYPE_AD_BASE -template -bool atomic_three::forward( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector< AD >& ataylor_x , - vector< AD >& ataylor_y ) -// END_PROTOTYPE_AD_BASE -{ return false; } - - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_hes_sparsity.hpp b/build-config/cppad/include/cppad/core/atomic/three_hes_sparsity.hpp deleted file mode 100644 index 03445cbe..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_hes_sparsity.hpp +++ /dev/null @@ -1,412 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_HES_SPARSITY_HPP -# define CPPAD_CORE_ATOMIC_THREE_HES_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_hes_sparsity$$ -$spell - Hessian - afun - hes -$$ - -$section Atomic Function Hessian Sparsity Patterns$$ - -$head Syntax$$ -$icode%ok% = %afun%.hes_sparsity( - %parameter_x%, %type_x%, %select_x%, %select_y%, %pattern_out% -)%$$ - -$head Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Implementation$$ -This function must be defined if -$cref/afun/atomic_three_ctor/atomic_user/afun/$$ is -used to define an $cref ADFun$$ object $icode f$$, -and Hessian sparsity patterns are computed for $icode f$$. - -$head Base$$ -See $cref/Base/atomic_three_afun/Base/$$. - -$head parameter_x$$ -See $cref/parameter_x/atomic_three/parameter_x/$$. - -$head type_x$$ -See $cref/type_x/atomic_three/type_x/$$. - -$head select_x$$ -This argument has size equal to the number of arguments to this -atomic function; i.e. the size of $icode ax$$. -It specifies which domain components are included in -the calculation of $icode pattern_out$$. -If $icode%select_x%[%j%]%$$ is false, then there will be no indices -$icode k$$ such that either of the following hold: -$codei% - %pattern_out%.row()[%k%] == %j% - %pattern_out%.col()[%k%] == %j% -%$$. - -$head select_y$$ -This argument has size equal to the number of results to this -atomic function; i.e. the size of $icode ay$$. -It specifies which range component functions $latex g_i (x)$$ are included in -of $icode pattern_out$$. - -$head pattern_out$$ -This input value of $icode pattern_out$$ does not matter. -Upon return it is the union, -with respect to $icode i$$ such that $icode%select_y%[%i%]%$$ is true, -of the sparsity pattern for Hessian of $latex g_i (x)$$. -To be specific, there are non-negative indices -$icode i$$, $icode r$$, $icode c$$, and $icode k$$ such that -$codei% - %pattern_out%.row()[%k%] == %r% - %pattern_out%.col()[%k%] == %c% -%$$ -if and only if -$icode%select_y%[%i%]%$$ is true, -$icode%select_x%[%r%]%$$ is true, -$icode%select_x%[%c%]%$$ is true, -and -$latex \[ - \partial_{x(r)} \partial_{x(c)} g_i(x) -\] $$ -is possibly non-zero. -Note that the sparsity pattern should be symmetric. - -$head ok$$ -If this calculation succeeded, $icode ok$$ is true. -Otherwise it is false. - -$children% - example/atomic_three/hes_sparsity.cpp -%$$ -$head Examples$$ -The file $cref atomic_three_hes_sparsity.cpp$$ contains an example and test -that uses this routine. -$end ------------------------------------------------------------------------------ -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_hes_sparsity.hpp -Third generation atomic Hessian dependency and sparsity patterns. -*/ -/*! -atomic_three to Hessian dependency and sparsity calculations. - -\param parameter_x [in] -contains the values for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param select_x [in] -which domain components to include in the dependency or sparsity pattern. - -\param select_y [in] -which range components to include in the dependency or sparsity pattern. - -\param pattern_out [out] -is the sparsity pattern for Hessian. -*/ -// BEGIN_PROTOTYPE -template -bool atomic_three::hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out ) -// END_PROTOTYPE -{ return false; } -/*! -Link from forward Hessian sweep to atomic_three. -2DO: move this functiton outside this file so can change -developer documentation to omhelp formating. - -\tparam InternalSparsity -Is the used internaly for sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param parameter_x -is parameter arguments to the function, other components are nan. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param x_index -is the variable index, on the tape, for the arguments to this function. -This size of x_index is n, the number of arguments to this function. -The index zero is used for parameters. - -\param y_index -is the variable index, on the tape, for the results for this function. -This size of y_index is m, the number of results for this function. -The index zero is used for parameters. - -\param for_jac_sparsity -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the forward Jacobian sparsity for the j-th argument to this atomic function. - -\param rev_jac_pattern -On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the reverse Jacobian sparsity for the i-th result to this atomic function. -This shows which components of the result affect the function we are -computing the Hessian of. - -\param hes_sparsity_for -This is the sparsity pattern for the Hessian. On input, the non-linear -terms in the atomic fuction have not been included. Upon return, they -have been included. -*/ -template -template -bool atomic_three::for_hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - size_t np1 , - size_t numvar , - const InternalSparsity& rev_jac_pattern , - InternalSparsity& for_sparsity ) -{ typedef typename InternalSparsity::const_iterator const_iterator; - // - CPPAD_ASSERT_UNKNOWN( rev_jac_pattern.end() == 1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar ); - size_t n = x_index.size(); - size_t m = y_index.size(); - // - // select_x - vector select_x(n); - for(size_t j = 0; j < n; j++) - { // check if should compute pattern w.r.t x[j] - select_x[j] = for_sparsity.number_elements(np1 + x_index[j]) > 0; - } - // - // bool select_y - vector select_y(m); - for(size_t i = 0; i < m; i++) - { // check if we should include y[i] - select_y[i] = rev_jac_pattern.number_elements(y_index[i]) > 0; - } - // ------------------------------------------------------------------------ - // call user's version of atomic function for Jacobian - sparse_rc< vector > pattern_out; - bool dependency = false; - bool ok = jac_sparsity( - parameter_x, type_x, dependency, select_x, select_y, pattern_out - ); - if( ! ok ) - return false; - // - // transfer sparsity patterns from pattern_out to var_sparsity - size_t nnz = pattern_out.nnz(); - const vector& row( pattern_out.row() ); - const vector& col( pattern_out.col() ); - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - CPPAD_ASSERT_KNOWN( - select_y[i] & select_x[j], - "atomic: jac_sparsity: pattern_out not in " - "select_x or select_y range" - ); - const_iterator itr(for_sparsity, np1 + x_index[j]); - size_t ell = *itr; - while( ell < np1 ) - { for_sparsity.post_element(np1 + y_index[i], ell ); - ell = *(++itr); - } - } - for(size_t i = 0; i < m; ++i) - for_sparsity.process_post( np1 + y_index[i] ); - // ------------------------------------------------------------------------ - // call user's version of atomic function for Hessian - ok = hes_sparsity( - parameter_x, type_x, select_x, select_y, pattern_out - ); - if( ! ok ) - return ok; - // - // add new elements to Hessian sparisty in calling routine - nnz = pattern_out.nnz(); - for(size_t k = 0; k < nnz; ++k) - { size_t r = row[k]; - size_t c = col[k]; - CPPAD_ASSERT_KNOWN( - select_x[r] & select_x[c], - "atomic: hes_sparsity: pattern_out not in select_x range" - ); - const_iterator itr_1(for_sparsity, np1 + x_index[r]); - size_t v1 = *itr_1; - while( v1 < np1 ) - { for_sparsity.binary_union( - v1, v1, np1 + x_index[c], for_sparsity - ); - v1 = *(++itr_1); - } - // no need to add same elements twice - if( c != r ) - { const_iterator itr_2(for_sparsity, np1 + x_index[c]); - size_t v2 = *itr_2; - while( v2 < np1 ) - { for_sparsity.binary_union( - v2, v2, np1 + x_index[r], for_sparsity - ); - v2 = *(++itr_2); - } - } - } - return ok; -} -/*! -Link from for_reverse Hessian sweep to atomic_three. - -\tparam InternalSparsity -Is the used internaly for sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param parameter_x -is parameter arguments to the function, other components are nan. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param x_index -is the variable index, on the tape, for the arguments to this function. -This size of x_index is n, the number of arguments to this function. -The index zero is used for parameters. - -\param y_index -is the variable index, on the tape, for the results for this function. -This size of y_index is m, the number of results for this function. -The index zero is used for parameters. - -\param for_jac_pattern -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the forward Jacobian pattern for the j-th argument to this atomic function. - -\param rev_jac_flag -On input, for i = 0, ... , m-1, rev_jac_flag[ y_index[i] ] is true -if the function we are computing the Hessian of has possibly non-zero Jacobian -w.r.t varialbe y_index[i]. -On output, for j = 0, ... , n, rev_jac_flag[ x_index[j] ] is set to true -if the varialbe with index x_index[j] has possible non-zero Jacobian -with repect to one of the true y_index[i] cases. -Otherwise, rev_jac_flag [ x_inde[j] ] is not changed. - -\param hes_sparsity_rev -Is the reverse mode sparsity pattern for the Hessian. On input, the non-linear -terms in the atomic fuction have not been included. Upon return, they -have been included. -*/ -template -template -bool atomic_three::rev_hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - const InternalSparsity& for_jac_pattern , - bool* rev_jac_flag , - InternalSparsity& hes_sparsity_rev ) -{ typedef typename InternalSparsity::const_iterator const_iterator; - size_t n = x_index.size(); - size_t m = y_index.size(); - // - // select_x - vector select_x(n); - for(size_t j = 0; j < n; j++) - { // check if should compute pattern w.r.t x[j] - const_iterator itr(for_jac_pattern, x_index[j]); - size_t i = *itr; - select_x[j] = i < for_jac_pattern.end(); - CPPAD_ASSERT_UNKNOWN( x_index[j] > 0 || ! select_x[j] ); - } - // - // bool select_y - vector select_y(m); - for(size_t i = 0; i < m; i++) - { // check if we should include y[i] - select_y[i] = rev_jac_flag[ y_index[i] ]; - CPPAD_ASSERT_UNKNOWN( y_index[i] > 0 || ! select_y[i] ); - } - // - // call atomic function for Jacobain sparsity - bool dependency = false; - sparse_rc< vector > pattern_jac; - bool ok = jac_sparsity( - parameter_x, type_x, dependency, select_x, select_y, pattern_jac - ); - const vector& row_jac( pattern_jac.row() ); - const vector& col_jac( pattern_jac.col() ); - size_t nnz_jac = pattern_jac.nnz(); - if( ! ok ) - return ok; - // - // call atomic function for Hessian sparsity - sparse_rc< vector > pattern_hes; - ok = hes_sparsity(parameter_x, type_x, select_x, select_y, pattern_hes); - const vector& row_hes( pattern_hes.row() ); - const vector& col_hes( pattern_hes.col() ); - size_t nnz_hes = pattern_hes.nnz(); - if( ! ok ) - return ok; - // - // propagate Hessian sparsity through the Jacobian - for(size_t k = 0; k < nnz_jac; ++k) - { size_t i = row_jac[k]; - size_t j = col_jac[k]; - CPPAD_ASSERT_KNOWN( - select_y[i] & select_x[j] , - "atomic: jac_sparsity: pattern_out not in " - "select_x or select_y range" - ); - // from y_index[i] to x_index[j] - hes_sparsity_rev.binary_union( - x_index[j], x_index[j], y_index[i], hes_sparsity_rev - ); - } - // - // propagate rev_jac_flag through the Jacobian - // (seems OK to exclude variables with zero forward jacobian) - for(size_t k = 0; k < nnz_jac; ++k) - { size_t j = col_jac[k]; - rev_jac_flag[ x_index[j] ] = true; - } - // - // new hessian sparsity terms between y and x - for(size_t k = 0; k < nnz_hes; ++k) - { size_t r = row_hes[k]; - size_t c = col_hes[k]; - CPPAD_ASSERT_KNOWN( - select_x[r] & select_x[c] , - "atomic: hes_sparsity: pattern_out not in select_x range" - ); - hes_sparsity_rev.binary_union( - x_index[r], x_index[r], x_index[c], for_jac_pattern - ); - hes_sparsity_rev.binary_union( - x_index[c], x_index[c], x_index[r], for_jac_pattern - ); - } - return ok; -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_jac_sparsity.hpp b/build-config/cppad/include/cppad/core/atomic/three_jac_sparsity.hpp deleted file mode 100644 index 234a3d67..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_jac_sparsity.hpp +++ /dev/null @@ -1,355 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_JAC_SPARSITY_HPP -# define CPPAD_CORE_ATOMIC_THREE_JAC_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_jac_sparsity$$ -$spell - Jacobian - afun - jac -$$ - -$section Atomic Function Jacobian Sparsity Patterns$$ - -$head Syntax$$ -$icode%ok% = %afun%.jac_sparsity( - %parameter_x%, %type_x%, %dependency%, %select_x%, %select_y%, %pattern_out% -)%$$ - -$head Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Implementation$$ -This function must be defined if -$cref/afun/atomic_three_ctor/atomic_user/afun/$$ is -used to define an $cref ADFun$$ object $icode f$$, -and Jacobian sparsity patterns are computed for $icode f$$. -(Computing Hessian sparsity patterns and optimizing -requires Jacobian sparsity patterns.) - -$head Base$$ -See $cref/Base/atomic_three_afun/Base/$$. - -$head parameter_x$$ -See $cref/parameter_x/atomic_three/parameter_x/$$. - -$head type_x$$ -See $cref/type_x/atomic_three/type_x/$$. - -$head dependency$$ -If $icode dependency$$ is true, -then $icode pattern_out$$ is a -$cref/dependency pattern/dependency.cpp/Dependency Pattern/$$ -for this atomic function. -Otherwise it is a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ for the -derivative of the atomic function. - -$head select_x$$ -This argument has size equal to the number of arguments to this -atomic function; i.e. the size of $icode ax$$. -It specifies which domain components are included in -the calculation of $icode pattern_out$$. -If $icode%select_x%[%j%]%$$ is false, then there will be no indices -$icode k$$ such that -$codei% - %pattern_out%.col()[%k%] == %j% -%$$. - -$head select_y$$ -This argument has size equal to the number of results to this -atomic function; i.e. the size of $icode ay$$. -It specifies which range components are included in -the calculation of $icode pattern_out$$. -If $icode%select_y%[%i%]%$$ is false, then there will be no indices -$icode k$$ such that -$codei% - %pattern_out%.row()[%k%] == %i% -%$$. - -$head pattern_out$$ -This input value of $icode pattern_out$$ does not matter. -Upon return it is a -dependency or sparsity pattern for the Jacobian of $latex g(x)$$, -the function corresponding to -$cref/afun/atomic_three_ctor/atomic_user/afun/$$; -$icode dependency$$ above. -To be specific, there are non-negative indices -$icode i$$, $icode j$$, $icode k$$ such that -$codei% - %pattern_out%.row()[%k%] == %i% - %pattern_out%.col()[%k%] == %j% -%$$ -if and only if -$icode%select_x%[%j%]%$$ is true, -$icode%select_y%[%j%]%$$ is true, -and $latex g_i(x)$$ depends on the value of $latex x_j$$ -(and the partial of $latex g_i(x)$$ with respect to -$latex x_j$$ is possibly non-zero). - -$head ok$$ -If this calculation succeeded, $icode ok$$ is true. -Otherwise it is false. - - -$children% - example/atomic_three/jac_sparsity.cpp -%$$ -$head Examples$$ -The file $cref atomic_three_jac_sparsity.cpp$$ contains an example and test -that uses this routine. -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_jac_sparsity.hpp -Third generation atomic Jacobian dependency and sparsity patterns. -*/ -/*! -atomic_three to Jacobian dependency and sparsity calculations. - -\param parameter_x [in] -contains the values for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param dependency [in] -if true, calculate dependency pattern, -otherwise calcuate sparsity pattern. - -\param select_x [in] -which domain components to include in the dependency or sparsity pattern. -The index zero is used for parameters. - -\param select_y [in] -which range components to include in the dependency or sparsity pattern. -The index zero is used for parameters. - -\param pattern_out [out] -is the dependency or sparsity pattern. -*/ -// BEGIN_PROTOTYPE -template -bool atomic_three::jac_sparsity( - const vector& parameter_x , - const vector& type_x , - bool dependency , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out ) -// END_PROTOTYPE -{ return false; } -/*! -Link from forward Jacobian sparsity calcuations to atomic_three - -\tparam InternalSparsity -Is the type used for internal sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param dependency -if true, calcuate dependency pattern, -otherwise calcuate sparsity pattern. - -\param parameter_x -is parameter arguments to the function, other components are nan. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param x_index -is the variable index, on the tape, for the arguments to this atomic function. -This size of x_index is n, the number of arguments to this atomic function. -The index zero is used for parameters. - -\param y_index -is the variable index, on the tape, for the results for this atomic function. -This size of y_index is m, the number of results for this atomic function. -The index zero is used for parameters. - -\param var_sparsity -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the sparsity for the j-th argument to this atomic function. -On output, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the sparsity for the i-th result for this atomic function. - -\return -is true if the computation succeeds. -*/ -template -template -bool atomic_three::for_jac_sparsity( - bool dependency , - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity ) -{ typedef typename InternalSparsity::const_iterator iterator; - - // number of arguments and resutls for this atomic function - size_t n = x_index.size(); - size_t m = y_index.size(); - - // select_y - vector select_y(m); - for(size_t i = 0; i < m; ++i) - select_y[i] = y_index[i] != 0; - - // determine select_x - vector select_x(n); - for(size_t j = 0; j < n; ++j) - { // check if x_j depends on any previous variable - iterator itr(var_sparsity, x_index[j]); - size_t ell = *itr; - select_x[j] = ell < var_sparsity.end(); - CPPAD_ASSERT_UNKNOWN( x_index[j] > 0 || ! select_x[j] ); - } - sparse_rc< vector > pattern_out; - bool ok = jac_sparsity( - parameter_x, type_x, dependency, select_x, select_y, pattern_out - ); - if( ! ok ) - return false; - // - // transfer sparsity patterns from pattern_out to var_sparsity - size_t nnz = pattern_out.nnz(); - const vector& row( pattern_out.row() ); - const vector& col( pattern_out.col() ); - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - CPPAD_ASSERT_KNOWN( - select_y[i] & select_x[j], - "atomic: jac_sparsity: pattern_out not in " - "select_x or select_y range" - ); - iterator itr(var_sparsity, x_index[j]); - size_t ell = *itr; - while( ell < var_sparsity.end() ) - { var_sparsity.post_element( y_index[i], ell ); - ell = *(++itr); - } - } - for(size_t i = 0; i < m; ++i) - var_sparsity.process_post( y_index[i] ); - // - return true; -} -/*! -Link from reverse Jacobian sparsity calcuations to atomic_three - -\tparam InternalSparsity -Is the type used for internal sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param dependency -if true, calcuate dependency pattern, -otherwise calcuate sparsity pattern. - -\param parameter_x -is parameter arguments to the function, other components are nan. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param x_index -is the variable index, on the tape, for the arguments to this atomic function. -This size of x_index is n, the number of arguments to this atomic function. - -\param y_index -is the variable index, on the tape, for the results for this atomic function. -This size of y_index is m, the number of results for this atomic function. - -\param var_sparsity -On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the sparsity of the outter function with respect to the i-th -result for this atomic function. -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the sparsity for the outter function with repsect to the j-th -argument to this atomic function. -On output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the sparsity for the outter function with repsect to the j-th -argument to this atomic function with the atomic function results -removed as arguments to the outter function. - -\return -is true if the computation succeeds. -*/ -template -template -bool atomic_three::rev_jac_sparsity( - bool dependency , - const vector& parameter_x , - const vector& type_x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity ) -{ typedef typename InternalSparsity::const_iterator iterator; - - // number of arguments and resutls for this atomic function - size_t n = x_index.size(); - size_t m = y_index.size(); - - // selection vectors - vector select_x(n), select_y(m); - - // 2DO: perhaps we could use for_type(type_x, type_y) - // to reduce the true components in select_x - for(size_t j = 0; j < n; ++j) - select_x[j] = true; - - // determine select_y - for(size_t i = 0; i < m; ++i) - { // check if y_i has sparsity is non-empty - iterator itr(var_sparsity, y_index[i]); - size_t ell = *itr; - select_y[i] = ell < var_sparsity.end(); - } - sparse_rc< vector > pattern_out; - bool ok = jac_sparsity( - parameter_x, type_x, dependency, select_x, select_y, pattern_out - ); - if( ! ok ) - return false; - // - // transfer sparsity patterns from pattern_out to var_sparsity - size_t nnz = pattern_out.nnz(); - const vector& row( pattern_out.row() ); - const vector& col( pattern_out.col() ); - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - CPPAD_ASSERT_KNOWN( - select_y[i] & select_x[j], - "atomic: jac_sparsity: pattern_out not in " - "select_x or select_y range" - ); - iterator itr(var_sparsity, y_index[i]); - size_t ell = *itr; - while( ell < var_sparsity.end() ) - { var_sparsity.post_element( x_index[j], ell ); - ell = *(++itr); - } - } - for(size_t j = 0; j < n; ++j) - var_sparsity.process_post( x_index[j] ); - // - return true; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_rev_depend.hpp b/build-config/cppad/include/cppad/core/atomic/three_rev_depend.hpp deleted file mode 100644 index d05e91a1..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_rev_depend.hpp +++ /dev/null @@ -1,125 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_REV_DEPEND_HPP -# define CPPAD_CORE_ATOMIC_THREE_REV_DEPEND_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_rev_depend$$ -$spell - afun - enum - cpp - taylor.hpp -$$ - -$section Atomic Function Reverse Dependency Calculation$$ - -$head Syntax$$ -$icode%ok% = %afun%.rev_depend( - %parameter_x%, %type_x%, %depend_x%, %depend_y% -)%$$ - -$subhead Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Dependency Analysis$$ -This calculation is sometimes referred to as a reverse dependency analysis. - -$head Implementation$$ -This function must be defined if -$cref/afun/atomic_three_ctor/atomic_user/afun/$$ is -used to define an $cref ADFun$$ object $icode f$$, -and $cref/f.optimize()/optimize/$$ is used. - -$head Base$$ -See $cref/Base/atomic_three_afun/Base/$$. - -$head parameter_x$$ -See $cref/parameter_x/atomic_three/parameter_x/$$. - -$head type_x$$ -See $cref/type_x/atomic_three/type_x/$$. - -$head depend_x$$ -This vector has size equal to the number of arguments for this atomic function; -i.e. $icode%n%=%ax%.size()%$$. -The input values of the elements of $icode depend_x$$ -are not specified (must not matter). -Upon return, for $latex j = 0 , \ldots , n-1$$, -$icode%depend_x%[%j%]%$$ is true if the values of interest depend -on the value of $cref/ax[j]/atomic_three_afun/ax/$$ in the corresponding -$icode%afun%(%ax%, %ay%)%$$ call. -Note that parameters and variables, -that the values of interest do not depend on, -may get removed by $cref/optimization/optimize/$$. -The corresponding values in $cref/parameter_x/atomic_three/parameter_x/$$, -and $cref/taylor_x/atomic_three_forward/taylor_x/$$ -(after optimization has removed them) are not specified. - -$head depend_y$$ -This vector has size equal to the number of results for this atomic function; -i.e. $icode%m%=%ay%.size()%$$. -For $latex i = 0 , \ldots , m-1$$, -$icode%depend_y%[%i%]%$$ is true if the values of interest depend -on the value of $cref/ay[i]/atomic_three_afun/ay/$$ in the corresponding -$icode%afun%(%ax%, %ay%)%$$ call. - -$head ok$$ -If this calculation succeeded, $icode ok$$ is true. -Otherwise, it is false. - -$childtable% - example/atomic_three/rev_depend.cpp -%$$ -$head Example$$ -The following is an example of a atomic function $code rev_depend$$ definition: -$cref atomic_three_rev_depend.cpp$$. - - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_rev_depend.hpp -Third generation atomic type computation. -*/ -/*! -Link from atomic_three to reverse dependency calculation - -\param parameter_x [in] -is the value of the parameters in the corresponding function call -afun(ax, ay). - -\param type_x [in] -is the value for each of the components of x. - -\param depend_x [out] -specifies which components of x affect values of interest. - -\param depend_y [in] -specifies which components of y affect values of interest. -*/ -// BEGIN_PROTOTYPE -template -bool atomic_three::rev_depend( - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y ) -// END_PROTOTYPE -{ return false; } - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/three_reverse.hpp b/build-config/cppad/include/cppad/core/atomic/three_reverse.hpp deleted file mode 100644 index 99dd6091..00000000 --- a/build-config/cppad/include/cppad/core/atomic/three_reverse.hpp +++ /dev/null @@ -1,354 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_THREE_REVERSE_HPP -# define CPPAD_CORE_ATOMIC_THREE_REVERSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_three_reverse$$ -$spell - sq - mul.hpp - afun - ty - px - py - Taylor - const - CppAD - atx - aty - apx - apy - af - aparameter - enum -$$ - -$section Atomic Function Reverse Mode$$ -$spell - ataylor - apartial -$$ - -$head Base$$ -This syntax is used by $icode%f%.Reverse%$$ where $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -and $icode afun$$ is used in $icode f$$; -see $cref/Base/atomic_three_afun/Base/$$. - -$subhead Syntax$$ -$icode%ok% = %afun%.reverse( - %parameter_x%, %type_x%, - %order_up%, %taylor_x%, %taylor_y%, %partial_x%, %partial_y% -) -%$$ - -$subhead Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE_BASE%// END_PROTOTYPE_BASE%1 -%$$ - -$head AD$$ -This syntax is used by $icode%af%.Reverse%$$ where $icode af$$ has prototype -$codei% - ADFun< AD<%Base%> , %Base% > %af% -%$$ -and $icode afun$$ is used in $icode af$$ (see $cref base2ad$$). - -$subhead Syntax$$ -$icode%ok% = %afun%.reverse( - %aparameter_x%, %type_x%, - %order_up%, %ataylor_x%, %ataylor_y%, %apartial_x%, %apartial_y% -) -%$$ - -$subhead Prototype$$ -$srcthisfile%0%// BEGIN_PROTOTYPE_AD_BASE%// END_PROTOTYPE_AD_BASE%1 -%$$ - -$head Implementation$$ -This function must be defined if -$cref/afun/atomic_three_ctor/atomic_user/afun/$$ is -used to define an $cref ADFun$$ object $icode f$$, -and reverse mode derivatives are computed for $icode f$$. -It can return $icode%ok% == false%$$ -(and not compute anything) for values -of $icode order_up$$ that are greater than those used by your -$cref/reverse/Reverse/$$ mode calculations. - -$head parameter_x$$ -See $cref/parameter_x/atomic_three/parameter_x/$$. - -$head aparameter_x$$ -The specifications for $icode aparameter_x$$ -is the same as for $cref/parameter_x/atomic_three/parameter_x/$$ -(only the type of $icode ataylor_x$$ is different). - -$head type_x$$ -See $cref/type_x/atomic_three/type_x/$$. - -$head order_up$$ -This argument specifies the highest order Taylor coefficient that -computing the derivative of. - -$head taylor_x$$ -The size of $icode taylor_x$$ is $codei%(%q%+1)*%n%$$. -For $latex j = 0 , \ldots , n-1$$ and $latex k = 0 , \ldots , q$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - x_j^k & = & \R{taylor\_x} [ j * ( q + 1 ) + k ] - \\ - X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^q t^q -\end{array} -\] $$ -Note that superscripts represent an index for $latex x_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex X(t)$$ correspond -to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - x_j^k = \frac{1}{ k ! } X_j^{(k)} (0) -\] $$ - -$subhead parameters$$ -If the $th j$$ component of $icode x$$ corresponds to a parameter, -$codei% - %type_x%[%j%] < CppAD::variable_enum -%$$ -In this case, -the $th j$$ component of $icode parameter_x$$ is equal to $latex x_j^0$$; -i.e., -$codei% - %parameter_x%[%j%] == %taylor_x%[ %j% * ( %q% + 1 ) + 0 ] -%$$ -Furthermore, for $icode%k% > 0%$$, -$codei% - %taylor_x%[ %j% * ( %q% + 1 ) + %k% ] == 0 -%$$ - -$head ataylor_x$$ -The specifications for $icode ataylor_x$$ is the same as for $icode taylor_x$$ -(only the type of $icode ataylor_x$$ is different). - -$head taylor_y$$ -The size of $icode taylor_y$$ is $codei%(%q%+1)*%m%$$. -Upon return, -For $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , q$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - Y_i (t) & = & g_i [ X(t) ] - \\ - Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q ) - \\ - y_i^k & = & \R{taylor\_y} [ i * ( q + 1 ) + k ] -\end{array} -\] $$ -where $latex o( t^q ) / t^q \rightarrow 0$$ as $latex t \rightarrow 0$$. -Note that superscripts represent an index for $latex y_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex Y(t)$$ correspond -to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0) -\] $$ - -$head ataylor_y$$ -The specifications for $icode ataylor_y$$ is the same as for $icode taylor_y$$ -(only the type of $icode ataylor_y$$ is different). - -$head F$$ -We use the notation $latex \{ x_j^k \} \in \B{R}^{n \times (q+1)}$$ for -$latex \[ - \{ x_j^k \W{:} j = 0 , \ldots , n-1, k = 0 , \ldots , q \} -\]$$ -We use the notation $latex \{ y_i^k \} \in \B{R}^{m \times (q+1)}$$ for -$latex \[ - \{ y_i^k \W{:} i = 0 , \ldots , m-1, k = 0 , \ldots , q \} -\]$$ -We define the function -$latex F : \B{R}^{n \times (q+1)} \rightarrow \B{R}^{m \times (q+1)}$$ by -$latex \[ - y_i^k = F_i^k [ \{ x_j^k \} ] -\] $$ -Note that -$latex \[ - F_i^0 ( \{ x_j^k \} ) = g_i ( X(0) ) = g_i ( x^0 ) -\] $$ -We also note that -$latex F_i^\ell ( \{ x_j^k \} )$$ is a function of -$latex x^0 , \ldots , x^\ell$$ -and is determined by the derivatives of $latex g_i (x)$$ -up to order $latex \ell$$. - -$head G, H$$ -We use $latex G : \B{R}^{m \times (q+1)} \rightarrow \B{R}$$ -to denote an arbitrary scalar valued function of $latex \{ y_i^k \}$$. -We use $latex H : \B{R}^{n \times (q+1)} \rightarrow \B{R}$$ -defined by -$latex \[ - H ( \{ x_j^k \} ) = G[ F( \{ x_j^k \} ) ] -\] $$ - -$head partial_y$$ -The size of $icode partial_y$$ is $codei%(%q%+1)*%m%%$$. -For $latex i = 0 , \ldots , m-1$$, $latex k = 0 , \ldots , q$$, -$latex \[ - \R{partial\_y} [ i * (q + 1 ) + k ] = \partial G / \partial y_i^k -\] $$ - -$head apartial_y$$ -The specifications for $icode apartial_y$$ is the same as for -$icode partial_y$$ (only the type of $icode apartial_y$$ is different). - -$head partial_x$$ -The size of $icode partial_x$$ is $codei%(%q%+1)*%n%%$$. -The input values of the elements of $icode partial_x$$ -are not specified (must not matter). -Upon return, -for $latex j = 0 , \ldots , n-1$$ and $latex \ell = 0 , \ldots , q$$, -$latex \[ -\begin{array}{rcl} -\R{partial\_x} [ j * (q + 1) + \ell ] & = & \partial H / \partial x_j^\ell -\\ -& = & -( \partial G / \partial \{ y_i^k \} ) \cdot - ( \partial \{ y_i^k \} / \partial x_j^\ell ) -\\ -& = & -\sum_{k=0}^q -\sum_{i=0}^{m-1} -( \partial G / \partial y_i^k ) ( \partial y_i^k / \partial x_j^\ell ) -\\ -& = & -\sum_{k=\ell}^q -\sum_{i=0}^{m-1} -\R{partial\_y}[ i * (q + 1 ) + k ] ( \partial F_i^k / \partial x_j^\ell ) -\end{array} -\] $$ -Note that we have used the fact that for $latex k < \ell$$, -$latex \partial F_i^k / \partial x_j^\ell = 0$$. - -$subhead Short Circuit Operations$$ -Note that if -$codei%IdenticalZero(%partial_y%[%i%*(%q%+1)+%k%])%$$ is true, -one does not need to compute $latex ( \partial F_i^k / \partial x_j^\ell )$$; -see $cref base_identical$$. -This can be used, -in a similar way to $cref/need_y/atomic_three_forward/need_y/$$, -to avoid unnecessary operations. - -$head apartial_x$$ -The specifications for $icode apartial_x$$ is the same as for -$icode partial_x$$ (only the type of $icode apartial_x$$ is different). - -$head ok$$ -If this calculation succeeded, $icode ok$$ is true. -Otherwise it is false. - -$children% - example/atomic_three/reverse.cpp -%$$ -$head Examples$$ -The file $cref atomic_three_reverse.cpp$$ contains an example and test -that uses this routine. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/three_reverse.hpp -Third Generation Atomic reverse mode. -*/ -/*! -Link from reverse mode sweep to users routine. - -\param parameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param order_up [in] -highest order for this reverse mode calculation. - -\param taylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param taylor_y [in] -Taylor coefficient corresponding to y for this calculation - -\param partial_x [out] -Partials w.r.t. the x Taylor coefficients. - -\param partial_y [in] -Partials w.r.t. the y Taylor coefficients. - -See atomic_three_reverse mode use documentation -*/ -// BEGIN_PROTOTYPE_BASE -template -bool atomic_three::reverse( - const vector& parameter_x , - const vector& type_x , - size_t order_up , - const vector& taylor_x , - const vector& taylor_y , - vector& partial_x , - const vector& partial_y ) -// END_PROTOTYPE_BASE -{ return false; } - -/*! -Link from reverse mode sweep to users routine. - -\param aparameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - - -\param order_up [in] -highest order for this reverse mode calculation. - -\param ataylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param ataylor_y [in] -Taylor coefficient corresponding to y for this calculation - -\param apartial_x [out] -Partials w.r.t. the x Taylor coefficients. - -\param apartial_y [in] -Partials w.r.t. the y Taylor coefficients. - -See atomic_three_reverse mode use documentation -*/ -// BEGIN_PROTOTYPE_AD_BASE -template -bool atomic_three::reverse( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t order_up , - const vector< AD >& ataylor_x , - const vector< AD >& ataylor_y , - vector< AD >& apartial_x , - const vector< AD >& apartial_y ) -// END_PROTOTYPE_AD_BASE -{ return false; } - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_afun.hpp b/build-config/cppad/include/cppad/core/atomic/two_afun.hpp deleted file mode 100644 index 8aba0f37..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_afun.hpp +++ /dev/null @@ -1,258 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_AFUN_HPP -# define CPPAD_CORE_ATOMIC_TWO_AFUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_afun$$ - -$spell - sq - mul - afun - const - CppAD - mat_mul.cpp -$$ - -$section Using AD Version of Atomic Function$$ - -$head Syntax$$ -$icode%afun%(%ax%, %ay%)%$$ - -$head Purpose$$ -Given $icode ax$$, -this call computes the corresponding value of $icode ay$$. -If $codei%AD<%Base%>%$$ operations are being recorded, -it enters the computation as an atomic operation in the recording; -see $cref/start recording/Independent/Start Recording/$$. - -$head ADVector$$ -The type $icode ADVector$$ must be a -$cref/simple vector class/SimpleVector/$$ with elements of type -$codei%AD<%Base%>%$$; see $cref/Base/atomic_two_ctor/atomic_base/Base/$$. - -$head afun$$ -is a $cref/atomic_user/atomic_two_ctor/atomic_user/$$ object -and this $icode afun$$ function call is implemented by the -$cref/atomic/atomic_two_ctor/atomic_base/$$ class. - -$head ax$$ -This argument has prototype -$codei% - const %ADVector%& %ax% -%$$ -and size must be equal to $icode n$$. -It specifies vector $latex x \in \B{R}^n$$ -at which an $codei%AD<%Base%>%$$ version of -$latex y = f(x)$$ is to be evaluated; see -$cref/Base/atomic_two_ctor/atomic_base/Base/$$. - -$head ay$$ -This argument has prototype -$codei% - %ADVector%& %ay% -%$$ -and size must be equal to $icode m$$. -The input values of its elements -are not specified (must not matter). -Upon return, it is an $codei%AD<%Base%>%$$ version of -$latex y = f(x)$$. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_afun.hpp -Implement user call to an atomic_two function. -*/ - -/*! -Implement the user call to afun(ax, ay) and atomic_one call to -afun(ax, ay, id). - -\tparam ADVector -A simple vector class with elements of type AD. - -\param id -optional extra information vector that is just passed through by CppAD, -and used by atomic_one derived class (not other derived classes). -This is an extra parameter to the virtual callbacks for atomic_one; -see the set_old member function. - -\param ax -is the argument vector for this call, -ax.size() determines the number of arguments. - -\param ay -is the result vector for this call, -ay.size() determines the number of results. -*/ -template -template -void atomic_base::operator()( - const ADVector& ax , - ADVector& ay , - size_t id ) -{ size_t i, j; - size_t n = ax.size(); - size_t m = ay.size(); -# ifndef NDEBUG - bool ok; - std::string msg = "atomic_base: " + atomic_name() + ".eval: "; - if( (n == 0) | (m == 0) ) - { msg += "ax.size() or ay.size() is zero"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - vector & tx = work_[thread]->tx; - vector & ty = work_[thread]->ty; - vector & vx = work_[thread]->vx; - vector & vy = work_[thread]->vy; - // - if( vx.size() != n ) - { vx.resize(n); - tx.resize(n); - } - if( vy.size() != m ) - { vy.resize(m); - ty.resize(m); - } - // - // Determine tape corresponding to variables in ax - tape_id_t tape_id = 0; - local::ADTape* tape = nullptr; - for(j = 0; j < n; j++) - { tx[j] = ax[j].value_; - vx[j] = ! Constant( ax[j] ); - if( vx[j] ) - { - if( tape_id == 0 ) - { tape = ax[j].tape_this(); - tape_id = ax[j].tape_id_; - CPPAD_ASSERT_UNKNOWN( tape != nullptr ); - } -# ifndef NDEBUG - if( tape_id != ax[j].tape_id_ ) - { msg += atomic_name() + - ": ax contains variables from different threads."; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } -# endif - } - } - // Use zero order forward mode to compute values - size_t p = 0, q = 0; - set_old(id); -# ifdef NDEBUG - forward(p, q, vx, vy, tx, ty); -# else - ok = forward(p, q, vx, vy, tx, ty); - if( ! ok ) - { msg += atomic_name() + ": ok is false for " - "zero order forward mode calculation."; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } -# endif - bool record_operation = false; - for(i = 0; i < m; i++) - { - // pass back values - ay[i].value_ = ty[i]; - - // initialize entire vector parameters (not in tape) - ay[i].tape_id_ = 0; - ay[i].taddr_ = 0; - - // we need to record this operation if - // any of the elemnts of ay are variables, - record_operation |= vy[i]; - } -# ifndef NDEBUG - if( record_operation & (tape == nullptr) ) - { msg += - "all elements of vx are false but vy contains a true element"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - // if tape is not null, ay is on the tape - if( record_operation ) - { - // Operator that marks beginning of this atomic operation - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AFunOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AFunOp) == 4 ); - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= - std::max( std::max( std::max(index_, id), n), m ), - "atomic_base: cppad_tape_addr_type maximum not large enough" - ); - tape->Rec_.PutArg(addr_t(index_), addr_t(id), addr_t(n), addr_t(m)); - tape->Rec_.PutOp(local::AFunOp); - - // Now put n operators, one for each element of argument vector - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunavOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunapOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunavOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunapOp) == 1 ); - for(j = 0; j < n; j++) - { if( Variable(ax[j]) ) - { // information for an argument that is a variable - tape->Rec_.PutArg(ax[j].taddr_); - tape->Rec_.PutOp(local::FunavOp); - } - else - { // information for an argument that is parameter - addr_t par = ax[j].taddr_; - if( ! Dynamic( ax[j] ) ) - par = tape->Rec_.put_con_par(ax[j].value_); - tape->Rec_.PutArg(par); - tape->Rec_.PutOp(local::FunapOp); - } - } - - // Now put m operators, one for each element of result vector - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunrpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunrpOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunrvOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunrvOp) == 1 ); - for(i = 0; i < m; i++) - { if( vy[i] ) - { ay[i].taddr_ = tape->Rec_.PutOp(local::FunrvOp); - ay[i].tape_id_ = tape_id; - ay[i].ad_type_ = variable_enum; - } - else - { CPPAD_ASSERT_UNKNOWN( ! Dynamic( ay[i] ) ); - addr_t par = tape->Rec_.put_con_par(ay[i].value_); - tape->Rec_.PutArg(par); - tape->Rec_.PutOp(local::FunrpOp); - } - } - - // Put a duplicate AFunOp at end of AFunOp sequence - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= - std::max( std::max( std::max(index_, id), n), m ), - "atomic_base: cppad_tape_addr_type maximum not large enough" - ); - tape->Rec_.PutArg(addr_t(index_), addr_t(id), addr_t(n), addr_t(m)); - tape->Rec_.PutOp(local::AFunOp); - } - return; -} - - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_clear.hpp b/build-config/cppad/include/cppad/core/atomic/two_clear.hpp deleted file mode 100644 index 0223be73..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_clear.hpp +++ /dev/null @@ -1,91 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_CLEAR_HPP -# define CPPAD_CORE_ATOMIC_TWO_CLEAR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_clear$$ -$spell - sq - alloc -$$ - -$section Free Static Variables$$ - -$head Syntax$$ -$codei%atomic_base<%Base%>::clear()%$$ - -$head Purpose$$ -Each $code atomic_base$$ objects holds onto work space in order to -avoid repeated memory allocation calls and thereby increase speed -(until it is deleted). -If an the $code atomic_base$$ object is global or static because, -the it does not get deleted. -This is a problem when using -$code thread_alloc$$ $cref/free_all/ta_free_all/$$ -to check that all allocated memory has been freed. -Calling this $code clear$$ function will free all the -memory currently being held onto by the -$codei%atomic_base<%Base%>%$$ class. - -$head Future Use$$ -If there is future use of an $code atomic_base$$ object, -after a call to $code clear$$, -the work space will be reallocated and held onto. - -$head Restriction$$ -This routine cannot be called -while in $cref/parallel/ta_in_parallel/$$ execution mode. - -$end ------------------------------------------------------------------------------- -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_clear.hpp -Free static variables in atomic_base class. -*/ -/*! -Free all thread_alloc static memory held by atomic_base (avoids reallocations). -(This does not include class_object() which is an std::vector.) -*/ -template -void atomic_base::clear(void) -{ CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "cannot use atomic_base clear during parallel execution" - ); - bool set_null = true; - size_t index = 0; - size_t type = 0; // set to avoid warning - std::string* name = nullptr; - void* v_ptr = nullptr; // set to avoid warning - size_t n_atomic = local::atomic_index( - set_null, index, type, name, v_ptr - ); - // - set_null = false; - for(index = 1; index <= n_atomic; ++index) - { local::atomic_index(set_null, index, type, name, v_ptr); - if( type == 2 ) - { atomic_base* op = reinterpret_cast(v_ptr); - if( op != nullptr ) - { for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++) - op->free_work(thread); - } - } - } - return; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_ctor.hpp b/build-config/cppad/include/cppad/core/atomic/two_ctor.hpp deleted file mode 100644 index c8f24801..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_ctor.hpp +++ /dev/null @@ -1,173 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_CTOR_HPP -# define CPPAD_CORE_ATOMIC_TWO_CTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_ctor$$ -$spell - enum - sq - std - afun - arg - CppAD - bool - ctor - const - mat_mul_xam.cpp - hpp -$$ - -$section Atomic Function Constructor$$ - -$head Syntax$$ -$icode%atomic_user afun%(%ctor_arg_list%) -%$$ -$codei%atomic_base<%Base%>(%name%, %sparsity%) -%$$ - -$head atomic_user$$ - -$subhead ctor_arg_list$$ -Is a list of arguments for the $icode atomic_user$$ constructor. - -$subhead afun$$ -The object $icode afun$$ must stay in scope for as long -as the corresponding atomic function is used. -This includes use by any $cref/ADFun/ADFun/$$ that -has this $icode atomic_user$$ operation in its -$cref/operation sequence/glossary/Operation/Sequence/$$. - -$subhead Implementation$$ -The user defined $icode atomic_user$$ class is a publicly derived class of -$codei%atomic_base<%Base%>%$$. -It should be declared as follows: -$codei% - class %atomic_user% : public CppAD::atomic_base<%Base%> { - public: - %atomic_user%(%ctor_arg_list%) : atomic_base<%Base%>(%name%, %sparsity%) - %...% - }; -%$$ -where $icode ...$$ -denotes the rest of the implementation of the derived class. -This includes completing the constructor and -all the virtual functions that have their -$code atomic_base$$ implementations replaced by -$icode atomic_user$$ implementations. - -$head atomic_base$$ - -$subhead Restrictions$$ -The $code atomic_base$$ constructor and destructor cannot be called in -$cref/parallel/ta_in_parallel/$$ mode. - -$subhead Base$$ -The template parameter determines the -$icode Base$$ type for this $codei%AD<%Base%>%$$ atomic operation. - -$subhead name$$ -This $code atomic_base$$ constructor argument has the following prototype -$codei% - const std::string& %name% -%$$ -It is the name for this atomic function and is used for error reporting. -The suggested value for $icode name$$ is $icode afun$$ or $icode atomic_user$$, -i.e., the name of the corresponding atomic object or class. - -$subhead sparsity$$ -This $code atomic_base$$ constructor argument has prototype -$codei% - atomic_base<%Base%>::option_enum %sparsity% -%$$ -The current $icode sparsity$$ for an $code atomic_base$$ object -determines which type of sparsity patterns it uses -and its value is one of the following: -$table -$icode sparsity$$ $cnext sparsity patterns $rnext -$codei%atomic_base<%Base%>::pack_sparsity_enum%$$ $pre $$ $cnext - $cref/vectorBool/CppAD_vector/vectorBool/$$ -$rnext -$codei%atomic_base<%Base%>::bool_sparsity_enum%$$ $pre $$ $cnext - $cref/vector/CppAD_vector/$$$code $$ -$rnext -$codei%atomic_base<%Base%>::set_sparsity_enum%$$ $pre $$ $cnext - $cref/vector/CppAD_vector/$$$code >$$ -$tend -There is a default value for $icode sparsity$$ if it is not -included in the constructor (which may be either the bool or set option). - -$end -------------------------------------------------------------------------------- -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_ctor.hpp -Constructors for atomic_base class. -*/ - -/*! -Base class for atomic_atomic functions. - -\tparam Base -This class is used for defining an AD atomic operation y = f(x). - -\par -make sure user does not invoke the default constructor -*/ -template -atomic_base::atomic_base(void) -{ CPPAD_ASSERT_KNOWN(false, - "Attempt to use the atomic_base default constructor" - ); -} -/*! -Constructor - -\param name -name used for error reporting - -\param sparsity [in] -what type of sparsity patterns are computed by this function, -bool_sparsity_enum or set_sparsity_enum. Default value is -bool sparsity patterns. -*/ -template -atomic_base::atomic_base( - const std::string& name, - option_enum sparsity -) : -sparsity_( sparsity ) -{ CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "atomic_base: constructor cannot be called in parallel mode." - ); - CPPAD_ASSERT_UNKNOWN( constant_enum < dynamic_enum ); - CPPAD_ASSERT_UNKNOWN( dynamic_enum < variable_enum ); - // - // atomic_index - bool set_null = false; - size_t index = 0; - size_t type = 2; - std::string copy_name = name; - void* copy_this = reinterpret_cast( this ); - index_ = local::atomic_index( - set_null, index, type, ©_name, copy_this - ); - // initialize work pointers as null; - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++) - work_[thread] = nullptr; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_for_sparse_hes.hpp b/build-config/cppad/include/cppad/core/atomic/two_for_sparse_hes.hpp deleted file mode 100644 index e0f1ed40..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_for_sparse_hes.hpp +++ /dev/null @@ -1,356 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_HES_HPP -# define CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_for_sparse_hes$$ -$spell - sq - mul.hpp - vx - afun - Jacobian - jac - CppAD - std - bool - hes - const -$$ - -$section Atomic Forward Hessian Sparsity Patterns$$ - -$head Syntax$$ -$icode%ok% = %afun%.for_sparse_hes(%vx%, %r%, %s%, %h%, %x%)%$$ - -$head Deprecated 2016-06-27$$ -$icode%ok% = %afun%.for_sparse_hes(%vx%, %r%, %s%, %h%)%$$ - -$head Purpose$$ -This function is used by $cref ForSparseHes$$ to compute -Hessian sparsity patterns. -If you are using $cref ForSparseHes$$, -one of the versions of this -virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. -$pre - -$$ -Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for -a diagonal matrix $latex R \in \B{R}^{n \times n}$$, and -a row vector $latex S \in \B{R}^{1 \times m}$$, -this routine computes the sparsity pattern for -$latex \[ - H(x) = R^\R{T} \cdot (S \cdot f)^{(2)}( x ) \cdot R -\] $$ - -$head Implementation$$ -If you are using and $cref ForSparseHes$$, -this virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. - -$subhead vx$$ -The argument $icode vx$$ has prototype -$codei% - const CppAD:vector& %vx% -%$$ -$icode%vx%.size() == %n%$$, and -for $latex j = 0 , \ldots , n-1$$, -$icode%vx%[%j%]%$$ is true if and only if -$icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$ -or $cref/dynamic parameter/glossary/Parameter/Dynamic/$$ -in the corresponding call to -$codei% - %afun%(%ax%, %ay%) -%$$ - -$subhead r$$ -This argument has prototype -$codei% - const CppAD:vector& %r% -%$$ -and is a $cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -the diagonal of $latex R \in \B{R}^{n \times n}$$. - -$subhead s$$ -The argument $icode s$$ has prototype -$codei% - const CppAD:vector& %s% -%$$ -and its size is $icode m$$. -It is a sparsity pattern for $latex S \in \B{R}^{1 \times m}$$. - -$subhead h$$ -This argument has prototype -$codei% - %atomic_sparsity%& %h% -%$$ -The input value of its elements -are not specified (must not matter). -Upon return, $icode h$$ is a -$cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex H(x) \in \B{R}^{n \times n}$$ which is defined above. - -$subhead x$$ -$index deprecated$$ -The argument has prototype -$codei% - const CppAD::vector<%Base%>& %x% -%$$ -and size is equal to the $icode n$$. -This is the $cref Value$$ value corresponding to the parameters in the -vector $cref/ax/atomic_two_afun/ax/$$ (when the atomic function was called). -To be specific, if -$codei% - if( Parameter(%ax%[%i%]) == true ) - %x%[%i%] = Value( %ax%[%i%] ); - else - %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN(); -%$$ -The version of this function with out the $icode x$$ argument is deprecated; -i.e., you should include the argument even if you do not use it. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_for_sparse_hes.hpp -Atomic forward mode Hessian sparsity patterns. -*/ -/*! -Link, after case split, from for_hes_sweep to atomic_base. - -\param vx [in] -which componens of x are variables. - -\param r [in] -is the forward Jacobian sparsity pattern w.r.t the argument vector x. - -\param s [in] -is the reverse Jacobian sparsity pattern w.r.t the result vector y. - -\param h [out] -is the Hessian sparsity pattern w.r.t the argument vector x. - -\param x -is the integer value of the x arguments that are parameters. -*/ -template -bool atomic_base::for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector< std::set >& h , - const vector& x ) -{ return false; } -template -bool atomic_base::for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector& h , - const vector& x ) -{ return false; } -template -bool atomic_base::for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vectorBool& h , - const vector& x ) -// deprecated versions -{ return false; } -template -bool atomic_base::for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector< std::set >& h ) -{ return false; } -template -bool atomic_base::for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vector& h ) -{ return false; } -template -bool atomic_base::for_sparse_hes( - const vector& vx , - const vector& r , - const vector& s , - vectorBool& h ) -{ return false; } -/*! -Link, before case split, from for_hes_sweep to atomic_base. -2DO: move this functiton outside this file so can change -developer documentation to omhelp formating. - -\tparam InternalSparsity -Is the used internaly for sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param x -is parameter arguments to the function, other components are nan. - -\param x_index -is the variable index, on the tape, for the arguments to this function. -This size of x_index is n, the number of arguments to this function. - -\param y_index -is the variable index, on the tape, for the results for this function. -This size of y_index is m, the number of results for this function. - -\param for_jac_sparsity -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the forward Jacobian sparsity for the j-th argument to this atomic function. - -\param rev_jac_sparsity -On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the reverse Jacobian sparsity for the i-th result to this atomic function. -This shows which components of the result affect the function we are -computing the Hessian of. - -\param for_hes_sparsity -This is the sparsity pattern for the Hessian. On input, the non-linear -terms in the atomic fuction have not been included. Upon return, they -have been included. -*/ -template -template -bool atomic_base::for_sparse_hes( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - size_t np1 , - size_t numvar , - const InternalSparsity& rev_jac_sparsity , - InternalSparsity& for_sparsity ) -{ typedef typename InternalSparsity::const_iterator const_iterator; - CPPAD_ASSERT_UNKNOWN( rev_jac_sparsity.end() == 1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar ); - size_t n = x_index.size(); - size_t m = y_index.size(); - bool ok = false; - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - // - // vx - vector vx(n); - for(size_t j = 0; j < n; j++) - vx[j] = x_index[j] != 0; - // - // bool_r - vector& bool_r( work_[thread]->bool_r ); - bool_r.resize(n); - for(size_t j = 0; j < n; j++) - { // check if we must compute row and column j of h - const_iterator itr(for_sparsity, np1 + x_index[j]); - size_t i = *itr; - bool_r[j] = i < np1; - } - // - // bool s - vector& bool_s( work_[thread]->bool_s ); - bool_s.resize(m); - for(size_t i = 0; i < m; i++) - { // check if row i of result is included in h - bool_s[i] = rev_jac_sparsity.is_element(y_index[i], 0); - } - // - // h - vectorBool& pack_h( work_[thread]->pack_h ); - vector& bool_h( work_[thread]->bool_h ); - vector< std::set >& set_h( work_[thread]->set_h ); - // - // call user's version of atomic function - std::string msg = ": atomic_base.for_sparse_hes: returned false"; - if( sparsity_ == pack_sparsity_enum ) - { pack_h.resize(n * n); - ok = for_sparse_hes(vx, bool_r, bool_s, pack_h, x); - if( ! ok ) - ok = for_sparse_hes(vx, bool_r, bool_s, pack_h); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = pack_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - } - else if( sparsity_ == bool_sparsity_enum ) - { bool_h.resize(n * n); - ok = for_sparse_hes(vx, bool_r, bool_s, bool_h, x); - if( ! ok ) - ok = for_sparse_hes(vx, bool_r, bool_s, bool_h); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = bool_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - } - else - { CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum ) - set_h.resize(n); - ok = for_sparse_hes(vx, bool_r, bool_s, set_h, x); - if( ! ok ) - ok = for_sparse_hes(vx, bool_r, bool_s, set_h); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = set_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - } - CPPAD_ASSERT_UNKNOWN( ok ); - // - // modify hessian in calling routine - for(size_t i = 0; i < n; i++) - { for(size_t j = 0; j < n; j++) - { if( (x_index[i] > 0) & (x_index[j] > 0) ) - { bool flag = false; - switch( sparsity_ ) - { case pack_sparsity_enum: - flag = pack_h[i * n + j]; - break; - // - case bool_sparsity_enum: - flag = bool_h[i * n + j]; - break; - // - case set_sparsity_enum: - flag = set_h[i].find(j) != set_h[i].end(); - break; - } - if( flag ) - { const_iterator itr_i(for_sparsity, np1 + x_index[i]); - size_t i_x = *itr_i; - while( i_x < np1 ) - { for_sparsity.binary_union( - i_x, i_x, np1 + x_index[j], for_sparsity - ); - i_x = *(++itr_i); - } - const_iterator itr_j(for_sparsity, np1 + x_index[j]); - size_t j_x = *itr_j; - while( j_x < np1 ) - { for_sparsity.binary_union( - j_x, j_x, np1 + x_index[i], for_sparsity - ); - j_x = *(++itr_j); - } - } - } - } - } - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_for_sparse_jac.hpp b/build-config/cppad/include/cppad/core/atomic/two_for_sparse_jac.hpp deleted file mode 100644 index 62fa426f..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_for_sparse_jac.hpp +++ /dev/null @@ -1,283 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_JAC_HPP -# define CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_for_sparse_jac$$ -$spell - sq - mul.hpp - afun - Jacobian - jac - const - CppAD - std - bool - std -$$ - -$section Atomic Forward Jacobian Sparsity Patterns$$ - -$head Syntax$$ -$icode%ok% = %afun%.for_sparse_jac(%q%, %r%, %s%, %x%) -%$$ - -$head Deprecated 2016-06-27$$ -$icode%ok% = %afun%.for_sparse_jac(%q%, %r%, %s%) -%$$ - -$head Purpose$$ -This function is used by $cref ForSparseJac$$ to compute -Jacobian sparsity patterns. -For a fixed matrix $latex R \in \B{R}^{n \times q}$$, -the Jacobian of $latex f( x + R * u)$$ with respect to $latex u \in \B{R}^q$$ is -$latex \[ - S(x) = f^{(1)} (x) * R -\] $$ -Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$, -$code for_sparse_jac$$ computes a sparsity pattern for $latex S(x)$$. - -$head Implementation$$ -If you are using -$cref ForSparseJac$$, -$cref ForSparseHes$$, or -$cref RevSparseHes$$, -one of the versions of this -virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. - -$subhead q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of columns in -$latex R \in \B{R}^{n \times q}$$ and the Jacobian -$latex S(x) \in \B{R}^{m \times q}$$. - -$subhead r$$ -This argument has prototype -$codei% - const %atomic_sparsity%& %r% -%$$ -and is a $cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex R \in \B{R}^{n \times q}$$. - -$subhead s$$ -This argument has prototype -$codei% - %atomic_sparsity%& %s% -%$$ -The input values of its elements -are not specified (must not matter). -Upon return, $icode s$$ is a -$cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex S(x) \in \B{R}^{m \times q}$$. - -$subhead x$$ -$index deprecated$$ -The argument has prototype -$codei% - const CppAD::vector<%Base%>& %x% -%$$ -and size is equal to the $icode n$$. -This is the $cref Value$$ value corresponding to the parameters in the -vector $cref/ax/atomic_two_afun/ax/$$ (when the atomic function was called). -To be specific, if -$codei% - if( Parameter(%ax%[%i%]) == true ) - %x%[%i%] = Value( %ax%[%i%] ); - else - %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN(); -%$$ -The version of this function with out the $icode x$$ argument is deprecated; -i.e., you should include the argument even if you do not use it. - -$head ok$$ -The return value $icode ok$$ has prototype -$codei% - bool %ok% -%$$ -If it is $code true$$, the corresponding evaluation succeeded, -otherwise it failed. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_for_sparse_jac.hpp -Atomic forward Jacobian sparsity pattern. -*/ -/*! -Link, after case split, from for_jac_sweep to atomic_base. - -\param q -is the column dimension for the Jacobian sparsity partterns. - -\param r -is the Jacobian sparsity pattern for the argument vector x - -\param s -is the Jacobian sparsity pattern for the result vector y - -\param x -is the integer value for x arguments that are parameters. -*/ -template -bool atomic_base::for_sparse_jac( - size_t q , - const vector< std::set >& r , - vector< std::set >& s , - const vector& x ) -{ return false; } -template -bool atomic_base::for_sparse_jac( - size_t q , - const vector& r , - vector& s , - const vector& x ) -{ return false; } -template -bool atomic_base::for_sparse_jac( - size_t q , - const vectorBool& r , - vectorBool& s , - const vector& x ) -{ return false; } -// deprecated versions -template -bool atomic_base::for_sparse_jac( - size_t q , - const vector< std::set >& r , - vector< std::set >& s ) -{ return false; } -template -bool atomic_base::for_sparse_jac( - size_t q , - const vector& r , - vector& s ) -{ return false; } -template -bool atomic_base::for_sparse_jac( - size_t q , - const vectorBool& r , - vectorBool& s ) -{ return false; } - -/*! -Link, before case split, from for_jac_sweep to atomic_base. - -\tparam InternalSparsity -Is the type used for internal sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param x -is parameter arguments to the function, other components are nan. - -\param x_index -is the variable index, on the tape, for the arguments to this function. -This size of x_index is n, the number of arguments to this function. - -\param y_index -is the variable index, on the tape, for the results for this function. -This size of y_index is m, the number of results for this function. - -\param var_sparsity -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the sparsity for the j-th argument to this atomic function. -On output, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the sparsity for the i-th result for this atomic function. -*/ -template -template -bool atomic_base::for_sparse_jac( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity ) -{ - // intial results are empty during forward mode - size_t q = var_sparsity.end(); - bool input_empty = true; - bool zero_empty = true; - bool transpose = false; - size_t m = y_index.size(); - bool ok = false; - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - // - std::string msg = ": atomic_base.for_sparse_jac: returned false"; - if( sparsity_ == pack_sparsity_enum ) - { vectorBool& pack_r ( work_[thread]->pack_r ); - vectorBool& pack_s ( work_[thread]->pack_s ); - local::sparse::get_internal_pattern( - transpose, x_index, var_sparsity, pack_r - ); - // - pack_s.resize(m * q ); - ok = for_sparse_jac(q, pack_r, pack_s, x); - if( ! ok ) - ok = for_sparse_jac(q, pack_r, pack_s); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = pack_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, y_index, var_sparsity, pack_s - ); - } - else if( sparsity_ == bool_sparsity_enum ) - { vector& bool_r ( work_[thread]->bool_r ); - vector& bool_s ( work_[thread]->bool_s ); - local::sparse::get_internal_pattern( - transpose, x_index, var_sparsity, bool_r - ); - bool_s.resize(m * q ); - ok = for_sparse_jac(q, bool_r, bool_s, x); - if( ! ok ) - ok = for_sparse_jac(q, bool_r, bool_s); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = bool_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, y_index, var_sparsity, bool_s - ); - } - else - { CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum ); - vector< std::set >& set_r ( work_[thread]->set_r ); - vector< std::set >& set_s ( work_[thread]->set_s ); - local::sparse::get_internal_pattern( - transpose, x_index, var_sparsity, set_r - ); - // - set_s.resize(m); - ok = for_sparse_jac(q, set_r, set_s, x); - if( ! ok ) - ok = for_sparse_jac(q, set_r, set_s); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = set_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, y_index, var_sparsity, set_s - ); - } - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_forward.hpp b/build-config/cppad/include/cppad/core/atomic/two_forward.hpp deleted file mode 100644 index 0b4ed9c2..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_forward.hpp +++ /dev/null @@ -1,402 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_FORWARD_HPP -# define CPPAD_CORE_ATOMIC_TWO_FORWARD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_forward$$ -$spell - sq - mul.hpp - hes - afun - vx - vy - ty - Taylor - const - CppAD - bool - atx - aty - af -$$ - -$section Atomic Forward Mode$$ - - -$head Syntax$$ - -$subhead Base$$ -$icode%ok% = %afun%.forward(%p%, %q%, %vx%, %vy%, %tx%, %ty%) -%$$ -This syntax is used by $icode%f%.Forward%$$ where $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -and $icode afun$$ is used in $icode f$$. - -$subhead AD$$ -$icode%ok% = %afun%.forward(%p%, %q%, %vx%, %vy%, %atx%, %aty%) -%$$ -This syntax is used by $icode%af%.Forward%$$ where $icode af$$ has prototype -$codei% - ADFun< AD<%Base%> , %Base% > %af% -%$$ -and $icode afun$$ is used in $icode af$$ (see $cref base2ad$$). - -$head Purpose$$ -This virtual function is used by $cref atomic_two_afun$$ -to evaluate function values. -It is also used buy -$cref/f.Forward/Forward/$$ (and $icode%af%.Forward%$$) -to compute function vales and derivatives. - -$head Implementation$$ -This virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. -It can just return $icode%ok% == false%$$ -(and not compute anything) for values -of $icode%q% > 0%$$ that are greater than those used by your -$cref/forward/Forward/$$ mode calculations. - -$head p$$ -The argument $icode p$$ has prototype -$codei% - size_t %p% -%$$ -It specifies the lowest order Taylor coefficient that we are evaluating. -During calls to $cref atomic_two_afun$$, $icode%p% == 0%$$. - -$head q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the highest order Taylor coefficient that we are evaluating. -During calls to $cref atomic_two_afun$$, $icode%q% == 0%$$. - -$head vx$$ -The $code forward$$ argument $icode vx$$ has prototype -$codei% - const CppAD::vector& %vx% -%$$ -The case $icode%vx%.size() > 0%$$ only occurs while evaluating a call to -$cref atomic_two_afun$$. -In this case, -$icode%p% == %q% == 0%$$, -$icode%vx%.size() == %n%$$, and -for $latex j = 0 , \ldots , n-1$$, -$icode%vx%[%j%]%$$ is true if and only if -$icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$ -or $cref/dynamic parameter/glossary/Parameter/Dynamic/$$ -in the corresponding call to -$codei% - %afun%(%ax%, %ay%) -%$$ -If $icode%vx%.size() == 0%$$, -then $icode%vy%.size() == 0%$$ and neither of these vectors -should be used. - -$head vy$$ -The $code forward$$ argument $icode vy$$ has prototype -$codei% - CppAD::vector& %vy% -%$$ -If $icode%vy%.size() == 0%$$, it should not be used. -Otherwise, -$icode%q% == 0%$$ and $icode%vy%.size() == %m%$$. -The input values of the elements of $icode vy$$ -are not specified (must not matter). -Upon return, for $latex j = 0 , \ldots , m-1$$, -$icode%vy%[%i%]%$$ is true if and only if -$icode%ay%[%i%]%$$ is a variable -or dynamic parameter -(CppAD uses $icode vy$$ to reduce the necessary computations). - -$head tx$$ -The argument $icode tx$$ has prototype -$codei% - const CppAD::vector<%Base%>& %tx% -%$$ -and $icode%tx%.size() == (%q%+1)*%n%$$. -It is used by $icode%f%.Forward%$$ where $icode f$$ has type -$codei%ADFun<%Base%> %f%$$ and $icode afun$$ is used in $icode f$$. -For $latex j = 0 , \ldots , n-1$$ and $latex k = 0 , \ldots , q$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - x_j^k & = & tx [ j * ( q + 1 ) + k ] - \\ - X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^q t^q -\end{array} -\] $$ -Note that superscripts represent an index for $latex x_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex X(t)$$ correspond -to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - x_j^k = \frac{1}{ k ! } X_j^{(k)} (0) -\] $$ - -$head atx$$ -The argument $icode atx$$ has prototype -$codei% - const CppAD::vector< AD<%Base%> >& %atx% -%$$ -Otherwise, $icode atx$$ specifications are the same as for $icode tx$$. - -$head ty$$ -The argument $icode ty$$ has prototype -$codei% - CppAD::vector<%Base%>& %ty% -%$$ -and $icode%tx%.size() == (%q%+1)*%m%$$. -It is set by $icode%f%.Forward%$$ where $icode f$$ has type -$codei%ADFun<%Base%> %f%$$ and $icode afun$$ is used in $icode f$$. -Upon return, -For $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , q$$, -$latex \[ -\begin{array}{rcl} - Y_i (t) & = & f_i [ X(t) ] - \\ - Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q ) - \\ - ty [ i * ( q + 1 ) + k ] & = & y_i^k -\end{array} -\] $$ -where $latex o( t^q ) / t^q \rightarrow 0$$ as $latex t \rightarrow 0$$. -Note that superscripts represent an index for $latex y_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex Y(t)$$ correspond -to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0) -\] $$ -If $latex p > 0$$, -for $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , p-1$$, -the input of $icode ty$$ satisfies -$latex \[ - ty [ i * ( q + 1 ) + k ] = y_i^k -\]$$ -and hence the corresponding elements need not be recalculated. - -$head aty$$ -The argument $icode aty$$ has prototype -$codei% - const CppAD::vector< AD<%Base%> >& %aty% -%$$ -Otherwise, $icode aty$$ specifications are the same as for $icode ty$$. - -$head ok$$ -If the required results are calculated, $icode ok$$ should be true. -Otherwise, it should be false. - -$head Discussion$$ -For example, suppose that $icode%q% == 2%$$, -and you know how to compute the function $latex f(x)$$, -its first derivative $latex f^{(1)} (x)$$, -and it component wise Hessian $latex f_i^{(2)} (x)$$. -Then you can compute $icode ty$$ using the following formulas: -$latex \[ -\begin{array}{rcl} -y_i^0 & = & Y(0) - = f_i ( x^0 ) -\\ -y_i^1 & = & Y^{(1)} ( 0 ) - = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 ) - = f_i^{(1)} ( x^0 ) x^1 -\\ -y_i^2 -& = & \frac{1}{2 !} Y^{(2)} (0) -\\ -& = & \frac{1}{2} X^{(1)} (0)^\R{T} f_i^{(2)} ( x^0 ) X^{(1)} ( 0 ) - + \frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 ) -\\ -& = & \frac{1}{2} (x^1)^\R{T} f_i^{(2)} ( x^0 ) x^1 - + f_i^{(1)} ( x^0 ) x^2 -\end{array} -\] $$ -For $latex i = 0 , \ldots , m-1$$, and $latex k = 0 , 1 , 2$$, -$latex \[ - ty [ i * (q + 1) + k ] = y_i^k -\] $$ - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_forward.hpp -Atomic forward mode -*/ -/*! -Link from atomic_base to forward mode (for replacement by derived class) - -\param p [in] -lowerest order for this forward mode calculation. - -\param q [in] -highest order for this forward mode calculation. - -\param vx [in] -if size not zero, which components of x are variables - -\param vy [out] -if size not zero, which components of y are variables - -\param tx [in] -Taylor coefficients corresponding to x for this calculation. - -\param ty [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for atomic_two -*/ -template -bool atomic_base::forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector& tx , - vector& ty ) -{ return false; } -/*! -Link from atomic_base to forward mode (for replacement by derived class) - -\param p [in] -lowerest order for this forward mode calculation. - -\param q [in] -highest order for this forward mode calculation. - -\param vx [in] -if size not zero, which components of x are variables - -\param vy [out] -if size not zero, which components of y are variables - -\param atx [in] -Taylor coefficients corresponding to x for this calculation. - -\param aty [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for atomic_two -*/ -template -bool atomic_base::forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector< AD >& atx , - vector< AD >& aty ) -{ return false; } -/*! -Convert atomic_three interface to atomic_two interface - -\param order_low [in] -lowerest order for this forward mode calculation. - -\param order_up [in] -highest order for this forward mode calculation. - -\param type_x [in] -if size not zero, which components of x are variables - -\param type_y [out] -if size not zero, which components of y are variables - -\param taylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param taylor_y [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for atomic_three -*/ -# define CPPAD_ATOMIC_BASE_MUSTDO 0 -template -bool atomic_base::forward( - size_t order_low , - size_t order_up , - const vector& type_x , - vector& type_y , - const vector& taylor_x , - vector& taylor_y ) -{ // - // atomic_base::afun(ax, ay) calls bool version directly - CPPAD_ASSERT_UNKNOWN( type_x.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( type_y.size() == 0 ); - // -# if CPPAD_ATOMIC_BASE_MUSTDO - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - vector & vx = work_[thread]->vx; - vector & vy = work_[thread]->vy; - vx.resize(type_x.size()); - vy.resize(type_y.size()); -# else - vector vx, vy; -# endif - // - bool ok = forward(order_low, order_up, vx, vy, taylor_x, taylor_y); - // - return ok; -} -# undef CPPAD_ATOMIC_BASE_MUSTDO -/*! -Convert atomic_three interface to atomic_two interface - -\param order_low [in] -lowerest order for this forward mode calculation. - -\param order_up [in] -highest order for this forward mode calculation. - -\param type_x [in] -if size not zero, which components of x are variables - -\param type_y [out] -if size not zero, which components of y are variables - -\param ataylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param ataylor_y [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for atomic_three -*/ -template -bool atomic_base::forward( - size_t order_low , - size_t order_up , - const vector& type_x , - vector& type_y , - const vector< AD >& ataylor_x , - vector< AD >& ataylor_y ) -{ // - // atomic_base::afun(ax, ay) calls bool version directly - CPPAD_ASSERT_UNKNOWN( type_x.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( type_y.size() == 0 ); - // - vector vx, vy; - bool ok = forward(order_low, order_up, vx, vy, ataylor_x, ataylor_y); - // - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_option.hpp b/build-config/cppad/include/cppad/core/atomic/two_option.hpp deleted file mode 100644 index 5cb1990f..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_option.hpp +++ /dev/null @@ -1,113 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_OPTION_HPP -# define CPPAD_CORE_ATOMIC_TWO_OPTION_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_option$$ -$spell - sq - enum - afun - bool - CppAD - std - typedef -$$ - -$section Set Atomic Function Options$$ - -$head Syntax$$ -$icode%afun%.option(%option_value%)%$$ - -$head Scope$$ -These settings do not apply to individual $icode afun$$ calls, -but rather all subsequent uses of the corresponding atomic operation -in an $cref ADFun$$ object. - -$head atomic_sparsity$$ -Note that, if you use $cref optimize$$, these sparsity patterns are used -to determine the $cref/dependency/dependency.cpp/$$ relationship between -argument and result variables. - -$subhead pack_sparsity_enum$$ -If $icode option_value$$ is $codei%atomic_base<%Base%>::pack_sparsity_enum%$$, -then the type used by $icode afun$$ for -$cref/sparsity patterns/glossary/Sparsity Pattern/$$, -(after the option is set) will be -$codei% - typedef CppAD::vectorBool %atomic_sparsity% -%$$ -If $icode r$$ is a sparsity pattern -for a matrix $latex R \in \B{R}^{p \times q}$$: -$icode%r%.size() == %p% * %q%$$. - -$subhead bool_sparsity_enum$$ -If $icode option_value$$ is $codei%atomic_base<%Base%>::bool_sparsity_enum%$$, -then the type used by $icode afun$$ for -$cref/sparsity patterns/glossary/Sparsity Pattern/$$, -(after the option is set) will be -$codei% - typedef CppAD::vector %atomic_sparsity% -%$$ -If $icode r$$ is a sparsity pattern -for a matrix $latex R \in \B{R}^{p \times q}$$: -$icode%r%.size() == %p% * %q%$$. - -$subhead set_sparsity_enum$$ -If $icode option_value$$ is $icode%atomic_base<%Base%>::set_sparsity_enum%$$, -then the type used by $icode afun$$ for -$cref/sparsity patterns/glossary/Sparsity Pattern/$$, -(after the option is set) will be -$codei% - typedef CppAD::vector< std::set > %atomic_sparsity% -%$$ -If $icode r$$ is a sparsity pattern -for a matrix $latex R \in \B{R}^{p \times q}$$: -$icode%r%.size() == %p%$$, and for $latex i = 0 , \ldots , p-1$$, -the elements of $icode%r%[%i%]%$$ are between zero and $latex q-1$$ inclusive. - -$end ------------------------------------------------------------------------------- -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_option.hpp -Setting atomic_base options. -*/ - -/*! -Setting atomic_base options. - -\param option_value -new option value. -*/ -template -void atomic_base::option(enum option_enum option_value) -{ switch( option_value ) - { case pack_sparsity_enum: - case bool_sparsity_enum: - case set_sparsity_enum: - sparsity_ = option_value; - break; - - default: - CPPAD_ASSERT_KNOWN( - false, - "atoic_base::option: option_value is not valid" - ); - } - return; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_rev_depend.hpp b/build-config/cppad/include/cppad/core/atomic/two_rev_depend.hpp deleted file mode 100644 index c6b02f2c..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_rev_depend.hpp +++ /dev/null @@ -1,99 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_REV_DEPEND_HPP -# define CPPAD_CORE_ATOMIC_TWO_REV_DEPEND_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_rev_depend.hpp -Third generation atomic type computation. -*/ -/*! -Link from atomic_two to reverse dependency calculation - -\param parameter_x [in] -is the value of the parameters in the corresponding function call -afun(ax, ay). - -\param type_x [in] -is the type for each component of ax in the corresponding function call -afun(ax, ay). - -\param depend_x [out] -specifies which components of x affect values of interest. - -\param depend_y [in] -specifies which components of y affect values of interest. -*/ -// BEGIN_PROTOTYPE -template -bool atomic_base::rev_depend( - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y ) -// END_PROTOTYPE -{ bool ok = true; - CPPAD_ASSERT_UNKNOWN( depend_x.size() == parameter_x.size() ); - size_t n = depend_x.size(); - size_t m = depend_y.size(); - // - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - // - if( sparsity_ == pack_sparsity_enum ) - { vectorBool& rt ( work_[thread]->pack_r ); - vectorBool& st ( work_[thread]->pack_s ); - // - st.resize(n * 1 ); - rt.resize(m * 1 ); - for(size_t i = 0; i < m; ++i) - rt[i] = depend_y[i]; - ok = rev_sparse_jac(1, rt, st, parameter_x); - if( ! ok ) - ok = rev_sparse_jac(1, rt, st); - if( ! ok ) - return false; - for(size_t j = 0; j < n; ++j) - depend_x[j] = st[j]; - } - else if( sparsity_ == bool_sparsity_enum ) - { - ok = rev_sparse_jac(1, depend_y, depend_x, parameter_x); - if( ! ok ) - ok = rev_sparse_jac(m, depend_y, depend_x); - if( ! ok ) - return false; - } - else - { CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum ); - vector< std::set >& rt ( work_[thread]->set_r ); - vector< std::set >& st ( work_[thread]->set_s ); - rt.resize(m); - st.resize(n); - for(size_t i = 0; i < m; ++i) - { if( depend_y[i] ) - rt[i].insert(0); - } - ok = rev_sparse_jac(m, rt, st, parameter_x); - if( ! ok ) - ok = rev_sparse_jac(m, rt, st); - if( ! ok ) - return false; - for(size_t j = 0; j < n; ++j) - depend_x[j] = ! st[j].empty(); - } - return ok; -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_rev_sparse_hes.hpp b/build-config/cppad/include/cppad/core/atomic/two_rev_sparse_hes.hpp deleted file mode 100644 index 27ac3804..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_rev_sparse_hes.hpp +++ /dev/null @@ -1,451 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_HES_HPP -# define CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_rev_sparse_hes$$ -$spell - sq - mul.hpp - vx - afun - Jacobian - jac - CppAD - std - bool - hes - const -$$ - -$section Atomic Reverse Hessian Sparsity Patterns$$ - -$head Syntax$$ -$icode%ok% = %afun%.rev_sparse_hes(%vx%, %s%, %t%, %q%, %r%, %u%, %v%, %x%)%$$ - -$head Deprecated 2016-06-27$$ -$icode%ok% = %afun%.rev_sparse_hes(%vx%, %s%, %t%, %q%, %r%, %u%, %v%)%$$ - -$head Purpose$$ -This function is used by $cref RevSparseHes$$ to compute -Hessian sparsity patterns. -If you are using $cref RevSparseHes$$ to compute -one of the versions of this -virtual function muse be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. -$pre - -$$ -There is an unspecified scalar valued function -$latex g : \B{R}^m \rightarrow \B{R}$$. -Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for -$latex R \in \B{R}^{n \times q}$$, -and information about the function $latex z = g(y)$$, -this routine computes the sparsity pattern for -$latex \[ - V(x) = (g \circ f)^{(2)}( x ) R -\] $$ - -$head Implementation$$ -If you are using and $cref RevSparseHes$$, -this virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. - -$subhead vx$$ -The argument $icode vx$$ has prototype -$codei% - const CppAD:vector& %vx% -%$$ -$icode%vx%.size() == %n%$$, and -for $latex j = 0 , \ldots , n-1$$, -$icode%vx%[%j%]%$$ is true if and only if -$icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$ -or $cref/dynamic parameter/glossary/Parameter/Dynamic/$$ -in the corresponding call to -$codei% - %afun%(%ax%, %ay%) -%$$ - -$subhead s$$ -The argument $icode s$$ has prototype -$codei% - const CppAD:vector& %s% -%$$ -and its size is $icode m$$. -It is a sparsity pattern for -$latex S(x) = g^{(1)} [ f(x) ] \in \B{R}^{1 \times m}$$. - -$subhead t$$ -This argument has prototype -$codei% - CppAD:vector& %t% -%$$ -and its size is $icode m$$. -The input values of its elements -are not specified (must not matter). -Upon return, $icode t$$ is a -sparsity pattern for -$latex T(x) \in \B{R}^{1 \times n}$$ where -$latex \[ - T(x) = (g \circ f)^{(1)} (x) = S(x) * f^{(1)} (x) -\]$$ - -$subhead q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of columns in -$latex R \in \B{R}^{n \times q}$$, -$latex U(x) \in \B{R}^{m \times q}$$, and -$latex V(x) \in \B{R}^{n \times q}$$. - -$subhead r$$ -This argument has prototype -$codei% - const %atomic_sparsity%& %r% -%$$ -and is a $cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex R \in \B{R}^{n \times q}$$. - -$head u$$ -This argument has prototype -$codei% - const %atomic_sparsity%& %u% -%$$ -and is a $cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex U(x) \in \B{R}^{m \times q}$$ which is defined by -$latex \[ -\begin{array}{rcl} -U(x) -& = & -\{ \partial_u \{ \partial_y g[ y + f^{(1)} (x) R u ] \}_{y=f(x)} \}_{u=0} -\\ -& = & -\partial_u \{ g^{(1)} [ f(x) + f^{(1)} (x) R u ] \}_{u=0} -\\ -& = & -g^{(2)} [ f(x) ] f^{(1)} (x) R -\end{array} -\] $$ - -$subhead v$$ -This argument has prototype -$codei% - %atomic_sparsity%& %v% -%$$ -The input value of its elements -are not specified (must not matter). -Upon return, $icode v$$ is a -$cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex V(x) \in \B{R}^{n \times q}$$ which is defined by -$latex \[ -\begin{array}{rcl} -V(x) -& = & -\partial_u [ \partial_x (g \circ f) ( x + R u ) ]_{u=0} -\\ -& = & -\partial_u [ (g \circ f)^{(1)}( x + R u ) ]_{u=0} -\\ -& = & -(g \circ f)^{(2)}( x ) R -\\ -& = & -f^{(1)} (x)^\R{T} g^{(2)} [ f(x) ] f^{(1)} (x) R -+ -\sum_{i=1}^m g_i^{(1)} [ f(x) ] \; f_i^{(2)} (x) R -\\ -& = & -f^{(1)} (x)^\R{T} U(x) -+ -\sum_{i=1}^m S_i (x) \; f_i^{(2)} (x) R -\end{array} -\] $$ - -$subhead x$$ -$index deprecated$$ -The argument has prototype -$codei% - const CppAD::vector<%Base%>& %x% -%$$ -and size is equal to the $icode n$$. -This is the $cref Value$$ value corresponding to the parameters in the -vector $cref/ax/atomic_two_afun/ax/$$ (when the atomic function was called). -To be specific, if -$codei% - if( Parameter(%ax%[%i%]) == true ) - %x%[%i%] = Value( %ax%[%i%] ); - else - %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN(); -%$$ -The version of this function with out the $icode x$$ argument is deprecated; -i.e., you should include the argument even if you do not use it. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_rev_sparse_hes.hpp -Atomic reverse mode Hessian sparsity patterns. -*/ -/*! -Link from reverse Hessian sparsity sweep to atomic_base - -\param vx [in] -which componens of x are variables. - -\param s [in] -is the reverse Jacobian sparsity pattern w.r.t the result vector y. - -\param t [out] -is the reverse Jacobian sparsity pattern w.r.t the argument vector x. - -\param q [in] -is the column dimension for the sparsity partterns. - -\param r [in] -is the forward Jacobian sparsity pattern w.r.t the argument vector x - -\param u [in] -is the Hessian sparsity pattern w.r.t the result vector y. - -\param v [out] -is the Hessian sparsity pattern w.r.t the argument vector x. - -\param x [in] -is the integer value of the x arguments that are parameters. -*/ -template -bool atomic_base::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector< std::set >& r , - const vector< std::set >& u , - vector< std::set >& v , - const vector& x ) -{ return false; } -template -bool atomic_base::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector& r , - const vector& u , - vector& v , - const vector& x ) -{ return false; } -template -bool atomic_base::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vectorBool& r , - const vectorBool& u , - vectorBool& v , - const vector& x ) -{ return false; } -// deprecated -template -bool atomic_base::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector< std::set >& r , - const vector< std::set >& u , - vector< std::set >& v ) -{ return false; } -template -bool atomic_base::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector& r , - const vector& u , - vector& v ) -{ return false; } -template -bool atomic_base::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vectorBool& r , - const vectorBool& u , - vectorBool& v ) -{ return false; } -/*! -Link, before case split, from rev_hes_sweep to atomic_base. - -\tparam InternalSparsity -Is the used internaly for sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param x -is parameter arguments to the function, other components are nan. - -\param x_index -is the variable index, on the tape, for the arguments to this function. -This size of x_index is n, the number of arguments to this function. - -\param y_index -is the variable index, on the tape, for the results for this function. -This size of y_index is m, the number of results for this function. - -\param for_jac_sparsity -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the forward Jacobian sparsity for the j-th argument to this atomic function. - -\param rev_jac_flag -This shows which variables affect the function we are -computing the Hessian of. -On input, for i = 0, ... , m-1, the rev_jac_flag[ y_index[i] ] is true -if the Jacobian of function (we are computing sparsity for) is no-zero. -Upon return, for j = 0, ... , n-1, rev_jac_flag [ x_index[j] ] -as been adjusted to accound removing this atomic function. - -\param rev_hes_sparsity -This is the sparsity pattern for the Hessian. -On input, for i = 0, ... , m-1, row y_index[i] is the reverse Hessian sparsity -with one of the partials with respect to to y_index[i]. -*/ -template -template -bool atomic_base::rev_sparse_hes( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - const InternalSparsity& for_jac_sparsity , - bool* rev_jac_flag , - InternalSparsity& rev_hes_sparsity ) -{ CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end() == rev_hes_sparsity.end() ); - size_t q = rev_hes_sparsity.end(); - size_t n = x_index.size(); - size_t m = y_index.size(); - bool ok = false; - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - bool zero_empty = true; - bool input_empty = false; - bool transpose = false; - // - // vx - vector vx(n); - for(size_t j = 0; j < n; j++) - vx[j] = x_index[j] != 0; - // - // note that s and t are vectors so transpose does not matter for bool case - vector bool_s( work_[thread]->bool_s ); - vector bool_t( work_[thread]->bool_t ); - // - bool_s.resize(m); - bool_t.resize(n); - // - for(size_t i = 0; i < m; i++) - { if( y_index[i] > 0 ) - bool_s[i] = rev_jac_flag[ y_index[i] ]; - } - // - std::string msg = ": atomic_base.rev_sparse_hes: returned false"; - if( sparsity_ == pack_sparsity_enum ) - { vectorBool& pack_r( work_[thread]->pack_r ); - vectorBool& pack_u( work_[thread]->pack_u ); - vectorBool& pack_v( work_[thread]->pack_h ); - // - pack_v.resize(n * q); - // - local::sparse::get_internal_pattern( - transpose, x_index, for_jac_sparsity, pack_r - ); - local::sparse::get_internal_pattern( - transpose, y_index, rev_hes_sparsity, pack_u - ); - // - ok = rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v, x); - if( ! ok ) - ok = rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = pack_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, x_index, rev_hes_sparsity, pack_v - ); - } - else if( sparsity_ == bool_sparsity_enum ) - { vector& bool_r( work_[thread]->bool_r ); - vector& bool_u( work_[thread]->bool_u ); - vector& bool_v( work_[thread]->bool_h ); - // - bool_v.resize(n * q); - // - local::sparse::get_internal_pattern( - transpose, x_index, for_jac_sparsity, bool_r - ); - local::sparse::get_internal_pattern( - transpose, y_index, rev_hes_sparsity, bool_u - ); - // - ok = rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v, x); - if( ! ok ) - ok = rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = bool_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, x_index, rev_hes_sparsity, bool_v - ); - } - else - { CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum ); - vector< std::set >& set_r( work_[thread]->set_r ); - vector< std::set >& set_u( work_[thread]->set_u ); - vector< std::set >& set_v( work_[thread]->set_h ); - // - set_v.resize(n); - // - local::sparse::get_internal_pattern( - transpose, x_index, for_jac_sparsity, set_r - ); - local::sparse::get_internal_pattern( - transpose, y_index, rev_hes_sparsity, set_u - ); - // - ok = rev_sparse_hes(vx, bool_s, bool_t, q, set_r, set_u, set_v, x); - if( ! ok ) - ok = rev_sparse_hes(vx, bool_s, bool_t, q, set_r, set_u, set_v); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = set_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, x_index, rev_hes_sparsity, set_v - ); - } - for(size_t j = 0; j < n; j++) - { if( x_index[j] > 0 ) - rev_jac_flag[ x_index[j] ] |= bool_t[j]; - } - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_rev_sparse_jac.hpp b/build-config/cppad/include/cppad/core/atomic/two_rev_sparse_jac.hpp deleted file mode 100644 index 36d16a40..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_rev_sparse_jac.hpp +++ /dev/null @@ -1,289 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_JAC_HPP -# define CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_rev_sparse_jac$$ -$spell - sq - mul.hpp - rt - afun - Jacobian - jac - CppAD - std - bool - const - hes -$$ - -$section Atomic Reverse Jacobian Sparsity Patterns$$ - -$head Syntax$$ -$icode%ok% = %afun%.rev_sparse_jac(%q%, %rt%, %st%, %x%) -%$$ - -$head Deprecated 2016-06-27$$ -$icode%ok% = %afun%.rev_sparse_jac(%q%, %rt%, %st%) -%$$ - -$head Purpose$$ -This function is used by -$cref RevSparseJac$$ to compute -Jacobian sparsity patterns. -If you are using $cref RevSparseJac$$, -one of the versions of this -virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. -$pre - -$$ -For a fixed matrix $latex R \in \B{R}^{q \times m}$$, -the Jacobian of $latex R * f( x )$$ with respect to $latex x \in \B{R}^n$$ is -$latex \[ - S(x) = R * f^{(1)} (x) -\] $$ -Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$, -$code rev_sparse_jac$$ computes a sparsity pattern for $latex S(x)$$. - -$head Implementation$$ -If you are using -$cref RevSparseJac$$ or $cref ForSparseHes$$, -this virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. - -$subhead q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of rows in -$latex R \in \B{R}^{q \times m}$$ and the Jacobian -$latex S(x) \in \B{R}^{q \times n}$$. - -$subhead rt$$ -This argument has prototype -$codei% - const %atomic_sparsity%& %rt% -%$$ -and is a -$cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex R^\R{T} \in \B{R}^{m \times q}$$. - -$subhead st$$ -This argument has prototype -$codei% - %atomic_sparsity%& %st% -%$$ -The input value of its elements -are not specified (must not matter). -Upon return, $icode s$$ is a -$cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ pattern for -$latex S(x)^\R{T} \in \B{R}^{n \times q}$$. - -$subhead x$$ -$index deprecated$$ -The argument has prototype -$codei% - const CppAD::vector<%Base%>& %x% -%$$ -and size is equal to the $icode n$$. -This is the $cref Value$$ corresponding to the parameters in the -vector $cref/ax/atomic_two_afun/ax/$$ (when the atomic function was called). -To be specific, if -$codei% - if( Parameter(%ax%[%i%]) == true ) - %x%[%i%] = Value( %ax%[%i%] ); - else - %x%[%i%] = CppAD::numeric_limits<%Base%>::quiet_NaN(); -%$$ -The version of this function with out the $icode x$$ argument is deprecated; -i.e., you should include the argument even if you do not use it. - -$head ok$$ -The return value $icode ok$$ has prototype -$codei% - bool %ok% -%$$ -If it is $code true$$, the corresponding evaluation succeeded, -otherwise it failed. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_rev_sparse_jac.hpp -Atomic reverse mode Jacobian sparsity patterns. -*/ -/*! -Link, after case split, from rev_jac_sweep to atomic_base - -\param q [in] -is the row dimension for the Jacobian sparsity partterns - -\param rt [out] -is the tansposed Jacobian sparsity pattern w.r.t to range variables y - -\param st [in] -is the tansposed Jacobian sparsity pattern for the argument variables x - -\param x -is the integer value for x arguments that are parameters. -*/ -template -bool atomic_base::rev_sparse_jac( - size_t q , - const vector< std::set >& rt , - vector< std::set >& st , - const vector& x ) -{ return false; } -template -bool atomic_base::rev_sparse_jac( - size_t q , - const vector& rt , - vector& st , - const vector& x ) -{ return false; } -template -bool atomic_base::rev_sparse_jac( - size_t q , - const vectorBool& rt , - vectorBool& st , - const vector& x ) -{ return false; } -// deprecated versions -template -bool atomic_base::rev_sparse_jac( - size_t q , - const vector< std::set >& rt , - vector< std::set >& st ) -{ return false; } -template -bool atomic_base::rev_sparse_jac( - size_t q , - const vector& rt , - vector& st ) -{ return false; } -template -bool atomic_base::rev_sparse_jac( - size_t q , - const vectorBool& rt , - vectorBool& st ) -{ return false; } - -/*! -Link, before case split, from rev_jac_sweep to atomic_base. - -\tparam InternalSparsity -Is the used internaly for sparsity calculations; i.e., -sparse_pack or sparse_list. - -\param x -is parameter arguments to the function, other components are nan. - -\param x_index -is the variable index, on the tape, for the arguments to this function. -This size of x_index is n, the number of arguments to this function. - -\param y_index -is the variable index, on the tape, for the results for this function. -This size of y_index is m, the number of results for this function. - -\param var_sparsity -On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the sparsity for the i-th argument to this atomic function. -On output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -the sparsity has been updated to remove y as a function of x. -*/ -template -template -bool atomic_base::rev_sparse_jac( - const vector& x , - const local::pod_vector& x_index , - const local::pod_vector& y_index , - InternalSparsity& var_sparsity ) -{ - // initial results may be non-empty during reverse mode - size_t q = var_sparsity.end(); - bool input_empty = false; - bool zero_empty = true; - bool transpose = false; - size_t n = x_index.size(); - bool ok = false; - size_t thread = thread_alloc::thread_num(); - allocate_work(thread); - // - std::string msg = ": atomic_base.rev_sparse_jac: returned false"; - if( sparsity_ == pack_sparsity_enum ) - { vectorBool& pack_rt ( work_[thread]->pack_r ); - vectorBool& pack_st ( work_[thread]->pack_s ); - local::sparse::get_internal_pattern( - transpose, y_index, var_sparsity, pack_rt - ); - // - pack_st.resize(n * q ); - ok = rev_sparse_jac(q, pack_rt, pack_st, x); - if( ! ok ) - ok = rev_sparse_jac(q, pack_rt, pack_st); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = pack_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, x_index, var_sparsity, pack_st - ); - } - else if( sparsity_ == bool_sparsity_enum ) - { vector& bool_rt ( work_[thread]->bool_r ); - vector& bool_st ( work_[thread]->bool_s ); - local::sparse::get_internal_pattern( - transpose, y_index, var_sparsity, bool_rt - ); - bool_st.resize(n * q ); - ok = rev_sparse_jac(q, bool_rt, bool_st, x); - if( ! ok ) - ok = rev_sparse_jac(q, bool_rt, bool_st); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = bool_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, x_index, var_sparsity, bool_st - ); - } - else - { CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum ); - vector< std::set >& set_rt ( work_[thread]->set_r ); - vector< std::set >& set_st ( work_[thread]->set_s ); - local::sparse::get_internal_pattern( - transpose, y_index, var_sparsity, set_rt - ); - set_st.resize(n); - ok = rev_sparse_jac(q, set_rt, set_st, x); - if( ! ok ) - ok = rev_sparse_jac(q, set_rt, set_st); - if( ! ok ) - { msg = atomic_name() + msg + " sparsity = set_sparsity_enum"; - CPPAD_ASSERT_KNOWN(false, msg.c_str()); - } - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, x_index, var_sparsity, set_st - ); - } - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/atomic/two_reverse.hpp b/build-config/cppad/include/cppad/core/atomic/two_reverse.hpp deleted file mode 100644 index 43270b17..00000000 --- a/build-config/cppad/include/cppad/core/atomic/two_reverse.hpp +++ /dev/null @@ -1,291 +0,0 @@ -# ifndef CPPAD_CORE_ATOMIC_TWO_REVERSE_HPP -# define CPPAD_CORE_ATOMIC_TWO_REVERSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin atomic_two_reverse$$ -$spell - sq - mul.hpp - afun - ty - px - py - Taylor - const - CppAD - atx - aty - apx - apy - af -$$ - -$section Atomic Reverse Mode$$ -$spell - bool -$$ - -$head Syntax$$ - -$subhead Base$$ -$icode%ok% = %afun%.reverse(%q%, %tx%, %ty%, %px%, %py%) -%$$ -This syntax is used by $icode%f%.Forward%$$ where $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -and $icode afun$$ is used in $icode f$$. - -$subhead AD$$ -$icode%ok% = %afun%.reverse(%q%, %atx%, %aty%, %apx%, %apy%) -%$$ -This syntax is used by $icode%af%.Forward%$$ where $icode af$$ has prototype -$codei% - ADFun< AD<%Base%> , %Base% > %af% -%$$ -and $icode afun$$ is used in $icode af$$ (see $cref base2ad$$). - -$head Purpose$$ -This function is used by $cref/reverse/Reverse/$$ -to compute derivatives. - -$head Implementation$$ -If you are using -$cref/reverse/Reverse/$$ mode, -this virtual function must be defined by the -$cref/atomic_user/atomic_two_ctor/atomic_user/$$ class. -It can just return $icode%ok% == false%$$ -(and not compute anything) for values -of $icode q$$ that are greater than those used by your -$cref/reverse/Reverse/$$ mode calculations. - -$head q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the highest order Taylor coefficient that -computing the derivative of. - -$head tx$$ -The argument $icode tx$$ has prototype -$codei% - const CppAD::vector<%Base%>& %tx% -%$$ -and $icode%tx%.size() == (%q%+1)*%n%$$. -For $latex j = 0 , \ldots , n-1$$ and $latex k = 0 , \ldots , q$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - x_j^k & = & tx [ j * ( q + 1 ) + k ] - \\ - X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^q t^q -\end{array} -\] $$ -Note that superscripts represent an index for $latex x_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex X(t)$$ correspond -to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - x_j^k = \frac{1}{ k ! } X_j^{(k)} (0) -\] $$ - -$head atx$$ -The argument $icode atx$$ has prototype -$codei% - const CppAD::vector< AD<%Base%> >& %atx% -%$$ -Otherwise, $icode atx$$ specifications are the same as for $icode tx$$. - -$head ty$$ -The argument $icode ty$$ has prototype -$codei% - const CppAD::vector<%Base%>& %ty% -%$$ -and $icode%tx%.size() == (%q%+1)*%m%$$. -For $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , q$$, -we use the Taylor coefficient notation -$latex \[ -\begin{array}{rcl} - Y_i (t) & = & f_i [ X(t) ] - \\ - Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^q t^q + o ( t^q ) - \\ - y_i^k & = & ty [ i * ( q + 1 ) + k ] -\end{array} -\] $$ -where $latex o( t^q ) / t^q \rightarrow 0$$ as $latex t \rightarrow 0$$. -Note that superscripts represent an index for $latex y_j^k$$ -and an exponent for $latex t^k$$. -Also note that the Taylor coefficients for $latex Y(t)$$ correspond -to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way: -$latex \[ - y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0) -\] $$ - -$head aty$$ -The argument $icode aty$$ has prototype -$codei% - const CppAD::vector< AD<%Base%> >& %aty% -%$$ -Otherwise, $icode aty$$ specifications are the same as for $icode ty$$. - - -$head F$$ -We use the notation $latex \{ x_j^k \} \in \B{R}^{n \times (q+1)}$$ for -$latex \[ - \{ x_j^k \W{:} j = 0 , \ldots , n-1, k = 0 , \ldots , q \} -\]$$ -We use the notation $latex \{ y_i^k \} \in \B{R}^{m \times (q+1)}$$ for -$latex \[ - \{ y_i^k \W{:} i = 0 , \ldots , m-1, k = 0 , \ldots , q \} -\]$$ -We define the function -$latex F : \B{R}^{n \times (q+1)} \rightarrow \B{R}^{m \times (q+1)}$$ by -$latex \[ - y_i^k = F_i^k [ \{ x_j^k \} ] -\] $$ -Note that -$latex \[ - F_i^0 ( \{ x_j^k \} ) = f_i ( X(0) ) = f_i ( x^0 ) -\] $$ -We also note that -$latex F_i^\ell ( \{ x_j^k \} )$$ is a function of -$latex x^0 , \ldots , x^\ell$$ -and is determined by the derivatives of $latex f_i (x)$$ -up to order $latex \ell$$. - - -$head G, H$$ -We use $latex G : \B{R}^{m \times (q+1)} \rightarrow \B{R}$$ -to denote an arbitrary scalar valued function of $latex \{ y_i^k \}$$. -We use $latex H : \B{R}^{n \times (q+1)} \rightarrow \B{R}$$ -defined by -$latex \[ - H ( \{ x_j^k \} ) = G[ F( \{ x_j^k \} ) ] -\] $$ - -$head py$$ -The argument $icode py$$ has prototype -$codei% - const CppAD::vector<%Base%>& %py% -%$$ -and $icode%py%.size() == m * (%q%+1)%$$. -For $latex i = 0 , \ldots , m-1$$, $latex k = 0 , \ldots , q$$, -$latex \[ - py[ i * (q + 1 ) + k ] = \partial G / \partial y_i^k -\] $$ - -$head apy$$ -The argument $icode apy$$ has prototype -$codei% - const CppAD::vector< AD<%Base%> >& %apy% -%$$ -Otherwise, $icode apy$$ specifications are the same as for $icode py$$. - -$subhead px$$ -The $icode px$$ has prototype -$codei% - CppAD::vector<%Base%>& %px% -%$$ -and $icode%px%.size() == n * (%q%+1)%$$. -The input values of the elements of $icode px$$ -are not specified (must not matter). -Upon return, -for $latex j = 0 , \ldots , n-1$$ and $latex \ell = 0 , \ldots , q$$, -$latex \[ -\begin{array}{rcl} -px [ j * (q + 1) + \ell ] & = & \partial H / \partial x_j^\ell -\\ -& = & -( \partial G / \partial \{ y_i^k \} ) \cdot - ( \partial \{ y_i^k \} / \partial x_j^\ell ) -\\ -& = & -\sum_{k=0}^q -\sum_{i=0}^{m-1} -( \partial G / \partial y_i^k ) ( \partial y_i^k / \partial x_j^\ell ) -\\ -& = & -\sum_{k=\ell}^q -\sum_{i=0}^{m-1} -py[ i * (q + 1 ) + k ] ( \partial F_i^k / \partial x_j^\ell ) -\end{array} -\] $$ -Note that we have used the fact that for $latex k < \ell$$, -$latex \partial F_i^k / \partial x_j^\ell = 0$$. - -$head apx$$ -The argument $icode apx$$ has prototype -$codei% - CppAD::vector< AD<%Base%> >& %apx% -%$$ -Otherwise, $icode apx$$ specifications are the same as for $icode px$$. - -$head ok$$ -The return value $icode ok$$ has prototype -$codei% - bool %ok% -%$$ -If it is $code true$$, the corresponding evaluation succeeded, -otherwise it failed. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file atomic/two_reverse.hpp -Atomic reverse mode. -*/ -/*! -Link from reverse mode sweep to users routine. - -\param q [in] -highest order for this reverse mode calculation. - -\param tx [in] -Taylor coefficients corresponding to x for this calculation. - -\param ty [in] -Taylor coefficient corresponding to y for this calculation - -\param px [out] -Partials w.r.t. the x Taylor coefficients. - -\param py [in] -Partials w.r.t. the y Taylor coefficients. - -See atomic_reverse mode use documentation -*/ -template -bool atomic_base::reverse( - size_t q , - const vector& tx , - const vector& ty , - vector& px , - const vector& py ) -{ return false; } - -template -bool atomic_base::reverse( - size_t q , - const vector< AD >& atx , - const vector< AD >& aty , - vector< AD >& apx , - const vector< AD >& apy ) -{ return false; } - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/azmul.hpp b/build-config/cppad/include/cppad/core/azmul.hpp deleted file mode 100644 index d091b24e..00000000 --- a/build-config/cppad/include/cppad/core/azmul.hpp +++ /dev/null @@ -1,247 +0,0 @@ -# ifndef CPPAD_CORE_AZMUL_HPP -# define CPPAD_CORE_AZMUL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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$$ -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$$ -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. - -$end -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -// ========================================================================== - -// case where x and y are AD ------------------------------------------- -template AD -azmul(const AD& x, const AD& y) -{ - // compute the Base part - AD result; - result.value_ = azmul(x.value_, y.value_); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if x and y tapes match - bool match_x = x.tape_id_ == tape_id; - bool match_y = y.tape_id_ == tape_id; - - // check if x and y are dynamic parameters - bool dyn_x = match_x & (x.ad_type_ == dynamic_enum); - bool dyn_y = match_y & (y.ad_type_ == dynamic_enum); - - // check if x and y are variables - bool var_x = match_x & (x.ad_type_ != dynamic_enum); - bool var_y = match_y & (y.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - x.tape_id_ == y.tape_id_ || ! match_x || ! match_y , - "azmul: AD variables or dynamic parameters on different threads." - ); - 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; - result.ad_type_ = variable_enum; - } - else if( ( ! dyn_y ) & IdenticalZero( y.value_ ) ) - { // result = variable * 0 - } - else if( ( ! dyn_y ) & 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 = y.taddr_; - if( ! dyn_y ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( var_y ) - { if( ( ! dyn_x ) & IdenticalZero(x.value_) ) - { // result = 0 * variable - } - else if( ( ! dyn_x ) & 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 = x.taddr_; - if( ! dyn_x ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( dyn_x | dyn_y ) - { addr_t arg0 = x.taddr_; - addr_t arg1 = y.taddr_; - if( ! dyn_x ) - arg0 = tape->Rec_.put_con_par(x.value_); - if( ! dyn_y ) - arg1 = tape->Rec_.put_con_par(y.value_); - // - // parameters with a dynamic parameter result - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::zmul_dyn, arg0, arg1 - ); - result.tape_id_ = tape_id; - result.ad_type_ = dynamic_enum; - } - return result; -} -// ========================================================================= -// Fold operations into case above -// ------------------------------------------------------------------------- -// Operations with VecAD_reference and AD only - -template AD -azmul(const AD& x, const VecAD_reference& y) -{ return azmul(x, y.ADBase()); } - -template AD -azmul(const VecAD_reference& x, const VecAD_reference& y) -{ return azmul(x.ADBase(), y.ADBase()); } - -template AD -azmul(const VecAD_reference& x, const AD& y) -{ return azmul(x.ADBase(), y); } -// ------------------------------------------------------------------------- -// Operations with Base - -template AD -azmul(const Base& x, const AD& y) -{ return azmul(AD(x), y); } - -template AD -azmul(const Base& x, const VecAD_reference& y) -{ return azmul(AD(x), y.ADBase()); } - -template AD -azmul(const AD& x, const Base& y) -{ return azmul(x, AD(y)); } - -template AD -azmul(const VecAD_reference& x, const Base& y) -{ return azmul(x.ADBase(), AD(y)); } - -// ========================================================================== -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/base2ad.hpp b/build-config/cppad/include/cppad/core/base2ad.hpp deleted file mode 100644 index bf5106e7..00000000 --- a/build-config/cppad/include/cppad/core/base2ad.hpp +++ /dev/null @@ -1,117 +0,0 @@ -# ifndef CPPAD_CORE_BASE2AD_HPP -# define CPPAD_CORE_BASE2AD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin base2ad$$ -$spell - af - Taylor -$$ - -$spell -$$ - -$section Create an AD Function From a Base Function$$ - -$head Syntax$$ -$icode%af% = %f%.base2ad()%$$ - -$head See Also$$ -$cref mul_level$$ - -$head Base$$ -This is the base type used to recorded the operation sequence in $icode f$$ -and $icode af$$; i.e., the type $codei%AD<%Base%>%$$ was used to record -the operation sequence. - -$head f$$ -This object has prototype -$codei% - ADFun<%Base%> %f% -%$$ -It does it's derivative calculations using the type $icode Base$$. - -$head af$$ -This object has prototype -$codei% - ADFun< AD<%Base%> , %Base% > %af% -%$$ -It has the same operation sequence as $icode f$$, -but it does it's derivative calculations using the type -$codei%AD<%Base>%$$. -This enables one to record new functions that are defined -using derivatives of the function $icode f$$. -Initially, there are no Taylor coefficients stored in $icode af$$ and -$cref%af.size_order()%size_order%$$ is zero. - -$children% - example/general/base2ad.cpp -%$$ -$head Example$$ -The file $cref base2ad.cpp$$ -contains an example and test of this operation. - -$end ----------------------------------------------------------------------------- -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file base2ad.hpp -*/ -/// Create an ADFun< AD, Base > from this ADFun -template -ADFun< AD, RecBase > ADFun::base2ad(void) const -{ ADFun< AD, RecBase > fun; - // - // bool values - fun.has_been_optimized_ = has_been_optimized_; - fun.check_for_nan_ = check_for_nan_; - // - // size_t values - fun.compare_change_count_ = compare_change_count_; - fun.compare_change_number_ = compare_change_number_; - fun.compare_change_op_index_ = compare_change_op_index_; - CPPAD_ASSERT_UNKNOWN( fun.num_order_taylor_ == 0 ) ; - CPPAD_ASSERT_UNKNOWN( fun.cap_order_taylor_ == 0 ); - CPPAD_ASSERT_UNKNOWN( fun.num_direction_taylor_ == 0 ); - fun.num_var_tape_ = num_var_tape_; - // - // pod_vector objects - fun.ind_taddr_ = ind_taddr_; - fun.dep_taddr_ = dep_taddr_; - fun.dep_parameter_ = dep_parameter_; - fun.cskip_op_ = cskip_op_; - fun.load_op2var_ = load_op2var_; - // - // pod_maybe_vector< AD > = pod_maybe_vector - CPPAD_ASSERT_UNKNOWN( fun.taylor_.size() == 0 ); - // - // player - // (uses move semantics) - fun.play_ = play_.base2ad(); - // - // subgraph - fun.subgraph_info_ = subgraph_info_; - // - // sparse_pack - fun.for_jac_sparse_pack_ = for_jac_sparse_pack_; - // - // sparse_list - fun.for_jac_sparse_set_ = for_jac_sparse_set_; - // - return fun; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/base_complex.hpp b/build-config/cppad/include/cppad/core/base_complex.hpp deleted file mode 100644 index 57354305..00000000 --- a/build-config/cppad/include/cppad/core/base_complex.hpp +++ /dev/null @@ -1,384 +0,0 @@ -# ifndef CPPAD_CORE_BASE_COMPLEX_HPP -# define CPPAD_CORE_BASE_COMPLEX_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -/* -$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 - erfc - Cond - namespace - bool -$$ - - -$section Enable use of AD where Base is std::complex$$ - -$children%example/general/complex_poly.cpp -%$$ -$head Example$$ -The file $cref complex_poly.cpp$$ contains an example use of -$code std::complex$$ type for a CppAD $icode Base$$ type. - -$head Include Order$$ -This file is included before $code $$ -so it is necessary to define the error handler -in addition to including -$cref/base_require.hpp/base_require/Include Order/$$ -$srccode%cpp% */ -# include -# include -# include -# include - -/* %$$ - -$head CondExpOp$$ -The type $code std::complex$$ 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 CondExpOp( - enum CppAD::CompareOp cop , - const std::complex &left , - const std::complex &right , - const std::complex &trueCase , - const std::complex &falseCase ) - { CppAD::ErrorHandler::Call( - true , __LINE__ , __FILE__ , - "std::complex CondExpOp(...)", - "Error: cannot use CondExp with a complex type" - ); - return std::complex(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 ) -} -/* %$$ -used $code CondExpOp$$ above to -define $codei%CondExp%Rel%$$ for $code std::complex$$ 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 &x , - const std::complex &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 IdenticalCon(const std::complex &x) - { return true; } - inline bool IdenticalZero(const std::complex &x) - { return (x == std::complex(0., 0.) ); } - inline bool IdenticalOne(const std::complex &x) - { return (x == std::complex(1., 0.) ); } - inline bool IdenticalEqualCon( - const std::complex &x, const std::complex &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& x) \ -{ CppAD::ErrorHandler::Call( \ - true , __LINE__ , __FILE__ , \ - #Fun"(x)", \ - "Error: cannot use " #Fun " with x complex " \ - ); \ - 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& x , - const std::complex& 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 &x) - { return static_cast( x.real() ); } -} -/* %$$ - -$head azmul$$ -$srccode%cpp% */ -namespace CppAD { - CPPAD_AZMUL( std::complex ) -} -/* %$$ - -$head isnan$$ -The gcc 4.1.1 complier defines the function -$codei% - int std::complex::isnan( std::complex %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& 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 >$$. -$srccode%cpp% */ -namespace CppAD { - CPPAD_STANDARD_MATH_UNARY(std::complex, cos) - CPPAD_STANDARD_MATH_UNARY(std::complex, cosh) - CPPAD_STANDARD_MATH_UNARY(std::complex, exp) - CPPAD_STANDARD_MATH_UNARY(std::complex, log) - CPPAD_STANDARD_MATH_UNARY(std::complex, sin) - CPPAD_STANDARD_MATH_UNARY(std::complex, sinh) - CPPAD_STANDARD_MATH_UNARY(std::complex, 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 >$$. -$srccode%cpp% */ -# undef CPPAD_USER_MACRO -# define CPPAD_USER_MACRO(Fun) \ -inline std::complex Fun(const std::complex& x) \ -{ CppAD::ErrorHandler::Call( \ - true , __LINE__ , __FILE__ , \ - #Fun"(x)", \ - "Error: cannot use " #Fun " with x complex " \ - ); \ - return std::complex(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) - CPPAD_USER_MACRO(asinh) - CPPAD_USER_MACRO(acosh) - CPPAD_USER_MACRO(atanh) - CPPAD_USER_MACRO(erf) - CPPAD_USER_MACRO(erfc) - CPPAD_USER_MACRO(expm1) - CPPAD_USER_MACRO(log1p) -} -/* %$$ - -$head pow $$ -The following defines a $code CppAD::pow$$ function that -is required to use $code AD< std::complex >$$: -$srccode%cpp% */ -namespace CppAD { - inline std::complex pow( - const std::complex &x , - const std::complex &y ) - { return std::pow(x, y); } -} -/* %$$ - -$head numeric_limits$$ -The following defines the CppAD $cref numeric_limits$$ -for the type $code std::complex$$: -$srccode%cpp% */ -namespace CppAD { - CPPAD_NUMERIC_LIMITS(double, std::complex) -} -/* %$$ - -$head to_string$$ -The following defines the function CppAD $cref to_string$$ -for the type $code std::complex$$: -$srccode%cpp% */ -namespace CppAD { - CPPAD_TO_STRING(std::complex) -} -/* %$$ -$end -*/ -# undef CPPAD_USER_MACRO_ONE -# define CPPAD_USER_MACRO_ONE(Fun) \ -inline bool Fun(const std::complex& x) \ -{ CppAD::ErrorHandler::Call( \ - true , __LINE__ , __FILE__ , \ - #Fun"(x)", \ - "Error: cannot use " #Fun " with x complex " \ - ); \ - return false; \ -} -# undef CPPAD_USER_MACRO_TWO -# define CPPAD_USER_MACRO_TWO(Fun) \ -inline std::complex Fun(const std::complex& x) \ -{ CppAD::ErrorHandler::Call( \ - true , __LINE__ , __FILE__ , \ - #Fun"(x)", \ - "Error: cannot use " #Fun " with x complex " \ - ); \ - return std::complex(0); \ -} -namespace CppAD { - // CondExpOp ------------------------------------------------------ - inline std::complex CondExpOp( - enum CppAD::CompareOp cop , - const std::complex &left , - const std::complex &right , - const std::complex &trueCase , - const std::complex &falseCase ) - { CppAD::ErrorHandler::Call( - true , __LINE__ , __FILE__ , - "std::complex CondExpOp(...)", - "Error: cannot use CondExp with a complex type" - ); - return std::complex(0); - } - // CondExpRel -------------------------------------------------------- - CPPAD_COND_EXP_REL( std::complex ) - // EqualOpSeq ----------------------------------------------------- - inline bool EqualOpSeq( - const std::complex &x , - const std::complex &y ) - { return x == y; - } - // Identical ------------------------------------------------------ - inline bool IdenticalCon(const std::complex &x) - { return true; } - inline bool IdenticalZero(const std::complex &x) - { return (x == std::complex(0., 0.) ); } - inline bool IdenticalOne(const std::complex &x) - { return (x == std::complex(1., 0.) ); } - inline bool IdenticalEqualCon( - const std::complex &x, const std::complex &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& x , - const std::complex& y ) - { return std::abs(x) >= std::abs(y); } - // Integer ------------------------------------------------------ - inline int Integer(const std::complex &x) - { return static_cast( x.real() ); } - // isnan ------------------------------------------------------------- - inline bool isnan(const std::complex& z) - { return (z != z); - } - // Valid standard math functions -------------------------------- - CPPAD_STANDARD_MATH_UNARY(std::complex, cos) - CPPAD_STANDARD_MATH_UNARY(std::complex, cosh) - CPPAD_STANDARD_MATH_UNARY(std::complex, exp) - CPPAD_STANDARD_MATH_UNARY(std::complex, log) - CPPAD_STANDARD_MATH_UNARY(std::complex, sin) - CPPAD_STANDARD_MATH_UNARY(std::complex, sinh) - CPPAD_STANDARD_MATH_UNARY(std::complex, 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 pow( - const std::complex &x , - const std::complex &y ) - { return std::pow(x, y); } - // numeric_limits ------------------------------------------------- - CPPAD_NUMERIC_LIMITS(float, std::complex) - // to_string ------------------------------------------------- - CPPAD_TO_STRING(std::complex) -} - -// undefine macros only used by this file -# undef CPPAD_USER_MACRO -# undef CPPAD_USER_MACRO_ONE -# undef CPPAD_USER_MACRO_TWO - -# endif diff --git a/build-config/cppad/include/cppad/core/base_cond_exp.hpp b/build-config/cppad/include/cppad/core/base_cond_exp.hpp deleted file mode 100644 index ff07cf2b..00000000 --- a/build-config/cppad/include/cppad/core/base_cond_exp.hpp +++ /dev/null @@ -1,284 +0,0 @@ -# ifndef CPPAD_CORE_BASE_COND_EXP_HPP -# define CPPAD_CORE_BASE_COND_EXP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$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$$ - -$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 Type is the Base type for this base require operation. -The argument Rel is one of Lt, Le, Eq, Ge, Gt. -The argument Op is the corresponding 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 Type is the 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 comparison operators. - -\tparam CompareType -is the type of the left and right operands to the comparison operator. - -\tparam ResultType -is the type of the result, which is the same as CompareType except -during forward and reverse mode sparese calculations. - -\param cop -specifices which comparison to use; i.e., -$code <$$, -$code <=$$, -$code ==$$, -$code >=$$, -$code >$$, or -$code !=$$. - -\param left -is the left operand to the comparison operator. - -\param right -is the right operand to the comparison operator. - -\param exp_if_true -is the return value is the comparison results in true. - -\param exp_if_false -is the return value is the comparison results in false. - -\return -see exp_if_true and exp_if_false above. -*/ -template -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 diff --git a/build-config/cppad/include/cppad/core/base_double.hpp b/build-config/cppad/include/cppad/core/base_double.hpp deleted file mode 100644 index b2ab521d..00000000 --- a/build-config/cppad/include/cppad/core/base_double.hpp +++ /dev/null @@ -1,229 +0,0 @@ -# ifndef CPPAD_CORE_BASE_DOUBLE_HPP -# define CPPAD_CORE_BASE_DOUBLE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -/* -$begin base_double.hpp$$ -$spell - namespaces - cppad - hpp - azmul - expm1 - atanh - acosh - asinh - erf - erfc - 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 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 IdenticalCon(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 IdenticalEqualCon(const double& x, const double& y) - { return (x == y); } -} -/* %$$ - -$head Integer$$ -$srccode%cpp% */ -namespace CppAD { - inline int Integer(const double& x) - { return static_cast(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; - using std::asinh; - using std::acosh; - using std::atanh; - using std::erf; - using std::erfc; - using std::expm1; - using std::log1p; -} -/* %$$ -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$$: -$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$$. -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 diff --git a/build-config/cppad/include/cppad/core/base_float.hpp b/build-config/cppad/include/cppad/core/base_float.hpp deleted file mode 100644 index 3c04fea4..00000000 --- a/build-config/cppad/include/cppad/core/base_float.hpp +++ /dev/null @@ -1,230 +0,0 @@ -# ifndef CPPAD_CORE_BASE_FLOAT_HPP -# define CPPAD_CORE_BASE_FLOAT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -/* -$begin base_float.hpp$$ -$spell - namespaces - cppad - hpp - azmul - expm1 - atanh - acosh - asinh - erf - erfc - 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 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 IdenticalCon(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 IdenticalEqualCon(const float& x, const float& y) - { return (x == y); } -} -/* %$$ - -$head Integer$$ -$srccode%cpp% */ -namespace CppAD { - inline int Integer(const float& x) - { return static_cast(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; - using std::asinh; - using std::acosh; - using std::atanh; - using std::erf; - using std::erfc; - using std::expm1; - using std::log1p; -} - -/* %$$ -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$$: -$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$$. -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 diff --git a/build-config/cppad/include/cppad/core/base_hash.hpp b/build-config/cppad/include/cppad/core/base_hash.hpp deleted file mode 100644 index 4bf9a5aa..00000000 --- a/build-config/cppad/include/cppad/core/base_hash.hpp +++ /dev/null @@ -1,84 +0,0 @@ -# ifndef CPPAD_CORE_BASE_HASH_HPP -# define CPPAD_CORE_BASE_HASH_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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/con_dyn_var/Parameter/$$. - -$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 diff --git a/build-config/cppad/include/cppad/core/base_limits.hpp b/build-config/cppad/include/cppad/core/base_limits.hpp deleted file mode 100644 index c7f68a6e..00000000 --- a/build-config/cppad/include/cppad/core/base_limits.hpp +++ /dev/null @@ -1,67 +0,0 @@ -# ifndef CPPAD_CORE_BASE_LIMITS_HPP -# define CPPAD_CORE_BASE_LIMITS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$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\ -{\ - public:\ - static Base min(void) \ - { return static_cast( std::numeric_limits::min() ); }\ - static Base max(void) \ - { return static_cast( std::numeric_limits::max() ); }\ - static Base epsilon(void) \ - { return static_cast( std::numeric_limits::epsilon() ); }\ - static Base quiet_NaN(void) \ - { return static_cast( std::numeric_limits::quiet_NaN() ); }\ - static const int digits10 = std::numeric_limits::digits10;\ -}; -/* %$$ -$end -*/ - -# endif diff --git a/build-config/cppad/include/cppad/core/base_std_math.hpp b/build-config/cppad/include/cppad/core/base_std_math.hpp deleted file mode 100644 index 6bef3947..00000000 --- a/build-config/cppad/include/cppad/core/base_std_math.hpp +++ /dev/null @@ -1,171 +0,0 @@ -# ifndef CPPAD_CORE_BASE_STD_MATH_HPP -# define CPPAD_CORE_BASE_STD_MATH_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin base_std_math$$ -$spell - expm1 - atanh - acosh - asinh - inline - fabs - isnan - alloc - std - acos - asin - atan - cos - exp - sqrt - const - CppAD - namespace - erf - erfc -$$ - -$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% = acosh(%x%)%$$ $cnext inverse hyperbolic cosine $rnext -$icode%y% = asin(%x%)%$$ $cnext inverse sine $rnext -$icode%y% = asinh(%x%)%$$ $cnext inverse hyperbolic sin $rnext -$icode%y% = atan(%x%)%$$ $cnext inverse tangent $rnext -$icode%y% = atanh(%x%)%$$ $cnext inverse hyperbolic tangent $rnext -$icode%y% = cos(%x%)%$$ $cnext cosine $rnext -$icode%y% = cosh(%x%)%$$ $cnext hyperbolic cosine $rnext -$icode%y% = erf(%x%)%$$ $cnext error function $rnext -$icode%y% = erfc(%x%)%$$ $cnext complementary error function $rnext -$icode%y% = exp(%x%)%$$ $cnext exponential $rnext -$icode%y% = expm1(%x%)%$$ $cnext exponential of x minus one $rnext -$icode%y% = fabs(%x%)%$$ $cnext absolute value $rnext -$icode%y% = log(%x%)%$$ $cnext natural logarithm $rnext -$icode%y% = log1p(%x%)%$$ $cnext logarithm of one plus x $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 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 - -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 x and return value y have type Type -using the corresponding function std::Fun. -*/ -# define CPPAD_STANDARD_MATH_UNARY(Type, Fun) \ - inline Type Fun(const Type& x) \ - { return std::Fun(x); } - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/base_to_string.hpp b/build-config/cppad/include/cppad/core/base_to_string.hpp deleted file mode 100644 index 5a4ded2e..00000000 --- a/build-config/cppad/include/cppad/core/base_to_string.hpp +++ /dev/null @@ -1,65 +0,0 @@ -# ifndef CPPAD_CORE_BASE_TO_STRING_HPP -# define CPPAD_CORE_BASE_TO_STRING_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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\ -{ std::string operator()(const Base& value) \ - { std::stringstream os;\ - int n_digits = 1 + CppAD::numeric_limits::digits10; \ - os << std::setprecision(n_digits);\ - os << value;\ - return os.str();\ - }\ -}; -/* %$$ -$end ------------------------------------------------------------------------------- -*/ -// make sure to_string has been included -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/bender_quad.hpp b/build-config/cppad/include/cppad/core/bender_quad.hpp deleted file mode 100644 index c3e32d25..00000000 --- a/build-config/cppad/include/cppad/core/bender_quad.hpp +++ /dev/null @@ -1,402 +0,0 @@ -# ifndef CPPAD_CORE_BENDER_QUAD_HPP -# define CPPAD_CORE_BENDER_QUAD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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$$ - -$head Syntax$$ -$codei% -# include -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. - - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN CppAD namespace - -template -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(); - - // declare the ADvector type - typedef CPPAD_TESTVECTOR(AD) 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 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 diff --git a/build-config/cppad/include/cppad/core/bool_fun.hpp b/build-config/cppad/include/cppad/core/bool_fun.hpp deleted file mode 100644 index 0964eee1..00000000 --- a/build-config/cppad/include/cppad/core/bool_fun.hpp +++ /dev/null @@ -1,241 +0,0 @@ -# ifndef CPPAD_CORE_BOOL_FUN_HPP -# define CPPAD_CORE_BOOL_FUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin BoolFun$$ -$spell - namespace - bool - CppAD - const -$$ - - -$section AD Boolean Functions$$ - -$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. - -$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 to bool. -*/ - -/*! -Macro that defines a unary function bool F(AD x) -using bool F(Base x). - -\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., F. -*/ -# define CPPAD_BOOL_UNARY(Base, unary_name) \ - inline bool unary_name (const CppAD::AD &x) \ - { \ - return CppAD::AD::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 -bool AD::UnaryBool( - bool FunName(const Base &x), - const AD &x -) -{ - return FunName(x.value_); -} - -/*! -Macro that defines a binary function bool F(AD x, AD y) -using bool F(Base x, Base y). - -\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., F. -*/ - -# define CPPAD_BOOL_BINARY(Base, binary_name) \ - inline bool binary_name ( \ - const CppAD::AD &x, const CppAD::AD &y) \ - { \ - return CppAD::AD::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 -bool AD::BinaryBool( - bool FunName(const Base &x, const Base &y), - const AD &x, const AD &y -) -{ - return FunName(x.value_, y.value_); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/bool_valued.hpp b/build-config/cppad/include/cppad/core/bool_valued.hpp deleted file mode 100644 index 56b183b3..00000000 --- a/build-config/cppad/include/cppad/core/bool_valued.hpp +++ /dev/null @@ -1,49 +0,0 @@ -# ifndef CPPAD_CORE_BOOL_VALUED_HPP -# define CPPAD_CORE_BOOL_VALUED_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin BoolValued$$ -$spell - Bool -$$ - - -$section Bool Valued Operations and Functions with AD Arguments$$ - -$children% - include/cppad/core/compare.hpp% - include/cppad/core/near_equal_ext.hpp% - include/cppad/core/bool_fun.hpp% - include/cppad/core/con_dyn_var.hpp% - include/cppad/core/equal_op_seq.hpp -%$$ -$table -$rref Compare$$ -$rref NearEqualExt$$ -$rref BoolFun$$ -$rref con_dyn_var$$ -$rref EqualOpSeq$$ -$tend - - -$end -*/ - -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/capacity_order.hpp b/build-config/cppad/include/cppad/core/capacity_order.hpp deleted file mode 100644 index 2ec0ee24..00000000 --- a/build-config/cppad/include/cppad/core/capacity_order.hpp +++ /dev/null @@ -1,256 +0,0 @@ -# ifndef CPPAD_CORE_CAPACITY_ORDER_HPP -# define CPPAD_CORE_CAPACITY_ORDER_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin capacity_order$$ -$spell - var - taylor_ - xq - yq -$$ - - -$section Controlling Taylor Coefficients Memory Allocation$$ - -$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 $icode%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. - -$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. - -\param c -is the number of orders to allocate memory for. -If c == 0 then 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_.clear() is called. - -\param r -is the number of directions to allocate memory for. -If c == 1 then r must also be one. -In all cases, it must hold that - - r == num_direction_taylor_ || num_order_taylor <= 1 - -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 r. -*/ - -template -void ADFun::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_.clear(); - 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_maybe new_taylor(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. - -\param c -is the number of orders to allocate memory for. -If c == 0, -num_order_taylor_, cap_order_taylor_, and num_direction_taylor_ -are all set to zero. -In addition, taylor_.clear() 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 is zero (one), num_direction_taylor_ is set to zero (one). -Otherwise, if num_direction_taylor_ is zero, it is set to one. -Othwerwise, num_direction_taylor_ is not modified. -*/ - -template -void ADFun::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 diff --git a/build-config/cppad/include/cppad/core/check_for_nan.hpp b/build-config/cppad/include/cppad/core/check_for_nan.hpp deleted file mode 100644 index 91fdac33..00000000 --- a/build-config/cppad/include/cppad/core/check_for_nan.hpp +++ /dev/null @@ -1,244 +0,0 @@ -# ifndef CPPAD_CORE_CHECK_FOR_NAN_HPP -# define CPPAD_CORE_CHECK_FOR_NAN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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% -%$$ -If $icode b$$ is true (false), -future calls to $icode%f%.Forward%$$ will (will not) check for $code nan$$. - -$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. - -$end -*/ - -# include -# include -# include - -# if CPPAD_HAS_MKSTEMP -# include -# include -# else -# if CPPAD_HAS_TMPNAM_S -# include -# else -# include -# endif -# endif - - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/*! -Set check_for_nan - -\param value -new value for this flag. -*/ -template -void ADFun::check_for_nan(bool value) -{ check_for_nan_ = value; } - -/*! -Get check_for_nan - -\return -current value of check_for_nan_. -*/ -template -bool ADFun::check_for_nan(void) const -{ return check_for_nan_; } - -/*! -Stores a vector in a file when nans occur. - -\param vec [in] -is the vector that is stored. - -\param [out] file_name -is the file where the vector is stored -*/ -template -void put_check_for_nan(const CppAD::vector& vec, std::string& file_name) -{ - size_t char_size = sizeof(Base) * vec.size(); - // 2DO: add vec.data() to C11 tests and use it when C11 true - // const char* char_ptr = reinterpret_cast( vec.data() ); - const char* char_ptr = reinterpret_cast( &vec[0] ); - -# if CPPAD_HAS_MKSTEMP - char pattern[] = "/tmp/fileXXXXXX"; - int fd = mkstemp(pattern); - file_name = pattern; - ssize_t flag = write(fd, char_ptr, char_size); - if( flag < 0 ) - { std::cerr << "put_check_nan: write error\n"; - std::exit(1); - } - close(fd); -# else -# if CPPAD_HAS_TMPNAM_S - std::vector name(L_tmpnam_s); - // if( tmpnam_s( name.data(), L_tmpnam_s ) != 0 ) - if( tmpnam_s( &name[0], L_tmpnam_s ) != 0 ) - { CPPAD_ASSERT_KNOWN( - false, - "Cannot create a temporary file name" - ); - } - // file_name = name.data(); - file_name = &name[0]; -# else - file_name = tmpnam( nullptr ); -# 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; -} - -/*! -Gets a vector that was stored by put_check_for_nan. - -\param vec [out] -is the vector that is stored. - -\param file_name [in] -is the file where the vector is stored -*/ -template -void get_check_for_nan(CppAD::vector& vec, const std::string& file_name) -{ // - std::streamsize char_size = std::streamsize( sizeof(Base) * vec.size() ); - // char* char_ptr = reinterpret_cast( vec.data() ); - char* char_ptr = reinterpret_cast( &vec[0] ); - // - 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 diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/chkpoint_one.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/chkpoint_one.hpp deleted file mode 100644 index 7ce66cfc..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/chkpoint_one.hpp +++ /dev/null @@ -1,621 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_CHKPOINT_ONE_HPP -# define CPPAD_CORE_CHKPOINT_ONE_CHKPOINT_ONE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_one.hpp -First generation checkpoint functions. -*/ - -/* -$begin chkpoint_one$$ -$spell - mul - chkpoint - alloc - inuse - sv - var - cppad.hpp - CppAD - checkpoint - checkpointing - algo - atom_fun - const - enum - bool - recomputed -$$ - -$section Checkpoint Functions: First Generation$$ - -$head Deprecated 2019-01-14$$ -Using the $code checkpoint$$ class has been deprecated. -Use $cref chkpoint_two$$ instead. - -$head Syntax$$ -$codei%checkpoint<%Base%> %atom_fun%( - %name%, %algo%, %ax%, %ay%, %sparsity%, %optimize% -) -%sv% = %atom_fun%.size_var() -%atom_fun%.option(%option_value%) -%algo%(%ax%, %ay%) -%atom_fun%(%ax%, %ay%) -checkpoint<%Base%>::clear()%$$ - -$head See Also$$ -$cref atomic_two$$, $cref rev_checkpoint.cpp$$ - -$head Purpose$$ - -$subhead Reduce Memory$$ -You can reduce the size of the tape and memory required for AD by -checkpointing functions of the form $latex y = f(x)$$ where -$latex f : \B{R}^n \rightarrow \B{R}^m$$. - -$subhead Faster Recording$$ -It may also reduce the time to make a recording the same function -for different values of the independent variable. -Note that the operation sequence for a recording that uses $latex f(x)$$ -may depend on its independent variables. - -$subhead Repeating Forward$$ -Normally, CppAD store $cref forward$$ mode results until they freed -using $cref capacity_order$$ or the corresponding $cref ADFun$$ object is -deleted. This is not true for checkpoint functions because a checkpoint -function may be used repeatedly with different arguments in the same tape. -Thus, forward mode results are recomputed each time a checkpoint function -is used during a forward or reverse mode sweep. - -$subhead Restriction$$ -The $cref/operation sequence/glossary/Operation/Sequence/$$ -representing $latex f(x)$$ cannot depend on the value of $latex x$$. -The approach in the $cref rev_checkpoint.cpp$$ example case be applied -when the operation sequence depends on $latex x$$. - -$subhead Multiple Level AD$$ -If $icode Base$$ is an AD type, it is possible to record $icode Base$$ -operations. -Note that $icode atom_fun$$ will treat $icode algo$$ as an atomic -operation while recording $codei%AD%<%Base%>%$$ operations, but not while -recording $icode Base$$ operations. -See the $code chkpoint_one_mul_level.cpp$$ example. - - -$head Method$$ -The $code checkpoint$$ class is derived from $code atomic_base$$ -and makes this easy. -It implements all the $code atomic_base$$ -$cref/virtual functions/atomic_two/Virtual Functions/$$ -and hence its source code $code cppad/core/chkpoint_one/chkpoint_one.hpp$$ -provides an example implementation of $cref atomic_two$$. -The difference is that $code chkpoint_one.hpp$$ uses AD -instead of user provided derivatives. - -$head constructor$$ -The syntax for the checkpoint constructor is -$codei% - checkpoint<%Base%> %atom_fun%(%name%, %algo%, %ax%, %ay%) -%$$ -$list number$$ -This constructor cannot be called in $cref/parallel/ta_in_parallel/$$ mode. -$lnext -You cannot currently be recording -$codei%AD<%Base%>%$$ operations when the constructor is called. -$lnext -This object $icode atom_fun$$ must not be destructed for as long -as any $codei%ADFun<%Base%>%$$ object uses its atomic operation. -$lnext -This class is implemented as a derived class of -$cref/atomic/atomic_two_ctor/atomic_base/$$ and hence -some of its error message will refer to $code atomic_base$$. -$lend - -$head Base$$ -The type $icode Base$$ specifies the base type for AD operations. - -$head ADVector$$ -The type $icode ADVector$$ must be a -$cref/simple vector class/SimpleVector/$$ with elements of type -$codei%AD<%Base%>%$$. - -$head name$$ -This $icode checkpoint$$ constructor argument has prototype -$codei% - const char* %name% -%$$ -It is the name used for error reporting. -The suggested value for $icode name$$ is $icode atom_fun$$; i.e., -the same name as used for the object being constructed. - -$head ax$$ -This argument has prototype -$codei% - const %ADVector%& %ax% -%$$ -and size must be equal to $icode n$$. -It specifies vector $latex x \in \B{R}^n$$ -at which an $codei%AD<%Base%>%$$ version of -$latex y = f(x)$$ is to be evaluated. - -$head ay$$ -This argument has prototype -$codei% - %ADVector%& %ay% -%$$ -Its input size must be equal to $icode m$$ and does not change. -The input values of its elements do not matter. -Upon return, it is an $codei%AD<%Base%>%$$ version of -$latex y = f(x)$$. - -$head sparsity$$ -This argument has prototype -$codei% - atomic_base<%Base%>::option_enum %sparsity% -%$$ -It specifies $cref/sparsity/atomic_two_ctor/atomic_base/sparsity/$$ -in the $code atomic_base$$ constructor and must be either -$codei%atomic_base<%Base%>::pack_sparsity_enum%$$, -$codei%atomic_base<%Base%>::bool_sparsity_enum%$$, or -$codei%atomic_base<%Base%>::set_sparsity_enum%$$. -This argument is optional and its default value is unspecified. - -$head optimize$$ -This argument has prototype -$codei% - bool %optimize% -%$$ -It specifies if the recording corresponding to the atomic function -should be $cref/optimized/optimize/$$. -One expects to use a checkpoint function many times, so it should -be worth the time to optimize its operation sequence. -For debugging purposes, it may be useful to use the -original operation sequence (before optimization) -because it corresponds more closely to $icode algo$$. -This argument is optional and its default value is true. - - -$head size_var$$ -This $code size_var$$ member function return value has prototype -$codei% - size_t %sv% -%$$ -It is the $cref/size_var/seq_property/size_var/$$ for the -$codei%ADFun<%Base%>%$$ object is used to store the operation sequence -corresponding to $icode algo$$. - -$head option$$ -The $code option$$ syntax can be used to set the type of sparsity -pattern used by $icode atom_fun$$. -This is an $codei%atomic_base<%Base%>%$$ function and its documentation -can be found at $cref atomic_two_option$$. - -$head algo$$ -The type of $icode algo$$ is arbitrary, except for the fact that -the syntax -$codei% - %algo%(%ax%, %ay%) -%$$ -must evaluate the function $latex y = f(x)$$ using -$codei%AD<%Base%>%$$ operations. -In addition, we assume that the -$cref/operation sequence/glossary/Operation/Sequence/$$ -does not depend on the value of $icode ax$$. - -$head atom_fun$$ -Given $icode ax$$ it computes the corresponding value of $icode ay$$ -using the operation sequence corresponding to $icode algo$$. -If $codei%AD<%Base%>%$$ operations are being recorded, -it enters the computation as single operation in the recording -see $cref/start recording/Independent/Start Recording/$$. -(Currently each use of $icode atom_fun$$ actually corresponds to -$icode%m%+%n%+2%$$ operations and creates $icode m$$ new variables, -but this is not part of the CppAD specifications and my change.) - -$head Memory$$ - -$subhead Restriction$$ -The $code clear$$ routine cannot be called -while in $cref/parallel/ta_in_parallel/$$ execution mode. - -$head Parallel Mode$$ -The CppAD checkpoint function delays the caching of certain calculations -until they are needed. -In $cref/parallel model/ta_parallel_setup/$$, -this may result in $cref/thread_alloc::inuse(thread)/ta_inuse/$$ -being non-zero even though the specified thread is no longer active. -This memory will be freed when the checkpoint object is deleted. - -$subhead clear$$ -The $code atomic_base$$ class holds onto static work space -that is not connected to a particular object -(in order to increase speed by avoiding system memory allocation calls). -This call makes to work space $cref/available/ta_available/$$ to -for other uses by the same thread. -This should be called when you are done using the -atomic functions for a specific value of $icode Base$$. - -$end -*/ - -template -class checkpoint : public atomic_base { -// --------------------------------------------------------------------------- -private: - /// same as option_enum in base class - typedef typename atomic_base::option_enum option_enum; - // - // ------------------------------------------------------------------------ - // member_ - // ------------------------------------------------------------------------ - // same checkpoint object can be used by multiple threads - struct member_struct { - // - /// AD function corresponding to this checkpoint object - ADFun f_; - ADFun< AD, Base > af_; - // - /// sparsity for entire Jacobian f(x)^{(1)} - /// does not change so can cache it - local::sparse::list_setvec jac_sparse_set_; - vectorBool jac_sparse_bool_; - // - /// sparsity for sum_i f_i(x)^{(2)} does not change so can cache it - local::sparse::list_setvec hes_sparse_set_; - vectorBool hes_sparse_bool_; - }; - /// This version of work is const except during constructor - member_struct const_member_; - - /// use pointers and allocate memory to avoid false sharing - member_struct* member_[CPPAD_MAX_NUM_THREADS]; - // - /// allocate member_ for this thread - void allocate_member(size_t thread) - { if( member_[thread] == nullptr ) - { member_[thread] = new member_struct; - // The function is recorded in sequential mode and placed in - // const_member_.f_, other threads have copy. - member_[thread]->f_ = const_member_.f_; - } - return; - } - // - /// free member_ for this thread - void free_member(size_t thread) - { if( member_[thread] != nullptr ) - { delete member_[thread]; - member_[thread] = nullptr; - } - return; - } - // ------------------------------------------------------------------------ - option_enum sparsity(void) - { return static_cast< atomic_base* >(this)->sparsity(); } - // ------------------------------------------------------------------------ - /// set jac_sparse_set_ - void set_jac_sparse_set(void); - /// set jac_sparse_bool_ - void set_jac_sparse_bool(void); - // ------------------------------------------------------------------------ - /// set hes_sparse_set_ - void set_hes_sparse_set(void); - /// set hes_sparse_bool_ - void set_hes_sparse_bool(void); - // ------------------------------------------------------------------------ - /*! - Link from user_atomic to forward sparse Jacobian pack and bool - - \copydetails atomic_base::for_sparse_jac - */ - template - bool for_sparse_jac( - size_t q , - const sparsity_type& r , - sparsity_type& s , - const vector& x - ); - // ------------------------------------------------------------------------ - /*! - Link from user_atomic to reverse sparse Jacobian pack and bool - - \copydetails atomic_base::rev_sparse_jac - */ - template - bool rev_sparse_jac( - size_t q , - const sparsity_type& rt , - sparsity_type& st , - const vector& x - ); - /*! - Link from user_atomic to reverse sparse Hessian bools - - \copydetails atomic_base::rev_sparse_hes - */ - template - bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const sparsity_type& r , - const sparsity_type& u , - sparsity_type& v , - const vector& x - ); -public: - // ------------------------------------------------------------------------ - /*! - Constructor of a checkpoint object - - \param name [in] - is the user's name for the AD version of this atomic operation. - - \param algo [in/out] - user routine that compute AD function values - (not const because state may change during evaluation). - - \param ax [in] - argument value where algo operation sequence is taped. - - \param ay [out] - function value at specified argument value. - - \param sparsity [in] - what type of sparsity patterns are computed by this function, - pack_sparsity_enum bool_sparsity_enum, or set_sparsity_enum. - The default value is unspecified. - - \param optimize [in] - should the operation sequence corresponding to the algo be optimized. - The default value is true, but it is - sometimes useful to use false for debugging purposes. - */ - template - checkpoint( - const char* name , - Algo& algo , - const ADVector& ax , - ADVector& ay , - option_enum sparsity = - atomic_base::pack_sparsity_enum , - bool optimize = true - ); - /// destructor - ~checkpoint(void) - { -# ifndef NDEBUG - if( thread_alloc::in_parallel() ) - { std::string msg = atomic_base::atomic_name(); - msg += ": checkpoint destructor called in parallel mode."; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; ++thread) - free_member(thread); - } - // ------------------------------------------------------------------------ - /*! - Implement the user call to atom_fun.size_var(). - */ - size_t size_var(void) - { // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - return member_[thread]->f_.size_var(); - } - // ------------------------------------------------------------------------ - /*! - Implement the user call to atom_fun(ax, ay). - - \tparam ADVector - A simple vector class with elements of type AD. - - \param id - optional parameter which must be zero if present. - - \param ax - is the argument vector for this call, - ax.size() determines the number of arguments. - - \param ay - is the result vector for this call, - ay.size() determines the number of results. - */ - template - void operator()(const ADVector& ax, ADVector& ay, size_t id = 0) - { CPPAD_ASSERT_KNOWN( - id == 0, - "checkpoint: id is non-zero in atom_fun(ax, ay, id)" - ); - this->atomic_base::operator()(ax, ay, id); - } - // ------------------------------------------------------------------------ - /*! - Link from user_atomic to forward mode - - \copydetails atomic_base::forward - */ - virtual bool forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector& tx , - vector& ty - ); - virtual bool forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector< AD >& atx , - vector< AD >& aty - ); - // ------------------------------------------------------------------------ - /*! - Link from user_atomic to reverse mode - - \copydetails atomic_base::reverse - */ - virtual bool reverse( - size_t q , - const vector& tx , - const vector& ty , - vector& px , - const vector& py - ); - virtual bool reverse( - size_t q , - const vector< AD >& atx , - const vector< AD >& aty , - vector< AD >& apx , - const vector< AD >& apy - ); - // ------------------------------------------------------------------------ - /*! - Link from user_atomic to forward sparse Jacobian pack - - \copydetails atomic_base::for_sparse_jac - */ - virtual bool for_sparse_jac( - size_t q , - const vectorBool& r , - vectorBool& s , - const vector& x - ); - /*! - Link from user_atomic to forward sparse Jacobian bool - - \copydetails atomic_base::for_sparse_jac - */ - virtual bool for_sparse_jac( - size_t q , - const vector& r , - vector& s , - const vector& x - ); - /*! - Link from user_atomic to forward sparse Jacobian sets - - \copydetails atomic_base::for_sparse_jac - */ - virtual bool for_sparse_jac( - size_t q , - const vector< std::set >& r , - vector< std::set >& s , - const vector& x - ); - // ------------------------------------------------------------------------ - /*! - Link from user_atomic to reverse sparse Jacobian pack - - \copydetails atomic_base::rev_sparse_jac - */ - virtual bool rev_sparse_jac( - size_t q , - const vectorBool& rt , - vectorBool& st , - const vector& x - ); - /*! - Link from user_atomic to reverse sparse Jacobian bool - - \copydetails atomic_base::rev_sparse_jac - */ - virtual bool rev_sparse_jac( - size_t q , - const vector& rt , - vector& st , - const vector& x - ); - /*! - Link from user_atomic to reverse Jacobian sets - - \copydetails atomic_base::rev_sparse_jac - */ - virtual bool rev_sparse_jac( - size_t q , - const vector< std::set >& rt , - vector< std::set >& st , - const vector& x - ); - // ------------------------------------------------------------------------ - /*! - Link from user_atomic to reverse sparse Hessian pack - - \copydetails atomic_base::rev_sparse_hes - */ - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vectorBool& r , - const vectorBool& u , - vectorBool& v , - const vector& x - ); - /*! - Link from user_atomic to reverse sparse Hessian bool - - \copydetails atomic_base::rev_sparse_hes - */ - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector& r , - const vector& u , - vector& v , - const vector& x - ); - /*! - Link from user_atomic to reverse sparse Hessian sets - - \copydetails atomic_base::rev_sparse_hes - */ - virtual bool rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector< std::set >& r , - const vector< std::set >& u , - vector< std::set >& v , - const vector& x - ); -}; - -} // END_CPPAD_NAMESPACE - -// functions implemented in cppad/core/checkpoint files -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/ctor.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/ctor.hpp deleted file mode 100644 index b6a3c9bc..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/ctor.hpp +++ /dev/null @@ -1,62 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_CTOR_HPP -# define CPPAD_CORE_CHKPOINT_ONE_CTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -template -checkpoint::checkpoint( - const char* name , - Algo& algo , - const ADVector& ax , - ADVector& ay , - option_enum sparsity , - bool optimize -) : atomic_base(name, sparsity) -{ -# ifndef NDEBUG - if( thread_alloc::in_parallel() ) - { std::string msg = name; - msg += ": checkpoint constructor called in parallel mode."; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; ++thread) - member_[thread] = nullptr; - // - CheckSimpleVector< CppAD::AD , ADVector>(); - // - // make a copy of ax because Independent modifies AD information - ADVector x_tmp(ax); - // delcare x_tmp as the independent variables - Independent(x_tmp); - // record mapping from x_tmp to ay - algo(x_tmp, ay); - // create function f_ : x -> y - const_member_.f_.Dependent(ay); - if( optimize ) - { // suppress checking for nan in f_ results - // (see optimize documentation for atomic functions) - const_member_.f_.check_for_nan(false); - // - // now optimize - const_member_.f_.optimize(); - } - // now disable checking of comparison operations - // 2DO: add a debugging mode that checks for changes and aborts - const_member_.f_.compare_change_count(0); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/for_sparse_jac.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/for_sparse_jac.hpp deleted file mode 100644 index 601bb05a..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/for_sparse_jac.hpp +++ /dev/null @@ -1,135 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_FOR_SPARSE_JAC_HPP -# define CPPAD_CORE_CHKPOINT_ONE_FOR_SPARSE_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -template -bool checkpoint::for_sparse_jac( - size_t q , - const sparsity_type& r , - sparsity_type& s , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - // during user sparsity calculations - size_t m = member_[thread]->f_.Range(); - size_t n = member_[thread]->f_.Domain(); - if( member_[thread]->jac_sparse_bool_.size() == 0 ) - set_jac_sparse_bool(); - if( member_[thread]->jac_sparse_set_.n_set() != 0 ) - member_[thread]->jac_sparse_set_.resize(0, 0); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == m * n ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == 0 ); - CPPAD_ASSERT_UNKNOWN( r.size() == n * q ); - CPPAD_ASSERT_UNKNOWN( s.size() == m * q ); - // - bool ok = true; - for(size_t i = 0; i < m; i++) - { for(size_t k = 0; k < q; k++) - s[i * q + k] = false; - } - // sparsity for s = jac_sparse_bool_ * r - for(size_t i = 0; i < m; i++) - { for(size_t k = 0; k < q; k++) - { // initialize sparsity for S(i,k) - bool s_ik = false; - // S(i,k) = sum_j J(i,j) * R(j,k) - for(size_t j = 0; j < n; j++) - { bool J_ij = member_[thread]->jac_sparse_bool_[ i * n + j]; - bool R_jk = r[j * q + k ]; - s_ik |= ( J_ij & R_jk ); - } - s[i * q + k] = s_ik; - } - } - return ok; -} -template -bool checkpoint::for_sparse_jac( - size_t q , - const vectorBool& r , - vectorBool& s , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - return for_sparse_jac< vectorBool >(q, r, s, x); -} -template -bool checkpoint::for_sparse_jac( - size_t q , - const vector& r , - vector& s , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - return for_sparse_jac< vector >(q, r, s, x); -} -template -bool checkpoint::for_sparse_jac( - size_t q , - const vector< std::set >& r , - vector< std::set >& s , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - // during user sparsity calculations - size_t m = member_[thread]->f_.Range(); - size_t n = member_[thread]->f_.Domain(); - if( member_[thread]->jac_sparse_bool_.size() != 0 ) - member_[thread]->jac_sparse_bool_.clear(); - if( member_[thread]->jac_sparse_set_.n_set() == 0 ) - set_jac_sparse_set(); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == m ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.end() == n ); - CPPAD_ASSERT_UNKNOWN( r.size() == n ); - CPPAD_ASSERT_UNKNOWN( s.size() == m ); - - bool ok = true; - for(size_t i = 0; i < m; i++) - s[i].clear(); - - // sparsity for s = jac_sparse_set_ * r - for(size_t i = 0; i < m; i++) - { // compute row i of the return pattern - local::sparse::list_setvec::const_iterator set_itr( - member_[thread]->jac_sparse_set_, i - ); - size_t j = *set_itr; - while(j < n ) - { std::set::const_iterator itr_j; - const std::set& r_j( r[j] ); - for(itr_j = r_j.begin(); itr_j != r_j.end(); itr_j++) - { size_t k = *itr_j; - CPPAD_ASSERT_UNKNOWN( k < q ); - s[i].insert(k); - } - j = *(++set_itr); - } - } - - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/forward.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/forward.hpp deleted file mode 100644 index c058c346..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/forward.hpp +++ /dev/null @@ -1,170 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_FORWARD_HPP -# define CPPAD_CORE_CHKPOINT_ONE_FORWARD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -// --------------------------------------------------------------------------- -template -bool checkpoint::forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector& tx , - vector& ty ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); - // - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 ); - CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( n == tx.size() / (q+1) ); - CPPAD_ASSERT_UNKNOWN( m == ty.size() / (q+1) ); - bool ok = true; - // - if( vx.size() == 0 ) - { // during user forward mode - if( member_[thread]->jac_sparse_set_.n_set() != 0 ) - member_[thread]->jac_sparse_set_.resize(0,0); - if( member_[thread]->jac_sparse_bool_.size() != 0 ) - member_[thread]->jac_sparse_bool_.clear(); - // - if( member_[thread]->hes_sparse_set_.n_set() != 0 ) - member_[thread]->hes_sparse_set_.resize(0,0); - if( member_[thread]->hes_sparse_bool_.size() != 0 ) - member_[thread]->hes_sparse_bool_.clear(); - } - if( vx.size() > 0 ) - { // need Jacobian sparsity pattern to determine variable relation - // during user recording using checkpoint functions - if( sparsity() == atomic_base::set_sparsity_enum ) - { if( member_[thread]->jac_sparse_set_.n_set() == 0 ) - set_jac_sparse_set(); - CPPAD_ASSERT_UNKNOWN( - member_[thread]->jac_sparse_set_.n_set() == m - ); - CPPAD_ASSERT_UNKNOWN( - member_[thread]->jac_sparse_set_.end() == n - ); - // - for(size_t i = 0; i < m; i++) - { vy[i] = false; - local::sparse::list_setvec::const_iterator set_itr( - member_[thread]->jac_sparse_set_, i - ); - size_t j = *set_itr; - while(j < n ) - { // y[i] depends on the value of x[j] - // cast avoid Microsoft warning (should not be needed) - vy[i] |= static_cast( vx[j] ); - j = *(++set_itr); - } - } - } - else - { if( member_[thread]->jac_sparse_set_.n_set() != 0 ) - member_[thread]->jac_sparse_set_.resize(0, 0); - if( member_[thread]->jac_sparse_bool_.size() == 0 ) - set_jac_sparse_bool(); - CPPAD_ASSERT_UNKNOWN( - member_[thread]->jac_sparse_set_.n_set() == 0 - ); - CPPAD_ASSERT_UNKNOWN( - member_[thread]->jac_sparse_bool_.size() == m * n - ); - // - for(size_t i = 0; i < m; i++) - { vy[i] = false; - for(size_t j = 0; j < n; j++) - { if( member_[thread]->jac_sparse_bool_[ i * n + j ] ) - { // y[i] depends on the value of x[j] - // cast avoid Microsoft warning - vy[i] |= static_cast( vx[j] ); - } - } - } - } - } - // compute forward results for orders zero through q - ty = member_[thread]->f_.Forward(q, tx); - - // no longer need the Taylor coefficients in f_ - // (have to reconstruct them every time) - // Hold onto sparsity pattern because it is always good. - size_t c = 0; - size_t r = 0; - member_[thread]->f_.capacity_order(c, r); - return ok; -} - -// --------------------------------------------------------------------------- -template -bool checkpoint::forward( - size_t p , - size_t q , - const vector& vx , - vector& vy , - const vector< AD >& atx , - vector< AD >& aty ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - // make sure af_ is defined - if( member_[thread]->af_.size_var() == 0 ) - member_[thread]->af_ = member_[thread]->f_.base2ad(); - // -# ifndef NDEBUG - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); -# endif - // - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 ); - CPPAD_ASSERT_UNKNOWN( atx.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( aty.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( n == atx.size() / (q+1) ); - CPPAD_ASSERT_UNKNOWN( m == aty.size() / (q+1) ); - CPPAD_ASSERT_UNKNOWN( vx.size() == 0 ) - bool ok = true; - // - // during user forward mode - if( member_[thread]->jac_sparse_set_.n_set() != 0 ) - member_[thread]->jac_sparse_set_.resize(0,0); - if( member_[thread]->jac_sparse_bool_.size() != 0 ) - member_[thread]->jac_sparse_bool_.clear(); - // - if( member_[thread]->hes_sparse_set_.n_set() != 0 ) - member_[thread]->hes_sparse_set_.resize(0,0); - if( member_[thread]->hes_sparse_bool_.size() != 0 ) - member_[thread]->hes_sparse_bool_.clear(); - // - // compute forward results for orders zero through q - aty = member_[thread]->af_.Forward(q, atx); - - // no longer need the Taylor coefficients in af_ - // (have to reconstruct them every time) - // Hold onto sparsity pattern because it is always good. - size_t c = 0; - size_t r = 0; - member_[thread]->af_.capacity_order(c, r); - // - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/rev_sparse_hes.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/rev_sparse_hes.hpp deleted file mode 100644 index d28c16ab..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/rev_sparse_hes.hpp +++ /dev/null @@ -1,214 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_HES_HPP -# define CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -template -bool checkpoint::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const sparsity_type& r , - const sparsity_type& u , - sparsity_type& v , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - size_t n = member_[thread]->f_.Domain(); -# ifndef NDEBUG - size_t m = member_[thread]->f_.Range(); -# endif - CPPAD_ASSERT_UNKNOWN( vx.size() == n ); - CPPAD_ASSERT_UNKNOWN( s.size() == m ); - CPPAD_ASSERT_UNKNOWN( t.size() == n ); - CPPAD_ASSERT_UNKNOWN( r.size() == n * q ); - CPPAD_ASSERT_UNKNOWN( u.size() == m * q ); - CPPAD_ASSERT_UNKNOWN( v.size() == n * q ); - // - bool ok = true; - - // make sure hes_sparse_bool_ has been set - if( member_[thread]->hes_sparse_bool_.size() == 0 ) - set_hes_sparse_bool(); - if( member_[thread]->hes_sparse_set_.n_set() != 0 ) - member_[thread]->hes_sparse_set_.resize(0, 0); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == n * n ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == 0 ); - - - // compute sparsity pattern for T(x) = S(x) * f'(x) - t = member_[thread]->f_.RevSparseJac(1, s); -# ifndef NDEBUG - for(size_t j = 0; j < n; j++) - CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] ) -# endif - - // V(x) = f'(x)^T * g''(y) * f'(x) * R + g'(y) * f''(x) * R - // U(x) = g''(y) * f'(x) * R - // S(x) = g'(y) - - // compute sparsity pattern for A(x) = f'(x)^T * U(x) - bool transpose = true; - sparsity_type a(n * q); - a = member_[thread]->f_.RevSparseJac(q, u, transpose); - - // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R, - // but use less efficient sparsity for f(x)''(x) * R so that - // hes_sparse_set_ can be used every time this is needed. - for(size_t i = 0; i < n; i++) - { for(size_t k = 0; k < q; k++) - { // initialize sparsity pattern for H(i,k) - bool h_ik = false; - // H(i,k) = sum_j f''(i,j) * R(j,k) - for(size_t j = 0; j < n; j++) - { bool f_ij = member_[thread]->hes_sparse_bool_[i * n + j]; - bool r_jk = r[j * q + k]; - h_ik |= ( f_ij & r_jk ); - } - // sparsity for H(i,k) - v[i * q + k] = h_ik; - } - } - - // compute sparsity pattern for V(x) = A(x) + H(x) - for(size_t i = 0; i < n; i++) - { for(size_t k = 0; k < q; k++) - // v[ i * q + k ] |= a[ i * q + k]; - v[ i * q + k ] = bool(v[ i * q + k]) | bool(a[ i * q + k]); - } - return ok; -} -template -bool checkpoint::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vectorBool& r , - const vectorBool& u , - vectorBool& v , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - return rev_sparse_hes< vectorBool >(vx, s, t, q, r, u, v, x); -} -template -bool checkpoint::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector& r , - const vector& u , - vector& v , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - return rev_sparse_hes< vector >(vx, s, t, q, r, u, v, x); -} -template -bool checkpoint::rev_sparse_hes( - const vector& vx , - const vector& s , - vector& t , - size_t q , - const vector< std::set >& r , - const vector< std::set >& u , - vector< std::set >& v , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - size_t n = member_[thread]->f_.Domain(); -# ifndef NDEBUG - size_t m = member_[thread]->f_.Range(); -# endif - CPPAD_ASSERT_UNKNOWN( vx.size() == n ); - CPPAD_ASSERT_UNKNOWN( s.size() == m ); - CPPAD_ASSERT_UNKNOWN( t.size() == n ); - CPPAD_ASSERT_UNKNOWN( r.size() == n ); - CPPAD_ASSERT_UNKNOWN( u.size() == m ); - CPPAD_ASSERT_UNKNOWN( v.size() == n ); - // - bool ok = true; - - // make sure hes_sparse_set_ has been set - if( member_[thread]->hes_sparse_bool_.size() != 0 ) - member_[thread]->hes_sparse_bool_.clear(); - if( member_[thread]->hes_sparse_set_.n_set() == 0 ) - set_hes_sparse_set(); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == n ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.end() == n ); - - // compute sparsity pattern for T(x) = S(x) * f'(x) - t = member_[thread]->f_.RevSparseJac(1, s); -# ifndef NDEBUG - for(size_t j = 0; j < n; j++) - CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] ) -# endif - - // V(x) = f'(x)^T * g''(y) * f'(x) * R + g'(y) * f''(x) * R - // U(x) = g''(y) * f'(x) * R - // S(x) = g'(y) - - // compute sparsity pattern for A(x) = f'(x)^T * U(x) - // 2DO: change a to use INTERNAL_SPARSE_SET - bool transpose = true; - vector< std::set > a(n); - a = member_[thread]->f_.RevSparseJac(q, u, transpose); - - // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R, - // but use less efficient sparsity for f(x)''(x) * R so that - // hes_sparse_set_ can be used every time this is needed. - for(size_t i = 0; i < n; i++) - { v[i].clear(); - local::sparse::list_setvec::const_iterator set_itr( - member_[thread]->hes_sparse_set_, i - ); - size_t j = *set_itr; - while( j < n ) - { std::set::const_iterator itr_j; - const std::set& r_j( r[j] ); - for(itr_j = r_j.begin(); itr_j != r_j.end(); itr_j++) - { size_t k = *itr_j; - v[i].insert(k); - } - j = *(++set_itr); - } - } - // compute sparsity pattern for V(x) = A(x) + H(x) - std::set::const_iterator itr; - for(size_t i = 0; i < n; i++) - { for(itr = a[i].begin(); itr != a[i].end(); itr++) - { size_t j = *itr; - CPPAD_ASSERT_UNKNOWN( j < q ); - v[i].insert(j); - } - } - - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/rev_sparse_jac.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/rev_sparse_jac.hpp deleted file mode 100644 index 6a425163..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/rev_sparse_jac.hpp +++ /dev/null @@ -1,139 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_JAC_HPP -# define CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -template -bool checkpoint::rev_sparse_jac( - size_t q , - const sparsity_type& rt , - sparsity_type& st , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - // during user sparsity calculations - size_t m = member_[thread]->f_.Range(); - size_t n = member_[thread]->f_.Domain(); - if( member_[thread]->jac_sparse_bool_.size() == 0 ) - set_jac_sparse_bool(); - if( member_[thread]->jac_sparse_set_.n_set() != 0 ) - member_[thread]->jac_sparse_set_.resize(0, 0); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == m * n ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == 0 ); - CPPAD_ASSERT_UNKNOWN( rt.size() == m * q ); - CPPAD_ASSERT_UNKNOWN( st.size() == n * q ); - bool ok = true; - // - // S = R * J where J is jacobian - for(size_t i = 0; i < q; i++) - { for(size_t j = 0; j < n; j++) - { // initialize sparsity for S(i,j) - bool s_ij = false; - // S(i,j) = sum_k R(i,k) * J(k,j) - for(size_t k = 0; k < m; k++) - { // sparsity for R(i, k) - bool R_ik = rt[ k * q + i ]; - bool J_kj = member_[thread]->jac_sparse_bool_[ k * n + j ]; - s_ij |= (R_ik & J_kj); - } - // set sparsity for S^T - st[ j * q + i ] = s_ij; - } - } - return ok; -} -template -bool checkpoint::rev_sparse_jac( - size_t q , - const vectorBool& rt , - vectorBool& st , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - return rev_sparse_jac< vectorBool >(q, rt, st, x); -} -template -bool checkpoint::rev_sparse_jac( - size_t q , - const vector& rt , - vector& st , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - return rev_sparse_jac< vector >(q, rt, st, x); -} -template -bool checkpoint::rev_sparse_jac( - size_t q , - const vector< std::set >& rt , - vector< std::set >& st , - const vector& x ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - // during user sparsity calculations - size_t m = member_[thread]->f_.Range(); - size_t n = member_[thread]->f_.Domain(); - if( member_[thread]->jac_sparse_bool_.size() != 0 ) - member_[thread]->jac_sparse_bool_.clear(); - if( member_[thread]->jac_sparse_set_.n_set() == 0 ) - set_jac_sparse_set(); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == m ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.end() == n ); - CPPAD_ASSERT_UNKNOWN( rt.size() == m ); - CPPAD_ASSERT_UNKNOWN( st.size() == n ); - // - bool ok = true; - // - for(size_t j = 0; j < n; j++) - st[j].clear(); - // - // sparsity for s = r * jac_sparse_set_ - // s^T = jac_sparse_set_^T * r^T - for(size_t i = 0; i < m; i++) - { // i is the row index in r^T - std::set::const_iterator itr_i; - const std::set& r_i( rt[i] ); - for(itr_i = r_i.begin(); itr_i != r_i.end(); itr_i++) - { // k is the column index in r^T - size_t k = *itr_i; - CPPAD_ASSERT_UNKNOWN( k < q ); - // - // i is column index in jac_sparse_set^T - local::sparse::list_setvec::const_iterator set_itr( - member_[thread]->jac_sparse_set_, i - ); - size_t j = *set_itr; - while( j < n ) - { // j is row index in jac_sparse_set^T - st[j].insert(k); - j = *(++set_itr); - } - } - } - - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/reverse.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/reverse.hpp deleted file mode 100644 index 654fddf8..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/reverse.hpp +++ /dev/null @@ -1,125 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_REVERSE_HPP -# define CPPAD_CORE_CHKPOINT_ONE_REVERSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -// --------------------------------------------------------------------------- -template -bool checkpoint::reverse( - size_t q , - const vector& tx , - const vector& ty , - vector& px , - const vector& py ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - -# ifndef NDEBUG - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); -# endif - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 ); - CPPAD_ASSERT_UNKNOWN( n == tx.size() / (q+1) ); - CPPAD_ASSERT_UNKNOWN( m == ty.size() / (q+1) ); - CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( px.size() == n * (q+1) ); - CPPAD_ASSERT_UNKNOWN( py.size() == m * (q+1) ); - bool ok = true; - - // put proper forward mode coefficients in f_ -# ifdef NDEBUG - // compute forward results for orders zero through q - member_[thread]->f_.Forward(q, tx); -# else - size_t i, j, k; - // - // compute forward results for orders zero through q - vector check_ty = member_[thread]->f_.Forward(q, tx); - for(i = 0; i < m; i++) - { for(k = 0; k <= q; k++) - { j = i * (q+1) + k; - CPPAD_ASSERT_UNKNOWN( check_ty[j] == ty[j] ); - } - } -# endif - // now can run reverse mode - px = member_[thread]->f_.Reverse(q+1, py); - - // no longer need the Taylor coefficients in f_ - // (have to reconstruct them every time) - size_t c = 0; - size_t r = 0; - member_[thread]->f_.capacity_order(c, r); - return ok; -} -// --------------------------------------------------------------------------- -template -bool checkpoint::reverse( - size_t q , - const vector< AD >& atx , - const vector< AD >& aty , - vector< AD >& apx , - const vector< AD >& apy ) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - // make sure af_ is defined - if( member_[thread]->af_.size_var() == 0 ) - member_[thread]->af_ = member_[thread]->f_.base2ad(); -# ifndef NDEBUG - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); -# endif - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 ); - CPPAD_ASSERT_UNKNOWN( n == atx.size() / (q+1) ); - CPPAD_ASSERT_UNKNOWN( m == aty.size() / (q+1) ); - CPPAD_ASSERT_UNKNOWN( atx.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( aty.size() % (q+1) == 0 ); - CPPAD_ASSERT_UNKNOWN( apx.size() == n * (q+1) ); - CPPAD_ASSERT_UNKNOWN( apy.size() == m * (q+1) ); - bool ok = true; - - // put proper forward mode coefficients in f_ -# ifdef NDEBUG - // compute forward results for orders zero through q - member_[thread]->af_.Forward(q, atx); -# else - size_t i, j, k; - // - // compute forward results for orders zero through q - vector< AD > check_aty = member_[thread]->af_.Forward(q, atx); - for(i = 0; i < m; i++) - { for(k = 0; k <= q; k++) - { j = i * (q+1) + k; - CPPAD_ASSERT_UNKNOWN( check_aty[j] == aty[j] ); - } - } -# endif - // now can run reverse mode - apx = member_[thread]->af_.Reverse(q+1, apy); - - // no longer need the Taylor coefficients in f_ - // (have to reconstruct them every time) - size_t c = 0; - size_t r = 0; - member_[thread]->af_.capacity_order(c, r); - return ok; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_bool.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_bool.hpp deleted file mode 100644 index 33c43197..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_bool.hpp +++ /dev/null @@ -1,53 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_BOOL_HPP -# define CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_BOOL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -void checkpoint::set_hes_sparse_bool(void) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == 0 ); - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); - // - // set version of sparsity for vector of all ones - vectorBool all_one(m); - for(size_t i = 0; i < m; i++) - all_one[i] = true; - - // set version of sparsity for n by n idendity matrix - vectorBool identity(n * n); - for(size_t j = 0; j < n; j++) - { for(size_t i = 0; i < n; i++) - identity[ i * n + j ] = (i == j); - } - - // compute sparsity pattern for H(x) = sum_i f_i(x)^{(2)} - bool transpose = false; - bool dependency = false; - member_[thread]->f_.ForSparseJac(n, identity, transpose, dependency); - member_[thread]->hes_sparse_bool_ = member_[thread]->f_.RevSparseHes(n, all_one, transpose); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == n * n ); - // - // drop the forward sparsity results from f_ - member_[thread]->f_.size_forward_bool(0); - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_bool() == 0 ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_set() == 0 ); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_set.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_set.hpp deleted file mode 100644 index d153b5a8..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_set.hpp +++ /dev/null @@ -1,57 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_SET_HPP -# define CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_SET_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -void checkpoint::set_hes_sparse_set(void) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == 0 ); - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); - // - // set version of sparsity for vector of all ones - vector all_one(m); - for(size_t i = 0; i < m; i++) - all_one[i] = true; - - // set version of sparsity for n by n idendity matrix - local::sparse::list_setvec identity; - identity.resize(n, n); - for(size_t j = 0; j < n; j++) - { // Not using post_element because only adding one element per set - identity.add_element(j, j); - } - - // compute sparsity pattern for H(x) = sum_i f_i(x)^{(2)} - bool transpose = false; - bool dependency = false; - member_[thread]->f_.ForSparseJacCheckpoint( - n, identity, transpose, dependency, member_[thread]->jac_sparse_set_ - ); - member_[thread]->f_.RevSparseHesCheckpoint( - n, all_one, transpose, member_[thread]->hes_sparse_set_ - ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == n ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.end() == n ); - // - // drop the forward sparsity results from f_ - member_[thread]->f_.size_forward_set(0); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_bool.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_bool.hpp deleted file mode 100644 index 3c640ba7..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_bool.hpp +++ /dev/null @@ -1,56 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_BOOL_HPP -# define CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_BOOL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -void checkpoint::set_jac_sparse_bool(void) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == 0 ); - bool transpose = false; - bool dependency = true; - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); - // Use the choice for forward / reverse that results in smaller - // size for the sparsity pattern of all variables in the tape. - if( n <= m ) - { vectorBool identity(n * n); - for(size_t j = 0; j < n; j++) - { for(size_t i = 0; i < n; i++) - identity[ i * n + j ] = (i == j); - } - member_[thread]->jac_sparse_bool_ = member_[thread]->f_.ForSparseJac( - n, identity, transpose, dependency - ); - member_[thread]->f_.size_forward_bool(0); - } - else - { vectorBool identity(m * m); - for(size_t j = 0; j < m; j++) - { for(size_t i = 0; i < m; i++) - identity[ i * m + j ] = (i == j); - } - member_[thread]->jac_sparse_bool_ = member_[thread]->f_.RevSparseJac( - m, identity, transpose, dependency - ); - } - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_bool() == 0 ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_set() == 0 ); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_set.hpp b/build-config/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_set.hpp deleted file mode 100644 index c138e9f5..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_set.hpp +++ /dev/null @@ -1,58 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_SET_HPP -# define CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_SET_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -template -void checkpoint::set_jac_sparse_set(void) -{ // make sure member_ is allocated for this thread - size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - // - CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == 0 ); - bool transpose = false; - bool dependency = true; - size_t n = member_[thread]->f_.Domain(); - size_t m = member_[thread]->f_.Range(); - // Use the choice for forward / reverse that results in smaller - // size for the sparsity pattern of all variables in the tape. - if( n <= m ) - { local::sparse::list_setvec identity; - identity.resize(n, n); - for(size_t j = 0; j < n; j++) - { // Not using post_element because only adding one element per set - identity.add_element(j, j); - } - member_[thread]->f_.ForSparseJacCheckpoint( - n, identity, transpose, dependency, member_[thread]->jac_sparse_set_ - ); - member_[thread]->f_.size_forward_set(0); - } - else - { local::sparse::list_setvec identity; - identity.resize(m, m); - for(size_t i = 0; i < m; i++) - { // Not using post_element because only adding one element per set - identity.add_element(i, i); - } - member_[thread]->f_.RevSparseJacCheckpoint( - m, identity, transpose, dependency, member_[thread]->jac_sparse_set_ - ); - } - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_set() == 0 ); - CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_bool() == 0 ); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/chk_fun.omh b/build-config/cppad/include/cppad/core/chkpoint_two/chk_fun.omh deleted file mode 100644 index bb449f53..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/chk_fun.omh +++ /dev/null @@ -1,65 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin chkpoint_two_chk_fun$$ - -$spell - const - chk - chkpoint -$$ - -$section Using Checkpoint Functions$$ - -$head Syntax$$ -$icode%chk_fun%(%ax%, %ay%)%$$ - -$head Purpose$$ -Given $icode ax$$, -this call computes the corresponding value of $icode ay$$. -If $codei%AD<%Base%>%$$ operations are being recorded, -it enters the computation as an $cref atomic_three$$ -operation in the recording; -see $cref/start recording/Independent/Start Recording/$$. - -$head chk_fun$$ -This object must have been created using the -$cref/chkpoint_two/chkpoint_two_ctor/chk_fun/$$ constructor. - -$head ADVector$$ -The type $icode ADVector$$ must be a -$cref/simple vector class/SimpleVector/$$ with elements of type -$codei%AD<%Base%>%$$. - -$head ax$$ -This argument has prototype -$codei% - const %ADVector%& ax -%$$ -and its size equal to $icode%n% = %fun%.Domain()%$$ -where $cref/fun/chkpoint_two_ctor/fun/$$ is the $codei%ADFun<%Base%>%$$ -function in used the constructor for $icode chk_fun$$. -It specifies vector $latex x \in \B{R}^n$$ -at which we are computing an $codei%AD<%Base%>%$$ version of -$latex y = g(x)$$. - -$head ay$$ -This argument has prototype -$codei% - %ADVector%& ay -%$$ -and its size must be equal to $icode%m% = %fun%.Range()%$$. -The input values of its elements do not matter. -Upon return, it is an $codei%AD<%Base%>%$$ version of -$latex y = g(x)$$. - - -$end diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/chkpoint_two.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/chkpoint_two.hpp deleted file mode 100644 index b89b0283..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/chkpoint_two.hpp +++ /dev/null @@ -1,311 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_CHKPOINT_TWO_HPP -# define CPPAD_CORE_CHKPOINT_TWO_CHKPOINT_TWO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two.hpp -Second generation checkpoint functions. -*/ - -/* -$begin chkpoint_two$$ -$spell - CppAD - chk - chkpoint - hpp - cppad - bool - hes -$$ - -$section Checkpoint Functions: Second Generation$$ - -$head Syntax$$ - -$subhead Constructor$$ -$codei%chkpoint_two<%Base%> %chk_fun%( %fun%, %name%, - %internal_bool%, %use_hes_sparsity%, %use_base2ad%, %use_in_parallel% -)%$$ - -$subhead Use Checkpoint Function$$ -$codei% %chk_fun%(%ax%, %ay%)%$$ - -$subhead new_dynamic$$ -$icode%chk_fun%.new_dynamic(%dynamic%)%$$ - -$head Reduce Memory$$ -You can reduce the size of the tape and memory required for AD -using a checkpoint representation of a function -$latex g : \B{R}^n \rightarrow \B{R}^m$$. - -$head Faster Recording$$ -It may also reduce the time to make a recording if the same $latex g(x)$$ -is used many times (with different values) during the -recording of an $codei%ADFun<%Base%>%$$ object. - -$head Repeating Forward$$ -Normally, CppAD stores $cref forward$$ mode results, -until they freed using $cref capacity_order$$, -or the corresponding $cref ADFun$$ object is deleted. -This is not true for $code chkpoint_two$$ functions -because the same checkpoint function may be used repeatedly -with different arguments during a single forward mode operation. -Thus, forward mode results are computed for each use of $icode chk_fun$$ -in a forward mode sweep. - -$head Operation Sequence$$ -The $cref/operation sequence/glossary/Operation/Sequence/$$ -representing $latex g(x)$$ is fixed; i.e., -it cannot depend on the value of $latex x$$. - -$head atomic_three$$ -The $code chkpoint_two$$ class is derived from $code atomic_three$$, -hence some of its error message will refer to atomic operations. -The $code chkpoint_two$$ class implements all the -$cref/virtual functions/atomic_three/Virtual Functions/$$ -and hence its source code, -$codei% - include/cppad/core/chkpoint_two/chkpoint_two.hpp -%$$ -provides an example for $cref atomic_three$$ operations. -The difference is that $code chkpoint_two.hpp$$ uses AD -instead of user provided derivatives. - -$head Base$$ -The type $icode Base$$ specifies the base type for AD operations; -i.e., $icode chk_fun$$ can be used during the recording of -$codei%AD<%Base%>%$$ operations. - - -$childtable%include/cppad/core/chkpoint_two/ctor.hpp - %include/cppad/core/chkpoint_two/chk_fun.omh - %include/cppad/core/chkpoint_two/dynamic.hpp - %example/chkpoint_two/get_started.cpp - %example/chkpoint_two/compare.cpp - %example/chkpoint_two/base2ad.cpp - %example/chkpoint_two/dynamic.cpp - %example/chkpoint_two/ode.cpp -%$$ - -$end -*/ - -template -class chkpoint_two : public atomic_three { -// --------------------------------------------------------------------------- -private: - /// are sparsity calculations using bools or sets of integers - const bool internal_bool_; - // - /// can this checkpoint function calculate Hessian sparsity patterns - const bool use_hes_sparsity_; - // - /// can this checkpoint function be used in base2ad recordings - const bool use_base2ad_; - // - /// can this checkpoint function be used in parallel mode - const bool use_in_parallel_; - // - /// Jacobian sparsity for g(x) with dependncy true. - /// This is set by the constructor and constant after that. - sparse_rc< vector > jac_sparsity_; - // - /// Hessian sparsity for g(x). If use_hes_sparsity_ is true, - /// This is set by the constructor and constant after that. - sparse_rc< vector > hes_sparsity_; - // - /// Function corresponding to this checkpoint object. - /// If use_in_parallel_, this is constant after the constructor. - ADFun g_; - // - /// AD version of function corresponding to this checkpoint object - /// If use_in_parallel_, this is constant after the constructor. - ADFun< AD, Base> ag_; - // ------------------------------------------------------------------------ - // member_ - // ------------------------------------------------------------------------ - /// If use_in_parallel_ is true, must have a separate copy member data - /// that is not constant. - struct member_struct { - // - /// function corresponding to this checkpoint object - ADFun g_; - // - /// AD version of this function object - ADFun< AD, Base > ag_; - // - }; - /// use pointers and allocate memory to avoid false sharing - /// (initialized to null by constructor) - member_struct* member_[CPPAD_MAX_NUM_THREADS]; - // - // ------------------------------------------------------------------------ - /// allocate member_ for this thread - void allocate_member(size_t thread) - { CPPAD_ASSERT_UNKNOWN( use_in_parallel_ ); - if( member_[thread] == nullptr ) - { // allocaate raw memory - size_t min_bytes = sizeof(member_struct); - size_t num_bytes; - void* v_ptr = thread_alloc::get_memory(min_bytes, num_bytes); - // convert to member_struct* - member_[thread] = reinterpret_cast(v_ptr); - // call member_struct constructor - new( member_[thread] ) member_struct; - // - // The thread has a copy of corresponding informaiton. - member_[thread]->g_ = g_; - member_[thread]->ag_ = ag_; - } - return; - } - // - // ------------------------------------------------------------------------ - /// free member_ for this thread - void free_member(size_t thread) - { if( member_[thread] != nullptr ) - { // call destructor - member_[thread]->~member_struct(); - // return raw m,emory to available pool for this thread - void* v_ptr = reinterpret_cast(member_[thread]); - thread_alloc::return_memory(v_ptr); - // mark member for this thread as not allocated - member_[thread] = nullptr; - } - return; - } - // ----------------------------------------------------------------------- - // atomic_three virtual functions - // ------------------------------------------------------------------------ - // type - virtual bool for_type( - const vector& parameter_x , - const vector& type_x , - vector& type_y - ); - // forward - virtual bool forward( - const vector& parameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector& taylor_x , - vector& taylor_y - ); - // AD forward - virtual bool forward( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector< AD >& ataylor_x , - vector< AD >& ataylor_y - ); - // reverse - virtual bool reverse( - const vector& parameter_x , - const vector& type_x , - size_t order_up , - const vector& taylor_x , - const vector& taylor_y , - vector& partial_x , - const vector& partial_y - ); - // AD reverse - virtual bool reverse( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t order_up , - const vector< AD >& ataylor_x , - const vector< AD >& ataylor_y , - vector< AD >& apartial_x , - const vector< AD >& apartial_y - ); - // jac_sparsity - virtual bool jac_sparsity( - const vector& parameter_x , - const vector& type_x , - bool dependency , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out - ); - // hes_sparsity - virtual bool hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out - ); - // rev_depend - virtual bool rev_depend( - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y - ); -public: - // ctor - chkpoint_two( - const ADFun& fun , - const std::string& name , - bool internal_bool , - bool use_hes_sparsity , - bool use_base2ad , - bool use_in_parallel - ); - // - // destructor - ~chkpoint_two(void); - // - // assignment operator - void operator=(const chkpoint_two& other) - { CPPAD_ASSERT_KNOWN(false, - "cannot use chkpoint_two assignment operator" - ); - } - // copy constructor - chkpoint_two(const chkpoint_two& other) - : - internal_bool_ ( other.internal_bool_ ) , - use_hes_sparsity_ ( other.use_hes_sparsity_ ) , - use_base2ad_ ( other.use_base2ad_ ) , - use_in_parallel_ ( other.use_in_parallel_ ) , - jac_sparsity_ ( other.jac_sparsity_ ) , - hes_sparsity_ ( other.hes_sparsity_ ) - { g_ = other.g_; - ag_ = other.ag_; - } - // - // new_dynamic - template - void new_dynamic(const BaseVector& dynamic); -}; - -} // END_CPPAD_NAMESPACE - -# include -# include -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/ctor.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/ctor.hpp deleted file mode 100644 index 96421da1..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/ctor.hpp +++ /dev/null @@ -1,222 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_CTOR_HPP -# define CPPAD_CORE_CHKPOINT_TWO_CTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin chkpoint_two_ctor$$ -$spell - chkpoint - chk - bool - hes -$$ - -$section Checkpoint Function Constructor$$ - -$head Syntax$$ -$codei%chkpoint_two<%Base%> %chk_fun%( %fun%, %name%, - %internal_bool%, %use_hes_sparsity%, %use_base2ad%, %use_in_parallel% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Parallel$$ -This constructor, and its corresponding destructor, must not be called in -$cref/parallel/ta_in_parallel/$$ mode. -The object $icode chk_fun$$ should not be destructed for as long as there is -an $codei%ADFun<%Base%>%$$ object the has $icode chk_fun$$ in its recording. - -$head Base$$ -The type $icode Base$$ specifies the base type for AD operations. - -$head fun$$ -This specifies the function $latex g(x)$$. -Note that $icode fun$$ may or may not have been -$cref/optimized/optimize/$$ before calling the constructor. -This will determine if the internal representation for $icode g(x)$$ -is optimized. - -$head name$$ -is the name used for reporting errors using this checkpoint function. - -$head internal_bool$$ -If true, sparsity calculations are done with sets represented -by vectors of boolean values. -Otherwise, vectors of sets are used for sparsity patterns. - -$head use_hes_sparsity$$ -If true, Hessian sparsity patterns can be calculated for -$codei%ADFun<%Base%>%$$ objects that have uses of $icode chk_fun$$ -in their recording. -This requires some extra memory and extra computation during the constructor. - -$head use_base2ad$$ -If this is true, $icode chk_fun$$ can be used during the recording -of $codei%ADFun<%Base%>%$$ objects that get converted to -$codei%ADFun< AD<%Base%> >%$$ objects using $cref base2ad$$. -This requires some extra memory and extra computation during the constructor. - -$head use_in_parallel$$ -If this is true, $icode chk_fun$$ can be used -$cref/in_parallel/ta_parallel_setup/in_parallel/$$. -This requires some extra memory for a constant copy of the $icode fun$$ -information and a separate copy (that changes) for each thread. - -$head chk_fun$$ -This is a checkpoint function representation of $latex g(x)$$ -that can be used during the recording of $codei%AD<%Base%>%$$ operations. - -$end -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/ctor.hpp -Constructor for chkpoint_two class. -*/ - -/*! -Constructor - -\tparam Base -base class for recording AD operations using this checkpoint object. - -\param fun -is the function g(x) corresponding to this checkpoint object. - -\param name -is the name used for error reporting. - -\param internal_bool -should sparisity calculations be done using bools (or sets). - -\param use_hes_sparsity -will this checkpoint function be used with Hessian sparsity calculations. - -\param use_base2ad -will this checkpoint function be used with base2ad. - -\param use_in_parallel -will this checkpoint function be used in parallel mode. -*/ - -// BEGIN_PROTOTYPE -template -chkpoint_two::chkpoint_two( - const ADFun& fun , - const std::string& name , - bool internal_bool , - bool use_hes_sparsity , - bool use_base2ad , - bool use_in_parallel ) -// END_PROTOTYPE -: -atomic_three(name) , -internal_bool_( internal_bool ) , -use_hes_sparsity_( use_hes_sparsity ) , -use_base2ad_ ( use_base2ad ) , -use_in_parallel_ ( use_in_parallel ) -{ CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "chkpoint_two: constructor cannot be called in parallel mode." - ); - // initialize member pointers as null; - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++) - member_[thread] = nullptr; - // - // g_ - g_ = fun; - // - // suppress check for nan because chkpoint_two object can be used in a - // function that gets optimized and some checkpoint results may not matter. - g_.check_for_nan(false); - // - // ag_ - if( use_base2ad ) - ag_ = g_.base2ad(); - // - // jac_sparsity__ - size_t n = g_.Domain(); - size_t m = g_.Range(); - sparse_rc< vector > pattern_in; - bool transpose = false; - bool dependency = true; - if( n <= m || use_hes_sparsity ) - { // use forward mode - pattern_in.resize(n, n, n); - for(size_t k = 0; k < n; ++k) - pattern_in.set(k, k, k); - g_.for_jac_sparsity( - pattern_in, - transpose, - dependency, - internal_bool, - jac_sparsity_ - ); - } - else - { // use reverse mode - pattern_in.resize(m, m, m); - for(size_t k = 0; k < m; ++k) - pattern_in.set(k, k, k); - g_.rev_jac_sparsity( - pattern_in, - transpose, - dependency, - internal_bool, - jac_sparsity_ - ); - } - // - // hes_sparsity_ - if( use_hes_sparsity ) - { vector select_y(m), select_x(n); - for(size_t i = 0; i < m; ++i) - select_y[i] = true; - if( n <= m ) - { for(size_t j = 0; j < n; ++j) - select_x[j] = true; - g_.for_hes_sparsity( - select_x, select_y, internal_bool, hes_sparsity_ - ); - } - else - { // forward jacobian sparsity is stored in g_ - g_.rev_hes_sparsity( - select_y, transpose, internal_bool, hes_sparsity_ - ); - } - } - // free memory holding forward Jacobian sparsity - if( internal_bool ) - g_.size_forward_bool(0); - else - g_.size_forward_set(0); -} -/// destructor -template -chkpoint_two::~chkpoint_two(void) -{ -# ifndef NDEBUG - if( thread_alloc::in_parallel() ) - { std::string msg = atomic_three::atomic_name(); - msg += ": chkpoint_two destructor called in parallel mode."; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; ++thread) - free_member(thread); - } -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/dynamic.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/dynamic.hpp deleted file mode 100644 index 6ce7f702..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/dynamic.hpp +++ /dev/null @@ -1,102 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_DYNAMIC_HPP -# define CPPAD_CORE_CHKPOINT_TWO_DYNAMIC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin chkpoint_two_dynamic$$ -$spell - chk - chkpoint - dyn_ind -$$ - -$section Dynamic Parameters in Checkpoint Functions$$ - -$head Syntax$$ -$icode%chk_fun%.new_dynamic(%dynamic%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head chk_fun$$ -This object must have been created using the -$cref/chkpoint_two/chkpoint_two_ctor/chk_fun/$$ constructor. - -$subhead Base$$ -This is the $cref/Base/chkpoint_two_ctor/Base/$$ type -in the $icode chk_fun$$ constructor. - -$subhead fun$$ -This is the function $cref/fun/chkpoint_two_ctor/fun/$$ -in the $icode chk_fun$$ constructor. - -$head BaseVector$$ -This must be a $cref SimpleVector$$ with elements of type $icode Base$$. - -$head dynamic$$ -This is a vector with new values for the dynamic parameters -in the function $icode fun$$. -Is size must be equal to -$cref/fun.size_dyn_ind()/seq_property/size_dyn_par/$$. -This only affects the copy of $icode fun$$ used by $icode chk_fun$$. - -$head Multi-Threading$$ -If one is using $cref/in_parallel/ta_in_parallel/$$, -there is a separate copy of $icode fun$$ for each thread. -In this case, only the dynamic parameters in the copy for the current -$cref/thread number/ta_thread_num/$$ are changed. - - -$end -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/dynamic.hpp -Change the dynnamic parameter in a checkpoint function. -*/ - -/*! -Constructor - -\tparam Base -base class for recording AD operations using this checkpoint object. - -\param dynamic -is the new values for the dynamic parameters in the function -defining this checkpoint object. -*/ - -// BEGIN_PROTOTYPE -template -template -void chkpoint_two::new_dynamic(const BaseVector& dynamic) -// END_PROTOTYPE -{ ADFun* g_ptr = &g_; - if( use_in_parallel_ ) - { size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - g_ptr = &(member_[thread]->g_); - } -# ifndef NDEBUG - else if( thread_alloc::in_parallel() ) - { std::string msg = atomic_three::atomic_name(); - msg += ": use_in_parallel is false and in_parallel() is true"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - g_ptr->new_dynamic(dynamic); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/for_type.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/for_type.hpp deleted file mode 100644 index 34e6f51c..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/for_type.hpp +++ /dev/null @@ -1,63 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_FOR_TYPE_HPP -# define CPPAD_CORE_CHKPOINT_TWO_FOR_TYPE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/for_type.hpp -Second generation checkpoint type computation. -*/ -/*! -Link from atomic_three to type calculation - -\param parameter_x [in] -is the value of the parameters in the corresponding function call -afun(ax, ay). - -\param type_x [in] -specifies which components of x are -constants, dynamics, and variables - -\param type_y [out] -specifies which components of y are -constants, dynamics, and variables -*/ -template -bool chkpoint_two::for_type( - const vector& parameter_x , - const vector& type_x , - vector& type_y ) -{ size_t nr = jac_sparsity_.nr(); - size_t nnz = jac_sparsity_.nnz(); - const vector& row( jac_sparsity_.row() ); - const vector& col( jac_sparsity_.col() ); - // - CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nr() == type_y.size() ); - CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nc() == type_x.size() ); - // - // initialize type_y as constant_enum - for(size_t i = 0; i < nr; ++i) - type_y[i] = constant_enum; - // - // loop over entries in Dependency pattern - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - type_y[i] = std::max(type_y[i], type_x[j]); - } - return true; -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/forward.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/forward.hpp deleted file mode 100644 index c80211d5..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/forward.hpp +++ /dev/null @@ -1,130 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_FORWARD_HPP -# define CPPAD_CORE_CHKPOINT_TWO_FORWARD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/forward.hpp -Second generation checkpoint forward mode. -*/ -/*! -Link from chkpoint_two to forward mode - -\param parameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param need_y [in] -specifies which components of taylor_y are needed, - -\param order_low [in] -lowerest order for this forward mode calculation. - -\param order_up [in] -highest order for this forward mode calculation. - -\param taylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param taylor_y [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for atomic_three -*/ -template -bool chkpoint_two::forward( - const vector& parameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector& taylor_x , - vector& taylor_y ) -{ ADFun* g_ptr = &g_; - if( use_in_parallel_ ) - { size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - g_ptr = &(member_[thread]->g_); - } -# ifndef NDEBUG - else if( thread_alloc::in_parallel() ) - { std::string msg = atomic_three::atomic_name(); - msg += ": use_in_parallel is false and in_parallel() is true"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - // compute forward mode results for all values and orders - taylor_y = g_ptr->Forward(order_up, taylor_x); - // - return true; -} -/*! -Link from chkpoint_two to AD forward mode - -\param aparameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param need_y [in] -specifies which components of taylor_y are needed, - -\param order_low [in] -lowerest order for this forward mode calculation. - -\param order_up [in] -highest order for this forward mode calculation. - -\param ataylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param ataylor_y [out] -Taylor coefficient corresponding to y for this calculation - -See the forward mode in user's documentation for atomic_three -*/ -template -bool chkpoint_two::forward( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - const vector< AD >& ataylor_x , - vector< AD >& ataylor_y ) -{ if( ! use_base2ad_ ) - return false; - // - ADFun< AD, Base >* ag_ptr = &ag_; - if( use_in_parallel_ ) - { size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - ag_ptr = &(member_[thread]->ag_); - } -# ifndef NDEBUG - else if( thread_alloc::in_parallel() ) - { std::string msg = atomic_three::atomic_name(); - msg += ": use_in_parallel is false and in_parallel() is true"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - // compute forward mode results for all values and orders - ataylor_y = ag_ptr->Forward(order_up, ataylor_x); - // - return true; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/hes_sparsity.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/hes_sparsity.hpp deleted file mode 100644 index 3e54b696..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/hes_sparsity.hpp +++ /dev/null @@ -1,86 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_HES_SPARSITY_HPP -# define CPPAD_CORE_CHKPOINT_TWO_HES_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/hes_sparsity.hpp -Second generation checkpoint Jacobian sparsity patterns. -*/ -/*! -chkpoint_two to Hessian sparsity calculations. - -\param parameter_x [in] -contains the values for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param select_x [in] -which domain components to include in the dependency or sparsity pattern. -The index zero is used for parameters. - -\param select_y [in] -which range components to include in the dependency or sparsity pattern. -The index zero is used for parameters. -This argument is ignored because the sparsity pattern corresponding to -all components true is computed during the construction and used for all cases. -This errors on the side of caution for the sake of speed. - - -\param pattern_out [out] -is the dependency or sparsity pattern. -*/ -// BEGIN_PROTOTYPE -template -bool chkpoint_two::hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out ) -// END_PROTOTYPE -{ CPPAD_ASSERT_UNKNOWN( hes_sparsity_.nr() == select_x.size() ); - CPPAD_ASSERT_UNKNOWN( hes_sparsity_.nc() == select_x.size() ); - if( ! use_hes_sparsity_ ) - return false; - - // count number of non-zeros - size_t nnz = hes_sparsity_.nnz(); - size_t nr = hes_sparsity_.nr(); - size_t nc = hes_sparsity_.nc(); - const vector& row = hes_sparsity_.row(); - const vector& col = hes_sparsity_.col(); - size_t nnz_out = 0; - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - if( select_x[j] & select_x[i] ) - ++nnz_out; - } - - // set the output sparsity pattern - pattern_out.resize(nr, nc, nnz_out); - size_t ell = 0; - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - if( select_x[j] & select_x[i] ) - pattern_out.set(ell++, i, j); - } - CPPAD_ASSERT_UNKNOWN( ell == nnz_out ); - // - return true; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/jac_sparsity.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/jac_sparsity.hpp deleted file mode 100644 index 1d1ef1e7..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/jac_sparsity.hpp +++ /dev/null @@ -1,86 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_JAC_SPARSITY_HPP -# define CPPAD_CORE_CHKPOINT_TWO_JAC_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/jac_sparsity.hpp -Second generation checkpoint Jacobian sparsity patterns. -*/ -/*! -chkpoint_two to Jacobian sparsity calculations. - -\param dependency [in] -This argument is ignored. -The return pattern is always a dependency pattern which is a correct, -but possibly not efficient, sparsity pattern. - -\param parameter_x [in] -contains the values for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param select_x [in] -which domain components to include in the dependency or sparsity pattern. -The index zero is used for parameters. - -\param select_y [in] -which range components to include in the dependency or sparsity pattern. -The index zero is used for parameters. - -\param pattern_out [out] -is the dependency or sparsity pattern. -*/ -// BEGIN_PROTOTYPE -template -bool chkpoint_two::jac_sparsity( - const vector& parameter_x , - const vector& type_x , - bool dependency , - const vector& select_x , - const vector& select_y , - sparse_rc< vector >& pattern_out ) -// END_PROTOTYPE -{ CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nr() == select_y.size() ); - CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nc() == select_x.size() ); - - // count number of non-zeros - size_t nnz = jac_sparsity_.nnz(); - size_t nr = jac_sparsity_.nr(); - size_t nc = jac_sparsity_.nc(); - const vector& row = jac_sparsity_.row(); - const vector& col = jac_sparsity_.col(); - size_t nnz_out = 0; - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - if( select_x[j] & select_y[i] ) - ++nnz_out; - } - - // set the output sparsity pattern - pattern_out.resize(nr, nc, nnz_out); - size_t ell = 0; - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - if( select_x[j] & select_y[i] ) - pattern_out.set(ell++, i, j); - } - CPPAD_ASSERT_UNKNOWN( ell == nnz_out ); - // - return true; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/rev_depend.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/rev_depend.hpp deleted file mode 100644 index 9c11634c..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/rev_depend.hpp +++ /dev/null @@ -1,66 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_REV_DEPEND_HPP -# define CPPAD_CORE_CHKPOINT_TWO_REV_DEPEND_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/rev_depend.hpp -Second generation checkpoint type computation. -*/ -/*! -Link from atomic_three to dependency calculation - -\param parameter_x [in] -is the value of the parameters in the corresponding function call -afun(ax, ay). - -\param type_x [in] -is the AD type for ax in the corresponding afun(ax, ay) call. - -\param depend_x [out] -specifies which components of x affect the values of interest - -\param depend_y [in] -specifies which components of y affect the vlaues of interest -*/ -template -bool chkpoint_two::rev_depend( - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y ) -{ size_t nc = jac_sparsity_.nc(); - size_t nnz = jac_sparsity_.nnz(); - const vector& row( jac_sparsity_.row() ); - const vector& col( jac_sparsity_.col() ); - // - CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nr() == depend_y.size() ); - CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nc() == depend_x.size() ); - // - // initialize depend_x as false - for(size_t j = 0; j < nc; ++j) - depend_x[j] = false; - // - // loop over entries in Dependency pattern - for(size_t k = 0; k < nnz; ++k) - { size_t i = row[k]; - size_t j = col[k]; - if( depend_y[i] ) - depend_x[j] = true; - } - return true; -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/chkpoint_two/reverse.hpp b/build-config/cppad/include/cppad/core/chkpoint_two/reverse.hpp deleted file mode 100644 index 5506c3e5..00000000 --- a/build-config/cppad/include/cppad/core/chkpoint_two/reverse.hpp +++ /dev/null @@ -1,139 +0,0 @@ -# ifndef CPPAD_CORE_CHKPOINT_TWO_REVERSE_HPP -# define CPPAD_CORE_CHKPOINT_TWO_REVERSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file chkpoint_two/reverse.hpp -Second generation checkpoint reverse mode. -*/ -/*! -Link from chkpoint_two to reverse mode - -\param parameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param order_up [in] -highest order Taylor coefficient aht we are computing derivative of - -\param taylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param taylor_y [in] -Taylor coefficient corresponding to y for this calculation - -\param partial_x [out] -Partials w.r.t. the x Taylor coefficients. - -\param partial_y [in] -Partials w.r.t. the y Taylor coefficients. - -See the reverse mode in user's documentation for atomic_three -*/ -template -bool chkpoint_two::reverse( - const vector& parameter_x , - const vector& type_x , - size_t order_up , - const vector& taylor_x , - const vector& taylor_y , - vector& partial_x , - const vector& partial_y ) - -{ ADFun* g_ptr = &g_; - if( use_in_parallel_ ) - { size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - g_ptr = &(member_[thread]->g_); - } -# ifndef NDEBUG - else if( thread_alloc::in_parallel() ) - { std::string msg = atomic_three::atomic_name(); - msg += ": use_in_parallel is false and in_parallel() is true"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - // compute forward mode Taylor coefficient orders 0 through order_up -# ifdef NDEBUG - g_ptr->Forward(order_up, taylor_x); -# else - vector check = g_ptr->Forward(order_up, taylor_x); - CPPAD_ASSERT_UNKNOWN( taylor_y.size() == check.size() ) - for(size_t i = 0; i < taylor_y.size(); ++i) - CPPAD_ASSERT_UNKNOWN( taylor_y[i] == check[i] ); -# endif - // now can run reverse mode - partial_x = g_ptr->Reverse(order_up+1, partial_y); - // - return true; -} -/*! -Link from chkpoint_two to AD reverse mode - -\param aparameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param order_up [in] -highest order Taylor coefficient aht we are computing derivative of - -\param ataylor_x [in] -Taylor coefficients corresponding to x for this calculation. - -\param ataylor_y [in] -Taylor coefficient corresponding to y for this calculation - -\param apartial_x [out] -Partials w.r.t. the x Taylor coefficients. - -\param apartial_y [in] -Partials w.r.t. the y Taylor coefficients. - -See the reverse mode in user's documentation for atomic_three -*/ -template -bool chkpoint_two::reverse( - const vector< AD >& aparameter_x , - const vector& type_x , - size_t order_up , - const vector< AD >& ataylor_x , - const vector< AD >& ataylor_y , - vector< AD >& apartial_x , - const vector< AD >& apartial_y ) -{ ADFun< AD, Base >* ag_ptr = &ag_; - if( use_in_parallel_ ) - { size_t thread = thread_alloc::thread_num(); - allocate_member(thread); - ag_ptr = &(member_[thread]->ag_); - } - // compute forward mode Taylor coefficient orders 0 through order_up -# ifdef NDEBUG - ag_ptr->Forward(order_up, ataylor_x); -# else - vector< AD > acheck = ag_ptr->Forward(order_up, ataylor_x); - CPPAD_ASSERT_UNKNOWN( ataylor_y.size() == acheck.size() ) - for(size_t i = 0; i < ataylor_y.size(); ++i) - CPPAD_ASSERT_UNKNOWN( ataylor_y[i] == acheck[i] ); -# endif - // now can run reverse mode - apartial_x = ag_ptr->Reverse(order_up+1, apartial_y); - // - return true; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/compare.hpp b/build-config/cppad/include/cppad/core/compare.hpp deleted file mode 100644 index 2a81cb4d..00000000 --- a/build-config/cppad/include/cppad/core/compare.hpp +++ /dev/null @@ -1,635 +0,0 @@ -# ifndef CPPAD_CORE_COMPARE_HPP -# define CPPAD_CORE_COMPARE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$begin Compare$$ -$spell - cos - Op - bool - const -$$ - - - -$section AD Binary Comparison Operators$$ - - -$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. - -$end -------------------------------------------------------------------------------- -*/ -// BEGIN CppAD namespace -namespace CppAD { -// -------------------------------- < -------------------------- -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool operator < (const AD &left , const AD &right) -{ bool result = (left.value_ < right.value_); - // - // check if we are recording compare operators - local::ADTape *tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - if( ! tape->Rec_.get_record_compare() ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "< : AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // variable < variable - 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 - { // variable < parameter - addr_t p = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - if( result ) - { tape->Rec_.PutOp(local::LtvpOp); - tape->Rec_.PutArg(left.taddr_, p); - } - else - { tape->Rec_.PutOp(local::LepvOp); - tape->Rec_.PutArg(p, left.taddr_); - } - } - } - else if ( var_right ) - { // parameter < variable - addr_t p = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(left.value_); - if( result ) - { tape->Rec_.PutOp(local::LtpvOp); - tape->Rec_.PutArg(p, right.taddr_); - } - else - { tape->Rec_.PutOp(local::LevpOp); - tape->Rec_.PutArg(right.taddr_, p); - } - } - else if( dyn_left | dyn_right ) - { // parameter < parameter - addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - if( result ) - { tape->Rec_.PutOp(local::LtppOp); - tape->Rec_.PutArg(arg0, arg1); - } - else - { tape->Rec_.PutOp(local::LeppOp); - tape->Rec_.PutArg(arg1, arg0); - } - } - return result; -} -// convert other cases into the case above -CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<) - -// -------------------------------- <= -------------------------- -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool operator <= (const AD &left , const AD &right) -{ bool result = (left.value_ <= right.value_); - // - // check if we are recording compare operators - local::ADTape *tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - if( ! tape->Rec_.get_record_compare() ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "<= : AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // variable <= variable - 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 - { // variable <= parameter - addr_t p = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - if( result ) - { tape->Rec_.PutOp(local::LevpOp); - tape->Rec_.PutArg(left.taddr_, p); - } - else - { tape->Rec_.PutOp(local::LtpvOp); - tape->Rec_.PutArg(p, left.taddr_); - } - } - } - else if ( var_right ) - { // parameter <= variable - addr_t p = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(left.value_); - if( result ) - { tape->Rec_.PutOp(local::LepvOp); - tape->Rec_.PutArg(p, right.taddr_); - } - else - { tape->Rec_.PutOp(local::LtvpOp); - tape->Rec_.PutArg(right.taddr_, p); - } - } - else if( dyn_left | dyn_right ) - { // parameter <= parameter - addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - if( result ) - { tape->Rec_.PutOp(local::LeppOp); - tape->Rec_.PutArg(arg0, arg1); - } - else - { tape->Rec_.PutOp(local::LtppOp); - tape->Rec_.PutArg(arg1, arg0); - } - } - return result; -} -// convert other cases into the case above -CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<=) - -// -------------------------------- > -------------------------- -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool operator > (const AD &left , const AD &right) -{ bool result = (left.value_ > right.value_); - // - // check if we are recording compare operators - local::ADTape *tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - if( ! tape->Rec_.get_record_compare() ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "> : AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // variable > variable - 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 - { // variable > parameter - addr_t p = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - if( result ) - { tape->Rec_.PutOp(local::LtpvOp); - tape->Rec_.PutArg(p, left.taddr_); - } - else - { tape->Rec_.PutOp(local::LevpOp); - tape->Rec_.PutArg(left.taddr_, p); - } - } - } - else if ( var_right ) - { // parameter > variable - addr_t p = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(left.value_); - if( result ) - { tape->Rec_.PutOp(local::LtvpOp); - tape->Rec_.PutArg(right.taddr_, p); - } - else - { tape->Rec_.PutOp(local::LepvOp); - tape->Rec_.PutArg(p, right.taddr_); - } - } - else if( dyn_left | dyn_right ) - { // parameter > parameter - addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - if( result ) - { tape->Rec_.PutOp(local::LtppOp); - tape->Rec_.PutArg(arg1, arg0); - } - else - { tape->Rec_.PutOp(local::LeppOp); - tape->Rec_.PutArg(arg0, arg1); - } - } - return result; -} -// convert other cases into the case above -CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>) - -// -------------------------------- >= -------------------------- -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool operator >= (const AD &left , const AD &right) -{ bool result = (left.value_ >= right.value_); - // - // check if we are recording compare operators - local::ADTape *tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - if( ! tape->Rec_.get_record_compare() ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - ">= : AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // variable >= variable - 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 - { // variable >= parameter - addr_t p = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - if( result ) - { tape->Rec_.PutOp(local::LepvOp); - tape->Rec_.PutArg(p, left.taddr_); - } - else - { tape->Rec_.PutOp(local::LtvpOp); - tape->Rec_.PutArg(left.taddr_, p); - } - } - } - else if ( var_right ) - { // parameter >= variable - addr_t p = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(left.value_); - if( result ) - { tape->Rec_.PutOp(local::LevpOp); - tape->Rec_.PutArg(right.taddr_, p); - } - else - { tape->Rec_.PutOp(local::LtpvOp); - tape->Rec_.PutArg(p, right.taddr_); - } - } - else if( dyn_left | dyn_right ) - { // parameter >= parameter - addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - if( result ) - { tape->Rec_.PutOp(local::LeppOp); - tape->Rec_.PutArg(arg1, arg0); - } - else - { tape->Rec_.PutOp(local::LtppOp); - tape->Rec_.PutArg(arg0, arg1); - } - } - return result; -} -// convert other cases into the case above -CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>=) - -// -------------------------------- == ------------------------- -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool operator == (const AD &left , const AD &right) -{ bool result = (left.value_ == right.value_); - // - // check if we are recording compare operators - local::ADTape *tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - if( ! tape->Rec_.get_record_compare() ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "==: AD variables or dynamic parameters on different threads." - ); - // - tape->Rec_.comp_eq( - var_left, var_right, dyn_left, dyn_right, left, right, result - ); - // - return result; -} -// convert other cases into the case above -CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(==) - -// -------------------------------- != ------------------------- -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool operator != (const AD &left , const AD &right) -{ bool result = (left.value_ != right.value_); - // - // check if we are recording compare operators - local::ADTape *tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - if( ! tape->Rec_.get_record_compare() ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "!=: AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // variable == variable - tape->Rec_.PutArg(left.taddr_, right.taddr_); - if( result ) - tape->Rec_.PutOp(local::NevvOp); - else - tape->Rec_.PutOp(local::EqvvOp); - } - else - { // variable == parameter - addr_t p = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - tape->Rec_.PutArg(p, left.taddr_); - if( result ) - tape->Rec_.PutOp(local::NepvOp); - else - tape->Rec_.PutOp(local::EqpvOp); - } - } - else if ( var_right ) - { // parameter == variable - addr_t p = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(left.value_); - tape->Rec_.PutArg(p, right.taddr_); - if( result ) - tape->Rec_.PutOp(local::NepvOp); - else - tape->Rec_.PutOp(local::EqpvOp); - } - else if( dyn_left | dyn_right ) - { // parameter == parameter - addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - tape->Rec_.PutArg(arg0, arg1); - if( result ) - tape->Rec_.PutOp(local::NeppOp); - else - tape->Rec_.PutOp(local::EqppOp); - } - return result; -} -// convert other cases into the case above -CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(!=) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/compound_assign.hpp b/build-config/cppad/include/cppad/core/compound_assign.hpp deleted file mode 100644 index e6459143..00000000 --- a/build-config/cppad/include/cppad/core/compound_assign.hpp +++ /dev/null @@ -1,141 +0,0 @@ -# ifndef CPPAD_CORE_COMPOUND_ASSIGN_HPP -# define CPPAD_CORE_COMPOUND_ASSIGN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$begin compound_assign$$ -$spell - Op - VecAD - const -$$ - -$section AD Compound Assignment Operators$$ - - - - - - -$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_base/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 -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/con_dyn_var.hpp b/build-config/cppad/include/cppad/core/con_dyn_var.hpp deleted file mode 100644 index b31db282..00000000 --- a/build-config/cppad/include/cppad/core/con_dyn_var.hpp +++ /dev/null @@ -1,186 +0,0 @@ -# ifndef CPPAD_CORE_CON_DYN_VAR_HPP -# define CPPAD_CORE_CON_DYN_VAR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- - -$begin con_dyn_var$$ -$spell - VecAD - const - bool -$$ - -$section Constant, Dynamic, Parameter, and Variable$$ - -$head Syntax$$ -$icode%b% = Constant(%x%) -%$$ -$icode%b% = Dynamic(%x%) -%$$ -$icode%b% = Parameter(%x%) -%$$ -$icode%b% = Variable(%x%) -%$$ - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const AD<%Base%> &%x% - const VecAD<%Base%> &%x% -%$$ - -$head b$$ -The return value $icode b$$ has prototype -$codei% - bool %b% -%$$ - -$head Constant$$ -The return value for $code Constant$$ is true -is true if and only if $icode x$$ is -a $cref/constant/glossary/Parameter/Constant/$$ parameter. -A $cref/VecAD/VecAD/$$ object is a constant parameter -if no element of the vector depends on the independent variables. - -$head Dynamic$$ -The return value for $code Dynamic$$ is true -is true if and only if $icode x$$ is -a $cref/dynamic/glossary/Parameter/Dynamic/$$ parameter. -No element of a $cref/VecAD/VecAD/$$ object -can depend on the dynamic parameters and this function returns false -for these objects. - -$head Parameter$$ -The return value for $code Parameter$$ is true -is true if and only if $icode x$$ is -a $cref/parameter/glossary/Parameter/$$. -A $cref/VecAD/VecAD/$$ object is a parameter -if no element of the vector depends on the independent variables. - -$head Variable$$ -The return value for $code Variable$$ is true -is true if and only if $icode x$$ is -a $cref/variable/glossary/Variable/$$. -A $cref/VecAD/VecAD/$$ object is a variable -if any element of the vector depends on the independent variables. - -$head Operation Sequence$$ -The result of this operation is not an -$cref/AD of Base/glossary/AD of Base/$$ object. -Thus it will not be recorded as part of an -AD of $icode Base$$ -$cref/operation sequence/glossary/Operation/Sequence/$$. - -$head Example$$ -$children% - example/general/con_dyn_var.cpp -%$$ -The file -$cref con_dyn_var.cpp$$ -contains an example and test of these functions. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { - // ----------------------------------------------------------------------- - // Constant - template - bool Constant(const AD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_== 0 || x.ad_type_ != constant_enum ); - if( x.tape_id_ == 0 ) - return true; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ != *AD::tape_id_ptr(thread); - } - // - template - bool Constant(const VecAD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_== 0 || x.ad_type_ != constant_enum ); - if( x.tape_id_ == 0 ) - return true; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ != *AD::tape_id_ptr(thread); - } - // ----------------------------------------------------------------------- - // Dynamic - template - bool Dynamic(const AD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_ == 0 || x.ad_type_ != constant_enum ); - if( (x.tape_id_ == 0) | (x.ad_type_ != dynamic_enum) ) - return false; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ == *AD::tape_id_ptr(thread); - } - // - template - bool Dynamic(const VecAD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_ == 0 || x.ad_type_ != constant_enum ); - if( (x.tape_id_ == 0) | (x.ad_type_ != dynamic_enum) ) - return false; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ == *AD::tape_id_ptr(thread); - } - // ----------------------------------------------------------------------- - // Parameter - template - bool Parameter(const AD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_ == 0 || x.ad_type_ != constant_enum ); - if( (x.tape_id_ == 0) | (x.ad_type_ == dynamic_enum) ) - return true; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ != *AD::tape_id_ptr(thread); - } - // - template - bool Parameter(const VecAD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_ == 0 || x.ad_type_ != constant_enum ); - if( (x.tape_id_ == 0) | (x.ad_type_ == dynamic_enum) ) - return true; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ != *AD::tape_id_ptr(thread); - } - // ----------------------------------------------------------------------- - // Variable - template - bool Variable(const AD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_ == 0 || x.ad_type_ != constant_enum ); - if( (x.tape_id_ == 0) | (x.ad_type_ != variable_enum) ) - return false; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ == *AD::tape_id_ptr(thread); - } - // - template - bool Variable(const VecAD &x) - { CPPAD_ASSERT_UNKNOWN( x.tape_id_ == 0 || x.ad_type_ != constant_enum ); - if( (x.tape_id_ == 0) | (x.ad_type_ != variable_enum) ) - return false; - // - size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS); - return x.tape_id_ == *AD::tape_id_ptr(thread); - } -} -// END CppAD namespace - - -# endif diff --git a/build-config/cppad/include/cppad/core/cond_exp.hpp b/build-config/cppad/include/cppad/core/cond_exp.hpp deleted file mode 100644 index 0ee0806b..00000000 --- a/build-config/cppad/include/cppad/core/cond_exp.hpp +++ /dev/null @@ -1,276 +0,0 @@ -# ifndef CPPAD_CORE_COND_EXP_HPP -# define CPPAD_CORE_COND_EXP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$begin CondExp$$ -$spell - Atan2 - CondExp - Taylor - std - Cpp - namespace - inline - const - abs - Rel - bool - Lt - Le - Eq - Ge - Gt -$$ - - -$section AD Conditional Expressions$$ - -$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. - -$head Atan2$$ -The following implementation of the -AD $cref atan2$$ function is a more complex -example of using conditional expressions: -$srcfile%include/cppad/core/atan2.hpp%0%BEGIN CondExp%// END CondExp%$$ - - -$end -------------------------------------------------------------------------------- -*/ -// BEGIN CppAD namespace -namespace CppAD { - -template -AD CondExpOp( - enum CompareOp cop , - const AD &left , - const AD &right , - const AD &if_true , - const AD &if_false ) -{ - AD result; - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check first case where do not need to tape - if( IdenticalCon(left) & IdenticalCon(right) ) - { switch( cop ) - { - case CompareLt: - if( left.value_ < right.value_ ) - result = if_true; - else - result = if_false; - break; - - case CompareLe: - if( left.value_ <= right.value_ ) - result = if_true; - else - result = if_false; - break; - - case CompareEq: - if( left.value_ == right.value_ ) - result = if_true; - else - result = if_false; - break; - - case CompareGe: - if( left.value_ >= right.value_ ) - result = if_true; - else - result = if_false; - break; - - case CompareGt: - if( left.value_ > right.value_ ) - result = if_true; - else - result = if_false; - break; - - default: - CPPAD_ASSERT_UNKNOWN(0); - result = if_true; - } - return result; - } - - // must use CondExp in case Base is an AD type and recording - result.value_ = CondExpOp(cop, - left.value_, right.value_, if_true.value_, if_false.value_); - - local::ADTape *tape = AD::tape_ptr(); - - // add this operation to the tape - if( tape != nullptr ) tape->Rec_.cond_exp( - tape->id_, cop, result, left, right, if_true, if_false - ); - - return result; -} - -// ------------ CondExpOp(left, right, if_true, if_false) ---------------- - -# define CPPAD_COND_EXP(Name) \ - template \ - CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION \ - AD CondExp##Name( \ - const AD &left , \ - const AD &right , \ - const AD &if_true , \ - const AD &if_false ) \ - { \ - return CondExpOp(Compare##Name, \ - left, right, if_true, if_false); \ - } - -// AD -CPPAD_COND_EXP(Lt) -CPPAD_COND_EXP(Le) -CPPAD_COND_EXP(Eq) -CPPAD_COND_EXP(Ge) -CPPAD_COND_EXP(Gt) -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -AD CondExp( - const AD &flag , - const AD &if_true , - const AD &if_false ) -{ - return CondExpOp(CompareGt, flag, AD(0), if_true, if_false); -} - -# undef CPPAD_COND_EXP -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/convert.hpp b/build-config/cppad/include/cppad/core/convert.hpp deleted file mode 100644 index 7ec6815b..00000000 --- a/build-config/cppad/include/cppad/core/convert.hpp +++ /dev/null @@ -1,50 +0,0 @@ -# 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 the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin Convert$$ -$spell -$$ - - -$section Conversion and I/O of AD Objects$$ - -$children% - 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 -%$$ -$table -$rref Value$$ -$rref Integer$$ -$rref ad_output$$ -$rref PrintFor$$ -$rref Var2Par$$ -$tend - - -$end -*/ - -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/cppad_assert.hpp b/build-config/cppad/include/cppad/core/cppad_assert.hpp deleted file mode 100644 index f8c9507a..00000000 --- a/build-config/cppad/include/cppad/core/cppad_assert.hpp +++ /dev/null @@ -1,188 +0,0 @@ -# ifndef CPPAD_CORE_CPPAD_ASSERT_HPP -# define CPPAD_CORE_CPPAD_ASSERT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/*! -\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$$ - -$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 -# include -# include - -/*! -\def CPPAD_ASSERT_KNOWN(exp, msg) -Check that exp is true, if not print msg and terminate execution. - -The C++ expression exp is expected to be true. -If it is false, -the CppAD use has made an error that is described by msg. -If the preprocessor symbol NDEBUG is not defined, -and 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 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 exp is true, if not terminate execution. - -The C++ expression 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 NDEBUG is not defined, -and 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 op has the specified number of of arguments and results. - -If 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 NDEBUG is defined, this macro has no effect -(not even the definition of (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 - -# endif diff --git a/build-config/cppad/include/cppad/core/dependent.hpp b/build-config/cppad/include/cppad/core/dependent.hpp deleted file mode 100644 index 96d4219d..00000000 --- a/build-config/cppad/include/cppad/core/dependent.hpp +++ /dev/null @@ -1,334 +0,0 @@ -# ifndef CPPAD_CORE_DEPENDENT_HPP -# define CPPAD_CORE_DEPENDENT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin Dependent$$ -$spell - alloc - num - taylor_ - ADvector - const -$$ - -$spell -$$ - -$section Stop Recording and Store Operation Sequence$$ - - -$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{R}^n \rightarrow \B{R}^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. - -$end ----------------------------------------------------------------------------- -*/ - - -// BEGIN CppAD namespace -namespace CppAD { - -/*! -\file dependent.hpp -Different versions of Dependent function. -*/ - -/*! -Determine the tape corresponding to this exeuction thread and then use -Dependent(tape, y) to store this tapes recording in a function. - -\param y [in] -The dependent variable vector for the corresponding function. -*/ -template -template -void ADFun::Dependent(const ADvector &y) -{ local::ADTape* tape = AD::tape_ptr(); - CPPAD_ASSERT_KNOWN( - tape != nullptr, - "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 tape corresponding to this exeuction thread and then use -Dependent(tape, y) 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 -template -void ADFun::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 *tape = AD::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: independent variable vector has been changed." - ); - CPPAD_ASSERT_KNOWN( - x[j].tape_id_ == x[0].tape_id_, - "ADFun: 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: 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 -template -void ADFun::Dependent(local::ADTape *tape, const ADvector &y) -{ - size_t m = y.size(); - size_t n = tape->size_independent_; - - // check ADvector is Simple Vector class with AD elements - CheckSimpleVector< AD, 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(size_t i = 0; i < m; i++) - { dep_parameter_[i] = CppAD::Parameter(y[i]); - addr_t y_taddr; - if( dep_parameter_[i] ) - { // make a tape copy of dependent variables that are parameters, - y_taddr = tape->RecordParOp( y[i] ); - } - else - y_taddr = y[i].taddr_; - - CPPAD_ASSERT_UNKNOWN( y_taddr > 0 ); - dep_taddr_[i] = size_t( y_taddr ); - } - - // put an EndOp at the end of the tape - tape->Rec_.PutOp(local::EndOp); - - // bool values in this object except check_for_nan_ - has_been_optimized_ = false; - // - // size_t values in this object - compare_change_count_ = 1; - compare_change_number_ = 0; - compare_change_op_index_ = 0; - num_order_taylor_ = 0; - cap_order_taylor_ = 0; - num_direction_taylor_ = 0; - num_var_tape_ = tape->Rec_.num_var_rec(); - - // taylor_ - taylor_.resize(0); - - // cskip_op_ - cskip_op_.resize( tape->Rec_.num_op_rec() ); - - // load_op2var_ - load_op2var_.resize( tape->Rec_.num_var_load_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 recording; i.e. ERASE Rec_. - play_.get_recording(tape->Rec_, n); - - // 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(size_t 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); - - // resize subgraph_info_ - subgraph_info_.resize( - ind_taddr_.size(), // n_dep - dep_taddr_.size(), // n_ind - play_.num_op_rec(), // n_op - play_.num_var_rec() // n_var - ); - // --------------------------------------------------------------------- - // End set ad_fun.hpp private member data - // --------------------------------------------------------------------- - - // now we can delete the tape - AD::tape_manage(delete_tape_manage); - - // 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 diff --git a/build-config/cppad/include/cppad/core/discrete/devel.omh b/build-config/cppad/include/cppad/core/discrete/devel.omh deleted file mode 100644 index 7ca21274..00000000 --- a/build-config/cppad/include/cppad/core/discrete/devel.omh +++ /dev/null @@ -1,22 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -$begin devel_discrete$$ -$spell -$$ - -$section Developer Documentation for Discrete Function$$ - -$childtable% - include/cppad/core/discrete/discrete.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/discrete/discrete.hpp b/build-config/cppad/include/cppad/core/discrete/discrete.hpp deleted file mode 100644 index c64f505a..00000000 --- a/build-config/cppad/include/cppad/core/discrete/discrete.hpp +++ /dev/null @@ -1,334 +0,0 @@ -# ifndef CPPAD_CORE_DISCRETE_DISCRETE_HPP -# define CPPAD_CORE_DISCRETE_DISCRETE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/* - ------------------------------------------------------------------------------ -$begin discrete_create$$ -$spell -$$ -$section Create a Discrete AD Function$$ - -$head Syntax$$ -$codei%CPPAD_DISCRETE_FUNCTION(%Base%, %name%) -%$$ -$icode%name(%ax%, %ay%) -%$$ - -$head Base$$ -is the base type for the discrete function. - -$head name$$ -is the name of the user defined function that corresponding to this operation. - -$head ax$$ -Is a $codei%AD<%Base%>%$$ corresponding to the argument for the function. - -$head ay$$ -Is a $codei%AD<%Base%>%$$ corresponding to the result for the function. - -$head fun$$ -The local object $code fun$$ is a member of the $code discrete$$ class. - -$head Source Code$$ -$srccode%hpp% */ -# define CPPAD_DISCRETE_FUNCTION(Base, name) \ -inline CppAD::AD name (const CppAD::AD& ax) \ -{ static CppAD::discrete fun(#name, name); \ - return fun.ad(ax); \ -} -# define CppADCreateDiscrete CPPAD_DISCRETE_FUNCTION -/* %$$ -$end ------------------------------------------------------------------------------ -$begin discrete_class$$ - -$section Declare discrete Class and Member Data$$ - -$head parallel_ad$$ -is a friend of this class so it can call List to initialize -its static data. - -$head F$$ -is the type for the user routine that computes $icode Base$$ function values. - -$head name_$$ -name of this user defined discrete function. - -$head f_$$ -user routine that computes $icode Base$$ function values. - -$head index_$$ -index of this object in $cref discrete_list$$ for this $icode Base$$. - -$head Source Code$$ -$srccode%hpp% */ -template -class discrete { -private: - template friend void parallel_ad(void); - typedef Base (*F) (const Base& x); - const std::string name_; - const F f_; - const size_t index_; -/* %$$ -$end ------------------------------------------------------------------------------- -$begin discrete_list$$ -$spell - alloc - std - CppAD -$$ -$section List of all objects in the discrete class$$ - -$head Syntax$$ -$icode%list% = discrete<%Base%>::List()%$$ - -$head Base$$ -Is the $cref/Base/discrete_create/Base/$$ -type for this list of discrete functions. - -$head list$$ -is a reference to the list of all the -$code discrete$$ object currently defined. - -$subhead std::vector$$ -We use $code std::vector$$ instead of $code CppAD::vector$$ -so it does not appear that there is a $cref memory_leak$$ -this list is not destroyed before -$cref/thread_alloc::free_all/ta_free_all/$$ is called by testing routines. - -$head Source Code$$ -$srccode%hpp% */ -private: - static std::vector& List(void) - { CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - static std::vector list; - return list; - } -/* %$$ -$end - ------------------------------------------------------------------------------ -$begin discrete_list_size$$ -$spell -$$ -$section Size of the Discrete Function List$$ - -$head Syntax$$ -$icode%size% = discrete<%Base%>::list_size()%$$ - -$head Base$$ -Is the $cref/Base/discrete_create/Base/$$ -type for this list of discrete functions. - -$head size$$ -is the number of discrete functions for this $icode Base$$ type. - -$head Source Code$$ -$srccode%hpp% */ -public: - static size_t list_size(void) - { return List().size(); } -/* %$$ -$end - ------------------------------------------------------------------------------ -$begin discrete_ctor$$ -$spell -$$ -$section Constructor Called by each Use of CPPAD_DISCRETE_FUNCTION$$ - -$head Syntax$$ -$codei%discrete<%Base%> %fun%(%name%, %f%)%$$ - -$head name$$ -is the name of this function. - -$head f$$ -user routine that implements this function for Base class. - -$head fun$$ -is the $code discrete$$ object created by this call to the constructor. - -$subhead name_$$ -is set equal to $icode name$$. - -$subhead f_$$ -is set equal to $icode f$$. - -$subhead index_$$ -This object is put at the end of $cref discrete_list$$ and $code index_$$ -is set to the index of this object in the discrete list. - -$head Parallel$$ -This constructor cannot be used in parallel mode because it changes -the static object returned by $cref discrete_list$$. - -$end -*/ -public: - discrete(const char* name, F f) : - name_(name), f_(f) , index_( List().size() ) - { std::string msg = "discrete: first call to the discrete function "; - msg += name; - msg += " is in parallel mode."; - CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - msg.c_str() - ); - List().push_back(this); - } -/* - ------------------------------------------------------------------------------ -$begin discrete_ad$$ -$spell -$$ -$section Implement AD Version of a Discrete Function$$ - -$head Syntax$$ -$icode%ay% = %fun%.ad(%ax)%$$ - -$head ax$$ -is the argument for the AD version of this function. - -$head ay$$ -is the return value for the AD version of this function. - -$head Prototype$$ -$srccode%hpp% */ - AD ad(const AD &ax) const -/* %$$ -$end -*/ - { - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= index_, - "discrete: cppad_tape_addr_type maximum not large enough" - ); - // - AD ay; - ay.value_ = f_(ax.value_); - // - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return ay; - // - // check if argument is a constant parameter - if( ax.tape_id_ != tape->id_ ) - return ay; - // - if( ax.ad_type_ == dynamic_enum ) - { - // tape dynamic paramter operation - ay.taddr_ = tape->Rec_.put_dyn_par( - ay.value_, local::dis_dyn, addr_t(index_), ax.taddr_ - ); - ay.tape_id_ = ax.tape_id_; - ay.ad_type_ = dynamic_enum; - - // make result a dynamic parameter - ay.tape_id_ = tape->id_; - ay.ad_type_ = dynamic_enum; - - CPPAD_ASSERT_UNKNOWN( Dynamic(ay) ); - } - else if( ax.ad_type_ == variable_enum ) - { - 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( - size_t( std::numeric_limits::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_; - ay.ad_type_ = variable_enum; - - CPPAD_ASSERT_UNKNOWN( Variable(ay) ); - } - else - { // other types not yet being used and should have this tape id - CPPAD_ASSERT_UNKNOWN(false); - } - return ay; - } -/* ------------------------------------------------------------------------------- -$begin discrete_name$$ - -$section Name Corresponding to a discrete Function$$ - -$head Syntax$$ -$codei%discrete<%Base%>::name(%index%)%$$ - -$head Base$$ -Is the $cref/Base/discrete_create/Base/$$ -type for this list of discrete functions. - -$head index$$ -Is the index, in the list, for this discrete function. - -$head Source Code$$ -$srccode%hpp% */ - static const char* name(size_t index) - { return List()[index]->name_.c_str(); } -/* %$$ -$end ------------------------------------------------------------------------------- -$begin discrete_eval$$ -$spell - eval -$$ -$section Link From Forward Mode Sweep to Users Routine$$ - -$head Syntax$$ -$icode%y% = discrete<%Base%>::eval(%index%, %x%)%$$ - -$head Base$$ -Is the $cref/Base/discrete_create/Base/$$ -type for this list of discrete functions. - -$head index$$ -index for this function in $cref discrete_list$$. - -$head x$$ -argument at which to evaluate $icode Base$$ version of this function. - -$head y$$ -result for the $icode Base$$ version of this function. - -$head Source Code$$ -$srccode%hpp% */ - static Base eval(size_t index, const Base& x) - { CPPAD_ASSERT_UNKNOWN(index < List().size() ); - return List()[index]->f_(x); - } -/* %$$ -$end -*/ -}; - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/discrete/user.omh b/build-config/cppad/include/cppad/core/discrete/user.omh deleted file mode 100644 index 931957bc..00000000 --- a/build-config/cppad/include/cppad/core/discrete/user.omh +++ /dev/null @@ -1,146 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin Discrete$$ -$spell - retaping - namespace - std - Eq - Cpp - const - inline - Geq -$$ - -$section Discrete AD Functions$$ - - -$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% - %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 diff --git a/build-config/cppad/include/cppad/core/div.hpp b/build-config/cppad/include/cppad/core/div.hpp deleted file mode 100644 index 2d36d445..00000000 --- a/build-config/cppad/include/cppad/core/div.hpp +++ /dev/null @@ -1,130 +0,0 @@ -# ifndef CPPAD_CORE_DIV_HPP -# define CPPAD_CORE_DIV_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD operator / (const AD &left , const AD &right) -{ - // compute the Base part - AD result; - result.value_ = left.value_ / right.value_; - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "Divide: AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // result = 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(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; - result.ad_type_ = variable_enum; - } - else if( (! dyn_right) & 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 = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( var_right ) - { if( (! dyn_left) & 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 = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter result - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::div_dyn, arg0, arg1 - ); - result.tape_id_ = tape_id; - result.ad_type_ = dynamic_enum; - } - return result; -} - -// convert other cases into the case above -CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(/) - - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/div_eq.hpp b/build-config/cppad/include/cppad/core/div_eq.hpp deleted file mode 100644 index 00ccc87b..00000000 --- a/build-config/cppad/include/cppad/core/div_eq.hpp +++ /dev/null @@ -1,129 +0,0 @@ -# ifndef CPPAD_CORE_DIV_EQ_HPP -# define CPPAD_CORE_DIV_EQ_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD& AD::operator /= (const AD &right) -{ - // compute the Base part - Base left; - left = value_; - value_ /= right.value_; - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "/= : AD variables or dynamic parameters on different threads." - ); - 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); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - else if( (! dyn_right) & 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 = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - tape->Rec_.PutArg(taddr_, p); - // put operator in the tape - taddr_ = tape->Rec_.PutOp(local::DivvpOp); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - } - else if( var_right ) - { if( (! dyn_left) & 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 = taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(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; - ad_type_ = variable_enum; - } - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter results - taddr_ = tape->Rec_.put_dyn_par( - value_, local::div_dyn, arg0, arg1 - ); - tape_id_ = tape_id; - ad_type_ = dynamic_enum; - } - return *this; -} - -CPPAD_FOLD_ASSIGNMENT_OPERATOR(/=) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/drivers.hpp b/build-config/cppad/include/cppad/core/drivers.hpp deleted file mode 100644 index fd0887fd..00000000 --- a/build-config/cppad/include/cppad/core/drivers.hpp +++ /dev/null @@ -1,22 +0,0 @@ -# ifndef CPPAD_CORE_DRIVERS_HPP -# define CPPAD_CORE_DRIVERS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/epsilon.hpp b/build-config/cppad/include/cppad/core/epsilon.hpp deleted file mode 100644 index 6bc014b8..00000000 --- a/build-config/cppad/include/cppad/core/epsilon.hpp +++ /dev/null @@ -1,60 +0,0 @@ -# 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 the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------------- -$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 - inline Type epsilon(void) - { return Type ( numeric_limits::epsilon() ); } - -} -# endif diff --git a/build-config/cppad/include/cppad/core/equal_op_seq.hpp b/build-config/cppad/include/cppad/core/equal_op_seq.hpp deleted file mode 100644 index 317f7551..00000000 --- a/build-config/cppad/include/cppad/core/equal_op_seq.hpp +++ /dev/null @@ -1,118 +0,0 @@ -# ifndef CPPAD_CORE_EQUAL_OP_SEQ_HPP -# define CPPAD_CORE_EQUAL_OP_SEQ_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------------- -$begin EqualOpSeq$$ -$spell - Op - const - bool -$$ - - -$section Check if Two Value are Identically Equal$$ - -$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$$. - - -$end ------------------------------------------------------------------------------- -*/ - - -namespace CppAD { - template - CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION - bool EqualOpSeq(const AD &x, const AD &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 diff --git a/build-config/cppad/include/cppad/core/for_hes_sparsity.hpp b/build-config/cppad/include/cppad/core/for_hes_sparsity.hpp deleted file mode 100644 index 284e5e1e..00000000 --- a/build-config/cppad/include/cppad/core/for_hes_sparsity.hpp +++ /dev/null @@ -1,287 +0,0 @@ -# ifndef CPPAD_CORE_FOR_HES_SPARSITY_HPP -# define CPPAD_CORE_FOR_HES_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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 select_domain$$ 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. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include - -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 -template -void ADFun::for_hes_sparsity( - const BoolVector& select_domain , - const BoolVector& select_range , - bool internal_bool , - sparse_rc& pattern_out ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - 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; - // - local::pod_vector select_domain_pod_vector(n); - for(size_t j = 0; j < n; ++j) - select_domain_pod_vector[j] = select_domain[j]; - // - sparse_rc pattern_tmp; - if( internal_bool ) - { - // reverse Jacobian sparsity pattern for select_range - local::sparse::pack_setvec 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_ ); - // Not using post_element because only adding one element per set - internal_rev_jac.add_element( dep_taddr_[i] , 0 ); - } - // reverse Jacobian sparsity for all variables on tape - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - internal_rev_jac, - not_used_rec_base - ); - // internal vector of sets that will hold Hessian - local::sparse::pack_setvec internal_for_hes; - internal_for_hes.resize(n + 1 + num_var_tape_, n + 1); - // - // compute forward Hessian sparsity pattern - local::sweep::for_hes( - &play_, - n, - num_var_tape_, - select_domain_pod_vector, - internal_rev_jac, - internal_for_hes, - not_used_rec_base - ); - // - // put the result in pattern_tmp - local::sparse::get_internal_pattern( - transpose, ind_taddr_, internal_for_hes, pattern_tmp - ); - } - else - { - // reverse Jacobian sparsity pattern for select_range - // (corresponds to s) - local::sparse::list_setvec 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_ ); - // Not using post_element because only adding one element per set - internal_rev_jac.add_element( dep_taddr_[i] , 0 ); - } - // reverse Jacobian sparsity for all variables on tape - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - internal_rev_jac, - not_used_rec_base - - ); - // internal vector of sets that will hold Hessian - local::sparse::list_setvec internal_for_hes; - internal_for_hes.resize(n + 1 + num_var_tape_, n + 1); - // - // compute forward Hessian sparsity pattern - local::sweep::for_hes( - &play_, - n, - num_var_tape_, - select_domain_pod_vector, - internal_rev_jac, - internal_for_hes, - not_used_rec_base - ); - // - // put the result in pattern_tmp - local::sparse::get_internal_pattern( - 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 diff --git a/build-config/cppad/include/cppad/core/for_jac_sparsity.hpp b/build-config/cppad/include/cppad/core/for_jac_sparsity.hpp deleted file mode 100644 index c29a0e58..00000000 --- a/build-config/cppad/include/cppad/core/for_jac_sparsity.hpp +++ /dev/null @@ -1,305 +0,0 @@ -# ifndef CPPAD_CORE_FOR_JAC_SPARSITY_HPP -# define CPPAD_CORE_FOR_JAC_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$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$$ -This argument has prototype -$codei% - bool %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. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include - -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 -template -void ADFun::for_jac_sparsity( - const sparse_rc& pattern_in , - bool transpose , - bool dependency , - bool internal_bool , - sparse_rc& pattern_out ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - // 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::sparse::set_internal_pattern( - zero_empty , - input_empty , - transpose , - ind_taddr_ , - for_jac_sparse_pack_ , - pattern_in - ); - - // compute sparsity for other variables - local::sweep::for_jac( - &play_, - dependency, - n, - num_var_tape_, - for_jac_sparse_pack_, - not_used_rec_base - - ); - // set the output pattern - local::sparse::get_internal_pattern( - 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::sparse::set_internal_pattern( - zero_empty , - input_empty , - transpose , - ind_taddr_ , - for_jac_sparse_set_ , - pattern_in - ); - - // compute sparsity for other variables - local::sweep::for_jac( - &play_, - dependency, - n, - num_var_tape_, - for_jac_sparse_set_, - not_used_rec_base - - ); - // get the ouput pattern - local::sparse::get_internal_pattern( - transpose, dep_taddr_, for_jac_sparse_set_, pattern_out - ); - } - return; -} - - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/for_one.hpp b/build-config/cppad/include/cppad/core/for_one.hpp deleted file mode 100644 index 0162a0a1..00000000 --- a/build-config/cppad/include/cppad/core/for_one.hpp +++ /dev/null @@ -1,163 +0,0 @@ -# ifndef CPPAD_CORE_FOR_ONE_HPP -# define CPPAD_CORE_FOR_ONE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin ForOne$$ -$spell - dy - typename - Taylor - const -$$ - - - - -$section First Order Partial Derivative: Driver Routine$$ - -$head Syntax$$ -$icode%dy% = %f%.ForOne(%x%, %j%)%$$ - - -$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$$. -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 -template -Vector ADFun::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(); - - 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 diff --git a/build-config/cppad/include/cppad/core/for_sparse_hes.hpp b/build-config/cppad/include/cppad/core/for_sparse_hes.hpp deleted file mode 100644 index 16811b74..00000000 --- a/build-config/cppad/include/cppad/core/for_sparse_hes.hpp +++ /dev/null @@ -1,566 +0,0 @@ -# ifndef CPPAD_CORE_FOR_SPARSE_HES_HPP -# define CPPAD_CORE_FOR_SPARSE_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$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{R}^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 %SetVector%& %r% -%$$ -(see $cref/SetVector/ForSparseHes/SetVector/$$ below) -If it has elements of type $code bool$$, -its size is $latex n$$. -If it has elements of type $code std::set$$, -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 %SetVector%& %s% -%$$ -(see $cref/SetVector/ForSparseHes/SetVector/$$ below) -If it has elements of type $code bool$$, -its size is $latex m$$. -If it has elements of type $code std::set$$, -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% - %SetVector%& %h% -%$$ -(see $cref/SetVector/ForSparseHes/SetVector/$$ 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$$, -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 SetVector$$ -The type $icode SetVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$ or $code std::set$$; -see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion -of the difference. -The type of the elements of -$cref/SetVector/ForSparseHes/SetVector/$$ 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. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file core/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 bool value. This argument is used to dispatch to the proper source -code depending on the vlaue of SetVector::value_type. - -\param r -See ForSparseHes(r, s). - -\param s -See ForSparseHes(r, s). - -\param h -is the return value for the corresponging call to ForSparseJac(q, s). -*/ -template -template -void ADFun::ForSparseHesCase( - bool set_type , - const SetVector& r , - const SetVector& s , - SetVector& h ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); - size_t m = Range(); - // - // check Vector is Simple SetVector class with bool elements - CheckSimpleVector(); - // - 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." - ); - // - // select_domain corresponding to r - local::pod_vector select_domain(n); - for(size_t j = 0; j < n; ++j) - { select_domain[j] = r[j]; - CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1); - CPPAD_ASSERT_UNKNOWN( play_.GetOp(j + 1) == local::InvOp ); - } - // sparsity pattern correspnding to s - local::sparse::pack_setvec 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_ ); - // - // Not using post_element because only adding one element per set - 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) - bool dependency = false; - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - rev_jac_pattern, - not_used_rec_base - ); - // vector of sets that will hold the forward Hessain values - local::sparse::pack_setvec for_hes_pattern; - for_hes_pattern.resize(n+1+num_var_tape_, n+1); - // - // compute the Hessian sparsity patterns - local::sweep::for_hes( - &play_, - n, - num_var_tape_, - select_domain, - rev_jac_pattern, - for_hes_pattern, - not_used_rec_base - - ); - // 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_setvec::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 std::set value. -This argument is used to dispatch to the proper source -code depending on the vlaue of SetVector::value_type. - -\param r -See ForSparseHes(r, s). - -\param s -See ForSparseHes(q, s). - -\param h -is the return value for the corresponging call to ForSparseJac(q, s). -*/ -template -template -void ADFun::ForSparseHesCase( - const std::set& set_type , - const SetVector& r , - const SetVector& s , - SetVector& h ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); -# ifndef NDEBUG - size_t m = Range(); -# endif - std::set::const_iterator itr_1; - // - // check SetVector is Simple Vector class with sets for elements - CheckSimpleVector, SetVector>( - local::one_element_std_set(), local::two_element_std_set() - ); - 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." - ); - // - // select_domain corresponding to r - local::pod_vector select_domain(n); - for(size_t j = 0; j < n; ++j) - { select_domain[j] = false; - CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1); - CPPAD_ASSERT_UNKNOWN( play_.GetOp(j + 1) == local::InvOp ); - } - itr_1 = r[0].begin(); - while( itr_1 != r[0].end() ) - { size_t j = *itr_1++; - select_domain[j] = true; - } - // sparsity pattern correspnding to s - local::sparse::list_setvec 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_ ); - // - // Not using post_element because only adding one element per set - 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) - bool dependency = false; - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - rev_jac_pattern, - not_used_rec_base - ); - // - // vector of sets that will hold reverse Hessain values - local::sparse::list_setvec for_hes_pattern; - for_hes_pattern.resize(n+1+num_var_tape_, n+1); - // - // compute the Hessian sparsity patterns - local::sweep::for_hes( - &play_, - n, - num_var_tape_, - select_domain, - rev_jac_pattern, - for_hes_pattern, - not_used_rec_base - - ); - // 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_setvec::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 SetVector -is a simple vector with elements of type bool -or std::set. - -\param r -is a vector with size n that specifies the sparsity pattern -for the diagonal of the matrix \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. - -\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 x is any argument value. -*/ - -template -template -SetVector ADFun::ForSparseHes( - const SetVector& r, const SetVector& s -) -{ - SetVector h; - typedef typename SetVector::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 -void ADFun::ForSparseHesCheckpoint( - vector& r , - vector& s , - local::sparse::list_setvec& h ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - - 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 RevJac(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_setvec for_hes_pattern; - for_hes_pattern.resize(n+1+num_var_tape_, n+1); - - // compute Hessian sparsity pattern for all variables - local::sweep::for_hes( - &play_, - n, - num_var_tape_, - for_jac_sparse_set_, - RevJac.data(), - for_hes_pattern, - not_used_rec_base - - ); - - // 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_setvec::const_iterator itr(for_hes_pattern, .j + 1); - size_t i = *itr; - while( i < q ) - { if( transpose ) - h.post_element(j, i); - else - h.post_element(i, j); - i = *(++itr); - } - } - // process posts - for(size_t i = 0; i < n; ++i) - h.process_post(i); -} -# endif - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/for_sparse_jac.hpp b/build-config/cppad/include/cppad/core/for_sparse_jac.hpp deleted file mode 100644 index 991ccfa7..00000000 --- a/build-config/cppad/include/cppad/core/for_sparse_jac.hpp +++ /dev/null @@ -1,764 +0,0 @@ -# ifndef CPPAD_CORE_FOR_SPARSE_JAC_HPP -# define CPPAD_CORE_FOR_SPARSE_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$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{R}^n \rightarrow \B{R}^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$$ -(see $cref/SetVector/ForSparseJac/SetVector/$$ 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{R}^n$$, -the sparsity pattern is valid for all values of -(even if it has $cref CondExp$$ or $cref VecAD$$ operations). - -$head q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of columns in -$latex R \in \B{R}^{n \times q}$$ and the Jacobian -$latex S(x) \in \B{R}^{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 %SetVector%& %r% -%$$ -see $cref/SetVector/ForSparseJac/SetVector/$$ 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$$, -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{R}^{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$$, -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{R}^{q \times n}$$. - -$head s$$ -The return value $icode s$$ has prototype -$codei% - %SetVector% %s% -%$$ -see $cref/SetVector/ForSparseJac/SetVector/$$ 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$$, -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{R}^{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$$, -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{R}^{q \times m}$$. - -$head SetVector$$ -The type $icode SetVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$ or $code std::set$$; -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. -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 - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file core/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 bool value. This argument is used to dispatch to the proper source -code depending on the value of SetVector::value_type. - -\param transpose -See ForSparseJac(q, r, transpose, dependency). - -\param dependency -See ForSparseJac(q, r, transpose, dependency). - -\param q -See ForSparseJac(q, r, transpose, dependency). - -\param r -See ForSparseJac(q, r, transpose, dependency). - -\param s -is the return value for the corresponding call to ForSparseJac(q, r). -*/ - -template -template -void ADFun::ForSparseJacCase( - bool set_type , - bool transpose , - bool dependency , - size_t q , - const SetVector& r , - SetVector& s ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t m = Range(); - size_t n = Domain(); - - // check SetVector is Simple Vector class with bool elements - CheckSimpleVector(); - - // dimension size of result vector - s.resize( m * q ); - - 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(size_t 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(size_t j = 0; j < q; j++) if( r[ j * n + i ] ) - for_jac_sparse_pack_.post_element( ind_taddr_[i], j); - } - else - { for(size_t j = 0; j < q; j++) if( r[ i * q + j ] ) - for_jac_sparse_pack_.post_element( ind_taddr_[i], j); - } - } - // process posts - for(size_t j = 0; j < n; j++) - for_jac_sparse_pack_.process_post( ind_taddr_[j] ); - - // evaluate the sparsity patterns - local::sweep::for_jac( - &play_, - dependency, - n, - num_var_tape_, - for_jac_sparse_pack_, - not_used_rec_base - - ); - - // return values corresponding to dependent variables - CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m * q ); - for(size_t 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(size_t j = 0; j < q; j++) - s[ j * m + i ] = false; - } - else - { for(size_t j = 0; j < q; j++) - s[ i * q + j ] = false; - } - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.end() == q ); - local::sparse::pack_setvec::const_iterator - itr(for_jac_sparse_pack_, dep_taddr_[i] ); - size_t j = *itr; - while( j < q ) - { if( transpose ) - s[j * m + i] = true; - else - s[i * q + j] = true; - j = *(++itr); - } - } -} -// --------------------------------------------------------------------------- -/*! -Private helper function for ForSparseJac(q, r) set sparsity. - -All of the description in the public member function ForSparseJac(q, r) -applies. - -\param set_type -is a std::set object. -This argument is used to dispatch to the proper source -code depending on the value of SetVector::value_type. - -\param transpose -See ForSparseJac(q, r, transpose, dependency). - -\param dependency -See ForSparseJac(q, r, transpose, dependency). - -\param q -See ForSparseJac(q, r, transpose, dependency). - -\param r -See ForSparseJac(q, r, transpose, dependency). - -\param s -is the return value for the corresponding call to ForSparseJac(q, r). -*/ -template -template -void ADFun::ForSparseJacCase( - const std::set& set_type , - bool transpose , - bool dependency , - size_t q , - const SetVector& r , - SetVector& s ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t m = Range(); - size_t n = Domain(); - - // check SetVector is Simple Vector class with sets for elements - CheckSimpleVector, SetVector>( - local::one_element_std_set(), local::two_element_std_set() - ); - - // dimension size of result vector - if( transpose ) - s.resize(q); - else - s.resize( m ); - - // temporary iterator - std::set::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(size_t i = 0; i < q; i++) - { // add the elements that are present - itr_1 = r[i].begin(); - while( itr_1 != r[i].end() ) - { size_t 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_.post_element( ind_taddr_[j], i); - } - } - } - else - { for(size_t 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() ) - { size_t 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_.post_element( ind_taddr_[i], j); - } - } - } - // process posts - for(size_t j = 0; j < n; j++) - for_jac_sparse_set_.process_post( ind_taddr_[j] ); - - // evaluate the sparsity patterns - local::sweep::for_jac( - &play_, - dependency, - n, - num_var_tape_, - for_jac_sparse_set_, - not_used_rec_base - - ); - - // 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(size_t 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_setvec::const_iterator - itr_2(for_jac_sparse_set_, dep_taddr_[i] ); - size_t 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 SetVector -is a simple vector with elements of type bool -or std::set. - -\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 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 x is any argument value. -If SetVector::value_type is bool, -the return value has size \f$ m * q \f$ (\f$ q * m \f$). -where m is the number of dependent variables -corresponding to the operation sequence stored in f. -If SetVector::value_type is std::set, -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 SetVector::value_type is bool, -the forward sparsity pattern for all of the variables on the -tape is stored in 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 SetVector::value_type is std::set, -the forward sparsity pattern for all of the variables on the -tape is stored in 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 -template -SetVector ADFun::ForSparseJac( - size_t q , - const SetVector& r , - bool transpose , - bool dependency ) -{ - SetVector s; - typedef typename SetVector::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 SetVector::value_type is bool, -the forward sparsity pattern for all of the variables on the -tape is stored in 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 SetVector::value_type is std::set, -the forward sparsity pattern for all of the variables on the -tape is stored in 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 -void ADFun::ForSparseJacCheckpoint( - size_t q , - const local::sparse::list_setvec& r , - bool transpose , - bool dependency , - local::sparse::list_setvec& s ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - 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_setvec::const_iterator itr(r, i); - size_t j = *itr; - while( j < n ) - { for_jac_sparse_set_.post_element( ind_taddr_[j], i ); - j = *(++itr); - } - } - } - else - { for(size_t j = 0; j < n; j++) - { local::sparse::list_setvec::const_iterator itr(r, j); - size_t i = *itr; - while( i < q ) - { for_jac_sparse_set_.post_element( ind_taddr_[j], i ); - i = *(++itr); - } - } - } - // process posts - for(size_t j = 0; j < n; j++) - for_jac_sparse_set_.process_post( ind_taddr_[j] ); - - // evaluate the sparsity pattern for all variables - local::sweep::for_jac( - &play_, - dependency, - n, - num_var_tape_, - for_jac_sparse_set_, - not_used_rec_base - - ); - - // 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_setvec::const_iterator - itr(for_jac_sparse_set_, dep_taddr_[i] ); - size_t j = *itr; - while( j < q ) - { if( transpose ) - s.post_element(j, i); - else - s.post_element(i, j); - j = *(++itr); - } - } - // process posts - for(size_t i = 0; i < s.n_set(); ++i) - s.process_post(i); - -} - - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/for_two.hpp b/build-config/cppad/include/cppad/core/for_two.hpp deleted file mode 100644 index 677266cf..00000000 --- a/build-config/cppad/include/cppad/core/for_two.hpp +++ /dev/null @@ -1,254 +0,0 @@ -# ifndef CPPAD_CORE_FOR_TWO_HPP -# define CPPAD_CORE_FOR_TWO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin ForTwo$$ -$spell - ddy - typename - Taylor - const -$$ - - - - - -$section Forward Mode Second Partial Derivative Driver$$ - -$head Syntax$$ -$icode%ddy% = %f%.ForTwo(%x%, %j%, %k%)%$$ - - -$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$$. -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 %BaseVector% &%x% -%$$ -(see $cref/BaseVector/ForTwo/BaseVector/$$ 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 %SizeVector_t% &%j% -%$$ -(see $cref/SizeVector_t/ForTwo/SizeVector_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 %SizeVector_t% &%k% -%$$ -(see $cref/SizeVector_t/ForTwo/SizeVector_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% - %BaseVector% %ddy% -%$$ -(see $cref/BaseVector/ForTwo/BaseVector/$$ 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 BaseVector$$ -The type $icode BaseVector$$ 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 SizeVector_t$$ -The type $icode SizeVector_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 -template -BaseVector ADFun::ForTwo( - const BaseVector &x, - const SizeVector_t &j, - const SizeVector_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 BaseVector is Simple Vector class with Base type elements - CheckSimpleVector(); - - // check SizeVector_t is Simple Vector class with size_t elements - CheckSimpleVector(); - - 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 - BaseVector ddy(m * p); - - // allocate memory to hold all possible diagonal Taylor coefficients - // (for large sparse cases, this is not efficient) - BaseVector D(m * n); - - // boolean flag for which diagonal coefficients are computed - CppAD::vector c(n); - for(j1 = 0; j1 < n; j1++) - c[j1] = false; - - // direction vector in argument space - BaseVector dx(n); - for(j1 = 0; j1 < n; j1++) - dx[j1] = Base(0.0); - - // result vector in range space - BaseVector 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 diff --git a/build-config/cppad/include/cppad/core/forward/compare_change.omh b/build-config/cppad/include/cppad/core/forward/compare_change.omh deleted file mode 100644 index 42cf778d..00000000 --- a/build-config/cppad/include/cppad/core/forward/compare_change.omh +++ /dev/null @@ -1,156 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin compare_change$$ -$spell - op - const -$$ - -$section Comparison Changes Between Taping and Zero Order Forward$$ - - -$head Syntax$$ -$icode%f%.compare_change_count(%count%) -%$$ -$icode%number% = %f%.compare_change_number() -%$$ -$icode%op_index% = %f%.compare_change_op_index() - -%$$ -$bold See Also$$ -$cref FunCheck$$ - - -$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$$; i.e, -given $latex x \in \B{R}^n$$, $latex F(x)$$ is defined by -$codei% - %F%(%x%) = %f%.Forward(0, %x%) -%$$ -see $cref forward_zero$$. -If $latex x$$ is such that -all the algorithm $cref/comparison/Compare/$$ operations -have the same result as when the algorithm was taped, -The function $latex F(x)$$ and the algorithm will have the same values. -(This is a sufficient, but not necessary condition). - - - - - -$head f$$ -In the $code compare_change_number$$ and $code compare_change_op_index$$ -syntax, the object $icode f$$ has prototype -$codei% - const ADFun<%Base%> %f% -%$$ -In the $code compare_change_count$$ -syntax, the object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ - -$head count$$ -The argument $icode count$$ has prototype -$icode% - size_t %count% -%$$ -It specifies which comparison change should correspond to the -information stored in $icode f$$ during subsequent calls to -$cref forward_zero$$; i.e., -$codei% - %f%.Forward(0, %x%) -%$$ -For example, if $icode%count% == 1%$$, -the operator index corresponding to the first comparison change -will be stored. -This is the default value used if $icode count$$ is not specified. - -$subhead Speed$$ -The special case where $icode count == 0$$, should be faster because -the comparisons are not checked during -$codei% - %f%.Forward(0, %x%) -%$$ - -$head number$$ -The return value $icode number$$ has prototype -$codei% - size_t %number% -%$$ -If $icode count$$ is non-zero, -$icode number$$ is the number of -$codei%AD<%Base%>%$$ $cref/comparison/Compare/$$ operations, -corresponding to the previous call to -$codei% - %f%.Forward(0, %x%) -%$$ -that have a different result for this value of $icode x$$ -than the value used when $icode f$$ was created by taping an algorithm. -If $icode count$$ is zero, -or if no calls to $icode%f%.Forward(0, %x%)%$$ follow the previous -setting of $icode count$$, -$icode number$$ is zero. - -$subhead Discussion$$ -If $icode count$$ and $icode number$$ are non-zero, -you may want to re-tape the algorithm with the -$cref/independent variables/glossary/Tape/Independent Variable/$$ -equal to the values in $icode x$$, -so the AD operation sequence properly represents the algorithm -for this value of independent variables. -On the other hand, re-taping the AD operation sequence usually takes -significantly more time than evaluation using $cref forward_zero$$. -If the functions values have not changed (see $cref FunCheck$$) -it may not be worth re-taping a new AD operation sequence. - -$head op_index$$ -The return value $icode op_index$$ has prototype -$codei% - size_t %op_index% -%$$ -If $icode count$$ is non-zero, -$icode op_index$$ is the operator index corresponding the -$icode count$$-th comparison change during the previous call to -$codei% - %f%.Forward(0, %x%) -%$$ -If $icode count$$ is greater than the corresponding -$icode number$$, there is no such comparison change and $icode op_index$$ -will also be zero. -If $icode count$$ is zero, -if the function $icode f$$ has been $cref/optimized/optimize/$$, -or if no calls to $icode%f%.Forward(0, %x%)%$$ follow the previous -setting of $icode count$$, -$icode op_index$$ is zero. - -$subhead Purpose$$ -The operator index can be used to generate an error during the taping -process so that the corresponding algorithm can be inspected. -In some cases, it is possible to re-design this part of the -algorithm to avoid the particular comparison operation. -For example, using an $cref/conditional expression/CondExp/$$ -may be appropriate in some cases. -See $cref/abort_op_index/Independent/abort_op_index/$$ in the syntax -$codei% - Independent(%x%, %abort_op_index%) -%$$ - -$children% - example/general/compare_change.cpp -%$$ -$head Example$$ -$cref compare_change.cpp$$ -contains an example and test of this operation. - -$end diff --git a/build-config/cppad/include/cppad/core/forward/devel.omh b/build-config/cppad/include/cppad/core/forward/devel.omh deleted file mode 100644 index 3d41dcd2..00000000 --- a/build-config/cppad/include/cppad/core/forward/devel.omh +++ /dev/null @@ -1,23 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin devel_forward$$ -$spell - Devel -$$ - -$section Devel: Forward Mode$$ - -$childtable% - include/cppad/core/forward/forward.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/forward/forward.hpp b/build-config/cppad/include/cppad/core/forward/forward.hpp deleted file mode 100644 index 3becb72a..00000000 --- a/build-config/cppad/include/cppad/core/forward/forward.hpp +++ /dev/null @@ -1,490 +0,0 @@ -# ifndef CPPAD_CORE_FORWARD_FORWARD_HPP -# define CPPAD_CORE_FORWARD_FORWARD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// documened after Forward but included here so easy to see -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/* ---------------------------------------- --------------------------------------- -$begin devel_forward_order$$ -$spell - yq - xq - Taylor - num_var - PriOp - dyn_ind -$$ - -$section Multiple orders, one direction, forward mode Taylor coefficients$$ - -$head Syntax$$ -$icode%yq% = %f%.Forward(%q%, %xq%, %s% ) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_FORWARD_ORDER%// END_FORWARD_ORDER%1 -%$$ - -$head Base$$ -The type used during the forward mode computations; i.e., the corresponding -recording of operations used the type AD. - -$head BaseVector$$ -is a Simple Vector class with elements of type Base. - -$head q$$ -is the highest order for this forward mode computation; i.e., -after this calculation there will be $icode%q%+1%$$ -Taylor coefficients per variable. - -$head xq$$ -contains Taylor coefficients for the independent variables. -The size of $icode xq$$ must either be $icode n$$ or $icode (q+1)*n$$, -We define $icode p = q + 1 - xq.size()/n$$. -For $icode j = 0 , ... , n-1$$, -$icode k = 0, ... , q$$, -$icode xq[ (q+1)*j + k - p ]$$ -is the k-th order coefficient for the j-th independent variable. - -$head s$$ -Is the stream where output corresponding to PriOp operations will written. - -$head yq$$ -contains Taylor coefficients for the dependent variables. -The size of the return value $icode yq$$ -has size $icode m*(q+1-p)$$. -For $icode i = 0, ... , m-1$$, -$icode k = p, ..., q$$, -$icode yq[(q+1-p)*i + (k-p)]$$ -is the k-th order coefficient for the i-th dependent variable. - -$head taylor_$$ -The Taylor coefficients up to order $icode p-1$$ are inputs -and the coefficients from order $icode p$$ through $icode q$$ are outputs. -Let $icode N = num_var_tape_$$, and -$icode C = cap_order_taylor_$$. -Note that for -$icode i = 1 , ..., N-1$$, -$icode k = 0 , ..., q$$, -$icode taylor_[ C*i + k ]$$ -is the k-th order coefficient, -for the i-th variable on the tape. -(The first independent variable has index one on the tape -and there is no variable with index zero.) - -$end -*/ -// BEGIN_FORWARD_ORDER -template -template -BaseVector ADFun::Forward( - size_t q , - const BaseVector& xq , - std::ostream& s ) -// END_FORWARD_ORDER -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - - // temporary indices - size_t i, j, k; - - // number of independent variables - size_t n = ind_taddr_.size(); - - // number of dependent variables - size_t m = dep_taddr_.size(); - - // check Vector is Simple Vector class with Base type elements - CheckSimpleVector(); - - // check size of xq - 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)" - ); - - // p = lowest order we are computing - size_t p = q + 1 - size_t(xq.size()) / n; - CPPAD_ASSERT_UNKNOWN( p == 0 || p == q ); - - // check one order case - 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)." - ); - - // if p > 1, the previous number of directions must be one - 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::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_op2var_.size() == play_.num_var_load_rec() ); - if( q == 0 ) - { - local::sweep::forward0(&play_, s, true, - n, num_var_tape_, C, - taylor_.data(), cskip_op_.data(), load_op2var_, - compare_change_count_, - compare_change_number_, - compare_change_op_index_, - not_used_rec_base - ); - } - else - { local::sweep::forward1(&play_, s, true, p, q, - n, num_var_tape_, C, - taylor_.data(), cskip_op_.data(), load_op2var_, - compare_change_count_, - compare_change_number_, - compare_change_op_index_, - not_used_rec_base - ); - } - - // return Taylor coefficients for dependent variables - BaseVector 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 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; -} -/* ---------------------------------------- --------------------------------------- -$begin devel_forward_dir$$ -$spell - yq - xq - Taylor - num_var -$$ - -$section One order, multiple directions, forward mode Taylor coefficients$$ - -$head Syntax$$ -$icode%yq% = %f%.Forward(%q%, %r%, %xq%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_FORWARD_DIR%// END_FORWARD_DIR%1 -%$$ - -$head Base$$ -The type used during the forward mode computations; i.e., the corresponding -recording of operations used the type AD. - -$head BaseVector$$ -is a Simple Vector class with elements of type Base. - -$head q$$ -is the order for this forward mode computation, -$icode q > 0$$. -There must be at least $icode q$$ Taylor coefficients -per variable before this call. -After this call there will be $icode q+1$$ -Taylor coefficients per variable. - -$head r$$ -is the number of directions for this calculation. -If $icode q != 1$$, r must be the same as in the previous -call to Forward where q was equal to one. - -$head xq$$ -contains Taylor coefficients for the independent variables. -The size of xq must either be $icode r*n$$, -For $icode j = 0 , ... , n-1$$, -$icode ell = 0, ... , r-1$$, -$icode xq[ ( r*j + ell ]$$ -is the q-th order coefficient for the j-th independent variable -and the ell-th direction. - -$head yq$$ -contains Taylor coefficients for the dependent variables. -The size of $icode y$$ is $icode r*m$$. -For $icode i = 0, ... , m-1$$, -$icode ell = 0, ... , r-1$$, -$icode yq[ r*i + ell ]$$ -is the q-th order coefficient for the i-th dependent variable -and the ell-th direction. - -$head taylor_$$ -The Taylor coefficients up to order $icode q-1$$ are inputs -and the coefficients of order q are outputs. -Let $icode N = num_var_tape_$$, and -$icode C = cap_order_taylor_$$. -Note that for -$icode i = 1 , ..., N-1$$, -$icode taylor_[ (C-1)*r*i + i + 0 ]$$ -is the zero order coefficient, -for the i-th variable, and all directions. -For $icode i = 1 , ..., N-1$$, -$icode k = 1 , ..., q$$, -$icode ell = 0 , ..., r-1$$, -$icode taylor_[ (C-1)*r*i + i + (k-1)*r + ell + 1 ]$$ -is the k-th order coefficient, -for the i-th variable, and ell-th direction. -(The first independent variable has index one on the tape -and there is no variable with index zero.) - -$end -*/ -// BEGIN_FORWARD_DIR -template -template -BaseVector ADFun::Forward( - size_t q , - size_t r , - const BaseVector& xq ) -// END_FORWARD_DIR -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - - // 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(); - - 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_op2var_.size() == play_.num_var_load_rec() ); - local::sweep::forward2( - &play_, - q, - r, - n, - num_var_tape_, - c, - taylor_.data(), - cskip_op_.data(), - load_op2var_, - not_used_rec_base - ); - - // return Taylor coefficients for dependent variables - BaseVector 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 diff --git a/build-config/cppad/include/cppad/core/forward/forward.omh b/build-config/cppad/include/cppad/core/forward/forward.omh deleted file mode 100644 index f5a64fa3..00000000 --- a/build-config/cppad/include/cppad/core/forward/forward.omh +++ /dev/null @@ -1,28 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin Forward$$ - -$section Forward Mode$$ - -$childtable% - include/cppad/core/forward/forward_zero.omh% - include/cppad/core/forward/forward_one.omh% - include/cppad/core/forward/forward_two.omh% - include/cppad/core/forward/forward_order.omh% - include/cppad/core/forward/forward_dir.omh% - include/cppad/core/forward/size_order.omh% - include/cppad/core/forward/compare_change.omh% - include/cppad/core/capacity_order.hpp% - include/cppad/core/num_skip.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/forward/forward_dir.omh b/build-config/cppad/include/cppad/core/forward/forward_dir.omh deleted file mode 100644 index c76c4f1a..00000000 --- a/build-config/cppad/include/cppad/core/forward/forward_dir.omh +++ /dev/null @@ -1,206 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin forward_dir$$ -$spell - Taylor - const - dir - cpp - yq - xq - xk - std::cout - ostream -$$ - -$section Multiple Directions Forward Mode$$ - - -$head Syntax$$ -$icode%yq% = %f%.Forward(%q%, %r%, %xq%) -%$$ - -$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$$. -Given a function $latex X : \B{R} \rightarrow \B{R}^n$$, -defined by its -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$, -forward mode computes the Taylor coefficients for the function -$latex \[ - Y (t) = F [ X(t) ] -\]$$ -This version of forward mode computes multiple directions as the same -time (reducing the number of passes through the tape). This requires more -memory, but might be faster in some cases. - -$head Reverse Mode$$ -Reverse mode for multiple directions has not yet been implemented. -If you have speed tests that indicate that multiple direction forward -mode is faster, and you want to try multiple direction reverse mode, -contact the CppAD project manager. - -$head Notation$$ - -$subhead n$$ -We use $icode n$$ to denote the dimension of the -$cref/domain/seq_property/Domain/$$ space for $icode f$$. - -$subhead m$$ -We use $icode m$$ to denote the dimension of the -$cref/range/seq_property/Range/$$ space for $icode f$$. - -$head f$$ -The $cref ADFun$$ object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$. -After this call we will have -$codei% - %f%.size_order() == %q% + 1 - %f%.size_direction() == %r% -%$$ - -$head q$$ -This argument has prototype -$codei% - size_t %q% -%$$ -It specifies the order of Taylor Coefficient that we are calculating -and must be greater than zero. -The zero order coefficients can only have one direction computed -and stored in $icode f$$ so use $cref forward_zero$$ -to compute the zero order coefficients. - -$head r$$ -This argument has prototype -$codei% - size_t %r% -%$$ -It specifies the number of directions that are computed together. -If ($icode%r% == 1%$$), you are only using one direction and -$cref forward_order$$ is simpler, and should be faster, -than this more general case. - -$head xq$$ -The argument $icode xq$$ has prototype -$codei% - const %Vector%& %xq% -%$$ -and its size must be $icode%n%*%r%$$ -(see $cref/Vector/forward_dir/Vector/$$ below). -For $latex \ell = 0 , \ldots , r-1$$, -$latex j = 0 , \ldots , n-1$$, -the $th j$$ component of the $th q$$ order Taylor coefficient -for $latex X_\ell (t)$$ is defined by -$pre - $$ $latex x_j^{(q),\ell} = $$ $icode%xq%[ %r% * %j% + %ell% ]%$$ - -$head Zero Order$$ -For $latex j = 0 , \ldots , n-1$$, -the $th j$$ component of the zero order Taylor coefficient -for $latex X_\ell (t)$$ is defined by -$pre - $$ $latex x_j^{(0)} = $$ $icode%xk%[ %j% ]%$$ -where $icode xk$$ corresponds to the previous call -$codei% - %f%.Forward(%k%, %xk%) -%$$ -with $icode%k% = 0%$$. - -$head Non-Zero Lower Orders$$ -For $latex \ell = 0 , \ldots , r-1$$, -$latex j = 0 , \ldots , n-1$$, -$latex k = 1, \ldots , q-1$$, -the $th j$$ component of the $th k$$ order Taylor coefficient -for $latex X_\ell (t)$$ is defined by -$pre - $$ $latex x_j^{(k),\ell} = $$ $icode%xk%[ %r% * %j% + %ell% ]%$$ -where $icode xk$$ corresponds to the previous call -$codei% - %f%.Forward(%k%, %r%, %xk%) -%$$ -Note that $icode r$$ must have the same value in this previous call. - -$head X(t)$$ -For $latex \ell = 0 , \ldots , r-1$$, the function -$latex X_\ell : \B{R} \rightarrow \B{R}^n$$ is defined using -the Taylor coefficients $latex x^{(k),\ell} \in \B{R}^n$$: -$latex \[ -X_\ell (t) = x^{(0)} + x^{(1),\ell} * t^1 + \cdots + x^{(q),\ell} t^q -\] $$ -Note that the $th k$$ derivative of $latex X_\ell (t)$$ is related to -its Taylor coefficients by -$latex \[ -\begin{array}{rcl} - x^{(0)} & = & X_\ell (0) - \\ - x^{(k), \ell} & = & \frac{1}{k !} X_\ell^{(k)} (0) -\end{array} -\] $$ -for $latex k = 1 , \ldots , q$$. - -$head Y(t)$$ -For $latex \ell = 0 , \ldots , r-1$$, the function -$latex Y_\ell : \B{R} \rightarrow \B{R}^m$$ is defined by -$latex Y_\ell (t) = F[ X_\ell (t) ] $$. -We use $latex y^{(0)}$$ for the zero order coefficient -and $latex y^{(k),\ell} \in \B{R}^m$$ to denote the -hight order coefficients; i.e., -$latex \[ -Y_\ell (t) = y^{(0)} + y^{(1),\ell} * t^1 + \cdots + y^{(q),\ell} * t^q -+ o( t^q ) -\] $$ -where $latex o( t^q ) * t^{-q} \rightarrow 0$$ as $latex t \rightarrow 0$$. -Note that the $th k$$ derivative of $latex Y_\ell (t)$$ is related to -its Taylor coefficients by -$latex \[ -\begin{array}{rcl} - y^{(0)} & = & Y_\ell (0) - \\ - y^{(k), \ell} & = & \frac{1}{k !} Y_\ell^{(k)} (0) -\end{array} -\] $$ -for $latex k = 1 , \ldots , q$$. - -$head yq$$ -The argument $icode yq$$ has prototype -$codei% - %Vector% %yq% -%$$ -and its size is $icode%m%*%r%$$ -(see $cref/Vector/forward_dir/Vector/$$ below). -For $latex \ell = 0 , \ldots , r-1$$, -$latex i = 0 , \ldots , m-1$$, -the $th i$$ component of the $th q$$ order Taylor coefficient -for $latex Y_\ell (t)$$ is given by -$pre - $$ $latex y_i^{(q),\ell} = $$ $icode%yq%[ %r% * %i% + %ell% ]%$$ - -$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. - -$children% - example/general/forward_dir.cpp -%$$ -$head Example$$ -The file -$cref forward_dir.cpp$$ -contains an example and test using one order (multiple orders). -They return true if they succeed and false otherwise. - -$end diff --git a/build-config/cppad/include/cppad/core/forward/forward_one.omh b/build-config/cppad/include/cppad/core/forward/forward_one.omh deleted file mode 100644 index 1be1c550..00000000 --- a/build-config/cppad/include/cppad/core/forward/forward_one.omh +++ /dev/null @@ -1,111 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin forward_one$$ -$spell - Jacobian - Taylor - const -$$ - -$section First Order Forward Mode: Derivative Values$$ - - -$head Syntax$$ -$icode%y1% = %f%.Forward(1, %x1%)%$$ - -$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$$. -The result of the syntax above is -$latex \[ - y1 = F^{(1)} (x0) * x1 -\] $$ -where $latex F^{(1)} (x0)$$ is the Jacobian of $latex F$$ -evaluated at $icode x0$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$. -Before this call to $code Forward$$, the value returned by -$codei% - %f%.size_order() -%$$ -must be greater than or equal one. -After this call it will be will be two (see $cref size_order$$). - -$head x0$$ -The vector $icode x0$$ in the formula -$latex \[ - y1 = F^{(1)} (x0) * x1 -\] $$ -corresponds to the previous call to $cref forward_zero$$ -using this ADFun object $icode f$$; i.e., -$codei% - %f%.Forward(0, %x0%) -%$$ -If there is no previous call with the first argument zero, -the value of the $cref/independent/Independent/$$ variables -during the recording of the AD sequence of operations is used -for $icode x0$$. - -$head x1$$ -The argument $icode x1$$ has prototype -$codei% - const %Vector%& %x1% -%$$ -(see $cref/Vector/forward_one/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 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 Example$$ -The file -$cref forward.cpp$$ -contains an example and test of this operation. - -$head Special Case$$ -This is special case of $cref forward_order$$ where -$latex \[ -\begin{array}{rcl} -Y(t) & = & F[ X(t) ] -\\ -X(t) & = & x^{(0)} t^0 + x^{(1)} * t^1 + \cdots, + x^{(q)} * t^q + o( t^q ) -\\ -Y(t) & = & y^{(0)} t^0 + y^{(1)} * t^1 + \cdots, + y^{(q)} * t^q + o( t^q ) -\end{array} -\] $$ -and $latex o( t^q ) * t^{-q} \rightarrow 0$$ as $latex t \rightarrow 0$$. -For this special case, $latex q = 1$$, -$latex x^{(0)}$$ $codei%= %x0%$$, -$latex x^{(1)}$$ $codei%= %x1%$$, -$latex X(t) = x^{(0)} + x^{(1)} t$$, and -$latex \[ - y^{(0)} + y^{(1)} t = F [ x^{(0)} + x^{(1)} t ] + o(t) -\] $$ -Taking the derivative with respect to $latex t$$, at $latex t = 0$$, -we obtain -$latex \[ - y^{(1)} = F^{(1)} [ x^{(0)} ] x^{(1)} -\] $$ -which agrees with the specifications for -$icode y1$$ in the $cref/purpose/forward_one/Purpose/$$ above. - -$end diff --git a/build-config/cppad/include/cppad/core/forward/forward_order.omh b/build-config/cppad/include/cppad/core/forward/forward_order.omh deleted file mode 100644 index 07e29700..00000000 --- a/build-config/cppad/include/cppad/core/forward/forward_order.omh +++ /dev/null @@ -1,243 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin forward_order$$ -$spell - std::cout - ostream - xk - xp - yp - Ind - vp - uj - Taylor - const - xq - yq -$$ - -$section Multiple Order Forward Mode$$ - - -$head Syntax$$ -$icode%yq% = %f%.Forward(%q%, %xq% ) -%$$ -$icode%yq% = %f%.Forward(%q%, %xq%, %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$$. -Given a function $latex X : \B{R} \rightarrow \B{R}^n$$, -defined by its -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$, -forward mode computes the Taylor coefficients for the function -$latex \[ - Y (t) = F [ X(t) ] -\]$$ - -$subhead Function Values$$ -If you are using forward mode to compute values for $latex F(x)$$, -$cref forward_zero$$ is simpler to understand -than this explanation of the general case. - -$subhead Derivative Values$$ -If you are using forward mode to compute values for $latex F^{(1)} (x) * dx$$, -$cref forward_one$$ is simpler to understand -than this explanation of the general case. - -$head Notation$$ - -$subhead n$$ -We use $icode n$$ to denote the dimension of the -$cref/domain/seq_property/Domain/$$ space for $icode f$$. - -$subhead m$$ -We use $icode m$$ to denote the dimension of the -$cref/range/seq_property/Range/$$ space for $icode f$$. - -$head f$$ -The $cref ADFun$$ object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$. -After this call we will have -$codei% - %f%.size_order() == %q% + 1 - %f%.size_direction() == 1 -%$$ - -$head One Order$$ -If $icode%xq%.size() == %n%$$, -then we are only computing one order. -In this case, before this call we must have -$codei% - %f%.size_order() >= %q% - %f%.size_direction() == 1 -%$$ - - -$head q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -and specifies the highest order of the Taylor coefficients to be calculated. - -$head xq$$ -The argument $icode xq$$ has prototype -$codei% - const %BaseVector%& %xq% -%$$ -(see $cref/BaseVector/forward_order/BaseVector/$$ below). -As above, we use $icode n$$ to denote the dimension of the -$cref/domain/seq_property/Domain/$$ space for $icode f$$. -The size of $icode xq$$ must be either $icode n$$ or -$icode%n%*(%q%+1)%$$. -After this call we will have -$codei% - %f%.size_order() == %q% + 1 -%$$ - -$subhead One Order$$ -If $icode%xq%.size() == %n%$$, -the $th q$$ order Taylor coefficient for $latex X(t)$$ -is defined by -$pre - $$ $latex x^{(q)} = $$ $icode xq$$. -For $latex k = 0 , \ldots , q-1$$, -the Taylor coefficient $latex x^{(k)}$$ -is defined by $icode xk$$ in the previous call to -$codei% - %f%.Forward(%k%, %xk%) -%$$ - -$subhead Multiple Orders$$ -If $icode%xq%.size() == %n%*(%q%+1)%$$, -For $latex k = 0 , \ldots , q$$, -$latex j = 0 , \ldots , n-1$$, -the $th j$$ component of the $th k$$ order Taylor coefficient -for $latex X(t)$$ is defined by -$pre - $$ $latex x_j^{(k)} = $$ $icode%xq%[ (%q%+1) * %j% + %k% ]%$$ - -$subhead Restrictions$$ -Note if $icode f$$ uses $cref atomic_one$$ functions, -the size of $icode xq$$ must be $icode n$$. - -$head s$$ -If the argument $icode s$$ is not present, $code std::cout$$ -is used in its place. -Otherwise, this argument has prototype -$codei% - std::ostream& %s% -%$$ -If order zero is begin calculated, -$icode s$$ specifies where the output corresponding to $cref PrintFor$$ -will be written. -If order zero is not being calculated, -$icode s$$ is not used - -$head X(t)$$ -The function -$latex X : \B{R} \rightarrow \B{R}^n$$ is defined using -the Taylor coefficients $latex x^{(k)} \in \B{R}^n$$: -$latex \[ - X(t) = x^{(0)} * t^0 + x^{(1)} * t^1 + \cdots + x^{(q)} * t^q -\] $$ -Note that for $latex k = 0 , \ldots , q$$, -the $th k$$ derivative of $latex X(t)$$ is related to the -Taylor coefficients by the equation -$latex \[ - x^{(k)} = \frac{1}{k !} X^{(k)} (0) -\] $$ - -$head Y(t)$$ -The function -$latex Y : \B{R} \rightarrow \B{R}^m$$ is defined by -$latex Y(t) = F[ X(t) ] $$. -We use $latex y^{(k)} \in \B{R}^m$$ -to denote the $th k$$ order Taylor coefficient of $latex Y(t)$$; i.e., -$latex \[ - Y(t) = y^{(0)} * t^0 + y^{(1)} * t^1 + \cdots + y^{(q)} * t^q + o( t^q ) -\] $$ -where $latex o( t^q ) * t^{-q} \rightarrow 0$$ as $latex t \rightarrow 0$$. -Note that $latex y^{(k)}$$ is related to -the $th k$$ derivative of $latex Y(t)$$ by the equation -$latex \[ - y^{(k)} = \frac{1}{k !} Y^{(k)} (0) -\] $$ - -$head yq$$ -The return value $icode yq$$ has prototype -$codei% - %BaseVector% %yq% -%$$ -(see $cref/BaseVector/forward_order/BaseVector/$$ below). - -$subhead One Order$$ -If $icode%xq%.size() == %n%$$, -the vector $icode yq$$ has size $icode m$$. -The $th q$$ order Taylor coefficient for $latex Y(t)$$ -is returned as -$codei% - %yq%$$ $latex = y^{(q)}$$. - -$subhead Multiple Orders$$ -If $icode%xq%.size() == %n%*(%q%+1)%$$, -the vector $icode yq$$ has size $icode%m%*(%q%+1)%$$. -For $latex k = 0 , \ldots , q$$, -for $latex i = 0 , \ldots , m-1$$, -the $th i$$ component of the $th k$$ order Taylor coefficient -for $latex Y(t)$$ is returned as -$codei% - %yq%[ (%q%+1) * %i% + %k% ]%$$ $latex = y_i^{(k)}$$ - -$head BaseVector$$ -The type $icode BaseVector$$ 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 Zero Order$$ -The case where -$latex q = 0$$ and $icode%xq%.size() == %n%$$, -corresponds to the zero order -$cref/special case/forward_zero/Special Case/$$. - -$head First Order$$ -The case where -$latex q = 1$$ and $icode%xq%.size() == %n%$$, -corresponds to the first order -$cref/special case/forward_one/Special Case/$$. - -$head Second Order$$ -The case where -$latex q = 2$$ and $icode%xq%.size() == %n%$$, -corresponds to the second order -$cref/special case/forward_two/Special Case/$$. - -$children% - example/general/forward.cpp% - example/general/forward_order.cpp -%$$ -$head Example$$ -The files -$cref forward.cpp$$ and $cref forward_order.cpp$$ -contain examples and tests of using forward mode with -one order and multiple orders respectively. -They return true if they succeed and false otherwise. - -$end diff --git a/build-config/cppad/include/cppad/core/forward/forward_two.omh b/build-config/cppad/include/cppad/core/forward/forward_two.omh deleted file mode 100644 index 782aa864..00000000 --- a/build-config/cppad/include/cppad/core/forward/forward_two.omh +++ /dev/null @@ -1,148 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin forward_two$$ -$spell - Jacobian - Taylor - const -$$ - -$section Second Order Forward Mode: Derivative Values$$ - - - -$head Syntax$$ -$icode%y2% = %f%.Forward(1, %x2%)%$$ - -$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$$. -The result of the syntax above is that for -$icode%i% = 0 , %...% , %m%-1%$$, -$codei% - %y2%[%i%]%$$ - $latex = F_i^{(1)} (x0) * x2 + \frac{1}{2} x1^T * F_i^{(2)} (x0) * x1$$ -$pre -$$ -where -$latex F^{(1)} (x0)$$ is the Jacobian of $latex F$$, and -$latex F_i^{(2)} (x0)$$ is the Hessian of th $th i$$ component of $latex F$$, -evaluated at $icode x0$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$. -Before this call to $code Forward$$, the value returned by -$codei% - %f%.size_order() -%$$ -must be greater than or equal two. -After this call it will be will be three (see $cref size_order$$). - -$head x0$$ -The vector $icode x0$$ in the formula for $icode%y2%[%i%]%$$ -corresponds to the previous call to $cref forward_zero$$ -using this ADFun object $icode f$$; i.e., -$codei% - %f%.Forward(0, %x0%) -%$$ -If there is no previous call with the first argument zero, -the value of the $cref/independent/Independent/$$ variables -during the recording of the AD sequence of operations is used -for $icode x0$$. - -$head x1$$ -The vector $icode x1$$ in the formula for $icode%y2%[%i%]%$$ -corresponds to the previous call to $cref forward_one$$ -using this ADFun object $icode f$$; i.e., -$codei% - %f%.Forward(1, %x1%) -%$$ - -$head x2$$ -The argument $icode x2$$ has prototype -$codei% - const %Vector%& %x2% -%$$ -(see $cref/Vector/forward_two/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 y2$$ -The result $icode y2$$ has prototype -$codei% - %Vector% %y2% -%$$ -(see $cref/Vector/forward_two/Vector/$$ below) -The size of $icode y1$$ is equal to $icode m$$, the dimension of the -$cref/range/seq_property/Range/$$ space for $icode f$$. -Its value is given element-wise by the formula in the -$cref/purpose/forward_two/Purpose/$$ above. - -$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 Example$$ -The file -$cref forward.cpp$$ -contains an example and test of this operation. - -$head Special Case$$ -This is special case of $cref forward_order$$ where -$latex \[ -\begin{array}{rcl} -Y(t) & = F[ X(t) ] -\\ -X(t) & = & x^{(0)} t^0 + x^{(1)} * t^1 + \cdots, + x^{(q)} * t^q + o( t^q ) -\\ -Y(t) & = & y^{(0)} t^0 + y^{(1)} * t^1 + \cdots, + y^{(q)} * t^q + o( t^q ) -\end{array} -\] $$ -and $latex o( t^q ) * t^{-q} \rightarrow 0$$ as $latex t \rightarrow 0$$. -For this special case, $latex q = 2$$, -$latex x^{(0)}$$ $codei%= %x0%$$, -$latex x^{(1)}$$ $codei%= %x1%$$, -$latex X(t) = x^{(0)} + x^{(1)} t + x^{(2)} t^2$$, and -$latex \[ -y^{(0)} + y^{(1)} t + y^{(2)} t^2 -= -F [ x^{(0)} + x^{(1)} t + x^{(2)} t^2 ] + o(t^2) -\] $$ -Restricting our attention to the $th i$$ component, and -taking the derivative with respect to $latex t$$, we obtain -$latex \[ -y_i^{(1)} + 2 y_i^{(2)} t -= -F_i^{(1)} [ x^{(0)} + x^{(1)} t + x^{(2)} t^2 ] [ x^{(1)} + 2 x^{(2)} t ] -+ -o(t) -\] $$ -Taking a second derivative with respect to $latex t$$, -and evaluating at $latex t = 0$$, we obtain -$latex \[ -2 y_i^{(2)} -= -[ x^{(1)} ]^T F_i^{(2)} [ x^{(0)} ] x^{(1)} -+ -F_i^{(1)} [ x^{(0)} ] 2 x^{(2)} -\] $$ -which agrees with the specification for $icode%y2%[%i%]%$$ in the -$cref/purpose/forward_two/Purpose/$$ above. - -$end diff --git a/build-config/cppad/include/cppad/core/forward/forward_zero.omh b/build-config/cppad/include/cppad/core/forward/forward_zero.omh deleted file mode 100644 index 8b3dc64c..00000000 --- a/build-config/cppad/include/cppad/core/forward/forward_zero.omh +++ /dev/null @@ -1,116 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin forward_zero$$ -$spell - std::cout - ostream - const - Taylor - dy - Jacobian -$$ - -$section Zero Order Forward Mode: Function Values$$ - -$head Syntax$$ -$icode%y0% = %f%.Forward(0, %x0%) -%$$ -$icode%y0% = %f%.Forward(0, %x0%, %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$$. -The result of the syntax above is -$latex \[ - y0 = F(x0) -\] $$ -See the $cref/FunCheck discussion/FunCheck/Discussion/$$ for -possible differences between $latex F(x)$$ and the algorithm that defined -the operation sequence. - -$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 this call to $code Forward$$, the value returned by -$codei% - %f%.size_order() -%$$ -will be equal to one (see $cref size_order$$). - -$head x0$$ -The argument $icode x0$$ has prototype -$codei% - const %Vector%& %x0% -%$$ -(see $cref/Vector/forward_zero/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 s$$ -If the argument $icode s$$ is not present, $code std::cout$$ -is used in its place. -Otherwise, this argument has prototype -$codei% - std::ostream& %s% -%$$ -It specifies where the output corresponding to $cref PrintFor$$, -and this zero order forward mode call, will be written. - -$head y0$$ -The result $icode y0$$ has prototype -$codei% - %Vector% %y0% -%$$ -(see $cref/Vector/forward_zero/Vector/$$ below) -and its value is $latex F(x)$$ at $icode%x% = %x0%$$. -The size of $icode y0$$ is equal to $icode m$$, the dimension of the -$cref/range/seq_property/Range/$$ space for $icode f$$. - -$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 Example$$ -The file -$cref forward.cpp$$ -contains an example and test of this operation. - -$head Special Case$$ -This is special case of $cref forward_order$$ where -$latex \[ -\begin{array}{rcl} -Y(t) & = & F[ X(t) ] -\\ -X(t) & = & x^{(0)} t^0 + x^{(1)} * t^1 + \cdots, + x^{(q)} * t^q + o( t^q ) -\\ -Y(t) & = & y^{(0)} t^0 + y^{(1)} * t^1 + \cdots, + y^{(q)} * t^q + o( t^q ) -\end{array} -\] $$ -and $latex o( t^q ) * t^{-q} \rightarrow 0$$ as $latex t \rightarrow 0$$. -For this special case, $latex q = 0$$, -$latex x^{(0)}$$ $codei%= %x0%$$, -$latex X(t) = x^{(0)}$$, and -$latex \[ - y^{(0)} = Y(t) = F[ X(t) ] = F( x^{(0)} ) -\] $$ -which agrees with the specifications for -$icode y0$$ in the $cref/purpose/forward_zero/Purpose/$$ above. - - - -$end diff --git a/build-config/cppad/include/cppad/core/forward/size_order.omh b/build-config/cppad/include/cppad/core/forward/size_order.omh deleted file mode 100644 index 29d5480e..00000000 --- a/build-config/cppad/include/cppad/core/forward/size_order.omh +++ /dev/null @@ -1,97 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin size_order$$ -$spell - var - Taylor - const -$$ - -$section Number Taylor Coefficient Orders Currently Stored$$ - -$head Syntax$$ -$icode%s% = %f%.size_order()%$$ - -$subhead See Also$$ -$cref seq_property$$ - -$head Purpose$$ -Determine the number of Taylor coefficient orders, per variable,direction, -currently calculated and stored in the ADFun object $icode f$$. -See the discussion under -$cref/Constructor/size_order/Constructor/$$, -$cref/Forward/size_order/Forward/$$, and -$cref/capacity_order/size_order/capacity_order/$$ -for a description of when this value can change. - - -$head f$$ -The object $icode f$$ has prototype -$codei% - const ADFun<%Base%> %f% -%$$ - -$head s$$ -The result $icode s$$ has prototype -$codei% - size_t %s% -%$$ -and is the number of Taylor coefficient orders, -per variable,direction in the AD operation sequence, -currently calculated and stored in the ADFun object $icode f$$. - -$head Constructor$$ -Directly after the $cref FunConstruct$$ syntax -$codei% - ADFun<%Base%> %f%(%x%, %y%) -%$$ -the value of $icode s$$ returned by $code size_order$$ is one. -This is because -there is an implicit call to $code Forward$$ that computes -the zero order Taylor coefficients during this constructor. - -$head Forward$$ -After a call to $cref/Forward/forward_order/$$ with the syntax -$codei% - %f%.Forward(%q%, %x_q%) -%$$ -the value of $icode s$$ returned by $code size_order$$ -would be $latex q + 1$$. -The call to $code Forward$$ above -uses the lower order Taylor coefficients to compute and store -the $th q$$ order Taylor coefficients for all -the variables in the operation sequence corresponding to $icode f$$. -Thus there are $latex q + 1$$ (order zero through $icode q$$) -Taylor coefficients per variable,direction. -(You can determine the number of variables in the operation sequence -using the $cref/size_var/seq_property/size_var/$$ function.) - -$head capacity_order$$ -If the number of Taylor coefficient orders -currently stored in $icode f$$ is less than or equal $icode c$$, -a call to $cref capacity_order$$ with the syntax -$codei% - %f%.capacity_order(%c%) -%$$ -does not affect the value $icode s$$ returned by $code size_order$$. -Otherwise, -the value $icode s$$ returned by $code size_order$$ -is equal to $icode c$$ -(only Taylor coefficients of order zero through $latex c-1$$ -have been retained). - -$head Example$$ -The file -$cref forward.cpp$$ -contains an example and test of this operation. - -$end diff --git a/build-config/cppad/include/cppad/core/fun_check.hpp b/build-config/cppad/include/cppad/core/fun_check.hpp deleted file mode 100644 index ebf60d8a..00000000 --- a/build-config/cppad/include/cppad/core/fun_check.hpp +++ /dev/null @@ -1,210 +0,0 @@ -# ifndef CPPAD_CORE_FUN_CHECK_HPP -# define CPPAD_CORE_FUN_CHECK_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$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{R}^n \rightarrow \B{R}^m$$ to denote the -$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$. -We use $latex G : \B{R}^n \rightarrow \B{R}^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%$$ 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. - -$end ---------------------------------------------------------------------------- -*/ - -namespace CppAD { - template - bool FunCheck( - ADFun &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 diff --git a/build-config/cppad/include/cppad/core/fun_construct.hpp b/build-config/cppad/include/cppad/core/fun_construct.hpp deleted file mode 100644 index 0ffd988b..00000000 --- a/build-config/cppad/include/cppad/core/fun_construct.hpp +++ /dev/null @@ -1,542 +0,0 @@ -# ifndef CPPAD_CORE_FUN_CONSTRUCT_HPP -# define CPPAD_CORE_FUN_CONSTRUCT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin FunConstruct$$ -$spell - alloc - num - Jac - bool - taylor - var - ADvector - const - Jacobian -$$ - -$spell -$$ - -$section Construct an ADFun Object and Stop Recording$$ - - -$head Syntax$$ -$codei%ADFun<%Base%> %f%(%x%, %y%); -%$$ -$codei%ADFun<%Base%> %f% -%$$ -$icode%f%.swap(%g%) -%$$ -$icode%f% = %g -%$$ - -$head Purpose$$ -The $codei%ADFun<%Base%>%$$ object $icode f$$ -stores 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{R}^n \rightarrow \B{R}^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 %ADVector% &%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 %ADVector% &%y% -%$$ -The sequence of operations that map $icode x$$ -to $icode y$$ are stored in the ADFun object $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 Default Constructor$$ -The default constructor -$codei% - ADFun<%Base%> %g% -%$$ -creates an -$codei%AD<%Base%>%$$ object with no corresponding operation sequence; i.e., -$codei% - %g%.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 swap$$ -The swap operation $code%f%.swap(%g%)%$$ exchanges the contents of -the two $codei%ADFun<%Base%>%$$ functions; i.e., -$icode f$$ ($icode g$$) before the swap is identical to -$icode g$$ ($icode f$$) after the swap. - -$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 Move Semantics$$ -In the special case where $icode f$$ is a temporary object -(and enough C++11 features are supported by the compiler) -this assignment will use move semantics. -This avoids the overhead of the copying all the information from -$icode f$$ to $icode g$$. - -$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. - -$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. - -$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 f -\endverbatim -An empty ADFun object is created. -The Dependent member function, -or the ADFun 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 AD. -*/ -template -ADFun::ADFun(void) : -function_name_(""), -exceed_collision_limit_(false), -has_been_optimized_(false), -check_for_nan_(true) , -compare_change_count_(0), -compare_change_number_(0), -compare_change_op_index_(0), -num_order_taylor_(0), -cap_order_taylor_(0), -num_direction_taylor_(0), -num_var_tape_(0) -{ } -// -// move semantics version of constructor -// (none of the defualt constructor values matter to the destructor) -template -ADFun::ADFun(ADFun&& f) -{ swap(f); } -// -// destructor -template -ADFun::~ADFun(void) -{ } -/*! -ADFun assignment operator - -The C++ syntax for this operation is -\verbatim - g = f -\endverbatim -where g and f are ADFun ADFun objects. -A copy of the the operation sequence currently stored in f -is placed in this ADFun object (called 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 AD. - -\param f -ADFun object containing the operation sequence to be copied. -*/ -template -void ADFun::operator=(const ADFun& f) -{ - // go through member variables in ad_fun.hpp order - // - // string objects - function_name_ = f.function_name_; - // - // bool objects - exceed_collision_limit_ = f.exceed_collision_limit_; - has_been_optimized_ = f.has_been_optimized_; - check_for_nan_ = f.check_for_nan_; - // - // size_t objects - 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_; - // - // pod_vector objects - ind_taddr_ = f.ind_taddr_; - dep_taddr_ = f.dep_taddr_; - dep_parameter_ = f.dep_parameter_; - cskip_op_ = f.cskip_op_; - load_op2var_ = f.load_op2var_; - // - // pod_vector_maybe_vectors - taylor_ = f.taylor_; - subgraph_partial_ = f.subgraph_partial_; - // - // player - play_ = f.play_; - // - // subgraph - subgraph_info_ = f.subgraph_info_; - // - // sparse_pack - for_jac_sparse_pack_ = f.for_jac_sparse_pack_; - // - // sparse_list - for_jac_sparse_set_ = f.for_jac_sparse_set_; -} -/// swap -template -void ADFun::swap(ADFun& f) -{ - // string objects - function_name_.swap( f.function_name_ ); - // - // bool objects - std::swap( exceed_collision_limit_ , f.exceed_collision_limit_); - std::swap( has_been_optimized_ , f.has_been_optimized_); - std::swap( check_for_nan_ , f.check_for_nan_); - // - // size_t objects - std::swap( compare_change_count_ , f.compare_change_count_); - std::swap( compare_change_number_ , f.compare_change_number_); - std::swap( compare_change_op_index_ , f.compare_change_op_index_); - std::swap( num_order_taylor_ , f.num_order_taylor_); - std::swap( cap_order_taylor_ , f.cap_order_taylor_); - std::swap( num_direction_taylor_ , f.num_direction_taylor_); - std::swap( num_var_tape_ , f.num_var_tape_); - // - // pod_vector objects - ind_taddr_.swap( f.ind_taddr_); - dep_taddr_.swap( f.dep_taddr_); - dep_parameter_.swap( f.dep_parameter_); - taylor_.swap( f.taylor_); - cskip_op_.swap( f.cskip_op_); - load_op2var_.swap( f.load_op2var_); - // - // player - play_.swap(f.play_); - // - // subgraph_info - subgraph_info_.swap(f.subgraph_info_); - // - // sparse_pack - for_jac_sparse_pack_.swap( f.for_jac_sparse_pack_); - // - // sparse_list - for_jac_sparse_set_.swap( f.for_jac_sparse_set_); -} -/// Move semantics version of constructor and assignment -template -void ADFun::operator=(ADFun&& f) -{ swap(f); } - - -/*! -ADFun constructor from an operation sequence. - -The C++ syntax for this operation is -\verbatim - ADFun f(x, y) -\endverbatim -The operation sequence that started with the previous call - Independent(x), and that ends with this operation, is stored -in this ADFun object f. - -\tparam Base -is the base for the recording that will be stored in the object f; -i.e., the operations were recorded using the type AD. - -\tparam ADVector -is a simple vector class with elements of typea AD. - -\param x -is the independent variable vector for this ADFun object. -The domain dimension of this object will be the size of x. - -\param y -is the dependent variable vector for this ADFun object. -The range dimension of this object will be the size of 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 y. -Thus, the zero order Taylor coefficients -corresponding to the value of the x vector -are stored in this ADFun object. -*/ -template -template -ADFun::ADFun(const ADVector &x, const ADVector &y) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - - CPPAD_ASSERT_KNOWN( - x.size() > 0, - "ADFun: independent variable vector has size zero." - ); - CPPAD_ASSERT_KNOWN( - Variable(x[0]), - "ADFun: independent variable vector has been changed." - ); - local::ADTape* tape = AD::tape_ptr(x[0].tape_id_); - CPPAD_ASSERT_KNOWN( - tape->size_independent_ == size_t ( x.size() ), - "ADFun: 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: independent variable vector has been changed." - ); - CPPAD_ASSERT_KNOWN( - x[j].tape_id_ == x[0].tape_id_, - "ADFun: 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: dependent vector contains variables for" - "\na different tape than the independent variables." - ); - } -# endif - - // stop the tape and store the operation sequence - Dependent(tape, y); - - // This function has not yet been optimized - exceed_collision_limit_ = false; - - // 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_op2var_.size() == play_.num_var_load_rec() ); - local::sweep::forward0(&play_, std::cout, false, - n, num_var_tape_, cap_order_taylor_, taylor_.data(), - cskip_op_.data(), load_op2var_, - compare_change_count_, - compare_change_number_, - compare_change_op_index_, - not_used_rec_base - ); - 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 diff --git a/build-config/cppad/include/cppad/core/fun_eval.hpp b/build-config/cppad/include/cppad/core/fun_eval.hpp deleted file mode 100644 index 3a67efa5..00000000 --- a/build-config/cppad/include/cppad/core/fun_eval.hpp +++ /dev/null @@ -1,20 +0,0 @@ -# ifndef CPPAD_CORE_FUN_EVAL_HPP -# define CPPAD_CORE_FUN_EVAL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/graph/cpp_ad_graph.omh b/build-config/cppad/include/cppad/core/graph/cpp_ad_graph.omh deleted file mode 100644 index b9f83878..00000000 --- a/build-config/cppad/include/cppad/core/graph/cpp_ad_graph.omh +++ /dev/null @@ -1,227 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin cpp_ad_graph$$ -$spell - std - arg - asinh - acosh - atanh - erf - erfc - expm - ind - vec - np - nx - nc - op - struct - enum - cpp - Heaviside -$$ - -$section C++ Representation of an AD Graph$$ - -$head See Also$$ -$tref json_ad_graph$$ - -$head function$$ -This section defines a computational graph representation of a function -$latex y = f(x, p)$$. -The vector $icode x$$ is called the independent variable vector, -$icode p$$ is called the independent dynamic parameter vector, -and $icode y$$ is called the dependent variable vector. - -$head Node Indices$$ -The nodes in an AD graph have the following order: -$pre - p_0 , ... , p_{np-1} , - x_0 , ... , x_{nx-1} , - c_0 , ... , c_{nc-1} , - r_0 , ... , r_{no-1} -$$ - -$subhead p$$ -The sub-vector -$pre p_0, ... , p_{np-1}$$ is the independent dynamic parameter vector; -see $cref/n_dynamic_ind/cpp_ad_graph/n_dynamic_ind/$$. -The node index corresponding to $icode p_0$$ is $code 1$$. - -$subhead x$$ -The sub-vector -$pre x_1, ... , x_nx$$ is the independent variable vector; -see $cref/n_variable_ind/cpp_ad_graph/n_variable_ind/$$. -The node index corresponding to $icode x_0$$ is -the index corresponding to $icode p_0$$ plus $icode np$$. - -$subhead c$$ -The sub-vector -$pre c_1, ... , c_nc$$ is the constant parameter vector; -see $cref/constant_vec/cpp_ad_graph/constant_vec/$$. -The node index corresponding to $icode c_0$$ is -the index corresponding to $icode x_0$$ plus $icode nx$$. - -$subhead r$$ -The sub-vector -$pre r_i$$ for $icode%i%=0,%...%,%no%-1%$$ is the result vector -for the $th i$$ operator; -see $cref/operator_vec/cpp_ad_graph/operator_vec/$$. -All of the node arguments for an the $th i$$ operator are nodes -that come before the first element of $icode r_i$$. -The node index corresponding to the first element of $icode r_0$$ is -the index corresponding to $icode c_0$$ plus $icode nc$$. -For $icode%i% > 0%$$, -The node index corresponding to the first element of $icode r_i$$ is -the index corresponding to the first element of $icode r_{i-1}$$ plus -the number of results for the $th i-1$$ operator. - -$head function_name$$ -is a $code std::string$$ containing the name for the function -corresponding to this graph. - -$head discrete_name_vec$$ -is a vector with elements of type $code std::string$$. -A discrete function has one argument, one result, and it derivative -is always zero; e.g., the Heaviside function. -Calls by this function to discrete functions use the index in this -vector to identify the discrete functions; see -$cref/dis_graph_op/cpp_ad_graph/operator_arg/dis_graph_op/$$ below. -If there are no calls to discrete functions, this vector can be empty. - -$head atomic_name_vec$$ -is a vector with elements of type $code std::string$$. -An atomic function can have any number of arguments and results -and non-zero derivatives. -Calls by this function to other functions use the index in this -vector to identify the other functions; see -$cref/atom_graph_op/cpp_ad_graph/operator_arg/atom_graph_op/$$ below. -If there are no calls to other functions, this vector can be empty. -Discrete functions are faster, and simpler to create and use -than atomic functions. - -$head print_text_vec$$ -is a vector with elements of type $code std::string$$. -The $cref/print/graph_op_enum/Print/$$ operators uses indices -in this vector for the corresponding -$cref/before/PrintFor/before/$$ and $cref/after/PrintFor/after/$$ values. -If there are no print operators, this vector can be empty. - -$head n_dynamic_ind$$ -is the number of independent dynamic parameters in the function -(called $icode np$$ above); see -$cref/dynamic/Independent/dynamic/$$. - -$head n_variable_ind$$ -is the number of independent variables in the function -(called $icode nx$$ above); see -$cref/x/Independent/x/$$. - -$head constant_vec$$ -is a vector of with elements of type -$code double$$ and size $icode nc$$ that can be used to define this function. - -$head operator_vec$$ -is a vector with elements of type $code graph_op_enum$$ -and size $icode no$$ (the number of operators in the graph). -For $icode%i%= 0, %...%, %no%-1%$$ -$icode%operator_vec%[%i%]%$$ contains the instructions -for computing the result vector $icode r_i$$. - -$subhead C++11$$ -If the c++ compiler being used does not support c++11, -it is assumed that operators that -$cref/require c++11/graph_op_enum/Unary/Require C++11/$$ -are $bold not$$ used. - -$head operator_arg$$ -is a vector with size equal to the sum of the size of each -of its sub-vectors (which are described below). -For $icode%i%= 0, %...%, %no%-1%$$, we use -$icode%first_node%[%i%]%$$ to denote the index in $icode operator_arg$$ -of the first node argument to the $th i$$ operator. -We use $icode%n_node_arg%[%i%]%$$ to denote the number of node arguments -for the $th i$$ operator. -For $icode%j% = 0 , %...%, %n_node_arg%[%i%]-1%$$, -the $th j$$ node argument for the $th i$$ operator has node index -$codei% - %operator_arg%[ %first_node%[%i%] + %j% ] -%$$ -Except for the -$code dis_graph_op$$, $code atom_graph_op$$, and $code sum_graph_op$$ cases, -the $icode operator_arg$$ sub-vector for the $th i$$ operator starts are -$icode%first_node%[%i%]%$$ and has $icode%n_node_arg%[%i%]%$$ elements. - -$subhead dis_graph_op$$ -In the case where $icode%operator_vec%[%i%].op_enum%$$ is -$code dis_graph_op$$: -$codei% - %name_index%[%i%] = %operator_arg%[ %first_node%[%i%] - 1 ] -%$$ -is the index in $cref/discrete_name_vec/cpp_ad_graph/discrete_name_vec/$$ -of the function being called by this operator. -For this operator, -the $icode operator_arg$$ sub-vector for the $th i$$ operator -starts at index $icode%first_node%[%i%]-1%$$ -and has $codei%2 = %n_node_arg%[%i%]+1%$$ elements. - -$subhead atom_graph_op$$ -In the case where $icode%operator_vec%[%i%].op_enum%$$ is -$code atom_graph_op$$: -$codei% - %name_index%[%i%] = %operator_arg%[ %first_node%[%i%] - 3 ] -%$$ -is the index in $cref/atomic_name_vec/cpp_ad_graph/atomic_name_vec/$$ -of the function being called by this operator. -$codei% - %n_result%[%i%] = %operator_arg%[ %first_node%[%i%] - 2 ] -%$$ -is the number of result nodes for this operator. -$codei% - %n_node_arg%[%i%] = %operator_arg%[ %first_node%[%i%] - 1 ] -%$$ -is the number of node arguments for this operator. -For this operator, -the $icode operator_arg$$ sub-vector for the $th i$$ operator -starts at index $icode%first_node%[%i%]-3%$$ -and has $icode%n_node_arg%[%i%]+3%$$ elements. - -$subhead sum_graph_op$$ -In the case where $icode%operator_vec%[%i%].op_enum%$$ is -$code sum_graph_op$$: -$codei% - %n_node_arg%[%i%] = %operator_arg%[ %first_node%[%i%] - 1 ] -%$$ -is the number of node arguments for this operator. -For this operator, -the $icode operator_arg$$ sub-vector for the $th i$$ operator -starts at index $icode%first_node%[%i%]-1%$$ -and has $icode%n_node_arg%[%i%]+1%$$ elements. - -$head dependent_vec$$ -is a vector with size equal to the number element in $icode y$$. -The $th i$$ element of $icode y$$ corresponds to the node index -$icode%dependent_vec%[%i%]%$$. - -$head cpp_graph$$ -The $code cpp_graph$$ class implements the data structure above. -It is defined by the documentation sections under Contents below: - -$childtable% - include/cppad/core/graph/graph_op_enum.hpp% - include/cppad/core/graph/cpp_graph.omh% - include/cppad/core/graph/from_graph.hpp% - include/cppad/core/graph/to_graph.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/graph/cpp_graph.hpp b/build-config/cppad/include/cppad/core/graph/cpp_graph.hpp deleted file mode 100644 index c259d888..00000000 --- a/build-config/cppad/include/cppad/core/graph/cpp_graph.hpp +++ /dev/null @@ -1,404 +0,0 @@ -# ifndef CPPAD_CORE_GRAPH_CPP_GRAPH_HPP -# define CPPAD_CORE_GRAPH_CPP_GRAPH_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -class cpp_graph { // BEGIN_CPP_GRAPH_CLASS -public: - typedef CppAD::graph::graph_op_enum graph_op_enum; -private: - // - std::string function_name_; - vector discrete_name_vec_; - vector atomic_name_vec_; - vector print_text_vec_; - size_t n_dynamic_ind_; - size_t n_variable_ind_; - vector constant_vec_; - vector operator_vec_; - vector operator_arg_; - vector dependent_vec_; -public: - typedef local::graph::cpp_graph_itr const_iterator; - // - const_iterator begin(void) const - { size_t op_index = 0; - return const_iterator(operator_vec_, operator_arg_, op_index); - } - const_iterator end(void) - { size_t op_index = operator_vec_.size(); - return const_iterator(operator_vec_, operator_arg_, op_index); - } -/* -------------------------------------------------------------------------------- -$begin cpp_graph_ctor$$ -$spell - obj - cpp - ind - vec - arg -$$ - -$section C++ AD Graph Constructor$$ - -$head Syntax$$ -$codei%cpp_graph %graph_obj% -%$$ -$icode%graph_obj%.initialize() -%$$ - -$head function_name$$ -$cref/function_name/cpp_ad_graph/function_name/$$ -is initialized to the empty string. - -$head n_dynamic_ind$$ -$cref/n_dynamic_ind/cpp_ad_graph/n_dynamic_ind/$$ is initialized as zero. - -$head n_variable_ind$$ -$cref/n_variable_ind/cpp_ad_graph/n_variable_ind/$$ is initialized as zero. - -$head constant_vec$$ -$cref/constant_vec/cpp_ad_graph/constant_vec/$$ is initialized as empty. - -$head operator_vec$$ -$cref/operator_vec/cpp_ad_graph/operator_vec/$$ is initialized as empty. - -$head operator_arg$$ -$cref/operator_arg/cpp_ad_graph/operator_arg/$$ is initialized as empty. - -$head dependent_vec$$ -$cref/dependent_vec/cpp_ad_graph/dependent_vec/$$ is initialized as empty. - -$end --------------------------------------------------------------------------------- -*/ -public: - void initialize(void) - { function_name_ = ""; - n_dynamic_ind_ = 0; - n_variable_ind_ = 0; - discrete_name_vec_.resize(0); - atomic_name_vec_.resize(0); - print_text_vec_.resize(0); - constant_vec_.resize(0); - operator_vec_.resize(0); - operator_arg_.resize(0); - dependent_vec_.resize(0); - return; - } - cpp_graph(void) - { initialize(); } -/* ---------------------------------------------------------------------------------- -$begin cpp_graph_scalar$$ -$spell - obj - cpp - ind - std - const -$$ - -$section C++ AD Graph Scalar Values$$ - -$head Syntax$$ - -$subhead Get$$ -$icode%function_name% = %graph_obj%.function_name_get() -%$$ -$icode%n_dynamic_ind% = %graph_obj%.n_dynamic_ind_get() -%$$ -$icode%n_variable_ind% = %graph_obj%.n_variable_ind_get() -%$$ - -$subhead Set$$ -$icode%graph_obj%.function_name_set(%function_name%) -%$$ -$icode%graph_obj%.n_dynamic_ind_set(%n_dynamic_ind%) -%$$ -$icode%graph_obj%.n_variable_ind_set(%n_variable_ind%) -%$$ - -$head Set$$ -The argument for all the set operations is const. - -$head graph_obj$$ -is an $code cpp_graph$$ object. -It is const for all the get functions. - -$head function_name$$ -is a $code std::string&$$ specifying the name of the function -for this graph. - -$head n_dynamic_ind$$ -is a $code size_t$$ specifying the number of independent dynamic parameters. - -$head n_variable_ind$$ -is a $code size_t$$ specifying the number of independent variables. - -$end -*/ - // function_name - const std::string& function_name_get(void) const - { return function_name_; } - void function_name_set(const std::string& function_name) - { function_name_ = function_name; } - // - // n_dynamic_ind - const size_t& n_dynamic_ind_get(void) const - { return n_dynamic_ind_; } - void n_dynamic_ind_set(const size_t n_dynamic_ind) - { n_dynamic_ind_ = n_dynamic_ind; } - // - // n_variable_ind - const size_t& n_variable_ind_get(void) const - { return n_variable_ind_; } - void n_variable_ind_set(const size_t n_variable_ind) - { n_variable_ind_ = n_variable_ind; } -/* ---------------------------------------------------------------------------------- -$begin cpp_graph_vector$$ -$spell - obj - cpp - ind - std - const - vec - arg - op_enum -$$ - -$section C++ AD Graph Vector Values$$ - -$head Syntax$$ - -$subhead Size$$ -$icode%size% = %graph_obj%.discrete_name_vec_size() -%$$ -$icode%size% = %graph_obj%.atomic_name_vec_size() -%$$ -$icode%size% = %graph_obj%.print_text_vec_size() -%$$ -$icode%size% = %graph_obj%.constant_vec_size() -%$$ -$icode%size% = %graph_obj%.operator_vec_size() -%$$ -$icode%size% = %graph_obj%.operator_arg_size() -%$$ -$icode%size% = %graph_obj%.dependent_vec_size() -%$$ - -$subhead Get$$ -$icode%discrete_name% = %graph_obj%.discrete_name_vec_get(%index%) -%$$ -$icode%atomic_name% = %graph_obj%.atomic_name_vec_get(%index%) -%$$ -$icode%print_text% = %graph_obj%.print_text_vec_get(%index%) -%$$ -$icode%constant% = %graph_obj%.constant_vec_get(%index%) -%$$ -$icode%op_enum% = %graph_obj%.operator_vec_get(%index%) -%$$ -$icode%argument% = %graph_obj%.operator_arg_get(%index%) -%$$ -$icode%node_index% = %graph_obj%.dependent_vec_get(%index%) -%$$ - -$subhead Push Back$$ -$icode%graph_obj%.discrete_name_vec_push_back(%discrete_name%) -%$$ -$icode%graph_obj%.atomic_name_vec_push_back(%atomic_name%) -%$$ -$icode%graph_obj%.print_text_vec_push_back(%print_text%) -%$$ -$icode%graph_obj%.constant_vec_push_back(%constant%) -%$$ -$icode%graph_obj%.operator_vec_push_back(%op_enum%) -%$$ -$icode%graph_obj%.operator_arg_push_back(%argument%) -%$$ -$icode%graph_obj%.dependent_vec_get(%node_index%) -%$$ - -$subhead Find$$ -$icode%discrete_index% = %graph_obj%.discrete_name_vec_find(%discrete_name%) -%$$ -$icode%atomic_index% = %graph_obj%.atomic_name_vec_find(%atomic_name%) -%$$ -$icode%print_index% = %graph_obj%.print_text_vec_find(%print_text%) -%$$ - -$head Arguments$$ -All of the member function arguments are either call by value or const. - -$head size$$ -is a $code size_t$$ value equal to the current size of the specified vector. - -$head index$$ -is a $code size_t$$ value that must be less than the current size -of the specified vector. - -$head push_back$$ -The arguments for all the push_back functions are const. -The size of the specified vector before a push_back, -is the index in the vector corresponding to the argument value. -The size of the vector after the push_back is the size before plus one. - -$head graph_obj$$ -is an $code cpp_graph$$ object. -It is const for the size, get, and find functions and -not const for the push_back functions. - -$head discrete_name$$ -is a $code std::string$$ equal to the name of a $cref discrete$$ function. - -$head atomic_name$$ -is a $code std::string$$ equal to the name of an $cref atomic_three$$ function. - -$head print_text$$ -is a $code std::string$$ equal to the text to be printed. - -$head constant$$ -is a $code double$$ equal to the constant with the corresponding -index in $code constant_vec$$. - -$head op_enum$$ -is the $cref graph_op_enum$$ for corresponding operator. - -$head argument$$ -is the $code size_t$$ value for corresponding operator argument. - -$head node_index$$ -is the node index for the corresponding dependent variable with -the corresponding index in -$cref/dependent_vec/cpp_ad_graph/dependent_vec/$$. - -$head discrete_index$$ -is the index such that -$codei% - %discrete_name% == %graph_obj%.discrete_name_vec_get(%discrete_index%) -%$$ -If there is no such index, -$codei% - %discrete_index% == %graph_obj%.discrete_name_vec_size() -%$$ - -$head atomic_index$$ -is the index such that -$codei% - %atomic_name% == %graph_obj%.atomic_name_vec_get(%atomic_index%) -%$$ -If there is no such index, -$codei% - %atomic_index% == %graph_obj%.atomic_name_vec_size() -%$$ - -$head print_index$$ -is the index such that -$codei% - %print_text% == %graph_obj%.print_text_vec_get(%print_index%) -%$$ -If there is no such index, -$codei% - %print_index% == %graph_obj%.print_text_vec_size() -%$$ - - -$end -*/ - // discrete_name_vec - const std::string& discrete_name_vec_get(size_t index) const - { return discrete_name_vec_[index]; } - size_t discrete_name_vec_size(void) const - { return discrete_name_vec_.size(); } - void discrete_name_vec_push_back(const std::string& discrete_name) - { discrete_name_vec_.push_back(discrete_name); } - size_t discrete_name_vec_find(const std::string& discrete_name) const - { for(size_t i = 0; i < discrete_name_vec_.size(); ++i) - if( discrete_name == discrete_name_vec_[i] ) - return i; - return discrete_name_vec_.size(); - } - // - // atomic_name_vec - const std::string& atomic_name_vec_get(size_t index) const - { return atomic_name_vec_[index]; } - size_t atomic_name_vec_size(void) const - { return atomic_name_vec_.size(); } - void atomic_name_vec_push_back(const std::string& atomic_name) - { atomic_name_vec_.push_back(atomic_name); } - size_t atomic_name_vec_find(const std::string& atomic_name) const - { for(size_t i = 0; i < atomic_name_vec_.size(); ++i) - if( atomic_name == atomic_name_vec_[i] ) - return i; - return atomic_name_vec_.size(); - } - // - // print_text_vec - const std::string& print_text_vec_get(size_t index) const - { return print_text_vec_[index]; } - size_t print_text_vec_size(void) const - { return print_text_vec_.size(); } - void print_text_vec_push_back(const std::string& atomic_name) - { print_text_vec_.push_back(atomic_name); } - size_t print_text_vec_find(const std::string& print_text) const - { for(size_t i = 0; i < print_text_vec_.size(); ++i) - if( print_text == print_text_vec_[i] ) - return i; - return print_text_vec_.size(); - } - // - // constant_vec - const double& constant_vec_get(size_t index) const - { return constant_vec_[index]; } - size_t constant_vec_size(void) const - { return constant_vec_.size(); } - void constant_vec_push_back(const double& constant) - { constant_vec_.push_back(constant); } - // - // oerator_vec - const graph_op_enum& operator_vec_get(size_t index) const - { return operator_vec_[index]; } - size_t operator_vec_size(void) const - { return operator_vec_.size(); } - void operator_vec_push_back(const graph_op_enum op_enum) - { operator_vec_.push_back(op_enum); } - // - // operator_arg - const size_t& operator_arg_get(size_t index) const - { return operator_arg_[index]; } - size_t operator_arg_size(void) const - { return operator_arg_.size(); } - void operator_arg_push_back(const size_t argument) - { operator_arg_.push_back(argument); } - // - // dependent_vec - const size_t& dependent_vec_get(size_t index) const - { return dependent_vec_[index]; } - size_t dependent_vec_size(void) const - { return dependent_vec_.size(); } - void dependent_vec_push_back(const size_t node_index) - { dependent_vec_.push_back(node_index); } - -}; // END CPP_GRAPH_CLASS - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/graph/cpp_graph.omh b/build-config/cppad/include/cppad/core/graph/cpp_graph.omh deleted file mode 100644 index d20dc2fb..00000000 --- a/build-config/cppad/include/cppad/core/graph/cpp_graph.omh +++ /dev/null @@ -1,20 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin cpp_graph$$ - -$section A C++ AD Graph Class$$ - -$childtable% - include/cppad/core/graph/cpp_graph.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/graph/from_graph.hpp b/build-config/cppad/include/cppad/core/graph/from_graph.hpp deleted file mode 100644 index 85ce50a8..00000000 --- a/build-config/cppad/include/cppad/core/graph/from_graph.hpp +++ /dev/null @@ -1,1498 +0,0 @@ -# ifndef CPPAD_CORE_GRAPH_FROM_GRAPH_HPP -# define CPPAD_CORE_GRAPH_FROM_GRAPH_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/* -$begin from_graph$$ -$spell - CppAD - ind - vec - arg - obj - op_enum - dyn2var -$$ - -$section ADFun Object Corresponding to a CppAD Graph$$ - -$head Syntax$$ -$codei% - ADFun<%Base%> %fun% - %fun%.from_graph(%graph_obj%) - %fun%.from_graph(%graph_obj%, %dyn2var%, %var2dyn%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_ONE_ARGUMENT%// END_ONE_ARGUMENT%1 -%$$ -$srcthisfile% - 0%// BEGIN_WITH_IS_DYNAMIC%// END_WITH_IS_DYNAMIC%1 -%$$ - -$head Base$$ -is the type corresponding to this $cref/ADFun/adfun/$$ object; -i.e., its calculations are done using the type $icode Base$$. - -$head RecBase$$ -in the prototype above, $icode RecBase$$ is the same type as $icode Base$$. - -$head graph_obj$$ -is a $cref cpp_ad_graph$$ representation of this function. - -$head dyn2var$$ -is a vector with size equal to the number of independent dynamic parameters -in the graph; i.e., the size of $cref/p/cpp_ad_graph/Node Indices/p/$$. -It specifies which independent dynamic parameters in the graph are -independent variables in the function $icode fun$$. - -$head var2dyn$$ -is a vector with size equal to the number of independent variables -in the graph; i.e., the size of $cref/x/cpp_ad_graph/Node Indices/x/$$. -It specifies which independent variables in the graph are -independent dynamic parameters in the function $icode fun$$. - -$head fun$$ -It $icode dyn2var$$ and $icode var2dyn$$ are not present, -the independent dynamic parameters and independent variables in $icode fun$$ -are the same as for the graph. -Otherwise, they are described below. - -$subhead m_true, m_false$$ -Let $icode m_true$$ ($icode m_false$$) be the number of true (false) -elements of $icode dyn2var$$. - -$subhead n_true, n_false$$ -Let $icode n_true$$ ($icode n_false$$) be the number of true (false) -elements of $icode var2dyn$$. - -$subhead Independent Dynamic Parameters$$ -The first $icode m_false$$ independent dynamic parameters in $icode fun$$ -correspond to the false components of $icode dyn2var$$ -and have the same order as in the graph. -The next $icode n_true$$ independent dynamic parameters in $icode fun$$ -correspond to the true components of $icode var2dyn$$ -and have the same order as in the graph. - -$subhead Independent Variables$$ -The first $icode m_true$$ independent variables in $icode fun$$ -correspond to the true components of $icode dyn2var$$ -and have the same order as in the graph. -The next $icode n_false$$ independent variables in $icode fun$$ -correspond to the false components of $icode var2dyn$$ -and have the same order as in the graph. - -$children% - example/graph/switch_var_dyn.cpp -%$$ -$head Examples$$ -The file $cref switch_var_dyn.cpp$$ contains an example and test -of this routine. -For simpler examples, that do not change the dynamic parameters and variables; -see $cref/graph_op_enum examples/graph_op_enum/Examples/$$. - -$end -*/ -// BEGIN_WITH_IS_DYNAMIC -template -void CppAD::ADFun::from_graph( - const CppAD::cpp_graph& graph_obj , - const CppAD::vector& dyn2var , - const CppAD::vector& var2dyn ) -// END_WITH_IS_DYNAMIC -{ using CppAD::isnan; - using namespace CppAD::graph; - // - // some sizes - const std::string function_name = graph_obj.function_name_get(); - const size_t n_dynamic_ind = graph_obj.n_dynamic_ind_get(); - const size_t n_variable_ind = graph_obj.n_variable_ind_get(); - const size_t n_constant = graph_obj.constant_vec_size(); - const size_t n_usage = graph_obj.operator_vec_size(); - const size_t n_dependent = graph_obj.dependent_vec_size(); - // - // n_dynamic_ind_fun - // n_variable_ind_fun - CPPAD_ASSERT_KNOWN( - n_variable_ind == var2dyn.size(), - "from_graph: size of var2dyn not equal " - "number of independent variables in graph" - ); - CPPAD_ASSERT_KNOWN( - n_dynamic_ind == dyn2var.size(), - "from_graph: size of dyn2val not equal " - "number of independent dynamic parameters in graph" - ); - size_t n_dynamic_ind_fun = 0; - size_t n_variable_ind_fun = 0; - for(size_t i = 0; i < n_dynamic_ind; ++i) - { if( dyn2var[i] ) - ++n_variable_ind_fun; - else - ++n_dynamic_ind_fun; - } - for(size_t i = 0; i < n_variable_ind; ++i) - { if( var2dyn[i] ) - ++n_dynamic_ind_fun; - else - ++n_variable_ind_fun; - } - // - // Start of node indices - size_t start_dynamic_ind = 1; - size_t start_independent = start_dynamic_ind + n_dynamic_ind; - size_t start_constant = start_independent + n_variable_ind; - size_t start_operator = start_constant + n_constant; - // - // initialize mappings from node index as empty - // (there is no node zero) - vector node_type( 1 ); - local::pod_vector node2fun( 1 ); - node_type[0] = number_ad_type_enum; // invalid value - node2fun[0] = 0; // invalid value - // - // discrete_index - // mapping from index in discrete_name_vec to discrete index - size_t n_list_discrete = discrete::list_size(); - size_t n_graph_discrete = graph_obj.discrete_name_vec_size(); - vector discrete_index( n_graph_discrete ); - for(size_t i = 0; i < n_graph_discrete; ++i) - discrete_index[i] = n_list_discrete; // invalid discrete index - for(size_t index = 0; index < n_list_discrete; ++index) - { const char* name( discrete::name(index) ); - size_t graph_index = graph_obj.discrete_name_vec_find(name); - if( graph_index != n_graph_discrete ) - { if( discrete_index[graph_index] != n_list_discrete ) - { std::string msg = "from_graph: error in call to "; - msg += name; - msg += ".\nThere is mor than one discrete "; - msg += "function with this name"; - // - // use this source code as point of detection - bool known = true; - int line = __LINE__; - const char* file = __FILE__; - const char* exp = "discrete_index[i] == n_list_discrete"; - // - // CppAD error handler - ErrorHandler::Call( known, line, file, exp, msg.c_str() ); - } - discrete_index[graph_index] = index; - } - } - // - // atomic_three_index - // mapping from index in atomic_name_vec to atomic three index - size_t n_graph_atomic = graph_obj.atomic_name_vec_size(); - vector atomic_three_index( n_graph_atomic ); - for(size_t index = 0; index < n_graph_atomic; ++index) - atomic_three_index[index] = 0; // invalid atomic index - - { bool set_null = true; - size_t index_in = 0; - size_t type; - std::string name; - void* ptr; - size_t n_atomic = CppAD::local::atomic_index( - set_null, index_in, type, &name, ptr - ); - set_null = false; - for(index_in = 1; index_in <= n_atomic; ++index_in) - { CppAD::local::atomic_index( - set_null, index_in, type, &name, ptr - ); - if( type == 3 ) - { size_t graph_index = graph_obj.atomic_name_vec_find(name); - if( graph_index != n_graph_atomic ) - { if( atomic_three_index[graph_index] != 0 ) - { std::string msg = "from_graph: error in call to "; - msg += name + ".\n"; - msg += "There is more than one atomic_three "; - msg += "function with this name"; - // - // use this source code as point of detection - bool known = true; - int line = __LINE__; - const char* file = __FILE__; - const char* exp = "atomic_index[index] == 0"; - // - // CppAD error handler - ErrorHandler::Call( - known, line, file, exp, msg.c_str() - ); - } - atomic_three_index[graph_index] = index_in; - } - } - } - } - // ---------------------------------------------------------------------- - // Create a recording for this function - // ---------------------------------------------------------------------- - - // start a recording - local::recorder rec; - CPPAD_ASSERT_UNKNOWN( rec.num_op_rec() == 0 ); - rec.set_num_dynamic_ind(n_dynamic_ind_fun); - rec.set_abort_op_index(0); - rec.set_record_compare(false); - - // rec_text_index - // mapping from print_text_vec index to recording index - vector rec_text_index( graph_obj.print_text_vec_size() ); - for(size_t i = 0; i < graph_obj.print_text_vec_size(); ++i) - { const std::string& text = graph_obj.print_text_vec_get(i); - rec_text_index[i] = rec.PutTxt( text.c_str() ); - } - - // nan - Base nan = CppAD::numeric_limits::quiet_NaN(); - - // Place the parameter with index 0 in the tape - const local::pod_vector_maybe& parameter( rec.all_par_vec()); - CPPAD_ASSERT_UNKNOWN( parameter.size() == 0 ); - addr_t i_par = rec.put_con_par(nan); - CPPAD_ASSERT_UNKNOWN( i_par == 0 ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_par] ) ); - // - // Place the variable with index 0 in the tape - CPPAD_ASSERT_NARG_NRES(local::BeginOp, 1, 1); - rec.PutOp(local::BeginOp); - rec.PutArg(0); - // - // Next come the independent dynamic parameters in the graph - addr_t i_var = 0; - for(size_t i = 0; i < n_dynamic_ind; ++i) - { - if( dyn2var[i] ) - { i_var = rec.PutOp( local::InvOp ); - node_type.push_back(variable_enum);; - node2fun.push_back(i_var); - } - else - { i_par = rec.put_dyn_par(nan, local::ind_dyn ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_par] ) ); - node_type.push_back(dynamic_enum); - node2fun.push_back(i_par); - } - } - - // Next come the independent variables in the graph - CPPAD_ASSERT_NARG_NRES(local::InvOp, 0, 1); - for(size_t i = 0; i < n_variable_ind; ++i) - { if( var2dyn[i] ) - { i_par = rec.put_dyn_par(nan, local::ind_dyn ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_par] ) ); - node_type.push_back(dynamic_enum); - node2fun.push_back(i_par); - } - else - { i_var = rec.PutOp( local::InvOp ); - node_type.push_back(variable_enum);; - node2fun.push_back(i_var); - } - } - CPPAD_ASSERT_UNKNOWN( size_t( i_par ) == n_dynamic_ind_fun ); - CPPAD_ASSERT_UNKNOWN( size_t( i_var ) == n_variable_ind_fun ); - - // Next come the constant parameters - for(size_t i = 0; i < n_constant; ++i) - { Base par = Base( graph_obj.constant_vec_get(i) ); - i_par = rec.put_con_par(par); - CPPAD_ASSERT_UNKNOWN( parameter[i_par] == par ); - // - node_type.push_back(constant_enum);; - node2fun.push_back(i_par); - } - - // - // local arrays used to avoid reallocating memory - local::pod_vector temporary; - vector type_x; - vector arg; - vector arg_node; - // - // arrays only used by atom_graph_op - vector parameter_x, taylor_y; - vector type_y; - vector< AD > ax, ay; - // - // define here because not using as loop index - cpp_graph::const_iterator graph_itr; - // - // loop over operators in the recording - size_t start_result = start_operator; - for(size_t op_index = 0; op_index < n_usage; ++op_index) - { // op_enum, str_index, n_result, arg_node - if( op_index == 0 ) - graph_itr = graph_obj.begin(); - else - ++graph_itr; - cpp_graph::const_iterator::value_type itr_value = *graph_itr; - const vector& str_index(*itr_value.str_index_ptr ); - graph_op_enum op_enum = itr_value.op_enum; - size_t n_result = itr_value.n_result; - size_t n_arg = itr_value.arg_node_ptr->size(); - arg.resize(n_arg); - // - // make sure type_x is large enough - type_x.resize(n_arg); -# ifndef NDEBUG - addr_t n_con_arg = 0; -# endif - addr_t n_dyn_arg = 0; - addr_t n_var_arg = 0; - for(size_t j = 0; j < n_arg; ++j) - { size_t node_index = (*itr_value.arg_node_ptr)[j]; - // - // argument to graph operator - CPPAD_ASSERT_KNOWN( node_index < start_result, - "from_graph op argument index is greater or equal\n" - "the starting index for the next result" - ); - // - // type of argument - type_x[j] = node_type[ node_index ]; - // - // argument to function operator - arg[j] = node2fun[ node_index ]; - CPPAD_ASSERT_UNKNOWN( arg[j] != 0 ); - // - // count number of arguments of different types -# ifndef NDEBUG - n_con_arg += addr_t( type_x[j] == constant_enum ); -# endif - n_dyn_arg += addr_t( type_x[j] == dynamic_enum ); - n_var_arg += addr_t( type_x[j] == variable_enum ); - } - CPPAD_ASSERT_UNKNOWN( - n_arg == size_t(n_con_arg + n_dyn_arg + n_var_arg) - ); - // - addr_t i_result = 0; // invalid value - // ------------------------------------------------------------------- - // conditional expressions - // ------------------------------------------------------------------- - if( op_enum == cexp_eq_graph_op || - op_enum == cexp_le_graph_op || - op_enum == cexp_lt_graph_op ) - { CPPAD_ASSERT_UNKNOWN( n_result == 1 && n_arg == 4 ); - // cop - CompareOp cop; - if( op_enum == cexp_eq_graph_op ) - cop = CompareEq; - else if ( op_enum == cexp_le_graph_op ) - cop = CompareLe; - else - cop = CompareLt; - // - if( n_var_arg == 0 ) - { if( n_dyn_arg == 0 ) - { // result is a constant parameter - Base result = CondExpOp(cop, - parameter[arg[0]], // left - parameter[arg[1]], // right - parameter[arg[2]], // if_true - parameter[arg[3]] // if_false - ); - i_result = rec.put_con_par(result); - } - else - { i_result = rec.put_dyn_cond_exp( - nan, cop, arg[0], arg[1], arg[2], arg[3] - ); - } - } - else - { // flag marking which arguments are variables - addr_t flag = 0; - addr_t bit = 1; - for(size_t j = 0; j < 4; ++j) - { if( type_x[j] == variable_enum ) - flag |= bit; - bit = 2 * bit; - } - CPPAD_ASSERT_UNKNOWN( flag != 0 ); - rec.PutArg(addr_t(cop), flag, arg[0], arg[1], arg[2], arg[3]); - i_result = rec.PutOp(local::CExpOp); - } - } - // ------------------------------------------------------------------- - // compare operators - // ------------------------------------------------------------------- - else if( - op_enum == comp_eq_graph_op || - op_enum == comp_le_graph_op || - op_enum == comp_lt_graph_op || - op_enum == comp_ne_graph_op ) - { CPPAD_ASSERT_UNKNOWN( n_result == 0 && n_arg == 2 ); - // - bool var_left = type_x[0] == variable_enum; - bool var_right = type_x[1] == variable_enum; - bool dyn_left = type_x[0] == dynamic_enum; - bool dyn_right = type_x[1] == dynamic_enum; - // - ax.resize(n_arg); - // ax[0] - if( var_left | dyn_left ) - ax[0].taddr_ = arg[0]; - else - ax[0].value_ = parameter_x[0]; - // ax[1] - if( var_right | dyn_right ) - ax[1].taddr_ = arg[1]; - else - ax[1].value_ = parameter_x[1]; - // - bool result; - switch( op_enum ) - { - case comp_eq_graph_op: - result = true; - rec.comp_eq( - var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result - ); - break; - - case comp_le_graph_op: - result = true; - rec.comp_le( - var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result - ); - break; - - case comp_lt_graph_op: - result = true; - rec.comp_lt( - var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result - ); - break; - - case comp_ne_graph_op: - result = false; - rec.comp_eq( - var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result - ); - break; - - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - } - // ------------------------------------------------------------------- - // sum operator - // ------------------------------------------------------------------- - else if( op_enum == sum_graph_op ) - { - CPPAD_ASSERT_KNOWN( n_result == 1 , - "AD graph sum operator: n_result is not 1" - ); - if( n_var_arg == 0 ) - { // result of the sum is a parameter - Base sum_constant = 0.0; - temporary.resize(0); - for(size_t j = 0; j < n_arg; j++) - { if( type_x[j] == constant_enum ) - sum_constant += parameter[ arg[j] ]; - else - { CPPAD_ASSERT_UNKNOWN( type_x[j] == dynamic_enum ); - temporary.push_back( arg[j] ); - } - } - CPPAD_ASSERT_UNKNOWN( temporary.size() == size_t(n_dyn_arg) ); - // - // start with constant parameter - i_result = rec.put_con_par(sum_constant); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == sum_constant ); - // - // sum the dynamic parameters - for(addr_t j = 0; j < n_dyn_arg; ++j) - { i_result = rec.put_dyn_par( - nan, local::add_dyn, i_result, temporary[j] - ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - } - } - else - { // result of the sum is a variable - size_t n_temporary = 6 + size_t(n_var_arg + n_dyn_arg); - if( temporary.size() < n_temporary ) - temporary.resize( n_temporary ); - Base sum_constant = 0.0; - addr_t j_variable = 5 ; - addr_t j_dynamic = 5 + n_var_arg; - for(size_t j = 0; j < n_arg; j++) - { if( type_x[j] == constant_enum ) - sum_constant += parameter[ arg[j] ]; - if( type_x[j] == variable_enum ) - temporary[ j_variable++ ] = arg[j]; - if( type_x[j] == dynamic_enum ) - temporary[ j_dynamic++ ] = arg[j]; - } - temporary[j_dynamic] = j_dynamic; - // - temporary[0] = rec.put_con_par(sum_constant); - CPPAD_ASSERT_UNKNOWN(parameter[temporary[0]] == sum_constant); - // - temporary[1] = 5 + n_var_arg; - temporary[2] = 5 + n_var_arg; - temporary[3] = temporary[2] + n_dyn_arg; - temporary[4] = temporary[2] + n_dyn_arg; - // - i_result = rec.PutOp(local::CSumOp); - for(size_t j = 0; j < n_temporary; ++j) - rec.PutArg( temporary[j] ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::CSumOp) == 1 ); - } - } - // ------------------------------------------------------------------- - // print operator - // ------------------------------------------------------------------- - else if( op_enum == print_graph_op ) - { CPPAD_ASSERT_UNKNOWN( n_arg == 2 && n_result == 0 ); - // - // before - size_t before_graph = str_index[0]; - addr_t before_rec = rec_text_index[before_graph]; - // - // after - size_t after_graph = str_index[1]; - addr_t after_rec = rec_text_index[after_graph]; - // - // base 2 representation of [ Var(notpos), Var(value) ] - addr_t is_var = 0; - if( type_x[0] == variable_enum ) - is_var += 1; - if( type_x[1] == variable_enum ) - is_var += 2; - // - // record this print operator - addr_t notpos = arg[0]; - addr_t value = arg[1]; - rec.PutOp(local::PriOp); - rec.PutArg(is_var, notpos, before_rec, value, after_rec); - } - // ------------------------------------------------------------------- - // discrete operator - // ------------------------------------------------------------------- - else if( op_enum == discrete_graph_op ) - { CPPAD_ASSERT_UNKNOWN( n_arg == 1 && n_result == 1 ); - size_t name_index = str_index[0]; - size_t function_index = discrete_index[name_index]; - if( function_index == n_list_discrete ) - { std::string msg = "from_graph: error in call to "; - msg += graph_obj.discrete_name_vec_get(name_index); - msg += ".\nNo previously defined discrete function "; - msg += "has this name"; - // - // use this source code as point of detection - bool known = true; - int line = __LINE__; - const char* file = __FILE__; - const char* exp = - "discrete_index[name_index] != n_list_discrete"; - // - // CppAD error handler - ErrorHandler::Call(known, line, file, exp, msg.c_str()); - } - if( type_x[0] == variable_enum ) - { CPPAD_ASSERT_NARG_NRES(local::DisOp, 2, 1); - i_result = rec.PutOp(local::DisOp); - rec.PutArg( addr_t(function_index) ); - rec.PutArg( arg[0] ); - } - else if( type_x[0] == dynamic_enum ) - { i_result = rec.put_dyn_par( - nan, local::dis_dyn, addr_t(function_index), arg[0] - ); - } - else - { Base result = discrete::eval( - function_index, parameter[ arg[0] ] - ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - } - } - // ------------------------------------------------------------------- - // atomic operator - // ------------------------------------------------------------------- - else if( op_enum == atom_graph_op ) - { size_t name_index = str_index[0]; - // - // atomic_index - CPPAD_ASSERT_UNKNOWN( name_index < atomic_three_index.size() ); - size_t atomic_index = atomic_three_index[name_index]; - if( atomic_index == 0 ) - { std::string msg = "from_graph: error in call to "; - msg += graph_obj.atomic_name_vec_get(name_index); - msg += ".\n"; - msg += "No previously defined atomic_three function "; - msg += "has this name"; - // - // use this source code as point of detection - bool known = true; - int line = __LINE__; - const char* file = __FILE__; - const char* exp = "atomic_index != 0"; - // - // CppAD error handler - ErrorHandler::Call(known, line, file, exp, msg.c_str()); - } - // - // afun - bool set_null = false; - size_t type; - std::string* name = nullptr; - void* v_ptr; - CppAD::local::atomic_index( - set_null, atomic_index, type, name, v_ptr - ); - CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >( v_ptr ); - // - // parameter_x - parameter_x.resize(n_arg); - for(size_t j = 0; j < n_arg; ++j) - { if( type_x[j] == constant_enum ) - parameter_x[j] = parameter[ arg[j] ]; - else - parameter_x[j] = nan; - } - // - // type_y - type_y.resize(n_result); - afun->for_type(parameter_x, type_x, type_y); - // - // taylor_y - size_t need_y = size_t(constant_enum); - size_t order_low = 0; - size_t order_up = 0; - taylor_y.resize(n_result); - afun->forward( - parameter_x , - type_x , - need_y , - order_low , - order_up , - parameter_x , - taylor_y - ); - // - // record_dynamic, record_variable - bool record_dynamic = false; - bool record_variable = false; - for(size_t i = 0; i < n_result; ++i) - { CPPAD_ASSERT_UNKNOWN( type_y[i] <= variable_enum ); - record_dynamic |= type_y[i] == dynamic_enum; - record_variable |= type_y[i] == variable_enum; - } - // tape_id is zero because not a true recording - tape_id_t tape_id = 0; - // - // ax, ay - if( record_dynamic || record_variable ) - { // tape_id (not a recording AD operations) - // ax - ax.resize(n_arg); - for(size_t j = 0; j < n_arg; ++j) - { ax[j].value_ = parameter_x[j]; - ax[j].taddr_ = arg[j]; - } - // ay - ay.resize(n_result); - for(size_t i = 0; i < n_result; ++i) - { ay[i].value_ = taylor_y[i]; - ay[i].taddr_ = 0; - } - } - if( record_dynamic ) rec.put_dyn_atomic( - tape_id, atomic_index, type_x, type_y, ax, ay - ); - if( record_variable ) rec.put_var_atomic( - tape_id, atomic_index, type_x, type_y, ax, ay - ); - // - // node_type, node2fun - for(size_t i = 0; i < n_result; ++i) - { node_type.push_back(type_y[i]); - switch( type_y[i] ) - { case constant_enum: - node2fun.push_back(rec.put_con_par(taylor_y[i])); - break; - - case dynamic_enum: - case variable_enum: - node2fun.push_back(ay[i].taddr_); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - } - } - // ------------------------------------------------------------------- - // unary operators - // ------------------------------------------------------------------- - else if( n_arg == 1 ) - { CPPAD_ASSERT_UNKNOWN( n_arg == 1 && n_result == 1 ); - Base result; // used in cases argument is a constant - if( type_x[0] == variable_enum ) switch( op_enum ) - { - case abs_graph_op: - i_result = rec.PutOp(local::AbsOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AbsOp) == 1 ); - break; - - case acosh_graph_op: - i_result = rec.PutOp(local::AcoshOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AcoshOp) == 1 ); - break; - - case asinh_graph_op: - i_result = rec.PutOp(local::AsinhOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AsinhOp) == 1 ); - break; - - case atanh_graph_op: - i_result = rec.PutOp(local::AtanhOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AtanhOp) == 1 ); - break; - - case erf_graph_op: - i_result = rec.PutOp(local::ErfOp); - CPPAD_ASSERT_UNKNOWN( NumArg(local::ErfOp) == 3 ); - // - // arg[0] = variable index for function argument - rec.PutArg( arg[0] ); - // - // parameter[ arg[1] ] = 0.0 - i_par = rec.put_con_par( Base(0.0) ); - rec.PutArg( i_par ); - // - // parameter[ arg[2] ] = 2 / sqrt(pi) - i_par = rec.put_con_par(Base( - 1.0 / std::sqrt( std::atan(1.0) ) - )); - rec.PutArg( i_par ); - // - break; - - case erfc_graph_op: - i_result = rec.PutOp(local::ErfcOp); - CPPAD_ASSERT_UNKNOWN( NumArg(local::ErfcOp) == 3 ); - // - // arg[0] = variable index for function argument - rec.PutArg( arg[0] ); - // - // parameter[ arg[1] ] = 0.0 - i_par = rec.put_con_par( Base(0.0) ); - rec.PutArg( i_par ); - // - // parameter[ arg[2] ] = 2 / sqrt(pi) - i_par = rec.put_con_par(Base( - 1.0 / std::sqrt( std::atan(1.0) ) - )); - rec.PutArg( i_par ); - // - break; - - case expm1_graph_op: - i_result = rec.PutOp(local::Expm1Op); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::Expm1Op) == 1 ); - break; - - case log1p_graph_op: - i_result = rec.PutOp(local::Log1pOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::Log1pOp) == 1 ); - break; - - case acos_graph_op: - i_result = rec.PutOp(local::AcosOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AcosOp) == 1 ); - break; - - case asin_graph_op: - i_result = rec.PutOp(local::AsinOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AsinOp) == 1 ); - break; - - case atan_graph_op: - i_result = rec.PutOp(local::AtanOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AtanOp) == 1 ); - break; - - case cosh_graph_op: - i_result = rec.PutOp(local::CoshOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::CoshOp) == 1 ); - break; - - case cos_graph_op: - i_result = rec.PutOp(local::CosOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::CosOp) == 1 ); - break; - - case exp_graph_op: - i_result = rec.PutOp(local::ExpOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::ExpOp) == 1 ); - break; - - case log_graph_op: - i_result = rec.PutOp(local::LogOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::LogOp) == 1 ); - break; - - case sign_graph_op: - i_result = rec.PutOp(local::SignOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::SignOp) == 1 ); - break; - - case sinh_graph_op: - i_result = rec.PutOp(local::SinhOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::SinhOp) == 1 ); - break; - - case sin_graph_op: - i_result = rec.PutOp(local::SinOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::SinOp) == 1 ); - break; - - case sqrt_graph_op: - i_result = rec.PutOp(local::SqrtOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::SqrtOp) == 1 ); - break; - - case tanh_graph_op: - i_result = rec.PutOp(local::TanhOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::TanhOp) == 1 ); - break; - - case tan_graph_op: - i_result = rec.PutOp(local::TanOp); - rec.PutArg( arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::TanOp) == 1 ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - else if( type_x[0] == dynamic_enum ) switch( op_enum ) - { - case abs_graph_op: - i_result = rec.put_dyn_par(nan, local::abs_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case acosh_graph_op: - i_result = rec.put_dyn_par(nan, local::acosh_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case asinh_graph_op: - i_result = rec.put_dyn_par(nan, local::asinh_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case atanh_graph_op: - i_result = rec.put_dyn_par(nan, local::atanh_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case erf_graph_op: - i_result = rec.put_dyn_par(nan, local::erf_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case erfc_graph_op: - i_result = rec.put_dyn_par(nan, local::erfc_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case expm1_graph_op: - i_result = rec.put_dyn_par(nan, local::expm1_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case log1p_graph_op: - i_result = rec.put_dyn_par(nan, local::log1p_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case acos_graph_op: - i_result = rec.put_dyn_par(nan, local::acos_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case asin_graph_op: - i_result = rec.put_dyn_par(nan, local::asin_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case atan_graph_op: - i_result = rec.put_dyn_par(nan, local::atan_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case cosh_graph_op: - i_result = rec.put_dyn_par(nan, local::cosh_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case cos_graph_op: - i_result = rec.put_dyn_par(nan, local::cos_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case exp_graph_op: - i_result = rec.put_dyn_par(nan, local::exp_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case log_graph_op: - i_result = rec.put_dyn_par(nan, local::log_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case sign_graph_op: - i_result = rec.put_dyn_par(nan, local::sign_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case sinh_graph_op: - i_result = rec.put_dyn_par(nan, local::sinh_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case sin_graph_op: - i_result = rec.put_dyn_par(nan, local::sin_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case sqrt_graph_op: - i_result = rec.put_dyn_par(nan, local::sqrt_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case tanh_graph_op: - i_result = rec.put_dyn_par(nan, local::tanh_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case tan_graph_op: - i_result = rec.put_dyn_par(nan, local::tan_dyn, arg[0] ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - else switch( op_enum ) - { - case abs_graph_op: - result = CppAD::abs( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case acosh_graph_op: - result = CppAD::acosh( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case asinh_graph_op: - result = CppAD::asinh( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case atanh_graph_op: - result = CppAD::atanh( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case erf_graph_op: - result = CppAD::erf( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case erfc_graph_op: - result = CppAD::erfc( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case expm1_graph_op: - result = CppAD::expm1( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case log1p_graph_op: - result = CppAD::log1p( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case acos_graph_op: - result = CppAD::acos( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case asin_graph_op: - result = CppAD::asin( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case atan_graph_op: - result = CppAD::atan( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case cosh_graph_op: - result = CppAD::cosh( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case cos_graph_op: - result = CppAD::cos( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case exp_graph_op: - result = CppAD::exp( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case log_graph_op: - result = CppAD::log( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case sign_graph_op: - result = CppAD::sign( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case sinh_graph_op: - result = CppAD::sinh( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case sin_graph_op: - result = CppAD::sin( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case sqrt_graph_op: - result = CppAD::sqrt( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case tanh_graph_op: - result = CppAD::tanh( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case tan_graph_op: - result = CppAD::tan( parameter[ arg[0] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - } - // ------------------------------------------------------------------- - // binary operators - // ------------------------------------------------------------------- - else - { CPPAD_ASSERT_UNKNOWN( n_arg == 2 && n_result == 1 ); - Base result; // used in cases where both arguments are constants - if( type_x[0] == variable_enum && type_x[1] == variable_enum ) - switch( op_enum ) - { - case add_graph_op: - i_result = rec.PutOp(local::AddvvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AddvvOp) == 2 ); - break; - - case azmul_graph_op: - i_result = rec.PutOp(local::ZmulvvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::ZmulvvOp) == 2 ); - break; - - case div_graph_op: - i_result = rec.PutOp(local::DivvvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::DivvvOp) == 2 ); - break; - - case mul_graph_op: - i_result = rec.PutOp(local::MulvvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::MulvvOp) == 2 ); - break; - - case pow_graph_op: - i_result = rec.PutOp(local::PowvvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::PowvvOp) == 2 ); - break; - - case sub_graph_op: - i_result = rec.PutOp(local::SubvvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::SubvvOp) == 2 ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - else if( type_x[0] == variable_enum ) switch( op_enum ) - { - // addition is communitative, so use Addpv - case add_graph_op: - i_result = rec.PutOp(local::AddpvOp); - rec.PutArg( arg[1], arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AddpvOp) == 2 ); - break; - - case azmul_graph_op: - i_result = rec.PutOp(local::ZmulvpOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::ZmulvpOp) == 2 ); - break; - - case div_graph_op: - i_result = rec.PutOp(local::DivvpOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::DivvpOp) == 2 ); - break; - - // multiplication is communitative, so use Mulpv - case mul_graph_op: - i_result = rec.PutOp(local::MulpvOp); - rec.PutArg( arg[1], arg[0] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::MulpvOp) == 2 ); - break; - - case pow_graph_op: - i_result = rec.PutOp(local::PowvpOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::PowvpOp) == 2 ); - break; - - case sub_graph_op: - i_result = rec.PutOp(local::SubvpOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::SubvpOp) == 2 ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - else if( type_x[1] == variable_enum ) switch( op_enum ) - { - case add_graph_op: - i_result = rec.PutOp(local::AddpvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::AddpvOp) == 2 ); - break; - - case azmul_graph_op: - i_result = rec.PutOp(local::ZmulpvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::ZmulpvOp) == 2 ); - break; - - case div_graph_op: - i_result = rec.PutOp(local::DivpvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::DivpvOp) == 2 ); - break; - - case mul_graph_op: - i_result = rec.PutOp(local::MulpvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::MulpvOp) == 2 ); - break; - - case pow_graph_op: - i_result = rec.PutOp(local::PowpvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::PowpvOp) == 2 ); - break; - - case sub_graph_op: - i_result = rec.PutOp(local::SubpvOp); - rec.PutArg( arg[0], arg[1] ); - CPPAD_ASSERT_UNKNOWN( NumArg(local::SubpvOp) == 2 ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - else if( type_x[0] == dynamic_enum || type_x[1] == dynamic_enum ) - switch( op_enum ) - { - case add_graph_op: - i_result = - rec.put_dyn_par(nan, local::add_dyn, arg[0], arg[1]); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case azmul_graph_op: - i_result = - rec.put_dyn_par(nan, local::zmul_dyn, arg[0], arg[1]); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case div_graph_op: - i_result = - rec.put_dyn_par(nan, local::div_dyn, arg[0], arg[1]); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case mul_graph_op: - i_result = - rec.put_dyn_par(nan, local::mul_dyn, arg[0], arg[1]); - break; - - case pow_graph_op: - i_result = - rec.put_dyn_par(nan, local::pow_dyn, arg[0], arg[1]); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - case sub_graph_op: - i_result = - rec.put_dyn_par(nan, local::sub_dyn, arg[0], arg[1]); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[i_result] ) ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - else switch( op_enum ) - { - case add_graph_op: - result = parameter[ arg[0] ] + parameter[ arg[1] ]; - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case azmul_graph_op: - result = azmul( parameter[ arg[0] ] , parameter[ arg[1] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case div_graph_op: - result = parameter[ arg[0] ] / parameter[ arg[1] ]; - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case mul_graph_op: - result = parameter[ arg[0] ] * parameter[ arg[1] ]; - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case pow_graph_op: - result = pow( parameter[ arg[0] ], parameter[ arg[1] ] ); - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - case sub_graph_op: - result = parameter[ arg[0] ] - parameter[ arg[1] ]; - i_result = rec.put_con_par(result); - CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result ); - break; - - default: - CPPAD_ASSERT_UNKNOWN( false ); - break; - - } - } - // case where node_type and node2fun for the results are set above - if( op_enum != atom_graph_op && n_result != 0 ) - { // set node_type and node2fun for result - // - CPPAD_ASSERT_UNKNOWN( i_result != 0 ); - CPPAD_ASSERT_UNKNOWN( n_result == 1 ); - if( n_var_arg > 0 ) - node_type.push_back(variable_enum); - else if( n_dyn_arg > 0 ) - node_type.push_back(dynamic_enum); - else - node_type.push_back(constant_enum); - node2fun.push_back(i_result); - } - // - start_result += n_result; - CPPAD_ASSERT_UNKNOWN( node2fun.size() == start_result ); - CPPAD_ASSERT_UNKNOWN( node_type.size() == start_result ); - } - // set this->dep_parameter_, set this->dep_taddr_ - // - CPPAD_ASSERT_NARG_NRES(local::ParOp, 1, 1); - dep_parameter_.resize( n_dependent ); - dep_taddr_.resize( n_dependent ); - for(size_t i = 0; i < n_dependent; ++i) - { - CPPAD_ASSERT_UNKNOWN( - node_type[ graph_obj.dependent_vec_get(i) ] != number_ad_type_enum - ); - if( node_type[ graph_obj.dependent_vec_get(i) ] == variable_enum ) - { dep_parameter_[i] = false; - dep_taddr_[i] = size_t( node2fun[ graph_obj.dependent_vec_get(i) ] ); - } - else - { dep_parameter_[i] = true; - dep_taddr_[i] = size_t( rec.PutOp(local::ParOp) ); - rec.PutArg( node2fun[ graph_obj.dependent_vec_get(i) ] ); - } - } - rec.PutOp(local::EndOp); - // ---------------------------------------------------------------------- - // End recording, set private member data except for - // dep__parameter_ and dep_taddr_ - // ---------------------------------------------------------------------- - // - // bool values in this object except check_for_nan_ - has_been_optimized_ = false; - // - // size_t values in this object - compare_change_count_ = 1; - compare_change_number_ = 0; - compare_change_op_index_ = 0; - num_order_taylor_ = 0; - cap_order_taylor_ = 0; - num_direction_taylor_ = 0; - num_var_tape_ = rec.num_var_rec(); - // - // taylor_ - taylor_.resize(0); - // - // cskip_op_ - cskip_op_.resize( rec.num_op_rec() ); - // - // load_op2var_ - load_op2var_.resize( rec.num_var_load_rec() ); - // - // play_ - // Now that each dependent variable has a place in the recording, - // and there is a EndOp at the end of the record, we can transfer the - // recording to the player and and erase the recording. - play_.get_recording(rec, n_variable_ind_fun); - // - // ind_taddr_ - // Note that play_ has been set, we can use it to check operators - ind_taddr_.resize(n_variable_ind_fun); - CPPAD_ASSERT_UNKNOWN( n_variable_ind_fun < num_var_tape_); - for(size_t j = 0; j < n_variable_ind_fun; 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); - // - // resize subgraph_info_ - subgraph_info_.resize( - ind_taddr_.size(), // n_dep - dep_taddr_.size(), // n_ind - play_.num_op_rec(), // n_op - play_.num_var_rec() // n_var - ); - // - // set the function name - function_name_ = function_name; - // - return; -} -// BEGIN_ONE_ARGUMENT -template -void CppAD::ADFun::from_graph( - const CppAD::cpp_graph& graph_obj ) -// END_ONE_ARGUMENT -{ size_t n_variable_ind = graph_obj.n_variable_ind_get(); - size_t n_dynamic_ind = graph_obj.n_dynamic_ind_get(); - CppAD::vector dyn2var(n_dynamic_ind), var2dyn(n_variable_ind); - for(size_t j = 0; j < n_dynamic_ind; ++j) - dyn2var[j] = false; - for(size_t j = 0; j < n_variable_ind; ++j) - var2dyn[j] = false; - // - from_graph(graph_obj, dyn2var, var2dyn); -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/graph/from_json.hpp b/build-config/cppad/include/cppad/core/graph/from_json.hpp deleted file mode 100644 index eca0676f..00000000 --- a/build-config/cppad/include/cppad/core/graph/from_json.hpp +++ /dev/null @@ -1,76 +0,0 @@ -# ifndef CPPAD_CORE_GRAPH_FROM_JSON_HPP -# define CPPAD_CORE_GRAPH_FROM_JSON_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -/* -$begin from_json$$ -$spell - Json -$$ - -$section ADFun Object Corresponding to a Json AD Graph$$ - -$head Syntax$$ -$codei% - ADFun<%Base%> %fun% - %fun%.from_json(%json%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head json$$ -is a $cref json_ad_graph$$. - -$head Base$$ -is the type corresponding to this $cref/ADFun/adfun/$$ object; -i.e., its calculations are done using the type $icode Base$$. - -$head RecBase$$ -in the prototype above, $icode RecBase$$ is the same type as $icode Base$$. - -$children% - example/json/from_json.cpp -%$$ -$head Example$$ -The file $cref from_json.cpp$$ is an example and test of this operation. - -$end -*/ -// BEGIN_PROTOTYPE -template -void CppAD::ADFun::from_json(const std::string& json) -// END_PROTOTYPE -{ - using CppAD::isnan; - // - // - // C++ graph object - cpp_graph graph_obj; - // - // convert json to graph representation - local::graph::json_parser(json, graph_obj); - // - // convert the graph representation to a function - from_graph(graph_obj); - // - return; -} - -# endif diff --git a/build-config/cppad/include/cppad/core/graph/graph_op_enum.hpp b/build-config/cppad/include/cppad/core/graph/graph_op_enum.hpp deleted file mode 100644 index 84eb8661..00000000 --- a/build-config/cppad/include/cppad/core/graph/graph_op_enum.hpp +++ /dev/null @@ -1,238 +0,0 @@ -# ifndef CPPAD_CORE_GRAPH_GRAPH_OP_ENUM_HPP -# define CPPAD_CORE_GRAPH_GRAPH_OP_ENUM_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ - -# include -# include -# include - -# include -# include - -/* -$begin graph_op_enum$$ -$spell - Cond - asinh - acosh - atanh - erf - erfc - expm - vec - enum - Exp - Gt - Le - notpos -$$ - -$section C++ AD Graph Operator Enum Type$$ - -$head Unary$$ -The unary operators have one argument and one result node. -The argument is a node index and the result is the next node. - -$subhead Require C++11$$ -The following unary operators require a compiler that supports c++11: -$code asinh$$, $code acosh$$, $code atanh$$, -$code erf$$, $code erfc$$, -$code expm1$$, $code log1p$$. - -$head Binary$$ -The binary operators have two arguments and one result node. -The arguments are node indices and the result is the next node. -The first (second) argument is the left (right) operand node index. - -$head Conditional Expression$$ -The conditional expression operators have four arguments and one result node. -The arguments are node indices and the result is the next node. -The first argument is $cref/left/CondExp/left/$$, -the second is $cref/right/CondExp/right/$$, -the third is $cref/if_true/CondExp/if_true/$$, -the fourth is $cref/if_false/CondExp/if_false/$$, -the result is given by -$codei% - if( %left% %cop% %right%) - %result% = %if_true%; - else - %result% = %if_false%; -%$$ -where $icode cop$$ is given in the comment after the enum type values below. - -$subhead Other Comparisons$$ -Note that -$codei% - CondExpGt(%left%, %right%, %if_true%, %if_false%) -%$$ -is equivalent to -$codei% - CondExpLe(%left%, %right%, %if_false%, %if_true%) -%$$ -Similar conversions can be used for all the possible -$cref/conditional expressions/CondExp/$$. - -$head Comparison$$ -The comparison operators have two arguments and no result node. -The first (second) argument is the left (right) operand node index. -The comparison result was true for the value of the independent -dynamic parameters and independent variables at which this graph was created. - -$subhead Other Comparisons$$ -The comparison result true for $icode%left% > %right%$$ -is equivalent to the comparison result true for $icode%right% < %left%$$. -The comparison result false for $icode%left% > %right%$$ -is equivalent to the comparison result true for $icode%left% <= %right%$$. -In a similar fashion, all the possible comparisons results -can be converted to a true result for one of the comparisons above. - -$head Summation$$ -The summation operator has one node result and a variable -number of arguments. -The first argument is the number of nodes in the summation, -and the other arguments are the indices of the nodes to be summed. -The total number of arguments for this operator -is one plus the number of nodes in the summation. - -$head Discrete Function$$ -The discrete function operator has two arguments and one node result. -The first argument is the index in -$cref/discrete_name_vec/cpp_ad_graph/discrete_name_vec/$$ for the -$cref/name/discrete/name/$$ of the discrete function that is called. -The second argument is the index of the node that is the argument -to the discrete function. - -$head Atomic Function$$ -The atomic function operator has a variable number of arguments -and a variable number of node results. -The total number of arguments for this operator is three plus the number -of arguments for the function being called. -$list number$$ -The first argument is the index in -$cref/atomic_name_vec/cpp_ad_graph/atomic_name_vec/$$ for the -$cref/name/atomic_three_ctor/atomic_three/name/$$ -of the $code atomic_three$$ function that is called. -$lnext -The second argument is the number of result for this function call. -The order of the results is determined by function being called. -$lnext -The third argument is the number of arguments -for this function call. -$lnext -The other arguments are the indices of nodes for each argument to the -function call. The order of the arguments is determined by function -being called. -$lend - -$head Print$$ -The print operator has four arguments. -$list number$$ -The first argument is the index in -$cref/print_text_vec/cpp_ad_graph/print_text_vec/$$ for the -$cref/before/PrintFor/before/$$ text for this print operator. -$lnext -The second argument is the index in -$cref/print_text_vec/cpp_ad_graph/print_text_vec/$$ for the -$cref/after/PrintFor/after/$$ text for this print operator. -$lnext -The third argument is the node corresponding to -$cref/notpos/PrintFor/notpos/$$ for this print operator. -$lnext -The fourth argument is the node corresponding to -$cref/value/PrintFor/value/$$ for this print operator. -$lend - - -$head Missing Operators$$ -As of yet the following $cref ADFun$$ operators do not have a corresponding -graph operator: -$list number$$ -Operators to load and store $cref VecAD$$ elements. -$lnext -An operator for the $cref atomic_two$$ interface. -$lend - - -$head Enum Values$$ -$srcthisfile% - 0%// BEGIN_SORT_THIS_LINE_PLUS_2%// END_SORT_THIS_LINE_MINUS_3%1 -%$$ - -$head Examples$$ - -$childtable% - example/graph/azmul_op.cpp% - example/graph/add_op.cpp% - example/graph/div_op.cpp% - example/graph/mul_op.cpp% - example/graph/pow_op.cpp% - example/graph/sub_op.cpp% - example/graph/unary_op.cpp% - example/graph/sum_op.cpp% - example/graph/comp_op.cpp% - example/graph/cexp_op.cpp% - example/graph/discrete_op.cpp% - example/graph/atom_op.cpp% - example/graph/print_op.cpp -%$$ - -$end -*/ -// BEGIN_SORT_THIS_LINE_PLUS_2 -namespace CppAD { namespace graph { - enum graph_op_enum { - abs_graph_op, // unary: absolute value - acos_graph_op, // unary: inverse cosine - acosh_graph_op, // unary: inverse hyperbolic cosine - add_graph_op, // binary: addition - asin_graph_op, // unary: inverse sine - asinh_graph_op, // unary: inverse hyperbolic sine - atan_graph_op, // unary: inverse tangent - atanh_graph_op, // unary: inverse hyperbolic tangent - atom_graph_op, // atomic function - azmul_graph_op, // binary: absolute zero multiplication - cexp_eq_graph_op, // conditional expression: == - cexp_le_graph_op, // conditional expression: <= - cexp_lt_graph_op, // conditional expression: < - comp_eq_graph_op, // comparison: == - comp_le_graph_op, // comparison: <= - comp_lt_graph_op, // comparison: < - comp_ne_graph_op, // comparison: != - cos_graph_op, // unary: cosine - cosh_graph_op, // unary: hyperbolic cosine - discrete_graph_op, // discrete function - div_graph_op, // binary: division - erf_graph_op, // unary: error function - erfc_graph_op, // unary: complementary error function - exp_graph_op, // unary: exponential - expm1_graph_op, // unary: exponential minus one - log1p_graph_op, // unary: logarithm of one plus argument - log_graph_op, // unary: logarithm - mul_graph_op, // binary: multiplication - pow_graph_op, // binary: first argument raised to second argument - print_graph_op, // print during zero order forward - sign_graph_op, // unary: sign of argument - sin_graph_op, // unary: sine - sinh_graph_op, // unary: hyperbolic sine - sqrt_graph_op, // unary: square root - sub_graph_op, // binary: subtraction - sum_graph_op, // summation - tan_graph_op, // unary: tangent - tanh_graph_op, // unary: hyperbolic tangent - n_graph_op // number of graph_op_enum operators - }; -} } -// END_SORT_THIS_LINE_MINUS_3 - - -# endif diff --git a/build-config/cppad/include/cppad/core/graph/json_ad_graph.omh b/build-config/cppad/include/cppad/core/graph/json_ad_graph.omh deleted file mode 100644 index a727f82b..00000000 --- a/build-config/cppad/include/cppad/core/graph/json_ad_graph.omh +++ /dev/null @@ -1,330 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin json_ad_graph$$ -$spell - Json - vec - enum_op - arg - ind - acyclic - str - np nx nc -$$ - -$section Json Representation of an AD Graph$$ - -$head See Also$$ -$tref cpp_ad_graph$$. - -$head Node Indices$$ -The nodes in an AD graph have the following order: -$pre - p_0 , ... , p_{np-1} , - x_0 , ... , x_{nx-1} , - c_0 , ... , c_{nc-1} , - r_0 , ... , r_{no-1} -$$ - -$subhead p$$ -The sub-vector -$pre p_0, ... , p_{np-1}$$ is the independent dynamic parameter vector; -see $cref/n_dynamic_ind/json_ad_graph/dynamic_ind_vec/n_dynamic_ind/$$. -The node index corresponding to $icode p_0$$ is $code 1$$. - -$subhead x$$ -The sub-vector -$pre x_0, ... , x_{nx-1}$$ is the independent variable vector; -see $cref/n_variable_ind/json_ad_graph/variable_ind_vec/n_variable_ind/$$. -The node index corresponding to $icode x_0$$ is -the index corresponding to $icode p_0$$ plus $icode np$$. - -$subhead c$$ -The sub-vector -$pre c_0, ... , c_{nc-1}$$ is the constant parameter vector; -see $cref/constant_vec/json_ad_graph/constant_vec/$$. -The node index corresponding to $icode c_0$$ is -the index corresponding to $icode x_0$$ plus $icode nx$$. - -$subhead r_i$$ -For $icode%i%=0,%...%,%no%-1%$$ -the sub-vector $pre r_i$$ -is the result vector for the $th i$$ operator usage; -see $cref/op_usage_vec/json_ad_graph/op_usage_vec/$$. -The value $icode no$$ is the number of operator usages; see -$cref/n_usage/json_ad_graph/op_usage_vec/n_usage/$$ below. -All of the arguments for an the $th i$$ operator are nodes -that come before the first element of $icode r_i$$. -The node index corresponding to the first element of $icode r_0$$ is -the index corresponding to $icode c_0$$ plus $icode nc$$. -For $icode%i% > 0%$$, -The node index corresponding to the first element of $icode r_i$$ is -the index corresponding to the first element of $icode r_{i-1}$$ plus -the number of results for the $th i-1$$ operator. - -$head Format$$ -A complete description of the format for an AD graph is given below. -For a general description of Json format see -$href% - https://en.wikipedia.org/wiki/JSON#Data_types_and_syntax% - Json data types and syntax -%$$. - -$head Token$$ - -$subhead White Space$$ -Any sequence of white space, except within a string, -terminates the current token and is otherwise ignored. - -$subhead Non-Negative Integer$$ -A non-negative integer is a non-empty sequence of the following -characters: $code 0123456789$$. - -$subhead Floating Point Number$$ -A floating point number is a non-empty sequence of the following -characters: $code 0123456789+-eE.$$. -Note that there can't be any white space between a leading plus -or minus sign and the rest of the number. - -$subhead String$$ -A string starts with the double quote character $code "$$ -and includes all the characters until the next double quote. -The value of a string is the sequence of characters between the -double quotes. -Currently there is no support using the double quote -as part of the value of a string. - -$subhead Single Character$$ -The following is a list of the single character tokens: -$table -Token $cnext Usage $rnext -$code ,$$ $cnext separates entries in a list $rnext -$code :$$ $cnext separates name from corresponding value $rnext -$code {$$ $cnext starts a list of name $code :$$ value pairs $rnext -$code }$$ $cnext ends a list of name $code:$$ value pairs $rnext -$code [$$ $cnext starts a list of values $rnext -$code ]$$ $cnext ends a list of values -$tend - -$head op_define_vec$$ -This vector has the following Json format: -$codei% - [ %n_define%, [ %first_op_define%, %...%, %last_op_define% ] ] -%$$ -where the non-negative integer $icode n_define$$ -is the number of operator definitions in this vector. - -$subhead op_define$$ -The possible operator definitions $icode op_define$$ are listed in -section $cref json_graph_op$$. -If an operator has a fixed number of arguments, one result, and -only node indices for arguments, its definition has the form -$codei% -{ - "op_code": %op_code%, - "name": %name%, - "n_arg": %n_arg% -} -%$$ -Otherwise the operator definition has the form -$codei% -{ - "op_code": %op_code%, - "name": %name% -} -%$$ -For example, the following is the $icode op_define$$ corresponding to the -$cref/add/json_graph_op/Binary Operators/add/$$ operator: -$codei% -{ - "op_code": %op_code%, - "name": "add", - "n_arg": 2 -} -%$$ - -$subhead op_code$$ -Note that every operator definition has a $icode op_code$$ value. -These values must start at one and increment by one for each operator -definition; i.e., the $icode op_code$$ for in $icode first_op_define$$ is -$code 1$$, the value in the next definition is $code 2$$, and so on. -The order of the definitions determines the $icode op_code$$ values -used to specify operators for this computational graph. - -$subhead n_arg$$ -This is the number of argument values for the operator; i.e., -the dimension of its domain space. -If it is present in an operator definition, -it is the same value for every usage of the operator. -Otherwise it is specified by the operator usage. - -$subhead n_result$$ -This is the number of results for the operator; i.e., -the dimension of its range space. -If $icode n_arg$$ is present in an operator definition, -$icode n_result$$ is one for every usage of the operator. -Otherwise it is specified by the operator usage. - -$head op_usage$$ -Each operation usage -has the following information: - -$subhead n_arg In Definition$$ -If $icode n_arg$$ is present in an operator definition, -it is not in a corresponding $icode op_usage$$ which as the form -$codei% - [ %op_code%, %first_arg%, %...%, %last_arg% ] -%$$ - -$subhead n_arg Not In Definition$$ -If $icode n_arg$$ is not in an operator definition, -it is in a corresponding $icode op_usage$$. -If there are no strings in a corresponding usage, it has the form -$codei% - [ %op_code%, %n_result%, %n_arg%, [ %first_arg%, %...%, %last_arg% ] ] -%$$ - -$subhead Strings In Usage$$ -If $icode n_arg$$ is not in an operator definition, -and there are strings in a corresponding usage, -a corresponding usage has the form -$codei% - [ %op_code%, %first_str%, %...%, %last_str%, %n_result%, %n_arg%, - [ %first_arg%, %...%, %last_arg% ] - ] -%$$ -where $icode first_str$$ ..., $icode last_str$$, -are a fixed number of strings that are part of the corresponding operator. - -$subhead first_arg, ..., last_arg$$ -The values $icode first_arg$$, ..., $icode last_arg$$, -are the node indices corresponding to each of the arguments for this operator. -They must be less than the node index corresponding to the first -result for this operator; see -$cref/r_i/json_ad_graph/Node Indices/r_i/$$ above. -They specify which previous results (results before this operator in the graph) -correspond to each of the arguments to this operator. -As a consequence, there cannot be any cycles in the graph where -the operators are represented by arcs from the argument to the result nodes; -i.e., the graph is acyclic. - -$head dynamic_ind_vec$$ -This is the independent dynamic parameter vector -(called $icode p$$ above); see -$cref/dynamic/Independent/dynamic/$$. -The function can depend on these parameters, -but no derivatives are computed with respect to these parameters. - -$subhead n_dynamic_ind$$ -We use the non-negative integer $icode n_dynamic_ind$$ -for the number of elements in this vector -(called $icode np$$ above). - -$head variable_ind_vec$$ -This is the independent variable vector -(called $icode x$$ above); see -$cref/x/Independent/x/$$. -The function can depend on these variable and -derivatives can be computed with respect to these variables. - -$subhead n_variable_ind$$ -We use the non-negative integer $icode n_variable_ind$$ -for the number of element in this vector -(called $icode nx$$ above). - -$head constant_vec$$ -This is the constant parameter vector (called $icode c$$ above). -These parameters can be used to define the function and cannot change. -The Json format for $icode constant_vec$$ is -$codei% - %n_constant%, [ %first_constant%, %...%, %last_constant% ] -%$$ -Each of the elements of this vector, -e.g., $icode first_constant$$, -is a $cref/floating point number/json_ad_graph/Token/Floating Point Number/$$ -specifying the value for the corresponding node. - -$subhead n_constant$$ -The non-negative integer $icode n_constant$$ -is the number of elements in this vector -(called $icode nc$$ above). - -$head op_usage_vec$$ -The Jason format for an $icode op_usage_vec$$ is -$codei% - [ %n_usage%, [ %first_op_usage%, %...%, %last_op_usage% ] ] -%$$ -Each of the elements of this vector, -e.g. $icode first_op_usage$$, -is an $cref/op_usage/json_ad_graph/op_usage/$$. - -$subhead n_usage$$ -The non-negative integer $icode n_usage$$ -is the number of operator usages (called $icode no$$ above). - -$head dependent_vec$$ -This is the vector of dependent variable node indices. -This identifies which nodes in the graph correspond to dependent variables. -The Json format for $icode dependent_vec$$ is -$codei% - [ %n_dependent%, [ %first_dependent%, %...%, %last_dependent% ] ] -%$$ -Each of the elements of this vector, -e.g. $icode first_dependent$$, -is a $cref/non-negative integer/json_ad_graph/Token/Non-Negative Integer/$$ -corresponding to a node index in the graph. - -$subhead n_dependent$$ -The non-negative integer $icode n_dependent$$ -is the number of elements in this vector. - -$head AD Graph$$ -Each operator corresponds to a set of arcs from its argument nodes -to its result nodes. -The graph is acyclic; see -$cref/ - first_arg, ..., last_arg/ - json_ad_graph/op_usage/ - first_arg, ..., last_arg -/$$. - -$subhead function_name$$ -A $icode function_name$$ is a -$cref/string/json_ad_graph/Token/String/$$ that is used to identify -the function. - -$subhead function$$ -The Json AD graph representation of a function is -$codei% -{ - "function_name": %function_name%, - "op_define_vec": %op_define_vec%, - "n_dynamic_ind": %n_dynamic_ind%, - "n_variable_ind": %n_variable_ind%, - "constant_vec": %constant_vec%, - "op_usage_vec": %op_usage_vec%, - "dependent_vec": %dependent_vec% -} -%$$ -This represents a the $latex y = f(x, p)$$ where -$latex p$$ is the dynamic parameter vector, -$latex x$$ is the independent variable vector, and -$latex y$$ is the dependent variable vector. - -$childtable%include/cppad/core/graph/json_graph_op.omh - %include/cppad/core/graph/from_json.hpp - %include/cppad/core/graph/to_json.hpp - %example/json/get_started.cpp - %example/json/sparse.cpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/graph/json_graph_op.omh b/build-config/cppad/include/cppad/core/graph/json_graph_op.omh deleted file mode 100644 index 0a80b46b..00000000 --- a/build-config/cppad/include/cppad/core/graph/json_graph_op.omh +++ /dev/null @@ -1,430 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin json_graph_op$$ -$spell - notpos - azmul - cexp_rel - eq - lt - le - Cond - Gt - log1p - expm1 - erfc - erf - atanh - asinh - acosh - acos - asin - atan - cos - exp - sqrt - tanh - Json - arg - op - mul - div - chkpoint - CppAD -$$ - -$section Json AD Graph Operator Definitions$$ - -$head Notation$$ - -$subhead op_code$$ -Each operator definition has a $icode op_code$$ value that -is used to identify it for a particular $icode json_ad_graph$$. - -$subhead Arguments$$ -The values $icode first_arg$$, ... , -$cref/last_arg/json_ad_graph/op_usage/first_arg, ..., last_arg/$$ -are the node indices for arguments to an operator. - -$head Unary Operators$$ -All these operations create one result node and -have the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": %name%, - "n_arg": 1 -} -%$$ -where $icode name$$ is a $cref/string/json_ad_graph/Token/String/$$. -A corresponding $icode op_usage$$ has the form -$codei% - [ %op_code%, %arg% ] -%$$ -The possible values for the string $icode name$$ are listed -in the table below. -The result is the node value as a function of the -argument value. -If c++11 is yes (no), -then c++11 or higher is required to use the operator with CppAD. - -$table -$icode name$$ $cnext result $cnext c++11 $rnext -$code abs$$ $cnext absolute value $cnext no $rnext -$code acos$$ $cnext inverse cosine $cnext no $rnext -$code asin$$ $cnext inverse sine $cnext no $rnext -$code atan$$ $cnext inverse tangent $cnext no $rnext -$code cosh$$ $cnext hyperbolic cosine $cnext no $rnext -$code cos$$ $cnext cosine $cnext no $rnext -$code exp$$ $cnext exponential $cnext no $rnext -$code log$$ $cnext logarithm $cnext no $rnext -$code sign$$ $cnext sign function $cnext no $rnext -$code sinh$$ $cnext hyperbolic sine $cnext no $rnext -$code sin$$ $cnext sine $cnext no $rnext -$code sqrt$$ $cnext square root $cnext no $rnext -$code tanh$$ $cnext hyperbolic tangent $cnext no $rnext -$code tan$$ $cnext tangent $cnext no $rnext -$code asinh$$ $cnext inverse hyperbolic sine $cnext yes $rnext -$code atanh$$ $cnext inverse hyperbolic sine $cnext yes $rnext -$code erf$$ $cnext error functions $cnext yes $rnext -$code erfc$$ $cnext complementary error function $cnext yes $rnext -$code expm1$$ $cnext minus one plus the exponential $cnext yes $rnext -$code log1p$$ $cnext log plus one $cnext yes $rnext -$code acosh$$ $cnext inverse hyperbolic cosine $cnext yes -$tend - -$subhead Example$$ -The file $cref json_unary_op.cpp$$ is an example and test -for one of these operators. - -$head Binary Operators$$ -All these operations create one result node and -have the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": %name%, - "n_arg": 2 -} -%$$ -where $icode name$$ is a $cref/string/json_ad_graph/Token/String/$$. -A corresponding $icode op_usage$$ has the form -$codei% - [ %op_code%, %first_arg%, %second_arg% ] -%$$ -The possible values for the string $icode name$$ are listed below: - -$subhead add$$ -The result is -the first argument value plus the second argument value; see -the example and test $cref json_add_op.cpp$$. - -$subhead azmul$$ -If the first argument value is zero, the result is zero -(even if the second argument value is nan). -Otherwise the result is -the first argument value times the second argument value; see -the example and test $cref json_azmul_op.cpp$$. - -$subhead div$$ -The result is -the first argument value divided by the second argument value; see -the example and test $cref json_div_op.cpp$$. - -$subhead mul$$ -The result is -the first argument value times the second argument value; see -the example and test $cref json_mul_op.cpp$$. - -$subhead pow$$ -The result is -the first argument value raised to the second argument value; see -the example and test $cref json_pow_op.cpp$$. - -$subhead sub$$ -The result is -the first argument value minus the second argument value; see -the example and test $cref json_sub_op.cpp$$. - -$head sum$$ -This operator has the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": "sum" -} -%$$ -A corresponding $icode op_usage$$ has the form -$codei% - [ %op_code%, %n_result%, %n_arg%, [ %first_arg%, %...%, %last_arg% ] ] -%$$ -where $icode n_result$$ is always $code 1$$. -This operation creates one node with value equal to -the sum of values corresponding to all of its argument nodes. - -$subhead Example$$ -The file $cref json_sum_op.cpp$$ is an example and test -of this operation. - -$head Conditional Expressions$$ -These operators are $cref/conditional expressions/CondExp/$$ -and have the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": "cexp_%rel%, - "n_arg": 4 -} -%$$ -where $icode rel$$ is $code eq$$ (equal), -$code le$$ (less than or equal), or -$code lt$$ (less than). -The first argument is $cref/left/CondExp/left/$$, -the second is $cref/right/CondExp/right/$$, -the third is $cref/if_true/CondExp/if_true/$$, -the fourth is $cref/if_false/CondExp/if_false/$$, -the result is given by -$codei% - if( %left% %cop% %right%) - %result% = %if_true%; - else - %result% = %if_false%; -%$$ -where the comparison $icode cop$$ is define by the cases below: - -$subhead cexp_eq$$ -For this operator $icode cop$$ is $code ==$$ - -$subhead cexp_le$$ -For this operator $icode cop$$ is $code <=$$ - -$subhead cexp_lt$$ -For this operator $icode cop$$ is $code <$$ - -$subhead Other Comparisons$$ -Note that -$codei% - CondExpGt(%left%, %right%, %if_true%, %if_false%) -%$$ -is equivalent to -$codei% - CondExpLe(%left%, %right%, %if_false%, %if_true%) -%$$ -Similar conversions can be used for all the possible -$cref/conditional expressions/CondExp/$$. - -$subhead Example$$ -The file $cref json_cexp_op.cpp$$ is an example and test -for one of these operators. - -$head Compare Operators$$ -These are $cref/comparison/Compare/$$ operators -and have the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": "comp_%rel%" -} -%$$ -where $icode rel$$ is $code eq$$ (equal), -$code ne$$ (not equal), -$code le$$ (less than or equal), or -$code lt$$ (less than). -A corresponding $icode op_usage$$ has the form -$codei% - [ %op_code%, %n_result%, %n_arg%, [ %left%, %right% ] ] -%$$ - -$subhead n_result$$ -This is always zero because a comparison operator does not create -any new nodes. - -$subhead n_arg$$ -This is always two because a comparison operator has two argument nodes -corresponding to the left and right operands. - -$subhead left, right$$ -The logical comparison is defined as the logical expression -$codei% - %left% %cop% %right% -%$$ -The comparison $icode cop$$ is define by the cases below. -The Json graph corresponds to the comparison being true. -If, for a value of the independent parameters and variables, -the comparison is false, -the Json graph may no longer be valid. -For example, the Json graph may only contain the code for the true case below: -$codei% - if( %left% %cop% %right% ) - { %source code when result is true% } - else - { %source code when result is false% } -%$$ -Including this operator enables CppAD to detect when the graph -may no longer be a valid representation of the intended function. - -$subhead comp_eq$$ -For this operator $icode cop$$ is $code ==$$ - -$subhead comp_le$$ -For this operator $icode cop$$ is $code <=$$ - -$subhead comp_lt$$ -For this operator $icode cop$$ is $code <$$ - -$subhead comp_ne$$ -For this operator $icode cop$$ is $code !=$$ - -$subhead Other Comparisons$$ -The comparison result true for $icode%left% > %right%$$ -is equivalent to the comparison result true for $icode%right% < %left%$$. -The comparison result false for $icode%left% > %right%$$ -is equivalent to the comparison result true for $icode%left% <= %right%$$. -In a similar fashion, all the possible comparisons results -can be converted to a true result for one of the comparisons above. - -$subhead Example$$ -The file $cref json_comp_op.cpp$$ is an example and test -for one of these operators. - -$head Discrete Functions$$ -This operator has the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": "discrete" -} -%$$ -A corresponding op_usage has the form -$codei% - [ %op_code%, %name%, %n_result%, %n_arg%, [ %arg% ] ] -%$$ - -$subhead name$$ -The value $icode name$$ is a -$cref/string/json_ad_graph/Token/String/$$ specifying the -$cref/name/discrete/name/$$ of the discrete function that is called. - -$subhead n_result$$ -This is always $code 1$$ because a discrete function -creates one new node. -The result node value is the specified discrete function of the argument value. - -$subhead n_arg$$ -This is always $code 1$$ because a discrete function has -one argument node. - -$subhead arg$$ -is the node index for the argument to the discrete function. - -$subhead Example$$ -the example and test $cref json_discrete_op.cpp$$. - - -$head Atomic Functions$$ -This operator has the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": "atom" -} -%$$ -A corresponding $icode op_usage$$ has the form -$codei% - [ %op_code%, %name%, %n_result%, %n_arg%, - [ %first_arg%, %...%, %last_arg% ] - ] -%$$ -This operator creates $icode n_result$$ nodes with values equal to -an evaluation of the $code atomic_three$$ function. - -$subhead name$$ -The value $icode name$$ is a -$cref/string/json_ad_graph/Token/String/$$ specifying the -$cref/name/atomic_three_ctor/atomic_three/name/$$ -of the $code atomic_three$$ function that is called. - -$subhead n_result$$ -is the number of results for this function; i.e., -its range space dimension. - -$subhead n_arg$$ -is the number of arguments to this function; i.e., -its domain space dimension. - -$subhead first_arg, ..., last_arg$$ -The values corresponding to the node indices -$icode first_arg$$, ..., $icode last_arg$$ are the -arguments (independent variables) for the atomic function evaluation. -In the case where the atomic function is a $code chkpoint_two$$ function, -the independent dynamic parameters are specified by calling its -$cref/new_dynamic/chkpoint_two/Syntax/new_dynamic/$$ routine. - -$subhead Example$$ -the example and test $cref json_atom_op.cpp$$. - -$head Print$$ -This operator has the following Json definition: -$codei% -{ - "op_code": %op_code%, - "name": "print" -} -%$$ -A corresponding $icode op_usage$$ has the form -$codei% - [ %op_code%, %before%, %after%, %n_result%, %n_arg%, [ %notpos%, %value% ] ] -%$$ - -$subhead before$$ -is a $cref/string/json_ad_graph/Token/String/$$ that is printed -$cref/before/PrintFor/before/$$ the value for this operator. - -$subhead after$$ -is a $cref/string/json_ad_graph/Token/String/$$ that is printed -$cref/after/PrintFor/after/$$ the value for this operator. - -$subhead n_result$$ -This is always zero because a print operator does not create -any new nodes. - -$subhead n_arg$$ -This is always two because a print operator has two argument nodes. - -$subhead notpos$$ -This is $cref/notpos/PrintFor/notpos/$$ -which determines if the value is printed. - -$subhead value$$ -This is the $cref/value/PrintFor/value/$$ that is printed. - -$subhead Example$$ -The file $cref json_print_op.cpp$$ is an example and test -of this operator. - -$childtable% - example/json/unary_op.cpp% - example/json/add_op.cpp% - example/json/azmul_op.cpp% - example/json/discrete_op.cpp% - example/json/div_op.cpp% - example/json/mul_op.cpp% - example/json/pow_op.cpp% - example/json/print_op.cpp% - example/json/sub_op.cpp% - example/json/sum_op.cpp% - example/json/comp_op.cpp% - example/json/cexp_op.cpp% - example/json/atom_op.cpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/graph/to_graph.hpp b/build-config/cppad/include/cppad/core/graph/to_graph.hpp deleted file mode 100644 index 02654e51..00000000 --- a/build-config/cppad/include/cppad/core/graph/to_graph.hpp +++ /dev/null @@ -1,1199 +0,0 @@ -# ifndef CPPAD_CORE_GRAPH_TO_GRAPH_HPP -# define CPPAD_CORE_GRAPH_TO_GRAPH_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-21 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -/* ------------------------------------------------------------------------------- -$begin to_graph$$ -$spell - Json - cpp - ind - vec - arg - obj - op_enum -$$ - -$section Create a C++ AD Graph Corresponding to an ADFun Object$$ - -$head Syntax$$ -$codei% - ADFun<%Base%> %fun% - %fun%.to_graph(%graph_obj%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Base$$ -is the type corresponding to this $cref/ADFun/adfun/$$ object; -i.e., its calculations are done using the type $icode Base$$. - -$head RecBase$$ -in the prototype above, $icode RecBase$$ is the same type as $icode Base$$. - -$head graph_obj$$ -This is a $code cpp_graph$$ object. -The input value of the object does not matter. -Upon return it is a $cref cpp_ad_graph$$ representation of this function. - -$head Restrictions$$ -The $code to_graph$$ routine is not yet implement for some -possible $cref ADFun$$ operators; see -$cref/missing operators/graph_op_enum/Missing Operators/$$. - -$head Examples$$ -See $cref/graph_op_enum examples/graph_op_enum/Examples/$$. - -$end -*/ -// BEGIN_PROTOTYPE -template -void CppAD::ADFun::to_graph( - CppAD::cpp_graph& graph_obj ) -// END_PROTOTYPE -{ using local::pod_vector; - using local::opcode_t; - using namespace CppAD::graph; - // -------------------------------------------------------------------- - if( local::graph::op_name2enum.size() == 0 ) - { CPPAD_ASSERT_KNOWN( ! thread_alloc::in_parallel() , - "call to set_operator_info in parallel mode" - ); - local::graph::set_operator_info(); - } - // -# ifndef NDEBUG -# endif - graph_obj.initialize(); - // - // -------------------------------------------------------------------- - // some constants - // -------------------------------------------------------------------- - // - // output: function_name - graph_obj.function_name_set(function_name_); - // - // dynamic parameter information - const pod_vector& dyn_par_op ( play_.dyn_par_op() ); - const pod_vector& dyn_par_arg( play_.dyn_par_arg() ); - const pod_vector& dyn_ind2par_ind ( play_.dyn_ind2par_ind() ); - const pod_vector& dyn_par_is( play_.dyn_par_is() ); - // - // number of dynamic parameters - const size_t n_dynamic = dyn_ind2par_ind.size(); - // - // output: n_dynamic_ind - size_t n_dynamic_ind = play_.num_dynamic_ind(); - graph_obj.n_dynamic_ind_set(n_dynamic_ind); - // - // number of parameters - const size_t n_parameter = play_.num_par_rec(); - // - // number of constant parameters -# ifndef NDEBUG - const size_t n_constant = n_parameter - n_dynamic - 1; -# endif - // - // output: n_variable_ind - size_t n_variable_ind = ind_taddr_.size(); - graph_obj.n_variable_ind_set(n_variable_ind); - // - // value of parameters - const Base* parameter = play_.GetPar(); - // - // number of variables - const size_t n_variable = play_.num_var_rec(); - // - // some checks - CPPAD_ASSERT_UNKNOWN( n_dynamic_ind <= n_dynamic ); - CPPAD_ASSERT_UNKNOWN( dyn_par_is.size() == n_parameter ); - CPPAD_ASSERT_UNKNOWN( n_parameter > 0 ); - CPPAD_ASSERT_UNKNOWN( isnan( parameter[0] ) ); - CPPAD_ASSERT_UNKNOWN( ! dyn_par_is[0] ); - // -------------------------------------------------------------------- - // par2node - pod_vector par2node(n_parameter); - par2node[0] = 0; // invalid value - for(size_t i = 1; i <= n_dynamic_ind; ++i) - par2node[i] = i; // independent dynamic parameters - for(size_t i = n_dynamic_ind + 1; i < n_parameter; ++i) - par2node[i] = 0; // will be set later - // ---------------------------------------------------------------------- - // - // initialize index of previous node in the graph - size_t previous_node = 0; - // - // n_dynamic_ind - previous_node += n_dynamic_ind; - // - // n_variable_ind - previous_node += n_variable_ind; - // -------------------------------------------------------------------- - // - // output: constant_vec - // constant_vec and par2node for constants - for(size_t i = 1; i < n_parameter; ++i) - { if( ! dyn_par_is[i] ) - { // this is a constant node - graph_obj.constant_vec_push_back( parameter[i] ); - par2node[i] = ++previous_node; - } - } - CPPAD_ASSERT_UNKNOWN( n_constant == graph_obj.constant_vec_size() ); - // ---------------------------------------------------------------------- - // output: initialize atomic_name_vec, operator_vec, operator_arg - // temporary used for elements of operator_vec - // - // Json operators are dynamic operators plus variables operators. - // Skip BeginOp, EndOp, and independent variables. - // - // dynamic parameter operations and par2node - // for dynamic parameters that are not constants or independent - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(local::ind_dyn) == 0 ); - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(local::atom_dyn) == 0 ); - size_t i_arg = 0; - pod_vector node_arg; - - for(size_t i_dyn = n_dynamic_ind; i_dyn < n_dynamic; ++i_dyn) - { // operator for this dynamic parameter - local::op_code_dyn dyn_op = local::op_code_dyn( dyn_par_op[i_dyn] ); - // - // parameter index for this dynamic parameter - size_t i_par = size_t( dyn_ind2par_ind[i_dyn] ); - CPPAD_ASSERT_UNKNOWN( par2node[i_par] == 0 ); - par2node[i_par] = ++previous_node; - // - // number of arguments for operators with exception of atom_dyn - size_t n_arg = num_arg_dyn(dyn_op); - if( n_arg > node_arg.size() ) - node_arg.resize(n_arg); - // - // parameter arguments in graph node space (except for atom_dyn) - if( dyn_op != local::atom_dyn ) - { size_t offset_par = num_non_par_arg_dyn(dyn_op); - for(size_t i = offset_par; i < n_arg; ++i) - { node_arg[i] = par2node[ dyn_par_arg[i_arg + i] ]; - CPPAD_ASSERT_UNKNOWN( node_arg[i] > 0 ); - } - } - // - // invalid value - graph_op_enum graph_op = n_graph_op; - switch(dyn_op) - { - // --------------------------------------------------------------- - // unary operators - - case local::abs_dyn: - case local::fabs_dyn: - graph_op = abs_graph_op; - break; - - case local::acosh_dyn: - graph_op = acosh_graph_op; - break; - - case local::asinh_dyn: - graph_op = asinh_graph_op; - break; - - case local::atanh_dyn: - graph_op = atanh_graph_op; - break; - - case local::erf_dyn: - graph_op = erf_graph_op; - break; - - case local::erfc_dyn: - graph_op = erfc_graph_op; - break; - - case local::expm1_dyn: - graph_op = expm1_graph_op; - break; - - case local::log1p_dyn: - graph_op = log1p_graph_op; - break; - - case local::acos_dyn: - graph_op = acos_graph_op; - break; - - case local::asin_dyn: - graph_op = asin_graph_op; - break; - - case local::atan_dyn: - graph_op = atan_graph_op; - break; - - case local::cosh_dyn: - graph_op = cosh_graph_op; - break; - - case local::cos_dyn: - graph_op = cos_graph_op; - break; - - case local::exp_dyn: - graph_op = exp_graph_op; - break; - - case local::log_dyn: - graph_op = log_graph_op; - break; - - case local::sign_dyn: - graph_op = sign_graph_op; - break; - - case local::sinh_dyn: - graph_op = sinh_graph_op; - break; - - case local::sin_dyn: - graph_op = sin_graph_op; - break; - - case local::sqrt_dyn: - graph_op = sqrt_graph_op; - break; - - case local::tanh_dyn: - graph_op = tanh_graph_op; - break; - - case local::tan_dyn: - graph_op = tan_graph_op; - break; - - // --------------------------------------------------------------- - // binary operators - - case local::add_dyn: - graph_op = add_graph_op; - break; - - case local::div_dyn: - graph_op = div_graph_op; - break; - - case local::mul_dyn: - graph_op = mul_graph_op; - break; - - case local::pow_dyn: - graph_op = pow_graph_op; - break; - - case local::sub_dyn: - graph_op = sub_graph_op; - break; - - case local::zmul_dyn: - graph_op = azmul_graph_op; - break; - - // --------------------------------------------------------------- - // graph_op determined later for these cases - case local::atom_dyn: - case local::cond_exp_dyn: - case local::dis_dyn: - case local::result_dyn: - break; - - // --------------------------------------------------------------- - default: - // This error should have been reported above - CPPAD_ASSERT_UNKNOWN( false ); - break; - } - switch( dyn_op ) - { // -------------------------------------------------------------- - case local::result_dyn: - // setting par2node[i_dyn] above is all that is necessary - CPPAD_ASSERT_UNKNOWN( n_arg == 0 ); - break; - - // -------------------------------------------------------------- - case local::dis_dyn: - { - // arg[0]: discrete function index - size_t discrete_index = size_t( dyn_par_arg[i_arg + 0] ); - // get the name for this dicrete function - std::string name = discrete::name( discrete_index ); - // - // set graph index for this discrete function call - size_t name_index = graph_obj.discrete_name_vec_find(name); - if( name_index == graph_obj.discrete_name_vec_size() ) - graph_obj.discrete_name_vec_push_back(name); - // - graph_op = discrete_graph_op; - graph_obj.operator_vec_push_back( graph_op ); - graph_obj.operator_arg_push_back( name_index ); - graph_obj.operator_arg_push_back( node_arg[1] ); - } - break; - - // -------------------------------------------------------------- - case local::atom_dyn: - { - // arg[0]: atomic function index - size_t atom_index = size_t( dyn_par_arg[i_arg + 0] ); - // arg[1]: number of arguments to function - n_arg = size_t( dyn_par_arg[i_arg + 1] ); - // arg[2]: number of results from function - size_t n_result = size_t( dyn_par_arg[i_arg + 2] ); - // - // get the name for this atomic function - std::string name; - { bool set_null = false; - size_t type; - void* ptr; - CppAD::local::atomic_index( - set_null, atom_index, type, &name, ptr - ); - } - // set graph index for this atomic function call - size_t name_index = graph_obj.atomic_name_vec_find(name); - if( name_index == graph_obj.atomic_name_vec_size() ) - graph_obj.atomic_name_vec_push_back(name); - // - // for atom_graph_op: - // name_index, n_result, n_arg come before first_node - graph_obj.operator_arg_push_back(name_index); - graph_obj.operator_arg_push_back(n_result); - graph_obj.operator_arg_push_back(n_arg); - // - graph_op = atom_graph_op; - graph_obj.operator_vec_push_back( graph_op ); - // - for(size_t j = 0; j < n_arg; ++j) - { // arg[4 + j] is j-th argument to the function - size_t node_j = par2node[ dyn_par_arg[i_arg + 4 + j] ]; - CPPAD_ASSERT_UNKNOWN( node_j < i_par ); - graph_obj.operator_arg_push_back( node_j ); - } - } - break; - - // -------------------------------------------------------------- - case local::cond_exp_dyn: - { - CompareOp cop = CompareOp( dyn_par_arg[i_arg + 0] ); - size_t left = node_arg[1]; - size_t right = node_arg[2]; - size_t if_true = node_arg[3]; - size_t if_false = node_arg[4]; - switch( cop ) - { case CompareLt: - graph_op = cexp_lt_graph_op; - break; - - case CompareLe: - graph_op = cexp_le_graph_op; - break; - - case CompareEq: - graph_op = cexp_eq_graph_op; - break; - - case CompareGe: - graph_op = cexp_lt_graph_op; - std::swap(if_true, if_false); - break; - - case CompareGt: - graph_op = cexp_le_graph_op; - std::swap(if_true, if_false); - break; - - case CompareNe: - graph_op = cexp_eq_graph_op; - std::swap(if_true, if_false); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - graph_obj.operator_vec_push_back( graph_op ); - graph_obj.operator_arg_push_back( left ); - graph_obj.operator_arg_push_back( right ); - graph_obj.operator_arg_push_back( if_true ); - graph_obj.operator_arg_push_back( if_false ); - } - break; - - // -------------------------------------------------------------- - // unary or binary - default: - CPPAD_ASSERT_UNKNOWN((n_arg == 1) | (n_arg == 2)); - // - graph_obj.operator_vec_push_back( graph_op ); - for(size_t i = 0; i < n_arg; ++i) - graph_obj.operator_arg_push_back( node_arg[i] ); - break; - } - i_arg += n_arg; - } - // ---------------------------------------------------------------------- - // variable operators - pod_vector var2node(n_variable); - var2node[0] = 0; // invalide node value - for(size_t i = 1; i <= n_variable_ind; ++i) - var2node[i] = n_dynamic_ind + i; - for(size_t i = n_variable_ind + 1; i < n_variable; ++i) - var2node[i] = 0; // invalid node value - // - local::play::const_sequential_iterator itr = play_.begin(); - local::OpCode var_op; - const addr_t* arg; - size_t i_var; - pod_vector is_var(2); - vector atom_node_arg; - bool in_atomic_call = false; - bool more_operators = true; - while(more_operators) - { // if non-zero, this is a fixed size operator with this many arguments - // and implemented after the switch. In additionk, is_var is set for - // each of the at most 2 arguments. - size_t fixed_n_arg = 0; - - // invalid value - graph_op_enum graph_op = n_graph_op; - - // next op - (++itr).op_info(var_op, arg, i_var); - - - // ------------------------------------------------------------------- - // Cases with fixed number of arguments, one or two arguments, and - // operator is not ignored. - // ------------------------------------------------------------------- - switch( var_op ) - { - // ------------------------------------------------------------- - // unary operators - case local::AbsOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::AcoshOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::AsinhOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::AtanhOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::ErfOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::ErfcOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::Expm1Op: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::Log1pOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::AcosOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::AsinOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::AtanOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::CoshOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::CosOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::ExpOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::LogOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::SignOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::SinhOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::SinOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::SqrtOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::TanhOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - case local::TanOp: - fixed_n_arg = 1; - is_var[0] = true; - break; - - // --------------------------------------------------------------- - // binary operators - // --------------------------------------------------------------- - - // first argument a parameter, second argument a variable - case local::AddpvOp: - case local::DivpvOp: - case local::MulpvOp: - case local::PowpvOp: - case local::SubpvOp: - case local::ZmulpvOp: - fixed_n_arg = 2; - is_var[0] = false; - is_var[1] = true; - break; - - // first argument a variable, second argument a parameter - case local::DivvpOp: - case local::PowvpOp: - case local::SubvpOp: - case local::ZmulvpOp: - fixed_n_arg = 2; - is_var[0] = true; - is_var[1] = false; - break; - - // first argument a variable, second argument a variable - case local::AddvvOp: - case local::DivvvOp: - case local::MulvvOp: - case local::PowvvOp: - case local::SubvvOp: - case local::ZmulvvOp: - fixed_n_arg = 2; - is_var[0] = true; - is_var[1] = true; - break; - - // -------------------------------------------------------------- - default: - break; - } - if( fixed_n_arg > 0 ) - { // Set graph_op - switch( var_op ) - { - // ---------------------------------------------------------- - // unary operators - - case local::AbsOp: - graph_op = abs_graph_op; - break; - - case local::AcoshOp: - graph_op = acosh_graph_op; - break; - - case local::AsinhOp: - graph_op = asinh_graph_op; - break; - - case local::AtanhOp: - graph_op = atanh_graph_op; - break; - - case local::ErfOp: - graph_op = erf_graph_op; - break; - - case local::ErfcOp: - graph_op = erfc_graph_op; - break; - - case local::Expm1Op: - graph_op = expm1_graph_op; - break; - - case local::Log1pOp: - graph_op = log1p_graph_op; - break; - - case local::AcosOp: - graph_op = acos_graph_op; - break; - - case local::AsinOp: - graph_op = asin_graph_op; - break; - - case local::AtanOp: - graph_op = atan_graph_op; - break; - - case local::CoshOp: - graph_op = cosh_graph_op; - break; - - case local::CosOp: - graph_op = cos_graph_op; - break; - - case local::ExpOp: - graph_op = exp_graph_op; - break; - - case local::LogOp: - graph_op = log_graph_op; - break; - - case local::SignOp: - graph_op = sign_graph_op; - break; - - case local::SinhOp: - graph_op = sinh_graph_op; - break; - - case local::SinOp: - graph_op = sin_graph_op; - break; - - case local::SqrtOp: - graph_op = sqrt_graph_op; - break; - - case local::TanhOp: - graph_op = tanh_graph_op; - break; - - case local::TanOp: - graph_op = tan_graph_op; - break; - - // ----------------------------------------------------------- - // binary operators - - case local::AddpvOp: - case local::AddvvOp: - graph_op = add_graph_op; - break; - - case local::DivpvOp: - case local::DivvpOp: - case local::DivvvOp: - graph_op = div_graph_op; - break; - - case local::MulpvOp: - case local::MulvvOp: - graph_op = mul_graph_op; - break; - - case local::PowpvOp: - case local::PowvpOp: - case local::PowvvOp: - graph_op = pow_graph_op; - break; - - case local::SubpvOp: - case local::SubvpOp: - case local::SubvvOp: - graph_op = sub_graph_op; - break; - - case local::ZmulpvOp: - case local::ZmulvpOp: - case local::ZmulvvOp: - graph_op = azmul_graph_op; - break; - - // ----------------------------------------------------------- - default: - // This should be one of the cases above - CPPAD_ASSERT_UNKNOWN(false); - break; - } - // - // var2node and previous_node for this operator - var2node[i_var] = ++previous_node; - // - // - graph_obj.operator_vec_push_back( graph_op ); - for(size_t i = 0; i < fixed_n_arg; ++i) - { if( is_var[i] ) - graph_obj.operator_arg_push_back( var2node[ arg[i] ] ); - else - graph_obj.operator_arg_push_back( par2node[ arg[i] ] ); - } - } - // ------------------------------------------------------------------- - // Other cases - // ------------------------------------------------------------------- - else switch( var_op ) - { - // ------------------------------------------------------------- - // comparison operators - case local::EqppOp: - case local::EqpvOp: - case local::EqvvOp: - case local::NeppOp: - case local::NepvOp: - case local::NevvOp: - case local::LtppOp: - case local::LtpvOp: - case local::LtvpOp: - case local::LtvvOp: - case local::LeppOp: - case local::LepvOp: - case local::LevpOp: - case local::LevvOp: - { // node_0, node_1 - size_t node_0, node_1; - switch( var_op ) - { // both nodes parameters - case local::EqppOp: - case local::NeppOp: - case local::LtppOp: - case local::LeppOp: - node_0 = par2node[arg[0]]; - node_1 = par2node[arg[1]]; - break; - - // first node parameter, second variable - case local::EqpvOp: - case local::NepvOp: - case local::LtpvOp: - case local::LepvOp: - node_0 = par2node[arg[0]]; - node_1 = var2node[arg[1]]; - break; - - // first node variable, second parameter - case local::LtvpOp: - case local::LevpOp: - node_0 = var2node[arg[0]]; - node_1 = par2node[arg[1]]; - break; - - // both nodes variables - case local::EqvvOp: - case local::NevvOp: - case local::LtvvOp: - case local::LevvOp: - node_0 = var2node[arg[0]]; - node_1 = var2node[arg[1]]; - break; - - // should never get here - default: - CPPAD_ASSERT_UNKNOWN(false); - node_0 = 0; // to avoid compiler warning - node_1 = 0; - break; - } - // Set graph_op - switch( var_op ) - { - case local::EqppOp: - case local::EqpvOp: - case local::EqvvOp: - graph_op = comp_eq_graph_op; - break; - - case local::NeppOp: - case local::NepvOp: - case local::NevvOp: - graph_op = comp_ne_graph_op; - break; - - case local::LtppOp: - case local::LtpvOp: - case local::LtvpOp: - case local::LtvvOp: - graph_op = comp_lt_graph_op; - break; - - case local::LeppOp: - case local::LepvOp: - case local::LevpOp: - case local::LevvOp: - graph_op = comp_le_graph_op; - break; - - // should never get here - default: - CPPAD_ASSERT_UNKNOWN(false); - graph_op = n_graph_op; // invalid values - break; - } - graph_obj.operator_vec_push_back( graph_op ); - graph_obj.operator_arg_push_back( node_0 ); - graph_obj.operator_arg_push_back( node_1 ); - } - break; - - // -------------------------------------------------------------- - // CSumOp - case local::CSumOp: - { // does this case have subtraction terms - bool has_subtract = (arg[1] != arg[2]) | (arg[3] != arg[4]); - // - // var2node for this operator - if( has_subtract ) - { // two cumulative sum and one subtract operators - var2node[i_var] = previous_node + 3; - } - else - { // one cumulative sum operator - var2node[i_var] = previous_node + 1; - } - // - // previous_node + 1 = sum corresponding to addition terms - // - graph_op = sum_graph_op; - CPPAD_ASSERT_UNKNOWN( 5 <= arg[1] ); - CPPAD_ASSERT_UNKNOWN( arg[2] <= arg[3] ); - size_t n_arg = size_t(1 + arg[1] - 5 + arg[3] - arg[2]); - // - // n_arg comes befrore first_node - graph_obj.operator_arg_push_back(n_arg); - // - // graph_op for addition terms - graph_obj.operator_vec_push_back( graph_op ); - // - // argument nodes - size_t arg_node = par2node[ arg[0] ]; - graph_obj.operator_arg_push_back( arg_node ); - size_t j_arg = 1; - for(addr_t i = 5; i < arg[1]; ++i) - { arg_node = var2node[ arg[i] ]; - CPPAD_ASSERT_UNKNOWN( arg_node > 0 ); - graph_obj.operator_arg_push_back( arg_node ); - ++j_arg; - } - for(addr_t i = arg[2]; i < arg[3]; ++i) - { arg_node = par2node[ arg[i] ]; - CPPAD_ASSERT_UNKNOWN( arg_node > 0 ); - graph_obj.operator_arg_push_back( arg_node ); - ++j_arg; - } - CPPAD_ASSERT_UNKNOWN( j_arg == n_arg ); - if( has_subtract ) - { // previous_node + 2 = sum corresponding to subtract terms - CPPAD_ASSERT_UNKNOWN( arg[1] <= arg[2] ); - CPPAD_ASSERT_UNKNOWN( arg[3] <= arg[4] ); - n_arg = size_t(arg[2] - arg[1] + arg[4] - arg[3]); - // - // n_arg comes before first_node - graph_obj.operator_arg_push_back(n_arg); - // - // graph_op for subtraction terms - graph_op = sum_graph_op; - graph_obj.operator_vec_push_back( graph_op ); - // - // argument nodes - j_arg = 0; - for(addr_t i = arg[1]; i < arg[2]; ++i) - { arg_node = var2node[ arg[i] ]; - CPPAD_ASSERT_UNKNOWN( arg_node > 0 ); - graph_obj.operator_arg_push_back( arg_node ); - ++j_arg; - } - for(addr_t i = arg[3]; i < arg[4]; ++i) - { arg_node = par2node[ arg[i] ]; - CPPAD_ASSERT_UNKNOWN( arg_node > 0 ); - graph_obj.operator_arg_push_back( arg_node ); - ++j_arg; - } - CPPAD_ASSERT_UNKNOWN( j_arg == n_arg ); - // - // previous_node + 3 = first sum minus second sum - graph_op = sub_graph_op; - graph_obj.operator_vec_push_back( graph_op ); - graph_obj.operator_arg_push_back( previous_node + 1 ); - graph_obj.operator_arg_push_back( previous_node + 2 ); - } - // previous node - if( has_subtract ) - previous_node += 3; - else - previous_node += 1; - } - itr.correct_before_increment(); - break; - - // -------------------------------------------------------------- - case local::DisOp: - { // discrete function index - size_t discrete_index = size_t( arg[0] ); - // name of this discrete function - std::string name = discrete::name( discrete_index ); - // - // set graph index for this discrete function call - size_t name_index = graph_obj.discrete_name_vec_find(name); - if( name_index == graph_obj.discrete_name_vec_size() ) - graph_obj.discrete_name_vec_push_back(name); - // - graph_op = discrete_graph_op; - graph_obj.operator_vec_push_back( graph_op ); - graph_obj.operator_arg_push_back( name_index ); - graph_obj.operator_arg_push_back( var2node[arg[1]] ); - // - var2node[i_var] = ++previous_node; - } - break; - // -------------------------------------------------------------- - case local::PriOp: - { - // before - std::string before( play_.GetTxt( size_t(arg[2]) ) ); - size_t before_index = graph_obj.print_text_vec_find(before); - if( before_index == graph_obj.print_text_vec_size() ) - graph_obj.print_text_vec_push_back(before); - // after - std::string after( play_.GetTxt( size_t(arg[4]) ) ); - size_t after_index = graph_obj.print_text_vec_find(after); - if( after_index == graph_obj.print_text_vec_size() ) - graph_obj.print_text_vec_push_back(after); - // notpos - size_t notpos_node; - if( arg[0] & 1 ) - notpos_node = var2node[ arg[1] ]; - else - notpos_node = par2node[ arg[1] ]; - // value - size_t value_node; - if( arg[0] & 1 ) - value_node = var2node[ arg[3] ]; - else - value_node = par2node[ arg[3] ]; - // - graph_op = print_graph_op; - graph_obj.operator_vec_push_back( graph_op ); - graph_obj.operator_arg_push_back( before_index ); - graph_obj.operator_arg_push_back( after_index ); - graph_obj.operator_arg_push_back( notpos_node ); - graph_obj.operator_arg_push_back( value_node ); - } - break; - - // -------------------------------------------------------------- - case local::FunapOp: - atom_node_arg.push_back( par2node[arg[0]] ); - break; - - case local::FunavOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var ); - atom_node_arg.push_back( var2node[arg[0]] ); - break; - - case local::FunrpOp: - par2node[arg[0]] = ++previous_node; - break; - - case local::FunrvOp: - var2node[i_var] = ++previous_node; - break; - - case local::AFunOp: - in_atomic_call = ! in_atomic_call; - if( in_atomic_call ) - { atom_node_arg.resize(0); - } - else - { // This is the AFunOp at the end of the call - size_t atom_index = size_t( arg[0] ); - size_t n_arg = size_t( arg[2] ); - size_t n_result = size_t( arg[3] ); - CPPAD_ASSERT_UNKNOWN( atom_node_arg.size() == n_arg ); - // - // get the name for this atomic function - std::string name; - { bool set_null = false; - size_t type; - void* ptr; - CppAD::local::atomic_index( - set_null, atom_index, type, &name, ptr - ); - } - // set graph index for this atomic function - size_t name_index = graph_obj.atomic_name_vec_find(name); - if( name_index == graph_obj.atomic_name_vec_size() ) - graph_obj.atomic_name_vec_push_back(name); - // - // for atom_graph_op: - // name_index, n_result, n_arg come before first_node - graph_obj.operator_arg_push_back(name_index); - graph_obj.operator_arg_push_back(n_result); - graph_obj.operator_arg_push_back(n_arg); - // - graph_op = atom_graph_op; - graph_obj.operator_vec_push_back( graph_op ); - for(size_t i = 0; i < n_arg; ++i) - graph_obj.operator_arg_push_back( atom_node_arg[i] ); - } - break; - // -------------------------------------------------------------- - // CExpOp: - case local::CExpOp: - { CompareOp cop = CompareOp( arg[0] ); - size_t left, right, if_true, if_false; - if( arg[1] & 1 ) - left = var2node[ arg[2] ]; - else - left = par2node[ arg[2] ]; - if( arg[1] & 2 ) - right = var2node[ arg[3] ]; - else - right = par2node[ arg[3] ]; - if( arg[1] & 4 ) - if_true = var2node[ arg[4] ]; - else - if_true = par2node[ arg[4] ]; - if( arg[1] & 8 ) - if_false = var2node[ arg[5] ]; - else - if_false = par2node[ arg[5] ]; - switch( cop ) - { case CompareLt: - graph_op = cexp_lt_graph_op; - break; - - case CompareLe: - graph_op = cexp_le_graph_op; - break; - - case CompareEq: - graph_op = cexp_eq_graph_op; - break; - - case CompareGe: - graph_op = cexp_lt_graph_op; - std::swap(if_true, if_false); - break; - - case CompareGt: - graph_op = cexp_le_graph_op; - std::swap(if_true, if_false); - break; - - case CompareNe: - graph_op = cexp_eq_graph_op; - std::swap(if_true, if_false); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - // var2node and previous_node for this operator - var2node[i_var] = ++previous_node; - // - graph_obj.operator_vec_push_back( graph_op ); - graph_obj.operator_arg_push_back( left ); - graph_obj.operator_arg_push_back( right ); - graph_obj.operator_arg_push_back( if_true ); - graph_obj.operator_arg_push_back( if_false ); - } - break; - - // -------------------------------------------------------------- - // EndOp: - case local::EndOp: - more_operators = false; - break; - - // -------------------------------------------------------------- - // InvOp: independent variables - case local::InvOp: - // no graph operators for independent variables - break; - - // -------------------------------------------------------------- - // ParOp: - case local::ParOp: - // no need for a graph operator, just map variable to parameter - var2node[i_var] = par2node[arg[0]]; - break; - - // -------------------------------------------------------------- - default: - // This error should have been reported above - CPPAD_ASSERT_UNKNOWN(false); - break; - } - } - // ---------------------------------------------------------------------- - // output: dependent_vec - size_t n_dependent = dep_taddr_.size(); - for(size_t i = 0; i < n_dependent; ++i) - graph_obj.dependent_vec_push_back( var2node[ dep_taddr_[i] ] ); - // - return; -} - -# endif diff --git a/build-config/cppad/include/cppad/core/graph/to_json.hpp b/build-config/cppad/include/cppad/core/graph/to_json.hpp deleted file mode 100644 index 7ae92e8e..00000000 --- a/build-config/cppad/include/cppad/core/graph/to_json.hpp +++ /dev/null @@ -1,96 +0,0 @@ -# ifndef CPPAD_CORE_GRAPH_TO_JSON_HPP -# define CPPAD_CORE_GRAPH_TO_JSON_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include -# include - -/* ------------------------------------------------------------------------------- -$begin to_json$$ -$spell - Json - cpp -$$ - -$section Json AD Graph Corresponding to an ADFun Object$$ - -$head Syntax$$ -$codei% - %json% = %fun%.to_json() -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head fun$$ -is the $cref/ADFun/adfun/$$ object. - -$head json$$ -The return value of $icode json$$ is a -$cref json_ad_graph$$ representation of the corresponding function. - -$head Base$$ -is the type corresponding to this $cref/ADFun/adfun/$$ object; -i.e., its calculations are done using the type $icode Base$$. - -$head RecBase$$ -in the prototype above, $icode RecBase$$ is the same type as $icode Base$$. - -$head Restrictions$$ -The $code to_json$$ routine is not yet implement for some -possible $cref ADFun$$ operators; see -$cref/missing operators/graph_op_enum/Missing Operators/$$. - -$children% - example/json/to_json.cpp -%$$ -$head Example$$ -The file $cref to_json.cpp$$ is an example and test of this operation. - -$end -*/ -// BEGIN_PROTOTYPE -template -std::string CppAD::ADFun::to_json(void) -// END_PROTOTYPE -{ using local::pod_vector; - using local::opcode_t; - // -------------------------------------------------------------------- - if( local::graph::op_name2enum.size() == 0 ) - { CPPAD_ASSERT_KNOWN( ! thread_alloc::in_parallel() , - "call to set_operator_info in parallel mode" - ); - local::graph::set_operator_info(); - } - // - // to_graph return values - cpp_graph graph_obj; - // - // graph corresponding to this function - to_graph(graph_obj); - // - // convert to json - std::string json; - local::graph::json_writer(json, graph_obj); - // - return json; -} - -# endif diff --git a/build-config/cppad/include/cppad/core/hash_code.hpp b/build-config/cppad/include/cppad/core/hash_code.hpp deleted file mode 100644 index 5b023650..00000000 --- a/build-config/cppad/include/cppad/core/hash_code.hpp +++ /dev/null @@ -1,70 +0,0 @@ -# ifndef CPPAD_CORE_HASH_CODE_HPP -# define CPPAD_CORE_HASH_CODE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file core/hash_code.hpp -CppAD hashing utility. -*/ -# include - -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 std::numeric_limits::max() >= CPPAD_HASH_TABLE_SIZE -\li sizeof(value) is even -\li sizeof(unsigned short) == 2 -*/ -template -unsigned short hash_code(const Value& value) -{ return local::local_hash_code(value); } - -/*! -hash code for an AD object. - -\tparam Base -is the base type for this AD value. - -\param u -the AD value that we are generating a hash code for. - -\return -is a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1. -*/ -template -unsigned short hash_code(const AD& u) -{ size_t code = hash_code(u.value_); - code += size_t(u.taddr_); - code += size_t(u.ad_type_ == dynamic_enum); - return (unsigned short)(code % CPPAD_HASH_TABLE_SIZE); -} - -} // END_CPPAD_NAMESPACE - - -# endif diff --git a/build-config/cppad/include/cppad/core/hessian.hpp b/build-config/cppad/include/cppad/core/hessian.hpp deleted file mode 100644 index bee11342..00000000 --- a/build-config/cppad/include/cppad/core/hessian.hpp +++ /dev/null @@ -1,213 +0,0 @@ -# ifndef CPPAD_CORE_HESSIAN_HPP -# define CPPAD_CORE_HESSIAN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin Hessian$$ -$spell - hes - typename - Taylor - HesLuDet - const -$$ - - -$section Hessian: Easy Driver$$ - -$head Syntax$$ -$icode%hes% = %f%.Hessian(%x%, %w%) -%$$ -$icode%hes% = %f%.Hessian(%x%, %l%) -%$$ - - -$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$$. -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 -template -Vector ADFun::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 -template -Vector ADFun::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(); - - 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 diff --git a/build-config/cppad/include/cppad/core/identical.hpp b/build-config/cppad/include/cppad/core/identical.hpp deleted file mode 100644 index 70a96fb9..00000000 --- a/build-config/cppad/include/cppad/core/identical.hpp +++ /dev/null @@ -1,100 +0,0 @@ -# ifndef CPPAD_CORE_IDENTICAL_HPP -# define CPPAD_CORE_IDENTICAL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -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 object is a parameter, and could never have -a different value during any tape playback. - -An AD object 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 x is identically a parameter. -*/ -template -bool IdenticalCon(const AD &x) -{ return Constant(x) & IdenticalCon(x.value_); } -// Zero ============================================================== -/*! -Determine if an AD 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 - x is equals zero and is identically a parameter \ref CppAD::IdenticalCon. -*/ -template -bool IdenticalZero(const AD &x) -{ return Constant(x) & IdenticalZero(x.value_); } -// One ============================================================== -/*! -Determine if an AD 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 - x is equals one and is identically a parameter \ref CppAD::IdenticalCon. -*/ -template -bool IdenticalOne(const AD &x) -{ return Constant(x) & IdenticalOne(x.value_); } -// Equal =================================================================== -/*! -Determine if two AD 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::IdenticalCon. -*/ -template -bool IdenticalEqualCon -(const AD &x, const AD &y) -{ bool constant; - constant = Constant(x) & Constant(y); - return constant & IdenticalEqualCon(x.value_, y.value_); -} -// ========================================================================== - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/independent/devel.omh b/build-config/cppad/include/cppad/core/independent/devel.omh deleted file mode 100644 index b6f29ded..00000000 --- a/build-config/cppad/include/cppad/core/independent/devel.omh +++ /dev/null @@ -1,30 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -$begin devel_independent$$ -$spell - op - alloc - num - Cpp - bool - const - var - typename -$$ - -$section Developer Documentation for Independent$$ - -$childtable% - include/cppad/core/independent/independent.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/core/independent/independent.hpp b/build-config/cppad/include/cppad/core/independent/independent.hpp deleted file mode 100644 index ee151c5d..00000000 --- a/build-config/cppad/include/cppad/core/independent/independent.hpp +++ /dev/null @@ -1,257 +0,0 @@ -# ifndef CPPAD_CORE_INDEPENDENT_INDEPENDENT_HPP -# define CPPAD_CORE_INDEPENDENT_INDEPENDENT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/* -$begin independent_all$$ -$spell - op -$$ - -$section Independent: All Arguments Present$$ - -$head Purpose$$ -This implements $cref Independent$$ with all the possible arguments present. - -$head Syntax$$ -$codei%Independent(%x%, %abort_op_index%, %record_compare%, %dynamic%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_ALL_ARGUMENT%// END_ALL_ARGUMENT%1 -%$$ - -$head Base$$ -The base type the recording started by this operation. - -$head ADVector$$ -is simple vector type with elements of type $codei%AD<%Base%>%$$. - -$head x$$ -is the vector of the independent variables. - -$head 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). - -$head record_compare$$ -should comparison operators be recorded. - -$head dynamic$$ -is the independent dynamic parameter vector. - -$end -*/ -// BEGIN_ALL_ARGUMENT -template -void Independent( - ADVector& x , - size_t abort_op_index , - bool record_compare , - ADVector& dynamic ) -// END_ALL_ARGUMENT -{ CPPAD_ASSERT_KNOWN( - abort_op_index == 0 || record_compare, - "Independent: abort_op_index is non-zero and record_compare is false." - ); - typedef typename ADVector::value_type ADBase; - typedef typename ADBase::value_type Base; - CPPAD_ASSERT_KNOWN( - ADBase::tape_ptr() == nullptr, - "Independent: cannot create a new tape because\n" - "a previous tape is still active (for this thread).\n" - "AD::abort_recording() would abort this previous recording." - ); - local::ADTape* tape = ADBase::tape_manage(new_tape_manage); - tape->Independent(x, abort_op_index, record_compare, dynamic); -} -/* ----------------------------------------------------------------------------- -$begin independent_x_abort_record$$ -$spell - op -$$ - -$section Independent: Default For dynamic$$ - -$head Purpose$$ -This implements $cref Independent$$ using -the default for the dynamic argument. - -$head Syntax$$ -$codei%Independent(%x%, %abort_op_index%, %record_compare%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_THREE_ARGUMENT%// END_THREE_ARGUMENT%1 -%$$ - -$head Base$$ -The base type the recording started by this operation. - -$head ADVector$$ -is simple vector type with elements of type $codei%AD<%Base%>%$$. - -$head x$$ -is the vector of the independent variables. - -$head 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). - -$head record_compare$$ -should comparison operators be recorded. - -$end -*/ -// BEGIN_THREE_ARGUMENT -template -void Independent(ADVector &x, size_t abort_op_index, bool record_compare) -// END_THREE_ARGUMENT -{ ADVector dynamic(0); // empty vector - Independent(x, abort_op_index, record_compare, dynamic); -} -/* ------------------------------------------------------------------------------- -$begin independent_x_abort_op_index$$ -$spell - op -$$ - -$section Independent: Default For record_compare, dynamic$$ - -$head Purpose$$ -This implements $cref Independent$$ using -the default for the record_compare and dynamic arguments. - -$head Syntax$$ -$codei%Independent(%x%, %abort_op_index%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_X_ABORT_OP_INDEX%// END_X_ABORT_OP_INDEX%1 -%$$ - -$head Base$$ -The base type the recording started by this operation. - -$head ADVector$$ -is simple vector type with elements of type $codei%AD<%Base%>%$$. - -$head x$$ -is the vector of the independent variables. - -$head 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). - -$end -*/ -// BEGIN_X_ABORT_OP_INDEX -template -void Independent(ADVector &x, size_t abort_op_index) -// END_X_ABORT_OP_INDEX -{ bool record_compare = true; - ADVector dynamic(0); // empty vector - Independent(x, abort_op_index, record_compare, dynamic); -} -/* ------------------------------------------------------------------------------- -$begin independent_x_dynamic$$ -$spell - op -$$ - -$section Independent: Default For abort_op_index, record_compare$$ - -$head Purpose$$ -This implements $cref Independent$$ using -the default for the abort_op_index and record_compare. - -$head Syntax$$ -$codei%Independent(%x%, %dynamic%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_X_DYNAMIC%// END_X_DYNAMIC%1 -%$$ - -$head Base$$ -The base type the recording started by this operation. - -$head ADVector$$ -is simple vector type with elements of type $codei%AD<%Base%>%$$. - -$head x$$ -is the vector of the independent variables. - -$head dynamic$$ -is the independent dynamic parameter vector. - -$end -*/ -// BEGIN_X_DYNAMIC -template -void Independent(ADVector& x, ADVector& dynamic) -// END_X_DYNAMIC -{ size_t abort_op_index = 0; - bool record_compare = true; - Independent(x, abort_op_index, record_compare, dynamic); -} -/* ------------------------------------------------------------------------------- -$begin independent_x$$ -$spell - op -$$ - -$section Independent: Default For abort_op_index, record_compare, dynamic$$ - -$head Purpose$$ -This implements $cref Independent$$ using -the default for the abort_op_index, record_compare and dynamic arguments. - -$head Syntax$$ -$codei%Independent(%x%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_ONE_ARGUMENT%// END_ONE_ARGUMENT%1 -%$$ - -$head Base$$ -The base type the recording started by this operation. - -$head ADVector$$ -is simple vector type with elements of type $codei%AD<%Base%>%$$. - -$head x$$ -is the vector of the independent variables. - -$end -*/ -// BEGIN_ONE_ARGUMENT -template -void Independent(ADVector &x) -// END_ONE_ARGUMENT -{ size_t abort_op_index = 0; - bool record_compare = true; - ADVector dynamic(0); // empty vector - Independent(x, abort_op_index, record_compare, dynamic); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/independent/user.omh b/build-config/cppad/include/cppad/core/independent/user.omh deleted file mode 100644 index e63eed83..00000000 --- a/build-config/cppad/include/cppad/core/independent/user.omh +++ /dev/null @@ -1,157 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -$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%, %dynamic%) -%$$ -$codei%Independent(%x%, %abort_op_index%) -%$$ -$codei%Independent(%x%, %abort_op_index%, %record_compare%) -%$$ -$codei%Independent(%x%, %abort_op_index%, %record_compare%, %dynamic%) -%$$ - -$head Start Recording$$ -The syntax above starts 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 or aborted; see below. - -$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% - %ADVector% &%x% -%$$ -(see $icode ADVector$$ 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$$ -If this argument has prototype -$codei% - size_t %abort_op_index% -%$$ -If it is present, -it specifies the operator index at which the execution will 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/$$ for $icode op_index$$ -and $cref/NDEBUG/Faq/Speed/NDEBUG/$$. -No abort will occur if $icode abort_op_index$$ is zero. -If this argument is not present, the default value zero is used -for $icode abort_index$$. - -$head record_compare$$ -This argument has prototype -$codei% - bool %record_compare% -%$$ -If it is present, -it specifies if AD $cref compare$$ operations are recorded. -It takes extra time and memory to record these operations. -On the other hand, they can be useful for detecting when and why -a functions recording would change; see $icode abort_op_index$$ above and -$cref compare_change$$. -If this argument is not present, the default value $code true$$ is used -for $icode record_compare$$. -If this argument is false, $icode abort_op_index$$ must be zero. - -$head dynamic$$ -If this argument is present, it has prototype -$codei% - const %ADVector%& %dynamic% -%$$ -(see $icode Vector$$ below). -It specifies the independent -$cref/dynamic/glossary/Parameter/Dynamic/$$ parameters. -The value of these parameters, -in the $cref ADFun$$ object $icode f$$, -that can be changed using $cref new_dynamic$$. - -$subhead Efficiency$$ -Any operations that use dynamic parameters will be recorded. -We use other dynamic parameters to denote parameters that depend on -the independent dynamic parameters $icode dynamic$$, -and do not depend on $icode x$$. -It is more efficient to compute other dynamic parameters before calling -$code Independent$$ and include them in the -independent dynamic parameter vector $icode dynamic$$. - -$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 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. - -$end diff --git a/build-config/cppad/include/cppad/core/integer.hpp b/build-config/cppad/include/cppad/core/integer.hpp deleted file mode 100644 index 8a3e976d..00000000 --- a/build-config/cppad/include/cppad/core/integer.hpp +++ /dev/null @@ -1,111 +0,0 @@ -# ifndef CPPAD_CORE_INTEGER_HPP -# define CPPAD_CORE_INTEGER_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------------- -$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 %% &%x% - const std::complex %% &%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 - CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION - int Integer(const AD &x) - { return Integer(x.value_); } - - template - CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION - int Integer(const VecAD_reference &x) - { return Integer( x.ADBase() ); } -} -# endif diff --git a/build-config/cppad/include/cppad/core/jacobian.hpp b/build-config/cppad/include/cppad/core/jacobian.hpp deleted file mode 100644 index 3490bb1f..00000000 --- a/build-config/cppad/include/cppad/core/jacobian.hpp +++ /dev/null @@ -1,237 +0,0 @@ -# ifndef CPPAD_CORE_JACOBIAN_HPP -# define CPPAD_CORE_JACOBIAN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin Jacobian$$ -$spell - jac - typename - Taylor - Jacobian - DetLu - const -$$ - - -$section Jacobian: Driver Routine$$ - -$head Syntax$$ -$icode%jac% = %f%.Jacobian(%x%)%$$ - - -$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$$. -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 -void JacobianFor(ADFun &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(); - - 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 -void JacobianRev(ADFun &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 -template -Vector ADFun::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 ); -# ifdef CPPAD_FOR_TMB - if( workForward < workReverse ) -# else - if( workForward <= workReverse ) -# endif - JacobianFor(*this, x, jac); - else - JacobianRev(*this, x, jac); - - return jac; -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/lu_ratio.hpp b/build-config/cppad/include/cppad/core/lu_ratio.hpp deleted file mode 100644 index f46207b3..00000000 --- a/build-config/cppad/include/cppad/core/lu_ratio.hpp +++ /dev/null @@ -1,335 +0,0 @@ -# ifndef CPPAD_CORE_LU_RATIO_HPP -# define CPPAD_CORE_LU_RATIO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin LuRatio$$ -$spell - cppad.hpp - xk - Cpp - Lu - bool - const - ip - jp - std - ADvector -$$ - - -$section LU Factorization of A Square Matrix and Stability Calculation$$ - -$head Syntax$$ -$code# include $$ -$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$$. - -$end --------------------------------------------------------------------------- -*/ -namespace CppAD { // BEGIN CppAD namespace - -// Lines different from the code in cppad/lu_factor.hpp end with // -template // -int LuRatio(SizeVector &ip, SizeVector &jp, ADvector &LU, AD &ratio) // -{ - typedef ADvector FloatVector; // - typedef AD Float; // - - // check numeric type specifications - CheckNumericType(); - - // check simple vector class specifications - CheckSimpleVector(); - CheckSimpleVector(); - - 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 diff --git a/build-config/cppad/include/cppad/core/mul.hpp b/build-config/cppad/include/cppad/core/mul.hpp deleted file mode 100644 index a85eb71d..00000000 --- a/build-config/cppad/include/cppad/core/mul.hpp +++ /dev/null @@ -1,136 +0,0 @@ -# ifndef CPPAD_CORE_MUL_HPP -# define CPPAD_CORE_MUL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD operator * (const AD &left , const AD &right) -{ - // compute the Base part - AD result; - result.value_ = left.value_ * right.value_; - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "Multiply: AD variables or dynamic parameters on different threads." - ); - 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; - result.ad_type_ = variable_enum; - } - else if( (! dyn_right) & IdenticalZero(right.value_) ) - { // result = variable * 0 - } - else if( (! dyn_right) & 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 = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( var_right ) - { if( (! dyn_left) & IdenticalZero(left.value_) ) - { // result = 0 * variable - } - else if( (! dyn_left) & 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 = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(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; - result.ad_type_ = variable_enum; - } - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter result - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::mul_dyn, arg0, arg1 - ); - result.tape_id_ = tape_id; - result.ad_type_ = dynamic_enum; - } - return result; -} - -// convert other cases into the case above -CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(*) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/mul_eq.hpp b/build-config/cppad/include/cppad/core/mul_eq.hpp deleted file mode 100644 index acc4e774..00000000 --- a/build-config/cppad/include/cppad/core/mul_eq.hpp +++ /dev/null @@ -1,138 +0,0 @@ -# ifndef CPPAD_CORE_MUL_EQ_HPP -# define CPPAD_CORE_MUL_EQ_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD& AD::operator *= (const AD &right) -{ - // compute the Base part - Base left; - left = value_; - value_ *= right.value_; - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "*= : AD variables or dynamic parameters on different threads." - ); - 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); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - else if( (! dyn_right) & IdenticalOne(right.value_) ) - { // this = variable * 1 - } - else if( (! dyn_right) & IdenticalZero(right.value_) ) - { // this = variable * 0 - tape_id_ = 0; // not in current tape - } - 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 = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - tape->Rec_.PutArg(p, taddr_); - // put operator in the tape - taddr_ = tape->Rec_.PutOp(local::MulpvOp); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - } - else if( var_right ) - { if( (! dyn_left) & IdenticalZero(left) ) - { // this = 0 * right - } - else if( (! dyn_left) & 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 = taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(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; - ad_type_ = variable_enum; - } - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter results - taddr_ = tape->Rec_.put_dyn_par( - value_, local::mul_dyn, arg0, arg1 - ); - tape_id_ = tape_id; - ad_type_ = dynamic_enum; - } - return *this; -} - -CPPAD_FOLD_ASSIGNMENT_OPERATOR(*=) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/near_equal_ext.hpp b/build-config/cppad/include/cppad/core/near_equal_ext.hpp deleted file mode 100644 index aa6003f8..00000000 --- a/build-config/cppad/include/cppad/core/near_equal_ext.hpp +++ /dev/null @@ -1,187 +0,0 @@ -# ifndef CPPAD_CORE_NEAR_EQUAL_EXT_HPP -# define CPPAD_CORE_NEAR_EQUAL_EXT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin NearEqualExt$$ -$spell - cout - endl - Microsoft - std - Cpp - namespace - const - bool -$$ - -$section Compare AD and Base Objects for Nearly Equal$$ - - -$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 -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual( -const AD &x, const AD &y, const Base &r, const Base &a) -{ return NearEqual(x.value_, y.value_, r, a); -} - -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual( -const Base &x, const AD &y, const Base &r, const Base &a) -{ return NearEqual(x, y.value_, r, a); -} - -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual( -const AD &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 -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual( - const VecAD_reference &x, const VecAD_reference &y, - const Base &r, const Base &a) -{ return NearEqual(x.ADBase(), y.ADBase(), r, a); -} -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual(const VecAD_reference &x, const AD &y, - const Base &r, const Base &a) -{ return NearEqual(x.ADBase(), y, r, a); -} -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual(const VecAD_reference &x, const Base &y, - const Base &r, const Base &a) -{ return NearEqual(x.ADBase(), y, r, a); -} -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual(const AD &x, const VecAD_reference &y, - const Base &r, const Base &a) -{ return NearEqual(x, y.ADBase(), r, a); -} -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool NearEqual(const Base &x, const VecAD_reference &y, - const Base &r, const Base &a) -{ return NearEqual(x, y.ADBase(), r, a); -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/new_dynamic.hpp b/build-config/cppad/include/cppad/core/new_dynamic.hpp deleted file mode 100644 index 441d577a..00000000 --- a/build-config/cppad/include/cppad/core/new_dynamic.hpp +++ /dev/null @@ -1,139 +0,0 @@ -# ifndef CPPAD_CORE_NEW_DYNAMIC_HPP -# define CPPAD_CORE_NEW_DYNAMIC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin new_dynamic$$ -$spell - const - Taylor - cpp - dyn - ind -$$ - -$section Change the Dynamic Parameters$$ - -$head Syntax$$ -$icode%f%.new_dynamic(%dynamic%)%$$ - -$head Purpose$$ -Often one is only interested in computing derivatives with respect -to a subset of arguments to a function. -In this case, it is easier to make all the arguments to the function -$cref/independent variables/glossary/Tape/Independent Variable/$$. -It is more efficient, -will use less memory and be faster, -if the only the argument were are computing derivatives with respect to -are independent variables and the other arguments are -$cref/dynamic/glossary/Parameter/Dynamic/$$ parameters. -The $code new_dynamic$$ method is used to change the value -of the dynamic parameters in $icode f$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$. - -$head dynamic$$ -This argument has prototype -$codei% - const %BaseVector%& %dynamic% -%$$ -(see $icode BaseVector$$ below). -It specifies a new value for the independent -$cref/dynamic/glossary/Parameter/Dynamic/$$ parameters. -It size must be the same as the size of the independent -$cref/dynamic/Independent/dynamic/$$ parameter vector -in the call to $code Independent$$ that started -the recording for $icode f$$; see -$cref/size_dyn_ind/seq_property/size_dyn_ind/$$. - -$head BaseVector$$ -The type $icode BaseVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$icode Base$$. - -$head Taylor Coefficients$$ -The Taylor coefficients computed by previous calls to -$cref/f.Forward/Forward/$$ are lost after this operation; including the -order zero coefficients (because they may depend on the dynamic parameters). -In order words; -$cref/f.size_order/size_order/$$ returns zero directly after -$icode%f%.new_dynamic%$$ is called. - -$children% - example/general/new_dynamic.cpp -%$$ -$head Example$$ -The file $cref new_dynamic.cpp$$ -contains an example and test of this operation. - -$end -*/ -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file new_dynamic.hpp -User interface to ADFun dynamic_parameter member function. -*/ - -/*! -Change the dynamic parameters in this ADFun object - -\param dynamic -is the vector of new values for the dynamic parameters. -*/ -template -template -void ADFun::new_dynamic(const BaseVector& dynamic) -{ using local::pod_vector; - CPPAD_ASSERT_KNOWN( - size_t( dynamic.size() ) == play_.num_dynamic_ind() , - "f.new_dynamic: dynamic.size() different from corresponding " - "call to Independent" - ); - // check BaseVector is Simple Vector class with Base elements - CheckSimpleVector(); - - // retrieve player information about the dynamic parameters - local::pod_vector_maybe& all_par_vec( play_.all_par_vec() ); - const pod_vector& dyn_par_is ( play_.dyn_par_is() ); - const pod_vector& dyn_par_op ( play_.dyn_par_op() ); - const pod_vector& dyn_par_arg( play_.dyn_par_arg() ); - const pod_vector& dyn_ind2par_ind ( play_.dyn_ind2par_ind() ); - - // set the dependent dynamic parameters - RecBase not_used_rec_base(0.0); - local::sweep::dynamic( - all_par_vec , - dynamic , - dyn_par_is , - dyn_ind2par_ind , - dyn_par_op , - dyn_par_arg , - not_used_rec_base - ); - - // the existing Taylor coefficients are no longer valid - num_order_taylor_ = 0; - - return; -} - - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/num_skip.hpp b/build-config/cppad/include/cppad/core/num_skip.hpp deleted file mode 100644 index 2d0697bb..00000000 --- a/build-config/cppad/include/cppad/core/num_skip.hpp +++ /dev/null @@ -1,124 +0,0 @@ -# ifndef CPPAD_CORE_NUM_SKIP_HPP -# define CPPAD_CORE_NUM_SKIP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin number_skip$$ -$spell - optimizer - var - taylor_ -$$ - - -$section Number of Variables that Can be Skipped$$ - -$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. - -$end ------------------------------------------------------------------------------ -*/ - -# include - -// 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 -size_t ADFun::number_skip(void) -{ // must pass through operation sequence to map operations to variables - - // information defined by atomic forward - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0; - - // number of variables skipped - size_t num_var_skip = 0; - - // start playback - local::play::const_sequential_iterator itr = play_.begin(); - local::OpCode op; - size_t i_var; - const addr_t* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN(op == local::BeginOp) - while(op != local::EndOp) - { // next op - (++itr).op_info(op, arg, i_var); - // - if( op == local::AFunOp ) - { // skip only appears at front or back AFunOp of atomic function call - bool skip_call = cskip_op_[ itr.op_index() ]; - local::play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - size_t num_op = atom_m + atom_n + 1; - for(size_t i = 0; i < num_op; i++) - { CPPAD_ASSERT_UNKNOWN( - op != local::CSkipOp && op != local::CSumOp - ); - (++itr).op_info(op, arg, i_var); - if( skip_call ) - num_var_skip += NumRes(op); - } - CPPAD_ASSERT_UNKNOWN( op == local::AFunOp ); - } - else - { if( cskip_op_[ itr.op_index() ] ) - num_var_skip += NumRes(op); - // - if( (op == local::CSkipOp) | (op == local::CSumOp) ) - itr.correct_before_increment(); - } - } - return num_var_skip; -} - -} // END CppAD namespace - - -# endif diff --git a/build-config/cppad/include/cppad/core/numeric_limits.hpp b/build-config/cppad/include/cppad/core/numeric_limits.hpp deleted file mode 100644 index c96e020b..00000000 --- a/build-config/cppad/include/cppad/core/numeric_limits.hpp +++ /dev/null @@ -1,215 +0,0 @@ -# ifndef CPPAD_CORE_NUMERIC_LIMITS_HPP -# define CPPAD_CORE_NUMERIC_LIMITS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------------- -$begin numeric_limits$$ -$spell - std - eps - CppAD - namespace - const -$$ - -$section Numeric Limits For an AD and Base Types$$ - -$head Syntax$$ -$icode%eps% = numeric_limits<%Float%>::epsilon() -%$$ -$icode%min% = numeric_limits<%Float%>::min() -%$$ -$icode%max% = numeric_limits<%Float%>::max() -%$$ -$icode%nan% = numeric_limits<%Float%>::quiet_NaN() -%$$ -$codei%numeric_limits<%Float%>::digits10%$$ - -$head CppAD::numeric_limits$$ -These functions and have the prototype -$codei% - static %Float% CppAD::numeric_limits<%Float%>::%fun%(%void%) -%$$ -where $icode fun$$ is -$code epsilon$$, $code min$$, $code max$$, and $code quiet_NaN$$. -(Note that $code digits10$$ is member variable and not a function.) - -$head std::numeric_limits$$ -CppAD does not use a specialization of $code std::numeric_limits$$ -because this would be to restrictive. -The C++ standard specifies that Non-fundamental standard -types, such as -$cref/std::complex/base_complex.hpp/$$ shall not have specializations -of $code std::numeric_limits$$; see Section 18.2 of -ISO/IEC 14882:1998(E). -In addition, since C++11, a only literal types can have a specialization -of $code std::numeric_limits$$. - -$head Float$$ -These functions are defined for all $codei%AD<%Base%>%$$, -and for all corresponding $icode Base$$ types; -see $icode Base$$ type $cref base_limits$$. - -$head epsilon$$ -The result $icode eps$$ is equal to machine epsilon and has prototype -$codei% - %Float% %eps% -%$$ -The file $cref num_limits.cpp$$ -tests the value $icode eps$$ by checking that the following are true -$codei% - 1 != 1 + %eps% - 1 == 1 + %eps% / 2 -%$$ -where all the values, and calculations, are done with the precision -corresponding to $icode Float$$. - -$head min$$ -The result $icode min$$ is equal to -the minimum positive normalized value and has prototype -$codei% - %Float% %min% -%$$ -The file $cref num_limits.cpp$$ -tests the value $icode min$$ by checking that the following are true -$codei% - abs( ((%min% / 100) * 100) / %min% - 1 ) > 3 * %eps% - abs( ((%min% * 100) / 100) / %min% - 1 ) < 3 * %eps% -%$$ -where all the values, and calculations, are done with the precision -corresponding to $icode Float$$. - -$head max$$ -The result $icode max$$ is equal to -the maximum finite value and has prototype -$codei% - %Float% %max% -%$$ -The file $cref num_limits.cpp$$ -tests the value $icode max$$ by checking that the following are true -$codei% - abs( ((%max% * 100) / 100) / %max% - 1 ) > 3 * %eps% - abs( ((%max% / 100) * 100) / %max% - 1 ) < 3 * %eps% -%$$ -where all the values, and calculations, are done with the precision -corresponding to $icode Float$$. - -$head quiet_NaN$$ -The result $icode nan$$ is not a number and has prototype -$codei% - %Float% %nan% -%$$ -The file $cref num_limits.cpp$$ -tests the value $icode nan$$ by checking that the following is true -$codei% - %nan% != %nan% -%$$ - -$head digits10$$ -The member variable $code digits10$$ has prototype -$codei% - static const int numeric_limits<%Float%>::digits10 -%$$ -It is the number of decimal digits that can be represented by a -$icode Float$$ value. A number with this many decimal digits can be -converted to $icode Float$$ and back to a string, -without change due to rounding or overflow. - - -$head Example$$ -$children% - example/general/num_limits.cpp -%$$ -The file -$cref num_limits.cpp$$ -contains an example and test of these functions. - -$end ------------------------------------------------------------------------------- -*/ -# include - -# include -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file numeric_limits.hpp -File that defines CppAD numeric_limits for AD types -*/ - -/// All tthese defaults correspond to errors -template -class numeric_limits { -public: - /// machine epsilon - static Float epsilon(void) - { CPPAD_ASSERT_KNOWN( - false, - "numeric_limits::epsilon() is not specialized for this Float" - ); - return Float(0); - } - /// minimum positive normalized value - static Float min(void) - { CPPAD_ASSERT_KNOWN( - false, - "numeric_limits::min() is not specialized for this Float" - ); - return Float(0); - } - /// maximum finite value - static Float max(void) - { CPPAD_ASSERT_KNOWN( - false, - "numeric_limits::max() is not specialized for this Float" - ); - return Float(0); - } - /// not a number - static Float quiet_NaN(void) - { CPPAD_ASSERT_KNOWN( - false, - "numeric_limits::quiet_NaN() is not specialized for this Float" - ); - return Float(0); - } - /// number of decimal digits - static const int digits10 = -1; -}; - -/// Partial specialization that defines limits for for all AD types -template -class numeric_limits< AD > { -public: - /// machine epsilon - static AD epsilon(void) - { return AD( numeric_limits::epsilon() ); } - /// minimum positive normalized value - static AD min(void) - { return AD( numeric_limits::min() ); } - /// maximum finite value - static AD max(void) - { return AD( numeric_limits::max() ); } - /// not a number - static AD quiet_NaN(void) - { return AD( numeric_limits::quiet_NaN() ); } - /// number of decimal digits - static const int digits10 = numeric_limits::digits10; -}; - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/omp_max_thread.hpp b/build-config/cppad/include/cppad/core/omp_max_thread.hpp deleted file mode 100644 index 200f2153..00000000 --- a/build-config/cppad/include/cppad/core/omp_max_thread.hpp +++ /dev/null @@ -1,93 +0,0 @@ -# ifndef CPPAD_CORE_OMP_MAX_THREAD_HPP -# define CPPAD_CORE_OMP_MAX_THREAD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin omp_max_thread$$ -$spell - alloc - num - omp - OpenMp - CppAD -$$ - -$section OpenMP Parallel Setup$$ - -$head Deprecated 2011-06-23$$ -Use $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$ -to set the number of threads. - -$head Syntax$$ -$codei%AD<%Base%>::omp_max_thread(%number%) -%$$ - -$head Purpose$$ -By default, for each $codei%AD<%Base%>%$$ class there is only one -tape that records $cref/AD of Base/glossary/AD of Base/$$ operations. -This tape is a global variable and hence it cannot be used -by multiple OpenMP threads at the same time. -The $code omp_max_thread$$ function is used to set the -maximum number of OpenMP threads that can be active. -In this case, there is a different tape corresponding to each -$codei%AD<%Base%>%$$ class and thread pair. - -$head number$$ -The argument $icode number$$ has prototype -$codei% - size_t %number% -%$$ -It must be greater than zero and specifies the maximum number of -OpenMp threads that will be active at one time. - - -$head Independent$$ -Each call to $cref/Independent(x)/Independent/$$ -creates a new $cref/active/glossary/Tape/Active/$$ tape. -All of the operations with the corresponding variables -must be preformed by the same OpenMP thread. -This includes the corresponding call to -$cref/f.Dependent(x,y)/Dependent/$$ or the -$cref/ADFun f(x, y)/FunConstruct/Sequence Constructor/$$ -during which the tape stops recording and the variables -become parameters. - -$head Restriction$$ -No tapes can be -$cref/active/glossary/Tape/Active/$$ when this function is called. - -$end ------------------------------------------------------------------------------ -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -void AD::omp_max_thread(size_t number) -{ -# ifdef _OPENMP - thread_alloc::parallel_setup( - number, omp_alloc::in_parallel, omp_alloc::get_thread_num - ); -# else - CPPAD_ASSERT_KNOWN( - number == 1, - "omp_max_thread: number > 1 and _OPENMP is not defined" - ); -# endif - parallel_ad(); -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/opt_val_hes.hpp b/build-config/cppad/include/cppad/core/opt_val_hes.hpp deleted file mode 100644 index b57f8e75..00000000 --- a/build-config/cppad/include/cppad/core/opt_val_hes.hpp +++ /dev/null @@ -1,522 +0,0 @@ -# ifndef CPPAD_CORE_OPT_VAL_HES_HPP -# define CPPAD_CORE_OPT_VAL_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin opt_val_hes$$ -$spell - hes - sy - Jacobian - hes - signdet - jac - Bradley - const - CppAD -$$ - - - -$section Jacobian and Hessian of Optimal Values$$ - -$head Syntax$$ -$icode%signdet% = opt_val_hes(%x%, %y%, %fun%, %jac%, %hes%)%$$ - -$head See Also$$ -$cref BenderQuad$$ - -$head Reference$$ -Algorithmic differentiation of implicit functions and optimal values, -Bradley M. Bell and James V. Burke, Advances in Automatic Differentiation, -2008, Springer. - -$head Purpose$$ -We are given a function -$latex S : \B{R}^n \times \B{R}^m \rightarrow \B{R}^\ell$$ -and we define $latex F : \B{R}^n \times \B{R}^m \rightarrow \B{R}$$ -and $latex V : \B{R}^n \rightarrow \B{R} $$ by -$latex \[ -\begin{array}{rcl} - F(x, y) & = & \sum_{k=0}^{\ell-1} S_k ( x , y) - \\ - V(x) & = & F [ x , Y(x) ] - \\ - 0 & = & \partial_y F [x , Y(x) ] -\end{array} -\] $$ -We wish to compute the Jacobian -and possibly also the Hessian, of $latex V (x)$$. - -$head BaseVector$$ -The type $icode BaseVector$$ must be a -$cref SimpleVector$$ class. -We use $icode Base$$ to refer to the type of the elements of -$icode BaseVector$$; i.e., -$codei% - %BaseVector%::value_type -%$$ - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %BaseVector%& %x% -%$$ -and its size must be equal to $icode n$$. -It specifies the point at which we evaluating -the Jacobian $latex V^{(1)} (x)$$ -(and possibly the Hessian $latex V^{(2)} (x)$$). - - -$head y$$ -The argument $icode y$$ has prototype -$codei% - const %BaseVector%& %y% -%$$ -and its size must be equal to $icode m$$. -It must be equal to $latex Y(x)$$; i.e., -it must solve the implicit equation -$latex \[ - 0 = \partial_y F ( x , y) -\] $$ - -$head Fun$$ -The argument $icode fun$$ is an object of type $icode Fun$$ -which must support the member functions listed below. -CppAD will may be recording operations of the type $codei%AD<%Base%>%$$ -when these member functions are called. -These member functions must not stop such a recording; e.g., -they must not call $cref/AD::abort_recording/abort_recording/$$. - -$subhead Fun::ad_vector$$ -The type $icode%Fun%::ad_vector%$$ must be a -$cref SimpleVector$$ class with elements of type $codei%AD<%Base%>%$$; i.e. -$codei% - %Fun%::ad_vector::value_type -%$$ -is equal to $codei%AD<%Base%>%$$. - -$subhead fun.ell$$ -The type $icode Fun$$ must support the syntax -$codei% - %ell% = %fun%.ell() -%$$ -where $icode ell$$ has prototype -$codei% - size_t %ell% -%$$ -and is the value of $latex \ell$$; i.e., -the number of terms in the summation. -$pre - -$$ -One can choose $icode ell$$ equal to one, and have -$latex S(x,y)$$ the same as $latex F(x, y)$$. -Each of the functions $latex S_k (x , y)$$, -(in the summation defining $latex F(x, y)$$) -is differentiated separately using AD. -For very large problems, breaking $latex F(x, y)$$ into the sum -of separate simpler functions may reduce the amount of memory necessary for -algorithmic differentiation and there by speed up the process. - -$subhead fun.s$$ -The type $icode Fun$$ must support the syntax -$codei% - %s_k% = %fun%.s(%k%, %x%, %y%) -%$$ -The $icode%fun%.s%$$ argument $icode k$$ has prototype -$codei% - size_t %k% -%$$ -and is between zero and $icode%ell% - 1%$$. -The argument $icode x$$ to $icode%fun%.s%$$ has prototype -$codei% - const %Fun%::ad_vector& %x% -%$$ -and its size must be equal to $icode n$$. -The argument $icode y$$ to $icode%fun%.s%$$ has prototype -$codei% - const %Fun%::ad_vector& %y% -%$$ -and its size must be equal to $icode m$$. -The $icode%fun%.s%$$ result $icode s_k$$ has prototype -$codei% - AD<%Base%> %s_k% -%$$ -and its value must be given by $latex s_k = S_k ( x , y )$$. - -$subhead fun.sy$$ -The type $icode Fun$$ must support the syntax -$codei% - %sy_k% = %fun%.sy(%k%, %x%, %y%) -%$$ -The argument $icode k$$ to $icode%fun%.sy%$$ has prototype -$codei% - size_t %k% -%$$ -The argument $icode x$$ to $icode%fun%.sy%$$ has prototype -$codei% - const %Fun%::ad_vector& %x% -%$$ -and its size must be equal to $icode n$$. -The argument $icode y$$ to $icode%fun%.sy%$$ has prototype -$codei% - const %Fun%::ad_vector& %y% -%$$ -and its size must be equal to $icode m$$. -The $icode%fun%.sy%$$ result $icode sy_k$$ has prototype -$codei% - %Fun%::ad_vector %sy_k% -%$$ -its size must be equal to $icode m$$, -and its value must be given by $latex sy_k = \partial_y S_k ( x , y )$$. - -$head jac$$ -The argument $icode jac$$ has prototype -$codei% - %BaseVector%& %jac% -%$$ -and has size $icode n$$ or zero. -The input values of its elements do not matter. -If it has size zero, it is not affected. Otherwise, on output -it contains the Jacobian of $latex V (x)$$; i.e., -for $latex j = 0 , \ldots , n-1$$, -$latex \[ - jac[ j ] = V^{(1)} (x)_j -\] $$ -where $icode x$$ is the first argument to $code opt_val_hes$$. - -$head hes$$ -The argument $icode hes$$ has prototype -$codei% - %BaseVector%& %hes% -%$$ -and has size $icode%n% * %n%$$ or zero. -The input values of its elements do not matter. -If it has size zero, it is not affected. Otherwise, on output -it contains the Hessian of $latex V (x)$$; i.e., -for $latex i = 0 , \ldots , n-1$$, and -$latex j = 0 , \ldots , n-1$$, -$latex \[ - hes[ i * n + j ] = V^{(2)} (x)_{i,j} -\] $$ - - -$head signdet$$ -If $icode%hes%$$ has size zero, $icode signdet$$ is not defined. -Otherwise -the return value $icode signdet$$ is the sign of the determinant for -$latex \partial_{yy}^2 F(x , y) $$. -If it is zero, then the matrix is singular and -the Hessian is not computed ($icode hes$$ is not changed). - -$head Example$$ -$children% - example/general/opt_val_hes.cpp -%$$ -The file -$cref opt_val_hes.cpp$$ -contains an example and test of this operation. - -$end ------------------------------------------------------------------------------ -*/ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file opt_val_hes.hpp -\brief Computing Jabobians and Hessians of Optimal Values -*/ - -/*! -Computing Jabobians and Hessians of Optimal Values - -We are given a function -\f$ S : {\rm R}^n \times {\rm R}^m \rightarrow {\rm R}^\ell \f$ -and we define \f$ F : {\rm R}^n \times {\rm R}^m \rightarrow {\rm R} \f$ -and \f$ V : {\rm R}^n \rightarrow {\rm R} \f$ by -\f[ -\begin{array}{rcl} - F(x, y) & = & \sum_{k=0}^{\ell-1} S_k ( x , y) - \\ - V(x) & = & F [ x , Y(x) ] - \\ - 0 & = & \partial_y F [x , Y(x) ] -\end{array} -\f] -We wish to compute the Jacobian -and possibly also the Hessian, of \f$ V (x) \f$. - -\tparam BaseVector -The type BaseVector must be a SimpleVector class. -We use Base to refer to the type of the elements of - BaseVector; i.e., -BaseVector::value_type. - -\param x -is a vector with size n. -It specifies the point at which we evaluating -the Jacobian \f$ V^{(1)} (x) \f$ -(and possibly the Hessian \f$ V^{(2)} (x) \f$). - - -\param y -is a vector with size m. -It must be equal to \f$ Y(x) \f$; i.e., -it must solve the implicit equation -\f[ - 0 = \partial_y F ( x , y) -\f] - -\param fun -The argument fun is an object of type Fun -wich must support the member functions listed below. -CppAD will may be recording operations of the type AD -when these member functions are called. -These member functions must not stop such a recording; e.g., -they must not call AD::abort_recording. - -\par Fun::ad_vector -The type Fun::ad_vector must be a -SimpleVector class with elements of type AD; i.e. -Fun::ad_vector::value_type -is equal to AD. - -\par fun.ell -the type Fun must support the syntax -\verbatim - ell = fun.ell() -\endverbatim -where ell is a size_t value that is set to \f$ \ell \f$; i.e., -the number of terms in the summation. - -\par fun.s -The type Fun must support the syntax -\verbatim - s_k = fun.s(k, x, y) -\endverbatim -The argument k has prototype size_t k. -The argument x has prototype const Fun::ad_vector& x -and its size must be equal to n. -The argument y has prototype const Fun::ad_vector& y -and its size must be equal to m. -The return value s_k has prototype AD s_k -and its value must be given by \f$ s_k = S_k ( x , y ) \f$. - -\par fun.sy -The type Fun must support the syntax -\verbatim - sy_k = fun.sy(k, x, y) -\endverbatim -The argument k has prototype size_t k. -The argument x has prototype const Fun::ad_vector& x -and its size must be equal to n. -The argument y has prototype const Fun::ad_vector& y -and its size must be equal to m. -The return value sy_k has prototype Fun::ad_vector& sy_k, -its size is m -and its value must be given by \f$ sy_k = \partial_y S_k ( x , y ) \f$. - -\param jac -is a vector with size n or zero. -The input values of its elements do not matter. -If it has size zero, it is not affected. Otherwise, on output -it contains the Jacobian of \f$ V (x) \f$; i.e., -for \f$ j = 0 , \ldots , n-1 \f$, -\f[ - jac[ j ] = V^{(1)} (x)_j -\f] $$ -where x is the first argument to opt_val_hes. - -\param hes -is a vector with size n * n or zero. -The input values of its elements do not matter. -If it has size zero, it is not affected. Otherwise, on output -it contains the Hessian of \f$ V (x) \f$; i.e., -for \f$ i = 0 , \ldots , n-1 \f$, and -\f$ j = 0 , \ldots , n-1 \f$, -\f[ - hes[ i * n + j ] = V^{(2)} (x)_{i,j} -\f] - -\return -If hes.size() == 0, the return value is not defined. -Otherwise, -the return value is the sign of the determinant for -\f$ \partial_{yy}^2 F(x , y) \f$$. -If it is zero, then the matrix is singular and hes is not set -to its specified value. -*/ - - -template -int opt_val_hes( - const BaseVector& x , - const BaseVector& y , - Fun fun , - BaseVector& jac , - BaseVector& hes ) -{ // determine the base type - typedef typename BaseVector::value_type Base; - - // check that BaseVector is a SimpleVector class with Base elements - CheckSimpleVector(); - - // determine the AD vector type - typedef typename Fun::ad_vector ad_vector; - - // check that ad_vector is a SimpleVector class with AD elements - CheckSimpleVector< AD , ad_vector >(); - - // size of the x and y spaces - size_t n = size_t(x.size()); - size_t m = size_t(y.size()); - - // number of terms in the summation - size_t ell = fun.ell(); - - // check size of return values - CPPAD_ASSERT_KNOWN( - size_t(jac.size()) == n || jac.size() == 0, - "opt_val_hes: size of the vector jac is not equal to n or zero" - ); - CPPAD_ASSERT_KNOWN( - size_t(hes.size()) == n * n || hes.size() == 0, - "opt_val_hes: size of the vector hes is not equal to n * n or zero" - ); - - // some temporary indices - size_t i, j, k; - - // AD version of S_k(x, y) - ad_vector s_k(1); - - // ADFun version of S_k(x, y) - ADFun S_k; - - // AD version of x - ad_vector a_x(n); - - // AD version of y - ad_vector a_y(n); - - if( jac.size() > 0 ) - { // this is the easy part, computing the V^{(1)} (x) which is equal - // to \partial_x F (x, y) (see Thoerem 2 of the reference). - - // copy x and y to AD version - for(j = 0; j < n; j++) - a_x[j] = x[j]; - for(j = 0; j < m; j++) - a_y[j] = y[j]; - - // initialize summation - for(j = 0; j < n; j++) - jac[j] = Base(0.); - - // add in \partial_x S_k (x, y) - for(k = 0; k < ell; k++) - { // start recording - Independent(a_x); - // record - s_k[0] = fun.s(k, a_x, a_y); - // stop recording and store in S_k - S_k.Dependent(a_x, s_k); - // compute partial of S_k with respect to x - BaseVector jac_k = S_k.Jacobian(x); - // add \partial_x S_k (x, y) to jac - for(j = 0; j < n; j++) - jac[j] += jac_k[j]; - } - } - // check if we are done - if( hes.size() == 0 ) - return 0; - - /* - In this case, we need to compute the Hessian. Using Theorem 1 of the - reference: - Y^{(1)}(x) = - F_yy (x, y)^{-1} F_yx (x, y) - Using Theorem 2 of the reference: - V^{(2)}(x) = F_xx (x, y) + F_xy (x, y) Y^{(1)}(x) - */ - // Base and AD version of xy - BaseVector xy(n + m); - ad_vector a_xy(n + m); - for(j = 0; j < n; j++) - a_xy[j] = xy[j] = x[j]; - for(j = 0; j < m; j++) - a_xy[n+j] = xy[n+j] = y[j]; - - // Initialization summation for Hessian of F - size_t nm_sq = (n + m) * (n + m); - BaseVector F_hes(nm_sq); - for(j = 0; j < nm_sq; j++) - F_hes[j] = Base(0.); - BaseVector hes_k(nm_sq); - - // add in Hessian of S_k to hes - for(k = 0; k < ell; k++) - { // start recording - Independent(a_xy); - // split out x - for(j = 0; j < n; j++) - a_x[j] = a_xy[j]; - // split out y - for(j = 0; j < m; j++) - a_y[j] = a_xy[n+j]; - // record - s_k[0] = fun.s(k, a_x, a_y); - // stop recording and store in S_k - S_k.Dependent(a_xy, s_k); - // when computing the Hessian it pays to optimize the tape - S_k.optimize(); - // compute Hessian of S_k - hes_k = S_k.Hessian(xy, 0); - // add \partial_x S_k (x, y) to jac - for(j = 0; j < nm_sq; j++) - F_hes[j] += hes_k[j]; - } - // Extract F_yx - BaseVector F_yx(m * n); - for(i = 0; i < m; i++) - { for(j = 0; j < n; j++) - F_yx[i * n + j] = F_hes[ (i+n)*(n+m) + j ]; - } - // Extract F_yy - BaseVector F_yy(n * m); - for(i = 0; i < m; i++) - { for(j = 0; j < m; j++) - F_yy[i * m + j] = F_hes[ (i+n)*(n+m) + j + n ]; - } - - // compute - Y^{(1)}(x) = F_yy (x, y)^{-1} F_yx (x, y) - BaseVector neg_Y_x(m * n); - Base logdet; - int signdet = CppAD::LuSolve(m, n, F_yy, F_yx, neg_Y_x, logdet); - if( signdet == 0 ) - return signdet; - - // compute hes = F_xx (x, y) + F_xy (x, y) Y^{(1)}(x) - for(i = 0; i < n; i++) - { for(j = 0; j < n; j++) - { hes[i * n + j] = F_hes[ i*(n+m) + j ]; - for(k = 0; k < m; k++) - hes[i*n+j] -= F_hes[i*(n+m) + k+n] * neg_Y_x[k*n+j]; - } - } - return signdet; -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/optimize.hpp b/build-config/cppad/include/cppad/core/optimize.hpp deleted file mode 100644 index 67f4e41a..00000000 --- a/build-config/cppad/include/cppad/core/optimize.hpp +++ /dev/null @@ -1,376 +0,0 @@ -# ifndef CPPAD_CORE_OPTIMIZE_HPP -# define CPPAD_CORE_OPTIMIZE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# define CPPAD_CORE_OPTIMIZE_PRINT_RESULT 0 - -/* -$begin optimize$$ -$spell - enum - jac - bool - Taylor - CppAD - cppad - std - const - onetape - op - optimizer -$$ - -$section Optimize an ADFun Object Tape$$ - - -$head Syntax$$ -$icode%f%.optimize() -%$$ -$icode%f%.optimize(%options%) -%$$ -$icode%flag% = %f%.exceed_collision_limit() -%$$ - -$head Purpose$$ -The operation sequence corresponding to an $cref ADFun$$ object can -be very large and involve many operations; see the -size functions in $cref seq_property$$. -The $icode%f%.optimize%$$ procedure reduces the number of operations, -and thereby the time and the memory, required to -compute function and derivative values. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ - -$head options$$ -This argument has prototype -$codei% - const std::string& %options% -%$$ -The default for $icode options$$ is the empty string. -If it is present, it must consist of one or more of the options below -separated by a single space character. - -$subhead no_conditional_skip$$ -The $code optimize$$ function can create conditional skip operators -to improve the speed of conditional expressions; see -$cref/optimize/CondExp/Optimize/$$. -If the sub-string $code no_conditional_skip$$ appears in $icode options$$, -conditional skip operations are not be generated. -This may make the optimize routine use significantly less memory -and take less time to optimize $icode f$$. -If conditional skip operations are generated, -it may save a significant amount of time when -using $icode f$$ for $cref forward$$ or $cref reverse$$ mode calculations; -see $cref number_skip$$. - -$subhead no_compare_op$$ -If the sub-string $code no_compare_op$$ appears in $icode options$$, -comparison operators will be removed from the optimized function. -These operators are necessary for the -$cref compare_change$$ functions to be meaningful. -On the other hand, they are not necessary, and take extra time, -when the compare_change functions are not used. - -$subhead no_print_for_op$$ -If the sub-string $code no_compare_op$$ appears in $icode options$$, -$cref PrintFor$$ operations will be removed form the optimized function. -These operators are useful for reporting problems evaluating derivatives -at independent variable values different from those used to record a function. - -$subhead no_cumulative_sum_op$$ -If this sub-string appears, -no cumulative sum operations will be generated during the optimization; see -$cref optimize_cumulative_sum.cpp$$. - -$subhead collision_limit=value$$ -If this substring appears, -where $icode value$$ is a sequence of decimal digits, -the optimizer's hash code collision limit will be set to $icode value$$. -When the collision limit is reached, the expressions with that hash code -are removed and a new lists of expressions with that has code is started. -The larger $icode value$$, the more identical expressions the optimizer -can recognize, but the slower the optimizer may run. -The default for $icode value$$ is $code 10$$. - -$head Re-Optimize$$ -Before 2019-06-28, optimizing twice was not supported and would fail -if cumulative sum operators were present after the first optimization. -This is now supported but it is not expected to have much benefit. -If you find a case where it does have a benefit, please inform the CppAD -developers of this. - -$head Efficiency$$ -If a $cref/zero order forward/forward_zero/$$ calculation is done during -the construction of $icode f$$, it will require more memory -and time than required after the optimization procedure. -In addition, it will need to be redone. -For this reason, it is more efficient to use -$codei% - ADFun<%Base%> %f%; - %f%.Dependent(%x%, %y%); - %f%.optimize(); -%$$ -instead of -$codei% - ADFun<%Base%> %f%(%x%, %y%) - %f%.optimize(); -%$$ -See the discussion about -$cref/sequence constructors/FunConstruct/Sequence Constructor/$$. - -$head Taylor Coefficients$$ -Any Taylor coefficients in the function object are lost; i.e., -$cref/f.size_order()/size_order/$$ after the optimization is zero. -(See the discussion about efficiency above.) - -$head Speed Testing$$ -You can run the CppAD $cref/speed/speed_main/$$ tests and see -the corresponding changes in number of variables and execution time. -Note that there is an interaction between using -$cref/optimize/speed_main/Global Options/optimize/$$ and -$cref/onetape/speed_main/Global Options/onetape/$$. -If $icode onetape$$ is true and $icode optimize$$ is true, -the optimized tape will be reused many times. -If $icode onetape$$ is false and $icode optimize$$ is true, -the tape will be re-optimized for each test. - -$head Atomic Functions$$ -There are some subtitle issue with optimized $cref atomic$$ functions -$latex v = g(u)$$: - -$subhead rev_sparse_jac$$ -The $cref atomic_two_rev_sparse_jac$$ function is be used to determine -which components of $icode u$$ affect the dependent variables of $icode f$$. -For each atomic operation, the current -$cref/atomic_sparsity/atomic_two_option/atomic_sparsity/$$ setting is used -to determine if $code pack_sparsity_enum$$, $code bool_sparsity_enum$$, -or $code set_sparsity_enum$$ is used to determine dependency relations -between argument and result variables. - -$subhead nan$$ -If $icode%u%[%i%]%$$ does not affect the value of -the dependent variables for $icode f$$, -the value of $icode%u%[%i%]%$$ is set to $cref nan$$. - -$head Checking Optimization$$ -If $cref/NDEBUG/Faq/Speed/NDEBUG/$$ is not defined, -and $cref/f.size_order()/size_order/$$ is greater than zero, -a $cref forward_zero$$ calculation is done using the optimized version -of $icode f$$ and the results are checked to see that they are -the same as before. -If they are not the same, the -$cref ErrorHandler$$ is called with a known error message -related to $icode%f%.optimize()%$$. - -$head exceed_collision_limit$$ -If the return value $icode flag$$ is true (false), -the previous call to $icode%f%.optimize%$$ exceed the -$cref/collision_limit/optimize/options/collision_limit=value/$$. - -$head Examples$$ -$comment childtable without Example instead of Contents for header$$ -$children% - example/optimize/optimize_twice.cpp - %example/optimize/forward_active.cpp - %example/optimize/reverse_active.cpp - %example/optimize/compare_op.cpp - %example/optimize/print_for.cpp - %example/optimize/conditional_skip.cpp - %example/optimize/nest_conditional.cpp - %example/optimize/cumulative_sum.cpp -%$$ -$table -$rref optimize_twice.cpp$$ -$rref optimize_forward_active.cpp$$ -$rref optimize_reverse_active.cpp$$ -$rref optimize_compare_op.cpp$$ -$rref optimize_print_for.cpp$$ -$rref optimize_conditional_skip.cpp$$ -$rref optimize_nest_conditional.cpp$$ -$rref optimize_cumulative_sum.cpp$$ -$tend - -$end ------------------------------------------------------------------------------ -*/ -# include -/*! -\file optimize.hpp -Optimize a player object operation sequence -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -Optimize a player object operation sequence - -The operation sequence for this object is replaced by one with fewer operations -but the same funcition and derivative values. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type - Base. - -\param options -\li -If the sub-string "no_conditional_skip" appears, -conditional skip operations will not be generated. -This may make the optimize routine use significantly less memory -and take significantly less time. -\li -If the sub-string "no_compare_op" appears, -then comparison operators will be removed from the optimized tape. -These operators are necessary for the compare_change function to be -be meaningful in the resulting recording. -On the other hand, they are not necessary and take extra time -when compare_change is not used. -*/ -template -void ADFun::optimize(const std::string& options) -{ -# if CPPAD_CORE_OPTIMIZE_PRINT_RESULT - // size of operation sequence before optimizatiton - size_t size_op_before = size_op(); -# endif - - // place to store the optimized version of the recording - local::recorder rec; - - // number of independent variables - size_t n = ind_taddr_.size(); - -# ifndef NDEBUG - size_t i, j, m = dep_taddr_.size(); - CppAD::vector x(n), y(m), check(m); - Base max_taylor(0); - bool check_zero_order = num_order_taylor_ > 0; - if( check_zero_order ) - { // zero order coefficients for independent vars - for(j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == local::InvOp ); - CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j+1 ); - x[j] = taylor_[ ind_taddr_[j] * cap_order_taylor_ + 0]; - } - // zero order coefficients for dependent vars - for(i = 0; i < m; i++) - { CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); - y[i] = taylor_[ dep_taddr_[i] * cap_order_taylor_ + 0]; - } - // maximum zero order coefficient not counting BeginOp at beginning - // (which is correpsonds to uninitialized memory). - for(i = 1; i < num_var_tape_; i++) - { if( abs_geq(taylor_[i*cap_order_taylor_+0] , max_taylor) ) - max_taylor = taylor_[i*cap_order_taylor_+0]; - } - } -# endif - - // create the optimized recording - size_t exceed = false; - switch( play_.address_type() ) - { - case local::play::unsigned_short_enum: - exceed = local::optimize::optimize_run( - options, n, dep_taddr_, &play_, &rec - ); - break; - - case local::play::unsigned_int_enum: - exceed = local::optimize::optimize_run( - options, n, dep_taddr_, &play_, &rec - ); - break; - - case local::play::size_t_enum: - exceed = local::optimize::optimize_run( - options, n, dep_taddr_, &play_, &rec - ); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - exceed_collision_limit_ = exceed; - - // number of variables in the recording - num_var_tape_ = rec.num_var_rec(); - - // now replace the recording - play_.get_recording(rec, n); - - // set flag so this function knows it has been optimized - has_been_optimized_ = true; - - // free memory allocated for sparse Jacobian calculation - // (the results are no longer valid) - for_jac_sparse_pack_.resize(0, 0); - for_jac_sparse_set_.resize(0,0); - - // free old Taylor coefficient memory - taylor_.clear(); - num_order_taylor_ = 0; - cap_order_taylor_ = 0; - - // resize and initilaize conditional skip vector - // (must use player size because it now has the recoreder information) - cskip_op_.resize( play_.num_op_rec() ); - - // resize subgraph_info_ - subgraph_info_.resize( - ind_taddr_.size(), // n_ind - dep_taddr_.size(), // n_dep - play_.num_op_rec(), // n_op - play_.num_var_rec() // n_var - ); - -# ifndef NDEBUG - if( check_zero_order ) - { std::stringstream s; - // - // zero order forward calculation using new operation sequence - check = Forward(0, x, s); - - // check results - Base eps99 = Base(99) * CppAD::numeric_limits::epsilon(); - for(i = 0; i < m; i++) - if( ! abs_geq( eps99 * max_taylor , check[i] - y[i] ) ) - { std::string msg = "Error during check of f.optimize()."; - msg += "\neps99 * max_taylor = " + to_string(eps99 * max_taylor); - msg += "\ncheck[i] = " + to_string(check[i]); - msg += "\ny[i] = " + to_string(y[i]); - CPPAD_ASSERT_KNOWN( - abs_geq( eps99 * max_taylor , check[i] - y[i] ) , - msg.c_str() - ); - } - - // Erase memory that this calculation was done so NDEBUG gives - // same final state for this object (from users perspective) - num_order_taylor_ = 0; - } -# endif -# if CPPAD_CORE_OPTIMIZE_PRINT_RESULT - // size of operation sequence after optimizatiton - size_t size_op_after = size_op(); - std::cout << "optimize: size_op: before = " << - size_op_before << ", after = " << size_op_after << "\n"; -# endif -} - -} // END_CPPAD_NAMESPACE - -# undef CPPAD_CORE_OPTIMIZE_PRINT_RESULT -# endif diff --git a/build-config/cppad/include/cppad/core/ordered.hpp b/build-config/cppad/include/cppad/core/ordered.hpp deleted file mode 100644 index 4f08934c..00000000 --- a/build-config/cppad/include/cppad/core/ordered.hpp +++ /dev/null @@ -1,100 +0,0 @@ -# ifndef CPPAD_CORE_ORDERED_HPP -# define CPPAD_CORE_ORDERED_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/*! -\file ordered.hpp -Check and AD values ordering properties relative to zero. -*/ - -// GreaterThanZero ============================================================ -/*! -Check if an AD is greater than zero. - -\param x -value we are checking. - -\return -returns true iff the x is greater than zero. -*/ -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool GreaterThanZero(const AD &x) -{ return GreaterThanZero(x.value_); } -// GreaterThanOrZero ========================================================= -/*! -Check if an AD is greater than or equal zero. - -\param x -value we are checking. - -\return -returns true iff the x is greater than or equal zero. -*/ -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool GreaterThanOrZero(const AD &x) -{ return GreaterThanOrZero(x.value_); } -// LessThanZero ============================================================ -/*! -Check if an AD is less than zero. - -\param x -value we are checking. - -\return -returns true iff the x is less than zero. -*/ -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool LessThanZero(const AD &x) -{ return LessThanZero(x.value_); } -// LessThanOrZero ========================================================= -/*! -Check if an AD is less than or equal zero. - -\param x -value we are checking. - -\return -returns true iff the x is less than or equal zero. -*/ -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool LessThanOrZero(const AD &x) -{ return LessThanOrZero(x.value_); } -// abs_geq ========================================================= -/*! -Check if absolute value of one AD is greater or equal another. - -\param x -value we are checking if it is greater than or equal other. - -\param y -value we are checking if it is less than other. - -\return -returns true iff the absolute value of x is greater than or equal -absolute value of y. -*/ -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -bool abs_geq(const AD& x, const AD& y) -{ return abs_geq(x.value_, y.value_); } -// ============================================================================ -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/parallel_ad.hpp b/build-config/cppad/include/cppad/core/parallel_ad.hpp deleted file mode 100644 index 34b3a52a..00000000 --- a/build-config/cppad/include/cppad/core/parallel_ad.hpp +++ /dev/null @@ -1,117 +0,0 @@ -# ifndef CPPAD_CORE_PARALLEL_AD_HPP -# define CPPAD_CORE_PARALLEL_AD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin parallel_ad$$ -$spell - CppAD - num - std -$$ - -$section Enable AD Calculations During Parallel Mode$$ - -$head Syntax$$ -$codei%parallel_ad<%Base%>()%$$ - -$head Purpose$$ -The function -$codei%parallel_ad<%Base%>()%$$ -must be called before any $codei%AD<%Base>%$$ objects are used -in $cref/parallel/ta_in_parallel/$$ mode. -In addition, if this routine is called after one is done using -parallel mode, it will free extra memory used to keep track of -the multiple $codei%AD<%Base%>%$$ tapes required for parallel execution. - -$head Discussion$$ -By default, for each $codei%AD<%Base%>%$$ class there is only one -tape that records $cref/AD of Base/glossary/AD of Base/$$ operations. -This tape is a global variable and hence it cannot be used -by multiple threads at the same time. -The $cref/parallel_setup/ta_parallel_setup/$$ function informs CppAD of the -maximum number of threads that can be active in parallel mode. -This routine does extra setup -(and teardown) for the particular $icode Base$$ type. - -$head CheckSimpleVector$$ -This routine has the side effect of calling the routines -$codei% - CheckSimpleVector< %Type%, CppAD::vector<%Type%> >() -%$$ -where $icode Type$$ is $icode Base$$ and $codei%AD<%Base%>%$$. - -$head Example$$ -The files -$cref team_openmp.cpp$$, -$cref team_bthread.cpp$$, and -$cref team_pthread.cpp$$, -contain examples and tests that implement this function. - -$head Restriction$$ -This routine cannot be called in parallel mode or while -there is a tape recording $codei%AD<%Base%>%$$ operations. - -$end ------------------------------------------------------------------------------ -*/ - -# include - -// BEGIN CppAD namespace -namespace CppAD { - -/*! -Enable parallel execution mode with AD by initializing -static variables that my be used. -*/ - -template -void parallel_ad(void) -{ CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "parallel_ad must be called before entering parallel execution mode." - ); - CPPAD_ASSERT_KNOWN( - AD::tape_ptr() == nullptr , - "parallel_ad cannot be called while a tape recording is in progress" - ); - - // ensure statics in following functions are initialized - elapsed_seconds(); - ErrorHandler::Current(); - local::NumArg(local::BeginOp); - local::NumRes(local::BeginOp); - local::one_element_std_set(); - local::two_element_std_set(); - - // the sparse_pack class has member functions with static data - local::sparse::pack_setvec sp; - sp.resize(1, 1); // so can call add_element - sp.add_element(0, 0); // has static data - sp.clear(0); // has static data - sp.is_element(0, 0); // has static data - local::sparse::pack_setvec::const_iterator itr(sp, 0); // has static data - ++itr; // has static data - - // statics that depend on the value of Base - AD::tape_id_ptr(0); - AD::tape_handle(0); - discrete::List(); - CheckSimpleVector< Base, CppAD::vector >(); - CheckSimpleVector< AD, CppAD::vector< AD > >(); - -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/pow.hpp b/build-config/cppad/include/cppad/core/pow.hpp deleted file mode 100644 index 5f510c67..00000000 --- a/build-config/cppad/include/cppad/core/pow.hpp +++ /dev/null @@ -1,295 +0,0 @@ -# ifndef CPPAD_CORE_POW_HPP -# define CPPAD_CORE_POW_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin pow$$ -$spell - Vec - std - namespace - CppAD - const -$$ - - -$section The AD Power Function$$ - -$head Syntax$$ -$icode%z% = pow(%x%, %y%)%$$ - -$head See Also$$ -$cref pow_int$$ - - -$head Purpose$$ -Determines the value of the power function which is defined by -$latex \[ - {\rm pow} (x, y) = x^y -\] $$ -This version of the $code pow$$ function may use -logarithms and exponentiation to compute derivatives. -This will not work if $icode x$$ is less than or equal zero. -If the value of $icode y$$ is an integer, -the $cref pow_int$$ function is used to compute this value -using only multiplication (and division if $icode y$$ is negative). -(This will work even if $icode x$$ is less than or equal zero.) - -$head x$$ -The argument $icode x$$ has one of the following prototypes -$codei% - const %Base%& %x% - const AD<%Base%>& %x% - const VecAD<%Base%>::reference& %x% -%$$ - -$head y$$ -The argument $icode y$$ has one of the following prototypes -$codei% - const %Base%& %y% - const AD<%Base%>& %y% - const VecAD<%Base%>::reference& %y% -%$$ - -$head z$$ -If both $icode x$$ and $icode y$$ are $icode Base$$ objects, -the result $icode z$$ is also a $icode Base$$ object. -Otherwise, it has prototype -$codei% - AD<%Base%> %z% -%$$ - -$head Operation Sequence$$ -This is an AD of $icode Base$$ -$cref/atomic operation/glossary/Operation/Atomic/$$ -and hence is part of the current -AD of $icode Base$$ -$cref/operation sequence/glossary/Operation/Sequence/$$. - -$head Example$$ -$children% - example/general/pow.cpp -%$$ -The file -$cref pow.cpp$$ -is an examples and tests of this function. - -$end -------------------------------------------------------------------------------- -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -// case where x and y are AD ----------------------------------------- -template AD -pow(const AD& x, const AD& y) -{ - // compute the Base part - AD result; - result.value_ = pow(x.value_, y.value_); - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if x and y tapes match - bool match_x = x.tape_id_ == tape_id; - bool match_y = y.tape_id_ == tape_id; - - // check if x and y are dynamic parameters - bool dyn_x = match_x & (x.ad_type_ == dynamic_enum); - bool dyn_y = match_y & (y.ad_type_ == dynamic_enum); - - // check if x and y are variables - bool var_x = match_x & (x.ad_type_ != dynamic_enum); - bool var_y = match_y & (y.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - x.tape_id_ == y.tape_id_ || ! match_x || ! match_y , - "pow: AD variables or dynamic parameters on different threads." - ); - if( var_x ) - { if( var_y ) - { // result = variable^variable - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowvvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowvvOp) == 2 ); - - // put operand addresses in tape - tape->Rec_.PutArg(x.taddr_, y.taddr_); - - // put operator in the tape - result.taddr_ = tape->Rec_.PutOp(local::PowvvOp); - - // make result a variable - result.tape_id_ = tape_id; - result.ad_type_ = variable_enum; - } - else if( IdenticalZero( y.value_ ) ) - { // result = variable^0 - } - else - { // result = variable^parameter - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowvpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowvpOp) == 2 ); - - // put operand addresses in tape - addr_t p = y.taddr_; - if( ! dyn_y ) - p = tape->Rec_.put_con_par(y.value_); - tape->Rec_.PutArg(x.taddr_, p); - - // put operator in the tape - result.taddr_ = tape->Rec_.PutOp(local::PowvpOp); - - // make result a variable - result.tape_id_ = tape_id; - result.ad_type_ = variable_enum; - } - } - else if( var_y ) - { if( IdenticalZero(x.value_) ) - { // result = 0^variable - } - else - { // result = parameter^variable - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowpvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowpvOp) == 2 ); - - // put operand addresses in tape - addr_t p = x.taddr_; - if( ! dyn_x ) - p = tape->Rec_.put_con_par(x.value_); - tape->Rec_.PutArg(p, y.taddr_); - - // put operator in the tape - result.taddr_ = tape->Rec_.PutOp(local::PowpvOp); - - // make result a variable - result.tape_id_ = tape_id; - result.ad_type_ = variable_enum; - } - } - else if( dyn_x | dyn_y ) - { addr_t arg0 = x.taddr_; - addr_t arg1 = y.taddr_; - if( ! dyn_x ) - arg0 = tape->Rec_.put_con_par(x.value_); - if( ! dyn_y ) - arg1 = tape->Rec_.put_con_par(y.value_); - // - // parameters with a dynamic parameter result - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::pow_dyn, arg0, arg1 - ); - result.tape_id_ = tape_id; - result.ad_type_ = dynamic_enum; - } - else - { CPPAD_ASSERT_KNOWN( ! (dyn_x | dyn_y) , - "pow: one operand is a dynamic parameter and other not a variable" - ); - } - return result; -} -// ========================================================================= -// Fold operations in same way as CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op) -// ------------------------------------------------------------------------- -// Operations with VecAD_reference and AD only - -template AD -pow(const AD& x, const VecAD_reference& y) -{ return pow(x, y.ADBase()); } - -template AD -pow(const VecAD_reference& x, const VecAD_reference& y) -{ return pow(x.ADBase(), y.ADBase()); } - -template AD -pow(const VecAD_reference& x, const AD& y) -{ return pow(x.ADBase(), y); } -// ------------------------------------------------------------------------- -// Operations with Base - -template AD -pow(const Base& x, const AD& y) -{ return pow(AD(x), y); } - -template AD -pow(const Base& x, const VecAD_reference& y) -{ return pow(AD(x), y.ADBase()); } - -template AD -pow(const AD& x, const Base& y) -{ return pow(x, AD(y)); } - -template AD -pow(const VecAD_reference& x, const Base& y) -{ return pow(x.ADBase(), AD(y)); } -// ------------------------------------------------------------------------- -// Operations with double - -template AD -pow(const double& x, const AD& y) -{ return pow(AD(x), y); } - -template AD -pow(const double& x, const VecAD_reference& y) -{ return pow(AD(x), y.ADBase()); } - -template AD -pow(const AD& x, const double& y) -{ return pow(x, AD(y)); } - -template AD -pow(const VecAD_reference& x, const double& y) -{ return pow(x.ADBase(), AD(y)); } -// ------------------------------------------------------------------------- -// Special case to avoid ambuigity when Base is double - -inline AD -pow(const double& x, const AD& y) -{ return pow(AD(x), y); } - -inline AD -pow(const double& x, const VecAD_reference& y) -{ return pow(AD(x), y.ADBase()); } - -inline AD -pow(const AD& x, const double& y) -{ return pow(x, AD(y)); } - -inline AD -pow(const VecAD_reference& x, const double& y) -{ return pow(x.ADBase(), AD(y)); } - -// ========================================================================= -// Fold operations for the cases where x is an int, -// but let cppad/utility/pow_int.hpp handle the cases where y is an int. -// ------------------------------------------------------------------------- -template AD pow -(const int& x, const VecAD_reference& y) -{ return pow(AD(x), y.ADBase()); } - -template AD pow -(const int& x, const AD& y) -{ return pow(AD(x), y); } - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/print_for.hpp b/build-config/cppad/include/cppad/core/print_for.hpp deleted file mode 100644 index 01eaad6d..00000000 --- a/build-config/cppad/include/cppad/core/print_for.hpp +++ /dev/null @@ -1,228 +0,0 @@ -# ifndef CPPAD_CORE_PRINT_FOR_HPP -# define CPPAD_CORE_PRINT_FOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin PrintFor$$ -$spell - notpos - var - VecAD - std - cout - const -$$ - - -$section Printing AD Values During Forward Mode$$ - -$head Syntax$$ -$icode%f%.Forward(0, %x%) -%$$ -$icode%f%.Forward(0, %x%, %s%) -%$$ -$codei%PrintFor(%before%, %value%) -%$$ -$codei%PrintFor(%notpos%, %before%, %value%, %after%) -%$$ - -$head See Also$$ -$cref ad_output$$ - -$head Purpose$$ -The $cref/zero order forward/forward_zero/$$ mode command -$codei% - %f%.Forward(0, %x%) -%$$ -sets the -$cref/independent variable/glossary/Tape/Independent Variable/$$ vector -equal to $icode x$$. -It then computes a value for all of the dependent variables in the -$cref/operation sequence/glossary/Operation/Sequence/$$ corresponding -to $icode f$$. -Putting a $code PrintFor$$ in the operation sequence, -prints $icode value$$, corresponding to $icode x$$, -to be printed during zero order forward operations. - -$head f.Forward(0, x)$$ -The objects $icode f$$, $icode x$$, and the purpose -for this operation, are documented in $cref Forward$$. - -$head notpos$$ -If present, the argument $icode notpos$$ has one of the following prototypes -$codei% - const AD<%Base%>& %notpos% - const VecAD<%Base%>::reference& %notpos% -%$$ -In this case -the text and $icode value$$ will be printed if and only if -$icode notpos$$ is not positive (greater than zero) and a finite number. - -$head before$$ -The argument $icode before$$ has prototype -$codei% - const char* %before% -%$$ -This text is written to $code std::cout$$ before $icode value$$. - -$head value$$ -The argument $icode value$$ has one of the following prototypes -$codei% - const AD<%Base%>& %value% - const VecAD<%Base%>::reference& %value% -%$$ -The $icode value$$, that corresponds to $icode x$$, -is written to $code std::cout$$ during the execution of -$codei% - %f%.Forward(0, %x%) -%$$ -Note that $icode value$$ may be a -$cref/variable/glossary/Variable/$$ or -$cref/parameter/glossary/Parameter/$$. -If a parameter is -$cref/dynamic/glossary/Parameter/Dynamic/$$ its value -will depend on the previous call to $cref new_dynamic$$. - -$head after$$ -The argument $icode after$$ has prototype -$codei% - const char* %after% -%$$ -This text is written to $code std::cout$$ after $icode value$$. - -$head s$$ -You can redirect this output to any standard output stream using the syntax -$codei% - %f%.Forward(0, %x%, %s%) -%$$ -see $cref/s/forward_zero/s/$$ in the zero order forward mode documentation. - -$head Discussion$$ -This is helpful for understanding why tape evaluations have trouble. -For example, if one of the operations in $icode f$$ is -$codei%log(%value%)%$$ and $icode%value% < 0%$$, -the corresponding result will $cref nan$$. - -$head Example$$ -$children% - example/print_for/print_for.cpp% - example/general/print_for.cpp -%$$ -The program -$cref print_for_cout.cpp$$ -is an example and test that prints to standard output. -The output of this program -states the conditions for passing and failing the test. -The function -$cref print_for_string.cpp$$ -is an example and test that prints to an standard string stream. -This function automatically check for correct output. - -$end ------------------------------------------------------------------------------- -*/ - -# include - -namespace CppAD { - template - void PrintFor( - const AD& notpos , - const char* before , - const AD& value , - const char* after ) - { CPPAD_ASSERT_NARG_NRES(local::PriOp, 5, 0); - - // check for case where we are not recording operations - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return; - - CPPAD_ASSERT_KNOWN( - std::strlen(before) <= 1000 , - "PrintFor: length of before is greater than 1000 characters" - ); - CPPAD_ASSERT_KNOWN( - std::strlen(after) <= 1000 , - "PrintFor: length of after is greater than 1000 characters" - ); - addr_t arg0, arg1, arg2, arg3, arg4; - - // arg[0] = base 2 representation of [Var(notpos), Var(value)] - arg0 = 0; - - // arg[1] = address for notpos - if( Constant(notpos) ) - arg1 = tape->Rec_.put_con_par(notpos.value_); - else if( Dynamic(notpos) ) - arg1 = notpos.taddr_; - else - { arg0 += 1; - arg1 = notpos.taddr_; - } - - // arg[2] = address of before - arg2 = tape->Rec_.PutTxt(before); - - // arg[3] = address for value - if( Constant(value) ) - arg3 = tape->Rec_.put_con_par(value.value_); - else if( Dynamic(value) ) - arg3 = value.taddr_; - else - { arg0 += 2; - arg3 = value.taddr_; - } - - // arg[4] = address of after - arg4 = tape->Rec_.PutTxt(after); - - // put the operator in the tape - tape->Rec_.PutArg(arg0, arg1, arg2, arg3, arg4); - tape->Rec_.PutOp(local::PriOp); - } - // Fold all other cases into the case above - template - void PrintFor(const char* before, const AD& value) - { PrintFor(AD(0), before, value, "" ); } - // - template - void PrintFor(const char* before, const VecAD_reference& value) - { PrintFor(AD(0), before, value.ADBase(), "" ); } - // - template - void PrintFor( - const VecAD_reference& notpos , - const char *before , - const VecAD_reference& value , - const char *after ) - { PrintFor(notpos.ADBase(), before, value.ADBase(), after); } - // - template - void PrintFor( - const VecAD_reference& notpos , - const char *before , - const AD& value , - const char *after ) - { PrintFor(notpos.ADBase(), before, value, after); } - // - template - void PrintFor( - const AD& notpos , - const char *before , - const VecAD_reference& value , - const char *after ) - { PrintFor(notpos, before, value.ADBase(), after); } -} - -# endif diff --git a/build-config/cppad/include/cppad/core/rev_hes_sparsity.hpp b/build-config/cppad/include/cppad/core/rev_hes_sparsity.hpp deleted file mode 100644 index 4bac9e41..00000000 --- a/build-config/cppad/include/cppad/core/rev_hes_sparsity.hpp +++ /dev/null @@ -1,253 +0,0 @@ -# ifndef CPPAD_CORE_REV_HES_SPARSITY_HPP -# define CPPAD_CORE_REV_HES_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin rev_hes_sparsity$$ -$spell - Jacobian - Hessian - jac - hes - bool - const - rc - cpp -$$ - -$section Reverse Mode Hessian Sparsity Patterns$$ - -$head Syntax$$ -$icode%f%.rev_hes_sparsity( - %select_range%, %transpose%, %internal_bool%, %pattern_out% -)%$$ - -$head Purpose$$ -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the -$cref/AD function/glossary/AD Function/$$ corresponding to -the operation sequence stored in $icode f$$. -Fix $latex R \in \B{R}^{n \times \ell}$$, $latex s \in \B{R}^m$$ -and define the function -$latex \[ - H(x) = ( s^\R{T} F )^{(2)} ( x ) R -\] $$ -Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$ -and for the vector $latex s$$, -$code rev_hes_sparsity$$ computes a sparsity pattern for $latex H(x)$$. - -$head x$$ -Note that the sparsity pattern $latex H(x)$$ corresponds to the -operation sequence stored in $icode f$$ and does not depend on -the argument $icode x$$. - -$head BoolVector$$ -The type $icode BoolVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$. - -$head SizeVector$$ -The type $icode SizeVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ - -$head R$$ -The sparsity pattern for the matrix $latex R$$ is specified by -$cref/pattern_in/for_jac_sparsity/pattern_in/$$ in the previous call -$codei% - %f%.for_jac_sparsity( - %pattern_in%, %transpose%, %dependency%, %internal_bool%, %pattern_out% -)%$$ - -$head select_range$$ -The argument $icode select_range$$ has prototype -$codei% - const %BoolVector%& %select_range% -%$$ -It has size $latex m$$ and specifies which components of the vector -$latex s$$ are non-zero; i.e., $icode%select_range%[%i%]%$$ is true -if and only if $latex s_i$$ is possibly non-zero. - -$head transpose$$ -This argument has prototype -$codei% - bool %transpose% -%$$ -See $cref/pattern_out/rev_hes_sparsity/pattern_out/$$ below. - -$head internal_bool$$ -If this is true, calculations are done with sets represented by a vector -of boolean values. Otherwise, a vector of sets of integers is used. -This must be the same as in the previous call to -$icode%f%.for_jac_sparsity%$$. - -$head pattern_out$$ -This argument has prototype -$codei% - sparse_rc<%SizeVector%>& %pattern_out% -%$$ -This input value of $icode pattern_out$$ does not matter. -If $icode transpose$$ it is false (true), -upon return $icode pattern_out$$ is a sparsity pattern for -$latex H(x)$$ ($latex H(x)^\R{T}$$). - -$head Sparsity for Entire Hessian$$ -Suppose that $latex R$$ is the $latex n \times n$$ identity matrix. -In this case, $icode pattern_out$$ is a sparsity pattern for -$latex (s^\R{T} F) F^{(2)} ( x )$$. - -$head Example$$ -$children% - example/sparse/rev_hes_sparsity.cpp -%$$ -The file -$cref rev_hes_sparsity.cpp$$ -contains an example and test of this operation. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/*! -Reverse Hessian sparsity patterns. - -\tparam Base -is the base type for this recording. - -\tparam BoolVector -is the simple vector with elements of type bool that is used for -sparsity for the vector s. - -\tparam SizeVector -is the simple vector with elements of type size_t that is used for -row, column index sparsity patterns. - -\param select_range -is a sparsity pattern for for s. - -\param transpose -Is the returned sparsity pattern transposed. - -\param internal_bool -If this is true, calculations are done with sets represented by a vector -of boolean values. Otherwise, a vector of standard sets is used. - -\param pattern_out -The value of transpose is false (true), -the return value is a sparsity pattern for H(x) ( H(x)^T ) where -\f[ - H(x) = R * F^{(1)} (x) -\f] -Here F is the function corresponding to the operation sequence -and x is any argument value. -*/ -template -template -void ADFun::rev_hes_sparsity( - const BoolVector& select_range , - bool transpose , - bool internal_bool , - sparse_rc& pattern_out ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); - size_t m = Range(); - // - CPPAD_ASSERT_KNOWN( - size_t( select_range.size() ) == m, - "rev_hes_sparsity: size of select_range is not equal to " - "number of dependent variables" - ); - // - // vector that holds reverse Jacobian sparsity flag - local::pod_vector rev_jac_pattern(num_var_tape_); - for(size_t i = 0; i < num_var_tape_; i++) - rev_jac_pattern[i] = false; - // - // initialize rev_jac_pattern for dependent variables - for(size_t i = 0; i < m; i++) - rev_jac_pattern[ dep_taddr_[i] ] = select_range[i]; - // - // - if( internal_bool ) - { CPPAD_ASSERT_KNOWN( - for_jac_sparse_pack_.n_set() > 0, - "rev_hes_sparsity: previous call to for_jac_sparsity did not " - "use bool for interanl sparsity patterns." - ); - // column dimension of internal sparstiy pattern - size_t ell = for_jac_sparse_pack_.end(); - // - // allocate memory for bool sparsity calculation - // (sparsity pattern is emtpy after a resize) - local::sparse::pack_setvec internal_hes; - internal_hes.resize(num_var_tape_, ell); - // - // compute the Hessian sparsity pattern - local::sweep::rev_hes( - &play_, - n, - num_var_tape_, - for_jac_sparse_pack_, - rev_jac_pattern.data(), - internal_hes, - not_used_rec_base - ); - // get sparstiy pattern for independent variables - local::sparse::get_internal_pattern( - transpose, ind_taddr_, internal_hes, pattern_out - ); - } - else - { CPPAD_ASSERT_KNOWN( - for_jac_sparse_set_.n_set() > 0, - "rev_hes_sparsity: previous call to for_jac_sparsity did not " - "use bool for interanl sparsity patterns." - ); - // column dimension of internal sparstiy pattern - size_t ell = for_jac_sparse_set_.end(); - // - // allocate memory for bool sparsity calculation - // (sparsity pattern is emtpy after a resize) - local::sparse::list_setvec internal_hes; - internal_hes.resize(num_var_tape_, ell); - // - // compute the Hessian sparsity pattern - local::sweep::rev_hes( - &play_, - n, - num_var_tape_, - for_jac_sparse_set_, - rev_jac_pattern.data(), - internal_hes, - not_used_rec_base - ); - // get sparstiy pattern for independent variables - local::sparse::get_internal_pattern( - transpose, ind_taddr_, internal_hes, pattern_out - ); - } - return; -} -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/rev_jac_sparsity.hpp b/build-config/cppad/include/cppad/core/rev_jac_sparsity.hpp deleted file mode 100644 index cc34d5f7..00000000 --- a/build-config/cppad/include/cppad/core/rev_jac_sparsity.hpp +++ /dev/null @@ -1,258 +0,0 @@ -# ifndef CPPAD_CORE_REV_JAC_SPARSITY_HPP -# define CPPAD_CORE_REV_JAC_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin rev_jac_sparsity$$ -$spell - Jacobian - jac - bool - const - rc - cpp -$$ - -$section Reverse Mode Jacobian Sparsity Patterns$$ - -$head Syntax$$ -$icode%f%.rev_jac_sparsity( - %pattern_in%, %transpose%, %dependency%, %internal_bool%, %pattern_out% -)%$$ - -$head Purpose$$ -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the -$cref/AD function/glossary/AD Function/$$ corresponding to -the operation sequence stored in $icode f$$. -Fix $latex R \in \B{R}^{\ell \times m}$$ and define the function -$latex \[ - J(x) = R * F^{(1)} ( x ) -\] $$ -Given the $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$, -$code rev_jac_sparsity$$ computes a sparsity pattern for $latex J(x)$$. - -$head x$$ -Note that the sparsity pattern $latex J(x)$$ corresponds to the -operation sequence stored in $icode f$$ and does not depend on -the argument $icode x$$. -(The operation sequence may contain -$cref CondExp$$ and $cref VecAD$$ operations.) - -$head SizeVector$$ -The type $icode SizeVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ - -$head pattern_in$$ -The argument $icode pattern_in$$ has prototype -$codei% - const sparse_rc<%SizeVector%>& %pattern_in% -%$$ -see $cref sparse_rc$$. -If $icode transpose$$ it is false (true), -$icode pattern_in$$ is a sparsity pattern for $latex R$$ ($latex R^\R{T}$$). - -$head transpose$$ -This argument has prototype -$codei% - bool %transpose% -%$$ -See $cref/pattern_in/rev_jac_sparsity/pattern_in/$$ above and -$cref/pattern_out/rev_jac_sparsity/pattern_out/$$ below. - -$head dependency$$ -This argument has prototype -$codei% - bool %dependency% -%$$ -see $cref/pattern_out/rev_jac_sparsity/pattern_out/$$ below. - -$head internal_bool$$ -If this is true, calculations are done with sets represented by a vector -of boolean values. Otherwise, a vector of sets of integers is used. - -$head pattern_out$$ -This argument has prototype -$codei% - sparse_rc<%SizeVector%>& %pattern_out% -%$$ -This input value of $icode pattern_out$$ does not matter. -If $icode transpose$$ it is false (true), -upon return $icode pattern_out$$ is a sparsity pattern for -$latex J(x)$$ ($latex J(x)^\R{T}$$). -If $icode dependency$$ is true, $icode pattern_out$$ is a -$cref/dependency pattern/dependency.cpp/Dependency Pattern/$$ -instead of sparsity pattern. - -$head Sparsity for Entire Jacobian$$ -Suppose that -$latex R$$ is the $latex m \times m$$ identity matrix. -In this case, $icode pattern_out$$ is a sparsity pattern for -$latex F^{(1)} ( x )$$ ( $latex F^{(1)} (x)^\R{T}$$ ) -if $icode transpose$$ is false (true). - -$head Example$$ -$children% - example/sparse/rev_jac_sparsity.cpp -%$$ -The file -$cref rev_jac_sparsity.cpp$$ -contains an example and test of this operation. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/*! -Reverse Jacobian sparsity patterns. - -\tparam Base -is the base type for this recording. - -\tparam SizeVector -is the simple vector with elements of type size_t that is used for -row, column index sparsity patterns. - -\param pattern_in -is the sparsity pattern for for R or R^T depending on transpose. - -\param transpose -Is the input and returned sparsity pattern transposed. - -\param dependency -Are the derivatives with respect to left and right of the expression below -considered to be non-zero: -\code - CondExpRel(left, right, if_true, if_false) -\endcode -This is used by the optimizer to obtain the correct dependency relations. - -\param internal_bool -If this is true, calculations are done with sets represented by a vector -of boolean values. Otherwise, a vector of standard sets is used. - -\param pattern_out -The value of transpose is false (true), -the return value is a sparsity pattern for J(x) ( J(x)^T ) where -\f[ - J(x) = R * F^{(1)} (x) -\f] -Here F is the function corresponding to the operation sequence -and x is any argument value. -*/ -template -template -void ADFun::rev_jac_sparsity( - const sparse_rc& pattern_in , - bool transpose , - bool dependency , - bool internal_bool , - sparse_rc& pattern_out ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - // number or rows, columns, and non-zeros in pattern_in - size_t nr_in = pattern_in.nr(); - size_t nc_in = pattern_in.nc(); - // - size_t ell = nr_in; - size_t m = nc_in; - if( transpose ) - std::swap(ell, m); - // - CPPAD_ASSERT_KNOWN( - m == Range() , - "rev_jac_sparsity: number columns in R " - "is not equal number of dependent variables." - ); - // number of independent variables - size_t n = Domain(); - // - bool zero_empty = true; - bool input_empty = true; - if( internal_bool ) - { // allocate memory for bool sparsity calculation - // (sparsity pattern is emtpy after a resize) - local::sparse::pack_setvec internal_jac; - internal_jac.resize(num_var_tape_, ell); - // - // set sparsity patttern for dependent variables - local::sparse::set_internal_pattern( - zero_empty , - input_empty , - ! transpose , - dep_taddr_ , - internal_jac , - pattern_in - ); - - // compute sparsity for other variables - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - internal_jac, - not_used_rec_base - - ); - // get sparstiy pattern for independent variables - local::sparse::get_internal_pattern( - ! transpose, ind_taddr_, internal_jac, pattern_out - ); - } - else - { // allocate memory for bool sparsity calculation - // (sparsity pattern is emtpy after a resize) - local::sparse::list_setvec internal_jac; - internal_jac.resize(num_var_tape_, ell); - // - // set sparsity patttern for dependent variables - local::sparse::set_internal_pattern( - zero_empty , - input_empty , - ! transpose , - dep_taddr_ , - internal_jac , - pattern_in - ); - - // compute sparsity for other variables - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - internal_jac, - not_used_rec_base - - ); - // get sparstiy pattern for independent variables - local::sparse::get_internal_pattern( - ! transpose, ind_taddr_, internal_jac, pattern_out - ); - } - return; -} -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/rev_one.hpp b/build-config/cppad/include/cppad/core/rev_one.hpp deleted file mode 100644 index 9c702b3c..00000000 --- a/build-config/cppad/include/cppad/core/rev_one.hpp +++ /dev/null @@ -1,161 +0,0 @@ -# ifndef CPPAD_CORE_REV_ONE_HPP -# define CPPAD_CORE_REV_ONE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin RevOne$$ -$spell - dw - Taylor - const -$$ - - - - -$section First Order Derivative: Driver Routine$$ - -$head Syntax$$ -$icode%dw% = %f%.RevOne(%x%, %i%)%$$ - - -$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$$. -The syntax above sets $icode dw$$ to the -derivative of $latex F_i$$ with respect to $latex x$$; i.e., -$latex \[ -dw = -F_i^{(1)} (x) -= \left[ - \D{ F_i }{ x_0 } (x) , \cdots , \D{ F_i }{ x_{n-1} } (x) -\right] -\] $$ - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$ -(see $cref/RevOne Uses Forward/RevOne/RevOne Uses Forward/$$ below). - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %Vector% &%x% -%$$ -(see $cref/Vector/RevOne/Vector/$$ below) -and its size -must be equal to $icode n$$, the dimension of the -$cref/domain/seq_property/Domain/$$ space for $icode f$$. -It specifies -that point at which to evaluate the derivative. - -$head i$$ -The index $icode i$$ has prototype -$codei% - size_t %i% -%$$ -and is less than $latex m$$, the dimension of the -$cref/range/seq_property/Range/$$ space for $icode f$$. -It specifies the -component of $latex F$$ that we are computing the derivative of. - -$head dw$$ -The result $icode dw$$ has prototype -$codei% - %Vector% %dw% -%$$ -(see $cref/Vector/RevOne/Vector/$$ below) -and its size is $icode n$$, the dimension of the -$cref/domain/seq_property/Domain/$$ space for $icode f$$. -The value of $icode dw$$ is the derivative of $latex F_i$$ -evaluated at $icode x$$; i.e., -for $latex j = 0 , \ldots , n - 1 $$ -$latex \[. - dw[ j ] = \D{ F_i }{ x_j } ( x ) -\] $$ - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$icode Base$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head RevOne Uses Forward$$ -After each call to $cref Forward$$, -the object $icode f$$ contains the corresponding -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$. -After a call to $code RevOne$$, -the zero order Taylor coefficients correspond to -$icode%f%.Forward(0, %x%)%$$ -and the other coefficients are unspecified. - -$head Example$$ -$children% - example/general/rev_one.cpp -%$$ -The routine -$cref/RevOne/rev_one.cpp/$$ is both an example and test. -It returns $code true$$, if it succeeds and $code false$$ otherwise. - -$end ------------------------------------------------------------------------------ -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -template -Vector ADFun::RevOne(const Vector &x, size_t i) -{ size_t i1; - - size_t n = Domain(); - size_t m = Range(); - - // check Vector is Simple Vector class with Base type elements - CheckSimpleVector(); - - CPPAD_ASSERT_KNOWN( - x.size() == n, - "RevOne: Length of x not equal domain dimension for f" - ); - CPPAD_ASSERT_KNOWN( - i < m, - "RevOne: the index i is not less than range dimension for f" - ); - - // point at which we are evaluating the derivative - Forward(0, x); - - // component which are are taking the derivative of - Vector w(m); - for(i1 = 0; i1 < m; i1++) - w[i1] = 0.; - w[i] = Base(1.0); - - // dimension the return value - Vector dw(n); - - // compute the return value - dw = Reverse(1, w); - - return dw; -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/rev_sparse_hes.hpp b/build-config/cppad/include/cppad/core/rev_sparse_hes.hpp deleted file mode 100644 index 6e11d187..00000000 --- a/build-config/cppad/include/cppad/core/rev_sparse_hes.hpp +++ /dev/null @@ -1,643 +0,0 @@ -# ifndef CPPAD_CORE_REV_SPARSE_HES_HPP -# define CPPAD_CORE_REV_SPARSE_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin RevSparseHes$$ -$spell - std - VecAD - Jacobian - Jac - Hessian - Hes - const - Bool - Dep - proportional - var - cpp -$$ - -$section Hessian Sparsity Pattern: Reverse Mode$$ - -$head Syntax$$ -$icode%h% = %f%.RevSparseHes(%q%, %s%) -%$$ -$icode%h% = %f%.RevSparseHes(%q%, %s%, %transpose%)%$$ - -$head Purpose$$ -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the -$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$. -For a fixed matrix $latex R \in \B{R}^{n \times q}$$ -and a fixed vector $latex S \in \B{R}^{1 \times m}$$, -we define -$latex \[ -\begin{array}{rcl} -H(x) -& = & \partial_x \left[ \partial_u S * F[ x + R * u ] \right]_{u=0} -\\ -& = & R^\R{T} * (S * F)^{(2)} ( x ) -\\ -H(x)^\R{T} -& = & (S * F)^{(2)} ( x ) * R -\end{array} -\] $$ -Given a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the matrix $latex R$$ and the vector $latex S$$, -$code RevSparseHes$$ returns a sparsity pattern for the $latex H(x)$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - const ADFun<%Base%> %f% -%$$ - -$head x$$ -If the operation sequence in $icode f$$ is -$cref/independent/glossary/Operation/Independent/$$ of -the independent variables in $latex x \in \B{R}^n$$, -the sparsity pattern is valid for all values of -(even if it has $cref CondExp$$ or $cref VecAD$$ operations). - -$head q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of columns in $latex R \in \B{R}^{n \times q}$$ -and the number of rows in $latex H(x) \in \B{R}^{q \times n}$$. -It must be the same value as in the previous $cref ForSparseJac$$ call -$codei% - %f%.ForSparseJac(%q%, %r%, %r_transpose%) -%$$ -Note that if $icode r_transpose$$ is true, $icode r$$ in the call above -corresponding to $latex R^\R{T} \in \B{R}^{q \times n}$$ - -$head transpose$$ -The argument $icode transpose$$ has prototype -$codei% - bool %transpose% -%$$ -The default value $code false$$ is used when $icode transpose$$ is not present. - - -$head r$$ -The matrix $latex R$$ is specified by the previous call -$codei% - %f%.ForSparseJac(%q%, %r%, %transpose%) -%$$ -see $cref/r/ForSparseJac/r/$$. -The type of the elements of -$cref/SetVector/RevSparseHes/SetVector/$$ must be the -same as the type of the elements of $icode r$$. - -$head s$$ -The argument $icode s$$ has prototype -$codei% - const %SetVector%& %s% -%$$ -(see $cref/SetVector/RevSparseHes/SetVector/$$ below) -If it has elements of type $code bool$$, -its size is $latex m$$. -If it has elements of type $code std::set$$, -its size is one and all the elements of $icode%s%[0]%$$ -are between zero and $latex m - 1$$. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the vector $icode S$$. - -$head h$$ -The result $icode h$$ has prototype -$codei% - %SetVector%& %h% -%$$ -(see $cref/SetVector/RevSparseHes/SetVector/$$ below). - -$subhead transpose false$$ -If $icode h$$ has elements of type $code bool$$, -its size is $latex q * n$$. -If it has elements of type $code std::set$$, -its size is $latex q$$ and all the set elements are between -zero and $icode%n%-1%$$ inclusive. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the matrix $latex H(x)$$. - -$subhead transpose true$$ -If $icode h$$ has elements of type $code bool$$, -its size is $latex n * q$$. -If it has elements of type $code std::set$$, -its size is $latex n$$ and all the set elements are between -zero and $icode%q%-1%$$ inclusive. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the matrix $latex H(x)^\R{T}$$. - -$head SetVector$$ -The type $icode SetVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$ or $code std::set$$; -see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion -of the difference. -The type of the elements of -$cref/SetVector/RevSparseHes/SetVector/$$ must be the -same as the type of the elements of $icode r$$. - -$head Entire Sparsity Pattern$$ -Suppose that $latex q = n$$ and -$latex R \in \B{R}^{n \times n}$$ is the $latex n \times n$$ identity matrix. -Further suppose that the $latex S$$ is the $th k$$ -$cref/elementary vector/glossary/Elementary Vector/$$; i.e. -$latex \[ -S_j = \left\{ \begin{array}{ll} - 1 & {\rm if} \; j = k - \\ - 0 & {\rm otherwise} -\end{array} \right. -\] $$ -In this case, -the corresponding value $icode h$$ is a -sparsity pattern for the Hessian matrix -$latex F_k^{(2)} (x) \in \B{R}^{n \times n}$$. - -$head Example$$ -$children% - example/sparse/rev_sparse_hes.cpp - %example/sparse/sparsity_sub.cpp -%$$ -The file -$cref rev_sparse_hes.cpp$$ -contains an example and test of this operation. -The file -$cref/sparsity_sub.cpp/sparsity_sub.cpp/RevSparseHes/$$ -contains an example and test of using $code RevSparseHes$$ -to compute the sparsity pattern for a subset of the Hessian. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file core/rev_sparse_hes.hpp -Reverse mode Hessian sparsity patterns. -*/ -// =========================================================================== -// RevSparseHesCase -/*! -Private helper function for RevSparseHes(q, s) bool sparsity. - -All of the description in the public member function RevSparseHes(q, s) -applies. - -\param set_type -is a bool value. This argument is used to dispatch to the proper source -code depending on the vlaue of SetVector::value_type. - -\param transpose -See RevSparseHes(q, s). - -\param q -See RevSparseHes(q, s). - -\param s -See RevSparseHes(q, s). - -\param h -is the return value for the corresponging call to RevSparseJac(q, s). -*/ -template -template -void ADFun::RevSparseHesCase( - bool set_type , - bool transpose , - size_t q , - const SetVector& s , - SetVector& h ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); - size_t m = Range(); - // - h.resize(q * n ); - - CPPAD_ASSERT_KNOWN( - for_jac_sparse_pack_.n_set() > 0, - "RevSparseHes: previous stored call to ForSparseJac did not " - "use bool for the elements of r." - ); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == 0 ); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == num_var_tape_ ); - // - // temporary indices - size_t i, j; - - // check Vector is Simple SetVector class with bool elements - CheckSimpleVector(); - - CPPAD_ASSERT_KNOWN( - q == for_jac_sparse_pack_.end(), - "RevSparseHes: q is not equal to its value\n" - "in the previous call to ForSparseJac with this ADFun object." - ); - CPPAD_ASSERT_KNOWN( - size_t(s.size()) == m, - "RevSparseHes: size of s is not equal to\n" - "range dimension for ADFun object." - ); - - // Array that will hold reverse Jacobian dependency flag. - // Initialize as true for the dependent variables. - local::pod_vector RevJac(num_var_tape_); - for(i = 0; i < num_var_tape_; i++) - RevJac[i] = false; - for(i = 0; i < m; i++) - { CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); - RevJac[ dep_taddr_[i] ] = s[i]; - } - - // vector of sets that will hold reverse Hessain values - local::sparse::pack_setvec rev_hes_pattern; - rev_hes_pattern.resize(num_var_tape_, q); - - // compute the Hessian sparsity patterns - local::sweep::rev_hes( - &play_, - n, - num_var_tape_, - for_jac_sparse_pack_, - RevJac.data(), - rev_hes_pattern, - not_used_rec_base - - ); - - // return values corresponding to independent variables - CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n * q ); - for(j = 0; j < n; j++) - { for(i = 0; i < q; i++) - { if( transpose ) - h[ j * q + i ] = false; - else - h[ i * n + j ] = false; - } - } - - // j is index corresponding to reverse mode partial - for(j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ ); - - // ind_taddr_[j] is operator taddr for j-th independent variable - CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 ); - CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp ); - - // extract the result from rev_hes_pattern - CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q ); - local::sparse::pack_setvec::const_iterator itr(rev_hes_pattern, j + 1); - i = *itr; - while( i < q ) - { if( transpose ) - h[ j * q + i ] = true; - else - h[ i * n + j ] = true; - i = *(++itr); - } - } -} -/*! -Private helper function for RevSparseHes(q, s) set sparsity. - -All of the description in the public member function RevSparseHes(q, s) -applies. - -\param set_type -is a std::set value. -This argument is used to dispatch to the proper source -code depending on the vlaue of SetVector::value_type. - -\param transpose -See RevSparseHes(q, s). - -\param q -See RevSparseHes(q, s). - -\param s -See RevSparseHes(q, s). - -\param h -is the return value for the corresponging call to RevSparseJac(q, s). -*/ -template -template -void ADFun::RevSparseHesCase( - const std::set& set_type , - bool transpose , - size_t q , - const SetVector& s , - SetVector& h ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); -# ifndef NDEBUG - size_t m = Range(); -# endif - // - if( transpose ) - h.resize(n); - else - h.resize(q); - - CPPAD_ASSERT_KNOWN( - for_jac_sparse_set_.n_set() > 0, - "RevSparseHes: previous stored call to ForSparseJac did not " - "use std::set for the elements of r." - ); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 ); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == num_var_tape_ ); - // - // temporary indices - size_t i, j; - std::set::const_iterator itr_1; - - // check SetVector is Simple Vector class with sets for elements - CheckSimpleVector, SetVector>( - local::one_element_std_set(), local::two_element_std_set() - ); - - CPPAD_ASSERT_KNOWN( - q == for_jac_sparse_set_.end(), - "RevSparseHes: q is not equal to its value\n" - "in the previous call to ForSparseJac with this ADFun object." - ); - CPPAD_ASSERT_KNOWN( - s.size() == 1, - "RevSparseHes: size of s is not equal to one." - ); - - // Array that will hold reverse Jacobian dependency flag. - // Initialize as true for the dependent variables. - local::pod_vector RevJac(num_var_tape_); - for(i = 0; i < num_var_tape_; i++) - RevJac[i] = false; - itr_1 = s[0].begin(); - while( itr_1 != s[0].end() ) - { i = *itr_1++; - CPPAD_ASSERT_KNOWN( - i < m, - "RevSparseHes: an element of the set s[0] has value " - "greater than or equal m" - ); - CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); - RevJac[ dep_taddr_[i] ] = true; - } - - - // vector of sets that will hold reverse Hessain values - local::sparse::list_setvec rev_hes_pattern; - rev_hes_pattern.resize(num_var_tape_, q); - - // compute the Hessian sparsity patterns - local::sweep::rev_hes( - &play_, - n, - num_var_tape_, - for_jac_sparse_set_, - RevJac.data(), - rev_hes_pattern, - not_used_rec_base - - ); - - // return values corresponding to independent variables - // j is index corresponding to reverse mode partial - CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == q || transpose ); - CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n || ! transpose ); - for(j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ ); - CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 ); - CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp ); - - // extract the result from rev_hes_pattern - // and add corresponding elements to result sets in h - CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q ); - local::sparse::list_setvec::const_iterator itr_2(rev_hes_pattern, j+1); - i = *itr_2; - while( i < q ) - { if( transpose ) - h[j].insert(i); - else - h[i].insert(j); - i = *(++itr_2); - } - } -} - -// =========================================================================== -// RevSparseHes - -/*! -User API for Hessian sparsity patterns using reverse mode. - -The C++ source code corresponding to this operation is -\verbatim - h = f.RevSparseHes(q, r) -\endverbatim - -\tparam Base -is the base type for this recording. - -\tparam SetVector -is a simple vector with elements of type bool -or std::set. - -\param transpose -is true (false) if is is equal to \f$ H(x) \f$ (\f$ H(x)^T \f$) -where -\f[ - H(x) = R^T (S * F)^{(2)} (x) -\f] -where \f$ F \f$ is the function corresponding to the operation sequence -and x is any argument value. - -\param q -is the value of q in the -by the previous call of the form -\verbatim - f.ForSparseJac(q, r, packed) -\endverbatim -The value r in this call is a sparsity pattern for the matrix \f$ R \f$. -The type of the element of r for the previous call to ForSparseJac -must be the same as the type of the elements of s. - -\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. - -\return -If transpose is false (true), -the return vector is a sparsity pattern for \f$ H(x) \f$ (\f$ H(x)^T \f$). -\f[ - H(x) = R^T ( S * F)^{(2)} (x) -\f] -where \f$ F \f$ is the function corresponding to the operation sequence -and x is any argument value. -*/ - -template -template -SetVector ADFun::RevSparseHes( - size_t q, const SetVector& s, bool transpose -) -{ - SetVector h; - typedef typename SetVector::value_type Set_type; - - // Should check to make sure q is same as in previous call to - // forward sparse Jacobian. - RevSparseHesCase( - Set_type() , - transpose , - q , - s , - h - ); - - return h; -} -// =========================================================================== -// RevSparseHesCheckpoint -/*! -Hessian sparsity patterns calculation used by checkpoint functions. - -\tparam Base -is the base type for this recording. - -\param transpose -is true (false) h is equal to \f$ H(x) \f$ (\f$ H(x)^T \f$) -where -\f[ - H(x) = R^T (S * F)^{(2)} (x) -\f] -where \f$ F \f$ is the function corresponding to the operation sequence -and \f$ x \f$ is any argument value. - -\param q -is the value of q in the by the previous call of the form -\verbatim - f.ForSparseJac(q, r) -\endverbatim -The value r in this call is a sparsity pattern for the matrix \f$ R \f$. - -\param s -is a vector with size m that specifies the sparsity pattern -for the vector \f$ S \f$, -where m is the number of dependent variables -corresponding to the operation sequence stored in play_. - -\param h -The input size and elements of h do not matter. -On output, h is the sparsity pattern for the matrix \f$ H(x) \f$ -or \f$ H(x)^T \f$ depending on transpose. - -\par Assumptions -The forward jacobian sparsity pattern must be currently stored -in this ADFUN object. -*/ -template -void ADFun::RevSparseHesCheckpoint( - size_t q , - vector& s , - bool transpose , - local::sparse::list_setvec& h ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); - size_t m = Range(); - - // checkpoint functions should get this right - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 ); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == num_var_tape_ ); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end() == q ); - CPPAD_ASSERT_UNKNOWN( s.size() == m ); - - // Array that holds the reverse Jacobiain dependcy flags. - // Initialize as true for dependent variables, flase for others. - local::pod_vector RevJac(num_var_tape_); - for(size_t i = 0; i < num_var_tape_; i++) - RevJac[i] = false; - for(size_t i = 0; i < m; i++) - { CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ) - RevJac[ dep_taddr_[i] ] = s[i]; - } - - // holds reverse Hessian sparsity pattern for all variables - local::sparse::list_setvec rev_hes_pattern; - rev_hes_pattern.resize(num_var_tape_, q); - - // compute Hessian sparsity pattern for all variables - local::sweep::rev_hes( - &play_, - n, - num_var_tape_, - for_jac_sparse_set_, - RevJac.data(), - rev_hes_pattern, - not_used_rec_base - - ); - - // dimension the return value - if( transpose ) - h.resize(n, q); - else - h.resize(q, n); - - // j is index corresponding to reverse mode partial - for(size_t j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ ); - - // ind_taddr_[j] is operator taddr for j-th independent variable - CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 ); - CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp ); - - // extract the result from rev_hes_pattern - CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q ); - local::sparse::list_setvec::const_iterator itr(rev_hes_pattern, j + 1); - size_t i = *itr; - while( i < q ) - { if( transpose ) - h.post_element(j, i); - else - h.post_element(i, j); - i = *(++itr); - } - } - for(size_t i = 0; i < h.n_set(); ++i) - h.process_post(i); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/rev_sparse_jac.hpp b/build-config/cppad/include/cppad/core/rev_sparse_jac.hpp deleted file mode 100644 index 8ea33422..00000000 --- a/build-config/cppad/include/cppad/core/rev_sparse_jac.hpp +++ /dev/null @@ -1,654 +0,0 @@ -# ifndef CPPAD_CORE_REV_SPARSE_JAC_HPP -# define CPPAD_CORE_REV_SPARSE_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin RevSparseJac$$ -$spell - optimizer - nz - CondExpRel - std - VecAD - var - Jacobian - Jac - const - Bool - Dep - proportional -$$ - -$section Jacobian Sparsity Pattern: Reverse Mode$$ - -$head Syntax$$ -$icode%s% = %f%.RevSparseJac(%q%, %r%) -%$$ -$icode%s% = %f%.RevSparseJac(%q%, %r%, %transpose%, %dependency%)%$$ - -$head Purpose$$ -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the -$cref/AD function/glossary/AD Function/$$ corresponding to $icode f$$. -For a fixed matrix $latex R \in \B{R}^{q \times m}$$, -the Jacobian of $latex R * F( x )$$ -with respect to $latex x$$ is -$latex \[ - S(x) = R * F^{(1)} ( x ) -\] $$ -Given a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for $latex R$$, -$code RevSparseJac$$ returns a sparsity pattern for the $latex S(x)$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ - -$head x$$ -If the operation sequence in $icode f$$ is -$cref/independent/glossary/Operation/Independent/$$ of -the independent variables in $latex x \in \B{R}^n$$, -the sparsity pattern is valid for all values of -(even if it has $cref CondExp$$ or $cref VecAD$$ operations). - -$head q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -It specifies the number of rows in -$latex R \in \B{R}^{q \times m}$$ and the -Jacobian $latex S(x) \in \B{R}^{q \times n}$$. - -$head transpose$$ -The argument $icode transpose$$ has prototype -$codei% - bool %transpose% -%$$ -The default value $code false$$ is used when $icode transpose$$ is not present. - -$head dependency$$ -The argument $icode dependency$$ has prototype -$codei% - bool %dependency% -%$$ -If $icode dependency$$ is true, -the $cref/dependency pattern/dependency.cpp/Dependency Pattern/$$ -(instead of sparsity pattern) is computed. - -$head r$$ -The argument $icode s$$ has prototype -$codei% - const %SetVector%& %r% -%$$ -see $cref/SetVector/RevSparseJac/SetVector/$$ below. - -$subhead transpose false$$ -If $icode r$$ has elements of type $code bool$$, -its size is $latex q * m$$. -If it has elements of type $code std::set$$, -its size is $icode q$$ and all its set elements are between -zero and $latex m - 1$$. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the matrix $latex R \in \B{R}^{q \times m}$$. - -$subhead transpose true$$ -If $icode r$$ has elements of type $code bool$$, -its size is $latex m * q$$. -If it has elements of type $code std::set$$, -its size is $icode m$$ and all its set elements are between -zero and $latex q - 1$$. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the matrix $latex R^\R{T} \in \B{R}^{m \times q}$$. - -$head s$$ -The return value $icode s$$ has prototype -$codei% - %SetVector% %s% -%$$ -see $cref/SetVector/RevSparseJac/SetVector/$$ below. - -$subhead transpose false$$ -If it has elements of type $code bool$$, -its size is $latex q * n$$. -If it has elements of type $code std::set$$, -its size is $icode q$$ and all its set elements are between -zero and $latex n - 1$$. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the matrix $latex S(x) \in {q \times n}$$. - -$subhead transpose true$$ -If it has elements of type $code bool$$, -its size is $latex n * q$$. -If it has elements of type $code std::set$$, -its size is $icode n$$ and all its set elements are between -zero and $latex q - 1$$. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the matrix $latex S(x)^\R{T} \in {n \times q}$$. - -$head SetVector$$ -The type $icode SetVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$ or $code std::set$$; -see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion -of the difference. - -$head Entire Sparsity Pattern$$ -Suppose that $latex q = m$$ and -$latex R$$ is the $latex m \times m$$ identity matrix. -In this case, -the corresponding value for $icode s$$ is a -sparsity pattern for the Jacobian $latex S(x) = F^{(1)} ( x )$$. - -$head Example$$ -$children% - example/sparse/rev_sparse_jac.cpp -%$$ -The file -$cref rev_sparse_jac.cpp$$ -contains an example and test of this operation. - -$end ------------------------------------------------------------------------------ -*/ - -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file core/rev_sparse_jac.hpp -Reverse mode Jacobian sparsity patterns. -*/ -// ========================================================================= -// RevSparseJacCase - -/*! -Private helper function for RevSparseJac(q, r, transpose) boolean sparsity. - -All of the description in the public member function - RevSparseJac(q, r, transpose) apply. - -\param set_type -is a bool value. -This argument is used to dispatch to the proper source code -depending on the value of SetVector::value_type. - -\param transpose -See RevSparseJac(q, r, transpose, dependency) - -\param dependency -See RevSparseJac(q, r, transpose, dependency) - -\param q -See RevSparseJac(q, r, transpose, dependency) - -\param r -See RevSparseJac(q, r, transpose, dependency) - -\param s -is the return value for the corresponding call to -RevSparseJac(q, r, transpose). -*/ - -template -template -void ADFun::RevSparseJacCase( - bool set_type , - bool transpose , - bool dependency , - size_t q , - const SetVector& r , - SetVector& s ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); - size_t m = Range(); - - // dimension of the result vector - s.resize( q * n ); - - // check SetVector is Simple Vector class with bool elements - CheckSimpleVector(); - // - CPPAD_ASSERT_KNOWN( - q > 0, - "RevSparseJac: q is not greater than zero" - ); - CPPAD_ASSERT_KNOWN( - size_t(r.size()) == q * m, - "RevSparseJac: size of r is not equal to\n" - "q times range dimension for ADFun object." - ); - // - // vector of sets that will hold the results - local::sparse::pack_setvec var_sparsity; - var_sparsity.resize(num_var_tape_, q); - - // The sparsity pattern corresponding to the dependent variables - for(size_t i = 0; i < m; i++) - { CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); - if( transpose ) - { for(size_t j = 0; j < q; j++) if( r[ i * q + j ] ) - var_sparsity.post_element( dep_taddr_[i], j ); - } - else - { for(size_t j = 0; j < q; j++) if( r[ j * m + i ] ) - var_sparsity.post_element( dep_taddr_[i], j ); - } - } - // process posts - for(size_t i = 0; i < m; i++) - var_sparsity.process_post( dep_taddr_[i] ); - - // evaluate the sparsity patterns - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - var_sparsity, - not_used_rec_base - - ); - - // return values corresponding to dependent variables - CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q * n ); - for(size_t j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) ); - - // ind_taddr_[j] is operator taddr for j-th independent variable - CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp ); - - // extract the result from var_sparsity - if( transpose ) - { for(size_t i = 0; i < q; i++) - s[ j * q + i ] = false; - } - else - { for(size_t i = 0; i < q; i++) - s[ i * n + j ] = false; - } - CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q ); - local::sparse::pack_setvec::const_iterator itr(var_sparsity, j+1); - size_t i = *itr; - while( i < q ) - { if( transpose ) - s[ j * q + i ] = true; - else - s[ i * n + j ] = true; - i = *(++itr); - } - } -} - -/*! -Private helper function for RevSparseJac(q, r, transpose) set sparsity - -All of the description in the public member function - RevSparseJac(q, r, transpose) apply. - -\param set_type -is a std::set object. -This argument is used to dispatch to the proper source code -depending on the value of SetVector::value_type. - -\param transpose -See RevSparseJac(q, r, transpose, dependency) - -\param dependency -See RevSparseJac(q, r, transpose, dependency) - -\param q -See RevSparseJac(q, r, transpose, dependency) - -\param r -See RevSparseJac(q, r, transpose, dependency) - -\param s -is the return value for the corresponding call to RevSparseJac(q, r, transpose) -*/ - -template -template -void ADFun::RevSparseJacCase( - const std::set& set_type , - bool transpose , - bool dependency , - size_t q , - const SetVector& r , - SetVector& s ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - // dimension of the result vector - if( transpose ) - s.resize( Domain() ); - else - s.resize( q ); - - // temporary indices - std::set::const_iterator itr_1; - - // check SetVector is Simple Vector class with sets for elements - CheckSimpleVector, SetVector>( - local::one_element_std_set(), local::two_element_std_set() - ); - - // domain dimensions for F - size_t n = ind_taddr_.size(); - size_t m = dep_taddr_.size(); - - CPPAD_ASSERT_KNOWN( - q > 0, - "RevSparseJac: q is not greater than zero" - ); - CPPAD_ASSERT_KNOWN( - size_t(r.size()) == q || transpose, - "RevSparseJac: size of r is not equal to q and transpose is false." - ); - CPPAD_ASSERT_KNOWN( - size_t(r.size()) == m || ! transpose, - "RevSparseJac: size of r is not equal to m and transpose is true." - ); - - // vector of lists that will hold the results - local::sparse::list_setvec var_sparsity; - var_sparsity.resize(num_var_tape_, q); - - // The sparsity pattern corresponding to the dependent variables - if( transpose ) - { for(size_t i = 0; i < m; i++) - { itr_1 = r[i].begin(); - while(itr_1 != r[i].end()) - { size_t j = *itr_1++; - CPPAD_ASSERT_KNOWN( - j < q, - "RevSparseJac: transpose is true and element of the set\n" - "r[i] has value greater than or equal q." - ); - CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); - var_sparsity.post_element( dep_taddr_[i], j ); - } - } - } - else - { for(size_t i = 0; i < q; i++) - { itr_1 = r[i].begin(); - while(itr_1 != r[i].end()) - { size_t j = *itr_1++; - CPPAD_ASSERT_KNOWN( - j < m, - "RevSparseJac: transpose is false and element of the set\n" - "r[i] has value greater than or equal range dimension." - ); - CPPAD_ASSERT_UNKNOWN( dep_taddr_[j] < num_var_tape_ ); - var_sparsity.post_element( dep_taddr_[j], i ); - } - } - } - // process posts - for(size_t i = 0; i < m; i++) - var_sparsity.process_post( dep_taddr_[i] ); - - // evaluate the sparsity patterns - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - var_sparsity, - not_used_rec_base - - ); - - // return values corresponding to dependent variables - CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || transpose ); - CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == n || ! transpose ); - for(size_t j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) ); - - // ind_taddr_[j] is operator taddr for j-th independent variable - CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp ); - - CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q ); - local::sparse::list_setvec::const_iterator itr_2(var_sparsity, j+1); - size_t i = *itr_2; - while( i < q ) - { if( transpose ) - s[j].insert(i); - else - s[i].insert(j); - i = *(++itr_2); - } - } -} - -// ========================================================================= -// RevSparseJac -/*! -User API for Jacobian sparsity patterns using reverse mode. - -The C++ source code corresponding to this operation is -\verbatim - s = f.RevSparseJac(q, r, transpose, dependency) -\endverbatim - -\tparam Base -is the base type for this recording. - -\tparam SetVector -is a simple vector with elements of type bool. -or std::set. - -\param q -is the number of rows in the matrix \f$ R \f$. - -\param r -is a sparsity pattern for the matrix \f$ R \f$. - -\param transpose -are the sparsity patterns for \f$ R \f$ and \f$ S(x) \f$ transposed. - -\param dependency -Are the derivatives with respect to left and right of the expression below -considered to be non-zero: -\code - CondExpRel(left, right, if_true, if_false) -\endcode -This is used by the optimizer to obtain the correct dependency relations. - - -\return -If transpose is false (true), the return value is a sparsity pattern -for \f$ S(x) \f$ (\f$ S(x)^T \f$) where -\f[ - S(x) = R * F^{(1)} (x) -\f] -and \f$ F \f$ is the function corresponding to the operation sequence -and x is any argument value. -If SetVector::value_type is bool, -the return value has size \f$ q * n \f$ ( \f$ n * q \f$). -If SetVector::value_type is std::set, -the return value has size \f$ q \f$ ( \f$ n \f$) -and with all its elements between zero and \f$ n - 1 \f$ (\f$ q - 1 \f$). -*/ -template -template -SetVector ADFun::RevSparseJac( - size_t q , - const SetVector& r , - bool transpose , - bool dependency ) -{ - SetVector s; - typedef typename SetVector::value_type Set_type; - - RevSparseJacCase( - Set_type() , - transpose , - dependency , - q , - r , - s - ); - return s; -} -// =========================================================================== -// RevSparseJacCheckpoint -/*! -Reverse mode Jacobian sparsity calculation used by checkpoint functions. - -\tparam Base -is the base type for this recording. - -\param transpose -is true (false) s is equal to \f$ S(x) \f$ (\f$ S(x)^T \f$) -where -\f[ - S(x) = R * F^{(1)} (x) -\f] -where \f$ F \f$ is the function corresponding to the operation sequence -and \f$ x \f$ is any argument value. - -\param q -is the number of rows in the matrix \f$ R \f$. - -\param r -is a sparsity pattern for the matrix \f$ R \f$. - -\param transpose -are the sparsity patterns for \f$ R \f$ and \f$ S(x) \f$ transposed. - -\param dependency -Are the derivatives with respect to left and right of the expression below -considered to be non-zero: -\code - CondExpRel(left, right, if_true, if_false) -\endcode -This is used by the optimizer to obtain the correct dependency relations. - -\param s -The input size and elements of s do not matter. -On output, s is the sparsity pattern for the matrix \f$ S(x) \f$ -or \f$ S(x)^T \f$ depending on transpose. - -*/ -template -void ADFun::RevSparseJacCheckpoint( - size_t q , - const local::sparse::list_setvec& r , - bool transpose , - bool dependency , - local::sparse::list_setvec& s ) -{ - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - size_t n = Domain(); - size_t m = Range(); - -# ifndef NDEBUG - if( transpose ) - { CPPAD_ASSERT_UNKNOWN( r.n_set() == m ); - CPPAD_ASSERT_UNKNOWN( r.end() == q ); - } - else - { CPPAD_ASSERT_UNKNOWN( r.n_set() == q ); - CPPAD_ASSERT_UNKNOWN( r.end() == m ); - } - for(size_t i = 0; i < m; i++) - CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); -# endif - - // holds reverse Jacobian sparsity pattern for all variables - local::sparse::list_setvec var_sparsity; - var_sparsity.resize(num_var_tape_, q); - - // set sparsity pattern for dependent variables - if( transpose ) - { for(size_t i = 0; i < m; i++) - { local::sparse::list_setvec::const_iterator itr(r, i); - size_t j = *itr; - while( j < q ) - { var_sparsity.post_element( dep_taddr_[i], j ); - j = *(++itr); - } - } - } - else - { for(size_t j = 0; j < q; j++) - { local::sparse::list_setvec::const_iterator itr(r, j); - size_t i = *itr; - while( i < m ) - { var_sparsity.post_element( dep_taddr_[i], j ); - i = *(++itr); - } - } - } - // process posts - for(size_t i = 0; i < m; i++) - var_sparsity.process_post( dep_taddr_[i] ); - - // evaluate the sparsity pattern for all variables - local::sweep::rev_jac( - &play_, - dependency, - n, - num_var_tape_, - var_sparsity, - not_used_rec_base - - ); - - // dimension the return value - if( transpose ) - s.resize(n, m); - else - s.resize(m, n); - - // return values corresponding to independent variables - for(size_t j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) ); - - // ind_taddr_[j] is operator taddr for j-th independent variable - CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp ); - - // extract the result from var_sparsity - CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q ); - local::sparse::list_setvec::const_iterator itr(var_sparsity, j+1); - size_t i = *itr; - while( i < q ) - { if( transpose ) - s.post_element(j, i); - else - s.post_element(i, j); - i = *(++itr); - } - } - // process posts - for(size_t i = 0; i < s.n_set(); i++) - s.process_post(i); - -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/rev_two.hpp b/build-config/cppad/include/cppad/core/rev_two.hpp deleted file mode 100644 index 43a928b8..00000000 --- a/build-config/cppad/include/cppad/core/rev_two.hpp +++ /dev/null @@ -1,234 +0,0 @@ -# ifndef CPPAD_CORE_REV_TWO_HPP -# define CPPAD_CORE_REV_TWO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin RevTwo$$ -$spell - ddw - typename - Taylor - const -$$ - - - - - -$section Reverse Mode Second Partial Derivative Driver$$ - -$head Syntax$$ -$icode%ddw% = %f%.RevTwo(%x%, %i%, %j%)%$$ - - -$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$$. -The syntax above sets -$latex \[ - ddw [ k * p + \ell ] - = - \DD{ F_{i[ \ell ]} }{ x_{j[ \ell ]} }{ x_k } (x) -\] $$ -for $latex k = 0 , \ldots , n-1$$ -and $latex \ell = 0 , \ldots , p$$, -where $latex p$$ is the size of the vectors $icode i$$ and $icode j$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$ -(see $cref/RevTwo Uses Forward/RevTwo/RevTwo Uses Forward/$$ below). - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %BaseVector% &%x% -%$$ -(see $cref/BaseVector/RevTwo/BaseVector/$$ below) -and its size -must be equal to $icode n$$, the dimension of the -$cref/domain/seq_property/Domain/$$ space for $icode f$$. -It specifies -that point at which to evaluate the partial derivatives listed above. - -$head i$$ -The argument $icode i$$ has prototype -$codei% - const %SizeVector_t% &%i% -%$$ -(see $cref/SizeVector_t/RevTwo/SizeVector_t/$$ below) -We use $icode p$$ to denote the size of the vector $icode i$$. -All of the indices in $icode i$$ -must be less than $icode m$$, the dimension of the -$cref/range/seq_property/Range/$$ space for $icode f$$; i.e., -for $latex \ell = 0 , \ldots , p-1$$, $latex i[ \ell ] < m$$. - -$head j$$ -The argument $icode j$$ has prototype -$codei% - const %SizeVector_t% &%j% -%$$ -(see $cref/SizeVector_t/RevTwo/SizeVector_t/$$ below) -and its size must be equal to $icode p$$, -the size of the vector $icode i$$. -All of the indices in $icode j$$ -must be less than $icode n$$; i.e., -for $latex \ell = 0 , \ldots , p-1$$, $latex j[ \ell ] < n$$. - -$head ddw$$ -The result $icode ddw$$ has prototype -$codei% - %BaseVector% %ddw% -%$$ -(see $cref/BaseVector/RevTwo/BaseVector/$$ below) -and its size is $latex n * p$$. -It contains the requested partial derivatives; to be specific, -for $latex k = 0 , \ldots , n - 1 $$ -and $latex \ell = 0 , \ldots , p - 1$$ -$latex \[ - ddw [ k * p + \ell ] - = - \DD{ F_{i[ \ell ]} }{ x_{j[ \ell ]} }{ x_k } (x) -\] $$ - -$head BaseVector$$ -The type $icode BaseVector$$ 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 SizeVector_t$$ -The type $icode SizeVector_t$$ must be a $cref SimpleVector$$ class with -$cref/elements of type size_t/SimpleVector/Elements of Specified Type/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head RevTwo Uses Forward$$ -After each call to $cref Forward$$, -the object $icode f$$ contains the corresponding -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$. -After a call to $code RevTwo$$, -the zero order Taylor coefficients correspond to -$icode%f%.Forward(0, %x%)%$$ -and the other coefficients are unspecified. - -$head Examples$$ -$children% - example/general/rev_two.cpp -%$$ -The routine -$cref/RevTwo/rev_two.cpp/$$ is both an example and test. -It returns $code true$$, if it succeeds and $code false$$ otherwise. - -$end ------------------------------------------------------------------------------ -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -template -BaseVector ADFun::RevTwo( - const BaseVector &x, - const SizeVector_t &i, - const SizeVector_t &j) -{ size_t i1; - size_t j1; - size_t k; - size_t l; - - size_t n = Domain(); - size_t m = Range(); - size_t p = i.size(); - - // check BaseVector is Simple Vector class with Base elements - CheckSimpleVector(); - - // check SizeVector_t is Simple Vector class with size_t elements - CheckSimpleVector(); - - CPPAD_ASSERT_KNOWN( - x.size() == n, - "RevTwo: Length of x not equal domain dimension for f." - ); - CPPAD_ASSERT_KNOWN( - i.size() == j.size(), - "RevTwo: Lenght of the i and j vectors are not equal." - ); - // point at which we are evaluating the second partials - Forward(0, x); - - // dimension the return value - BaseVector ddw(n * p); - - // direction vector in argument space - BaseVector dx(n); - for(j1 = 0; j1 < n; j1++) - dx[j1] = Base(0.0); - - // direction vector in range space - BaseVector w(m); - for(i1 = 0; i1 < m; i1++) - w[i1] = Base(0.0); - - // place to hold the results of a reverse calculation - BaseVector r(n * 2); - - // check the indices in i and j - for(l = 0; l < p; l++) - { i1 = i[l]; - j1 = j[l]; - CPPAD_ASSERT_KNOWN( - i1 < m, - "RevTwo: an eleemnt of i not less than range dimension for f." - ); - CPPAD_ASSERT_KNOWN( - j1 < n, - "RevTwo: an element of j not less than domain dimension for f." - ); - } - - // loop over all forward directions - for(j1 = 0; j1 < n; j1++) - { // first order forward mode calculation done - bool first_done = false; - for(l = 0; l < p; l++) if( j[l] == j1 ) - { if( ! first_done ) - { first_done = true; - - // first order forward mode in j1 direction - dx[j1] = Base(1.0); - Forward(1, dx); - dx[j1] = Base(0.0); - } - // execute a reverse in this component direction - i1 = i[l]; - w[i1] = Base(1.0); - r = Reverse(2, w); - w[i1] = Base(0.0); - - // place the reverse result in return value - for(k = 0; k < n; k++) - ddw[k * p + l] = r[k * 2 + 1]; - } - } - return ddw; -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/reverse.hpp b/build-config/cppad/include/cppad/core/reverse.hpp deleted file mode 100644 index 6ab09824..00000000 --- a/build-config/cppad/include/cppad/core/reverse.hpp +++ /dev/null @@ -1,208 +0,0 @@ -# ifndef CPPAD_CORE_REVERSE_HPP -# define CPPAD_CORE_REVERSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-21 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file core/reverse.hpp -Compute derivatives using reverse mode. -*/ - - -/*! -Use reverse mode to compute derivative of forward mode Taylor coefficients. - -The function -\f$ X : {\bf R} \times {\bf R}^{n \times q} \rightarrow {\bf R} \f$ -is defined by -\f[ -X(t , u) = \sum_{k=0}^{q-1} u^{(k)} t^k -\f] -The function -\f$ Y : {\bf R} \times {\bf R}^{n \times q} \rightarrow {\bf R} \f$ -is defined by -\f[ -Y(t , u) = F[ X(t, u) ] -\f] -The function -\f$ W : {\bf R}^{n \times q} \rightarrow {\bf R} \f$ is defined by -\f[ -W(u) = \sum_{k=0}^{q-1} ( w^{(k)} )^{\rm T} -\frac{1}{k !} \frac{ \partial^k } { t^k } Y(0, u) -\f] - -\tparam Base -base type for the operator; i.e., this operation sequence was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\tparam BaseVector -is a Simple Vector class with elements of type Base. - -\param q -is the number of the number of Taylor coefficients that are being -differentiated (per variable). - -\param w -is the weighting for each of the Taylor coefficients corresponding -to dependent variables. -If the argument w has size m * q , -for \f$ k = 0 , \ldots , q-1 \f$ and \f$ i = 0, \ldots , m-1 \f$, -\f[ - w_i^{(k)} = w [ i * q + k ] -\f] -If the argument w has size m , -for \f$ k = 0 , \ldots , q-1 \f$ and \f$ i = 0, \ldots , m-1 \f$, -\f[ -w_i^{(k)} = \left\{ \begin{array}{ll} - w [ i ] & {\rm if} \; k = q-1 - \\ - 0 & {\rm otherwise} -\end{array} \right. -\f] - -\return -Is a vector \f$ dw \f$ such that -for \f$ j = 0 , \ldots , n-1 \f$ and -\f$ k = 0 , \ldots , q-1 \f$ -\f[ - dw[ j * q + k ] = W^{(1)} ( x )_{j,k} -\f] -where the matrix \f$ x \f$ is the value for \f$ u \f$ -that corresponding to the forward mode Taylor coefficients -for the independent variables as specified by previous calls to Forward. - -*/ -template -template -BaseVector ADFun::Reverse(size_t q, const BaseVector &w) -{ // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - - // constants - const Base zero(0); - - // temporary indices - size_t i, j, k; - - // number of independent variables - size_t n = ind_taddr_.size(); - - // number of dependent variables - size_t m = dep_taddr_.size(); - - // check BaseVector is Simple Vector class with Base type elements - CheckSimpleVector(); - - CPPAD_ASSERT_KNOWN( - size_t(w.size()) == m || size_t(w.size()) == (m * q), - "Argument w to Reverse does not have length equal to\n" - "the dimension of the range or dimension of range times q." - ); - CPPAD_ASSERT_KNOWN( - q > 0, - "The first argument to Reverse must be greater than zero." - ); - CPPAD_ASSERT_KNOWN( - num_order_taylor_ >= q, - "Less than q Taylor coefficients are currently stored" - " in this ADFun object." - ); - // special case where multiple forward directions have been computed, - // but we are only using the one direction zero order results - if( (q == 1) & (num_direction_taylor_ > 1) ) - { num_order_taylor_ = 1; // number of orders to copy - size_t c = cap_order_taylor_; // keep the same capacity setting - size_t r = 1; // only keep one direction - capacity_order(c, r); - } - CPPAD_ASSERT_KNOWN( - num_direction_taylor_ == 1, - "Reverse mode for Forward(q, r, xq) with more than one direction" - "\n(r > 1) is not yet supported for q > 1." - ); - - // initialize entire Partial matrix to zero - local::pod_vector_maybe Partial(num_var_tape_ * q); - for(i = 0; i < num_var_tape_; i++) - for(j = 0; j < q; j++) - Partial[i * q + j] = zero; - - // set the dependent variable direction - // (use += because two dependent variables can point to same location) - for(i = 0; i < m; i++) - { CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ ); - if( size_t(w.size()) == m ) - Partial[dep_taddr_[i] * q + q - 1] += w[i]; - else - { for(k = 0; k < q; k++) - Partial[ dep_taddr_[i] * q + k ] += w[i * q + k ]; - } - } - - // evaluate the derivatives - CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() ); - CPPAD_ASSERT_UNKNOWN( load_op2var_.size() == play_.num_var_load_rec() ); - local::play::const_sequential_iterator play_itr = play_.end(); - local::sweep::reverse( - q - 1, - n, - num_var_tape_, - &play_, - cap_order_taylor_, - taylor_.data(), - q, - Partial.data(), - cskip_op_.data(), - load_op2var_, - play_itr, - not_used_rec_base - ); - - // return the derivative values - BaseVector value(n * q); - for(j = 0; j < n; j++) - { CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ ); - - // independent variable taddr equals its operator taddr - CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp ); - - // by the Reverse Identity Theorem - // partial of y^{(k)} w.r.t. u^{(0)} is equal to - // partial of y^{(q-1)} w.r.t. u^{(q - 1 - k)} - if( size_t(w.size()) == m ) - { for(k = 0; k < q; k++) - value[j * q + k ] = - Partial[ind_taddr_[j] * q + q - 1 - k]; - } - else - { for(k = 0; k < q; k++) - value[j * q + k ] = - Partial[ind_taddr_[j] * q + k]; - } - } - CPPAD_ASSERT_KNOWN( ! ( hasnan(value) && check_for_nan_ ) , - "dw = f.Reverse(q, w): has a nan,\n" - "but none of its Taylor coefficents are nan." - ); - - return value; -} - - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/sign.hpp b/build-config/cppad/include/cppad/core/sign.hpp deleted file mode 100644 index 27188fea..00000000 --- a/build-config/cppad/include/cppad/core/sign.hpp +++ /dev/null @@ -1,121 +0,0 @@ -# ifndef CPPAD_CORE_SIGN_HPP -# define CPPAD_CORE_SIGN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin sign$$ -$spell - CppAD - Dirac -$$ -$section The Sign: sign$$ - -$head Syntax$$ -$icode%y% = sign(%x%)%$$ - -$head Description$$ -Evaluates the $code sign$$ function which is defined by -$latex \[ -{\rm sign} (x) = -\left\{ \begin{array}{rl} - +1 & {\rm if} \; x > 0 \\ - 0 & {\rm if} \; x = 0 \\ - -1 & {\rm if} \; x < 0 -\end{array} \right. -\] $$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -CppAD computes the derivative of the $code sign$$ function as zero for all -argument values $icode x$$. -The correct mathematical derivative is different and -is given by -$latex \[ - {\rm sign}^{(1)} (x) = 2 \delta (x) -\] $$ -where $latex \delta (x)$$ is the Dirac Delta function. - -$head Example$$ -$children% - example/general/sign.cpp -%$$ -The file -$cref sign.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD AD::sign_me (void) const -{ - AD result; - result.value_ = sign(value_); - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - - // check if operand is a constant parameter - if( tape_id_ != tape->id_ ) - return result; - - if(ad_type_ == dynamic_enum) - { // dynamic paramter argument - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::sign_dyn, taddr_ - ); - result.tape_id_ = tape_id_; - result.ad_type_ = dynamic_enum; - } - else - { // variable argument - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SignOp) == 1 ); - - // corresponding operand address - tape->Rec_.PutArg(taddr_); - - // put operator in the tape - result.taddr_ = tape->Rec_.PutOp(local::SignOp); - - // make result a variable - result.tape_id_ = tape->id_; - result.ad_type_ = variable_enum; - } - return result; -} - -template -AD sign(const AD &x) -{ return x.sign_me(); -} -template -AD sign(const VecAD_reference &x) -{ return x.ADBase().sign_me(); } - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/sparse.hpp b/build-config/cppad/include/cppad/core/sparse.hpp deleted file mode 100644 index 7db70d82..00000000 --- a/build-config/cppad/include/cppad/core/sparse.hpp +++ /dev/null @@ -1,38 +0,0 @@ -# ifndef CPPAD_CORE_SPARSE_HPP -# define CPPAD_CORE_SPARSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// -# include -# include -// -# include -# include -// -# include -# include -// -# include -# include -// -# include -# include -// -# include -# include -// -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/sparse_hes.hpp b/build-config/cppad/include/cppad/core/sparse_hes.hpp deleted file mode 100644 index 15996a7d..00000000 --- a/build-config/cppad/include/cppad/core/sparse_hes.hpp +++ /dev/null @@ -1,544 +0,0 @@ -# ifndef CPPAD_CORE_SPARSE_HES_HPP -# define CPPAD_CORE_SPARSE_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin sparse_hes$$ -$spell - const - Taylor - rc - rcv - nr - nc - hes - std - cppad - colpack - cmake - Jacobian -$$ - -$section Computing Sparse Hessians$$ - -$head Syntax$$ -$icode%n_sweep% = %f%.sparse_hes( - %x%, %w%, %subset%, %pattern%, %coloring%, %work% -)%$$ - -$head Purpose$$ -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the -function corresponding to $icode f$$. -Here $icode n$$ is the $cref/domain/seq_property/Domain/$$ size, -and $icode m$$ is the $cref/range/seq_property/Range/$$ size, or $icode f$$. -The syntax above takes advantage of sparsity when computing the Hessian -$latex \[ - H(x) = \dpow{2}{x} \sum_{i=0}^{m-1} w_i F_i (x) -\] $$ -In the sparse case, this should be faster and take less memory than -$cref Hessian$$. -The matrix element $latex H_{i,j} (x)$$ is the second partial of -$latex w^\R{T} F (x)$$ with respect to $latex x_i$$ and $latex x_j$$. - -$head SizeVector$$ -The type $icode SizeVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. - -$head BaseVector$$ -The type $icode BaseVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. - -$head f$$ -This object has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the Taylor coefficients stored in $icode f$$ are affected -by this operation; see -$cref/uses forward/sparse_hes/Uses Forward/$$ below. - -$head x$$ -This argument has prototype -$codei% - const %BaseVector%& %x% -%$$ -and its size is $icode n$$. -It specifies the point at which to evaluate the Hessian -$latex H(x)$$. - -$head w$$ -This argument has prototype -$codei% - const %BaseVector%& %w% -%$$ -and its size is $icode m$$. -It specifies the weight for each of the components of $latex F(x)$$; -i.e. $latex w_i$$ is the weight for $latex F_i (x)$$. - -$head subset$$ -This argument has prototype -$codei% - sparse_rcv<%SizeVector%, %BaseVector%>& %subset% -%$$ -Its row size and column size is $icode n$$; i.e., -$icode%subset%.nr() == %n%$$ and $icode%subset%.nc() == %n%$$. -It specifies which elements of the Hessian are computed. -$list number$$ -The input value of its value vector -$icode%subset%.val()%$$ does not matter. -Upon return it contains the value of the corresponding elements -of the Hessian. -$lnext -All of the row, column pairs in $icode subset$$ must also appear in -$icode pattern$$; i.e., they must be possibly non-zero. -$lnext -The Hessian is symmetric, so one has a choice as to which off diagonal -elements to put in $icode subset$$. -It will probably be more efficient if one makes this choice so that -the there are more entries in each non-zero column of $icode subset$$; -see $cref/n_sweep/sparse_hes/n_sweep/$$ below. -$lend - -$head pattern$$ -This argument has prototype -$codei% - const sparse_rc<%SizeVector%>& %pattern% -%$$ -Its row size and column size is $icode n$$; i.e., -$icode%pattern%.nr() == %n%$$ and $icode%pattern%.nc() == %n%$$. -It is a sparsity pattern for the Hessian $latex H(x)$$. -If the $th i$$ row ($th j$$ column) does not appear in $icode subset$$, -the $th i$$ row ($th j$$ column) of $icode pattern$$ does not matter -and need not be computed. -This argument is not used (and need not satisfy any conditions), -when $cref/work/sparse_hes/work/$$ is non-empty. - -$subhead subset$$ -If the $th i$$ row and $th i$$ column do not appear in $icode subset$$, -the $th i$$ row and column of $icode pattern$$ do not matter. -In this case the $th i-th$$ row and column may have no entries in -$icode pattern$$ even though they are possibly non-zero in $latex H(x)$$. -(This can be used to reduce the amount of computation required to find -$icode pattern$$.) - -$head coloring$$ -The coloring algorithm determines which rows and columns -can be computed during the same sweep. -This field has prototype -$codei% - const std::string& %coloring% -%$$ -This value only matters when work is empty; i.e., -after the $icode work$$ constructor or $icode%work%.clear()%$$. - -$subhead cppad.symmetric$$ -This coloring takes advantage of the fact that the Hessian matrix -is symmetric when find a coloring that requires fewer -$cref/sweeps/sparse_hes/n_sweep/$$. - -$subhead cppad.general$$ -This is the same as the sparse Jacobian -$cref/cppad/sparse_jac/coloring/cppad/$$ method -which does not take advantage of symmetry. - -$subhead colpack.symmetric$$ -If $cref colpack_prefix$$ was specified on the -$cref/cmake command/cmake/CMake Command/$$ line, -you can set $icode coloring$$ to $code colpack.symmetric$$. -This also takes advantage of the fact that the Hessian matrix is symmetric. - -$subhead colpack.general$$ -If $cref colpack_prefix$$ was specified on the -$cref/cmake command/cmake/CMake Command/$$ line, -you can set $icode coloring$$ to $code colpack.general$$. -This is the same as the sparse Jacobian -$cref/colpack/sparse_jac/coloring/colpack/$$ method -which does not take advantage of symmetry. - -$subhead colpack.star Deprecated 2017-06-01$$ -The $code colpack.star$$ method is deprecated. -It is the same as the $code colpack.symmetric$$ method -which should be used instead. - - -$head work$$ -This argument has prototype -$codei% - sparse_hes_work& %work% -%$$ -We refer to its initial value, -and its value after $icode%work%.clear()%$$, as empty. -If it is empty, information is stored in $icode work$$. -This can be used to reduce computation when -a future call is for the same object $icode f$$, -and the same subset of the Hessian. -In fact, it can be used with a different $icode f$$ -and a different $icode subset$$ provided that Hessian sparsity pattern -for $icode f$$ and the sparsity pattern in $icode subset$$ are the same. -If either of these values change, use $icode%work%.clear()%$$ to -empty this structure. - -$head n_sweep$$ -The return value $icode n_sweep$$ has prototype -$codei% - size_t %n_sweep% -%$$ -It is the number of first order forward sweeps -used to compute the requested Hessian values. -Each first forward sweep is followed by a second order reverse sweep -so it is also the number of reverse sweeps. -It is also the number of colors determined by the coloring method -mentioned above. -This is proportional to the total computational work, -not counting the zero order forward sweep, -or combining multiple columns and rows into a single sweep. - -$head Uses Forward$$ -After each call to $cref Forward$$, -the object $icode f$$ contains the corresponding -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$. -After a call to $code sparse_hes$$ -the zero order coefficients correspond to -$codei% - %f%.Forward(0, %x%) -%$$ -All the other forward mode coefficients are unspecified. - -$head Example$$ -$children% - example/sparse/sparse_hes.cpp -%$$ -The files $cref sparse_hes.cpp$$ -is an example and test of $code sparse_hes$$. -It returns $code true$$, if it succeeds, and $code false$$ otherwise. - -$head Subset Hessian$$ -The routine -$cref sparse_sub_hes.cpp$$ -is an example and test that compute a subset of a sparse Hessian. -It returns $code true$$, for success, and $code false$$ otherwise. - -$end -*/ -# include -# include -# include -# include - -/*! -\file sparse_hes.hpp -Sparse Hessian calculation routines. -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/*! -Class used to hold information used by Sparse Hessian routine in this file, -so it does not need to be recomputed every time. -*/ -class sparse_hes_work { - public: - /// row and column indicies for return values - /// (some may be reflected by symmetric coloring algorithms) - CppAD::vector row; - CppAD::vector col; - /// indices that sort the row and col arrays by color - CppAD::vector order; - /// results of the coloring algorithm - CppAD::vector color; - - /// constructor - sparse_hes_work(void) - { } - /// inform CppAD that this information needs to be recomputed - void clear(void) - { - row.clear(); - col.clear(); - order.clear(); - color.clear(); - } -}; -// ---------------------------------------------------------------------------- -/*! -Calculate sparse Hessians using forward mode - -\tparam Base -the base type for the recording that is stored in the ADFun object. - -\tparam SizeVector -a simple vector class with elements of type size_t. - -\tparam BaseVector -a simple vector class with elements of type Base. - -\param x -a vector of length n, the number of independent variables in f -(this ADFun object). - -\param w -a vector of length m, the number of dependent variables in f -(this ADFun object). - -\param subset -specifices the subset of the sparsity pattern where the Hessian is evaluated. -subset.nr() == n, -subset.nc() == n. - -\param pattern -is a sparsity pattern for the Hessian of w^T * f; -pattern.nr() == n, -pattern.nc() == n, -where m is number of dependent variables in f. - -\param coloring -determines which coloring algorithm is used. -This must be cppad.symmetric, cppad.general, colpack.symmetic, -or colpack.star. - -\param work -this structure must be empty, or contain the information stored -by a previous call to sparse_hes. -The previous call must be for the same ADFun object f -and the same subset. - -\return -This is the number of first order forward -(and second order reverse) sweeps used to compute thhe Hessian. -*/ -template -template -size_t ADFun::sparse_hes( - const BaseVector& x , - const BaseVector& w , - sparse_rcv& subset , - const sparse_rc& pattern , - const std::string& coloring , - sparse_hes_work& work ) -{ size_t n = Domain(); - // - CPPAD_ASSERT_KNOWN( - subset.nr() == n, - "sparse_hes: subset.nr() not equal domain dimension for f" - ); - CPPAD_ASSERT_KNOWN( - subset.nc() == n, - "sparse_hes: subset.nc() not equal domain dimension for f" - ); - CPPAD_ASSERT_KNOWN( - size_t( x.size() ) == n, - "sparse_hes: x.size() not equal domain dimension for f" - ); - CPPAD_ASSERT_KNOWN( - size_t( w.size() ) == Range(), - "sparse_hes: w.size() not equal range dimension for f" - ); - // - // work information - vector& row(work.row); - vector& col(work.col); - vector& color(work.color); - vector& order(work.order); - // - // subset information - const SizeVector& subset_row( subset.row() ); - const SizeVector& subset_col( subset.col() ); - // - // point at which we are evaluationg the Hessian - Forward(0, x); - // - // number of elements in the subset - size_t K = subset.nnz(); - // - // check for case were there is nothing to do - // (except for call to Forward(0, x) - if( K == 0 ) - return 0; - // -# ifndef NDEBUG - if( color.size() != 0 ) - { CPPAD_ASSERT_KNOWN( - color.size() == n, - "sparse_hes: work is non-empty and conditions have changed" - ); - CPPAD_ASSERT_KNOWN( - row.size() == K, - "sparse_hes: work is non-empty and conditions have changed" - ); - CPPAD_ASSERT_KNOWN( - col.size() == K, - "sparse_hes: work is non-empty and conditions have changed" - ); - // - for(size_t k = 0; k < K; k++) - { bool ok = row[k] == subset_row[k] && col[k] == subset_col[k]; - ok |= row[k] == subset_col[k] && col[k] == subset_row[k]; - CPPAD_ASSERT_KNOWN( - ok, - "sparse_hes: work is non-empty and conditions have changed" - ); - } - } -# endif - // - // check for case where input work is empty - if( color.size() == 0 ) - { // compute work color and order vectors - CPPAD_ASSERT_KNOWN( - pattern.nr() == n, - "sparse_hes: pattern.nr() not equal domain dimension for f" - ); - CPPAD_ASSERT_KNOWN( - pattern.nc() == n, - "sparse_hes: pattern.nc() not equal domain dimension for f" - ); - // - // initialize work row, col to be same as subset row, col - row.resize(K); - col.resize(K); - // cannot assign vectors becasue may be of different types - // (SizeVector and CppAD::vector) - for(size_t k = 0; k < K; k++) - { row[k] = subset_row[k]; - col[k] = subset_col[k]; - } - // - // convert pattern to an internal version of its transpose - local::pod_vector internal_index(n); - for(size_t j = 0; j < n; j++) - internal_index[j] = j; - bool transpose = true; - bool zero_empty = false; - bool input_empty = true; - local::sparse::list_setvec internal_pattern; - internal_pattern.resize(n, n); - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, internal_index, internal_pattern, pattern - ); - // - // execute coloring algorithm - // (we are using transpose becasue coloring groups rows, not columns) - color.resize(n); - if( coloring == "cppad.general" ) - local::color_general_cppad(internal_pattern, col, row, color); - else if( coloring == "cppad.symmetric" ) - local::color_symmetric_cppad(internal_pattern, col, row, color); - else if( coloring == "colpack.general" ) - { -# if CPPAD_HAS_COLPACK - local::color_general_colpack(internal_pattern, col, row, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "sparse_hes: coloring = colpack.star " - "and colpack_prefix not in cmake command line." - ); -# endif - } - else if( - coloring == "colpack.symmetric" || - coloring == "colpack.star" - ) - { -# if CPPAD_HAS_COLPACK - local::color_symmetric_colpack(internal_pattern, col, row, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "sparse_hes: coloring = colpack.symmetic or colpack.star " - "and colpack_prefix not in cmake command line." - ); -# endif - } - else CPPAD_ASSERT_KNOWN( - false, - "sparse_hes: coloring is not valid." - ); - // - // put sorting indices in color order - SizeVector key(K); - order.resize(K); - for(size_t k = 0; k < K; k++) - key[k] = color[ col[k] ]; - index_sort(key, order); - } - // Base versions of zero and one - Base one(1.0); - Base zero(0.0); - // - size_t n_color = 1; - for(size_t j = 0; j < n; j++) if( color[j] < n ) - n_color = std::max(n_color, color[j] + 1); - // - // initialize the return Hessian values as zero - for(size_t k = 0; k < K; k++) - subset.set(k, zero); - // - // direction vector for calls to first order forward - BaseVector dx(n); - // - // return values for calls to second order reverse - BaseVector ddw(2 * n); - // - // loop over colors - size_t k = 0; - for(size_t ell = 0; ell < n_color; ell++) - if( k == K ) - { // kludge because colpack returns colors that are not used - // (it does not know about the subset corresponding to row, col) - CPPAD_ASSERT_UNKNOWN( - coloring == "colpack.general" || - coloring == "colpack.symmetric" || - coloring == "colpack.star" - ); - } - else if( color[ col[ order[k] ] ] != ell ) - { // kludge because colpack returns colors that are not used - // (it does not know about the subset corresponding to row, col) - CPPAD_ASSERT_UNKNOWN( - coloring == "colpack.general" || - coloring == "colpack.symmetic" || - coloring == "colpack.star" - ); - } - else - { CPPAD_ASSERT_UNKNOWN( color[ col[ order[k] ] ] == ell ); - // - // combine all columns with this color - for(size_t j = 0; j < n; j++) - { dx[j] = zero; - if( color[j] == ell ) - dx[j] = one; - } - // call forward mode for all these rows at once - Forward(1, dx); - // - // evaluate derivative of w^T * F'(x) * dx - ddw = Reverse(2, w); - // - // set the corresponding components of the result - while( k < K && color[ col[order[k]] ] == ell ) - { size_t index = row[ order[k] ] * 2 + 1; - subset.set(order[k], ddw[index] ); - k++; - } - } - // check that all the required entries have been set - CPPAD_ASSERT_UNKNOWN( k == K ); - return n_color; -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/core/sparse_hessian.hpp b/build-config/cppad/include/cppad/core/sparse_hessian.hpp deleted file mode 100644 index 94115da2..00000000 --- a/build-config/cppad/include/cppad/core/sparse_hessian.hpp +++ /dev/null @@ -1,861 +0,0 @@ -# ifndef CPPAD_CORE_SPARSE_HESSIAN_HPP -# define CPPAD_CORE_SPARSE_HESSIAN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin sparse_hessian$$ -$spell - jacobian - recomputed - CppAD - valarray - std - Bool - hes - const - Taylor - cppad - cmake - colpack -$$ - -$section Sparse Hessian$$ - -$head Syntax$$ -$icode%hes% = %f%.SparseHessian(%x%, %w%) -%hes% = %f%.SparseHessian(%x%, %w%, %p%) -%n_sweep% = %f%.SparseHessian(%x%, %w%, %p%, %row%, %col%, %hes%, %work%) -%$$ - -$head Purpose$$ -We use $latex n$$ for the $cref/domain/seq_property/Domain/$$ size, -and $latex m$$ for the $cref/range/seq_property/Range/$$ size of $icode f$$. -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ do denote the -$cref/AD function/glossary/AD Function/$$ -corresponding to $icode f$$. -The syntax above sets $icode hes$$ to the Hessian -$latex \[ - H(x) = \dpow{2}{x} \sum_{i=1}^m w_i F_i (x) -\] $$ -This routine takes advantage of the sparsity of the Hessian -in order to reduce the amount of computation necessary. -If $icode row$$ and $icode col$$ are present, it also takes -advantage of the reduced set of elements of the Hessian that -need to be computed. -One can use speed tests (e.g. $cref speed_test$$) -to verify that results are computed faster -than when using the routine $cref Hessian$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$ -(see $cref/Uses Forward/sparse_hessian/Uses Forward/$$ below). - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %BaseVector%& %x% -%$$ -(see $cref/BaseVector/sparse_hessian/BaseVector/$$ below) -and its size -must be equal to $icode n$$, the dimension of the -$cref/domain/seq_property/Domain/$$ space for $icode f$$. -It specifies -that point at which to evaluate the Hessian. - -$head w$$ -The argument $icode w$$ has prototype -$codei% - const %BaseVector%& %w% -%$$ -and size $latex m$$. -It specifies the value of $latex w_i$$ in the expression -for $icode hes$$. -The more components of $latex w$$ that are identically zero, -the more sparse the resulting Hessian may be (and hence the more efficient -the calculation of $icode hes$$ may be). - -$head p$$ -The argument $icode p$$ is optional and has prototype -$codei% - const %SetVector%& %p% -%$$ -(see $cref/SetVector/sparse_hessian/SetVector/$$ below) -If it has elements of type $code bool$$, -its size is $latex n * n$$. -If it has elements of type $code std::set$$, -its size is $latex n$$ and all its set elements are between -zero and $latex n - 1$$. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the Hessian $latex H(x)$$. - -$subhead Purpose$$ -If this sparsity pattern does not change between calls to -$codei SparseHessian$$, it should be faster to calculate $icode p$$ once and -pass this argument to $codei SparseHessian$$. -If you specify $icode p$$, CppAD will use the same -type of sparsity representation -(vectors of $code bool$$ or vectors of $code std::set$$) -for its internal calculations. -Otherwise, the representation -for the internal calculations is unspecified. - -$subhead work$$ -If you specify $icode work$$ in the calling sequence, -it is not necessary to keep the sparsity pattern; see the heading -$cref/p/sparse_hessian/work/p/$$ under the $icode work$$ description. - -$subhead Column Subset$$ -If the arguments $icode row$$ and $icode col$$ are present, -and $cref/color_method/sparse_hessian/work/color_method/$$ is -$code cppad.general$$ or $code cppad.symmetric$$, -it is not necessary to compute the entire sparsity pattern. -Only the following subset of column values will matter: -$codei% - { %col%[%k%] : %k% = 0 , %...% , %K%-1 } -%$$. - - -$head row, col$$ -The arguments $icode row$$ and $icode col$$ are optional and have prototype -$codei% - const %SizeVector%& %row% - const %SizeVector%& %col% -%$$ -(see $cref/SizeVector/sparse_hessian/SizeVector/$$ below). -They specify which rows and columns of $latex H (x)$$ are -returned and in what order. -We use $latex K$$ to denote the value $icode%hes%.size()%$$ -which must also equal the size of $icode row$$ and $icode col$$. -Furthermore, -for $latex k = 0 , \ldots , K-1$$, it must hold that -$latex row[k] < n$$ and $latex col[k] < n$$. -In addition, -all of the $latex (row[k], col[k])$$ pairs must correspond to a true value -in the sparsity pattern $icode p$$. - -$head hes$$ -The result $icode hes$$ has prototype -$codei% - %BaseVector% %hes% -%$$ -In the case where $icode row$$ and $icode col$$ are not present, -the size of $icode hes$$ is $latex n * n$$ and -its size is $latex n * n$$. -In this case, for $latex i = 0 , \ldots , n - 1 $$ -and $latex ell = 0 , \ldots , n - 1$$ -$latex \[ - hes [ j * n + \ell ] = \DD{ w^{\rm T} F }{ x_j }{ x_\ell } ( x ) -\] $$ -$pre - -$$ -In the case where the arguments $icode row$$ and $icode col$$ are present, -we use $latex K$$ to denote the size of $icode hes$$. -The input value of its elements does not matter. -Upon return, for $latex k = 0 , \ldots , K - 1$$, -$latex \[ - hes [ k ] = \DD{ w^{\rm T} F }{ x_j }{ x_\ell } (x) - \; , \; - \; {\rm where} \; - j = row[k] - \; {\rm and } \; - \ell = col[k] -\] $$ - -$head work$$ -If this argument is present, it has prototype -$codei% - sparse_hessian_work& %work% -%$$ -This object can only be used with the routines $code SparseHessian$$. -During its the first use, information is stored in $icode work$$. -This is used to reduce the work done by future calls to $code SparseHessian$$ -with the same $icode f$$, $icode p$$, $icode row$$, and $icode col$$. -If a future call is made where any of these values have changed, -you must first call $icode%work%.clear()%$$ -to inform CppAD that this information needs to be recomputed. - -$subhead color_method$$ -The coloring algorithm determines which rows and columns -can be computed during the same sweep. -This field has prototype -$codei% - std::string %work%.color_method -%$$ -This value only matters on the first call to $code sparse_hessian$$ that -follows the $icode work$$ constructor or a call to -$icode%work%.clear()%$$. -$codei% - -"cppad.symmetric" -%$$ -This is the default coloring method (after a constructor or $code clear()$$). -It takes advantage of the fact that the Hessian matrix -is symmetric to find a coloring that requires fewer -$cref/sweeps/sparse_hessian/n_sweep/$$. -$codei% - -"cppad.general" -%$$ -This is the same as the $code "cppad"$$ method for the -$cref/sparse_jacobian/sparse_jacobian/work/color_method/$$ calculation. -$codei% - -"colpack.symmetric" -%$$ -This method requires that -$cref colpack_prefix$$ was specified on the -$cref/cmake command/cmake/CMake Command/$$ line. -It also takes advantage of the fact that the Hessian matrix is symmetric. -$codei% - -"colpack.general" -%$$ -This is the same as the $code "colpack"$$ method for the -$cref/sparse_jacobian/sparse_jacobian/work/color_method/$$ calculation. - -$subhead colpack.star Deprecated 2017-06-01$$ -The $code colpack.star$$ method is deprecated. -It is the same as the $code colpack.symmetric$$ -which should be used instead. - -$subhead p$$ -If $icode work$$ is present, and it is not the first call after -its construction or a clear, -the sparsity pattern $icode p$$ is not used. -This enables one to free the sparsity pattern -and still compute corresponding sparse Hessians. - -$head n_sweep$$ -The return value $icode n_sweep$$ has prototype -$codei% - size_t %n_sweep% -%$$ -It is the number of first order forward sweeps -used to compute the requested Hessian values. -Each first forward sweep is followed by a second order reverse sweep -so it is also the number of reverse sweeps. -This is proportional to the total work that $code SparseHessian$$ does, -not counting the zero order forward sweep, -or the work to combine multiple columns into a single -forward-reverse sweep pair. - -$head BaseVector$$ -The type $icode BaseVector$$ 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 SetVector$$ -The type $icode SetVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$ or $code std::set$$; -see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion -of the difference. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$subhead Restrictions$$ -If $icode SetVector$$ has elements of $code std::set$$, -then $icode%p%[%i%]%$$ must return a reference (not a copy) to the -corresponding set. -According to section 26.3.2.3 of the 1998 C++ standard, -$code std::valarray< std::set >$$ does not satisfy -this condition. - -$head SizeVector$$ -The type $icode SizeVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Uses Forward$$ -After each call to $cref Forward$$, -the object $icode f$$ contains the corresponding -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$. -After a call to any of the sparse Hessian routines, -the zero order Taylor coefficients correspond to -$icode%f%.Forward(0, %x%)%$$ -and the other coefficients are unspecified. - -$children% - example/sparse/sparse_hessian.cpp% - example/sparse/sub_sparse_hes.cpp% - example/sparse/sparse_sub_hes.cpp -%$$ - -$head Example$$ -The routine -$cref sparse_hessian.cpp$$ -is examples and tests of $code sparse_hessian$$. -It return $code true$$, if it succeeds and $code false$$ otherwise. - -$head Subset Hessian$$ -The routine -$cref sub_sparse_hes.cpp$$ -is an example and test that compute a sparse Hessian -for a subset of the variables. -It returns $code true$$, for success, and $code false$$ otherwise. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file sparse_hessian.hpp -Sparse Hessian driver routine and helper functions. -*/ -// =========================================================================== -/*! -class used by SparseHessian to hold information -so it does not need to be recomputed. -*/ -class sparse_hessian_work { - public: - /// Coloring method: "cppad", or "colpack" - /// (this field is set by user) - std::string color_method; - /// row and column indicies for return values - /// (some may be reflected by star coloring algorithm) - CppAD::vector row; - CppAD::vector col; - /// indices that sort the user row and col arrays by color - CppAD::vector order; - /// results of the coloring algorithm - CppAD::vector color; - - /// constructor - sparse_hessian_work(void) : color_method("cppad.symmetric") - { } - /// inform CppAD that this information needs to be recomputed - void clear(void) - { color_method = "cppad.symmetric"; - row.clear(); - col.clear(); - order.clear(); - color.clear(); - } -}; -// =========================================================================== -/*! -Private helper function that does computation for all Sparse Hessian cases. - -\tparam Base -is the base type for the recording that is stored in this ADFun. - -\tparam SizeVector -is sparse_pack or sparse_list. - -\param x [in] -is a vector specifing the point at which to compute the Hessian. - -\param w [in] -is the weighting vector that defines a scalar valued function by -a weighted sum of the components of the vector valued function -$latex F(x)$$. - -\param sparsity [in] -is the sparsity pattern for the Hessian that we are calculating. - -\param user_row [in] -is the vector of row indices for the returned Hessian values. - -\param user_col [in] -is the vector of columns indices for the returned Hessian values. -It must have the same size as user_row. - -\param hes [out] -is the vector of Hessian values. -It must have the same size as user_row. -The return value hes[k] is the second partial of -\f$ w^{\rm T} F(x)\f$ with respect to the -row[k] and col[k] component of \f$ x\f$. - -\param work -This structure contains information that is computed by SparseHessianCompute. -If the sparsity pattern, row vector, or col vectors -are not the same between calls to SparseHessianCompute, - work.clear() must be called to reinitialize work. - -\return -Is the number of first order forward sweeps used to compute the -requested Hessian values. -(This is also equal to the number of second order reverse sweeps.) -The total work, not counting the zero order -forward sweep, or the time to combine computations, is proportional to this -return value. -*/ -template -template -size_t ADFun::SparseHessianCompute( - const BaseVector& x , - const BaseVector& w , - SetVector& sparsity , - const SizeVector& user_row , - const SizeVector& user_col , - BaseVector& hes , - sparse_hessian_work& work ) -{ - using CppAD::vectorBool; - size_t i, k, ell; - - CppAD::vector& row(work.row); - CppAD::vector& col(work.col); - CppAD::vector& color(work.color); - CppAD::vector& order(work.order); - - size_t n = Domain(); - - // some values - const Base zero(0); - const Base one(1); - - // check BaseVector is Simple Vector class with Base type elements - CheckSimpleVector(); - - // number of components of Hessian that are required - size_t K = hes.size(); - CPPAD_ASSERT_UNKNOWN( size_t( user_row.size() ) == K ); - CPPAD_ASSERT_UNKNOWN( size_t( user_col.size() ) == K ); - - CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n ); - CPPAD_ASSERT_UNKNOWN( color.size() == 0 || color.size() == n ); - CPPAD_ASSERT_UNKNOWN( row.size() == 0 || row.size() == K ); - CPPAD_ASSERT_UNKNOWN( col.size() == 0 || col.size() == K ); - - - // Point at which we are evaluating the Hessian - Forward(0, x); - - // check for case where nothing (except Forward above) to do - if( K == 0 ) - return 0; - - // Rows of the Hessian (i below) correspond to the forward mode index - // and columns (j below) correspond to the reverse mode index. - if( color.size() == 0 ) - { - CPPAD_ASSERT_UNKNOWN( sparsity.n_set() == n ); - CPPAD_ASSERT_UNKNOWN( sparsity.end() == n ); - - // copy user rwo and col to work space - row.resize(K); - col.resize(K); - for(k = 0; k < K; k++) - { row[k] = user_row[k]; - col[k] = user_col[k]; - } - - // execute coloring algorithm - color.resize(n); - if( work.color_method == "cppad.general" ) - local::color_general_cppad(sparsity, row, col, color); - else if( work.color_method == "cppad.symmetric" ) - local::color_symmetric_cppad(sparsity, row, col, color); - else if( work.color_method == "colpack.general" ) - { -# if CPPAD_HAS_COLPACK - local::color_general_colpack(sparsity, row, col, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "SparseHessian: work.color_method = colpack.general " - "and colpack_prefix missing from cmake command line." - ); -# endif - } - else if( - work.color_method == "colpack.symmetric" || - work.color_method == "colpack.star" - ) - { -# if CPPAD_HAS_COLPACK - local::color_symmetric_colpack(sparsity, row, col, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "SparseHessian: work.color_method is " - "colpack.symmetric or colpack.star\n" - "and colpack_prefix missing from cmake command line." - ); -# endif - } - else - { CPPAD_ASSERT_KNOWN( - false, - "SparseHessian: work.color_method is not valid." - ); - } - - // put sorting indices in color order - SizeVector key(K); - order.resize(K); - for(k = 0; k < K; k++) - key[k] = color[ row[k] ]; - index_sort(key, order); - - } - size_t n_color = 1; - for(ell = 0; ell < n; ell++) if( color[ell] < n ) - n_color = std::max(n_color, color[ell] + 1); - - // direction vector for calls to forward (rows of the Hessian) - BaseVector u(n); - - // location for return values from reverse (columns of the Hessian) - BaseVector ddw(2 * n); - - // initialize the return value - for(k = 0; k < K; k++) - hes[k] = zero; - - // loop over colors -# ifndef NDEBUG - const std::string& coloring = work.color_method; -# endif - k = 0; - for(ell = 0; ell < n_color; ell++) - if( k == K ) - { // kludge because colpack returns colors that are not used - // (it does not know about the subset corresponding to row, col) - CPPAD_ASSERT_UNKNOWN( - coloring == "colpack.general" || - coloring == "colpack.symmetic" || - coloring == "colpack.star" - ); - } - else if( color[ row[ order[k] ] ] != ell ) - { // kludge because colpack returns colors that are not used - // (it does not know about the subset corresponding to row, col) - CPPAD_ASSERT_UNKNOWN( - coloring == "colpack.general" || - coloring == "colpack.symmetic" || - coloring == "colpack.star" - ); - } - else - { CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell ); - - // combine all rows with this color - for(i = 0; i < n; i++) - { u[i] = zero; - if( color[i] == ell ) - u[i] = one; - } - // call forward mode for all these rows at once - Forward(1, u); - - // evaluate derivative of w^T * F'(x) * u - ddw = Reverse(2, w); - - // set the corresponding components of the result - while( k < K && color[ row[ order[k] ] ] == ell ) - { hes[ order[k] ] = ddw[ col[ order[k] ] * 2 + 1 ]; - k++; - } - } - return n_color; -} -// =========================================================================== -// Public Member Functions -// =========================================================================== -/*! -Compute user specified subset of a sparse Hessian. - -The C++ source code corresponding to this operation is -\verbatim - SparceHessian(x, w, p, row, col, hes, work) -\endverbatim - -\tparam Base -is the base type for the recording that is stored in this ADFun. - -\tparam SizeVector -is a simple vector class with elements of type size_t. - -\param x [in] -is a vector specifing the point at which to compute the Hessian. - -\param w [in] -is the weighting vector that defines a scalar valued function by -a weighted sum of the components of the vector valued function -$latex F(x)$$. - -\param p [in] -is the sparsity pattern for the Hessian that we are calculating. - -\param row [in] -is the vector of row indices for the returned Hessian values. - -\param col [in] -is the vector of columns indices for the returned Hessian values. -It must have the same size are r. - -\param hes [out] -is the vector of Hessian values. -It must have the same size are r. -The return value hes[k] is the second partial of -\f$ w^{\rm T} F(x)\f$ with respect to the -row[k] and col[k] component of \f$ x\f$. - -\param work -This structure contains information that is computed by SparseHessianCompute. -If the sparsity pattern, row vector, or col vectors -are not the same between calls to SparseHessian, - work.clear() must be called to reinitialize work. - -\return -Is the number of first order forward sweeps used to compute the -requested Hessian values. -(This is also equal to the number of second order reverse sweeps.) -The total work, not counting the zero order -forward sweep, or the time to combine computations, is proportional to this -return value. -*/ -template -template -size_t ADFun::SparseHessian( - const BaseVector& x , - const BaseVector& w , - const SetVector& p , - const SizeVector& row , - const SizeVector& col , - BaseVector& hes , - sparse_hessian_work& work ) -{ - size_t n = Domain(); - size_t K = hes.size(); -# ifndef NDEBUG - size_t k; - CPPAD_ASSERT_KNOWN( - size_t(x.size()) == n , - "SparseHessian: size of x not equal domain dimension for f." - ); - CPPAD_ASSERT_KNOWN( - size_t(row.size()) == K && size_t(col.size()) == K , - "SparseHessian: either r or c does not have the same size as ehs." - ); - CPPAD_ASSERT_KNOWN( - work.color.size() == 0 || work.color.size() == n, - "SparseHessian: invalid value in work." - ); - for(k = 0; k < K; k++) - { CPPAD_ASSERT_KNOWN( - row[k] < n, - "SparseHessian: invalid value in r." - ); - CPPAD_ASSERT_KNOWN( - col[k] < n, - "SparseHessian: invalid value in c." - ); - } - if( work.color.size() != 0 ) - for(size_t j = 0; j < n; j++) CPPAD_ASSERT_KNOWN( - work.color[j] <= n, - "SparseHessian: invalid value in work." - ); -# endif - // check for case where there is nothing to compute - size_t n_sweep = 0; - if( K == 0 ) - return n_sweep; - - typedef typename SetVector::value_type Set_type; - typedef typename local::sparse::internal_pattern::pattern_type Pattern_type; - Pattern_type s; - if( work.color.size() == 0 ) - { bool transpose = false; - const char* error_msg = "SparseHessian: sparsity pattern" - " does not have proper row or column dimension"; - sparsity_user2internal(s, p, n, n, transpose, error_msg); - } - n_sweep = SparseHessianCompute(x, w, s, row, col, hes, work); - return n_sweep; -} -/*! -Compute a sparse Hessian. - -The C++ source code coresponding to this operation is -\verbatim - hes = SparseHessian(x, w, p) -\endverbatim - - -\tparam Base -is the base type for the recording that is stored in this -ADFun. - -\param x [in] -is a vector specifing the point at which to compute the Hessian. - -\param w [in] -The Hessian is computed for a weighted sum of the components -of the function corresponding to this ADFun object. -The argument w specifies the weights for each component. -It must have size equal to the range dimension for this ADFun object. - -\param p [in] -is a sparsity pattern for the Hessian. - -\return -Will be a vector of size n * n containing the Hessian of -at the point specified by x -(where n is the domain dimension for this ADFun object). -*/ -template -template -BaseVector ADFun::SparseHessian( - const BaseVector& x, const BaseVector& w, const SetVector& p -) -{ size_t i, j, k; - - size_t n = Domain(); - BaseVector hes(n * n); - - CPPAD_ASSERT_KNOWN( - size_t(x.size()) == n, - "SparseHessian: size of x not equal domain size for f." - ); - - typedef typename SetVector::value_type Set_type; - typedef typename local::sparse::internal_pattern::pattern_type Pattern_type; - - // initialize the return value as zero - Base zero(0); - for(i = 0; i < n; i++) - for(j = 0; j < n; j++) - hes[i * n + j] = zero; - - // arguments to SparseHessianCompute - Pattern_type s; - CppAD::vector row; - CppAD::vector col; - sparse_hessian_work work; - bool transpose = false; - const char* error_msg = "SparseHessian: sparsity pattern" - " does not have proper row or column dimension"; - sparsity_user2internal(s, p, n, n, transpose, error_msg); - k = 0; - for(i = 0; i < n; i++) - { typename Pattern_type::const_iterator itr(s, i); - j = *itr; - while( j != s.end() ) - { row.push_back(i); - col.push_back(j); - k++; - j = *(++itr); - } - } - size_t K = k; - BaseVector H(K); - - // now we have folded this into the following case - SparseHessianCompute(x, w, s, row, col, H, work); - - // now set the non-zero return values - for(k = 0; k < K; k++) - hes[ row[k] * n + col[k] ] = H[k]; - - return hes; -} -/*! -Compute a sparse Hessian - -The C++ source code coresponding to this operation is -\verbatim - hes = SparseHessian(x, w) -\endverbatim - - -\tparam Base -is the base type for the recording that is stored in this -ADFun object. -The argument w specifies the weights for each component. -It must have size equal to the range dimension for this ADFun object. - -\return -Will be a vector of size n * n containing the Hessian of -at the point specified by x -(where n is the domain dimension for this ADFun object). -*/ -template -template -BaseVector ADFun::SparseHessian(const BaseVector &x, const BaseVector &w) -{ size_t i, j, k; - typedef CppAD::vectorBool BoolVector; - - size_t m = Range(); - size_t n = Domain(); - - // determine the sparsity pattern p for Hessian of w^T F - BoolVector r(n * n); - for(j = 0; j < n; j++) - { for(k = 0; k < n; k++) - r[j * n + k] = false; - r[j * n + j] = true; - } - ForSparseJac(n, r); - // - BoolVector s(m); - for(i = 0; i < m; i++) - s[i] = w[i] != 0; - BoolVector p = RevSparseHes(n, s); - - // compute sparse Hessian - return SparseHessian(x, w, p); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/sparse_jac.hpp b/build-config/cppad/include/cppad/core/sparse_jac.hpp deleted file mode 100644 index 2dd1beb2..00000000 --- a/build-config/cppad/include/cppad/core/sparse_jac.hpp +++ /dev/null @@ -1,629 +0,0 @@ -# ifndef CPPAD_CORE_SPARSE_JAC_HPP -# define CPPAD_CORE_SPARSE_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin sparse_jac$$ -$spell - Jacobian - Jacobians - const - jac - Taylor - rc - rcv - nr - nc - std - Cppad - Colpack - cmake -$$ - -$section Computing Sparse Jacobians$$ - -$head Syntax$$ -$icode%n_color% = %f%.sparse_jac_for( - %group_max%, %x%, %subset%, %pattern%, %coloring%, %work% -) -%$$ -$icode%n_color% = %f%.sparse_jac_rev( - %x%, %subset%, %pattern%, %coloring%, %work% -)%$$ - -$head Purpose$$ -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the -function corresponding to $icode f$$. -Here $icode n$$ is the $cref/domain/seq_property/Domain/$$ size, -and $icode m$$ is the $cref/range/seq_property/Range/$$ size, or $icode f$$. -The syntax above takes advantage of sparsity when computing the Jacobian -$latex \[ - J(x) = F^{(1)} (x) -\] $$ -In the sparse case, this should be faster and take less memory than -$cref Jacobian$$. -We use the notation $latex J_{i,j} (x)$$ to denote the partial of -$latex F_i (x)$$ with respect to $latex x_j$$. - -$head SizeVector$$ -The type $icode SizeVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. - -$head BaseVector$$ -The type $icode BaseVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. - -$head sparse_jac_for$$ -This function uses first order forward mode sweeps $cref forward_one$$ -to compute multiple columns of the Jacobian at the same time. - -$head sparse_jac_rev$$ -This uses function first order reverse mode sweeps $cref reverse_one$$ -to compute multiple rows of the Jacobian at the same time. - -$head f$$ -This object has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the Taylor coefficients stored in $icode f$$ are affected -by this operation; see -$cref/uses forward/sparse_jac/Uses Forward/$$ below. - -$head group_max$$ -This argument has prototype -$codei% - size_t %group_max% -%$$ -and must be greater than zero. -It specifies the maximum number of colors to group during -a single forward sweep. -If a single color is in a group, -a single direction for of first order forward mode -$cref forward_one$$ is used for each color. -If multiple colors are in a group, -the multiple direction for of first order forward mode -$cref forward_dir$$ is used with one direction for each color. -This uses separate memory for each direction (more memory), -but my be significantly faster. - -$head x$$ -This argument has prototype -$codei% - const %BaseVector%& %x% -%$$ -and its size is $icode n$$. -It specifies the point at which to evaluate the Jacobian -$latex J(x)$$. - -$head subset$$ -This argument has prototype -$codei% - sparse_rcv<%SizeVector%, %BaseVector%>& %subset% -%$$ -Its row size is $icode%subset%.nr() == %m%$$, -and its column size is $icode%subset%.nc() == %n%$$. -It specifies which elements of the Jacobian are computed. -The input value of its value vector -$icode%subset%.val()%$$ does not matter. -Upon return it contains the value of the corresponding elements -of the Jacobian. -All of the row, column pairs in $icode subset$$ must also appear in -$icode pattern$$; i.e., they must be possibly non-zero. - -$head pattern$$ -This argument has prototype -$codei% - const sparse_rc<%SizeVector%>& %pattern% -%$$ -Its row size is $icode%pattern%.nr() == %m%$$, -and its column size is $icode%pattern%.nc() == %n%$$. -It is a sparsity pattern for the Jacobian $latex J(x)$$. -This argument is not used (and need not satisfy any conditions), -when $cref/work/sparse_jac/work/$$ is non-empty. - -$head coloring$$ -The coloring algorithm determines which rows (reverse) or columns (forward) -can be computed during the same sweep. -This field has prototype -$codei% - const std::string& %coloring% -%$$ -This value only matters when work is empty; i.e., -after the $icode work$$ constructor or $icode%work%.clear()%$$. - -$subhead cppad$$ -This uses a general purpose coloring algorithm written for Cppad. - -$subhead colpack$$ -If $cref colpack_prefix$$ is specified on the -$cref/cmake command/cmake/CMake Command/$$ line, -you can set $icode coloring$$ to $code colpack$$. -This uses a general purpose coloring algorithm that is part of Colpack. - -$head work$$ -This argument has prototype -$codei% - sparse_jac_work& %work% -%$$ -We refer to its initial value, -and its value after $icode%work%.clear()%$$, as empty. -If it is empty, information is stored in $icode work$$. -This can be used to reduce computation when -a future call is for the same object $icode f$$, -the same member function $code sparse_jac_for$$ or $code sparse_jac_rev$$, -and the same subset of the Jacobian. -In fact, it can be used with a different $icode f$$ -and a different $icode subset$$ provided that Jacobian sparsity pattern -for $icode f$$ and the sparsity pattern in $icode subset$$ are the same. -If any of these values change, use $icode%work%.clear()%$$ to -empty this structure. - -$head n_color$$ -The return value $icode n_color$$ has prototype -$codei% - size_t %n_color% -%$$ -If $code sparse_jac_for$$ ($code sparse_jac_rev$$) is used, -$icode n_color$$ is the number of first order forward directions -used to compute the requested Jacobian values. -It is also the number of colors determined by the coloring method -mentioned above. -This is proportional to the total computational work, -not counting the zero order forward sweep, -or combining multiple columns (rows) into a single sweep. -Note that if $icode%group_max% == 1%$$, -or if we are using $code sparse_jac_rev$$, -$icode n_color$$ is equal to the number of sweeps. - -$head Uses Forward$$ -After each call to $cref Forward$$, -the object $icode f$$ contains the corresponding -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$. -After a call to $code sparse_jac_forward$$ or $code sparse_jac_rev$$, -the zero order coefficients correspond to -$codei% - %f%.Forward(0, %x%) -%$$ -All the other forward mode coefficients are unspecified. - -$head Example$$ -$children% - example/sparse/sparse_jac_for.cpp% - example/sparse/sparse_jac_rev.cpp -%$$ -The files $cref sparse_jac_for.cpp$$ and $cref sparse_jac_rev.cpp$$ -are examples and tests of $code sparse_jac_for$$ and $code sparse_jac_rev$$. -They return $code true$$, if they succeed, and $code false$$ otherwise. - -$end -*/ -# include -# include -# include -# include - -/*! -\file sparse_jac.hpp -Sparse Jacobian calculation routines. -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -Class used to hold information used by Sparse Jacobian routines in this file, -so they do not need to be recomputed every time. -*/ -class sparse_jac_work { - public: - /// indices that sort the user row and col arrays by color - CppAD::vector order; - /// results of the coloring algorithm - CppAD::vector color; - // - /// constructor - sparse_jac_work(void) - { } - /// reset work to empty. - /// This informs CppAD that color and order need to be recomputed - void clear(void) - { order.clear(); - color.clear(); - } -}; -// ---------------------------------------------------------------------------- -/*! -Calculate sparse Jacobains using forward mode - -\tparam Base -the base type for the recording that is stored in the ADFun object. - -\tparam SizeVector -a simple vector class with elements of type size_t. - -\tparam BaseVector -a simple vector class with elements of type Base. - -\param group_max -specifies the maximum number of colors to group during a single forward sweep. -This must be greater than zero and group_max = 1 minimizes memory usage. - -\param x -a vector of length n, the number of independent variables in f -(this ADFun object). - -\param subset -specifices the subset of the sparsity pattern where the Jacobian is evaluated. -subset.nr() == m, -subset.nc() == n. - -\param pattern -is a sparsity pattern for the Jacobian of f; -pattern.nr() == m, -pattern.nc() == n, -where m is number of dependent variables in f. - -\param coloring -determines which coloring algorithm is used. -This must be cppad or colpack. - -\param work -this structure must be empty, or contain the information stored -by a previous call to sparse_jac_for. -The previous call must be for the same ADFun object f -and the same subset. - -\return -This is the number of first order forward sweeps used to compute -the Jacobian. -*/ -template -template -size_t ADFun::sparse_jac_for( - size_t group_max , - const BaseVector& x , - sparse_rcv& subset , - const sparse_rc& pattern , - const std::string& coloring , - sparse_jac_work& work ) -{ size_t m = Range(); - size_t n = Domain(); - // - CPPAD_ASSERT_KNOWN( - subset.nr() == m, - "sparse_jac_for: subset.nr() not equal range dimension for f" - ); - CPPAD_ASSERT_KNOWN( - subset.nc() == n, - "sparse_jac_for: subset.nc() not equal domain dimension for f" - ); - // - // row and column vectors in subset - const SizeVector& row( subset.row() ); - const SizeVector& col( subset.col() ); - // - vector& color(work.color); - vector& order(work.order); - CPPAD_ASSERT_KNOWN( - color.size() == 0 || color.size() == n, - "sparse_jac_for: work is non-empty and conditions have changed" - ); - // - // point at which we are evaluationg the Jacobian - Forward(0, x); - // - // number of elements in the subset - size_t K = subset.nnz(); - // - // check for case were there is nothing to do - // (except for call to Forward(0, x) - if( K == 0 ) - return 0; - // - // check for case where input work is empty - if( color.size() == 0 ) - { // compute work color and order vectors - CPPAD_ASSERT_KNOWN( - pattern.nr() == m, - "sparse_jac_for: pattern.nr() not equal range dimension for f" - ); - CPPAD_ASSERT_KNOWN( - pattern.nc() == n, - "sparse_jac_for: pattern.nc() not equal domain dimension for f" - ); - // - // convert pattern to an internal version of its transpose - local::pod_vector internal_index(n); - for(size_t j = 0; j < n; j++) - internal_index[j] = j; - bool transpose = true; - bool zero_empty = false; - bool input_empty = true; - local::sparse::list_setvec pattern_transpose; - pattern_transpose.resize(n, m); - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, internal_index, pattern_transpose, pattern - ); - // - // execute coloring algorithm - // (we are using transpose because coloring groups rows, not columns). - color.resize(n); - if( coloring == "cppad" ) - local::color_general_cppad(pattern_transpose, col, row, color); - else if( coloring == "colpack" ) - { -# if CPPAD_HAS_COLPACK - local::color_general_colpack(pattern_transpose, col, row, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "sparse_jac_for: coloring = colpack " - "and colpack_prefix missing from cmake command line." - ); -# endif - } - else CPPAD_ASSERT_KNOWN( - false, - "sparse_jac_for: coloring is not valid." - ); - // - // put sorting indices in color order - SizeVector key(K); - order.resize(K); - for(size_t k = 0; k < K; k++) - key[k] = color[ col[k] ]; - index_sort(key, order); - } - // Base versions of zero and one - Base one(1.0); - Base zero(0.0); - // - size_t n_color = 1; - for(size_t j = 0; j < n; j++) if( color[j] < n ) - n_color = std::max(n_color, color[j] + 1); - // - // initialize the return Jacobian values as zero - for(size_t k = 0; k < K; k++) - subset.set(k, zero); - // - // index in subset - size_t k = 0; - // number of colors computed so far - size_t color_count = 0; - // - while( color_count < n_color ) - { // number of colors that will be in this group - size_t group_size = std::min(group_max, n_color - color_count); - // - // forward mode values for independent and dependent variables - BaseVector dx(n * group_size), dy(m * group_size); - // - // set dx - for(size_t ell = 0; ell < group_size; ell++) - { // combine all columns with this color - for(size_t j = 0; j < n; j++) - { dx[j * group_size + ell] = zero; - if( color[j] == ell + color_count ) - dx[j * group_size + ell] = one; - } - } - if( group_size == 1 ) - dy = Forward(1, dx); - else - dy = Forward(1, group_size, dx); - // - // store results in subset - for(size_t ell = 0; ell < group_size; ell++) - { // color with index ell + color_count is in this group - while(k < K && color[ col[ order[k] ] ] == ell + color_count ) - { // subset element with index order[k] is included in this color - size_t r = row[ order[k] ]; - subset.set( order[k], dy[ r * group_size + ell ] ); - ++k; - } - } - // advance color count - color_count += group_size; - } - CPPAD_ASSERT_UNKNOWN( color_count == n_color ); - // - return n_color; -} -// ---------------------------------------------------------------------------- -/*! -Calculate sparse Jacobains using reverse mode - -\tparam Base -the base type for the recording that is stored in the ADFun object. - -\tparam SizeVector -a simple vector class with elements of type size_t. - -\tparam BaseVector -a simple vector class with elements of type Base. - -\param x -a vector of length n, the number of independent variables in f -(this ADFun object). - -\param subset -specifices the subset of the sparsity pattern where the Jacobian is evaluated. -subset.nr() == m, -subset.nc() == n. - -\param pattern -is a sparsity pattern for the Jacobian of f; -pattern.nr() == m, -pattern.nc() == n, -where m is number of dependent variables in f. - -\param coloring -determines which coloring algorithm is used. -This must be cppad or colpack. - -\param work -this structure must be empty, or contain the information stored -by a previous call to sparse_jac_rev. -The previous call must be for the same ADFun object f -and the same subset. - -\return -This is the number of first order reverse sweeps used to compute -the Jacobian. -*/ -template -template -size_t ADFun::sparse_jac_rev( - const BaseVector& x , - sparse_rcv& subset , - const sparse_rc& pattern , - const std::string& coloring , - sparse_jac_work& work ) -{ size_t m = Range(); - size_t n = Domain(); - // - CPPAD_ASSERT_KNOWN( - subset.nr() == m, - "sparse_jac_rev: subset.nr() not equal range dimension for f" - ); - CPPAD_ASSERT_KNOWN( - subset.nc() == n, - "sparse_jac_rev: subset.nc() not equal domain dimension for f" - ); - // - // row and column vectors in subset - const SizeVector& row( subset.row() ); - const SizeVector& col( subset.col() ); - // - vector& color(work.color); - vector& order(work.order); - CPPAD_ASSERT_KNOWN( - color.size() == 0 || color.size() == m, - "sparse_jac_rev: work is non-empty and conditions have changed" - ); - // - // point at which we are evaluationg the Jacobian - Forward(0, x); - // - // number of elements in the subset - size_t K = subset.nnz(); - // - // check for case were there is nothing to do - // (except for call to Forward(0, x) - if( K == 0 ) - return 0; - // - // check for case where input work is empty - if( color.size() == 0 ) - { // compute work color and order vectors - CPPAD_ASSERT_KNOWN( - pattern.nr() == m, - "sparse_jac_rev: pattern.nr() not equal range dimension for f" - ); - CPPAD_ASSERT_KNOWN( - pattern.nc() == n, - "sparse_jac_rev: pattern.nc() not equal domain dimension for f" - ); - // - // convert pattern to an internal version - local::pod_vector internal_index(m); - for(size_t i = 0; i < m; i++) - internal_index[i] = i; - bool transpose = false; - bool zero_empty = false; - bool input_empty = true; - local::sparse::list_setvec internal_pattern; - internal_pattern.resize(m, n); - local::sparse::set_internal_pattern(zero_empty, input_empty, - transpose, internal_index, internal_pattern, pattern - ); - // - // execute coloring algorithm - color.resize(m); - if( coloring == "cppad" ) - local::color_general_cppad(internal_pattern, row, col, color); - else if( coloring == "colpack" ) - { -# if CPPAD_HAS_COLPACK - local::color_general_colpack(internal_pattern, row, col, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "sparse_jac_rev: coloring = colpack " - "and colpack_prefix missing from cmake command line." - ); -# endif - } - else CPPAD_ASSERT_KNOWN( - false, - "sparse_jac_rev: coloring is not valid." - ); - // - // put sorting indices in color order - SizeVector key(K); - order.resize(K); - for(size_t k = 0; k < K; k++) - key[k] = color[ row[k] ]; - index_sort(key, order); - } - // Base versions of zero and one - Base one(1.0); - Base zero(0.0); - // - size_t n_color = 1; - for(size_t i = 0; i < m; i++) if( color[i] < m ) - n_color = std::max(n_color, color[i] + 1); - // - // initialize the return Jacobian values as zero - for(size_t k = 0; k < K; k++) - subset.set(k, zero); - // - // weighting vector and return values for calls to Reverse - BaseVector w(m), dw(n); - // - // loop over colors - size_t k = 0; - for(size_t ell = 0; ell < n_color; ell++) - if( k == K ) - { // kludge because colpack returns colors that are not used - // (it does not know about the subset corresponding to row, col) - CPPAD_ASSERT_UNKNOWN( coloring == "colpack" ); - } - else if( color[ row[ order[k] ] ] != ell ) - { // kludge because colpack returns colors that are not used - // (it does not know about the subset corresponding to row, col) - CPPAD_ASSERT_UNKNOWN( coloring == "colpack" ); - } - else - { CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell ); - // - // combine all rows with this color - for(size_t i = 0; i < m; i++) - { w[i] = zero; - if( color[i] == ell ) - w[i] = one; - } - // call reverse mode for all these rows at once - dw = Reverse(1, w); - // - // set the corresponding components of the result - while( k < K && color[ row[order[k]] ] == ell ) - { subset.set(order[k], dw[col[order[k]]] ); - k++; - } - } - return n_color; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/sparse_jacobian.hpp b/build-config/cppad/include/cppad/core/sparse_jacobian.hpp deleted file mode 100644 index dfd849eb..00000000 --- a/build-config/cppad/include/cppad/core/sparse_jacobian.hpp +++ /dev/null @@ -1,1086 +0,0 @@ -# ifndef CPPAD_CORE_SPARSE_JACOBIAN_HPP -# define CPPAD_CORE_SPARSE_JACOBIAN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// maximum number of sparse directions to compute at the same time - -// # define CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION 1 -# define CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION 64 - -/* -$begin sparse_jacobian$$ -$spell - cppad - colpack - cmake - recomputed - valarray - std - CppAD - Bool - jac - Jacobian - Jacobians - const - Taylor -$$ - -$section Sparse Jacobian$$ - -$head Syntax$$ -$icode%jac% = %f%.SparseJacobian(%x%) -%jac% = %f%.SparseJacobian(%x%, %p%) -%n_sweep% = %f%.SparseJacobianForward(%x%, %p%, %row%, %col%, %jac%, %work%) -%n_sweep% = %f%.SparseJacobianReverse(%x%, %p%, %row%, %col%, %jac%, %work%) -%$$ - -$head Purpose$$ -We use $latex n$$ for the $cref/domain/seq_property/Domain/$$ size, -and $latex m$$ for the $cref/range/seq_property/Range/$$ size of $icode f$$. -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ do denote the -$cref/AD function/glossary/AD Function/$$ -corresponding to $icode f$$. -The syntax above sets $icode jac$$ to the Jacobian -$latex \[ - jac = F^{(1)} (x) -\] $$ -This routine takes advantage of the sparsity of the Jacobian -in order to reduce the amount of computation necessary. -If $icode row$$ and $icode col$$ are present, it also takes -advantage of the reduced set of elements of the Jacobian that -need to be computed. -One can use speed tests (e.g. $cref speed_test$$) -to verify that results are computed faster -than when using the routine $cref Jacobian$$. - -$head f$$ -The object $icode f$$ has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the $cref ADFun$$ object $icode f$$ is not $code const$$ -(see $cref/Uses Forward/sparse_jacobian/Uses Forward/$$ below). - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %BaseVector%& %x% -%$$ -(see $cref/BaseVector/sparse_jacobian/BaseVector/$$ 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 p$$ -The argument $icode p$$ is optional and has prototype -$codei% - const %SetVector%& %p% -%$$ -(see $cref/SetVector/sparse_jacobian/SetVector/$$ below). -If it has elements of type $code bool$$, -its size is $latex m * n$$. -If it has elements of type $code std::set$$, -its size is $latex m$$ and all its set elements are between -zero and $latex n - 1$$. -It specifies a -$cref/sparsity pattern/glossary/Sparsity Pattern/$$ -for the Jacobian $latex F^{(1)} (x)$$. -$pre - -$$ -If this sparsity pattern does not change between calls to -$codei SparseJacobian$$, it should be faster to calculate $icode p$$ once -(using $cref ForSparseJac$$ or $cref RevSparseJac$$) -and then pass $icode p$$ to $codei SparseJacobian$$. -Furthermore, if you specify $icode work$$ in the calling sequence, -it is not necessary to keep the sparsity pattern; see the heading -$cref/p/sparse_jacobian/work/p/$$ under the $icode work$$ description. -$pre - -$$ -In addition, -if you specify $icode p$$, CppAD will use the same -type of sparsity representation -(vectors of $code bool$$ or vectors of $code std::set$$) -for its internal calculations. -Otherwise, the representation -for the internal calculations is unspecified. - -$head row, col$$ -The arguments $icode row$$ and $icode col$$ are optional and have prototype -$codei% - const %SizeVector%& %row% - const %SizeVector%& %col% -%$$ -(see $cref/SizeVector/sparse_jacobian/SizeVector/$$ below). -They specify which rows and columns of $latex F^{(1)} (x)$$ are -computes and in what order. -Not all the non-zero entries in $latex F^{(1)} (x)$$ need be computed, -but all the entries specified by $icode row$$ and $icode col$$ -must be possibly non-zero in the sparsity pattern. -We use $latex K$$ to denote the value $icode%jac%.size()%$$ -which must also equal the size of $icode row$$ and $icode col$$. -Furthermore, -for $latex k = 0 , \ldots , K-1$$, it must hold that -$latex row[k] < m$$ and $latex col[k] < n$$. - -$head jac$$ -The result $icode jac$$ has prototype -$codei% - %BaseVector%& %jac% -%$$ -In the case where the arguments $icode row$$ and $icode col$$ are not present, -the size of $icode jac$$ is $latex m * n$$ and -for $latex i = 0 , \ldots , m-1$$, -$latex j = 0 , \ldots , n-1$$, -$latex \[ - jac [ i * n + j ] = \D{ F_i }{ x_j } (x) -\] $$ -$pre - -$$ -In the case where the arguments $icode row$$ and $icode col$$ are present, -we use $latex K$$ to denote the size of $icode jac$$. -The input value of its elements does not matter. -Upon return, for $latex k = 0 , \ldots , K - 1$$, -$latex \[ - jac [ k ] = \D{ F_i }{ x_j } (x) - \; , \; - \; {\rm where} \; - i = row[k] - \; {\rm and } \; - j = col[k] -\] $$ - -$head work$$ -If this argument is present, it has prototype -$codei% - sparse_jacobian_work& %work% -%$$ -This object can only be used with the routines -$code SparseJacobianForward$$ and $code SparseJacobianReverse$$. -During its the first use, information is stored in $icode work$$. -This is used to reduce the work done by future calls to the same mode -(forward or reverse), -the same $icode f$$, $icode p$$, $icode row$$, and $icode col$$. -If a future call is for a different mode, -or any of these values have changed, -you must first call $icode%work%.clear()%$$ -to inform CppAD that this information needs to be recomputed. - -$subhead color_method$$ -The coloring algorithm determines which columns (forward mode) -or rows (reverse mode) can be computed during the same sweep. -This field has prototype -$codei% - std::string %work%.color_method -%$$ -and its default value (after a constructor or $code clear()$$) -is $code "cppad"$$. -If $cref colpack_prefix$$ is specified on the -$cref/cmake command/cmake/CMake Command/$$ line, -you can set this method to $code "colpack"$$. -This value only matters on the first call to $code sparse_jacobian$$ -that follows the $icode work$$ constructor or a call to -$icode%work%.clear()%$$. - -$subhead p$$ -If $icode work$$ is present, and it is not the first call after -its construction or a clear, -the sparsity pattern $icode p$$ is not used. -This enables one to free the sparsity pattern -and still compute corresponding sparse Jacobians. - -$head n_sweep$$ -The return value $icode n_sweep$$ has prototype -$codei% - size_t %n_sweep% -%$$ -If $code SparseJacobianForward$$ ($code SparseJacobianReverse$$) is used, -$icode n_sweep$$ is the number of first order forward (reverse) sweeps -used to compute the requested Jacobian values. -(This is also the number of colors determined by the coloring method -mentioned above). -This is proportional to the total work that $code SparseJacobian$$ does, -not counting the zero order forward sweep, -or the work to combine multiple columns (rows) into a single sweep. - -$head BaseVector$$ -The type $icode BaseVector$$ 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 SetVector$$ -The type $icode SetVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$ or $code std::set$$; -see $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for a discussion -of the difference. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$subhead Restrictions$$ -If $icode SetVector$$ has elements of $code std::set$$, -then $icode%p%[%i%]%$$ must return a reference (not a copy) to the -corresponding set. -According to section 26.3.2.3 of the 1998 C++ standard, -$code std::valarray< std::set >$$ does not satisfy -this condition. - -$head SizeVector$$ -The type $icode SizeVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Uses Forward$$ -After each call to $cref Forward$$, -the object $icode f$$ contains the corresponding -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$. -After a call to any of the sparse Jacobian routines, -the zero order Taylor coefficients correspond to -$icode%f%.Forward(0, %x%)%$$ -and the other coefficients are unspecified. - -After $code SparseJacobian$$, -the previous calls to $cref Forward$$ are undefined. - -$head Example$$ -$children% - example/sparse/sparse_jacobian.cpp -%$$ -The routine -$cref sparse_jacobian.cpp$$ -is examples and tests of $code sparse_jacobian$$. -It return $code true$$, if it succeeds and $code false$$ otherwise. - -$end -============================================================================== -*/ -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file sparse_jacobian.hpp -Sparse Jacobian driver routine and helper functions. -*/ -// =========================================================================== -/*! -class used by SparseJacobian to hold information so it does not need to be -recomputed. -*/ -class sparse_jacobian_work { - public: - /// Coloring method: "cppad", or "colpack" - /// (this field is set by user) - std::string color_method; - /// indices that sort the user row and col arrays by color - CppAD::vector order; - /// results of the coloring algorithm - CppAD::vector color; - - /// constructor - sparse_jacobian_work(void) : color_method("cppad") - { } - /// reset coloring method to its default and - /// inform CppAD that color and order need to be recomputed - void clear(void) - { color_method = "cppad"; - order.clear(); - color.clear(); - } -}; -// =========================================================================== -/*! -Private helper function forward mode cases - -\tparam Base -is the base type for the recording that is stored in this -ADFun object. - -\tparam BaseVector -is a simple vector class with elements of type Base. - -\tparam SetVector -is either sparse_pack or sparse_list. - -\tparam SizeVector -is a simple vector class with elements of type size_t. - -\param x [in] -is a vector specifing the point at which to compute the Jacobian. - -\param p_transpose [in] -If work.color.size() != 0, -then p_transpose is not used. -Otherwise, it is a -sparsity pattern for the transpose of the Jacobian of this ADFun object. -Note that we do not change the values in p_transpose, -but is not const because we use its iterator facility. - -\param row [in] -is the vector of row indices for the returned Jacobian values. - -\param col [in] -is the vector of columns indices for the returned Jacobian values. -It must have the same size as row. - -\param jac [out] -is the vector of Jacobian values. We use K to denote the size of jac. -The return value jac[k] is the partial of the -row[k] range component of the function with respect -the the col[k] domain component of its argument. - -\param work -work.color_method is an input. The rest of -this structure contains information that is computed by SparseJacobainFor. -If the sparsity pattern, row vector, or col vectors -are not the same between calls to SparseJacobianFor, - work.clear() must be called to reinitialize work. - -\return -Is the number of first order forward sweeps used to compute the -requested Jacobian values. The total work, not counting the zero order -forward sweep, or the time to combine computations, is proportional to this -return value. -*/ -template -template -size_t ADFun::SparseJacobianFor( - const BaseVector& x , - SetVector& p_transpose , - const SizeVector& row , - const SizeVector& col , - BaseVector& jac , - sparse_jacobian_work& work ) -{ - size_t j, k, ell; - - CppAD::vector& order(work.order); - CppAD::vector& color(work.color); - - size_t m = Range(); - size_t n = Domain(); - - // some values - const Base zero(0); - const Base one(1); - - // check BaseVector is Simple Vector class with Base type elements - CheckSimpleVector(); - - CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n ); - CPPAD_ASSERT_UNKNOWN( color.size() == 0 || color.size() == n ); - - // number of components of Jacobian that are required - size_t K = size_t(jac.size()); - CPPAD_ASSERT_UNKNOWN( size_t( row.size() ) == K ); - CPPAD_ASSERT_UNKNOWN( size_t( col.size() ) == K ); - - // Point at which we are evaluating the Jacobian - Forward(0, x); - - // check for case where nothing (except Forward above) to do - if( K == 0 ) - return 0; - - if( color.size() == 0 ) - { - CPPAD_ASSERT_UNKNOWN( p_transpose.n_set() == n ); - CPPAD_ASSERT_UNKNOWN( p_transpose.end() == m ); - - // execute coloring algorithm - color.resize(n); - if( work.color_method == "cppad" ) - local::color_general_cppad(p_transpose, col, row, color); - else if( work.color_method == "colpack" ) - { -# if CPPAD_HAS_COLPACK - local::color_general_colpack(p_transpose, col, row, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "SparseJacobianForward: work.color_method = colpack " - "and colpack_prefix missing from cmake command line." - ); -# endif - } - else CPPAD_ASSERT_KNOWN( - false, - "SparseJacobianForward: work.color_method is not valid." - ); - - // put sorting indices in color order - SizeVector key(K); - order.resize(K); - for(k = 0; k < K; k++) - key[k] = color[ col[k] ]; - index_sort(key, order); - } - size_t n_color = 1; - for(j = 0; j < n; j++) if( color[j] < n ) - n_color = std::max(n_color, color[j] + 1); - - // initialize the return value - for(k = 0; k < K; k++) - jac[k] = zero; - -# if CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION == 1 - // direction vector and return values for calls to forward - BaseVector dx(n), dy(m); - - // loop over colors - k = 0; - for(ell = 0; ell < n_color; ell++) - { CPPAD_ASSERT_UNKNOWN( color[ col[ order[k] ] ] == ell ); - - // combine all columns with this color - for(j = 0; j < n; j++) - { dx[j] = zero; - if( color[j] == ell ) - dx[j] = one; - } - // call forward mode for all these columns at once - dy = Forward(1, dx); - - // set the corresponding components of the result - while( k < K && color[ col[order[k]] ] == ell ) - { jac[ order[k] ] = dy[row[order[k]]]; - k++; - } - } -# else - // abbreviation for this value - size_t max_r = CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION; - CPPAD_ASSERT_UNKNOWN( max_r > 1 ); - - // count the number of colors done so far - size_t count_color = 0; - // count the sparse matrix entries done so far - k = 0; - while( count_color < n_color ) - { // number of colors we will do this time - size_t r = std::min(max_r , n_color - count_color); - BaseVector dx(n * r), dy(m * r); - - // loop over colors we will do this tme - for(ell = 0; ell < r; ell++) - { // combine all columns with this color - for(j = 0; j < n; j++) - { dx[j * r + ell] = zero; - if( color[j] == ell + count_color ) - dx[j * r + ell] = one; - } - } - size_t q = 1; - dy = Forward(q, r, dx); - - // store results - for(ell = 0; ell < r; ell++) - { // set the components of the result for this color - while( k < K && color[ col[order[k]] ] == ell + count_color ) - { jac[ order[k] ] = dy[ row[order[k]] * r + ell ]; - k++; - } - } - count_color += r; - } -# endif - return n_color; -} -/*! -Private helper function for reverse mode cases. - -\tparam Base -is the base type for the recording that is stored in this -ADFun object. - -\tparam BaseVector -is a simple vector class with elements of type Base. - -\tparam SetVector -is either sparse_pack or sparse_list. - -\tparam SizeVector -is a simple vector class with elements of type size_t. - -\param x [in] -is a vector specifing the point at which to compute the Jacobian. - -\param p [in] -If work.color.size() != 0, then p is not used. -Otherwise, it is a -sparsity pattern for the Jacobian of this ADFun object. -Note that we do not change the values in p, -but is not const because we use its iterator facility. - -\param row [in] -is the vector of row indices for the returned Jacobian values. - -\param col [in] -is the vector of columns indices for the returned Jacobian values. -It must have the same size as row. - -\param jac [out] -is the vector of Jacobian values. -It must have the same size as row. -The return value jac[k] is the partial of the -row[k] range component of the function with respect -the the col[k] domain component of its argument. - -\param work -work.color_method is an input. The rest of -This structure contains information that is computed by SparseJacobainRev. -If the sparsity pattern, row vector, or col vectors -are not the same between calls to SparseJacobianRev, - work.clear() must be called to reinitialize work. - -\return -Is the number of first order reverse sweeps used to compute the -reverse Jacobian values. The total work, not counting the zero order -forward sweep, or the time to combine computations, is proportional to this -return value. -*/ -template -template -size_t ADFun::SparseJacobianRev( - const BaseVector& x , - SetVector& p , - const SizeVector& row , - const SizeVector& col , - BaseVector& jac , - sparse_jacobian_work& work ) -{ - size_t i, k, ell; - - CppAD::vector& order(work.order); - CppAD::vector& color(work.color); - - size_t m = Range(); - size_t n = Domain(); - - // some values - const Base zero(0); - const Base one(1); - - // check BaseVector is Simple Vector class with Base type elements - CheckSimpleVector(); - - CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n ); - CPPAD_ASSERT_UNKNOWN (color.size() == m || color.size() == 0 ); - - // number of components of Jacobian that are required - size_t K = size_t(jac.size()); - CPPAD_ASSERT_UNKNOWN( size_t( size_t( row.size() ) ) == K ); - CPPAD_ASSERT_UNKNOWN( size_t( size_t( col.size() ) ) == K ); - - // Point at which we are evaluating the Jacobian - Forward(0, x); - - // check for case where nothing (except Forward above) to do - if( K == 0 ) - return 0; - - if( color.size() == 0 ) - { - CPPAD_ASSERT_UNKNOWN( p.n_set() == m ); - CPPAD_ASSERT_UNKNOWN( p.end() == n ); - - // execute the coloring algorithm - color.resize(m); - if( work.color_method == "cppad" ) - local::color_general_cppad(p, row, col, color); - else if( work.color_method == "colpack" ) - { -# if CPPAD_HAS_COLPACK - local::color_general_colpack(p, row, col, color); -# else - CPPAD_ASSERT_KNOWN( - false, - "SparseJacobianReverse: work.color_method = colpack " - "and colpack_prefix missing from cmake command line." - ); -# endif - } - else CPPAD_ASSERT_KNOWN( - false, - "SparseJacobianReverse: work.color_method is not valid." - ); - - // put sorting indices in color order - SizeVector key(K); - order.resize(K); - for(k = 0; k < K; k++) - key[k] = color[ row[k] ]; - index_sort(key, order); - } - size_t n_color = 1; - for(i = 0; i < m; i++) if( color[i] < m ) - n_color = std::max(n_color, color[i] + 1); - - // weighting vector for calls to reverse - BaseVector w(m); - - // location for return values from Reverse - BaseVector dw(n); - - // initialize the return value - for(k = 0; k < K; k++) - jac[k] = zero; - - // loop over colors - k = 0; - for(ell = 0; ell < n_color; ell++) - { CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell ); - - // combine all the rows with this color - for(i = 0; i < m; i++) - { w[i] = zero; - if( color[i] == ell ) - w[i] = one; - } - // call reverse mode for all these rows at once - dw = Reverse(1, w); - - // set the corresponding components of the result - while( k < K && color[ row[order[k]] ] == ell ) - { jac[ order[k] ] = dw[col[order[k]]]; - k++; - } - } - return n_color; -} -// ========================================================================== -// Public Member functions -// ========================================================================== -/*! -Compute user specified subset of a sparse Jacobian using forward mode. - -The C++ source code corresponding to this operation is -\verbatim - SparceJacobianForward(x, p, row, col, jac, work) -\endverbatim - -\tparam Base -is the base type for the recording that is stored in this -ADFun object. - -\tparam BaseVector -is a simple vector class with elements of type Base. - -\tparam SetVector -is a simple vector class with elements of type - bool or std::set. - -\tparam SizeVector -is a simple vector class with elements of type size_t. - -\param x [in] -is a vector specifing the point at which to compute the Jacobian. - -\param p [in] -is the sparsity pattern for the Jacobian that we are calculating. - -\param row [in] -is the vector of row indices for the returned Jacobian values. - -\param col [in] -is the vector of columns indices for the returned Jacobian values. -It must have the same size as row. - -\param jac [out] -is the vector of Jacobian values. -It must have the same size as row. -The return value jac[k] is the partial of the -row[k] range component of the function with respect -the the col[k] domain component of its argument. - -\param work [in,out] -this structure contains information that depends on the function object, -sparsity pattern, row vector, and col vector. -If they are not the same between calls to SparseJacobianForward, - work.clear() must be called to reinitialize them. - -\return -Is the number of first order forward sweeps used to compute the -requested Jacobian values. The total work, not counting the zero order -forward sweep, or the time to combine computations, is proportional to this -return value. -*/ -template -template -size_t ADFun::SparseJacobianForward( - const BaseVector& x , - const SetVector& p , - const SizeVector& row , - const SizeVector& col , - BaseVector& jac , - sparse_jacobian_work& work ) -{ - size_t n = Domain(); - size_t m = Range(); - size_t K = jac.size(); -# ifndef NDEBUG - size_t k; - CPPAD_ASSERT_KNOWN( - size_t(x.size()) == n , - "SparseJacobianForward: size of x not equal domain dimension for f." - ); - CPPAD_ASSERT_KNOWN( - size_t(row.size()) == K && size_t(col.size()) == K , - "SparseJacobianForward: either r or c does not have " - "the same size as jac." - ); - CPPAD_ASSERT_KNOWN( - work.color.size() == 0 || work.color.size() == n, - "SparseJacobianForward: invalid value in work." - ); - for(k = 0; k < K; k++) - { CPPAD_ASSERT_KNOWN( - row[k] < m, - "SparseJacobianForward: invalid value in r." - ); - CPPAD_ASSERT_KNOWN( - col[k] < n, - "SparseJacobianForward: invalid value in c." - ); - } - if( work.color.size() != 0 ) - for(size_t j = 0; j < n; j++) CPPAD_ASSERT_KNOWN( - work.color[j] <= n, - "SparseJacobianForward: invalid value in work." - ); -# endif - // check for case where there is nothing to compute - size_t n_sweep = 0; - if( K == 0 ) - return n_sweep; - - typedef typename SetVector::value_type Set_type; - typedef typename local::sparse::internal_pattern::pattern_type Pattern_type; - Pattern_type s_transpose; - if( work.color.size() == 0 ) - { bool transpose = true; - const char* error_msg = "SparseJacobianForward: transposed sparsity" - " pattern does not have proper row or column dimension"; - sparsity_user2internal(s_transpose, p, n, m, transpose, error_msg); - } - n_sweep = SparseJacobianFor(x, s_transpose, row, col, jac, work); - return n_sweep; -} -/*! -Compute user specified subset of a sparse Jacobian using forward mode. - -The C++ source code corresponding to this operation is -\verbatim - SparceJacobianReverse(x, p, row, col, jac, work) -\endverbatim - -\tparam Base -is the base type for the recording that is stored in this -ADFun object. - -\tparam BaseVector -is a simple vector class with elements of type Base. - -\tparam SetVector -is a simple vector class with elements of type - bool or std::set. - -\tparam SizeVector -is a simple vector class with elements of type size_t. - -\param x [in] -is a vector specifing the point at which to compute the Jacobian. - -\param p [in] -is the sparsity pattern for the Jacobian that we are calculating. - -\param row [in] -is the vector of row indices for the returned Jacobian values. - -\param col [in] -is the vector of columns indices for the returned Jacobian values. -It must have the same size as row. - -\param jac [out] -is the vector of Jacobian values. -It must have the same size as row. -The return value jac[k] is the partial of the -row[k] range component of the function with respect -the the col[k] domain component of its argument. - -\param work [in,out] -this structure contains information that depends on the function object, -sparsity pattern, row vector, and col vector. -If they are not the same between calls to SparseJacobianReverse, - work.clear() must be called to reinitialize them. - -\return -Is the number of first order reverse sweeps used to compute the -reverse Jacobian values. The total work, not counting the zero order -forward sweep, or the time to combine computations, is proportional to this -return value. -*/ -template -template -size_t ADFun::SparseJacobianReverse( - const BaseVector& x , - const SetVector& p , - const SizeVector& row , - const SizeVector& col , - BaseVector& jac , - sparse_jacobian_work& work ) -{ - size_t m = Range(); - size_t n = Domain(); - size_t K = jac.size(); -# ifndef NDEBUG - size_t k; - CPPAD_ASSERT_KNOWN( - size_t(x.size()) == n , - "SparseJacobianReverse: size of x not equal domain dimension for f." - ); - CPPAD_ASSERT_KNOWN( - size_t(row.size()) == K && size_t(col.size()) == K , - "SparseJacobianReverse: either r or c does not have " - "the same size as jac." - ); - CPPAD_ASSERT_KNOWN( - work.color.size() == 0 || work.color.size() == m, - "SparseJacobianReverse: invalid value in work." - ); - for(k = 0; k < K; k++) - { CPPAD_ASSERT_KNOWN( - row[k] < m, - "SparseJacobianReverse: invalid value in r." - ); - CPPAD_ASSERT_KNOWN( - col[k] < n, - "SparseJacobianReverse: invalid value in c." - ); - } - if( work.color.size() != 0 ) - for(size_t i = 0; i < m; i++) CPPAD_ASSERT_KNOWN( - work.color[i] <= m, - "SparseJacobianReverse: invalid value in work." - ); -# endif - // check for case where there is nothing to compute - size_t n_sweep = 0; - if( K == 0 ) - return n_sweep; - - typedef typename SetVector::value_type Set_type; - typedef typename local::sparse::internal_pattern::pattern_type Pattern_type; - Pattern_type s; - if( work.color.size() == 0 ) - { bool transpose = false; - const char* error_msg = "SparseJacobianReverse: sparsity" - " pattern does not have proper row or column dimension"; - sparsity_user2internal(s, p, m, n, transpose, error_msg); - } - n_sweep = SparseJacobianRev(x, s, row, col, jac, work); - return n_sweep; -} -/*! -Compute a sparse Jacobian. - -The C++ source code corresponding to this operation is -\verbatim - jac = SparseJacobian(x, p) -\endverbatim - -\tparam Base -is the base type for the recording that is stored in this -ADFun object. - -\tparam BaseVector -is a simple vector class with elements of type Base. - -\tparam SetVector -is a simple vector class with elements of type - bool or std::set. - -\param x [in] -is a vector specifing the point at which to compute the Jacobian. - -\param p [in] -is the sparsity pattern for the Jacobian that we are calculating. - -\return -Will be a vector if size m * n containing the Jacobian at the -specified point (in row major order). -*/ -template -template -BaseVector ADFun::SparseJacobian( - const BaseVector& x, const SetVector& p -) -{ size_t i, j, k; - - size_t m = Range(); - size_t n = Domain(); - BaseVector jac(m * n); - - CPPAD_ASSERT_KNOWN( - size_t(x.size()) == n, - "SparseJacobian: size of x not equal domain size for f." - ); - CheckSimpleVector(); - - typedef typename SetVector::value_type Set_type; - typedef typename local::sparse::internal_pattern::pattern_type Pattern_type; - - // initialize the return value as zero - Base zero(0); - for(i = 0; i < m; i++) - for(j = 0; j < n; j++) - jac[i * n + j] = zero; - - sparse_jacobian_work work; - CppAD::vector row; - CppAD::vector col; - if( n <= m ) - { - // need an internal copy of sparsity pattern - Pattern_type s_transpose; - bool transpose = true; - const char* error_msg = "SparseJacobian: transposed sparsity" - " pattern does not have proper row or column dimension"; - sparsity_user2internal(s_transpose, p, n, m, transpose, error_msg); - - k = 0; - for(j = 0; j < n; j++) - { typename Pattern_type::const_iterator itr(s_transpose, j); - i = *itr; - while( i != s_transpose.end() ) - { row.push_back(i); - col.push_back(j); - k++; - i = *(++itr); - } - } - size_t K = k; - BaseVector J(K); - - // now we have folded this into the following case - SparseJacobianFor(x, s_transpose, row, col, J, work); - - // now set the non-zero return values - for(k = 0; k < K; k++) - jac[ row[k] * n + col[k] ] = J[k]; - } - else - { - // need an internal copy of sparsity pattern - Pattern_type s; - bool transpose = false; - const char* error_msg = "SparseJacobian: sparsity" - " pattern does not have proper row or column dimension"; - sparsity_user2internal(s, p, m, n, transpose, error_msg); - - k = 0; - for(i = 0; i < m; i++) - { typename Pattern_type::const_iterator itr(s, i); - j = *itr; - while( j != s.end() ) - { row.push_back(i); - col.push_back(j); - k++; - j = *(++itr); - } - } - size_t K = k; - BaseVector J(K); - - // now we have folded this into the following case - SparseJacobianRev(x, s, row, col, J, work); - - // now set the non-zero return values - for(k = 0; k < K; k++) - jac[ row[k] * n + col[k] ] = J[k]; - } - - return jac; -} - -/*! -Compute a sparse Jacobian. - -The C++ source code corresponding to this operation is -\verbatim - jac = SparseJacobian(x) -\endverbatim - -\tparam Base -is the base type for the recording that is stored in this -ADFun object. - -\tparam BaseVector -is a simple vector class with elements of the Base. - -\param x [in] -is a vector specifing the point at which to compute the Jacobian. - -\return -Will be a vector of size m * n containing the Jacobian at the -specified point (in row major order). -*/ -template -template -BaseVector ADFun::SparseJacobian( const BaseVector& x ) -{ typedef CppAD::vectorBool BoolVector; - - size_t m = Range(); - size_t n = Domain(); - - // sparsity pattern for Jacobian - BoolVector p(m * n); - - if( n <= m ) - { size_t j, k; - - // use forward mode - BoolVector r(n * n); - for(j = 0; j < n; j++) - { for(k = 0; k < n; k++) - r[j * n + k] = false; - r[j * n + j] = true; - } - p = ForSparseJac(n, r); - } - else - { size_t i, k; - - // use reverse mode - BoolVector s(m * m); - for(i = 0; i < m; i++) - { for(k = 0; k < m; k++) - s[i * m + k] = false; - s[i * m + i] = true; - } - p = RevSparseJac(m, s); - } - return SparseJacobian(x, p); -} - -} // END_CPPAD_NAMESPACE -# undef CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION -# endif diff --git a/build-config/cppad/include/cppad/core/standard_math.hpp b/build-config/cppad/include/cppad/core/standard_math.hpp deleted file mode 100644 index 8144d473..00000000 --- a/build-config/cppad/include/cppad/core/standard_math.hpp +++ /dev/null @@ -1,118 +0,0 @@ -# ifndef CPPAD_CORE_STANDARD_MATH_HPP -# define CPPAD_CORE_STANDARD_MATH_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin unary_standard_math$$ -$spell - const - VecAD - fabs -$$ - -$section The Unary Standard Math Functions$$ - -$head Syntax$$ -$icode%y% = %fun%(%x%)%$$ - -$head Purpose$$ -Evaluates the standard math function $icode fun$$. - -$head Possible Types$$ - -$subhead Base$$ -If $icode Base$$ satisfies the -$cref/base type requirements/base_require/$$ -and argument $icode x$$ has prototype -$codei% - const %Base%& %x% -%$$ -then the result $icode y$$ has prototype -$codei% - %Base% %y% -%$$ - -$subhead AD$$ -If the argument $icode x$$ has prototype -$codei% - const AD<%Base%>& %x% -%$$ -then the result $icode y$$ has prototype -$codei% - AD<%Base%> %y% -%$$ - -$subhead VecAD$$ -If the argument $icode x$$ has prototype -$codei% - const VecAD<%Base%>::reference& %x% -%$$ -then the result $icode y$$ has prototype -$codei% - AD<%Base%> %y% -%$$ - -$children%include/cppad/core/std_math_11.hpp - %include/cppad/core/abs.hpp - %include/cppad/core/sign.hpp -%$$ - -$head fun$$ -The possible values for $icode fun$$ are -$table -$icode fun$$ $pre $$ $cnext Description $rnext -$cref abs$$ $cnext $title abs$$ $rnext -$cref acos$$ $cnext $title acos$$ $rnext -$cref acosh$$ $cnext $title acosh$$ $rnext -$cref asin$$ $cnext $title asin$$ $rnext -$cref asinh$$ $cnext $title asinh$$ $rnext -$cref atan$$ $cnext $title atan$$ $rnext -$cref atanh$$ $cnext $title atanh$$ $rnext -$cref cos$$ $cnext $title cos$$ $rnext -$cref cosh$$ $cnext $title cosh$$ $rnext -$cref erf$$ $cnext $title erf$$ $rnext -$cref exp$$ $cnext $title exp$$ $rnext -$cref expm1$$ $cnext $title expm1$$ $rnext -$cref/fabs/abs/$$ $cnext $title abs$$ $rnext -$cref log10$$ $cnext $title log10$$ $rnext -$cref log1p$$ $cnext $title log1p$$ $rnext -$cref log$$ $cnext $title log$$ $rnext -$cref sign$$ $cnext $title sign$$ $rnext -$cref sin$$ $cnext $title sin$$ $rnext -$cref sinh$$ $cnext $title sinh$$ $rnext -$cref sqrt$$ $cnext $title sqrt$$ $rnext -$cref tan$$ $cnext $title tan$$ $rnext -$cref tanh$$ $cnext $title tanh$$ -$tend - -$end -*/ -# include -# include - -/* -$begin binary_math$$ - -$section The Binary Math Functions$$ - -$childtable%include/cppad/core/atan2.hpp - %include/cppad/core/pow.hpp - %include/cppad/core/azmul.hpp -%$$ - -$end -*/ -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/std_math_11.hpp b/build-config/cppad/include/cppad/core/std_math_11.hpp deleted file mode 100644 index 8cc88122..00000000 --- a/build-config/cppad/include/cppad/core/std_math_11.hpp +++ /dev/null @@ -1,884 +0,0 @@ -# ifndef CPPAD_CORE_STD_MATH_11_HPP -# define CPPAD_CORE_STD_MATH_11_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------------- -$begin acos$$ -$spell - acos -$$ - -$section Inverse Cosine Function: acos$$ - -$head Syntax$$ -$icode%y% = acos(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{acos}^{(1)} (x) & = & - (1 - x * x)^{-1/2} -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/acos.cpp -%$$ -The file -$cref acos.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$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 Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Example$$ -$children% - example/general/acosh.cpp -%$$ -The file -$cref acosh.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin asin$$ -$spell - asin -$$ - -$section Inverse Sine Function: asin$$ - -$head Syntax$$ -$icode%y% = asin(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{asin}^{(1)} (x) & = & (1 - x * x)^{-1/2} -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/asin.cpp -%$$ -The file -$cref asin.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$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 Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Example$$ -$children% - example/general/asinh.cpp -%$$ -The file -$cref asinh.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin atan$$ -$spell - atan -$$ - -$section Inverse Tangent Function: atan$$ - -$head Syntax$$ -$icode%y% = atan(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{atan}^{(1)} (x) & = & \frac{1}{1 + x^2} -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/atan.cpp -%$$ -The file -$cref atan.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$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 Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Example$$ -$children% - example/general/atanh.cpp -%$$ -The file -$cref atanh.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin cos$$ -$spell - cos -$$ - -$section The Cosine Function: cos$$ - -$head Syntax$$ -$icode%y% = cos(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{cos}^{(1)} (x) & = & - \sin(x) -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/cos.cpp -%$$ -The file -$cref cos.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin cosh$$ -$spell - cosh -$$ - -$section The Hyperbolic Cosine Function: cosh$$ - -$head Syntax$$ -$icode%y% = cosh(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{cosh}^{(1)} (x) & = & \sinh(x) -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/cosh.cpp -%$$ -The file -$cref cosh.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$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 Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Example$$ -$children% - example/general/erf.cpp -%$$ -The file -$cref erf.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin erfc$$ -$spell - erf - erfc - Vec - CppAD -$$ -$section The Complementary Error Function: erfc$$ - -$head Syntax$$ -$icode%y% = erfc(%x%)%$$ - -$head Description$$ -Returns the value of the complementary error function which is defined by -$icode%y% == 1 - erf(%x%)%$$. - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Example$$ -$children% - example/general/erfc.cpp -%$$ -The file -$cref erfc.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin exp$$ -$spell - exp -$$ - -$section The Exponential Function: exp$$ - -$head Syntax$$ -$icode%y% = exp(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{exp}^{(1)} (x) & = & \exp(x) -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/exp.cpp -%$$ -The file -$cref exp.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin expm1$$ -$spell - exp - expm1 - 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 Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Example$$ -$children% - example/general/expm1.cpp -%$$ -The file -$cref expm1.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin log$$ -$spell -$$ - -$section The Exponential Function: log$$ - -$head Syntax$$ -$icode%y% = log(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{log}^{(1)} (x) & = & \frac{1}{x} -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/log.cpp -%$$ -The file -$cref log.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$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 Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Example$$ -$children% - example/general/log1p.cpp -%$$ -The file -$cref log1p.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin log10$$ -$spell - CppAD -$$ - -$section The Base 10 Logarithm Function: log10$$ - -$head Syntax$$ -$icode%y% = log10(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Method$$ -CppAD uses the representation -$latex \[ -\begin{array}{lcr} - {\rm log10} (x) & = & \log(x) / \log(10) -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/log10.cpp -%$$ -The file -$cref log10.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin sin$$ -$spell - sin -$$ - -$section The Sine Function: sin$$ - -$head Syntax$$ -$icode%y% = sin(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{sin}^{(1)} (x) & = & \cos(x) -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/sin.cpp -%$$ -The file -$cref sin.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin sinh$$ -$spell - sinh -$$ - -$section The Hyperbolic Sine Function: sinh$$ - -$head Syntax$$ -$icode%y% = sinh(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{sinh}^{(1)} (x) & = & \cosh(x) -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/sinh.cpp -%$$ -The file -$cref sinh.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin sqrt$$ -$spell - sqrt -$$ - -$section The Square Root Function: sqrt$$ - -$head Syntax$$ -$icode%y% = sqrt(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{sqrt}^{(1)} (x) & = & \frac{1}{2 \R{sqrt} (x) } -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/sqrt.cpp -%$$ -The file -$cref sqrt.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin tan$$ -$spell - tan -$$ - -$section The Tangent Function: tan$$ - -$head Syntax$$ -$icode%y% = tan(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{tan}^{(1)} (x) & = & 1 + \tan (x)^2 -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/tan.cpp -%$$ -The file -$cref tan.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -$begin tanh$$ -$spell - tanh -$$ - -$section The Hyperbolic Tangent Function: tanh$$ - -$head Syntax$$ -$icode%y% = tanh(%x%)%$$ - -$head x, y$$ -See the $cref/possible types/unary_standard_math/Possible Types/$$ -for a unary standard math function. - -$head Atomic$$ -This is an $cref/atomic operation/glossary/Operation/Atomic/$$. - -$head Derivative$$ -$latex \[ -\begin{array}{lcr} - \R{tanh}^{(1)} (x) & = & 1 - \tanh (x)^2 -\end{array} -\] $$ - -$head Example$$ -$children% - example/general/tanh.cpp -%$$ -The file -$cref tanh.cpp$$ -contains an example and test of this function. - -$end -------------------------------------------------------------------------------- -*/ - -/*! -\file std_math_11.hpp -Define AD standard math functions (using their Base versions) -*/ - -/*! -\def CPPAD_STANDARD_MATH_UNARY_AD(Name, Op) -Defines function Name with argument type AD and tape operation Op - -The macro defines the function x.Name() where x has type AD. -It then uses this funciton to define Name(x) where x has type -AD or VecAD_reference. - -If x is a variable, the tape unary operator Op is used -to record the operation and the result is identified as correspoding -to this operation; i.e., Name(x).taddr_ idendifies the operation and -Name(x).tape_id_ identifies the tape. - -This macro is used to define AD versions of -acos, asin, atan, cos, cosh, exp, fabs, log, sin, sinh, sqrt, tan, tanh. -*/ - -# define CPPAD_STANDARD_MATH_UNARY_AD(Name, Op) \ - template \ - inline AD Name(const AD &x) \ - { return x.Name##_me(); \ - } \ - template \ - inline AD AD::Name##_me (void) const \ - { \ - AD result; \ - result.value_ = CppAD::Name(value_); \ - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); \ - \ - local::ADTape* tape = AD::tape_ptr(); \ - if( tape == nullptr ) \ - return result; \ - \ - if( tape_id_ != tape->id_ ) \ - return result; \ - \ - if(ad_type_ == dynamic_enum) \ - { result.taddr_ = tape->Rec_.put_dyn_par( \ - result.value_, local::Name##_dyn, taddr_ \ - ); \ - result.tape_id_ = tape_id_; \ - result.ad_type_ = dynamic_enum; \ - } \ - else \ - { CPPAD_ASSERT_UNKNOWN( NumArg(Op) == 1 ); \ - tape->Rec_.PutArg(taddr_); \ - result.taddr_ = tape->Rec_.PutOp(Op); \ - result.tape_id_ = tape->id_; \ - result.ad_type_ = variable_enum; \ - } \ - return result; \ - } \ - template \ - inline AD Name(const VecAD_reference &x) \ - { return x.ADBase().Name##_me(); } - -// BEGIN CppAD namespace -namespace CppAD { - - CPPAD_STANDARD_MATH_UNARY_AD(acos, local::AcosOp) - CPPAD_STANDARD_MATH_UNARY_AD(acosh, local::AcoshOp) - CPPAD_STANDARD_MATH_UNARY_AD(asin, local::AsinOp) - CPPAD_STANDARD_MATH_UNARY_AD(asinh, local::AsinhOp) - CPPAD_STANDARD_MATH_UNARY_AD(atan, local::AtanOp) - CPPAD_STANDARD_MATH_UNARY_AD(atanh, local::AtanhOp) - CPPAD_STANDARD_MATH_UNARY_AD(cos, local::CosOp) - CPPAD_STANDARD_MATH_UNARY_AD(cosh, local::CoshOp) - CPPAD_STANDARD_MATH_UNARY_AD(exp, local::ExpOp) - CPPAD_STANDARD_MATH_UNARY_AD(expm1, local::Expm1Op) - CPPAD_STANDARD_MATH_UNARY_AD(fabs, local::AbsOp) - CPPAD_STANDARD_MATH_UNARY_AD(log, local::LogOp) - CPPAD_STANDARD_MATH_UNARY_AD(log1p, local::Log1pOp) - CPPAD_STANDARD_MATH_UNARY_AD(sin, local::SinOp) - CPPAD_STANDARD_MATH_UNARY_AD(sinh, local::SinhOp) - CPPAD_STANDARD_MATH_UNARY_AD(sqrt, local::SqrtOp) - CPPAD_STANDARD_MATH_UNARY_AD(tan, local::TanOp) - CPPAD_STANDARD_MATH_UNARY_AD(tanh, local::TanhOp) - - - // Error function is a special case - template - inline AD erf(const AD &x) - { bool complement = false; - return x.erf_me(complement); - } - template - inline AD erfc(const AD &x) - { bool complement = true; - return x.erf_me(complement); - } - template - inline AD AD::erf_me (bool complement) const - { - AD result; - if( complement ) - result.value_ = CppAD::erfc(value_); - else - result.value_ = CppAD::erf(value_); - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - - // check if operand is a constant parameter - if( tape_id_ != tape->id_ ) - return result; - - if(ad_type_ == dynamic_enum) - { local::op_code_dyn op = local::erf_dyn; - if( complement ) - op = local::erfc_dyn; - - // dynamic paramter argument - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, op, taddr_ - ); - result.tape_id_ = tape_id_; - result.ad_type_ = dynamic_enum; - } - else - { local::OpCode op = local::ErfOp; - if( complement ) - op = local::ErfcOp; - - // variable argument - CPPAD_ASSERT_UNKNOWN( local::NumArg(op) == 3 ); - - // arg[0] = argument to erf function - tape->Rec_.PutArg(taddr_); - - // arg[1] = zero - addr_t p = tape->Rec_.put_con_par( Base(0.0) ); - tape->Rec_.PutArg(p); - - // arg[2] = 2 / sqrt(pi) - p = tape->Rec_.put_con_par(Base( - 1.0 / std::sqrt( std::atan(1.0) ) - )); - tape->Rec_.PutArg(p); - // - result.taddr_ = tape->Rec_.PutOp(op); - result.tape_id_ = tape->id_; - result.ad_type_ = variable_enum; - } - return result; - } - template - inline AD erf(const VecAD_reference &x) - { bool complement = false; - return x.ADBase().erf_me(complement); - } - template - inline AD erfc(const VecAD_reference &x) - { bool complement = true; - return x.ADBase().erf_me(complement); - } - - /*! - Compute the log of base 10 of x where has type AD - - \tparam Base - is the base type (different from base for log) - for this AD type, see base_require. - - \param x - is the argument for the log10 function. - - \result - if the result is y, then \f$ x = 10^y \f$. - */ - template - inline AD log10(const AD &x) - { return CppAD::log(x) / CppAD::log( Base(10) ); } - template - inline AD log10(const VecAD_reference &x) - { return CppAD::log(x.ADBase()) / CppAD::log( Base(10) ); } -} - -# undef CPPAD_STANDARD_MATH_UNARY_AD - -# endif diff --git a/build-config/cppad/include/cppad/core/sub.hpp b/build-config/cppad/include/cppad/core/sub.hpp deleted file mode 100644 index 0f743eec..00000000 --- a/build-config/cppad/include/cppad/core/sub.hpp +++ /dev/null @@ -1,125 +0,0 @@ -# ifndef CPPAD_CORE_SUB_HPP -# define CPPAD_CORE_SUB_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD operator - (const AD &left , const AD &right) -{ - // compute the Base part - AD result; - result.value_ = left.value_ - right.value_; - CPPAD_ASSERT_UNKNOWN( Parameter(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = left.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (left.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (left.ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - - CPPAD_ASSERT_KNOWN( - left.tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "Subtract: AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // result = variable - variable - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvvOp) == 2 ); - - // put operand addresses in tape - tape->Rec_.PutArg(left.taddr_, right.taddr_); - // put operator in the tape - result.taddr_ = tape->Rec_.PutOp(local::SubvvOp); - // make result a variable - result.tape_id_ = tape_id; - result.ad_type_ = variable_enum; - } - else if( (! dyn_right) & IdenticalZero(right.value_) ) - { // result = variable - 0 - result.make_variable(left.tape_id_, left.taddr_); - } - else - { // result = variable - parameter - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvpOp) == 2 ); - - // put operand addresses in tape - addr_t p = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - tape->Rec_.PutArg(left.taddr_, p); - // put operator in the tape - result.taddr_ = tape->Rec_.PutOp(local::SubvpOp); - // make result a variable - result.tape_id_ = tape_id; - result.ad_type_ = variable_enum; - } - } - else if( var_right ) - { // result = parameter - variable - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubpvOp) == 2 ); - - // put operand addresses in tape - addr_t p = left.taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(left.value_); - tape->Rec_.PutArg(p, right.taddr_); - // put operator in the tape - result.taddr_ = tape->Rec_.PutOp(local::SubpvOp); - // make result a variable - result.tape_id_ = tape_id; - result.ad_type_ = variable_enum; - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = left.taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left.value_); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter result - result.taddr_ = tape->Rec_.put_dyn_par( - result.value_, local::sub_dyn, arg0, arg1 - ); - result.tape_id_ = tape_id; - result.ad_type_ = dynamic_enum; - } - return result; -} - -// convert other cases into the case above -CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(-) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/sub_eq.hpp b/build-config/cppad/include/cppad/core/sub_eq.hpp deleted file mode 100644 index 7344321a..00000000 --- a/build-config/cppad/include/cppad/core/sub_eq.hpp +++ /dev/null @@ -1,124 +0,0 @@ -# ifndef CPPAD_CORE_SUB_EQ_HPP -# define CPPAD_CORE_SUB_EQ_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD& AD::operator -= (const AD &right) -{ - // compute the Base part - Base left; - left = value_; - value_ -= right.value_; - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - 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 ); - - // check if left and right tapes match - bool match_left = tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - - // check if left and right are dynamic parameters - bool dyn_left = match_left & (ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if left and right are variables - bool var_left = match_left & (ad_type_ != dynamic_enum); - bool var_right = match_right & (right.ad_type_ != dynamic_enum); - - CPPAD_ASSERT_KNOWN( - tape_id_ == right.tape_id_ || ! match_left || ! match_right , - "-= : AD variables or dynamic parameters on different threads." - ); - if( var_left ) - { if( var_right ) - { // this = variable - variable - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvvOp) == 2 ); - - // put operand addresses in tape - tape->Rec_.PutArg(taddr_, right.taddr_); - // put operator in the tape - taddr_ = tape->Rec_.PutOp(local::SubvvOp); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - else if( (! dyn_right) & IdenticalZero(right.value_) ) - { // this = variable - 0 - } - else - { // this = variable - parameter - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvpOp) == 2 ); - - // put operand addresses in tape - addr_t p = right.taddr_; - if( ! dyn_right ) - p = tape->Rec_.put_con_par(right.value_); - tape->Rec_.PutArg(taddr_, p); - // put operator in the tape - taddr_ = tape->Rec_.PutOp(local::SubvpOp); - // check that this is a variable - CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); - CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum); - } - } - else if( var_right ) - { // this = parameter - variable - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubpvOp) == 2 ); - - // put operand addresses in tape - addr_t p = taddr_; - if( ! dyn_left ) - p = tape->Rec_.put_con_par(left); - tape->Rec_.PutArg(p, right.taddr_); - - // put operator in the tape - taddr_ = tape->Rec_.PutOp(local::SubpvOp); - - // make this a variable - tape_id_ = tape_id; - ad_type_ = variable_enum; - } - else if( dyn_left | dyn_right ) - { addr_t arg0 = taddr_; - addr_t arg1 = right.taddr_; - if( ! dyn_left ) - arg0 = tape->Rec_.put_con_par(left); - if( ! dyn_right ) - arg1 = tape->Rec_.put_con_par(right.value_); - // - // parameters with a dynamic parameter results - taddr_ = tape->Rec_.put_dyn_par( - value_, local::sub_dyn, arg0, arg1 - ); - tape_id_ = tape_id; - ad_type_ = dynamic_enum; - } - return *this; -} - -CPPAD_FOLD_ASSIGNMENT_OPERATOR(-=) - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/subgraph_jac_rev.hpp b/build-config/cppad/include/cppad/core/subgraph_jac_rev.hpp deleted file mode 100644 index a58b2256..00000000 --- a/build-config/cppad/include/cppad/core/subgraph_jac_rev.hpp +++ /dev/null @@ -1,351 +0,0 @@ -# ifndef CPPAD_CORE_SUBGRAPH_JAC_REV_HPP -# define CPPAD_CORE_SUBGRAPH_JAC_REV_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin subgraph_jac_rev$$ -$spell - Jacobians - Jacobian - Subgraphs - subgraph - jac - rcv - Taylor - rev - nr - nc - const - Bool - nnz -$$ - -$section Compute Sparse Jacobians Using Subgraphs$$ - -$head Syntax$$ -$icode%f%.subgraph_jac_rev(%x%, %subset%) -%$$ -$icode%f%.subgraph_jac_rev( - %select_domain%, %select_range%, %x%, %matrix_out% -)%$$ - -$head See Also$$ -$cref/clear_subgraph/subgraph_reverse/clear_subgraph/$$. - -$head Purpose$$ -We use $latex F : \B{R}^n \rightarrow \B{R}^m$$ to denote the -function corresponding to $icode f$$. -Here $icode n$$ is the $cref/domain/seq_property/Domain/$$ size, -and $icode m$$ is the $cref/range/seq_property/Range/$$ size, or $icode f$$. -The syntax above takes advantage of sparsity when computing the Jacobian -$latex \[ - J(x) = F^{(1)} (x) -\] $$ -The first syntax requires one to know what which elements of the Jacobian -they want to compute. -The second syntax computes the sparsity pattern and the value -of the Jacobian at the same time. -If one only wants the sparsity pattern, -it should be faster to use $cref subgraph_sparsity$$. - -$head Method$$ -This routine uses a subgraph technique. To be specific, -for each dependent variable, -it creates a subgraph of the operation sequence -containing the variables that affect the dependent variable. -This avoids the overhead of performing set operations -that is inherent in other methods for computing sparsity patterns. - -$head BaseVector$$ -The type $icode BaseVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$icode Base$$. - -$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 BoolVector$$ -The type $icode BoolVector$$ is a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$. - -$head f$$ -This object has prototype -$codei% - ADFun<%Base%> %f% -%$$ -Note that the Taylor coefficients stored in $icode f$$ are affected -by this operation; see -$cref/uses forward/sparse_jac/Uses Forward/$$ below. - -$head x$$ -This argument has prototype -$codei% - const %BaseVector%& %x% -%$$ -It is the value of $icode x$$ at which we are computing the Jacobian. - -$head Uses Forward$$ -After each call to $cref Forward$$, -the object $icode f$$ contains the corresponding -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$. -After a call to $code sparse_jac_forward$$ or $code sparse_jac_rev$$, -the zero order coefficients correspond to -$codei% - %f%.Forward(0, %x%) -%$$ -All the other forward mode coefficients are unspecified. - -$head subset$$ -This argument has prototype -$codei% - sparse_rcv<%SizeVector%, %BaseVector%>& %subset% -%$$ -Its row size is $icode%subset%.nr() == %m%$$, -and its column size is $icode%subset%.nc() == %n%$$. -It specifies which elements of the Jacobian are computed. -The input elements in its value vector -$icode%subset%.val()%$$ do not matter. -Upon return it contains the value of the corresponding elements -of the Jacobian. - -$head select_domain$$ -The argument $icode select_domain$$ has prototype -$codei% - const %BoolVector%& %select_domain% -%$$ -It has size $latex n$$ and specifies which independent variables -to include. - -$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 range -to include in the calculation. -A subgraph is built for each dependent variable and the selected set -of independent variables. - -$head matrix_out$$ -This argument has prototype -$codei% - sparse_rcv<%SizeVector%, %BaseVector%>& %matrix_out% -%$$ -This input value of $icode matrix_out$$ does not matter. -Upon return $icode matrix_out$$ is -$cref/sparse matrix/sparse_rcv/$$ representation of $latex F^{(1)} (x)$$. -The matrix has $latex m$$ rows, $latex n$$ columns. -If $icode%select_domain%[%j%]%$$ is true, -$icode%select_range%[%i%]%$$ is true, and -$latex F_i (x)$$ depends on $latex x_j$$, -then the pair $latex (i, j)$$ is in $icode matrix_out$$. -For each $icode%k% = 0 , %...%, %matrix_out%.nnz()%$$, let -$codei% - %i% = %matrix_out%.row()[%k%] - %j% = %matrix_out%.col()[%k%] - %v% = %matrix_out%.val()[%k%] -%$$ -It follows that the partial of $latex F_i (x)$$ with respect to -$latex x_j$$ is equal to $latex v$$. - - -$head Example$$ -$children% - example/sparse/subgraph_jac_rev.cpp% - example/sparse/subgraph_hes2jac.cpp -%$$ -The files $cref subgraph_jac_rev.cpp$$ and $cref subgraph_hes2jac.cpp$$ -are examples and tests using $code subgraph_jac_rev$$. -They returns $code true$$ for success and $code false$$ for failure. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/*! -Subgraph 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. - -\tparam BaseVector -a simple vector class with elements of type Base. - -\param x -a vector of length n, the number of independent variables in f -(this ADFun object). - -\param subset -specifices the subset of the sparsity pattern where the Jacobian is evaluated. -subset.nr() == m, -subset.nc() == n. -*/ -template -template -void ADFun::subgraph_jac_rev( - const BaseVector& x , - sparse_rcv& subset ) -{ size_t m = Range(); - size_t n = Domain(); - // - CPPAD_ASSERT_KNOWN( - subset.nr() == m, - "subgraph_jac_rev: subset.nr() not equal range dimension for f" - ); - CPPAD_ASSERT_KNOWN( - subset.nc() == n, - "subgraph_jac_rev: subset.nc() not equal domain dimension for f" - ); - // - // point at which we are evaluating Jacobian - Forward(0, x); - // - // nnz and row, column, and row_major vectors for subset - size_t nnz = subset.nnz(); - const SizeVector& row( subset.row() ); - const SizeVector& col( subset.col() ); - SizeVector row_major = subset.row_major(); - // - // determine set of independent variabels - local::pod_vector select_domain(n); - for(size_t j = 0; j < n; j++) - select_domain[j] = false; - for(size_t k = 0; k < nnz; k++) - select_domain[ col[k] ] = true; - // - // initialize reverse mode computation on subgraphs - subgraph_reverse(select_domain); - // - // memory used to hold subgraph_reverse results - BaseVector dw; - SizeVector dw_col; - // - // initialize index in row_major - size_t k = 0; - Base zero(0); - while(k < nnz ) - { size_t q = 1; - size_t i_dep = row[ row_major[k] ]; - size_t i_ind = col[ row_major[k] ]; - size_t ell = i_dep; - subgraph_reverse(q, ell, dw_col, dw); - // - size_t c = 0; - while( i_dep == ell ) - { // row numbers match - // - // advance c to possible match with column i_ind - while( c < size_t( dw_col.size() ) && dw_col[c] < i_ind ) - ++c; - // - // check for match with i_ind - if( i_ind == dw_col[c] ) - subset.set( row_major[k], dw[i_ind] ); - else - subset.set( row_major[k], zero); - // - // advance to next (i_dep, i_ind) - ++k; - if( k == nnz ) - { i_dep = m; - i_ind = n; - } - else - { i_dep = row[ row_major[k] ]; - i_ind = col[ row_major[k] ]; - } - } - } - return; -} -template -template -void ADFun::subgraph_jac_rev( - const BoolVector& select_domain , - const BoolVector& select_range , - const BaseVector& x , - sparse_rcv& matrix_out ) -{ size_t m = Range(); - size_t n = Domain(); - // - // point at which we are evaluating Jacobian - Forward(0, x); - // - // nnz and row, column, and row_major vectors for subset - local::pod_vector row_out; - local::pod_vector col_out; - local::pod_vector_maybe val_out; - // - // initialize reverse mode computation on subgraphs - subgraph_reverse(select_domain); - // - // memory used to hold subgraph_reverse results - BaseVector dw; - SizeVector col; - // - // loop through selected independent variables - for(size_t i = 0; i < m; ++i) if( select_range[i] ) - { // compute Jacobian and sparsity for this dependent variable - size_t q = 1; - subgraph_reverse(q, i, col, dw); - CPPAD_ASSERT_UNKNOWN( size_t( dw.size() ) == n ); - // - // offset for this dependent variable - size_t index = row_out.size(); - CPPAD_ASSERT_UNKNOWN( col_out.size() == index ); - CPPAD_ASSERT_UNKNOWN( val_out.size() == index ); - // - // extend vectors to hold results for this dependent variable - size_t col_size = size_t( col.size() ); - row_out.extend( col_size ); - col_out.extend( col_size ); - val_out.extend( col_size ); - // - // store results for this dependent variable - for(size_t c = 0; c < col_size; ++c) - { row_out[index + c] = i; - col_out[index + c] = col[c]; - val_out[index + c] = dw[ col[c] ]; - } - } - // - // create sparsity pattern corresponding to row_out, col_out - size_t nr = m; - size_t nc = n; - size_t nnz = row_out.size(); - sparse_rc pattern(nr, nc, nnz); - for(size_t k = 0; k < nnz; ++k) - pattern.set(k, row_out[k], col_out[k]); - // - // create sparse matrix - sparse_rcv matrix(pattern); - for(size_t k = 0; k < nnz; ++k) - matrix.set(k, val_out[k]); - // - // return matrix - matrix_out = matrix; - // - return; -} -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/subgraph_reverse.hpp b/build-config/cppad/include/cppad/core/subgraph_reverse.hpp deleted file mode 100644 index 7286745a..00000000 --- a/build-config/cppad/include/cppad/core/subgraph_reverse.hpp +++ /dev/null @@ -1,494 +0,0 @@ -# ifndef CPPAD_CORE_SUBGRAPH_REVERSE_HPP -# define CPPAD_CORE_SUBGRAPH_REVERSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin subgraph_reverse$$ -$spell - resize - subgraph - Subgraphs - dw - Taylor - Bool - const -$$ - -$section Reverse Mode Using Subgraphs$$ - -$head Syntax$$ -$icode%f%.subgraph_reverse(%select_domain%) -%$$ -$icode%f%.subgraph_reverse(%q%, %ell%, %col%, %dw%) -%$$ -$icode%f%.clear_subgraph() -%$$ - -$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$$. -Reverse mode computes the derivative of the $cref Forward$$ mode -$cref/Taylor coefficients/glossary/Taylor Coefficient/$$ -with respect to the domain variable $latex x$$. - -$head Notation$$ -We use the reverse mode -$cref/notation/reverse_any/Notation/$$ with the following change: -the vector -$cref/w^(k)/reverse_any/Notation/w^(k)/$$ is defined -$latex \[ -w_i^{(k)} = \left\{ \begin{array}{ll} - 1 & {\rm if} \; k = q-1 \; \R{and} \; i = \ell - \\ - 0 & {\rm otherwise} -\end{array} \right. -\] $$ - -$head BaseVector$$ -The type $icode BaseVector$$ 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 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 select_domain$$ -The argument $icode select_domain$$ has prototype -$codei% - const %BoolVector%& %select_domain% -%$$ -It has size $latex n$$ and specifies which independent variables -to include in future $code subgraph_reverse$$ calculations. -If $icode%select_domain%[%j%]%$$ is false, -it is assumed that $latex u^{(k)}_j = 0$$ for $latex k > 0$$; i.e., -the $th j$$ component of the Taylor coefficient for $latex x$$, -with order greater that zero, are zero; see -$cref/u^(k)/reverse_any/Notation/u^(k)/$$. - -$head q$$ -The argument $icode q$$ has prototype -$codei% - size_t %q% -%$$ -and specifies the number of Taylor coefficient orders to be differentiated. - -$head ell$$ -The argument $icode ell$$ has prototype -$codei% - size_t %ell% -%$$ -and specifies the dependent variable index that we are computing -the derivatives for; i.e. $latex \ell$$. -This index can only be used once per, and after, a call that selects -the independent variables using $icode select_domain$$. - -$head col$$ -This argument $icode col$$ has prototype -$codei% - %SizeVector% %col% -%$$ -The input size and value of its elements do not matter. -The $icode%col%.resize%$$ member function is used to change its size -to the number the number of possible non-zero derivative components. -For each $icode c$$, -$codei% - %select_domain%[ %col%[%c%] ] == true - %col%[%c%+1] >= %col%[%c%] -%$$ -and the derivative with respect to the $th j$$ independent -variable is possibly non-zero where -$icode%j% = %col%[%c%]%$$. - -$head dw$$ -The argument $icode dw$$ has prototype -$codei% - %Vector% %dw% -%$$ -Its input size and value does not matter. -Upon return, -it is a vector with size $latex n \times q$$. -For $latex c = 0 , \ldots , %col%.size()-1$$, -and $latex k = 0, \ldots , q-1$$, -$latex \[ - dw[ j * q + k ] = W^{(1)} ( x )_{j,k} -\] $$ -is the derivative of the specified Taylor coefficients w.r.t the $th j$$ -independent variable where $icode%j% = %col%[%c%]%$$. -Note that this corresponds to the $cref reverse_any$$ convention when -$cref/w/reverse_any/w/$$ has size $icode%m% * %q%$$. - -$head clear_subgraph$$ -Calling this routine will free memory that holds -information between calls to subgraph calculations so that -it does not need to be recalculated. -(This memory is automatically freed when $icode f$$ is deleted.) -You cannot free this memory between calls that select the domain -and corresponding calls that compute reverse mode derivatives. -Some of this information is also used by $cref subgraph_sparsity$$. - -$head Example$$ -$children% - example/sparse/subgraph_reverse.cpp -%$$ -The file -$cref subgraph_reverse.cpp$$ -contains an example and test of this operation. - -$end -*/ -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file subgraph_reverse.hpp -Compute derivatvies using reverse mode and subgraphs. -*/ - -/// clear all subgraph information -template -void ADFun::clear_subgraph(void) -{ play_.clear_random(); - subgraph_info_.clear(); - subgraph_partial_.clear(); -} - -/*! -Initialize reverse mode derivative computation on subgraphs. - -\param select_domain -is a vector with size equal to the dimension of the domain for this function. -Only derivatives w.r.t. the components that are true will be computed. - -\par subgraph_info_.map_user_op() -If the input size of this vector is zero, -its value for this player (play_) is computed. - -\par subgraph_info.in_subgraph_ -This vector is initialized for a reverse mode computation on subgraphs. - -\par subgraph_info.select_domain() -This vector is set equal to the select_domain argument. - -\par subgraph_info.process_range() -This vector is initialized to have size Range() and its elements are false. -*/ - -template -template -void ADFun::subgraph_reverse( const BoolVector& select_domain ) -{ using local::pod_vector; - // - CPPAD_ASSERT_UNKNOWN( - dep_taddr_.size() == subgraph_info_.n_dep() - ); - CPPAD_ASSERT_UNKNOWN( - size_t( select_domain.size() ) == subgraph_info_.n_ind() - ); - - // map_user_op - if( subgraph_info_.map_user_op().size() == 0 ) - subgraph_info_.set_map_user_op(&play_); - else - { CPPAD_ASSERT_UNKNOWN( subgraph_info_.check_map_user_op(&play_) ); - } - CPPAD_ASSERT_UNKNOWN( - subgraph_info_.map_user_op().size() == play_.num_op_rec() - ); - - // initialize for reverse mode subgraph computations - switch( play_.address_type() ) - { - case local::play::unsigned_short_enum: - subgraph_info_.init_rev(&play_, select_domain); - break; - - case local::play::unsigned_int_enum: - subgraph_info_.init_rev(&play_, select_domain); - break; - - case local::play::size_t_enum: - subgraph_info_.init_rev(&play_, select_domain); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - CPPAD_ASSERT_UNKNOWN( - subgraph_info_.in_subgraph().size() == play_.num_op_rec() - ); - - return; -} - - -/*! -Use reverse mode to compute derivative of Taylor coefficients on a subgraph. - -The function -\f$ X : {\bf R} \times {\bf R}^{n \times q} \rightarrow {\bf R} \f$ -is defined by -\f[ -X(t , u) = \sum_{k=0}^{q-1} u^{(k)} t^k -\f] -The function -\f$ Y : {\bf R} \times {\bf R}^{n \times q} \rightarrow {\bf R} \f$ -is defined by -\f[ -Y(t , u) = F[ X(t, u) ] -\f] -The function -\f$ W : {\bf R}^{n \times q} \rightarrow {\bf R} \f$ is defined by -\f[ -W(u) = \sum_{k=0}^{q-1} ( w^{(k)} )^{\rm T} -\frac{1}{k !} \frac{ \partial^k } { t^k } Y(0, u) -\f] - -\param q -is the number of Taylor coefficient we are differentiating. - -\param ell -is the component of the range that is selected for differentiation. - -\param col -is the set of indices j = col[c] where the return value is defined. -If an index j is not in col, then either its derivative is zero, -or it is not in select_domain. - -\param dw -Is a vector \f$ dw \f$ such that -for j = col[c], -\f$ k = 0 , \ldots , q-1 \f$ -\f[ - dw[ j * q + k ] = W^{(1)} ( x )_{j,k} -\f] -where the matrix \f$ x \f$ is the value for \f$ u \f$ -that corresponding to the forward mode Taylor coefficients -for the independent variables as specified by previous calls to Forward. - -\par subgraph_info.process_range() -The element process_range[ell] is set to true by this operation. - -\par subgraph_info.in_subgraph_ -some of the elements of this vector are set to have value ell -(so it can not longer be used to determine the subgraph corresponding to -the ell-th dependent variable). -*/ -template -template -void ADFun::subgraph_reverse_helper( - size_t q , - size_t ell , - SizeVector& col , - BaseVector& dw ) -{ using local::pod_vector; - // used to identify the RecBase type in calls to sweeps - RecBase not_used_rec_base(0.0); - // - // get a random iterator for this player - play_.template setup_random(); - typename local::play::const_random_iterator random_itr = - play_.template get_random(); - - // check BaseVector is Simple Vector class with Base type elements - CheckSimpleVector(); - CPPAD_ASSERT_KNOWN( - q > 0, - "The second argument to Reverse must be greater than zero." - ); - CPPAD_ASSERT_KNOWN( - num_order_taylor_ >= q, - "Less than q Taylor coefficients are currently stored" - " in this ADFun object." - ); - CPPAD_ASSERT_KNOWN( - num_direction_taylor_ == 1, - "reverse mode for Forward(q, r, xq) with more than one direction" - "\n(r > 1) is not yet supported." - ); - CPPAD_ASSERT_KNOWN( - ell < dep_taddr_.size(), - "dependent variable index in to large for this function" - ); - CPPAD_ASSERT_KNOWN( - subgraph_info_.process_range()[ell] == false, - "This dependent variable index has already been processed\n" - "after the previous subgraph_reverse(select_domain)." - ); - - // subgraph of operators connected to dependent variable ell - pod_vector subgraph; - subgraph_info_.get_rev( - random_itr, dep_taddr_, addr_t(ell), subgraph - ); - - // Add all the atomic function call operators - // for calls that have first operator in the subgraph - local::subgraph::entire_call(random_itr, subgraph); - - // First add the BeginOp and EndOp to the subgraph and then sort it - // sort the subgraph - addr_t i_op_begin_op = 0; - addr_t i_op_end_op = addr_t( play_.num_op_rec() - 1); - subgraph.push_back(i_op_begin_op); - subgraph.push_back(i_op_end_op); - std::sort( subgraph.data(), subgraph.data() + subgraph.size() ); - CPPAD_ASSERT_UNKNOWN( subgraph[0] == i_op_begin_op ); - CPPAD_ASSERT_UNKNOWN( subgraph[subgraph.size()-1] == i_op_end_op ); - /* - // Use this printout for debugging - std::cout << "{ "; - for(size_t k = 0; k < subgraph.size(); k++) - { if( k > 0 ) - std::cout << ", "; - std::cout << subgraph[k]; - } - std::cout << "}\n"; - */ - - // initialize subgraph_partial_ matrix to zero on subgraph - Base zero(0); - subgraph_partial_.resize(num_var_tape_ * q); - for(size_t k = 0; k < subgraph.size(); ++k) - { - size_t i_op = size_t( subgraph[k] ); - local::OpCode op; - const addr_t* arg; - size_t i_var; - random_itr.op_info(i_op, op, arg, i_var); - if( NumRes(op) == 0 ) - { CPPAD_ASSERT_UNKNOWN( - op == local::AFunOp || - op == local::FunapOp || - op == local::FunavOp || - op == local::FunrpOp || - op == local::EndOp - ); - } - else if( op != local::BeginOp ) - { CPPAD_ASSERT_UNKNOWN( i_var >= NumRes(op) ); - size_t j_var = i_var + 1 - NumRes(op); - for(size_t i = j_var; i <= i_var; ++i) - { for(size_t j = 0; j < q; ++j) - subgraph_partial_[i * q + j] = zero; - } - } - } - - // set partial to one for component we are differentiating - subgraph_partial_[ dep_taddr_[ell] * q + q - 1] = Base(1); - - // evaluate the derivatives - CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() ); - CPPAD_ASSERT_UNKNOWN( load_op2var_.size() == play_.num_var_load_rec() ); - size_t n = Domain(); - // - local::play::const_subgraph_iterator subgraph_itr = - play_.end_subgraph(random_itr, &subgraph); - // - local::sweep::reverse( - q - 1, - n, - num_var_tape_, - &play_, - cap_order_taylor_, - taylor_.data(), - q, - subgraph_partial_.data(), - cskip_op_.data(), - load_op2var_, - subgraph_itr, - not_used_rec_base - ); - - // number of non-zero in return value - size_t col_size = 0; - size_t subgraph_index = 0; - CPPAD_ASSERT_UNKNOWN( subgraph[subgraph_index] == 0 ); - // Skip BeginOp - ++subgraph_index; - while( subgraph_index < subgraph.size() ) - { // check for InvOp - if( subgraph[subgraph_index] > addr_t(n) ) - subgraph_index = subgraph.size(); - else - { ++col_size; - ++subgraph_index; - } - } - col.resize(col_size); - - // return the derivative values - dw.resize(n * q); - for(size_t c = 0; c < col_size; ++c) - { size_t i_op = size_t( subgraph[c + 1] ); - CPPAD_ASSERT_UNKNOWN( play_.GetOp(i_op) == local::InvOp ); - // - size_t j = i_op - 1; - CPPAD_ASSERT_UNKNOWN( i_op == random_itr.var2op( ind_taddr_[j] ) ); - // - // return paritial for this independent variable - col[c] = j; - for(size_t k = 0; k < q; k++) - dw[j * q + k ] = subgraph_partial_[ind_taddr_[j] * q + k]; - } - // - CPPAD_ASSERT_KNOWN( ! ( hasnan(dw) && check_for_nan_ ) , - "f.subgraph_reverse(dw, q, ell): dw has a nan,\n" - "but none of f's Taylor coefficents are nan." - ); - // - return; -} -/*! -\copydoc subgraph_reverse_helper - -*/ -template -template -void ADFun::subgraph_reverse( - size_t q , - size_t ell , - SizeVector& col , - BaseVector& dw ) -{ using local::pod_vector; - // - // call proper version of helper function - switch( play_.address_type() ) - { - case local::play::unsigned_short_enum: - subgraph_reverse_helper(q, ell, col, dw); - break; - - case local::play::unsigned_int_enum: - subgraph_reverse_helper(q, ell, col, dw); - break; - - case local::play::size_t_enum: - subgraph_reverse_helper(q, ell, col, dw); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - // - return; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/subgraph_sparsity.hpp b/build-config/cppad/include/cppad/core/subgraph_sparsity.hpp deleted file mode 100644 index 40f7f038..00000000 --- a/build-config/cppad/include/cppad/core/subgraph_sparsity.hpp +++ /dev/null @@ -1,242 +0,0 @@ -# ifndef CPPAD_CORE_SUBGRAPH_SPARSITY_HPP -# define CPPAD_CORE_SUBGRAPH_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin subgraph_sparsity$$ -$spell - const - subgraph - subgraphs - rc - Jacobian - bool -$$ - -$section Subgraph Dependency Sparsity Patterns$$ - -$head Syntax$$ -$icode%f%.subgraph_sparsity( - %select_domain%, %select_range%, %transpose%, %pattern_out% -)%$$ - -$head See Also$$ -$cref/clear_subgraph/subgraph_reverse/clear_subgraph/$$. - -$head Notation$$ -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$$. - - -$head Method$$ -This routine uses a subgraph technique. To be specific, -for each dependent variable, -it creates a subgraph of the operation sequence -containing the variables that affect the dependent variable. -This avoids the overhead of performing set operations -that is inherent in other methods for computing sparsity patterns. - -$head Atomic Function$$ -The sparsity calculation for -$cref/atomic functions/atomic_two_afun/$$ in the $icode f$$ operation sequence -are not efficient. To be specific, each atomic function is treated as if -all of its outputs depend on all of its inputs. -This may be improved upon in the future; see the -$cref/subgraph sparsity/wish_list/Subgraph/Sparsity/$$ -wish list item. - -$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 select_domain$$ has prototype -$codei% - const %BoolVector%& %select_domain% -%$$ -It has size $latex n$$ and specifies which independent variables -to include in the calculation. -If not all the independent variables are included in the calculation, -a forward pass on the operation sequence is used to determine which -nodes may be in the subgraphs. - -$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 range -to include in the calculation. -A subgraph is built for each dependent variable -and the selected set of independent variables. - -$head transpose$$ -This argument has prototype -$codei% - bool %transpose% -%$$ -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}$$) defined below. - -$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 -$cref/dependency pattern/dependency.cpp/Dependency Pattern/$$ -for $latex F(x)$$. -The pattern has $latex m$$ rows, $latex n$$ columns. -If $icode%select_domain%[%j%]%$$ is true, -$icode%select_range%[%i%]%$$ is true, and -$latex F_i (x)$$ depends on $latex x_j$$, -then the pair $latex (i, j)$$ is in $icode pattern_out$$. -Not that this is also a sparsity pattern for the Jacobian -$latex \[ - J(x) = R F^{(1)} (x) D -\] $$ -where $latex D$$ ($latex R$$) is the diagonal matrix corresponding -to $icode select_domain$$ ($icode select_range$$). - -$head Example$$ -$children% - example/sparse/subgraph_sparsity.cpp -%$$ -The file -$cref subgraph_sparsity.cpp$$ -contains an example and test of this operation. - -$end ------------------------------------------------------------------------------ -*/ -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/*! -Subgraph 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 select_domain -sparsity pattern for the diagonal of the square matrix D. - -\param select_range -sparsity pattern for the diagnoal of the square matrix R - -\param transpose -If true, the return is a dependency sparsity pattern for -\f$ D F^{(1)} (x)^T R \f$ - -\param pattern_out -The input value does not matter. -The return value is a dependency sparsity pattern for \f$ R F^{(1)} (x) D \f$ -where F is the function corresponding to the operation sequence -and x is any argument value. -is the sparsity pattern transposed. -*/ -template -template -void ADFun::subgraph_sparsity( - const BoolVector& select_domain , - const BoolVector& select_range , - bool transpose , - sparse_rc& pattern_out ) -{ - // compute the sparsity pattern in row, col - local::pod_vector row; - local::pod_vector col; - - // create the optimized recording - switch( play_.address_type() ) - { - case local::play::unsigned_short_enum: - local::subgraph::subgraph_sparsity( - &play_, - subgraph_info_, - dep_taddr_, - select_domain, - select_range, - row, - col - ); - break; - - case local::play::unsigned_int_enum: - local::subgraph::subgraph_sparsity( - &play_, - subgraph_info_, - dep_taddr_, - select_domain, - select_range, - row, - col - ); - break; - - case local::play::size_t_enum: - local::subgraph::subgraph_sparsity( - &play_, - subgraph_info_, - dep_taddr_, - select_domain, - select_range, - row, - col - ); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - - CPPAD_ASSERT_UNKNOWN( row.size() == col.size() ); - - // return the sparsity pattern - size_t nr = dep_taddr_.size(); - size_t nc = ind_taddr_.size(); - size_t nnz = row.size(); - if( transpose ) - { pattern_out.resize(nc, nr, nnz); - for(size_t k = 0; k < nnz; k++) - pattern_out.set(k, col[k], row[k]); - } - else - { pattern_out.resize(nr, nc, nnz); - for(size_t k = 0; k < nnz; k++) - pattern_out.set(k, row[k], col[k]); - } - return; -} -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/tape_link.hpp b/build-config/cppad/include/cppad/core/tape_link.hpp deleted file mode 100644 index cbe865d6..00000000 --- a/build-config/cppad/include/cppad/core/tape_link.hpp +++ /dev/null @@ -1,265 +0,0 @@ -# ifndef CPPAD_CORE_TAPE_LINK_HPP -# define CPPAD_CORE_TAPE_LINK_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file tape_link.hpp -Routines that Link AD and local::ADTape Objects. - -The routines that connect the AD class to the corresponding tapes -(one for each thread). -*/ - -/*! -Pointer to the tape identifier for this AD class and the specific thread. - -\tparam Base -is the base type for this AD class. - -\param thread -is the thread number. The following condition must hold -\code -(! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num() -\endcode - -\return -is a pointer to the tape identifier for this thread and AD class. -*/ -template -tape_id_t* AD::tape_id_ptr(size_t thread) -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - static tape_id_t tape_id_table[CPPAD_MAX_NUM_THREADS]; - CPPAD_ASSERT_UNKNOWN( - (! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num() - ); - return tape_id_table + thread; -} - -/*! -Handle for the tape for this AD class and the specific thread. - -\tparam Base -is the base type for this AD class. - - -\param thread -is the thread number; i.e., -\code -(! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num() -\endcode - -\return -is a handle for the tape for this AD class and the specified thread. -*/ -template -local::ADTape** AD::tape_handle(size_t thread) -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - static local::ADTape* tape_table[CPPAD_MAX_NUM_THREADS]; - CPPAD_ASSERT_UNKNOWN( - (! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num() - ); - return tape_table + thread; -} - -/*! -Pointer for the tape for this AD class and the current thread. - -\code -thread == thread_alloc::thread_num() -\endcode - -\tparam Base -is the base type corresponding to AD operations. - -\return -is a pointer to the tape that is currently recording AD operations -for the current thread. -If this value is nullptr, there is no tape currently -recording AD operations for this thread. -*/ -template -local::ADTape* AD::tape_ptr(void) -{ size_t thread = thread_alloc::thread_num(); - return *tape_handle(thread); -} - -/*! -Pointer for the tape for this AD class and the specified tape -identifier. - -\tparam Base -is the base type corresponding to AD operations. - -\param tape_id -is the identifier for the tape that is currently recording -AD operations for the current thread. -It must hold that the current thread is -\code - thread = size_t( tape_id % CPPAD_MAX_NUM_THREADS ) -\endcode -and that there is a tape recording AD operations -for this thread. -If this is not the currently executing thread, -a variable from a different thread is being recorded on the -tape for this thread which is a user error. - -\return -is a pointer to the tape that is currently recording AD operations -for the current thread (and it is not nullptr). - -\par Restrictions -This routine should only be called if there is a tape recording operaitons -for the specified thread. -*/ -template -local::ADTape* AD::tape_ptr(tape_id_t tape_id) -{ size_t thread = size_t( tape_id % CPPAD_MAX_NUM_THREADS ); - CPPAD_ASSERT_KNOWN( - thread == thread_alloc::thread_num(), - "Attempt to use an AD variable with two different threads." - ); - CPPAD_ASSERT_UNKNOWN( tape_id == *tape_id_ptr(thread) ); - CPPAD_ASSERT_UNKNOWN( *tape_handle(thread) != nullptr ); - return *tape_handle(thread); -} - -/*! -Create and delete tapes that record AD operations for current thread. - -\par thread -the current thread is given by -\code -thread = thread_alloc::thread_num() -\endcode - -\tparam Base -is the base type corresponding to AD operations. - -\param job -This argument determines if we are creating a new tape, or deleting an -old one. - -- new_tape_manage : -Creates and a new tape. -It is assumed that there is no tape recording AD operations -for this thread when tape_manage is called. - -- delete_tape_manage : -It is assumed that there is a tape recording AD operations -for this thread when tape_manage is called. -The value of *tape_id_ptr(thread) will be advanced by - CPPAD_MAX_NUM_THREADS. - - -\return -- job == new_tape_manage: a pointer to the new tape is returned. -- job == delete_tape_manage: the value nullptr is returned. -*/ -template -local::ADTape* AD::tape_manage(tape_manage_enum job) -{ - CPPAD_ASSERT_UNKNOWN( - job == new_tape_manage || job == delete_tape_manage - ); - // thread, tape_id, and tape for this call - size_t thread = thread_alloc::thread_num(); - tape_id_t* tape_id_p = tape_id_ptr(thread); - local::ADTape** tape_h = tape_handle(thread); - - - // ----------------------------------------------------------------------- - // new_tape_manage - if( job == new_tape_manage ) - { - // tape for this thread must be null at the start - CPPAD_ASSERT_UNKNOWN( *tape_h == nullptr ); - - // allocate separate memroy to avoid false sharing - *tape_h = new local::ADTape(); - - // if tape id is zero, initialize it so that - // thread == tape id % CPPAD_MAX_NUM_THREADS - if( *tape_id_p == 0 ) - { size_t new_tape_id = thread + CPPAD_MAX_NUM_THREADS; - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= new_tape_id, - "cppad_tape_id_type maximum value has been exceeded" - ); - *tape_id_p = static_cast( new_tape_id ); - } - // make sure tape_id value is valid for this thread - CPPAD_ASSERT_UNKNOWN( - size_t( *tape_id_p % CPPAD_MAX_NUM_THREADS ) == thread - ); - // set the tape_id for this tape - (*tape_h)->id_ = *tape_id_p; - } - // ----------------------------------------------------------------------- - // delete_tape_manage - if( job == delete_tape_manage ) - { // delete this tape - CPPAD_ASSERT_UNKNOWN( *tape_h != nullptr ); - delete *tape_h; - *tape_h = nullptr; - // - // advance tape_id so that all AD variables become parameters - CPPAD_ASSERT_KNOWN( - std::numeric_limits::max() - - CPPAD_MAX_NUM_THREADS > *tape_id_p, - "To many different tapes given the type used for " - "CPPAD_TAPE_ID_TYPE" - ); - *tape_id_p += CPPAD_MAX_NUM_THREADS; - } - // ----------------------------------------------------------------------- - return *tape_h; -} - -/*! -Get a pointer to tape that records AD operations for the current thread. - -\tparam Base -is the base type corresponding to AD operations. - -\par thread -The current thread must be given by -\code - thread = this->tape_id_ % CPPAD_MAX_NUM_THREADS -\endcode - -\return -is a pointer to the tape that is currently recording AD operations -for the current thread. -This value must not be nullptr; i.e., there must be a tape currently -recording AD operations for this thread. -*/ - -template -local::ADTape *AD::tape_this(void) const -{ - size_t thread = size_t( tape_id_ % CPPAD_MAX_NUM_THREADS ); - CPPAD_ASSERT_UNKNOWN( tape_id_ == *tape_id_ptr(thread) ); - CPPAD_ASSERT_UNKNOWN( *tape_handle(thread) != nullptr ); - return *tape_handle(thread); -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/core/test_vector.hpp b/build-config/cppad/include/cppad/core/test_vector.hpp deleted file mode 100644 index 34182adc..00000000 --- a/build-config/cppad/include/cppad/core/test_vector.hpp +++ /dev/null @@ -1,135 +0,0 @@ -# ifndef CPPAD_CORE_TEST_VECTOR_HPP -# define CPPAD_CORE_TEST_VECTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin test_vector$$ -$spell - autotools - ifdef - undef - Microsofts - CppADvector - hpp - std - endif - ublas - Dir - valarray - stdvector -$$ - - -$section Choosing The Vector Testing Template Class$$ - -$head Deprecated 2012-07-03$$ -The $code CPPAD_TEST_VECTOR$$ macro has been deprecated, -use $cref/CPPAD_TESTVECTOR/testvector/$$ instead. - -$head Syntax$$ -$codei%CPPAD_TEST_VECTOR<%Scalar%> -%$$ - -$head Introduction$$ -Many of the CppAD $cref/examples/example/$$ and tests use -the $code CPPAD_TEST_VECTOR$$ template class to pass information. -The default definition for this template class is -$cref/CppAD::vector/CppAD_vector/$$. - -$head MS Windows$$ -The include path for boost is not defined in the Windows project files. -If we are using Microsofts compiler, the following code overrides the setting -of $code CPPAD_BOOSTVECTOR$$: -$srccode%cpp% */ -// The next 7 lines are C++ source code. -# ifdef _MSC_VER -# if CPPAD_BOOSTVECTOR -# undef CPPAD_BOOSTVECTOR -# define CPPAD_BOOSTVECTOR 0 -# undef CPPAD_CPPADVECTOR -# define CPPAD_CPPADVECTOR 1 -# endif -# endif -/* %$$ - -$head CppAD::vector$$ -By default $code CPPAD_CPPADVECTOR$$ is true -and $code CPPAD_TEST_VECTOR$$ is defined by the following source code -$srccode%cpp% */ -// The next 3 line are C++ source code. -# if CPPAD_CPPADVECTOR -# define CPPAD_TEST_VECTOR CppAD::vector -# endif -/* %$$ -If you specify $code --with-eigenvector$$ on the -$cref/configure/autotools/Configure/$$ command line, -$code CPPAD_EIGENVECTOR$$ is true. -This vector type cannot be supported by $code CPPAD_TEST_VECTOR$$ -(use $cref/CPPAD_TESTVECTOR/testvector/$$ for this support) -so $code CppAD::vector$$ is used in this case -$srccode%cpp% */ -// The next 3 line are C++ source code. -# if CPPAD_EIGENVECTOR -# define CPPAD_TEST_VECTOR CppAD::vector -# endif -/* %$$ - - -$head std::vector$$ -If you specify $code --with-stdvector$$ on the -$cref/configure/autotools/Configure/$$ -command line during CppAD installation, -$code CPPAD_STDVECTOR$$ is true -and $code CPPAD_TEST_VECTOR$$ is defined by the following source code -$srccode%cpp% */ -// The next 4 lines are C++ source code. -# if CPPAD_STDVECTOR -# include -# define CPPAD_TEST_VECTOR std::vector -# endif -/* %$$ -In this case CppAD will use $code std::vector$$ for its examples and tests. -Use of $code CppAD::vector$$, $code std::vector$$, -and $code std::valarray$$ with CppAD is always tested to some degree. -Specifying $code --with-stdvector$$ will increase the amount of -$code std::vector$$ testing. - -$head boost::numeric::ublas::vector$$ -If you specify a value for $icode boost_dir$$ on the configure -command line during CppAD installation, -$code CPPAD_BOOSTVECTOR$$ is true -and $code CPPAD_TEST_VECTOR$$ is defined by the following source code -$srccode%cpp% */ -// The next 4 lines are C++ source code. -# if CPPAD_BOOSTVECTOR -# include -# define CPPAD_TEST_VECTOR boost::numeric::ublas::vector -# endif -/* %$$ -In this case CppAD will use Ublas vectors for its examples and tests. -Use of $code CppAD::vector$$, $code std::vector$$, -and $code std::valarray$$ with CppAD is always tested to some degree. -Specifying $icode boost_dir$$ will increase the amount of -Ublas vector testing. - -$head CppADvector Deprecated 2007-07-28$$ -The preprocessor symbol $code CppADvector$$ is defined to -have the same value as $code CPPAD_TEST_VECTOR$$ but its use is deprecated: -$srccode%cpp% */ -# define CppADvector CPPAD_TEST_VECTOR -/* %$$ -$end ------------------------------------------------------------------------- -*/ - -# endif diff --git a/build-config/cppad/include/cppad/core/testvector.hpp b/build-config/cppad/include/cppad/core/testvector.hpp deleted file mode 100644 index ec8bd00c..00000000 --- a/build-config/cppad/include/cppad/core/testvector.hpp +++ /dev/null @@ -1,116 +0,0 @@ -# ifndef CPPAD_CORE_TESTVECTOR_HPP -# define CPPAD_CORE_TESTVECTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin testvector$$ -$spell - CppAD - cmake - testvector - cppad - Eigen - ifdef - hpp - std - endif - ublas -$$ - - -$section Using The CppAD Test Vector Template Class$$ - -$head Syntax$$ -$codei%CPPAD_TESTVECTOR(%Scalar%) -%$$ - -$head Choice$$ -The user can choose, during the install procedure, -which template class to use in the examples and tests; see below. -This shows that any -$cref/simple vector/SimpleVector/$$ class can be used in place of -$codei% - CPPAD_TESTVECTOR(%Type%) -%$$ -When writing their own code, -users can choose a specific simple vector they prefer; for example, -$codei% - CppAD::vector<%Type%> -%$$ - - -$head CppAD::vector$$ -If in the $cref/cmake command/cmake/CMake Command/$$ -you specify $cref cppad_testvector$$ to be $code cppad$$, -$code CPPAD_CPPADVECTOR$$ will be true. -In this case, -$code CPPAD_TESTVECTOR$$ is defined by the following source code: -$srccode%cpp% */ -# if CPPAD_CPPADVECTOR -# define CPPAD_TESTVECTOR(Scalar) CppAD::vector< Scalar > -# endif -/* %$$ -In this case CppAD will use its own vector for -many of its examples and tests. - -$head std::vector$$ -If in the cmake command -you specify $icode cppad_testvector$$ to be $code std$$, -$code CPPAD_STDVECTOR$$ will be true. -In this case, -$code CPPAD_TESTVECTOR$$ is defined by the following source code: -$srccode%cpp% */ -# if CPPAD_STDVECTOR -# include -# define CPPAD_TESTVECTOR(Scalar) std::vector< Scalar > -# endif -/* %$$ -In this case CppAD will use standard vector for -many of its examples and tests. - -$head boost::numeric::ublas::vector$$ -If in the cmake command -you specify $icode cppad_testvector$$ to be $code boost$$, -$code CPPAD_BOOSTVECTOR$$ will be true. -In this case, -$code CPPAD_TESTVECTOR$$ is defined by the following source code: -$srccode%cpp% */ -# if CPPAD_BOOSTVECTOR -# include -# define CPPAD_TESTVECTOR(Scalar) boost::numeric::ublas::vector< Scalar > -# endif -/* %$$ -In this case CppAD will use this boost vector for -many of its examples and tests. - -$head CppAD::eigen_vector$$ -If in the cmake command -you specify $icode cppad_testvector$$ to be $code eigen$$, -$code CPPAD_EIGENVECTOR$$ will be true. -In this case, -$code CPPAD_TESTVECTOR$$ is defined by the following source code: -$srccode%cpp% */ -# if CPPAD_EIGENVECTOR -# include -# define CPPAD_TESTVECTOR(Scalar) CppAD::eigen_vector< Scalar > -# endif -/* %$$ -see $cref/eigen_vector/cppad_eigen.hpp/eigen_vector/$$. -In this case CppAD will use the Eigen vector -for many of its examples and tests. - -$end ------------------------------------------------------------------------- -*/ - -# endif diff --git a/build-config/cppad/include/cppad/core/unary_minus.hpp b/build-config/cppad/include/cppad/core/unary_minus.hpp deleted file mode 100644 index 5fa689d0..00000000 --- a/build-config/cppad/include/cppad/core/unary_minus.hpp +++ /dev/null @@ -1,100 +0,0 @@ -# ifndef CPPAD_CORE_UNARY_MINUS_HPP -# define CPPAD_CORE_UNARY_MINUS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin UnaryMinus$$ -$spell - Vec - const - inline -$$ - - -$section AD Unary Minus Operator$$ - -$head Syntax$$ - -$icode%y% = - %x%$$ - - -$head Purpose$$ -Computes the negative of $icode x$$. - -$head Base$$ -The operation in the syntax above must be supported for the case where -the operand is a $code const$$ $icode Base$$ object. - -$head x$$ -The operand $icode x$$ has one of the following prototypes -$codei% - const AD<%Base%> &%x% - const VecAD<%Base%>::reference &%x% -%$$ - -$head y$$ -The result $icode y$$ has type -$codei% - AD<%Base%> %y% -%$$ -It is equal to the negative of the operand $icode x$$. - -$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 Derivative$$ -If $latex f$$ is a -$cref/Base function/glossary/Base Function/$$, -$latex \[ - \D{[ - f(x) ]}{x} = - \D{f(x)}{x} -\] $$ - -$head Example$$ -$children% - example/general/unary_minus.cpp -%$$ -The file -$cref unary_minus.cpp$$ -contains an example and test of this operation. - -$end -------------------------------------------------------------------------------- -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -// Broken g++ compiler inhibits declaring unary minus a member or friend -template -AD AD::operator - (void) const -{ // 2DO: make a more efficient by adding unary minus to op_code.h (some day) - // - AD result(0); - result -= *this; - return result; -} - - -template -AD operator - (const VecAD_reference &right) -{ return - right.ADBase(); } - -} -// END CppAD namespace - - -# endif diff --git a/build-config/cppad/include/cppad/core/unary_plus.hpp b/build-config/cppad/include/cppad/core/unary_plus.hpp deleted file mode 100644 index 2dfb47cd..00000000 --- a/build-config/cppad/include/cppad/core/unary_plus.hpp +++ /dev/null @@ -1,97 +0,0 @@ -# ifndef CPPAD_CORE_UNARY_PLUS_HPP -# define CPPAD_CORE_UNARY_PLUS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin UnaryPlus$$ -$spell - Vec - const - inline -$$ - - -$section AD Unary Plus Operator$$ - -$head Syntax$$ - -$icode%y% = + %x%$$ - - -$head Purpose$$ -Performs the unary plus operation -(the result $icode y$$ is equal to the operand $icode x$$). - - -$head x$$ -The operand $icode x$$ has one of the following prototypes -$codei% - const AD<%Base%> &%x% - const VecAD<%Base%>::reference &%x% -%$$ - -$head y$$ -The result $icode y$$ has type -$codei% - AD<%Base%> %y% -%$$ -It is equal to the operand $icode x$$. - -$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 Derivative$$ -If $latex f$$ is a -$cref/Base function/glossary/Base Function/$$, -$latex \[ - \D{[ + f(x) ]}{x} = \D{f(x)}{x} -\] $$ - - - -$head Example$$ -$children% - example/general/unary_plus.cpp -%$$ -The file -$cref unary_plus.cpp$$ -contains an example and test of this operation. - -$end -------------------------------------------------------------------------------- -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -AD AD::operator + (void) const -{ AD result(*this); - - return result; -} - - -template -AD operator + (const VecAD_reference &right) -{ return right.ADBase(); } - -} -// END CppAD namespace - - -# endif diff --git a/build-config/cppad/include/cppad/core/undef.hpp b/build-config/cppad/include/cppad/core/undef.hpp deleted file mode 100644 index f7f8f276..00000000 --- a/build-config/cppad/include/cppad/core/undef.hpp +++ /dev/null @@ -1,100 +0,0 @@ -# ifndef CPPAD_CORE_UNDEF_HPP -# define CPPAD_CORE_UNDEF_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- -Preprecessor definitions that presist after cppad/cppad.hpp is included. -These are part of the user API with some exceptions that are used -by the CppAD examples and tests. - -# undef CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL used by CPPAD_USER_ATOMIC -# undef CPPAD_ASSERT_KNOWN used by cppad_ipopt -# undef CPPAD_ASSERT_UNKNOWN used by cppad_ipopt -# undef CPPAD_HASH_TABLE_SIZE used by test_more/optimize.cpp -# undef EIGEN_MATRIXBASE_PLUGIN example use of Eigen with CppAD -# undef CPPAD_HAS_COLPACK used by speed/cppad/sparse_*.cpp - -# undef CPPAD_BOOL_BINARY in user api -# undef CPPAD_BOOL_UNARY in user api -# undef CPPAD_DEBUG_AND_RELEASE in user api -# undef CPPAD_DISCRETE_FUNCTION in user api -# undef CPPAD_EIGENVECTOR in user api -# undef CPPAD_MAX_NUM_THREADS in user api -# undef CPPAD_NUMERIC_LIMITS in user api -# undef CPPAD_NULL in user api -# undef CPPAD_PACKAGE_STRING in user api -# undef CPPAD_STANDARD_MATH_UNARY in user api -# undef CPPAD_TAPE_ADDR_TYPE in user api -# undef CPPAD_TAPE_ID_TYPE in user api -# undef CPPAD_TESTVECTOR in user api -# undef CPPAD_TO_STRING in user api -# undef CPPAD_USE_CPLUSPLUS_2011 in user api - -# undef CPPAD_TRACK_COUNT in deprecated api -# undef CPPAD_TRACK_DEL_VEC in deprecated api -# undef CPPAD_TRACK_EXTEND in deprecated api -# undef CPPAD_TRACK_NEW_VEC in deprecated api -# undef CPPAD_USER_ATOMIC in deprecated api - -# undef CPPAD_TEST_VECTOR deprecated verssion of CPPAD_TESTVECTOR -# undef CppADCreateBinaryBool deprecated version of CPPAD_BOOL_BINARY -# undef CppADCreateDiscrete deprecated version of CPPAD_DISCRETE_FUNCTION -# undef CppADCreateUnaryBool deprecated version of CPPAD_BOOL_UNARY -# undef CppADTrackCount deprecated version of CPPAD_TRACK_COUNT -# undef CppADTrackDelVec deprecated version of CPPAD_TRACK_DEL_VEC -# undef CppADTrackExtend deprecated version of CPPAD_TRACK_EXTEND -# undef CppADTrackNewVec deprecated version of CPPAD_TRACK_NEW_VEC -# undef CppADvector deprecated version of CPPAD_TEST_VECTOR - -// for conditional testing when implicit conversion is not present -# undef CPPAD_DEPRECATED ------------------------------------------------------------------------------ -*/ -// Preprecessor definitions that do not presist. None of these are in the -// user API. -# undef CPPAD_ASSERT_NARG_NRES -# undef CPPAD_AZMUL -# undef CPPAD_BOOSTVECTOR -# undef CPPAD_COMPILER_HAS_CONVERSION_WARN -# undef CPPAD_COND_EXP -# undef CPPAD_COND_EXP_BASE_REL -# undef CPPAD_COND_EXP_REL -# undef CPPAD_CPPADVECTOR -# undef CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR -# undef CPPAD_FOLD_ASSIGNMENT_OPERATOR -# undef CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR -# undef CPPAD_HAS_ADOLC -# undef CPPAD_HAS_EIGEN -# undef CPPAD_HAS_GETTIMEOFDAY -# undef CPPAD_HAS_IPOPT -# undef CPPAD_HAS_MKSTEMP -# undef CPPAD_HAS_TMPNAM_S -# undef CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -# undef CPPAD_LIB_EXPORT -# undef CPPAD_MAX_NUM_CAPACITY -# undef CPPAD_MIN_DOUBLE_CAPACITY -# undef CPPAD_NDEBUG_NOEXCEPT -# undef CPPAD_NOEXCEPT -# undef CPPAD_STANDARD_MATH_UNARY_AD -# undef CPPAD_STDVECTOR -# undef CPPAD_TRACE_CAPACITY -# undef CPPAD_TRACE_THREAD -# undef CPPAD_TRACK_DEBUG -# undef CPPAD_USER_MACRO -# undef CPPAD_USER_MACRO_ONE -# undef CPPAD_USER_MACRO_TWO -# undef CPPAD_VEC_AD_COMP_ASSIGN -# undef CPPAD_VEC_ENUM_TYPE - -# endif diff --git a/build-config/cppad/include/cppad/core/user_ad.hpp b/build-config/cppad/include/cppad/core/user_ad.hpp deleted file mode 100644 index da41b5c2..00000000 --- a/build-config/cppad/include/cppad/core/user_ad.hpp +++ /dev/null @@ -1,71 +0,0 @@ -# ifndef CPPAD_CORE_USER_AD_HPP -# define CPPAD_CORE_USER_AD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- - -$begin AD$$ -$spell - std - bool - cos - Cpp -$$ - -$section AD Objects$$ - - -$head Purpose$$ -The sections listed below describe the operations -that are available to $cref/AD of Base/glossary/AD of Base/$$ objects. -These objects are used to $cref/tape/glossary/Tape/$$ -an AD of $icode Base$$ -$cref/operation sequence/glossary/Operation/Sequence/$$. -This operation sequence can -be transferred to an $cref ADFun$$ object where it -can be used to evaluate the corresponding -function and derivative values. - -$head Base Type Requirements$$ -The $icode Base$$ requirements are provided by the CppAD package -for the following base types: -$code float$$, -$code double$$, -$code std::complex$$, -$code std::complex$$. -Otherwise, see $cref base_require$$. - - -$childtable% - include/cppad/core/ad_ctor.hpp% - include/cppad/core/ad_assign.hpp% - include/cppad/core/convert.hpp% - include/cppad/core/ad_valued.hpp% - include/cppad/core/bool_valued.hpp% - include/cppad/core/vec_ad/user.omh% - include/cppad/base_require.hpp -%$$ - -$end ---------------------------------------------------------------------------- -*/ - -# include -# include -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/core/value.hpp b/build-config/cppad/include/cppad/core/value.hpp deleted file mode 100644 index 6da7d258..00000000 --- a/build-config/cppad/include/cppad/core/value.hpp +++ /dev/null @@ -1,95 +0,0 @@ -# ifndef CPPAD_CORE_VALUE_HPP -# define CPPAD_CORE_VALUE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin Value$$ -$spell - const -$$ - - - -$section Convert From an AD Type to its Base Type$$ - -$head Syntax$$ -$icode%b% = Value(%x%)%$$ - -$head See Also$$ -$cref var2par$$ - - -$head Purpose$$ -Converts from an AD type to the corresponding -$cref/base type/glossary/Base Type/$$. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const AD<%Base%> &%x% -%$$ - -$head b$$ -The return value $icode b$$ has prototype -$codei% - %Base% %b% -%$$ - -$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 Restriction$$ -The argument $icode x$$ must not be a -$cref/variable/glossary/Variable/$$ or -$cref/dynamic/glossary/Parameter/Dynamic/$$ parameter -because its dependency information -would not be included in the $code Value$$ result $icode b$$. - -$head Example$$ -$children% - example/general/value.cpp -%$$ -The file -$cref value.cpp$$ -contains an example and test of this operation. - -$end -------------------------------------------------------------------------------- -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -Base Value(const AD &x) -{ Base result; - // - CPPAD_ASSERT_KNOWN( - ! ( Variable(x) | Dynamic(x) ) , - "Value: argument is a variable or dynamic parameter" - ); - // - result = x.value_; - return result; -} - -} -// END CppAD namespace - - -# endif diff --git a/build-config/cppad/include/cppad/core/var2par.hpp b/build-config/cppad/include/cppad/core/var2par.hpp deleted file mode 100644 index 83074f2c..00000000 --- a/build-config/cppad/include/cppad/core/var2par.hpp +++ /dev/null @@ -1,88 +0,0 @@ -# ifndef CPPAD_CORE_VAR2PAR_HPP -# define CPPAD_CORE_VAR2PAR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------------- - -$begin Var2Par$$ -$spell - var - const -$$ - - -$section Convert an AD Variable to a Parameter$$ - -$head Syntax$$ -$icode%y% = Var2Par(%x%)%$$ - -$head See Also$$ -$cref value$$ - -$head Purpose$$ -Returns a -$cref/parameter/glossary/Parameter/$$ $icode y$$ -with the same value as the -$cref/variable/glossary/Variable/$$ $icode x$$. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const AD<%Base%> &x -%$$ -The argument $icode x$$ may be a variable, parameter, or dynamic parameter. - - -$head y$$ -The result $icode y$$ has prototype -$codei% - AD<%Base%> &y -%$$ -The return value $icode y$$ will be a parameter. - - -$head Example$$ -$children% - example/general/var2par.cpp -%$$ -The file -$cref var2par.cpp$$ -contains an example and test of this operation. - -$end ------------------------------------------------------------------------------- -*/ - -// BEGIN CppAD namespace -namespace CppAD { - -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -AD Var2Par(const AD &x) -{ AD y(x.value_); - return y; -} - - -template -CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION -AD Var2Par(const VecAD_reference &x) -{ AD y(x.ADBase()); - y.id_ = 0; -} - - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/core/vec_ad/user.omh b/build-config/cppad/include/cppad/core/vec_ad/user.omh deleted file mode 100644 index 796f15dc..00000000 --- a/build-config/cppad/include/cppad/core/vec_ad/user.omh +++ /dev/null @@ -1,306 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin VecAD$$ -$spell - cppad.hpp - CondExpGt - grep - Ld - vp - Lu - wc - op - Ldp - Ldv - Taylor - VecAD - const - Cpp - ind -$$ - - -$section AD Vectors that Record Index Operations$$ - - -$head Syntax$$ -$codei%VecAD<%Base%> %vec%(%n%)%$$ -$pre -$$ -$icode%vec%.size()%$$ -$pre -$$ -$icode%base% = %vec%[%i%]%$$ -$pre -$$ -$icode%abase% = %vec%[%ind%] -%$$ -$icode%vec%[%ind%] = %right% -%$$ -$icode%left% = %vec%[%ind%] -%$$ - -$head Purpose$$ -If either $icode vec$$ or $icode ind$$ is a -$cref/variable/glossary/Variable/$$ or -$cref/dynamic parameter/glossary/Parameter/Dynamic/$$, -the indexing operation -$codei% - %vec%[%ind%] -%$$ -is recorded in the corresponding $codei%AD<%Base%>%$$ -$cref/operation sequence/glossary/Operation/Sequence/$$ and -included in the corresponding $cref ADFun$$ object $icode f$$. -Such an index can change each time -zero order $cref/f.Forward/Forward/$$ is used; i.e., -each time $icode f$$ is evaluated with new value for the -$cref/independent variables/glossary/Tape/Independent Variable/$$. -Note that the value of $icode%vec%[%ind%]%$$ -depends on the value of $icode ind$$ -in a discrete fashion and CppAD computes its partial derivative with -respect to $icode ind$$ as zero. - -$head Alternatives$$ -If only the values in $icode vec$$, -and not the indices $icode ind$$, -depend on the independent variables, -a $cref SimpleVector$$ with elements of type $codei%AD<%Base%>%$$ -would be more efficient than using $codei%VecAD<%Base%>%$$. -If only the indices, and not the values in the vector, -depend on the independent variables, -a $cref Discrete$$ functions would be a much more efficient. - -$head Efficiency$$ -If one uses $code VecAD$$ vector where one could use a simple vector, -the $cref sparsity_pattern$$ will be less efficient -because the dependence on different elements cannot be separated. -In addition, $code VecAD$$ objects that only depend on dynamic parameters -are treated as if they were variables making sparsity patterns -even less efficient (have more possibly non-zero values than necessary); -see $cref/VecAD vectors/wish_list/Dynamic Parameters/VecAD Vectors/$$ -under dynamic parameters in the wish list. - -$head VecAD::reference$$ -The expression $icode%vec%[%ind%]%$$ has prototype -$codei% - VecAD<%Base%>::reference %vec%[%ind%] -%$$ -which is like the $codei%AD<%Base%>%$$ type -with some notable exceptions: - -$subhead Exceptions$$ - -$list number$$ -This object cannot be used with the -$cref Value$$ function to compute the corresponding $icode Base$$ value. -In some cases, the syntax -$codei% - %vec%[%i%] -%$$ -can be used to obtain the corresponding $icode Base$$ value; see below. - -$lnext -This object cannot be used as the left hand side in a -with a $cref/compound assignment/compound_assign/$$; i.e., -$code +=$$, -$code -=$$, -$code *=$$, or -$code /=$$. -For example, the following syntax is not valid: -$codei% - %vec%[%ind%] += %z%; -%$$ -no matter what the types of $icode z$$. - -$lnext -Assignment to $codei%vec%[%ind%]%$$ returns a $code void$$. -For example, the following syntax is not valid: -$codei% - %z% = %vec%[%ind%] = %u%; -%$$ -no matter what the types of $icode z$$, and $icode u$$. - -$lnext -A $icode%vec%[%ind%]%$$ object cannot appear in a $cref CondExp$$; -For example, the following syntax is not valid: -$codei% - CondExpGt(%vec%[%ind%], %u%, %v%, %w%) -%$$ -no matter what the types of $icode u$$, $icode v$$, and $icode w$$. - -$lnext -A $icode%vec%[%ind%]%$$ object should not be used with the -$code Constant$$, $code Dynamic$$, $code Parameter$$, and $code Variable$$ -functions (see $cref con_dyn_var$$). -The entire vector $icode vec$$ should be used instead. - -$lnext -A $code VecAD$$ vector -cannot be passed to $code Independent$$ function. - -$lend - -$head Constructor$$ - -$subhead vec$$ -The syntax -$codei% - VecAD<%Base%> %vec%(%n%) -%$$ -creates an $code VecAD$$ object $icode vec$$ with -$icode n$$ elements. -The initial value of the elements of $icode vec$$ is unspecified. - -$subhead n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ - -$head size$$ -The syntax -$codei% - %vec%.size() -%$$ -returns the number of elements in the vector $icode vec$$; -i.e., the value of $icode n$$ when it was constructed. - -$head Base Indexing$$ -We refer to the syntax -$codei% - %base% = %vec%[%i%] -%$$ -as base indexing of a $code VecAD$$ object. -This indexing is only valid if the vector $icode vec$$ is a -$cref/constant/con_dyn_var/Constant/$$; i.e., -it does not depend on the independent variables. - -$subhead i$$ -The operand $icode i$$ has prototype -$codei% - size_t %i% -%$$ -and must be less than $icode n$$; i.e., less than -the number of elements in $icode vec$$. - -$subhead base$$ -The result $icode base$$ has prototype -$codei% - %Base%& %base% -%$$ -i.e., it is a reference to the $th i$$ element in the vector $icode vec$$. -It can be used to change the element value; -for example, -$codei% - %vec%[%i%] = %b% -%$$ -is valid where $icode b$$ is a $icode Base$$ object. -The reference $icode base$$ is no longer valid once the -$icode vec$$ changes in any way; i.e., has another assignment. - -$head AD Indexing$$ -We refer to the syntax -$codei% - %vec%[%ind%] -%$$ -as AD indexing of a $code VecAD$$ object. - -$subhead ind$$ -The argument $icode ind$$ has prototype -$codei% - const AD<%Base%>& %ind% -%$$ -The value of $icode ind$$ must be greater than or equal zero -and less than $icode n$$; i.e., less than -the number of elements in $icode vec$$. - -$subhead result$$ -The resulting expression has prototype -$codei% - VecAD<%Base%>::reference %vec%[%ind%] -%$$ -This objects operations are recorded as part of the $codei%AD<%Base%>%$$ -$cref/operation sequence/glossary/Operation/Sequence/$$. -It acts like a reference to the -element with index $codei%floor(%ind%)%$$ in the vector $icode vec$$; -($codei%floor(%ind%)%$$ is -the greatest integer less than or equal $icode ind$$). - -$subhead right$$ -Is the right hand side of the assignment statement -and specifies the new value for the corresponding element of $icode vec$$. -It has one of the following prototypes: -$codei% - int %% %right% - const %Base%& %right% - const AD<%Base%>& %right% - const VecAD_reverence<%Base%>& %right% -%$$ - -$subhead left$$ -Is the left hand side of the assignment statement -is the current value for the corresponding element of $icode vec$$. -It has the following prototype: -$codei% - const AD<%Base%>& %left% -%$$ - -$head Example$$ -$children% - example/general/vec_ad.cpp -%$$ -The file -$cref vec_ad.cpp$$ -contains an example and test using $code VecAD$$ vectors. - - -$head Speed and Memory$$ -The $cref VecAD$$ vector type is inefficient because every -time an element of a vector is accessed, a new CppAD -$cref/variable/glossary/Variable/$$ is created on the tape -using either the $code Ldp$$ or $code Ldv$$ operation -(unless all of the elements of the vector are -$cref/parameters/glossary/Parameter/$$). -The effect of this can be seen by executing the following steps: - -$list number$$ -In the file $code cppad/local/forward1sweep.h$$, -change the definition of $code CPPAD_FORWARD1SWEEP_TRACE$$ to -$codep - # define CPPAD_FORWARD1SWEEP_TRACE 1 -$$ -$lnext -In the $code Example$$ directory, execute the command -$codep - ./test_one.sh lu_vec_ad_ok.cpp lu_vec_ad.cpp -DNDEBUG > lu_vec_ad_ok.log -$$ -This will write a trace of all the forward tape operations, -for the test case $cref lu_vec_ad_ok.cpp$$, -to the file $code lu_vec_ad_ok.log$$. -$lnext -In the $code Example$$ directory execute the commands -$codep - grep "op=" lu_vec_ad_ok.log | wc -l - grep "op=Ld[vp]" lu_vec_ad_ok.log | wc -l - grep "op=St[vp][vp]" lu_vec_ad_ok.log | wc -l -$$ -The first command counts the number of operators in the tracing, -the second counts the number of VecAD load operations, -and the third counts the number of VecAD store operations. -(For CppAD version 05-11-20 these counts were 956, 348, and 118 -respectively.) -$lend - -$end ------------------------------------------------------------------------- -*/ diff --git a/build-config/cppad/include/cppad/core/vec_ad/vec_ad.hpp b/build-config/cppad/include/cppad/core/vec_ad/vec_ad.hpp deleted file mode 100644 index 29f1a065..00000000 --- a/build-config/cppad/include/cppad/core/vec_ad/vec_ad.hpp +++ /dev/null @@ -1,642 +0,0 @@ -# ifndef CPPAD_CORE_VEC_AD_VEC_AD_HPP -# define CPPAD_CORE_VEC_AD_VEC_AD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/* - ------------------------------------------------------------------------------ -$begin vec_ad_comp_assign$$ -$spell - Vec - op -$$ -$section VecAD: Prints Error Message If A Compound Assignment Is Used$$ - -$head Syntax$$ -$codei%CPPAD_VEC_AD_COMP_ASSIGN(%cop%) -%$$ -$icode%ref cop right -%$$ - -$head CPPAD_VEC_AD_COMP_ASSIGN$$ -This macro defines the compound assignment operator $icode cop$$ -for a VecAD reference element to be an error with an error message. - -$head cop$$ -Is one of the following computed assignment operators: -+= , -= , *= , /=. - -$head ref$$ -is the VecAD reference. - -$head right$$ -is the right hand side for the compound assignment. - -$head Source$$ -$srccode%hpp% */ -# define CPPAD_VEC_AD_COMP_ASSIGN(cop) \ -VecAD_reference& operator cop (const VecAD_reference &right) \ -{ CPPAD_ASSERT_KNOWN(false, \ - "Can't use VecAD::reference on left side of " #cop \ - ); \ - return *this; \ -} \ -VecAD_reference& operator cop (const AD &right) \ -{ CPPAD_ASSERT_KNOWN(false, \ - "Can't use VecAD::reference on left side of " #cop \ - ); \ - return *this; \ -} \ -VecAD_reference& operator cop (const Base &right) \ -{ CPPAD_ASSERT_KNOWN(false, \ - "Can't use VecAD::reference on left side of " #cop \ - ); \ - return *this; \ -} \ -VecAD_reference& operator cop (int right) \ -{ CPPAD_ASSERT_KNOWN(false, \ - "Can't use VecAD::reference on left side of " #cop \ - ); \ - return *this; \ -} -/* %$$ -$end ------------------------------------------------------------------------------- -$begin vec_ad_reference$$ -$spell - Vec - ind - const -$$ -$section VecAD Element Reference Class$$ - -$head Syntax$$ -$codei%VecAD_reverence %ref%(%vec%, %ind%) -%$$ -$icode%ref% = %right% -%$$ -$icode ref cop right -%$$ -$icode%element% = %ref%.ADBase() -%$$ - -$head vec_$$ -This private data is a reference to $icode vec$$ in the constructor. - -$head ind_$$ -This private data is a copy of $icode ind$$ in the constructor. - -$head Base$$ -Elements of this reference class act like an -$codei%AD<%Base%>%$$ object (in a restricted sense), -in addition they track (on the tape) the index $icode ind$$ they correspond to. - -$head vec$$ -is the vector containing the element being referenced and has prototype -$codei% - VecAD<%Base%> %vec% -%$$ - -$head ind$$ -is the index of the element being referenced and has prototype -$codei% - const AD<%Base%>& ind -%$$ -If $icode%ind%.tape_id_%$$ matches a current recording, -so does $icode%vec%.tape_id_%$$ and -the $cref/AD type/atomic_three/ad_type/$$ corresponding to $icode vec$$ -includes this indexing operation; i.e., it is greater than or equal -the AD type corresponding to $icode ind$$. - -$head right$$ -Is the right hand side of the assignment statement and has one -of the following prototypes: -$codei% - int %% %right% - const %Base%& %right% - const AD<%Base%>& %right% - const VecAD_reverence<%Base%>& %right% -%$$ - -$head cop$$ -Is one of the following computed assignment operators: -+= , -= , *= , /=. -All of these operations report an error. - -$head element$$ -Is a copy of the element corresponding to the reference $icode ref$$ -and has prototype: -$codei% - AD<%Base%> %element% -%$$ - -$end -*/ -template -class VecAD_reference { - friend bool Constant (const VecAD &vec); - friend bool Parameter (const VecAD &vec); - friend bool Dynamic (const VecAD &vec); - friend bool Variable (const VecAD &vec); - friend class VecAD; - friend class local::ADTape; - -private: - VecAD& vec_; // reverence to vector - AD ind_; // index for this element -public: - VecAD_reference(VecAD& vec, const AD& ind) - : vec_( vec ) , ind_(ind) - { } - - // assignment operators - void operator = (const VecAD_reference &right); - void operator = (const AD &right); - void operator = (const Base &right); - void operator = (int right); - - // compound assignments - CPPAD_VEC_AD_COMP_ASSIGN( += ) - CPPAD_VEC_AD_COMP_ASSIGN( -= ) - CPPAD_VEC_AD_COMP_ASSIGN( *= ) - CPPAD_VEC_AD_COMP_ASSIGN( /= ) - - - /// Conversion from VecAD_reference to AD. - /// puts the correspond vecad load instruction in the tape. - AD ADBase(void) const - { // start with default construtor (hence dynamic_ is false). - AD result; - - size_t i = static_cast( Integer(ind_) ); - CPPAD_ASSERT_UNKNOWN( i < vec_.length_ ); - - // AD value corresponding to this element - result.value_ = vec_.data_[i]; - CPPAD_ASSERT_UNKNOWN( Constant(result) ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return result; - - // tape_id cannot match the default value zero - CPPAD_ASSERT_UNKNOWN( tape->id_ > 0 ); - - // check if vector, index match tape_id - bool match_vec = vec_.tape_id_ == tape->id_; - bool match_ind = ind_.tape_id_ == tape->id_; - - // check if vector, index are dynamic parmaerters - CPPAD_ASSERT_UNKNOWN( vec_.ad_type_ != dynamic_enum); - bool dyn_ind = match_ind & (ind_.ad_type_ == dynamic_enum); - - // check if vector, index are variables - bool var_vec = match_vec & (vec_.ad_type_ == variable_enum); - bool var_ind = match_ind & (ind_.ad_type_ == variable_enum); - - // check if vector, index are constants - bool con_vec = ! var_vec; - bool con_ind = ! ( dyn_ind | var_ind); - if( con_vec & con_ind ) - return result; -# ifndef NDEBUG - if( match_vec & match_ind ) CPPAD_ASSERT_KNOWN( - vec_.tape_id_ == ind_.tape_id_ , - "VecAD: vector and index are dynamic parameters or variables " - "on different treads." - ); -# endif - // parameter or variable index corresponding to ind_ - addr_t ind_taddr = ind_.taddr_; - if( con_ind ) - ind_taddr = tape->Rec_.put_con_par(ind_.value_); - - // index corresponding to this element - CPPAD_ASSERT_UNKNOWN( var_vec ); - { CPPAD_ASSERT_UNKNOWN( vec_.offset_ > 0 ); - size_t load_op_index = tape->Rec_.num_var_load_rec(); - // - if( var_ind ) - { CPPAD_ASSERT_UNKNOWN( local::NumRes(local::LdvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::LdvOp) == 3 ); - - // put operand addresses in tape, ind_ is a variable - result.taddr_ = tape->Rec_.PutLoadOp(local::LdvOp); - tape->Rec_.PutArg( - (addr_t) vec_.offset_, ind_taddr, (addr_t) load_op_index - ); - - // change result to variable for this load - result.tape_id_ = tape->id_; - result.ad_type_ = variable_enum; - } - else - { CPPAD_ASSERT_UNKNOWN( local::NumRes(local::LdpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::LdpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( con_ind | dyn_ind ); - - - // put operand addresses in tape - tape->Rec_.PutArg( - (addr_t) vec_.offset_, ind_taddr, (addr_t) load_op_index - ); - // put operator in the tape, ind_ is a parameter - result.taddr_ = tape->Rec_.PutLoadOp(local::LdpOp); - - // change result to variable for this load - result.tape_id_ = tape->id_; - result.ad_type_ = variable_enum; - } - } - return result; - } -}; -// --------------------------------------------------------------------------- -/*! -$begin vec_ad_class$$ -$spell - Vec - ind - enum - taddr -$$ -$section VecAD Class Objects$$ - -$head Syntax$$ -$codei%VecAD %empty%, %vec%(%length%) -%$$ -$icode%length% = %vec%.size() -%$$ -$icode%b% = %vec%[%i%] -%$$ -$icode%ref% = %vec%[%ind%] -%$$ - -$head length$$ -is the size of the vector and has prototype -$codei% - size_t %length% -%$$ - -$head Private Members$$ -$srcthisfile% - 0%// BEGIN_VECAD_PRIVATE_DATA%// END_VECAD_PRIVATE_DATA%1 -%$$ - -$subhead length_$$ -is a copy of $icode length$$. - -$subhead data_$$ -This vector has size $icode length$$ and -contains the value of the elements of the vector. - -$subhead taddr_$$ -This vector has size $icode length$$. -If $code tape_id_$$ matches the current recording -and $code ad_type_$$ is $code dynamic_enum$$, -$codei%taddr[%i%]%$$ is the parameter index for the corresponding element. - -$subhead offset_$$ -If $icode tape_id_$$ is the current tape, -$icode offset_$$ is the index of the first element of this vector -in the combined vector that contains all the VecAD elements for this recording. -$icode%offset_%-1%$$ is the index of the size of this vector -in the combined vector. - -$subhead tape_id_$$ -is the tape currently associated with this vector. - -$subhead ad_type_$$ -is the $cref/ad_type/atomic_three/ad_type/$$ corresponding to this -vector. - -$head i$$ -is a $code size_t$$ value less than $icode length$$. -This form of indexing can only be used when $icode vec$$ is a -constant parameter; i.e., its operations are not being recorded. - -$head b$$ -is a reference to the $icode Base$$ value -for the $th i$$ element of the vector. - -$head ind$$ -is a $codei%AD<%Base%>%$$ value less than $icode length$$. -This form of indexing gets recorded and the value of the index -can change. - -$head ref$$ -is a reference to the $codei%AD<%Base%>%$$ value -for the $th x$$ element of the vector. -If the vector is a parameter and the index is a variable, -the vector is changed to be a variable. - -$end -*/ -template -class VecAD { - friend bool Constant (const VecAD &vec); - friend bool Parameter (const VecAD &vec); - friend bool Dynamic (const VecAD &vec); - friend bool Variable (const VecAD &vec); - friend class local::ADTape; - friend class VecAD_reference; - - friend std::ostream& operator << - (std::ostream &os, const VecAD &vec_); -private: -// BEGIN_VECAD_PRIVATE_DATA - const size_t length_; - local::pod_vector_maybe data_; - local::pod_vector taddr_; - tape_id_t tape_id_; - addr_t offset_; - ad_type_enum ad_type_; -// END_VECAD_PRIVATE_DATA -public: - // declare the user's view of this type here - typedef VecAD_reference reference; - - // default constructor - // initialize tape_id_ same as for default constructor; see default.hpp - VecAD(void) - : length_(0), tape_id_(0), offset_(0), ad_type_(constant_enum) - { CPPAD_ASSERT_UNKNOWN( Constant(*this) ); } - - // sizing constructor - // initialize tape_id_ same as for constants; see ad_copy.hpp - VecAD(size_t length) - : length_(length), tape_id_(0), offset_(0), ad_type_(constant_enum) - { if( length_ > 0 ) - { size_t i; - Base zero(0); - data_.extend(length_); - taddr_.extend(length_); - - // Initialize data to zero so all have same value. - // This uses less memory and avoids a valgrind error - // during TapeRec::PutPar - for(i = 0; i < length_; i++) - { data_[i] = zero; - taddr_[i] = 0; - } - } - CPPAD_ASSERT_UNKNOWN( Constant(*this) ); - } - - // destructor - ~VecAD(void) - { } - - // number of elements in the vector - size_t size(void) - { return length_; } - - // element access (not taped) - Base& operator[](size_t i) - { - CPPAD_ASSERT_KNOWN( - Constant(*this), - "VecAD: cannot use size_t indexing because this" - " VecAD vector is not a constant paraameter." - ); - CPPAD_ASSERT_KNOWN( - i < length_, - "VecAD: element index is >= vector length" - ); - - return data_[i]; - } - - // element access (taped) - VecAD_reference operator[](const AD &ind) - { - CPPAD_ASSERT_KNOWN( - 0 <= Integer(ind), - "VecAD: element index is less than zero" - ); - CPPAD_ASSERT_KNOWN( - static_cast( Integer(ind) ) < length_, - "VecAD: element index is >= vector length" - ); - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return VecAD_reference(*this, ind); - - // tape_id cannot match the defautl value zero - CPPAD_ASSERT_UNKNOWN( tape->id_ > 0 ); - - // check if vector, index match tape_id - bool match_vec = tape_id_ == tape->id_; - bool match_ind = ind.tape_id_ == tape->id_; - - // check if vector, index are dynamic parmaerters - CPPAD_ASSERT_UNKNOWN( ad_type_ != dynamic_enum ); - bool dyn_ind = match_ind & (ind.ad_type_ == dynamic_enum); - - // check if vector, index are variables - bool var_vec = match_vec & (ad_type_ == variable_enum); - bool var_ind = match_ind & (ind.ad_type_ == variable_enum); - - // check if vector, index are constants - bool con_vec = ! var_vec; - bool con_ind = ! ( dyn_ind | var_ind); - if( con_vec & con_ind ) - return VecAD_reference(*this, ind); -# ifndef NDEBUG - if( match_vec & match_ind ) CPPAD_ASSERT_KNOWN( - tape_id_ == ind.tape_id_ , - "VecAD: vector and index are dynamic parameters or variables " - "on different treads." - ); -# endif - if( con_vec ) - { // place a copy of vector in tape - for(size_t i = 0; i < length_; ++i) - taddr_[i] = tape->Rec_.put_con_par( data_[i] ); - offset_ = tape->Rec_.put_var_vecad(length_, taddr_); - - // Advance pointer by one so starts at first component of this - // vector; i.e., skip length at begining (so is always > 0) - offset_++; - - // tape_id corresponding to this vector - tape_id_ = ind.tape_id_; - - // VecAD objects go striaght from constants to variables; i.e., - // they never are dynamic parameters. - ad_type_ = variable_enum; - } - CPPAD_ASSERT_UNKNOWN( Variable(*this) ); - return VecAD_reference(*this, ind); - } - -}; -// --------------------------------------------------------------------------- -// ref = right -template -void VecAD_reference::operator=(const AD &right) -{ - // index in vector for this element - size_t index = static_cast( Integer(ind_) ); - CPPAD_ASSERT_UNKNOWN( index < vec_.length_ ); - - // Base part of assignment for this element - vec_.data_[index] = right.value_; - - // check if there is a recording in progress - local::ADTape* tape = AD::tape_ptr(); - if( tape == nullptr ) - return; - - // tape_id cannot match the defautl value zero - tape_id_t tape_id = tape->id_; - CPPAD_ASSERT_UNKNOWN( tape_id > 0 ); - - // check if vector, index, right match tape_id - bool match_vec = vec_.tape_id_ == tape_id; - bool match_ind = ind_.tape_id_ == tape_id; - bool match_right = right.tape_id_ == tape_id; - CPPAD_ASSERT_UNKNOWN( match_vec || ! match_ind ); - - // check if vector, index, right are dynamic parmaerters - CPPAD_ASSERT_UNKNOWN(vec_.ad_type_ != dynamic_enum); - bool dyn_ind = match_ind & (ind_.ad_type_ == dynamic_enum); - bool dyn_right = match_right & (right.ad_type_ == dynamic_enum); - - // check if vector, index, right are variables - bool var_vec = match_vec & (vec_.ad_type_ == variable_enum); - bool var_ind = match_ind & (ind_.ad_type_ == variable_enum); - bool var_right = match_right & (right.ad_type_ == variable_enum); - - // check if vector, index, right are constants - bool con_vec = ! var_vec; - bool con_ind = ! ( dyn_ind | var_ind); - bool con_right = ! ( dyn_right | var_right); - if( con_vec & con_right ) - return; - -# ifndef NDEBUG - if( match_ind ) - { CPPAD_ASSERT_UNKNOWN( ind_.tape_id_ == vec_.tape_id_ ); - CPPAD_ASSERT_UNKNOWN( ind_.ad_type_ <= vec_.ad_type_ ); - } - if( match_vec & match_right ) CPPAD_ASSERT_KNOWN( - vec_.tape_id_ == right.tape_id_ , - "VecAD: vector and element are dynamic parameters or variables " - "on different treads." - ); -# endif - - if( con_vec ) - { CPPAD_ASSERT_UNKNOWN( con_ind ); - - // place a copy of vector in tape - for(size_t i = 0; i < vec_.length_; ++i) - vec_.taddr_[i] = tape->Rec_.put_con_par( vec_.data_[i] ); - vec_.offset_ = tape->Rec_.put_var_vecad(vec_.length_, vec_.taddr_); - - // advance offset from size of vector to first element in vector - (vec_.offset_)++; - - // tape_id corresponding to this vector - vec_.tape_id_ = right.tape_id_; - - // VecAD objects go striaght from constants to variables; i.e., - // they never are dynamic parameters. - vec_.ad_type_ = variable_enum; - } - CPPAD_ASSERT_UNKNOWN( Variable(vec_) ); - CPPAD_ASSERT_UNKNOWN( vec_.offset_ > 0 ); - - // parameter or variable index for ind_ - addr_t ind_taddr = ind_.taddr_; - if( con_ind ) - ind_taddr = tape->Rec_.put_con_par(ind_.value_); - CPPAD_ASSERT_UNKNOWN( ind_taddr > 0 ); - - // parameter or variable index for right - addr_t right_taddr = right.taddr_; - if( con_right ) - right_taddr = tape->Rec_.put_con_par(right.value_); - CPPAD_ASSERT_UNKNOWN( right_taddr > 0 ); - - // record the setting of this array element - if( var_right ) - { // resulting vector is a variable - vec_.ad_type_ = variable_enum; - - // put operator arguments in tape - tape->Rec_.PutArg(vec_.offset_, ind_taddr, right_taddr); - - if( con_ind | dyn_ind) - { CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StpvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StpvOp) == 0 ); - - // put operator in the tape, ind_ is parameter, right is variable - tape->Rec_.PutOp(local::StpvOp); - - } - else - { CPPAD_ASSERT_UNKNOWN( var_ind ); - CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StvvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StvvOp) == 0 ); - - // put operator in the tape, ind_ is variable, right is variable - tape->Rec_.PutOp(local::StvvOp); - } - } - else - { - // put operator arguments in tape - tape->Rec_.PutArg(vec_.offset_, ind_taddr, right_taddr); - - // record the setting of this array element - if( con_ind | dyn_ind ) - { CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StppOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StppOp) == 0 ); - - // put operator in the tape, ind_ is parameter, right is parameter - tape->Rec_.PutOp(local::StppOp); - } - else - { CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StvpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StvpOp) == 0 ); - - // put operator in the tape, ind_ is variable, right is parameter - tape->Rec_.PutOp(local::StvpOp); - } - } -} -template -void VecAD_reference::operator=(const Base &right) -{ *this = AD(right); } -// -template -void VecAD_reference::operator= -(const VecAD_reference &right) -{ *this = right.ADBase(); } -// -template -void VecAD_reference::operator=(int right) -{ *this = Base(right); } -// --------------------------------------------------------------------------- - -} // END_CPPAD_NAMESPACE - -// preprocessor symbols that are local to this file -# undef CPPAD_VEC_AD_COMP_ASSIGN - -# endif diff --git a/build-config/cppad/include/cppad/core/zdouble.hpp b/build-config/cppad/include/cppad/core/zdouble.hpp deleted file mode 100644 index 8c08f71d..00000000 --- a/build-config/cppad/include/cppad/core/zdouble.hpp +++ /dev/null @@ -1,528 +0,0 @@ -# ifndef CPPAD_CORE_ZDOUBLE_HPP -# define CPPAD_CORE_ZDOUBLE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin zdouble$$ -$spell - zdouble - op - bool - inf - CppAD -$$ -$section zdouble: An AD Base Type With Absolute Zero$$ - -$head Deprecated 2015-09-26$$ -Use the function $cref azmul$$ instead. - -$head Absolute Zero$$ -The $code zdouble$$ class acts like the $code double$$ type -with the added property that zero times any value is zero. -This includes zero time $cref nan$$ and zero times infinity. -In addition, zero divided by any value and any value times zero -are also zero. - -$head Syntax$$ - -$subhead Constructor and Assignment$$ -$codei% zdouble z -%$$ -$codei% zdouble z(x) -%$$ -$icode% z1% %op% %x% -%$$ -where $icode x$$ is a $code double$$ or $code zdouble$$ object -and $icode op$$ is $code =$$, $code +=$$, $code -=$$, $code *=$$ -or $code /=-$$. - -$subhead Comparison Operators$$ -$icode% b% = %z% %op% %x% -%$$ -$icode% b% = %x% %op% %z% -%$$ -where $icode b$$ is a $code bool$$ object, -$icode z$$ is a $code zdouble$$ object, -$icode x$$ is a $code double$$ or $code zdouble$$ object, and -$icode op$$ is $code ==$$, $code !=$$, $code <=$$, $code >=$$, -$code <$$ or $code >$$. - -$subhead Arithmetic Operators$$ -$icode% z2% = %z1% %op% %x% -%$$ -$icode% z2% = %x% %op% %z1% -%$$ -where $icode z1$$, $icode z2$$ are $code zdouble$$ objects, -$icode x$$ is a $code double$$ or $code zdouble$$ object, and -$icode op$$ is $code +$$, $code -$$, $code *$$ or $code /$$. - - -$subhead Standard Math$$ -$icode% z2% = %fun%(%z1%) -%$$ -$icode% z3% = pow(%z1%, %z2%) -%$$ -where $icode z1$$, $icode z2$$, $icode z3$$ are $code zdouble$$ objects and -$icode fun$$ is a $cref unary_standard_math$$ function. - -$subhead Nan$$ -There is a specialization of $cref nan$$ so that -$icode% - z2% = nan(%z1%) -%$$ -returns 'not a number' when $icode z1$$ has type $code zdouble$$. -Note that this template function needs to be specialized because -$codei - zdouble(0.0) == zdouble(0.0) / zdouble(0.0) -$$ - - -$head Motivation$$ - -$subhead General$$ -Often during computing (and more so in parallel computing) alternative -values for an expression are computed and one of the alternatives -is chosen using some boolean variable. -This is often represented by -$codei% - %result% = %flag% * %value_if_true% + (1 - %flag%) * %value_if_false% -%$$ -where $icode flag$$ is one for true and zero for false. -This representation does not work for $code double$$ when the value -being multiplied by zero is $code +inf$$, $code -inf$$, or $code nan$$. - -$subhead CppAD$$ -In CppAD one can use -$cref/conditional expressions/CondExp/$$ to achieve the representation -$codei% - %result% = %flag% * %value_if_true% + (1 - %flag%) * %value_if_false% -%$$ -This works fine except when there are -$cref/multiple levels of AD/mul_level/$$; e.g., -when using $codei%AD< AD >%$$. -In this case the corresponding AD function objects have type -$cref/ADFun< AD >/FunConstruct/$$. -When these AD function objects compute derivatives using -$cref reverse$$ mode, the conditional expressions are represented use -zeros to multiply the expression that is not used. -Using $codei%AD< AD >%$$ instead of $code AD< AD >$$ -makes this representation work and fixes the problem. - -$head Base Type Requirements$$ -The type $code zdouble$$ satisfies all of the CppAD -$cref/base type requirements/base_require/$$. - -$end -*/ -# include -# include - -/*! -\file zdouble.hpp -Define a class like double but with an absolute zero. -*/ - -/*! -\def CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(op) -Define a compound assignment member operator that functions the same -as corresponding double operator. -*/ -# define CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(op) \ - zdouble& operator op (const zdouble& z) \ - { dbl_ op z.dbl_; \ - return *this; \ - } \ - zdouble& operator op (const double& x) \ - { dbl_ op x; \ - return *this; \ - } - -/*! -\def CPPAD_ZDOUBLE_UNARY_OPERATOR(op) -Define a unary compound assignment member operator. -*/ -# define CPPAD_ZDOUBLE_UNARY_OPERATOR(op) \ - zdouble operator op (void) const \ - { return zdouble( op dbl_ ); } - -/*! -# define CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(op) -Define a binary arithmetic member operator that functions the same -as corresponding double operator. -*/ -# define CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(op) \ - zdouble operator op (const zdouble& z) const \ - { return zdouble( dbl_ op z.dbl_ ); } \ - zdouble operator op (const double& x) const \ - { return zdouble( dbl_ op x ); } - -/*! -\def CPPAD_ZDOUBLE_COMPARE_OPERATOR(op) -Define a comparison member operator. -*/ -# define CPPAD_ZDOUBLE_COMPARE_OPERATOR(op) \ - bool operator op (const zdouble& z) const \ - { return dbl_ op z.dbl_; } \ - bool operator op (const double& x) const \ - { return dbl_ op x; } - -/*! -\def CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(op) -Define a binary arithmetic operator that is not a member because -the double operand is on the left. -*/ -# define CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(op) \ - inline zdouble operator op(const double& x, const zdouble& z) \ - { return zdouble(x) op z; } - -/*! -\def CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(op, op_switch) -Define a comparison operator that is not a member because -the double operand is on the left. -Convert it to the case where the double operand is on the right by -by using op_switch instead of op. -*/ -# define CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(op, op_switch) \ - inline bool operator op(const double& x, const zdouble& z) \ - { return z op_switch x; } - -/*! -\def CPPAD_ZDOUBLE_STD_MATH_FRIEND(fun) -Declare that a standard math function is a friend. -*/ -# define CPPAD_ZDOUBLE_STD_MATH_FRIEND(fun) \ - friend zdouble fun(const zdouble& z); -/*! -\def CPPAD_ZDOUBLE_STD_MATH(fun) -Define a standard math function. -*/ -# define CPPAD_ZDOUBLE_STD_MATH(fun) \ - inline zdouble fun(const zdouble& z ) \ - { return zdouble( std::fun(z.dbl_) ); } - -namespace CppAD { // CPPAD_BEGIN_NAMESPACDE - - -/*! -Class that is like double, except that it has an absolute zero. -*/ -class zdouble { - /*! - For zdouble objects z1, z2, and std::ostream os, - declare the following friends: - \code - os << z1 - Integer(z1) - fabs(z1) - pow(z1, z2) - fabs_geq(z1, z2) - fun(z1) - \endcode - where fun is any of the standard math unary functions. - */ - friend std::ostream& operator << (std::ostream &os, const zdouble& z); - friend int Integer(const zdouble& z); - friend zdouble pow(const zdouble& x, const zdouble& y); - friend bool abs_geq(const zdouble& x, const zdouble& y); - // - CPPAD_ZDOUBLE_STD_MATH_FRIEND(acos) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(asin) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(atan) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(cos) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(cosh) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(exp) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(fabs) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(log) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(log10) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(sin) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(sinh) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(sqrt) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(tan) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(tanh) - // - CPPAD_ZDOUBLE_STD_MATH_FRIEND(asinh) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(acosh) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(atanh) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(erf) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(erfc) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(expm1) - CPPAD_ZDOUBLE_STD_MATH_FRIEND(log1p) - // -private: - /// The value for this object - double dbl_; -public: - /// Default constructor - zdouble(void) - : dbl_() - { } - /// Copy constructor - zdouble(const zdouble& z) - : dbl_(z.dbl_) - { } - /// Constructor from double - zdouble(const double& dbl) - : dbl_(dbl) - { } - // - /// Destructor - ~zdouble(void) - { } - // - /// Assignment from zdouble - zdouble& operator=(const zdouble& z) - { dbl_ = z.dbl_; - return *this; - } - /// Assignment from double - zdouble& operator=(const double& dbl) - { dbl_ = dbl; - return *this; - } - // - /// Normal compound assignment - CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(+=) - /// Normal compound assignment - CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(-=) - /// Normal unary operator - CPPAD_ZDOUBLE_UNARY_OPERATOR(+) - /// Normal unary operator - CPPAD_ZDOUBLE_UNARY_OPERATOR(-) - /// Normal compare operator - CPPAD_ZDOUBLE_COMPARE_OPERATOR(==) - /// Normal compare operator - CPPAD_ZDOUBLE_COMPARE_OPERATOR(!=) - /// Normal compare operator - CPPAD_ZDOUBLE_COMPARE_OPERATOR(<=) - /// Normal compare operator - CPPAD_ZDOUBLE_COMPARE_OPERATOR(>=) - /// Normal compare operator - CPPAD_ZDOUBLE_COMPARE_OPERATOR(<) - /// Normal compare operator - CPPAD_ZDOUBLE_COMPARE_OPERATOR(>) - // - /// Normal binary arithmetic operator - CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(+) - /// Normal binary arithmetic operator - CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(-) - // - /// Binary arithmetic * with absolute zero - zdouble operator * (const zdouble& z) const - { bool zero = (dbl_ == 0.0) || (z.dbl_ == 0.0); - return zdouble( zero ? 0.0 : (dbl_ * z.dbl_) ); - } - /// Binary arithmetic * with absolute zero - zdouble operator * (const double& x) const - { bool zero = (dbl_ == 0.0) || (x == 0.0); - return zdouble( zero ? 0.0 : (dbl_ * x) ); - } - /// Binary arithmetic / with absolute zero - zdouble operator / (const zdouble& z) const - { bool zero = (dbl_ == 0.0); - return zdouble( zero ? 0.0 : (dbl_ / z.dbl_) ); - } - /// Binary arithmetic / with absolute zero - zdouble operator / (const double& x) const - { bool zero = (dbl_ == 0.0); - return zdouble( zero ? 0.0 : (dbl_ / x) ); - } - // - /// Compute assignmnet *= with absolute zero - zdouble& operator *= (const zdouble& z) - { bool zero = (dbl_ == 0.0) || (z.dbl_ == 0.0); - zero ? (dbl_ = 0.0) : (dbl_ *= z.dbl_); - return *this; - } - /// Compute assignmnet *= with absolute zero - zdouble& operator *= (const double& x) - { bool zero = (dbl_ == 0.0) || (x == 0.0); - zero ? (dbl_ = 0.0) : (dbl_ *= x); - return *this; - } - // - /// Compute assignmnet /= with absolute zero - zdouble& operator /= (const zdouble& z) - { bool zero = (dbl_ == 0.0); - zero ? (dbl_ = 0.0) : (dbl_ /= z.dbl_); - return *this; - } - /// Compute assignmnet /= with absolute zero - zdouble& operator /= (const double& x) - { bool zero = (dbl_ == 0.0); - zero ? (dbl_ = 0.0) : (dbl_ /= x); - return *this; - } -}; -// BEGIN nan -/// Must specialize CppAD::nan because zdouble 0/0 is not nan. -template <> inline -zdouble nan(const zdouble& zero) -{ - return zdouble( std::numeric_limits::quiet_NaN() ); -} -// END nan -// -/// Normal non-member compare operator -CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(==, ==) -/// Normal non-member compare operator -CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(!=, !=) -/// Normal non-member compare operator -CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(<=, >=) -/// Normal non-member compare operator -CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(>=, <=) -/// Normal non-member compare operator -CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(<, >) -/// Normal non-member compare operator -CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(>, <) -// -/// Normal binary arithmetic operator -CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(+) -/// Normal binary arithmetic operator -CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(-) -/// Binary arithmetic operator with absolute zero -CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(*) -/// Binary arithmetic operator with absolute zero -CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(/) -// ------------------------------------------------------------------------- -// Base type requirements -// ------------------------------------------------------------------------- - -/// Base type requirement: CondExpOp -inline zdouble CondExpOp( - enum CompareOp cop , - const zdouble& left , - const zdouble& right , - const zdouble& exp_if_true , - const zdouble& exp_if_false ) -{ return CondExpTemplate(cop, left, right, exp_if_true, exp_if_false); -} - -/// Base type requirement: CondExpRel -CPPAD_COND_EXP_REL(zdouble) - -/// Base type requirement: EqualOpSeq -inline bool EqualOpSeq(const zdouble& x, const zdouble& y) -{ return x == y; } - -/// Base type requirement: Identical -inline bool IdenticalCon(const zdouble& x) -{ return true; } -inline bool IdenticalZero(const zdouble& x) -{ return (x == 0.0); } -inline bool IdenticalOne(const zdouble& x) -{ return (x == 1.); } -inline bool IdenticalEqualCon(const zdouble& x, const zdouble& y) -{ return (x == y); } - -/// Base type requirement: output operator -inline std::ostream& operator << (std::ostream &os, const zdouble& z) -{ os << z.dbl_; - return os; -} - -/// Base type requirement: Integer -inline int Integer(const zdouble& x) -{ return static_cast(x.dbl_); } - -/// Base type requirement: azmul -inline zdouble azmul(const zdouble& x, const zdouble& y) -{ return x * y; } - -/// Base type requirement: Ordered -inline bool GreaterThanZero(const zdouble& x) -{ return x > 0.0; } -inline bool GreaterThanOrZero(const zdouble& x) -{ return x >= 0.0; } -inline bool LessThanZero(const zdouble& x) -{ return x < 0.0; } -inline bool LessThanOrZero(const zdouble& x) -{ return x <= 0.0; } -inline bool abs_geq(const zdouble& x, const zdouble& y) -{ return std::fabs(x.dbl_) >= std::fabs(y.dbl_); } - -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(acos) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(asin) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(atan) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(cos) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(cosh) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(exp) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(fabs) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(log) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(log10) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(sin) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(sinh) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(sqrt) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(tan) -/// Normal standard math function -CPPAD_ZDOUBLE_STD_MATH(tanh) -// -/// C++2011 standard math function -CPPAD_ZDOUBLE_STD_MATH(asinh) -/// C++2011 standard math function -CPPAD_ZDOUBLE_STD_MATH(acosh) -/// C++2011 standard math function -CPPAD_ZDOUBLE_STD_MATH(atanh) -/// C++2011 standard math function -CPPAD_ZDOUBLE_STD_MATH(erf) -/// C++2011 standard math function -CPPAD_ZDOUBLE_STD_MATH(erfc) -/// C++2011 standard math function -CPPAD_ZDOUBLE_STD_MATH(expm1) -/// C++2011 standard math function -CPPAD_ZDOUBLE_STD_MATH(log1p) - -/// Base type requirement: abs -inline zdouble abs(const zdouble& x) -{ return fabs(x); } - -/// Base type requirement: sign -inline zdouble sign(const zdouble& x) -{ if( x > 0.0 ) - return zdouble(1.); - if( x == 0.0 ) - return zdouble(0.0); - return zdouble(-1.); -} - -/// Base type requirement: pow -inline zdouble pow(const zdouble& x, const zdouble& y) -{ return std::pow(x.dbl_, y.dbl_); } - -/// Base type requirement: limits -CPPAD_NUMERIC_LIMITS(double, zdouble) - -} // CPPAD_END_NAMESPACE - -/// undef all macros defined in this file -# undef CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR -# undef CPPAD_ZDOUBLE_UNARY_OPERATOR -# undef CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR -# undef CPPAD_ZDOUBLE_COMPARE_OPERATOR -# undef CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR -# undef CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR -# undef CPPAD_ZDOUBLE_STD_MATH_FRIEND -# undef CPPAD_ZDOUBLE_STD_MATH - -# endif diff --git a/build-config/cppad/include/cppad/cppad.hpp b/build-config/cppad/include/cppad/cppad.hpp deleted file mode 100644 index 4bfdfc94..00000000 --- a/build-config/cppad/include/cppad/cppad.hpp +++ /dev/null @@ -1,79 +0,0 @@ -# ifndef CPPAD_CPPAD_HPP -# define CPPAD_CPPAD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file cppad.hpp -\brief includes the entire CppAD package in the necessary order. - -\namespace CppAD -\brief contains all the variables and functions defined by the CppAD package. -*/ - -# include // all base type requirements -// --------------------------------------------------------------------------- -// CppAD general purpose library routines (can be included separately) -# include -// -------------------------------------------------------------------------- -// System routines that can be used by rest of CppAD with out including - -# include -# include -# include -# include - -// --------------------------------------------------------------------------- -// definitions needed by rest of includes - -// definitions that come from the installation -# include - -// definitions that are local to the CppAD include files -# include - -// vectors used with CppAD -# include - -// deprecated vectors used with CppAD -# include - -// Declare classes and fucntions that are used before defined -# include - -// --------------------------------------------------------------------------- -// declare the AD template class - -# include - -// --------------------------------------------------------------------------- - -# include // AD class methods available to the user -// tape that tape for AD acts as a user of Base operations -// so user_ad.hpp must come before op.hpp -# include // executes taped operations -# include // ADFun objects - -// --------------------------------------------------------------------------- -// library routines that require the rest of CppAD -# include -# include -# include -# include -# include -# if CPPAD_HAS_IPOPT -# include -# endif - -// undo definitions in Define.h -# include - -# endif diff --git a/build-config/cppad/include/cppad/example/atomic_three/mat_mul.hpp b/build-config/cppad/include/cppad/example/atomic_three/mat_mul.hpp deleted file mode 100644 index b0c1af48..00000000 --- a/build-config/cppad/include/cppad/example/atomic_three/mat_mul.hpp +++ /dev/null @@ -1,661 +0,0 @@ -# ifndef CPPAD_EXAMPLE_ATOMIC_THREE_MAT_MUL_HPP -# define CPPAD_EXAMPLE_ATOMIC_THREE_MAT_MUL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin atomic_three_mat_mul.hpp$$ -$spell - Taylor - ty - px - CppAD - jac - hes - nr - nc - afun - mul -$$ - -$section Matrix Multiply as an Atomic Operation$$ - -$head See Also$$ -$cref atomic_two_eigen_mat_mul.hpp$$ - -$head Purpose$$ -Use scalar $code double$$ operations in an $cref atomic_three$$ operation -that computes the matrix product for $code AD -namespace { // Begin empty namespace -using CppAD::vector; -// -// matrix result = left * right -class atomic_mat_mul : public CppAD::atomic_three { -/* %$$ -$head Constructor$$ -$srccode%cpp% */ -public: - // --------------------------------------------------------------------- - // constructor - atomic_mat_mul(void) : CppAD::atomic_three("mat_mul") - { } -private: -/* %$$ -$head Left Operand Element Index$$ -Index in the Taylor coefficient matrix $icode tx$$ of a left matrix element. -$srccode%cpp% */ - size_t left( - size_t i , // left matrix row index - size_t j , // left matrix column index - size_t k , // Taylor coeffocient order - size_t nk , // number of Taylor coefficients in tx - size_t nr_left , // rows in left matrix - size_t n_middle , // rows in left and columns in right - size_t nc_right ) // columns in right matrix - { assert( i < nr_left ); - assert( j < n_middle ); - return (3 + i * n_middle + j) * nk + k; - } -/* %$$ -$head Right Operand Element Index$$ -Index in the Taylor coefficient matrix $icode tx$$ of a right matrix element. -$srccode%cpp% */ - size_t right( - size_t i , // right matrix row index - size_t j , // right matrix column index - size_t k , // Taylor coeffocient order - size_t nk , // number of Taylor coefficients in tx - size_t nr_left , // rows in left matrix - size_t n_middle , // rows in left and columns in right - size_t nc_right ) // columns in right matrix - { assert( i < n_middle ); - assert( j < nc_right ); - size_t offset = 3 + nr_left * n_middle; - return (offset + i * nc_right + j) * nk + k; - } -/* %$$ -$head Result Element Index$$ -Index in the Taylor coefficient matrix $icode ty$$ of a result matrix element. -$srccode%cpp% */ - size_t result( - size_t i , // result matrix row index - size_t j , // result matrix column index - size_t k , // Taylor coeffocient order - size_t nk , // number of Taylor coefficients in ty - size_t nr_left , // rows in left matrix - size_t n_middle , // rows in left and columns in right - size_t nc_right ) // columns in right matrix - { assert( i < nr_left ); - assert( j < nc_right ); - return (i * nc_right + j) * nk + k; - } -/* %$$ -$head Forward Matrix Multiply$$ -Forward mode multiply Taylor coefficients in $icode tx$$ and sum into -$icode ty$$ (for one pair of left and right orders) -$srccode%cpp% */ - void forward_multiply( - size_t k_left , // order for left coefficients - size_t k_right , // order for right coefficients - const vector& tx , // domain space Taylor coefficients - vector& ty , // range space Taylor coefficients - size_t nr_left , // rows in left matrix - size_t n_middle , // rows in left and columns in right - size_t nc_right ) // columns in right matrix - { - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t nk = tx.size() / nx; -# ifndef NDEBUG - size_t ny = nr_left * nc_right; - assert( nk == ty.size() / ny ); -# endif - // - size_t k_result = k_left + k_right; - assert( k_result < nk ); - // - for(size_t i = 0; i < nr_left; i++) - { for(size_t j = 0; j < nc_right; j++) - { double sum = 0.0; - for(size_t ell = 0; ell < n_middle; ell++) - { size_t i_left = left( - i, ell, k_left, nk, nr_left, n_middle, nc_right - ); - size_t i_right = right( - ell, j, k_right, nk, nr_left, n_middle, nc_right - ); - sum += tx[i_left] * tx[i_right]; - } - size_t i_result = result( - i, j, k_result, nk, nr_left, n_middle, nc_right - ); - ty[i_result] += sum; - } - } - } -/* %$$ -$head Reverse Matrix Multiply$$ -Reverse mode partials of Taylor coefficients and sum into $icode px$$ -(for one pair of left and right orders) -$srccode%cpp% */ - void reverse_multiply( - size_t k_left , // order for left coefficients - size_t k_right , // order for right coefficients - const vector& tx , // domain space Taylor coefficients - const vector& ty , // range space Taylor coefficients - vector& px , // partials w.r.t. tx - const vector& py , // partials w.r.t. ty - size_t nr_left , // rows in left matrix - size_t n_middle , // rows in left and columns in right - size_t nc_right ) // columns in right matrix - { - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t nk = tx.size() / nx; -# ifndef NDEBUG - size_t ny = nr_left * nc_right; - assert( nk == ty.size() / ny ); -# endif - assert( tx.size() == px.size() ); - assert( ty.size() == py.size() ); - // - size_t k_result = k_left + k_right; - assert( k_result < nk ); - // - for(size_t i = 0; i < nr_left; i++) - { for(size_t j = 0; j < nc_right; j++) - { size_t i_result = result( - i, j, k_result, nk, nr_left, n_middle, nc_right - ); - for(size_t ell = 0; ell < n_middle; ell++) - { size_t i_left = left( - i, ell, k_left, nk, nr_left, n_middle, nc_right - ); - size_t i_right = right( - ell, j, k_right, nk, nr_left, n_middle, nc_right - ); - // sum += tx[i_left] * tx[i_right]; - px[i_left] += tx[i_right] * py[i_result]; - px[i_right] += tx[i_left] * py[i_result]; - } - } - } - return; - } -/* %$$ -$head for_type$$ -Routine called by CppAD during $cref/afun(ax, ay)/atomic_three_afun/$$. -$srccode%cpp% */ - // calculate type_y - virtual bool for_type( - const vector& parameter_x , - const vector& type_x , - vector& type_y ) - { assert( parameter_x.size() == type_x.size() ); - bool ok = true; - ok &= type_x[0] == CppAD::constant_enum; - ok &= type_x[1] == CppAD::constant_enum; - ok &= type_x[2] == CppAD::constant_enum; - if( ! ok ) - return false; - // - size_t nr_left = size_t( parameter_x[0] ); - size_t n_middle = size_t( parameter_x[1] ); - size_t nc_right = size_t( parameter_x[2] ); - // - ok &= type_x.size() == 3 + (nr_left + nc_right) * n_middle; - ok &= type_y.size() == n_middle * nc_right; - if( ! ok ) - return false; - // - // commpute type_y - size_t nk = 1; // number of orders - size_t k = 0; // order - for(size_t i = 0; i < nr_left; ++i) - { for(size_t j = 0; j < nc_right; ++j) - { // compute type for result[i, j] - CppAD::ad_type_enum type_yij = CppAD::constant_enum; - for(size_t ell = 0; ell < n_middle; ++ell) - { // index for left(i, ell) - size_t i_left = left( - i, ell, k, nk, nr_left, n_middle, nc_right - ); - // indx for right(ell, j) - size_t i_right = right( - ell, j, k, nk, nr_left, n_middle, nc_right - ); - // multiplication on left or right by the constant zero - // always results in a constant - bool zero_left = type_x[i_left] == CppAD::constant_enum; - zero_left &= parameter_x[i_left] == 0.0; - bool zero_right = type_x[i_right] == CppAD::constant_enum; - zero_right &= parameter_x[i_right] == 0.0; - if( ! (zero_left | zero_right) ) - { type_yij = std::max(type_yij, type_x[i_left] ); - type_yij = std::max(type_yij, type_x[i_right] ); - } - } - size_t i_result = result( - i, j, k, nk, nr_left, n_middle, nc_right - ); - type_y[i_result] = type_yij; - } - } - return true; - } -/* %$$ -$head forward$$ -Routine called by CppAD during $cref Forward$$ mode. -$srccode%cpp% */ - virtual bool forward( - const vector& parameter_x , - const vector& type_x , - size_t need_y , - size_t q , - size_t p , - const vector& tx , - vector& ty ) - { size_t n_order = p + 1; - size_t nr_left = size_t( tx[ 0 * n_order + 0 ] ); - size_t n_middle = size_t( tx[ 1 * n_order + 0 ] ); - size_t nc_right = size_t( tx[ 2 * n_order + 0 ] ); -# ifndef NDEBUG - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t ny = nr_left * nc_right; -# endif - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - size_t i, j, ell; - - // initialize result as zero - size_t k; - for(i = 0; i < nr_left; i++) - { for(j = 0; j < nc_right; j++) - { for(k = q; k <= p; k++) - { size_t i_result = result( - i, j, k, n_order, nr_left, n_middle, nc_right - ); - ty[i_result] = 0.0; - } - } - } - for(k = q; k <= p; k++) - { // sum the produces that result in order k - for(ell = 0; ell <= k; ell++) - forward_multiply( - ell, k - ell, tx, ty, nr_left, n_middle, nc_right - ); - } - - // all orders are implemented, so always return true - return true; - } -/* %$$ -$head reverse$$ -Routine called by CppAD during $cref Reverse$$ mode. -$srccode%cpp% */ - virtual bool reverse( - const vector& parameter_x , - const vector& type_x , - size_t p , - const vector& tx , - const vector& ty , - vector& px , - const vector& py ) - { size_t n_order = p + 1; - size_t nr_left = size_t( tx[ 0 * n_order + 0 ] ); - size_t n_middle = size_t( tx[ 1 * n_order + 0 ] ); - size_t nc_right = size_t( tx[ 2 * n_order + 0 ] ); -# ifndef NDEBUG - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t ny = nr_left * nc_right; -# endif - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - assert( px.size() == tx.size() ); - assert( py.size() == ty.size() ); - - // initialize summation - for(size_t i = 0; i < px.size(); i++) - px[i] = 0.0; - - // number of orders to differentiate - size_t k = n_order; - while(k--) - { // differentiate the produces that result in order k - for(size_t ell = 0; ell <= k; ell++) - reverse_multiply( - ell, k - ell, tx, ty, px, py, nr_left, n_middle, nc_right - ); - } - - // all orders are implented, so always return true - return true; - } -/* %$$ -$head jac_sparsity$$ -$srccode%cpp% */ - // Jacobian sparsity routine called by CppAD - virtual bool jac_sparsity( - const vector& parameter_x , - const vector& type_x , - bool dependency , - const vector& select_x , - const vector& select_y , - CppAD::sparse_rc< vector >& pattern_out ) - { - size_t n = select_x.size(); - size_t m = select_y.size(); - assert( parameter_x.size() == n ); - assert( type_x.size() == n ); - // - size_t nr_left = size_t( parameter_x[0] ); - size_t n_middle = size_t( parameter_x[1] ); - size_t nc_right = size_t( parameter_x[2] ); - size_t nk = 1; // only one order - size_t k = 0; // order zero - // - // count number of non-zeros in sparsity pattern - size_t nnz = 0; - for(size_t i = 0; i < nr_left; ++i) - { for(size_t j = 0; j < nc_right; ++j) - { size_t i_result = result( - i, j, k, nk, nr_left, n_middle, nc_right - ); - if( select_y[i_result] ) - { for(size_t ell = 0; ell < n_middle; ++ell) - { size_t i_left = left( - i, ell, k, nk, nr_left, n_middle, nc_right - ); - size_t i_right = right( - ell, j, k, nk, nr_left, n_middle, nc_right - ); - bool zero_left = - type_x[i_left] == CppAD::constant_enum; - zero_left &= parameter_x[i_left] == 0.0; - bool zero_right = - type_x[i_right] == CppAD::constant_enum; - zero_right &= parameter_x[i_right] == 0.0; - if( ! (zero_left | zero_right ) ) - { bool var_left = - type_x[i_left] == CppAD::variable_enum; - bool var_right = - type_x[i_right] == CppAD::variable_enum; - if( select_x[i_left] & var_left ) - ++nnz; - if( select_x[i_right] & var_right ) - ++nnz; - } - } - } - } - } - // - // fill in the sparsity pattern - pattern_out.resize(m, n, nnz); - size_t idx = 0; - for(size_t i = 0; i < nr_left; ++i) - { for(size_t j = 0; j < nc_right; ++j) - { size_t i_result = result( - i, j, k, nk, nr_left, n_middle, nc_right - ); - if( select_y[i_result] ) - { for(size_t ell = 0; ell < n_middle; ++ell) - { size_t i_left = left( - i, ell, k, nk, nr_left, n_middle, nc_right - ); - size_t i_right = right( - ell, j, k, nk, nr_left, n_middle, nc_right - ); - bool zero_left = - type_x[i_left] == CppAD::constant_enum; - zero_left &= parameter_x[i_left] == 0.0; - bool zero_right = - type_x[i_right] == CppAD::constant_enum; - zero_right &= parameter_x[i_right] == 0.0; - if( ! (zero_left | zero_right ) ) - { bool var_left = - type_x[i_left] == CppAD::variable_enum; - bool var_right = - type_x[i_right] == CppAD::variable_enum; - if( select_x[i_left] & var_left ) - pattern_out.set(idx++, i_result, i_left); - if( select_x[i_right] & var_right ) - pattern_out.set(idx++, i_result, i_right); - } - } - } - } - } - assert( idx == nnz ); - // - return true; - } -/* %$$ -$head hes_sparsity$$ -$srccode%cpp% */ - // Jacobian sparsity routine called by CppAD - virtual bool hes_sparsity( - const vector& parameter_x , - const vector& type_x , - const vector& select_x , - const vector& select_y , - CppAD::sparse_rc< vector >& pattern_out ) - { - size_t n = select_x.size(); - assert( parameter_x.size() == n ); - assert( type_x.size() == n ); - // - size_t nr_left = size_t( parameter_x[0] ); - size_t n_middle = size_t( parameter_x[1] ); - size_t nc_right = size_t( parameter_x[2] ); - size_t nk = 1; // only one order - size_t k = 0; // order zero - // - // count number of non-zeros in sparsity pattern - size_t nnz = 0; - for(size_t i = 0; i < nr_left; ++i) - { for(size_t j = 0; j < nc_right; ++j) - { size_t i_result = result( - i, j, k, nk, nr_left, n_middle, nc_right - ); - if( select_y[i_result] ) - { for(size_t ell = 0; ell < n_middle; ++ell) - { // i_left depends on i, ell - size_t i_left = left( - i, ell, k, nk, nr_left, n_middle, nc_right - ); - // i_right depens on ell, j - size_t i_right = right( - ell, j, k, nk, nr_left, n_middle, nc_right - ); - bool var_left = select_x[i_left] & - (type_x[i_left] == CppAD::variable_enum); - bool var_right = select_x[i_right] & - (type_x[i_right] == CppAD::variable_enum); - if( var_left & var_right ) - nnz += 2; - } - } - } - } - // - // fill in the sparsity pattern - pattern_out.resize(n, n, nnz); - size_t idx = 0; - for(size_t i = 0; i < nr_left; ++i) - { for(size_t j = 0; j < nc_right; ++j) - { size_t i_result = result( - i, j, k, nk, nr_left, n_middle, nc_right - ); - if( select_y[i_result] ) - { for(size_t ell = 0; ell < n_middle; ++ell) - { size_t i_left = left( - i, ell, k, nk, nr_left, n_middle, nc_right - ); - size_t i_right = right( - ell, j, k, nk, nr_left, n_middle, nc_right - ); - bool var_left = select_x[i_left] & - (type_x[i_left] == CppAD::variable_enum); - bool var_right = select_x[i_right] & - (type_x[i_right] == CppAD::variable_enum); - if( var_left & var_right ) - { // Cannot possibly set the same (i_left, i_right) - // pair twice. - assert( i_left != i_right ); - pattern_out.set(idx++, i_left, i_right); - pattern_out.set(idx++, i_right, i_left); - } - } - } - } - } - assert( idx == nnz ); - // - return true; - } -/* %$$ -$head rev_depend$$ -Routine called when a function using $code mat_mul$$ is optimized. -$srccode%cpp% */ - // calculate depend_x - virtual bool rev_depend( - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y ) - { assert( parameter_x.size() == depend_x.size() ); - assert( parameter_x.size() == type_x.size() ); - bool ok = true; - // - size_t nr_left = size_t( parameter_x[0] ); - size_t n_middle = size_t( parameter_x[1] ); - size_t nc_right = size_t( parameter_x[2] ); - // - ok &= depend_x.size() == 3 + (nr_left + nc_right) * n_middle; - ok &= depend_y.size() == n_middle * nc_right; - if( ! ok ) - return false; - // - // initialize depend_x - for(size_t ell = 0; ell < 3; ++ell) - depend_x[ell] = true; // always need these parameters - for(size_t ell = 3; ell < depend_x.size(); ++ell) - depend_x[ell] = false; // initialize as false - // - // commpute depend_x - size_t nk = 1; // number of orders - size_t k = 0; // order - for(size_t i = 0; i < nr_left; ++i) - { for(size_t j = 0; j < nc_right; ++j) - { // check depend for result[i, j] - size_t i_result = result( - i, j, k, nk, nr_left, n_middle, nc_right - ); - if( depend_y[i_result] ) - { for(size_t ell = 0; ell < n_middle; ++ell) - { // index for left(i, ell) - size_t i_left = left( - i, ell, k, nk, nr_left, n_middle, nc_right - ); - // indx for right(ell, j) - size_t i_right = right( - ell, j, k, nk, nr_left, n_middle, nc_right - ); - bool zero_left = - type_x[i_left] == CppAD::constant_enum; - zero_left &= parameter_x[i_left] == 0.0; - bool zero_right = - type_x[i_right] == CppAD::constant_enum; - zero_right &= parameter_x[i_right] == 0.0; - if( ! zero_right ) - depend_x[i_left] = true; - if( ! zero_left ) - depend_x[i_right] = true; - } - } - } - } - return true; - } -/* %$$ -$head End Class Definition$$ -$srccode%cpp% */ -}; // End of mat_mul class -} // End empty namespace -/* %$$ -$comment end nospell$$ -$end -*/ - - -# endif diff --git a/build-config/cppad/include/cppad/example/atomic_two/eigen_cholesky.hpp b/build-config/cppad/include/cppad/example/atomic_two/eigen_cholesky.hpp deleted file mode 100644 index 0b2b0861..00000000 --- a/build-config/cppad/include/cppad/example/atomic_two/eigen_cholesky.hpp +++ /dev/null @@ -1,376 +0,0 @@ -# ifndef CPPAD_EXAMPLE_ATOMIC_TWO_EIGEN_CHOLESKY_HPP -# define CPPAD_EXAMPLE_ATOMIC_TWO_EIGEN_CHOLESKY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin atomic_two_eigen_cholesky.hpp$$ -$spell - Eigen - Taylor - Cholesky - op -$$ - -$section atomic_two Eigen Cholesky Factorization Class$$ - -$head Purpose$$ -Construct an atomic operation that computes a lower triangular matrix -$latex L $$ such that $latex L L^\R{T} = A$$ -for any positive integer $latex p$$ -and symmetric positive definite matrix $latex A \in \B{R}^{p \times p}$$. - -$head Start Class Definition$$ -$srccode%cpp% */ -# include -# include - - -/* %$$ -$head Public$$ - -$subhead Types$$ -$srccode%cpp% */ -namespace { // BEGIN_EMPTY_NAMESPACE - -template -class atomic_eigen_cholesky : public CppAD::atomic_base { -public: - // ----------------------------------------------------------- - // type of elements during calculation of derivatives - typedef Base scalar; - // type of elements during taping - typedef CppAD::AD ad_scalar; - // - // type of matrix during calculation of derivatives - typedef Eigen::Matrix< - scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> matrix; - // type of matrix during taping - typedef Eigen::Matrix< - ad_scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > ad_matrix; - // - // lower triangular scalar matrix - typedef Eigen::TriangularView lower_view; -/* %$$ -$subhead Constructor$$ -$srccode%cpp% */ - // constructor - atomic_eigen_cholesky(void) : CppAD::atomic_base( - "atom_eigen_cholesky" , - CppAD::atomic_base::set_sparsity_enum - ) - { } -/* %$$ -$subhead op$$ -$srccode%cpp% */ - // use atomic operation to invert an AD matrix - ad_matrix op(const ad_matrix& arg) - { size_t nr = size_t( arg.rows() ); - size_t ny = ( (nr + 1 ) * nr ) / 2; - size_t nx = 1 + ny; - assert( nr == size_t( arg.cols() ) ); - // ------------------------------------------------------------------- - // packed version of arg - CPPAD_TESTVECTOR(ad_scalar) packed_arg(nx); - size_t index = 0; - packed_arg[index++] = ad_scalar( nr ); - // lower triangle of symmetric matrix A - for(size_t i = 0; i < nr; i++) - { for(size_t j = 0; j <= i; j++) - packed_arg[index++] = arg( long(i), long(j) ); - } - assert( index == nx ); - // ------------------------------------------------------------------- - // packed version of result = arg^{-1}. - // This is an atomic_base function call that CppAD uses to - // store the atomic operation on the tape. - CPPAD_TESTVECTOR(ad_scalar) packed_result(ny); - (*this)(packed_arg, packed_result); - // ------------------------------------------------------------------- - // unpack result matrix L - ad_matrix result = ad_matrix::Zero( long(nr), long(nr) ); - index = 0; - for(size_t i = 0; i < nr; i++) - { for(size_t j = 0; j <= i; j++) - result( long(i), long(j) ) = packed_result[index++]; - } - return result; - } - /* %$$ -$head Private$$ - -$subhead Variables$$ -$srccode%cpp% */ -private: - // ------------------------------------------------------------- - // one forward mode vector of matrices for argument and result - CppAD::vector f_arg_, f_result_; - // one reverse mode vector of matrices for argument and result - CppAD::vector r_arg_, r_result_; - // ------------------------------------------------------------- -/* %$$ -$subhead forward$$ -$srccode%cpp% */ - // forward mode routine called by CppAD - virtual bool forward( - // lowest order Taylor coefficient we are evaluating - size_t p , - // highest order Taylor coefficient we are evaluating - size_t q , - // which components of x are variables - const CppAD::vector& vx , - // which components of y are variables - CppAD::vector& vy , - // tx [ j * (q+1) + k ] is x_j^k - const CppAD::vector& tx , - // ty [ i * (q+1) + k ] is y_i^k - CppAD::vector& ty - ) - { size_t n_order = q + 1; - size_t nr = size_t( CppAD::Integer( tx[ 0 * n_order + 0 ] ) ); - size_t ny = ((nr + 1) * nr) / 2; -# ifndef NDEBUG - size_t nx = 1 + ny; -# endif - assert( vx.size() == 0 || nx == vx.size() ); - assert( vx.size() == 0 || ny == vy.size() ); - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - // - // ------------------------------------------------------------------- - // make sure f_arg_ and f_result_ are large enough - assert( f_arg_.size() == f_result_.size() ); - if( f_arg_.size() < n_order ) - { f_arg_.resize(n_order); - f_result_.resize(n_order); - // - for(size_t k = 0; k < n_order; k++) - { f_arg_[k].resize( long(nr), long(nr) ); - f_result_[k].resize( long(nr), long(nr) ); - } - } - // ------------------------------------------------------------------- - // unpack tx into f_arg_ - for(size_t k = 0; k < n_order; k++) - { size_t index = 1; - // unpack arg values for this order - for(long i = 0; i < long(nr); i++) - { for(long j = 0; j <= i; j++) - { f_arg_[k](i, j) = tx[ index * n_order + k ]; - f_arg_[k](j, i) = f_arg_[k](i, j); - index++; - } - } - } - // ------------------------------------------------------------------- - // result for each order - // (we could avoid recalculting f_result_[k] for k=0,...,p-1) - // - Eigen::LLT cholesky(f_arg_[0]); - f_result_[0] = cholesky.matrixL(); - lower_view L_0 = f_result_[0].template triangularView(); - for(size_t k = 1; k < n_order; k++) - { // initialize sum as A_k - matrix f_sum = f_arg_[k]; - // compute A_k - B_k - for(size_t ell = 1; ell < k; ell++) - f_sum -= f_result_[ell] * f_result_[k-ell].transpose(); - // compute L_0^{-1} * (A_k - B_k) * L_0^{-T} - matrix temp = L_0.template solve(f_sum); - temp = L_0.transpose().template solve(temp); - // divide the diagonal by 2 - for(long i = 0; i < long(nr); i++) - temp(i, i) /= scalar(2.0); - // L_k = L_0 * low[ L_0^{-1} * (A_k - B_k) * L_0^{-T} ] - lower_view view = temp.template triangularView(); - f_result_[k] = f_result_[0] * view; - } - // ------------------------------------------------------------------- - // pack result_ into ty - for(size_t k = 0; k < n_order; k++) - { size_t index = 0; - for(long i = 0; i < long(nr); i++) - { for(long j = 0; j <= i; j++) - { ty[ index * n_order + k ] = f_result_[k](i, j); - index++; - } - } - } - // ------------------------------------------------------------------- - // check if we are computing vy - if( vx.size() == 0 ) - return true; - // ------------------------------------------------------------------ - // This is a very dumb algorithm that over estimates which - // elements of the inverse are variables (which is not efficient). - bool var = false; - for(size_t i = 0; i < ny; i++) - var |= vx[1 + i]; - for(size_t i = 0; i < ny; i++) - vy[i] = var; - // - return true; - } -/* %$$ -$subhead reverse$$ -$srccode%cpp% */ - // reverse mode routine called by CppAD - virtual bool reverse( - // highest order Taylor coefficient that we are computing derivative of - size_t q , - // forward mode Taylor coefficients for x variables - const CppAD::vector& tx , - // forward mode Taylor coefficients for y variables - const CppAD::vector& ty , - // upon return, derivative of G[ F[ {x_j^k} ] ] w.r.t {x_j^k} - CppAD::vector& px , - // derivative of G[ {y_i^k} ] w.r.t. {y_i^k} - const CppAD::vector& py - ) - { size_t n_order = q + 1; - size_t nr = size_t( CppAD::Integer( tx[ 0 * n_order + 0 ] ) ); -# ifndef NDEBUG - size_t ny = ( (nr + 1 ) * nr ) / 2; - size_t nx = 1 + ny; -# endif - // - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - assert( px.size() == tx.size() ); - assert( py.size() == ty.size() ); - // ------------------------------------------------------------------- - // make sure f_arg_ is large enough - assert( f_arg_.size() == f_result_.size() ); - // must have previous run forward with order >= n_order - assert( f_arg_.size() >= n_order ); - // ------------------------------------------------------------------- - // make sure r_arg_, r_result_ are large enough - assert( r_arg_.size() == r_result_.size() ); - if( r_arg_.size() < n_order ) - { r_arg_.resize(n_order); - r_result_.resize(n_order); - // - for(size_t k = 0; k < n_order; k++) - { r_arg_[k].resize( long(nr), long(nr) ); - r_result_[k].resize( long(nr), long(nr) ); - } - } - // ------------------------------------------------------------------- - // unpack tx into f_arg_ - for(size_t k = 0; k < n_order; k++) - { size_t index = 1; - // unpack arg values for this order - for(long i = 0; i < long(nr); i++) - { for(long j = 0; j <= i; j++) - { f_arg_[k](i, j) = tx[ index * n_order + k ]; - f_arg_[k](j, i) = f_arg_[k](i, j); - index++; - } - } - } - // ------------------------------------------------------------------- - // unpack py into r_result_ - for(size_t k = 0; k < n_order; k++) - { r_result_[k] = matrix::Zero( long(nr), long(nr) ); - size_t index = 0; - for(long i = 0; i < long(nr); i++) - { for(long j = 0; j <= i; j++) - { r_result_[k](i, j) = py[ index * n_order + k ]; - index++; - } - } - } - // ------------------------------------------------------------------- - // initialize r_arg_ as zero - for(size_t k = 0; k < n_order; k++) - r_arg_[k] = matrix::Zero( long(nr), long(nr) ); - // ------------------------------------------------------------------- - // matrix reverse mode calculation - lower_view L_0 = f_result_[0].template triangularView(); - // - for(size_t k1 = n_order; k1 > 1; k1--) - { size_t k = k1 - 1; - // - // L_0^T * bar{L}_k - matrix tmp1 = L_0.transpose() * r_result_[k]; - // - //low[ L_0^T * bar{L}_k ] - for(long i = 0; i < long(nr); i++) - tmp1(i, i) /= scalar(2.0); - matrix tmp2 = tmp1.template triangularView(); - // - // L_0^{-T} low[ L_0^T * bar{L}_k ] - tmp1 = L_0.transpose().template solve( tmp2 ); - // - // M_k = L_0^{-T} * low[ L_0^T * bar{L}_k ]^{T} L_0^{-1} - matrix M_k = L_0.transpose().template - solve( tmp1.transpose() ); - // - // remove L_k and compute bar{B}_k - matrix barB_k = scalar(0.5) * ( M_k + M_k.transpose() ); - r_arg_[k] += barB_k; - barB_k = scalar(-1.0) * barB_k; - // - // 2.0 * lower( bar{B}_k L_k ) - matrix temp = scalar(2.0) * barB_k * f_result_[k]; - temp = temp.template triangularView(); - // - // remove C_k - r_result_[0] += temp; - // - // remove B_k - for(size_t ell = 1; ell < k; ell++) - { // bar{L}_ell = 2 * lower( \bar{B}_k * L_{k-ell} ) - temp = scalar(2.0) * barB_k * f_result_[k-ell]; - r_result_[ell] += temp.template triangularView(); - } - } - // M_0 = L_0^{-T} * low[ L_0^T * bar{L}_0 ]^{T} L_0^{-1} - matrix M_0 = L_0.transpose() * r_result_[0]; - for(long i = 0; i < long(nr); i++) - M_0(i, i) /= scalar(2.0); - M_0 = M_0.template triangularView(); - M_0 = L_0.template solve( M_0 ); - M_0 = L_0.transpose().template solve( M_0 ); - // remove L_0 - r_arg_[0] += scalar(0.5) * ( M_0 + M_0.transpose() ); - // ------------------------------------------------------------------- - // pack r_arg into px - // note that only the lower triangle of barA_k is stored in px - for(size_t k = 0; k < n_order; k++) - { size_t index = 0; - px[ index * n_order + k ] = 0.0; - index++; - for(long i = 0; i < long(nr); i++) - { for(long j = 0; j < i; j++) - { px[ index * n_order + k ] = 2.0 * r_arg_[k](i, j); - index++; - } - px[ index * n_order + k] = r_arg_[k](i, i); - index++; - } - } - // ------------------------------------------------------------------- - return true; - } -/* %$$ -$head End Class Definition$$ -$srccode%cpp% */ -}; // End of atomic_eigen_cholesky class - -} // END_EMPTY_NAMESPACE -/* %$$ -$end -*/ - - -# endif diff --git a/build-config/cppad/include/cppad/example/atomic_two/eigen_mat_inv.hpp b/build-config/cppad/include/cppad/example/atomic_two/eigen_mat_inv.hpp deleted file mode 100644 index 41b242e9..00000000 --- a/build-config/cppad/include/cppad/example/atomic_two/eigen_mat_inv.hpp +++ /dev/null @@ -1,395 +0,0 @@ -# ifndef CPPAD_EXAMPLE_ATOMIC_TWO_EIGEN_MAT_INV_HPP -# define CPPAD_EXAMPLE_ATOMIC_TWO_EIGEN_MAT_INV_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin atomic_two_eigen_mat_inv.hpp$$ -$spell - Eigen - Taylor -$$ - -$section atomic_two Eigen Matrix Inversion Class$$ - -$head Purpose$$ -Construct an atomic operation that computes the matrix inverse -$latex R = A^{-1}$$ -for any positive integer $latex p$$ -and invertible matrix $latex A \in \B{R}^{p \times p}$$. - -$head Matrix Dimensions$$ -This example puts the matrix dimension $latex p$$ -in the atomic function arguments, -instead of the $cref/constructor/atomic_two_ctor/$$, -so it can be different for different calls to the atomic function. - -$head Theory$$ - -$subhead Forward$$ -The zero order forward mode Taylor coefficient is give by -$latex \[ - R_0 = A_0^{-1} -\]$$ -For $latex k = 1 , \ldots$$, -the $th k$$ order Taylor coefficient of $latex A R$$ is given by -$latex \[ - 0 = \sum_{\ell=0}^k A_\ell R_{k-\ell} -\] $$ -Solving for $latex R_k$$ in terms of the coefficients -for $latex A$$ and the lower order coefficients for $latex R$$ we have -$latex \[ - R_k = - R_0 \left( \sum_{\ell=1}^k A_\ell R_{k-\ell} \right) -\] $$ -Furthermore, once we have $latex R_k$$ we can compute the sum using -$latex \[ - A_0 R_k = - \left( \sum_{\ell=1}^k A_\ell R_{k-\ell} \right) -\] $$ - - -$subhead Product of Three Matrices$$ -Suppose $latex \bar{E}$$ is the derivative of the -scalar value function $latex s(E)$$ with respect to $latex E$$; i.e., -$latex \[ - \bar{E}_{i,j} = \frac{ \partial s } { \partial E_{i,j} } -\] $$ -Also suppose that $latex t$$ is a scalar valued argument and -$latex \[ - E(t) = B(t) C(t) D(t) -\] $$ -It follows that -$latex \[ - E'(t) = B'(t) C(t) D(t) + B(t) C'(t) D(t) + B(t) C(t) D'(t) -\] $$ - -$latex \[ - (s \circ E)'(t) - = - \R{tr} [ \bar{E}^\R{T} E'(t) ] -\] $$ -$latex \[ - = - \R{tr} [ \bar{E}^\R{T} B'(t) C(t) D(t) ] + - \R{tr} [ \bar{E}^\R{T} B(t) C'(t) D(t) ] + - \R{tr} [ \bar{E}^\R{T} B(t) C(t) D'(t) ] -\] $$ -$latex \[ - = - \R{tr} [ B(t) D(t) \bar{E}^\R{T} B'(t) ] + - \R{tr} [ D(t) \bar{E}^\R{T} B(t) C'(t) ] + - \R{tr} [ \bar{E}^\R{T} B(t) C(t) D'(t) ] -\] $$ -$latex \[ - \bar{B} = \bar{E} (C D)^\R{T} \W{,} - \bar{C} = \B{R}^\R{T} \bar{E} D^\R{T} \W{,} - \bar{D} = (B C)^\R{T} \bar{E} -\] $$ - -$subhead Reverse$$ -For $latex k > 0$$, reverse mode -eliminates $latex R_k$$ and expresses the function values -$latex s$$ in terms of the coefficients of $latex A$$ -and the lower order coefficients of $latex R$$. -The effect on $latex \bar{R}_0$$ -(of eliminating $latex R_k$$) is -$latex \[ -\bar{R}_0 -= \bar{R}_0 - \bar{R}_k \left( \sum_{\ell=1}^k A_\ell R_{k-\ell} \right)^\R{T} -= \bar{R}_0 + \bar{R}_k ( A_0 R_k )^\R{T} -\] $$ -For $latex \ell = 1 , \ldots , k$$, -the effect on $latex \bar{R}_{k-\ell}$$ and $latex A_\ell$$ -(of eliminating $latex R_k$$) is -$latex \[ -\bar{A}_\ell = \bar{A}_\ell - R_0^\R{T} \bar{R}_k R_{k-\ell}^\R{T} -\] $$ -$latex \[ -\bar{R}_{k-\ell} = \bar{R}_{k-\ell} - ( R_0 A_\ell )^\R{T} \bar{R}_k -\] $$ -We note that -$latex \[ - R_0 '(t) A_0 (t) + R_0 (t) A_0 '(t) = 0 -\] $$ -$latex \[ - R_0 '(t) = - R_0 (t) A_0 '(t) R_0 (t) -\] $$ -The reverse mode formula that eliminates $latex R_0$$ is -$latex \[ - \bar{A}_0 - = \bar{A}_0 - R_0^\R{T} \bar{R}_0 R_0^\R{T} -\]$$ - -$nospell - -$head Start Class Definition$$ -$srccode%cpp% */ -# include -# include -# include - - - -/* %$$ -$head Public$$ - -$subhead Types$$ -$srccode%cpp% */ -namespace { // BEGIN_EMPTY_NAMESPACE - -template -class atomic_eigen_mat_inv : public CppAD::atomic_base { -public: - // ----------------------------------------------------------- - // type of elements during calculation of derivatives - typedef Base scalar; - // type of elements during taping - typedef CppAD::AD ad_scalar; - // type of matrix during calculation of derivatives - typedef Eigen::Matrix< - scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> matrix; - // type of matrix during taping - typedef Eigen::Matrix< - ad_scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > ad_matrix; -/* %$$ -$subhead Constructor$$ -$srccode%cpp% */ - // constructor - atomic_eigen_mat_inv(void) : CppAD::atomic_base( - "atom_eigen_mat_inv" , - CppAD::atomic_base::set_sparsity_enum - ) - { } -/* %$$ -$subhead op$$ -$srccode%cpp% */ - // use atomic operation to invert an AD matrix - ad_matrix op(const ad_matrix& arg) - { size_t nr = size_t( arg.rows() ); - size_t ny = nr * nr; - size_t nx = 1 + ny; - assert( nr == size_t( arg.cols() ) ); - // ------------------------------------------------------------------- - // packed version of arg - CPPAD_TESTVECTOR(ad_scalar) packed_arg(nx); - packed_arg[0] = ad_scalar( nr ); - for(size_t i = 0; i < ny; i++) - packed_arg[1 + i] = arg.data()[i]; - // ------------------------------------------------------------------- - // packed version of result = arg^{-1}. - // This is an atomic_base function call that CppAD uses to - // store the atomic operation on the tape. - CPPAD_TESTVECTOR(ad_scalar) packed_result(ny); - (*this)(packed_arg, packed_result); - // ------------------------------------------------------------------- - // unpack result matrix - ad_matrix result(nr, nr); - for(size_t i = 0; i < ny; i++) - result.data()[i] = packed_result[i]; - return result; - } - /* %$$ -$head Private$$ - -$subhead Variables$$ -$srccode%cpp% */ -private: - // ------------------------------------------------------------- - // one forward mode vector of matrices for argument and result - CppAD::vector f_arg_, f_result_; - // one reverse mode vector of matrices for argument and result - CppAD::vector r_arg_, r_result_; - // ------------------------------------------------------------- -/* %$$ -$subhead forward$$ -$srccode%cpp% */ - // forward mode routine called by CppAD - virtual bool forward( - // lowest order Taylor coefficient we are evaluating - size_t p , - // highest order Taylor coefficient we are evaluating - size_t q , - // which components of x are variables - const CppAD::vector& vx , - // which components of y are variables - CppAD::vector& vy , - // tx [ j * (q+1) + k ] is x_j^k - const CppAD::vector& tx , - // ty [ i * (q+1) + k ] is y_i^k - CppAD::vector& ty - ) - { size_t n_order = q + 1; - size_t nr = size_t( CppAD::Integer( tx[ 0 * n_order + 0 ] ) ); - size_t ny = nr * nr; -# ifndef NDEBUG - size_t nx = 1 + ny; -# endif - assert( vx.size() == 0 || nx == vx.size() ); - assert( vx.size() == 0 || ny == vy.size() ); - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - // - // ------------------------------------------------------------------- - // make sure f_arg_ and f_result_ are large enough - assert( f_arg_.size() == f_result_.size() ); - if( f_arg_.size() < n_order ) - { f_arg_.resize(n_order); - f_result_.resize(n_order); - // - for(size_t k = 0; k < n_order; k++) - { f_arg_[k].resize( long(nr), long(nr) ); - f_result_[k].resize( long(nr), long(nr) ); - } - } - // ------------------------------------------------------------------- - // unpack tx into f_arg_ - for(size_t k = 0; k < n_order; k++) - { // unpack arg values for this order - for(size_t i = 0; i < ny; i++) - f_arg_[k].data()[i] = tx[ (1 + i) * n_order + k ]; - } - // ------------------------------------------------------------------- - // result for each order - // (we could avoid recalculting f_result_[k] for k=0,...,p-1) - // - f_result_[0] = f_arg_[0].inverse(); - for(size_t k = 1; k < n_order; k++) - { // initialize sum - matrix f_sum = matrix::Zero( long(nr), long(nr) ); - // compute sum - for(size_t ell = 1; ell <= k; ell++) - f_sum -= f_arg_[ell] * f_result_[k-ell]; - // result_[k] = arg_[0]^{-1} * sum_ - f_result_[k] = f_result_[0] * f_sum; - } - // ------------------------------------------------------------------- - // pack result_ into ty - for(size_t k = 0; k < n_order; k++) - { for(size_t i = 0; i < ny; i++) - ty[ i * n_order + k ] = f_result_[k].data()[i]; - } - // ------------------------------------------------------------------- - // check if we are computing vy - if( vx.size() == 0 ) - return true; - // ------------------------------------------------------------------ - // This is a very dumb algorithm that over estimates which - // elements of the inverse are variables (which is not efficient). - bool var = false; - for(size_t i = 0; i < ny; i++) - var |= vx[1 + i]; - for(size_t i = 0; i < ny; i++) - vy[i] = var; - return true; - } -/* %$$ -$subhead reverse$$ -$srccode%cpp% */ - // reverse mode routine called by CppAD - virtual bool reverse( - // highest order Taylor coefficient that we are computing derivative of - size_t q , - // forward mode Taylor coefficients for x variables - const CppAD::vector& tx , - // forward mode Taylor coefficients for y variables - const CppAD::vector& ty , - // upon return, derivative of G[ F[ {x_j^k} ] ] w.r.t {x_j^k} - CppAD::vector& px , - // derivative of G[ {y_i^k} ] w.r.t. {y_i^k} - const CppAD::vector& py - ) - { size_t n_order = q + 1; - size_t nr = size_t( CppAD::Integer( tx[ 0 * n_order + 0 ] ) ); - size_t ny = nr * nr; -# ifndef NDEBUG - size_t nx = 1 + ny; -# endif - // - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - assert( px.size() == tx.size() ); - assert( py.size() == ty.size() ); - // ------------------------------------------------------------------- - // make sure f_arg_ is large enough - assert( f_arg_.size() == f_result_.size() ); - // must have previous run forward with order >= n_order - assert( f_arg_.size() >= n_order ); - // ------------------------------------------------------------------- - // make sure r_arg_, r_result_ are large enough - assert( r_arg_.size() == r_result_.size() ); - if( r_arg_.size() < n_order ) - { r_arg_.resize(n_order); - r_result_.resize(n_order); - // - for(size_t k = 0; k < n_order; k++) - { r_arg_[k].resize( long(nr), long(nr) ); - r_result_[k].resize( long(nr), long(nr) ); - } - } - // ------------------------------------------------------------------- - // unpack tx into f_arg_ - for(size_t k = 0; k < n_order; k++) - { // unpack arg values for this order - for(size_t i = 0; i < ny; i++) - f_arg_[k].data()[i] = tx[ (1 + i) * n_order + k ]; - } - // ------------------------------------------------------------------- - // unpack py into r_result_ - for(size_t k = 0; k < n_order; k++) - { for(size_t i = 0; i < ny; i++) - r_result_[k].data()[i] = py[ i * n_order + k ]; - } - // ------------------------------------------------------------------- - // initialize r_arg_ as zero - for(size_t k = 0; k < n_order; k++) - r_arg_[k] = matrix::Zero( long(nr), long(nr) ); - // ------------------------------------------------------------------- - // matrix reverse mode calculation - // - for(size_t k1 = n_order; k1 > 1; k1--) - { size_t k = k1 - 1; - // bar{R}_0 = bar{R}_0 + bar{R}_k (A_0 R_k)^T - r_result_[0] += - r_result_[k] * f_result_[k].transpose() * f_arg_[0].transpose(); - // - for(size_t ell = 1; ell <= k; ell++) - { // bar{A}_l = bar{A}_l - R_0^T bar{R}_k R_{k-l}^T - r_arg_[ell] -= f_result_[0].transpose() - * r_result_[k] * f_result_[k-ell].transpose(); - // bar{R}_{k-l} = bar{R}_{k-1} - (R_0 A_l)^T bar{R}_k - r_result_[k-ell] -= f_arg_[ell].transpose() - * f_result_[0].transpose() * r_result_[k]; - } - } - r_arg_[0] -= - f_result_[0].transpose() * r_result_[0] * f_result_[0].transpose(); - // ------------------------------------------------------------------- - // pack r_arg into px - for(size_t k = 0; k < n_order; k++) - { for(size_t i = 0; i < ny; i++) - px[ (1 + i) * n_order + k ] = r_arg_[k].data()[i]; - } - // - return true; - } -/* %$$ -$head End Class Definition$$ -$srccode%cpp% */ -}; // End of atomic_eigen_mat_inv class - -} // END_EMPTY_NAMESPACE -/* %$$ -$$ $comment end nospell$$ -$end -*/ - - -# endif diff --git a/build-config/cppad/include/cppad/example/atomic_two/eigen_mat_mul.hpp b/build-config/cppad/include/cppad/example/atomic_two/eigen_mat_mul.hpp deleted file mode 100644 index d8a4c7e6..00000000 --- a/build-config/cppad/include/cppad/example/atomic_two/eigen_mat_mul.hpp +++ /dev/null @@ -1,658 +0,0 @@ -# ifndef CPPAD_EXAMPLE_ATOMIC_TWO_EIGEN_MAT_MUL_HPP -# define CPPAD_EXAMPLE_ATOMIC_TWO_EIGEN_MAT_MUL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin atomic_two_eigen_mat_mul.hpp$$ -$spell - Eigen - Taylor - nr - nc -$$ - -$section atomic_two Eigen Matrix Multiply Class$$ - -$head See Also$$ -$cref atomic_three_mat_mul.hpp$$ - -$head Purpose$$ -Construct an atomic operation that computes the matrix product, -$latex R = A \times \B{R}$$ -for any positive integers $latex r$$, $latex m$$, $latex c$$, -and any $latex A \in \B{R}^{r \times m}$$, -$latex B \in \B{R}^{m \times c}$$. - -$head Matrix Dimensions$$ -This example puts the matrix dimensions in the atomic function arguments, -instead of the $cref/constructor/atomic_two_ctor/$$, so that they can -be different for different calls to the atomic function. -These dimensions are: -$table -$icode nr_left$$ - $cnext number of rows in the left matrix; i.e, $latex r$$ $rend -$icode n_middle$$ - $cnext rows in the left matrix and columns in right; i.e, $latex m$$ $rend -$icode nc_right$$ - $cnext number of columns in the right matrix; i.e., $latex c$$ -$tend - -$head Theory$$ - -$subhead Forward$$ -For $latex k = 0 , \ldots $$, the $th k$$ order Taylor coefficient -$latex R_k$$ is given by -$latex \[ - R_k = \sum_{\ell = 0}^{k} A_\ell B_{k-\ell} -\] $$ - -$subhead Product of Two Matrices$$ -Suppose $latex \bar{E}$$ is the derivative of the -scalar value function $latex s(E)$$ with respect to $latex E$$; i.e., -$latex \[ - \bar{E}_{i,j} = \frac{ \partial s } { \partial E_{i,j} } -\] $$ -Also suppose that $latex t$$ is a scalar valued argument and -$latex \[ - E(t) = C(t) D(t) -\] $$ -It follows that -$latex \[ - E'(t) = C'(t) D(t) + C(t) D'(t) -\] $$ - -$latex \[ - (s \circ E)'(t) - = - \R{tr} [ \bar{E}^\R{T} E'(t) ] -\] $$ -$latex \[ - = - \R{tr} [ \bar{E}^\R{T} C'(t) D(t) ] + - \R{tr} [ \bar{E}^\R{T} C(t) D'(t) ] -\] $$ -$latex \[ - = - \R{tr} [ D(t) \bar{E}^\R{T} C'(t) ] + - \R{tr} [ \bar{E}^\R{T} C(t) D'(t) ] -\] $$ -$latex \[ - \bar{C} = \bar{E} D^\R{T} \W{,} - \bar{D} = C^\R{T} \bar{E} -\] $$ - -$subhead Reverse$$ -Reverse mode eliminates $latex R_k$$ as follows: -for $latex \ell = 0, \ldots , k-1$$, -$latex \[ -\bar{A}_\ell = \bar{A}_\ell + \bar{R}_k B_{k-\ell}^\R{T} -\] $$ -$latex \[ -\bar{B}_{k-\ell} = \bar{B}_{k-\ell} + A_\ell^\R{T} \bar{R}_k -\] $$ - - -$nospell - -$head Start Class Definition$$ -$srccode%cpp% */ -# include -# include - - -/* %$$ -$head Public$$ - -$subhead Types$$ -$srccode%cpp% */ -namespace { // BEGIN_EMPTY_NAMESPACE - -template -class atomic_eigen_mat_mul : public CppAD::atomic_base { -public: - // ----------------------------------------------------------- - // type of elements during calculation of derivatives - typedef Base scalar; - // type of elements during taping - typedef CppAD::AD ad_scalar; - // type of matrix during calculation of derivatives - typedef Eigen::Matrix< - scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> matrix; - // type of matrix during taping - typedef Eigen::Matrix< - ad_scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > ad_matrix; -/* %$$ -$subhead Constructor$$ -$srccode%cpp% */ - // constructor - atomic_eigen_mat_mul(void) : CppAD::atomic_base( - "atom_eigen_mat_mul" , - CppAD::atomic_base::set_sparsity_enum - ) - { } -/* %$$ -$subhead op$$ -$srccode%cpp% */ - // use atomic operation to multiply two AD matrices - ad_matrix op( - const ad_matrix& left , - const ad_matrix& right ) - { size_t nr_left = size_t( left.rows() ); - size_t n_middle = size_t( left.cols() ); - size_t nc_right = size_t( right.cols() ); - assert( n_middle == size_t( right.rows() ) ); - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t ny = nr_left * nc_right; - size_t n_left = nr_left * n_middle; - size_t n_right = n_middle * nc_right; - size_t n_result = nr_left * nc_right; - // - assert( 3 + n_left + n_right == nx ); - assert( n_result == ny ); - // ----------------------------------------------------------------- - // packed version of left and right - CPPAD_TESTVECTOR(ad_scalar) packed_arg(nx); - // - packed_arg[0] = ad_scalar( nr_left ); - packed_arg[1] = ad_scalar( n_middle ); - packed_arg[2] = ad_scalar( nc_right ); - for(size_t i = 0; i < n_left; i++) - packed_arg[3 + i] = left.data()[i]; - for(size_t i = 0; i < n_right; i++) - packed_arg[ 3 + n_left + i ] = right.data()[i]; - // ------------------------------------------------------------------ - // Packed version of result = left * right. - // This as an atomic_base funciton call that CppAD uses - // to store the atomic operation on the tape. - CPPAD_TESTVECTOR(ad_scalar) packed_result(ny); - (*this)(packed_arg, packed_result); - // ------------------------------------------------------------------ - // unpack result matrix - ad_matrix result(nr_left, nc_right); - for(size_t i = 0; i < n_result; i++) - result.data()[i] = packed_result[ i ]; - // - return result; - } -/* %$$ -$head Private$$ - -$subhead Variables$$ -$srccode%cpp% */ -private: - // ------------------------------------------------------------- - // one forward mode vector of matrices for left, right, and result - CppAD::vector f_left_, f_right_, f_result_; - // one reverse mode vector of matrices for left, right, and result - CppAD::vector r_left_, r_right_, r_result_; - // ------------------------------------------------------------- -/* %$$ -$subhead forward$$ -$srccode%cpp% */ - // forward mode routine called by CppAD - virtual bool forward( - // lowest order Taylor coefficient we are evaluating - size_t p , - // highest order Taylor coefficient we are evaluating - size_t q , - // which components of x are variables - const CppAD::vector& vx , - // which components of y are variables - CppAD::vector& vy , - // tx [ 3 + j * (q+1) + k ] is x_j^k - const CppAD::vector& tx , - // ty [ i * (q+1) + k ] is y_i^k - CppAD::vector& ty - ) - { size_t n_order = q + 1; - size_t nr_left = size_t( CppAD::Integer( tx[ 0 * n_order + 0 ] ) ); - size_t n_middle = size_t( CppAD::Integer( tx[ 1 * n_order + 0 ] ) ); - size_t nc_right = size_t( CppAD::Integer( tx[ 2 * n_order + 0 ] ) ); -# ifndef NDEBUG - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t ny = nr_left * nc_right; -# endif - // - assert( vx.size() == 0 || nx == vx.size() ); - assert( vx.size() == 0 || ny == vy.size() ); - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - // - size_t n_left = nr_left * n_middle; - size_t n_right = n_middle * nc_right; - size_t n_result = nr_left * nc_right; - assert( 3 + n_left + n_right == nx ); - assert( n_result == ny ); - // - // ------------------------------------------------------------------- - // make sure f_left_, f_right_, and f_result_ are large enough - assert( f_left_.size() == f_right_.size() ); - assert( f_left_.size() == f_result_.size() ); - if( f_left_.size() < n_order ) - { f_left_.resize(n_order); - f_right_.resize(n_order); - f_result_.resize(n_order); - // - for(size_t k = 0; k < n_order; k++) - { f_left_[k].resize( long(nr_left), long(n_middle) ); - f_right_[k].resize( long(n_middle), long(nc_right) ); - f_result_[k].resize( long(nr_left), long(nc_right) ); - } - } - // ------------------------------------------------------------------- - // unpack tx into f_left and f_right - for(size_t k = 0; k < n_order; k++) - { // unpack left values for this order - for(size_t i = 0; i < n_left; i++) - f_left_[k].data()[i] = tx[ (3 + i) * n_order + k ]; - // - // unpack right values for this order - for(size_t i = 0; i < n_right; i++) - f_right_[k].data()[i] = tx[ ( 3 + n_left + i) * n_order + k ]; - } - // ------------------------------------------------------------------- - // result for each order - // (we could avoid recalculting f_result_[k] for k=0,...,p-1) - for(size_t k = 0; k < n_order; k++) - { // result[k] = sum_ell left[ell] * right[k-ell] - f_result_[k] = matrix::Zero( long(nr_left), long(nc_right) ); - for(size_t ell = 0; ell <= k; ell++) - f_result_[k] += f_left_[ell] * f_right_[k-ell]; - } - // ------------------------------------------------------------------- - // pack result_ into ty - for(size_t k = 0; k < n_order; k++) - { for(size_t i = 0; i < n_result; i++) - ty[ i * n_order + k ] = f_result_[k].data()[i]; - } - // ------------------------------------------------------------------ - // check if we are computing vy - if( vx.size() == 0 ) - return true; - // ------------------------------------------------------------------ - // compute variable information for y; i.e., vy - // (note that the constant zero times a variable is a constant) - scalar zero(0.0); - assert( n_order == 1 ); - for(size_t i = 0; i < nr_left; i++) - { for(size_t j = 0; j < nc_right; j++) - { bool var = false; - for(size_t ell = 0; ell < n_middle; ell++) - { // left information - size_t index = 3 + i * n_middle + ell; - bool var_left = vx[index]; - bool nz_left = var_left | - (f_left_[0]( long(i), long(ell) ) != zero); - // right information - index = 3 + n_left + ell * nc_right + j; - bool var_right = vx[index]; - bool nz_right = var_right | - (f_right_[0]( long(ell), long(j) ) != zero); - // effect of result - var |= var_left & nz_right; - var |= nz_left & var_right; - } - size_t index = i * nc_right + j; - vy[index] = var; - } - } - return true; - } -/* %$$ -$subhead reverse$$ -$srccode%cpp% */ - // reverse mode routine called by CppAD - virtual bool reverse( - // highest order Taylor coefficient that we are computing derivative of - size_t q , - // forward mode Taylor coefficients for x variables - const CppAD::vector& tx , - // forward mode Taylor coefficients for y variables - const CppAD::vector& ty , - // upon return, derivative of G[ F[ {x_j^k} ] ] w.r.t {x_j^k} - CppAD::vector& px , - // derivative of G[ {y_i^k} ] w.r.t. {y_i^k} - const CppAD::vector& py - ) - { size_t n_order = q + 1; - size_t nr_left = size_t( CppAD::Integer( tx[ 0 * n_order + 0 ] ) ); - size_t n_middle = size_t( CppAD::Integer( tx[ 1 * n_order + 0 ] ) ); - size_t nc_right = size_t( CppAD::Integer( tx[ 2 * n_order + 0 ] ) ); -# ifndef NDEBUG - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t ny = nr_left * nc_right; -# endif - // - assert( nx * n_order == tx.size() ); - assert( ny * n_order == ty.size() ); - assert( px.size() == tx.size() ); - assert( py.size() == ty.size() ); - // - size_t n_left = nr_left * n_middle; - size_t n_right = n_middle * nc_right; - size_t n_result = nr_left * nc_right; - assert( 3 + n_left + n_right == nx ); - assert( n_result == ny ); - // ------------------------------------------------------------------- - // make sure f_left_, f_right_ are large enough - assert( f_left_.size() == f_right_.size() ); - assert( f_left_.size() == f_result_.size() ); - // must have previous run forward with order >= n_order - assert( f_left_.size() >= n_order ); - // ------------------------------------------------------------------- - // make sure r_left_, r_right_, and r_result_ are large enough - assert( r_left_.size() == r_right_.size() ); - assert( r_left_.size() == r_result_.size() ); - if( r_left_.size() < n_order ) - { r_left_.resize(n_order); - r_right_.resize(n_order); - r_result_.resize(n_order); - // - for(size_t k = 0; k < n_order; k++) - { r_left_[k].resize( long(nr_left), long(n_middle) ); - r_right_[k].resize( long(n_middle), long(nc_right) ); - r_result_[k].resize( long(nr_left), long(nc_right) ); - } - } - // ------------------------------------------------------------------- - // unpack tx into f_left and f_right - for(size_t k = 0; k < n_order; k++) - { // unpack left values for this order - for(size_t i = 0; i < n_left; i++) - f_left_[k].data()[i] = tx[ (3 + i) * n_order + k ]; - // - // unpack right values for this order - for(size_t i = 0; i < n_right; i++) - f_right_[k].data()[i] = tx[ (3 + n_left + i) * n_order + k ]; - } - // ------------------------------------------------------------------- - // unpack py into r_result_ - for(size_t k = 0; k < n_order; k++) - { for(size_t i = 0; i < n_result; i++) - r_result_[k].data()[i] = py[ i * n_order + k ]; - } - // ------------------------------------------------------------------- - // initialize r_left_ and r_right_ as zero - for(size_t k = 0; k < n_order; k++) - { r_left_[k] = matrix::Zero( long(nr_left), long(n_middle) ); - r_right_[k] = matrix::Zero( long(n_middle), long(nc_right) ); - } - // ------------------------------------------------------------------- - // matrix reverse mode calculation - for(size_t k1 = n_order; k1 > 0; k1--) - { size_t k = k1 - 1; - for(size_t ell = 0; ell <= k; ell++) - { // nr x nm = nr x nc * nc * nm - r_left_[ell] += r_result_[k] * f_right_[k-ell].transpose(); - // nm x nc = nm x nr * nr * nc - r_right_[k-ell] += f_left_[ell].transpose() * r_result_[k]; - } - } - // ------------------------------------------------------------------- - // pack r_left and r_right int px - for(size_t k = 0; k < n_order; k++) - { // dimensions are integer constants - px[ 0 * n_order + k ] = 0.0; - px[ 1 * n_order + k ] = 0.0; - px[ 2 * n_order + k ] = 0.0; - // - // pack left values for this order - for(size_t i = 0; i < n_left; i++) - px[ (3 + i) * n_order + k ] = r_left_[k].data()[i]; - // - // pack right values for this order - for(size_t i = 0; i < n_right; i++) - px[ (3 + i + n_left) * n_order + k] = r_right_[k].data()[i]; - } - // - return true; - } -/* %$$ -$subhead for_sparse_jac$$ -$srccode%cpp% */ - // forward Jacobian sparsity routine called by CppAD - virtual bool for_sparse_jac( - // number of columns in the matrix R - size_t q , - // sparsity pattern for the matrix R - const CppAD::vector< std::set >& r , - // sparsity pattern for the matrix S = f'(x) * R - CppAD::vector< std::set >& s , - const CppAD::vector& x ) - { - size_t nr_left = size_t( CppAD::Integer( x[0] ) ); - size_t n_middle = size_t( CppAD::Integer( x[1] ) ); - size_t nc_right = size_t( CppAD::Integer( x[2] ) ); -# ifndef NDEBUG - size_t nx = 3 + (nr_left + nc_right) * n_middle; - size_t ny = nr_left * nc_right; -# endif - // - assert( nx == r.size() ); - assert( ny == s.size() ); - // - size_t n_left = nr_left * n_middle; - for(size_t i = 0; i < nr_left; i++) - { for(size_t j = 0; j < nc_right; j++) - { // pack index for entry (i, j) in result - size_t i_result = i * nc_right + j; - s[i_result].clear(); - for(size_t ell = 0; ell < n_middle; ell++) - { // pack index for entry (i, ell) in left - size_t i_left = 3 + i * n_middle + ell; - // pack index for entry (ell, j) in right - size_t i_right = 3 + n_left + ell * nc_right + j; - // check if result of for this product is alwasy zero - // note that x is nan for commponents that are variables - bool zero = x[i_left] == Base(0.0) || x[i_right] == Base(0); - if( ! zero ) - { s[i_result] = - CppAD::set_union(s[i_result], r[i_left] ); - s[i_result] = - CppAD::set_union(s[i_result], r[i_right] ); - } - } - } - } - return true; - } -/* %$$ -$subhead rev_sparse_jac$$ -$srccode%cpp% */ - // reverse Jacobian sparsity routine called by CppAD - virtual bool rev_sparse_jac( - // number of columns in the matrix R^T - size_t q , - // sparsity pattern for the matrix R^T - const CppAD::vector< std::set >& rt , - // sparsoity pattern for the matrix S^T = f'(x)^T * R^T - CppAD::vector< std::set >& st , - const CppAD::vector& x ) - { - size_t nr_left = size_t( CppAD::Integer( x[0] ) ); - size_t n_middle = size_t( CppAD::Integer( x[1] ) ); - size_t nc_right = size_t( CppAD::Integer( x[2] ) ); - size_t nx = 3 + (nr_left + nc_right) * n_middle; -# ifndef NDEBUG - size_t ny = nr_left * nc_right; -# endif - // - assert( nx == st.size() ); - assert( ny == rt.size() ); - // - // initialize S^T as empty - for(size_t i = 0; i < nx; i++) - st[i].clear(); - - // sparsity for S(x)^T = f'(x)^T * R^T - size_t n_left = nr_left * n_middle; - for(size_t i = 0; i < nr_left; i++) - { for(size_t j = 0; j < nc_right; j++) - { // pack index for entry (i, j) in result - size_t i_result = i * nc_right + j; - st[i_result].clear(); - for(size_t ell = 0; ell < n_middle; ell++) - { // pack index for entry (i, ell) in left - size_t i_left = 3 + i * n_middle + ell; - // pack index for entry (ell, j) in right - size_t i_right = 3 + n_left + ell * nc_right + j; - // - st[i_left] = CppAD::set_union(st[i_left], rt[i_result]); - st[i_right] = CppAD::set_union(st[i_right], rt[i_result]); - } - } - } - return true; - } -/* %$$ -$subhead for_sparse_hes$$ -$srccode%cpp% */ - virtual bool for_sparse_hes( - // which components of x are variables for this call - const CppAD::vector& vx, - // sparsity pattern for the diagonal of R - const CppAD::vector& r , - // sparsity pattern for the vector S - const CppAD::vector& s , - // sparsity patternfor the Hessian H(x) - CppAD::vector< std::set >& h , - const CppAD::vector& x ) - { - size_t nr_left = size_t( CppAD::Integer( x[0] ) ); - size_t n_middle = size_t( CppAD::Integer( x[1] ) ); - size_t nc_right = size_t( CppAD::Integer( x[2] ) ); - size_t nx = 3 + (nr_left + nc_right) * n_middle; -# ifndef NDEBUG - size_t ny = nr_left * nc_right; -# endif - // - assert( vx.size() == nx ); - assert( r.size() == nx ); - assert( s.size() == ny ); - assert( h.size() == nx ); - // - // initilize h as empty - for(size_t i = 0; i < nx; i++) - h[i].clear(); - // - size_t n_left = nr_left * n_middle; - for(size_t i = 0; i < nr_left; i++) - { for(size_t j = 0; j < nc_right; j++) - { // pack index for entry (i, j) in result - size_t i_result = i * nc_right + j; - if( s[i_result] ) - { for(size_t ell = 0; ell < n_middle; ell++) - { // pack index for entry (i, ell) in left - size_t i_left = 3 + i * n_middle + ell; - // pack index for entry (ell, j) in right - size_t i_right = 3 + n_left + ell * nc_right + j; - if( r[i_left] & r[i_right] ) - { h[i_left].insert(i_right); - h[i_right].insert(i_left); - } - } - } - } - } - return true; - } -/* %$$ -$subhead rev_sparse_hes$$ -$srccode%cpp% */ - // reverse Hessian sparsity routine called by CppAD - virtual bool rev_sparse_hes( - // which components of x are variables for this call - const CppAD::vector& vx, - // sparsity pattern for S(x) = g'[f(x)] - const CppAD::vector& s , - // sparsity pattern for d/dx g[f(x)] = S(x) * f'(x) - CppAD::vector& t , - // number of columns in R, U(x), and V(x) - size_t q , - // sparsity pattern for R - const CppAD::vector< std::set >& r , - // sparsity pattern for U(x) = g^{(2)} [ f(x) ] * f'(x) * R - const CppAD::vector< std::set >& u , - // sparsity pattern for - // V(x) = f'(x)^T * U(x) + sum_{i=0}^{m-1} S_i(x) f_i^{(2)} (x) * R - CppAD::vector< std::set >& v , - // parameters as integers - const CppAD::vector& x ) - { - size_t nr_left = size_t( CppAD::Integer( x[0] ) ); - size_t n_middle = size_t( CppAD::Integer( x[1] ) ); - size_t nc_right = size_t( CppAD::Integer( x[2] ) ); - size_t nx = 3 + (nr_left + nc_right) * n_middle; -# ifndef NDEBUG - size_t ny = nr_left * nc_right; -# endif - // - assert( vx.size() == nx ); - assert( s.size() == ny ); - assert( t.size() == nx ); - assert( r.size() == nx ); - assert( v.size() == nx ); - // - // initilaize return sparsity patterns as false - for(size_t j = 0; j < nx; j++) - { t[j] = false; - v[j].clear(); - } - // - size_t n_left = nr_left * n_middle; - for(size_t i = 0; i < nr_left; i++) - { for(size_t j = 0; j < nc_right; j++) - { // pack index for entry (i, j) in result - size_t i_result = i * nc_right + j; - for(size_t ell = 0; ell < n_middle; ell++) - { // pack index for entry (i, ell) in left - size_t i_left = 3 + i * n_middle + ell; - // pack index for entry (ell, j) in right - size_t i_right = 3 + n_left + ell * nc_right + j; - // - // back propagate T(x) = S(x) * f'(x). - t[i_left] |= bool( s[i_result] ); - t[i_right] |= bool( s[i_result] ); - // - // V(x) = f'(x)^T * U(x) + sum_i S_i(x) * f_i''(x) * R - // U(x) = g''[ f(x) ] * f'(x) * R - // S_i(x) = g_i'[ f(x) ] - // - // back propagate f'(x)^T * U(x) - v[i_left] = CppAD::set_union(v[i_left], u[i_result] ); - v[i_right] = CppAD::set_union(v[i_right], u[i_result] ); - // - // back propagate S_i(x) * f_i''(x) * R - // (here is where we use vx to check for cross terms) - if( s[i_result] & vx[i_left] & vx[i_right] ) - { v[i_left] = CppAD::set_union(v[i_left], r[i_right] ); - v[i_right] = CppAD::set_union(v[i_right], r[i_left] ); - } - } - } - } - return true; - } -/* %$$ -$head End Class Definition$$ -$srccode%cpp% */ -}; // End of atomic_eigen_mat_mul class - -} // END_EMPTY_NAMESPACE -/* %$$ -$$ $comment end nospell$$ -$end -*/ - - -# endif diff --git a/build-config/cppad/include/cppad/example/base_adolc.hpp b/build-config/cppad/include/cppad/example/base_adolc.hpp deleted file mode 100644 index 009b8982..00000000 --- a/build-config/cppad/include/cppad/example/base_adolc.hpp +++ /dev/null @@ -1,359 +0,0 @@ -# ifndef CPPAD_EXAMPLE_BASE_ADOLC_HPP -# define CPPAD_EXAMPLE_BASE_ADOLC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin base_adolc.hpp$$ -$spell - stringstream - struct - string - setprecision - str - valgrind - azmul - expm1 - atanh - acosh - asinh - erf - erfc - ifndef - define - endif - Rel - codassign - eps - std - abs_geq - fabs - cppad.hpp - undef - Lt - Le - Eq - Ge - Gt - namespace - cassert - condassign - hpp - bool - const - Adolc - adouble - CondExpOp - inline - enum - CppAD - pow - acos - asin - atan - cos - cosh - exp - sqrt - atrig -$$ - - -$section Enable use of AD where Base is Adolc's adouble Type$$ - -$head Syntax$$ -$codei%# include -%$$ -$children% - example/general/mul_level_adolc.cpp -%$$ - -$head Example$$ -The file $cref mul_level_adolc.cpp$$ contains an example use of -Adolc's $code adouble$$ type for a CppAD $icode Base$$ type. -The file $cref mul_level_adolc_ode.cpp$$ contains a more realistic -(and complex) example. - -$head Include Files$$ -This file $code base_adolc.hpp$$ requires $code adouble$$ to be defined. -In addition, it is included before $code $$, -but it needs to include parts of CppAD that are used by this file. -This is done with the following include commands: -$srccode%cpp% */ -# include -# include -/* %$$ - -$head CondExpOp$$ -The type $code adouble$$ supports a conditional assignment function -with the syntax -$codei% - condassign(%a%, %b%, %c%, %d%) -%$$ -which evaluates to -$codei% - %a% = (%b% > 0) ? %c% : %d%; -%$$ -This enables one to include conditionals in the recording of -$code adouble$$ operations and later evaluation for different -values of the independent variables -(in the same spirit as the CppAD $cref CondExp$$ function). -$srccode%cpp% */ -namespace CppAD { - inline adouble CondExpOp( - enum CppAD::CompareOp cop , - const adouble &left , - const adouble &right , - const adouble &trueCase , - const adouble &falseCase ) - { adouble result; - switch( cop ) - { - case CompareLt: // left < right - condassign(result, right - left, trueCase, falseCase); - break; - - case CompareLe: // left <= right - condassign(result, left - right, falseCase, trueCase); - break; - - case CompareEq: // left == right - condassign(result, left - right, falseCase, trueCase); - condassign(result, right - left, falseCase, result); - break; - - case CompareGe: // left >= right - condassign(result, right - left, falseCase, trueCase); - break; - - case CompareGt: // left > right - condassign(result, left - right, trueCase, falseCase); - break; - default: - CppAD::ErrorHandler::Call( - true , __LINE__ , __FILE__ , - "CppAD::CondExp", - "Error: for unknown reason." - ); - result = trueCase; - } - return result; - } -} -/* %$$ - -$head CondExpRel$$ -The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation -$srccode%cpp% */ -namespace CppAD { - CPPAD_COND_EXP_REL(adouble) -} -/* %$$ - -$head EqualOpSeq$$ -The Adolc user interface does not specify a way to determine if -two $code adouble$$ variables correspond to the same operations sequence. -Make $code EqualOpSeq$$ an error if it gets used: -$srccode%cpp% */ -namespace CppAD { - inline bool EqualOpSeq(const adouble &x, const adouble &y) - { CppAD::ErrorHandler::Call( - true , __LINE__ , __FILE__ , - "CppAD::EqualOpSeq(x, y)", - "Error: adouble does not support EqualOpSeq." - ); - return false; - } -} -/* %$$ - -$head Identical$$ -The Adolc user interface does not specify a way to determine if an -$code adouble$$ depends on the independent variables. -To be safe (but slow) return $code false$$ in all the cases below. -$srccode%cpp% */ -namespace CppAD { - inline bool IdenticalCon(const adouble &x) - { return false; } - inline bool IdenticalZero(const adouble &x) - { return false; } - inline bool IdenticalOne(const adouble &x) - { return false; } - inline bool IdenticalEqualCon(const adouble &x, const adouble &y) - { return false; } -} -/* %$$ - -$head Integer$$ -$srccode%cpp% */ - inline int Integer(const adouble &x) - { return static_cast( x.getValue() ); } -/* %$$ - -$head azmul$$ -$srccode%cpp% */ -namespace CppAD { - CPPAD_AZMUL( adouble ) -} -/* %$$ - -$head Ordered$$ -$srccode%cpp% */ -namespace CppAD { - inline bool GreaterThanZero(const adouble &x) - { return (x > 0); } - inline bool GreaterThanOrZero(const adouble &x) - { return (x >= 0); } - inline bool LessThanZero(const adouble &x) - { return (x < 0); } - inline bool LessThanOrZero(const adouble &x) - { return (x <= 0); } - inline bool abs_geq(const adouble& x, const adouble& y) - { return fabs(x) >= fabs(y); } -} -/* %$$ - -$head Unary Standard Math$$ -The following $cref/required/base_require/$$ functions -are defined by the Adolc package for the $code adouble$$ base case: -$pre -$$ -$code acos$$, -$code acosh$$, -$code asin$$, -$code asinh$$, -$code atan$$, -$code atanh$$, -$code cos$$, -$code cosh$$, -$code erf$$, -$code exp$$, -$code fabs$$, -$code log$$, -$code sin$$, -$code sinh$$, -$code sqrt$$, -$code tan$$. - -$head erfc$$ -If you provide $code --enable-atrig-erf$$ on the configure command line, -the adolc package supports all the c++11 math functions except -$code erfc$$, $code expm1$$, and $code log1p$$. -For the reason, we make using $code erfc$$ an error: -$srccode%cpp% */ -namespace CppAD { -# define CPPAD_BASE_ADOLC_NO_SUPPORT(fun) \ - inline adouble fun(const adouble& x) \ - { CPPAD_ASSERT_KNOWN( \ - false, \ - #fun ": adolc does not support this function" \ - ); \ - return 0.0; \ - } - CPPAD_BASE_ADOLC_NO_SUPPORT(erfc) - CPPAD_BASE_ADOLC_NO_SUPPORT(expm1) - CPPAD_BASE_ADOLC_NO_SUPPORT(log1p) -# undef CPPAD_BASE_ADOLC_NO_SUPPORT -} -/* %$$ - -$head sign$$ -This $cref/required/base_require/$$ function is defined using the -$code codassign$$ function so that its $code adouble$$ operation sequence -does not depend on the value of $icode x$$. -$srccode%cpp% */ -namespace CppAD { - inline adouble sign(const adouble& x) - { adouble s_plus, s_minus, half(.5); - // set s_plus to sign(x)/2, except for case x == 0, s_plus = -.5 - condassign(s_plus, +x, -half, +half); - // set s_minus to -sign(x)/2, except for case x == 0, s_minus = -.5 - condassign(s_minus, -x, -half, +half); - // set s to sign(x) - return s_plus - s_minus; - } -} -/* %$$ - -$head abs$$ -This $cref/required/base_require/$$ function uses the adolc $code fabs$$ -function: -$srccode%cpp% */ -namespace CppAD { - inline adouble abs(const adouble& x) - { return fabs(x); } -} -/* %$$ - -$head pow$$ -This $cref/required/base_require/$$ function -is defined by the Adolc package for the $code adouble$$ base case. - -$head numeric_limits$$ -The following defines the CppAD $cref numeric_limits$$ -for the type $code adouble$$: -$srccode%cpp% */ -namespace CppAD { - CPPAD_NUMERIC_LIMITS(double, adouble) -} -/* %$$ - -$head to_string$$ -The following defines the CppAD $cref to_string$$ function -for the type $code adouble$$: -$srccode%cpp% */ -namespace CppAD { - template <> struct to_string_struct - { std::string operator()(const adouble& x) - { std::stringstream os; - int n_digits = 1 + std::numeric_limits::digits10; - os << std::setprecision(n_digits); - os << x.value(); - return os.str(); - } - }; -} -/* %$$ - -$head hash_code$$ -It appears that an $code adouble$$ object can have fields -that are not initialized. -This results in a $code valgrind$$ error when these fields are used by the -$cref/default/base_hash/Default/$$ hashing function. -For this reason, the $code adouble$$ class overrides the default definition. -$srccode|cpp| */ -namespace CppAD { - inline unsigned short hash_code(const adouble& x) - { unsigned short code = 0; - double value = x.value(); - if( value == 0.0 ) - return code; - double log_x = std::log( fabs( value ) ); - // assume log( std::numeric_limits::max() ) is near 700 - code = static_cast( - (CPPAD_HASH_TABLE_SIZE / 700 + 1) * log_x - ); - code = code % CPPAD_HASH_TABLE_SIZE; - return code; - } -} -/* |$$ -Note that after the hash codes match, the -$cref/Identical/base_adolc.hpp/Identical/$$ function will be used -to make sure two values are the same and one can replace the other. -A more sophisticated implementation of the $code Identical$$ function -would detect which $code adouble$$ values depend on the -$code adouble$$ independent variables (and hence can change). - - -$end -*/ -# endif diff --git a/build-config/cppad/include/cppad/example/code_gen_fun.hpp b/build-config/cppad/include/cppad/example/code_gen_fun.hpp deleted file mode 100644 index 6f7efdc5..00000000 --- a/build-config/cppad/include/cppad/example/code_gen_fun.hpp +++ /dev/null @@ -1,62 +0,0 @@ -# ifndef CPPAD_EXAMPLE_CODE_GEN_FUN_HPP -# define CPPAD_EXAMPLE_CODE_GEN_FUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -// BEGIN C++ -# include - -class code_gen_fun { -public: - // type of evaluation for Jacobians (possibly Hessians in the future) - enum evaluation_enum { none_enum, dense_enum, sparse_enum }; -private: - // dynamic_lib_ - std::unique_ptr< CppAD::cg::DynamicLib > dynamic_lib_; - // - // model_ (contains a reference to dynamic_lib_) - std::unique_ptr< CppAD::cg::GenericModel > model_; - // -public: - // ----------------------------------------------------------------------- - // constructors - // ----------------------------------------------------------------------- - // fun_name() - code_gen_fun(void); - // - // fun_name( file_name ) - code_gen_fun(const std::string& file_name); - // - // fun_name(file_name, cg_fun, eval_jac) - code_gen_fun( - const std::string& file_name , - CppAD::ADFun< CppAD::cg::CG >& cg_fun , - evaluation_enum eval_jac = none_enum - ); - // ----------------------------------------------------------------------- - // operations - // ----------------------------------------------------------------------- - // swap(other_fun) - void swap(code_gen_fun& other_fun); - // - // y = fun_name(x) - CppAD::vector operator()(const CppAD::vector & x); - // - // J = fun_name.jacobian(x) - CppAD::vector jacobian(const CppAD::vector & x); - // - // Jrcv = fun_name.sparse_jacobian(x) - CppAD::sparse_rcv< CppAD::vector, CppAD::vector > - sparse_jacobian(const CppAD::vector& x); -}; -// END C++ - -# endif diff --git a/build-config/cppad/include/cppad/example/cppad_eigen.hpp b/build-config/cppad/include/cppad/example/cppad_eigen.hpp deleted file mode 100644 index a7b06f29..00000000 --- a/build-config/cppad/include/cppad/example/cppad_eigen.hpp +++ /dev/null @@ -1,195 +0,0 @@ -# ifndef CPPAD_EXAMPLE_CPPAD_EIGEN_HPP -# define CPPAD_EXAMPLE_CPPAD_EIGEN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -// cppad.hpp gets included at the end -# define EIGEN_MATRIXBASE_PLUGIN -# include - -/* -$begin cppad_eigen.hpp$$ -$spell - impl - typename - Real Real - inline - neg - eps - atan - Num - acos - asin - CppAD - std::numeric - enum - Mul - Eigen - cppad.hpp - namespace - struct - typedef - const - imag - sqrt - exp - cos -$$ -$section Enable Use of Eigen Linear Algebra Package with CppAD$$ - -$head Syntax$$ -$codei%# include -%$$ -$children% - include/cppad/example/eigen_plugin.hpp% - example/general/eigen_array.cpp% - example/general/eigen_det.cpp -%$$ - -$head Purpose$$ -Enables the use of the $cref eigen$$ -linear algebra package with the type $icode%AD<%Base%>%$$; see -$href% - https://eigen.tuxfamily.org/dox/TopicCustomizing_CustomScalar.html% - custom scalar types -%$$. - -$head Example$$ -The files $cref eigen_array.cpp$$ and $cref eigen_det.cpp$$ -contain an example and test of this include file. -They return true if they succeed and false otherwise. - -$head Include Files$$ -The file $code $$ is included before -these definitions and $code $$ is included after. - -$head CppAD Declarations$$ -First declare some items that are defined by cppad.hpp: -$srccode%cpp% */ -namespace CppAD { - // AD - template class AD; - // numeric_limits - template class numeric_limits; -} -/* %$$ -$head Eigen NumTraits$$ -Eigen needs the following definitions to work properly -with $codei%AD<%Base%>%$$ scalars: -$srccode%cpp% */ -namespace Eigen { - template struct NumTraits< CppAD::AD > - { // type that corresponds to the real part of an AD value - typedef CppAD::AD Real; - // type for AD operations that result in non-integer values - typedef CppAD::AD NonInteger; - // type to use for numeric literals such as "2" or "0.5". - typedef CppAD::AD Literal; - // type for nested value inside an AD expression tree - typedef CppAD::AD Nested; - - enum { - // does not support complex Base types - IsComplex = 0 , - // does not support integer Base types - IsInteger = 0 , - // only support signed Base types - IsSigned = 1 , - // must initialize an AD object - RequireInitialization = 1 , - // computational cost of the corresponding operations - ReadCost = 1 , - AddCost = 2 , - MulCost = 2 - }; - - // machine epsilon with type of real part of x - // (use assumption that Base is not complex) - static CppAD::AD epsilon(void) - { return CppAD::numeric_limits< CppAD::AD >::epsilon(); } - - // relaxed version of machine epsilon for comparison of different - // operations that should result in the same value - static CppAD::AD dummy_precision(void) - { return 100. * - CppAD::numeric_limits< CppAD::AD >::epsilon(); - } - - // minimum normalized positive value - static CppAD::AD lowest(void) - { return CppAD::numeric_limits< CppAD::AD >::min(); } - - // maximum finite value - static CppAD::AD highest(void) - { return CppAD::numeric_limits< CppAD::AD >::max(); } - - // number of decimal digits that can be represented without change. - static int digits10(void) - { return CppAD::numeric_limits< CppAD::AD >::digits10; } - }; -} -/* %$$ -$head CppAD Namespace$$ -Eigen also needs the following definitions to work properly -with $codei%AD<%Base%>%$$ scalars: -$srccode%cpp% */ -namespace CppAD { - // functions that return references - template const AD& conj(const AD& x) - { return x; } - template const AD& real(const AD& x) - { return x; } - - // functions that return values (note abs is defined by cppad.hpp) - template AD imag(const AD& x) - { return CppAD::AD(0.); } - template AD abs2(const AD& x) - { return x * x; } -} - -/* %$$ -$head eigen_vector$$ -The class $code CppAD::eigen_vector$$ is a wrapper for Eigen column vectors -so that they are $cref/simple vectors/SimpleVector/$$. -To be specific, it converts $code Eigen::Index$$ arguments and -return values to $code size_t$$. -$srccode%cpp% */ -namespace CppAD { - template - class eigen_vector : public Eigen::Matrix { - private: - // base_class - typedef Eigen::Matrix base_class; - public: - // constructor - eigen_vector(size_t n) : base_class( Eigen::Index(n) ) - { } - eigen_vector(void) : base_class() - { } - // operator[] - Scalar& operator[](size_t i) - { return base_class::operator[]( Eigen::Index(i) ); } - const Scalar& operator[](size_t i) const - { return base_class::operator[]( Eigen::Index(i) ); } - // size - size_t size(void) const - { return size_t( base_class::size() ); } - // resize - void resize(size_t n) - { base_class::resize( Eigen::Index(n) ); } - }; -} -// -# include -/* %$$ -$end -*/ -# endif diff --git a/build-config/cppad/include/cppad/example/eigen_plugin.hpp b/build-config/cppad/include/cppad/example/eigen_plugin.hpp deleted file mode 100644 index 73f1aeec..00000000 --- a/build-config/cppad/include/cppad/example/eigen_plugin.hpp +++ /dev/null @@ -1,28 +0,0 @@ -# ifndef CPPAD_EXAMPLE_EIGEN_PLUGIN_HPP -# define CPPAD_EXAMPLE_EIGEN_PLUGIN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*$ -$begin eigen_plugin.hpp$$ -$spell - eigen_plugin.hpp - typedef -$$ - -$section Source Code for eigen_plugin.hpp$$ -$srccode%cpp% */ -// Declaration needed, before eigen-3.3.3, so Eigen vector is a simple vector -typedef Scalar value_type; -/* %$$ -$end -*/ -# endif diff --git a/build-config/cppad/include/cppad/ipopt/solve.hpp b/build-config/cppad/include/cppad/ipopt/solve.hpp deleted file mode 100644 index f353621b..00000000 --- a/build-config/cppad/include/cppad/ipopt/solve.hpp +++ /dev/null @@ -1,639 +0,0 @@ -# ifndef CPPAD_IPOPT_SOLVE_HPP -# define CPPAD_IPOPT_SOLVE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin ipopt_solve$$ -$spell - Jacobian - Jacobians - retape - Bvector - bool - infeasibility - const - cpp - cppad - doesn't - ADvector - eval - fg - gl - gu - hpp - inf - ipopt - maxiter - naninf - nf - ng - nx - obj - optimizer - std - xi - xl - xu - zl - zu - cmake -$$ - -$section Use Ipopt to Solve a Nonlinear Programming Problem$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%ipopt::solve( - %options%, %xi%, %xl%, %xu%, %gl%, %gu%, %fg_eval%, %solution% -)%$$ - -$head Purpose$$ -The function $code ipopt::solve$$ solves nonlinear programming -problems of the form -$latex \[ -\begin{array}{rll} -{\rm minimize} & f (x) -\\ -{\rm subject \; to} & gl \leq g(x) \leq gu -\\ - & xl \leq x \leq xu -\end{array} -\] $$ -This is done using -$href% - http://www.coin-or.org/projects/Ipopt.xml% - Ipopt -%$$ -optimizer and CppAD for the derivative and sparsity calculations. - -$head Include File$$ -If $cref/include_ipopt/cmake/include_ipopt/$$ is on the cmake command line, -the file $code cppad/ipopt/solve.hpp$$ is included by $code cppad/cppad.hpp$$. -Otherwise, -$code cppad/ipopt/solve.hpp$$ can be included directly -(If $code cppad/cppad.hpp$$ has not yet been included, -$code cppad/ipopt/solve.hpp$$ will automatically include it.) - -$head Bvector$$ -The type $icode Bvector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code bool$$. - -$head Dvector$$ -The type $icode DVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code double$$. - -$head options$$ -The argument $icode options$$ has prototype -$codei% - const std::string %options% -%$$ -It contains a list of options. -Each option, including the last option, -is terminated by the $code '\n'$$ character. -Each line consists of two or three tokens separated by one or more spaces. - -$subhead Retape$$ -You can set the retape flag with the following syntax: -$codei% - Retape %value% -%$$ -If the value is $code true$$, $code ipopt::solve$$ with retape the -$cref/operation sequence/glossary/Operation/Sequence/$$ for each -new value of $icode x$$. -If the value is $code false$$, $code ipopt::solve$$ -will tape the operation sequence at the value -of $icode xi$$ and use that sequence for the entire optimization process. -The default value is $code false$$. - -$subhead Sparse$$ -You can set the sparse Jacobian and Hessian flag with the following syntax: -$codei% - Sparse %value% %direction% -%$$ -If the value is $code true$$, $code ipopt::solve$$ will use a sparse -matrix representation for the computation of Jacobians and Hessians. -Otherwise, it will use a full matrix representation for -these calculations. -The default for $icode value$$ is $code false$$. -If sparse is true, retape must be false. -$pre - -$$ -It is unclear if $cref sparse_jacobian$$ would be faster user -forward or reverse mode so you are able to choose the direction. -If -$codei% - %value% == true && %direction% == forward -%$$ -the Jacobians will be calculated using $code SparseJacobianForward$$. -If -$codei% - %value% == true && %direction% == reverse -%$$ -the Jacobians will be calculated using $code SparseJacobianReverse$$. - -$subhead String$$ -You can set any Ipopt string option using a line with the following syntax: -$codei% - String %name% %value% -%$$ -Here $icode name$$ is any valid Ipopt string option -and $icode value$$ is its setting. - -$subhead Numeric$$ -You can set any Ipopt numeric option using a line with the following syntax: -$codei% - Numeric %name% %value% -%$$ -Here $icode name$$ is any valid Ipopt numeric option -and $icode value$$ is its setting. - -$subhead Integer$$ -You can set any Ipopt integer option using a line with the following syntax: -$codei% - Integer %name% %value% -%$$ -Here $icode name$$ is any valid Ipopt integer option -and $icode value$$ is its setting. - -$head xi$$ -The argument $icode xi$$ has prototype -$codei% - const %Vector%& %xi% -%$$ -and its size is equal to $icode nx$$. -It specifies the initial point where Ipopt starts the optimization process. - -$head xl$$ -The argument $icode xl$$ has prototype -$codei% - const %Vector%& %xl% -%$$ -and its size is equal to $icode nx$$. -It specifies the lower limits for the argument in the optimization problem. - -$head xu$$ -The argument $icode xu$$ has prototype -$codei% - const %Vector%& %xu% -%$$ -and its size is equal to $icode nx$$. -It specifies the upper limits for the argument in the optimization problem. - -$head gl$$ -The argument $icode gl$$ has prototype -$codei% - const %Vector%& %gl% -%$$ -and its size is equal to $icode ng$$. -It specifies the lower limits for the constraints in the optimization problem. - -$head gu$$ -The argument $icode gu$$ has prototype -$codei% - const %Vector%& %gu% -%$$ -and its size is equal to $icode ng$$. -It specifies the upper limits for the constraints in the optimization problem. - -$head fg_eval$$ -The argument $icode fg_eval$$ has prototype -$codei% - %FG_eval% %fg_eval% -%$$ -where the class $icode FG_eval$$ is unspecified except for the fact that -it supports the syntax -$codei% - %FG_eval%::ADvector - %fg_eval%(%fg%, %x%) -%$$ -The type $icode ADvector$$ -and the arguments to $icode fg$$, $icode x$$ have the following meaning: - -$subhead ADvector$$ -The type $icode%FG_eval%::ADvector%$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$code AD$$. - -$subhead x$$ -The $icode fg_eval$$ argument $icode x$$ has prototype -$codei% - const %ADvector%& %x% -%$$ -where $icode%nx% = %x%.size()%$$. - -$subhead fg$$ -The $icode fg_eval$$ argument $icode fg$$ has prototype -$codei% - %ADvector%& %fg% -%$$ -where $codei%1 + %ng% = %fg%.size()%$$. -The input value of the elements of $icode fg$$ does not matter. -Upon return from $icode fg_eval$$, -$codei% - %fg%[0] =%$$ $latex f (x)$$ $codei% -%$$ -and for $latex i = 0, \ldots , ng-1$$, -$codei% - %fg%[1 + %i%] =%$$ $latex g_i (x)$$ - -$head solution$$ -The argument $icode solution$$ has prototype -$codei% - ipopt::solve_result<%Dvector%>& %solution% -%$$ -After the optimization process is completed, $icode solution$$ contains -the following information: - -$subhead status$$ -The $icode status$$ field of $icode solution$$ has prototype -$codei% - ipopt::solve_result<%Dvector%>::status_type %solution%.status -%$$ -It is the final Ipopt status for the optimizer. -Here is a list of the possible values for the status: - -$table -$icode status$$ $cnext Meaning -$rnext -not_defined $cnext -The optimizer did not return a final status for this problem. -$rnext -unknown $cnext -The status returned by the optimizer is not defined in the Ipopt -documentation for $code finalize_solution$$. -$rnext -success $cnext -Algorithm terminated successfully at a point satisfying the convergence -tolerances (see Ipopt options). -$rnext -maxiter_exceeded $cnext -The maximum number of iterations was exceeded (see Ipopt options). -$rnext -stop_at_tiny_step $cnext -Algorithm terminated because progress was very slow. -$rnext -stop_at_acceptable_point $cnext -Algorithm stopped at a point that was converged, -not to the 'desired' tolerances, but to 'acceptable' tolerances -(see Ipopt options). -$rnext -local_infeasibility $cnext -Algorithm converged to a non-feasible point -(problem may have no solution). -$rnext -user_requested_stop $cnext -This return value should not happen. -$rnext -diverging_iterates $cnext -It the iterates are diverging. -$rnext -restoration_failure $cnext -Restoration phase failed, algorithm doesn't know how to proceed. -$rnext -error_in_step_computation $cnext -An unrecoverable error occurred while Ipopt tried to -compute the search direction. -$rnext -invalid_number_detected $cnext -Algorithm received an invalid number (such as $code nan$$ or $code inf$$) -from the users function $icode%fg_info%.eval%$$ or from the CppAD evaluations -of its derivatives -(see the Ipopt option $code check_derivatives_for_naninf$$). -$rnext -internal_error $cnext -An unknown Ipopt internal error occurred. -Contact the Ipopt authors through the mailing list. -$tend - -$subhead x$$ -The $code x$$ field of $icode solution$$ has prototype -$codei% - %Vector% %solution%.x -%$$ -and its size is equal to $icode nx$$. -It is the final $latex x$$ value for the optimizer. - -$subhead zl$$ -The $code zl$$ field of $icode solution$$ has prototype -$codei% - %Vector% %solution%.zl -%$$ -and its size is equal to $icode nx$$. -It is the final Lagrange multipliers for the -lower bounds on $latex x$$. - -$subhead zu$$ -The $code zu$$ field of $icode solution$$ has prototype -$codei% - %Vector% %solution%.zu -%$$ -and its size is equal to $icode nx$$. -It is the final Lagrange multipliers for the -upper bounds on $latex x$$. - -$subhead g$$ -The $code g$$ field of $icode solution$$ has prototype -$codei% - %Vector% %solution%.g -%$$ -and its size is equal to $icode ng$$. -It is the final value for the constraint function $latex g(x)$$. - -$subhead lambda$$ -The $code lambda$$ field of $icode solution$$ has prototype -$codei% - %Vector%> %solution%.lambda -%$$ -and its size is equal to $icode ng$$. -It is the final value for the -Lagrange multipliers corresponding to the constraint function. - -$subhead obj_value$$ -The $code obj_value$$ field of $icode solution$$ has prototype -$codei% - double %solution%.obj_value -%$$ -It is the final value of the objective function $latex f(x)$$. - -$children% - example/ipopt_solve/get_started.cpp% - example/ipopt_solve/retape.cpp% - example/ipopt_solve/ode_inverse.cpp -%$$ -$head Example$$ -All the examples return true if it succeeds and false otherwise. - -$subhead get_started$$ -The file -$cref%example/ipopt_solve/get_started.cpp%ipopt_solve_get_started.cpp%$$ -is an example and test of $code ipopt::solve$$ -taken from the Ipopt manual. - -$subhead retape$$ -The file -$cref%example/ipopt_solve/retape.cpp%ipopt_solve_retape.cpp%$$ -demonstrates when it is necessary to specify -$cref/retape/ipopt_solve/options/Retape/$$ as true. - -$subhead ode_inverse$$ -The file -$cref%example/ipopt_solve/ode_inverse.cpp%ipopt_solve_ode_inverse.cpp%$$ -demonstrates using Ipopt to solve for parameters in an ODE model. - -$end -------------------------------------------------------------------------------- -*/ -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -namespace ipopt { -/*! -\file solve.hpp -\brief Implement the ipopt::solve Nonlinear Programming Solver -*/ - -/*! -Use Ipopt to Solve a Nonlinear Programming Problem - -\tparam Bvector -simple vector class with elements of type bool. - -\tparam Dvector -simple vector class with elements of type double. - -\tparam FG_eval -function object used to evaluate f(x) and g(x); see fg_eval below. -It must also support -\code - FG_eval::ADvector -\endcode -to dentify the type used for the arguments to fg_eval. - -\param options -list of options, one for each line. -Ipopt options (are optional) and have one of the following forms -\code - String name value - Numeric name value - Integer name value -\endcode -The following other possible options are listed below: -\code - Retape value -\endcode - - -\param xi -initial argument value to start optimization procedure at. - -\param xl -lower limit for argument during optimization - -\param xu -upper limit for argument during optimization - -\param gl -lower limit for g(x) during optimization. - -\param gu -upper limit for g(x) during optimization. - -\param fg_eval -function that evaluates the objective and constraints using the syntax -\code - fg_eval(fg, x) -\endcode - -\param solution -structure that holds the solution of the optimization. -*/ -template -void solve( - const std::string& options , - const Dvector& xi , - const Dvector& xl , - const Dvector& xu , - const Dvector& gl , - const Dvector& gu , - FG_eval& fg_eval , - ipopt::solve_result& solution ) -{ bool ok = true; - - typedef typename FG_eval::ADvector ADvector; - - CPPAD_ASSERT_KNOWN( - xi.size() == xl.size() && xi.size() == xu.size() , - "ipopt::solve: size of xi, xl, and xu are not all equal." - ); - CPPAD_ASSERT_KNOWN( - gl.size() == gu.size() , - "ipopt::solve: size of gl and gu are not equal." - ); - size_t nx = xi.size(); - size_t ng = gl.size(); - - // Create an IpoptApplication - using Ipopt::IpoptApplication; - Ipopt::SmartPtr app = new IpoptApplication(); - - // process the options argument - size_t begin_1, end_1, begin_2, end_2, begin_3, end_3; - begin_1 = 0; - bool retape = false; - bool sparse_forward = false; - bool sparse_reverse = false; - while( begin_1 < options.size() ) - { // split this line into tokens - while( options[begin_1] == ' ') - begin_1++; - end_1 = options.find_first_of(" \n", begin_1); - begin_2 = end_1; - while( options[begin_2] == ' ') - begin_2++; - end_2 = options.find_first_of(" \n", begin_2); - begin_3 = end_2; - while( options[begin_3] == ' ') - begin_3++; - end_3 = options.find_first_of(" \n", begin_3); - - // check for errors - CPPAD_ASSERT_KNOWN( - (end_1 != std::string::npos) & - (end_2 != std::string::npos) & - (end_3 != std::string::npos) , - "ipopt::solve: missing '\\n' at end of an option line" - ); - CPPAD_ASSERT_KNOWN( - (end_1 > begin_1) & (end_2 > begin_2) , - "ipopt::solve: an option line does not have two tokens" - ); - - // get first two tokens - std::string tok_1 = options.substr(begin_1, end_1 - begin_1); - std::string tok_2 = options.substr(begin_2, end_2 - begin_2); - - // get third token - std::string tok_3; - bool three_tok = false; - three_tok |= tok_1 == "Sparse"; - three_tok |= tok_1 == "String"; - three_tok |= tok_1 == "Numeric"; - three_tok |= tok_1 == "Integer"; - if( three_tok ) - { CPPAD_ASSERT_KNOWN( - (end_3 > begin_3) , - "ipopt::solve: a Sparse, String, Numeric, or Integer\n" - "option line does not have three tokens." - ); - tok_3 = options.substr(begin_3, end_3 - begin_3); - } - - // switch on option type - if( tok_1 == "Retape" ) - { CPPAD_ASSERT_KNOWN( - (tok_2 == "true") | (tok_2 == "false") , - "ipopt::solve: Retape value is not true or false" - ); - retape = (tok_2 == "true"); - } - else if( tok_1 == "Sparse" ) - { CPPAD_ASSERT_KNOWN( - (tok_2 == "true") | (tok_2 == "false") , - "ipopt::solve: Sparse value is not true or false" - ); - CPPAD_ASSERT_KNOWN( - (tok_3 == "forward") | (tok_3 == "reverse") , - "ipopt::solve: Sparse direction is not forward or reverse" - ); - if( tok_2 == "false" ) - { sparse_forward = false; - sparse_reverse = false; - } - else - { sparse_forward = tok_3 == "forward"; - sparse_reverse = tok_3 == "reverse"; - } - } - else if ( tok_1 == "String" ) - app->Options()->SetStringValue(tok_2.c_str(), tok_3.c_str()); - else if ( tok_1 == "Numeric" ) - { Ipopt::Number value = std::atof( tok_3.c_str() ); - app->Options()->SetNumericValue(tok_2.c_str(), value); - } - else if ( tok_1 == "Integer" ) - { Ipopt::Index value = std::atoi( tok_3.c_str() ); - app->Options()->SetIntegerValue(tok_2.c_str(), value); - } - else - CPPAD_ASSERT_KNOWN( - false, - "ipopt::solve: First token is not one of\n" - "Retape, Sparse, String, Numeric, Integer" - ); - - begin_1 = end_3; - while( options[begin_1] == ' ') - begin_1++; - if( options[begin_1] != '\n' ) CPPAD_ASSERT_KNOWN( - false, - "ipopt::solve: either more than three tokens " - "or no '\\n' at end of a line" - ); - begin_1++; - } - CPPAD_ASSERT_KNOWN( - ! ( retape & (sparse_forward | sparse_reverse) ) , - "ipopt::solve: retape and sparse both true is not supported." - ); - - // Initialize the IpoptApplication and process the options - Ipopt::ApplicationReturnStatus status = app->Initialize(); - ok &= status == Ipopt::Solve_Succeeded; - if( ! ok ) - { solution.status = solve_result::unknown; - return; - } - - // Create an interface from Ipopt to this specific problem. - // Note the assumption here that ADvector is same as cppd_ipopt::ADvector - size_t nf = 1; - Ipopt::SmartPtr cppad_nlp = - new CppAD::ipopt::solve_callback( - nf, - nx, - ng, - xi, - xl, - xu, - gl, - gu, - fg_eval, - retape, - sparse_forward, - sparse_reverse, - solution - ); - - // Run the IpoptApplication - app->OptimizeTNLP(cppad_nlp); - - return; -} - -} // end ipopt namespace -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/ipopt/solve_callback.hpp b/build-config/cppad/include/cppad/ipopt/solve_callback.hpp deleted file mode 100644 index 898f6ff1..00000000 --- a/build-config/cppad/include/cppad/ipopt/solve_callback.hpp +++ /dev/null @@ -1,1192 +0,0 @@ -# ifndef CPPAD_IPOPT_SOLVE_CALLBACK_HPP -# define CPPAD_IPOPT_SOLVE_CALLBACK_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -namespace ipopt { -/*! -\file solve_callback.hpp -\brief Class that connects ipopt::solve to Ipopt -*/ - -/*! -Class that Ipopt uses for obtaining information about this problem. - - -\section Evaluation_Methods Evaluation Methods -The set of evaluation methods for this class is -\verbatim - { eval_f, eval_grad_f, eval_g, eval_jac_g, eval_h } -\endverbatim -Note that the bool return flag for the evaluations methods -does not appear in the Ipopt documentation. -Looking at the code, it seems to be a flag telling Ipopt to abort -when the flag is false. -*/ -template -class solve_callback : public Ipopt::TNLP -{ -private: - // ------------------------------------------------------------------ - // Types used by this class - // ------------------------------------------------------------------ - /// A Scalar value used by Ipopt - typedef Ipopt::Number Number; - /// An index value used by Ipopt - typedef Ipopt::Index Index; - /// Indexing style used in Ipopt sparsity structure - typedef Ipopt::TNLP::IndexStyleEnum IndexStyleEnum; - // ------------------------------------------------------------------ - // Values directly passed in to constuctor - // ------------------------------------------------------------------ - /// dimension of the range space for f(x). - /// The objective is sum_i f_i (x). - /// Note that, at this point, there is no advantage having nf_ > 1. - const size_t nf_; - /// dimension of the domain space for f(x) and g(x) - const size_t nx_; - /// dimension of the range space for g(x) - const size_t ng_; - /// initial value for x - const Dvector& xi_; - /// lower limit for x - const Dvector& xl_; - /// upper limit for x - const Dvector& xu_; - /// lower limit for g(x) - const Dvector& gl_; - /// upper limit for g(x) - const Dvector& gu_; - /// object that evaluates f(x) and g(x) - FG_eval& fg_eval_; - /// should operation sequence be retaped for each new x. - bool retape_; - /// Should sparse methods be used to compute Jacobians and Hessians - /// with forward mode used for Jacobian. - bool sparse_forward_; - /// Should sparse methods be used to compute Jacobians and Hessians - /// with reverse mode used for Jacobian. - bool sparse_reverse_; - /// final results are returned to this structure - solve_result& solution_; - // ------------------------------------------------------------------ - // Values that are initilaized by the constructor - // ------------------------------------------------------------------ - /// AD function object that evaluates x -> [ f(x) , g(x) ] - /// If retape is false, this object is initialzed by constructor - /// otherwise it is set by cache_new_x each time it is called. - CppAD::ADFun adfun_; - /// value of x corresponding to previous new_x - Dvector x0_; - /// value of fg corresponding to previous new_x - Dvector fg0_; - // ---------------------------------------------------------------------- - // Jacobian information - // ---------------------------------------------------------------------- - /// Sparsity pattern for Jacobian of [f(x), g(x) ]. - /// If sparse is true, this pattern set by constructor and does not change. - /// Otherwise this vector has size zero. - CppAD::vectorBool pattern_jac_; - /// Row indices of [f(x), g(x)] for Jacobian of g(x) in row order. - /// (Set by constructor and not changed.) - CppAD::vector row_jac_; - /// Column indices for Jacobian of g(x), same order as row_jac_. - /// (Set by constructor and not changed.) - CppAD::vector col_jac_; - /// col_order_jac_ sorts row_jac_ and col_jac_ in column order. - /// (Set by constructor and not changed.) - CppAD::vector col_order_jac_; - /// Work vector used by SparseJacobian, stored here to avoid recalculation. - CppAD::sparse_jacobian_work work_jac_; - // ---------------------------------------------------------------------- - // Hessian information - // ---------------------------------------------------------------------- - /// Sparsity pattern for Hessian of Lagragian - /// \f[ L(x) = \sigma \sum_i f_i (x) + \sum_i \lambda_i g_i (x) \f] - /// If sparse is true, this pattern set by constructor and does not change. - /// Otherwise this vector has size zero. - CppAD::vectorBool pattern_hes_; - /// Row indices of Hessian lower left triangle in row order. - /// (Set by constructor and not changed.) - CppAD::vector row_hes_; - /// Column indices of Hessian left triangle in same order as row_hes_. - /// (Set by constructor and not changed.) - CppAD::vector col_hes_; - /// Work vector used by SparseJacobian, stored here to avoid recalculation. - CppAD::sparse_hessian_work work_hes_; - // ------------------------------------------------------------------ - // Private member functions - // ------------------------------------------------------------------ - /*! - Cache information for a new value of x. - - \param x - is the new value for x. - - \par x0_ - the elements of this vector are set to the new value for x. - - \par fg0_ - the elements of this vector are set to the new value for [f(x), g(x)] - - \par adfun_ - If retape is true, the operation sequence for this function - is changes to correspond to the argument x. - If retape is false, the operation sequence is not changed. - The zero order Taylor coefficients for this function are set - so they correspond to the argument x. - */ - void cache_new_x(const Number* x) - { size_t i; - if( retape_ ) - { // make adfun_, as well as x0_ and fg0_ correspond to this x - ADvector a_x(nx_), a_fg(nf_ + ng_); - for(i = 0; i < nx_; i++) - { x0_[i] = x[i]; - a_x[i] = x[i]; - } - CppAD::Independent(a_x); - fg_eval_(a_fg, a_x); - adfun_.Dependent(a_x, a_fg); - } - else - { // make x0_ and fg0_ correspond to this x - for(i = 0; i < nx_; i++) - x0_[i] = x[i]; - } - fg0_ = adfun_.Forward(0, x0_); - } -public: - // ---------------------------------------------------------------------- - /*! - Constructor for the interface between ipopt::solve and Ipopt - - \param nf - dimension of the range space for f(x) - - \param nx - dimension of the domain space for f(x) and g(x). - - \param ng - dimension of the range space for g(x) - - \param xi - initial value of x during the optimization procedure (size nx). - - \param xl - lower limit for x (size nx). - - \param xu - upper limit for x (size nx). - - \param gl - lower limit for g(x) (size ng). - - \param gu - upper limit for g(x) (size ng). - - \param fg_eval - function object that evaluations f(x) and g(x) using fg_eval(fg, x) - - \param retape - should the operation sequence be retaped for each argument value. - - \param sparse_forward - should sparse matrix computations be used for Jacobians and Hessians - with forward mode for Jacobian. - - \param sparse_reverse - should sparse matrix computations be used for Jacobians and Hessians - with reverse mode for Jacobian. - (sparse_forward and sparse_reverse cannot both be true). - - \param solution - object where final results are stored. - */ - solve_callback( - size_t nf , - size_t nx , - size_t ng , - const Dvector& xi , - const Dvector& xl , - const Dvector& xu , - const Dvector& gl , - const Dvector& gu , - FG_eval& fg_eval , - bool retape , - bool sparse_forward , - bool sparse_reverse , - solve_result& solution ) : - nf_ ( nf ), - nx_ ( nx ), - ng_ ( ng ), - xi_ ( xi ), - xl_ ( xl ), - xu_ ( xu ), - gl_ ( gl ), - gu_ ( gu ), - fg_eval_ ( fg_eval ), - retape_ ( retape ), - sparse_forward_ ( sparse_forward ), - sparse_reverse_ ( sparse_reverse ), - solution_ ( solution ) - { CPPAD_ASSERT_UNKNOWN( ! ( sparse_forward_ & sparse_reverse_ ) ); - - size_t i, j; - size_t nfg = nf_ + ng_; - - // initialize x0_ and fg0_ wih proper dimensions and value nan - x0_.resize(nx); - fg0_.resize(nfg); - for(i = 0; i < nx_; i++) - x0_[i] = CppAD::nan(0.0); - for(i = 0; i < nfg; i++) - fg0_[i] = CppAD::nan(0.0); - - if( ! retape_ ) - { // make adfun_ correspond to x -> [ f(x), g(x) ] - ADvector a_x(nx_), a_fg(nfg); - for(i = 0; i < nx_; i++) - a_x[i] = xi_[i]; - CppAD::Independent(a_x); - fg_eval_(a_fg, a_x); - adfun_.Dependent(a_x, a_fg); - // optimize because we will make repeated use of this tape - adfun_.optimize(); - } - if( sparse_forward_ | sparse_reverse_ ) - { CPPAD_ASSERT_UNKNOWN( ! retape ); - size_t m = nf_ + ng_; - // - // ----------------------------------------------------------- - // Jacobian - pattern_jac_.resize( m * nx_ ); - if( nx_ <= m ) - { // use forward mode to compute sparsity - - // number of bits that are packed into one unit in vectorBool - size_t n_column = vectorBool::bit_per_unit(); - - // sparsity patterns for current columns - vectorBool r(nx_ * n_column), s(m * n_column); - - // compute the sparsity pattern n_column columns at a time - size_t n_loop = (nx_ - 1) / n_column + 1; - for(size_t i_loop = 0; i_loop < n_loop; i_loop++) - { // starting column index for this iteration - size_t i_column = i_loop * n_column; - - // pattern that picks out the appropriate columns - for(i = 0; i < nx_; i++) - { for(j = 0; j < n_column; j++) - r[i * n_column + j] = (i == i_column + j); - } - s = adfun_.ForSparseJac(n_column, r); - - // fill in the corresponding columns of total_sparsity - for(i = 0; i < m; i++) - { for(j = 0; j < n_column; j++) - { if( i_column + j < nx_ ) - pattern_jac_[i * nx_ + i_column + j] = - s[i * n_column + j]; - } - } - } - } - else - { // use reverse mode to compute sparsity - - // number of bits that are packed into one unit in vectorBool - size_t n_row = vectorBool::bit_per_unit(); - - // sparsity patterns for current rows - vectorBool r(n_row * m), s(n_row * nx_); - - // compute the sparsity pattern n_row row at a time - size_t n_loop = (m - 1) / n_row + 1; - for(size_t i_loop = 0; i_loop < n_loop; i_loop++) - { // starting row index for this iteration - size_t i_row = i_loop * n_row; - - // pattern that picks out the appropriate rows - for(i = 0; i < n_row; i++) - { for(j = 0; j < m; j++) - r[i * m + j] = (i_row + i == j); - } - s = adfun_.RevSparseJac(n_row, r); - - // fill in correspoding rows of total sparsity - for(i = 0; i < n_row; i++) - { for(j = 0; j < nx_; j++) - if( i_row + i < m ) - pattern_jac_[ (i_row + i) * nx_ + j ] = - s[ i * nx_ + j]; - } - } - } - /* - { // use reverse mode to compute sparsity - CppAD::vectorBool s(m * m); - for(i = 0; i < m; i++) - { for(j = 0; j < m; j++) - s[i * m + j] = (i == j); - } - pattern_jac_ = adfun_.RevSparseJac(m, s); - } - */ - // Set row and column indices in Jacoian of [f(x), g(x)] - // for Jacobian of g(x). These indices are in row major order. - for(i = nf_; i < nfg; i++) - { for(j = 0; j < nx_; j++) - { if( pattern_jac_[ i * nx_ + j ] ) - { row_jac_.push_back(i); - col_jac_.push_back(j); - } - } - } - // Set row and column indices in Jacoian of [f(x), g(x)] - // for Jacobian of g(x). These indices are in row major order. - // ----------------------------------------------------------- - // Hessian - pattern_hes_.resize(nx_ * nx_); - - // number of bits that are packed into one unit in vectorBool - size_t n_column = vectorBool::bit_per_unit(); - - // sparsity patterns for current columns - vectorBool r(nx_ * n_column), h(nx_ * n_column); - - // sparsity pattern for range space of function - vectorBool s(m); - for(i = 0; i < m; i++) - s[i] = true; - - // compute the sparsity pattern n_column columns at a time - size_t n_loop = (nx_ - 1) / n_column + 1; - for(size_t i_loop = 0; i_loop < n_loop; i_loop++) - { // starting column index for this iteration - size_t i_column = i_loop * n_column; - - // pattern that picks out the appropriate columns - for(i = 0; i < nx_; i++) - { for(j = 0; j < n_column; j++) - r[i * n_column + j] = (i == i_column + j); - } - adfun_.ForSparseJac(n_column, r); - - // sparsity pattern corresponding to paritls w.r.t. (theta, u) - // of partial w.r.t. the selected columns - bool transpose = true; - h = adfun_.RevSparseHes(n_column, s, transpose); - - // fill in the corresponding columns of total_sparsity - for(i = 0; i < nx_; i++) - { for(j = 0; j < n_column; j++) - { if( i_column + j < nx_ ) - pattern_hes_[i * nx_ + i_column + j] = - h[i * n_column + j]; - } - } - } - // Set row and column indices for Lower triangle of Hessian - // of Lagragian. These indices are in row major order. - for(i = 0; i < nx_; i++) - { for(j = 0; j < nx_; j++) - { if( pattern_hes_[ i * nx_ + j ] ) - if( j <= i ) - { row_hes_.push_back(i); - col_hes_.push_back(j); - } - } - } - } - else - { // Set row and column indices in Jacoian of [f(x), g(x)] - // for Jacobian of g(x). These indices are in row major order. - for(i = nf_; i < nfg; i++) - { for(j = 0; j < nx_; j++) - { row_jac_.push_back(i); - col_jac_.push_back(j); - } - } - // Set row and column indices for lower triangle of Hessian. - // These indices are in row major order. - for(i = 0; i < nx_; i++) - { for(j = 0; j <= i; j++) - { row_hes_.push_back(i); - col_hes_.push_back(j); - } - } - } - - // Column order indirect sort of the Jacobian indices - col_order_jac_.resize( col_jac_.size() ); - index_sort( col_jac_, col_order_jac_ ); - } - // ----------------------------------------------------------------------- - /*! - Return dimension information about optimization problem. - - \param[out] n - is set to the value nx_. - - \param[out] m - is set to the value ng_. - - \param[out] nnz_jac_g - is set to ng_ * nx_ (sparsity not yet implemented) - - \param[out] nnz_h_lag - is set to nx_*(nx_+1)/2 (sparsity not yet implemented) - - \param[out] index_style - is set to C_STYLE; i.e., zeoro based indexing is used in the - information passed to Ipopt. - */ - virtual bool get_nlp_info( - Index& n , - Index& m , - Index& nnz_jac_g , - Index& nnz_h_lag , - IndexStyleEnum& index_style ) - { - n = static_cast(nx_); - m = static_cast(ng_); - nnz_jac_g = static_cast(row_jac_.size()); - nnz_h_lag = static_cast(row_hes_.size()); - -# ifndef NDEBUG - if( ! (sparse_forward_ | sparse_reverse_) ) - { size_t nnz = static_cast(nnz_jac_g); - CPPAD_ASSERT_UNKNOWN( nnz == ng_ * nx_); - // - nnz = static_cast(nnz_h_lag); - CPPAD_ASSERT_UNKNOWN( nnz == (nx_ * (nx_ + 1)) / 2 ); - } -# endif - - // use the fortran index style for row/col entries - index_style = C_STYLE; - - return true; - } - // ----------------------------------------------------------------------- - /*! - Return bound information about optimization problem. - - \param[in] n - is the dimension of the domain space for f(x) and g(x); i.e., - it must be equal to nx_. - - \param[out] x_l - is a vector of size nx_. - The input value of its elements does not matter. - On output, it is a copy of the lower bound for \f$ x \f$; i.e., - xl_. - - \param[out] x_u - is a vector of size nx_. - The input value of its elements does not matter. - On output, it is a copy of the upper bound for \f$ x \f$; i.e., - xu_. - - \param[in] m - is the dimension of the range space for g(x). i.e., - it must be equal to ng_. - - \param[out] g_l - is a vector of size ng_. - The input value of its elements does not matter. - On output, it is a copy of the lower bound for \f$ g(x) \f$; i.e., gl_. - - \param[out] g_u - is a vector of size ng_. - The input value of its elements does not matter. - On output, it is a copy of the upper bound for \f$ g(x) \f$; i.e, gu_. - */ - virtual bool get_bounds_info( - Index n , - Number* x_l , - Number* x_u , - Index m , - Number* g_l , - Number* g_u ) - { size_t i; - // here, the n and m we gave IPOPT in get_nlp_info are passed back - CPPAD_ASSERT_UNKNOWN(static_cast(n) == nx_); - CPPAD_ASSERT_UNKNOWN(static_cast(m) == ng_); - - // pass back bounds - for(i = 0; i < nx_; i++) - { x_l[i] = xl_[i]; - x_u[i] = xu_[i]; - } - for(i = 0; i < ng_; i++) - { g_l[i] = gl_[i]; - g_u[i] = gu_[i]; - } - - return true; - } - // ----------------------------------------------------------------------- - /*! - Return initial x value where optimiation is started. - - \param[in] n - must be equal to the domain dimension for f(x) and g(x); i.e., - it must be equal to nx_. - - \param[in] init_x - must be equal to true. - - \param[out] x - is a vector of size nx_. - The input value of its elements does not matter. - On output, it is a copy of the initial value for \f$ x \f$; i.e. xi_. - - \param[in] init_z - must be equal to false. - - \param z_L - is not used. - - \param z_U - is not used. - - \param[in] m - must be equal to the domain dimension for f(x) and g(x); i.e., - it must be equal to ng_. - - \param init_lambda - must be equal to false. - - \param lambda - is not used. - */ - virtual bool get_starting_point( - Index n , - bool init_x , - Number* x , - bool init_z , - Number* z_L , - Number* z_U , - Index m , - bool init_lambda , - Number* lambda ) - { size_t j; - - CPPAD_ASSERT_UNKNOWN(static_cast(n) == nx_ ); - CPPAD_ASSERT_UNKNOWN(static_cast(m) == ng_ ); - CPPAD_ASSERT_UNKNOWN(init_x == true); - CPPAD_ASSERT_UNKNOWN(init_z == false); - CPPAD_ASSERT_UNKNOWN(init_lambda == false); - - for(j = 0; j < nx_; j++) - x[j] = xi_[j]; - - return true; - } - // ----------------------------------------------------------------------- - /*! - Evaluate the objective fucntion f(x). - - \param[in] n - is the dimension of the argument space for f(x); i.e., must be equal nx_. - - \param[in] x - is a vector of size nx_ containing the point at which to evaluate - the function sum_i f_i (x). - - \param[in] new_x - is false if the previous call to any one of the - \ref Evaluation_Methods used the same value for x. - - \param[out] obj_value - is the value of the objective sum_i f_i (x) at this value of x. - - \return - The return value is always true; see \ref Evaluation_Methods. - */ - virtual bool eval_f( - Index n , - const Number* x , - bool new_x , - Number& obj_value ) - { size_t i; - if( new_x ) - cache_new_x(x); - // - double sum = 0.0; - for(i = 0; i < nf_; i++) - sum += fg0_[i]; - obj_value = static_cast(sum); - return true; - } - // ----------------------------------------------------------------------- - /*! - Evaluate the gradient of f(x). - - \param[in] n - is the dimension of the argument space for f(x); i.e., must be equal nx_. - - \param[in] x - has a vector of size nx_ containing the point at which to evaluate - the gradient of f(x). - - \param[in] new_x - is false if the previous call to any one of the - \ref Evaluation_Methods used the same value for x. - - \param[out] grad_f - is a vector of size nx_. - The input value of its elements does not matter. - The output value of its elements is the gradient of f(x) - at this value of. - - \return - The return value is always true; see \ref Evaluation_Methods. - */ - virtual bool eval_grad_f( - Index n , - const Number* x , - bool new_x , - Number* grad_f ) - { size_t i; - if( new_x ) - cache_new_x(x); - // - Dvector w(nf_ + ng_), dw(nx_); - for(i = 0; i < nf_; i++) - w[i] = 1.0; - for(i = 0; i < ng_; i++) - w[nf_ + i] = 0.0; - dw = adfun_.Reverse(1, w); - for(i = 0; i < nx_; i++) - grad_f[i] = dw[i]; - return true; - } - // ----------------------------------------------------------------------- - /*! - Evaluate the function g(x). - - \param[in] n - is the dimension of the argument space for g(x); i.e., must be equal nx_. - - \param[in] x - has a vector of size n containing the point at which to evaluate - the gradient of g(x). - - \param[in] new_x - is false if the previous call to any one of the - \ref Evaluation_Methods used the same value for x. - - \param[in] m - is the dimension of the range space for g(x); i.e., must be equal to ng_. - - \param[out] g - is a vector of size ng_. - The input value of its elements does not matter. - The output value of its elements is - the value of the function g(x) at this value of x. - - \return - The return value is always true; see \ref Evaluation_Methods. - */ - virtual bool eval_g( - Index n , - const Number* x , - bool new_x , - Index m , - Number* g ) - { size_t i; - if( new_x ) - cache_new_x(x); - // - for(i = 0; i < ng_; i++) - g[i] = fg0_[nf_ + i]; - return true; - } - // ----------------------------------------------------------------------- - /*! - Evaluate the Jacobian of g(x). - - \param[in] n - is the dimension of the argument space for g(x); - i.e., must be equal nx_. - - \param x - If values is not NULL, - x is a vector of size nx_ containing the point at which to evaluate - the gradient of g(x). - - \param[in] new_x - is false if the previous call to any one of the - \ref Evaluation_Methods used the same value for x. - - \param[in] m - is the dimension of the range space for g(x); - i.e., must be equal to ng_. - - \param[in] nele_jac - is the number of possibly non-zero elements in the Jacobian of g(x); - i.e., must be equal to ng_ * nx_. - - \param iRow - if values is not NULL, iRow is not defined. - if values is NULL, iRow - is a vector with size nele_jac. - The input value of its elements does not matter. - On output, - For k = 0 , ... , nele_jac-1, iRow[k] is the - base zero row index for the - k-th possibly non-zero entry in the Jacobian of g(x). - - \param jCol - if values is not NULL, jCol is not defined. - if values is NULL, jCol - is a vector with size nele_jac. - The input value of its elements does not matter. - On output, - For k = 0 , ... , nele_jac-1, jCol[k] is the - base zero column index for the - k-th possibly non-zero entry in the Jacobian of g(x). - - \param values - if values is not NULL, values - is a vector with size nele_jac. - The input value of its elements does not matter. - On output, - For k = 0 , ... , nele_jac-1, values[k] is the - value for the - k-th possibly non-zero entry in the Jacobian of g(x). - - \return - The return value is always true; see \ref Evaluation_Methods. - */ - virtual bool eval_jac_g( - Index n, - const Number* x, - bool new_x, - - Index m, - Index nele_jac, - Index* iRow, - Index *jCol, - - Number* values) - { size_t i, j, k, ell; - CPPAD_ASSERT_UNKNOWN(static_cast(m) == ng_ ); - CPPAD_ASSERT_UNKNOWN(static_cast(n) == nx_ ); - // - size_t nk = row_jac_.size(); - CPPAD_ASSERT_UNKNOWN( static_cast(nele_jac) == nk ); - // - if( new_x ) - cache_new_x(x); - - if( values == NULL ) - { for(k = 0; k < nk; k++) - { i = row_jac_[k]; - j = col_jac_[k]; - CPPAD_ASSERT_UNKNOWN( i >= nf_ ); - iRow[k] = static_cast(i - nf_); - jCol[k] = static_cast(j); - } - return true; - } - // - if( nk == 0 ) - return true; - // - if( sparse_forward_ ) - { Dvector jac(nk); - adfun_.SparseJacobianForward( - x0_ , pattern_jac_, row_jac_, col_jac_, jac, work_jac_ - ); - for(k = 0; k < nk; k++) - values[k] = jac[k]; - } - else if( sparse_reverse_ ) - { Dvector jac(nk); - adfun_.SparseJacobianReverse( - x0_ , pattern_jac_, row_jac_, col_jac_, jac, work_jac_ - ); - for(k = 0; k < nk; k++) - values[k] = jac[k]; - } - else if( nx_ < ng_ ) - { // use forward mode - Dvector x1(nx_), fg1(nf_ + ng_); - for(j = 0; j < nx_; j++) - x1[j] = 0.0; - // index in col_order_jac_ of next entry - ell = 0; - k = col_order_jac_[ell]; - for(j = 0; j < nx_; j++) - { // compute j-th column of Jacobian of g(x) - x1[j] = 1.0; - fg1 = adfun_.Forward(1, x1); - while( ell < nk && col_jac_[k] <= j ) - { CPPAD_ASSERT_UNKNOWN( col_jac_[k] == j ); - i = row_jac_[k]; - CPPAD_ASSERT_UNKNOWN( i >= nf_ ) - values[k] = fg1[i]; - ell++; - if( ell < nk ) - k = col_order_jac_[ell]; - } - x1[j] = 0.0; - } - } - else - { // user reverse mode - size_t nfg = nf_ + ng_; - // user reverse mode - Dvector w(nfg), dw(nx_); - for(i = 0; i < nfg; i++) - w[i] = 0.0; - // index in row_jac_ of next entry - k = 0; - for(i = nf_; i < nfg; i++) - { // compute i-th row of Jacobian of g(x) - w[i] = 1.0; - dw = adfun_.Reverse(1, w); - while( k < nk && row_jac_[k] <= i ) - { CPPAD_ASSERT_UNKNOWN( row_jac_[k] == i ); - j = col_jac_[k]; - values[k] = dw[j]; - k++; - } - w[i] = 0.0; - } - } - return true; - } - // ----------------------------------------------------------------------- - /*! - Evaluate the Hessian of the Lagragian - - \section The_Hessian_of_the_Lagragian The Hessian of the Lagragian - The Hessian of the Lagragian is defined as - \f[ - H(x, \sigma, \lambda ) - = - \sigma \nabla^2 f(x) + \sum_{i=0}^{m-1} \lambda_i \nabla^2 g(x)_i - \f] - - \param[in] n - is the dimension of the argument space for g(x); - i.e., must be equal nx_. - - \param x - if values is not NULL, x - is a vector of size nx_ containing the point at which to evaluate - the Hessian of the Lagragian. - - \param[in] new_x - is false if the previous call to any one of the - \ref Evaluation_Methods used the same value for x. - - \param[in] obj_factor - the value \f$ \sigma \f$ multiplying the Hessian of - f(x) in the expression for \ref The_Hessian_of_the_Lagragian. - - \param[in] m - is the dimension of the range space for g(x); - i.e., must be equal to ng_. - - \param[in] lambda - if values is not NULL, lambda - is a vector of size ng_ specifing the value of \f$ \lambda \f$ - in the expression for \ref The_Hessian_of_the_Lagragian. - - \param[in] new_lambda - is true if the previous call to eval_h had the same value for - lambda and false otherwise. - (Not currently used.) - - \param[in] nele_hess - is the number of possibly non-zero elements in the - Hessian of the Lagragian; - i.e., must be equal to nx_*(nx_+1)/2. - - \param iRow - if values is not NULL, iRow is not defined. - if values is NULL, iRow - is a vector with size nele_hess. - The input value of its elements does not matter. - On output, - For k = 0 , ... , nele_hess-1, iRow[k] is the - base zero row index for the - k-th possibly non-zero entry in the Hessian fo the Lagragian. - - \param jCol - if values is not NULL, jCol is not defined. - if values is NULL, jCol - is a vector with size nele_hess. - The input value of its elements does not matter. - On output, - For k = 0 , ... , nele_hess-1, jCol[k] is the - base zero column index for the - k-th possibly non-zero entry in the Hessian of the Lagragian. - - \param values - if values is not NULL, it - is a vector with size nele_hess. - The input value of its elements does not matter. - On output, - For k = 0 , ... , nele_hess-1, values[k] is the - value for the - k-th possibly non-zero entry in the Hessian of the Lagragian. - - \return - The return value is always true; see \ref Evaluation_Methods. - */ - virtual bool eval_h( - Index n , - const Number* x , - bool new_x , - Number obj_factor , - Index m , - const Number* lambda , - bool new_lambda , - Index nele_hess , - Index* iRow , - Index* jCol , - Number* values ) - { size_t i, j, k; - CPPAD_ASSERT_UNKNOWN(static_cast(m) == ng_ ); - CPPAD_ASSERT_UNKNOWN(static_cast(n) == nx_ ); - // - size_t nk = row_hes_.size(); - CPPAD_ASSERT_UNKNOWN( static_cast(nele_hess) == nk ); - // - if( new_x ) - cache_new_x(x); - // - if( values == NULL ) - { for(k = 0; k < nk; k++) - { i = row_hes_[k]; - j = col_hes_[k]; - iRow[k] = static_cast(i); - jCol[k] = static_cast(j); - } - return true; - } - // - if( nk == 0 ) - return true; - - // weigting vector for Lagragian - Dvector w(nf_ + ng_); - for(i = 0; i < nf_; i++) - w[i] = obj_factor; - for(i = 0; i < ng_; i++) - w[i + nf_] = lambda[i]; - // - if( sparse_forward_ | sparse_reverse_ ) - { Dvector hes(nk); - adfun_.SparseHessian( - x0_, w, pattern_hes_, row_hes_, col_hes_, hes, work_hes_ - ); - for(k = 0; k < nk; k++) - values[k] = hes[k]; - } - else - { Dvector hes(nx_ * nx_); - hes = adfun_.Hessian(x0_, w); - for(k = 0; k < nk; k++) - { i = row_hes_[k]; - j = col_hes_[k]; - values[k] = hes[i * nx_ + j]; - } - } - return true; - } - // ---------------------------------------------------------------------- - /*! - Pass solution information from Ipopt to users solution structure. - - \param[in] status - is value that the Ipopt solution status - which gets mapped to a correponding value for - \n - solution_.status - - \param[in] n - is the dimension of the domain space for f(x) and g(x); i.e., - it must be equal to nx_. - - \param[in] x - is a vector with size nx_ specifing the final solution. - This is the output value for - \n - solution_.x - - \param[in] z_L - is a vector with size nx_ specifing the Lagragian multipliers for the - constraint \f$ x^l \leq x \f$. - This is the output value for - \n - solution_.zl - - \param[in] z_U - is a vector with size nx_ specifing the Lagragian multipliers for the - constraint \f$ x \leq x^u \f$. - This is the output value for - \n - solution_.zu - - \param[in] m - is the dimension of the range space for g(x). i.e., - it must be equal to ng_. - - \param[in] g - is a vector with size ng_ containing the value of the constraint function - g(x) at the final solution x. - This is the output value for - \n - solution_.g - - \param[in] lambda - is a vector with size ng_ specifing the Lagragian multipliers for the - constraints \f$ g^l \leq g(x) \leq g^u \f$. - This is the output value for - \n - solution_.lambda - - \param[in] obj_value - is the value of the objective function f(x) at the final solution x. - This is the output value for - \n - solution_.obj_value - - \param[in] ip_data - is unspecified (by Ipopt) and hence not used. - - \param[in] ip_cq - is unspecified (by Ipopt) and hence not used. - - \par solution_[out] - this is a reference to the solution argument - in the constructor for solve_callback. - The results are stored here - (see documentation above). - */ - virtual void finalize_solution( - Ipopt::SolverReturn status , - Index n , - const Number* x , - const Number* z_L , - const Number* z_U , - Index m , - const Number* g , - const Number* lambda , - Number obj_value , - const Ipopt::IpoptData* ip_data , - Ipopt::IpoptCalculatedQuantities* ip_cq - ) - { size_t i, j; - - CPPAD_ASSERT_UNKNOWN(static_cast(n) == nx_ ); - CPPAD_ASSERT_UNKNOWN(static_cast(m) == ng_ ); - - switch(status) - { // convert status from Ipopt enum to solve_result enum - case Ipopt::SUCCESS: - solution_.status = solve_result::success; - break; - - case Ipopt::MAXITER_EXCEEDED: - solution_.status = - solve_result::maxiter_exceeded; - break; - - case Ipopt::STOP_AT_TINY_STEP: - solution_.status = - solve_result::stop_at_tiny_step; - break; - - case Ipopt::STOP_AT_ACCEPTABLE_POINT: - solution_.status = - solve_result::stop_at_acceptable_point; - break; - - case Ipopt::LOCAL_INFEASIBILITY: - solution_.status = - solve_result::local_infeasibility; - break; - - case Ipopt::USER_REQUESTED_STOP: - solution_.status = - solve_result::user_requested_stop; - break; - - case Ipopt::DIVERGING_ITERATES: - solution_.status = - solve_result::diverging_iterates; - break; - - case Ipopt::RESTORATION_FAILURE: - solution_.status = - solve_result::restoration_failure; - break; - - case Ipopt::ERROR_IN_STEP_COMPUTATION: - solution_.status = - solve_result::error_in_step_computation; - break; - - case Ipopt::INVALID_NUMBER_DETECTED: - solution_.status = - solve_result::invalid_number_detected; - break; - - case Ipopt::INTERNAL_ERROR: - solution_.status = - solve_result::internal_error; - break; - - default: - solution_.status = - solve_result::unknown; - } - - solution_.x.resize(nx_); - solution_.zl.resize(nx_); - solution_.zu.resize(nx_); - for(j = 0; j < nx_; j++) - { solution_.x[j] = x[j]; - solution_.zl[j] = z_L[j]; - solution_.zu[j] = z_U[j]; - } - solution_.g.resize(ng_); - solution_.lambda.resize(ng_); - for(i = 0; i < ng_; i++) - { solution_.g[i] = g[i]; - solution_.lambda[i] = lambda[i]; - } - solution_.obj_value = obj_value; - return; - } -}; - -} // end namespace ipopt -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/ipopt/solve_result.hpp b/build-config/cppad/include/cppad/ipopt/solve_result.hpp deleted file mode 100644 index 8cc12ce3..00000000 --- a/build-config/cppad/include/cppad/ipopt/solve_result.hpp +++ /dev/null @@ -1,73 +0,0 @@ -# ifndef CPPAD_IPOPT_SOLVE_RESULT_HPP -# define CPPAD_IPOPT_SOLVE_RESULT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -namespace ipopt { -/*! -\file solve_result.hpp -Class that contains information about solve problem result -*/ - -/*! -Class that contains information about solve problem result - -\tparam Dvector -a simple vector with elements of type double -*/ -template -class solve_result -{ -public: - /// possible values for the result status - enum status_type { - not_defined, - success, - maxiter_exceeded, - stop_at_tiny_step, - stop_at_acceptable_point, - local_infeasibility, - user_requested_stop, - feasible_point_found, - diverging_iterates, - restoration_failure, - error_in_step_computation, - invalid_number_detected, - too_few_degrees_of_freedom, - internal_error, - unknown - }; - - /// possible values for solution status - status_type status; - /// the approximation solution - Dvector x; - /// Lagrange multipliers corresponding to lower bounds on x - Dvector zl; - /// Lagrange multipliers corresponding to upper bounds on x - Dvector zu; - /// value of g(x) - Dvector g; - /// Lagrange multipliers correspondiing constraints on g(x) - Dvector lambda; - /// value of f(x) - double obj_value; - /// constructor initializes solution status as not yet defined - solve_result(void) - { status = not_defined; } -}; - -} // end namespace ipopt -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/abs_op.hpp b/build-config/cppad/include/cppad/local/abs_op.hpp deleted file mode 100644 index f0e7fe41..00000000 --- a/build-config/cppad/include/cppad/local/abs_op.hpp +++ /dev/null @@ -1,160 +0,0 @@ -# ifndef CPPAD_LOCAL_ABS_OP_HPP -# define CPPAD_LOCAL_ABS_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file abs_op.hpp -Forward and reverse mode calculations for z = fabs(x). -*/ - -/*! -Compute forward mode Taylor coefficient for result of op = AbsOp. - -The C++ source code corresponding to this operation is -\verbatim - z = fabs(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op -*/ -template -void forward_abs_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - for(size_t j = p; j <= q; j++) - z[j] = sign(x[0]) * x[j]; -} - -/*! -Multiple directions forward mode Taylor coefficient for op = AbsOp. - -The C++ source code corresponding to this operation is -\verbatim - z = fabs(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_dir -*/ -template -void forward_abs_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - z[m + ell] = sign(x[0]) * x[m + ell]; -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = AbsOp. - -The C++ source code corresponding to this operation is -\verbatim - z = fabs(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_0 -*/ -template -void forward_abs_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base x0 = *(taylor + i_x * cap_order); - Base* z = taylor + i_z * cap_order; - - z[0] = fabs(x0); -} -/*! -Compute reverse mode partial derivatives for result of op = AbsOp. - -The C++ source code corresponding to this operation is -\verbatim - z = fabs(x) -\endverbatim - -\copydetails CppAD::local::reverse_unary1_op -*/ - -template -void reverse_abs_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ size_t j; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to result - Base* pz = partial + i_z * nc_partial; - - // do not need azmul because sign is either +1, -1, or zero - for(j = 0; j <= d; j++) - px[j] += sign(x[0]) * pz[j]; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/acos_op.hpp b/build-config/cppad/include/cppad/local/acos_op.hpp deleted file mode 100644 index 512c3b94..00000000 --- a/build-config/cppad/include/cppad/local/acos_op.hpp +++ /dev/null @@ -1,263 +0,0 @@ -# ifndef CPPAD_LOCAL_ACOS_OP_HPP -# define CPPAD_LOCAL_ACOS_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file acos_op.hpp -Forward and reverse mode calculations for z = acos(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = AcosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acos(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(1 - x * x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_acos_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - size_t k; - Base uj; - if( p == 0 ) - { z[0] = acos( x[0] ); - uj = Base(1.0) - x[0] * x[0]; - b[0] = sqrt( uj ); - p++; - } - for(size_t j = p; j <= q; j++) - { uj = Base(0.0); - for(k = 0; k <= j; k++) - uj -= x[k] * x[j-k]; - b[j] = Base(0.0); - z[j] = Base(0.0); - for(k = 1; k < j; k++) - { b[j] -= Base(double(k)) * b[k] * b[j-k]; - z[j] -= Base(double(k)) * z[k] * b[j-k]; - } - b[j] /= Base(double(j)); - z[j] /= Base(double(j)); - // - b[j] += uj / Base(2.0); - z[j] -= x[j]; - // - b[j] /= b[0]; - z[j] /= b[0]; - } -} -/*! -Multiple directions forward mode Taylor coefficient for op = AcosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acos(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(1 - x * x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_acos_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* b = z - num_taylor_per_var; // called y in documentation - - size_t k, ell; - size_t m = (q-1) * r + 1; - for(ell = 0; ell < r; ell ++) - { Base uq = - 2.0 * x[m + ell] * x[0]; - for(k = 1; k < q; k++) - uq -= x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - b[m+ell] = Base(0.0); - z[m+ell] = Base(0.0); - for(k = 1; k < q; k++) - { b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - } - b[m+ell] = ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0]; - z[m+ell] = -( x[m+ell] + z[m+ell] / Base(double(q)) ) / b[0]; - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = AcosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acos(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( 1 - x * x ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_acos_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - z[0] = acos( x[0] ); - b[0] = sqrt( Base(1.0) - x[0] * x[0] ); -} -/*! -Compute reverse mode partial derivatives for result of op = AcosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acos(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( 1 - x * x ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_acos_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* b = z - cap_order; // called y in documentation - Base* pb = pz - nc_partial; - - Base inv_b0 = Base(1.0) / b[0]; - - // number of indices to access - size_t j = d; - size_t k; - while(j) - { - // scale partials w.r.t b[j] by 1 / b[0] - pb[j] = azmul(pb[j], inv_b0); - - // scale partials w.r.t z[j] by 1 / b[0] - pz[j] = azmul(pz[j], inv_b0); - - // update partials w.r.t b^0 - pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]); - - // update partial w.r.t. x^0 - px[0] -= azmul(pb[j], x[j]); - - // update partial w.r.t. x^j - px[j] -= pz[j] + azmul(pb[j], x[0]); - - // further scale partial w.r.t. z[j] by 1 / j - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { // update partials w.r.t b^(j-k) - pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]); - - // update partials w.r.t. x^k - px[k] -= azmul(pb[j], x[j-k]); - - // update partials w.r.t. z^k - pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]); - } - --j; - } - - // j == 0 case - px[0] -= azmul( pz[0] + azmul(pb[0], x[0]), inv_b0); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/acosh_op.hpp b/build-config/cppad/include/cppad/local/acosh_op.hpp deleted file mode 100644 index 4aabec0a..00000000 --- a/build-config/cppad/include/cppad/local/acosh_op.hpp +++ /dev/null @@ -1,264 +0,0 @@ -# ifndef CPPAD_LOCAL_ACOSH_OP_HPP -# define CPPAD_LOCAL_ACOSH_OP_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file acosh_op.hpp -Forward and reverse mode calculations for z = acosh(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = AcoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(x * x - 1) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_acosh_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - size_t k; - Base uj; - if( p == 0 ) - { z[0] = acosh( x[0] ); - uj = x[0] * x[0] - Base(1.0); - b[0] = sqrt( uj ); - p++; - } - for(size_t j = p; j <= q; j++) - { uj = Base(0.0); - for(k = 0; k <= j; k++) - uj += x[k] * x[j-k]; - b[j] = Base(0.0); - z[j] = Base(0.0); - for(k = 1; k < j; k++) - { b[j] -= Base(double(k)) * b[k] * b[j-k]; - z[j] -= Base(double(k)) * z[k] * b[j-k]; - } - b[j] /= Base(double(j)); - z[j] /= Base(double(j)); - // - b[j] += uj / Base(2.0); - z[j] += x[j]; - // - b[j] /= b[0]; - z[j] /= b[0]; - } -} -/*! -Multiple directions forward mode Taylor coefficient for op = AcoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(x * x - 1) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_acosh_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* b = z - num_taylor_per_var; // called y in documentation - - size_t k, ell; - size_t m = (q-1) * r + 1; - for(ell = 0; ell < r; ell ++) - { Base uq = 2.0 * x[m + ell] * x[0]; - for(k = 1; k < q; k++) - uq += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - b[m+ell] = Base(0.0); - z[m+ell] = Base(0.0); - for(k = 1; k < q; k++) - { b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - } - b[m+ell] = ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0]; - z[m+ell] = ( x[m+ell] - z[m+ell] / Base(double(q)) ) / b[0]; - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = AcoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( x * x - 1 ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_acosh_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - z[0] = acosh( x[0] ); - b[0] = sqrt( x[0] * x[0] - Base(1.0) ); -} -/*! -Compute reverse mode partial derivatives for result of op = AcoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = acosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( x * x - 1 ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_acosh_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* b = z - cap_order; // called y in documentation - Base* pb = pz - nc_partial; - - Base inv_b0 = Base(1.0) / b[0]; - - // number of indices to access - size_t j = d; - size_t k; - while(j) - { - // scale partials w.r.t b[j] by 1 / b[0] - pb[j] = azmul(pb[j], inv_b0); - - // scale partials w.r.t z[j] by 1 / b[0] - pz[j] = azmul(pz[j], inv_b0); - - // update partials w.r.t b^0 - pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]); - - // update partial w.r.t. x^0 - px[0] += azmul(pb[j], x[j]); - - // update partial w.r.t. x^j - px[j] += pz[j] + azmul(pb[j], x[0]); - - // further scale partial w.r.t. z[j] by 1 / j - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { // update partials w.r.t b^(j-k) - pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]); - - // update partials w.r.t. x^k - px[k] += azmul(pb[j], x[j-k]); - - // update partials w.r.t. z^k - pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]); - } - --j; - } - - // j == 0 case - px[0] += azmul(pz[0] + azmul(pb[0], x[0]), inv_b0); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/ad_tape.hpp b/build-config/cppad/include/cppad/local/ad_tape.hpp deleted file mode 100644 index d0f19af1..00000000 --- a/build-config/cppad/include/cppad/local/ad_tape.hpp +++ /dev/null @@ -1,186 +0,0 @@ -# ifndef CPPAD_LOCAL_AD_TAPE_HPP -# define CPPAD_LOCAL_AD_TAPE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL__NAMESPACE - -/*! -Class used to hold tape that records AD operations. - -\tparam Base -An AD object is used to recording AD operations. -*/ - -template -class ADTape { - // Friends ============================================================= - - // classes ------------------------------------------------------------- - friend class AD; - friend class ADFun; - friend class atomic_base; - friend class atomic_three; - friend class discrete; - friend class VecAD; - friend class VecAD_reference; - - // functions ----------------------------------------------------------- - // PrintFor - friend void CppAD::PrintFor ( - const AD& flag , - const char* before , - const AD& var , - const char* after - ); - // CondExpOp - friend AD CppAD::CondExpOp ( - enum CompareOp cop , - const AD &left , - const AD &right , - const AD &trueCase , - const AD &falseCase - ); - // pow - friend AD CppAD::pow - (const AD &x, const AD &y); - // azmul - friend AD CppAD::azmul - (const AD &x, const AD &y); - // Parameter - friend bool CppAD::Parameter - (const AD &u); - // Variable - friend bool CppAD::Variable - (const AD &u); - // operators ----------------------------------------------------------- - // arithematic binary operators -# if _MSC_VER - // see https://stackoverflow.com/questions/63288453 - template friend AD CppAD::operator * - (const AD &left, const AD &right); -# else - friend AD CppAD::operator * - (const AD &left, const AD &right); -# endif - friend AD CppAD::operator + - (const AD &left, const AD &right); - friend AD CppAD::operator - - (const AD &left, const AD &right); - friend AD CppAD::operator / - (const AD &left, const AD &right); - - // comparison operators -# if _MSC_VER - template friend bool CppAD::operator == - (const AD &left, const AD &right); - template friend bool CppAD::operator != - (const AD &left, const AD &right); -# else - friend bool CppAD::operator == - (const AD &left, const AD &right); - friend bool CppAD::operator != - (const AD &left, const AD &right); -# endif - friend bool CppAD::operator < - (const AD &left, const AD &right); - friend bool CppAD::operator <= - (const AD &left, const AD &right); - friend bool CppAD::operator > - (const AD &left, const AD &right); - friend bool CppAD::operator >= - (const AD &left, const AD &right); - // ====================================================================== - -// -------------------------------------------------------------------------- -private: - // ---------------------------------------------------------------------- - // private data - /*! - Unique identifier for this tape. It is always greater than - CPPAD_MAX_NUM_THREADS, and different for every tape (even ones that have - been deleted). In addition, id_ % CPPAD_MAX_NUM_THREADS is the thread - number for this tape. Set by Independent and effectively const - */ - tape_id_t id_; - /// Number of independent variables in this tapes reconding. - /// Set by Independent and effectively const - size_t size_independent_; - /// This is where the information is recorded. - local::recorder Rec_; - // ---------------------------------------------------------------------- - // private functions - // - // add a parameter to the tape - addr_t RecordParOp(const AD& y); - - // see CondExp.h - void RecordCondExp( - enum CompareOp cop , - AD &returnValue , - const AD &left , - const AD &right , - const AD &trueCase , - const AD &falseCase - ); - -public: - // public function only used by CppAD::Independent - template - void Independent( - ADBaseVector& x , - size_t abort_op_index , - bool record_compare , - ADBaseVector& dynamic - ); - -}; -// --------------------------------------------------------------------------- -// Private functions -// - -/*! -Place a parameter in the tape as a variable. - -On rare occations it is necessary to place a parameter in the tape; e.g., -when it is one of the dependent variabes. - -\param y -value of the parameter that we are placing in the tape as a variable. - -\return -variable index (for this recording) correpsonding to the parameter. - -\par 2DO -All these operates are preformed in Rec_, so we should -move this routine from ADTape to recorder. -*/ -template -addr_t ADTape::RecordParOp(const AD& y) -{ CPPAD_ASSERT_UNKNOWN( NumRes(ParOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumArg(ParOp) == 1 ); - addr_t z_taddr = Rec_.PutOp(ParOp); - if( Dynamic(y) ) - { addr_t ind = y.taddr_; - Rec_.PutArg(ind); - } - else - { addr_t ind = Rec_.put_con_par(y.value_); - Rec_.PutArg(ind); - } - return z_taddr; -} - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/add_op.hpp b/build-config/cppad/include/cppad/local/add_op.hpp deleted file mode 100644 index 6b193346..00000000 --- a/build-config/cppad/include/cppad/local/add_op.hpp +++ /dev/null @@ -1,338 +0,0 @@ -# ifndef CPPAD_LOCAL_ADD_OP_HPP -# define CPPAD_LOCAL_ADD_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file add_op.hpp -Forward and reverse mode calculations for z = x + y. -*/ - -// --------------------------- Addvv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = AddvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_addvv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - for(size_t j = p; j <= q; j++) - z[j] = x[j] + y[j]; -} -/*! -Multiple directions forward mode Taylor coefficients for op = AddvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_addvv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t m = (q-1)*r + 1 ; - for(size_t ell = 0; ell < r; ell++) - z[m+ell] = x[m+ell] + y[m+ell]; -} - -/*! -Compute zero order forward mode Taylor coefficients for result of op = AddvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_addvv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x[0] + y[0]; -} - -/*! -Compute reverse mode partial derivatives for result of op = AddvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_addvv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t i = d + 1; - while(i) - { --i; - px[i] += pz[i]; - py[i] += pz[i]; - } -} - -// --------------------------- Addpv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = AddpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op -*/ -template -void forward_addpv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - if( p == 0 ) - { // Paraemter value - Base x = parameter[ arg[0] ]; - z[0] = x + y[0]; - p++; - } - for(size_t j = p; j <= q; j++) - z[j] = y[j]; -} -/*! -Multiple directions forward mode Taylor coefficients for op = AddpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_dir -*/ -template -void forward_addpv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q-1) * r + 1; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m; - Base* z = taylor + i_z * num_taylor_per_var + m; - - for(size_t ell = 0; ell < r; ell++) - z[ell] = y[ell]; -} -/*! -Compute zero order forward mode Taylor coefficient for result of op = AddpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_addpv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 ); - - // Paraemter value - Base x = parameter[ arg[0] ]; - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x + y[0]; -} - -/*! -Compute reverse mode partial derivative for result of op = AddpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x + y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_addpv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Partial derivatives corresponding to arguments and result - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t i = d + 1; - while(i) - { --i; - py[i] += pz[i]; - } -} - - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/asin_op.hpp b/build-config/cppad/include/cppad/local/asin_op.hpp deleted file mode 100644 index 5909aead..00000000 --- a/build-config/cppad/include/cppad/local/asin_op.hpp +++ /dev/null @@ -1,263 +0,0 @@ -# ifndef CPPAD_LOCAL_ASIN_OP_HPP -# define CPPAD_LOCAL_ASIN_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file asin_op.hpp -Forward and reverse mode calculations for z = asin(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = AsinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asin(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(1 - x * x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_asin_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AsinOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AsinOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - size_t k; - Base uj; - if( p == 0 ) - { z[0] = asin( x[0] ); - uj = Base(1.0) - x[0] * x[0]; - b[0] = sqrt( uj ); - p++; - } - for(size_t j = p; j <= q; j++) - { uj = Base(0.0); - for(k = 0; k <= j; k++) - uj -= x[k] * x[j-k]; - b[j] = Base(0.0); - z[j] = Base(0.0); - for(k = 1; k < j; k++) - { b[j] -= Base(double(k)) * b[k] * b[j-k]; - z[j] -= Base(double(k)) * z[k] * b[j-k]; - } - b[j] /= Base(double(j)); - z[j] /= Base(double(j)); - // - b[j] += uj / Base(2.0); - z[j] += x[j]; - // - b[j] /= b[0]; - z[j] /= b[0]; - } -} -/*! -Multiple directions forward mode Taylor coefficient for op = AsinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asin(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(1 - x * x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_asin_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* b = z - num_taylor_per_var; // called y in documentation - - size_t k, ell; - size_t m = (q-1) * r + 1; - for(ell = 0; ell < r; ell ++) - { Base uq = - 2.0 * x[m + ell] * x[0]; - for(k = 1; k < q; k++) - uq -= x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - b[m+ell] = Base(0.0); - z[m+ell] = Base(0.0); - for(k = 1; k < q; k++) - { b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - } - b[m+ell] = ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0]; - z[m+ell] = ( x[m+ell] - z[m+ell] / Base(double(q)) ) / b[0]; - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = AsinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asin(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( 1 - x * x ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_asin_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AsinOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AsinOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - z[0] = asin( x[0] ); - b[0] = sqrt( Base(1.0) - x[0] * x[0] ); -} -/*! -Compute reverse mode partial derivatives for result of op = AsinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asin(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( 1 - x * x ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_asin_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AsinOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AsinOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* b = z - cap_order; // called y in documentation - Base* pb = pz - nc_partial; - - Base inv_b0 = Base(1.0) / b[0]; - - // number of indices to access - size_t j = d; - size_t k; - while(j) - { - // scale partials w.r.t b[j] by 1 / b[0] - pb[j] = azmul(pb[j], inv_b0); - - // scale partials w.r.t z[j] by 1 / b[0] - pz[j] = azmul(pz[j], inv_b0); - - // update partials w.r.t b^0 - pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]); - - // update partial w.r.t. x^0 - px[0] -= azmul(pb[j], x[j]); - - // update partial w.r.t. x^j - px[j] += pz[j] - azmul(pb[j], x[0]); - - // further scale partial w.r.t. z[j] by 1 / j - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { // update partials w.r.t b^(j-k) - pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]); - - // update partials w.r.t. x^k - px[k] -= azmul(pb[j], x[j-k]); - - // update partials w.r.t. z^k - pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]); - } - --j; - } - - // j == 0 case - px[0] += azmul(pz[0] - azmul(pb[0], x[0]), inv_b0); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/asinh_op.hpp b/build-config/cppad/include/cppad/local/asinh_op.hpp deleted file mode 100644 index 84b16b57..00000000 --- a/build-config/cppad/include/cppad/local/asinh_op.hpp +++ /dev/null @@ -1,264 +0,0 @@ -# ifndef CPPAD_LOCAL_ASINH_OP_HPP -# define CPPAD_LOCAL_ASINH_OP_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file asinh_op.hpp -Forward and reverse mode calculations for z = asinh(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = AsinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asinh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(1 + x * x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_asinh_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AsinhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AsinhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - size_t k; - Base uj; - if( p == 0 ) - { z[0] = asinh( x[0] ); - uj = Base(1.0) + x[0] * x[0]; - b[0] = sqrt( uj ); - p++; - } - for(size_t j = p; j <= q; j++) - { uj = Base(0.0); - for(k = 0; k <= j; k++) - uj += x[k] * x[j-k]; - b[j] = Base(0.0); - z[j] = Base(0.0); - for(k = 1; k < j; k++) - { b[j] -= Base(double(k)) * b[k] * b[j-k]; - z[j] -= Base(double(k)) * z[k] * b[j-k]; - } - b[j] /= Base(double(j)); - z[j] /= Base(double(j)); - // - b[j] += uj / Base(2.0); - z[j] += x[j]; - // - b[j] /= b[0]; - z[j] /= b[0]; - } -} -/*! -Multiple directions forward mode Taylor coefficient for op = AsinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asinh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt(1 + x * x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_asinh_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* b = z - num_taylor_per_var; // called y in documentation - - size_t k, ell; - size_t m = (q-1) * r + 1; - for(ell = 0; ell < r; ell ++) - { Base uq = 2.0 * x[m + ell] * x[0]; - for(k = 1; k < q; k++) - uq += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - b[m+ell] = Base(0.0); - z[m+ell] = Base(0.0); - for(k = 1; k < q; k++) - { b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - } - b[m+ell] = ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0]; - z[m+ell] = ( x[m+ell] - z[m+ell] / Base(double(q)) ) / b[0]; - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = AsinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asinh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( 1 + x * x ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_asinh_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AsinhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AsinhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - z[0] = asinh( x[0] ); - b[0] = sqrt( Base(1.0) + x[0] * x[0] ); -} -/*! -Compute reverse mode partial derivatives for result of op = AsinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = asinh(x) -\endverbatim -The auxillary result is -\verbatim - y = sqrt( 1 + x * x ) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_asinh_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AsinhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AsinhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* b = z - cap_order; // called y in documentation - Base* pb = pz - nc_partial; - - Base inv_b0 = Base(1.0) / b[0]; - - // number of indices to access - size_t j = d; - size_t k; - while(j) - { - // scale partials w.r.t b[j] by 1 / b[0] - pb[j] = azmul(pb[j], inv_b0); - - // scale partials w.r.t z[j] by 1 / b[0] - pz[j] = azmul(pz[j], inv_b0); - - // update partials w.r.t b^0 - pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]); - - // update partial w.r.t. x^0 - px[0] += azmul(pb[j], x[j]); - - // update partial w.r.t. x^j - px[j] += pz[j] + azmul(pb[j], x[0]); - - // further scale partial w.r.t. z[j] by 1 / j - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { // update partials w.r.t b^(j-k) - pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]); - - // update partials w.r.t. x^k - px[k] += azmul(pb[j], x[j-k]); - - // update partials w.r.t. z^k - pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]); - } - --j; - } - - // j == 0 case - px[0] += azmul(pz[0] + azmul(pb[0], x[0]), inv_b0); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/atan_op.hpp b/build-config/cppad/include/cppad/local/atan_op.hpp deleted file mode 100644 index 1dbd2c2f..00000000 --- a/build-config/cppad/include/cppad/local/atan_op.hpp +++ /dev/null @@ -1,235 +0,0 @@ -# ifndef CPPAD_LOCAL_ATAN_OP_HPP -# define CPPAD_LOCAL_ATAN_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file atan_op.hpp -Forward and reverse mode calculations for z = atan(x). -*/ - - -/*! -Forward mode Taylor coefficient for result of op = AtanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atan(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 + x * x -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_atan_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - size_t k; - if( p == 0 ) - { z[0] = atan( x[0] ); - b[0] = Base(1.0) + x[0] * x[0]; - p++; - } - for(size_t j = p; j <= q; j++) - { - b[j] = Base(2.0) * x[0] * x[j]; - z[j] = Base(0.0); - for(k = 1; k < j; k++) - { b[j] += x[k] * x[j-k]; - z[j] -= Base(double(k)) * z[k] * b[j-k]; - } - z[j] /= Base(double(j)); - z[j] += x[j]; - z[j] /= b[0]; - } -} - -/*! -Multiple direction Taylor coefficient for op = AtanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atan(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 + x * x -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_atan_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* b = z - num_taylor_per_var; // called y in documentation - - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { b[m+ell] = Base(2.0) * x[m+ell] * x[0]; - z[m+ell] = Base(double(q)) * x[m+ell]; - for(size_t k = 1; k < q; k++) - { b[m+ell] += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - } - z[m+ell] /= ( Base(double(q)) * b[0] ); - } -} - -/*! -Zero order forward mode Taylor coefficient for result of op = AtanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atan(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 + x * x -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_atan_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - z[0] = atan( x[0] ); - b[0] = Base(1.0) + x[0] * x[0]; -} -/*! -Reverse mode partial derivatives for result of op = AtanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atan(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 + x * x -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_atan_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* b = z - cap_order; // called y in documentation - Base* pb = pz - nc_partial; - - Base inv_b0 = Base(1.0) / b[0]; - - // number of indices to access - size_t j = d; - size_t k; - while(j) - { // scale partials w.r.t z[j] and b[j] - pz[j] = azmul(pz[j], inv_b0); - pb[j] *= Base(2.0); - - pb[0] -= azmul(pz[j], z[j]); - px[j] += pz[j] + azmul(pb[j], x[0]); - px[0] += azmul(pb[j], x[j]); - - // more scaling of partials w.r.t z[j] - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]); - pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]); - px[k] += azmul(pb[j], x[j-k]); - } - --j; - } - px[0] += azmul(pz[0], inv_b0) + Base(2.0) * azmul(pb[0], x[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/atanh_op.hpp b/build-config/cppad/include/cppad/local/atanh_op.hpp deleted file mode 100644 index a1adc6af..00000000 --- a/build-config/cppad/include/cppad/local/atanh_op.hpp +++ /dev/null @@ -1,236 +0,0 @@ -# ifndef CPPAD_LOCAL_ATANH_OP_HPP -# define CPPAD_LOCAL_ATANH_OP_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file atanh_op.hpp -Forward and reverse mode calculations for z = atanh(x). -*/ - - -/*! -Forward mode Taylor coefficient for result of op = AtanhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atanh(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 - x * x -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_atanh_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - size_t k; - if( p == 0 ) - { z[0] = atanh( x[0] ); - b[0] = Base(1.0) - x[0] * x[0]; - p++; - } - for(size_t j = p; j <= q; j++) - { - b[j] = - Base(2.0) * x[0] * x[j]; - z[j] = Base(0.0); - for(k = 1; k < j; k++) - { b[j] -= x[k] * x[j-k]; - z[j] -= Base(double(k)) * z[k] * b[j-k]; - } - z[j] /= Base(double(j)); - z[j] += x[j]; - z[j] /= b[0]; - } -} - -/*! -Multiple direction Taylor coefficient for op = AtanhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atanh(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 - x * x -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_atanh_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* b = z - num_taylor_per_var; // called y in documentation - - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { b[m+ell] = - Base(2.0) * x[m+ell] * x[0]; - z[m+ell] = Base(double(q)) * x[m+ell]; - for(size_t k = 1; k < q; k++) - { b[m+ell] -= x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell]; - } - z[m+ell] /= ( Base(double(q)) * b[0] ); - } -} - -/*! -Zero order forward mode Taylor coefficient for result of op = AtanhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atanh(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 - x * x -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_atanh_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* b = z - cap_order; // called y in documentation - - z[0] = atanh( x[0] ); - b[0] = Base(1.0) - x[0] * x[0]; -} -/*! -Reverse mode partial derivatives for result of op = AtanhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = atanh(x) -\endverbatim -The auxillary result is -\verbatim - y = 1 - x * x -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_atanh_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* b = z - cap_order; // called y in documentation - Base* pb = pz - nc_partial; - - Base inv_b0 = Base(1.0) / b[0]; - - // number of indices to access - size_t j = d; - size_t k; - while(j) - { // scale partials w.r.t z[j] and b[j] - pz[j] = azmul(pz[j], inv_b0); - pb[j] *= Base(2.0); - - pb[0] -= azmul(pz[j], z[j]); - px[j] += pz[j] - azmul(pb[j], x[0]); - px[0] -= azmul(pb[j], x[j]); - - // more scaling of partials w.r.t z[j] - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]); - pz[k] -= Base(double(k)) * azmul(pz[j], b[j-k]); - px[k] -= azmul(pb[j], x[j-k]); - } - --j; - } - px[0] += azmul(pz[0], inv_b0) - Base(2.0) * azmul(pb[0], x[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/atom_state.hpp b/build-config/cppad/include/cppad/local/atom_state.hpp deleted file mode 100644 index ab1c1ba6..00000000 --- a/build-config/cppad/include/cppad/local/atom_state.hpp +++ /dev/null @@ -1,32 +0,0 @@ -# ifndef CPPAD_LOCAL_ATOM_STATE_HPP -# define CPPAD_LOCAL_ATOM_STATE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE - -enum enum_atom_state { - /// next AFunOp marks beginning of a atomic function call - start_atom, - - /// next FunapOp (FunavOp) is a parameter (variable) argument - arg_atom, - - /// next FunrpOp (FunrvOp) is a parameter (variable) result - ret_atom, - - /// next AFunOp marks end of a atomic function call - end_atom -}; - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/atomic_index.hpp b/build-config/cppad/include/cppad/local/atomic_index.hpp deleted file mode 100644 index ce6e88ba..00000000 --- a/build-config/cppad/include/cppad/local/atomic_index.hpp +++ /dev/null @@ -1,161 +0,0 @@ -# ifndef CPPAD_LOCAL_ATOMIC_INDEX_HPP -# define CPPAD_LOCAL_ATOMIC_INDEX_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -$begin atomic_index$$ -$spell - ptr -$$ - -$section Store and Retrieve Atomic Function Information by Index$$ - -$head Syntax$$ -$icode%index_out% = local::atomic_index<%Base%>( - %set_null%, %index_in%, %type%, %name%, %ptr% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_ATOMIC_INDEX%// END_PROTOTYPE%1 -%$$ - -$head Base$$ -Is the base type for the tape for the atomic functions -that we are using an index to identify. - -$head Special Case$$ -In the special case, -$icode set_null$$ is true and $icode index_in$$ is zero. -For this case, $icode index_out$$ is set to -the number of atomic functions stored in $codei%atomic_index<%Base%>%$$ -and no information is stored or changed. -In this case, the atomic functions correspond to $icode index_in$$ from -one to $icode index_out$$ inclusive. - -$head set_null$$ -If this is not the special case: -This value should only be true during a call to an atomic function destructor. -If it is true, the $icode ptr$$ corresponding to $icode index_in$$ -is set to null. - -$head index_in$$ -If this is not the special case: - -$subhead zero$$ -The value $icode index_in$$ should only be zero -during a call to an atomic function constructor. -In this case, a copy of the input value of -$icode type$$, $codei%*%name%$$, and $icode ptr$$ are stored. -The value $icode index_out$$ -is the $icode index_in$$ value corresponding to these input values. - -$subhead non-zero$$ -If $icode index_in$$ is non-zero, -the information corresponding to this index is returned. - -$head type$$ -If this is not the special case: -If $icode index_in$$ is zero, $icode type$$ is an input. -Otherwise it is set to the value corresponding to this index. -The type corresponding to an index -is intended to be $code 2$$ for $cref atomic_two$$ functions -and $code 3$$ for $cref atomic_three$$ functions. - -$head name$$ -If this is not the special case: -If $icode index_in$$ is zero, $code name$$ is an input and must not be null. -Otherwise, if $icode name$$ is not null, $codei%*%name%$$ -is set to the name corresponding to $icode index_in$$. -Allowing for $icode name$$ to be null avoids -a string copy when it is not needed. - -$head ptr$$ -If this is not the special case: -If $icode index_in$$ is zero, $icode ptr$$ is an input. -Otherwise it is set to the value corresponding to $icode index_in$$. -In the special case where $icode set_null$$ is true, -$icode ptr$$ is set to the null pointer and this is the $icode ptr$$ value -corresponding to $icode index_in$$ for future calls to $code atomic_index$$. - -$head index_out$$ -If this is not the special case: -If $icode index_in$$ is zero, -$icode index_out$$ is non-zero and is the index value -corresponding to the input values for -$icode type$$, $codei%*%name%$$, and $icode ptr$$. -Otherwise, $index_out$$ is zero. - -$end -*/ -# include -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE - -struct atomic_index_info { - size_t type; - std::string name; - void* ptr; -}; - -// BEGIN_ATOMIC_INDEX -template -size_t atomic_index( - bool set_null , - const size_t& index_in , - size_t& type , - std::string* name , - void*& ptr ) -// END_PROTOTYPE -{ // - // information for each index - static std::vector vec; -# ifndef NDEBUG - if( index_in == 0 || set_null ) - { CPPAD_ASSERT_KNOWN( ! thread_alloc::in_parallel(), - "calling atomic function constructor or destructor in parallel mode" - ); - } -# endif - if( set_null & (index_in == 0) ) - return vec.size(); - // - // case were we are retreving informaiton for an atomic function - if( 0 < index_in ) - { CPPAD_ASSERT_UNKNOWN( index_in <= vec.size() ) - // - // case where we are setting the pointer to null - if( set_null ) - vec[index_in-1].ptr = nullptr; - // - atomic_index_info& entry = vec[index_in - 1]; - type = entry.type; - ptr = entry.ptr; - if( name != nullptr ) - *name = entry.name; - return 0; - } - // - // case where we are storing information for an atomic function - atomic_index_info entry; - entry.type = type; - entry.name = *name; - entry.ptr = ptr; - vec.push_back(entry); - // - return vec.size(); -} - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/color_general.hpp b/build-config/cppad/include/cppad/local/color_general.hpp deleted file mode 100644 index 5a4e876a..00000000 --- a/build-config/cppad/include/cppad/local/color_general.hpp +++ /dev/null @@ -1,275 +0,0 @@ -# ifndef CPPAD_LOCAL_COLOR_GENERAL_HPP -# define CPPAD_LOCAL_COLOR_GENERAL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file color_general.hpp -Coloring algorithm for a general sparse matrix. -*/ -// -------------------------------------------------------------------------- -/*! -Determine which rows of a general sparse matrix can be computed together; -i.e., do not have non-zero entries with the same column index. - -\tparam SizeVector -is a simple vector class with elements of type size_t. - -\tparam SetVector -is vector_of_sets class. - -\param pattern [in] -Is a representation of the sparsity pattern for the matrix. - -\param row [in] -is a vector specifying which row indices to compute. - -\param col [in] -is a vector, with the same size as row, -that specifies which column indices to compute. -For each valid index k, the index pair -(row[k], col[k]) must be present in the sparsity pattern. -It may be that some entries in the sparsity pattern do not need to be computed; -i.e, do not appear in the set of -(row[k], col[k]) entries. - -\param color [out] -is a vector with size m. -The input value of its elements does not matter. -Upon return, it is a coloring for the rows of the sparse matrix. -\n -\n -If for some i, color[i] == m, then -the i-th row does not appear in the vector row. -Otherwise, color[i] < m. -\n -\n -Suppose two differen rows, i != r have the same color and -column index j is such that both of the pairs -(i, j) and (r, j) appear in the sparsity pattern. -It follows that neither of these pairs appear in the set of -(row[k], col[k]) entries. -\n -\n -This routine tries to minimize, with respect to the choice of colors, -the maximum, with respct to k, of color[ row[k] ] -(not counting the indices k for which row[k] == m). -*/ -template -void color_general_cppad( - const SetVector& pattern , - const SizeVector& row , - const SizeVector& col , - CppAD::vector& color ) -{ - size_t K = row.size(); - size_t m = pattern.n_set(); - size_t n = pattern.end(); - - CPPAD_ASSERT_UNKNOWN( size_t( col.size() ) == K ); - CPPAD_ASSERT_UNKNOWN( size_t( color.size() ) == m ); - - // We define the set of rows, columns, and pairs that appear - // by the set ( row[k], col[k] ) for k = 0, ... , K-1. - - // initialize rows that appear - CppAD::vector row_appear(m); - for(size_t i = 0; i < m; i++) - row_appear[i] = false; - - // rows and columns that appear - SetVector c2r_appear, r2c_appear; - c2r_appear.resize(n, m); - r2c_appear.resize(m, n); - for(size_t k = 0; k < K; k++) - { CPPAD_ASSERT_KNOWN( pattern.is_element(row[k], col[k]) , - "color_general_cppad: requesting value for a matrix element\n" - "that is not in the matrice's sparsity pattern.\n" - "Such a value must be zero." - ); - row_appear[ row[k] ] = true; - c2r_appear.post_element(col[k], row[k]); - r2c_appear.post_element(row[k], col[k]); - } - // process posts - for(size_t j = 0; j < n; ++j) - c2r_appear.process_post(j); - for(size_t i = 0; i < m; ++i) - r2c_appear.process_post(i); - - // for each column, which rows are non-zero and do not appear - SetVector not_appear; - not_appear.resize(n, m); - for(size_t i = 0; i < m; i++) - { typename SetVector::const_iterator pattern_itr(pattern, i); - size_t j = *pattern_itr; - while( j != pattern.end() ) - { if( ! c2r_appear.is_element(j , i) ) - not_appear.post_element(j, i); - j = *(++pattern_itr); - } - } - // process posts - for(size_t j = 0; j < n; ++j) - not_appear.process_post(j); - - // initial coloring - color.resize(m); - size_t ell = 0; - for(size_t i = 0; i < m; i++) - { if( row_appear[i] ) - color[i] = ell++; - else - color[i] = m; - } - /* - See GreedyPartialD2Coloring Algorithm Section 3.6.2 of - Graph Coloring in Optimization Revisited by - Assefaw Gebremedhin, Fredrik Maane, Alex Pothen - - The algorithm above was modified (by Brad Bell) to take advantage of the - fact that only the entries (subset of the sparsity pattern) specified by - row and col need to be computed. - */ - CppAD::vector forbidden(m); - for(size_t i = 1; i < m; i++) // for each row that appears - if( color[i] < m ) - { - // initial all colors as ok for this row - // (value of forbidden for ell > initial color[i] does not matter) - for(ell = 0; ell <= color[i]; ell++) - forbidden[ell] = false; - - // ----------------------------------------------------- - // Forbid colors for which this row would destroy results: - // - // for each column that is non-zero for this row - typename SetVector::const_iterator pattern_itr(pattern, i); - size_t j = *pattern_itr; - while( j != pattern.end() ) - { // for each row that appears with this column - typename SetVector::const_iterator c2r_itr(c2r_appear, j); - size_t r = *c2r_itr; - while( r != c2r_appear.end() ) - { // if this is not the same row, forbid its color - if( (r < i) & (color[r] < m) ) - forbidden[ color[r] ] = true; - r = *(++c2r_itr); - } - j = *(++pattern_itr); - } - - - // ----------------------------------------------------- - // Forbid colors that destroy results needed for this row. - // - // for each column that appears with this row - typename SetVector::const_iterator r2c_itr(r2c_appear, i); - j = *r2c_itr; - while( j != r2c_appear.end() ) - { // For each row that is non-zero for this column - // (the appear rows have already been checked above). - typename SetVector::const_iterator not_itr(not_appear, j); - size_t r = *not_itr; - while( r != not_appear.end() ) - { // if this is not the same row, forbid its color - if( (r < i) & (color[r] < m) ) - forbidden[ color[r] ] = true; - r = *(++not_itr); - } - j = *(++r2c_itr); - } - - // pick the color with smallest index - ell = 0; - while( forbidden[ell] ) - { ell++; - CPPAD_ASSERT_UNKNOWN( ell <= color[i] ); - } - color[i] = ell; - } - return; -} - -# if CPPAD_HAS_COLPACK -/*! -Colpack version of determining which rows of a sparse matrix -can be computed together. - -\copydetails color_general -*/ -template -void color_general_colpack( - const SetVector& pattern , - const SizeVector& row , - const SizeVector& col , - CppAD::vector& color ) -{ - size_t m = pattern.n_set(); - size_t n = pattern.end(); - - // Determine number of non-zero entries in each row - CppAD::vector n_nonzero(m); - size_t n_nonzero_total = 0; - for(size_t i = 0; i < m; i++) - { n_nonzero[i] = 0; - typename SetVector::const_iterator pattern_itr(pattern, i); - size_t j = *pattern_itr; - while( j != pattern.end() ) - { n_nonzero[i]++; - j = *(++pattern_itr); - } - n_nonzero_total += n_nonzero[i]; - } - - // Allocate memory and fill in Adolc sparsity pattern - CppAD::vector adolc_pattern(m); - CppAD::vector adolc_memory(m + n_nonzero_total); - size_t i_memory = 0; - for(size_t i = 0; i < m; i++) - { adolc_pattern[i] = adolc_memory.data() + i_memory; - CPPAD_ASSERT_KNOWN( - std::numeric_limits::max() >= n_nonzero[i], - "Matrix is too large for colpack" - ); - adolc_pattern[i][0] = static_cast( n_nonzero[i] ); - typename SetVector::const_iterator pattern_itr(pattern, i); - size_t j = *pattern_itr; - size_t k = 1; - while(j != pattern.end() ) - { - CPPAD_ASSERT_KNOWN( - std::numeric_limits::max() >= j, - "Matrix is too large for colpack" - ); - adolc_pattern[i][k++] = static_cast( j ); - j = *(++pattern_itr); - } - CPPAD_ASSERT_UNKNOWN( k == 1 + n_nonzero[i] ); - i_memory += k; - } - CPPAD_ASSERT_UNKNOWN( i_memory == m + n_nonzero_total ); - - // Must use an external routine for this part of the calculation because - // ColPack/ColPackHeaders.h has as 'using namespace std' at global level. - cppad_colpack_general(color, m, n, adolc_pattern); - - return; -} -# endif // CPPAD_HAS_COLPACK - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/color_symmetric.hpp b/build-config/cppad/include/cppad/local/color_symmetric.hpp deleted file mode 100644 index cb6119ed..00000000 --- a/build-config/cppad/include/cppad/local/color_symmetric.hpp +++ /dev/null @@ -1,309 +0,0 @@ -# ifndef CPPAD_LOCAL_COLOR_SYMMETRIC_HPP -# define CPPAD_LOCAL_COLOR_SYMMETRIC_HPP -# include -# include - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file color_symmetric.hpp -Coloring algorithm for a symmetric sparse matrix. -*/ -// -------------------------------------------------------------------------- -/*! -CppAD algorithm for determining which rows of a symmetric sparse matrix can be -computed together. - -\tparam SizeVector -is a simple vector class with elements of type size_t. - -\tparam SetVector -is a vector_of_sets class. - -\param pattern [in] -Is a representation of the sparsity pattern for the matrix. - -\param row [in/out] -is a vector specifying which row indices to compute. - -\param col [in/out] -is a vector, with the same size as row, -that specifies which column indices to compute. -\n -\n -Input: -For each valid index k, the index pair -(row[k], col[k]) must be present in the sparsity pattern. -It may be that some entries in the sparsity pattern do not need to be computed; -i.e, do not appear in the set of -(row[k], col[k]) entries. -\n -\n -Output: -On output, some of row and column indices may have been swapped -\code - std::swap( row[k], col[k] ) -\endcode -So the the the color for row[k] can be used to compute entry -(row[k], col[k]). - -\param color [out] -is a vector with size m. -The input value of its elements does not matter. -Upon return, it is a coloring for the rows of the sparse matrix. -Note that if color[i] == m, then there is no index k for which -row[k] == i (for the return value of row). -\n -\n -Fix any (i, j) in the sparsity pattern. -Suppose that there is a row index i1 with -i1 != i, color[i1] == color[i] and (i1, j) is in the sparsity pattern. -If follows that for all j1 with -j1 != j and color[j1] == color[j], -(j1, i ) is not in the sparsity pattern. -\n -\n -This routine tries to minimize, with respect to the choice of colors, -the maximum, with respect to k, of color[ row[k] ]. -*/ -template -void color_symmetric_cppad( - const SetVector& pattern , - CppAD::vector& row , - CppAD::vector& col , - CppAD::vector& color ) -{ - size_t K = row.size(); - size_t m = pattern.n_set(); - CPPAD_ASSERT_UNKNOWN( m == pattern.end() ); - CPPAD_ASSERT_UNKNOWN( color.size() == m ); - CPPAD_ASSERT_UNKNOWN( col.size() == K ); - - // row, column pairs that appear in ( row[k], col[k] ) - CppAD::vector< std::set > pair_needed(m); - std::set::iterator itr1, itr2; - for(size_t k1 = 0; k1 < K; k1++) - { CPPAD_ASSERT_UNKNOWN( pattern.is_element(row[k1], col[k1]) ); - pair_needed[ row[k1] ].insert( col[k1] ); - pair_needed[ col[k1] ].insert( row[k1] ); - } - - // order the rows decending by number of pairs needed - CppAD::vector key(m), order2row(m); - for(size_t i1 = 0; i1 < m; i1++) - { CPPAD_ASSERT_UNKNOWN( pair_needed[i1].size() <= m ); - key[i1] = m - pair_needed[i1].size(); - } - CppAD::index_sort(key, order2row); - - // mapping from order index to row index - CppAD::vector row2order(m); - for(size_t o1 = 0; o1 < m; o1++) - row2order[ order2row[o1] ] = o1; - - // initial coloring - color.resize(m); - size_t c1 = 0; - for(size_t o1 = 0; o1 < m; o1++) - { size_t i1 = order2row[o1]; - if( pair_needed[i1].empty() ) - color[i1] = m; - else - color[i1] = c1++; - } - - // which colors are forbidden for this row - CppAD::vector forbidden(m); - - // must start with row zero so that we remove results computed for it - for(size_t o1 = 0; o1 < m; o1++) // for each row that appears (in order) - if( color[ order2row[o1] ] < m ) - { size_t i1 = order2row[o1]; - c1 = color[i1]; - - // initial all colors as ok for this row - // (value of forbidden for c > c1 does not matter) - for(size_t c2 = 0; c2 <= c1; c2++) - forbidden[c2] = false; - - // ----------------------------------------------------- - // Forbid grouping with rows that would destroy results that are - // needed for this row. - itr1 = pair_needed[i1].begin(); - while( itr1 != pair_needed[i1].end() ) - { // entry (i1, j1) is needed for this row - size_t j1 = *itr1; - - // Forbid rows i2 != i1 that have non-zero sparsity at (i2, j1). - // Note that this is the same as non-zero sparsity at (j1, i2) - typename SetVector::const_iterator pattern_itr(pattern, j1); - size_t i2 = *pattern_itr; - while( i2 != pattern.end() ) - { size_t c2 = color[i2]; - if( c2 < c1 ) - forbidden[c2] = true; - i2 = *(++pattern_itr); - } - itr1++; - } - // ----------------------------------------------------- - // Forbid grouping with rows that this row would destroy results for - for(size_t o2 = 0; o2 < o1; o2++) - { size_t i2 = order2row[o2]; - size_t c2 = color[i2]; - itr2 = pair_needed[i2].begin(); - while( itr2 != pair_needed[i2].end() ) - { size_t j2 = *itr2; - // row i2 needs pair (i2, j2). - // Forbid grouping with i1 if (i1, j2) has non-zero sparsity - if( pattern.is_element(i1, j2) ) - forbidden[c2] = true; - itr2++; - } - } - - // pick the color with smallest index - size_t c2 = 0; - while( forbidden[c2] ) - { c2++; - CPPAD_ASSERT_UNKNOWN( c2 <= c1 ); - } - color[i1] = c2; - - // no longer need results that are computed by this row - itr1 = pair_needed[i1].begin(); - while( itr1 != pair_needed[i1].end() ) - { size_t j1 = *itr1; - if( row2order[j1] > o1 ) - { itr2 = pair_needed[j1].find(i1); - if( itr2 != pair_needed[j1].end() ) - { pair_needed[j1].erase(itr2); - if( pair_needed[j1].empty() ) - color[j1] = m; - } - } - itr1++; - } - } - - // determine which sparsity entries need to be reflected - for(size_t k1 = 0; k1 < row.size(); k1++) - { size_t i1 = row[k1]; - size_t j1 = col[k1]; - itr1 = pair_needed[i1].find(j1); - if( itr1 == pair_needed[i1].end() ) - { row[k1] = j1; - col[k1] = i1; -# ifndef NDEBUG - itr1 = pair_needed[j1].find(i1); - CPPAD_ASSERT_UNKNOWN( itr1 != pair_needed[j1].end() ); -# endif - } - } - return; -} - -// -------------------------------------------------------------------------- -/*! -Colpack algorithm for determining which rows of a symmetric sparse matrix -can be computed together. - -\copydetails CppAD::local::color_symmetric_cppad -*/ -template -void color_symmetric_colpack( - const SetVector& pattern , - CppAD::vector& row , - CppAD::vector& col , - CppAD::vector& color ) -{ -# if ! CPPAD_HAS_COLPACK - CPPAD_ASSERT_UNKNOWN(false); - return; -# else - size_t i, j, k; - size_t m = pattern.n_set(); - CPPAD_ASSERT_UNKNOWN( m == pattern.end() ); - CPPAD_ASSERT_UNKNOWN( row.size() == col.size() ); - - // Determine number of non-zero entries in each row - CppAD::vector n_nonzero(m); - size_t n_nonzero_total = 0; - for(i = 0; i < m; i++) - { n_nonzero[i] = 0; - typename SetVector::const_iterator pattern_itr(pattern, i); - j = *pattern_itr; - while( j != pattern.end() ) - { n_nonzero[i]++; - j = *(++pattern_itr); - } - n_nonzero_total += n_nonzero[i]; - } - - // Allocate memory and fill in Adolc sparsity pattern - CppAD::vector adolc_pattern(m); - CppAD::vector adolc_memory(m + n_nonzero_total); - size_t i_memory = 0; - for(i = 0; i < m; i++) - { adolc_pattern[i] = adolc_memory.data() + i_memory; - CPPAD_ASSERT_KNOWN( - std::numeric_limits::max() >= n_nonzero[i], - "Matrix is too large for colpack" - ); - adolc_pattern[i][0] = static_cast( n_nonzero[i] ); - typename SetVector::const_iterator pattern_itr(pattern, i); - j = *pattern_itr; - k = 1; - while(j != pattern.end() ) - { - CPPAD_ASSERT_KNOWN( - std::numeric_limits::max() >= j, - "Matrix is too large for colpack" - ); - adolc_pattern[i][k++] = static_cast( j ); - j = *(++pattern_itr); - } - CPPAD_ASSERT_UNKNOWN( k == 1 + n_nonzero[i] ); - i_memory += k; - } - CPPAD_ASSERT_UNKNOWN( i_memory == m + n_nonzero_total ); - - // Must use an external routine for this part of the calculation because - // ColPack/ColPackHeaders.h has as 'using namespace std' at global level. - cppad_colpack_symmetric(color, m, adolc_pattern); - - // determine which sparsity entries need to be reflected - for(size_t k1 = 0; k1 < row.size(); k1++) - { size_t i1 = row[k1]; - size_t j1 = col[k1]; - bool reflect = false; - for(size_t i2 = 0; i2 < m; i2++) - if( (i1 != i2) & (color[i1]==color[i2]) ) - { for(size_t k2 = 1; k2 <= adolc_pattern[i2][0]; k2++) - { size_t j2 = adolc_pattern[i2][k2]; - reflect |= (j1 == j2); - } - } - if( reflect ) - { row[k1] = j1; - col[k1] = i1; - } - } - return; -# endif // CPPAD_HAS_COLPACK -} - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/comp_op.hpp b/build-config/cppad/include/cppad/local/comp_op.hpp deleted file mode 100644 index e9098da1..00000000 --- a/build-config/cppad/include/cppad/local/comp_op.hpp +++ /dev/null @@ -1,420 +0,0 @@ -# ifndef CPPAD_LOCAL_COMP_OP_HPP -# define CPPAD_LOCAL_COMP_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file comp_op.hpp -Zero order forward mode check how many comparisons changed. -*/ - -// -------------------------------- <= ----------------------------------- -/*! -Zero order forward mode comparison check that left <= right - -\param count -It the condition is not true, ths counter is incremented by one. - -\param arg -parameter[ arg[0] ] is the left operand and -parameter[ arg[1] ] is the right operand. - -\param parameter -vector of parameter values. -*/ -template -void forward_lepp_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LeppOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LeppOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base y = parameter[ arg[1] ]; - - count += size_t( GreaterThanZero(x - y) ); -} -/*! -Zero order forward mode comparison check that left <= right - -\param count -It the condition is not true, ths counter is incremented by one. - -\param arg -parameter[ arg[0] ] is the left operand and -taylor[ size_t(arg[1]) * cap_order + 0 ] is the zero order Taylor coefficient -for the right operand. - -\param parameter -vector of parameter values. - -\param cap_order -number of Taylor coefficients allocated for each variable - -\param taylor -vector of taylor coefficients. -*/ -template -void forward_lepv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LepvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LepvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += GreaterThanZero(x - y[0]); -} -/*! -Zero order forward mode comparison check that left <= right - -\param count -It the condition is not true, ths counter is incremented by one. - -\param arg -taylor[ size_t(arg[0]) * cap_order + 0 ] is the zero order Taylor coefficient -for the left operand and parameter[ arg[1] ] is the right operand - -\param parameter -vector of parameter values. - -\param cap_order -number of Taylor coefficients allocated for each variable - -\param taylor -vector of taylor coefficients. -*/ -template -void forward_levp_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LevpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LevpOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base y = parameter[ arg[1] ]; - - count += GreaterThanZero(x[0] - y); -} -/*! -Zero order forward mode comparison check that left <= right - -\param count -It the condition is not true, ths counter is incremented by one. - -\param arg -taylor[ size_t(arg[0]) * cap_order + 0 ] is the zero order Taylor coefficient -for the left operand and -taylor[ size_t(arg[1]) * cap_order + 0 ] is the zero order Taylor coefficient -for the right operand. - -\param parameter -vector of parameter values. - -\param cap_order -number of Taylor coefficients allocated for each variable - -\param taylor -vector of taylor coefficients. -*/ -template -void forward_levv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LevvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LevvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += GreaterThanZero(x[0] - y[0]); -} -// ------------------------------- < ------------------------------------- -/*! -Zero order forward mode comparison check that left < right - -\param count -It the condition is not true, ths counter is incremented by one. - -\param arg -parameter[ arg[0] ] is the left operand and -parameter[ arg[1] ] is the right operand. - -\param parameter -vector of parameter values. -*/ -template -void forward_ltpp_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LtppOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LtppOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base y = parameter[ arg[1] ]; - - count += GreaterThanOrZero(x - y); -} -/*! -Zero order forward mode comparison check that left < right - -\copydetails CppAD::local::forward_lepv_op_0 -*/ -template -void forward_ltpv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LtpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LtpvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += GreaterThanOrZero(x - y[0]); -} -/*! -Zero order forward mode comparison check that left < right - -\copydetails CppAD::local::forward_levp_op_0 -*/ -template -void forward_ltvp_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LtvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LtvpOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base y = parameter[ arg[1] ]; - - count += GreaterThanOrZero(x[0] - y); -} -/*! -Zero order forward mode comparison check that left < right - -\copydetails CppAD::local::forward_levv_op_0 -*/ -template -void forward_ltvv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LtvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LtvvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += GreaterThanOrZero(x[0] - y[0]); -} -// ------------------------------ == ------------------------------------- -/*! -Zero order forward mode comparison check that left == right - -\param count -It the condition is not true, ths counter is incremented by one. - -\param arg -parameter[ arg[0] ] is the left operand and -parameter[ arg[1] ] is the right operand. - -\param parameter -vector of parameter values. -*/ -template -void forward_eqpp_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(EqppOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(EqppOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base y = parameter[ arg[1] ]; - - count += size_t(x != y); -} -/*! -Zero order forward mode comparison check that left == right - -\copydetails CppAD::local::forward_lepv_op_0 -*/ -template -void forward_eqpv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(EqpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(EqpvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += size_t(x != y[0]); -} -/*! -Zero order forward mode comparison check that left == right - -\copydetails CppAD::local::forward_levv_op_0 -*/ -template -void forward_eqvv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(EqvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(EqvvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += size_t(x[0] != y[0]); -} -// -------------------------------- != ----------------------------------- -/*! -Zero order forward mode comparison check that left != right - -\param count -It the condition is not true, ths counter is incremented by one. - -\param arg -parameter[ arg[0] ] is the left operand and -parameter[ arg[1] ] is the right operand. - -\param parameter -vector of parameter values. -*/ -template -void forward_nepp_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(NeppOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(NeppOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base y = parameter[ arg[1] ]; - - count += size_t(x == y); -} -/*! -Zero order forward mode comparison check that left != right - -\copydetails CppAD::local::forward_lepv_op_0 -*/ -template -void forward_nepv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(NepvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(NepvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base x = parameter[ arg[0] ]; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += size_t(x == y[0]); -} -/*! -Zero order forward mode comparison check that left != right - -\copydetails CppAD::local::forward_levv_op_0 -*/ -template -void forward_nevv_op_0( - size_t& count , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(NevvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(NevvOp) == 0 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - - count += size_t(x[0] == y[0]); -} - - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/cond_op.hpp b/build-config/cppad/include/cppad/local/cond_op.hpp deleted file mode 100644 index 7cc1dd27..00000000 --- a/build-config/cppad/include/cppad/local/cond_op.hpp +++ /dev/null @@ -1,1317 +0,0 @@ -# ifndef CPPAD_LOCAL_COND_OP_HPP -# define CPPAD_LOCAL_COND_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file cond_op.hpp -Forward, reverse, and sparse operations for conditional expressions. -*/ - -/*! -Shared documentation for conditional expressions (not called). - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\param parameter -For j = 0, 1, 2, 3, -if y_j is a parameter, parameter [ arg[2 + j] ] is its value. - -\param cap_order -number of columns in the matrix containing the Taylor coefficients. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - -*/ -template -void conditional_exp_op( - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order ) -{ // This routine is only for documentation, it should never be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Shared documentation for conditional expression sparse operations (not called). - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - -*/ -template -void sparse_conditional_exp_op( - size_t i_z , - const addr_t* arg , - size_t num_par ) -{ // This routine is only for documentation, it should never be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Compute forward mode Taylor coefficients for op = CExpOp. - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\param parameter -For j = 0, 1, 2, 3, -if y_j is a parameter, parameter [ arg[2 + j] ] is its value. - -\param cap_order -number of columns in the matrix containing the Taylor coefficients. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - - -\param p -is the lowest order of the Taylor coefficient of z that we are computing. - -\param q -is the highest order of the Taylor coefficient of z that we are computing. - -\param taylor -\b Input: -For j = 0, 1, 2, 3 and k = 0 , ... , q, -if y_j is a variable then -taylor [ arg[2+j] * cap_order + k ] -is the k-th order Taylor coefficient corresponding to y_j. -\n -\b Input: taylor [ i_z * cap_order + k ] -for k = 0 , ... , p-1, -is the k-th order Taylor coefficient corresponding to z. -\n -\b Output: taylor [ i_z * cap_order + k ] -for k = p , ... , q, -is the k-th order Taylor coefficient corresponding to z. - -*/ -template -void forward_cond_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ Base y_0, y_1, y_2, y_3; - Base zero(0); - Base* z = taylor + i_z * cap_order; - - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast (CompareNe) ); - CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); - - if( arg[1] & 1 ) - { - y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); - y_0 = parameter[ arg[2] ]; - } - if( arg[1] & 2 ) - { - y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); - y_1 = parameter[ arg[3] ]; - } - if( p == 0 ) - { if( arg[1] & 4 ) - { - y_2 = taylor[ size_t(arg[4]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); - y_2 = parameter[ arg[4] ]; - } - if( arg[1] & 8 ) - { - y_3 = taylor[ size_t(arg[5]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); - y_3 = parameter[ arg[5] ]; - } - z[0] = CondExpOp( - CompareOp( arg[0] ), - y_0, - y_1, - y_2, - y_3 - ); - p++; - } - for(size_t d = p; d <= q; d++) - { if( arg[1] & 4 ) - { - y_2 = taylor[ size_t(arg[4]) * cap_order + d]; - } - else - y_2 = zero; - if( arg[1] & 8 ) - { - y_3 = taylor[ size_t(arg[5]) * cap_order + d]; - } - else - y_3 = zero; - z[d] = CondExpOp( - CompareOp( arg[0] ), - y_0, - y_1, - y_2, - y_3 - ); - } - return; -} - -/*! -Multiple directions forward mode Taylor coefficients for op = CExpOp. - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\param parameter -For j = 0, 1, 2, 3, -if y_j is a parameter, parameter [ arg[2 + j] ] is its value. - -\param cap_order -number of columns in the matrix containing the Taylor coefficients. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - - -\param q -is order of the Taylor coefficient of z that we are computing. - -\param r -is the number of Taylor coefficient directions that we are computing. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param taylor -\b Input: -For j = 0, 1, 2, 3, k = 1, ..., q, -if y_j is a variable then -taylor [ arg[2+j] * tpv + 0 ] -is the zero order Taylor coefficient corresponding to y_j and -taylor [ arg[2+j] * tpv + (k-1)*r+1+ell is its -k-th order Taylor coefficient in the ell-th direction. -\n -\b Input: -For j = 0, 1, 2, 3, k = 1, ..., q-1, -taylor [ i_z * tpv + 0 ] -is the zero order Taylor coefficient corresponding to z and -taylor [ i_z * tpv + (k-1)*r+1+ell is its -k-th order Taylor coefficient in the ell-th direction. -\n -\b Output: taylor [ i_z * tpv + (q-1)*r+1+ell ] -is the q-th order Taylor coefficient corresponding to z -in the ell-th direction. -*/ -template -void forward_cond_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ Base y_0, y_1, y_2, y_3; - Base zero(0); - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* z = taylor + i_z * num_taylor_per_var; - - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast (CompareNe) ); - CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - if( arg[1] & 1 ) - { - y_0 = taylor[ size_t(arg[2]) * num_taylor_per_var + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); - y_0 = parameter[ arg[2] ]; - } - if( arg[1] & 2 ) - { - y_1 = taylor[ size_t(arg[3]) * num_taylor_per_var + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); - y_1 = parameter[ arg[3] ]; - } - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { if( arg[1] & 4 ) - { - y_2 = taylor[ size_t(arg[4]) * num_taylor_per_var + m + ell]; - } - else - y_2 = zero; - if( arg[1] & 8 ) - { - y_3 = taylor[ size_t(arg[5]) * num_taylor_per_var + m + ell]; - } - else - y_3 = zero; - z[m+ell] = CondExpOp( - CompareOp( arg[0] ), - y_0, - y_1, - y_2, - y_3 - ); - } - return; -} - -/*! -Compute zero order forward mode Taylor coefficients for op = CExpOp. - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\param parameter -For j = 0, 1, 2, 3, -if y_j is a parameter, parameter [ arg[2 + j] ] is its value. - -\param cap_order -number of columns in the matrix containing the Taylor coefficients. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - - -\param taylor -\b Input: -For j = 0, 1, 2, 3, -if y_j is a variable then - taylor [ arg[2+j] * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to y_j. -\n -\b Output: taylor [ i_z * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to z. -*/ -template -void forward_cond_op_0( - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ Base y_0, y_1, y_2, y_3; - Base* z; - - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast (CompareNe) ); - CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); - - if( arg[1] & 1 ) - { - y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); - y_0 = parameter[ arg[2] ]; - } - if( arg[1] & 2 ) - { - y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); - y_1 = parameter[ arg[3] ]; - } - if( arg[1] & 4 ) - { - y_2 = taylor[ size_t(arg[4]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par ); - y_2 = parameter[ arg[4] ]; - } - if( arg[1] & 8 ) - { - y_3 = taylor[ size_t(arg[5]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par ); - y_3 = parameter[ arg[5] ]; - } - z = taylor + i_z * cap_order; - z[0] = CondExpOp( - CompareOp( arg[0] ), - y_0, - y_1, - y_2, - y_3 - ); - return; -} - -/*! -Compute reverse mode Taylor coefficients for op = CExpOp. - -This routine is given the partial derivatives of a function -G( z , y , x , w , ... ) -and it uses them to compute the partial derivatives of -\verbatim - H( y , x , w , u , ... ) = G[ z(y) , y , x , w , u , ... ] -\endverbatim -where y above represents y_0, y_1, y_2, y_3. - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\param parameter -For j = 0, 1, 2, 3, -if y_j is a parameter, parameter [ arg[2 + j] ] is its value. - -\param cap_order -number of columns in the matrix containing the Taylor coefficients. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - - -\param d -is the order of the Taylor coefficient of z that we are computing. - -\param taylor -\b Input: -For j = 0, 1, 2, 3 and k = 0 , ... , d, -if y_j is a variable then - taylor [ arg[2+j] * cap_order + k ] -is the k-th order Taylor coefficient corresponding to y_j. -\n - taylor [ i_z * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to z. - -\param nc_partial -number of columns in the matrix containing the Taylor coefficients. - -\param partial -\b Input: -For j = 0, 1, 2, 3 and k = 0 , ... , d, -if y_j is a variable then - partial [ arg[2+j] * nc_partial + k ] -is the partial derivative of G( z , y , x , w , u , ... ) -with respect to the k-th order Taylor coefficient corresponding to y_j. -\n -\b Input: partial [ i_z * cap_order + k ] -for k = 0 , ... , d -is the partial derivative of G( z , y , x , w , u , ... ) -with respect to the k-th order Taylor coefficient corresponding to z. -\n -\b Output: -For j = 0, 1, 2, 3 and k = 0 , ... , d, -if y_j is a variable then - partial [ arg[2+j] * nc_partial + k ] -is the partial derivative of H( y , x , w , u , ... ) -with respect to the k-th order Taylor coefficient corresponding to y_j. - -*/ -template -void reverse_cond_op( - size_t d , - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ Base y_0, y_1; - Base zero(0); - Base* pz; - Base* py_2; - Base* py_3; - - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast (CompareNe) ); - CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); - - pz = partial + i_z * nc_partial + 0; - if( arg[1] & 1 ) - { - y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); - y_0 = parameter[ arg[2] ]; - } - if( arg[1] & 2 ) - { - y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); - y_1 = parameter[ arg[3] ]; - } - if( arg[1] & 4 ) - { - py_2 = partial + size_t(arg[4]) * nc_partial; - size_t j = d + 1; - while(j--) - { py_2[j] += CondExpOp( - CompareOp( arg[0] ), - y_0, - y_1, - pz[j], - zero - ); - } - } - if( arg[1] & 8 ) - { - py_3 = partial + size_t(arg[5]) * nc_partial; - size_t j = d + 1; - while(j--) - { py_3[j] += CondExpOp( - CompareOp( arg[0] ), - y_0, - y_1, - zero, - pz[j] - ); - } - } - return; -} - -/*! -Compute forward Jacobian sparsity patterns for op = CExpOp. - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - - -\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 sparsity -\b Input: -if y_2 is a variable, the set with index t is -the sparsity pattern corresponding to y_2. -This identifies which of the independent variables the variable y_2 -depends on. -\n -\b Input: -if y_3 is a variable, the set with index t is -the sparsity pattern corresponding to y_3. -This identifies which of the independent variables the variable y_3 -depends on. -\n -\b Output: -The set with index T is -the sparsity pattern corresponding to z. -This identifies which of the independent variables the variable z -depends on. -*/ -template -void forward_sparse_jacobian_cond_op( - bool dependency , - size_t i_z , - const addr_t* arg , - size_t num_par , - Vector_set& sparsity ) -{ - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast (CompareNe) ); - CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); -# ifndef NDEBUG - addr_t k = 1; - for( size_t j = 0; j < 4; j++) - { if( ! ( arg[1] & k ) ) - CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par ); - k *= 2; - } -# endif - sparsity.clear(i_z); - if( dependency ) - { if( arg[1] & 1 ) - sparsity.binary_union(i_z, i_z, size_t(arg[2]), sparsity); - if( arg[1] & 2 ) - sparsity.binary_union(i_z, i_z, size_t(arg[3]), sparsity); - } - if( arg[1] & 4 ) - sparsity.binary_union(i_z, i_z, size_t(arg[4]), sparsity); - if( arg[1] & 8 ) - sparsity.binary_union(i_z, i_z, size_t(arg[5]), sparsity); - return; -} - -/*! -Compute reverse Jacobian sparsity patterns for op = CExpOp. - -This routine is given the sparsity patterns -for a function G(z, y, x, ... ) -and it uses them to compute the sparsity patterns for -\verbatim - H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ] -\endverbatim -where y represents the combination of y_0, y_1, y_2, and y_3. - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - - -\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 sparsity -if y_2 is a variable, the set with index t is -the sparsity pattern corresponding to y_2. -This identifies which of the dependent variables depend on the variable y_2. -On input, this pattern corresponds to the function G. -On ouput, it corresponds to the function H. -\n -\n -if y_3 is a variable, the set with index t is -the sparsity pattern corresponding to y_3. -This identifies which of the dependent variables depeond on the variable y_3. -On input, this pattern corresponds to the function G. -On ouput, it corresponds to the function H. -\n -\b Output: -The set with index T is -the sparsity pattern corresponding to z. -This identifies which of the dependent variables depend on the variable z. -On input and output, this pattern corresponds to the function G. -*/ -template -void reverse_sparse_jacobian_cond_op( - bool dependency , - size_t i_z , - const addr_t* arg , - size_t num_par , - Vector_set& sparsity ) -{ - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast (CompareNe) ); - CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); -# ifndef NDEBUG - addr_t k = 1; - for( size_t j = 0; j < 4; j++) - { if( ! ( arg[1] & k ) ) - CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par ); - k *= 2; - } -# endif - if( dependency ) - { if( arg[1] & 1 ) - sparsity.binary_union( size_t(arg[2]), size_t(arg[2]), i_z, sparsity); - if( arg[1] & 2 ) - sparsity.binary_union( size_t(arg[3]), size_t(arg[3]), i_z, sparsity); - } - // -------------------------------------------------------------------- - if( arg[1] & 4 ) - sparsity.binary_union( size_t(arg[4]), size_t(arg[4]), i_z, sparsity); - if( arg[1] & 8 ) - sparsity.binary_union( size_t(arg[5]), size_t(arg[5]), i_z, sparsity); - return; -} - -/*! -Compute reverse Hessian sparsity patterns for op = CExpOp. - -This routine is given the sparsity patterns -for a function G(z, y, x, ... ) -and it uses them to compute the sparsity patterns for -\verbatim - H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ] -\endverbatim -where y represents the combination of y_0, y_1, y_2, and y_3. - - -The C++ source code coresponding to this operation is -\verbatim - z = CondExpRel(y_0, y_1, y_2, y_3) -\endverbatim -where Rel is one of the following: Lt, Le, Eq, Ge, Gt. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, y_0 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 2 -\n -If this is zero, y_1 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 4 -\n -If this is zero, y_2 is a parameter. Otherwise it is a variable. -\n -\n - arg[1] & 8 -\n -If this is zero, y_3 is a parameter. Otherwise it is a variable. -\n -\n - arg[2 + j ] for j = 0, 1, 2, 3 -\n -is the index corresponding to y_j. - -\param num_par -is the total number of values in the vector parameter. - -\par Checked Assertions -\li NumArg(CExpOp) == 6 -\li NumRes(CExpOp) == 1 -\li arg[0] < static_cast ( CompareNe ) -\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters. -\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par. - - - -\param jac_reverse - jac_reverse[i_z] -is false (true) if the Jacobian of G with respect to z is always zero -(may be non-zero). -\n -\n - jac_reverse[ arg[4] ] -If y_2 is a variable, - jac_reverse[ arg[4] ] -is false (true) if the Jacobian with respect to y_2 is always zero -(may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. -\n -\n - jac_reverse[ arg[5] ] -If y_3 is a variable, - jac_reverse[ arg[5] ] -is false (true) if the Jacobian with respect to y_3 is always zero -(may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. - -\param hes_sparsity -The set with index i_z in hes_sparsity -is the Hessian sparsity pattern for the function G -where one of the partials is with respect to z. -\n -\n -If y_2 is a variable, -the set with index arg[4] in hes_sparsity -is the Hessian sparsity pattern -where one of the partials is with respect to y_2. -On input, this pattern corresponds to the function G. -On output, this pattern corresponds to the function H. -\n -\n -If y_3 is a variable, -the set with index arg[5] in hes_sparsity -is the Hessian sparsity pattern -where one of the partials is with respect to y_3. -On input, this pattern corresponds to the function G. -On output, this pattern corresponds to the function H. -*/ -template -void reverse_sparse_hessian_cond_op( - size_t i_z , - const addr_t* arg , - size_t num_par , - bool* jac_reverse , - Vector_set& hes_sparsity ) -{ - - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast (CompareNe) ); - CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); -# ifndef NDEBUG - addr_t k = 1; - for( size_t j = 0; j < 4; j++) - { if( ! ( arg[1] & k ) ) - CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par ); - k *= 2; - } -# endif - if( arg[1] & 4 ) - { - hes_sparsity.binary_union( size_t(arg[4]), size_t(arg[4]), i_z, hes_sparsity); - jac_reverse[ arg[4] ] |= jac_reverse[i_z]; - } - if( arg[1] & 8 ) - { - hes_sparsity.binary_union( size_t(arg[5]), size_t(arg[5]), i_z, hes_sparsity); - jac_reverse[ arg[5] ] |= jac_reverse[i_z]; - } - return; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/cos_op.hpp b/build-config/cppad/include/cppad/local/cos_op.hpp deleted file mode 100644 index f7d44e1b..00000000 --- a/build-config/cppad/include/cppad/local/cos_op.hpp +++ /dev/null @@ -1,238 +0,0 @@ -# ifndef CPPAD_LOCAL_COS_OP_HPP -# define CPPAD_LOCAL_COS_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file cos_op.hpp -Forward and reverse mode calculations for z = cos(x). -*/ - -/*! -Compute forward mode Taylor coefficient for result of op = CosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cos(x) -\endverbatim -The auxillary result is -\verbatim - y = sin(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_cos_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* c = taylor + i_z * cap_order; - Base* s = c - cap_order; - - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op. - // (except that there is a sign difference for the hyperbolic case). - size_t k; - if( p == 0 ) - { s[0] = sin( x[0] ); - c[0] = cos( x[0] ); - p++; - } - for(size_t j = p; j <= q; j++) - { - s[j] = Base(0.0); - c[j] = Base(0.0); - for(k = 1; k <= j; k++) - { s[j] += Base(double(k)) * x[k] * c[j-k]; - c[j] -= Base(double(k)) * x[k] * s[j-k]; - } - s[j] /= Base(double(j)); - c[j] /= Base(double(j)); - } -} -/*! -Compute forward mode Taylor coefficient for result of op = CosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cos(x) -\endverbatim -The auxillary result is -\verbatim - y = sin(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_cos_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* c = taylor + i_z * num_taylor_per_var; - Base* s = c - num_taylor_per_var; - - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op - // (except that there is a sign difference for the hyperbolic case). - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { s[m+ell] = Base(double(q)) * x[m + ell] * c[0]; - c[m+ell] = - Base(double(q)) * x[m + ell] * s[0]; - for(size_t k = 1; k < q; k++) - { s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell]; - c[m+ell] -= Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell]; - } - s[m+ell] /= Base(double(q)); - c[m+ell] /= Base(double(q)); - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = CosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cos(x) -\endverbatim -The auxillary result is -\verbatim - y = sin(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_cos_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* c = taylor + i_z * cap_order; // called z in documentation - Base* s = c - cap_order; // called y in documentation - - c[0] = cos( x[0] ); - s[0] = sin( x[0] ); -} -/*! -Compute reverse mode partial derivatives for result of op = CosOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cos(x) -\endverbatim -The auxillary result is -\verbatim - y = sin(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_cos_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* c = taylor + i_z * cap_order; // called z in doc - Base* pc = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* s = c - cap_order; // called y in documentation - Base* ps = pc - nc_partial; - - - // rest of this routine is identical for the following cases: - // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op. - size_t j = d; - size_t k; - while(j) - { - ps[j] /= Base(double(j)); - pc[j] /= Base(double(j)); - for(k = 1; k <= j; k++) - { - px[k] += Base(double(k)) * azmul(ps[j], c[j-k]); - px[k] -= Base(double(k)) * azmul(pc[j], s[j-k]); - - ps[j-k] -= Base(double(k)) * azmul(pc[j], x[k]); - pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]); - - } - --j; - } - px[0] += azmul(ps[0], c[0]); - px[0] -= azmul(pc[0], s[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/cosh_op.hpp b/build-config/cppad/include/cppad/local/cosh_op.hpp deleted file mode 100644 index 875200c0..00000000 --- a/build-config/cppad/include/cppad/local/cosh_op.hpp +++ /dev/null @@ -1,238 +0,0 @@ -# ifndef CPPAD_LOCAL_COSH_OP_HPP -# define CPPAD_LOCAL_COSH_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file cosh_op.hpp -Forward and reverse mode calculations for z = cosh(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = CoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sinh(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_cosh_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* c = taylor + i_z * cap_order; - Base* s = c - cap_order; - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op. - // (except that there is a sign difference for hyperbolic case). - size_t k; - if( p == 0 ) - { s[0] = sinh( x[0] ); - c[0] = cosh( x[0] ); - p++; - } - for(size_t j = p; j <= q; j++) - { - s[j] = Base(0.0); - c[j] = Base(0.0); - for(k = 1; k <= j; k++) - { s[j] += Base(double(k)) * x[k] * c[j-k]; - c[j] += Base(double(k)) * x[k] * s[j-k]; - } - s[j] /= Base(double(j)); - c[j] /= Base(double(j)); - } -} -/*! -Compute forward mode Taylor coefficient for result of op = CoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sinh(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_cosh_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* s = taylor + i_z * num_taylor_per_var; - Base* c = s - num_taylor_per_var; - - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op - // (except that there is a sign difference for the hyperbolic case). - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { s[m+ell] = Base(double(q)) * x[m + ell] * c[0]; - c[m+ell] = Base(double(q)) * x[m + ell] * s[0]; - for(size_t k = 1; k < q; k++) - { s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell]; - c[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell]; - } - s[m+ell] /= Base(double(q)); - c[m+ell] /= Base(double(q)); - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = CoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sinh(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_cosh_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* c = taylor + i_z * cap_order; // called z in documentation - Base* s = c - cap_order; // called y in documentation - - c[0] = cosh( x[0] ); - s[0] = sinh( x[0] ); -} -/*! -Compute reverse mode partial derivatives for result of op = CoshOp. - -The C++ source code corresponding to this operation is -\verbatim - z = cosh(x) -\endverbatim -The auxillary result is -\verbatim - y = sinh(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_cosh_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* c = taylor + i_z * cap_order; // called z in doc - Base* pc = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* s = c - cap_order; // called y in documentation - Base* ps = pc - nc_partial; - - - // rest of this routine is identical for the following cases: - // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op. - size_t j = d; - size_t k; - while(j) - { - ps[j] /= Base(double(j)); - pc[j] /= Base(double(j)); - for(k = 1; k <= j; k++) - { - px[k] += Base(double(k)) * azmul(ps[j], c[j-k]); - px[k] += Base(double(k)) * azmul(pc[j], s[j-k]); - - ps[j-k] += Base(double(k)) * azmul(pc[j], x[k]); - pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]); - - } - --j; - } - px[0] += azmul(ps[0], c[0]); - px[0] += azmul(pc[0], s[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/cppad_colpack.hpp b/build-config/cppad/include/cppad/local/cppad_colpack.hpp deleted file mode 100644 index ee96ab5f..00000000 --- a/build-config/cppad/include/cppad/local/cppad_colpack.hpp +++ /dev/null @@ -1,104 +0,0 @@ -# ifndef CPPAD_LOCAL_CPPAD_COLPACK_HPP -# define CPPAD_LOCAL_CPPAD_COLPACK_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# if CPPAD_HAS_COLPACK - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file cppad_colpack.hpp -External interface to Colpack routines used by cppad. -*/ -// --------------------------------------------------------------------------- -/*! -Link from CppAD to ColPack used for general sparse matrices. - -This CppAD library routine is necessary because -ColPack/ColPackHeaders.h has a -using namespace std at the global level. - -\param m [in] -is the number of rows in the sparse matrix - -\param n [in] -is the nubmer of columns in the sparse matrix. - -\param adolc_pattern [in] -This vector has size m, -adolc_pattern[i][0] is the number of non-zeros in row i. -For j = 1 , ... , adolc_sparsity[i], -adolc_pattern[i][j] is the column index (base zero) for the -non-zeros in row i. - -\param color [out] -is a vector with size m. -The input value of its elements does not matter. -Upon return, it is a coloring for the rows of the sparse matrix. -\n -\n -If for some i, color[i] == m, then -adolc_pattern[i][0] == 0. -Otherwise, color[i] < m. -\n -\n -Suppose two differen rows, i != r have the same color. -It follows that for all column indices j; -it is not the case that both -(i, j) and (r, j) appear in the sparsity pattern. -\n -\n -This routine tries to minimize, with respect to the choice of colors, -the number of colors. -*/ -extern void cppad_colpack_general( - CppAD::vector& color , - size_t m , - size_t n , - const CppAD::vector& adolc_pattern -); - -/*! -Link from CppAD to ColPack used for symmetric sparse matrices -(not yet used or tested). - -This CppAD library routine is necessary because -ColPack/ColPackHeaders.h has a -using namespace std at the global level. - -\param n [in] -is the nubmer of rows and columns in the symmetric sparse matrix. - -\param adolc_pattern [in] -This vector has size n, -adolc_pattern[i][0] is the number of non-zeros in row i. -For j = 1 , ... , adolc_sparsity[i], -adolc_pattern[i][j] is the column index (base zero) for the -non-zeros in row i. - -\param color [out] -The input value of its elements does not matter. -Upon return, it is a coloring for the rows of the sparse matrix. -The properties of this coloring have not yet been determined; see -Efficient Computation of Sparse Hessians Using Coloring -and Automatic Differentiation (pdf/ad/gebemedhin14.pdf) -*/ -extern void cppad_colpack_symmetric( - CppAD::vector& color , - size_t n , - const CppAD::vector& adolc_pattern -); - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif -# endif - diff --git a/build-config/cppad/include/cppad/local/cskip_op.hpp b/build-config/cppad/include/cppad/local/cskip_op.hpp deleted file mode 100644 index f9250608..00000000 --- a/build-config/cppad/include/cppad/local/cskip_op.hpp +++ /dev/null @@ -1,199 +0,0 @@ -# ifndef CPPAD_LOCAL_CSKIP_OP_HPP -# define CPPAD_LOCAL_CSKIP_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file cskip_op.hpp -Zero order forward mode set which operations to skip. -*/ - -/*! -Zero order forward mode execution of op = CSkipOp. - -\par Parameters and Variables -The terms parameter and variable depend on if we are referring to its -AD or Base value. -We use Base parameter and Base variable to refer to the -correspond Base value. -We use AD parameter and AD variable to refer to the -correspond AD value. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type Base. - -\param i_z -variable index corresponding to the result of the previous operation. -This is used for error checking. To be specific, -the left and right operands for the CExpOp operation must have indexes -less than or equal this value. - -\param arg [in] -\n - arg[0] -is static cast to size_t from the enum type -\verbatim - enum CompareOp { - CompareLt, - CompareLe, - CompareEq, - CompareGe, - CompareGt, - CompareNe - } -\endverbatim -for this operation. -Note that arg[0] cannot be equal to CompareNe. -\n -\n - arg[1] & 1 -\n -If this is zero, left is an AD parameter. -Otherwise it is an AD variable. -\n -\n - arg[1] & 2 -\n -If this is zero, right is an AD parameter. -Otherwise it is an AD variable. -\n - arg[2] -is the index corresponding to left in comparison. -\n - arg[3] -is the index corresponding to right in comparison. -\n - arg[4] -is the number of operations to skip if the comparison result is true. -\n - arg[5] -is the number of operations to skip if the comparison result is false. -\n -arg[5+i] -for i = 1 , ... , arg[4] are the operations to skip if the -comparison result is true and both left and right are -identically Base parameters. -\n -arg[5+arg[4]+i] -for i = 1 , ... , arg[5] are the operations to skip if the -comparison result is false and both left and right are -identically Base parameters. - -\param num_par [in] -is the total number of values in the vector parameter. - -\param parameter [in] -If left is an AD parameter, -parameter [ arg[2] ] is its value. -If right is an AD parameter, -parameter [ arg[3] ] is its value. - -\param cap_order [in] -number of columns in the matrix containing the Taylor coefficients. - -\param taylor [in] -If left is an AD variable, -taylor [ size_t(arg[2]) * cap_order + 0 ] -is the zeroth order Taylor coefficient corresponding to left. -If right is an AD variable, -taylor [ size_t(arg[3]) * cap_order + 0 ] -is the zeroth order Taylor coefficient corresponding to right. - -\param cskip_op [in,out] -is vector specifying which operations are at this point are know to be -unecessary and can be skipped. -This is both an input and an output. -*/ -template -void forward_cskip_op_0( - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - Base* taylor , - bool* cskip_op ) -{ - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < size_t(CompareNe) ); - CPPAD_ASSERT_UNKNOWN( arg[1] != 0 ); - - Base left, right; - if( arg[1] & 1 ) - { // If variable arg[2] <= i_z, it has already been computed, - // but it will be skipped for higher orders. - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= i_z ); - left = taylor[ size_t(arg[2]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); - left = parameter[ arg[2] ]; - } - if( arg[1] & 2 ) - { // If variable arg[3] <= i_z, it has already been computed, - // but it will be skipped for higher orders. - CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) <= i_z ); - right = taylor[ size_t(arg[3]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); - right = parameter[ arg[3] ]; - } - bool ok_to_skip = IdenticalCon(left) & IdenticalCon(right); - if( ! ok_to_skip ) - return; - - // initialize to avoid compiler warning - bool true_case = false; - Base diff = left - right; - switch( CompareOp( arg[0] ) ) - { - case CompareLt: - true_case = LessThanZero(diff); - break; - - case CompareLe: - true_case = LessThanOrZero(diff); - break; - - case CompareEq: - true_case = IdenticalZero(diff); - break; - - case CompareGe: - true_case = GreaterThanOrZero(diff); - break; - - case CompareGt: - true_case = GreaterThanZero(diff); - break; - - case CompareNe: - true_case = ! IdenticalZero(diff); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - if( true_case ) - { for(addr_t i = 0; i < arg[4]; i++) - cskip_op[ arg[6+i] ] = true; - } - else - { for(addr_t i = 0; i < arg[5]; i++) - cskip_op[ arg[6+arg[4]+i] ] = true; - } - return; -} -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/csum_op.hpp b/build-config/cppad/include/cppad/local/csum_op.hpp deleted file mode 100644 index 84eecde7..00000000 --- a/build-config/cppad/include/cppad/local/csum_op.hpp +++ /dev/null @@ -1,612 +0,0 @@ -# ifndef CPPAD_LOCAL_CSUM_OP_HPP -# define CPPAD_LOCAL_CSUM_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file csum_op.hpp -Forward, reverse and sparsity calculations for cummulative summation. -*/ - -/*! -Compute forward mode Taylor coefficients for result of op = CsumOp. - -This operation is -\verbatim - z = s + x(0) + ... + x(n1-1) - y(0) - ... - y(n2-1) - + p(0) + ... + p(n3-1) - q(0) - ... - q(n4-1). -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type -Base. - -\param p -lowest order of the Taylor coefficient that we are computing. - -\param q -highest order of the Taylor coefficient that we are computing. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg --- arg[0] -parameter[arg[0]] is the parameter value s in this cummunative summation. - --- arg[1] -end in arg of addition variables in summation. -arg[5] , ... , arg[arg[1]-1] correspond to x(0), ... , x(n1-1) - --- arg[2] -end in arg of subtraction variables in summation. -arg[arg[1]] , ... , arg[arg[2]-1] correspond to y(0), ... , y(n2-1) - --- arg[3] -end in arg of addition dynamic parameters in summation. -arg[arg[2]] , ... , arg[arg[3]-1] correspond to p(0), ... , p(n3-1) - --- arg[4] -end in arg of subtraction dynamic parameters in summation. -arg[arg[3]] , ... , arg[arg[4]-1] correspond to q(0), ... , q(n4-1) - -\param num_par -is the number of parameters in parameter. - -\param parameter -is the parameter vector for this operation sequence. - -\param cap_order -number of colums in the matrix containing all the Taylor coefficients. - -\param taylor -\b Input: taylor [ arg[5+i] * cap_order + k ] -for i = 0, ..., n1-1 -and k = 0 , ... , q -is the k-th order Taylor coefficient corresponding to x(i) -\n -\b Input: taylor [ arg[arg[1]+1] * cap_order + k ] -for i = 0, ..., n2-1 -and k = 0 , ... , q -is the k-th order Taylor coefficient corresponding to y(i) -\n -\b Input: taylor [ i_z * cap_order + k ] -for k = 0 , ... , p, -is the k-th order Taylor coefficient corresponding to z. -\n -\b Output: taylor [ i_z * cap_order + k ] -for k = p , ... , q, -is the k-th order Taylor coefficient corresponding to z. -*/ -template -void forward_csum_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ Base zero(0); - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumRes(CSumOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - CPPAD_ASSERT_UNKNOWN( - arg[arg[4]] == arg[4] - ); - - // Taylor coefficients corresponding to result - Base* z = taylor + i_z * cap_order; - for(size_t k = p; k <= q; k++) - z[k] = zero; - if( p == 0 ) - { // normal parameters in the sum - z[p] = parameter[ arg[0] ]; - // addition dynamic parameters - for(size_t i = size_t(arg[2]); i < size_t(arg[3]); ++i) - z[p] += parameter[ arg[i] ]; - // subtraction dynamic parameters - for(size_t i = size_t(arg[3]); i < size_t(arg[4]); ++i) - z[p] -= parameter[ arg[i] ]; - } - Base* x; - for(size_t i = 5; i < size_t(arg[1]); ++i) - { CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - x = taylor + size_t(arg[i]) * cap_order; - for(size_t k = p; k <= q; k++) - z[k] += x[k]; - } - for(size_t i = size_t(arg[1]); i < size_t(arg[2]); ++i) - { CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - x = taylor + size_t(arg[i]) * cap_order; - for(size_t k = p; k <= q; k++) - z[k] -= x[k]; - } -} - -/*! -Multiple direction forward mode Taylor coefficients for op = CsumOp. - -This operation is -\verbatim - z = s + x(0) + ... + x(m-1) - y(0) - ... - y(n-1). -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type -Base. - -\param q -order ot the Taylor coefficients that we are computing. - -\param r -number of directions for Taylor coefficients that we are computing. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg --- arg[0] -parameter[arg[0]] is the parameter value s in this cummunative summation. - --- arg[1] -end in arg of addition variables in summation. -arg[5] , ... , arg[arg[1]-1] correspond to x(0), ... , x(m-1) - --- arg[2] -end in arg of subtraction variables in summation. -arg[arg[1]] , ... , arg[arg[2]-1] correspond to y(0), ... , y(n-1) - --- arg[3] -end in arg of addition dynamic parameters in summation. - --- arg[4] -end in arg of subtraction dynamic parameters in summation. - -\param num_par -is the number of parameters in parameter. - -\param parameter -is the parameter vector for this operation sequence. - -\param cap_order -number of colums in the matrix containing all the Taylor coefficients. - -\param taylor -\b Input: taylor [ arg[5+i]*((cap_order-1)*r + 1) + 0 ] -for i = 0, ..., m-1 -is the 0-th order Taylor coefficient corresponding to x(i) and -taylor [ arg[5+i]*((cap_order-1)*r + 1) + (q-1)*r + ell + 1 ] -for i = 0, ..., m-1, -ell = 0 , ... , r-1 -is the q-th order Taylor coefficient corresponding to x(i) -and direction ell. -\n -\b Input: taylor [ arg[arg[1]+1]*((cap_order-1)*r + 1) + 0 ] -for i = 0, ..., n-1 -is the 0-th order Taylor coefficient corresponding to y(i) and -taylor [ arg[arg[1]+1]*((cap_order-1)*r + 1) + (q-1)*r + ell + 1 ] -for i = 0, ..., n-1, -ell = 0 , ... , r-1 -is the q-th order Taylor coefficient corresponding to y(i) -and direction ell. -\n -\b Output: taylor [ i_z*((cap_order-1)*r+1) + (q-1)*r + ell + 1 ] -is the q-th order Taylor coefficient corresponding to z -for direction ell = 0 , ... , r-1. -*/ -template -void forward_csum_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ Base zero(0); - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumRes(CSumOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - CPPAD_ASSERT_UNKNOWN( - arg[arg[4]] == arg[4] - ); - - // Taylor coefficients corresponding to result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q-1)*r + 1; - Base* z = taylor + i_z * num_taylor_per_var + m; - for(size_t ell = 0; ell < r; ell++) - z[ell] = zero; - Base* x; - for(size_t i = 5; i < size_t(arg[1]); ++i) - { CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - x = taylor + size_t(arg[i]) * num_taylor_per_var + m; - for(size_t ell = 0; ell < r; ell++) - z[ell] += x[ell]; - } - for(size_t i = size_t(arg[1]); i < size_t(arg[2]); ++i) - { CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - x = taylor + size_t(arg[i]) * num_taylor_per_var + m; - for(size_t ell = 0; ell < r; ell++) - z[ell] -= x[ell]; - } -} - -/*! -Compute reverse mode Taylor coefficients for result of op = CsumOp. - -This operation is -\verbatim - z = q + x(0) + ... + x(m-1) - y(0) - ... - y(n-1). - H(y, x, w, ...) = G[ z(x, y), y, x, w, ... ] -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type -Base. - -\param d -order the highest order Taylor coefficient that we are computing -the partial derivatives with respect to. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg --- arg[0] -parameter[arg[0]] is the parameter value s in this cummunative summation. - --- arg[1] -end in arg of addition variables in summation. -arg[5] , ... , arg[arg[1]-1] correspond to x(0), ... , x(m-1) - --- arg[2] -end in arg of subtraction variables in summation. -arg[arg[1]] , ... , arg[arg[2]-1] correspond to y(0), ... , y(n-1) - --- arg[3] -end in arg of addition dynamic parameters in summation. - --- arg[4] -end in arg of subtraction dynamic parameters in summation. - -\param nc_partial -number of colums in the matrix containing all the partial derivatives. - -\param partial -\b Input: partial [ arg[5+i] * nc_partial + k ] -for i = 0, ..., m-1 -and k = 0 , ... , d -is the partial derivative of G(z, y, x, w, ...) with respect to the -k-th order Taylor coefficient corresponding to x(i) -\n -\b Input: partial [ arg[arg[1]+1] * nc_partial + k ] -for i = 0, ..., n-1 -and k = 0 , ... , d -is the partial derivative of G(z, y, x, w, ...) with respect to the -k-th order Taylor coefficient corresponding to y(i) -\n -\b Input: partial [ i_z * nc_partial + k ] -for i = 0, ..., n-1 -and k = 0 , ... , d -is the partial derivative of G(z, y, x, w, ...) with respect to the -k-th order Taylor coefficient corresponding to z. -\n -\b Output: partial [ arg[5+i] * nc_partial + k ] -for i = 0, ..., m-1 -and k = 0 , ... , d -is the partial derivative of H(y, x, w, ...) with respect to the -k-th order Taylor coefficient corresponding to x(i) -\n -\b Output: partial [ arg[arg[1]+1] * nc_partial + k ] -for i = 0, ..., n-1 -and k = 0 , ... , d -is the partial derivative of H(y, x, w, ...) with respect to the -k-th order Taylor coefficient corresponding to y(i) -*/ - -template -void reverse_csum_op( - size_t d , - size_t i_z , - const addr_t* arg , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumRes(CSumOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partial derivative corresponding to result - Base* pz = partial + i_z * nc_partial; - Base* px; - size_t d1 = d + 1; - for(size_t i = 5; i < size_t(arg[1]); ++i) - { CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - px = partial + size_t(arg[i]) * nc_partial; - size_t k = d1; - while(k--) - px[k] += pz[k]; - } - for(size_t i = size_t(arg[1]); i < size_t(arg[2]); ++i) - { CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - px = partial + size_t(arg[i]) * nc_partial; - size_t k = d1; - while(k--) - px[k] -= pz[k]; - } -} - - -/*! -Forward mode Jacobian sparsity pattern for CSumOp operator. - -This operation is -\verbatim - z = q + x(0) + ... + x(m-1) - y(0) - ... - y(n-1). -\endverbatim - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the index in sparsity corresponding to z. - -\param arg --- arg[0] -parameter[arg[0]] is the parameter value s in this cummunative summation. - --- arg[1] -end in arg of addition variables in summation. -arg[5] , ... , arg[arg[1]-1] correspond to x(0), ... , x(m-1) - --- arg[2] -end in arg of subtraction variables in summation. -arg[arg[1]] , ... , arg[arg[2]-1] correspond to y(0), ... , y(n-1) - --- arg[3] -end in arg of addition dynamic parameters in summation. - --- arg[4] -end in arg of subtraction dynamic parameters in summation. - -\param sparsity -\b Input: -For i = 0, ..., m-1, -the set with index arg[5+i] in sparsity -is the sparsity bit pattern for x(i). -This identifies which of the independent variables the variable -x(i) depends on. -\n -\b Input: -For i = 0, ..., n-1, -the set with index arg[2+arg[0]+i] in sparsity -is the sparsity bit pattern for x(i). -This identifies which of the independent variables the variable -y(i) depends on. -\n -\b Output: -The set with index i_z in sparsity -is the sparsity bit pattern for z. -This identifies which of the independent variables the variable z -depends on. -*/ - -template -void forward_sparse_jacobian_csum_op( - size_t i_z , - const addr_t* arg , - Vector_set& sparsity ) -{ sparsity.clear(i_z); - - for(size_t i = 5; i < size_t(arg[2]); ++i) - { CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - sparsity.binary_union( - i_z , // index in sparsity for result - i_z , // index in sparsity for left operand - size_t(arg[i]), // index for right operand - sparsity // sparsity vector for right operand - ); - } -} - -/*! -Reverse mode Jacobian sparsity pattern for CSumOp operator. - -This operation is -\verbatim - z = q + x(0) + ... + x(m-1) - y(0) - ... - y(n-1). - H(y, x, w, ...) = G[ z(x, y), y, x, w, ... ] -\endverbatim - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the index in sparsity corresponding to z. - -\param arg --- arg[0] -parameter[arg[0]] is the parameter value s in this cummunative summation. - --- arg[1] -end in arg of addition variables in summation. -arg[5] , ... , arg[arg[1]-1] correspond to x(0), ... , x(m-1) - --- arg[2] -end in arg of subtraction variables in summation. -arg[arg[1]] , ... , arg[arg[2]-1] correspond to y(0), ... , y(n-1) - --- arg[3] -end in arg of addition dynamic parameters in summation. - --- arg[4] -end in arg of subtraction dynamic parameters in summation. - -\param sparsity -For i = 0, ..., m-1, -the set with index arg[5+i] in sparsity -is the sparsity bit pattern for x(i). -This identifies which of the dependent variables depend on x(i). -On input, the sparsity patter corresponds to G, -and on ouput it corresponds to H. -\n -For i = 0, ..., m-1, -the set with index arg[2+arg[0]+i] in sparsity -is the sparsity bit pattern for y(i). -This identifies which of the dependent variables depend on y(i). -On input, the sparsity patter corresponds to G, -and on ouput it corresponds to H. -\n -\b Input: -The set with index i_z in sparsity -is the sparsity bit pattern for z. -On input it corresponds to G and on output it is undefined. -*/ - -template -void reverse_sparse_jacobian_csum_op( - size_t i_z , - const addr_t* arg , - Vector_set& sparsity ) -{ - for(size_t i = 5; i < size_t(arg[2]); ++i) - { - CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - sparsity.binary_union( - size_t(arg[i]), // index in sparsity for result - size_t(arg[i]), // index in sparsity for left operand - i_z , // index for right operand - sparsity // sparsity vector for right operand - ); - } -} -/*! -Reverse mode Hessian sparsity pattern for CSumOp operator. - -This operation is -\verbatim - z = q + x(0) + ... + x(m-1) - y(0) - ... - y(n-1). - H(y, x, w, ...) = G[ z(x, y), y, x, w, ... ] -\endverbatim - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the index in sparsity corresponding to z. - -\param arg --- arg[0] -parameter[arg[0]] is the parameter value s in this cummunative summation. - --- arg[1] -end in arg of addition variables in summation. -arg[5] , ... , arg[arg[1]-1] correspond to x(0), ... , x(m-1) - --- arg[2] -end in arg of subtraction variables in summation. -arg[arg[1]] , ... , arg[arg[2]-1] correspond to y(0), ... , y(n-1) - --- arg[3] -end in arg of addition dynamic parameters in summation. - --- arg[4] -end in arg of subtraction dynamic parameters in summation. - -\param rev_jacobian -rev_jacobian[i_z] -is all false (true) if the Jabobian of G with respect to z must be zero -(may be non-zero). -\n -\n -For i = 0, ..., m-1 -rev_jacobian[ arg[5+i] ] -is all false (true) if the Jacobian with respect to x(i) -is zero (may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. -\n -\n -For i = 0, ..., n-1 -rev_jacobian[ arg[2+arg[0]+i] ] -is all false (true) if the Jacobian with respect to y(i) -is zero (may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. - -\param rev_hes_sparsity -The set with index i_z in in rev_hes_sparsity -is the Hessian sparsity pattern for the fucntion G -where one of the partials derivative is with respect to z. -\n -\n -For i = 0, ..., m-1 -The set with index arg[5+i] in rev_hes_sparsity -is the Hessian sparsity pattern -where one of the partials derivative is with respect to x(i). -On input, it corresponds to the function G, -and on output it corresponds to the function H. -\n -\n -For i = 0, ..., n-1 -The set with index arg[2+arg[0]+i] in rev_hes_sparsity -is the Hessian sparsity pattern -where one of the partials derivative is with respect to y(i). -On input, it corresponds to the function G, -and on output it corresponds to the function H. -*/ - -template -void reverse_sparse_hessian_csum_op( - size_t i_z , - const addr_t* arg , - bool* rev_jacobian , - Vector_set& rev_hes_sparsity ) -{ - for(size_t i = 5; i < size_t(arg[2]); ++i) - { - CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z ); - rev_hes_sparsity.binary_union( - size_t(arg[i]), // index in sparsity for result - size_t(arg[i]), // index in sparsity for left operand - i_z , // index for right operand - rev_hes_sparsity // sparsity vector for right operand - ); - rev_jacobian[arg[i]] |= rev_jacobian[i_z]; - } -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/declare_ad.hpp b/build-config/cppad/include/cppad/local/declare_ad.hpp deleted file mode 100644 index 1b75f8b6..00000000 --- a/build-config/cppad/include/cppad/local/declare_ad.hpp +++ /dev/null @@ -1,183 +0,0 @@ -# ifndef CPPAD_LOCAL_DECLARE_AD_HPP -# define CPPAD_LOCAL_DECLARE_AD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include - -/*! -\file declare_ad.hpp CppAD forward declarations; i.e., before definition -*/ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE - -template class ADTape; -template class player; -template class recorder; - -} } // END_CPPAD_LOCAL_NAMESPACE - -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 - }; - - // simple typedefs - typedef CPPAD_TAPE_ADDR_TYPE addr_t; - typedef CPPAD_TAPE_ID_TYPE tape_id_t; - - // classes - class sparse_hes_work; - class sparse_jac_work; - class sparse_jacobian_work; - class sparse_hessian_work; - template class AD; - template class ADFun; - template class atomic_base; - template class atomic_three; - template class discrete; - template class VecAD; - template class VecAD_reference; - - // functions with one VecAD argument - template bool Constant (const VecAD &u); - template bool Dynamic (const VecAD &u); - template bool Parameter (const VecAD &u); - template bool Variable (const VecAD &u); - - // functions with one AD argument - template bool Constant (const AD &u); - template bool Dynamic (const AD &u); - template bool Parameter (const AD &u); - template bool Variable (const AD &u); - // - template int Integer (const AD &u); - template bool IdenticalZero (const AD &u); - template bool IdenticalOne (const AD &u); - template bool IdenticalCon (const AD &u); - template bool LessThanZero (const AD &u); - template bool LessThanOrZero (const AD &u); - template bool GreaterThanZero (const AD &u); - template bool GreaterThanOrZero (const AD &u); - template AD Var2Par (const AD &u); - template AD abs (const AD &u); - template AD acos (const AD &u); - template AD asin (const AD &u); - template AD atan (const AD &u); - template AD cos (const AD &u); - template AD cosh (const AD &u); - template AD exp (const AD &u); - template AD log (const AD &u); - template AD log10 (const AD &u); - template AD sin (const AD &u); - template AD sinh (const AD &u); - template AD sqrt (const AD &u); - template AD tan (const AD &u); - // - template unsigned short hash_code(const AD& u); - - // arithematic operators - template AD operator + ( - const AD &left, const AD &right); - template AD operator - ( - const AD &left, const AD &right); - template AD operator * ( - const AD &left, const AD &right); - template AD operator / ( - const AD &left, const AD &right); - - // comparison operators - template bool operator < ( - const AD &left, const AD &right); - template bool operator <= ( - const AD &left, const AD &right); - template bool operator > ( - const AD &left, const AD &right); - template bool operator >= ( - const AD &left, const AD &right); - template bool operator == ( - const AD &left, const AD &right); - template bool operator != ( - const AD &left, const AD &right); - - // pow - template AD pow ( - const AD &x, const AD &y); - - // azmul - template AD azmul ( - const AD &x, const AD &y); - - // NearEqual - template bool NearEqual( - const AD &x, const AD &y, const Base &r, const Base &a); - - template bool NearEqual( - const Base &x, const AD &y, const Base &r, const Base &a); - - template bool NearEqual( - const AD &x, const Base &y, const Base &r, const Base &a); - - // CondExpOp - template AD CondExpOp ( - enum CompareOp cop , - const AD &left , - const AD &right , - const AD &trueCase , - const AD &falseCase - ); - - // IdenticalEqualCon - template - bool IdenticalEqualCon (const AD &u, const AD &v); - - // EqualOpSeq - template - bool EqualOpSeq (const AD &u, const AD &v); - - // PrintFor - template - void PrintFor( - const AD& flag , - const char* before , - const AD& var , - const char* after - ); - - // Value - template Base Value(const AD &x); - - // Pow function - template AD pow - (const AD &x, const AD &y); - - // input operator - template std::istream& - operator >> (std::istream &is, AD &x); - - // output operator - template std::ostream& - operator << (std::ostream &os, const AD &x); - template std::ostream& - operator << (std::ostream &os, const VecAD_reference &e); - template std::ostream& - operator << (std::ostream &os, const VecAD &vec); -} - -# endif diff --git a/build-config/cppad/include/cppad/local/define.hpp b/build-config/cppad/include/cppad/local/define.hpp deleted file mode 100644 index 8c52b377..00000000 --- a/build-config/cppad/include/cppad/local/define.hpp +++ /dev/null @@ -1,321 +0,0 @@ -# ifndef CPPAD_LOCAL_DEFINE_HPP -# define CPPAD_LOCAL_DEFINE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/*! -\file define.hpp -Define processor symbols and macros that are used by CppAD. -*/ - -/*! -\def CPPAD_VEC_ENUM_TYPE -Is the type used to store vectors of enum values when the vector -may be large and we want to conserve memory. The following must hold for -any enum_value that is stored using the type CPPAD_VEC_ENUM_TYPE: - - size_t(enum_value) <= std::numeric_limits::max() - && is_pod - -*/ -# define CPPAD_VEC_ENUM_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://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/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. -It uses this case to define the cases where -left has type AD and right has type -VecAD_reference, -Base, or -double. -The argument right is const and call by reference. -This macro converts the operands to AD and then -uses the definition of the same operation for that case. -*/ - -# define CPPAD_FOLD_ASSIGNMENT_OPERATOR(Op) \ -/* ----------------------------------------------------------------*/ \ -template \ -AD& operator Op \ -(AD &left, double right) \ -{ return left Op AD(right); } \ - \ -template \ -AD& operator Op \ -(AD &left, const Base &right) \ -{ return left Op AD(right); } \ - \ -inline AD& operator Op \ -(AD &left, const double &right) \ -{ return left Op AD(right); } \ - \ -template \ -AD& operator Op \ -(AD &left, const VecAD_reference &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. -It uses this case to define the cases either left -or right has type VecAD_reference or AD -and the type of the other operand is one of the following: -VecAD_reference, AD, Base, double. -All of the arguments are const and call by reference. -This macro converts the operands to AD and then -uses the definition of the same operation for that case. -*/ -# define CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op) \ -/* ----------------------------------------------------------------*/ \ -/* Operations with VecAD_reference and AD only*/ \ - \ -template \ -AD operator Op \ -(const AD &left, const VecAD_reference &right) \ -{ return left Op right.ADBase(); } \ - \ -template \ -AD operator Op \ -(const VecAD_reference &left, const VecAD_reference &right)\ -{ return left.ADBase() Op right.ADBase(); } \ - \ -template \ -AD operator Op \ - (const VecAD_reference &left, const AD &right) \ -{ return left.ADBase() Op right; } \ -/* ----------------------------------------------------------------*/ \ -/* Operations Base */ \ - \ -template \ -AD operator Op \ - (const Base &left, const AD &right) \ -{ return AD(left) Op right; } \ - \ -template \ -AD operator Op \ - (const Base &left, const VecAD_reference &right) \ -{ return AD(left) Op right.ADBase(); } \ - \ -template \ -AD operator Op \ - (const AD &left, const Base &right) \ -{ return left Op AD(right); } \ - \ -template \ -AD operator Op \ - (const VecAD_reference &left, const Base &right) \ -{ return left.ADBase() Op AD(right); } \ - \ -/* ----------------------------------------------------------------*/ \ -/* Operations double */ \ - \ -template \ -AD operator Op \ - (const double &left, const AD &right) \ -{ return AD(left) Op right; } \ - \ -template \ -AD operator Op \ - (const double &left, const VecAD_reference &right) \ -{ return AD(left) Op right.ADBase(); } \ - \ -template \ -AD operator Op \ - (const AD &left, const double &right) \ -{ return left Op AD(right); } \ - \ -template \ -AD operator Op \ - (const VecAD_reference &left, const double &right) \ -{ return left.ADBase() Op AD(right); } \ -/* ----------------------------------------------------------------*/ \ -/* Special case to avoid ambuigity when Base is double */ \ - \ -inline AD operator Op \ - (const double &left, const AD &right) \ -{ return AD(left) Op right; } \ - \ -inline AD operator Op \ - (const double &left, const VecAD_reference &right) \ -{ return AD(left) Op right.ADBase(); } \ - \ -inline AD operator Op \ - (const AD &left, const double &right) \ -{ return left Op AD(right); } \ - \ -inline AD operator Op \ - (const VecAD_reference &left, const double &right) \ -{ return left.ADBase() Op AD(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 and the result has type bool. -It uses this case to define the cases either left -or right has type -VecAD_reference or AD -and the type of the other operand is one of the following: -VecAD_reference, AD, Base, double. -All of the arguments are const and call by reference. -This macro converts the operands to AD and then -uses the definition of the same operation for that case. -*/ -# define CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op) \ -/* ----------------------------------------------------------------*/ \ -/* Operations with VecAD_reference and AD only*/ \ - \ -template \ -bool operator Op \ -(const AD &left, const VecAD_reference &right) \ -{ return left Op right.ADBase(); } \ - \ -template \ -bool operator Op \ -(const VecAD_reference &left, const VecAD_reference &right)\ -{ return left.ADBase() Op right.ADBase(); } \ - \ -template \ -bool operator Op \ - (const VecAD_reference &left, const AD &right) \ -{ return left.ADBase() Op right; } \ -/* ----------------------------------------------------------------*/ \ -/* Operations Base */ \ - \ -template \ -bool operator Op \ - (const Base &left, const AD &right) \ -{ return AD(left) Op right; } \ - \ -template \ -bool operator Op \ - (const Base &left, const VecAD_reference &right) \ -{ return AD(left) Op right.ADBase(); } \ - \ -template \ -bool operator Op \ - (const AD &left, const Base &right) \ -{ return left Op AD(right); } \ - \ -template \ -bool operator Op \ - (const VecAD_reference &left, const Base &right) \ -{ return left.ADBase() Op AD(right); } \ - \ -/* ----------------------------------------------------------------*/ \ -/* Operations double */ \ - \ -template \ -bool operator Op \ - (const double &left, const AD &right) \ -{ return AD(left) Op right; } \ - \ -template \ -bool operator Op \ - (const double &left, const VecAD_reference &right) \ -{ return AD(left) Op right.ADBase(); } \ - \ -template \ -bool operator Op \ - (const AD &left, const double &right) \ -{ return left Op AD(right); } \ - \ -template \ -bool operator Op \ - (const VecAD_reference &left, const double &right) \ -{ return left.ADBase() Op AD(right); } \ -/* ----------------------------------------------------------------*/ \ -/* Special case to avoid ambuigity when Base is double */ \ - \ -inline bool operator Op \ - (const double &left, const AD &right) \ -{ return AD(left) Op right; } \ - \ -inline bool operator Op \ - (const double &left, const VecAD_reference &right) \ -{ return AD(left) Op right.ADBase(); } \ - \ -inline bool operator Op \ - (const AD &left, const double &right) \ -{ return left Op AD(right); } \ - \ -inline bool operator Op \ - (const VecAD_reference &left, const double &right) \ -{ return left.ADBase() Op AD(right); } - -# endif diff --git a/build-config/cppad/include/cppad/local/discrete_op.hpp b/build-config/cppad/include/cppad/local/discrete_op.hpp deleted file mode 100644 index e3fa0809..00000000 --- a/build-config/cppad/include/cppad/local/discrete_op.hpp +++ /dev/null @@ -1,121 +0,0 @@ -# ifndef CPPAD_LOCAL_DISCRETE_OP_HPP -# define CPPAD_LOCAL_DISCRETE_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file discrete_op.hpp -Forward mode for z = f(x) where f is piecewise constant. -*/ - - -/*! -forward mode Taylor coefficient for result of op = DisOp. - -The C++ source code corresponding to this operation is -\verbatim - z = f(x) -\endverbatim -where f is a piecewise constant function (and it's derivative is always -calculated as zero). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param p -is the lowest order Taylor coefficient that will be calculated. - -\param q -is the highest order Taylor coefficient that will be calculated. - -\param r -is the number of directions, for each order, -that will be calculated (except for order zero wich only has one direction). - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg - arg[0] -\n -is the index, in the order of the discrete functions defined by the user, -for this discrete function. -\n -\n - arg[1] -variable index corresponding to the argument for this operator; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param taylor -\b Input: taylor [ arg[1] * tpv + 0 ] -is the zero order Taylor coefficient corresponding to x. -\n -\b Output: if p == 0 -taylor [ i_z * tpv + 0 ] -is the zero order Taylor coefficient corresponding to z. -For k = max(p, 1), ... , q, -taylor [ i_z * tpv + (k-1)*r + 1 + ell ] -is the k-th order Taylor coefficient corresponding to z -(which is zero). - -\par Checked Assertions where op is the unary operator with one result: -\li NumArg(op) == 2 -\li NumRes(op) == 1 -\li q < cap_order -\li 0 < r -*/ -template -void forward_dis_op( - size_t p , - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DisOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DisOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < r ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + size_t(arg[1]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - if( p == 0 ) - { z[0] = discrete::eval(size_t(arg[0]), x[0]); - p++; - } - for(size_t ell = 0; ell < r; ell++) - for(size_t k = p; k <= q; k++) - z[ (k-1) * r + 1 + ell ] = Base(0.0); -} - - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/div_op.hpp b/build-config/cppad/include/cppad/local/div_op.hpp deleted file mode 100644 index 9fcb196a..00000000 --- a/build-config/cppad/include/cppad/local/div_op.hpp +++ /dev/null @@ -1,574 +0,0 @@ -# ifndef CPPAD_LOCAL_DIV_OP_HPP -# define CPPAD_LOCAL_DIV_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file div_op.hpp -Forward and reverse mode calculations for z = x / y. -*/ - -// --------------------------- Divvv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = DivvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_divvv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - - // Using CondExp, it can make sense to divide by zero, - // so do not make it an error. - size_t k; - for(size_t d = p; d <= q; d++) - { z[d] = x[d]; - for(k = 1; k <= d; k++) - z[d] -= z[d-k] * y[k]; - z[d] /= y[0]; - } -} -/*! -Multiple directions forward mode Taylor coefficients for op = DivvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_divvv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - - // Using CondExp, it can make sense to divide by zero, - // so do not make it an error. - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = x[m+ell] - z[0] * y[m+ell]; - for(size_t k = 1; k < q; k++) - z[m+ell] -= z[(q-k-1)*r+1+ell] * y[(k-1)*r+1+ell]; - z[m+ell] /= y[0]; - } -} - - -/*! -Compute zero order forward mode Taylor coefficients for result of op = DivvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_divvv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x[0] / y[0]; -} - -/*! -Compute reverse mode partial derivatives for result of op = DivvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_divvv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Arguments - const Base* y = taylor + size_t(arg[1]) * cap_order; - const Base* z = taylor + i_z * cap_order; - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // Using CondExp, it can make sense to divide by zero - // so do not make it an error. - Base inv_y0 = Base(1.0) / y[0]; - - size_t k; - // number of indices to access - size_t j = d + 1; - while(j) - { --j; - // scale partial w.r.t. z[j] - pz[j] = azmul(pz[j], inv_y0); - - px[j] += pz[j]; - for(k = 1; k <= j; k++) - { pz[j-k] -= azmul(pz[j], y[k] ); - py[k] -= azmul(pz[j], z[j-k]); - } - py[0] -= azmul(pz[j], z[j]); - } -} - -// --------------------------- Divpv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = DivpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_divpv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - // Paraemter value - Base x = parameter[ arg[0] ]; - - // Using CondExp, it can make sense to divide by zero, - // so do not make it an error. - size_t k; - if( p == 0 ) - { z[0] = x / y[0]; - p++; - } - for(size_t d = p; d <= q; d++) - { z[d] = Base(0.0); - for(k = 1; k <= d; k++) - z[d] -= z[d-k] * y[k]; - z[d] /= y[0]; - } -} -/*! -Multiple directions forward mode Taylor coefficients for op = DivpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_divpv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - // Using CondExp, it can make sense to divide by zero, - // so do not make it an error. - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = - z[0] * y[m+ell]; - for(size_t k = 1; k < q; k++) - z[m+ell] -= z[(q-k-1)*r+1+ell] * y[(k-1)*r+1+ell]; - z[m+ell] /= y[0]; - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = DivpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_divpv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 ); - - // Paraemter value - Base x = parameter[ arg[0] ]; - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x / y[0]; -} - -/*! -Compute reverse mode partial derivative for result of op = DivpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_divpv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Arguments - const Base* y = taylor + size_t(arg[1]) * cap_order; - const Base* z = taylor + i_z * cap_order; - - // Partial derivatives corresponding to arguments and result - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // Using CondExp, it can make sense to divide by zero so do not - // make it an error. - Base inv_y0 = Base(1.0) / y[0]; - - size_t k; - // number of indices to access - size_t j = d + 1; - while(j) - { --j; - // scale partial w.r.t z[j] - pz[j] = azmul(pz[j], inv_y0); - - for(k = 1; k <= j; k++) - { pz[j-k] -= azmul(pz[j], y[k] ); - py[k] -= azmul(pz[j], z[j-k] ); - } - py[0] -= azmul(pz[j], z[j]); - } -} - - -// --------------------------- Divvp ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = DivvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_divvp_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z = taylor + i_z * cap_order; - - // Parameter value - Base y = parameter[ arg[1] ]; - - // Using CondExp and multiple levels of AD, it can make sense - // to divide by zero so do not make it an error. - for(size_t d = p; d <= q; d++) - z[d] = x[d] / y; -} -/*! -Multiple direction forward mode Taylor coefficients for op = DivvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_divvp_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - // Parameter value - Base y = parameter[ arg[1] ]; - - // Using CondExp and multiple levels of AD, it can make sense - // to divide by zero so do not make it an error. - size_t m = (q-1)*r + 1; - for(size_t ell = 0; ell < r; ell++) - z[m + ell] = x[m + ell] / y; -} - - -/*! -Compute zero order forward mode Taylor coefficients for result of op = DivvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_divvp_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 ); - - // Parameter value - Base y = parameter[ arg[1] ]; - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x[0] / y; -} - -/*! -Compute reverse mode partial derivative for result of op = DivvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x / y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_divvp_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Argument values - Base y = parameter[ arg[1] ]; - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // Using CondExp, it can make sense to divide by zero - // so do not make it an error. - Base inv_y = Base(1.0) / y; - - // number of indices to access - size_t j = d + 1; - while(j) - { --j; - px[j] += azmul(pz[j], inv_y); - } -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/erf_op.hpp b/build-config/cppad/include/cppad/local/erf_op.hpp deleted file mode 100644 index 937c8197..00000000 --- a/build-config/cppad/include/cppad/local/erf_op.hpp +++ /dev/null @@ -1,598 +0,0 @@ -# ifndef CPPAD_LOCAL_ERF_OP_HPP -# define CPPAD_LOCAL_ERF_OP_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file erf_op.hpp -Forward and reverse mode calculations for z = erf(x) or erfc(x). -*/ - -/*! -Forward mode Taylor coefficient for result of op = ErfOp or ErfcOp. - -The C++ source code corresponding to this operation is one of -\verbatim - z = erf(x) - z = erfc(x) -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type Base. - -\param op -must be either ErfOp or ErfcOp and indicates if this is -z = erf(x) or z = erfc(x). - -\param p -lowest order of the Taylor coefficients that we are computing. - -\param q -highest order of the Taylor coefficients that we are computing. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -The auxillary results are called y_j have index i_z - j. - -\param arg -arg[0]: is the variable index corresponding to x. -\n -arg[1]: is the parameter index corresponding to the value zero. -\n -arg[2]: is the parameter index correspodning to the value 2 / sqrt(pi). - -\param parameter -parameter[ arg[1] ] is the value zero, -and parameter[ arg[2] ] is the value 2 / sqrt(pi). - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: -taylor [ size_t(arg[0]) * cap_order + k ] -for k = 0 , ... , q, -is the k-th order Taylor coefficient corresponding to x. -\n -\b Input: -taylor [ i_z * cap_order + k ] -for k = 0 , ... , p - 1, -is the k-th order Taylor coefficient corresponding to z. -\n -\b Input: -taylor [ ( i_z - j) * cap_order + k ] -for k = 0 , ... , p-1, -and j = 0 , ... , 4, -is the k-th order Taylor coefficient corresponding to the j-th result for z. -\n -\b Output: -taylor [ (i_z-j) * cap_order + k ], -for k = p , ... , q, -and j = 0 , ... , 4, -is the k-th order Taylor coefficient corresponding to the j-th result for z. - -*/ -template -void forward_erf_op( - OpCode op , - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp ); - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z + 2 - ); - - // array used to pass parameter values for sub-operations - addr_t addr[2]; - - // convert from final result to first result - i_z -= 4; // 4 = NumRes(ErfOp) - 1; - - // z_0 = x * x - addr[0] = arg[0]; // x - addr[1] = arg[0]; // x - forward_mulvv_op(p, q, i_z+0, addr, parameter, cap_order, taylor); - - // z_1 = - x * x - addr[0] = arg[1]; // zero - addr[1] = addr_t( i_z ); // z_0 - forward_subpv_op(p, q, i_z+1, addr, parameter, cap_order, taylor); - - // z_2 = exp( - x * x ) - forward_exp_op(p, q, i_z+2, i_z+1, cap_order, taylor); - - // z_3 = (2 / sqrt(pi)) * exp( - x * x ) - addr[0] = arg[2]; // 2 / sqrt(pi) - addr[1] = addr_t( i_z + 2 ); // z_2 - forward_mulpv_op(p, q, i_z+3, addr, parameter, cap_order, taylor); - - // pointers to taylor coefficients for x , z_3, and z_4 - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z_3 = taylor + (i_z+3) * cap_order; - Base* z_4 = taylor + (i_z+4) * cap_order; - - // calculte z_4 coefficients - if( p == 0 ) - { // z4 (t) = erf[x(t)] - if( op == ErfOp ) - z_4[0] = erf(x[0]); - else - z_4[0] = erfc(x[0]); - p++; - } - // sign - Base sign(1.0); - if( op == ErfcOp ) - sign = Base(-1.0); - // - for(size_t j = p; j <= q; j++) - { // erf: z_4' (t) = erf'[x(t)] * x'(t) = z3(t) * x'(t) - // erfc: z_4' (t) = - erf'[x(t)] * x'(t) = - z3(t) * x'(t) - // z_4[1] + 2 * z_4[2] * t + ... = - // sign * (z_3[0] + z_3[1] * t + ...) * (x[1] + 2 * x[2] * t + ...) - Base base_j = static_cast(double(j)); - z_4[j] = static_cast(0); - for(size_t k = 1; k <= j; k++) - z_4[j] += sign * (Base(double(k)) / base_j) * x[k] * z_3[j-k]; - } -} - -/*! -Zero order Forward mode Taylor coefficient for result of op = ErfOp or ErfcOp. - -The C++ source code corresponding to this operation one of -\verbatim - z = erf(x) - z = erfc(x) -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type Base. - -\param op -must be either ErfOp or ErfcOp and indicates if this is -z = erf(x) or z = erfc(x). - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -The auxillary results are called y_j have index i_z - j. - -\param arg -arg[0]: is the variable index corresponding to x. -\n -arg[1]: is the parameter index corresponding to the value zero. -\n -arg[2]: is the parameter index correspodning to the value 2 / sqrt(pi). - -\param parameter -parameter[ arg[1] ] is the value zero, -and parameter[ arg[2] ] is the value 2 / sqrt(pi). - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: -taylor [ size_t(arg[0]) * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to x. -\n -\b Input: -taylor [ i_z * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to z. -\n -\b Output: -taylor [ (i_z-j) * cap_order + 0 ], -for j = 0 , ... , 4, -is the zero order Taylor coefficient for j-th result corresponding to z. - -*/ -template -void forward_erf_op_0( - OpCode op , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp ); - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z + 2 - ); - - // array used to pass parameter values for sub-operations - addr_t addr[2]; - - // convert from final result to first result - i_z -= 4; // 4 = NumRes(ErfOp) - 1; - - // z_0 = x * x - addr[0] = arg[0]; // x - addr[1] = arg[0]; // x - forward_mulvv_op_0(i_z+0, addr, parameter, cap_order, taylor); - - // z_1 = - x * x - addr[0] = arg[1]; // zero - addr[1] = addr_t(i_z); // z_0 - forward_subpv_op_0(i_z+1, addr, parameter, cap_order, taylor); - - // z_2 = exp( - x * x ) - forward_exp_op_0(i_z+2, i_z+1, cap_order, taylor); - - // z_3 = (2 / sqrt(pi)) * exp( - x * x ) - addr[0] = arg[2]; // 2 / sqrt(pi) - addr[1] = addr_t(i_z + 2); // z_2 - forward_mulpv_op_0(i_z+3, addr, parameter, cap_order, taylor); - - // zero order Taylor coefficient for z_4 - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z_4 = taylor + (i_z + 4) * cap_order; - if( op == ErfOp ) - z_4[0] = erf(x[0]); - else - z_4[0] = erfc(x[0]); -} -/*! -Forward mode Taylor coefficient for result of op = ErfOp or ErfcOp. - -The C++ source code corresponding to this operation is one of -\verbatim - z = erf(x) - z = erfc(x) -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type Base. - -\param op -must be either ErfOp or ErfcOp and indicates if this is -z = erf(x) or z = erfc(x). - -\param q -order of the Taylor coefficients that we are computing. - -\param r -number of directions for the Taylor coefficients that we afre computing. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -The auxillary results have index i_z - j for j = 0 , ... , 4 -(and include z). - -\param arg -arg[0]: is the variable index corresponding to x. -\n -arg[1]: is the parameter index corresponding to the value zero. -\n -arg[2]: is the parameter index correspodning to the value 2 / sqrt(pi). - -\param parameter -parameter[ arg[1] ] is the value zero, -and parameter[ arg[2] ] is the value 2 / sqrt(pi). - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param taylor -\b Input: If x is a variable, -taylor [ arg[0] * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ arg[0] * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to x and the ell-th direction. -\n -\b Input: -taylor [ (i_z - j) * tpv + 0 ] -is the zero order Taylor coefficient for all directions and the -j-th result for z. -for k = 1 , ... , q-1, -ell = 0, ... , r-1, - -taylor[ (i_z - j) * tpv + (k-1)*r + ell + 1] - -is the Taylor coefficient for the k-th order, ell-th direction, -and j-th auzillary result. -\n -\b Output: -taylor [ (i_z-j) * tpv + (q-1)*r + ell + 1 ], -for ell = 0 , ... , r-1, -is the Taylor coefficient for the q-th order, ell-th direction, -and j-th auzillary result. - -*/ -template -void forward_erf_op_dir( - OpCode op , - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp ); - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z + 2 - ); - - // array used to pass parameter values for sub-operations - addr_t addr[2]; - - // convert from final result to first result - i_z -= 4; // 4 = NumRes(ErfOp) - 1; - - // z_0 = x * x - addr[0] = arg[0]; // x - addr[1] = arg[0]; // x - forward_mulvv_op_dir(q, r, i_z+0, addr, parameter, cap_order, taylor); - - // z_1 = - x * x - addr[0] = arg[1]; // zero - addr[1] = addr_t( i_z ); // z_0 - forward_subpv_op_dir(q, r, i_z+1, addr, parameter, cap_order, taylor); - - // z_2 = exp( - x * x ) - forward_exp_op_dir(q, r, i_z+2, i_z+1, cap_order, taylor); - - // z_3 = (2 / sqrt(pi)) * exp( - x * x ) - addr[0] = arg[2]; // 2 / sqrt(pi) - addr[1] = addr_t( i_z + 2 ); // z_2 - forward_mulpv_op_dir(q, r, i_z+3, addr, parameter, cap_order, taylor); - - // pointers to taylor coefficients for x , z_3, and z_4 - size_t num_taylor_per_var = (cap_order - 1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var; - Base* z_3 = taylor + (i_z+3) * num_taylor_per_var; - Base* z_4 = taylor + (i_z+4) * num_taylor_per_var; - - // sign - Base sign(1.0); - if( op == ErfcOp ) - sign = Base(-1.0); - - // erf: z_4' (t) = erf'[x(t)] * x'(t) = z3(t) * x'(t) - // erfc: z_4' (t) = - erf'[x(t)] * x'(t) = z3(t) * x'(t) - // z_4[1] + 2 * z_4[2] * t + ... = - // sign * (z_3[0] + z_3[1] * t + ...) * (x[1] + 2 * x[2] * t + ...) - Base base_q = static_cast(double(q)); - for(size_t ell = 0; ell < r; ell++) - { // index in z_4 and x for q-th order term - size_t m = (q-1)*r + ell + 1; - // initialize q-th order term summation - z_4[m] = sign * z_3[0] * x[m]; - for(size_t k = 1; k < q; k++) - { size_t x_index = (k-1)*r + ell + 1; - size_t z3_index = (q-k-1)*r + ell + 1; - Base bk = Base(double(k)); - z_4[m] += sign * (bk / base_q) * x[x_index] * z_3[z3_index]; - } - } -} - -/*! -Compute reverse mode partial derivatives for result of op = ErfOp or ErfcOp. - -The C++ source code corresponding to this operation is one of -\verbatim - z = erf(x) - z = erfc(x) -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type Base. - -\param op -must be either ErfOp or ErfcOp and indicates if this is -z = erf(x) or z = erfc(x). - -\param d -highest order Taylor of the Taylor coefficients that we are computing -the partial derivatives with respect to. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -The auxillary results are called y_j have index i_z - j. - -\param arg -arg[0]: is the variable index corresponding to x. -\n -arg[1]: is the parameter index corresponding to the value zero. -\n -arg[2]: is the parameter index correspodning to the value 2 / sqrt(pi). - -\param parameter -parameter[ arg[1] ] is the value zero, -and parameter[ arg[2] ] is the value 2 / sqrt(pi). - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: -taylor [ size_t(arg[0]) * cap_order + k ] -for k = 0 , ... , d, -is the k-th order Taylor coefficient corresponding to x. -\n -taylor [ (i_z - j) * cap_order + k ] -for k = 0 , ... , d, -and for j = 0 , ... , 4, -is the k-th order Taylor coefficient corresponding to the j-th result -for this operation. - -\param nc_partial -number of columns in the matrix containing all the partial derivatives - -\param partial -\b Input: -partial [ size_t(arg[0]) * nc_partial + k ] -for k = 0 , ... , d, -is the partial derivative of G( z , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Input: -partial [ (i_z - j) * nc_partial + k ] -for k = 0 , ... , d, -and for j = 0 , ... , 4, -is the partial derivative of G( z , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for the j-th result of this operation. -\n -\b Output: -partial [ size_t(arg[0]) * nc_partial + k ] -for k = 0 , ... , d, -is the partial derivative of H( x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Output: -partial [ (i_z-j) * nc_partial + k ] -for k = 0 , ... , d, -and for j = 0 , ... , 4, -may be used as work space; i.e., may change in an unspecified manner. - -*/ -template -void reverse_erf_op( - OpCode op , - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp ); - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z + 2 - ); - - // array used to pass parameter values for sub-operations - addr_t addr[2]; - - // If pz is zero, make sure this operation has no effect - // (zero times infinity or nan would be non-zero). - Base* pz = partial + i_z * nc_partial; - bool skip(true); - for(size_t i_d = 0; i_d <= d; i_d++) - skip &= IdenticalZero(pz[i_d]); - if( skip ) - return; - - // convert from final result to first result - i_z -= 4; // 4 = NumRes(ErfOp) - 1; - - // Taylor coefficients and partials corresponding to x - const Base* x = taylor + size_t(arg[0]) * cap_order; - Base* px = partial + size_t(arg[0]) * nc_partial; - - // Taylor coefficients and partials corresponding to z_3 - const Base* z_3 = taylor + (i_z+3) * cap_order; - Base* pz_3 = partial + (i_z+3) * nc_partial; - - // Taylor coefficients and partials corresponding to z_4 - Base* pz_4 = partial + (i_z+4) * nc_partial; - - // sign - Base sign(1.0); - if( op == ErfcOp ) - sign = Base(-1.0); - - // Reverse z_4 - size_t j = d; - while(j) - { pz_4[j] /= Base(double(j)); - for(size_t k = 1; k <= j; k++) - { px[k] += sign * azmul(pz_4[j], z_3[j-k]) * Base(double(k)); - pz_3[j-k] += sign * azmul(pz_4[j], x[k]) * Base(double(k)); - } - j--; - } - px[0] += sign * azmul(pz_4[0], z_3[0]); - - // z_3 = (2 / sqrt(pi)) * exp( - x * x ) - addr[0] = arg[2]; // 2 / sqrt(pi) - addr[1] = addr_t( i_z + 2 ); // z_2 - reverse_mulpv_op( - d, i_z+3, addr, parameter, cap_order, taylor, nc_partial, partial - ); - - // z_2 = exp( - x * x ) - reverse_exp_op( - d, i_z+2, i_z+1, cap_order, taylor, nc_partial, partial - ); - - // z_1 = - x * x - addr[0] = arg[1]; // zero - addr[1] = addr_t( i_z ); // z_0 - reverse_subpv_op( - d, i_z+1, addr, parameter, cap_order, taylor, nc_partial, partial - ); - - // z_0 = x * x - addr[0] = arg[0]; // x - addr[1] = arg[0]; // x - reverse_mulvv_op( - d, i_z+0, addr, parameter, cap_order, taylor, nc_partial, partial - ); - -} - - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif // CPPAD_ERF_OP_INCLUDED diff --git a/build-config/cppad/include/cppad/local/exp_op.hpp b/build-config/cppad/include/cppad/local/exp_op.hpp deleted file mode 100644 index a5fca7ae..00000000 --- a/build-config/cppad/include/cppad/local/exp_op.hpp +++ /dev/null @@ -1,194 +0,0 @@ -# ifndef CPPAD_LOCAL_EXP_OP_HPP -# define CPPAD_LOCAL_EXP_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file exp_op.hpp -Forward and reverse mode calculations for z = exp(x). -*/ - - -/*! -Forward mode Taylor coefficient for result of op = ExpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = exp(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op -*/ -template -void forward_exp_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - size_t k; - if( p == 0 ) - { z[0] = exp( x[0] ); - p++; - } - for(size_t j = p; j <= q; j++) - { - z[j] = x[1] * z[j-1]; - for(k = 2; k <= j; k++) - z[j] += Base(double(k)) * x[k] * z[j-k]; - z[j] /= Base(double(j)); - } -} - - -/*! -Multiple direction forward mode Taylor coefficient for op = ExpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = exp(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_dir -*/ -template -void forward_exp_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t m = (q-1)*r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = Base(double(q)) * x[m+ell] * z[0]; - for(size_t k = 1; k < q; k++) - z[m+ell] += Base(double(k)) * x[(k-1)*r+ell+1] * z[(q-k-1)*r+ell+1]; - z[m+ell] /= Base(double(q)); - } -} - -/*! -Zero order forward mode Taylor coefficient for result of op = ExpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = exp(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_0 -*/ -template -void forward_exp_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = exp( x[0] ); -} -/*! -Reverse mode partial derivatives for result of op = ExpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = exp(x) -\endverbatim - -\copydetails CppAD::local::reverse_unary1_op -*/ - -template -void reverse_exp_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // If pz is zero, make sure this operation has no effect - // (zero times infinity or nan would be non-zero). - bool skip(true); - for(size_t i_d = 0; i_d <= d; i_d++) - skip &= IdenticalZero(pz[i_d]); - if( skip ) - return; - - // loop through orders in reverse - size_t j, k; - j = d; - while(j) - { // scale partial w.r.t z[j] - pz[j] /= Base(double(j)); - - for(k = 1; k <= j; k++) - { px[k] += Base(double(k)) * azmul(pz[j], z[j-k]); - pz[j-k] += Base(double(k)) * azmul(pz[j], x[k]); - } - --j; - } - px[0] += azmul(pz[0], z[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/expm1_op.hpp b/build-config/cppad/include/cppad/local/expm1_op.hpp deleted file mode 100644 index ea80fc96..00000000 --- a/build-config/cppad/include/cppad/local/expm1_op.hpp +++ /dev/null @@ -1,199 +0,0 @@ -# ifndef CPPAD_LOCAL_EXPM1_OP_HPP -# define CPPAD_LOCAL_EXPM1_OP_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file expm1_op.hpp -Forward and reverse mode calculations for z = expm1(x). -*/ - - -/*! -Forward mode Taylor coefficient for result of op = Expm1Op. - -The C++ source code corresponding to this operation is -\verbatim - z = expm1(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op -*/ -template -void forward_expm1_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - size_t k; - if( p == 0 ) - { z[0] = expm1( x[0] ); - p++; - } - for(size_t j = p; j <= q; j++) - { - z[j] = x[1] * z[j-1]; - for(k = 2; k <= j; k++) - z[j] += Base(double(k)) * x[k] * z[j-k]; - z[j] /= Base(double(j)); - z[j] += x[j]; - } -} - - -/*! -Multiple direction forward mode Taylor coefficient for op = Expm1Op. - -The C++ source code corresponding to this operation is -\verbatim - z = expm1(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_dir -*/ -template -void forward_expm1_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t m = (q-1)*r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = Base(double(q)) * x[m+ell] * z[0]; - for(size_t k = 1; k < q; k++) - z[m+ell] += Base(double(k)) * x[(k-1)*r+ell+1] * z[(q-k-1)*r+ell+1]; - z[m+ell] /= Base(double(q)); - z[m+ell] += x[m+ell]; - } -} - -/*! -Zero order forward mode Taylor coefficient for result of op = Expm1Op. - -The C++ source code corresponding to this operation is -\verbatim - z = expm1(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_0 -*/ -template -void forward_expm1_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = expm1( x[0] ); -} -/*! -Reverse mode partial derivatives for result of op = Expm1Op. - -The C++ source code corresponding to this operation is -\verbatim - z = expm1(x) -\endverbatim - -\copydetails CppAD::local::reverse_unary1_op -*/ - -template -void reverse_expm1_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - // If pz is zero, make sure this operation has no effect - // (zero times infinity or nan would be non-zero). - bool skip(true); - for(size_t i_d = 0; i_d <= d; i_d++) - skip &= IdenticalZero(pz[i_d]); - if( skip ) - return; - - // loop through orders in reverse - size_t j, k; - j = d; - while(j) - { px[j] += pz[j]; - - // scale partial w.r.t z[j] - pz[j] /= Base(double(j)); - - for(k = 1; k <= j; k++) - { px[k] += Base(double(k)) * azmul(pz[j], z[j-k]); - pz[j-k] += Base(double(k)) * azmul(pz[j], x[k]); - } - --j; - } - px[0] += pz[0] + azmul(pz[0], z[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/graph/cpp_graph_itr.hpp b/build-config/cppad/include/cppad/local/graph/cpp_graph_itr.hpp deleted file mode 100644 index deb5ebdf..00000000 --- a/build-config/cppad/include/cppad/local/graph/cpp_graph_itr.hpp +++ /dev/null @@ -1,386 +0,0 @@ -# ifndef CPPAD_LOCAL_GRAPH_CPP_GRAPH_ITR_HPP -# define CPPAD_LOCAL_GRAPH_CPP_GRAPH_ITR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -// BEGIN_CPPAD_LOCAL_GRAPH_NAMESPACE -namespace CppAD { namespace local { namespace graph { - -class cpp_graph_itr { -/* -$begin cpp_graph_itr_data$$ -$spell - Iterator -$$ - -$section C++ AD Graph Iterator Private Member Data$$ -$srccode%hpp% */ -private: - // valuse set by constructor - const vector* operator_vec_; - const vector* operator_arg_; - // - // set by constructor and ++ - size_t op_index_; - size_t first_arg_; - // - // set by get_value - size_t first_node_; - graph_op_enum op_enum_; - vector str_index_; - size_t n_result_; - vector arg_node_; -/* %$$ -$end ------------------------------------------------------------------------------- -$begin cpp_graph_itr_get_value$$ -$spell - obj - op - arg - vec - enum - Iterator - itr - str -$$ - -$section C++ AD Graph Iterator get_value()$$ - -$head Syntax$$ -$icode%itr%.get_value()%$$ - -$head op_index_$$ -This input is the operator index for the value we are retrieving. - -$head first_arg_$$ -This input is the first argument index for the value we are retrieving. - -$head first_node_$$ -The input value of this argument does not matter. -It is set to the index in $code operator_arg_$$ -of the first node argument for this operator. - -$head op_enum_$$ -The input value of this argument does not matter. -It is set to the $cref graph_op_enum$$ for the operator - -$head str_index_$$ -The input value of this argument does not matter. -Upon return its size is zero except for the special cases -listed below: - -$subhead atom_graph_op$$ -If $icode op_enum_$$ is $code atom_graph_op$$, -$code str_index_.size() == 1$$ and -$code str_index_[0]$$ is the index in -$cref/atomic_name_vec/cpp_ad_graph/atomic_name_vec/$$ -for the function called by this operator. - -$subhead discrete_graph_op$$ -If $icode op_enum_$$ is $code discrete_graph_op$$, -$code str_index_.size() == 1$$ and -$code str_index_[0]$$ is the index in -$cref/discrete_name_vec/cpp_ad_graph/discrete_name_vec/$$ -for the function called by this operator. - -$subhead print_graph_op$$ -If $icode op_enum_$$ is $code print_graph_op$$, -$code str_index_.size() == 2$$ and -$code str_index_[0]$$ ( $code str_index_[1]$$ ) -is the index in -$cref/print_text_vec/cpp_ad_graph/print_text_vec/$$ for the -$cref/before/PrintFor/before/$$ ($cref/after/PrintFor/after/$$) text. - -$head n_result_$$ -The input value of this argument does not matter. -This is set to the number of result nodes for this operator. - -$head arg_node_$$ -The input value of this argument does not matter. -Upon return, its size is the number of arguments, -that are node indices, for this operator usage. -The value of the elements are the node indices. - -$head Prototype$$ -$srccode%hpp% */ - void get_value(void) -/* %$$ -$end -*/ -{ // initialize output values - size_t invalid_index = std::numeric_limits::max(); - size_t n_arg = invalid_index; - first_node_ = invalid_index; - n_result_ = invalid_index; - str_index_.resize(0); - arg_node_.resize(0); - // - // op_enum - op_enum_ = (*operator_vec_)[op_index_]; - // - // n_result_, n_arg, str_index_ - switch( op_enum_ ) - { - // unary operators - case abs_graph_op: - case acos_graph_op: - case acosh_graph_op: - case asin_graph_op: - case asinh_graph_op: - case atan_graph_op: - case atanh_graph_op: - case cos_graph_op: - case cosh_graph_op: - case erf_graph_op: - case erfc_graph_op: - case exp_graph_op: - case expm1_graph_op: - case log1p_graph_op: - case log_graph_op: - case sign_graph_op: - case sin_graph_op: - case sinh_graph_op: - case sqrt_graph_op: - case tan_graph_op: - case tanh_graph_op: - first_node_ = first_arg_; - n_result_ = 1; - n_arg = 1; - break; - - // binary operators - case add_graph_op: - case azmul_graph_op: - case div_graph_op: - case mul_graph_op: - case pow_graph_op: - case sub_graph_op: - first_node_ = first_arg_; - n_result_ = 1; - n_arg = 2; - break; - - // discrete_graph_op - case discrete_graph_op: - first_node_ = first_arg_ + 1; - str_index_.push_back( (*operator_arg_)[first_node_ - 1] ); - n_result_ = 1; - n_arg = 1; - break; - - - // atom_graph_op - case atom_graph_op: - first_node_ = first_arg_ + 3; - str_index_.push_back( (*operator_arg_)[first_node_ - 3] ); - n_result_ = (*operator_arg_)[first_node_ - 2]; - n_arg = (*operator_arg_)[first_node_ - 1]; - break; - - // print_graph_op - case print_graph_op: - first_node_ = first_arg_ + 2; - str_index_.push_back( (*operator_arg_)[first_node_ - 2] ); - str_index_.push_back( (*operator_arg_)[first_node_ - 1] ); - n_result_ = 0; - n_arg = 2; - break; - - - // conditional expressions - case cexp_eq_graph_op: - case cexp_le_graph_op: - case cexp_lt_graph_op: - first_node_ = first_arg_; - n_result_ = 1; - n_arg = 4; - break; - - // comparison operators - case comp_eq_graph_op: - case comp_le_graph_op: - case comp_lt_graph_op: - case comp_ne_graph_op: - first_node_ = first_arg_; - n_result_ = 0; - n_arg = 2; - break; - - // sum_graph_op - case sum_graph_op: - first_node_ = first_arg_ + 1; - n_result_ = 1; - n_arg = (*operator_arg_)[first_node_ - 1]; - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - // set arg_node - arg_node_.resize(n_arg); - for(size_t i = 0; i < n_arg; i++) - arg_node_[i] = (*operator_arg_)[first_node_ + i]; - - return; -} -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cpp_graph_itr_types$$ -$spell - Iterator -$$ - -$section C++ AD Graph Iterator Types$$ - -$srccode%hpp% */ -public: - typedef struct { - graph_op_enum op_enum; - const vector* str_index_ptr; - size_t n_result; - const vector* arg_node_ptr; - } value_type; - typedef std::input_iterator_tag iterator_category; -/* %$$ -$end ------------------------------------------------------------------------------- -$begin cpp_graph_itr_ctor$$ -$spell - Iterator - itr - vec - arg - op - cpp -$$ - -$section C++ AD Graph Iterator Constructors$$ - -$head Syntax$$ -$codei%cpp_graph_itr %default% -%$$ -$codei%cpp_graph_itr %itr%(%operator_vec%, %operator_arg%, %op_index% -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_CTOR%// END_CTOR%1 -%$$ - -$head default$$ -The result of the default constructor can only be used as a target -for the assignment operator. - -$head operator_vec$$ -Is the $cref/operator_vec/cpp_ad_graph/operator_vec/$$ -for the $code cpp_graph$$ container that this iterator refers to. - -$head operator_arg$$ -Is the $cref/operator_arg/cpp_ad_graph/operator_vec/$$ -for the $code cpp_graph$$ container that this iterator refers to. - -$head op_index$$ -This must be either zero (the $code begin()$$ for the container) -or equal to the size of $icode operator_vec$$ -(the $code end()$$ for the container). - -$end -*/ - cpp_graph_itr(void) - : operator_vec_(nullptr), operator_arg_(nullptr) - { } - // BEGIN_CTOR - cpp_graph_itr( - const vector& operator_vec , - const vector& operator_arg , - size_t op_index ) - // END_CTOR - : - operator_vec_(&operator_vec) , - operator_arg_(&operator_arg) , - op_index_(op_index) - { // end constructor - if( op_index == operator_vec.size() ) - return; - // - // begin constructor - CPPAD_ASSERT_KNOWN( op_index == 0, - "cpp_graph_itr: constructor op_index not 0 or operator_vec.size()" - ); - // start at the beginning of operator_vec - first_arg_ = 0; - // - // get the value, and first_node_, for this operator - get_value(); - } -/* %$$ ------------------------------------------------------------------------------- -$begin cpp_graph_itr_input$$ -$spell - Iterator -$$ - -$section C++ AD Graph Iterator Input Operations$$ - -$srccode%hpp% */ - // itr == other - bool operator==(const cpp_graph_itr& other) const - { return op_index_ == other.op_index_; - } - // itr != other - bool operator!=(const cpp_graph_itr& other) const - { return op_index_ != other.op_index_; - } - // *itr - value_type operator*(void) - { CPPAD_ASSERT_KNOWN( operator_vec_ != nullptr, - "cpp_graph_itr: attempt to dereference default iterator" - ); - CPPAD_ASSERT_KNOWN( op_index_ < operator_vec_->size(), - "cpp_graph_itr: attempt to dereference past last element in graph" - ); - value_type ret; - ret.op_enum = op_enum_; - ret.str_index_ptr = &str_index_; - ret.n_result = n_result_; - ret.arg_node_ptr = &arg_node_; - return ret; - } - // ++itr - cpp_graph_itr& operator++(void) - { ++op_index_; - first_arg_ = first_node_ + arg_node_.size(); - get_value(); - return *this; - } - // itr++ - cpp_graph_itr operator++(int) - { cpp_graph_itr ret(*this); - ++op_index_; - first_arg_ = first_node_ + arg_node_.size(); - get_value(); - return ret; - } -/* %$$ -$end -*/ - -}; - -} } } // END_CPPAD_LOCAL_GRAPH_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/graph/cpp_graph_itr.omh b/build-config/cppad/include/cppad/local/graph/cpp_graph_itr.omh deleted file mode 100644 index ec6b64b6..00000000 --- a/build-config/cppad/include/cppad/local/graph/cpp_graph_itr.omh +++ /dev/null @@ -1,23 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ -$begin cpp_graph_itr$$ -$spell - Iterator -$$ - -$section C++ AD Graph Iterator Class$$ - -$childtable% - include/cppad/local/graph/cpp_graph_itr.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/local/graph/cpp_graph_op.hpp b/build-config/cppad/include/cppad/local/graph/cpp_graph_op.hpp deleted file mode 100644 index 0f278ed1..00000000 --- a/build-config/cppad/include/cppad/local/graph/cpp_graph_op.hpp +++ /dev/null @@ -1,94 +0,0 @@ -# ifndef CPPAD_LOCAL_GRAPH_CPP_GRAPH_OP_HPP -# define CPPAD_LOCAL_GRAPH_CPP_GRAPH_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ - -# include -# include -# include - -# include -# include -# include - -namespace CppAD { namespace local { namespace graph { -/* -$begin cpp_graph_op$$ -$spell - vec - asinh - acosh - atanh - erf - erfc - expm - namespace - enum - struct - op - arg - CppAD - addr_t -$$ - -$section C++ AD Graph Operators$$ - -$head Namespace$$ -All of these definitions -are in the $code CppAD::local::graph$$ namespace. - -$head CppAD::graph$$ -$srccode%hpp% */ - using namespace CppAD::graph; -/* %$$ - -$head addr_t$$ -$srccode%hpp% */ - typedef CPPAD_TAPE_ADDR_TYPE addr_t; -/* %$$ - -$head op_name2enum$$ -This is a mapping from the operator name to its enum value. -The name is the operator enum without the $code _operator$$ at the end. -$srccode%hpp% */ - extern std::map< std::string, graph_op_enum > op_name2enum; -/* %$$ - -$head op_enum2fixed_n_arg$$ -This is the number of arguments for the operators that have -a fixed number of arguments and one result. -For other operators, this value is zero. -$srccode%hpp% */ - extern size_t op_enum2fixed_n_arg[]; -/* %$$ - -$head op_enum2name$$ -This is mapping from operator enum value to its name. -In the $code local::graph$$ namespace: -$srccode%hpp% */ - extern const char* op_enum2name[]; -/* %$$ - -$head set_operator_info$$ -This routine sets the values in -$code op_enum2fixed_n_arg$$, -$code op_enum2name$$, and -$code op_name2enum$$. -$srccode%hpp% */ - extern void set_operator_info(void); -/* %$$ -$end -*/ - -} } } // END_CPPAD_LOCAL_GRAPH_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/graph/dev_graph.omh b/build-config/cppad/include/cppad/local/graph/dev_graph.omh deleted file mode 100644 index db7f8c77..00000000 --- a/build-config/cppad/include/cppad/local/graph/dev_graph.omh +++ /dev/null @@ -1,28 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------ -$begin dev_graph$$ -$spell - Json -$$ - -$section Developer AD Graph Documentation$$ - -$childtable% - include/cppad/local/graph/cpp_graph_itr.omh% - include/cppad/local/graph/cpp_graph_op.hpp% - include/cppad/local/graph/json_lexer.omh% - include/cppad/local/graph/json_parser.hpp% - include/cppad/local/graph/json_writer.hpp -%$$ - - -$end diff --git a/build-config/cppad/include/cppad/local/graph/json_lexer.hpp b/build-config/cppad/include/cppad/local/graph/json_lexer.hpp deleted file mode 100644 index 11873ce5..00000000 --- a/build-config/cppad/include/cppad/local/graph/json_lexer.hpp +++ /dev/null @@ -1,389 +0,0 @@ -# ifndef CPPAD_LOCAL_GRAPH_JSON_LEXER_HPP -# define CPPAD_LOCAL_GRAPH_JSON_LEXER_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ - -# include -# include - -// BEGIN_NAMESPACE_CPPAD_LOCAL_GRAPH -namespace CppAD { namespace local { namespace graph { - -// =========================================================================== -class json_lexer { -// =========================================================================== - -/* -------------------------------------------------------------------------------- -$begin json_lexer_member_data$$ -$spell - json - lexer -$$ - -$section json lexer: Private Data$$ - -$head graph_$$ -The $cref json_ad_graph$$. - -$head index_$$ -is the index in the graph for the current character. -If a token is returned, this corresponds to the last character -it the token. - -$head line_number_$$ -line number in the graph for the current character - -$head char_number_$$ -character number in the graph for the current character - -$head token_$$ -used to return tokens. - -$head function_name_$$ -is the function name for this graph. -This is initialized as empty, -should be set as soon as it is parsed, -and is used for error reporting. - -$head token$$ -returns current value of $code token_$$. - -$head line_number$$ -returns current value of $code line_number_$$ -(which corresponds to last character in the token). - -$head char_number$$ -returns current value of $code char_number_$$. -(which corresponds to last character in the token). - -$head set_function_name$$ -sets the value of $code function_name_$$. - -$head Source Code$$ -$srccode%hpp% */ -private: - const std::string& json_; - size_t index_; - size_t line_number_; - size_t char_number_; - std::string token_; - std::string function_name_; -public: - const std::string& token(void) const; - size_t line_number(void) const; - size_t char_number(void) const; - void set_function_name(const std::string& function_name); -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_report_error$$ -$spell - json - lexer - CppAD -$$ - -$section json lexer: Report an Error$$ - -$head Syntax$$ -$codei% - %json_lexer%.report_error(%expected%, %found%) -%$$ - -$head json_lexer$$ -is a $code local::graph::json_lexer$$ object. - -$head expected$$ -is the token that is expected. - -$head found$$ -is the token or text that was found. - -$head Report$$ -The current CppAD $cref ErrorHandler$$ is used to report -an error parsing this Json AD graph. - -$head Prototype$$ -$srccode%hpp% */ -public: - void report_error(const std::string& expected, const std::string& found); -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_next_index$$ -$spell - json - lexer -$$ - -$section json lexer: Advance Index by One$$ - -$head Syntax$$ -$codei% - %json_lexer%.next_index() -%$$ - -$head json_lexer$$ -is a $code local::graph::json_lexer$$ object. - -$head index_$$ -The input value of $code index_$$ is increased by one. -It is an error to call this routine when the input value -of $code index_$$ is greater than or equal $code json_.size()$$. - -$head line_number_$$ -If the previous character, before the call, was a new line, -$code line_number_$$ is increased by one. - -$head char_number_$$ -If the previous character, before the call, was a new line, -$code char_number$$ is set to one. -Otherwise, $code char_number_$$ is increased by one. - -$head Prototype$$ -$srccode%hpp% */ -private: - void next_index(void); -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_skip_white_space$$ -$spell - json - lexer -$$ - -$section json lexer: Skip White Space That Separates Tokens$$ - -$head Syntax$$ -$codei% - %json_lexer%.skip_white_space() -%$$ - -$head json_lexer$$ -is a json lexer object. - -$head Discussion$$ -This member functions is used to increase $code index_$$ until either -a non-white space character is found or $code index_$$ is equal -to $code json_.size()$$. - -$head Prototype$$ -$srccode%hpp% */ -private: - void skip_white_space(void); -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_constructor$$ -$spell - json - lexer - enum - op - arg -$$ - -$section json lexer: Constructor$$ - -$head Syntax$$ -$codei% - local::graph::lexer %json_lexer%(%json%) -%$$ - -$head json$$ -The argument $icode json$$ is an $cref json_ad_graph$$ -and it is assumed that $icode json$$ does not change -for as long as $icode json_lexer$$ exists. - -$head Initialization$$ -The current token, index, line number, and character number -are set to the first non white space character in $code json_$$. -If this is not a left brace character $code '{'$$, -the error is reported and the constructor does not return. - -$head Side Effect$$ -If $code local::graph::op_name2enum.size() == 0$$, -the routine $cref/set_operator_info/cpp_graph_op/set_operator_info/$$ -is called to initialize -$code op_enum2fixed_n_arg$$, -$code op_enum2name$$, and -$code op_name2enum$$. -This initialization cannot be done in -$cref/parallel mode/ta_in_parallel/$$. - -$head Prototype$$ -$srccode%hpp% */ -public: - json_lexer(const std::string& json); -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_check_next_char$$ -$spell - json - lexer - ch -$$ - -$section Get and Check Next Single Character Token$$ - -$head Syntax$$ -$codei% - %json_lexer%.check_next_char(%ch%) -%$$ - -$head index_$$ -The search for the character starts -at one greater than the input value for $code index_$$ and skips white space. - -$head ch$$ -Is a non white space -single character token that is expected. -If this character is not found, -the error is reported and this function does not return. -In the special case where $icode ch$$ is $code '\0'$$, -any non-white space character will be accepted -(but there must be such a character). - -$head token_$$ -If this routine returns, $code token_$$ has size one -and contains the character that is found. - - -$head Prototype$$ -$srccode%hpp% */ -public: - void check_next_char(char ch); -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_check_next_string$$ -$spell - json - lexer -$$ - -$section Get and Check Next Single Character Token$$ - -$head Syntax$$ -$codei% - %json_lexer%.check_next_string(%expected%) -%$$ - -$head index_$$ -The search for the string starts -at one greater than the input value for $code index_$$ and skips white space. - -$head expected$$ -Is the value (not including double quotes) for the string that is expected. -If this string is not found, the error is reported -and this function does not return. -In the special case where $icode expected$$ is empty, -any string will be accepted. - -$head token_$$ -If this routine returns, -$icode token_$$ is the string that was found. - - -$head Prototype$$ -$srccode%hpp% */ -public: - void check_next_string(const std::string& expected); -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_next_non_neg_int$$ -$spell - json - lexer - neg -$$ - -$section Get Next Non-Negative Integer$$ - -$head Syntax$$ -$codei% - %json_lexer%.next_non_neg_int() - %value% = %json_lexer%.token2size_t() -%$$ - -$head index_$$ -The search for the non-negative integer starts -at one greater than the input value for $code index_$$ and skips white space. - -$head token_$$ -is set to the non-negative integer. -If the next token is not a non-negative integer, -the error is reported and this function does not return. - -$head value$$ -If the current token is a non-negative integer, -$icode value$$ is the corresponding value. - -$head Prototype$$ -$srccode%hpp% */ -public: - void next_non_neg_int(void); - size_t token2size_t(void) const; - -/* %$$ -$end -------------------------------------------------------------------------------- -$begin json_lexer_next_float$$ -$spell - json - lexer -$$ - -$section Get Next Floating Point Number$$ - -$head Syntax$$ -$codei% - %ok% = %json_lexer%.next_float() - %value% = %json_lexer%.token2double() -%$$ - -$head index_$$ -The search for the floating point number starts -at one greater than the input value for $code index_$$ and skips white space. - -$head token_$$ -is set to the floating point number. -If the next token is not a floating point number, -the error is reported and this function does not return. - -$head value$$ -If the current token is a floating point number, -$icode value$$ is the corresponding value. - -$head Prototype$$ -$srccode%hpp% */ -public: - void next_float(void); - double token2double(void) const; - -/* %$$ -$end -*/ - -// ========================================================================== -}; // end class lexer -// ========================================================================== - - -} } } // END_NAMESPACE_CPPAD_LOCAL_GRAPH - - -# endif diff --git a/build-config/cppad/include/cppad/local/graph/json_lexer.omh b/build-config/cppad/include/cppad/local/graph/json_lexer.omh deleted file mode 100644 index 5d8cc410..00000000 --- a/build-config/cppad/include/cppad/local/graph/json_lexer.omh +++ /dev/null @@ -1,24 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------ -$begin json_lexer$$ -$spell - Json -$$ - -$section Lexical Analysis Class for a Json AD Graph$$. - -$childtable% - include/cppad/local/graph/json_lexer.hpp -%$$ - - -$end diff --git a/build-config/cppad/include/cppad/local/graph/json_parser.hpp b/build-config/cppad/include/cppad/local/graph/json_parser.hpp deleted file mode 100644 index 17bcc7c7..00000000 --- a/build-config/cppad/include/cppad/local/graph/json_parser.hpp +++ /dev/null @@ -1,55 +0,0 @@ -# ifndef CPPAD_LOCAL_GRAPH_JSON_PARSER_HPP -# define CPPAD_LOCAL_GRAPH_JSON_PARSER_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ - -# include -# include -# include -# include - -/* -$begin json_parser$$ -$spell - Json - CppAD - obj -$$ - -$section Json AD Graph Parser$$ - -$head Syntax$$ -$codei%json_parser(%json%, %graph_obj%)%$$ - -$head json$$ -The $cref json_ad_graph$$. - -$head graph_obj$$ -This is a $code cpp_graph$$ object. -The input value of the object does not matter. -Upon return it is a $cref cpp_ad_graph$$ representation of this function. - -$head Prototype$$ -$srccode%hpp% */ -namespace CppAD { namespace local { namespace graph { - void json_parser( - const std::string& json , - cpp_graph& graph_obj - ); -} } } -/* %$$ -$end -*/ - - -# endif diff --git a/build-config/cppad/include/cppad/local/graph/json_writer.hpp b/build-config/cppad/include/cppad/local/graph/json_writer.hpp deleted file mode 100644 index 36a4cb39..00000000 --- a/build-config/cppad/include/cppad/local/graph/json_writer.hpp +++ /dev/null @@ -1,54 +0,0 @@ -# ifndef CPPAD_LOCAL_GRAPH_JSON_WRITER_HPP -# define CPPAD_LOCAL_GRAPH_JSON_WRITER_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ - -# include -# include -# include -# include - -/* -$begin json_writer$$ -$spell - Json - CppAD - obj -$$ - -$section Json AD Graph Writer$$ - -$head Syntax$$ -$codei%json_writer( %json%, %graph_obj% )%$$ - -$head json$$ -The input value of $icode json$$ does not matter, -upon return it a $cref/json/json_ad_graph/$$ representation of the AD graph. - -$head graph_obj$$ -This is a $code cpp_graph$$ object. - -$head Prototype$$ -$srccode%hpp% */ -namespace CppAD { namespace local { namespace graph { - void json_writer( - std::string& json , - const cpp_graph& graph_obj - ); -} } } -/* %$$ -$end -*/ - - -# endif diff --git a/build-config/cppad/include/cppad/local/hash_code.hpp b/build-config/cppad/include/cppad/local/hash_code.hpp deleted file mode 100644 index 7812dd71..00000000 --- a/build-config/cppad/include/cppad/local/hash_code.hpp +++ /dev/null @@ -1,244 +0,0 @@ -# ifndef CPPAD_LOCAL_HASH_CODE_HPP -# define CPPAD_LOCAL_HASH_CODE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -/*! -\file local/hash_code.hpp -CppAD hashing utility. -*/ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_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 std::numeric_limits::max() >= CPPAD_HASH_TABLE_SIZE -\li sizeof(value) is even -\li sizeof(unsigned short) == 2 -*/ -template -unsigned short local_hash_code(const Value& value) -{ CPPAD_ASSERT_UNKNOWN( - std::numeric_limits::max() - >= - CPPAD_HASH_TABLE_SIZE - ); - CPPAD_ASSERT_UNKNOWN( sizeof(unsigned short) == 2 ); - CPPAD_ASSERT_UNKNOWN( sizeof(value) % 2 == 0 ); - // - const unsigned short* v - = reinterpret_cast(& value); - // - size_t i = sizeof(value) / 2 - 1; - // - size_t sum = v[i]; - // - while(i--) - sum += v[i]; - // - unsigned short code = static_cast( - sum % CPPAD_HASH_TABLE_SIZE - ); - return code; -} - -/*! -Specialized hash code for a CppAD operator and its arguments. - -\param op -is the operator that we are computing a hash code for. -If it is not one of the following operartors, the operator is not -hash coded and zero is returned: - -\li unary operators: -AbsOp, AcosOp, AcoshOp, AsinOp, AsinhOp, AtanOp, AtanhOp, CosOp, CoshOp -ExpOp, Expm1Op, LogOp, Log1pOp, SinOp, SinhOp, SqrtOp, TanOp, TanhOp - -\li binary operators where first argument is a parameter: -AddpvOp, DivpvOp, MulpvOp, PowpvOp, SubpvOp, ZmulpvOp - -\li binary operators where second argument is a parameter: -DivvpOp, PowvpOp, SubvpOp, Zmulvp - -\li binary operators where first is an index and second is a variable: -DisOp - -\li binary operators where both arguments are variables: -AddvvOp, DivvvOp, MulvvOp, PowvvOp, SubvvOp, ZmulvvOp - -\param arg -is a vector of length NumArg(op) or 2 (which ever is smaller), -containing the corresponding argument indices for this operator. - -\param npar -is the number of parameters corresponding to this operation sequence. - -\param par -is a vector of length npar containing the parameters -for this operation sequence; i.e., -given a parameter index of i, the corresponding parameter value is - par[i]. - - -\return -is a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1. - -\par Checked Assertions - op must be one of the operators specified above. In addition, -\li std::numeric_limits::max() >= CPPAD_HASH_TABLE_SIZE -\li sizeof(size_t) is even -\li sizeof(Base) is even -\li sizeof(unsigned short) == 2 -\li size_t(op) < size_t(NumberOp) <= CPPAD_HASH_TABLE_SIZE -\li if the j-th argument for this operation is a parameter, arg[j] < npar. -*/ - -template -unsigned short local_hash_code( - OpCode op , - const addr_t* arg , - size_t npar , - const Base* par ) -{ CPPAD_ASSERT_UNKNOWN( - std::numeric_limits::max() - >= - CPPAD_HASH_TABLE_SIZE - ); - CPPAD_ASSERT_UNKNOWN( size_t (op) < size_t(NumberOp) ); - CPPAD_ASSERT_UNKNOWN( sizeof(unsigned short) == 2 ); - CPPAD_ASSERT_UNKNOWN( sizeof(addr_t) % 2 == 0 ); - CPPAD_ASSERT_UNKNOWN( sizeof(Base) % 2 == 0 ); - unsigned short op_fac = static_cast ( - CPPAD_HASH_TABLE_SIZE / static_cast(NumberOp) - ); - CPPAD_ASSERT_UNKNOWN( op_fac > 0 ); - - // number of shorts per addr_t value - size_t short_addr_t = sizeof(addr_t) / 2; - - // initialize with value that separates operators as much as possible - unsigned short code = static_cast( - static_cast(op) * op_fac - ); - - // now code in the operands - size_t i; - const unsigned short* v; - - // first argument - switch(op) - { // Binary operators where first arugment is a parameter. - // Code parameters by value instead of - // by index for two reasons. One, it gives better separation. - // Two, different indices can be same parameter value. - case AddpvOp: - case DivpvOp: - case MulpvOp: - case PowpvOp: - case SubpvOp: - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - code += hash_code( par[arg[0]] ); - // - v = reinterpret_cast(arg + 1); - i = short_addr_t; - while(i--) - code += v[i]; - break; - - // Binary operator where first argument is an index and - // second is a variable (same as both variables). - case DisOp: - - // Binary operators where both arguments are variables - case AddvvOp: - case DivvvOp: - case MulvvOp: - case PowvvOp: - case SubvvOp: - case ZmulvvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - v = reinterpret_cast(arg + 0); - i = 2 * short_addr_t; - while(i--) - code += v[i]; - break; - - // Binary operators where second arugment is a parameter. - case DivvpOp: - case PowvpOp: - case SubvpOp: - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - v = reinterpret_cast(arg + 0); - i = short_addr_t; - while(i--) - code += v[i]; - code += hash_code( par[arg[1]] ); - break; - - // Unary operators - case AbsOp: - case AcosOp: - case AcoshOp: - case AsinOp: - case AsinhOp: - case AtanOp: - case AtanhOp: - case CosOp: - case CoshOp: - case ErfOp: - case ErfcOp: - case ExpOp: - case Expm1Op: - case LogOp: - case Log1pOp: - case SignOp: - case SinOp: - case SinhOp: - case SqrtOp: - case TanOp: - case TanhOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 || op == ErfOp ); - v = reinterpret_cast(arg + 0); - i = short_addr_t; - while(i--) - code += v[i]; - break; - - // should have been one of he cases above - default: - CPPAD_ASSERT_UNKNOWN(false); - } - - return code % CPPAD_HASH_TABLE_SIZE; -} - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/independent.hpp b/build-config/cppad/include/cppad/local/independent.hpp deleted file mode 100644 index b3bd82c8..00000000 --- a/build-config/cppad/include/cppad/local/independent.hpp +++ /dev/null @@ -1,119 +0,0 @@ -# ifndef CPPAD_LOCAL_INDEPENDENT_HPP -# define CPPAD_LOCAL_INDEPENDENT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* -\file local/independent.hpp -Start recording AD operations. -*/ - -/*! -Start recording AD operations: Implementation in local namespace. - -\tparam ADVector -This is simple vector type with elements of type AD. - -\param x -Vector of the independent variables. - -\param abort_op_index -operator index at which execution will be aborted (during the recording - -\param record_compare -should comparison operators be recorded. -of operations). The value zero corresponds to not aborting (will not match). - -\param dynamic -Vector of dynamic parameters. -*/ -template -template -void ADTape::Independent( - ADVector& x , - size_t abort_op_index , - bool record_compare , - ADVector& dynamic -) { - // check ADVector is Simple Vector class with AD elements - CheckSimpleVector< AD, ADVector>(); - - // dimension of the domain space - size_t n = x.size(); - CPPAD_ASSERT_KNOWN( - n > 0, - "Indepdendent: the argument vector x has zero size" - ); - CPPAD_ASSERT_UNKNOWN( Rec_.num_var_rec() == 0 ); - CPPAD_ASSERT_UNKNOWN( Rec_.get_abort_op_index() == 0 ); - CPPAD_ASSERT_UNKNOWN( Rec_.get_record_compare() == true ); - CPPAD_ASSERT_UNKNOWN( Rec_.get_num_dynamic_ind() == 0 ); - - // set record_compare and abort_op_index before doing anything else - Rec_.set_record_compare(record_compare); - Rec_.set_abort_op_index(abort_op_index); - Rec_.set_num_dynamic_ind( dynamic.size() ); - - // mark the beginning of the tape and skip the first variable index - // (zero) because parameters use taddr zero - CPPAD_ASSERT_NARG_NRES(BeginOp, 1, 1); - Rec_.PutOp(BeginOp); - Rec_.PutArg(0); - - // place each of the independent variables in the tape - CPPAD_ASSERT_NARG_NRES(InvOp, 0, 1); - for(size_t j = 0; j < n; j++) - { // tape address for this independent variable - CPPAD_ASSERT_UNKNOWN( ! Variable(x[j] ) ); - x[j].taddr_ = Rec_.PutOp(InvOp); - x[j].tape_id_ = id_; - x[j].ad_type_ = variable_enum; - CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == j+1 ); - CPPAD_ASSERT_UNKNOWN( Variable(x[j] ) ); - } - - // done specifying all of the independent variables - size_independent_ = n; - - // parameter index zero is used by dynamic parameter tape - // to indicate that an argument is a variable - Base nan = CppAD::numeric_limits::quiet_NaN(); -# ifndef NDEBUG - CPPAD_ASSERT_UNKNOWN( Rec_.put_con_par(nan) == 0 ); -# else - Rec_.put_con_par(nan); -# endif - - // Place independent dynamic parameters at beginning of parameter vector, - // just after the nan at index zero. - for(size_t j = 0; j < Rec_.get_num_dynamic_ind(); ++j) - { CPPAD_ASSERT_UNKNOWN( ! Dynamic( dynamic[j] ) ); - CPPAD_ASSERT_UNKNOWN( Parameter( dynamic[j] ) ); - // - // dynamic parameters are placed at the end, so i == j -# ifndef NDEBUG - addr_t i = Rec_.put_dyn_par(dynamic[j].value_ , ind_dyn); - CPPAD_ASSERT_UNKNOWN( size_t(i) == j+1 ); -# else - Rec_.put_dyn_par(dynamic[j].value_ , ind_dyn); -# endif - // - // make this parameter dynamic - dynamic[j].taddr_ = static_cast(j+1); - dynamic[j].tape_id_ = id_; - dynamic[j].ad_type_ = dynamic_enum; - CPPAD_ASSERT_UNKNOWN( Dynamic( dynamic[j] ) ); - } -} -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/is_pod.hpp b/build-config/cppad/include/cppad/local/is_pod.hpp deleted file mode 100644 index 68dbc2de..00000000 --- a/build-config/cppad/include/cppad/local/is_pod.hpp +++ /dev/null @@ -1,79 +0,0 @@ -# ifndef CPPAD_LOCAL_IS_POD_HPP -# define CPPAD_LOCAL_IS_POD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin is_pod$$ -$spell - nullptr - CppAD - namespace - bool - inline -$$ - -$section The is_pod Template Function$$ - -$head Default Definition$$ -The default template definition is that -$codei% - is_pod<%Type%>() -%$$ -is false for all types. - -$head Fundamental Types$$ -This file specializes $codei%is_pod<%Type%>%$$ to be true where $icode Type$$ -is any of the c++11 fundamental types that hold data; i.e., -$code void$$ and $code nullptr_t$$ are excluded. - -$head Other Type$$ -You can inform CppAD that a particular $icode Type$$ is plain old data by -defining -$codei% - namespace CppAD { namespace local { - template <> inline bool is_pod<%Type%>(void) { return true; } - } } -%$$ -$end -*/ -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE - // - template inline bool is_pod(void) { return false; } - // bool - template <> inline bool is_pod(void) {return true;} - // short - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - // int - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - // long - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - // long long - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - // Character types - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - // floating point types - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - template <> inline bool is_pod(void) {return true;} - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/is_pod.hpp.in b/build-config/cppad/include/cppad/local/is_pod.hpp.in deleted file mode 100644 index ea11fa84..00000000 --- a/build-config/cppad/include/cppad/local/is_pod.hpp.in +++ /dev/null @@ -1,41 +0,0 @@ -# ifndef CPPAD_LOCAL_IS_POD_HPP -# define CPPAD_LOCAL_IS_POD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -// make sure size_t is defined because autotools version of -// is_pod_specialize_98 uses it -# include - -/*! -\file is_pod.hpp -File that defines is_pod(void) -*/ -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -Is this type plain old data; i.e., its constructor need not be called. - -The default definition is false. This include file defines it as true -for all the fundamental types except for void and nullptr_t. -*/ -template bool is_pod(void) { return false; } -// The following command suppresses doxygen processing for the code below -/// \cond -// C++98 Fundamental types -@is_pod_specialize_98@ - -// C++11 Fundamental types -@is_pod_specialize_11@ - -/// \endcond -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/load_op.hpp b/build-config/cppad/include/cppad/local/load_op.hpp deleted file mode 100644 index b70dd411..00000000 --- a/build-config/cppad/include/cppad/local/load_op.hpp +++ /dev/null @@ -1,697 +0,0 @@ -# ifndef CPPAD_LOCAL_LOAD_OP_HPP -# define CPPAD_LOCAL_LOAD_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* - ------------------------------------------------------------------------------ -$begin load_op_var$$ -$spell - pv - Vec - op - var - isvar - ind - Taylor - arg - num - Addr - vecad -$$ -$section Accessing an Element in a Variable VecAD Vector$$ - -$head See Also$$ -$cref/op_code_var load/op_code_var/Load/$$. - -$head Syntax$$ -$codei%forward_load_%I%_op_0( - %play%, - %i_z%, - %arg%, - %parameter%, - %cap_order%, - %taylor%, - %vec_ad2isvar%, - %vec_ad2index%, - %load_op2var% -) -%$$ -where the index type $icode I$$ is $code p$$ (for parameter) -or $code v$$ (for variable). - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_FORWARD_LOAD_P_OP_0%// END_FORWARD_LOAD_P_OP_0%1 -%$$ -The prototype for $code forward_load_v_op_0$$ is the same -except for the function name. - -$head Notation$$ - -$subhead v$$ -We use $icode v$$ to denote the $cref VecAD$$ vector for this operation. - -$subhead x$$ -We use $icode x$$ to denote the $codei%AD%<%Base%>%$$ -index for this operation. - -$subhead i_vec$$ -We use $icode i_vec$$ to denote the $code size_t$$ value -corresponding to $icode x$$. - -$subhead n_load$$ -This is the number of load instructions in this recording; i.e., -$icode%play%->num_var_load_rec()%$$. - -$subhead n_all$$ -This is the number of values in the single array that includes -all the vectors together with the size of each vector; i.e., -$icode%play%->num_var_vecad_ind_rec()%$$. - -$head Addr$$ -Is the type used for address on this tape. - -$head Base$$ -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type Base. - -$head play$$ -is the tape that this operation appears in. -This is for error detection and not used when NDEBUG is defined. - -$head i_z$$ -is the AD variable index corresponding to the result of this load operation. - -$head arg$$ - -$subhead arg[0]$$ -is the offset of this VecAD vector relative to the beginning -of the $icode vec_ad2isvar$$ and $icode vec_ad2index$$ arrays. - -$subhead arg[1]$$ -If this is -$code forward_load_p_op_0$$ ($code forward_load_v_op_0$$) -$icode%arg%[%1%]%$$ is the parameter index (variable index) -corresponding to $cref/i_vec/load_op_var/Notation/i_vec/$$. - -$subhead arg[2]$$ -Is the index of this VecAD load instruction in the -$icode load_op2var$$ array. - -$head parameter$$ -This is the vector of parameters for this recording which has size -$icode%play%->num_par_rec()%$$. - -$head cap_order$$ -number of columns in the matrix containing the Taylor coefficients. - -$head taylor$$ -Is the matrix of Taylor coefficients. - -$subhead Input$$ -In the $code forward_load_v_op_0$$ case, -$codei% - size_t( %taylor%[ %arg%[1]% * %cap_order% + 0 ] ) -%$$ -is the index in this VecAD vector. - -$subhead Output$$ -$icode%taylor%[ %i_z% * %cap_order% + 0 ]%$$ -is set to the zero order Taylor coefficient for the result of this operator. - -$head vec_ad2isvar$$ -This vector has size $icode n_all$$. -If $icode%vec_ad2isvar%[ %arg%[%0%] + %i_vec% ]%$$ is false (true), -the vector element is parameter (variable). - -$subhead i_pv$$ -If this element is a parameter (variable), -$codei% - %i_pv% = %vec_ad2index%[ %arg%[%0%] + %i_vec% ] -%$$ -is the corresponding parameter (variable) index; - -$head vec_ad2index$$ -This array has size $icode n_all$$ -The value $icode%vec_ad2index%[ %arg%[0] - 1 ]%$$ -is the number of elements in the user vector containing this load. -$icode%vec_ad2index%[%i_pv%]%$$ is the variable or -parameter index for this element, - -$head load_op2var$$ -is a vector with size $icode n_load$$. -The input value of its elements does not matter. -If the result of this load is a variable, -$codei% - %load_op2var%[%arg%[2]] = %i_pv% -%$$ -Otherwise, -$codei% - %load_op2var%[%arg%[2]] = 0 -%$$ - -$end -*/ -// BEGIN_FORWARD_LOAD_P_OP_0 -template -void forward_load_p_op_0( - const local::player* play , - size_t i_z , - const Addr* arg , - const Base* parameter , - size_t cap_order , - Base* taylor , - const bool* vec_ad2isvar , - const size_t* vec_ad2index , - Addr* load_op2var ) -// END_FORWARD_LOAD_P_OP_0 -{ CPPAD_ASSERT_UNKNOWN( NumArg(LdpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LdpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < play->num_par_rec() ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < play->num_var_load_rec() ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - addr_t i_vec = addr_t( Integer( parameter[ arg[1] ] ) ); - CPPAD_ASSERT_KNOWN( - size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] , - "VecAD: dynamic parmaeter index out or range during zero order forward" - ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0] + i_vec) < play->num_var_vecad_ind_rec() ); - - size_t i_pv = vec_ad2index[ arg[0] + i_vec ]; - Base* z = taylor + i_z * cap_order; - if( vec_ad2isvar[ arg[0] + i_vec ] ) - { CPPAD_ASSERT_UNKNOWN( i_pv < i_z ); - load_op2var[ arg[2] ] = addr_t( i_pv ); - Base* v_x = taylor + i_pv * cap_order; - z[0] = v_x[0]; - } - else - { CPPAD_ASSERT_UNKNOWN( i_pv < play->num_par_rec() ); - load_op2var[ arg[2] ] = 0; - Base v_x = parameter[i_pv]; - z[0] = v_x; - } -} -template -void forward_load_v_op_0( - const local::player* play , - size_t i_z , - const Addr* arg , - const Base* parameter , - size_t cap_order , - Base* taylor , - const bool* vec_ad2isvar , - const size_t* vec_ad2index , - Addr* load_op2var ) -{ CPPAD_ASSERT_UNKNOWN( NumArg(LdvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LdvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < play->num_var_load_rec() ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - addr_t i_vec = addr_t(Integer(taylor[ size_t(arg[1]) * cap_order + 0 ] )); - CPPAD_ASSERT_KNOWN( - size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] , - "VecAD: variable index out or range during zero order forward" - ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0] + i_vec) < play->num_var_vecad_ind_rec() ); - - size_t i_pv = vec_ad2index[ arg[0] + i_vec ]; - Base* z = taylor + i_z * cap_order; - if( vec_ad2isvar[ arg[0] + i_vec ] ) - { CPPAD_ASSERT_UNKNOWN( i_pv < i_z ); - load_op2var[ arg[2] ] = addr_t( i_pv ); - Base* v_x = taylor + i_pv * cap_order; - z[0] = v_x[0]; - } - else - { CPPAD_ASSERT_UNKNOWN( i_pv < play->num_par_rec() ); - load_op2var[ arg[2] ] = 0; - Base v_x = parameter[i_pv]; - z[0] = v_x; - } -} -/*! ------------------------------------------------------------------------------- -Shared documentation for sparsity operations corresponding to -op = LdpOp or LdvOp (not called). - - -The C++ source code corresponding to this operation is -\verbatim - v[x] = y -\endverbatim -where v is a VecAD vector, x is an AD object, -and y is AD or Base objects. -We define the index corresponding to v[x] by -\verbatim - i_pv = vec_ad2index[ arg[0] + i_vec ] -\endverbatim -where i_vec is defined under the heading arg[1] below: - - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param op -is the code corresponding to this operator; -i.e., LdpOp or LdvOp. - -\param i_z -is the AD variable index corresponding to the variable z; i.e., -the set with index i_z in var_sparsity is the sparsity pattern -corresponding to z. - -\param arg -\n - arg[0] -is the offset corresponding to this VecAD vector in the VecAD combined array. - -\param num_combined -is the total number of elements in the VecAD combinded array. - -\param combined -is the VecAD combined array. -\n -\n - combined[ arg[0] - 1 ] -is the index of the set corresponding to the vector v in vecad_sparsity. -We use the notation i_v for this value; i.e., -\verbatim - i_v = combined[ arg[0] - 1 ] -\endverbatim - -\param var_sparsity -The set with index i_z in var_sparsity is the sparsity pattern for z. -This is an output for forward mode operations, -and an input for reverse mode operations. - -\param vecad_sparsity -The set with index i_v is the sparsity pattern for the vector v. -This is an input for forward mode operations. -For reverse mode operations, -the sparsity pattern for z is added to the sparsity pattern for v. - -\par Checked Assertions -\li NumArg(op) == 3 -\li NumRes(op) == 1 -\li 0 < arg[0] -\li arg[0] < num_combined -\li i_v < vecad_sparsity.n_set() -*/ -template -void sparse_load_op( - OpCode op , - size_t i_z , - const Addr* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - - - -/*! -Forward mode, except for zero order, for op = LdpOp or op = LdvOp - - - -The C++ source code corresponding to this operation is -\verbatim - v[x] = y -\endverbatim -where v is a VecAD vector, x is an AD object, -and y is AD or Base objects. -We define the index corresponding to v[x] by -\verbatim - i_pv = vec_ad2index[ arg[0] + i_vec ] -\endverbatim -where i_vec is defined under the heading arg[1] below: - - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type Base. - -\param play -is the tape that this operation appears in. -This is for error detection and not used when NDEBUG is defined. - -\param op -is the code corresponding to this operator; i.e., LdpOp or LdvOp -(only used for error checking). - -\param p -is the lowest order of the Taylor coefficient that we are computing. - -\param q -is the highest order of the Taylor coefficient that we are computing. - -\param r -is the number of directions for the Taylor coefficients that we -are computing. - -\param cap_order -number of columns in the matrix containing the Taylor coefficients. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg -arg[2] -Is the index of this vecad load instruction in the load_op2var array. - -\param load_op2var -is a vector with size play->num_var_load_rec(). -It contains the variable index corresponding to each load instruction. -In the case where the index is zero, -the instruction corresponds to a parameter (not variable). - -\par i_var -We use the notation -\verbatim - i_var = size_t( load_op2var[ arg[2] ] ) -\endverbatim - -\param taylor -\n -Input -\n -If i_var > 0, v[x] is a variable and -for k = 1 , ... , q -taylor[ i_var * tpv + (k-1)*r+1+ell ] -is the k-th order coefficient for v[x] in the ell-th direction, -\n -\n -Output -\n -for k = p , ... , q, -taylor[ i_z * tpv + (k-1)*r+1+ell ] -is set to the k-order Taylor coefficient for z in the ell-th direction. -*/ -template -void forward_load_op( - const local::player* play, - OpCode op , - size_t p , - size_t q , - size_t r , - size_t cap_order , - size_t i_z , - const Addr* arg , - const Addr* load_op2var , - Base* taylor ) -{ - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( 0 < r); - CPPAD_ASSERT_UNKNOWN( 0 < p); - CPPAD_ASSERT_UNKNOWN( p <= q ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < play->num_var_load_rec() ); - - size_t i_var = size_t( load_op2var[ arg[2] ] ); - CPPAD_ASSERT_UNKNOWN( i_var < i_z ); - - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* z = taylor + i_z * num_taylor_per_var; - if( i_var > 0 ) - { Base* v_x = taylor + i_var * num_taylor_per_var; - for(size_t ell = 0; ell < r; ell++) - { for(size_t k = p; k <= q; k++) - { size_t m = (k-1) * r + 1 + ell; - z[m] = v_x[m]; - } - } - } - else - { for(size_t ell = 0; ell < r; ell++) - { for(size_t k = p; k <= q; k++) - { size_t m = (k-1) * r + 1 + ell; - z[m] = Base(0.0); - } - } - } -} - -/*! -Reverse mode for op = LdpOp or LdvOp. - - -The C++ source code corresponding to this operation is -\verbatim - v[x] = y -\endverbatim -where v is a VecAD vector, x is an AD object, -and y is AD or Base objects. -We define the index corresponding to v[x] by -\verbatim - i_pv = vec_ad2index[ arg[0] + i_vec ] -\endverbatim -where i_vec is defined under the heading arg[1] below: - - -This routine is given the partial derivatives of a function -G(z , y[x] , w , u ... ) -and it uses them to compute the partial derivatives of -\verbatim - H( y[x] , w , u , ... ) = G[ z( y[x] ) , y[x] , w , u , ... ] -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param op -is the code corresponding to this operator; i.e., LdpOp or LdvOp -(only used for error checking). - -\param d -highest order the Taylor coefficient that we are computing the partial -derivative with respect to. - -\param i_z -is the AD variable index corresponding to the variable z. - -\param arg - arg[2] -Is the index of this vecad load instruction in the -load_op2var array. - -\param cap_order -number of columns in the matrix containing the Taylor coefficients -(not used). - -\param taylor -matrix of Taylor coefficients (not used). - -\param nc_partial -number of colums in the matrix containing all the partial derivatives -(not used if arg[2] is zero). - -\param partial -If arg[2] is zero, y[x] is a parameter -and no values need to be modified; i.e., partial is not used. -Otherwise, y[x] is a variable and: -\n -\n - partial [ i_z * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G -with respect to the k-th order Taylor coefficient for z. -\n -\n -If arg[2] is not zero, - partial [ arg[2] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative with respect to -the k-th order Taylor coefficient for x. -On input, it corresponds to the function G, -and on output it corresponds to the the function H. - -\param load_op2var -is a vector with size play->num_var_load_rec(). -It contains the variable index corresponding to each load instruction. -In the case where the index is zero, -the instruction corresponds to a parameter (not variable). - -\par Checked Assertions -\li NumArg(op) == 3 -\li NumRes(op) == 1 -\li d < cap_order -\li size_t(arg[2]) < i_z -*/ -template -void reverse_load_op( - OpCode op , - size_t d , - size_t i_z , - const Addr* arg , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial , - const Addr* load_op2var ) -{ size_t i_load = size_t( load_op2var[ arg[2] ] ); - - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( i_load < i_z ); - - if( i_load > 0 ) - { - Base* pz = partial + i_z * nc_partial; - Base* py_x = partial + i_load * nc_partial; - size_t j = d + 1; - while(j--) - py_x[j] += pz[j]; - } -} - - -/*! -Forward mode sparsity operations for LdpOp and LdvOp - -\param dependency -is this a dependency (or sparsity) calculation. - -\copydetails CppAD::local::sparse_load_op -*/ -template -void forward_sparse_load_op( - bool dependency , - OpCode op , - size_t i_z , - const Addr* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity ) -{ - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); - size_t i_v = combined[ arg[0] - 1 ]; - CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); - - var_sparsity.assignment(i_z, i_v, vecad_sparsity); - if( dependency & (op == LdvOp) ) - var_sparsity.binary_union(i_z, i_z, size_t(arg[1]), var_sparsity); - - return; -} - - -/*! -Reverse mode Jacobian sparsity operations for LdpOp and LdvOp - -\param dependency -is this a dependency (or sparsity) calculation. - -\copydetails CppAD::local::sparse_load_op -*/ -template -void reverse_sparse_jacobian_load_op( - bool dependency , - OpCode op , - size_t i_z , - const Addr* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity ) -{ - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); - size_t i_v = combined[ arg[0] - 1 ]; - CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); - - vecad_sparsity.binary_union(i_v, i_v, i_z, var_sparsity); - if( dependency & (op == LdvOp) ) - var_sparsity.binary_union( size_t(arg[1]), size_t(arg[1]), i_z, var_sparsity); - - return; -} - - -/*! -Reverse mode Hessian sparsity operations for LdpOp and LdvOp - -\copydetails CppAD::local::sparse_load_op - -\param var_jacobian - var_jacobian[i_z] -is false (true) if the Jacobian of G with respect to z is always zero -(many be non-zero). - -\param vecad_jacobian - vecad_jacobian[i_v] -is false (true) if the Jacobian with respect to x is always zero -(may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. - -*/ -template -void reverse_sparse_hessian_load_op( - OpCode op , - size_t i_z , - const Addr* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity , - bool* var_jacobian , - bool* vecad_jacobian ) -{ - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); - size_t i_v = combined[ arg[0] - 1 ]; - CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); - - vecad_sparsity.binary_union(i_v, i_v, i_z, var_sparsity); - - vecad_jacobian[i_v] |= var_jacobian[i_z]; - - return; -} - - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/log1p_op.hpp b/build-config/cppad/include/cppad/local/log1p_op.hpp deleted file mode 100644 index fba31a25..00000000 --- a/build-config/cppad/include/cppad/local/log1p_op.hpp +++ /dev/null @@ -1,203 +0,0 @@ -# ifndef CPPAD_LOCAL_LOG1P_OP_HPP -# define CPPAD_LOCAL_LOG1P_OP_HPP - -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file log1p_op.hpp -Forward and reverse mode calculations for z = log1p(x). -*/ - -/*! -Compute forward mode Taylor coefficient for result of op = Log1pOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log1p(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op -*/ -template -void forward_log1p_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - size_t k; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - if( p == 0 ) - { z[0] = log1p( x[0] ); - p++; - if( q == 0 ) - return; - } - if ( p == 1 ) - { z[1] = x[1] / (Base(1.0) + x[0]); - p++; - } - for(size_t j = p; j <= q; j++) - { - z[j] = -z[1] * x[j-1]; - for(k = 2; k < j; k++) - z[j] -= Base(double(k)) * z[k] * x[j-k]; - z[j] /= Base(double(j)); - z[j] += x[j]; - z[j] /= (Base(1.0) + x[0]); - } -} - -/*! -Muiltiple directions Taylor coefficient for op = Log1pOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log1p(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_dir -*/ -template -void forward_log1p_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = Base(double(q)) * x[m+ell]; - for(size_t k = 1; k < q; k++) - z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - z[m+ell] /= (Base(double(q)) + Base(q) * x[0]); - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = Log1pOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log1p(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_0 -*/ -template -void forward_log1p_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = log1p( x[0] ); -} - -/*! -Compute reverse mode partial derivatives for result of op = Log1pOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log1p(x) -\endverbatim - -\copydetails CppAD::local::reverse_unary1_op -*/ - -template -void reverse_log1p_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ size_t j, k; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - Base inv_1px0 = Base(1.0) / (Base(1) + x[0]); - - j = d; - while(j) - { // scale partial w.r.t z[j] - pz[j] = azmul(pz[j] , inv_1px0); - - px[0] -= azmul(pz[j], z[j]); - px[j] += pz[j]; - - // further scale partial w.r.t. z[j] - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { pz[k] -= Base(double(k)) * azmul(pz[j], x[j-k]); - px[j-k] -= Base(double(k)) * azmul(pz[j], z[k]); - } - --j; - } - px[0] += azmul(pz[0], inv_1px0); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/log_op.hpp b/build-config/cppad/include/cppad/local/log_op.hpp deleted file mode 100644 index 937062c5..00000000 --- a/build-config/cppad/include/cppad/local/log_op.hpp +++ /dev/null @@ -1,202 +0,0 @@ -# ifndef CPPAD_LOCAL_LOG_OP_HPP -# define CPPAD_LOCAL_LOG_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file log_op.hpp -Forward and reverse mode calculations for z = log(x). -*/ - -/*! -Compute forward mode Taylor coefficient for result of op = LogOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op -*/ -template -void forward_log_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - size_t k; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - if( p == 0 ) - { z[0] = log( x[0] ); - p++; - if( q == 0 ) - return; - } - if ( p == 1 ) - { z[1] = x[1] / x[0]; - p++; - } - for(size_t j = p; j <= q; j++) - { - z[j] = -z[1] * x[j-1]; - for(k = 2; k < j; k++) - z[j] -= Base(double(k)) * z[k] * x[j-k]; - z[j] /= Base(double(j)); - z[j] += x[j]; - z[j] /= x[0]; - } -} - -/*! -Muiltiple directions Taylor coefficient for op = LogOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_dir -*/ -template -void forward_log_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = Base(double(q)) * x[m+ell]; - for(size_t k = 1; k < q; k++) - z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell]; - z[m+ell] /= (Base(double(q)) * x[0]); - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = LogOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_0 -*/ -template -void forward_log_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = log( x[0] ); -} - -/*! -Compute reverse mode partial derivatives for result of op = LogOp. - -The C++ source code corresponding to this operation is -\verbatim - z = log(x) -\endverbatim - -\copydetails CppAD::local::reverse_unary1_op -*/ - -template -void reverse_log_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ size_t j, k; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - Base inv_x0 = Base(1.0) / x[0]; - - j = d; - while(j) - { // scale partial w.r.t z[j] - pz[j] = azmul(pz[j] , inv_x0); - - px[0] -= azmul(pz[j], z[j]); - px[j] += pz[j]; - - // further scale partial w.r.t. z[j] - pz[j] /= Base(double(j)); - - for(k = 1; k < j; k++) - { pz[k] -= Base(double(k)) * azmul(pz[j], x[j-k]); - px[j-k] -= Base(double(k)) * azmul(pz[j], z[k]); - } - --j; - } - px[0] += azmul(pz[0], inv_x0); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/mul_op.hpp b/build-config/cppad/include/cppad/local/mul_op.hpp deleted file mode 100644 index d7fe1512..00000000 --- a/build-config/cppad/include/cppad/local/mul_op.hpp +++ /dev/null @@ -1,359 +0,0 @@ -# ifndef CPPAD_LOCAL_MUL_OP_HPP -# define CPPAD_LOCAL_MUL_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file mul_op.hpp -Forward and reverse mode calculations for z = x * y. -*/ - -// --------------------------- Mulvv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = MulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_mulvv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - size_t k; - for(size_t d = p; d <= q; d++) - { z[d] = Base(0.0); - for(k = 0; k <= d; k++) - z[d] += x[d-k] * y[k]; - } -} -/*! -Multiple directions forward mode Taylor coefficients for op = MulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_mulvv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t k, ell, m; - for(ell = 0; ell < r; ell++) - { m = (q-1)*r + ell + 1; - z[m] = x[0] * y[m] + x[m] * y[0]; - for(k = 1; k < q; k++) - z[m] += x[(q-k-1)*r + ell + 1] * y[(k-1)*r + ell + 1]; - } -} - -/*! -Compute zero order forward mode Taylor coefficients for result of op = MulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_mulvv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x[0] * y[0]; -} - -/*! -Compute reverse mode partial derivatives for result of op = MulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_mulvv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Arguments - const Base* x = taylor + size_t(arg[0]) * cap_order; - const Base* y = taylor + size_t(arg[1]) * cap_order; - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - - // number of indices to access - size_t j = d + 1; - size_t k; - while(j) - { --j; - for(k = 0; k <= j; k++) - { - px[j-k] += azmul(pz[j], y[k]); - py[k] += azmul(pz[j], x[j-k]); - } - } -} -// --------------------------- Mulpv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = MulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_mulpv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - // Paraemter value - Base x = parameter[ arg[0] ]; - - for(size_t d = p; d <= q; d++) - z[d] = x * y[d]; -} -/*! -Multiple directions forward mode Taylor coefficients for op = MulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_mulpv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q-1) * r + 1; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m; - Base* z = taylor + i_z * num_taylor_per_var + m; - - // Paraemter value - Base x = parameter[ arg[0] ]; - - for(size_t ell = 0; ell < r; ell++) - z[ell] = x * y[ell]; -} -/*! -Compute zero order forward mode Taylor coefficient for result of op = MulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_mulpv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); - - // Paraemter value - Base x = parameter[ arg[0] ]; - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x * y[0]; -} - -/*! -Compute reverse mode partial derivative for result of op = MulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x * y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_mulpv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Arguments - Base x = parameter[ arg[0] ]; - - // Partial derivatives corresponding to arguments and result - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t j = d + 1; - while(j) - { --j; - py[j] += azmul(pz[j], x); - } -} - - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/op.hpp b/build-config/cppad/include/cppad/local/op.hpp deleted file mode 100644 index fbed5728..00000000 --- a/build-config/cppad/include/cppad/local/op.hpp +++ /dev/null @@ -1,59 +0,0 @@ -# ifndef CPPAD_LOCAL_OP_HPP -# define CPPAD_LOCAL_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// used by the sparse operators -# include - -// operations -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - - -# endif diff --git a/build-config/cppad/include/cppad/local/op_code_dyn.hpp b/build-config/cppad/include/cppad/local/op_code_dyn.hpp deleted file mode 100644 index 195d72ff..00000000 --- a/build-config/cppad/include/cppad/local/op_code_dyn.hpp +++ /dev/null @@ -1,439 +0,0 @@ -# ifndef CPPAD_LOCAL_OP_CODE_DYN_HPP -# define CPPAD_LOCAL_OP_CODE_DYN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -$begin op_code_dyn$$ -$spell - vec - Op - dyn - arg - hpp - cond_exp - ind - zmul - Namespace - enum - CppAD -$$ - -$section Dynamic Parameter Op Codes$$ - -$head Namespace$$ -The $code op_code_dyn$$ enum type is in the $code CppAD::local$$ namespace. - -$head AD Type$$ -All the operators below have no variable arguments, -at least one dynamic parameter argument, -and at most one constant argument; see -$cref ad_type_enum$$. -For example, all the unary operators have one dynamic parameter argument -and one dynamic parameter result. - -$head Unary$$ -The number of arguments for a unary operator is one -and it is a parameter index. -All the unary operators have one result that is a dynamic parameter. - -$head Binary$$ -The number of arguments for a binary operator is two -and they are parameter indices. -All the binary operators have one result that is a dynamic parameter. -For binary operators the first argument is the left operand -and the second is the right operand. - -$subhead zmul_dyn$$ -This binary operator has a non-standard name; see $cref azmul$$ for -its definition. - -$head ind_dyn$$ -This is an independent dynamic parameter operator. -It has no arguments and one result which is the value of the corresponding -independent dynamic parameter in the call to $cref new_dynamic$$. - -$comment ----------------------------------------------------------------- $$ -$head atom_dyn$$ -This operator is a call to an atomic function. -The number of arguments to this operator is -$icode%arg%[4+%n%+%m%]%$$; see below. - -$subhead arg[0]$$ -This is the index that identifies this atomic function; see -$code local/atomic_index.hpp$$. - -$subhead arg[1]$$ -This is the number of arguments to this atomic function. -We use the notation $icode%n% = %arg%[1]%$$ below. - -$subhead arg[2]$$ -This is the number of results for this atomic function. -We use the notation $icode%m% = %arg%[2]%$$ below. - -$subhead arg[3]$$ -This is the number of result values that are dynamic parameters -for this function call. - -$subhead arg[4+j]$$ -For $icode%j% = 0 , %...% , %n%-1%$$, -this is the parameter index for the $th j$$ argument to this atomic -function call. - -$subhead arg[4+n+i]$$ -For $icode%i% = 0 , %...% , %m%-1%$$, -this is the parameter index for the $th i$$ result to this atomic -function call. - -$subhead arg[4+n+m]$$ -This is the number of arguments to this operator; i.e., -$codei%5+%n%+%m%$$. - -$head result_dyn$$ -This is a place holder for a result of an atomic function call -that is a dynamic parameter. -It has no arguments, no results, and is only there so that the -number of dynamic parameters and the number of dynamic operators are equal. - -$comment ----------------------------------------------------------------- $$ -$head cond_exp_dyn$$ -This is a conditional expression operator and has five arguments -and one result. - -$subhead arg[0]$$ -This is the -$cref/CompareOp/base_cond_exp/CompareOp/$$ value for this operator. - -$subhead arg[1]$$ -This is the parameter index for the left operand to the comparison. - -$subhead arg[2]$$ -This is the parameter index for the right operand to the comparison. - -$subhead arg[3]$$ -This is the index of the parameter equal to the operator result if -the comparison result is true. - -$subhead arg[4]$$ -This is the index of the parameter equal to the operator result if -the comparison result is false. - -$comment ----------------------------------------------------------------- $$ -$head dis_dyn$$ -This is a call to a discrete function. -The discrete function has one argument and one result. -This operator has two arguments and one result. -It is not a binary operator because the first argument -is not the index of a parameter. - -$subhead arg[0]$$ -Is the discrete function index which depends on the $icode Base$$ -type used when this function was recorded. - -$subhead arg[1]$$ -Is the parameter index for the argument to the function. - -$comment ----------------------------------------------------------------- $$ -$head Source$$ -$srcthisfile% - 0%// BEGIN_OP_CODE_DYN%// END_OP_CODE_DYN%1 -%$$ -$end -*/ - -// BEGIN_SORT_THIS_LINE_PLUS_3 -// BEGIN_OP_CODE_DYN -enum op_code_dyn { - abs_dyn, // unary - acos_dyn, // unary - acosh_dyn, // unary - add_dyn, // binary - asin_dyn, // unary - asinh_dyn, // unary - atan_dyn, // unary - atanh_dyn, // unary - atom_dyn, // ? arguments: atomic function call - cond_exp_dyn, // 5 arguments: conditional expression - cos_dyn, // unary - cosh_dyn, // unary - dis_dyn, // 2 arguments: discrete function - div_dyn, // binary - erfc_dyn, // unary - erf_dyn, // unary - exp_dyn, // unary - expm1_dyn, // unary - fabs_dyn, // unary - ind_dyn, // 0 arguments: independent parameter - log1p_dyn, // unary - log_dyn, // unary - mul_dyn, // binary - pow_dyn, // binary - result_dyn, // 0 arguments: atomic function result - sign_dyn, // unary - sin_dyn, // unary - sinh_dyn, // unary - sqrt_dyn, // unary - sub_dyn, // binary - tan_dyn, // unary - tanh_dyn, // unary - zmul_dyn, // binary - number_dyn // number of operator codes and invalid operator value -}; -// END_OP_CODE_DYN -// END_SORT_THIS_LINE_MINUS_4 - -/* -$begin num_arg_dyn$$ -$spell - num_arg_dyn - op - enum -$$ - -$section Number of Arguments to a Dynamic Parameter Operator$$ - -$head Syntax$$ -$icode%n_arg% = local::num_arg_dyn(%op%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_NUM_ARG_DYN_PROTOTYPE%// END_NUM_ARG_DYN_PROTOTYPE%1 -%$$ - -$head Parallel Mode$$ -This routine has static data so its first call cannot be in Parallel mode. - -$head op$$ -is the operator in question. - -$head n_arg$$ -The return value is the number of arguments as commented in the -$cref/source/op_code_dyn/Source/$$ for $code enum op_code_dyn$$. -There is one exception: if $icode op$$ is $code atom_dyn$$, -$icode n_arg$$ is zero; see $cref/atom_dyn/op_code_dyn/atom_dyn/$$ -for the true number of arguments in this case. - -$head atom_dyn$$ -All of the dynamic parameter operators have a fixed number of arguments -except for the $cref/atom_dyn/op_code_dyn/atom_dyn/$$ -operator which calls an atomic functions. -In this special case the return value $icode n_arg$$ is zero -which is not correct. - -$end -*/ -// BEGIN_NUM_ARG_DYN_PROTOTYPE -inline size_t num_arg_dyn(op_code_dyn op) -// END_NUM_ARG_DYN_PROTOTYPE -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - // BEGIN_SORT_THIS_LINE_PLUS_2 - static const size_t num_arg_table[] = { - /* abs_dyn */ 1, - /* acos_dyn */ 1, - /* acosh_dyn */ 1, - /* add_dyn */ 2, - /* asin_dyn */ 1, - /* asinh_dyn */ 1, - /* atan_dyn */ 1, - /* atanh_dyn */ 1, - /* atom_dyn */ 0, - /* cond_exp_dyn */ 5, - /* cos_dyn */ 1, - /* cosh_dyn */ 1, - /* dis_dyn */ 2, - /* div_dyn */ 2, - /* erfc_dyn */ 1, - /* erf_dyn */ 1, - /* exp_dyn */ 1, - /* expm1_dyn */ 1, - /* fabs_dyn */ 1, - /* ind_dyn */ 0, - /* log1p_dyn */ 1, - /* log_dyn */ 1, - /* mul_dyn */ 2, - /* pow_dyn */ 2, - /* result_dyn */ 0, - /* sign_dyn */ 1, - /* sin_dyn */ 1, - /* sinh_dyn */ 1, - /* sqrt_dyn */ 1, - /* sub_dyn */ 2, - /* tan_dyn */ 1, - /* tanh_dyn */ 1, - /* zmul_dyn */ 2, - 0 // number_dyn (not used) - }; - // END_SORT_THIS_LINE_MINUS_3 - // - static bool first = true; - if( first ) - { CPPAD_ASSERT_UNKNOWN( - size_t(number_dyn)+1 == sizeof(num_arg_table)/sizeof(num_arg_table[0]) - ); - first = false; - } - return num_arg_table[op]; -} - -/* -$begin op_name_dyn$$ -$spell - dyn - op - enum - cond_exp -$$ - -$section Number of Arguments to a Dynamic Parameter Operator$$ - -$head Syntax$$ -$icode%name% = local::op_name_dyn(%op%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_OP_NAME_DYN_PROTOTYPE%// END_OP_NAME_DYN_PROTOTYPE%1 -%$$ - -$head Parallel Mode$$ -This routine has static data so its first call cannot be in Parallel mode. - -$head op$$ -is the operator in question. - -$head name$$ -The return value $icode name$$ is the same as the operator enum symbol -(see $cref/source/op_code_dyn/Source/$$ for $code enum op_code_dyn$$) -without the $code _dyn$$ at the end. For example, -the name corresponding to the -$cref/cond_exp_dyn/op_code_dyn/cond_exp_dyn/$$ operator is $code cond_exp$$. - -$end -*/ -// BEGIN_OP_NAME_DYN_PROTOTYPE -inline const char* op_name_dyn(op_code_dyn op) -// END_OP_NAME_DYN_PROTOTYPE -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - // BEGIN_SORT_THIS_LINE_PLUS_2 - static const char* op_name_table[] = { - /* abs_dyn */ "abs", - /* acos_dyn */ "acos", - /* acosh_dyn */ "acosh", - /* add_dyn */ "add", - /* asin_dyn */ "asin", - /* asinh_dyn */ "asinh", - /* atan_dyn */ "atan", - /* atanh_dyn */ "atanh", - /* atom_dyn */ "call", - /* cond_exp_dyn */ "cond_exp", - /* cos_dyn */ "cos", - /* cosh_dyn */ "cosh", - /* dis_dyn */ "dis", - /* div_dyn */ "div", - /* erfc_dyn */ "erfc", - /* erf_dyn */ "erf", - /* exp_dyn */ "exp", - /* expm1_dyn */ "expm1", - /* fabs_dyn */ "fabs", - /* ind_dyn */ "ind", - /* log1p_dyn */ "log1p", - /* log_dyn */ "log", - /* mul_dyn */ "mul", - /* pow_dyn */ "pow", - /* result_dyn */ "result", - /* sign_dyn */ "sign", - /* sin_dyn */ "sin", - /* sinh_dyn */ "sinh", - /* sqrt_dyn */ "sqrt", - /* sub_dyn */ "sub", - /* tan_dyn */ "tan", - /* tanh_dyn */ "tanh", - /* zmul_dyn */ "zmul", - /* number_dyn */ "number" - }; - // END_SORT_THIS_LINE_MINUS_3 - static bool first = true; - if( first ) - { CPPAD_ASSERT_UNKNOWN( - size_t(number_dyn)+1 == sizeof(op_name_table)/sizeof(op_name_table[0]) - ); - first = false; - } - return op_name_table[op]; -} - -/* -$begin num_non_par_arg_dyn$$ -$spell - arg - dyn - op - num -$$ - -$section Number Non-Parameter Arguments to a Dynamic Parameters Operator$$ - -$head Syntax$$ -$icode%num% = local::num_non_par_arg_dyn(%op%) -%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_NUM_NON_PAR_ARG_DYN%// END_NUM_NON_PAR_ARG_DYN%1 -%$$ - -$head op$$ -is the operator in question. - -$head num$$ -The return value $icode num$$ is the number of arguments, -for this operator $icode op$$, that are not parameters indices. -All of the non-parameter arguments come first -so $icode num$$ is also the offset for the -first argument that is a parameter index. - -$head atom_dyn$$ -The $cref/atom_dyn/op_code_dyn/atom_dyn/$$ case is special, -$icode num$$ is zero for this case but it is not as documented above; see -$cref/atom_dyn/op_code_dyn/atom_dyn/$$. - -$end -*/ -// BEGIN_NUM_NON_PAR_ARG_DYN -inline size_t num_non_par_arg_dyn(op_code_dyn op) -// END_NUM_NON_PAR_ARG_DYN -{ - size_t num; - switch(op) - { case atom_dyn: - num = 4; - break; - - case cond_exp_dyn: - case dis_dyn: - num = 1; - break; - - default: - num = 0; - } - // - return num; -} - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/op_code_var.hpp b/build-config/cppad/include/cppad/local/op_code_var.hpp deleted file mode 100644 index f1115594..00000000 --- a/build-config/cppad/include/cppad/local/op_code_var.hpp +++ /dev/null @@ -1,1512 +0,0 @@ -# ifndef CPPAD_LOCAL_OP_CODE_VAR_HPP -# define CPPAD_LOCAL_OP_CODE_VAR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include -# include - -# include -# include -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -$begin op_code_var$$ -$spell - ind - pos - Pri - Ldp - Ldv - Vec - Stpp - Stvp - Stpv - Stvv - initializes - Cond - Rel - Namespace - CppAD - Op - opcode - enum - arg - addr - pv - vp - vv - AAddpv - exp - Funap - Funav - Funrp - Funrv -$$ - -$head Namespace$$ -All of these definitions are in the $code CppAD::local$$ namespace. - -$section Variable Op Codes$$ - -$head opcode_t$$ -This type is used to save space when storing operator enum type in vectors. -$srccode%hpp% */ -typedef CPPAD_VEC_ENUM_TYPE opcode_t; -/* %$$ - -$head OpCode$$ -This enum type is used to distinguish different $codei%AD<%Base%>%$$ -atomic operations. -Each value in the enum type ends with the characters $code Op$$. -Ignoring the $code Op$$ at the end, -the operators appear in alphabetical order. - -$head arg[i]$$ -We use the notation $icode%arg[%i%]%$$ below -for the $th i$$ operator argument which is a position integer -represented using the type $code addr_t$$. - -$head Unary$$ -An operator commented as unary below -has one argument (arg[0]) and it is a variable index. -All of these operators have one result variable. - -$head Binary And Compare$$ -An operator commented as binary or compare below -has two arguments. -If it is a compare operator it has no result variables -(the result is true or false but not a variable). -Otherwise, it has one result variable. -These operators use the following convention for the operator ending -and the left argument (arg[0]) and right argument (arg[1]): -$table -$icode Ending$$ $pre $$ $cnext $icode Left$$ $cnext $icode Right$$ $rnext -$code pvOp$$ $cnext parameter index $cnext variable index $rnext -$code vpOp$$ $cnext variable index $cnext parameter index $rnext -$code vvOp$$ $cnext variable index $cnext variable index -$tend -For example, $code AddpvOp$$ represents the addition operator where the left -operand is a parameter and the right operand is a variable. - -$subhead Pow$$ -The binary $codei%pow(%x%, %y%)%$$ operators are -special because they have three variable results instead of one. -To be specific, they compute -$codei%log(%x%)%$$, -$codei%log(%x%) * %y%$$, -$codei%exp( log(%x%) * %y%)%$$ - -$comment ------------------------------------------------------------------ $$ -$head AFunOp$$ -This operator appears at the start and end of every atomic function call. -This operator has no results variables. - -$subhead arg[0]$$ -This is the $cref atomic_index$$ for this function. - -$subhead arg[1]$$ -This is the $cref/id/atomic_one/id/$$ information used by an -old atomic class that has been deprecated - -$subhead arg[2]$$ -is the number of arguments to this atomic function. -We use the notation $icode%n% = %arg%[2]%$$ below. - -$subhead arg[3]$$ -is the number of results for this atomic function. -We use the notation $icode%m% = %arg%[3]%$$ below. - -$subhead Arguments$$ -There are $icode n$$ operators after the first $code AFunOp$$, -one for each argument. -If the $th j$$ argument is a parameter (variable) -the corresponding operator is $code FunapOp$$ ( $code FunavOp$$ ), and -the corresponding operator argument is a parameter index (variable index). -These operators have no result variables. - -$subhead Results$$ -There are $icode m$$ operators after the last argument operator -one for each result. -If the $th i$$ result is a parameter (variable) -the corresponding operator is $code FunrpOp$$ ( $code FunrvOp$$ ). -In the parameter case, there is one argument and it is the parameter index, -and not result variables. -In the variable case, there are no arguments and one result variable. -The index for the new variable with the next possible index. - -$comment ------------------------------------------------------------------ $$ -$head BeginOp$$ -This operator marks the start of the tape. -It has one parameter index argument that is nan and corresponds -to parameter index zero. -It also has one variable result that has index zero which is used to -indicate that a value is not a variable. -for indicate an parameter. - -$comment ------------------------------------------------------------------ $$ -$head CExpOp$$ -This is a $cref/conditional expression/condexp/$$; i.e., the corresponding -source code is -$codei% - %result% = CondExp%Rel%(%left%, %right%, %if_true%, %if_false% -%$$ -This operator has one variable result. - -$subhead arg[0]$$ -This is a $cref/CompareOp/base_cond_exp/CompareOp/$$ value corresponding -to $cref/Rel/condexp/Rel/$$ above. ($icode%Rel% = Ne%$$ is not possible). - -$subhead arg[1]$$ -The first four bits of this integer are used as flags; see below. - -$subhead arg[2]$$ -If arg[1] & 1 is true (false), -this is the variable index (parameter index) corresponding to $icode left$$. - -$subhead arg[3]$$ -If arg[1] & 2 is true (false), -this is the variable index (parameter index) corresponding to $icode right$$. - -$subhead arg[4]$$ -If arg[1] & 4 is true (false), -this is the variable index (parameter index) corresponding to $icode if_true$$. - -$subhead arg[5]$$ -If arg[1] & 8 is true (false), -this is the variable index (parameter index) corresponding to $icode if_false$$. - -$comment ------------------------------------------------------------------ $$ -$head CSkipOp$$ -The conditional skip operator (used to skip operations that depend on false -branches to conditional expressions). -This operator has not result variables. - -$subhead arg[0]$$ -This is a $cref/CompareOp/base_cond_exp/CompareOp/$$ value corresponding -to this conditional skip. - -$subhead arg[1]$$ -The first two bits of this integer are used as flags; see below. - -$subhead arg[2]$$ -If arg[1] & 1 is true (false), -this is the variable index (parameter index) corresponding to $icode left$$. - -$subhead arg[3]$$ -If arg[1] & 2 is true (false), -this is the variable index (parameter index) corresponding to $icode right$$. - -$subhead arg[4]$$ -is the number of operations to skip if the comparison is true. -We use the notation $icode%n% = %arg%[4]%$$ below. - -$subhead arg[5]$$ -is the number of operations to skip if the comparison is false. -We use the notation $icode%m% = %arg%[5]%$$ below. - -$subhead arg[6+i]$$ -For $icode%i% = 0, %...%, %n%-1%$$, this is the index -of an operator that can be skipped if the comparison is true. - -$subhead arg[6+n+i]$$ -For $icode%i% = 0, %...%, %m%-1%$$, this is the index -of an operator that can be skipped if the comparison is false. - -$subhead arg[6+n+m]$$ -The is the total number operators that might be skipped; i.e., $icode%n%+%m%$$. - -$comment ------------------------------------------------------------------ $$ -$head CSumOp$$ -Is a cumulative summation operator -which has one result variable. - -$subhead arg[0]$$ -is the index of the parameter that initializes the summation. - -$subhead arg[1]$$ -argument index that flags the end of the addition variables, -we use the notation $icode%k% = %arg%[1]%$$ below. - -$subhead arg[2]$$ -argument index that flags the end of the subtraction variables, -we use the notation $icode%ell% = %arg%[2]%$$ below. - -$subhead arg[3]$$ -argument index that flags the end of the addition dynamic parameters, -we use the notation $icode%m% = %arg%[3]%$$ below. - -$subhead arg[4]$$ -argument index that flags the end of the subtraction dynamic parameters, -we use the notation $icode%n% = %arg%[4]%$$ below. - -$subhead arg[5+i]$$ -for $icode%i% = 0, %...%, %k%-6%$$, -this is the index of the $th i$$ variable to be added in the summation. - -$subhead arg[k+i]$$ -for $icode%i% = 0, %...%, %ell%-%k%-1%$$, -this is the index of the $th i$$ variable to be subtracted in the summation. - -$subhead arg[ell+i]$$ -for $icode%i% = 0, %...%, %m%-%ell%-1%$$, this is the index of the -$th i$$ dynamic parameter to be added in the summation. - -$subhead arg[m+i]$$ -for $icode%i% = 0, %...%, %n%-%m%-1%$$, this is the index of the -$th i$$ dynamic parameter to be subtracted in the summation. - -$subhead arg[n]$$ -This is equal to $icode n$$. -Note that there are $icode%n%+1%$$ arguments to this operator -and having this value at the end enable reverse model to know how far -to back up to get to the start of this operation. - -$comment ------------------------------------------------------------------ $$ -$head DisOp$$ -Call to a user defined $cref discrete$$ function. -This operator has one result variable. - -$subhead arg[0]$$ -is the index, in the order of the functions defined by the user, -for this discrete function. - -$subhead arg[1]$$ -variable index corresponding to the argument for this function call. - -$comment ------------------------------------------------------------------ $$ -$head Load$$ -The load operators create a new variable corresponding to -$icode%vec%[%ind%]%$$ where $icode vec$$ is a $cref VecAD$$ vector -and $icode ind$$ is an $codei%AD<%Base%>%$$. -For these operators either $icode vec$$ or $icode ind$$ is a variable -and there is one variable result. - -$subhead LdpOp$$ -This load is used for an index $icode ind$$ that is a parameter. - -$subhead LdvOp$$ -This load is used for an index $icode ind$$ that is a variable. - -$subhead arg[0]$$ -is the offset of this VecAD vector -relative to the beginning of the single array -that contains all VecAD elements for all the VecAD vectors. -This corresponds to the first element of this vector and not its size -(which comes just before the first element). - -$subhead arg[1]$$ -is the index in this VecAD vector for this load operation. -For the $code LdpOp$$ ($code LdvOp$$) operator this is the -parameter index (variable index) corresponding to $icode ind$$. - -$subhead arg[2]$$ -is the index of this VecAD load operation in the set of all -the load operations in this recording. -This includes both dynamic parameter and variable loads. -It is used to map load operations to corresponding -dynamic parameters and variables. - -$comment ------------------------------------------------------------------ $$ -$head Store$$ -The store operators store information corresponding to -$icode%vec%[%ind%]% = %right%$$ where $icode vec$$ is a $cref VecAD$$ vector -and $icode ind$$ is an $codei%AD<%Base%>%$$. -For these operators either $icode vec$$, $icode ind$$, or $icode right$$ -is a variable and there is no result. - -$subhead StppOp$$ -This store is used when $icode ind$$ and $icode right$$ are parameters. - -$subhead StpvOp$$ -This store is used when $icode ind$$ is a parameter -and $icode right$$ is a variable. - -$subhead StvpOp$$ -This store is used when $icode ind$$ is a variable -and $icode right$$ is a parameter. - -$subhead StvvOp$$ -This store is used when $icode index$$ and $icode right$$ are variables. - -$subhead arg[0]$$ -is the offset of this VecAD vector -relative to the beginning of the single array -that contains all VecAD elements for all the VecAD vectors. -This corresponds to the first element of this vector and not its size -(which comes just before the first element). - -$subhead arg[1]$$ -is the index in this VecAD vector for this store operation. -For the $code StppOp$$ and $code StpvOp$$ cases -this is the parameter index corresponding to $icode ind$$. -For the $code StvpOp$$ and $code StvvOp$$ cases, -this is the variable index corresponding to $icode ind$$. - -$subhead arg[2]$$ -For the $code StppOp$$ and $code StvpOp$$ cases, -this is the parameter index corresponding to $icode right$$. -For the $code StpvOp$$ and $code StvvOp$$ cases, -this is the variable index corresponding to $icode right$$. - -$comment ------------------------------------------------------------------ $$ -$head ParOp$$ -This operator has one result that is equal to a parameter -(not that all the derivatives for this result will be zero). - -$subhead arg[0]$$ -Is the index of the parameter that determines the value of the variable. - -$comment ------------------------------------------------------------------ $$ -$head PriOp$$ -This operator implements the $cref PrintFor$$ command -$codei% - PrintFor(%pos%, %before%, %value%, %after%) -%$$ - -$subhead arg[0]$$ -The first two bits of this integer are used as flags; see below. - -$subhead arg[1]$$ -If arg[1] & 1 is true (false), -this is the variable index (parameter index) corresponding to $icode pos$$. - -$subhead arg[2]$$ -is the text index corresponding to $icode before$$. - -$subhead arg[3]$$ -If arg[1] & 2 is true (false), -this is the variable index (parameter index) corresponding to $icode value$$. - -$subhead arg[4]$$ -is the text index corresponding to $icode after$$. - -$comment ------------------------------------------------------------------ $$ - -$head Source$$ -$srccode%hpp% */ -// BEGIN_SORT_THIS_LINE_PLUS_2 -enum OpCode { - AbsOp, // unary fabs - AcosOp, // unary acos - AcoshOp, // unary acosh - AddpvOp, // binary + - AddvvOp, // ... - AFunOp, // see its heading above - AsinOp, // unary asin - AsinhOp, // unary asinh - AtanOp, // unary atan - AtanhOp, // unary atanh - BeginOp, // see its heading above - CExpOp, // ... - CosOp, // unary cos - CoshOp, // unary cosh - CSkipOp, // see its heading above - CSumOp, // ... - DisOp, // ... - DivpvOp, // binary / - DivvpOp, // ... - DivvvOp, // ... - EndOp, // used to mark the end of the tape - EqppOp, // compare equal - EqpvOp, // ... - EqvvOp, // ... - ErfOp, // unary erf - ErfcOp, // unary erfc - ExpOp, // unary exp - Expm1Op, // unary expm1 - FunapOp, // see AFun heading above - FunavOp, // ... - FunrpOp, // ... - FunrvOp, // ... - InvOp, // independent variable, no argumements, one result variable - LdpOp, // see its heading above - LdvOp, // ... - LeppOp, // compare <= - LepvOp, // ... - LevpOp, // ... - LevvOp, // ... - LogOp, // unary log - Log1pOp, // unary log1p - LtppOp, // compare < - LtpvOp, // ... - LtvpOp, // ... - LtvvOp, // ... - MulpvOp, // binary * - MulvvOp, // ... - NeppOp, // compare != - NepvOp, // ... - NevvOp, // ... - ParOp, // see its heading above - PowpvOp, // see Pow heading above - PowvpOp, // ... - PowvvOp, // ... - PriOp, // see its heading above - SignOp, // unary sign - SinOp, // unary sin - SinhOp, // unary sinh - SqrtOp, // unary sqrt - StppOp, // see its heading above - StpvOp, // ... - StvpOp, // ... - StvvOp, // ... - SubpvOp, // binary - - SubvpOp, // ... - SubvvOp, // ... - TanOp, // unary tan - TanhOp, // unary tanh - ZmulpvOp, // binary azmul - ZmulvpOp, // ... - ZmulvvOp, // ... - NumberOp // number of operator codes (not an operator) -}; -// END_SORT_THIS_LINE_MINUS_3 -/* %$$ -$end -*/ -// Note that bin/check_op_code.sh assumes the pattern NumberOp occurs -// at the end of this list and only at the end of this list. - -/*! -Number of arguments for a specified operator. - -\return -Number of arguments corresponding to the specified operator. - -\param op -Operator for which we are fetching the number of arugments. - -\par NumArgTable -this table specifes the number of arguments stored for each -occurance of the operator that is the i-th value in the OpCode enum type. -For example, for the first three OpCode enum values we have -\verbatim -OpCode j NumArgTable[j] Meaning -AbsOp 0 1 index of variable we are taking absolute value of -AcosOp 1 1 index of variable we are taking acos of -AcoshOp 2 1 index of variable we are taking acosh of -\endverbatim -Note that the meaning of the arguments depends on the operator. -*/ -inline size_t NumArg( OpCode op) -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - // agreement with OpCode is checked by bin/check_op_code.sh - static const size_t NumArgTable[] = { - 1, // AbsOp - 1, // AcosOp - 1, // AcoshOp - 2, // AddpvOp - 2, // AddvvOp - 4, // AFunOp - 1, // AsinOp - 1, // AsinhOp - 1, // AtanOp - 1, // AtanhOp - 1, // BeginOp offset first real argument to have index 1 - 6, // CExpOp - 1, // CosOp - 1, // CoshOp - 0, // CSkipOp (actually has a variable number of arguments, not zero) - 0, // CSumOp (actually has a variable number of arguments, not zero) - 2, // DisOp - 2, // DivpvOp - 2, // DivvpOp - 2, // DivvvOp - 0, // EndOp - 2, // EqppOp - 2, // EqpvOp - 2, // EqvvOp - 3, // ErfOp - 3, // ErfcOp - 1, // ExpOp - 1, // Expm1Op - 1, // FunapOp - 1, // FunavOp - 1, // FunrpOp - 0, // FunrvOp - 0, // InvOp - 3, // LdpOp - 3, // LdvOp - 2, // LeppOp - 2, // LepvOp - 2, // LevpOp - 2, // LevvOp - 1, // LogOp - 1, // Log1pOp - 2, // LtppOp - 2, // LtpvOp - 2, // LtvpOp - 2, // LtvvOp - 2, // MulpvOp - 2, // MulvvOp - 2, // NeppOp - 2, // NepvOp - 2, // NevvOp - 1, // ParOp - 2, // PowpvOp - 2, // PowvpOp - 2, // PowvvOp - 5, // PriOp - 1, // SignOp - 1, // SinOp - 1, // SinhOp - 1, // SqrtOp - 3, // StppOp - 3, // StpvOp - 3, // StvpOp - 3, // StvvOp - 2, // SubpvOp - 2, // SubvpOp - 2, // SubvvOp - 1, // TanOp - 1, // TanhOp - 2, // ZmulpvOp - 2, // ZmulvpOp - 2, // ZmulvvOp - 0 // NumberOp not used - }; -# ifndef NDEBUG - // only do these checks once to save time - static bool first = true; - if( first ) - { first = false; - // check that NumberOp is last value in op code table - CPPAD_ASSERT_UNKNOWN( - size_t(NumberOp) + 1 == sizeof(NumArgTable)/sizeof(NumArgTable[0]) - ); - //Check that the type CPPAD_VEC_ENUM_TYPE as required by define.hpp - CPPAD_ASSERT_UNKNOWN( is_pod() ); - size_t number_op_size_t = size_t( NumberOp ); - CPPAD_ASSERT_UNKNOWN( - number_op_size_t < std::numeric_limits::max() - ); - } - // do this check every time - CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) ); -# endif - - return NumArgTable[op]; -} - -/*! -Number of variables resulting from the specified operation. - -\param op -Operator for which we are fecching the number of results. - -\par NumResTable -table specifes the number of varibles that result for each -occurance of the operator that is the i-th value in the OpCode enum type. -For example, for the first three OpCode enum values we have -\verbatim -OpCode j NumResTable[j] Meaning -AbsOp 0 1 variable that is the result of the absolute value -AcosOp 1 2 acos(x) and sqrt(1-x*x) are required for this op -AcoshOp 2 2 acosh(x) and sqrt(x*x-1) are required for this op -\endverbatim -*/ -inline size_t NumRes(OpCode op) -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - // agreement with OpCode is checked by bin/check_op_code.sh - static const size_t NumResTable[] = { - 1, // AbsOp - 2, // AcosOp - 2, // AcoshOp - 1, // AddpvOp - 1, // AddvvOp - 0, // AFunOp - 2, // AsinOp - 2, // AsinhOp - 2, // AtanOp - 2, // AtanhOp - 1, // BeginOp offsets first variable to have index one (not zero) - 1, // CExpOp - 2, // CosOp - 2, // CoshOp - 0, // CSkipOp - 1, // CSumOp - 1, // DisOp - 1, // DivpvOp - 1, // DivvpOp - 1, // DivvvOp - 0, // EndOp - 0, // EqppOp - 0, // EqpvOp - 0, // EqvvOp - 5, // ErfOp - 5, // ErfcOp - 1, // ExpOp - 1, // Expm1Op - 0, // FunapOp - 0, // FunavOp - 0, // FunrpOp - 1, // FunrvOp - 1, // InvOp - 1, // LdpOp - 1, // LdvOp - 0, // LeppOp - 0, // LepvOp - 0, // LevpOp - 0, // LevvOp - 1, // LogOp - 1, // Log1pOp - 0, // LtppOp - 0, // LtpvOp - 0, // LtvpOp - 0, // LtvvOp - 1, // MulpvOp - 1, // MulvvOp - 0, // NeppOp - 0, // NepvOp - 0, // NevvOp - 1, // ParOp - 3, // PowpvOp - 3, // PowvpOp - 3, // PowvvOp - 0, // PriOp - 1, // SignOp - 2, // SinOp - 2, // SinhOp - 1, // SqrtOp - 0, // StppOp - 0, // StpvOp - 0, // StvpOp - 0, // StvvOp - 1, // SubpvOp - 1, // SubvpOp - 1, // SubvvOp - 2, // TanOp - 2, // TanhOp - 1, // ZmulpvOp - 1, // ZmulvpOp - 1, // ZmulvvOp - 0 // NumberOp not used and avoids g++ 4.3.2 warn when pycppad builds - }; - // check ensuring conversion to size_t is as expected - CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) + 1 == - sizeof(NumResTable) / sizeof(NumResTable[0]) - ); - // this test ensures that all indices are within the table - CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) ); - - return NumResTable[op]; -} - - -/*! -Fetch the name for a specified operation. - -\return -name of the specified operation. - -\param op -Operator for which we are fetching the name -*/ -inline const char* OpName(OpCode op) -{ // agreement with OpCode is checked by bin/check_op_code.sh - static const char *OpNameTable[] = { - "Abs" , - "Acos" , - "Acosh" , - "Addpv" , - "Addvv" , - "AFun" , - "Asin" , - "Asinh" , - "Atan" , - "Atanh" , - "Begin" , - "CExp" , - "Cos" , - "Cosh" , - "CSkip" , - "CSum" , - "Dis" , - "Divpv" , - "Divvp" , - "Divvv" , - "End" , - "Eqpp" , - "Eqpv" , - "Eqvv" , - "Erf" , - "Erfc" , - "Exp" , - "Expm1" , - "Funap" , - "Funav" , - "Funrp" , - "Funrv" , - "Inv" , - "Ldp" , - "Ldv" , - "Lepp" , - "Lepv" , - "Levp" , - "Levv" , - "Log" , - "Log1p" , - "Ltpp" , - "Ltpv" , - "Ltvp" , - "Ltvv" , - "Mulpv" , - "Mulvv" , - "Nepp" , - "Nepv" , - "Nevv" , - "Par" , - "Powpv" , - "Powvp" , - "Powvv" , - "Pri" , - "Sign" , - "Sin" , - "Sinh" , - "Sqrt" , - "Stpp" , - "Stpv" , - "Stvp" , - "Stvv" , - "Subpv" , - "Subvp" , - "Subvv" , - "Tan" , - "Tanh" , - "Zmulpv", - "Zmulvp", - "Zmulvv", - "Number" // not used - }; - // check ensuring conversion to size_t is as expected - CPPAD_ASSERT_UNKNOWN( - size_t(NumberOp) + 1 == sizeof(OpNameTable)/sizeof(OpNameTable[0]) - ); - // this test ensures that all indices are within the table - CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) ); - - return OpNameTable[op]; -} - -/*! -Prints a single field corresponding to an operator. - -A specified leader is printed in front of the value -and then the value is left justified in the following width character. - -\tparam Type -is the type of the value we are printing. - -\param os -is the stream that we are printing to. - -\param leader -are characters printed before the value. - -\param value -is the value being printed. - -\param width -is the number of character to print the value in. -If the value does not fit in the width, the value is replace -by width '*' characters. -*/ -template -void printOpField( - std::ostream &os , - const char * leader , - const Type &value , - size_t width ) -{ - std::ostringstream buffer; - std::string str; - - // first print the leader - os << leader; - - // print the value into an internal buffer - buffer << std::setw( int(width) ) << value; - str = buffer.str(); - - // length of the string - size_t len = str.size(); - if( len > width ) - { - for(size_t i = 0; i < width-1; i++) - os << str[i]; - os << "*"; - return; - } - - // count number of spaces at begining - size_t nspace = 0; - while(str[nspace] == ' ' && nspace < len) - nspace++; - - // left justify the string - size_t i = nspace; - while( i < len ) - os << str[i++]; - - i = width - len + nspace; - while(i--) - os << " "; -} - -/*! -Prints a single operator and its operands - -\tparam Base -Is the base type for these AD< Base > operations. - -\param os -is the output stream that the information is printed on. - -\param play -Is the entire recording for the tape that this operator is in. - -\param i_op -is the index for the operator corresponding to this operation. - -\param i_var -is the index for the variable corresponding to the result of this operation -(if NumRes(op) > 0). - -\param op -The operator code (OpCode) for this operation. - -\param arg -is the vector of argument indices for this operation -(must have NumArg(op) elements). -*/ -template -void printOp( - std::ostream& os , - const local::player* play, - size_t i_op , - size_t i_var , - OpCode op , - const addr_t* arg ) -{ - CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "cannot print trace of AD operations in parallel mode" - ); - static const char *CompareOpName[] = - { "Lt", "Le", "Eq", "Ge", "Gt", "Ne" }; - - // print operator - printOpField(os, "o=", i_op, 5); - if( NumRes(op) > 0 && op != BeginOp ) - printOpField(os, "v=", i_var, 5); - else - printOpField(os, "v=", "", 5); - if( op == CExpOp || op == CSkipOp ) - { printOpField(os, "", OpName(op), 5); - printOpField(os, "", CompareOpName[ arg[0] ], 3); - } - else - printOpField(os, "", OpName(op), 8); - - // print other fields - size_t ncol = 5; - switch( op ) - { - case CSkipOp: - /* - arg[0] = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne - arg[1] & 1 = is left a variable - arg[1] & 2 = is right a variable - arg[2] = index correspoding to left - arg[3] = index correspoding to right - arg[4] = number of operations to skip if CExpOp comparison is true - arg[5] = number of operations to skip if CExpOp comparison is false - arg[6] -> arg[5+arg[4]] = skip operations if true - arg[6+arg[4]] -> arg[5+arg[4]+arg[5]] = skip operations if false - arg[6+arg[4]+arg[5]] = arg[4] + arg[5] - */ - CPPAD_ASSERT_UNKNOWN( arg[6+arg[4]+arg[5]] == arg[4]+arg[5] ); - CPPAD_ASSERT_UNKNOWN(arg[1] != 0); - if( arg[1] & 1 ) - printOpField(os, " vl=", arg[2], ncol); - else - printOpField(os, " pl=", play->GetPar(arg[2]), ncol); - if( arg[1] & 2 ) - printOpField(os, " vr=", arg[3], ncol); - else - printOpField(os, " pr=", play->GetPar(arg[3]), ncol); - if( size_t(arg[4]) < 3 ) - { for(addr_t i = 0; i < arg[4]; i++) - printOpField(os, " ot=", arg[6+i], ncol); - } - else - { printOpField(os, "\n\tot=", arg[6+0], ncol); - for(addr_t i = 1; i < arg[4]; i++) - printOpField(os, " ot=", arg[6+i], ncol); - } - if( size_t(arg[5]) < 3 ) - { for(addr_t i = 0; i < arg[5]; i++) - printOpField(os, " of=", arg[6+arg[4]+i], ncol); - } - else - { printOpField(os, "\n\tof=", arg[6+arg[4]+0], ncol); - { for(addr_t i = 1; i < arg[5]; i++) - printOpField(os, " of=", arg[6+arg[4]+i], ncol); - } - } - break; - - case CSumOp: - /* - arg[0] = index of parameter that initializes summation - arg[1] = end in arg of addition variables in summation - arg[2] = end in arg of subtraction variables in summation - arg[3] = end in arg of addition dynamic parameters in summation - arg[4] = end in arg of subtraction dynamic parameters in summation - arg[5], ... , arg[arg[1]-1]: indices for addition variables - arg[arg[1]], ... , arg[arg[2]-1]: indices for subtraction variables - arg[arg[2]], ... , arg[arg[3]-1]: indices for additon dynamics - arg[arg[3]], ... , arg[arg[4]-1]: indices for subtraction dynamics - arg[arg[4]] = arg[4] - */ - CPPAD_ASSERT_UNKNOWN( arg[arg[4]] == arg[4] ); - printOpField(os, " pr=", play->GetPar(arg[0]), ncol); - for(addr_t i = 5; i < arg[1]; i++) - printOpField(os, " +v=", arg[i], ncol); - for(addr_t i = arg[1]; i < arg[2]; i++) - printOpField(os, " -v=", arg[i], ncol); - for(addr_t i = arg[2]; i < arg[3]; i++) - printOpField(os, " +d=", play->GetPar(arg[i]), ncol); - for(addr_t i = arg[3]; i < arg[4]; i++) - printOpField(os, " -d=", play->GetPar(arg[i]), ncol); - break; - - case LdpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - printOpField(os, "off=", arg[0], ncol); - printOpField(os, " p=", play->GetPar(arg[1]), ncol); - break; - - case LdvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - printOpField(os, "off=", arg[0], ncol); - printOpField(os, " v=", arg[1], ncol); - break; - - case StppOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - printOpField(os, "off=", arg[0], ncol); - printOpField(os, " pl=", play->GetPar(arg[1]), ncol); - printOpField(os, " pr=", play->GetPar(arg[2]), ncol); - break; - - case StpvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - printOpField(os, "off=", arg[0], ncol); - printOpField(os, " p=", play->GetPar(arg[1]), ncol); - printOpField(os, " v=", arg[2], ncol); - break; - - case StvpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - printOpField(os, "off=", arg[0], ncol); - printOpField(os, " v=", arg[1], ncol); - printOpField(os, " p=", play->GetPar(arg[2]), ncol); - break; - - case StvvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - printOpField(os, "off=", arg[0], ncol); - printOpField(os, " vl=", arg[1], ncol); - printOpField(os, " vr=", arg[2], ncol); - break; - - case AddvvOp: - case DivvvOp: - case EqvvOp: - case LevvOp: - case LtvvOp: - case NevvOp: - case MulvvOp: - case PowvvOp: - case SubvvOp: - case ZmulvvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - printOpField(os, " vl=", arg[0], ncol); - printOpField(os, " vr=", arg[1], ncol); - break; - - case AddpvOp: - case EqpvOp: - case DivpvOp: - case LepvOp: - case LtpvOp: - case NepvOp: - case SubpvOp: - case MulpvOp: - case PowpvOp: - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - printOpField(os, " pl=", play->GetPar(arg[0]), ncol); - printOpField(os, " vr=", arg[1], ncol); - break; - - case DivvpOp: - case LevpOp: - case LtvpOp: - case PowvpOp: - case SubvpOp: - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - printOpField(os, " vl=", arg[0], ncol); - printOpField(os, " pr=", play->GetPar(arg[1]), ncol); - break; - - case 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 FunavOp: - case TanOp: - case TanhOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - printOpField(os, " v=", arg[0], ncol); - break; - - case ErfOp: - case ErfcOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - // arg[1] points to the parameter 0 - // arg[2] points to the parameter 2 / sqrt(pi) - printOpField(os, " v=", arg[0], ncol); - break; - - case ParOp: - case FunapOp: - case FunrpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - printOpField(os, " p=", play->GetPar(arg[0]), ncol); - break; - - case AFunOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 ); - { - // get the name of this atomic function - bool set_null = false; - size_t atom_index = size_t( arg[0] ); - size_t type = 0; // set to avoid warning - std::string name; - void* v_ptr = nullptr; // set to avoid warning - atomic_index(set_null, atom_index, type, &name, v_ptr); - printOpField(os, " f=", name.c_str(), ncol); - printOpField(os, " i=", arg[1], ncol); - printOpField(os, " n=", arg[2], ncol); - printOpField(os, " m=", arg[3], ncol); - } - break; - - case PriOp: - CPPAD_ASSERT_NARG_NRES(op, 5, 0); - if( arg[0] & 1 ) - printOpField(os, " v=", arg[1], ncol); - else - printOpField(os, " p=", play->GetPar(arg[1]), ncol); - os << "before=\"" << play->GetTxt(arg[2]) << "\""; - if( arg[0] & 2 ) - printOpField(os, " v=", arg[3], ncol); - else - printOpField(os, " p=", play->GetPar(arg[3]), ncol); - os << "after=\"" << play->GetTxt(arg[4]) << "\""; - break; - - case BeginOp: - // argument not used (created by independent) - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - break; - - case EndOp: - case InvOp: - case FunrvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 ); - break; - - case DisOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - { const char* name = discrete::name(arg[0]); - printOpField(os, " f=", name, ncol); - printOpField(os, " x=", arg[1], ncol); - } - break; - - - case CExpOp: - CPPAD_ASSERT_UNKNOWN(arg[1] != 0); - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 ); - if( arg[1] & 1 ) - printOpField(os, " vl=", arg[2], ncol); - else - printOpField(os, " pl=", play->GetPar(arg[2]), ncol); - if( arg[1] & 2 ) - printOpField(os, " vr=", arg[3], ncol); - else - printOpField(os, " pr=", play->GetPar(arg[3]), ncol); - if( arg[1] & 4 ) - printOpField(os, " vt=", arg[4], ncol); - else - printOpField(os, " pt=", play->GetPar(arg[4]), ncol); - if( arg[1] & 8 ) - printOpField(os, " vf=", arg[5], ncol); - else - printOpField(os, " pf=", play->GetPar(arg[5]), ncol); - break; - - case EqppOp: - case LeppOp: - case LtppOp: - case NeppOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - printOpField(os, " pl=", play->GetPar(arg[0]), ncol); - printOpField(os, " pr=", play->GetPar(arg[1]), ncol); - break; - - default: - CPPAD_ASSERT_UNKNOWN(0); - } -} - -/*! -Prints the result values correspnding to an operator. - -\tparam Base -Is the base type for these AD< Base > operations. - -\tparam Value -Determines the type of the values that we are printing. - -\param os -is the output stream that the information is printed on. - -\param nfz -is the number of forward sweep calculated values of type Value -that correspond to this operation -(ignored if NumRes(op) == 0). - -\param fz -points to the first forward calculated value -that correspond to this operation -(ignored if NumRes(op) == 0). - -\param nrz -is the number of reverse sweep calculated values of type Value -that correspond to this operation -(ignored if NumRes(op) == 0). - -\param rz -points to the first reverse calculated value -that correspond to this operation -(ignored if NumRes(op) == 0). -*/ -template -void printOpResult( - std::ostream &os , - size_t nfz , - const Value *fz , - size_t nrz , - const Value *rz ) -{ - size_t k; - for(k = 0; k < nfz; k++) - os << "| fz[" << k << "]=" << fz[k]; - for(k = 0; k < nrz; k++) - os << "| rz[" << k << "]=" << rz[k]; -} - -/*! -Determines which arguments are variaibles for an operator. - -\param op -is the operator. Note that CSkipOp and CSumOp are special cases -because the true number of arguments is not equal to NumArg(op) -and the true number of arguments num_arg can be large. -It may be more efficient to handle these cases separately -(see below). - -\param arg -is the argument vector for this operator. - -\param is_variable -If the input value of the elements in this vector do not matter. -Upon return, resize has been used to set its size to the true number -of arguments to this operator. -If op != CSkipOp and op != CSumOp, is_variable.size() = NumArg(op). -The j-th argument for this operator is a -variable index if and only if is_variable[j] is true. Note that the variable -index 0, for the BeginOp, does not correspond to a real variable and false -is returned for this case. - -\par CSkipOp -In the case of CSkipOp, -\code - is_variable.size() = 7 + arg[4] + arg[5]; - is_variable[2] = (arg[1] & 1) != 0; - is_variable[3] = (arg[1] & 2) != 0; -\endcode -and all the other is_variable[j] values are false. - -\par CSumOp -In the case of CSumOp, -\code - is_variable.size() = arg[4] - for(size_t j = 5; j < arg[2]; ++j) - is_variable[j] = true; -\endcode -and all the other is_variable values are false. -*/ -template -void arg_is_variable( - OpCode op , - const Addr* arg , - pod_vector& is_variable ) -{ size_t num_arg = NumArg(op); - is_variable.resize( num_arg ); - // - switch(op) - { - // ------------------------------------------------------------------- - // cases where true number of arugments = NumArg(op) == 0 - - case EndOp: - case InvOp: - case FunrvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 ); - break; - - // ------------------------------------------------------------------- - // cases where NumArg(op) == 1 - case AbsOp: - case AcoshOp: - case AcosOp: - case AsinhOp: - case AsinOp: - case AtanhOp: - case AtanOp: - case CoshOp: - case CosOp: - case Expm1Op: - case ExpOp: - case Log1pOp: - case LogOp: - case SignOp: - case SinhOp: - case SinOp: - case SqrtOp: - case TanhOp: - case TanOp: - case FunavOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - is_variable[0] = true; - break; - - case BeginOp: - case ParOp: - case FunapOp: - case FunrpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - is_variable[0] = false; - break; - - - // ------------------------------------------------------------------- - // cases where NumArg(op) == 2 - - case AddpvOp: - case DisOp: - case DivpvOp: - case EqpvOp: - case LepvOp: - case LtpvOp: - case MulpvOp: - case NepvOp: - case PowpvOp: - case SubpvOp: - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - is_variable[0] = false; - is_variable[1] = true; - break; - - case DivvpOp: - case LevpOp: - case LtvpOp: - case PowvpOp: - case SubvpOp: - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - is_variable[0] = true; - is_variable[1] = false; - break; - - case AddvvOp: - case DivvvOp: - case EqvvOp: - case LevvOp: - case LtvvOp: - case MulvvOp: - case NevvOp: - case PowvvOp: - case SubvvOp: - case ZmulvvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - is_variable[0] = true; - is_variable[1] = true; - break; - - case ErfOp: - case ErfcOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - is_variable[0] = true; - is_variable[1] = false; // parameter index corresponding to zero - is_variable[2] = false; // parameter index corresponding to one - break; - - // -------------------------------------------------------------------- - // cases where NumArg(op) == 3 - - case LdpOp: - case StppOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - is_variable[0] = false; - is_variable[1] = false; - is_variable[2] = false; - break; - - case LdvOp: - case StvpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - is_variable[0] = false; - is_variable[1] = true; - is_variable[2] = false; - break; - - case StpvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - is_variable[0] = false; - is_variable[1] = false; - is_variable[2] = true; - break; - - case StvvOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - is_variable[0] = false; - is_variable[1] = true; - is_variable[2] = true; - break; - - // -------------------------------------------------------------------- - // case where NumArg(op) == 4 - case AFunOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 ); - for(size_t i = 0; i < 4; i++) - is_variable[i] = false; - break; - - // -------------------------------------------------------------------- - // case where NumArg(op) == 5 - case PriOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 5 ); - is_variable[0] = false; - is_variable[1] = (arg[0] & 1) != 0; - is_variable[2] = false; - is_variable[3] = (arg[0] & 2) != 0; - is_variable[4] = false; - break; - - // -------------------------------------------------------------------- - // case where NumArg(op) == 6 - case CExpOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 ); - is_variable[0] = false; - is_variable[1] = false; - is_variable[2] = (arg[0] & 1) != 0; - is_variable[3] = (arg[0] & 2) != 0; - is_variable[4] = (arg[0] & 4) != 0; - is_variable[5] = (arg[0] & 8) != 0; - break; - - // ------------------------------------------------------------------- - // CSkipOp: - case CSkipOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 ) - // - // true number of arguments - num_arg = size_t(7 + arg[4] + arg[5]); - is_variable.resize(num_arg); - is_variable[0] = false; - is_variable[1] = false; - is_variable[2] = (arg[1] & 1) != 0; - is_variable[3] = (arg[1] & 2) != 0; - for(size_t i = 4; i < num_arg; ++i) - is_variable[i] = false; - break; - - // ------------------------------------------------------------------- - // CSumOp: - case CSumOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 ) - // - // true number of arguments - num_arg = size_t(arg[4]); - // - is_variable.resize( num_arg ); - for(size_t i = 0; i < num_arg; ++i) - is_variable[i] = (5 <= i) & (i < size_t(arg[2])); - break; - - case EqppOp: - case LeppOp: - case LtppOp: - case NeppOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - is_variable[0] = false; - is_variable[1] = false; - break; - - // -------------------------------------------------------------------- - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - return; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/cexp_info.hpp b/build-config/cppad/include/cppad/local/optimize/cexp_info.hpp deleted file mode 100644 index 92e457c6..00000000 --- a/build-config/cppad/include/cppad/local/optimize/cexp_info.hpp +++ /dev/null @@ -1,123 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_CEXP_INFO_HPP -# define CPPAD_LOCAL_OPTIMIZE_CEXP_INFO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include // defines CompareOp -# include - -/*! -$begin optimize_cexp_info$$ -$spell - struct - cexp - op - Funap - Funav - Funrp - Funrv - cskip - arg -$$ - -$section Optimization Information About Conditional Expressions$$ - -$head struct_cexp_info$$ -information about a conditional expression -in the old operation sequence (before optimization). -$srcthisfile% - 0%// BEGIN_STRUCT_CEXP_INFO%// END_STRUCT_CEXP_INFO%1 -%$$ - -$subhead i_op$$ -is the operator index for this conditional expression. - -$subhead left$$ -is the variable or parameter index (depending on flag) -for left operand in the comparison. - -$subhead right$$ -is the variable or parameter index (depending on flag) -for right operand in the comparison. - -$subhead max_left_right$$ -is the maximum of the left and right variable indices. -This is a variable index, so parameters correspond to index zero. - -$subhead cop$$ -is the comparison operator for this conditional expression. - -$subhead flag$$ -$list number$$ -(flag & 1) is true if and only if left is a variable -$lnext -(flag & 2) is true if and only if right is a variable -$lend - -$head struct_cskip_new$$ -information about a conditional expression -in thew new operation sequence (after optimization). -$srcthisfile% - 0%// BEGIN_STRUCT_CSKIP_NEW%// END_STRUCT_CSKIP_NEW%1 -%$$ - -$subhead left$$ -is the variable or parameter index (depending on flag) -for left operand in the comparison. - -$subhead right$$ -is the variable or parameter index (depending on flag) -for right operand in the comparison. - -$subhead max_left_right$$ -is the maximum of the left and right variable indices. -This is a variable index, so parameters correspond to index zero. - -$subhead i_arg$$ -index where this conditional skips arguments start -(in the vector or arguments for all operators). - -$end -*/ - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { -/*! -Information about one conditional expression. -*/ -// BEGIN_STRUCT_CEXP_INFO -struct struct_cexp_info { - addr_t i_op; - addr_t left; - addr_t right; - addr_t max_left_right; - CompareOp cop; - unsigned char flag; -}; -// END_STRUCT_CEXP_INFO - -// BEGIN_STRUCT_CSKIP_NEW -struct struct_cskip_new { - size_t left; - size_t right; - size_t max_left_right; - size_t i_arg; -}; -// END_STRUCT_CSKIP_NEW - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -namespace CppAD { namespace local { - template <> inline bool is_pod(void) - { return true; } -} } - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/csum_op_info.hpp b/build-config/cppad/include/cppad/local/optimize/csum_op_info.hpp deleted file mode 100644 index 3f8572f5..00000000 --- a/build-config/cppad/include/cppad/local/optimize/csum_op_info.hpp +++ /dev/null @@ -1,42 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_CSUM_OP_INFO_HPP -# define CPPAD_LOCAL_OPTIMIZE_CSUM_OP_INFO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include // defines addr_t - -/*! -\file csum_op_info.hpp -Information about one old variable that is part of a new CSumOp operation. -*/ - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { -/*! -Information about one old variable that is part of a new CSumOp operation. -*/ -struct struct_csum_op_info { - /// Pointer to first argument (child) for this old operator. - /// Set by the reverse sweep at beginning of optimization. - const addr_t* arg; - - /// Was this old variable added to the summation - /// (if not it was subtracted) - bool add; - - /// Operator for which this old variable is the result, NumRes(op) > 0. - OpCode op; -}; - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/csum_stacks.hpp b/build-config/cppad/include/cppad/local/optimize/csum_stacks.hpp deleted file mode 100644 index 1ebb5da4..00000000 --- a/build-config/cppad/include/cppad/local/optimize/csum_stacks.hpp +++ /dev/null @@ -1,47 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_CSUM_STACKS_HPP -# define CPPAD_LOCAL_OPTIMIZE_CSUM_STACKS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -/*! -\file csum_stacks.hpp -Information about one cumulative summation operation. -*/ - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { -/*! -Information about one cumulative summation operation. -*/ -struct struct_csum_stacks { - - /// old operator indices for this cummulative summation - std::stack op_info; - - /// old variable indices to be added - std::stack add_var; - - /// old variable indices to be subtracted - std::stack sub_var; - - /// dynamic parameter indices to be added - std::stack add_dyn; - - /// dynamic parameter indices to be subtracted - std::stack sub_dyn; -}; - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/get_cexp_info.hpp b/build-config/cppad/include/cppad/local/optimize/get_cexp_info.hpp deleted file mode 100644 index bb2e1f42..00000000 --- a/build-config/cppad/include/cppad/local/optimize/get_cexp_info.hpp +++ /dev/null @@ -1,260 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_GET_CEXP_INFO_HPP -# define CPPAD_LOCAL_OPTIMIZE_GET_CEXP_INFO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/*! -$begin optimize_get_cexp_info.hpp$$ -$spell - cexp - itr - op - iterator - bool - Exp - deallocate - Funap - Funav - Funrp - Funrv - num - var -$$ - -$section Information for Each Conditional Expression$$ - -$head Syntax$$ -$codei%get_cexp_info( - %play%, - %random_itr%, - %op_previous%, - %op_usage%, - %cexp2op%, - %cexp_set%, - %cexp_info%, - %skip_op_true%, - %skip_op_false% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - - -$head Restrictions$$ -Do not call this routine unless you are optimizing conditional expressions -and there are conditional expressions in the operation sequence. - -$head Base$$ -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type Base. - -$head play$$ -This is the old operation sequence. - -$head random_itr$$ -This is a random iterator for the old operation sequence. - -$head cexp2op$$ -This is the number of conditional expressions in the operation sequence -and must be non-zero. - -$head cexp_set$$ -This is a vector of sets, the i-th set, set[i], -is a set of elements for the i-th operator. -If e is an element of set[i], let j = e / 2 and k = e % 2. -If the comparison for the j-th conditional expression is equal to bool(k), -the i-th operator can be skipped (is not used by any of the results). -Note that j indexes the subset of operators that are conditional expressions -in the old operation sequence. - -$head cexp_info$$ -The input size of this vector must be zero. -Upon return cexp_info has size equal to the number of conditional expressions -in the operation sequence; i.e., the number of CExpOp operators. -The value cexp_info[j] is the information corresponding to the j-th -conditional expression in the operation sequence. -This vector is in the same order as the operation sequence; i.e. -if j1 > j2, cexp_info[j1].i_op > cexp_info[j2].i_op. -Note that skip_op_true and skip_op_false could be part of this structure, -but then we would allocate and deallocate two vectors for each conditional -expression in the operation sequence. - -$head skip_op_true$$ -This vector of sets is empty on input. -Upon return, the j-th set is the operators that are not used when -comparison result for cexp_info[j] is true. -Note that FunapOp, FunavOp, FunrpOp, and FunrvOp, are not in this -set and should be skipped when the corresponding AFunOp are skipped. - -$head skip_op_false$$ -This vector of sets is empty on input. -Upon return, the j-th set is the operators that are not used when -comparison result for cexp_info[j] is false. -Note that FunapOp, FunavOp, FunrpOp, and FunrvOp, are not in this -set and should be skipped when the corresponding AFunOp are skipped. - -$head op_previous$$ -This argument has size equal to the number of operators -in the operation sequence; i.e., num_op = play->nun_var_rec(). -If op_previous[i] == 0, no replacement was found for the i-th operator. -If op_previous[i] != 0, op_usage[ op_previous[i] ] == usage_t(yes_usage). - -$head op_usage$$ -This argument has size equal to the number of operators -in the operation sequence; i.e., num_op = play->nun_var_rec(). -The value op_usage[i] is the usage for -the i-th operator in the operation sequence. - -$end -*/ - -// BEGIN_PROTOTYPE -template -void get_cexp_info( - const player* play , - const play::const_random_iterator& random_itr , - const pod_vector& op_previous , - const pod_vector& op_usage , - const pod_vector& cexp2op , - const sparse::list_setvec& cexp_set , - vector& cexp_info , - sparse::list_setvec& skip_op_true , - sparse::list_setvec& skip_op_false ) -// END_PROTOTYPE -{ - CPPAD_ASSERT_UNKNOWN( cexp_set.n_set() > 0 ); - CPPAD_ASSERT_UNKNOWN( cexp_info.size() == 0 ); - - // number of operators in the tape - const size_t num_op = play->num_op_rec(); - CPPAD_ASSERT_UNKNOWN( op_usage.size() == num_op ); - CPPAD_ASSERT_UNKNOWN( op_previous.size() == num_op ); - // - // number of conditional expressions in the tape - size_t num_cexp_op = cexp2op.size(); - // - // initialize mapping from variable index to operator index - CPPAD_ASSERT_UNKNOWN( - size_t( (std::numeric_limits::max)() ) >= num_op - ); - // ---------------------------------------------------------------------- - // compute cexp_info - // ---------------------------------------------------------------------- - // - // initialize information for each conditional expression - cexp_info.resize(num_cexp_op); - skip_op_true.resize(num_cexp_op, num_op); - skip_op_false.resize(num_cexp_op, num_op); - // - for(size_t i = 0; i < num_cexp_op; i++) - { size_t i_op = size_t( cexp2op[i] ); - CPPAD_ASSERT_UNKNOWN( - op_previous[i_op] == 0 || op_usage[i_op] == usage_t(yes_usage) - ); - OpCode op; // operator - const addr_t* arg; // arguments - size_t i_var; // variable index of first result - random_itr.op_info(i_op, op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == CExpOp ); - // - struct_cexp_info info; - info.i_op = addr_t(i_op); - info.cop = CompareOp( arg[0] ); - info.flag = static_cast(arg[1]); - info.left = arg[2]; - info.right = arg[3]; - // - // max_left_right - addr_t index = 0; - if( arg[1] & 1 ) - index = std::max(index, info.left); - if( arg[1] & 2 ) - index = std::max(index, info.right); - info.max_left_right = index; - // - cexp_info[i] = info; - }; - // Determine which operators can be conditionally skipped - size_t i_op = 0; - while(i_op < num_op) - { size_t j_op = i_op; - bool keep = op_usage[i_op] != usage_t(no_usage); - keep &= op_usage[i_op] != usage_t(csum_usage); - keep &= op_previous[i_op] == 0; - if( keep ) - { sparse::list_setvec_const_iterator itr(cexp_set, i_op); - if( *itr != cexp_set.end() ) - { if( play->GetOp(i_op) == AFunOp ) - { // i_op is the first operations in this atomic function call. - // Find the last operation in this call. - ++j_op; - while( play->GetOp(j_op) != AFunOp ) - { switch( play->GetOp(j_op) ) - { case FunapOp: - case FunavOp: - case FunrpOp: - case FunrvOp: - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - ++j_op; - } - } - } - while( *itr != cexp_set.end() ) - { size_t element = *itr; - size_t index = element / 2; - bool compare = bool( element % 2 ); - if( compare == false ) - { // cexp_info[index].skip_op_false.push_back(i_op); - skip_op_false.post_element(index, i_op); - if( j_op != i_op ) - { // cexp_info[index].skip_op_false.push_back(j_op); - skip_op_false.post_element(index, j_op); - } - } - else - { // cexp_info[index].skip_op_true.push_back(i_op); - skip_op_true.post_element(index, i_op); - if( j_op != i_op ) - { // cexp_info[index].skip_op_true.push_back(j_op); - skip_op_true.post_element(index, j_op); - } - } - ++itr; - } - } - CPPAD_ASSERT_UNKNOWN( i_op <= j_op ); - i_op += (1 + j_op) - i_op; - } - // process postings for skip_op_false, skip_op_true - for(size_t i = 0; i < num_cexp_op; ++i) - { skip_op_false.process_post(i); - skip_op_true.process_post(i); - } - return; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/get_dyn_previous.hpp b/build-config/cppad/include/cppad/local/optimize/get_dyn_previous.hpp deleted file mode 100644 index e36f0bba..00000000 --- a/build-config/cppad/include/cppad/local/optimize/get_dyn_previous.hpp +++ /dev/null @@ -1,447 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_GET_DYN_PREVIOUS_HPP -# define CPPAD_LOCAL_OPTIMIZE_GET_DYN_PREVIOUS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file get_cexp_info.hpp -Create operator information tables -*/ - -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/*! -mapping from a dynamic parameter index to its arguments - -\param i_dyn -is the dynamic parameter index - -\param dyn_ind2par_ind -is the mapping from dynamic parameter index to parameter index -(size is number of dynamic parameters). - -\param dyn_par_is -i-th element is true (false) if i-th parameter is (is not) dynamic -(size is number of parameters). - -\param dyn_arg_offset -j-th element is the offset in dyn_par_arg of the first argument for j-th -dynamic parameter's operator (size is number of dynamic parameters). -This is only defined for dynamic parameters indices less than or equal i_dyn. - -\param dyn_par_arg -it the vector of arguments for all the dynamic parameter operators. -This is only defined for dynamic parameters indices less than or equal i_dyn. - -\param par_ind2dyn_ind -is the mapping from parameter index to dynamic parameter index -(size is number of parameters). This is only defined for parameter -indices less than or equal the parameter index corresponding to i_dyn. - -\param dyn_previous -is the mapping from dynamic parameter index to previous dynamic parameter -that can be used as a replacement (size is number of dynamic parameters). -This is only defined for dynamic parameters indices less than or equal i_dyn. - -\param arg_match -Size of this vector must be number of arguments for operator for i_dyn. -The input value of its elements does not matter. -Upn return it containts the parameter indices for the arguments -to use when matching this operator -Arguments that are dynamic prarameters, and have previous matches, -have been replaced by their previous matches. -*/ -inline void dyn_arg_match( - size_t i_dyn , - const pod_vector& dyn_ind2par_ind , - const pod_vector & dyn_par_is , - const pod_vector& dyn_arg_offset , - const pod_vector& dyn_par_arg , - const pod_vector& par_ind2dyn_ind , - const pod_vector& dyn_previous , - pod_vector& arg_match ) -{ - // number of dynamic parameters - addr_t num_dynamic_par = addr_t( dyn_ind2par_ind.size() ); - // - // check some assumptions - CPPAD_ASSERT_UNKNOWN( size_t( num_dynamic_par ) == dyn_arg_offset.size() ); - CPPAD_ASSERT_UNKNOWN( size_t( num_dynamic_par ) == dyn_previous.size() ); - CPPAD_ASSERT_UNKNOWN( dyn_par_is.size() == par_ind2dyn_ind.size() ); - // - // number of arguments for this operator - addr_t n_arg = addr_t( arg_match.size() ); - // - // index in dyn_par_arg of first argument for this operator - addr_t i_arg = dyn_arg_offset[i_dyn]; - // - // loop over arguments for this operator - for(addr_t j = 0; j < n_arg; ++j) - { // parameter index for this argument - addr_t j_par = dyn_par_arg[i_arg + j]; - CPPAD_ASSERT_UNKNOWN( j_par < dyn_ind2par_ind[i_dyn] ); - // - // map dynamic parameters arguments to previous matches - if( dyn_par_is[j_par] ) - { addr_t j_dyn = par_ind2dyn_ind[j_par]; - if( dyn_previous[j_dyn] != num_dynamic_par ) - { CPPAD_ASSERT_UNKNOWN( dyn_previous[j_dyn] < j_dyn ); - // previous dynamic parameter - j_dyn = dyn_previous[j_dyn]; - // correspoding parameter - j_par = dyn_ind2par_ind[j_dyn]; - } - } - arg_match[j] = j_par; - } - return; -} - -/*! -Get mapping from each dynamic parameter to a previous dynamic parameter -that can be used to replace it (if one exists). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param play -This is the old operation sequence. - -\param random_itr -This is a random iterator for the old operation sequence. - -\param par_usage -The size of this vector is the number of parameters in the -operation sequence.i.e., play->nun_var_rec(). -It is the usage counting previous operator optimization of operators. - -\param dyn_previous -The input size of this vector must be zero. -Upon return it has size equal to the number of dynamic parameters in the -operation sequence; i.e., num_dyn = play->num_dynamic_par(). -Let k = dyn_parvious[j]. If k == num_dyn, no replacement was found for the -j-th dynamic parameter. If k != num_dyn, the k-th dynamic parameter can be -used in place of the j-th dynamic parameter, k < j, dyn_previous[k] != num_dyn, -par_usage[dyn_ind2par_ind[k]] == true. -*/ - -template -void get_dyn_previous( - const player* play , - const play::const_random_iterator& random_itr , - pod_vector& par_usage , - pod_vector& dyn_previous ) -{ - // number of parameters in the recording - size_t num_par = play->num_par_rec(); - - // number of dynamic parameters in the recording - size_t num_dynamic_par = play->num_dynamic_par(); - - // number of independent dynamic parameters in the recording - size_t num_dynamic_ind = play->num_dynamic_ind(); - - // check some assumptions - CPPAD_ASSERT_UNKNOWN( dyn_previous.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( par_usage.size() == num_par ); - CPPAD_ASSERT_UNKNOWN( num_dynamic_par <= num_par ); - CPPAD_ASSERT_UNKNOWN( num_dynamic_ind <= num_dynamic_par ); - CPPAD_ASSERT_UNKNOWN( num_arg_dyn( ind_dyn ) == 0 ); - - // dynamic parameter information - dyn_previous.resize( num_dynamic_par ); - const pod_vector& dyn_ind2par_ind( play->dyn_ind2par_ind() ); - const pod_vector& dyn_par_is( play->dyn_par_is() ); - const pod_vector& dyn_par_op( play->dyn_par_op() ); - const pod_vector& dyn_par_arg( play->dyn_par_arg() ); - - // mapping from parameter index to dynamic parameter index - // only defined when dyn_par_is is true - pod_vector par_ind2dyn_ind(num_par); - - // mapping from dynamic parameter index to first argument index - pod_vector dyn_arg_offset(num_dynamic_par); - - // ---------------------------------------------------------------------- - // compute dyn_previous - // ---------------------------------------------------------------------- - sparse::list_setvec hash_table_dyn; - hash_table_dyn.resize(CPPAD_HASH_TABLE_SIZE, num_dynamic_par); - // - // Initialize in dyn_par_arg - // (independent dynamic parameters do not have any arguments) - size_t i_arg = 0; - // - // independent dynamic parameters - for(size_t i_dyn = 0; i_dyn < num_dynamic_ind; ++i_dyn) - { // parameter index - size_t i_par = size_t( dyn_ind2par_ind[i_dyn] ); - // dynamic parameter index is one greater because phantom parameter - // at index 0 is not dynamic - CPPAD_ASSERT_UNKNOWN( i_par == i_dyn + 1 ); - // mapping from parameter index to dynamic parameter index - par_ind2dyn_ind[i_par] = addr_t( i_dyn ); - // never get optimized out - dyn_previous[i_dyn] = addr_t( num_dynamic_par ); - } - // - // other dynamic parameters - for(size_t i_dyn = num_dynamic_ind; i_dyn < num_dynamic_par; ++i_dyn) - { // Initialize previous for this dynamic parameter. This is only - // defined for dynamic parameter indices less than or equal i_dyn - dyn_previous[i_dyn] = addr_t( num_dynamic_par ); - // - // mapping from dynamic parameter index to argument offset - // is only defined for j_dyn <= i_dyn - dyn_arg_offset[i_dyn] = addr_t( i_arg ); - // - // parameter index for this dynamic parameter - size_t i_par = size_t( dyn_ind2par_ind[i_dyn] ); - // - // mapping from parameter indices to dynamic parameter indices - // is only defined when dyn_par_is[i_par] is true and for parameter - // indices less than or equal i_par - CPPAD_ASSERT_UNKNOWN( dyn_par_is[i_par] ); - par_ind2dyn_ind[i_par] = addr_t( i_dyn ); - // - // operator for this dynamic parameter - op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] ); - // - // temporary used below and decaled here to reduce memory allocation - pod_vector arg_match; - // - // temporaries used below and decaled here to reduce indentation level - bool match; - size_t code; - size_t count; - // - // check for a previous match for i_dyn - if( par_usage[i_par] ) switch( op ) - { - // --------------------------------------------------------------- - // unary operators - case abs_dyn: - case acos_dyn: - case acosh_dyn: - case asin_dyn: - case asinh_dyn: - case atan_dyn: - case atanh_dyn: - case cos_dyn: - case cosh_dyn: - case erf_dyn: - case erfc_dyn: - case exp_dyn: - case expm1_dyn: - case fabs_dyn: - case log_dyn: - case log1p_dyn: - case sign_dyn: - case sin_dyn: - case sinh_dyn: - case sqrt_dyn: - case tan_dyn: - case tanh_dyn: - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 1); - CPPAD_ASSERT_UNKNOWN( dyn_par_is[i_par] ); - { size_t num_arg = 1; - arg_match.resize(num_arg); - dyn_arg_match( - i_dyn, - dyn_ind2par_ind, - dyn_par_is, - dyn_arg_offset, - dyn_par_arg, - par_ind2dyn_ind, - dyn_previous, - arg_match - ); - opcode_t op_t = opcode_t(op); - code = optimize_hash_code( - op_t, num_arg, arg_match.data() - ); - // - // iterator for the set with this hash code - sparse::list_setvec_const_iterator itr(hash_table_dyn, code); - // - // check for a match - count = 0; - match = false; - while( ! match && *itr != num_dynamic_par ) - { ++count; - // - // candidate for current dynamic parameter - size_t k_dyn = *itr; - CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn ); - // - // argument offset for the candidate - addr_t k_arg = dyn_arg_offset[k_dyn]; - // - match = op_t == dyn_par_op[k_dyn]; - match &= arg_match[0] == dyn_par_arg[k_arg + 0]; - if( ! match ) - ++itr; - } - if( match ) - { size_t k_dyn = *itr; - CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn ); - dyn_previous[i_dyn] = addr_t( k_dyn ); - } - else - { CPPAD_ASSERT_UNKNOWN( count < 11 ); - if( count == 10 ) - { // restart list for this hash code - hash_table_dyn.clear(code); - } - // Add this entry to hash table. - // Not using post_element becasue we need to iterate for - // this code before adding another element for this code. - hash_table_dyn.add_element(code, i_dyn); - } - } - break; - - // --------------------------------------------------------------- - // binary operators - case add_dyn: - case div_dyn: - case mul_dyn: - case pow_dyn: - case sub_dyn: - case zmul_dyn: - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 2); - CPPAD_ASSERT_UNKNOWN( dyn_par_is[i_par] ); - match = false; - { size_t num_arg = 2; - arg_match.resize(num_arg); - dyn_arg_match( - i_dyn, - dyn_ind2par_ind, - dyn_par_is, - dyn_arg_offset, - dyn_par_arg , - par_ind2dyn_ind, - dyn_previous, - arg_match - ); - opcode_t op_t = opcode_t(op); - code = optimize_hash_code( - op_t, num_arg, arg_match.data() - ); - // - // iterator for the set with this hash code - sparse::list_setvec_const_iterator itr(hash_table_dyn, code); - // - // check for a match - count = 0; - while( ! match && *itr != num_dynamic_par ) - { ++count; - // - // candidate for current dynamic parameter - size_t k_dyn = *itr; - CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn ); - // - // argument offset for the candidate - addr_t k_arg = dyn_arg_offset[k_dyn]; - // - match = op_t == dyn_par_op[k_dyn]; - match &= arg_match[0] == dyn_par_arg[k_arg + 0]; - match &= arg_match[1] == dyn_par_arg[k_arg + 1]; - if( ! match ) - ++itr; - } - if( match ) - { size_t k_dyn = *itr; - CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn ); - dyn_previous[i_dyn] = addr_t( k_dyn ); - } - } - if( (! match) & ( (op == add_dyn) | (op == mul_dyn) ) ) - { size_t num_arg = 2; - std::swap( arg_match[0], arg_match[1] ); - opcode_t op_t = opcode_t(op); - size_t code_swp = optimize_hash_code( - op_t, num_arg, arg_match.data() - ); - // - // iterator for the set with this hash code - sparse::list_setvec_const_iterator itr(hash_table_dyn, code_swp); - // - // check for a match - while( ! match && *itr != num_dynamic_par ) - { // - // candidate for current dynamic parameter - size_t k_dyn = *itr; - CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn ); - // - // argument offset for the candidate - addr_t k_arg = dyn_arg_offset[k_dyn]; - // - match = op_t == dyn_par_op[k_dyn]; - match &= arg_match[0] == dyn_par_arg[k_arg + 0]; - match &= arg_match[1] == dyn_par_arg[k_arg + 1]; - if( ! match ) - ++itr; - } - if( match ) - { size_t k_dyn = *itr; - CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn ); - dyn_previous[i_dyn] = addr_t( k_dyn ); - } - } - if( ! match ) - { CPPAD_ASSERT_UNKNOWN( count < 11 ); - if( count == 10 ) - { // restart list for this hash code - hash_table_dyn.clear(code); - } - // Add the entry to hash table - // Not using post_element becasue we need to iterate for - // this code before adding another element for this code. - hash_table_dyn.add_element(code, i_dyn); - } - - // -------------------------------------------------------------- - // skipping these cases for now - case dis_dyn: - case cond_exp_dyn: - case atom_dyn: - case result_dyn: - break; - - - // -------------------------------------------------------------- - // should be no other cases; e.g., no ind_dyn or number_dyn. - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - i_arg += num_arg_dyn(op); - if( op == atom_dyn ) - { CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 0 ); - size_t n = size_t( dyn_par_arg[i_arg + 1] ); - size_t m = size_t( dyn_par_arg[i_arg + 2] ); - size_t n_arg = 5 + n + m; - i_arg += n_arg; - } - } -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/get_op_previous.hpp b/build-config/cppad/include/cppad/local/optimize/get_op_previous.hpp deleted file mode 100644 index 312a8470..00000000 --- a/build-config/cppad/include/cppad/local/optimize/get_op_previous.hpp +++ /dev/null @@ -1,269 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_GET_OP_PREVIOUS_HPP -# define CPPAD_LOCAL_OPTIMIZE_GET_OP_PREVIOUS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { -/* -$begin optimize_get_op_previous$$ -$spell - itr - iterator - bool - Exp - num - var - Op - cexp - Arg - Res -$$ - -$section Get Mapping From Op to Previous Op That is Equivalent$$ - -$head Syntax$$ -$icode%exceed_collision_limit% = get_op_previous( - %collision_limit%, - %play%, - %random_itr%, - %cexp_set%, - %op_previous%, - %op_usage% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Base$$ -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type Base. - -$head collision_limit$$ -is the maximum number of collisions (matches) -allowed in the hash expression has table. - -$head play$$ -is the old operation sequence. - -$head random_itr$$ -is a random iterator for the old operation sequence. - -$head cexp_set$$ -set[i] is a set of elements for the i-th operator. -Suppose that e is an element of set[i], j = e / 2, k = e % 2. -If the comparison for the j-th conditional expression is equal to bool(k), -the i-th operator can be skipped (is not used by any of the results). -Note the j indexes the CExpOp operators in the operation sequence. -On input, cexp_set is does not count previous optimization. -On output, it does count previous optimization. - -$head op_previous$$ -The input size of this vector must be zero. -Upon return it has size equal to the number of operators -in the operation sequence; i.e., num_op = play->nun_var_rec(). -Let j = op_previous[i]. If j = 0, no replacement was found for i-th operator. -If j != 0: -$list number$$ -j < i -$lnext -op_previous[j] == 0 -$lnext -op_usage[j] == usage_t(yes_usage) -$lnext -i-th operator has NumArg(op) <= 3 -$lnext -i-th operator has 0 < NumRes(op) -$lnext -i-th operator is not one of the following: -$nospell PriOp, ParOp, InvOp, EndOp, CexpOp, BeginOp.$$ -$lnext -i-th operator is not one of the load store operator: -$nospell LtpvOp, LtvpOp, LtvvOp, StppOp, StpvOp, StvpOp, StvvOp.$$ -$lnext -i-th operator is not a atomic function operator: -$nospell AFunOp, FunapOp, FunavOp, FunrpOp, FunrvOp.$$ -$lend - -$head op_usage$$ -The size of this vector is the number of operators in the -old operation sequence.i.e., play->nun_var_rec(). -On input, op_usage[i] is the usage for -the i-th operator in the operation sequence not counting previous -optimization. -On output, it is the usage counting previous operator optimization. - -$head exceed_collision_limit$$ -If the $icode collision_limit$$ is exceeded (is not exceeded), -the return value is true (false). - -$end -*/ - -// BEGIN_PROTOTYPE -template -bool get_op_previous( - size_t collision_limit , - const player* play , - const play::const_random_iterator& random_itr , - sparse::list_setvec& cexp_set , - pod_vector& op_previous , - pod_vector& op_usage ) -// END_PROTOTYPE -{ bool exceed_collision_limit = false; - // - // number of operators in the tape - const size_t num_op = random_itr.num_op(); - CPPAD_ASSERT_UNKNOWN( op_previous.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( op_usage.size() == num_op ); - op_previous.resize( num_op ); - // - // number of conditional expressions in the tape - // - // initialize mapping from variable index to operator index - CPPAD_ASSERT_UNKNOWN( - size_t( (std::numeric_limits::max)() ) >= num_op - ); - // ---------------------------------------------------------------------- - // compute op_previous - // ---------------------------------------------------------------------- - sparse::list_setvec hash_table_op; - hash_table_op.resize(CPPAD_HASH_TABLE_SIZE, num_op); - // - pod_vector work_bool; - pod_vector work_addr_t; - for(size_t i_op = 0; i_op < num_op; ++i_op) - { op_previous[i_op] = 0; - - if( op_usage[i_op] == usage_t(yes_usage) ) - switch( random_itr.get_op(i_op) ) - { - // ---------------------------------------------------------------- - // these operators never match pevious operators - case BeginOp: - case CExpOp: - case CSkipOp: - case CSumOp: - case EndOp: - case InvOp: - case LdpOp: - case LdvOp: - case ParOp: - case PriOp: - case StppOp: - case StpvOp: - case StvpOp: - case StvvOp: - case AFunOp: - case FunapOp: - case FunavOp: - case FunrpOp: - case FunrvOp: - break; - - // ---------------------------------------------------------------- - // check for a previous match - case AbsOp: - case AcosOp: - case AcoshOp: - case AddpvOp: - case AddvvOp: - case AsinOp: - case AsinhOp: - case AtanOp: - case AtanhOp: - case CosOp: - case CoshOp: - case DisOp: - case DivpvOp: - case DivvpOp: - case DivvvOp: - case EqpvOp: - case EqvvOp: - case ErfOp: - case ErfcOp: - case ExpOp: - case Expm1Op: - case LepvOp: - case LevpOp: - case LevvOp: - case LogOp: - case Log1pOp: - case LtpvOp: - case LtvpOp: - case LtvvOp: - case MulpvOp: - case MulvvOp: - case NepvOp: - case NevvOp: - case PowpvOp: - case PowvpOp: - case PowvvOp: - case SignOp: - case SinOp: - case SinhOp: - case SqrtOp: - case SubpvOp: - case SubvpOp: - case SubvvOp: - case TanOp: - case TanhOp: - case ZmulpvOp: - case ZmulvpOp: - case ZmulvvOp: - exceed_collision_limit |= match_op( - collision_limit, - random_itr, - op_previous, - i_op, - hash_table_op, - work_bool, - work_addr_t - ); - if( op_previous[i_op] != 0 ) - { // like a unary operator that assigns i_op equal to previous. - size_t previous = size_t( op_previous[i_op] ); - bool sum_op = false; - CPPAD_ASSERT_UNKNOWN( previous < i_op ); - op_inc_arg_usage( - play, sum_op, i_op, previous, op_usage, cexp_set - ); - } - break; - - // ---------------------------------------------------------------- - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - } - /* --------------------------------------------------------------------- - // Print out hash code usage summary - CppAD::vector count(collision_limit + 1); - for(size_t i = 0; i <= collision_limit; ++i) - count[i] = 0; - for(size_t code = 0; code < CPPAD_HASH_TABLE_SIZE; ++code) - { size_t size = hash_table_op.number_elements(code); - ++count[size]; - } - std::cout << "count = " << count << "\n"; - --------------------------------------------------------------------- */ - return exceed_collision_limit; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/get_op_usage.hpp b/build-config/cppad/include/cppad/local/optimize/get_op_usage.hpp deleted file mode 100644 index 504f2f85..00000000 --- a/build-config/cppad/include/cppad/local/optimize/get_op_usage.hpp +++ /dev/null @@ -1,853 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_GET_OP_USAGE_HPP -# define CPPAD_LOCAL_OPTIMIZE_GET_OP_USAGE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/// Is this an addition or subtraction operator -inline bool op_add_or_sub( - OpCode op ///< operator we are checking -) -{ bool result; - switch(op) - { - case AddpvOp: - case AddvvOp: - case SubpvOp: - case SubvpOp: - case SubvvOp: - result = true; - break; - - default: - result = false; - break; - } - return result; -} - -/*! -$begin optimize_op_inc_arg_usage$$ -$spell - cexp - op - arg - csum - optimizer -$$ - -$section -Increase Argument Usage and Propagate cexp_set From Result to Argument -$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_OP_INC_ARG_USAGE%// END_PROTOTYPE%1 -%$$ - - -$head play$$ -is the player for the old operation sequence. - -$head check_csum$$ -is result an addition or subtraction operator, -and the optimizer is allowed to generate cumulative sum operators. - -$head i_result$$ -is the operator index for the result operator. -There are no posting waiting to be processed for the corresponding cexp_set. - -$head i_arg$$ -is the operator index for the argument to the result operator. -There may be postings waiting to be processed for the corresponding cexp_set. - -$head op_usage$$ -structure that holds the information for each of the operators. -The output value of op_usage[i_arg] is increased; to be specific, -If check_csum is true and the input value of op_usage[i_arg] -is usage_t(no_usage), its output value is usage_t(csum_usage). -Otherwise, the output value of op_usage[i_arg] is usage_t(yes_usage). - -$head cexp_set$$ -This is a vector of sets with one set for each operator. -We denote the i-th set by set[i]. -These are the conditional expression conditions that must be -satisfied for this argument to be used. - -$list number$$ -In the special case where cexp_set.n_set() is zero, -cexp_set is not changed. -$lnext -If cexp_set.n_set() != 0 and op_usage[i_arg] == usage_t(no_usage), -the input value of set[i_arg] must be empty. -In this case the output value if set[i_arg] is equal to set[i_result] -(which may also be empty). -$lnext -If cexp_set.n_set() != 0 and op_usage[i_arg] != usage_t(no_usage), -the output value of set[i_arg] is the intersection of -its input value and set[i_result]. -$lend - -$end -*/ -// BEGIN_OP_INC_ARG_USAGE -template -void op_inc_arg_usage( - const player* play , - bool check_csum , - size_t i_result , - size_t i_arg , - pod_vector& op_usage , - sparse::list_setvec& cexp_set ) -// END_PROTOTYPE -{ // value of argument input on input to this routine - enum_usage arg_usage = enum_usage( op_usage[i_arg] ); - // - // new value for usage - op_usage[i_arg] = usage_t(yes_usage); - if( check_csum ) - { if( arg_usage == no_usage ) - { OpCode op_a = play->GetOp(i_arg); - if( op_add_or_sub( op_a ) ) - { op_usage[i_arg] = usage_t(csum_usage); - } - } - } - // - // cexp_set - if( cexp_set.n_set() == 0 ) - return; - // - if( arg_usage == no_usage ) - { // set[i_arg] = set[i_result] - // not necessary to process posts for set i_result - cexp_set.assignment(i_arg, i_result, cexp_set); - } - else - { // set[i_arg] = set[i_arg] intersect set[i_result] - // is necessary to process postts for set i_arg - cexp_set.process_post(i_arg); - cexp_set.binary_intersection(i_arg, i_arg, i_result, cexp_set); - } - // - return; -} - -/*! -$begin optimize_get_op_usage$$ -$spell - Ind - var - itr - dep_taddr - cexp - vecad - Addr - iterator - NumRes - PriOp - Exp - bool - Vec -$$ - -$section -Use Reverse Activity Analysis to Get Usage Information for Each Operator -$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_GET_OP_USAGE%// END_PROTOTYPE%1 -%$$ - -$head Base$$ -Base type for the operator; i.e., this operation was recorded -using $codei%AD<%Base%>%$$ and computations by this routine are done -using type $icode Base$$. - -$head Addr$$ -Type used by random iterator for the player. - -$head cumulative_sum_op$$ -If this is true (false), cumulative summation operator are allowed -(not allowed) to be generated by the optimization. - -$head compare_op$$ -if this is true, arguments are considered used if they appear in compare -operators. This is a side effect because compare operators have boolean -results (and the result is not in the tape; i.e. NumRes(op) is zero -for these operators. (This is an example of a side effect.) - -$head print_for_op$$ -if this is true, arguments are considered used if they appear in -print forward operators; i.e., PriOp. -This is also a side effect; i.e. NumRes(PriOp) is zero. - -$head conditional_skip$$ -If this is true, -the conditional expression information cexp_info will be calculated. -This may be time intensive and may not have much benefit in the optimized -recording. - - -$head play$$ -This is the operation sequence. - -$head random_itr$$ -This is a random iterator for the operation sequence. - -$head dep_taddr$$ -is a vector of indices for the dependent variables -(where the reverse activity analysis starts). - -$head cexp2op$$ -The input size of this vector must be zero. -Upon return it has size equal to the number of conditional expressions, -CExpOp operators. The value $icode%cexp2op[%j%]%$$ is the operator -index corresponding to the $th j$$ conditional expressions. - -$head cexp_set$$ -This is a vector of sets that is empty on input. -If $icode conditional_skip$$ is false, $icode cexp_usage$$ is not modified. -Otherwise, set[i] is a set of elements for the i-th operator. -Suppose that e is an element of set[i], j = e / 2, k = e % 2. -If the comparison for the j-th conditional expression is equal to bool(k), -the i-th operator can be skipped (is not used by any of the results). -Note that j indexes the CExpOp operators in the operation sequence. - -$head vecad_used$$ -The input size of this vector must be zero. -Upon return it has size equal to the number of VecAD vectors -in the operations sequences; i.e., play->num_var_vecad_rec(). -The VecAD vectors are indexed in the order that their indices appear -in the one large play->GetVecInd that holds all the VecAD vectors. - -$head op_usage$$ -The input size of this vector must be zero. -Upon return it has size equal to the number of operators -in the operation sequence; i.e., num_op = play->nun_var_rec(). -The value $icode%op_usage%[%i%]%$$ has been set to the usage for -the i-th operator in the operation sequence. -Atomic function calls are a special case, -the first and second AFunOp have usage corresponding to the entire call. -The arguments have the usage for particular parameter or variable. -This usage is only for creating variables, not for creating -dynamic parameters. - -$end -*/ -// BEGIN_GET_OP_USAGE -template -void get_op_usage( - bool conditional_skip , - bool compare_op , - bool print_for_op , - bool cumulative_sum_op , - const player* play , - const play::const_random_iterator& random_itr , - const pod_vector& dep_taddr , - pod_vector& cexp2op , - sparse::list_setvec& cexp_set , - pod_vector& vecad_used , - pod_vector& op_usage ) -// END_PROTOTYPE -{ - CPPAD_ASSERT_UNKNOWN( cexp_set.n_set() == 0 ); - CPPAD_ASSERT_UNKNOWN( vecad_used.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( op_usage.size() == 0 ); - - // number of operators in the tape - const size_t num_op = play->num_op_rec(); - // - // initialize mapping from variable index to operator index - CPPAD_ASSERT_UNKNOWN( - size_t( (std::numeric_limits::max)() ) >= num_op - ); - // ----------------------------------------------------------------------- - // information about current operator - OpCode op; // operator - const addr_t* arg; // arguments - size_t i_op; // operator index - size_t i_var; // variable index of first result - // ----------------------------------------------------------------------- - // information about atomic function calls - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - enum_atom_state atom_state; - // - // work space used by user atomic functions - vector atom_x; // value of parameters in x - vector type_x; // type for each argument - vector atom_ix; // variables indices for argument vector - vector depend_y; // results that are used - vector depend_x; // arguments that are used - // - // parameter information (used by atomic function calls) -# ifndef NDEBUG - size_t num_par = play->num_par_rec(); -# endif - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - // ----------------------------------------------------------------------- - // vecad information - size_t num_vecad = play->num_var_vecad_rec(); - size_t num_vecad_ind = play->num_var_vecad_ind_rec(); - // - vecad_used.resize(num_vecad); - for(size_t i = 0; i < num_vecad; i++) - vecad_used[i] = false; - // - vector arg2vecad(num_vecad_ind); - for(size_t i = 0; i < num_vecad_ind; i++) - arg2vecad[i] = num_vecad; // invalid value - size_t arg_0 = 1; // value of arg[0] for theh first vecad - for(size_t i = 0; i < num_vecad; i++) - { - // mapping from arg[0] value to index for this vecad object. - arg2vecad[arg_0] = i; - // - // length of this vecad object - size_t length = play->GetVecInd(arg_0 - 1); - // - // set to proper index in GetVecInd for next VecAD arg[0] value - arg_0 += length + 1; - } - CPPAD_ASSERT_UNKNOWN( arg_0 == num_vecad_ind + 1 ); - // ----------------------------------------------------------------------- - // conditional expression information - // - size_t num_cexp_op = 0; - if( conditional_skip ) - { for(i_op = 0; i_op < num_op; ++i_op) - { if( random_itr.get_op(i_op) == CExpOp ) - { // count the number of conditional expressions. - ++num_cexp_op; - } - } - } - // - cexp2op.resize( num_cexp_op ); - // - // number of sets - size_t num_set = 0; - if( conditional_skip && num_cexp_op > 0) - num_set = num_op; - // - // conditional expression index = element / 2 - // conditional expression compare = bool ( element % 2) - size_t end_set = 2 * num_cexp_op; - // - if( num_set > 0 ) - cexp_set.resize(num_set, end_set); - // ----------------------------------------------------------------------- - // initilaize operator usage for reverse dependency analysis. - op_usage.resize( num_op ); - for(i_op = 0; i_op < num_op; ++i_op) - op_usage[i_op] = usage_t(no_usage); - for(size_t i = 0; i < dep_taddr.size(); i++) - { i_op = random_itr.var2op(dep_taddr[i]); - op_usage[i_op] = usage_t(yes_usage); // dependent variables - } - // ---------------------------------------------------------------------- - // Reverse pass to compute usage and cexp_set for each operator - // ---------------------------------------------------------------------- - // - // Initialize reverse pass - size_t last_atom_i_op = 0; - size_t cexp_index = num_cexp_op; - atom_state = end_atom; - i_op = num_op; - while(i_op != 0 ) - { --i_op; - if( num_set > 0 ) - { // no more elements will be added to this set - cexp_set.process_post(i_op); - } - // - // this operator information - random_itr.op_info(i_op, op, arg, i_var); - // - // Is the result of this operation used. - // (This only makes sense when NumRes(op) > 0.) - usage_t use_result = op_usage[i_op]; - // - bool check_csum = false; - switch( op ) - { - // ============================================================= - // normal operators - // ============================================================= - - // Only one variable with index arg[0] - case SubvpOp: - check_csum = cumulative_sum_op; - // - case AbsOp: - case AcosOp: - case AcoshOp: - case AsinOp: - case AsinhOp: - case AtanOp: - case AtanhOp: - case CosOp: - case CoshOp: - case DivvpOp: - case ErfOp: - case ErfcOp: - case ExpOp: - case Expm1Op: - case LogOp: - case Log1pOp: - case PowvpOp: - case SignOp: - case SinOp: - case SinhOp: - case SqrtOp: - case TanOp: - case TanhOp: - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - if( use_result != usage_t(no_usage) ) - { size_t j_op = random_itr.var2op(size_t(arg[0])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - break; // -------------------------------------------- - - // Only one variable with index arg[1] - case AddpvOp: - case SubpvOp: - check_csum = cumulative_sum_op; - // - case DisOp: - case DivpvOp: - case MulpvOp: - case PowpvOp: - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - if( use_result != usage_t(no_usage) ) - { size_t j_op = random_itr.var2op(size_t(arg[1])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - break; // -------------------------------------------- - - // arg[0] and arg[1] are the only variables - case AddvvOp: - case SubvvOp: - check_csum = cumulative_sum_op; - // - case DivvvOp: - case MulvvOp: - case PowvvOp: - case ZmulvvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - if( use_result != usage_t(no_usage) ) - { for(size_t i = 0; i < 2; i++) - { size_t j_op = random_itr.var2op(size_t(arg[i])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - } - break; // -------------------------------------------- - - // Conditional expression operators - // arg[2], arg[3], arg[4], arg[5] are parameters or variables - case CExpOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - if( conditional_skip ) - { --cexp_index; - cexp2op[ cexp_index ] = addr_t(i_op); - } - if( use_result != usage_t(no_usage) ) - { CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - // propgate from result to left argument - if( arg[1] & 1 ) - { size_t j_op = random_itr.var2op(size_t(arg[2])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - // propgate from result to right argument - if( arg[1] & 2 ) - { size_t j_op = random_itr.var2op(size_t(arg[3])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - // are if_true and if_false cases the same variable - bool same_variable = (arg[1] & 4) != 0; - same_variable &= (arg[1] & 8) != 0; - same_variable &= arg[4] == arg[5]; - // - // if_true - if( arg[1] & 4 ) - { size_t j_op = random_itr.var2op(size_t(arg[4])); - bool can_skip = conditional_skip & (! same_variable); - can_skip &= op_usage[j_op] == usage_t(no_usage); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - if( can_skip ) - { // j_op corresponds to the value used when the - // comparison result is true. It can be skipped when - // the comparison is false (0). - size_t element = 2 * cexp_index + 0; - cexp_set.post_element(j_op, element); - // - op_usage[j_op] = usage_t(yes_usage); - } - } - // - // if_false - if( arg[1] & 8 ) - { size_t j_op = random_itr.var2op(size_t(arg[5])); - bool can_skip = conditional_skip & (! same_variable); - can_skip &= op_usage[j_op] == usage_t(no_usage); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - if( can_skip ) - { // j_op corresponds to the value used when the - // comparison result is false. It can be skipped when - // the comparison is true (0). - size_t element = 2 * cexp_index + 1; - cexp_set.post_element(j_op, element); - // - op_usage[j_op] = usage_t(yes_usage); - } - } - } - break; // -------------------------------------------- - - // Operations that are never used - // (new CSkip options are generated if conditional_skip is true) - case CSkipOp: - case ParOp: - break; - - // Operators that are always used - case InvOp: - case BeginOp: - case EndOp: - op_usage[i_op] = usage_t(yes_usage); - break; // ----------------------------------------------- - - // The print forward operator - case PriOp: - CPPAD_ASSERT_NARG_NRES(op, 5, 0); - if( print_for_op ) - { op_usage[i_op] = usage_t(yes_usage); - if( arg[0] & 1 ) - { // arg[1] is a variable - size_t j_op = random_itr.var2op(size_t(arg[1])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - if( arg[0] & 2 ) - { // arg[3] is a variable - size_t j_op = random_itr.var2op(size_t(arg[3])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - } - break; // ----------------------------------------------------- - - // ============================================================= - // Comparison operators - // ============================================================= - - // Compare operators where arg[1] is only variable - case LepvOp: - case LtpvOp: - case EqpvOp: - case NepvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - if( compare_op ) - { op_usage[i_op] = usage_t(yes_usage); - // - size_t j_op = random_itr.var2op(size_t(arg[1])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - break; // ---------------------------------------------- - - // Compare operators where arg[0] is only variable - case LevpOp: - case LtvpOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - if( compare_op ) - { op_usage[i_op] = usage_t(yes_usage); - // - size_t j_op = random_itr.var2op(size_t(arg[0])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - break; // ---------------------------------------------- - - // Compare operators where arg[0] and arg[1] are variables - case LevvOp: - case LtvvOp: - case EqvvOp: - case NevvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - if( compare_op ) - { op_usage[i_op] = usage_t(yes_usage); - // - for(size_t i = 0; i < 2; i++) - { size_t j_op = random_itr.var2op(size_t(arg[i])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - } - break; // ---------------------------------------------- - - // ============================================================= - // VecAD operators - // ============================================================= - - // load operator using a parameter index - case LdpOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - if( use_result != usage_t(no_usage) ) - { size_t i_vec = arg2vecad[ arg[0] ]; - vecad_used[i_vec] = true; - } - break; // -------------------------------------------- - - // load operator using a variable index - case LdvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - if( use_result != usage_t(no_usage) ) - { size_t i_vec = arg2vecad[ arg[0] ]; - vecad_used[i_vec] = true; - // - size_t j_op = random_itr.var2op(size_t(arg[1])); - op_usage[j_op] = usage_t(yes_usage); - } - break; // -------------------------------------------- - - // Store a variable using a parameter index - case StpvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - if( vecad_used[ arg2vecad[ arg[0] ] ] ) - { op_usage[i_op] = usage_t(yes_usage); - // - size_t j_op = random_itr.var2op(size_t(arg[2])); - op_usage[j_op] = usage_t(yes_usage); - } - break; // -------------------------------------------- - - // Store a variable using a variable index - case StvvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - if( vecad_used[ arg2vecad[ arg[0] ] ] ) - { op_usage[i_op] = usage_t(yes_usage); - // - size_t j_op = random_itr.var2op(size_t(arg[1])); - op_usage[j_op] = usage_t(yes_usage); - size_t k_op = random_itr.var2op(size_t(arg[2])); - op_usage[k_op] = usage_t(yes_usage); - } - break; // ----------------------------------------------------- - - // ============================================================= - // cumulative summation operator - // ============================================================ - case CSumOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 ); - { - for(size_t i = 5; i < size_t(arg[2]); i++) - { size_t j_op = random_itr.var2op(size_t(arg[i])); - op_inc_arg_usage( - play, check_csum, i_op, j_op, op_usage, cexp_set - ); - } - } - break; - - // ============================================================= - // user defined atomic operators - // ============================================================ - - case AFunOp: - // start or end atomic operation sequence - if( atom_state == end_atom ) - { // reverse_user using random_itr instead of play - atom_index = size_t(arg[0]); - atom_old = size_t(arg[1]); - atom_n = size_t(arg[2]); - atom_m = size_t(arg[3]); - atom_j = atom_n; - atom_i = atom_m; - atom_state = ret_atom; - // ------------------------------------------------------- - last_atom_i_op = i_op; - CPPAD_ASSERT_UNKNOWN( i_op > atom_n + atom_m + 1 ); - CPPAD_ASSERT_UNKNOWN( - op_usage[last_atom_i_op] == usage_t(no_usage) - ); -# ifndef NDEBUG - if( cexp_set.n_set() > 0 ) - { cexp_set.process_post(last_atom_i_op); - CPPAD_ASSERT_UNKNOWN( - cexp_set.number_elements(last_atom_i_op) == 0 - ); - } -# endif - // - atom_x.resize( atom_n ); - type_x.resize( atom_n ); - atom_ix.resize( atom_n ); - // - depend_y.resize( atom_m ); - depend_x.resize( atom_n ); - for(size_t i = 0; i < atom_m; i++) - depend_y[ i ] = false; - } - else - { // reverse_user using random_itr instead of play - CPPAD_ASSERT_UNKNOWN( atom_state == start_atom ); - CPPAD_ASSERT_UNKNOWN( atom_n == size_t(arg[2]) ); - CPPAD_ASSERT_UNKNOWN( atom_m == size_t(arg[3]) ); - CPPAD_ASSERT_UNKNOWN( atom_j == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - atom_state = end_atom; - // ------------------------------------------------------- - CPPAD_ASSERT_UNKNOWN( - i_op + atom_n + atom_m + 1 == last_atom_i_op - ); - if( op_usage[last_atom_i_op] != usage_t(no_usage) ) - { // call atomic function for this operation - sweep::call_atomic_rev_depend( - atom_index, atom_old, atom_x, type_x, depend_x, depend_y - ); - for(size_t j = 0; j < atom_n; j++) - if( depend_x[j] ) - { // The parameter or variable correspnding to the j-th - // argument gets used - op_usage[i_op + 1 + j] = true; - if( type_x[j] == variable_enum ) - { CPPAD_ASSERT_UNKNOWN( atom_ix[j] > 0 ); - if( depend_x[j] ) - { size_t j_op = random_itr.var2op(atom_ix[j]); - op_inc_arg_usage(play, check_csum, - last_atom_i_op, j_op, op_usage, cexp_set - ); - } - } - } - } - // copy set infomation from last to first - if( cexp_set.n_set() > 0 ) - { cexp_set.process_post(last_atom_i_op); - cexp_set.assignment(i_op, last_atom_i_op, cexp_set); - } - // copy usage information from last to first - op_usage[i_op] = op_usage[last_atom_i_op]; - } - break; // ------------------------------------------------------- - - case FunapOp: - // parameter argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - // - // reverse_user using random_itr instead of play - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( 0 < atom_j && atom_j <= atom_n ); - --atom_j; - if( atom_j == 0 ) - atom_state = start_atom; - // ------------------------------------------------------------- - atom_ix[atom_j] = 0; - // - // parameter arguments - atom_x[atom_j] = parameter[arg[0]]; - if( play->dyn_par_is()[arg[0]] ) - type_x[atom_j] = dynamic_enum; - else - type_x[atom_j] = constant_enum; - // - break; - - case FunavOp: - // variable argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - // - // reverse_user using random_itr instead of play - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( 0 < atom_j && atom_j <= atom_n ); - --atom_j; - if( atom_j == 0 ) - atom_state = start_atom; - // ------------------------------------------------------------- - atom_ix[atom_j] = size_t(arg[0]); - // - // variable arguments as parameters - atom_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - type_x[atom_j] = variable_enum; - // - break; - - case FunrvOp: - // variable result in an atomic operation sequence - // - // reverse_user using random_itr instead of play - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( 0 < atom_i && atom_i <= atom_m ); - --atom_i; - if( atom_i == 0 ) - atom_state = arg_atom; - // ------------------------------------------------------------- - if( use_result ) - { depend_y[atom_i] = true; - op_inc_arg_usage( - play, check_csum, i_op, last_atom_i_op, op_usage, cexp_set - ); - } - break; // -------------------------------------------------------- - - case FunrpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - // - // reverse_user using random_itr instead of play - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( 0 < atom_i && atom_i <= atom_m ); - --atom_i; - if( atom_i == 0 ) - atom_state = arg_atom; - break; - // ============================================================ - - // all cases should be handled above - default: - CPPAD_ASSERT_UNKNOWN(0); - } - } - return; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/get_par_usage.hpp b/build-config/cppad/include/cppad/local/optimize/get_par_usage.hpp deleted file mode 100644 index 64539716..00000000 --- a/build-config/cppad/include/cppad/local/optimize/get_par_usage.hpp +++ /dev/null @@ -1,506 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_GET_PAR_USAGE_HPP -# define CPPAD_LOCAL_OPTIMIZE_GET_PAR_USAGE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file get_cexp_info.hpp -Create operator information tables -*/ -# include - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/*! -$begin optimize_get_par_usage$$ -$spell - Addr - iterator - itr - op - num - var - vecad - Vec - Ind -$$ - -$section Use Reverse Activity Analysis to Get Usage for Each Parameter$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_GET_PAR_USAGE%// END_PROTOTYPE%1 -%$$ - -$head Base$$ -Base type for the operator; i.e., this operation was recorded -using $codei%AD<%Base%>%$$ -and computations by this routine are done using type $icode Base$$. - -$head Addr$$ -Type used by random iterator for the player. - -$head play$$ -This is the operation sequence. - -$head random_itr$$ -This is a random iterator for the operation sequence. - -$head op_usage$$ -This argument has size equal to the number of operators -in the operation sequence; i.e., num_op = play->nun_var_rec(). -The value $icode%op_usage%[%i%]%$$ have been set to the usage for -the i-th operator in the operation sequence. - -$head vecad_used$$ -This argument has size equal to the number of VecAD vectors -in the operations sequences; i.e., play->num_var_vecad_rec(). -The VecAD vectors are indexed in the order that their indices appear -in the one large play->GetVecInd that holds all the VecAD vectors. - -$head par_usage$$ -The input size of this vector must be zero. -Upon return it has size equal to the number of parameters -in the operation sequence; i.e., play->num_par_rec(); -The value $icode%par_usage%[%i%]%$$ is true if an only if -the i-th parameter is used to compute a dependent variable -or parameter. -The nan at the beginning of the parameter vector -and the independent dynamic parameters are always used. - -$end -*/ - -// BEGIN_GET_PAR_USAGE -template -void get_par_usage( - const player* play , - const play::const_random_iterator& random_itr , - const pod_vector& op_usage , - pod_vector& vecad_used , - pod_vector& par_usage ) -// END_PROTOTYPE -{ - CPPAD_ASSERT_UNKNOWN( op_usage.size() == play->num_op_rec() ); - CPPAD_ASSERT_UNKNOWN( par_usage.size() == 0 ); - // - // number of operators in the tape - const size_t num_op = play->num_op_rec(); - // - // number of parameters in the tape - const size_t num_par = play->num_par_rec(); - // - // number of dynamic parameters - const size_t num_dynamic_par = play->num_dynamic_par(); - // - // number of independent dynamic parameters - size_t num_dynamic_ind = play->num_dynamic_ind(); - // - // number of VecAD vectors - size_t num_vecad_vec = play->num_var_vecad_rec(); - // - // dynamic parameter information - const pod_vector& dyn_par_is( play->dyn_par_is() ); - const pod_vector& dyn_par_op( play->dyn_par_op() ); - const pod_vector& dyn_par_arg( play->dyn_par_arg() ); - const pod_vector& dyn_ind2par_ind( play->dyn_ind2par_ind() ); - const pod_vector_maybe& all_par_vec( play->all_par_vec() ); - // ----------------------------------------------------------------------- - // initialize par_usage - par_usage.resize(num_par); - par_usage[0] = true; // true for nan at beginning of parameter vector - for(size_t i_par = 1; i_par <= num_dynamic_ind; ++i_par) - par_usage[i_par] = true; // true for independent dynamic parameters - for(size_t i_par = num_dynamic_ind+1; i_par < num_par; ++i_par) - par_usage[i_par] = false; // initialize as false for other parameters - // - // ----------------------------------------------------------------------- - // set usage to true for VecAD parameters that get used - size_t start_this_vector = 0; - for(size_t i_vec = 0; i_vec < num_vecad_vec; ++i_vec) - { // length of this vector (note length is not a parameter) - size_t length = play->GetVecInd(start_this_vector); - // - if( vecad_used[i_vec] ) - { // this vector gets used - for(size_t k = 1; k <= length; ++k) - { // index of parameter used by this VecAD vector - size_t i_par = play->GetVecInd(start_this_vector + k); - // must not be a dynamic parameter - CPPAD_ASSERT_UNKNOWN( ! dyn_par_is[i_par] ); - // set usage for this parameter - par_usage[i_par] = true; - } - } - start_this_vector += length + 1; - } - CPPAD_ASSERT_UNKNOWN( start_this_vector == play->num_var_vecad_ind_rec() ); - // - // ----------------------------------------------------------------------- - // forward pass to mark which parameters are used by necessary operators - // ----------------------------------------------------------------------- - // - // information about atomic function calls - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - enum_atom_state atom_state = start_atom; - // - // work space used by user atomic functions - vector parameter_x; // value of parameters in x - vector type_x; // type for each component of z - vector atom_ix; // variables indices for argument vector - vector depend_y; // results that are used - vector depend_x; // arguments that are used - // - for(size_t i_op = 0; i_op < num_op; ++i_op) - { - // information about current operator - OpCode op; // operator - const addr_t* arg; // arguments - size_t i_var; // variable index of first result - random_itr.op_info(i_op, op, arg, i_var); - // - bool skip = op_usage[i_op] == usage_t(no_usage); - skip &= atom_state == start_atom; - if( ! skip ) switch( op ) - { - // add or subtract with left a parameter and right a variable - case AddpvOp: - case SubpvOp: - if( dyn_par_is[ arg[0] ] ) - par_usage[ arg[0] ] = true; - else - { // determine if this parameter will be absorbed by csum - if( ! (op_usage[i_op] == csum_usage) ) - { // determine operator corresponding to variable - size_t j_op = random_itr.var2op(size_t(arg[1])); - CPPAD_ASSERT_UNKNOWN( op_usage[j_op] != no_usage ); - if( op_usage[j_op] != csum_usage ) - par_usage[ arg[0] ] = true; - } - } - break; - - // subtract with left a variable and right a parameter - case SubvpOp: - if( dyn_par_is[ arg[1] ] ) - par_usage[ arg[1] ] = true; - else - { // determine if this parameter will be absorbed by csum - if( ! (op_usage[i_op] == csum_usage) ) - { // determine operator corresponding to variable - size_t j_op = random_itr.var2op(size_t(arg[0])); - CPPAD_ASSERT_UNKNOWN( op_usage[j_op] != no_usage ); - if( op_usage[j_op] != csum_usage ) - par_usage[ arg[1] ] = true; - } - } - break; - - - - // cases with no parameter arguments - case AbsOp: - case AcosOp: - case AcoshOp: - case AddvvOp: - case AsinOp: - case AsinhOp: - case AtanOp: - case AtanhOp: - case BeginOp: - case CosOp: - case CoshOp: - case CSkipOp: - case DisOp: - case DivvvOp: - case EndOp: - case EqvvOp: - case ExpOp: - case Expm1Op: - case InvOp: - case LdvOp: - case LevvOp: - case LogOp: - case Log1pOp: - case LtvvOp: - case MulvvOp: - case NevvOp: - case PowvvOp: - case SignOp: - case SinOp: - case SinhOp: - case SqrtOp: - case StvvOp: - case SubvvOp: - case TanOp: - case TanhOp: - case ZmulvvOp: - break; - - // cases where first and second arguments are parameters - case EqppOp: - case LeppOp: - case LtppOp: - case NeppOp: - CPPAD_ASSERT_UNKNOWN( 2 <= NumArg(op) ) - par_usage[arg[0]] = true; - par_usage[arg[1]] = true; - break; - - - // cases where only first argument is a parameter - case CSumOp: - case EqpvOp: - case DivpvOp: - case LepvOp: - case LtpvOp: - case MulpvOp: - case NepvOp: - case ParOp: - case PowpvOp: - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( 1 <= NumArg(op) || op == CSumOp ) - par_usage[arg[0]] = true; - break; - - // cases where only second argument is a parameter - case DivvpOp: - case LevpOp: - case LdpOp: - case LtvpOp: - case PowvpOp: - case StpvOp: - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( 2 <= NumArg(op) ) - par_usage[arg[1]] = true; - break; - - // cases where second and thrid arguments are parameters - case ErfOp: - case ErfcOp: - case StppOp: - CPPAD_ASSERT_UNKNOWN( 3 <= NumArg(op) ) - par_usage[arg[1]] = true; - par_usage[arg[2]] = true; - break; - - // cases where only third argument is a parameter - case StvpOp: - CPPAD_ASSERT_UNKNOWN( 3 <= NumArg(op) ) - par_usage[arg[2]] = true; - break; - - // conditional expression operator - case CExpOp: - CPPAD_ASSERT_UNKNOWN( 6 == NumArg(op) ) - if( (arg[1] & 1) == 0 ) - par_usage[arg[2]] = true; - if( (arg[1] & 2) == 0 ) - par_usage[arg[3]] = true; - if( (arg[1] & 4) == 0 ) - par_usage[arg[4]] = true; - if( (arg[1] & 8) == 0 ) - par_usage[arg[5]] = true; - break; - - // print function - case PriOp: - if( (arg[0] & 1) == 0 ) - par_usage[arg[1]] = true; - if( (arg[0] & 2) == 0 ) - par_usage[arg[3]] = true; - CPPAD_ASSERT_UNKNOWN( 5 == NumArg(op) ) - break; - - // -------------------------------------------------------------- - // atomic function calls - case AFunOp: - if( atom_state == start_atom ) - { atom_index = size_t(arg[0]); - atom_old = size_t(arg[1]); - atom_n = size_t(arg[2]); - atom_m = size_t(arg[3]); - atom_j = 0; - atom_i = 0; - atom_state = arg_atom; - // ------------------------------------------------------- - parameter_x.resize( atom_n ); - type_x.resize( atom_n ); - atom_ix.resize( atom_n ); - // - depend_y.resize( atom_m ); - depend_x.resize( atom_n ); - } - else - { CPPAD_ASSERT_UNKNOWN( atom_state == end_atom ); - CPPAD_ASSERT_UNKNOWN( atom_n == size_t(arg[2]) ); - CPPAD_ASSERT_UNKNOWN( atom_m == size_t(arg[3]) ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( atom_i == atom_m ); - atom_state = start_atom; - // - // call atomic function for this operation - sweep::call_atomic_rev_depend( - atom_index, atom_old, parameter_x, type_x, depend_x, depend_y - ); - for(size_t j = 0; j < atom_n; j++) - if( depend_x[j] && type_x[j] != variable_enum ) - { // This user argument is a parameter that is needed - - CPPAD_ASSERT_UNKNOWN( atom_ix[j] > 0 ); - par_usage[ atom_ix[j] ] = true; - } - } - break; - - case FunavOp: - // this argument is a variable - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - atom_ix[atom_j] = 0; - parameter_x[atom_j] = all_par_vec[0]; // variables get value nan - type_x[atom_j] = variable_enum; - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunapOp: - // this argument is a parameter - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - atom_ix[atom_j] = size_t( arg[0] ); - parameter_x[atom_j] = all_par_vec[arg[0]]; // parameter value - if( dyn_par_is[arg[0]] ) - type_x[atom_j] = dynamic_enum; - else - type_x[atom_j] = dynamic_enum; - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunrpOp: - // this result is a parameter - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - depend_y[atom_i] = op_usage[i_op] != usage_t(no_usage); - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - - case FunrvOp: - // this result is a variable - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - depend_y[atom_i] = op_usage[i_op] != usage_t(no_usage); - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - // -------------------------------------------------------------- - - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - } - // ----------------------------------------------------------------------- - // reverse pass to determine which dynamic parameters are necessary - // ----------------------------------------------------------------------- - size_t i_arg = dyn_par_arg.size(); // index in dyn_par_arg - size_t i_dyn = num_dynamic_par; // index in dyn_ind2par_ind - while(i_dyn) - { // next dynamic parameter in reverse order - --i_dyn; - op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] ); - while( op == result_dyn ) - { --i_dyn; - op = op_code_dyn( dyn_par_op[i_dyn] ); - CPPAD_ASSERT_UNKNOWN( op == result_dyn || op == atom_dyn ); - } - if( op == atom_dyn ) - { // number of arguments for this operator - size_t n_arg = size_t( dyn_par_arg[i_arg - 1] ); - // - // index of first argument for this operation - i_arg -= n_arg; - // - atom_index = size_t( dyn_par_arg[i_arg + 0] ); - size_t n = size_t( dyn_par_arg[i_arg + 1] ); - size_t m = size_t( dyn_par_arg[i_arg + 2] ); - CPPAD_ASSERT_UNKNOWN( n_arg == 5 + n + m ); - // - // parameter_x, type_x - parameter_x.resize(n); - type_x.resize(n); - for(size_t j = 0; j < n; ++j) - { // parameter index zero is used for variable - CPPAD_ASSERT_UNKNOWN( isnan( all_par_vec[0] ) ); - addr_t arg_j = dyn_par_arg[i_arg + 4 + j]; - parameter_x[j] = all_par_vec[arg_j]; - if( arg_j == 0 ) - type_x[j] = variable_enum; - else if( dyn_par_is[arg_j] ) - type_x[j] = dynamic_enum; - else - type_x[j] = constant_enum; - } - // - // depend_y - depend_y.resize(m); - for(size_t i = 0; i < m; ++i) - { // a constant prameter cannot depend on a dynamic parameter - // so do not worry about constant parameters in depend_y - size_t i_par = size_t( dyn_par_arg[i_arg + 4 + n + i] ); - depend_y[i] = par_usage[i_par]; - } - // - // call back to atomic function for this operation - depend_x.resize(n); - atom_old = 0; // not used with dynamic parameters - sweep::call_atomic_rev_depend( - atom_index, atom_old, parameter_x, type_x, depend_x, depend_y - ); - // - // transfer depend_x to par_usage - for(size_t j = 0; j < n; ++j) - { size_t i_par = size_t( dyn_par_arg[i_arg + 4 + j] ); - par_usage[i_par] = par_usage[i_par] | depend_x[j]; - } - } - else - { // corresponding parameter index - size_t i_par = size_t( dyn_ind2par_ind[i_dyn] ); - CPPAD_ASSERT_UNKNOWN( dyn_par_is[i_par] ); - // - // number of argumens to this operator - size_t n_arg = num_arg_dyn(op); - // - // index of first argument for this operator - CPPAD_ASSERT_UNKNOWN( op != atom_dyn ); - i_arg -= n_arg; - // - // if this dynamic parameter is needed - if( par_usage[i_par] ) - { // need dynamic parameters that are used to generate this one - size_t offset = num_non_par_arg_dyn(op); - for(size_t i = offset; i < n_arg; ++i) - par_usage[ dyn_par_arg[i_arg + i] ] = true; - } - } - } - CPPAD_ASSERT_UNKNOWN( i_arg == 0 ); - // - return; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/hash_code.hpp b/build-config/cppad/include/cppad/local/optimize/hash_code.hpp deleted file mode 100644 index 812ca4bc..00000000 --- a/build-config/cppad/include/cppad/local/optimize/hash_code.hpp +++ /dev/null @@ -1,57 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_HASH_CODE_HPP -# define CPPAD_LOCAL_OPTIMIZE_HASH_CODE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file local/optimize/hash_code.hpp -CppAD hashing utility. -*/ - - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { -/*! -Specialized hash code for a CppAD operator and its arguments -(used during optimization). - -\param op -is the operator that we are computing a hash code for. - -\param num_arg -number of elements of arg to include in the hash code. - -\param arg -is a vector of length num_arg -containing the corresponding argument indices for this operator. - -\return -is a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1. -*/ - -inline size_t optimize_hash_code( - opcode_t op , - size_t num_arg , - const addr_t* arg ) -{ CPPAD_ASSERT_UNKNOWN( num_arg < 4 ); - size_t prime = 1; - size_t sum = prime * size_t(op); - for(size_t i = 0; i < num_arg; i++) - { prime = prime + 2; // 3, 5, 7 in that order - sum += prime * size_t(arg[i]); - } - // - return sum % CPPAD_HASH_TABLE_SIZE; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/match_op.hpp b/build-config/cppad/include/cppad/local/optimize/match_op.hpp deleted file mode 100644 index b053e279..00000000 --- a/build-config/cppad/include/cppad/local/optimize/match_op.hpp +++ /dev/null @@ -1,292 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_MATCH_OP_HPP -# define CPPAD_LOCAL_OPTIMIZE_MATCH_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { -/* -$begin optimize_match_op$$ - -$section Search for a Previous Operator that Matches Current Operator$$ -$spell - op - itr - bool - addr - erf - erfc - iterator -$$ - -$head Syntax$$ -$codei%exceed_collision_limit% = match_op( - %collision_limit%, - %random_itr%, - %op_previous%, - %current%, - %hash_tape_op%, - %work_bool%, - %work_addr_t% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Operator Arguments$$ -If an argument for the current operator is a variable, -and the argument has previous match, -the previous match for the argument is used when checking for a match -for the current operator. - -$head collision_limit$$ -is the maximum number of collisions (matches) allowed for one -expression hash code value. - -$head random_itr$$ -is a random iterator for the old operation sequence. - -$head op_previous$$ -Mapping from operator index to previous operator that can replace this one. -The input value of -$codei% - %previous% = %op_previous%[%current%] -%$$ -is assumed to be zero. If a match if found, the output value of -$icode previous$$ is set to the matching operator index, -otherwise it is left as is. Note that $icode%previous% < %current%$$ -and $icode%op_previous[%previous%]%$$ is zero. - -$head current$$ -is the index of the current operator which cannot be any of the -operators in the list below: -$srcthisfile% - 0%// BEGIN_INVALID_OP%// END_INVALID_OP%1 -%$$ -After this initialization, the value of $icode current$$ -increases with each call to match_op. - -$subhead erf$$ -The operators $code ErfOp$$ and $code ErfcOp$$ have -three arguments, but only one true argument (the others are always the same). - - -$head hash_table_op$$ -is assumed to be initialized as a vector of empty sets before the -first call to match_op (for a pass of the operation sequence). -$codei% - %hash_table_op%.n_set() == CPPAD_HASH_TABLE_SIZE - %hash_table_op%.end() == %op_previous%.size() -%$$ -If $icode i_op$$ is an element of the j-th set, -then the operation $icode%op_previous%[%i_op%]%$$ has hash code j, -and does not match any other element of the j-th set. -An entry to j-th set for the current operator is added each time -match_op is called and a match for the current operator is not found. - -$head work_bool$$ -work space that is used by match_op between calls to increase speed. -Should be empty on first call for this forward pass of the operation -sequence and not modified until forward pass is done - -$head work_addr_t$$ -work space that is used by match_op between calls to increase speed. -Should be empty on first call for this forward pass of the operation -sequence and not modified until forward pass is done - -$head exceed_collision_limit$$ -If the $icode collision_limit$$ is exceeded (is not exceeded), -the return value is true (false). - -$end -*/ -// BEGIN_PROTOTYPE -template -bool match_op( - size_t collision_limit , - const play::const_random_iterator& random_itr , - pod_vector& op_previous , - size_t current , - sparse::list_setvec& hash_table_op , - pod_vector& work_bool , - pod_vector& work_addr_t ) -// END_PROTOTYPE -{ -# ifndef NDEBUG - switch( random_itr.get_op(current) ) - { - // BEGIN_INVALID_OP - case BeginOp: - case CExpOp: - case CSkipOp: - case CSumOp: - case EndOp: - case InvOp: - case LdpOp: - case LdvOp: - case ParOp: - case PriOp: - case StppOp: - case StpvOp: - case StvpOp: - case StvvOp: - case AFunOp: - case FunapOp: - case FunavOp: - case FunrpOp: - case FunrvOp: - // END_INVALID_OP - CPPAD_ASSERT_UNKNOWN(false); - break; - - default: - break; - } -# endif - // initialize return value - bool exceed_collision_limit = false; - // num_op - size_t num_op = random_itr.num_op(); - // - // num_var - size_t num_var = random_itr.num_var(); - // - // variable is a reference to, and better name for, work_bool - pod_vector& variable(work_bool); - // - // var2previous_var is a reference to, and better name for, work_addr_t - pod_vector& var2previous_var(work_addr_t); - if( var2previous_var.size() == 0 ) - { var2previous_var.resize(num_var); - for(size_t i = 0; i < num_var; ++i) - var2previous_var[i] = addr_t(i); - } - // - CPPAD_ASSERT_UNKNOWN( var2previous_var.size() == num_var ); - CPPAD_ASSERT_UNKNOWN( num_op == op_previous.size() ); - CPPAD_ASSERT_UNKNOWN( op_previous[current] == 0 ); - CPPAD_ASSERT_UNKNOWN( - hash_table_op.n_set() == CPPAD_HASH_TABLE_SIZE - ); - CPPAD_ASSERT_UNKNOWN( hash_table_op.end() == num_op ); - CPPAD_ASSERT_UNKNOWN( current < num_op ); - // - // op, arg, i_var - OpCode op; - const addr_t* arg; - size_t i_var; - random_itr.op_info(current, op, arg, i_var); - // - // num_arg - size_t num_arg = NumArg(op); - CPPAD_ASSERT_UNKNOWN( 0 < num_arg ); - CPPAD_ASSERT_UNKNOWN( - (num_arg < 3) | ( (num_arg == 3) & (op == ErfOp || op == ErfcOp) ) - ); - // - arg_is_variable(op, arg, variable); - CPPAD_ASSERT_UNKNOWN( variable.size() == num_arg ); - // - // If j-th argument to this operator is a variable, and a previous - // variable will be used in its place, use the previous variable for - // hash coding and matching. - addr_t arg_match[] = { - // Invalid value that will not be used. This initialization avoid - // a wraning on some compilers - std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max() - }; - if( (op == AddvvOp) | (op == MulvvOp ) ) - { // in special case where operator is commutative and operands are variables, - // put lower index first so hash code does not depend on operator order - CPPAD_ASSERT_UNKNOWN( num_arg == 2 ); - arg_match[0] = var2previous_var[ arg[0] ]; - arg_match[1] = var2previous_var[ arg[1] ]; - if( arg_match[1] < arg_match[0] ) - std::swap( arg_match[0], arg_match[1] ); - } - else for(size_t j = 0; j < num_arg; ++j) - { arg_match[j] = arg[j]; - if( variable[j] ) - arg_match[j] = var2previous_var[ arg[j] ]; - } - - // - size_t code = optimize_hash_code(opcode_t(op), num_arg, arg_match); - // - // iterator for the set with this hash code - sparse::list_setvec_const_iterator itr(hash_table_op, code); - // - // check for a match - size_t count = 0; - while( *itr != num_op ) - { ++count; - // - // candidate previous for current operator - size_t candidate = *itr; - CPPAD_ASSERT_UNKNOWN( candidate < current ); - CPPAD_ASSERT_UNKNOWN( op_previous[candidate] == 0 ); - // - OpCode op_c; - const addr_t* arg_c; - size_t i_var_c; - random_itr.op_info(candidate, op_c, arg_c, i_var_c); - // - // check for a match - bool match = op == op_c; - size_t j = 0; - while( match & (j < num_arg) ) - { if( variable[j] ) - match &= arg_match[j] == var2previous_var[ arg_c[j] ]; - else - match &= arg_match[j] == arg_c[j]; - ++j; - } - if( (! match) & ( (op == AddvvOp) | (op == MulvvOp) ) ) - { // communative so check for reverse order match - match = op == op_c; - match &= arg_match[0] == var2previous_var[ arg_c[1] ]; - match &= arg_match[1] == var2previous_var[ arg_c[0] ]; - } - if( match ) - { op_previous[current] = static_cast( candidate ); - if( NumRes(op) > 0 ) - { CPPAD_ASSERT_UNKNOWN( i_var_c < i_var ); - var2previous_var[i_var] = addr_t( i_var_c ); - } - return exceed_collision_limit; - } - ++itr; - } - - // see print (that is commented out) at bottom of get_op_previous.hpp - CPPAD_ASSERT_UNKNOWN( count <= collision_limit ); - if( count == collision_limit ) - { // restart the list - hash_table_op.clear(code); - // limit has been exceeded - exceed_collision_limit = true; - } - // No match was found. Add this operator to the set for this hash code - // Not using post_element becasue we need to iterate for - // this code before adding another element for this code. - hash_table_op.add_element(code, current); - // - return exceed_collision_limit; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/optimize_run.hpp b/build-config/cppad/include/cppad/local/optimize/optimize_run.hpp deleted file mode 100644 index 48aab64d..00000000 --- a/build-config/cppad/include/cppad/local/optimize/optimize_run.hpp +++ /dev/null @@ -1,1351 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_OPTIMIZE_RUN_HPP -# define CPPAD_LOCAL_OPTIMIZE_OPTIMIZE_RUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-21 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/*! -$begin optimize_run$$ -$spell - dep_taddr - Addr - const - iterator - PriOp - optimizer -$$ - -$section Convert a player object to an optimized recorder object $$ - -$head Syntax$$ -$codei%exceed_collision_limit% = local::optimize::optimize_run( - %options%, %n%, %dep_taddr%, %play%, %rec% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Addr$$ -Type to use for array elements in $code const_random_iterator$$. - -$head Base$$ -Base type for the operator; i.e., this operation was recorded -using $codei%AD<%Base%>%$$ -and computations by this routine are done using type $icode Base$$. - -$head options$$ - -$subhead no_conditional_skip$$ -If this sub-string appears, -conditional skip operations will not be generated. -This may make the optimize routine use significantly less memory -and take significantly less time. - -$subhead no_compare_op$$ -If this sub-string appears, -then comparison operators will be removed from the optimized tape. -These operators are necessary for the $cref compare_change$$ feature to be -meaningful in the resulting recording. -On the other hand, they are not necessary and take extra time -when this feature is not needed. - -$subhead no_print_for_op$$ -If this sub-string appears, -then $cref printfor$$ operators $code PriOp$$ -will be removed from the optimized tape. -These operators are useful for reporting problems evaluating derivatives -at independent variable values different from those used to record a function. - -$subhead no_cumulative_sum_op$$ -If this sub-string appears, -no cumulative sum operations will be generated during the optimization; see -$cref optimize_cumulative_sum.cpp$$. - -$subhead collision_limit=value$$ -If this substring appears, -where $icode value$$ is a sequence of decimal digits, -the optimizer's hash code collision limit will be set to $icode value$$. -When the collision limit is exceeded, the expressions with that hash code -are removed and a new lists of expressions with that has code is started. -The larger $icode value$$, the more identical expressions the optimizer -can recognize, but the slower the optimizer may run. -The default for $icode value$$ is $code 10$$. - -$head n$$ -is the number of independent variables on the tape. - -$head dep_taddr$$ -On input this vector contains the indices for each of the dependent -variable values in the operation sequence corresponding to $icode play$$. -Upon return it contains the indices for the same variables but in -the operation sequence corresponding to $icode rec$$. - -$head play$$ -This is the operation sequence that we are optimizing. -It is $code const$$ except for the fact that -$icode%play%->setup_random ()%$$is called. - -$head rec$$ -The input contents of this recording must be empty; i.e., -it corresponds to directly after the default constructor. -Upon return, it contains an optimized version of the -operation sequence corresponding to $icode play$$. - -$head exceed_collision_limit$$ -If the $icode collision_limit$$ is exceeded (is not exceeded), -the return value is true (false). - -$childtable% - include/cppad/local/optimize/cexp_info.hpp% - include/cppad/local/optimize/get_cexp_info.hpp% - include/cppad/local/optimize/get_op_usage.hpp% - include/cppad/local/optimize/get_par_usage.hpp% - include/cppad/local/optimize/record_csum.hpp% - include/cppad/local/optimize/match_op.hpp% - include/cppad/local/optimize/get_op_previous.hpp -%$$ - -$end -*/ - -// BEGIN_PROTOTYPE -template -bool optimize_run( - const std::string& options , - size_t n , - pod_vector& dep_taddr , - player* play , - recorder* rec ) -// END_PROTOTYPE -{ bool exceed_collision_limit = false; - // - // check that recorder is empty - CPPAD_ASSERT_UNKNOWN( rec->num_op_rec() == 0 ); - // - // get a random iterator for this player - play->template setup_random(); - local::play::const_random_iterator random_itr = - play->template get_random(); - - bool conditional_skip = true; - bool compare_op = true; - bool print_for_op = true; - bool cumulative_sum_op = true; - size_t collision_limit = 10; - size_t index = 0; - while( index < options.size() ) - { while( index < options.size() && options[index] == ' ' ) - ++index; - std::string option; - while( index < options.size() && options[index] != ' ' ) - option += options[index++]; - if( option != "" ) - { if( option == "no_conditional_skip" ) - conditional_skip = false; - else if( option == "no_compare_op" ) - compare_op = false; - else if( option == "no_print_for_op" ) - print_for_op = false; - else if( option == "no_cumulative_sum_op" ) - cumulative_sum_op = false; - else if( option.substr(0, 16) == "collision_limit=" ) - { std::string value = option.substr(16, option.size()); - bool value_ok = value.size() > 0; - for(size_t i = 0; i < value.size(); ++i) - { value_ok &= '0' <= value[i]; - value_ok &= value[i] <= '9'; - } - if( ! value_ok ) - { option += " value is not a sequence of decimal digits"; - CPPAD_ASSERT_KNOWN( false , option.c_str() ); - } - collision_limit = size_t( std::atoi( value.c_str() ) ); - if( collision_limit < 1 ) - { option += " value must be greater than zero"; - CPPAD_ASSERT_KNOWN( false , option.c_str() ); - } - } - else - { option += " is not a valid optimize option"; - CPPAD_ASSERT_KNOWN( false , option.c_str() ); - } - } - } - // number of operators in the player - const size_t num_op = play->num_op_rec(); - CPPAD_ASSERT_UNKNOWN( - num_op < size_t( (std::numeric_limits::max)() ) - ); - - // number of variables in the player -# ifndef NDEBUG - const size_t num_var = play->num_var_rec(); -# endif - - // number of parameter in the player - const size_t num_par = play->num_par_rec(); - - // number of VecAD indices - size_t num_vecad_ind = play->num_var_vecad_ind_rec(); - - // number of VecAD vectors - size_t num_vecad_vec = play->num_var_vecad_rec(); - - // number of independent dynamic parameters - size_t num_dynamic_ind = play->num_dynamic_ind(); - - // number of dynamic parameters - size_t num_dynamic_par = play->num_dynamic_par(); - - // mapping from dynamic parameter index to paramemter index - const pod_vector& dyn_ind2par_ind( play->dyn_ind2par_ind() ); - - // number of dynamic parameters - CPPAD_ASSERT_UNKNOWN( num_dynamic_ind <= play->num_dynamic_par () ); - - // ----------------------------------------------------------------------- - // operator information - pod_vector cexp2op; - sparse::list_setvec cexp_set; - pod_vector vecad_used; - pod_vector op_usage; - get_op_usage( - conditional_skip, - compare_op, - print_for_op, - cumulative_sum_op, - play, - random_itr, - dep_taddr, - cexp2op, - cexp_set, - vecad_used, - op_usage - ); - pod_vector op_previous; - exceed_collision_limit |= get_op_previous( - collision_limit, - play, - random_itr, - cexp_set, - op_previous, - op_usage - ); - size_t num_cexp = cexp2op.size(); - CPPAD_ASSERT_UNKNOWN( conditional_skip || num_cexp == 0 ); - vector cexp_info; // struct_cexp_info not POD - sparse::list_setvec skip_op_true; - sparse::list_setvec skip_op_false; - // - if( cexp2op.size() > 0 ) get_cexp_info( - play, - random_itr, - op_previous, - op_usage, - cexp2op, - cexp_set, - cexp_info, - skip_op_true, - skip_op_false - ); - - // We no longer need cexp_set, and cexp2op, so free their memory - cexp_set.resize(0, 0); - cexp2op.clear(); - // ----------------------------------------------------------------------- - // dynamic parameter information - pod_vector par_usage; - get_par_usage( - play, - random_itr, - op_usage, - vecad_used, - par_usage - ); - pod_vector dyn_previous; - get_dyn_previous( - play , - random_itr , - par_usage , - dyn_previous - ); - // ----------------------------------------------------------------------- - - // conditional expression information - // - // Size of the conditional expression information structure. - // This is equal to the number of conditional expressions when - // conditional_skip is true, otherwise it is zero. - // - // sort the conditional expression information by max_left_right - // this is the conditional skip order - vector cskip_order(num_cexp); - if( num_cexp > 0 ) - { vector keys(num_cexp); - for(size_t i = 0; i < num_cexp; i++) - keys[i] = size_t( cexp_info[i].max_left_right ); - CppAD::index_sort(keys, cskip_order); - } - // initial index in conditional skip order - size_t cskip_order_next = 0; - // - // initialize index in conditional expression order - size_t cexp_next = 0; - - // mapping from conditional expression index to conditional skip - // information on new tape - pod_vector cskip_new(num_cexp); - // - // flag used to indicate that there is no conditional skip - // for this conditional expression - for(size_t i = 0; i < num_cexp; i++) - cskip_new[i].i_arg = 0; - // ======================================================================= - // Create new recording - // ======================================================================= - // - // dynamic parameter information in player - const pod_vector& dyn_par_is( play->dyn_par_is() ); - const pod_vector& dyn_par_op( play->dyn_par_op() ); - const pod_vector& dyn_par_arg( play->dyn_par_arg() ); - // - // start mapping from old parameter indices to new parameter indices - // for all parameters that get used. - pod_vector new_par( num_par ); - addr_t addr_t_max = (std::numeric_limits::max)(); - for(size_t i_par = 0; i_par < num_par; ++i_par) - new_par[i_par] = addr_t_max; // initialize as not used - // - // start new recording - CPPAD_ASSERT_UNKNOWN( rec->num_op_rec() == 0 ); - rec->set_num_dynamic_ind(num_dynamic_ind); - rec->set_abort_op_index(0); - rec->set_record_compare( compare_op ); - - // copy parameters with index 0 - CPPAD_ASSERT_UNKNOWN( ! dyn_par_is[0] && isnan( play->GetPar(0) ) ); - rec->put_con_par( play->GetPar(0) ); - new_par[0] = 0; - - // set new_par for the independent dynamic parameters - for(size_t i_par = 1; i_par <= num_dynamic_ind; i_par++) - { CPPAD_ASSERT_UNKNOWN( dyn_par_is[i_par] ); - addr_t i = rec->put_dyn_par(play->GetPar(i_par), ind_dyn); - CPPAD_ASSERT_UNKNOWN( size_t(i) == i_par ); - new_par[i_par] = i; - } - - // set new_par for the constant parameters that are used - for(size_t i_par = num_dynamic_ind + 1; i_par < num_par; ++i_par) - if( ! dyn_par_is[i_par] ) - { CPPAD_ASSERT_UNKNOWN( i_par == 0 || num_dynamic_ind < i_par ); - if( par_usage[i_par] ) - { // value of this parameter - Base par = play->GetPar(i_par); - new_par[i_par] = rec->put_con_par(par); - } - } - - // index corresponding to the parameter zero - addr_t zero_par_index = rec->put_con_par( Base(0) ); - - // set new_par for the dependent dynamic parameters - size_t i_dyn = num_dynamic_ind; // dynamic parmaeter index - size_t i_arg = 0; // dynamic parameter argument index - pod_vector arg_vec; - for(size_t i_par = num_dynamic_ind + 1; i_par < num_par; ++i_par) - if( dyn_par_is[i_par] ) - { // operator for this dynamic parameter - op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] ); - // - // number of arguments for this dynamic parameter - size_t n_arg = num_arg_dyn(op); - // - // number of dynamic parameter results for this operator - size_t n_dyn = 1; - // - if( op == atom_dyn ) - { size_t atom_index = size_t( dyn_par_arg[i_arg + 0] ); - size_t atom_n = size_t( dyn_par_arg[i_arg + 1] ); - size_t atom_m = size_t( dyn_par_arg[i_arg + 2] ); - n_dyn = size_t( dyn_par_arg[i_arg + 3] ); - n_arg = 5 + atom_n + atom_m; - // - // check if any dynamic parameter result for this operator is used - bool call_used = false; -# ifndef NDEBUG - bool found_i_par = false; - for(size_t i = 0; i < atom_m; ++i) - { size_t j_par = size_t( dyn_par_arg[i_arg + 4 + atom_n + i] ); - if( dyn_par_is[j_par] ) - { call_used |= par_usage[j_par]; - CPPAD_ASSERT_UNKNOWN( j_par == i_par || found_i_par ); - // j_par > i_par corresponds to result_dyn operator - CPPAD_ASSERT_UNKNOWN( j_par >= i_par ); - found_i_par |= j_par == i_par; - } - } - CPPAD_ASSERT_UNKNOWN( found_i_par ); -# else - for(size_t i = 0; i < atom_m; ++i) - { size_t j_par = size_t( dyn_par_arg[i_arg + 4 + atom_n + i] ); - if( dyn_par_is[j_par] ) - call_used |= par_usage[j_par]; - } -# endif - if( call_used ) - { arg_vec.resize(0); - arg_vec.push_back( addr_t( atom_index ) ); - arg_vec.push_back( addr_t( atom_n ) ); - arg_vec.push_back( addr_t( atom_m ) ); - arg_vec.push_back( addr_t( n_dyn ) ); - for(size_t j = 0; j < atom_n; ++j) - { addr_t arg_j = dyn_par_arg[i_arg + 4 + j]; - if( arg_j > 0 && par_usage[arg_j] ) - arg_vec.push_back( new_par[ arg_j ] ); - else - arg_vec.push_back(0); - } - bool first_dynamic_result = true; - for(size_t i = 0; i < atom_m; ++i) - { addr_t res_i = dyn_par_arg[i_arg + 4 + atom_n + i]; - CPPAD_ASSERT_UNKNOWN( dyn_par_is[res_i] || res_i == 0 ); - // - if( dyn_par_is[res_i] ) - { Base par = play->GetPar( size_t(res_i) ); - if( first_dynamic_result ) - { first_dynamic_result = false; - new_par[res_i] = rec->put_dyn_par(par, atom_dyn); - } - else - new_par[res_i] = rec->put_dyn_par(par, result_dyn); - arg_vec.push_back( new_par[res_i] ); - } - else - { // this result is a constant parameter - if( new_par[res_i] != addr_t_max ) - arg_vec.push_back( new_par[res_i] ); - else - { // this constant parameter is not used - arg_vec.push_back(0); // phantom parameter - } - } - } - arg_vec.push_back( addr_t(5 + atom_n + atom_m ) ); - rec->put_dyn_arg_vec( arg_vec ); - } - } - else if( par_usage[i_par] & (op != result_dyn) ) - { size_t j_dyn = size_t( dyn_previous[i_dyn] ); - if( j_dyn != num_dynamic_par ) - { size_t j_par = size_t( dyn_ind2par_ind[j_dyn] ); - CPPAD_ASSERT_UNKNOWN( j_par < i_par ); - new_par[i_par] = new_par[j_par]; - } - else - { - // value of this parameter - Base par = play->GetPar(i_par); - // - if( op == cond_exp_dyn ) - { // cond_exp_dyn - CPPAD_ASSERT_UNKNOWN( num_dynamic_ind <= i_par ); - CPPAD_ASSERT_UNKNOWN( n_arg == 5 ); - new_par[i_par] = rec->put_dyn_cond_exp( - par , // par - CompareOp( dyn_par_arg[i_arg + 0] ), // cop - new_par[ dyn_par_arg[i_arg + 1] ] , // left - new_par[ dyn_par_arg[i_arg + 2] ] , // right - new_par[ dyn_par_arg[i_arg + 3] ] , // if_true - new_par[ dyn_par_arg[i_arg + 4] ] // if_false - ); - } - else if( op == dis_dyn ) - { // dis_dyn - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - new_par[i_par] = rec->put_dyn_par( - par , // par - op , // op - dyn_par_arg[i_arg + 0] , // index - new_par[ dyn_par_arg[i_arg + 1] ] // parameter - ); - } - else if( n_arg == 1 ) - { // cases with one argument - CPPAD_ASSERT_UNKNOWN( num_non_par_arg_dyn(op) == 0 ); - CPPAD_ASSERT_UNKNOWN( num_dynamic_ind <= i_par ); - new_par[i_par] = rec->put_dyn_par( par, op, - new_par[ dyn_par_arg[i_arg + 0] ] - ); - } - else if( n_arg == 2 ) - { // cases with two arguments - CPPAD_ASSERT_UNKNOWN( num_dynamic_ind <= i_par ); - CPPAD_ASSERT_UNKNOWN( num_non_par_arg_dyn(op) == 0 ); - new_par[i_par] = rec->put_dyn_par( par, op, - new_par[ dyn_par_arg[i_arg + 0] ], - new_par[ dyn_par_arg[i_arg + 1] ] - ); - } - else - { // independent dynamic parmaeter case - CPPAD_ASSERT_UNKNOWN( op == ind_dyn ) - CPPAD_ASSERT_UNKNOWN( i_par <= num_dynamic_ind ); - CPPAD_ASSERT_UNKNOWN( n_arg == 0 ); - new_par[i_par] = rec->put_dyn_par( par, op); - } - } - } - ++i_dyn; - i_arg += n_arg; - } - // ----------------------------------------------------------------------- - // There is an additional constant parameter for each cumulative summation - // (that does not have a corresponding old parameter index). - // ------------------------------------------------------------------------ - // initialize mapping from old VecAD index to new VecAD index - CPPAD_ASSERT_UNKNOWN( - size_t( (std::numeric_limits::max)() ) >= num_vecad_ind - ); - pod_vector new_vecad_ind(num_vecad_ind); - for(size_t i = 0; i < num_vecad_ind; i++) - new_vecad_ind[i] = addr_t( num_vecad_ind ); // invalid index - { - size_t j = 0; // index into the old set of indices - for(size_t i = 0; i < num_vecad_vec; i++) - { // length of this VecAD - size_t length = play->GetVecInd(j); - if( vecad_used[i] ) - { // Put this VecAD vector in new recording - CPPAD_ASSERT_UNKNOWN(length < num_vecad_ind); - new_vecad_ind[j] = rec->put_var_vecad_ind( addr_t(length) ); - for(size_t k = 1; k <= length; k++) new_vecad_ind[j+k] = - rec->put_var_vecad_ind( - new_par[ play->GetVecInd(j+k) ] - ); - } - // start of next VecAD - j += length + 1; - } - CPPAD_ASSERT_UNKNOWN( j == num_vecad_ind ); - } - - // temporary buffer for new argument values - addr_t new_arg[6]; - - // temporary work space used by record_csum - // (decalared here to avoid realloaction of memory) - struct_csum_stacks csum_work; - - // tempory used to hold a size_pair - struct_size_pair size_pair; - // - // Mapping from old operator index to new variable index, - // zero is invalid except for new_var[0]. - pod_vector new_var(num_op); - // - // Mapping from old operator index to new operator index will share - // memory with op_previous. Must get op_previous[i_op] for this operator - // before over writting it with new_op[i_op]. - pod_vector& new_op( op_previous ); - CPPAD_ASSERT_UNKNOWN( new_op.size() == num_op ); - // ------------------------------------------------------------- - // information for current operator - size_t i_op; // index - OpCode op; // operator - const addr_t* arg; // arguments - size_t i_var; // variable index of primary (last) result - // - // information about atomic function - enum_atom_state atom_state = start_atom; - size_t atom_i = 0; - size_t atom_j = 0; - // - i_var = 0; - for(i_op = 0; i_op < num_op; ++i_op) - { // if non-zero, use previous result in place of this operator. - // Must get this information before writing new_op[i_op]. - size_t previous = size_t( op_previous[i_op] ); - // - // zero is invalid except for new_op[0]. - new_op[i_op] = 0; - // - // Zero is invalid except for new_var[0] and previous is zero unless - // this operator is replace by a previous operator. - new_var[i_op] = 0; - if( op_usage[i_op] == usage_t(yes_usage) ) - new_var[i_op] = new_var[previous]; - // - // temporary used in some switch cases - addr_t mask; - // - // this operator information - size_t i_tmp; - random_itr.op_info(i_op, op, arg, i_tmp); - if( NumRes(op) > 0 ) - i_var = i_tmp; - // - // is this new result the top of a cummulative summation - bool top_csum; - // - // determine if we should insert a conditional skip here - bool skip = conditional_skip; - if( skip ) - { skip &= cskip_order_next < num_cexp; - skip &= op != BeginOp; - skip &= op != InvOp; - skip &= atom_state == start_atom; - if( skip ) - { size_t j = cskip_order[cskip_order_next]; - if( NumRes(op) > 0 ) - skip &= size_t( cexp_info[j].max_left_right ) < i_var; - else - skip &= size_t( cexp_info[j].max_left_right ) <= i_var; - } - if( skip ) - { size_t j = cskip_order[cskip_order_next]; - cskip_order_next++; - size_t n_true = skip_op_true.number_elements(j); - size_t n_false = skip_op_false.number_elements(j); - skip &= n_true > 0 || n_false > 0; - if( skip ) - { CPPAD_ASSERT_UNKNOWN( NumRes(CSkipOp) == 0 ); - size_t n_arg = 7 + size_t(n_true) + size_t(n_false); - // reserve space for the arguments to this operator but - // delay setting them until we have all the new addresses - cskip_new[j].i_arg = rec->ReserveArg(n_arg); - // i_arg == 0 is used to check if conditional expression - // has been skipped. - CPPAD_ASSERT_UNKNOWN( cskip_new[j].i_arg > 0 ); - // There is no corresponding old operator in this case - rec->PutOp(CSkipOp); - } - } - } - // - CPPAD_ASSERT_UNKNOWN( - size_t( (std::numeric_limits::max)() ) >= rec->num_op_rec() - ); - // - // For each call, first and second AFunOp will have same op_usage - skip = op_usage[i_op] != usage_t( yes_usage ); - skip &= atom_state != arg_atom && atom_state != ret_atom; - if( skip ) - { if( op == CExpOp ) - ++cexp_next; - // - if( op == AFunOp ) - { if( atom_state == start_atom ) - atom_state = end_atom; - else - { CPPAD_ASSERT_UNKNOWN( atom_state == end_atom ); - atom_state = start_atom; - } - } - } - else switch( op ) - { // op_usage[i_op] == usage_t(yes_usage) - - case BeginOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - // Put BeginOp at beginning of recording - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutOp(BeginOp); - rec->PutArg(arg[0]); - break; - - // -------------------------------------------------------------- - // Unary operators, argument a variable, one result - case AbsOp: - case AcosOp: - case AcoshOp: - case AsinOp: - case AsinhOp: - case AtanOp: - case AtanhOp: - case CosOp: - case CoshOp: - case ErfOp: - case ErfcOp: - case ExpOp: - case Expm1Op: - case LogOp: - case Log1pOp: - case SignOp: - case SinOp: - case SinhOp: - case SqrtOp: - case TanOp: - case TanhOp: - if( previous == 0 ) - { // - new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ]; - rec->PutArg( new_arg[0] ); - // - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutOp(op); - CPPAD_ASSERT_UNKNOWN( - new_arg[0] < new_var[random_itr.var2op(i_var)] - ); - if( op == ErfOp || op == ErfcOp ) - { CPPAD_ASSERT_NARG_NRES(op, 3, 5); - // Error function is a special case - // second argument is always the parameter 0 - // third argument is always the parameter 2 / sqrt(pi) - CPPAD_ASSERT_UNKNOWN( NumArg(ErfOp) == 3 ); - rec->PutArg( rec->put_con_par( Base(0.0) ) ); - rec->PutArg( rec->put_con_par( - Base( 1.0 / std::sqrt( std::atan(1.0) ) ) - ) ); - } - else - { // some of these operators have an auxillary result; - // e.g. sine and cosine are computed together. - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) ==1 || NumRes(op) == 2 ); - } - } - break; - // --------------------------------------------------- - // Binary operators, left variable, right parameter, one result - case SubvpOp: - // check if this is the top of a csum connection - i_tmp = random_itr.var2op(size_t(arg[0])); - top_csum = op_usage[i_tmp] == usage_t(csum_usage); - if( top_csum ) - { CPPAD_ASSERT_UNKNOWN( previous == 0 ); - // - // convert to a sequence of summation operators - size_pair = record_csum( - play , - random_itr , - op_usage , - new_par , - new_var , - i_var , - rec , - csum_work - ); - new_op[i_op] = addr_t( size_pair.i_op ); - new_var[i_op] = addr_t( size_pair.i_var ); - // abort rest of this case - break; - } - case DivvpOp: - case PowvpOp: - case ZmulvpOp: - if( previous == 0 ) - { // - size_pair = record_vp( - play , - random_itr , - new_par , - new_var , - i_op , - rec - ); - new_op[i_op] = addr_t( size_pair.i_op ); - new_var[i_op] = addr_t( size_pair.i_var ); - } - break; - // --------------------------------------------------- - // Binary operators, left index, right variable, one result - case DisOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - if( previous == 0 ) - { // - new_arg[0] = arg[0]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - rec->PutArg( new_arg[0], new_arg[1] ); - // - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutOp(op); - CPPAD_ASSERT_UNKNOWN( - new_arg[1] < new_var[random_itr.var2op(i_var)] - ); - } - break; - - // --------------------------------------------------- - // Binary operators, left parameter, right variable, one result - case SubpvOp: - case AddpvOp: - // check if this is the top of a csum connection - i_tmp = random_itr.var2op(size_t(arg[1])); - top_csum = op_usage[i_tmp] == usage_t(csum_usage); - if( top_csum ) - { CPPAD_ASSERT_UNKNOWN( previous == 0 ); - // - // convert to a sequence of summation operators - size_pair = record_csum( - play , - random_itr , - op_usage , - new_par , - new_var , - i_var , - rec , - csum_work - ); - new_op[i_op] = addr_t( size_pair.i_op ); - new_var[i_op] = addr_t( size_pair.i_var ); - // abort rest of this case - break; - } - case DivpvOp: - case MulpvOp: - case PowpvOp: - case ZmulpvOp: - if( previous == 0 ) - { // - size_pair = record_pv( - play , - random_itr , - new_par , - new_var , - i_op , - rec - ); - new_op[i_op] = addr_t( size_pair.i_op ); - new_var[i_op] = addr_t( size_pair.i_var ); - } - break; - // --------------------------------------------------- - // Binary operator, left and right variables, one result - case AddvvOp: - case SubvvOp: - // check if this is the top of a csum connection - i_tmp = random_itr.var2op(size_t(arg[0])); - top_csum = op_usage[i_tmp] == usage_t(csum_usage); - i_tmp = random_itr.var2op(size_t(arg[1])); - top_csum |= op_usage[i_tmp] == usage_t(csum_usage); - if( top_csum ) - { CPPAD_ASSERT_UNKNOWN( previous == 0 ); - // - // convert to a sequence of summation operators - size_pair = record_csum( - play , - random_itr , - op_usage , - new_par , - new_var , - i_var , - rec , - csum_work - ); - new_op[i_op] = addr_t( size_pair.i_op ); - new_var[i_op] = addr_t( size_pair.i_var ); - // abort rest of this case - break; - } - case DivvvOp: - case MulvvOp: - case PowvvOp: - case ZmulvvOp: - if( previous == 0 ) - { // - size_pair = record_vv( - play , - random_itr , - new_var , - i_op , - rec - ); - new_op[i_op] = addr_t( size_pair.i_op ); - new_var[i_op] = addr_t( size_pair.i_var ); - } - break; - // --------------------------------------------------- - // Conditional expression operators - case CExpOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - 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 ) - { new_arg[i] = new_var[ random_itr.var2op(size_t(arg[i])) ]; - CPPAD_ASSERT_UNKNOWN( - size_t(new_arg[i]) < num_var - ); - } - else - new_arg[i] = new_par[ 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] - ); - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutOp(op); - // - // The new addresses for left and right are used during - // fill in the arguments for the CSkip operations. This does not - // affect max_left_right which is used during this sweep. - if( conditional_skip ) - { CPPAD_ASSERT_UNKNOWN( cexp_next < num_cexp ); - CPPAD_ASSERT_UNKNOWN( - size_t( cexp_info[cexp_next].i_op ) == i_op - ); - cskip_new[ cexp_next ].left = size_t( new_arg[2] ); - cskip_new[ cexp_next ].right = size_t( new_arg[3] ); - ++cexp_next; - } - break; - // --------------------------------------------------- - // Operations with no arguments and no results - case EndOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 0, 0); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - break; - // --------------------------------------------------- - // Comparison operations: two arguments and no results - case LepvOp: - case LtpvOp: - case EqpvOp: - case NepvOp: - CPPAD_ASSERT_UNKNOWN( compare_op ); - CPPAD_ASSERT_NARG_NRES(op, 2, 0); - if( previous == 0 ) - { new_arg[0] = new_par[ arg[0] ]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - rec->PutArg(new_arg[0], new_arg[1]); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - } - break; - // - case LevpOp: - case LtvpOp: - CPPAD_ASSERT_UNKNOWN( compare_op ); - CPPAD_ASSERT_NARG_NRES(op, 2, 0); - if( previous == 0 ) - { new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ]; - new_arg[1] = new_par[ arg[1] ]; - rec->PutArg(new_arg[0], new_arg[1]); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - } - break; - // - case LevvOp: - case LtvvOp: - case EqvvOp: - case NevvOp: - CPPAD_ASSERT_UNKNOWN( compare_op ); - CPPAD_ASSERT_NARG_NRES(op, 2, 0); - if( previous == 0 ) - { new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - rec->PutArg(new_arg[0], new_arg[1]); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - } - break; - - // --------------------------------------------------- - // Operations with no arguments and one result - case InvOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutOp(op); - break; - - // --------------------------------------------------- - // Unary operators, argument a parameter, one result - case ParOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - new_arg[0] = new_par[ arg[0] ]; - rec->PutArg( new_arg[0] ); - // - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutOp(op); - break; - - // --------------------------------------------------- - // print forward operator - case PriOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 5, 0); - // arg[0] - new_arg[0] = arg[0]; - // - // arg[1] - if( arg[0] & 1 ) - { new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var ); - } - else - { new_arg[1] = new_par[ arg[1] ]; - } - // - // arg[3] - if( arg[0] & 2 ) - { new_arg[3] = new_var[ random_itr.var2op(size_t(arg[3])) ]; - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[3]) < num_var ); - } - else - { new_arg[3] = new_par[ arg[3] ]; - } - new_arg[2] = rec->PutTxt( play->GetTxt(size_t(arg[2])) ); - new_arg[4] = rec->PutTxt( play->GetTxt(size_t(arg[4])) ); - // - rec->PutArg( - new_arg[0] , - new_arg[1] , - new_arg[2] , - new_arg[3] , - new_arg[4] - ); - // new operator - new_op[i_op] = addr_t( rec->num_op_rec() ); - // no new variable - rec->PutOp(op); - break; - - // --------------------------------------------------- - // VecAD operators - - // Load using a parameter index - case LdpOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 3, 1); - new_arg[0] = new_vecad_ind[ arg[0] ]; - new_arg[1] = new_par[ arg[1] ]; - CPPAD_ASSERT_UNKNOWN( - size_t( (std::numeric_limits::max)() ) >= rec->num_var_load_rec() - ); - new_arg[2] = addr_t( rec->num_var_load_rec() ); - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind ); - rec->PutArg( - new_arg[0], - new_arg[1], - new_arg[2] - ); - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutLoadOp(op); - break; - - // Load using a variable index - case LdvOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 3, 1); - new_arg[0] = new_vecad_ind[ arg[0] ]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - CPPAD_ASSERT_UNKNOWN( - size_t( (std::numeric_limits::max)() ) >= rec->num_var_load_rec() - ); - new_arg[2] = addr_t( rec->num_var_load_rec() ); - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind ); - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var ); - rec->PutArg( - new_arg[0], - new_arg[1], - new_arg[2] - ); - new_op[i_op] = addr_t( rec->num_op_rec() ); - new_var[i_op] = rec->PutLoadOp(op); - break; - - // Store a parameter using a parameter index - case StppOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - new_arg[0] = new_vecad_ind[ arg[0] ]; - new_arg[1] = new_par[ arg[1] ]; - new_arg[2] = new_par[ arg[2] ]; - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind ); - rec->PutArg( - new_arg[0], - new_arg[1], - new_arg[2] - ); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - break; - - // Store a parameter using a variable index - case StvpOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - new_arg[0] = new_vecad_ind[ arg[0] ]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - new_arg[2] = new_par[ arg[2] ]; - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind ); - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var ); - rec->PutArg( - new_arg[0], - new_arg[1], - new_arg[2] - ); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - break; - - // Store a variable using a parameter index - case StpvOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - new_arg[0] = new_vecad_ind[ arg[0] ]; - new_arg[1] = new_par[ arg[1] ]; - new_arg[2] = new_var[ random_itr.var2op(size_t(arg[2])) ]; - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind ); - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[2]) < num_var ); - rec->PutArg( - new_arg[0], - new_arg[1], - new_arg[2] - ); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - break; - - // Store a variable using a variable index - case StvvOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - new_arg[0] = new_vecad_ind[ arg[0] ]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - new_arg[2] = new_var[ random_itr.var2op(size_t(arg[2])) ]; - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind ); - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var ); - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[2]) < num_var ); - rec->PutArg( - new_arg[0], - new_arg[1], - new_arg[2] - ); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(op); - break; - - // ----------------------------------------------------------- - // atomic function call operators - - case AFunOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 4, 0); - // atom_index, atom_old, atom_n, atom_m - rec->PutArg(arg[0], arg[1], arg[2], arg[3]); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(AFunOp); - if( atom_state == start_atom ) - { atom_state = arg_atom; - atom_j = size_t( arg[2] ); // just for counting arguments - atom_i = size_t( arg[3] ); // just for counting results - CPPAD_ASSERT_UNKNOWN( atom_j > 0 ); - CPPAD_ASSERT_UNKNOWN( atom_i > 0 ); - } - else - { CPPAD_ASSERT_UNKNOWN( atom_state == end_atom ); - atom_state = start_atom; - } - break; - - case FunapOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - new_arg[0] = new_par[ arg[0] ]; - if( new_arg[0] == addr_t_max ) - new_arg[0] = zero_par_index; - rec->PutArg(new_arg[0]); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(FunapOp); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - --atom_j; - if( atom_j == 0 ) - atom_state = ret_atom; - break; - - case FunavOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ]; - CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_var ); - if( new_arg[0] != 0 ) - { rec->PutArg(new_arg[0]); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(FunavOp); - } - else - { // This argument does not affect the result and - // has been optimized out so use nan in its place. - new_arg[0] = zero_par_index; - rec->PutArg(new_arg[0]); - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(FunapOp); - } - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - --atom_j; - if( atom_j == 0 ) - atom_state = ret_atom; - break; - - case FunrpOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - new_arg[0] = new_par[ arg[0] ]; - if( new_arg[0] == addr_t_max ) - { // This parameter is not used here or anywhere. - CPPAD_ASSERT_UNKNOWN( op_usage[i_op] == usage_t(no_usage) ); - new_arg[0] = zero_par_index; - } - rec->PutArg(new_arg[0]); - // - new_op[i_op] = addr_t( rec->num_op_rec() ); - rec->PutOp(FunrpOp); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - --atom_i; - if( atom_i == 0 ) - atom_state = end_atom; - break; - - case FunrvOp: - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - new_op[i_op] = addr_t( rec->num_op_rec() ); - if( op_usage[i_op] == usage_t(yes_usage) ) - new_var[i_op] = rec->PutOp(FunrvOp); - else - { // change FunrvOp -> FunrpOp to avoid creating new variable - CPPAD_ASSERT_UNKNOWN( op_usage[i_op] == usage_t(no_usage) ); - CPPAD_ASSERT_NARG_NRES(FunrpOp, 1, 0); - rec->PutArg( zero_par_index ); - rec->PutOp(FunrpOp); - } - - --atom_i; - if( atom_i == 0 ) - atom_state = end_atom; - break; - // --------------------------------------------------- - case CSumOp: - // --------------------------------------------------- - CPPAD_ASSERT_UNKNOWN( previous == 0 ); - // - // check if more entries can be included in this summation - size_pair = record_csum( - play , - random_itr , - op_usage , - new_par , - new_var , - i_var , - rec , - csum_work - ); - new_op[i_op] = addr_t( size_pair.i_op ); - new_var[i_op] = addr_t( size_pair.i_var ); - break; - // --------------------------------------------------- - - // all cases should be handled above - default: - CPPAD_ASSERT_UNKNOWN(false); - } - } - // modify the dependent variable vector to new indices - for(size_t i = 0; i < dep_taddr.size(); i++ ) - { dep_taddr[i] = size_t(new_var[ random_itr.var2op(dep_taddr[i]) ]); - CPPAD_ASSERT_UNKNOWN( size_t(dep_taddr[i]) < num_var ); - } - -# ifndef NDEBUG - for(i_op = 0; i_op < num_op; i_op++) - { random_itr.op_info(i_op, op, arg, i_var); - if( NumRes(op) > 0 ) - CPPAD_ASSERT_UNKNOWN( - size_t(new_op[i_op]) < rec->num_op_rec() - ); - } -# endif - // make sure that all the conditional expressions have been - // checked to see if they are still present - CPPAD_ASSERT_UNKNOWN( cskip_order_next == num_cexp ); - // fill in the arguments for the CSkip operations - for(size_t i = 0; i < num_cexp; i++) - { // if cskip_new[i].i_arg == 0, this conditional expression was skipped - if( cskip_new[i].i_arg > 0 ) - { // size_t i_arg - struct_cexp_info info = cexp_info[i]; - addr_t n_true = addr_t( skip_op_true.number_elements(i) ); - addr_t n_false = addr_t( skip_op_false.number_elements(i) ); - i_arg = cskip_new[i].i_arg; - addr_t left = addr_t( cskip_new[i].left ); - addr_t right = addr_t( cskip_new[i].right ); - rec->ReplaceArg(i_arg++, addr_t(info.cop) ); - rec->ReplaceArg(i_arg++, addr_t(info.flag) ); - rec->ReplaceArg(i_arg++, left ); - rec->ReplaceArg(i_arg++, right ); - rec->ReplaceArg(i_arg++, n_true ); - rec->ReplaceArg(i_arg++, n_false ); - sparse::list_setvec::const_iterator itr_true(skip_op_true, i); - while( *itr_true != skip_op_true.end() ) - { i_op = *itr_true; - // op_usage[i_op] == usage_t(yes_usage) - CPPAD_ASSERT_UNKNOWN( new_op[i_op] != 0 ); - rec->ReplaceArg(i_arg++, new_op[i_op] ); - // - ++itr_true; - } - sparse::list_setvec::const_iterator itr_false(skip_op_false, i); - while( *itr_false != skip_op_false.end() ) - { i_op = *itr_false; - // op_usage[i_op] == usage_t(yes_usage) - CPPAD_ASSERT_UNKNOWN( new_op[i_op] != 0 ); - rec->ReplaceArg(i_arg++, new_op[i_op] ); - // - ++itr_false; - } - rec->ReplaceArg(i_arg++, n_true + n_false); -# ifndef NDEBUG - size_t n_arg = 7 + size_t(n_true) + size_t(n_false); - CPPAD_ASSERT_UNKNOWN( cskip_new[i].i_arg + n_arg == i_arg ); -# endif - } - } - return exceed_collision_limit; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/record_csum.hpp b/build-config/cppad/include/cppad/local/optimize/record_csum.hpp deleted file mode 100644 index 5f986579..00000000 --- a/build-config/cppad/include/cppad/local/optimize/record_csum.hpp +++ /dev/null @@ -1,386 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_CSUM_HPP -# define CPPAD_LOCAL_OPTIMIZE_RECORD_CSUM_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/*! -$begin optimize_record_csum$$ -$spell - iutr - iterator - op - var - itr - NumRes - csum - Addpv - Addvv - Subpv - Subvp - Subvv -$$ - -$section Recording a Cumulative Summation Operator$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_RECORD_CSUM%// END_PROROTYPE%1 -%$$ - -$head play$$ -player object corresponding to the old recording. - -$head random_itr$$ -is a random iterator corresponding to the old operation sequence. - -$head op_usage$$ -mapping from old operator index to how it is used. - -$head new_par$$ -mapping from old parameter index to parameter index in new recording. - -$head new_var$$ -mapping from old operator index to variable index in new recording. - -$head current$$ -is the index in the old operation sequence for -the variable corresponding to the result for the current operator. -We use the notation $icode%i_op% = %random_itr%.var2op(%current%)%$$. -It follows that NumRes( random_itr.get_op[i_op] ) > 0. -If 0 < j_op < i_op, either op_usage[j_op] == usage_t(csum_usage), -op_usage[j_op] = usage_t(no_usage), or new_var[j_op] != 0. - -$head rec$$ -is the object that will record the new operations. - -$head return$$ -is the operator and variable indices in the new operation sequence. - -$head stack$$ -Is temporary work space. On input and output, -stack.op_info, stack.add_var, and stack.sub_var, are all empty. -These stacks are passed in so that they are created once -and then be reused with calls to $code record_csum$$. - -$head Assumptions$$ -$list number$$ -random_itr.get_op[i_op] must be one of the following: -CSumOp, AddpvOp, AddvvOp, SubpvOp, SubvpOp, SubvvOp. -$lnext -op_usage[i_op] == usage_t(yes_usage). -$lnext -Either this is a CSumOp, or -op_usage[j_op] == usage_t(csum_usage) is true from some -j_op that corresponds to a variable that is an argument to -random_itr.get_op[i_op]. -$lend - -$end -*/ - -// BEGIN_RECORD_CSUM -template -struct_size_pair record_csum( - const player* play , - const play::const_random_iterator& random_itr , - const pod_vector& op_usage , - const pod_vector& new_par , - const pod_vector& new_var , - size_t current , - recorder* rec , - // local information passed so stacks need not be allocated for every call - struct_csum_stacks& stack ) -// END_PROROTYPE -{ -# ifndef NDEBUG - // number of parameters corresponding to the old operation sequence. - size_t npar = play->num_par_rec(); -# endif - - // vector of length npar containing the parameters the old operation - // sequence; i.e., given a parameter index i < npar, the corresponding - // parameter value is par[i]. - const Base* par = play->GetPar(); - - // which parameters are dynamic - const pod_vector& dyn_par_is( play->dyn_par_is() ); - - // check assumption about work space - CPPAD_ASSERT_UNKNOWN( stack.op_info.empty() ); - CPPAD_ASSERT_UNKNOWN( stack.add_var.empty() ); - CPPAD_ASSERT_UNKNOWN( stack.sub_var.empty() ); - // - // this operator is not csum connected to some other result - size_t i_op = random_itr.var2op(current); - CPPAD_ASSERT_UNKNOWN( ! ( op_usage[i_op] == usage_t(csum_usage) ) ); - // - // information corresponding to the root node in the cummulative summation - struct struct_csum_op_info info; - size_t not_used; - random_itr.op_info(i_op, info.op, info.arg, not_used); - info.add = true; // was parrent operator positive or negative - // - // initialize stack as containing this one operator - stack.op_info.push( info ); - // - // initialize sum of parameter values as zero - Base sum_par(0); - // -# ifndef NDEBUG - // one argument of this operator must have been csum connected to it - bool ok = info.op == CSumOp; - if( (! ok) & (info.op != SubpvOp) & (info.op != AddpvOp) ) - { // first argument is a varialbe being added - i_op = random_itr.var2op(size_t(info.arg[0])); - ok |= op_usage[i_op] == usage_t(csum_usage); - } - if( (! ok) & (info.op != SubvpOp) ) - { // second argument is a varialbe being added or subtracted - i_op = random_itr.var2op(size_t(info.arg[1])); - ok |= op_usage[i_op] == usage_t(csum_usage); - } - CPPAD_ASSERT_UNKNOWN( ok ); -# endif - // - // while there are operators left on the stack - while( ! stack.op_info.empty() ) - { // get this summation operator - info = stack.op_info.top(); - stack.op_info.pop(); - OpCode op = info.op; - const addr_t* arg = info.arg; - bool add = info.add; - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 ); - // - if( op == CSumOp ) - { // --------------------------------------------------------------- - // Begin op == CSumOp - // - // arg[0] is constant parameter that initializes the sum - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < npar ); - CPPAD_ASSERT_UNKNOWN( ! dyn_par_is[ arg[0] ] ); - if( add ) - sum_par += par[arg[0]]; - else - sum_par -= par[arg[0]]; - // - // stack entries for addition variable - size_t var_start = 5; // start addition variables - size_t var_end = size_t( arg[1] ); // end addition variables - bool add_var = add; // addition variables - for(size_t j = 0; j < 2; ++j) - { for(size_t i = var_start; i < var_end; ++i) - { // - // check if the i-th argument has csum usage - i_op = random_itr.var2op(size_t(arg[i])); - if( op_usage[i_op] == usage_t(csum_usage) ) - { // there is no result corresponding to i-th argument - CPPAD_ASSERT_UNKNOWN( size_t( new_var[i_op]) == 0 ); - - // push operator corresponding to the i-th argument - random_itr.op_info(i_op, info.op, info.arg, not_used); - info.add = add; - stack.op_info.push( info ); - } - else - { // there are no nodes below this one - CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < current ); - if( add_var ) - stack.add_var.push(arg[i]); - else - stack.sub_var.push(arg[i]); - } - } - var_start = var_end; // start subtraction variables - var_end = size_t( arg[2] ); // end subtraction variables - add_var = ! add; // subtraction variables - } - // - // stack entries for addition dynamic parameters - size_t dyn_start = var_end; // start addition dynamics - size_t dyn_end = size_t( arg[3] ); // end addition dynamics - bool dny_add = add; // addition dynamics - for(size_t j = 0; j < 2; ++j) - { for(size_t i = dyn_start; i < dyn_end; ++i) - { // i-th argument is a dynamic parameter - // (can't yet be a result, so no nodes below) - CPPAD_ASSERT_UNKNOWN( dyn_par_is[ arg[i] ] ); - if( dny_add ) - stack.add_dyn.push(arg[i]); - else - stack.sub_dyn.push(arg[i]); - } - dyn_start = dyn_end; // start subtraction dynamics - dyn_end = size_t( arg[4] ); // end subtraction dynamics - dny_add = ! add; // subtraction dynamics - } - // End op == CSumOp - // --------------------------------------------------------------- - } - else - { // --------------------------------------------------------------- - // Begin op != CSumOp - // - // is this a subtraction operator - bool subtract = (op==SubpvOp) | (op==SubvpOp) | (op==SubvvOp); - // - // is the i-th arguemnt a parameter - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 ); - bool par_arg[2]; - switch(op) - { case SubpvOp: - case AddpvOp: - par_arg[0] = true; - par_arg[1] = false; - break; - // - case SubvpOp: - par_arg[0] = false; - par_arg[1] = true; - break; - // - default: - par_arg[0] = false; - par_arg[1] = false; - break; - } - // - // loop over the arguments to this operator - for(size_t i = 0; i < 2; ++i) - { if( subtract & (i == 1) ) - add = ! add; - if( par_arg[i] ) - { // case where i-th argument is a parameter - CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < npar ); - // - if( dyn_par_is[ arg[i] ] ) - { // i-th argument is a dynamic parameter - // (can't yet be a result, so no nodes below) - if( add ) - stack.add_dyn.push(arg[i]); - else - stack.sub_dyn.push(arg[i]); - } - else - { // i-th argument is constant parameter - if( add ) - sum_par += par[arg[i]]; - else - sum_par -= par[arg[i]]; - } - } - else - { // case where i-th argument is a variable - // - // check if the i-th argument has csum usage - i_op = random_itr.var2op(size_t(arg[i])); - if( op_usage[i_op] == usage_t(csum_usage) ) - { // there is no result corresponding to i-th argument - CPPAD_ASSERT_UNKNOWN( size_t( new_var[i_op]) == 0 ); - - // push operator corresponding to the i-th argument - random_itr.op_info(i_op, info.op, info.arg, not_used); - info.add = add; - stack.op_info.push( info ); - } - else - { // there are no nodes below this one - CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < current ); - if( add ) - stack.add_var.push(arg[i]); - else - stack.sub_var.push(arg[i]); - } - } - } - // End op != CSumOp - // --------------------------------------------------------------- - } - } - // number of variables to add in this cummulative sum operator - size_t n_add_var = stack.add_var.size(); - - // number of variables to subtract in this cummulative sum operator - size_t n_sub_var = stack.sub_var.size(); - - // number of dynamics to add in this cummulative sum operator - size_t n_add_dyn = stack.add_dyn.size(); - - // number of dynamics to subtract in this cummulative sum operator - size_t n_sub_dyn = stack.sub_dyn.size(); - - // first five arguments to cumulative sum operator - addr_t new_arg = rec->put_con_par(sum_par); - rec->PutArg(new_arg); // arg[0]: initial sum - size_t end = n_add_var + 5; - rec->PutArg( addr_t(end) ); // arg[1]: end for add variables - end += n_sub_var; - rec->PutArg( addr_t(end) ); // arg[2]: end for sub variables - end += n_add_dyn; - rec->PutArg( addr_t(end) ); // arg[3]: end for add dynamics - end += n_sub_dyn; - rec->PutArg( addr_t(end) ); // arg[4]: end for sub dynamics - - // addition variable arguments - for(size_t i = 0; i < n_add_var; i++) - { CPPAD_ASSERT_UNKNOWN( ! stack.add_var.empty() ); - addr_t old_arg = stack.add_var.top(); - new_arg = new_var[ random_itr.var2op(size_t(old_arg)) ]; - CPPAD_ASSERT_UNKNOWN( 0 < new_arg && size_t(new_arg) < current ); - rec->PutArg(new_arg); // arg[5+i] - stack.add_var.pop(); - } - - // subtraction variable arguments - for(size_t i = 0; i < n_sub_var; i++) - { CPPAD_ASSERT_UNKNOWN( ! stack.sub_var.empty() ); - addr_t old_arg = stack.sub_var.top(); - new_arg = new_var[ random_itr.var2op(size_t(old_arg)) ]; - CPPAD_ASSERT_UNKNOWN( 0 < new_arg && size_t(new_arg) < current ); - rec->PutArg(new_arg); // arg[arg[1] + i] - stack.sub_var.pop(); - } - - // addition dynamic arguments - for(size_t i = 0; i < n_add_dyn; ++i) - { addr_t old_arg = stack.add_dyn.top(); - new_arg = new_par[ old_arg ]; - rec->PutArg(new_arg); // arg[arg[2] + i] - stack.add_dyn.pop(); - } - - // subtraction dynamic arguments - for(size_t i = 0; i < n_sub_dyn; ++i) - { addr_t old_arg = stack.sub_dyn.top(); - new_arg = new_par[ old_arg ]; - rec->PutArg(new_arg); // arg[arg[3] + i] - stack.sub_dyn.pop(); - } - - // number of additions plus number of subtractions - rec->PutArg( addr_t(end) ); // arg[arg[4]] = arg[4] - // - // return value - struct_size_pair ret; - ret.i_op = rec->num_op_rec(); - ret.i_var = size_t(rec->PutOp(CSumOp)); - // - return ret; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/record_pv.hpp b/build-config/cppad/include/cppad/local/optimize/record_pv.hpp deleted file mode 100644 index a0809aa2..00000000 --- a/build-config/cppad/include/cppad/local/optimize/record_pv.hpp +++ /dev/null @@ -1,102 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_PV_HPP -# define CPPAD_LOCAL_OPTIMIZE_RECORD_PV_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file record_pv.hpp -Record an operation of the form (parameter op variable). -*/ -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/*! -Record an operation of the form (parameter op variable). - -\param play -player object corresponding to the old recroding. - -\param random_itr -random iterator corresponding to old recording. - -\param new_par -mapping from old parameter index to parameter index in new recording. - -\param new_var -mapping from old operator index to variable index in new recording. - -\param i_op -is the index in the old operation sequence for this operator. -The operator must be one of the following: -AddpvOp, DivpvOp, MulpvOp, PowpvOp, SubpvOp, ZmulpvOp. - -\param rec -is the object that will record the new operations. - -\return -is the operator and variable indices in the new operation sequence. -*/ -template -struct_size_pair record_pv( - const player* play , - const play::const_random_iterator& random_itr , - const pod_vector& new_par , - const pod_vector& new_var , - size_t i_op , - recorder* rec ) -{ - // get_op_info - OpCode op; - const addr_t* arg; - size_t i_var; - random_itr.op_info(i_op, op, arg, i_var); - // -# ifndef NDEBUG - switch(op) - { case AddpvOp: - case DivpvOp: - case MulpvOp: - case PowpvOp: - case SubpvOp: - case ZmulpvOp: - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - // number of parameters corresponding to the old operation sequence. - size_t npar = play->num_par_rec(); -# endif - // - // vector of length npar containing the parameters the old operation - // sequence; i.e., given a parameter index i < npar, the corresponding - // parameter value is par[i]. - // - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < npar ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_var ); // DAG condition - // - addr_t new_arg[2]; - new_arg[0] = new_par[ arg[0] ]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - rec->PutArg( new_arg[0], new_arg[1] ); - // - struct_size_pair ret; - ret.i_op = rec->num_op_rec(); - ret.i_var = size_t(rec->PutOp(op)); - CPPAD_ASSERT_UNKNOWN( 0 < new_arg[1] && size_t(new_arg[1]) < ret.i_var ); - return ret; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/record_vp.hpp b/build-config/cppad/include/cppad/local/optimize/record_vp.hpp deleted file mode 100644 index ca784bb1..00000000 --- a/build-config/cppad/include/cppad/local/optimize/record_vp.hpp +++ /dev/null @@ -1,101 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_VP_HPP -# define CPPAD_LOCAL_OPTIMIZE_RECORD_VP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file record_vp.hpp -Record an operation of the form (variable op parameter). -*/ -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - - -/*! -Record an operation of the form (variable op parameter). - -\param play -player object corresponding to the old recroding. - -\param random_itr -is a random iterator corresponding to the old recording. - -\param new_par -mapping from old parameter index to parameter index in new recording. - -\param new_var -mapping from old operator index to variable index in new recording. - -\param i_op -is the index in the old operation sequence for this operator. -the must be one of the following: -DivvpOp, PowvpOp, SubvpOp, ZmulvpOp. - -\param rec -is the object that will record the new operations. - -\return -is the operator and variable indices in the new operation sequence. -*/ -template -struct_size_pair record_vp( - const player* play , - const play::const_random_iterator& random_itr , - const pod_vector& new_par , - const pod_vector& new_var , - size_t i_op , - recorder* rec ) -{ - // get_op_info - OpCode op; - const addr_t* arg; - size_t i_var; - random_itr.op_info(i_op, op, arg, i_var); - // -# ifndef NDEBUG - switch(op) - { case DivvpOp: - case PowvpOp: - case SubvpOp: - case ZmulvpOp: - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - // number of parameters corresponding to the old operation sequence. - size_t npar = play->num_par_rec(); -# endif - - // vector of length npar containing the parameters the old operation - // sequence; i.e., given a parameter index i < npar, the corresponding - // parameter value is par[i]. - // - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_var ); // DAG condition - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < npar ); - // - addr_t new_arg[2]; - new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ]; - new_arg[1] = new_par[ arg[1] ]; - rec->PutArg( new_arg[0], new_arg[1] ); - // - struct_size_pair ret; - ret.i_op = rec->num_op_rec(); - ret.i_var = size_t(rec->PutOp(op)); - CPPAD_ASSERT_UNKNOWN( 0 < new_arg[0] && size_t(new_arg[0]) < ret.i_var ); - return ret; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/record_vv.hpp b/build-config/cppad/include/cppad/local/optimize/record_vv.hpp deleted file mode 100644 index 1f6ab735..00000000 --- a/build-config/cppad/include/cppad/local/optimize/record_vv.hpp +++ /dev/null @@ -1,91 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_VV_HPP -# define CPPAD_LOCAL_OPTIMIZE_RECORD_VV_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file record_vv.hpp -Record an operation of the form (variable op variable). -*/ -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { -/*! -Record an operation of the form (variable op variable). - -\param play -player object corresponding to the old recroding. - -\param random_itr -random iterator corresponding to the old recording. - -\param new_var -mapping from old operator index to variable index in new recording. - -\param i_op -is the index in the old operation sequence for this operator. -the must be one of the following: -AddvvOp, DivvvOp, MulvvOp, PowvvOp, SubvvOp, ZmulvvOp. - -\param rec -is the object that will record the new operations. - -\return -is the operator and variable indices in the new operation sequence. -*/ -template -struct_size_pair record_vv( - const player* play , - const play::const_random_iterator& random_itr , - const pod_vector& new_var , - size_t i_op , - recorder* rec ) -{ - // get_op_info - OpCode op; - const addr_t* arg; - size_t i_var; - random_itr.op_info(i_op, op, arg, i_var); - // -# ifndef NDEBUG - switch(op) - { case AddvvOp: - case DivvvOp: - case MulvvOp: - case PowvvOp: - case SubvvOp: - case ZmulvvOp: - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - } -# endif - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_var ); // DAG condition - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_var ); // DAG condition - // - addr_t new_arg[2]; - new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ]; - new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ]; - rec->PutArg( new_arg[0], new_arg[1] ); - // - struct_size_pair ret; - ret.i_op = rec->num_op_rec(); - ret.i_var = size_t(rec->PutOp(op)); - CPPAD_ASSERT_UNKNOWN( 0 < new_arg[0] && size_t(new_arg[0]) < ret.i_var ); - CPPAD_ASSERT_UNKNOWN( 0 < new_arg[1] && size_t(new_arg[1]) < ret.i_var ); - return ret; -} - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/size_pair.hpp b/build-config/cppad/include/cppad/local/optimize/size_pair.hpp deleted file mode 100644 index 96d33921..00000000 --- a/build-config/cppad/include/cppad/local/optimize/size_pair.hpp +++ /dev/null @@ -1,32 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_SIZE_PAIR_HPP -# define CPPAD_LOCAL_OPTIMIZE_SIZE_PAIR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/*! -\file size_pair.hpp -Information for one variable and one operation sequence. -*/ -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -/*! -\file size_pair.hpp -Information for one variable in one operation sequence. -*/ -struct struct_size_pair { - size_t i_op; /// operator index for this variable - size_t i_var; /// variable index for this variable -}; - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/optimize/usage.hpp b/build-config/cppad/include/cppad/local/optimize/usage.hpp deleted file mode 100644 index 8eb2f5e0..00000000 --- a/build-config/cppad/include/cppad/local/optimize/usage.hpp +++ /dev/null @@ -1,39 +0,0 @@ -# ifndef CPPAD_LOCAL_OPTIMIZE_USAGE_HPP -# define CPPAD_LOCAL_OPTIMIZE_USAGE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -namespace CppAD { namespace local { namespace optimize { - -typedef CPPAD_VEC_ENUM_TYPE usage_t; - -enum enum_usage { - /// This operator is not used. - no_usage, - - /// This operator is used one or more times. - yes_usage, - - /*! - This operator is only used once, it is a summation operator, - and its parrent is a summation operator. Furthermore, its result is not - a dependent variable. Hence case it can be removed as part of a - cumulative summation starting at its parent or above. - */ - csum_usage -}; - - -} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/parameter_op.hpp b/build-config/cppad/include/cppad/local/parameter_op.hpp deleted file mode 100644 index f8617f0c..00000000 --- a/build-config/cppad/include/cppad/local/parameter_op.hpp +++ /dev/null @@ -1,89 +0,0 @@ -# ifndef CPPAD_LOCAL_PARAMETER_OP_HPP -# define CPPAD_LOCAL_PARAMETER_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file parameter_op.hpp -Zero order forward mode for ParOp -*/ - - -/*! -Compute zero order forward mode Taylor coefficient for result of op = ParOp. - -The C++ source code corresponding to this operation is one of the following -\verbatim - ADFun f(x, y) - f.Dependent(x, y) -\endverbatim -where some of the components of the vector y are parameters. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to the component of y -that is a parameter. - -\param arg - arg[0] -\n -index corresponding to the parameter value for this operator. - -\param num_par -is the number of parameters in parameter. - -\param parameter -\b Input: parameter[ arg[0] ] is the value of a component -of y that is a parameter. - -\param cap_order -number of colums in the matrix containing all the Taylor coefficients. - -\param taylor -\b Output: taylor [ i_z * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to z. - -\par Checked Assertions where op is the unary operator with one result: -\li NumArg(op) == 1 -\li NumRes(op) == 1 -\li size_t(arg[0]) < num_par -\li 0 < cap_order -*/ -template -void forward_par_op_0( - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ParOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ParOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - Base* z = taylor + i_z * cap_order; - - z[0] = parameter[ arg[0] ]; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/play/addr_enum.hpp b/build-config/cppad/include/cppad/local/play/addr_enum.hpp deleted file mode 100644 index 5286cac7..00000000 --- a/build-config/cppad/include/cppad/local/play/addr_enum.hpp +++ /dev/null @@ -1,30 +0,0 @@ -# ifndef CPPAD_LOCAL_PLAY_ADDR_ENUM_HPP -# define CPPAD_LOCAL_PLAY_ADDR_ENUM_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE -namespace CppAD { namespace local { namespace play { - -/*! -\file addr_enum.hpp -*/ -/// enum corresponding to type used for addressing iterators for a player -enum addr_enum { - unsigned_short_enum , - unsigned_int_enum , - size_t_enum -}; - -} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/play/atom_op_info.hpp b/build-config/cppad/include/cppad/local/play/atom_op_info.hpp deleted file mode 100644 index 264055bf..00000000 --- a/build-config/cppad/include/cppad/local/play/atom_op_info.hpp +++ /dev/null @@ -1,89 +0,0 @@ -# ifndef CPPAD_LOCAL_PLAY_ATOM_OP_INFO_HPP -# define CPPAD_LOCAL_PLAY_ATOM_OP_INFO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE -namespace CppAD { namespace local { namespace play { - -/*! -\file atom_op_info.hpp -*/ - -/*! -\brief -Unpack extra information corresponding to a AFunOp - -\param op [in] -must be a AFunOp - -\param op_arg [in] -is the arguments for this operator - -\param atom_old [out] -is the extra information passed to the old style atomic functions. - -\param atom_index [out] -is the index in local::atomic_index corresponding to this atomic functions. - -\param atom_m [out] -is the number of results for this user atmoic function. - -\param atom_n [out] -is the number of arguments for this user atmoic function. - -\return -Is a pointer to this atomic function. -*/ -// MUSTDO: change return to void once all sweeps switch to use call_atomic. -template -atomic_base* atom_op_info( - const OpCode op , - const addr_t* op_arg , - size_t& atom_index , - size_t& atom_old , - size_t& atom_m , - size_t& atom_n ) -{ atomic_base* atom_fun; - // - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); - CPPAD_ASSERT_NARG_NRES(op, 4, 0); - // - atom_index = size_t(op_arg[0]); - atom_old = size_t(op_arg[1]); - atom_n = size_t(op_arg[2]); - atom_m = size_t(op_arg[3]); - CPPAD_ASSERT_UNKNOWN( atom_n > 0 ); - // - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); - if( type == 3 ) - return nullptr; -# ifndef NDEBUG - if( v_ptr == nullptr ) - { // atom_fun is null so cannot use atom_fun->atomic_name() - std::string msg = atomic_base::class_name(atom_index) - + ": atomic_base function has been deleted"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# endif - // the atomic_base object corresponding to this atomic function - atom_fun = reinterpret_cast< atomic_base* >( v_ptr ); - return atom_fun; -} - -} } } // END_CPPAD_LOCAL_PLAY_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/play/player.hpp b/build-config/cppad/include/cppad/local/play/player.hpp deleted file mode 100644 index b3f3386f..00000000 --- a/build-config/cppad/include/cppad/local/play/player.hpp +++ /dev/null @@ -1,853 +0,0 @@ -# ifndef CPPAD_LOCAL_PLAY_PLAYER_HPP -# define CPPAD_LOCAL_PLAY_PLAYER_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include -# include -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file player.hpp -File used to define the player class. -*/ - -/*! -Class used to store and play back an operation sequence recording. - -\tparam Base -These were AD< Base > operations when recorded. Operations during playback -are done using the type Base . -*/ - -template -class player { - // player must be a friend of player< AD > for base2ad to work - template friend class player; -private: - // ---------------------------------------------------------------------- - // information that defines the recording - - /// Number of independent dynamic parameters - size_t num_dynamic_ind_; - - /// Number of variables in the recording. - size_t num_var_rec_; - - /// number of vecad load opeations in the reconding - size_t num_var_load_rec_; - - /// Number of VecAD vectors in the recording - size_t num_var_vecad_rec_; - - /// The operators in the recording. - pod_vector op_vec_; - - /// The operation argument indices in the recording - pod_vector arg_vec_; - - /// Character strings ('\\0' terminated) in the recording. - pod_vector text_vec_; - - /// The VecAD indices in the recording. - pod_vector all_var_vecad_ind_; - - /// All of the parameters in the recording. - /// Use pod_maybe because Base may not be plain old data. - pod_vector_maybe all_par_vec_; - - /// Which elements of all_par_vec_ are dynamic parameters - /// (size equal number of parametrers) - pod_vector dyn_par_is_; - - /// mapping from dynamic parameter index to parameter index - /// 1: size equal to number of dynamic parameters - /// 2: dyn_ind2par_ind_[j] < dyn_ind2par_ind_[j+1] - pod_vector dyn_ind2par_ind_; - - /// operators for just the dynamic parameters - /// (size equal number of dynamic parameters) - pod_vector dyn_par_op_; - - /// arguments for the dynamic parameter operators - pod_vector dyn_par_arg_; - - // ---------------------------------------------------------------------- - // Information needed to use member functions that begin with random_ - // and for using const_subgraph_iterator. - - /// index in arg_vec_ corresonding to the first argument for each operator - pod_vector op2arg_vec_; - - /*! - Index of the result variable for each operator. If the operator has - no results, this is not defined. The invalid index num_var_rec_ is used - when NDEBUG is not defined. If the operator has more than one result, this - is the primary result; i.e., the last result. Auxillary are only used by - the operator and not used by other operators. - */ - pod_vector op2var_vec_; - - /// Mapping from primary variable index to corresponding operator index. - /// This is used to traverse sub-graphs of the operation sequence. - /// This value is valid (invalid) for primary (auxillary) variables. - pod_vector var2op_vec_; - -public: - // ================================================================= - /// default constructor - // set all scalars to zero to avoid valgraind warning when ani assignment - // occures before values get set. - player(void) : - num_dynamic_ind_(0) , - num_var_rec_(0) , - num_var_load_rec_(0) , - num_var_vecad_rec_(0) - { } - // move semantics constructor - // (none of the default constructor values matter to the destructor) - player(player& play) - { swap(play); } - // ================================================================= - /// destructor - ~player(void) - { } - // ====================================================================== - /// type used for addressing iterators for this player - play::addr_enum address_type(void) const - { - // required - size_t required = 0; - required = std::max(required, num_var_rec_ ); // number variables - required = std::max(required, op_vec_.size() ); // number operators - required = std::max(required, arg_vec_.size() ); // number arguments - // - // unsigned short - if( required <= std::numeric_limits::max() ) - return play::unsigned_short_enum; - // - // unsigned int - if( required <= std::numeric_limits::max() ) - return play::unsigned_int_enum; - // - // unsigned size_t - CPPAD_ASSERT_UNKNOWN( - required <= std::numeric_limits::max() - ); - return play::size_t_enum; - } - // =============================================================== - /*! - Moving an operation sequence from a recorder to this player - - \param rec - the object that was used to record the operation sequence. After this - operation, the state of the recording is no longer defined. For example, - the pod_vector member variables in this have been swapped with rec. - - \param n_ind - the number of independent variables (only used for error checking - when NDEBUG is not defined). - - \par - Use an assert to check that the length of the following vectors is - less than the maximum possible value for addr_t; i.e., that an index - in these vectors can be represented using the type addr_t: - op_vec_, all_var_vecad_ind_, arg_vec_, test_vec_, all_par_vec_, text_vec_, - dyn_par_arg_. - */ - void get_recording(recorder& rec, size_t n_ind) - { -# ifndef NDEBUG - size_t addr_t_max = size_t( std::numeric_limits::max() ); -# endif - // just set size_t values - num_dynamic_ind_ = rec.num_dynamic_ind_; - num_var_rec_ = rec.num_var_rec_; - num_var_load_rec_ = rec.num_var_load_rec_; - - // op_vec_ - op_vec_.swap(rec.op_vec_); - CPPAD_ASSERT_UNKNOWN(op_vec_.size() < addr_t_max ); - - // op_arg_vec_ - arg_vec_.swap(rec.arg_vec_); - CPPAD_ASSERT_UNKNOWN(arg_vec_.size() < addr_t_max ); - - // all_par_vec_ - all_par_vec_.swap(rec.all_par_vec_); - CPPAD_ASSERT_UNKNOWN(all_par_vec_.size() < addr_t_max ); - - // dyn_par_is_, dyn_par_op_, dyn_par_arg_ - dyn_par_is_.swap( rec.dyn_par_is_ ); - dyn_par_op_.swap( rec.dyn_par_op_ ); - dyn_par_arg_.swap( rec.dyn_par_arg_ ); - CPPAD_ASSERT_UNKNOWN(dyn_par_arg_.size() < addr_t_max ); - - // text_rec_ - text_vec_.swap(rec.text_vec_); - CPPAD_ASSERT_UNKNOWN(text_vec_.size() < addr_t_max ); - - // all_var_vecad_ind_ - all_var_vecad_ind_.swap(rec.all_var_vecad_ind_); - CPPAD_ASSERT_UNKNOWN(all_var_vecad_ind_.size() < addr_t_max ); - - // num_var_vecad_rec_ - num_var_vecad_rec_ = 0; - { // all_var_vecad_ind_ contains size of each VecAD followed by - // the parameter indices used to inialize it. - size_t i = 0; - while( i < all_var_vecad_ind_.size() ) - { num_var_vecad_rec_++; - i += size_t( all_var_vecad_ind_[i] ) + 1; - } - CPPAD_ASSERT_UNKNOWN( i == all_var_vecad_ind_.size() ); - } - - // mapping from dynamic parameter index to parameter index - dyn_ind2par_ind_.resize( dyn_par_op_.size() ); - size_t i_dyn = 0; - for(size_t i_par = 0; i_par < all_par_vec_.size(); ++i_par) - { if( dyn_par_is_[i_par] ) - { dyn_ind2par_ind_[i_dyn] = addr_t( i_par ); - ++i_dyn; - } - } - CPPAD_ASSERT_UNKNOWN( i_dyn == dyn_ind2par_ind_.size() ); - - // random access information - clear_random(); - - // some checks - check_inv_op(n_ind); - check_variable_dag(); - check_dynamic_dag(); - } - // ---------------------------------------------------------------------- - /*! - Check that InvOp operators start with second operator and are contiguous, - and there are n_ind of them. - */ -# ifdef NDEBUG - void check_inv_op(size_t n_ind) const - { return; } -# else - void check_inv_op(size_t n_ind) const - { play::const_sequential_iterator itr = begin(); - OpCode op; - const addr_t* op_arg; - size_t var_index; - itr.op_info(op, op_arg, var_index); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); - size_t i_op = 0; - while( op != EndOp ) - { // start at second operator - (++itr).op_info(op, op_arg, var_index); - ++i_op; - CPPAD_ASSERT_UNKNOWN( (op == InvOp) == (i_op <= n_ind) ); - } - return; - } -# endif - // ---------------------------------------------------------------------- - /*! - Check variable graph to make sure arguments have value less - than or equal to the previously created variable. This is the directed - acyclic graph condition (DAG). - */ -# ifdef NDEBUG - void check_variable_dag(void) const - { return; } -# else - void check_variable_dag(void) const - { play::const_sequential_iterator itr = begin(); - OpCode op; - const addr_t* op_arg; - size_t var_index; - itr.op_info(op, op_arg, var_index); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); - // - addr_t arg_var_bound = 0; - while( op != EndOp ) - { (++itr).op_info(op, op_arg, var_index); - switch(op) - { - // cases where nothing to do - case BeginOp: - case EndOp: - case EqppOp: - case InvOp: - case LdpOp: - case LeppOp: - case LtppOp: - case NeppOp: - case ParOp: - case AFunOp: - case FunapOp: - case FunrpOp: - case FunrvOp: - case StppOp: - break; - - // only first argument is a variable - case AbsOp: - case AcosOp: - case AcoshOp: - case AsinOp: - case AsinhOp: - case AtanOp: - case AtanhOp: - case CosOp: - case CoshOp: - case DivvpOp: - case ErfOp: - case ErfcOp: - case ExpOp: - case Expm1Op: - case LevpOp: - case LogOp: - case Log1pOp: - case LtvpOp: - case PowvpOp: - case SignOp: - case SinOp: - case SinhOp: - case SqrtOp: - case SubvpOp: - case TanOp: - case TanhOp: - case FunavOp: - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN(op_arg[0] <= arg_var_bound ); - break; - - // only second argument is a variable - case AddpvOp: - case DisOp: - case DivpvOp: - case EqpvOp: - case LdvOp: - case LepvOp: - case LtpvOp: - case MulpvOp: - case NepvOp: - case PowpvOp: - case StvpOp: - case SubpvOp: - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN(op_arg[1] <= arg_var_bound ); - break; - - // only first and second arguments are variables - case AddvvOp: - case DivvvOp: - case EqvvOp: - case LevvOp: - case LtvvOp: - case MulvvOp: - case NevvOp: - case PowvvOp: - case SubvvOp: - case ZmulvvOp: - CPPAD_ASSERT_UNKNOWN(op_arg[0] <= arg_var_bound ); - CPPAD_ASSERT_UNKNOWN(op_arg[1] <= arg_var_bound ); - break; - - // StpvOp - case StpvOp: - CPPAD_ASSERT_UNKNOWN(op_arg[2] <= arg_var_bound ); - break; - - // StvvOp - case StvvOp: - CPPAD_ASSERT_UNKNOWN(op_arg[1] <= arg_var_bound ); - CPPAD_ASSERT_UNKNOWN(op_arg[2] <= arg_var_bound ); - break; - - // CSumOp - case CSumOp: - { CPPAD_ASSERT_UNKNOWN( 5 < op_arg[2] ); - for(addr_t j = 5; j < op_arg[2]; j++) - CPPAD_ASSERT_UNKNOWN(op_arg[j] <= arg_var_bound); - } - itr.correct_before_increment(); - break; - - // CExpOp - case CExpOp: - if( op_arg[1] & 1 ) - CPPAD_ASSERT_UNKNOWN( op_arg[2] <= arg_var_bound); - if( op_arg[1] & 2 ) - CPPAD_ASSERT_UNKNOWN( op_arg[3] <= arg_var_bound); - if( op_arg[1] & 4 ) - CPPAD_ASSERT_UNKNOWN( op_arg[4] <= arg_var_bound); - if( op_arg[1] & 8 ) - CPPAD_ASSERT_UNKNOWN( op_arg[5] <= arg_var_bound); - break; - - // PriOp - case PriOp: - if( op_arg[0] & 1 ) - CPPAD_ASSERT_UNKNOWN( op_arg[1] <= arg_var_bound); - if( op_arg[0] & 2 ) - CPPAD_ASSERT_UNKNOWN( op_arg[3] <= arg_var_bound); - break; - - // CSkipOp - case CSkipOp: - if( op_arg[1] & 1 ) - CPPAD_ASSERT_UNKNOWN( op_arg[2] <= arg_var_bound); - if( op_arg[1] & 2 ) - CPPAD_ASSERT_UNKNOWN( op_arg[3] <= arg_var_bound); - itr.correct_before_increment(); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - - - } - if( NumRes(op) > 0 ) - { if( var_index > 0 ) - { CPPAD_ASSERT_UNKNOWN(size_t(arg_var_bound) < var_index); - } - else - { CPPAD_ASSERT_UNKNOWN(size_t(arg_var_bound) == var_index); - } - // - arg_var_bound = addr_t(var_index); - } - } - return; - } -# endif - // ---------------------------------------------------------------------- - /*! - Check dynamic parameter graph to make sure arguments have value less - than or equal to the previously created dynamic parameter. - This is the directed acyclic graph condition (DAG). - */ -# ifdef NDEBUG - void check_dynamic_dag(void) const - { return; } -# else - void check_dynamic_dag(void) const - { // number of dynamic parameters - size_t num_dyn = dyn_par_op_.size(); - // - size_t i_arg = 0; // initialize dynamic parameter argument index - for(size_t i_dyn = 0; i_dyn < num_dyn; ++i_dyn) - { // i_par is parameter index - addr_t i_par = dyn_ind2par_ind_[i_dyn]; - CPPAD_ASSERT_UNKNOWN( dyn_par_is_[i_par] ); - // - // operator for this dynamic parameter - op_code_dyn op = op_code_dyn( dyn_par_op_[i_dyn] ); - // - // number of arguments for this dynamic parameter - size_t n_arg = num_arg_dyn(op); - if( op == atom_dyn ) - { size_t n = size_t( dyn_par_arg_[i_arg + 1] ); - size_t m = size_t( dyn_par_arg_[i_arg + 2] ); - n_arg = 5 + n + m; - CPPAD_ASSERT_UNKNOWN( - n_arg == size_t( dyn_par_arg_[i_arg + 4 + n + m] ) - ); - for(size_t i = 4; i < n - 1; ++i) - CPPAD_ASSERT_UNKNOWN( dyn_par_arg_[i_arg + i] < i_par ); -# ifndef NDEBUG - for(size_t i = 4+n; i < 4+n+m; ++i) - { addr_t j_par = dyn_par_arg_[i_arg + i]; - CPPAD_ASSERT_UNKNOWN( (j_par == 0) || (j_par >= i_par) ); - } -# endif - } - else - { size_t num_non_par = num_non_par_arg_dyn(op); - for(size_t i = num_non_par; i < n_arg; ++i) - CPPAD_ASSERT_UNKNOWN( dyn_par_arg_[i_arg + i] < i_par); - } - // - // next dynamic parameter - i_arg += n_arg; - } - return; - } -# endif - // =============================================================== - /*! - Copy a player to another player - - \param play - object that contains the operatoion sequence to copy. - */ - void operator=(const player& play) - { - // size_t objects - num_dynamic_ind_ = play.num_dynamic_ind_; - num_var_rec_ = play.num_var_rec_; - num_var_load_rec_ = play.num_var_load_rec_; - num_var_vecad_rec_ = play.num_var_vecad_rec_; - // - // pod_vectors - op_vec_ = play.op_vec_; - arg_vec_ = play.arg_vec_; - text_vec_ = play.text_vec_; - all_var_vecad_ind_ = play.all_var_vecad_ind_; - dyn_par_is_ = play.dyn_par_is_; - dyn_ind2par_ind_ = play.dyn_ind2par_ind_; - dyn_par_op_ = play.dyn_par_op_; - dyn_par_arg_ = play.dyn_par_arg_; - op2arg_vec_ = play.op2arg_vec_; - op2var_vec_ = play.op2var_vec_; - var2op_vec_ = play.var2op_vec_; - // - // pod_maybe_vectors - all_par_vec_ = play.all_par_vec_; - } - // =============================================================== - /// Create a player< AD > from this player - player< AD > base2ad(void) const - { player< AD > play; - // - // size_t objects - play.num_dynamic_ind_ = num_dynamic_ind_; - play.num_var_rec_ = num_var_rec_; - play.num_var_load_rec_ = num_var_load_rec_; - play.num_var_vecad_rec_ = num_var_vecad_rec_; - // - // pod_vectors - play.op_vec_ = op_vec_; - play.arg_vec_ = arg_vec_; - play.text_vec_ = text_vec_; - play.all_var_vecad_ind_ = all_var_vecad_ind_; - play.dyn_par_is_ = dyn_par_is_; - play.dyn_ind2par_ind_ = dyn_ind2par_ind_; - play.dyn_par_op_ = dyn_par_op_; - play.dyn_par_arg_ = dyn_par_arg_; - play.op2arg_vec_ = op2arg_vec_; - play.op2var_vec_ = op2var_vec_; - play.var2op_vec_ = var2op_vec_; - // - // pod_maybe_vector< AD > = pod_maybe_vector - play.all_par_vec_.resize( all_par_vec_.size() ); - for(size_t i = 0; i < all_par_vec_.size(); ++i) - play.all_par_vec_[i] = all_par_vec_[i]; - // - return play; - } - // =============================================================== - /// swap this recording with another recording - /// (used for move semantics version of ADFun assignment operation) - void swap(player& other) - { // size_t objects - std::swap(num_dynamic_ind_, other.num_dynamic_ind_); - std::swap(num_var_rec_, other.num_var_rec_); - std::swap(num_var_load_rec_, other.num_var_load_rec_); - std::swap(num_var_vecad_rec_, other.num_var_vecad_rec_); - // - // pod_vectors - op_vec_.swap( other.op_vec_); - arg_vec_.swap( other.arg_vec_); - text_vec_.swap( other.text_vec_); - all_var_vecad_ind_.swap( other.all_var_vecad_ind_); - dyn_par_is_.swap( other.dyn_par_is_); - dyn_ind2par_ind_.swap( other.dyn_ind2par_ind_); - dyn_par_op_.swap( other.dyn_par_op_); - dyn_par_arg_.swap( other.dyn_par_arg_); - op2arg_vec_.swap( other.op2arg_vec_); - op2var_vec_.swap( other.op2var_vec_); - var2op_vec_.swap( other.var2op_vec_); - // - // pod_maybe_vectors - all_par_vec_.swap( other.all_par_vec_); - } - // move semantics assignment - void operator=(player&& play) - { swap(play); } - // ================================================================= - /// Enable use of const_subgraph_iterator and member functions that begin - // with random_(no work if already setup). - template - void setup_random(void) - { play::random_setup( - num_var_rec_ , - op_vec_ , - arg_vec_ , - op2arg_vec_.pod_vector_ptr() , - op2var_vec_.pod_vector_ptr() , - var2op_vec_.pod_vector_ptr() - ); - } - /// Free memory used for functions that begin with random_ - /// and random iterators and subgraph iterators - void clear_random(void) - { - op2arg_vec_.clear(); - op2var_vec_.clear(); - var2op_vec_.clear(); - CPPAD_ASSERT_UNKNOWN( op2arg_vec_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( op2var_vec_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( var2op_vec_.size() == 0 ); - } - /// get non-const version of all_par_vec - pod_vector_maybe& all_par_vec(void) - { return all_par_vec_; } - /// get non-const version of all_par_vec - const pod_vector_maybe& all_par_vec(void) const - { return all_par_vec_; } - // ================================================================ - // const functions that retrieve infromation from this player - // ================================================================ - /// const version of dynamic parameter flag - const pod_vector& dyn_par_is(void) const - { return dyn_par_is_; } - /// const version of dynamic parameter index to parameter index - const pod_vector& dyn_ind2par_ind(void) const - { return dyn_ind2par_ind_; } - /// const version of dynamic parameter operator - const pod_vector& dyn_par_op(void) const - { return dyn_par_op_; } - /// const version of dynamic parameter arguments - const pod_vector& dyn_par_arg(void) const - { return dyn_par_arg_; } - /*! - \brief - fetch an operator from the recording. - - \return - the i-th operator in the recording. - - \param i - the index of the operator in recording - */ - OpCode GetOp (size_t i) const - { return OpCode(op_vec_[i]); } - - /*! - \brief - Fetch a VecAD index from the recording. - - \return - the i-th VecAD index in the recording. - - \param i - the index of the VecAD index in recording - */ - size_t GetVecInd (size_t i) const - { return size_t( all_var_vecad_ind_[i] ); } - - /*! - \brief - Fetch a parameter from the recording. - - \return - the i-th parameter in the recording. - - \param i - the index of the parameter in recording - */ - Base GetPar(size_t i) const - { return all_par_vec_[i]; } - - /*! - \brief - Fetch entire parameter vector from the recording. - - \return - the entire parameter vector. - - */ - const Base* GetPar(void) const - { return all_par_vec_.data(); } - - /*! - \brief - Fetch a '\\0' terminated string from the recording. - - \return - the beginning of the string. - - \param i - the index where the string begins. - */ - const char *GetTxt(size_t i) const - { CPPAD_ASSERT_UNKNOWN(i < text_vec_.size() ); - return text_vec_.data() + i; - } - - /// Fetch number of independent dynamic parameters in the recording - size_t num_dynamic_ind(void) const - { return num_dynamic_ind_; } - - /// Fetch number of dynamic parameters in the recording - size_t num_dynamic_par(void) const - { return dyn_par_op_.size(); } - - /// Fetch number of dynamic parameters operator arguments in the recording - size_t num_dynamic_arg(void) const - { return dyn_par_arg_.size(); } - - /// Fetch number of variables in the recording. - size_t num_var_rec(void) const - { return num_var_rec_; } - - /// Fetch number of vecad load operations - size_t num_var_load_rec(void) const - { return num_var_load_rec_; } - - /// Fetch number of operators in the recording. - size_t num_op_rec(void) const - { return op_vec_.size(); } - - /// Fetch number of VecAD indices in the recording. - size_t num_var_vecad_ind_rec(void) const - { return all_var_vecad_ind_.size(); } - - /// Fetch number of VecAD vectors in the recording - size_t num_var_vecad_rec(void) const - { return num_var_vecad_rec_; } - - /// Fetch number of argument indices in the recording. - size_t num_op_arg_rec(void) const - { return arg_vec_.size(); } - - /// Fetch number of parameters in the recording. - size_t num_par_rec(void) const - { return all_par_vec_.size(); } - - /// Fetch number of characters (representing strings) in the recording. - size_t num_text_rec(void) const - { return text_vec_.size(); } - - /// A measure of amount of memory used to store - /// the operation sequence, just lengths, not capacities. - /// In user api as f.size_op_seq(); see the file seq_property.omh. - size_t size_op_seq(void) const - { // check assumptions made by ad_fun::size_op_seq() - CPPAD_ASSERT_UNKNOWN( op_vec_.size() == num_op_rec() ); - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == num_op_arg_rec() ); - CPPAD_ASSERT_UNKNOWN( all_par_vec_.size() == num_par_rec() ); - CPPAD_ASSERT_UNKNOWN( text_vec_.size() == num_text_rec() ); - CPPAD_ASSERT_UNKNOWN( all_var_vecad_ind_.size() == num_var_vecad_ind_rec() ); - return op_vec_.size() * sizeof(opcode_t) - + arg_vec_.size() * sizeof(addr_t) - + all_par_vec_.size() * sizeof(Base) - + dyn_par_is_.size() * sizeof(bool) - + dyn_ind2par_ind_.size() * sizeof(addr_t) - + dyn_par_op_.size() * sizeof(opcode_t) - + dyn_par_arg_.size() * sizeof(addr_t) - + text_vec_.size() * sizeof(char) - + all_var_vecad_ind_.size() * sizeof(addr_t) - ; - } - /// A measure of amount of memory used for random access routine - /// In user api as f.size_random(); see the file seq_property.omh. - size_t size_random(void) const - { -# ifndef NDEBUG - if( op2arg_vec_.size() == 0 ) - { CPPAD_ASSERT_UNKNOWN( op2var_vec_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( var2op_vec_.size() == 0 ); - } - else - { size_t size = 0; - switch( address_type() ) - { case play::unsigned_short_enum: - size = sizeof(unsigned short); - break; - // - case play::unsigned_int_enum: - size = sizeof(unsigned int); - break; - // - case play::size_t_enum: - size = sizeof(size_t); - break; - - default: - CPPAD_ASSERT_UNKNOWN(false); - break; - } - CPPAD_ASSERT_UNKNOWN( op2arg_vec_.size()/size == num_op_rec() ); - CPPAD_ASSERT_UNKNOWN( op2var_vec_.size()/size == num_op_rec() ); - CPPAD_ASSERT_UNKNOWN( var2op_vec_.size()/size == num_var_rec() ); - } -# endif - CPPAD_ASSERT_UNKNOWN( sizeof(unsigned char) == 1 ); - return op2arg_vec_.size() - + op2var_vec_.size() - + var2op_vec_.size() - ; - } - // ----------------------------------------------------------------------- - /// const sequential iterator begin - play::const_sequential_iterator begin(void) const - { size_t op_index = 0; - size_t num_var = num_var_rec_; - return play::const_sequential_iterator( - num_var, &op_vec_, &arg_vec_, op_index - ); - } - /// const sequential iterator end - play::const_sequential_iterator end(void) const - { size_t op_index = op_vec_.size() - 1; - size_t num_var = num_var_rec_; - return play::const_sequential_iterator( - num_var, &op_vec_, &arg_vec_, op_index - ); - } - // ----------------------------------------------------------------------- - /// const subgraph iterator begin - play::const_subgraph_iterator begin_subgraph( - const play::const_random_iterator& random_itr , - const pod_vector* subgraph ) const - { size_t subgraph_index = 0; - return play::const_subgraph_iterator( - random_itr, - subgraph, - subgraph_index - ); - } - /// const subgraph iterator end - template - play::const_subgraph_iterator end_subgraph( - const play::const_random_iterator& random_itr , - const pod_vector* subgraph ) const - { size_t subgraph_index = subgraph->size() - 1; - return play::const_subgraph_iterator( - random_itr, - subgraph, - subgraph_index - ); - } - // ----------------------------------------------------------------------- - /// const random iterator - template - play::const_random_iterator get_random(void) const - { return play::const_random_iterator( - op_vec_, - arg_vec_, - op2arg_vec_.pod_vector_ptr(), - op2var_vec_.pod_vector_ptr(), - var2op_vec_.pod_vector_ptr() - ); - } -}; - -} } // END_CPPAD_lOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/play/random_iterator.hpp b/build-config/cppad/include/cppad/local/play/random_iterator.hpp deleted file mode 100644 index fa9e4da1..00000000 --- a/build-config/cppad/include/cppad/local/play/random_iterator.hpp +++ /dev/null @@ -1,152 +0,0 @@ -# ifndef CPPAD_LOCAL_PLAY_RANDOM_ITERATOR_HPP -# define CPPAD_LOCAL_PLAY_RANDOM_ITERATOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE -namespace CppAD { namespace local { namespace play { - -/*! -\file random_iterator.hpp -*/ - -/*! -Constant random iterator for a player object. - -\tparam Addr -An integer type capable of representing the largest value in the vectors -arg_vec, op2arg_vec, op2var_vec, var2op_vec. -*/ -template -class const_random_iterator { -private: - /// vector of operators on the tape - const pod_vector* op_vec_; - - /// vector of arguments for all the operators - /// (note that this is same type as used in recorder; i.e., addr_t) - const pod_vector* arg_vec_; - - /// mapping from operator index to index of first argument in arg_vec_ - const pod_vector* op2arg_vec_; - - /// mapping from operator index to index of primary (last) result - const pod_vector* op2var_vec_; - - /// mapping from primary variable index to operator index - /// (only specified for primary variables) - const pod_vector* var2op_vec_; - -public: - /// default constructor - const_random_iterator(void) : - op_vec_(nullptr) , - arg_vec_(nullptr) , - op2arg_vec_(nullptr) , - op2var_vec_(nullptr) , - var2op_vec_(nullptr) - { } - /// default assignment operator - void operator=(const const_random_iterator& rhs) - { - op_vec_ = rhs.op_vec_; - op2arg_vec_ = rhs.op2arg_vec_; - op2var_vec_ = rhs.op2var_vec_; - var2op_vec_ = rhs.var2op_vec_; - return; - } - /*! - Create a random iterator - - \par var2op_vec - This variable is not needed and can be null if the var2op member - function is not used. - */ - const_random_iterator( - const pod_vector& op_vec , ///< op_vec_ - const pod_vector& arg_vec , ///< arg_vec_ - const pod_vector* op2arg_vec , ///< op2ar_vec_ - const pod_vector* op2var_vec , ///< op2var_vec_ - const pod_vector* var2op_vec ) ///< var2op_vec_ - : - op_vec_ ( &op_vec ) , - arg_vec_ ( &arg_vec ) , - op2arg_vec_ ( op2arg_vec ) , - op2var_vec_ ( op2var_vec ) , - var2op_vec_ ( var2op_vec ) - { } - /*! - \brief - fetch the information corresponding to an operator - - \param op_index - index for this operator [in] - - \param op [out] - op code for this operator. - - \param op_arg [out] - pointer to the first arguement to this operator. - - \param var_index [out] - index of the last variable (primary variable) for this operator. - If there is no primary variable for this operator, i_var not sepcified - and could have any value. - */ - void op_info( - size_t op_index , - OpCode& op , - const addr_t*& op_arg , - size_t& var_index ) const - { op = OpCode( (*op_vec_)[op_index] ); - op_arg = (*op2arg_vec_)[op_index] + arg_vec_->data(); - var_index = (*op2var_vec_)[op_index]; - return; - } - /*! - \brief - map variable index to operator index. - - \param var_index - must be the index of a primary variable. - - \return - is the index of the operator corresponding to this primary variable. - */ - size_t var2op(size_t var_index) const - { // check that var2op_vec was not null in constructor - CPPAD_ASSERT_UNKNOWN( var2op_vec_ != nullptr ); - // - // operator index - size_t op_index = size_t( (*var2op_vec_)[var_index] ); - // - // check that var_index is a primary variable index (see random_setup) - CPPAD_ASSERT_UNKNOWN( op_index < op_vec_->size() ); - // - return op_index; - } - /// get operator corresponding to operator index - OpCode get_op(size_t op_index) const - { return OpCode( (*op_vec_)[op_index] ); - } - /// number of operators - size_t num_op(void) const - { return op_vec_->size(); } - // - /// number of variables - size_t num_var(void) const - { return var2op_vec_->size(); } -}; - -} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/play/random_setup.hpp b/build-config/cppad/include/cppad/local/play/random_setup.hpp deleted file mode 100644 index 75570ebe..00000000 --- a/build-config/cppad/include/cppad/local/play/random_setup.hpp +++ /dev/null @@ -1,144 +0,0 @@ -# ifndef CPPAD_LOCAL_PLAY_RANDOM_SETUP_HPP -# define CPPAD_LOCAL_PLAY_RANDOM_SETUP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE -namespace CppAD { namespace local { namespace play { - -/*! -\file random_setup.hpp -*/ - -/*! -Set up random access to a player object. - -\tparam Addr -An integer type capable of representing the largest value in the vectors -arg_vec, op2arg_vec, op2var_vec, var2op_vec. - -\param num_var -num_var is the number of variables in this operation sequence. - -\param op_vec -The mapping -op = OpCode[ op_vec[op_index] ] -maps from operator index op_index to the operator op. - -\param arg_vec -is a vector of all the arguments for all the operators. -The mapping op2arg_vec will map from operator indices -to index in this vector. - -\param op2arg_vec -On input, op2arg_vec is either the empty vector -(or contains the proper result from a previous call to random_setup). -Upon return it maps each operator index to the index in op_arg_vec of its -first argument for the operator. - -\param op2var_vec -On input, op2var_vec is either the empty vector -(or contains the proper result from a previous call to random_setup). -Upon return it maps each operator index to the primary (last) -result for the operator. If there are no results for the operator, -the return value map value is not specified. - -\param var2op_vec -On input, var2op_vec is either the empty vector -(or contains the proper result from a previous call to random_setup). -Upon return it maps each primary variable index to the corresponding -operator index. The value of the map is only specifed for primary variable -indices. -*/ -template -void random_setup( - size_t num_var , - const pod_vector& op_vec , - const pod_vector& arg_vec , - pod_vector* op2arg_vec , - pod_vector* op2var_vec , - pod_vector* var2op_vec ) -{ - if( op2arg_vec->size() != 0 ) - { CPPAD_ASSERT_UNKNOWN( op2arg_vec->size() == op_vec.size() ); - CPPAD_ASSERT_UNKNOWN( op2var_vec->size() == op_vec.size() ); - CPPAD_ASSERT_UNKNOWN( var2op_vec->size() == num_var ); - return; - } - CPPAD_ASSERT_UNKNOWN( op2var_vec->size() == 0 ); - CPPAD_ASSERT_UNKNOWN( op2var_vec->size() == 0 ); - CPPAD_ASSERT_UNKNOWN( var2op_vec->size() == 0 ); - CPPAD_ASSERT_UNKNOWN( OpCode( op_vec[0] ) == BeginOp ); - CPPAD_ASSERT_NARG_NRES(BeginOp, 1, 1); - // - size_t num_op = op_vec.size(); - size_t var_index = 0; - size_t arg_index = 0; - // - op2arg_vec->resize( num_op ); - op2var_vec->resize( num_op ); - var2op_vec->resize( num_var ); -# ifndef NDEBUG - // value of var2op for auxillary variables is num_op (invalid) - for(size_t i_var = 0; i_var < num_var; ++i_var) - (*var2op_vec)[i_var] = Addr( num_op ); - // value of op2var is num_var (invalid) when NumRes(op) = 0 - for(size_t i_op = 0; i_op < num_op; ++i_op) - (*op2var_vec)[i_op] = Addr( num_var ); -# endif - for(size_t i_op = 0; i_op < num_op; ++i_op) - { OpCode op = OpCode( op_vec[i_op] ); - // - // index of first argument for this operator - (*op2arg_vec)[i_op] = Addr( arg_index ); - arg_index += NumArg(op); - // - // index of first result for next operator - var_index += NumRes(op); - if( NumRes(op) > 0 ) - { // index of last (primary) result for this operator - (*op2var_vec)[i_op] = Addr( var_index - 1 ); - // - // mapping from primary variable to its operator - (*var2op_vec)[var_index - 1] = Addr( i_op ); - } - // CSumOp - if( op == CSumOp ) - { CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); - // - // pointer to first argument for this operator - const addr_t* op_arg = arg_vec.data() + arg_index; - // - // The actual number of arugments for this operator is - // op_arg[4] + 1 - // Correct index of first argument for next operator - arg_index += size_t(op_arg[4] + 1); - } - // - // CSkip - if( op == CSkipOp ) - { CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 ); - // - // pointer to first argument for this operator - const addr_t* op_arg = arg_vec.data() + arg_index; - // - // The actual number of arugments for this operator is - // 7 + op_arg[4] + op_arg[5]. - // Correct index of first argument for next operator. - arg_index += size_t(7 + op_arg[4] + op_arg[5]); - } - } -} - -} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/play/sequential_iterator.hpp b/build-config/cppad/include/cppad/local/play/sequential_iterator.hpp deleted file mode 100644 index 2fba394f..00000000 --- a/build-config/cppad/include/cppad/local/play/sequential_iterator.hpp +++ /dev/null @@ -1,290 +0,0 @@ -# ifndef CPPAD_LOCAL_PLAY_SEQUENTIAL_ITERATOR_HPP -# define CPPAD_LOCAL_PLAY_SEQUENTIAL_ITERATOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE -namespace CppAD { namespace local { namespace play { - -/*! -\file sequential_iterator.hpp -*/ - -/*! -Constant sequential iterator for a player object. - -\tparam Addr -An integer type capable of representing the largest value in the vectors -arg_vec, op2arg_vec, op2var_vec, var2op_vec. - -\par -Except for constructor, the public API for this class is the same as -for the subgraph_iterator class. -*/ -class const_sequential_iterator { -private: - /// pointer to the first operator in the player, BeginOp = *op_begin_ - const opcode_t* op_begin_; - - /// pointer one past last operator in the player, EndOp = *(op_end_ - 1) - const opcode_t* op_end_; - - /// pointer to the first argument for the first operator - const addr_t* arg_begin_; - - /// pointer on past last argumemnt for last operator - const addr_t* arg_end_; - - /// pointer to current operator - const opcode_t* op_cur_; - - /// pointer to first argument for current operator - const addr_t* arg_; - - /// number of variables in tape (not const for assignment operator) - size_t num_var_; - - /// index of last result for current operator - size_t var_index_; - - /// value of current operator; i.e. op_ = *op_cur_ - OpCode op_; -public: - /// default constructor - const_sequential_iterator(void) : - op_begin_(nullptr) , - op_end_(nullptr) , - arg_begin_(nullptr) , - arg_end_(nullptr) , - op_cur_(nullptr) , - arg_(nullptr) , - num_var_(0) , - var_index_(0) , - op_(NumberOp) - { } - /// assignment operator - void operator=(const const_sequential_iterator& rhs) - { - op_begin_ = rhs.op_begin_; - op_end_ = rhs.op_end_; - arg_begin_ = rhs.arg_begin_; - arg_end_ = rhs.arg_end_; - op_cur_ = rhs.op_cur_; - arg_ = rhs.arg_; - num_var_ = rhs.num_var_; - var_index_ = rhs.var_index_; - op_ = rhs.op_; - return; - } - /*! - Create a sequential iterator starting either at beginning or end of tape - - \param num_var - is the number of variables in the tape. - - \param op_vec - is the vector of operators on the tape. - - \param arg_vec - is the vector of arguments for all the operators - - \param op_index - is the operator index that iterator will start at. - It must be zero or op_vec_->size() - 1. - - \par Assumptions - - OpCode(op_vec_[0]) == BeginOp - - OpCode(op_vec_[op_vec_->size() - 1]) == EndOp - */ - const_sequential_iterator( - size_t num_var , - const pod_vector* op_vec , - const pod_vector* arg_vec , - size_t op_index ) - : - op_begin_ ( op_vec->data() ) , - op_end_ ( op_vec->data() + op_vec->size() ) , - arg_begin_ ( arg_vec->data() ) , - arg_end_ ( arg_vec->data() + arg_vec->size() ), - num_var_ ( num_var ) - { if( op_index == 0 ) - { - // index of last result for BeginOp - var_index_ = 0; - // - // first argument to BeginOp - arg_ = arg_vec->data(); - // - // BeginOp - op_cur_ = op_begin_; - op_ = OpCode( *op_cur_ ); - CPPAD_ASSERT_UNKNOWN( op_ == BeginOp ); - CPPAD_ASSERT_NARG_NRES(op_, 1, 1); - } - else - { CPPAD_ASSERT_UNKNOWN(op_index == op_vec->size()-1); - // - // index of last result for EndOp - var_index_ = num_var - 1; - // - // first argument to EndOp (has no arguments) - arg_ = arg_vec->data() + arg_vec->size(); - // - // EndOp - op_cur_ = op_end_ - 1; - op_ = OpCode( *op_cur_ ); - CPPAD_ASSERT_UNKNOWN( op_ == EndOp ); - CPPAD_ASSERT_NARG_NRES(op_, 0, 0); - } - } - /*! - Advance iterator to next operator - */ - const_sequential_iterator& operator++(void) - { - // first argument for next operator - arg_ += NumArg(op_); - // - // next operator - ++op_cur_; - op_ = OpCode( *op_cur_ ); - // - // last result for next operator - var_index_ += NumRes(op_); - // - return *this; - } - /*! - Correction applied before ++ operation when current operator - is CSumOp or CSkipOp. - */ - void correct_before_increment(void) - { // number of arguments for this operator depends on argument data - CPPAD_ASSERT_UNKNOWN( NumArg(op_) == 0 ); - const addr_t* arg = arg_; - // - // CSumOp - if( op_ == CSumOp ) - { // add actual number of arguments to arg_ - arg_ += arg[4] + 1; - } - // - // CSkip - else - { CPPAD_ASSERT_UNKNOWN( op_ == CSkipOp ); - // - CPPAD_ASSERT_UNKNOWN( arg + 5 < arg_end_ ); - addr_t n_skip = arg[4] + arg[5]; - CPPAD_ASSERT_UNKNOWN( n_skip == arg[6 + n_skip] ); - // - // add actual number of arguments to arg_ - arg_ += 7 + n_skip; - } - return; - } - /*! - Backup iterator to previous operator - */ - const_sequential_iterator& operator--(void) - { // - // last result for next operator - var_index_ -= NumRes(op_); - // - // next operator - --op_cur_; - op_ = OpCode( *op_cur_ ); - // - // first argument for next operator - arg_ -= NumArg(op_); - // - return *this; - } - /*! - Correction applied after -- operation when current operator - is CSumOp or CSkipOp. - - \param arg [out] - corrected point to arguments for this operation. - */ - void correct_after_decrement(const addr_t*& arg) - { // number of arguments for this operator depends on argument data - CPPAD_ASSERT_UNKNOWN( NumArg(op_) == 0 ); - // - // infromation for number of arguments is stored in arg_ - 1 - CPPAD_ASSERT_UNKNOWN( arg_begin_ < arg_ ); - // - // CSumOp - if( op_ == CSumOp ) - { // index of arg[4] - addr_t arg_4 = *(arg_ - 1); - // - // corrected index of first argument to this operator - arg = arg_ -= arg_4 + 1; - // - CPPAD_ASSERT_UNKNOWN( arg[arg[4] ] == arg[4] ); - } - // - // CSkip - else - { CPPAD_ASSERT_UNKNOWN( op_ == CSkipOp ); - // - // number to possibly skip is stored in last argument - addr_t n_skip = *(arg_ - 1); - // - // corrected index of frist argument to this operator - arg = arg_ -= 7 + n_skip; - // - CPPAD_ASSERT_UNKNOWN( arg[4] + arg[5] == n_skip ); - } - CPPAD_ASSERT_UNKNOWN( arg_begin_ <= arg ); - CPPAD_ASSERT_UNKNOWN( arg + NumArg(op_) <= arg_end_ ); - } - /*! - \brief - Get information corresponding to current operator. - - \param op [out] - op code for this operator. - - \param arg [out] - pointer to the first arguement to this operator. - - \param var_index [out] - index of the last variable (primary variable) for this operator. - If there is no primary variable for this operator, var_index - is not sepcified and could have any value. - */ - void op_info( - OpCode& op , - const addr_t*& arg , - size_t& var_index ) const - { // op - CPPAD_ASSERT_UNKNOWN( op_begin_ <= op_cur_ && op_cur_ < op_end_ ) - op = op_; - // - // arg - arg = arg_; - CPPAD_ASSERT_UNKNOWN( arg_begin_ <= arg ); - CPPAD_ASSERT_UNKNOWN( arg + NumArg(op) <= arg_end_ ); - // - // var_index - CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_ || NumRes(op) == 0 ); - var_index = var_index_; - } - /// current operator index - size_t op_index(void) - { return size_t(op_cur_ - op_begin_); } -}; - -} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/play/subgraph_iterator.hpp b/build-config/cppad/include/cppad/local/play/subgraph_iterator.hpp deleted file mode 100644 index 036d844f..00000000 --- a/build-config/cppad/include/cppad/local/play/subgraph_iterator.hpp +++ /dev/null @@ -1,132 +0,0 @@ -# ifndef CPPAD_LOCAL_PLAY_SUBGRAPH_ITERATOR_HPP -# define CPPAD_LOCAL_PLAY_SUBGRAPH_ITERATOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE -namespace CppAD { namespace local { namespace play { - -/*! -\file random_iterator.hpp -*/ - -/*! -Constant subgraph iterator for a player object. - -\tparam Addr -An integer type capable of representing the largest value in the vectors -arg_vec, op2arg_vec, op2var_vec, var2op_vec. - -Except for constructor, the public API for this class is the same as -for the sequential iterator class. -*/ -template -class const_subgraph_iterator { -private: - /// a random iterator used to access player information - const const_random_iterator* random_itr_; - - /// sorted subset of operator indices that we will include - const pod_vector* subgraph_; - - /// index in subgraph of current operator - /// The initial value for this index must be zero or subgraph.size()-1. - size_t subgraph_index_; - -public: - /// default constructor - const_subgraph_iterator(void) : - random_itr_(nullptr) , - subgraph_(nullptr) , - subgraph_index_(0) - { } - /// default assignment operator - void operator=(const const_subgraph_iterator& rhs) - { - random_itr_ = rhs.random_itr_; - subgraph_ = rhs.subgraph_; - subgraph_index_ = rhs.subgraph_index_; - return; - } - /*! - Create a subgraph iterator starting either at beginning or end of subgraph - */ - const_subgraph_iterator( - const const_random_iterator& random_itr , ///< random_itr_ - const pod_vector* subgraph , ///< subgraph_ - size_t subgraph_index ) ///< subgraph_index_ - : - random_itr_ ( &random_itr ) , - subgraph_ ( subgraph ) , - subgraph_index_ ( subgraph_index ) - { CPPAD_ASSERT_UNKNOWN( - subgraph_index == 0 || subgraph_index == subgraph->size() - 1 - ); - } - /*! - Advance iterator to next operator - */ - const_subgraph_iterator& operator++(void) - { ++subgraph_index_; - return *this; - } - /// No correction necessary when using random access to player - void correct_before_increment(void) - { return; } - /*! - Backup iterator to previous operator - */ - const_subgraph_iterator& operator--(void) - { --subgraph_index_; - return *this; - } - /*! - No correction necessary when using random access to player. - - \param op_arg - not used or modified. - */ - void correct_after_decrement(const addr_t*& op_arg) - { return; } - /*! - \brief - Get information corresponding to current operator. - - \param op [out] - op code for this operator. - - \param op_arg [out] - pointer to the first arguement to this operator. - - \param var_index [out] - index of the last variable (primary variable) for this operator. - If there is no primary variable for this operator, var_index - is not sepcified and could have any value. - */ - void op_info( - OpCode& op , - const addr_t*& op_arg , - size_t& var_index ) const - { // op - size_t op_index = size_t( (*subgraph_)[subgraph_index_] ); - random_itr_->op_info(op_index, op, op_arg, var_index); - } - /// current operator index - size_t op_index(void) - { return size_t( (*subgraph_)[subgraph_index_] ); } -}; - -} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/pod_vector.hpp b/build-config/cppad/include/cppad/local/pod_vector.hpp deleted file mode 100644 index 3af47c6e..00000000 --- a/build-config/cppad/include/cppad/local/pod_vector.hpp +++ /dev/null @@ -1,565 +0,0 @@ -# ifndef CPPAD_LOCAL_POD_VECTOR_HPP -# define CPPAD_LOCAL_POD_VECTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# if CPPAD_CSTDINT_HAS_8_TO_64 -# include -# endif -# include -# include -# include -# include -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file pod_vector.hpp -File used to define pod_vector classes -*/ -// --------------------------------------------------------------------------- -/*! -A vector class with that does not use element constructors or destructors -(elements are Plain Old Data; i.e., is_pod must be true). - -*/ -template -class pod_vector { -private: - /// maximum number of bytes current allocation can hold - size_t byte_capacity_; - - /// number of bytes currently in this vector - size_t byte_length_; - - /// pointer to the first type elements - /// (not defined and should not be used when byte_capacity_ = 0) - Type *data_; - - /// do not use the copy constructor - explicit pod_vector(const pod_vector& ) - { CPPAD_ASSERT_UNKNOWN(false); } -public: - /// default constructor sets byte_capacity_ = byte_length_ = data_ = 0 - pod_vector(void) - : byte_capacity_(0), byte_length_(0), data_(nullptr) - { CPPAD_ASSERT_UNKNOWN( is_pod() ); - } - - /// sizing constructor - pod_vector( - /// number of elements in this vector - size_t n ) - : byte_capacity_(0), byte_length_(0), data_(nullptr) - { CPPAD_ASSERT_UNKNOWN( is_pod() ); - extend(n); - } - - /// Destructor: returns allocated memory to thread_alloc; - /// see extend and resize. If this is not plain old data, - /// the destructor for each element is called. - ~pod_vector(void) - { if( byte_capacity_ > 0 ) - { - void* v_ptr = reinterpret_cast( data_ ); - thread_alloc::return_memory(v_ptr); - } - } - - /* - Return a pointer to a pod_vector with a different type of element. - - - This vector and the other share the same memory. - - - The the other vector should not be deleted. - - - The following operations work the same for this and the other vector: - swap, clear, assignment. - */ - template - pod_vector* pod_vector_ptr(void) - { return reinterpret_cast< pod_vector* >(this); - } - template - const pod_vector* pod_vector_ptr(void) const - { return reinterpret_cast< const pod_vector* >(this); - } - - /// current number of elements in this vector. - size_t size(void) const - { return byte_length_ / sizeof(Type); } - - /// current capacity (amount of allocated storage) for this vector. - size_t capacity(void) const - { return byte_capacity_ / sizeof(Type); } - - /// current data pointer is no longer valid after any of the following: - /// extend, resize, erase, clear, assignment and destructor. - Type* data(void) - { return data_; } - - /// const version of data pointer (see non-const documentation) - const Type* data(void) const - { return data_; } - - // ---------------------------------------------------------------------- - /// non-constant element access; i.e., we can change this element value - Type& operator[]( - /// element index, must be less than length - size_t i - ) - { CPPAD_ASSERT_UNKNOWN( i * sizeof(Type) < byte_length_ ); - return data_[i]; - } - /// non-constant element access; i.e., we can change this element value - template - Type& operator[]( - /// element index, must be less than length and convertable to size_t - Index i - ) - { return (*this)[size_t(i)]; } - // ---------------------------------------------------------------------- - /// constant element access; i.e., we cannot change this element value - const Type& operator[]( - /// element index, must be less than length - size_t i - ) const - { CPPAD_ASSERT_UNKNOWN( i * sizeof(Type) < byte_length_ ); - return data_[i]; - } - /// constant element access; i.e., we cannot change this element value - template - const Type& operator[]( - /// element index, must be less than length and convertable to size_t - Index i - ) const - { return (*this)[size_t(i)]; } - // ---------------------------------------------------------------------- - - /*! - Add an element to theh back of this vector - - \param e - is the element we are adding to the back of the vector. - */ - void push_back(const Type& e) - { size_t i = extend(1); - data_[i] = e; - } - - /*! - Swap all properties of this vector with another. - This is useful when moving a vector that grows after it has reached - its final size (without copying every element). - - \param other - is the other vector that we are swapping this vector with. - */ - void swap(pod_vector& other) - { std::swap(byte_capacity_, other.byte_capacity_); - std::swap(byte_length_, other.byte_length_); - std::swap(data_, other.data_); - } - // ---------------------------------------------------------------------- - /*! - Increase the number of elements the end of this vector - (existing elements are always preserved). - - \param n - is the number of elements to add to end of this vector. - - \return - is the number of elements in the vector before it was extended. - This is the index of the first new element added to the vector. - - - If Type is plain old data, new elements are not initialized; - i.e., their constructor is not called. Otherwise, the constructor - is called for each new element. - - - This and resize are the only routine that allocate memory for - pod_vector. They uses thread_alloc for this allocation. - */ - size_t extend(size_t n) - { size_t old_length = byte_length_; - byte_length_ += n * sizeof(Type); - - // check if we can use current memory - if( byte_length_ <= byte_capacity_ ) - return old_length / sizeof(Type); - - // save more old information - size_t old_capacity = byte_capacity_; - void* old_v_ptr = reinterpret_cast(data_); - - // get new memory and set capacity - void* v_ptr = thread_alloc::get_memory(byte_length_, byte_capacity_); - data_ = reinterpret_cast(v_ptr); - - // copy old data to new - if( old_length > 0 ) - std::memcpy(v_ptr, old_v_ptr, old_length); - - // return old memory to available pool - if( old_capacity > 0 ) - thread_alloc::return_memory(old_v_ptr); - - // return value for extend(n) is the old length - CPPAD_ASSERT_UNKNOWN( byte_length_ <= byte_capacity_ ); - return old_length / sizeof(Type); - } - // ---------------------------------------------------------------------- - /*! - resize the vector (existing elements preserved when n <= capacity() ). - - \param n - is the new size for this vector. - - \par - if n <= capacity(), no memory is freed or allocated, the capacity - is not changed, and existing elements are preserved. - If n > capacity(), new memory is allocates and all the - data in the vector is lost. - - - If Type is plain old data, new elements are not initialized; - i.e., their constructor is not called. Otherwise, the constructor - is called for each new element. - - - This and extend are the only routine that allocate memory for - pod_vector. They uses thread_alloc for this allocation. - */ - void resize(size_t n) - { byte_length_ = n * sizeof(Type); - - // check if we must allocate new memory - if( byte_capacity_ < byte_length_ ) - { void* v_ptr; - // - if( byte_capacity_ > 0 ) - { // return old memory to available pool - v_ptr = reinterpret_cast( data_ ); - thread_alloc::return_memory(v_ptr); - } - // - // get new memory and set capacity - v_ptr = thread_alloc::get_memory(byte_length_, byte_capacity_); - data_ = reinterpret_cast(v_ptr); - // - } - CPPAD_ASSERT_UNKNOWN( byte_length_ <= byte_capacity_ ); - } - // ---------------------------------------------------------------------- - /*! - Remove all the elements from this vector and free its memory. - */ - void clear(void) - { if( byte_capacity_ > 0 ) - { - void* v_ptr = reinterpret_cast( data_ ); - thread_alloc::return_memory(v_ptr); - } - data_ = nullptr; - byte_capacity_ = 0; - byte_length_ = 0; - } - // ----------------------------------------------------------------------- - /// vector assignment operator - void operator=( - /// right hand size of the assingment operation - const pod_vector& x - ) - { CPPAD_ASSERT_UNKNOWN( x.byte_length_ % sizeof(Type) == 0 ); - resize( x.byte_length_ / sizeof(Type) ); - if( byte_length_ > 0 ) - { - void* v_ptr = reinterpret_cast( data_ ); - void* v_ptr_x = reinterpret_cast( x.data_ ); - std::memcpy(v_ptr, v_ptr_x, byte_length_); - } - - } -}; -// --------------------------------------------------------------------------- -/*! -A vector class with that does not use element constructors or destructors -when is_pod is true. -*/ -template -class pod_vector_maybe { -private: - /// maximum number of Type elements current allocation can hold - size_t capacity_; - - /// number of elements currently in this vector - size_t length_; - - /// pointer to the first type elements - /// (not defined and should not be used when capacity_ = 0) - Type *data_; - - /// do not use the copy constructor - explicit pod_vector_maybe(const pod_vector_maybe& ) - { CPPAD_ASSERT_UNKNOWN(false); } -public: - /// default constructor sets capacity_ = length_ = data_ = 0 - pod_vector_maybe(void) - : capacity_(0), length_(0), data_(nullptr) - { CPPAD_ASSERT_UNKNOWN( is_pod() ); - } - - /// sizing constructor - pod_vector_maybe( - /// number of elements in this vector - size_t n ) - : capacity_(0), length_(0), data_(nullptr) - { extend(n); } - - - /// Destructor: returns allocated memory to thread_alloc; - /// see extend and resize. If this is not plain old data, - /// the destructor for each element is called. - ~pod_vector_maybe(void) - { if( capacity_ > 0 ) - { if( ! is_pod() ) - { // call destructor for each element - for(size_t i = 0; i < capacity_; i++) - (data_ + i)->~Type(); - } - void* v_ptr = reinterpret_cast( data_ ); - thread_alloc::return_memory(v_ptr); - } - } - - /// current number of elements in this vector. - size_t size(void) const - { return length_; } - - /// current capacity (amount of allocated storage) for this vector. - size_t capacity(void) const - { return capacity_; } - - /// current data pointer is no longer valid after any of the following: - /// extend, resize, erase, clear, assignment, and destructor. - Type* data(void) - { return data_; } - - /// const version of data pointer (see non-const documentation) - const Type* data(void) const - { return data_; } - // ---------------------------------------------------------------------- - /// non-constant element access; i.e., we can change this element value - Type& operator[]( - /// element index, must be less than length - size_t i - ) - { CPPAD_ASSERT_UNKNOWN( i < length_ ); - return data_[i]; - } - /// non-constant element access; i.e., we can change this element value - template - Type& operator[]( - /// element index, must be less than length and convertable to size_t - Index i - ) - { return (*this)[size_t(i)]; } - - // ---------------------------------------------------------------------- - /// constant element access; i.e., we cannot change this element value - const Type& operator[]( - /// element index, must be less than length - size_t i - ) const - { CPPAD_ASSERT_UNKNOWN( i < length_ ); - return data_[i]; - } - /// constant element access; i.e., we cannot change this element value - template - const Type& operator[]( - /// element index, must be less than length and convertable to size_t - Index i - ) const - { return (*this)[size_t(i)]; } - - // ---------------------------------------------------------------------- - /*! - Add an element to theh back of this vector - - \param e - is the element we are adding to the back of the vector. - */ - void push_back(const Type& e) - { size_t i = extend(1); - data_[i] = e; - } - - /*! - Swap all properties of this vector with another. - This is useful when moving a vector that grows after it has reached - its final size (without copying every element). - - \param other - is the other vector that we are swapping this vector with. - */ - void swap(pod_vector_maybe& other) - { std::swap(capacity_, other.capacity_); - std::swap(length_, other.length_); - std::swap(data_, other.data_); - } - // ---------------------------------------------------------------------- - /*! - Increase the number of elements the end of this vector - (existing elements are always preserved). - - \param n - is the number of elements to add to end of this vector. - - \return - is the number of elements in the vector before it was extended. - This is the index of the first new element added to the vector. - - - If Type is plain old data, new elements are not initialized; - i.e., their constructor is not called. Otherwise, the constructor - is called for each new element. - - - This and resize are the only routine that allocate memory for - pod_vector_maybe. They uses thread_alloc for this allocation. - */ - size_t extend(size_t n) - { size_t old_length = length_; - length_ += n; - - // check if we can use current memory - if( length_ <= capacity_ ) - return old_length; - - // save more old information - size_t old_capacity = capacity_; - Type* old_data = data_; - - // get new memory and set capacity - size_t length_bytes = length_ * sizeof(Type); - size_t capacity_bytes; - void* v_ptr = thread_alloc::get_memory(length_bytes, capacity_bytes); - capacity_ = capacity_bytes / sizeof(Type); - data_ = reinterpret_cast(v_ptr); - - if( ! is_pod() ) - { // call constructor for each new element - for(size_t i = 0; i < capacity_; i++) - new(data_ + i) Type(); - } - - // copy old data to new - for(size_t i = 0; i < old_length; i++) - data_[i] = old_data[i]; - - // return old memory to available pool - if( old_capacity > 0 ) - { if( ! is_pod() ) - { for(size_t i = 0; i < old_capacity; i++) - (old_data + i)->~Type(); - } - v_ptr = reinterpret_cast( old_data ); - thread_alloc::return_memory(v_ptr); - } - - // return value for extend(n) is the old length - CPPAD_ASSERT_UNKNOWN( length_ <= capacity_ ); - return old_length; - } - // ---------------------------------------------------------------------- - /*! - resize the vector (existing elements preserved when n <= capacity_). - - \param n - is the new size for this vector. - - \par - if n <= capacity(), no memory is freed or allocated, the capacity - is not changed, and existing elements are preserved. - If n > capacity(), new memory is allocates and all the - data in the vector is lost. - - - If Type is plain old data, new elements are not initialized; - i.e., their constructor is not called. Otherwise, the constructor - is called for each new element. - - - This and extend are the only routine that allocate memory for - pod_vector_maybe. They uses thread_alloc for this allocation. - */ - void resize(size_t n) - { length_ = n; - - // check if we must allocate new memory - if( capacity_ < length_ ) - { void* v_ptr; - // - // return old memory to available pool - if( capacity_ > 0 ) - { if( ! is_pod() ) - { // call destructor for each old element - for(size_t i = 0; i < capacity_; i++) - (data_ + i)->~Type(); - } - v_ptr = reinterpret_cast( data_ ); - thread_alloc::return_memory(v_ptr); - } - // - // get new memory and set capacity - size_t length_bytes = length_ * sizeof(Type); - size_t capacity_bytes; - v_ptr = thread_alloc::get_memory(length_bytes, capacity_bytes); - capacity_ = capacity_bytes / sizeof(Type); - data_ = reinterpret_cast(v_ptr); - // - CPPAD_ASSERT_UNKNOWN( length_ <= capacity_ ); - // - if( ! is_pod() ) - { // call constructor for each new element - for(size_t i = 0; i < capacity_; i++) - new(data_ + i) Type(); - } - } - } - // ---------------------------------------------------------------------- - /*! - Remove all the elements from this vector and free its memory. - */ - void clear(void) - { if( capacity_ > 0 ) - { if( ! is_pod() ) - { // call destructor for each element - for(size_t i = 0; i < capacity_; i++) - (data_ + i)->~Type(); - } - void* v_ptr = reinterpret_cast( data_ ); - thread_alloc::return_memory(v_ptr); - } - data_ = nullptr; - capacity_ = 0; - length_ = 0; - } - // ----------------------------------------------------------------------- - /// vector assignment operator - void operator=( - /// right hand size of the assingment operation - const pod_vector_maybe& x - ) - { resize( x.length_ ); - // - CPPAD_ASSERT_UNKNOWN( length_ == x.length_ ); - for(size_t i = 0; i < length_; i++) - { data_[i] = x.data_[i]; } - } -}; - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/pow_op.hpp b/build-config/cppad/include/cppad/local/pow_op.hpp deleted file mode 100644 index 6994756f..00000000 --- a/build-config/cppad/include/cppad/local/pow_op.hpp +++ /dev/null @@ -1,672 +0,0 @@ -# ifndef CPPAD_LOCAL_POW_OP_HPP -# define CPPAD_LOCAL_POW_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file pow_op.hpp -Forward and reverse mode calculations for z = pow(x, y). -*/ - -// --------------------------- Powvv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = PowvvOp. - -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_pow_op -*/ - -template -void forward_powvv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // 2 = NumRes(PowvvOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - // z_0 = log(x) - forward_log_op(p, q, i_z, size_t(arg[0]), cap_order, taylor); - - // z_1 = z_0 * y - addr_t adr[2]; - adr[0] = addr_t( i_z ); - adr[1] = arg[1]; - forward_mulvv_op(p, q, i_z+1, adr, parameter, cap_order, taylor); - - // z_2 = exp(z_1) - // final result for zero order case is exactly the same as for Base - if( p == 0 ) - { // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z_2 = taylor + (i_z+2) * cap_order; - - z_2[0] = pow(x[0], y[0]); - p++; - } - if( p <= q ) - forward_exp_op(p, q, i_z+2, i_z+1, cap_order, taylor); -} -/*! -Multiple directions forward mode Taylor coefficients for op = PowvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_pow_op_dir -*/ - -template -void forward_powvv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // 2 = NumRes(PowvvOp) - 1 - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - // z_0 = log(x) - forward_log_op_dir(q, r, i_z, size_t(arg[0]), cap_order, taylor); - - // z_1 = y * z_0 - addr_t adr[2]; - adr[0] = addr_t( i_z ); - adr[1] = arg[1]; - forward_mulvv_op_dir(q, r, i_z+1, adr, parameter, cap_order, taylor); - - // z_2 = exp(z_1) - forward_exp_op_dir(q, r, i_z+2, i_z+1, cap_order, taylor); -} -/*! -Compute zero order forward mode Taylor coefficients for result of op = PowvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_pow_op_0 -*/ - -template -void forward_powvv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // NumRes(PowvvOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z_0 = taylor + i_z * cap_order; - Base* z_1 = z_0 + cap_order; - Base* z_2 = z_1 + cap_order; - - z_0[0] = log( x[0] ); - z_1[0] = z_0[0] * y[0]; - z_2[0] = pow(x[0], y[0]); - -} - -/*! -Compute reverse mode partial derivatives for result of op = PowvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::reverse_pow_op -*/ - -template -void reverse_powvv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // convert from final result to first result - i_z -= 2; // NumRes(PowvvOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - // z_2 = exp(z_1) - reverse_exp_op( - d, i_z+2, i_z+1, cap_order, taylor, nc_partial, partial - ); - - // z_1 = z_0 * y - addr_t adr[2]; - adr[0] = addr_t( i_z ); - adr[1] = arg[1]; - reverse_mulvv_op( - d, i_z+1, adr, parameter, cap_order, taylor, nc_partial, partial - ); - - // z_0 = log(x) - reverse_log_op( - d, i_z, size_t(arg[0]), cap_order, taylor, nc_partial, partial - ); -} - -// --------------------------- Powpv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = PowpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_pow_op -*/ - -template -void forward_powpv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // 2 = NumRes(PowpvOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowpvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* z_0 = taylor + i_z * cap_order; - - // z_0 = log(x) - Base x = parameter[ arg[0] ]; - size_t d; - for(d = p; d <= q; d++) - { if( d == 0 ) - z_0[d] = log(x); - else - z_0[d] = Base(0.0); - } - - // 2DO: remove requirement that i_z * cap_order <= max addr_t value - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= i_z * cap_order, - "cppad_tape_addr_type maximum value has been exceeded\n" - "This is due to a kludge in the pow operation and should be fixed." - ); - - // z_1 = z_0 * y - addr_t adr[2]; - // offset of z_i in taylor (as if it were a parameter); i.e., log(x) - adr[0] = addr_t( i_z * cap_order ); - // offset of y in taylor (as a variable) - adr[1] = arg[1]; - - // Trick: use taylor both for the parameter vector and variable values - forward_mulpv_op(p, q, i_z+1, adr, taylor, cap_order, taylor); - - // z_2 = exp(z_1) - // zero order case exactly same as Base type operation - if( p == 0 ) - { Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z_2 = taylor + (i_z+2) * cap_order; - z_2[0] = pow(x, y[0]); - p++; - } - if( p <= q ) - forward_exp_op(p, q, i_z+2, i_z+1, cap_order, taylor); -} -/*! -Multiple directions forward mode Taylor coefficients for op = PowpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_pow_op_dir -*/ - -template -void forward_powpv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // 2 = NumRes(PowpvOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowpvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* z_0 = taylor + i_z * num_taylor_per_var; - - // z_0 = log(x) - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - z_0[m+ell] = Base(0.0); - - // 2DO: remove requirement i_z * num_taylor_per_var <= max addr_t value - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= i_z * num_taylor_per_var, - "cppad_tape_addr_type maximum value has been exceeded\n" - "This is due to a kludge in the pow operation and should be fixed." - ); - - // z_1 = z_0 * y - addr_t adr[2]; - // offset of z_0 in taylor (as if it were a parameter); i.e., log(x) - adr[0] = addr_t( i_z * num_taylor_per_var ); - // ofset of y in taylor (as a variable) - adr[1] = arg[1]; - - // Trick: use taylor both for the parameter vector and variable values - forward_mulpv_op_dir(q, r, i_z+1, adr, taylor, cap_order, taylor); - - // z_2 = exp(z_1) - forward_exp_op_dir(q, r, i_z+2, i_z+1, cap_order, taylor); -} -/*! -Compute zero order forward mode Taylor coefficient for result of op = PowpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_pow_op_0 -*/ - -template -void forward_powpv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // NumRes(PowpvOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowpvOp) == 3 ); - - // Paraemter value - Base x = parameter[ arg[0] ]; - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z_0 = taylor + i_z * cap_order; - Base* z_1 = z_0 + cap_order; - Base* z_2 = z_1 + cap_order; - - // z_0 = log(x) - z_0[0] = log(x); - - // z_1 = z_0 * y - z_1[0] = z_0[0] * y[0]; - - // z_2 = exp(z_1) - // zero order case exactly same as Base type operation - z_2[0] = pow(x, y[0]); -} - -/*! -Compute reverse mode partial derivative for result of op = PowpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::reverse_pow_op -*/ - -template -void reverse_powpv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // convert from final result to first result - i_z -= 2; // NumRes(PowpvOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // z_2 = exp(z_1) - reverse_exp_op( - d, i_z+2, i_z+1, cap_order, taylor, nc_partial, partial - ); - - // 2DO: remove requirement that i_z * cap_order <= max addr_t value - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= i_z * cap_order, - "cppad_tape_addr_type maximum value has been exceeded\n" - "This is due to a kludge in the pow operation and should be fixed." - ); - - // z_1 = z_0 * y - addr_t adr[2]; - adr[0] = addr_t( i_z * cap_order ); // offset of z_0[0] in taylor - adr[1] = arg[1]; // index of y in taylor and partial - // use taylor both for parameter and variable values - reverse_mulpv_op( - d, i_z+1, adr, taylor, cap_order, taylor, nc_partial, partial - ); - - // z_0 = log(x) - // x is a parameter -} - -// --------------------------- Powvp ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = PowvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_pow_op -*/ - -template -void forward_powvp_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // 2 = NumRes(PowvpOp) - 1 - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - // z_0 = log(x) - forward_log_op(p, q, i_z, size_t(arg[0]), cap_order, taylor); - - // z_1 = y * z_0 - addr_t adr[2]; - adr[0] = arg[1]; - adr[1] = addr_t( i_z ); - forward_mulpv_op(p, q, i_z+1, adr, parameter, cap_order, taylor); - - // z_2 = exp(z_1) - // zero order case exactly same as Base type operation - if( p == 0 ) - { Base* z_2 = taylor + (i_z+2) * cap_order; - Base* x = taylor + size_t(arg[0]) * cap_order; - Base y = parameter[ arg[1] ]; - z_2[0] = pow(x[0], y); - p++; - } - if( p <= q ) - forward_exp_op(p, q, i_z+2, i_z+1, cap_order, taylor); -} -/*! -Multiple directions forward mode Taylor coefficients for op = PowvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_pow_op_dir -*/ - -template -void forward_powvp_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // 2 = NumRes(PowvpOp) - 1 - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - // z_0 = log(x) - forward_log_op_dir(q, r, i_z, size_t(arg[0]), cap_order, taylor); - - // z_1 = y * z_0 - addr_t adr[2]; - adr[0] = arg[1]; - adr[1] = addr_t( i_z ); - forward_mulpv_op_dir(q, r, i_z+1, adr, parameter, cap_order, taylor); - - // z_2 = exp(z_1) - forward_exp_op_dir(q, r, i_z+2, i_z+1, cap_order, taylor); -} - -/*! -Compute zero order forward mode Taylor coefficients for result of op = PowvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_pow_op_0 -*/ - -template -void forward_powvp_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // convert from final result to first result - i_z -= 2; // NumRes(PowvpOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 3 ); - - // Paraemter value - Base y = parameter[ arg[1] ]; - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z_0 = taylor + i_z * cap_order; - Base* z_1 = z_0 + cap_order; - Base* z_2 = z_1 + cap_order; - - // z_0 = log(x) - z_0[0] = log(x[0]); - - // z_1 = z_0 * y - z_1[0] = z_0[0] * y; - - // z_2 = exp(z_1) - // zero order case exactly same as Base type operation - z_2[0] = pow(x[0], y); -} - -/*! -Compute reverse mode partial derivative for result of op = PowvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = pow(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::reverse_pow_op -*/ - -template -void reverse_powvp_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // convert from final result to first result - i_z -= 2; // NumRes(PowvpOp) - 1; - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - CPPAD_ASSERT_UNKNOWN( - size_t( std::numeric_limits::max() ) >= i_z - ); - - // z_2 = exp(z_1) - reverse_exp_op( - d, i_z+2, i_z+1, cap_order, taylor, nc_partial, partial - ); - - // z_1 = y * z_0 - addr_t adr[2]; - adr[0] = arg[1]; - adr[1] = addr_t( i_z ); - reverse_mulpv_op( - d, i_z+1, adr, parameter, cap_order, taylor, nc_partial, partial - ); - - // z_0 = log(x) - reverse_log_op( - d, i_z, size_t(arg[0]), cap_order, taylor, nc_partial, partial - ); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/print_op.hpp b/build-config/cppad/include/cppad/local/print_op.hpp deleted file mode 100644 index f338ecbd..00000000 --- a/build-config/cppad/include/cppad/local/print_op.hpp +++ /dev/null @@ -1,147 +0,0 @@ -# ifndef CPPAD_LOCAL_PRINT_OP_HPP -# define CPPAD_LOCAL_PRINT_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -Print operation for parameters; i.e., op = PriOp. - -The C++ source code corresponding to this operation is -\verbatim - f.Forward(0, x) - PrintFor(before, var) - PrintFor(pos, before, var, after) -\endverbatim -The PrintFor call puts the print operation on the tape -and the print occurs during the zero order forward mode computation. - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param s_out -the results are printed on this output stream. - -\param arg - arg[0] & 1 -\n -If this is zero, pos is a parameter. Otherwise it is a variable. -\n - arg[0] & 2 -\n -If this is zero, var is a parameter. Otherwise it is a variable. -\n -\n - arg[1] -\n -If pos is a parameter, parameter[arg[1]] is its value. -Othwise taylor[ size_t(arg[1]) * cap_order + 0 ] is the zero -order Taylor coefficient for pos. -\n -\n - arg[2] -\n -index of the text to be printed before var -if pos is not a positive value. -\n -\n - arg[3] -\n -If var is a parameter, parameter[arg[3]] is its value. -Othwise taylor[ size_t(arg[3]) * cap_order + 0 ] is the zero -order Taylor coefficient for var. -\n -\n - arg[4] -\n -index of the text to be printed after var -if pos is not a positive value. - -\param num_text -is the total number of text characters on the tape -(only used for error checking). - -\param text -\b Input: text[arg[1]] is the first character of the text -that will be printed. All the characters from there to (but not including) -the first '\\0' are printed. - -\param num_par -is the total number of values in the parameter vector - -\param parameter -Contains the value of parameters. - -\param cap_order -number of colums in the matrix containing all the Taylor coefficients. - -\param taylor -Contains the value of variables. - -\par Checked Assertions: -\li NumArg(PriOp) == 5 -\li NumRes(PriOp) == 0 -\li text != nullptr -\li arg[1] < num_text -\li if pos is a parameter, arg[1] < num_par -\li if var is a parameter, arg[3] < num_par -*/ -template -void forward_pri_0( - std::ostream& s_out , - const addr_t* arg , - size_t num_text , - const char* text , - size_t num_par , - const Base* parameter , - size_t cap_order , - const Base* taylor ) -{ Base pos, var; - const char* before; - const char* after; - CPPAD_ASSERT_NARG_NRES(PriOp, 5, 0); - - // pos - if( arg[0] & 1 ) - { pos = taylor[ size_t(arg[1]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - pos = parameter[ arg[1] ]; - } - - // before - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_text ); - before = text + arg[2]; - - // var - if( arg[0] & 2 ) - { var = taylor[ size_t(arg[3]) * cap_order + 0 ]; - } - else - { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par ); - var = parameter[ arg[3] ]; - } - - // after - CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_text ); - after = text + arg[4]; - - if( ! GreaterThanZero( pos ) ) - s_out << before << var << after; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/prototype_op.hpp b/build-config/cppad/include/cppad/local/prototype_op.hpp deleted file mode 100644 index dc93132e..00000000 --- a/build-config/cppad/include/cppad/local/prototype_op.hpp +++ /dev/null @@ -1,1458 +0,0 @@ -# ifndef CPPAD_LOCAL_PROTOTYPE_OP_HPP -# define CPPAD_LOCAL_PROTOTYPE_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file prototype_op.hpp -Documentation for generic cases (these generic cases are never used). -*/ - -// ==================== Unary operators with one result ==================== - - -/*! -Prototype for forward mode unary operator with one result (not used). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param p -lowest order of the Taylor coefficient that we are computing. - -\param q -highest order of the Taylor coefficient that we are computing. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: taylor [ i_x * cap_order + k ], -for k = 0 , ... , q, -is the k-th order Taylor coefficient corresponding to x. -\n -\b Input: taylor [ i_z * cap_order + k ], -for k = 0 , ... , p-1, -is the k-th order Taylor coefficient corresponding to z. -\n -\b Output: taylor [ i_z * cap_order + k ], -for k = p , ... , q, -is the k-th order Taylor coefficient corresponding to z. - -\par Checked Assertions -\li NumArg(op) == 1 -\li NumRes(op) == 1 -\li q < cap_order -\li p <= q -*/ -template -void forward_unary1_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for multiple direction forward mode unary operator with one result -(not used). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param q -order of the Taylor coefficients that we are computing. - -\param r -number of directions for Taylor coefficients that we are computing. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param taylor -\b Input: If x is a variable, -taylor [ arg[0] * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ arg[0] * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to x and the ell-th direction. -\n -\b Input: taylor [ i_z * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ i_z * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q-1, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to z and the ell-th direction. -\n -\b Output: -taylor [ i_z * tpv + (q-1)*r + ell + 1], -ell = 0, ..., r-1, -is the q-th order Taylor coefficient -corresponding to z and the ell-th direction. - -\par Checked Assertions -\li NumArg(op) == 1 -\li NumRes(op) == 2 -\li i_x < i_z -\li 0 < q -\li q < cap_order -*/ -template -void forward_unary1_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for zero order forward mode unary operator with one result (not used). -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: taylor [ i_x * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to x. -\n -\b Output: taylor [ i_z * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to z. - -\par Checked Assertions -\li NumArg(op) == 1 -\li NumRes(op) == 1 -\li i_x < i_z -\li 0 < cap_order -*/ -template -void forward_unary1_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for reverse mode unary operator with one result (not used). - -This routine is given the partial derivatives of a function -G(z , x , w, u ... ) -and it uses them to compute the partial derivatives of -\verbatim - H( x , w , u , ... ) = G[ z(x) , x , w , u , ... ] -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param d -highest order Taylor coefficient that -we are computing the partial derivatives with respect to. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor to z. - -\param i_x -variable index corresponding to the argument for this operation; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor - taylor [ i_x * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to x. -\n - taylor [ i_z * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to z. - -\param nc_partial -number of colums in the matrix containing all the partial derivatives. - -\param partial -\b Input: partial [ i_x * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Input: partial [ i_z * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for z. -\n -\b Output: partial [ i_x * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of H( x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Output: partial [ i_z * nc_partial + k ] -for k = 0 , ... , d -may be used as work space; i.e., may change in an unspecified manner. - - -\par Checked Assumptions -\li NumArg(op) == 1 -\li NumRes(op) == 1 -\li i_x < i_z -\li d < cap_order -\li d < nc_partial -*/ -template -void reverse_unary1_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -// ==================== Unary operators with two results ==================== - -/*! -Prototype for forward mode unary operator with two results (not used). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param p -lowest order of the Taylor coefficients that we are computing. - -\param q -highest order of the Taylor coefficients that we are computing. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -The auxillary result is called y has index i_z - 1. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: taylor [ i_x * cap_order + k ] -for k = 0 , ... , q, -is the k-th order Taylor coefficient corresponding to x. -\n -\b Input: taylor [ i_z * cap_order + k ] -for k = 0 , ... , p - 1, -is the k-th order Taylor coefficient corresponding to z. -\n -\b Input: taylor [ ( i_z - 1) * cap_order + k ] -for k = 0 , ... , p-1, -is the k-th order Taylor coefficient corresponding to the auxillary result y. -\n -\b Output: taylor [ i_z * cap_order + k ], -for k = p , ... , q, -is the k-th order Taylor coefficient corresponding to z. -\n -\b Output: taylor [ ( i_z - 1 ) * cap_order + k ], -for k = p , ... , q, -is the k-th order Taylor coefficient corresponding to -the autillary result y. - -\par Checked Assertions -\li NumArg(op) == 1 -\li NumRes(op) == 2 -\li i_x + 1 < i_z -\li q < cap_order -\li p <= q -*/ -template -void forward_unary2_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for multiple direction forward mode unary operator with two results -(not used). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param q -order of the Taylor coefficients that we are computing. - -\param r -number of directions for Taylor coefficients that we are computing. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -The auxillary result is called y has index i_z - 1. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param taylor -\b Input: taylor [ i_x * tpv + 0 ] -is the zero order Taylor coefficient for all directions and -taylor [ i_x * tpv + (k-1)*r + ell + 1 -for k = 1 , ... , q, -ell = 0 , ..., r-1, -is the k-th order Taylor coefficient -corresponding to x and the ell-th direction. -\n -\b Input: taylor [ i_z * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ i_z * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q-1, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to z and the ell-th direction. -\n -\b Input: taylor [ (i_z-1) * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ (i_z-1) * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q-1, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to the auxillary result y and the ell-th direction. -\n -\b Output: -taylor [ i_z * tpv + (q-1)*r + ell + 1], -ell = 0, ..., r-1, -is the q-th order Taylor coefficient -corresponding to z and the ell-th direction. - -\par Checked Assertions -\li NumArg(op) == 1 -\li NumRes(op) == 2 -\li i_x + 1 < i_z -\li 0 < q -\li q < cap_order -*/ -template -void forward_unary2_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for zero order forward mode unary operator with two results (not used). -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -The auxillary result is called y and has index i_z - 1. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: taylor [ i_x * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to x. -\n -\b Output: taylor [ i_z * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to z. -\n -\b Output: taylor [ ( i_z - 1 ) * cap_order + j ] -is the j-th order Taylor coefficient corresponding to -the autillary result y. - -\par Checked Assertions -\li NumArg(op) == 1 -\li NumRes(op) == 2 -\li i_x + 1 < i_z -\li j < cap_order -*/ -template -void forward_unary2_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for reverse mode unary operator with two results (not used). - -This routine is given the partial derivatives of a function -G( z , y , x , w , ... ) -and it uses them to compute the partial derivatives of -\verbatim - H( x , w , u , ... ) = G[ z(x) , y(x), x , w , u , ... ] -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param d -highest order Taylor coefficient that -we are computing the partial derivatives with respect to. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor to z. -The auxillary result is called y and has index i_z - 1. - -\param i_x -variable index corresponding to the argument for this operation; -i.e. the row index in taylor corresponding to x. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor - taylor [ i_x * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to x. -\n - taylor [ i_z * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to z. -\n - taylor [ ( i_z - 1) * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to -the auxillary variable y. - -\param nc_partial -number of colums in the matrix containing all the partial derivatives. - -\param partial -\b Input: partial [ i_x * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of -G( z , y , x , w , u , ... ) -with respect to the k-th order Taylor coefficient for x. -\n -\b Input: partial [ i_z * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , y , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for z. -\n -\b Input: partial [ ( i_z - 1) * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for the auxillary variable y. -\n -\b Output: partial [ i_x * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of H( x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Output: partial [ ( i_z - j ) * nc_partial + k ] -for j = 0 , 1 , and for k = 0 , ... , d -may be used as work space; i.e., may change in an unspecified manner. - - -\par Checked Assumptions -\li NumArg(op) == 1 -\li NumRes(op) == 2 -\li i_x + 1 < i_z -\li d < cap_order -\li d < nc_partial -*/ -template -void reverse_unary2_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} -// =================== Binary operators with one result ==================== - -/*! -Prototype forward mode x op y (not used) - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param p -lowest order of the Taylor coefficient that we are computing. - -\param q -highest order of the Taylor coefficient that we are computing. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: If x is a variable, -taylor [ size_t(arg[0]) * cap_order + k ], -for k = 0 , ... , q, -is the k-th order Taylor coefficient corresponding to x. -\n -\b Input: If y is a variable, -taylor [ size_t(arg[1]) * cap_order + k ], -for k = 0 , ... , q, -is the k-th order Taylor coefficient corresponding to y. -\n -\b Input: taylor [ i_z * cap_order + k ], -for k = 0 , ... , p-1, -is the k-th order Taylor coefficient corresponding to z. -\n -\b Output: taylor [ i_z * cap_order + k ], -for k = p, ... , q, -is the k-th order Taylor coefficient corresponding to z. - -\par Checked Assertions -\li NumArg(op) == 2 -\li NumRes(op) == 1 -\li q < cap_order -\li p <= q -*/ -template -void forward_binary_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype multiple direction forward mode x op y (not used) - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param q -is the order of the Taylor coefficients that we are computing. - -\param r -number of directions for Taylor coefficients that we are computing - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param taylor -\b Input: If x is a variable, -taylor [ arg[0] * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ arg[0] * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to x and the ell-th direction. -\n -\b Input: If y is a variable, -taylor [ arg[1] * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ arg[1] * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to y and the ell-th direction. -\n -\b Input: taylor [ i_z * tpv + 0 ], -is the zero order Taylor coefficient for all directions and -taylor [ i_z * tpv + (k-1)*r + ell + 1 ], -for k = 1 , ... , q-1, -ell = 0, ..., r-1, -is the k-th order Taylor coefficient -corresponding to z and the ell-th direction. -\n -\b Output: -taylor [ i_z * tpv + (q-1)*r + ell + 1], -ell = 0, ..., r-1, -is the q-th order Taylor coefficient -corresponding to z and the ell-th direction. - -\par Checked Assertions -\li NumArg(op) == 2 -\li NumRes(op) == 1 -\li 0 < q < cap_order -*/ -template -void forward_binary_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - - -/*! -Prototype zero order forward mode x op y (not used) - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: If x is a variable, taylor [ arg[0] * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to x. -\n -\b Input: If y is a variable, taylor [ arg[1] * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to y. -\n -\b Output: taylor [ i_z * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to z. - -\par Checked Assertions -\li NumArg(op) == 2 -\li NumRes(op) == 1 -*/ -template -void forward_binary_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for reverse mode binary operator x op y (not used). - -This routine is given the partial derivatives of a function -G( z , y , x , w , ... ) -and it uses them to compute the partial derivatives of -\verbatim - H( y , x , w , u , ... ) = G[ z(x , y) , y , x , w , u , ... ] -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param d -highest order Taylor coefficient that -we are computing the partial derivatives with respect to. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in taylor corresponding to z. - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor - taylor [ i_z * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to z. -\n -If x is a variable, taylor [ arg[0] * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to x. -\n -If y is a variable, taylor [ arg[1] * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to y. - -\param nc_partial -number of colums in the matrix containing all the partial derivatives. - -\param partial -\b Input: partial [ i_z * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of -G( z , y , x , w , u , ... ) -with respect to the k-th order Taylor coefficient for z. -\n -\b Input: If x is a variable, partial [ arg[0] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , y , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Input: If y is a variable, partial [ arg[1] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for the auxillary variable y. -\n -\b Output: If x is a variable, partial [ arg[0] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of H( y , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Output: If y is a variable, partial [ arg[1] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of H( y , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for y. -\n -\b Output: partial [ i_z * nc_partial + k ] -for k = 0 , ... , d -may be used as work space; i.e., may change in an unspecified manner. - -\par Checked Assumptions -\li NumArg(op) == 2 -\li NumRes(op) == 1 -\li If x is a variable, arg[0] < i_z -\li If y is a variable, arg[1] < i_z -\li d < cap_order -\li d < nc_partial -*/ -template -void reverse_binary_op( - size_t d , - size_t i_z , - addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} -// ======================= Pow Function =================================== -/*! -Prototype for forward mode z = pow(x, y) (not used). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param p -lowest order of the Taylor coefficient that we are computing. - -\param q -highest order of the Taylor coefficient that we are computing. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -Note that there are three results for this operation, -below they are referred to as z_0, z_1, z_2 and correspond to -\verbatim - z_0 = log(x) - z_1 = z0 * y - z_2 = exp(z1) -\endverbatim -It follows that the final result is equal to z; i.e., z = z_2 = pow(x, y). - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: If x is a variable, -taylor [ size_t(arg[0]) * cap_order + k ] -for k = 0 , ... , q, -is the k-th order Taylor coefficient corresponding to x. -\n -\b Input: If y is a variable, -taylor [ size_t(arg[1]) * cap_order + k ] -for k = 0 , ... , q -is the k-th order Taylor coefficient corresponding to y. -\n -\b Input: taylor [ (i_z-2+j) * cap_order + k ], -for j = 0, 1, 2 , for k = 0 , ... , p-1, -is the k-th order Taylor coefficient corresponding to z_j. -\n -\b Output: taylor [ (i_z-2+j) * cap_order + k ], -is the k-th order Taylor coefficient corresponding to z_j. - -\par Checked Assertions -\li NumArg(op) == 2 -\li NumRes(op) == 3 -\li If x is a variable, arg[0] < i_z - 2 -\li If y is a variable, arg[1] < i_z - 2 -\li q < cap_order -\li p <= q -*/ -template -void forward_pow_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} -/*! -Prototype for multiple direction forward mode z = pow(x, y) (not used). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param q -order of the Taylor coefficient that we are computing. - -\param r -is the number of Taylor coefficient directions that we are computing - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -Note that there are three results for this operation, -below they are referred to as z_0, z_1, z_2 and correspond to -\verbatim - z_0 = log(x) - z_1 = z0 * y - z_2 = exp(z1) -\endverbatim -It follows that the final result is equal to z; i.e., z = z_2 = pow(x, y). - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\par tpv -We use the notation -tpv = (cap_order-1) * r + 1 -which is the number of Taylor coefficients per variable - -\param taylor -\b Input: If x is a variable, -taylor [ arg[0] * tpv + 0 ] -is the zero order coefficient corresponding to x and -taylor [ arg[0] * tpv + (k-1)*r+1+ell ] -for k = 1 , ... , q, -ell = 0 , ... , r-1, -is the k-th order Taylor coefficient corresponding to x -for the ell-th direction. -\n -\n -\b Input: If y is a variable, -taylor [ arg[1] * tpv + 0 ] -is the zero order coefficient corresponding to y and -taylor [ arg[1] * tpv + (k-1)*r+1+ell ] -for k = 1 , ... , q, -ell = 0 , ... , r-1, -is the k-th order Taylor coefficient corresponding to y -for the ell-th direction. -\n -\n -\b Input: -taylor [ (i_z-2+j) * tpv + 0 ], -is the zero order coefficient corresponding to z_j and -taylor [ (i_z-2+j) * tpv + (k-1)*r+1+ell ], -for j = 0, 1, 2 , k = 0 , ... , q-1, ell = 0, ... , r-1, -is the k-th order Taylor coefficient corresponding to z_j -for the ell-th direction. -\n -\n -\b Output: -taylor [ (i_z-2+j) * tpv + (q-1)*r+1+ell ], -for j = 0, 1, 2 , ell = 0, ... , r-1, -is the q-th order Taylor coefficient corresponding to z_j -for the ell-th direction. - -\par Checked Assertions -\li NumArg(op) == 2 -\li NumRes(op) == 3 -\li If x is a variable, arg[0] < i_z - 2 -\li If y is a variable, arg[1] < i_z - 2 -\li 0 < q -\li q < cap_order -*/ -template -void forward_pow_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} -/*! -Prototype for zero order forward mode z = pow(x, y) (not used). - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -Note that there are three results for this operation, -below they are referred to as z_0, z_1, z_2 and correspond to -\verbatim - z_0 = log(x) - z_1 = z0 * y - z_2 = exp(z1) -\endverbatim -It follows that the final result is equal to z; i.e., z = z_2 = pow(x, y). - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor -\b Input: If x is a variable, taylor [ arg[0] * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to x. -\n -\b Input: If y is a variable, taylor [ arg[1] * cap_order + 0 ] -is the k-th order Taylor coefficient corresponding to y. -\n -\b Output: taylor [ (i_z - 2 + j) * cap_order + 0 ] -is the zero order Taylor coefficient corresponding to z_j. - -\par Checked Assertions -\li NumArg(op) == 2 -\li NumRes(op) == 3 -\li If x is a variable, arg[0] < i_z - 2 -\li If y is a variable, arg[1] < i_z - 2 -*/ -template -void forward_pow_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} -/*! -Prototype for reverse mode z = pow(x, y) (not used). - -This routine is given the partial derivatives of a function -G( z , y , x , w , ... ) -and it uses them to compute the partial derivatives of -\verbatim - H( y , x , w , u , ... ) = G[ pow(x , y) , y , x , w , u , ... ] -\endverbatim - -\tparam Base -base type for the operator; i.e., this operation was recorded -using AD< Base > and computations by this routine are done using type - Base . - -\param d -highest order Taylor coefficient that -we are computing the partial derivatives with respect to. - -\param i_z -variable index corresponding to the last (primary) result for this operation; -i.e. the row index in taylor corresponding to z. -Note that there are three results for this operation, -below they are referred to as z_0, z_1, z_2 and correspond to -\verbatim - z_0 = log(x) - z_1 = z0 * y - z_2 = exp(z1) -\endverbatim -It follows that the final result is equal to z; i.e., z = z_2 = pow(x, y). - -\param arg - arg[0] -index corresponding to the left operand for this operator; -i.e. the index corresponding to x. -\n - arg[1] -index corresponding to the right operand for this operator; -i.e. the index corresponding to y. - -\param parameter -If x is a parameter, parameter [ arg[0] ] -is the value corresponding to x. -\n -If y is a parameter, parameter [ arg[1] ] -is the value corresponding to y. - -\param cap_order -maximum number of orders that will fit in the taylor array. - -\param taylor - taylor [ (i_z - 2 + j) * cap_order + k ] -for j = 0, 1, 2 and k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to z_j. -\n -If x is a variable, taylor [ arg[0] * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to x. -\n -If y is a variable, taylor [ arg[1] * cap_order + k ] -for k = 0 , ... , d -is the k-th order Taylor coefficient corresponding to y. - -\param nc_partial -number of colums in the matrix containing all the partial derivatives. - -\param partial -\b Input: partial [ (i_z - 2 + j) * nc_partial + k ] -for j = 0, 1, 2, and k = 0 , ... , d -is the partial derivative of -G( z , y , x , w , u , ... ) -with respect to the k-th order Taylor coefficient for z_j. -\n -\b Input: If x is a variable, partial [ arg[0] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , y , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Input: If y is a variable, partial [ arg[1] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of G( z , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for the auxillary variable y. -\n -\b Output: If x is a variable, partial [ arg[0] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of H( y , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for x. -\n -\b Output: If y is a variable, partial [ arg[1] * nc_partial + k ] -for k = 0 , ... , d -is the partial derivative of H( y , x , w , u , ... ) with respect to -the k-th order Taylor coefficient for y. -\n -\b Output: partial [ ( i_z - j ) * nc_partial + k ] -for j = 0 , 1 , 2 and for k = 0 , ... , d -may be used as work space; i.e., may change in an unspecified manner. - -\par Checked Assumptions -\li NumArg(op) == 2 -\li NumRes(op) == 3 -\li If x is a variable, arg[0] < i_z - 2 -\li If y is a variable, arg[1] < i_z - 2 -\li d < cap_order -\li d < nc_partial -*/ -template -void reverse_pow_op( - size_t d , - size_t i_z , - addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -// ==================== Sparsity Calculations ============================== -/*! -Prototype for reverse mode Hessian sparsity unary operators. - -This routine is given the forward mode Jacobian sparsity patterns for x. -It is also given the reverse mode dependence of G on z. -In addition, it is given the revese mode Hessian sparsity -for the quanity of interest G(z , y , ... ) -and it uses them to compute the sparsity patterns for -\verbatim - H( x , w , u , ... ) = G[ z(x) , x , w , u , ... ] -\endverbatim - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in sparsity corresponding to z. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in sparsity corresponding to x. - -\param rev_jacobian - rev_jacobian[i_z] -is all false (true) if the Jacobian of G with respect to z must be zero -(may be non-zero). -\n -\n - rev_jacobian[i_x] -is all false (true) if the Jacobian with respect to x must be zero -(may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. - -\param for_jac_sparsity -The set with index i_x in for_jac_sparsity -is the forward mode Jacobian sparsity pattern for the variable x. - -\param rev_hes_sparsity -The set with index i_z in in rev_hes_sparsity -is the Hessian sparsity pattern for the fucntion G -where one of the partials derivative is with respect to z. -\n -\n -The set with index i_x in rev_hes_sparsity -is the Hessian sparsity pattern -where one of the partials derivative is with respect to x. -On input, it corresponds to the function G, -and on output it corresponds to the function H. - -\par Checked Assertions: -\li i_x < i_z -*/ - -template -void reverse_sparse_hessian_unary_op( - size_t i_z , - size_t i_x , - bool* rev_jacobian , - Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - -/*! -Prototype for reverse mode Hessian sparsity binary operators. - -This routine is given the sparsity patterns the Hessian -of a function G(z, y, x, ... ) -and it uses them to compute the sparsity patterns for the Hessian of -\verbatim - H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ] -\endverbatim - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in sparsity corresponding to z. - -\param arg - arg[0] -variable index corresponding to the left operand for this operator; -i.e. the set with index arg[0] in var_sparsity -is the spasity pattern correspoding to x. -\n -\n arg[1] -variable index corresponding to the right operand for this operator; -i.e. the row index in sparsity patterns corresponding to y. - -\param jac_reverse - jac_reverse[i_z] -is false (true) if the Jacobian of G with respect to z is always zero -(may be non-zero). -\n -\n - jac_reverse[ arg[0] ] -is false (true) if the Jacobian with respect to x is always zero -(may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. -\n -\n - jac_reverse[ arg[1] ] -is false (true) if the Jacobian with respect to y is always zero -(may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. - -\param for_jac_sparsity -The set with index arg[0] in for_jac_sparsity for the -is the forward Jacobian sparsity pattern for x. -\n -\n -The set with index arg[1] in for_jac_sparsity -is the forward sparsity pattern for y. - -\param rev_hes_sparsity -The set wiht index i_x in rev_hes_sparsity -is the Hessian sparsity pattern for the function G -where one of the partial derivatives is with respect to z. -\n -\n -The set with index arg[0] in rev_hes_sparsity -is the Hessian sparsity pattern where one of the -partial derivatives is with respect to x. -On input, it corresponds to the function G, -and on output it correspondst to H. -\n -\n -The set with index arg[1] in rev_hes_sparsity -is the Hessian sparsity pattern where one of the -partial derivatives is with respect to y. -On input, it corresponds to the function G, -and on output it correspondst to H. - -\par Checked Assertions: -\li arg[0] < i_z -\li arg[1] < i_z -*/ -template -void reverse_sparse_hessian_binary_op( - size_t i_z , - const addr_t* arg , - bool* jac_reverse , - Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/record/comp_op.hpp b/build-config/cppad/include/cppad/local/record/comp_op.hpp deleted file mode 100644 index 04669f84..00000000 --- a/build-config/cppad/include/cppad/local/record/comp_op.hpp +++ /dev/null @@ -1,287 +0,0 @@ -# ifndef CPPAD_LOCAL_RECORD_COMP_OP_HPP -# define CPPAD_LOCAL_RECORD_COMP_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* -$begin recorder_put_comp_op$$ -$spell - rel - aleft - eq - le - lt - var - dyn - taddr -$$ - -$section Put Compare Operators in Recording$$ - -$head Syntax$$ -$icode%rec%.put_comp_%rel%( %aleft%, %aright%, %result%) -%$$ - -$subhead rel$$ -The text $icode rel$$ in the function name above -is $code eq$$ (for equals), -$code le$$ (for less than or equal), or -$code lt$$ (for less than). - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_COMP_EQ%// END_COMP_EQ%1 -%$$ -The other prototypes for the functions $code comp_le$$ and $code comp_lt$$ -are same except for the function name. - -$head var_left$$ -is true if the left operand is a variable. - -$head var_right$$ -is true if the right operand is a variable. - -$head dyn_left$$ -is true if the left operand is a dynamic parameter. - -$head dyn_right$$ -is true if the right operand is a dynamic parameter. - -$head aleft$$ -is the compare operator left operand. - -$head aright$$ -is the compare operator right operand. - -$head taddr_$$ -The values $icode%aleft.taddr_%$$ and $icode%aright%.taddr_%$$ -are the proper address for dynamic parameters and variables -and does not matter for constants. - -$head value_$$ -The values $icode%aleft.value_%$$ and $icode%aright%.value_%$$ -are the proper address for constants and does not matter -for variables and dynamic parameters. - -$head result$$ -This is the result for this comparison corresponding to this -recording (sequence of operations). - -$end -*/ -// BEGIN_COMP_EQ -template -void recorder::comp_eq( - bool var_left , - bool var_right , - bool dyn_left , - bool dyn_right , - const AD& aleft , - const AD& aright , - bool result ) -// END_COMP_EQ -{ if( var_left ) - { if( var_right ) - { // variable == variable - PutArg(aleft.taddr_, aright.taddr_); - if( result ) - PutOp(EqvvOp); - else - PutOp(NevvOp); - } - else - { // variable == parameter - addr_t p = aright.taddr_; - if( ! dyn_right ) - p = put_con_par(aright.value_); - PutArg(p, aleft.taddr_); - if( result ) - PutOp(EqpvOp); - else - PutOp(NepvOp); - } - } - else if ( var_right ) - { // parameter == variable - addr_t p = aleft.taddr_; - if( ! dyn_left ) - p = put_con_par(aleft.value_); - PutArg(p, aright.taddr_); - if( result ) - PutOp(EqpvOp); - else - PutOp(NepvOp); - } - else if( dyn_left | dyn_right ) - { // parameter == parameter - addr_t arg0 = aleft.taddr_; - addr_t arg1 = aright.taddr_; - if( ! dyn_left ) - arg0 = put_con_par(aleft.value_); - if( ! dyn_right ) - arg1 = put_con_par(aright.value_); - // - PutArg(arg0, arg1); - if( result ) - PutOp(EqppOp); - else - PutOp(NeppOp); - } -} -// --------------------------------------------------------------------------- -// comp_le -template -void recorder::comp_le( - bool var_left , - bool var_right , - bool dyn_left , - bool dyn_right , - const AD& aleft , - const AD& aright , - bool result ) -{ - if( var_left ) - { if( var_right ) - { // variable <= variable - if( result ) - { PutOp(LevvOp); - PutArg(aleft.taddr_, aright.taddr_); - } - else - { PutOp(LtvvOp); - PutArg(aright.taddr_, aleft.taddr_); - } - } - else - { // variable <= parameter - addr_t p = aright.taddr_; - if( ! dyn_right ) - p = put_con_par(aright.value_); - if( result ) - { PutOp(LevpOp); - PutArg(aleft.taddr_, p); - } - else - { PutOp(LtpvOp); - PutArg(p, aleft.taddr_); - } - } - } - else if ( var_right ) - { // parameter <= variable - addr_t p = aleft.taddr_; - if( ! dyn_left ) - p = put_con_par(aleft.value_); - if( result ) - { PutOp(LepvOp); - PutArg(p, aright.taddr_); - } - else - { PutOp(LtvpOp); - PutArg(aright.taddr_, p); - } - } - else if( dyn_left | dyn_right ) - { // parameter <= parameter - addr_t arg0 = aleft.taddr_; - addr_t arg1 = aright.taddr_; - if( ! dyn_left ) - arg0 = put_con_par(aleft.value_); - if( ! dyn_right ) - arg1 = put_con_par(aright.value_); - // - if( result ) - { PutOp(LeppOp); - PutArg(arg0, arg1); - } - else - { PutOp(LtppOp); - PutArg(arg1, arg0); - } - } -} -// -------------------------------------------------------------------------- -// comp_lt -template -void recorder::comp_lt( - bool var_left , - bool var_right , - bool dyn_left , - bool dyn_right , - const AD& aleft , - const AD& aright , - bool result ) -{ - if( var_left ) - { if( var_right ) - { // variable < variable - if( result ) - { PutOp(LtvvOp); - PutArg(aleft.taddr_, aright.taddr_); - } - else - { PutOp(LevvOp); - PutArg(aright.taddr_, aleft.taddr_); - } - } - else - { // variable < parameter - addr_t p = aright.taddr_; - if( ! dyn_right ) - p = put_con_par(aright.value_); - if( result ) - { PutOp(LtvpOp); - PutArg(aleft.taddr_, p); - } - else - { PutOp(LepvOp); - PutArg(p, aleft.taddr_); - } - } - } - else if ( var_right ) - { // parameter < variable - addr_t p = aleft.taddr_; - if( ! dyn_left ) - p = put_con_par(aleft.value_); - if( result ) - { PutOp(LtpvOp); - PutArg(p, aright.taddr_); - } - else - { PutOp(LevpOp); - PutArg(aright.taddr_, p); - } - } - else if( dyn_left | dyn_right ) - { // parameter < parameter - addr_t arg0 = aleft.taddr_; - addr_t arg1 = aright.taddr_; - if( ! dyn_left ) - arg0 = put_con_par(aleft.value_); - if( ! dyn_right ) - arg1 = put_con_par(aright.value_); - // - if( result ) - { PutOp(LtppOp); - PutArg(arg0, arg1); - } - else - { PutOp(LeppOp); - PutArg(arg1, arg0); - } - } -} -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/record/cond_exp.hpp b/build-config/cppad/include/cppad/local/record/cond_exp.hpp deleted file mode 100644 index f72e3249..00000000 --- a/build-config/cppad/include/cppad/local/record/cond_exp.hpp +++ /dev/null @@ -1,176 +0,0 @@ -# ifndef CPPAD_LOCAL_RECORD_COND_EXP_HPP -# define CPPAD_LOCAL_RECORD_COND_EXP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* -$begin recorder_cond_exp$$ -$spell - cond_exp - ptr -$$ - -$section Record a Variable or Dynamic Parameter Conditional Expression$$ - -$head Syntax$$ -$icode%rec%.cond_exp( - %tape_id%, %cop%, %result%, %left%, %right%, %if_true%, %if_false% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_COND_EXP%// END_COND_EXP%1 -%$$ - -$head tape_id$$ -identifier for the tape that this operation is being recorded on. -Passing tape_id avoids having to call tape_ptr() in case where -left, right, if_true, and if_false are all be constant at this AD level -(but left and right are not identically constant). - -$head cop$$ -Which $cref/comparison operator/base_cond_exp/CompareOp/$$; -i.e., <, <=, ==, >=, >, or !=. - -$head result$$ -is the result for this operation conditional expression. -On input, $icode%result%.value_%$$ is the proper value and -the other fields do not matter. -Upon return, the other fields have been set to their proper values. -It is an error to call this routine when all the arguments are constants; i.e., -when the result is a constant. - -$head left$$ -value of the left operand in the comparison. -If $icode%left%.tape_id_%$$ is not zero it must equal $icode tape_id$$. - -$head right$$ -value of the right operand in the comparison. -If $icode%right%.tape_id_%$$ is not zero it must equal $icode tape_id$$. - -$head if_true$$ -value of the result if the comparison value is true. -If $icode%if_true%.tape_id_%$$ is not zero it must equal $icode tape_id$$. - -$head if_false$$ -value of the result if the comparison value is false. -If $icode%if_false%.tape_id_%$$ is not zero it must equal $icode tape_id$$. - -$end -*/ -// BEGIN_COND_EXP -template -void recorder::cond_exp( - tape_id_t tape_id , - enum CompareOp cop , - AD &result , - const AD &left , - const AD &right , - const AD &if_true , - const AD &if_false ) -// END_COND_EXP -{ // check for invalid tape_id - CPPAD_ASSERT_UNKNOWN( tape_id != 0 ); - - // arg[0] = cop - addr_t arg0 = addr_t( cop ); - - // arg[1] = base 2 represenation of the value - // [Var(left), Var(right), Var(if_true), Var(if_false)] - addr_t arg1 = 0; - - // arg[2] = left address - // set first bit in arg1 - addr_t arg2 = left.taddr_; - if( Constant(left) ) - arg2 = put_con_par(left.value_); - else - { CPPAD_ASSERT_KNOWN( tape_id == left.tape_id_ , - "CondExpRel: arguments are variables or dynamics for different thread" - ); - if(left.ad_type_ != dynamic_enum) - arg1 += 1; - } - - // arg[3] = right address - // set second bit in arg1 - addr_t arg3 = right.taddr_; - if( Constant(right) ) - arg3 = put_con_par(right.value_); - else - { CPPAD_ASSERT_KNOWN( tape_id == right.tape_id_ , - "CondExpRel: arguments are variables or dynamics for different thread" - ); - if(right.ad_type_ != dynamic_enum) - arg1 += 2; - } - - // arg[4] = if_true address - // set third bit in arg1 - addr_t arg4 = if_true.taddr_; - if( Constant(if_true) ) - arg4 = put_con_par(if_true.value_); - else - { CPPAD_ASSERT_KNOWN( tape_id == if_true.tape_id_ , - "CondExpRel: arguments are variables or dynamics for different thread" - ); - if(if_true.ad_type_ != dynamic_enum) - arg1 += 4; - } - - // arg[5] = if_false address - // set fourth bit in arg1 - addr_t arg5 = if_false.taddr_; - if( Constant(if_false) ) - arg5 = put_con_par(if_false.value_); - else - { CPPAD_ASSERT_KNOWN( tape_id == if_false.tape_id_ , - "CondExpRel: arguments are variables or dynamics for different thread" - ); - if(if_false.ad_type_ != dynamic_enum) - arg1 += 8; - } - if( arg1 == 0 ) - { // none of the arguments are variables, record cond_exp_dyn - - // put the result at the end of the parameter vector as dynamic - // put_dyn_cond_exp(par, cop, left, right, if_true, if_false) - result.taddr_ = put_dyn_cond_exp( - result.value_, CompareOp(arg0), arg2, arg3, arg4, arg5 - ); - result.ad_type_ = dynamic_enum; - result.tape_id_ = tape_id; - - // check that result is a dynamic parameter - CPPAD_ASSERT_UNKNOWN( Dynamic(result) ); - } - else - { CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 ); - CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 ); - - // put operator in tape - result.taddr_ = PutOp(CExpOp); - PutArg(arg0, arg1, arg2, arg3, arg4, arg5); - - // make result a variable - CPPAD_ASSERT_UNKNOWN( result.ad_type_ == constant_enum ); - result.ad_type_ = variable_enum; - result.tape_id_ = tape_id; - - // check that result is a variable - CPPAD_ASSERT_UNKNOWN( Variable(result) ); - } -} -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/record/put_dyn_atomic.hpp b/build-config/cppad/include/cppad/local/record/put_dyn_atomic.hpp deleted file mode 100644 index 51b0f0a1..00000000 --- a/build-config/cppad/include/cppad/local/record/put_dyn_atomic.hpp +++ /dev/null @@ -1,169 +0,0 @@ -# ifndef CPPAD_LOCAL_RECORD_PUT_DYN_ATOMIC_HPP -# define CPPAD_LOCAL_RECORD_PUT_DYN_ATOMIC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* -$begin recorder_put_dyn_atomic$$ -$spell - ptr - dyn - enum - taddr -$$ - -$section Put a Dynamic Parameter Atomic Call Operator in Recording$$ - -$head Syntax$$ -$icode%rec%.put_dyn_atomic( - %tape_id%, %atomic_index%, %type_x%, %type_y%, %ax%, %ay% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUT_DYN_ATOMIC%// END_PROTOTYPE%1 -%$$ - -$head tape_id$$ -identifies the tape that this recording corresponds to. -This is zero if and only if there is no tape for this recording; i.e. -$codei%AD<%Base%>.tape_ptr()%$$ is null. - -$head atomic_index$$ -is the $cref atomic_index$$ for this atomic function. - -$head type_x$$ -is the $cref ad_type_enum$$ for each of the atomic function arguments. - -$head type_y$$ -is the $code ad_type_enum$$ for each of the atomic function results. - -$head ax$$ -is the atomic function argument vector for this call. - -$subhead value_$$ -The value $icode%ax%[%j%].value_%$$ is the proper value for -parameters and does not matter for variables. - -$subhead taddr_$$ -The value $icode%ax%[%j%].taddr_%$$ is the proper address for -dynamic parameters and does not matter for constants or variables. - -$head ay$$ -is the atomic function result vector for this call. - -$subhead Input$$ -On input, $icode%ay%[%j%].value_%$$ has the proper value for parameters -(result for the atomic function). - -$subhead Output$$ -Upon return, if the $th i$$ result is a dynamic parameter, -$codei% - %ay%[%i%].ad_type_ = dynamic_enum - %ay%[%i%].tape_id_ = %tape_id% - %ay%[%i%].taddr_ = %p_index% -%$$ -where $icode p_index$$ is the index of this dynamic parameter -in the vector of all parameters. - -$end -*/ - -// BEGIN_PUT_DYN_ATOMIC -template template -void recorder::put_dyn_atomic( - tape_id_t tape_id , - size_t atomic_index , - const vector& type_x , - const vector& type_y , - const VectorAD& ax , - VectorAD& ay ) -// END_PROTOTYPE -{ CPPAD_ASSERT_UNKNOWN( - (tape_id == 0) == (AD::tape_ptr() == nullptr) - ); - CPPAD_ASSERT_UNKNOWN( ax.size() == type_x.size() ); - CPPAD_ASSERT_UNKNOWN( ay.size() == type_y.size() ); - size_t n = ax.size(); - size_t m = ay.size(); - size_t num_dyn = 0; - for(size_t i = 0; i < m; ++i) - if( type_y[i] == dynamic_enum ) - ++num_dyn; - CPPAD_ASSERT_UNKNOWN( num_dyn > 0 ); - // - dyn_par_arg_.push_back( addr_t(atomic_index )); // arg[0] = atomic_index - dyn_par_arg_.push_back( addr_t( n ) ); // arg[1] = n - dyn_par_arg_.push_back( addr_t( m ) ); // arg[2] = m - dyn_par_arg_.push_back( addr_t( num_dyn ) ); // arg[3] = num_dyn - // arg[4 + j] for j = 0, ... , n-1 - for(size_t j = 0; j < n; ++j) - { addr_t arg = 0; - switch( type_x[j] ) - { case constant_enum: - arg = put_con_par( ax[j].value_ ); - break; - - case dynamic_enum: - arg = ax[j].taddr_; - break; - - case variable_enum: - arg = 0; // phantom parameter index - CPPAD_ASSERT_UNKNOWN( isnan( all_par_vec_[arg] ) ) - break; - - default: - arg = 0; - CPPAD_ASSERT_UNKNOWN( false ); - } - dyn_par_arg_.push_back( arg ); // arg[4 + j] - } - // arg[4 + n + i] for i = 0, ... , m-1 - bool first_dynamic_result = true; - for(size_t i = 0; i < m; ++i) - { addr_t arg; - switch( type_y[i] ) - { case constant_enum: - arg = 0; // phantom parameter index - break; - - case dynamic_enum: - // one operator for each dynamic parameter result - // so number of operators is equal number of dynamic parameters - if( first_dynamic_result ) - arg = put_dyn_par(ay[i].value_, atom_dyn ); // atom_dyn - else - arg = put_dyn_par(ay[i].value_, result_dyn ); // result_dyn - ay[i].ad_type_ = dynamic_enum; - ay[i].taddr_ = arg; - ay[i].tape_id_ = tape_id; - first_dynamic_result = false; - break; - - case variable_enum: - arg = 0; // phantom parameter (has value nan) - break; - - default: - arg = 0; - CPPAD_ASSERT_UNKNOWN( false ); - } - dyn_par_arg_.push_back( arg ); // arg[4 + n + i] - } - dyn_par_arg_.push_back( addr_t(5 + n + m) ); // arg[4 + n + m] -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/record/put_var_atomic.hpp b/build-config/cppad/include/cppad/local/record/put_var_atomic.hpp deleted file mode 100644 index ea4f0a8f..00000000 --- a/build-config/cppad/include/cppad/local/record/put_var_atomic.hpp +++ /dev/null @@ -1,150 +0,0 @@ -# ifndef CPPAD_LOCAL_RECORD_PUT_VAR_ATOMIC_HPP -# define CPPAD_LOCAL_RECORD_PUT_VAR_ATOMIC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* -$begin recorder_put_var_atomic$$ -$spell - ptr - var - enum - taddr -$$ - -$section Put a Variable Atomic Call Operator in Recording$$ - -$head Syntax$$ -$icode%rec%.put_var_atomic( - %tape_id%, %atomic_index%, %type_x%, %type_y%, %ax%, %ay% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUT_VAR_ATOMIC%// END_PROTOTYPE%1 -%$$ - -$head tape_id$$ -identifies the tape that this recording corresponds to. -This is zero if and only if there is no tape for this recording; i.e. -$codei%AD<%Base%>.tape_ptr()%$$ is null. - -$head atomic_index$$ -is the $cref atomic_index$$ for this atomic function. - -$head type_x$$ -is the $cref ad_type_enum$$ for each of the atomic function arguments. - -$head type_y$$ -is the $code ad_type_enum$$ for each of the atomic function results. - -$head ax$$ -is the atomic function argument vector for this call. - -$subhead value_$$ -The value $icode%ax%[%j%].value_%$$ is the proper value for all arguments. - -$subhead taddr_$$ -The value $icode%ax%[%j%].taddr_%$$ is the proper address -for dynamic parameters and variables and does not matter for constants. - -$head ay$$ -is the atomic function result vector for this call. - -$subhead Input$$ -On input, $icode%ay%[%i%]%$$ has all the correct values for -parameters and does not matter for variables. - -$subhead Output$$ -Upon return, if the $th i$$ result is a variable, -$codei% - %ay%[%i%].ad_type_ = dynamic_enum - %ay%[%i%].tape_id_ = %tape_id% - %ay%[%i%].taddr_ = %v_index% -%$$ -where $icode v_index$$ is the index of this variable -in the arrays containing all the variables. - -$end -*/ -// BEGIN_PUT_VAR_ATOMIC -template template -void recorder::put_var_atomic( - tape_id_t tape_id , - size_t atomic_index , - const vector& type_x , - const vector& type_y , - const VectorAD& ax , - VectorAD& ay ) -// END_PROTOTYPE -{ CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= - std::max( std::max(atomic_index, ax.size() ), ay.size() ), - "atomic_three: cppad_tape_addr_type maximum not large enough" - ); - CPPAD_ASSERT_UNKNOWN( - (tape_id == 0) == (AD::tape_ptr() == nullptr) - ); - // Operator that marks beginning of this atomic operation - CPPAD_ASSERT_NARG_NRES(local::AFunOp, 4, 0 ); - addr_t old_id = 0; // used by atomic_two to implement atomic_one interface - size_t n = ax.size(); - size_t m = ay.size(); - PutArg(addr_t(atomic_index), old_id, addr_t(n), addr_t(m)); - PutOp(local::AFunOp); - - // Now put n operators, one for each element of argument vector - CPPAD_ASSERT_NARG_NRES(local::FunavOp, 1, 0 ); - CPPAD_ASSERT_NARG_NRES(local::FunapOp, 1, 0 ); - for(size_t j = 0; j < n; j++) - { if( type_x[j] == variable_enum ) - { // information for an argument that is a variable - PutArg(ax[j].taddr_); - PutOp(local::FunavOp); - } - else - { // information for an argument that is parameter - addr_t par = ax[j].taddr_; - if( type_x[j] == constant_enum ) - par = put_con_par(ax[j].value_); - PutArg(par); - PutOp(local::FunapOp); - } - } - - // Now put m operators, one for each element of result vector - CPPAD_ASSERT_NARG_NRES(local::FunrvOp, 0, 1); - CPPAD_ASSERT_NARG_NRES(local::FunrpOp, 1, 0); - for(size_t i = 0; i < m; i++) - { if( type_y[i] == variable_enum ) - { ay[i].taddr_ = PutOp(local::FunrvOp); - ay[i].tape_id_ = tape_id; - ay[i].ad_type_ = variable_enum; - } - else - { addr_t par = ay[i].taddr_; - if( type_y[i] == constant_enum ) - par = put_con_par( ay[i].value_ ); - PutArg(par); - PutOp(local::FunrpOp); - } - } - - // Put a duplicate AFunOp at end of AFunOp sequence - PutArg(addr_t(atomic_index), old_id, addr_t(n), addr_t(m)); - PutOp(local::AFunOp); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/record/put_var_vecad.hpp b/build-config/cppad/include/cppad/local/record/put_var_vecad.hpp deleted file mode 100644 index 6ccda7ae..00000000 --- a/build-config/cppad/include/cppad/local/record/put_var_vecad.hpp +++ /dev/null @@ -1,130 +0,0 @@ -# ifndef CPPAD_LOCAL_RECORD_PUT_VAR_VECAD_HPP -# define CPPAD_LOCAL_RECORD_PUT_VAR_VECAD_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* ------------------------------------------------------------------------------- -$begin put_var_vecad_ind$$ -$spell - Vec - var - vecad - ind - taddr -$$ - -$section Add One Index to End of Combined Variable VecAD Vector$$ - -$head Syntax$$ -$icode%offset% = %rec%.put_var_vecad_ind(%vec_ind%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUT_VAR_VECAD_IND%// END_PUT_VAR_VECAD_IND%1 -%$$ - -$head Purpose$$ -For each variable VecAD vector, this routine is used to store the length -of the vector followed by the parameter index corresponding to initial -value in the vector; i.e., the values just before it changed from a parameter -to a variable. - -$head vec_ind$$ -is the index to be placed at the end of the combined vector of VecAD indices. - -$head offset$$ -is the index in the combined variable VecAD vector -where the value $icode vec_ind$$ is stored. -This index starts at zero after the recorder default constructor and -increments by one for each call to put_var_vecad_ind. - -$end -*/ -// BEGIN_PUT_VAR_VECAD_IND -template -addr_t recorder::put_var_vecad_ind(addr_t vec_ind) -// END_PUT_VAR_VECAD_IND -{ size_t offset = all_var_vecad_ind_.size(); - all_var_vecad_ind_.push_back( vec_ind ); - CPPAD_ASSERT_KNOWN( - size_t( addr_t( offset ) ) == offset, - "cppad_tape_addr_type cannot support needed index range" - ); - return static_cast( offset ); -} -/* ------------------------------------------------------------------------------- -$begin recorder_put_var_vecad$$ -$spell - Vec - var - vecad - taddr -$$ -$section Tape Initialization for a Variable VecAD Object$$ - -$head Syntax$$ -$icode%offset% = %rec%.put_var_vecad(%length%, %taddr%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUT_VAR_VECAD_VEC%// END_PUT_VAR_VECAD_VEC%1 -%$$ - -$head Usage$$ -This routine should be called once for each variable VecAD object just -before it changes from a parameter to a variable. - -$head length$$ -is the size of the VecAD object. - -$head taddr$$ -vector of parameter indices corresponding to the value of this VecAD vector -just before it becomes a variable. - -$head offset$$ -index of the start of this VecAD vector in the combined variable VecAD vector. -The value corresponding to $icode offset$$ is the length of this VecAD vector. -There are $icode length$$ more indices following the length. -These values are the parameter indices. - -$end -*/ -// BEGIN_PUT_VAR_VECAD_VEC -template -addr_t recorder::put_var_vecad( - size_t length , - const pod_vector& taddr ) -// END_PUT_VAR_VECAD_VEC -{ CPPAD_ASSERT_UNKNOWN( length > 0 ); - CPPAD_ASSERT_UNKNOWN( length == taddr.size() ); - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= length, - "A VecAD vector length is too large fur cppad_tape_addr_type" - ); - - // store the length in VecInd - addr_t start = put_var_vecad_ind( addr_t(length) ); - - // store indices of the values in VecInd - for(size_t i = 0; i < length; i++) - put_var_vecad_ind( taddr[i] ); - - // return the taddr of the length (where the vector starts) - return start; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/record/recorder.hpp b/build-config/cppad/include/cppad/local/record/recorder.hpp deleted file mode 100644 index 97c01bc8..00000000 --- a/build-config/cppad/include/cppad/local/record/recorder.hpp +++ /dev/null @@ -1,848 +0,0 @@ -# ifndef CPPAD_LOCAL_RECORD_RECORDER_HPP -# define CPPAD_LOCAL_RECORD_RECORDER_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include -# include - -// ---------------------------------------------------------------------------- -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file recorder.hpp -File used to define the recorder class. -*/ - -/*! -Class used to store an operation sequence while it is being recorded -(the operation sequence is copied to the player class for playback). - -\tparam Base -This is an AD< Base > operation sequence recording; i.e., -it records operations of type AD< Base >. -*/ -template -class recorder { - friend class player; - -private: - /// are comparison operators being recorded - bool record_compare_; - - /// operator index at which to abort recording with an error - /// (do not abort when zero) - size_t abort_op_index_; - - /// Number of variables in the recording. - size_t num_var_rec_; - - /// Number of dynamic parameters in the recording - size_t num_dynamic_ind_; - - /// Number vecad load operations (LdpOp or LdvOp) currently in recording. - size_t num_var_load_rec_; - - /// The operators in the recording. - pod_vector op_vec_; - - /// The VecAD indices in the recording. - pod_vector all_dyn_vecad_ind_; - pod_vector all_var_vecad_ind_; - - /// The argument indices in the recording - pod_vector arg_vec_; - - /// Character strings ('\\0' terminated) in the recording. - pod_vector text_vec_; - - /// Hash table to reduced number of duplicate parameters in all_par_vec_ - pod_vector par_hash_table_; - - /// Vector containing all the parameters in the recording. - /// Use pod_vector_maybe because Base may not be plain old data. - pod_vector_maybe all_par_vec_; - - /// Which elements of all_par_vec_ are dynamic parameters - /// (same size are all_par_vec_) - pod_vector dyn_par_is_; - - /// operators for just the dynamic parameters in all_par_vec_ - pod_vector dyn_par_op_; - - /// arguments for the dynamic parameter operators - pod_vector dyn_par_arg_; - -// ---------------------- Public Functions ----------------------------------- -public: - /// Default constructor - recorder(void) : - num_var_rec_(0) , - num_dynamic_ind_(0) , - num_var_load_rec_(0) , - par_hash_table_( CPPAD_HASH_TABLE_SIZE ) - { record_compare_ = true; - abort_op_index_ = 0; - // It does not matter if unitialized hash codes match but this - // initilaization is here to avoid valgrind warnings. - void* ptr = static_cast( par_hash_table_.data() ); - int value = 0; - size_t num = CPPAD_HASH_TABLE_SIZE * sizeof(addr_t); - std::memset(ptr, value, num); - } - - /// Set record_compare option - void set_record_compare(bool record_compare) - { record_compare_ = record_compare; } - - /// Set the abort index - void set_abort_op_index(size_t abort_op_index) - { abort_op_index_ = abort_op_index; } - - /// Set number of independent dynamic parameters - void set_num_dynamic_ind(size_t num_dynamic_ind) - { num_dynamic_ind_ = num_dynamic_ind; } - - /// Get record_compare option - bool get_record_compare(void) const - { return record_compare_; } - - /// Get the abort_op_index - size_t get_abort_op_index(void) const - { return abort_op_index_; } - - /// Get number of independent dynamic parameters - size_t get_num_dynamic_ind(void) const - { return num_dynamic_ind_; } - - /// Destructor - ~recorder(void) - { } - - /// Put a dynamic parameter in all_par_vec_. - addr_t put_dyn_par( - const Base &par, op_code_dyn op - ); - addr_t put_dyn_par( - const Base &par, op_code_dyn op, addr_t arg0 - ); - addr_t put_dyn_par( - const Base &par, op_code_dyn op, addr_t arg0, addr_t arg1 - ); - addr_t put_dyn_cond_exp( - const Base &par, CompareOp cop, - addr_t left, addr_t right, addr_t if_true, addr_t if_false - ); - - /// Put a vector of dynamic parameter arguments at end of tape - void put_dyn_arg_vec(const pod_vector& arg); - - /// Put next operator in the operation sequence. - addr_t PutOp(OpCode op); - /// Put a vecad load operator in the operation sequence (special case) - addr_t PutLoadOp(OpCode op); - - // VecAD operations - addr_t put_var_vecad_ind(addr_t vec_ind); - addr_t put_var_vecad(size_t length, const pod_vector& taddr); - - /// Find or add a constant parameter to the vector of all parameters. - addr_t put_con_par(const Base &par); - /// Put one operation argument index in the recording - void PutArg(addr_t arg0); - /// Put two operation argument index in the recording - void PutArg(addr_t arg0, addr_t arg1); - /// Put three operation argument index in the recording - void PutArg(addr_t arg0, addr_t arg1, addr_t arg2); - /// Put four operation argument index in the recording - void PutArg(addr_t arg0, addr_t arg1, addr_t arg2, addr_t arg3); - /// Put five operation argument index in the recording - void PutArg(addr_t arg0, addr_t arg1, addr_t arg2, addr_t arg3, - addr_t arg4); - /// Put six operation argument index in the recording - void PutArg(addr_t arg0, addr_t arg1, addr_t arg2, addr_t arg3, - addr_t arg4, addr_t arg5); - // - // put_dyn_atomic - template - void put_dyn_atomic( - tape_id_t tape_id , - size_t atom_index , - const vector& type_x , - const vector& type_y , - const VectorAD& ax , - VectorAD& ay - ); - // - // put_var_atomic - template - void put_var_atomic( - tape_id_t tape_id , - size_t atom_index , - const vector& type_x , - const vector& type_y , - const VectorAD& ax , - VectorAD& ay - ); - - // Reserve space for a specified number of arguments - size_t ReserveArg(size_t n_arg); - - // Replace an argument value - void ReplaceArg(size_t i_arg, addr_t value); - - /// Put a character string in the text for this recording. - addr_t PutTxt(const char *text); - - /// record a variable or dynamic parameter conditional expression - void cond_exp( - tape_id_t tape_id , - enum CompareOp cop , - AD &result , - const AD &left , - const AD &right , - const AD &if_true , - const AD &if_false - ); - - /// record a comparison operators for varialbes or just dynamic parameters - void comp_eq( - bool var_left , - bool var_right , - bool dyn_left , - bool dyn_right , - const AD& aleft , - const AD& aright , - bool result - ); - void comp_le( - bool var_left , - bool var_right , - bool dyn_left , - bool dyn_right , - const AD& aleft , - const AD& aright , - bool result - ); - void comp_lt( - bool var_left , - bool var_right , - bool dyn_left , - bool dyn_right , - const AD& aleft , - const AD& aright , - bool result - ); - - // ----------------------------------------------------------------------- - // functions implemented here - - /// Number of variables currently stored in the recording. - size_t num_var_rec(void) const - { return num_var_rec_; } - - /// Number LdpOp, LdvOp, and load_dyn operations currently in recording - size_t num_var_load_rec(void) const - { return num_var_load_rec_; } - - /// Number of operators currently stored in the recording. - size_t num_op_rec(void) const - { return op_vec_.size(); } - - /// current parameter vector - const pod_vector_maybe& all_par_vec(void) const - { return all_par_vec_; } - - /// Approximate amount of memory used by the recording - size_t Memory(void) const - { return op_vec_.capacity() * sizeof(opcode_t) - + all_dyn_vecad_ind_.capacity() * sizeof(addr_t) - + all_var_vecad_ind_.capacity() * sizeof(addr_t) - + arg_vec_.capacity() * sizeof(addr_t) - + all_par_vec_.capacity() * sizeof(Base) - + text_vec_.capacity() * sizeof(char); - } - -}; - -/*! -Put next operator in the operation sequence. - -This sets the op code for the next operation in this recording. -This call must be followed by putting the corresponding -\verbatim - NumArg(op) -\endverbatim -argument indices in the recording. - -\param op -Is the op code corresponding to the the operation that is being -recorded (which must not be LdpOp or LdvOp). - -\return -The return value is the index of the primary (last) variable -corresponding to the result of this operation. -The number of variables corresponding to the operation is given by -\verbatim - NumRes(op) -\endverbatim -With each call to PutOp or PutLoadOp, -the return index increases by the number of variables corresponding -to the call. -This index starts at zero after the default constructor. -*/ -template -addr_t recorder::PutOp(OpCode op) -{ size_t i = op_vec_.extend(1); - CPPAD_ASSERT_KNOWN( - (abort_op_index_ == 0) || (abort_op_index_ != i), - "Operator index equals abort_op_index in Independent" - ); - op_vec_[i] = static_cast(op); - CPPAD_ASSERT_UNKNOWN( op_vec_.size() == i + 1 ); - CPPAD_ASSERT_UNKNOWN( (op != LdpOp) & (op != LdvOp) ); - - // first operator should be a BeginOp and NumRes( BeginOp ) > 0 - num_var_rec_ += NumRes(op); - CPPAD_ASSERT_UNKNOWN( num_var_rec_ > 0 ); - - // index of last variable corresponding to this operation - // (if NumRes(op) > 0) - CPPAD_ASSERT_KNOWN( - (size_t) std::numeric_limits::max() >= num_var_rec_ - 1, - "cppad_tape_addr_type maximum value has been exceeded" - ) - - return static_cast( num_var_rec_ - 1 ); -} - -/*! -Put next LdpOp or LdvOp operator in operation sequence (special cases). - -This sets the op code for the next operation in this recording. -This call must be followed by putting the corresponding -\verbatim - NumArg(op) -\endverbatim -argument indices in the recording. - -\param op -Is the op code corresponding to the the operation that is being -recorded (which must be LdpOp or LdvOp). - -\return -The return value is the index of the primary (last) variable -corresponding to the result of this operation. -The number of variables corresponding to the operation is given by -\verbatim - NumRes(op) -\endverbatim -which must be one for this operation. -With each call to PutLoadOp or PutOp, -the return index increases by the number of variables corresponding -to this call to the call. -This index starts at zero after the default constructor. - -\par num_var_load_rec() -The return value for num_var_load_rec() -increases by one after each call to this function. -*/ -template -addr_t recorder::PutLoadOp(OpCode op) -{ size_t i = op_vec_.extend(1); - CPPAD_ASSERT_KNOWN( - (abort_op_index_ == 0) || (abort_op_index_ != i), - "This is the abort operator index specified by " - "Independent(x, abort_op_index)." - ); - op_vec_[i] = op; - CPPAD_ASSERT_UNKNOWN( op_vec_.size() == i + 1 ); - CPPAD_ASSERT_UNKNOWN( (op == LdpOp) | (op == LdvOp) ); - - // first operator should be a BeginOp and NumRes( BeginOp ) > 0 - num_var_rec_ += NumRes(op); - CPPAD_ASSERT_UNKNOWN( num_var_rec_ > 0 ); - - // count this vecad load operation - num_var_load_rec_++; - - // index of last variable corresponding to this operation - // (if NumRes(op) > 0) - CPPAD_ASSERT_KNOWN( - (size_t) std::numeric_limits::max() >= num_var_rec_ - 1, - "cppad_tape_addr_type maximum value has been exceeded" - ) - return static_cast( num_var_rec_ - 1 ); -} - -/*! -Put a dynamic parameter at the end of the vector for all parameters. - -\param par -is value of dynamic parameter to be placed at the end of the vector. - -\param op -is the operator for this dynamic parameter. -There are no arguments to this operator, so numarg(op) == 0. - -\return -is the index in all_par_vec_ corresponding to this dynamic parameter value. -*/ -template -addr_t recorder::put_dyn_par(const Base &par, op_code_dyn op) -{ // independent parameters come first - CPPAD_ASSERT_UNKNOWN( - op == ind_dyn || op == result_dyn || op == atom_dyn - ); - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 0 ); - all_par_vec_.push_back( par ); - dyn_par_is_.push_back(true); - dyn_par_op_.push_back( opcode_t(op) ); - return static_cast( all_par_vec_.size() - 1 ); -} -/*! -Put a dynamic parameter at the end of the vector for all parameters. - -\param par -is value of dynamic parameter to be placed at the end of the vector. - -\param op -is the operator for this dynamic parameter. -There is one argument to this operator, so numarg(op) == 1. - -\param arg0 -this is the argument to the operator represented -as an index in the all_par_vec_ vector. - -\return -is the index in all_par_vec_ corresponding to this dynamic parameter value. -*/ -template -addr_t recorder::put_dyn_par( - const Base &par, op_code_dyn op, addr_t arg0 -) -{ // independent parameters come first - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 1 ); - all_par_vec_.push_back( par ); - dyn_par_is_.push_back(true); - dyn_par_op_.push_back( opcode_t(op) ); - dyn_par_arg_.push_back(arg0); - return static_cast( all_par_vec_.size() - 1 ); -} -/*! -Put a dynamic parameter at the end of the vector for all parameters. - -\param par -is value of dynamic parameter to be placed at the end of the vector. - -\param op -is the operator for this dynamic parameter. -There are two arguments to this operator, so numarg(op) == 2. - -\param arg0 -this is the first argument to the operator represented -as an index in the all_par_vec_ vector. - -\param arg1 -this is the second argument to the operator represented -as an index in the all_par_vec_ vector. -One of the two arguments must be a dynamic parameter. - -\return -is the index in all_par_vec_ corresponding to this dynamic parameter value. -*/ -template -addr_t recorder::put_dyn_par( - const Base &par, op_code_dyn op, addr_t arg0, addr_t arg1 -) -{ // independent parameters come first - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 2 ); - all_par_vec_.push_back( par ); - dyn_par_is_.push_back(true); - dyn_par_op_.push_back( opcode_t(op) ); - dyn_par_arg_.push_back(arg0); - dyn_par_arg_.push_back(arg1); - return static_cast( all_par_vec_.size() - 1 ); -} -/*! -Put a dynamic parameter, that is result of conditional expression, -at the end of the vector for all parameters. - -\param par -is value of dynamic parameter to be placed at the end of the vector. - -\param cop -is the operator comparison operator; i.e., Lt, Le, Eq, Ge, Gt, Ne. - -\param left -is the left argument in conditional expression (which is a parameter). - -\param right -is the right argument in conditional expression (which is a parameter). - -\param if_true -is the if_true argument in conditional expression (which is a parameter). - -\param if_false -is the if_false argument in conditional expression (which is a parameter). - -\return -is the index in all_par_vec_ corresponding to this dynamic parameter value. -*/ -template -addr_t recorder::put_dyn_cond_exp(const Base &par, CompareOp cop, - addr_t left, addr_t right, addr_t if_true, addr_t if_false -) -{ // independent parameters come first - CPPAD_ASSERT_UNKNOWN( num_arg_dyn(cond_exp_dyn) == 5 ); - addr_t ret = addr_t( all_par_vec_.size() ); - all_par_vec_.push_back( par ); - dyn_par_is_.push_back(true); - dyn_par_op_.push_back( opcode_t(cond_exp_dyn) ); - dyn_par_arg_.push_back( addr_t(cop) ); - dyn_par_arg_.push_back(left); - dyn_par_arg_.push_back(right); - dyn_par_arg_.push_back(if_true); - dyn_par_arg_.push_back(if_false); - return ret; -} -// --------------------------------------------------------------------------- -/*! -Puts a vector of arguments at the end of the current dynamic parameter tape - -\param arg_vec [in] -is the vector of values to be added at the end of the tape. -*/ -template -void recorder::put_dyn_arg_vec(const pod_vector& arg_vec) -{ for(size_t i = 0; i < arg_vec.size(); ++i) - dyn_par_arg_.push_back( arg_vec[i] ); -} - -// --------------------------------------------------------------------------- -/*! -Find or add a constant parameter to the current vector of all parameters. - -\param par -is the parameter to be found or placed in the vector of parameters. - -\return -is the index in the parameter vector corresponding to this parameter value. -This value is not necessarily placed at the end of the vector -(because values that are identically equal may be reused). -*/ -template -addr_t recorder::put_con_par(const Base &par) -{ -# ifndef NDEBUG - // index zero is used to signify that a value is not a parameter; - // i.e., it is a variable. - if( all_par_vec_.size() == 0 ) - CPPAD_ASSERT_UNKNOWN( isnan(par) ); -# endif - // --------------------------------------------------------------------- - // check for a match with a previous parameter - // - // get hash code for this value - size_t code = static_cast( hash_code(par) ); - - // current index in all_par_vec_ corresponding to this hash code - size_t index = static_cast( par_hash_table_[code] ); - - // check if the old parameter matches the new one - if( (0 < index) & (index < all_par_vec_.size()) ) - { if( ! dyn_par_is_[index] ) - if( IdenticalEqualCon(all_par_vec_[index], par) ) - return static_cast( index ); - } - // --------------------------------------------------------------------- - // put paramerter in all_par_vec_ and replace hash entry for this codee - // - index = all_par_vec_.size(); - all_par_vec_.push_back( par ); - dyn_par_is_.push_back(false); - // - // change the hash table for this code to point to new value - par_hash_table_[code] = static_cast( index ); - // - // return the parameter index - CPPAD_ASSERT_KNOWN( - static_cast( std::numeric_limits::max() ) >= index, - "cppad_tape_addr_type maximum value has been exceeded" - ) - return static_cast( index ); -} -// -------------------------- PutArg -------------------------------------- -/*! -Prototype for putting operation argument indices in the recording. - -The following syntax -\verbatim - rec.PutArg(arg0) - rec.PutArg(arg0, arg1) - . - . - . - rec.PutArg(arg0, arg1, ..., arg5) -\endverbatim -places the values passed to PutArg at the current end of the -operation argument indices for the recording. - arg0 comes before arg1, etc. -The proper number of operation argument indices -corresponding to the operation code op is given by -\verbatim - NumArg(op) -\endverbatim -The number of the operation argument indices starts at zero -after the default constructor. -*/ -inline void prototype_put_arg(void) -{ // This routine should not be called - CPPAD_ASSERT_UNKNOWN(false); -} -/*! -Put one operation argument index in the recording - -\param arg0 -The operation argument index - -\copydetails prototype_put_arg -*/ -template -void recorder::PutArg(addr_t arg0) -{ - size_t i = arg_vec_.extend(1); - arg_vec_[i] = arg0; - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == i + 1 ); -} -/*! -Put two operation argument index in the recording - -\param arg0 -First operation argument index. - -\param arg1 -Second operation argument index. - -\copydetails prototype_put_arg -*/ -template -void recorder::PutArg(addr_t arg0, addr_t arg1) -{ - size_t i = arg_vec_.extend(2); - arg_vec_[i++] = arg0; - arg_vec_[i] = arg1; - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == i + 1 ); -} -/*! -Put three operation argument index in the recording - -\param arg0 -First operation argument index. - -\param arg1 -Second operation argument index. - -\param arg2 -Third operation argument index. - -\copydetails prototype_put_arg -*/ -template -void recorder::PutArg(addr_t arg0, addr_t arg1, addr_t arg2) -{ - size_t i = arg_vec_.extend(3); - arg_vec_[i++] = arg0; - arg_vec_[i++] = arg1; - arg_vec_[i] = arg2; - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == i + 1 ); -} -/*! -Put four operation argument index in the recording - -\param arg0 -First operation argument index. - -\param arg1 -Second operation argument index. - -\param arg2 -Third operation argument index. - -\param arg3 -Fourth operation argument index. - -\copydetails prototype_put_arg -*/ -template -void recorder::PutArg(addr_t arg0, addr_t arg1, addr_t arg2, - addr_t arg3) -{ - size_t i = arg_vec_.extend(4); - arg_vec_[i++] = arg0; - arg_vec_[i++] = arg1; - arg_vec_[i++] = arg2; - arg_vec_[i] = arg3; - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == i + 1 ); - -} -/*! -Put five operation argument index in the recording - -\param arg0 -First operation argument index. - -\param arg1 -Second operation argument index. - -\param arg2 -Third operation argument index. - -\param arg3 -Fourth operation argument index. - -\param arg4 -Fifth operation argument index. - -\copydetails prototype_put_arg -*/ -template -void recorder::PutArg(addr_t arg0, addr_t arg1, addr_t arg2, - addr_t arg3, addr_t arg4) -{ - size_t i = arg_vec_.extend(5); - arg_vec_[i++] = arg0; - arg_vec_[i++] = arg1; - arg_vec_[i++] = arg2; - arg_vec_[i++] = arg3; - arg_vec_[i] = arg4; - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == i + 1 ); - -} -/*! -Put six operation argument index in the recording - -\param arg0 -First operation argument index. - -\param arg1 -Second operation argument index. - -\param arg2 -Third operation argument index. - -\param arg3 -Fourth operation argument index. - -\param arg4 -Fifth operation argument index. - -\param arg5 -Sixth operation argument index. - -\copydetails prototype_put_arg -*/ -template -void recorder::PutArg(addr_t arg0, addr_t arg1, addr_t arg2, - addr_t arg3, addr_t arg4, addr_t arg5) -{ - size_t i = arg_vec_.extend(6); - arg_vec_[i++] = arg0; - arg_vec_[i++] = arg1; - arg_vec_[i++] = arg2; - arg_vec_[i++] = arg3; - arg_vec_[i++] = arg4; - arg_vec_[i] = arg5; - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == i + 1 ); -} -// -------------------------------------------------------------------------- -/*! -Reserve space for arguments, but delay placing values there. - -\param n_arg -number of arguements to reserve space for - -\return -is the index in the argument vector corresponding to the -first of the arguments being reserved. -*/ -template -size_t recorder::ReserveArg(size_t n_arg) -{ - size_t i = arg_vec_.extend(n_arg); - CPPAD_ASSERT_UNKNOWN( arg_vec_.size() == i + n_arg ); - return i; -} - -/*! -\brief -Replace an argument value in the recording -(intended to fill in reserved values). - -\param i_arg -is the index, in argument vector, for the value that is replaced. - -\param value -is the new value for the argument with the specified index. -*/ -template -void recorder::ReplaceArg(size_t i_arg, addr_t value) -{ arg_vec_[i_arg] = value; } -// -------------------------------------------------------------------------- -/*! -Put a character string in the text for this recording. - -\param text -is a '\\0' terminated character string that is to be put in the -vector of characters corresponding to this recording. -The terminator '\\0' will be included. - -\return -is the offset with in the text vector for this recording at which -the character string starts. -*/ -template -addr_t recorder::PutTxt(const char *text) -{ - // determine length of the text including terminating '\0' - size_t n = 0; - while( text[n] != '\0' ) - n++; - CPPAD_ASSERT_UNKNOWN( n <= 1000 ); - n++; - CPPAD_ASSERT_UNKNOWN( text[n-1] == '\0' ); - - // copy text including terminating '\0' - size_t i = text_vec_.extend(n); - size_t j; - for(j = 0; j < n; j++) - text_vec_[i + j] = text[j]; - CPPAD_ASSERT_UNKNOWN( text_vec_.size() == i + n ); - - CPPAD_ASSERT_KNOWN( - size_t( std::numeric_limits::max() ) >= i, - "cppad_tape_addr_type maximum value has been exceeded" - ); - // - return static_cast( i ); -} - -} } // END_CPPAD_LOCAL_NAMESPACE - -// ---------------------------------------------------------------------------- -// member function implementations -# include -# include -# include -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/local/record/recorder.omh b/build-config/cppad/include/cppad/local/record/recorder.omh deleted file mode 100644 index 8d954259..00000000 --- a/build-config/cppad/include/cppad/local/record/recorder.omh +++ /dev/null @@ -1,25 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------ -$begin recorder$$ - -$section Recorder Class Documentation$$ - -$childtable% - include/cppad/local/record/put_var_vecad.hpp% - include/cppad/local/record/put_dyn_atomic.hpp% - include/cppad/local/record/put_var_atomic.hpp% - include/cppad/local/record/cond_exp.hpp% - include/cppad/local/record/comp_op.hpp -%$$ - - -$end diff --git a/build-config/cppad/include/cppad/local/set_get_in_parallel.hpp b/build-config/cppad/include/cppad/local/set_get_in_parallel.hpp deleted file mode 100644 index c7932964..00000000 --- a/build-config/cppad/include/cppad/local/set_get_in_parallel.hpp +++ /dev/null @@ -1,66 +0,0 @@ -# ifndef CPPAD_LOCAL_SET_GET_IN_PARALLEL_HPP -# define CPPAD_LOCAL_SET_GET_IN_PARALLEL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE - -/*! -\file set_get_in_parallel.hpp -File used to set and get user in_parallel routine. -*/ -/*! -Set and call the routine that determine if we are in parallel execution mode. - -\return -value retuned by most recent setting for in_parallel_new. -If set is true, -or the most recent setting is nullptr (its initial value), -the return value is false. -Otherwise the function corresponding to the most recent setting -is called and its value returned by set_get_in_parallel. - -\param in_parallel_new [in] -If set is false, in_parallel_new it is not used. -Otherwise, the current value of in_parallel_new becomes the -most recent setting for in_parallel_user. - -\param set -If set is true, then parallel_new is becomes the most -recent setting for this set_get_in_parallel. -In this case, it is assumed that we are currently in sequential execution mode. -*/ -static bool set_get_in_parallel( - bool (*in_parallel_new)(void) , - bool set = false ) -{ static bool (*in_parallel_user)(void) = nullptr; - - if( set ) - { in_parallel_user = in_parallel_new; - // Doing a raw assert in this case because set_get_in_parallel is used - // by ErrorHandler and hence cannot use ErrorHandler. - // CPPAD_ASSERT_UNKNOWN( in_parallel_user() == false ) - assert(in_parallel_user == nullptr || in_parallel_user() == false); - return false; - } - // - if( in_parallel_user == nullptr ) - return false; - // - return in_parallel_user(); -} - -} } // END_CPPAD_LOCAL_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sign_op.hpp b/build-config/cppad/include/cppad/local/sign_op.hpp deleted file mode 100644 index 2906b51d..00000000 --- a/build-config/cppad/include/cppad/local/sign_op.hpp +++ /dev/null @@ -1,153 +0,0 @@ -# ifndef CPPAD_LOCAL_SIGN_OP_HPP -# define CPPAD_LOCAL_SIGN_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file sign_op.hpp -Forward and reverse mode calculations for z = sign(x). -*/ - -/*! -Compute forward mode Taylor coefficient for result of op = SignOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sign(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op -*/ -template -void forward_sign_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - if( p == 0 ) - { z[0] = sign(x[0]); - p++; - } - for(size_t j = p; j <= q; j++) - z[j] = Base(0.); -} -/*! -Multiple direction forward mode Taylor coefficient for op = SignOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sign(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_dir -*/ -template -void forward_sign_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q - 1) * r + 1; - Base* z = taylor + i_z * num_taylor_per_var; - - for(size_t ell = 0; ell < r; ell++) - z[m+ell] = Base(0.); -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = SignOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sign(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_0 -*/ -template -void forward_sign_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base x0 = *(taylor + i_x * cap_order); - Base* z = taylor + i_z * cap_order; - - z[0] = sign(x0); -} -/*! -Compute reverse mode partial derivatives for result of op = SignOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sign(x) -\endverbatim - -\copydetails CppAD::local::reverse_unary1_op -*/ - -template -void reverse_sign_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // nothing to do because partials of sign are zero - return; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sin_op.hpp b/build-config/cppad/include/cppad/local/sin_op.hpp deleted file mode 100644 index de3471c8..00000000 --- a/build-config/cppad/include/cppad/local/sin_op.hpp +++ /dev/null @@ -1,240 +0,0 @@ -# ifndef CPPAD_LOCAL_SIN_OP_HPP -# define CPPAD_LOCAL_SIN_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file sin_op.hpp -Forward and reverse mode calculations for z = sin(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = SinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sin(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_sin_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* s = taylor + i_z * cap_order; - Base* c = s - cap_order; - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op. - // (except that there is a sign difference for the hyperbolic case). - size_t k; - if( p == 0 ) - { s[0] = sin( x[0] ); - c[0] = cos( x[0] ); - p++; - } - for(size_t j = p; j <= q; j++) - { - s[j] = Base(0.0); - c[j] = Base(0.0); - for(k = 1; k <= j; k++) - { s[j] += Base(double(k)) * x[k] * c[j-k]; - c[j] -= Base(double(k)) * x[k] * s[j-k]; - } - s[j] /= Base(double(j)); - c[j] /= Base(double(j)); - } -} -/*! -Compute forward mode Taylor coefficient for result of op = SinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sin(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_sin_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* s = taylor + i_z * num_taylor_per_var; - Base* c = s - num_taylor_per_var; - - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op - // (except that there is a sign difference for the hyperbolic case). - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { s[m+ell] = Base(double(q)) * x[m + ell] * c[0]; - c[m+ell] = - Base(double(q)) * x[m + ell] * s[0]; - for(size_t k = 1; k < q; k++) - { s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell]; - c[m+ell] -= Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell]; - } - s[m+ell] /= Base(double(q)); - c[m+ell] /= Base(double(q)); - } -} - - -/*! -Compute zero order forward mode Taylor coefficient for result of op = SinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sin(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_sin_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* s = taylor + i_z * cap_order; // called z in documentation - Base* c = s - cap_order; // called y in documentation - - s[0] = sin( x[0] ); - c[0] = cos( x[0] ); -} - -/*! -Compute reverse mode partial derivatives for result of op = SinOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sin(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_sin_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* s = taylor + i_z * cap_order; // called z in doc - Base* ps = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* c = s - cap_order; // called y in documentation - Base* pc = ps - nc_partial; - - - // rest of this routine is identical for the following cases: - // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op. - size_t j = d; - size_t k; - while(j) - { - ps[j] /= Base(double(j)); - pc[j] /= Base(double(j)); - for(k = 1; k <= j; k++) - { - px[k] += Base(double(k)) * azmul(ps[j], c[j-k]); - px[k] -= Base(double(k)) * azmul(pc[j], s[j-k]); - - ps[j-k] -= Base(double(k)) * azmul(pc[j], x[k]); - pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]); - - } - --j; - } - px[0] += azmul(ps[0], c[0]); - px[0] -= azmul(pc[0], s[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sinh_op.hpp b/build-config/cppad/include/cppad/local/sinh_op.hpp deleted file mode 100644 index 9fd05568..00000000 --- a/build-config/cppad/include/cppad/local/sinh_op.hpp +++ /dev/null @@ -1,239 +0,0 @@ -# ifndef CPPAD_LOCAL_SINH_OP_HPP -# define CPPAD_LOCAL_SINH_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file sinh_op.hpp -Forward and reverse mode calculations for z = sinh(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = SinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sinh(x) -\endverbatim -The auxillary result is -\verbatim - y = cosh(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_sinh_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* s = taylor + i_z * cap_order; - Base* c = s - cap_order; - - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op - // (except that there is a sign difference for hyperbolic case). - size_t k; - if( p == 0 ) - { s[0] = sinh( x[0] ); - c[0] = cosh( x[0] ); - p++; - } - for(size_t j = p; j <= q; j++) - { - s[j] = Base(0.0); - c[j] = Base(0.0); - for(k = 1; k <= j; k++) - { s[j] += Base(double(k)) * x[k] * c[j-k]; - c[j] += Base(double(k)) * x[k] * s[j-k]; - } - s[j] /= Base(double(j)); - c[j] /= Base(double(j)); - } -} -/*! -Compute forward mode Taylor coefficient for result of op = SinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sinh(x) -\endverbatim -The auxillary result is -\verbatim - y = cosh(x) -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_sinh_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* s = taylor + i_z * num_taylor_per_var; - Base* c = s - num_taylor_per_var; - - - // rest of this routine is identical for the following cases: - // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op - // (except that there is a sign difference for the hyperbolic case). - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { s[m+ell] = Base(double(q)) * x[m + ell] * c[0]; - c[m+ell] = Base(double(q)) * x[m + ell] * s[0]; - for(size_t k = 1; k < q; k++) - { s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell]; - c[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell]; - } - s[m+ell] /= Base(double(q)); - c[m+ell] /= Base(double(q)); - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = SinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sinh(x) -\endverbatim -The auxillary result is -\verbatim - y = cosh(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_sinh_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* s = taylor + i_z * cap_order; // called z in documentation - Base* c = s - cap_order; // called y in documentation - - s[0] = sinh( x[0] ); - c[0] = cosh( x[0] ); -} -/*! -Compute reverse mode partial derivatives for result of op = SinhOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sinh(x) -\endverbatim -The auxillary result is -\verbatim - y = cosh(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_sinh_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* s = taylor + i_z * cap_order; // called z in doc - Base* ps = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* c = s - cap_order; // called y in documentation - Base* pc = ps - nc_partial; - - - // rest of this routine is identical for the following cases: - // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op. - size_t j = d; - size_t k; - while(j) - { - ps[j] /= Base(double(j)); - pc[j] /= Base(double(j)); - for(k = 1; k <= j; k++) - { - px[k] += Base(double(k)) * azmul(ps[j], c[j-k]); - px[k] += Base(double(k)) * azmul(pc[j], s[j-k]); - - ps[j-k] += Base(double(k)) * azmul(pc[j], x[k]); - pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]); - - } - --j; - } - px[0] += azmul(ps[0], c[0]); - px[0] += azmul(pc[0], s[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sparse/binary_op.hpp b/build-config/cppad/include/cppad/local/sparse/binary_op.hpp deleted file mode 100644 index 77cceef1..00000000 --- a/build-config/cppad/include/cppad/local/sparse/binary_op.hpp +++ /dev/null @@ -1,617 +0,0 @@ -# ifndef CPPAD_LOCAL_SPARSE_BINARY_OP_HPP -# define CPPAD_LOCAL_SPARSE_BINARY_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE -namespace CppAD { namespace local { namespace sparse { -// END_DECLARE_NAMESPACE - -/*! -\file sparse_binary_op.hpp -Forward and reverse mode sparsity patterns for binary operators. -*/ - - -/*! -Forward mode Jacobian sparsity pattern for all binary operators. - -The C++ source code corresponding to a binary operation has the form -\verbatim - z = fun(x, y) -\endverbatim -where fun is a C++ binary function and both x and y are variables, -or it has the form -\verbatim - z = x op y -\endverbatim -where op is a C++ binary unary operator and both x and y are variables. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e., z. - -\param arg - arg[0] -variable index corresponding to the left operand for this operator; -i.e., x. -\n -\n arg[1] -variable index corresponding to the right operand for this operator; -i.e., y. - -\param sparsity -\b Input: -The set with index arg[0] in sparsity -is the sparsity bit pattern for x. -This identifies which of the independent variables the variable x -depends on. -\n -\n -\b Input: -The set with index arg[1] in sparsity -is the sparsity bit pattern for y. -This identifies which of the independent variables the variable y -depends on. -\n -\n -\b Output: -The set with index i_z in sparsity -is the sparsity bit pattern for z. -This identifies which of the independent variables the variable z -depends on. - -\par Checked Assertions: -\li arg[0] < i_z -\li arg[1] < i_z -*/ - -template -void for_jac_binary_op( - size_t i_z , - const addr_t* arg , - Vector_set& sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); - - sparsity.binary_union(i_z, size_t(arg[0]), size_t(arg[1]), sparsity); - - return; -} - -/*! -Reverse mode Jacobian sparsity pattern for all binary operators. - -The C++ source code corresponding to a unary operation has the form -\verbatim - z = fun(x, y) -\endverbatim -where fun is a C++ unary function and x and y are variables, -or it has the form -\verbatim - z = x op y -\endverbatim -where op is a C++ bianry operator and x and y are variables. - -This routine is given the sparsity patterns -for a function G(z, y, x, ... ) -and it uses them to compute the sparsity patterns for -\verbatim - H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ] -\endverbatim - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e., z. - -\param arg - arg[0] -variable index corresponding to the left operand for this operator; -i.e., x. - -\n -\n arg[1] -variable index corresponding to the right operand for this operator; -i.e., y. - -\param sparsity -The set with index i_z in sparsity -is the sparsity pattern for z corresponding ot the function G. -\n -\n -The set with index arg[0] in sparsity -is the sparsity pattern for x. -On input, it corresponds to the function G, -and on output it corresponds to H. -\n -\n -The set with index arg[1] in sparsity -is the sparsity pattern for y. -On input, it corresponds to the function G, -and on output it corresponds to H. -\n -\n - -\par Checked Assertions: -\li arg[0] < i_z -\li arg[1] < i_z -*/ -template -void rev_jac_binary_op( - size_t i_z , - const addr_t* arg , - Vector_set& sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); - - sparsity.binary_union( size_t(arg[0]), size_t(arg[0]), i_z, sparsity); - sparsity.binary_union( size_t(arg[1]), size_t(arg[1]), i_z, sparsity); - - return; -} -// --------------------------------------------------------------------------- -/*! -Reverse mode Hessian sparsity pattern for add and subtract operators. - -The C++ source code corresponding to a unary operation has the form -\verbatim - z = x op y -\endverbatim -where op is + or - and x, y are variables. - -\copydetails CppAD::local::reverse_sparse_hessian_binary_op -*/ -template -void rev_hes_addsub_op( - size_t i_z , - const addr_t* arg , - bool* jac_reverse , - const Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); - - // check for no effect - if( ! jac_reverse[i_z] ) - return; - - // propagate hessian sparsity from i_z to arg[0] and arg[1] - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity - ); - - jac_reverse[arg[0]] = true; - jac_reverse[arg[1]] = true; - - return; -} - -/*! -Reverse mode Hessian sparsity pattern for multiplication operator. - -The C++ source code corresponding to a unary operation has the form -\verbatim - z = x * y -\endverbatim -where x and y are variables. - -\copydetails CppAD::local::reverse_sparse_hessian_binary_op -*/ -template -void rev_hes_mul_op( - size_t i_z , - const addr_t* arg , - bool* jac_reverse , - const Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); - - // check for no effect - if( ! jac_reverse[i_z] ) - return; - - // progagate hessian sparsity from i_z to arg[0] and arg[1] - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity - ); - - // new hessian sparsity terms between i_z and arg[0], arg[1] - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), size_t(arg[1]), for_jac_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), size_t(arg[0]), for_jac_sparsity - ); - - jac_reverse[arg[0]] = true; - jac_reverse[arg[1]] = true; - return; -} - -/*! -Reverse mode Hessian sparsity pattern for division operator. - -The C++ source code corresponding to a unary operation has the form -\verbatim - z = x / y -\endverbatim -where x and y are variables. - -\copydetails CppAD::local::reverse_sparse_hessian_binary_op -*/ -template -void rev_hes_div_op( - size_t i_z , - const addr_t* arg , - bool* jac_reverse , - const Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); - - // check for no effect - if( ! jac_reverse[i_z] ) - return; - - // propagate hessian sparsity from i_z to arg[0] and arg[1] - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity - ); - - // new hessian sparsity terms between i_z and arg[0], arg[1] - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), size_t(arg[1]), for_jac_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), size_t(arg[0]), for_jac_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), size_t(arg[1]), for_jac_sparsity - ); - - jac_reverse[arg[0]] = true; - jac_reverse[arg[1]] = true; - return; -} - -/*! -Reverse mode Hessian sparsity pattern for power function. - -The C++ source code corresponding to a unary operation has the form -\verbatim - z = pow(x, y) -\endverbatim -where x and y are variables. - -\copydetails CppAD::local::reverse_sparse_hessian_binary_op -*/ -template -void rev_hes_pow_op( - size_t i_z , - const addr_t* arg , - bool* jac_reverse , - const Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z ); - - // check for no effect - if( ! jac_reverse[i_z] ) - return; - - // propigate hessian sparsity from i_z to arg[0] and arg[1] - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity - ); - - // new hessian sparsity terms between i_z and arg[0], arg[1] - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), size_t(arg[0]), for_jac_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[0]), size_t(arg[0]), size_t(arg[1]), for_jac_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), size_t(arg[0]), for_jac_sparsity - ); - rev_hes_sparsity.binary_union( - size_t(arg[1]), size_t(arg[1]), size_t(arg[1]), for_jac_sparsity - ); - - // I cannot think of a case where this is necessary, but it including - // it makes it like the other cases. - jac_reverse[arg[0]] = true; - jac_reverse[arg[1]] = true; - return; -} -// --------------------------------------------------------------------------- -/* -$begin sparse_for_hes_nl_binary_op$$ -$spell - hes - div - op - np - numvar - Jacobian - arg - mul - Namespace -$$ - -$section Forward Hessian Sparsity for Nonlinear Binary Operators$$ - -$head Namespace$$ -$srcthisfile% - 0%// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE%// END_DECLARE_NAMESPACE%0 -%$$ - -$head for_hes_mul_op$$ - -$subhead Syntax$$ -$codei%for_hes_mul_op(%i_v%, %np1%, %numvar%, %for_sparsity%)%$$ - -$subhead Prototype$$ -$srcthisfile% - 0%// BEGIN_for_hes_mul_op%// END_for_hes_mul_op%1 -%$$ - -$head for_hes_div_op$$ - -$subhead Syntax$$ -$codei%for_hes_div_op(%i_v%, %np1%, %numvar%, %for_sparsity%)%$$ - -$subhead Prototype$$ -$srcthisfile% - 0%// BEGIN_for_hes_div_op%// END_for_hes_div_op%1 -%$$ - -$head for_hes_pow_op$$ - -$subhead Syntax$$ -$codei%for_hes_pow_op(%i_v%, %np1%, %numvar%, %for_sparsity%)%$$ - -$subhead Prototype$$ -$srcthisfile% - 0%// BEGIN_for_hes_pow_op%// END_for_hes_pow_op%1 -%$$ - -$head C++ Source$$ -The C++ source code corresponding to this operation is -$codei% - %w% = %v0% * %v1% - %w% = %v0% / %v1% - %w% = pow(%v0% , %v1%) -%$$ - -$head np1$$ -This is the number of independent variables plus one; -i.e. size of $icode x$$ plus one. - -$head numvar$$ -This is the total number of variables in the tape. - -$head i_w$$ -is the index of the variable corresponding to the result $icode w$$. - -$head arg$$ -is the index of the argument vector for the nonlinear binary operation; i.e., -$icode%arg%[0]%$$, $icode%arg%[1]%$$ are the left and right operands; i.e., -corresponding to $icode v0$$, $icode v1$$. - -$head for_sparsity$$ -We have the conditions $icode%np1% = %for_sparsity%.end()%$$ -and $icode%for_sparsity%.n_set() = %np1% + %numvar%$$. - -$subhead Input Jacobian Sparsity$$ -For $icode%i%= 0, ..., %i_w%-1%$$, -the $icode%np1%+%i%$$ row of $icode for_sparsity$$ is the Jacobian sparsity -for the $th i$$ variable. These values do not change. -Note that $icode%i%=0%$$ corresponds to a parameter and -the corresponding Jacobian sparsity is empty. - -$subhead Input Hessian Sparsity$$ -For $icode%j%=1, ..., %n%$$, -the $th j$$ row of $icode for_sparsity$$ is the Hessian sparsity -before including the function $latex w(x)$$. - -$subhead Output Jacobian Sparsity$$ -the $icode i_w$$ row of $icode for_sparsity$$ is the Jacobian sparsity -for the variable $icode w$$. - -$subhead Output Hessian Sparsity$$ -For $icode%j%=1, ..., %n%$$, -the $th j$$ row of $icode for_sparsity$$ is the Hessian sparsity -after including the function $latex w(x)$$. - -$end -*/ -// BEGIN_for_hes_mul_op -template -void for_hes_mul_op( - size_t np1 , - size_t numvar , - size_t i_w , - const addr_t* arg , - Vector_set& for_sparsity ) -// END_for_hes_mul_op -{ // - CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar ); - // - size_t i_v0 = size_t(arg[0]); - size_t i_v1 = size_t(arg[1]); - CPPAD_ASSERT_UNKNOWN( i_v0 < i_w ); - CPPAD_ASSERT_UNKNOWN( i_v1 < i_w ); - CPPAD_ASSERT_UNKNOWN( i_w < numvar ); - - // set Jacobian sparsity J(i_w) - for_sparsity.binary_union(np1 + i_w, np1 + i_v0, np1 + i_v1, for_sparsity); - - // -------------------------------------------------- - // set of independent variables that v0 depends on - typename Vector_set::const_iterator itr_0(for_sparsity, i_v0 + np1); - - // loop over independent variables non-zero partial for v0 - size_t i_x = *itr_0; - while( i_x < np1 ) - { // N(i_x) = N(i_x) union J(v1) - for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity); - i_x = *(++itr_0); - } - // -------------------------------------------------- - // set of independent variables that v1 depends on - typename Vector_set::const_iterator itr_1(for_sparsity, i_v1 + np1); - - // loop over independent variables with non-zero partial for v1 - i_x = *itr_1; - while( i_x < np1 ) - { // N(i_x) = N(i_x) union J(v0) - for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity); - i_x = *(++itr_1); - } - return; -} -// BEGIN_for_hes_div_op -template -void for_hes_div_op( - size_t np1 , - size_t numvar , - size_t i_w , - const addr_t* arg , - Vector_set& for_sparsity ) -// END_for_hes_div_op -{ // - CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar ); - // - size_t i_v0 = size_t(arg[0]); - size_t i_v1 = size_t(arg[1]); - CPPAD_ASSERT_UNKNOWN( i_v0 < i_w ); - CPPAD_ASSERT_UNKNOWN( i_v1 < i_w ); - CPPAD_ASSERT_UNKNOWN( i_w < numvar ); - - // set Jacobian sparsity J(i_w) - for_sparsity.binary_union(np1 + i_w, np1 + i_v0, np1 + i_v1, for_sparsity); - - // -------------------------------------------------- - // set of independent variables that v0 depends on - typename Vector_set::const_iterator itr_0(for_sparsity, i_v0 + np1); - - // loop over independent variables non-zero partial for v0 - size_t i_x = *itr_0; - while( i_x < np1 ) - { // N(i_x) = N(i_x) union J(v1) - for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity); - i_x = *(++itr_0); - } - // -------------------------------------------------- - // set of independent variables that v1 depends on - typename Vector_set::const_iterator itr_1(for_sparsity, i_v1 + np1); - - // loop over independent variables with non-zero partial for v1 - i_x = *itr_1; - while( i_x < np1 ) - { // N(i_x) = N(i_x) union J(v0) - for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity); - // N(i_x) = N(i_x) union J(v1) - for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity); - i_x = *(++itr_1); - } - return; -} -// BEGIN_for_hes_pow_op -template -void for_hes_pow_op( - size_t np1 , - size_t numvar , - size_t i_w , - const addr_t* arg , - Vector_set& for_sparsity ) -// END_for_hes_pow_op -{ // - CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar ); - // - size_t i_v0 = size_t(arg[0]); - size_t i_v1 = size_t(arg[1]); - CPPAD_ASSERT_UNKNOWN( i_v0 < i_w ); - CPPAD_ASSERT_UNKNOWN( i_v1 < i_w ); - CPPAD_ASSERT_UNKNOWN( i_w < numvar ); - - // set Jacobian sparsity J(i_w) - for_sparsity.binary_union(np1 + i_w, np1 + i_v0, np1 + i_v1, for_sparsity); - - // -------------------------------------------------- - // set of independent variables that v0 depends on - typename Vector_set::const_iterator itr_0(for_sparsity, i_v0 + np1); - - // loop over independent variables non-zero partial for v0 - size_t i_x = *itr_0; - while( i_x < np1 ) - { // N(i_x) = N(i_x) union J(v0) - for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity); - // N(i_x) = N(i_x) union J(v1) - for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity); - i_x = *(++itr_0); - } - // -------------------------------------------------- - // set of independent variables that v1 depends on - typename Vector_set::const_iterator itr_1(for_sparsity, i_v1 + np1); - - // loop over independent variables with non-zero partial for v1 - i_x = *itr_1; - while( i_x < np1 ) - { // N(i_x) = N(i_x) union J(v0) - for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity); - // N(i_x) = N(i_x) union J(v1) - for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity); - i_x = *(++itr_1); - } - return; -} -// --------------------------------------------------------------------------- -} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sparse/dev_sparse.omh b/build-config/cppad/include/cppad/local/sparse/dev_sparse.omh deleted file mode 100644 index f2a26c1f..00000000 --- a/build-config/cppad/include/cppad/local/sparse/dev_sparse.omh +++ /dev/null @@ -1,23 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------ -$begin dev_sparse$$ - -$section Developer Sparse Documentation$$ - -$childtable% - include/cppad/local/sparse/unary_op.hpp% - include/cppad/local/sparse/binary_op.hpp% - include/cppad/local/sparse/setvector.omh -%$$ - - -$end diff --git a/build-config/cppad/include/cppad/local/sparse/internal.hpp b/build-config/cppad/include/cppad/local/sparse/internal.hpp deleted file mode 100644 index e76c919a..00000000 --- a/build-config/cppad/include/cppad/local/sparse/internal.hpp +++ /dev/null @@ -1,455 +0,0 @@ -# ifndef CPPAD_LOCAL_SPARSE_INTERNAL_HPP -# define CPPAD_LOCAL_SPARSE_INTERNAL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// necessary definitions -# include -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE -namespace CppAD { namespace local { namespace sparse { - -/*! -\file sparse_internal.hpp -Routines that enable code to be independent of which internal spasity pattern -is used. -*/ -// --------------------------------------------------------------------------- -/*! -Template structure used obtain the internal sparsity pattern type -form the corresponding element type. -The general form is not valid, must use a specialization. - -\tparam Element_type -type of an element in the sparsity structrue. - -\par internal_pattern::pattern_type -is the type of the corresponding internal sparsity pattern. -*/ -template struct internal_pattern; -/// Specilization for bool elements. -template <> -struct internal_pattern -{ - typedef sparse::pack_setvec pattern_type; -}; -/// Specilization for std::set elements. -template <> -struct internal_pattern< std::set > -{ - typedef list_setvec pattern_type; -}; -// --------------------------------------------------------------------------- -/*! -Update the internal sparsity pattern for a sub-set of rows - -\tparam SizeVector -The type used for index sparsity patterns. This is a simple vector -with elements of type size_t. - -\tparam InternalSparsitiy -The type used for intenal sparsity patterns. This can be either -sparse::pack_setvec or list_setvec. - -\param zero_empty -If this is true, the internal sparstity pattern corresponds to row zero -must be empty on input and will be emtpy output; i.e., any corresponding -values in pattern_in will be ignored. - -\param input_empty -If this is true, the initial sparsity pattern for row -internal_index[i] is empty for all i. -In this case, one is setting the sparsity patterns; i.e., -the output pattern in row internal_index[i] is the corresponding -entries in pattern. - -\param transpose -If this is true, pattern_in is transposed. - -\param internal_index -This specifies the sub-set of rows in internal_pattern that we are updating. -If traspose is false (true), -this is the mapping from row (column) index in pattern_in to the corresponding -row index in the internal_pattern. - -\param internal_pattern -On input, the number of sets internal_pattern.n_set(), -and possible elements internal_pattern.end(), have been set. -If input_empty is true, and all of the sets -in internal_index are empty on input. -On output, the entries in pattern_in are added to internal_pattern. -To be specific, suppose transpose is false, and (i, j) is a possibly -non-zero entry in pattern_in, the entry (internal_index[i], j) is added -to internal_pattern. -On the other hand, if transpose is true, -the entry (internal_index[j], i) is added to internal_pattern. - -\param pattern_in -This is the sparsity pattern for variables, -or its transpose, depending on the value of transpose. -*/ -template -void set_internal_pattern( - bool zero_empty , - bool input_empty , - bool transpose , - const pod_vector& internal_index , - InternalSparsity& internal_pattern , - const sparse_rc& pattern_in ) -{ - size_t nr = internal_index.size(); -# ifndef NDEBUG - size_t nc = internal_pattern.end(); - if( transpose ) - { CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nc ); - CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nr ); - } - else - { CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nr ); - CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nc ); - } - if( input_empty ) for(size_t i = 0; i < nr; i++) - { size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); - } -# endif - const SizeVector& row( pattern_in.row() ); - const SizeVector& col( pattern_in.col() ); - size_t nnz = row.size(); - for(size_t k = 0; k < nnz; k++) - { size_t r = row[k]; - size_t c = col[k]; - if( transpose ) - std::swap(r, c); - // - size_t i_var = internal_index[r]; - CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); - CPPAD_ASSERT_UNKNOWN( c < nc ); - bool ignore = zero_empty && i_var == 0; - if( ! ignore ) - internal_pattern.post_element( internal_index[r], c ); - } - // process posts - for(size_t i = 0; i < nr; ++i) - internal_pattern.process_post( internal_index[i] ); -} -template -void set_internal_pattern( - bool zero_empty , - bool input_empty , - bool transpose , - const pod_vector& internal_index , - InternalSparsity& internal_pattern , - const vectorBool& pattern_in ) -{ size_t nr = internal_index.size(); - size_t nc = internal_pattern.end(); -# ifndef NDEBUG - CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr * nc ); - if( input_empty ) for(size_t i = 0; i < nr; i++) - { size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); - } -# endif - for(size_t i = 0; i < nr; i++) - { for(size_t j = 0; j < nc; j++) - { bool flag = pattern_in[i * nc + j]; - if( transpose ) - flag = pattern_in[j * nr + i]; - if( flag ) - { size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); - CPPAD_ASSERT_UNKNOWN( j < nc ); - bool ignore = zero_empty && i_var == 0; - if( ! ignore ) - internal_pattern.post_element( i_var, j); - } - } - } - // process posts - for(size_t i = 0; i < nr; ++i) - internal_pattern.process_post( internal_index[i] ); - return; -} -template -void set_internal_pattern( - bool zero_empty , - bool input_empty , - bool transpose , - const pod_vector& internal_index , - InternalSparsity& internal_pattern , - const vector& pattern_in ) -{ size_t nr = internal_index.size(); - size_t nc = internal_pattern.end(); -# ifndef NDEBUG - CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr * nc ); - if( input_empty ) for(size_t i = 0; i < nr; i++) - { size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); - } -# endif - for(size_t i = 0; i < nr; i++) - { for(size_t j = 0; j < nc; j++) - { bool flag = pattern_in[i * nc + j]; - if( transpose ) - flag = pattern_in[j * nr + i]; - if( flag ) - { size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); - CPPAD_ASSERT_UNKNOWN( j < nc ); - bool ignore = zero_empty && i_var == 0; - if( ! ignore ) - internal_pattern.post_element( i_var, j); - } - } - } - // process posts - for(size_t i = 0; i < nr; ++i) - internal_pattern.process_post( internal_index[i] ); - return; -} -template -void set_internal_pattern( - bool zero_empty , - bool input_empty , - bool transpose , - const pod_vector& internal_index , - InternalSparsity& internal_pattern , - const vector< std::set >& pattern_in ) -{ size_t nr = internal_index.size(); - size_t nc = internal_pattern.end(); -# ifndef NDEBUG - if( input_empty ) for(size_t i = 0; i < nr; i++) - { size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 ); - } -# endif - if( transpose ) - { CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nc ); - for(size_t j = 0; j < nc; j++) - { std::set::const_iterator itr( pattern_in[j].begin() ); - while( itr != pattern_in[j].end() ) - { size_t i = *itr; - size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); - CPPAD_ASSERT_UNKNOWN( j < nc ); - bool ignore = zero_empty && i_var == 0; - if( ! ignore ) - internal_pattern.post_element( i_var, j); - ++itr; - } - } - } - else - { CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr ); - for(size_t i = 0; i < nr; i++) - { std::set::const_iterator itr( pattern_in[i].begin() ); - while( itr != pattern_in[i].end() ) - { size_t j = *itr; - size_t i_var = internal_index[i]; - CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() ); - CPPAD_ASSERT_UNKNOWN( j < nc ); - bool ignore = zero_empty && i_var == 0; - if( ! ignore ) - internal_pattern.post_element( i_var, j); - ++itr; - } - } - } - // process posts - for(size_t i = 0; i < nr; ++i) - internal_pattern.process_post( internal_index[i] ); - return; -} -// --------------------------------------------------------------------------- -/*! -Get sparsity pattern for a sub-set of variables - -\tparam SizeVector -The type used for index sparsity patterns. This is a simple vector -with elements of type size_t. - -\tparam InternalSparsitiy -The type used for intenal sparsity patterns. This can be either -sparse::pack_setvec or list_setvec. - -\param transpose -If this is true, pattern_out is transposed. - -\param internal_index -If transpose is false (true) -this is the mapping from row (column) an index in pattern_out -to the corresponding row index in internal_pattern. - -\param internal_pattern -This is the internal sparsity pattern. - -\param pattern_out -The input value of pattern_out does not matter. -Upon return it is an index sparsity pattern for each of the variables -in internal_index, or its transpose, depending on the value of transpose. -*/ -template -void get_internal_pattern( - bool transpose , - const pod_vector& internal_index , - const InternalSparsity& internal_pattern , - sparse_rc& pattern_out ) -{ typedef typename InternalSparsity::const_iterator iterator; - // number variables - size_t nr = internal_index.size(); - // column size of interanl sparstiy pattern - size_t nc = internal_pattern.end(); - // determine nnz, the number of possibly non-zero index pairs - size_t nnz = 0; - for(size_t i = 0; i < nr; i++) - { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); - iterator itr(internal_pattern, internal_index[i]); - size_t j = *itr; - while( j < nc ) - { ++nnz; - j = *(++itr); - } - } - // transposed - if( transpose ) - { pattern_out.resize(nc, nr, nnz); - // - size_t k = 0; - for(size_t i = 0; i < nr; i++) - { iterator itr(internal_pattern, internal_index[i]); - size_t j = *itr; - while( j < nc ) - { pattern_out.set(k++, j, i); - j = *(++itr); - } - } - return; - } - // not transposed - pattern_out.resize(nr, nc, nnz); - // - size_t k = 0; - for(size_t i = 0; i < nr; i++) - { iterator itr(internal_pattern, internal_index[i]); - size_t j = *itr; - while( j < nc ) - { pattern_out.set(k++, i, j); - j = *(++itr); - } - } - return; -} -template -void get_internal_pattern( - bool transpose , - const pod_vector& internal_index , - const InternalSparsity& internal_pattern , - vectorBool& pattern_out ) -{ typedef typename InternalSparsity::const_iterator iterator; - // number variables - size_t nr = internal_index.size(); - // - // column size of interanl sparstiy pattern - size_t nc = internal_pattern.end(); - // - pattern_out.resize(nr * nc); - for(size_t ij = 0; ij < nr * nc; ij++) - pattern_out[ij] = false; - // - for(size_t i = 0; i < nr; i++) - { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); - iterator itr(internal_pattern, internal_index[i]); - size_t j = *itr; - while( j < nc ) - { if( transpose ) - pattern_out[j * nr + i] = true; - else - pattern_out[i * nc + j] = true; - j = *(++itr); - } - } - return; -} -template -void get_internal_pattern( - bool transpose , - const pod_vector& internal_index , - const InternalSparsity& internal_pattern , - vector& pattern_out ) -{ typedef typename InternalSparsity::const_iterator iterator; - // number variables - size_t nr = internal_index.size(); - // - // column size of interanl sparstiy pattern - size_t nc = internal_pattern.end(); - // - pattern_out.resize(nr * nc); - for(size_t ij = 0; ij < nr * nc; ij++) - pattern_out[ij] = false; - // - for(size_t i = 0; i < nr; i++) - { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); - iterator itr(internal_pattern, internal_index[i]); - size_t j = *itr; - while( j < nc ) - { if( transpose ) - pattern_out[j * nr + i] = true; - else - pattern_out[i * nc + j] = true; - j = *(++itr); - } - } - return; -} -template -void get_internal_pattern( - bool transpose , - const pod_vector& internal_index , - const InternalSparsity& internal_pattern , - vector< std::set >& pattern_out ) -{ typedef typename InternalSparsity::const_iterator iterator; - // number variables - size_t nr = internal_index.size(); - // - // column size of interanl sparstiy pattern - size_t nc = internal_pattern.end(); - // - if( transpose ) - pattern_out.resize(nc); - else - pattern_out.resize(nr); - for(size_t k = 0; k < pattern_out.size(); k++) - pattern_out[k].clear(); - // - for(size_t i = 0; i < nr; i++) - { CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() ); - iterator itr(internal_pattern, internal_index[i]); - size_t j = *itr; - while( j < nc ) - { if( transpose ) - pattern_out[j].insert(i); - else - pattern_out[i].insert(j); - j = *(++itr); - } - } - return; -} - - - -} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sparse/list_setvec.hpp b/build-config/cppad/include/cppad/local/sparse/list_setvec.hpp deleted file mode 100644 index 4ea5241b..00000000 --- a/build-config/cppad/include/cppad/local/sparse/list_setvec.hpp +++ /dev/null @@ -1,1721 +0,0 @@ -# ifndef CPPAD_LOCAL_SPARSE_LIST_SETVEC_HPP -# define CPPAD_LOCAL_SPARSE_LIST_SETVEC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE -namespace CppAD { namespace local { namespace sparse { - -// forward declaration of iterator class -class list_setvec_const_iterator; - -// ========================================================================= -class list_setvec { // BEGIN_CLASS_LIST_SETVEC -// ========================================================================= - -/* -------------------------------------------------------------------------------- -$begin list_setvec_member_data$$ -$spell - setvec - struct -$$ - -$section class list_setvec: Private Member Data$$ - -$head pair_size_t$$ -This $code struct$$ is local to the $code list_setvec$$ class. -It is the type used for each entry in a singly linked list -and has the following fields: - -$subhead value$$ -The is the value of an entry in the list -(for sets, the first entry in the list is a reference count). - -$subhead next$$ -This is the index in $code data_$$ for the next entry in the list. -If there are no more entries in the list, this value is zero; i.e., -$code data_[0]$$ is used to represent the end of a list. - -$head end_$$ -The possible elements in each set are $code 0$$, $code 1$$, ..., -$code end_-1$$ - -$head number_not_used_$$ -Number of elements of the $code data_$$ vector that are not being used. - -$head data_not_used_$$ -Index in $code data_$$ for the start of the linked list of elements -that are not being used. - -$head data_$$ -The data for all the singly linked lists. -If $icode%n_set% > 0%$$, -$codei%data[0].value == end_%$$ and -$codei%data[0].next == 0%$$. - -$head start_$$ -The size of this vector is the number of set; i.e., -$cref/n_set/SetVector/Vector Operations/n_set/$$. -The starting index for $th i$$ set is $codei%start_[%i%]%$$. -If $codei%start_[%i%] == 0%$$, the i-th set has no elements. -Otherwise it is the index of the reference count for the list. - -$subhead Reference Count$$ -If $codei%start_[%i%] != 0%$$, $codei%data_[start_[%i%]].value%$$ -is the reference count for the $th i$$ list -(not the value of an element in the list). -The reference count must be greater than zero. - -$subhead First Element$$ -If $codei%start_[%i%] != 0%$$, -$codei% - %first_index% = data_[start_[%i%]].next -%$$ -is the index of the first element in the list. -This must be non-zero because the list is empty. - -$subhead Next Element$$ -Starting with $icode%index% = %first_index%$$, -while $icode%index% != 0%$$, -The value of the corresponding element in the list is -$codei%data_[%index%].value%$$ (which must be less than $code end_$$). -The $icode index$$ for the next element of the list is -$codei%data_[%index%].next%$$. - -$subhead Last Element$$ -An index $icode last$$ corresponds to the last element of a list if -$codei%data_[%last%].next == 0%$$. -(Note that $code data_[0].value == end_$$). - -$head post_$$ -The size of this vector is the number of set; i.e., -$cref/n_set/SetVector/Vector Operations/n_set/$$. -Starting with $icode%index% = post_[%i%]%$$, -while $icode%index% != 0%$$, -The value of the next element posted to the $th i$$ list is -$codei%data_[%index%].value%$$ (which must be less than $code end_$$). -The $icode index$$ for the next element posted to the $th i$$ list is -$codei%data_[%index%].next%$$. - -$head temporary_$$ -A temporary vector, used by member functions, that keeps its capacity -to avoid re-allocating memory. -If a member function calls another, -no conditions about $code temporary_$$ should be assumed during that call. - -$head Source Code$$ -$srccode%hpp% */ -private: - struct pair_size_t {size_t value; size_t next; }; - friend bool CppAD::local::is_pod(void); - // - size_t end_; - size_t number_not_used_; - size_t data_not_used_; - // - pod_vector data_; - pod_vector start_; - pod_vector post_; - pod_vector temporary_; -/* %$$ -$end ------------------------------------------------------------------------------- -$begin list_setvec_reference_count$$ -$spell - vec - setvec - const -$$ - -$section class list_setvec private: Number of References to a Set$$ - -$head Syntax$$ -$icode%count% = %vec%.reference_count(%i%)%$$ - -$head vec$$ -Is a $code list_setvec$$ object and can be $code const$$. - -$head i$$ -is the index of the set that we are retrieving the references for. - -$head count$$ -is the reference count. - -$head Prototype$$ -$srccode%hpp% */ -private: - size_t reference_count(size_t i) const -/* %$$ -$end -*/ - { // start data index - size_t start = start_[i]; - if( start == 0 ) - return 0; - // - // reference count - return data_[start].value; - } -/* ------------------------------------------------------------------------------- -$begin list_setvec_drop$$ -$spell - setvec - vec - decremented -$$ -$section class list_setvec private: Drop a Set No Longer Being Used$$ - -$head Syntax$$ -$icode%not_used% = %vec%.drop(%i%)%$$ - -$head i$$ -is the index of the set that is dropped. - -$head reference_count$$ -if the set is non-empty, the -$cref/reference count/list_setvec_member_data/start_/Reference Count/$$ -is decremented. - -$head start_$$ -The value $codei%start_[%i%]%$$ is set to zero; i.e., -the $th i$$ set is empty after the call. - -$head post_$$ -The value $codei%post_[%i%]%$$ is set to zero; i.e., -any postings to the list are also dropped. - -$head data_not_used_$$ -The elements of $code data_$$ were information for the $th i$$ set, -and are no longer being used, are added to the linked list starting at -$code data_not_used$$. -This includes both set elements and postings. - -$head not_used$$ -is the number of elements of $code data_$$ that were begin used for the -$th i$$ set and are no longer being used; i.e., the number of elements -moved to $code data_not_used$$. - -$head Prototype$$ -$srccode%hpp% */ -private: - size_t drop(size_t i) -/* %$$ -$end -*/ - { // inialize count of addition elements not being used. - size_t number_drop = 0; - - // the elements in the post list will no longer be used - size_t post = post_[i]; - if( post != 0 ) - { // drop this posting - post_[i] = 0; - // - // count elements in this posting - ++number_drop; - size_t previous = post; - size_t next = data_[previous].next; - while( next != 0 ) - { previous = next; - next = data_[previous].next; - ++number_drop; - } - // - // add the posting elements to data_not_used_ - data_[previous].next = data_not_used_; - data_not_used_ = post; - } - - // check for empty set - size_t start = start_[i]; - if( start == 0 ) - return number_drop; - - // decrement reference counter - CPPAD_ASSERT_UNKNOWN( data_[start].value > 0 ); - data_[start].value--; - - // set this set to empty - start_[i] = 0; - - // If new reference count is positive, the list corresponding to - // start is still being used. - if( data_[start].value > 0 ) - return number_drop; - - // - // count elements representing this set - ++number_drop; - size_t previous = start; - size_t next = data_[previous].next; - while( next != 0 ) - { previous = next; - next = data_[previous].next; - ++number_drop; - } - // - // add representing this set to data_not_used_ - data_[previous].next = data_not_used_; - data_not_used_ = start; - // - return number_drop; - } -/* ------------------------------------------------------------------------------- -$begin list_setvec_get_data_index$$ -$spell - decremented - setvec - vec -$$ - -$section class list_setvec private: Get a New List Pair$$ - -$head Syntax$$ -$icode%index% = %vec%.get_data_index()%$$ - -$head vec$$ -Is a $code list_setvec$$ object. - -$head data_not_used_$$ -If the input value of $code data_not_used_$$ is zero, -it is not changed. -Otherwise, the index for the element at the front of that list is returned. -In this case, -$code data_not_used$$ is advanced to the next element in that list. - -$head number_not_used_$$ -If the input value of $code data_not_used_$$ is zero, -$code number_not_used_$$ is not changed. -Otherwise it is decremented by one. - -$head index$$ -If the input value of $code data_not_used_$$ is zero, -the size of $code data_$$ is increased by one and index corresponding -to the end of $code data_$$ is returned. -Otherwise, the input value for $code data_not_used_$$ is returned. - -$head Prototype$$ -$srccode%hpp% */ -private: - size_t get_data_index(void) -/* %$$ -$end -*/ - { size_t index; - if( data_not_used_ > 0 ) - { CPPAD_ASSERT_UNKNOWN( number_not_used_ > 0 ); - --number_not_used_; - index = data_not_used_; - data_not_used_ = data_[index].next; - } - else - { index = data_.extend(1); - } - return index; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_check_data_structure$$ -$spell - setvec - vec - const -$$ - -$section class list_setvec private: Check Data Structure$$ - -$head Syntax$$ -$icode%vec%.check_data_structure()%$$ - -$head vec$$ -Is a $code list_setvec$$ object that is effectively const. -It is not declared const because the data structure is modified and -then restored. - -$head NDEBUG$$ -If $code NDEBUG$$ is defined, the routine does nothing. -Otherwise, if an error is found in the data structure, -a $code CPPAD_ASSERT_UNKNOWN$$ is generated. - -$head Prototype$$ -$srccode%hpp% */ -private: - void check_data_structure(void) -/* %$$ -$end -*/ -# ifdef NDEBUG - { return; } -# else - { // number of sets - CPPAD_ASSERT_UNKNOWN( post_.size() == start_.size() ); - size_t n_set = start_.size(); - if( n_set == 0 ) - { CPPAD_ASSERT_UNKNOWN( end_ == 0 ); - CPPAD_ASSERT_UNKNOWN( number_not_used_ == 0 ); - CPPAD_ASSERT_UNKNOWN( data_not_used_ == 0 ); - CPPAD_ASSERT_UNKNOWN( data_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( start_.size() == 0 ); - return; - } - // check data index zero - CPPAD_ASSERT_UNKNOWN( data_[0].value == end_ ); - CPPAD_ASSERT_UNKNOWN( data_[0].next == 0 ); - // ----------------------------------------------------------- - // save a copy of the reference counters in temporary_ - temporary_.resize(n_set); - for(size_t i = 0; i < n_set; i++) - temporary_[i] = reference_count(i); - // ----------------------------------------------------------- - // Initialize number of entries in data used by sets and posts. - // Start with 1 for data_[0]. - size_t number_used_by_sets = 1; - // ----------------------------------------------------------- - // count the number of entries in data_ that are used by sets - for(size_t i = 0; i < n_set; i++) - { size_t start = start_[i]; - if( start > 0 ) - { // check structure for this non-empty set - size_t reference_count = data_[start].value; - size_t next = data_[start].next; - CPPAD_ASSERT_UNKNOWN( reference_count > 0 ); - CPPAD_ASSERT_UNKNOWN( next != 0 ); - CPPAD_ASSERT_UNKNOWN( data_[next].value < end_ ); - // - // decrement the reference counter - data_[start].value--; - // - // count the entries when find last reference - if( data_[start].value == 0 ) - { - // restore reference count - data_[start].value = temporary_[i]; - - // number of data entries used for this set - number_used_by_sets += number_elements(i) + 1; - /* - number of elements checks that value < end_ - .resizeeach pair in the list except for the start pair - and the pair with index zero. - */ - } - } - } - // ------------------------------------------------------------------ - // count the number of entries in data_ that are used by posts - size_t number_used_by_posts = 0; - for(size_t i = 0; i < n_set; i++) - { size_t post = post_[i]; - if( post > 0 ) - { size_t value = data_[post].value; - size_t next = data_[post].next; - CPPAD_ASSERT_UNKNOWN( value < end_ ); - // - while( value < end_ ) - { ++number_used_by_posts; - value = data_[next].value; - next = data_[next].next; - } - } - } - // ------------------------------------------------------------------ - // count number of entries in data_not_used_ - size_t count = 0; - size_t next = data_not_used_; - while( next != 0 ) - { ++count; - next = data_[next].next; - } - CPPAD_ASSERT_UNKNOWN( number_not_used_ == count ); - // ------------------------------------------------------------------ - size_t number_used = number_used_by_sets + number_used_by_posts; - CPPAD_ASSERT_UNKNOWN( - number_used + number_not_used_ == data_.size() - ); - return; - } -# endif -/* -------------------------------------------------------------------------------- -$begin list_setvec_vec_memory$$ -$spell - setvec -$$ - -$section class list_setvec: Approximate Memory Used by Vector$$ - -$head Public$$ -This function is declared public, but is not part of -$cref SetVector$$ concept. - -$head Implementation$$ -$srccode%hpp% */ -public: - size_t memory(void) const - { return data_.capacity() * sizeof(pair_size_t); } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_vec_print$$ -$spell - setvec -$$ - -$section class list_setvec: Print a Vector of Sets$$ - - -$head Public$$ -This function is declared public, but is not part of -$cref SetVector$$ concept. - -$head Prototype$$ -$srccode%hpp% */ -public: - void print(void) const; -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_iterators$$ -$spell - setvec - Iterators - typedef - const_iterator -$$ - -$section class list_setvec: Iterators$$ - -$head SetVector Concept$$ -$cref/const_iterator/SetVector/const_iterator/$$ - -$head typedef$$ -$srccode%hpp% */ -public: - friend class list_setvec_const_iterator; - typedef list_setvec_const_iterator const_iterator; -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_default_ctor$$ -$spell - setvec -$$ - -$section class list_setvec: Default Constructor$$ - -$head SetVector Concept$$ -$cref/constructor/SetVector/Vector Operations/Constructor/$$ - -$head size_t Members$$ -All of the $code size_t$$ member variables are initialized as zero. - -$head pod_vector Members$$ -All of the $code pod_vector$$ member variables are initialized -using their default constructors. - -$head Implementation$$ -$srccode%hpp% */ -public: - list_setvec(void) - : end_(0), number_not_used_(0), data_not_used_(0) - { } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_destructor$$ -$spell - setvec -$$ - -$section class list_setvec: Destructor$$ - -$head Implementation$$ -If $code NDEBUG$$ is not defined, -$cref/check data structure/list_setvec_check_data_structure/$$. -$srccode%hpp% */ -public: - ~list_setvec(void) - { check_data_structure(); } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_copy_ctor$$ -$spell - setvec - CppAD -$$ - -$section class list_setvec: Copy Constructor$$ - -$head v$$ -The vector of sets that we are attempting to make a copy of. - -$head Implementation$$ -Using the copy constructor is probably due to a $code list_setvec$$ -being passed by value instead of by reference. -This is a CppAD programing error (not CppAD user error). -$srccode%hpp% */ -public: - list_setvec(const list_setvec& v) - { CPPAD_ASSERT_UNKNOWN(false); } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_vec_resize$$ -$spell - setvec - resize -$$ - -$section class list_setvec: Vector resize$$ - -$head SetVector Concept$$ -$cref/vector resize/SetVector/Vector Operations/resize/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void resize(size_t n_set, size_t end) -/* %$$ -$end -*/ - { check_data_structure(); - - if( n_set == 0 ) - { CPPAD_ASSERT_UNKNOWN( end == 0 ); - // - // restore object to start after constructor - // (no memory allocated for this object) - data_.clear(); - start_.clear(); - post_.clear(); - number_not_used_ = 0; - data_not_used_ = 0; - end_ = 0; - // - return; - } - end_ = end; - // - start_.resize(n_set); - post_.resize(n_set); - // - for(size_t i = 0; i < n_set; i++) - { start_[i] = 0; - post_[i] = 0; - } - // - // last element, marks the end for all lists - data_.resize(1); - data_[0].value = end_; - data_[0].next = 0; - // - number_not_used_ = 0; - data_not_used_ = 0; - } -/* %$$ -------------------------------------------------------------------------------- -$begin list_setvec_vec_n_set$$ -$spell - setvec -$$ - -$section class list_setvec: Number of Sets$$ - -$head SetVector Concept$$ -$cref/n_set/SetVector/Vector Operations/n_set/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - size_t n_set(void) const - { return start_.size(); } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_vec_end$$ -$spell - setvec -$$ - -$section class list_setvec: End Value$$ - -$head SetVector Concept$$ -$cref/end/SetVector/Vector Operations/end/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - size_t end(void) const - { return end_; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_vec_assignment$$ -$spell - setvec -$$ - -$section class list_setvec: Vector Assignment$$ - -$head SetVector Concept$$ -$cref/vector assignment/SetVector/Vector Operations/Assignment/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void operator=(const list_setvec& other) -/* %$$ -$end -*/ - { end_ = other.end_; - number_not_used_ = other.number_not_used_; - data_not_used_ = other.data_not_used_; - data_ = other.data_; - start_ = other.start_; - post_ = other.post_; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_vec_swap$$ -$spell - setvec -$$ - -$section class list_setvec: Vector Swap$$ - -$head SetVector Concept$$ -$cref/vector swap/SetVector/Vector Operations/swap/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void swap(list_setvec& other) -/* %$$ -$end -*/ - { // size_t objects - std::swap(end_ , other.end_); - std::swap(number_not_used_ , other.number_not_used_); - std::swap(data_not_used_ , other.data_not_used_); - - // pod_vectors - data_.swap( other.data_); - start_.swap( other.start_); - post_.swap( other.post_); - temporary_.swap( other.temporary_); - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_number_elements$$ -$spell - setvec -$$ - -$section class list_setvec: Number of Elements in a Set$$ - -$head SetVector Concept$$ -$cref/number_elements/SetVector/number_elements/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - size_t number_elements(size_t i) const -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( post_[i] == 0 ); - - // check if the set is empty - size_t start = start_[i]; - if( start == 0 ) - return 0; - - // initialize counter - size_t count = 0; - - // advance to the first element in the set - size_t next = data_[start].next; - while( next != 0 ) - { CPPAD_ASSERT_UNKNOWN( data_[next].value < end_ ); - count++; - next = data_[next].next; - } - CPPAD_ASSERT_UNKNOWN( count > 0 ); - return count; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_add_element$$ -$spell - setvec -$$ - -$section class list_setvec: Add an Elements to a Set$$ - -$head SetVector Concept$$ -$cref/add_element/SetVector/add_element/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void add_element(size_t i, size_t element) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( i < start_.size() ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - - // check for case where starting set is empty - size_t start = start_[i]; - if( start == 0 ) - { start = get_data_index(); - start_[i] = start; - data_[start].value = 1; // reference count - // - size_t next = get_data_index(); - data_[start].next = next; - // - data_[next].value = element; - data_[next].next = 0; - return; - } - // - // start of set with this index - size_t previous = start_[i]; - // - // first entry in this set - size_t next = data_[previous].next; - size_t value = data_[next].value; - // - // locate place to insert this element - while( value < element ) - { previous = next; - next = data_[next].next; - value = data_[next].value; - } - // - // check for case where element is in the set - if( value == element ) - return; - // - // - // check for case where this is the only reference to this set - CPPAD_ASSERT_UNKNOWN( element < value ); - if( data_[start].value == 1 ) - { size_t insert = get_data_index(); - data_[insert].next = next; - data_[insert].value = element; - data_[previous].next = insert; - // - return; - } - // - // must make a separate copy with new element inserted - CPPAD_ASSERT_UNKNOWN( data_[start].value > 1 ); - data_[start].value--; // reverence counter for old list - // - size_t start_new = get_data_index(); - data_[start_new].value = 1; // reference counter for new list - size_t previous_new = start_new; - // - // start of old set with this index - previous = start_[i]; - // - // first entry in old set - next = data_[previous].next; - value = data_[next].value; - // - // locate place to insert this element - while( value < element ) - { // copy to new list - size_t next_new = get_data_index(); - data_[previous_new].next = next_new; - data_[next_new].value = value; - previous_new = next_new; - // - // get next value - previous = next; - next = data_[next].next; - value = data_[next].value; - } - CPPAD_ASSERT_UNKNOWN( element < value ); - // - // insert the element - size_t next_new = get_data_index(); - data_[previous_new].next = next_new; - data_[next_new].value = element; - previous_new = next_new; - // - // copy rest of the old set - while( value < end_ ) - { // copy to new list - next_new = get_data_index(); - data_[previous_new].next = next_new; - data_[next_new].value = value; - previous_new = next_new; - // - // get next value - previous = next; - next = data_[next].next; - value = data_[next].value; - } - CPPAD_ASSERT_UNKNOWN( next == 0 ); - data_[previous_new].next = 0; - // - // hook up new list - start_[i] = start_new; - return; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_post_element$$ -$spell - setvec -$$ - -$section class list_setvec: Post an Elements for Addition to a Set$$ - -$head SetVector Concept$$ -$cref/post_element/SetVector/post_element/$$ - -$head post_$$ -The element is added at the front of the linked list -that starts at $code post_$$. - -$head Prototype$$ -$srccode%hpp% */ -public: - void post_element(size_t i, size_t element) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( i < start_.size() ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - - // put element at the front of this list - size_t next = post_[i]; - size_t post = get_data_index(); - post_[i] = post; - data_[post].value = element; - data_[post].next = next; - - return; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_process_post$$ -$spell - setvec -$$ - -$section class list_setvec: Add Posted Elements to a Set$$ - -$head SetVector Concept$$ -$cref/process_post/SetVector/process_post/$$ - -$head post_$$ -Upon call, $codei%post_[%i%]%$$ is the linked list of elements to -be added to the $th i$$ set. -Upon return, $codei%post_[%i%]%$$ is zero; i.e., the list is empty. - -$head Prototype$$ -$srccode%hpp% */ -public: - void process_post(size_t i) -/* %$$ -$end -*/ - { // post - size_t post = post_[i]; - // - // check if there are no elements to process - if( post == 0 ) - return; - // - // check if there is only one element to process - size_t next = data_[post].next; - if( next == 0 ) - { // done with this posting - size_t value = data_[post].value; - post_[i] = 0; - data_[post].next = data_not_used_; - data_not_used_ = post; - ++number_not_used_; - // - add_element(i, value); - // - return; - } - // - // copy posting to temporary_ - temporary_.resize(0); - size_t previous = post; - size_t value = data_[previous].value; - CPPAD_ASSERT_UNKNOWN( value < end_ ); - temporary_.push_back(value); - while( next != 0 ) - { previous = next; - value = data_[previous].value; - CPPAD_ASSERT_UNKNOWN( value < end_ ); - temporary_.push_back(value); - next = data_[previous].next; - } - size_t number_post = temporary_.size(); - // - // done with this posting - post_[i] = 0; - data_[previous].next = data_not_used_; - data_not_used_ = post; - number_not_used_ += number_post;; - // - // sort temporary_ - CPPAD_ASSERT_UNKNOWN( number_post > 1 ); - std::sort( temporary_.data(), temporary_.data() + number_post); - // posting is the set { temporary_[0], ... , [number_post-1] } - // ------------------------------------------------------------------- - // put union of posting and set i in - // temporary_[number_post], ... , temporary_[ temporary_.size()-1 ] - // - size_t i_next = start_[i]; - size_t i_value = end_; - if( i_next > 0 ) - { // skip reference count - i_next = data_[i_next].next; - i_value = data_[i_next].value; - } - bool post_is_subset = true; - size_t previous_post = end_; - for(size_t j =0; j < number_post; ++j) - { size_t post_value = temporary_[j]; - CPPAD_ASSERT_UNKNOWN( post_value < end_ ); - while( i_value < post_value ) - { // i_value is in union - temporary_.push_back(i_value); - i_next = data_[i_next].next; - i_value = data_[i_next].value; - } - if( i_value == post_value ) - { i_next = data_[i_next].next; - i_value = data_[i_next].value; - } - else - post_is_subset = false; - // - if( previous_post != post_value ) - { // post_value is in union - temporary_.push_back(post_value); - } - previous_post = post_value; - } - // check if posting is a subset of set i - if( post_is_subset ) - return; - // - // rest of elements in set i - while( i_value < end_ ) - { temporary_.push_back(i_value); - i_next = data_[i_next].next; - i_value = data_[i_next].value; - } - - // adjust number_not_used_ - size_t number_drop = drop(i); - number_not_used_ += number_drop; - - // put new set in linked list for set i - CPPAD_ASSERT_UNKNOWN( temporary_.size() >= number_post + 1 ); - size_t index = get_data_index(); - start_[i] = index; // start for the union - data_[index].value = 1; // reference count for the union - for(size_t j = number_post; j < temporary_.size(); ++j) - { next = get_data_index(); - data_[index].next = next; - data_[next].value = temporary_[j]; // next element in union - index = next; - } - data_[index].next = 0; // end of union - // - return; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_is_element$$ -$spell - setvec -$$ - -$section class list_setvec: Is an Element in a Set$$ - -$head SetVector Concept$$ -$cref/is_element/SetVector/is_element/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - bool is_element(size_t i, size_t element) const -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( post_[i] == 0 ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - // - size_t start = start_[i]; - if( start == 0 ) - return false; - // - size_t next = data_[start].next; - size_t value = data_[next].value; - while( value < element ) - { next = data_[next].next; - value = data_[next].value; - } - return element == value; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_clear$$ -$spell - setvec -$$ - -$section class list_setvec: Assign a Set to be Empty$$ - -$head SetVector Concept$$ -$cref/clear/SetVector/clear/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void clear(size_t target) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( target < start_.size() ); - - // adjust number_not_used_ - size_t number_drop = drop(target); - number_not_used_ += number_drop; - - return; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_assignment$$ -$spell - setvec -$$ - -$section class list_setvec: Assign a Set To Equal Another Set$$ - -$head SetVector Concept$$ -$cref/assignment/SetVector/assignment/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void assignment( - size_t this_target , - size_t other_source , - const list_setvec& other ) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( other.post_[ other_source ] == 0 ); - // - CPPAD_ASSERT_UNKNOWN( this_target < start_.size() ); - CPPAD_ASSERT_UNKNOWN( other_source < other.start_.size() ); - CPPAD_ASSERT_UNKNOWN( end_ == other.end_ ); - - // check if we are assigning a set to itself - if( (this == &other) & (this_target == other_source) ) - return; - - // set depending on cases below - size_t this_start; - - // If this and other are the same, use another reference to same list - size_t other_start = other.start_[other_source]; - if( this == &other ) - { this_start = other_start; - if( other_start != 0 ) - { data_[other_start].value++; // increment reference count - CPPAD_ASSERT_UNKNOWN( data_[other_start].value > 1 ); - } - } - else if( other_start == 0 ) - { this_start = 0; - } - else - { // make a copy of the other list in this list_setvec - this_start = get_data_index(); - size_t this_next = get_data_index(); - data_[this_start].value = 1; // reference count - data_[this_start].next = this_next; - // - size_t next = other.data_[other_start].next; - CPPAD_ASSERT_UNKNOWN( next != 0 ); - while( next != 0 ) - { data_[this_next].value = other.data_[next].value; - next = other.data_[next].next; - if( next == 0 ) - data_[this_next].next = 0; - else - { size_t tmp = get_data_index(); - data_[this_next].next = tmp; - this_next = tmp; - } - } - } - - // adjust number_not_used_ - size_t number_drop = drop(this_target); - number_not_used_ += number_drop; - - // set the new start value for this_target - start_[this_target] = this_start; - - return; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_binary_union$$ -$spell - setvec -$$ - -$section class list_setvec: Assign a Set To Union of Two Sets$$ - -$head SetVector Concept$$ -$cref/binary_union/SetVector/binary_union/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void binary_union( - size_t this_target , - size_t this_left , - size_t other_right , - const list_setvec& other ) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 ); - CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 ); - // - CPPAD_ASSERT_UNKNOWN( this_target < start_.size() ); - CPPAD_ASSERT_UNKNOWN( this_left < start_.size() ); - CPPAD_ASSERT_UNKNOWN( other_right < other.start_.size() ); - CPPAD_ASSERT_UNKNOWN( end_ == other.end_ ); - - // start indices for left and right sets - size_t start_left = start_[this_left]; - size_t start_right = other.start_[other_right]; - - // if right is empty, the result is the left set - if( start_right == 0 ) - { assignment(this_target, this_left, *this); - return; - } - // if left is empty, the result is the right set - if( start_left == 0 ) - { assignment(this_target, other_right, other); - return; - } - // if niether case holds, then both left and right are non-empty - CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 ); - CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 ); - - // we will use temparary_ for temporary storage of the union - temporary_.resize(0); - - // for left next and value - size_t next_left = data_[start_left].next; - size_t value_left = data_[next_left].value; - - // right next and value - size_t next_right = other.data_[start_right].next; - size_t value_right = other.data_[next_right].value; - - // both left and right set are non-empty - CPPAD_ASSERT_UNKNOWN( value_left < end_ && value_right < end_ ); - - // flag that detects if left is or right is a subset of the other - bool left_is_subset = true; - bool right_is_subset = true; - - while( (value_left < end_) & (value_right < end_) ) - { if( value_left == value_right ) - { // value is in both sets - temporary_.push_back(value_left); - // - // advance left - next_left = data_[next_left].next; - value_left = data_[next_left].value; - // - // advance right - next_right = other.data_[next_right].next; - value_right = other.data_[next_right].value; - } - else if( value_left < value_right ) - { // need a value from left that is not in right - left_is_subset = false; - temporary_.push_back(value_left); - // - // advance left to its next element - next_left = data_[next_left].next; - value_left = data_[next_left].value; - } - else - { CPPAD_ASSERT_UNKNOWN( value_right < value_left ) - // need a value from right that is not in left - right_is_subset = false; - temporary_.push_back(value_right); - // - // advance right to its next element - next_right = other.data_[next_right].next; - value_right = other.data_[next_right].value; - } - } - right_is_subset &= value_right == end_; - left_is_subset &= value_left == end_; - // - // check right first in case they are equal will do this assignment - if( right_is_subset ) - { assignment(this_target, this_left, *this); - return; - } - if( left_is_subset ) - { assignment(this_target, other_right, other); - return; - } - while( value_left < end_ ) - { CPPAD_ASSERT_UNKNOWN( value_right == end_); - temporary_.push_back(value_left); - next_left = data_[next_left].next; - value_left = data_[next_left].value; - } - while( value_right < end_ ) - { CPPAD_ASSERT_UNKNOWN( value_left == end_); - temporary_.push_back(value_right); - next_right = other.data_[next_right].next; - value_right = other.data_[next_right].value; - } - - // adjust number_not_used_ - size_t number_drop = drop(this_target); - number_not_used_ += number_drop; - - // put new set in linked for this_target - CPPAD_ASSERT_UNKNOWN( temporary_.size() >= 2 ); - size_t index = get_data_index(); - start_[this_target] = index; // start for the union - data_[index].value = 1; // reference count for the union - for(size_t i = 0; i < temporary_.size(); ++i) - { size_t next = get_data_index(); - data_[index].next = next; - data_[next].value = temporary_[i]; // next element in union - index = next; - } - data_[index].next = 0; // end of union - - return; - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_binary_intersection$$ -$spell - setvec -$$ - -$section class list_setvec: Assign a Set To Equal Another Set$$ - -$head SetVector Concept$$ -$cref/binary_intersection/SetVector/binary_intersection/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void binary_intersection( - size_t this_target , - size_t this_left , - size_t other_right , - const list_setvec& other ) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 ); - CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 ); - // - CPPAD_ASSERT_UNKNOWN( this_target < start_.size() ); - CPPAD_ASSERT_UNKNOWN( this_left < start_.size() ); - CPPAD_ASSERT_UNKNOWN( other_right < other.start_.size() ); - CPPAD_ASSERT_UNKNOWN( end_ == other.end_ ); - - // start indices for left and right sets - size_t start_left = start_[this_left]; - size_t start_right = other.start_[other_right]; - - // if left or right is empty, the result is empty - if( (start_left == 0) | (start_right == 0) ) - { clear(this_target); - return; - } - // if niether case holds, then both left and right are non-empty - CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 ); - CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 ); - - // we will use temparary_ for temporary storage of the intersection - temporary_.resize(0); - - // left next and value - size_t next_left = data_[start_left].next; - size_t value_left = data_[next_left].value; - - // right next and value - size_t next_right = other.data_[start_right].next; - size_t value_right = other.data_[next_right].value; - - // both left and right set are non-empty - CPPAD_ASSERT_UNKNOWN( value_left < end_ && value_right < end_ ); - - // flag that detects if left is or right is a subset of the other - bool left_is_subset = true; - bool right_is_subset = true; - - while( (value_left < end_) & (value_right < end_) ) - { if( value_left == value_right ) - { // value is in both sets - temporary_.push_back(value_left); - // - // advance left - next_left = data_[next_left].next; - value_left = data_[next_left].value; - // - // advance right - next_right = other.data_[next_right].next; - value_right = other.data_[next_right].value; - } - else if( value_left < value_right ) - { // there is a value in left that is not in right - left_is_subset = false; - // - // advance left to its next element - next_left = data_[next_left].next; - value_left = data_[next_left].value; - } - else - { CPPAD_ASSERT_UNKNOWN( value_right < value_left ) - // there is a value in right that is not in left - right_is_subset = false; - // - // advance right to its next element - next_right = other.data_[next_right].next; - value_right = other.data_[next_right].value; - } - } - right_is_subset &= value_right == end_; - left_is_subset &= value_left == end_; - // - // check left first in case they are equal will do this assignment - if( left_is_subset ) - { assignment(this_target, this_left, *this); - return; - } - if( right_is_subset ) - { assignment(this_target, other_right, other); - return; - } - - // adjust number_not_used_ - size_t number_drop = drop(this_target); - number_not_used_ += number_drop; - - // check for empty result - if( temporary_.size() == 0 ) - return; - - // put new set in linked for this_target - size_t index = get_data_index(); - start_[this_target] = index; // start for the union - data_[index].value = 1; // reference count for the union - for(size_t i = 0; i < temporary_.size(); ++i) - { size_t next = get_data_index(); - data_[index].next = next; - data_[next].value = temporary_[i]; // next element in union - index = next; - } - data_[index].next = 0; // end of union - - return; - } -// ========================================================================= -}; // END_CLASS_LIST_SETVEC -// ========================================================================= - -// ========================================================================= -class list_setvec_const_iterator { // BEGIN_CLASS_LIST_SETVEC_CONST_ITERATOR -// ========================================================================= - -/* -$begin list_setvec_const_iterator_member_data$$ -$spell - setvec - const_iterator -$$ - -$section class list_setvec_const_iterator private: Member Data$$ - -$head pair_size_t$$ -This type is the same as -$cref/list_setvec pair_size_t/list_setvec_member_data/pair_size_t/$$. - -$head end_$$ -This is -$cref/end_/list_setvec_member_data/end_/$$ -for the $code list_setvec$$ object this iterator refers to. - -$head data_$$ -This is -$cref/data_/list_setvec_member_data/data_/$$ -for the $code list_setvec$$ object this iterator refers to. - -$head next_pair_$$ -Next element in the set that this iterator refers to. -If $code next_pair_.value == end_$$ there are no more elements in the set. - -$head Source Code$$ -$srccode%hpp% */ -private: - typedef list_setvec::pair_size_t pair_size_t; - const size_t end_; - const pod_vector& data_; - pair_size_t next_pair_; -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_const_iterator_ctor$$ -$spell - setvec - const_iterator -$$ - -$section class list_setvec_const_iterator: Constructor$$ - -$head SetVector Concept$$ -$cref/iterator constructor/SetVector/const_iterator/Constructor/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - list_setvec_const_iterator (const list_setvec& list, size_t i) -/* %$$ -$end -*/ - : end_ ( list.end_ ), data_( list.data_ ) - { CPPAD_ASSERT_UNKNOWN( list.post_[i] == 0 ); - // - size_t start = list.start_[i]; - if( start == 0 ) - { next_pair_.next = 0; - next_pair_.value = end_; - } - else - { // value for this entry is reference count for list - CPPAD_ASSERT_UNKNOWN( data_[start].value > 0 ); - - // data index where list truely starts - size_t next = data_[start].next; - CPPAD_ASSERT_UNKNOWN( next != 0 ); - - // true first entry in the list - next_pair_ = data_[next]; - CPPAD_ASSERT_UNKNOWN( next_pair_.value < end_ ); - } - } -/* -------------------------------------------------------------------------------- -$begin list_setvec_const_iterator_dereference$$ -$spell - setvec - const_iterator - Dereference -$$ - -$section class list_setvec_const_iterator: Dereference$$ - -$head SetVector Concept$$ -$cref/iterator deference/SetVector/const_iterator/Dereference/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - size_t operator*(void) - { return next_pair_.value; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin list_setvec_const_iterator_increment$$ -$spell - setvec - const_iterator -$$ - -$section class list_setvec_const_iterator: Increment$$ - -$head SetVector Concept$$ -$cref/iterator increment/SetVector/const_iterator/Increment/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - list_setvec_const_iterator& operator++(void) - { next_pair_ = data_[next_pair_.next]; - return *this; - } -/* %$$ -$end -*/ -// =========================================================================== -}; // END_CLASS_LIST_SETVEC_CONST_ITERATOR -// =========================================================================== - -// Implemented after list_setvec_const_iterator so can use it -inline void list_setvec::print(void) const -{ std::cout << "list_setvec:\n"; - for(size_t i = 0; i < n_set(); i++) - { std::cout << "set[" << i << "] = {"; - const_iterator itr(*this, i); - while( *itr != end() ) - { std::cout << *itr; - if( *(++itr) != end() ) std::cout << ","; - } - std::cout << "}\n"; - } - return; -} -// ---------------------------------------------------------------------------- -/* -$begin sparsity_user2internal_list_setvec$$ -$spell - setvec - std -$$ - -$section Copy A Vector of Standard Sets To A list_setvec Object$$ - -$head SetVector$$ -is a $cref/simple vector/SimpleVector/$$ type with elements of type -$code std::set$$. - -$head internal$$ -The input value of this object does not matter. -Upon return it contains the same sparsity pattern as $icode user$$ -(or its transpose). - -$head user$$ -is the sparsity pattern we are copying to $icode internal$$. - -$head n_set$$ -is the number of sets in the output sparsity pattern $icode internal$$. -If $icode transpose$$ is false, $icode n_set$$ is equal to -$icode%user%.size()%$$. - -$head end$$ -is the end value for the output sparsity pattern $icode internal$$. -$code list_setvec$$ sparsity pattern $icode internal$$. -If $icode transpose$$ is true, $icode end$$ is equal to -$icode%user%.size()%$$. - -$head transpose$$ -If $icode transpose$$ is false, -element $icode j$$ is in the $th i$$ $icode internal$$ set if -$icode j$$ is in the $icode%user%[%i%]%$$. -Otherwise, -element $icode j$$ is in the $th i$$ $icode internal$$ set if -$icode i$$ is in the $icode%user%[%j%]%$$. - -$head error_msg$$ -is the error message to display if some values in the $icode user$$ -sparsity pattern are not valid. - -$head Prototype$$ -$srccode%hpp% */ -template -void sparsity_user2internal( - list_setvec& internal , - const SetVector& user , - size_t n_set , - size_t end , - bool transpose , - const char* error_msg ) -/* %$$ -$end -**/ -{ -# ifndef NDEBUG - if( transpose ) - CPPAD_ASSERT_KNOWN( end == size_t( user.size() ), error_msg); - if( ! transpose ) - CPPAD_ASSERT_KNOWN( n_set == size_t( user.size() ), error_msg); -# endif - - // iterator for user set - std::set::const_iterator itr; - - // size of internal sparsity pattern - internal.resize(n_set, end); - - if( transpose ) - { // transposed pattern case - for(size_t j = 0; j < end; j++) - { itr = user[j].begin(); - while(itr != user[j].end()) - { size_t i = *itr++; - CPPAD_ASSERT_KNOWN(i < n_set, error_msg); - internal.post_element(i, j); - } - } - for(size_t i = 0; i < n_set; ++i) - internal.process_post(i); - } - else - { for(size_t i = 0; i < n_set; i++) - { itr = user[i].begin(); - while(itr != user[i].end()) - { size_t j = *itr++; - CPPAD_ASSERT_KNOWN( j < end, error_msg); - internal.post_element(i, j); - } - internal.process_post(i); - } - } - return; -} - -} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE - -// ========================================================================= -// Tell pod_vector class that each pair_size_t is plain old data and hence -// the corresponding constructor need not be called. -namespace CppAD { namespace local { - template <> inline bool - is_pod(void) - { return true; } -} } - -# endif diff --git a/build-config/cppad/include/cppad/local/sparse/list_setvec.omh b/build-config/cppad/include/cppad/local/sparse/list_setvec.omh deleted file mode 100644 index 5a41db6b..00000000 --- a/build-config/cppad/include/cppad/local/sparse/list_setvec.omh +++ /dev/null @@ -1,32 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------- -$begin list_setvec$$ -$spell - Namespace - CppAD - setvec -$$ - -$section Implement SetVector Using Singly Linked Lists$$ - -$head Namespace$$ -This class is in the $code CppAD::local::sparse$$ namespace. - -$head Public$$ -The public member function for the $code list_setvec$$ class implement the -$cref SetVector$$ concept. - -$childtable% - include/cppad/local/sparse/list_setvec.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/local/sparse/pack_setvec.hpp b/build-config/cppad/include/cppad/local/sparse/pack_setvec.hpp deleted file mode 100644 index 55d80928..00000000 --- a/build-config/cppad/include/cppad/local/sparse/pack_setvec.hpp +++ /dev/null @@ -1,910 +0,0 @@ -# ifndef CPPAD_LOCAL_SPARSE_PACK_SETVEC_HPP -# define CPPAD_LOCAL_SPARSE_PACK_SETVEC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include - -// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE -namespace CppAD { namespace local { namespace sparse { - -// forward declaration of iterator class -class pack_setvec_const_iterator; - -// ============================================================================ -class pack_setvec { -// ============================================================================ -/* -$begin pack_setvec_member_data$$ -$spell - setvec - resize -$$ - -$section class pack_setvec: Private Member Data$$ - -$head Pack$$ -Type used to pack multiple elements of a set (multiple bits) onto one -$icode Pack$$ value. - -$head n_bit_$$ -Number of bits (elements) per $icode Pack$$ value. - -$head zero_$$ -The $icode Pack$$ value with all bits zero. - -$head one_$$ -The $icode Pack$$ value with all bits zero, except for the lowest order bit. - -$head n_set_$$ -Number of sets that we are representing. - -$head end_$$ -The possible elements in each set are $code 0$$, $code 1$$, ..., -$code end_-1$$. - -$head n_pack_$$ -Number of Pack values used to represent one set in the vector; i.e., -to represent $code end_$$ bits. - -$head data_$$ -Data for all of the sets. - -$head Source Code$$ -$srccode%hpp% */ -private: - typedef size_t Pack; - const size_t n_bit_; - const Pack zero_; - const Pack one_; - size_t n_set_; - size_t end_; - size_t n_pack_; - pod_vector data_; -/* %$$ -$end ------------------------------------------------------------------------------ -$begin pack_setvec_vec_memory$$ -$spell - setvec -$$ - -$section class pack_setvec: Approximate Memory Used by Vector$$ - -$head Public$$ -This function is declared public, but is not part of -$cref SetVector$$ concept. - -$head Implementation$$ -$srccode%hpp% */ -public: - size_t memory(void) const - { return data_.capacity() * sizeof(Pack); } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_vec_print$$ -$spell - setvec -$$ - -$section class pack_setvec: Print a Vector of Sets$$ - - -$head Public$$ -This function is declared public, but is not part of -$cref SetVector$$ concept. - -$head Prototype$$ -$srccode%hpp% */ -public: - void print(void) const; -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_iterators$$ -$spell - setvec - Iterators - typedef - const_iterator -$$ - -$section class pack_setvec: Iterators$$ - -$head SetVector Concept$$ -$cref/const_iterator/SetVector/const_iterator/$$ - -$head typedef$$ -$srccode%hpp% */ -public: - /// declare a const iterator - friend class pack_setvec_const_iterator; - typedef pack_setvec_const_iterator const_iterator; -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_default_ctor$$ -$spell - setvec -$$ - -$section class pack_setvec: Default Constructor$$ - -$head SetVector Concept$$ -$cref/constructor/SetVector/Vector Operations/Constructor/$$ - -$head n_bit_$$ -This member variable is set to the number of bits in a $icode Pack$$ value. - -$head one_$$ -This member variable has only its lowest order bit non-zero; - -$head data_$$ -This member is initialized as the empty vector; i.e., size zero.. - -$head Other$$ -All the other member data are $code size_t$$ values -that are initialized as zero. - -$head Implementation$$ -$srccode%hpp% */ -public: - pack_setvec(void) : - n_bit_( std::numeric_limits::digits ), - zero_(0), one_(1), n_set_(0), end_(0), n_pack_(0), data_(0) - { } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_destructor$$ -$spell - setvec -$$ - -$section class pack_setvec: Destructor$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - ~pack_setvec(void) - { } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_copy_ctor$$ -$spell - setvec - CppAD -$$ - -$section class pack_setvec: Copy Constructor$$ - -$head v$$ -The vector of sets that we are attempting to make a copy of. - -$head Implementation$$ -Using the copy constructor is probably due to a $code pack_setvec$$ -being passed by value instead of by reference. -This is a CppAD programing error (not CppAD user error). -$srccode%hpp% */ -public: - pack_setvec(const pack_setvec& v) : - n_bit_( std::numeric_limits::digits ), zero_(0), one_(1) - { CPPAD_ASSERT_UNKNOWN(0); } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_vec_resize$$ -$spell - setvec - resize -$$ - -$section class pack_setvec: Vector resize$$ - -$head SetVector Concept$$ -$cref/vector resize/SetVector/Vector Operations/resize/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void resize(size_t n_set, size_t end) -/* %$$ -$end -*/ - { n_set_ = n_set; - end_ = end; - if( n_set_ == 0 ) - { CPPAD_ASSERT_UNKNOWN( end == 0 ); - data_.clear(); - return; - } - // now start a new vector with empty sets - Pack zero(0); - // - n_pack_ = ( 1 + (end_ - 1) / n_bit_ ); - size_t i = n_set_ * n_pack_; - // - data_.resize(i); - while(i--) - data_[i] = zero; - } -/* %$$ -------------------------------------------------------------------------------- -$begin pack_setvec_vec_n_set$$ -$spell - setvec -$$ - -$section class pack_setvec: Number of Sets$$ - -$head SetVector Concept$$ -$cref/n_set/SetVector/Vector Operations/n_set/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - size_t n_set(void) const - { return n_set_; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_vec_end$$ -$spell - setvec -$$ - -$section class pack_setvec: End Value$$ - -$head SetVector Concept$$ -$cref/end/SetVector/Vector Operations/end/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - size_t end(void) const - { return end_; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_vec_assignment$$ -$spell - setvec -$$ - -$section class pack_setvec: Vector Assignment$$ - -$head SetVector Concept$$ -$cref/vector assignment/SetVector/Vector Operations/Assignment/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void operator=(const pack_setvec& other) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( n_bit_ == other.n_bit_); - CPPAD_ASSERT_UNKNOWN( zero_ == other.zero_); - CPPAD_ASSERT_UNKNOWN( one_ == other.one_); - n_set_ = other.n_set_; - end_ = other.end_; - n_pack_ = other.n_pack_; - data_ = other.data_; - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_vec_swap$$ -$spell - setvec -$$ - -$section class pack_setvec: Vector Swap$$ - -$head SetVector Concept$$ -$cref/vector swap/SetVector/Vector Operations/swap/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void swap(pack_setvec& other) -/* %$$ -$end -*/ - { // size_t objects - CPPAD_ASSERT_UNKNOWN( n_bit_ == other.n_bit_); - CPPAD_ASSERT_UNKNOWN( zero_ == other.zero_); - CPPAD_ASSERT_UNKNOWN( one_ == other.one_); - std::swap(n_set_ , other.n_set_); - std::swap(end_ , other.end_); - std::swap(n_pack_ , other.n_pack_); - // - // pod_vectors - data_.swap(other.data_); - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_number_elements$$ -$spell - setvec -$$ - -$section class pack_setvec: Number of Elements in a Set$$ - -$head SetVector Concept$$ -$cref/number_elements/SetVector/number_elements/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - size_t number_elements(size_t i) const -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( i < n_set_ ); - // - // special case where data_[i] is 0 or 1 - if( end_ == 1 ) - { CPPAD_ASSERT_UNKNOWN( n_pack_ == 1 ); - return size_t( data_[i] ); - } - // - // initialize count of non-zero bits in this set - size_t count = 0; - // - // mask corresonding to first bit in Pack - Pack mask = one_; - // - // number of bits in last Packing unit - size_t n_last = (end_ - 1) % n_bit_ + 1; - // - // count bits in last unit - Pack unit = data_[(i + 1) * n_pack_ - 1]; - for(size_t bit = 0; bit < n_last; ++bit) - { CPPAD_ASSERT_UNKNOWN( mask >= one_ ); - if( mask & unit ) - ++count; - mask = mask << 1; - } - if( n_pack_ == 1 ) - return count; - // - // count bits in other units - for(size_t bit = 0; bit < n_bit_; ++bit) - { CPPAD_ASSERT_UNKNOWN( mask >= one_ ); - size_t k = n_pack_; - while(--k) - { if( data_[i * n_pack_ + k] & mask ) - ++count; - } - mask = mask << 1; - } - return count; - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_add_element$$ -$spell - setvec -$$ - -$section class pack_setvec: Add an Elements to a Set$$ - -$head SetVector Concept$$ -$cref/add_element/SetVector/add_element/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void add_element(size_t i, size_t element) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( i < n_set_ ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - if( end_ == 1 ) - data_[i] |= one_; - else - { size_t j = element / n_bit_; - size_t k = element - j * n_bit_; - Pack mask = one_ << k; - data_[ i * n_pack_ + j] |= mask; - } - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_post_element$$ -$spell - setvec -$$ - -$section class pack_setvec: Add an Elements to a Set$$ - -$head SetVector Concept$$ -$cref/post_element/SetVector/post_element/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - void post_element(size_t i, size_t element) - { add_element(i, element); } -/* %$$ -$end -*/ -/* -------------------------------------------------------------------------------- -$begin pack_setvec_process_post$$ -$spell - setvec -$$ - -$section class pack_setvec: Add Posted Elements to a Set$$ - -$head SetVector Concept$$ -$cref/process_post/SetVector/process_post/$$ - -$head Implementation$$ -$srccode%hpp% */ -public: - void process_post(size_t i) - { return; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_is_element$$ -$spell - setvec -$$ - -$section class pack_setvec: Is an Element in a Set$$ - -$head SetVector Concept$$ -$cref/is_element/SetVector/is_element/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - bool is_element(size_t i, size_t element) const -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( i < n_set_ ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - if( end_ == 1 ) - return data_[i] != zero_; - // - size_t j = element / n_bit_; - size_t k = element - j * n_bit_; - Pack mask = one_ << k; - return (data_[i * n_pack_ + j] & mask) != zero_; - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_clear$$ -$spell - setvec -$$ - -$section class pack_setvec: Assign a Set to be Empty$$ - -$head SetVector Concept$$ -$cref/clear/SetVector/clear/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void clear(size_t target) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( target < n_set_ ); - size_t t = target * n_pack_; - - size_t j = n_pack_; - while(j--) - data_[t++] = zero_; - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_assignment$$ -$spell - setvec -$$ - -$section class pack_setvec: Assign a Set To Equal Another Set$$ - -$head SetVector Concept$$ -$cref/assignment/SetVector/assignment/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void assignment( - size_t this_target , - size_t other_value , - const pack_setvec& other ) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( this_target < n_set_ ); - CPPAD_ASSERT_UNKNOWN( other_value < other.n_set_ ); - CPPAD_ASSERT_UNKNOWN( n_pack_ == other.n_pack_ ); - size_t t = this_target * n_pack_; - size_t v = other_value * n_pack_; - - size_t j = n_pack_; - while(j--) - data_[t++] = other.data_[v++]; - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_binary_union$$ -$spell - setvec -$$ - -$section class pack_setvec: Assign a Set To Equal Union of Two Sets$$ - -$head SetVector Concept$$ -$cref/binary_union/SetVector/binary_union/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void binary_union( - size_t this_target , - size_t this_left , - size_t other_right , - const pack_setvec& other ) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( this_target < n_set_ ); - CPPAD_ASSERT_UNKNOWN( this_left < n_set_ ); - CPPAD_ASSERT_UNKNOWN( other_right < other.n_set_ ); - CPPAD_ASSERT_UNKNOWN( n_pack_ == other.n_pack_ ); - - size_t t = this_target * n_pack_; - size_t l = this_left * n_pack_; - size_t r = other_right * n_pack_; - - size_t j = n_pack_; - while(j--) - data_[t++] = ( data_[l++] | other.data_[r++] ); - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_binary_intersection$$ -$spell - setvec -$$ - -$section class pack_setvec: Assign a Set To Intersection of Two Sets$$ - -$head SetVector Concept$$ -$cref/binary_intersection/SetVector/binary_intersection/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - void binary_intersection( - size_t this_target , - size_t this_left , - size_t other_right , - const pack_setvec& other ) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( this_target < n_set_ ); - CPPAD_ASSERT_UNKNOWN( this_left < n_set_ ); - CPPAD_ASSERT_UNKNOWN( other_right < other.n_set_ ); - CPPAD_ASSERT_UNKNOWN( n_pack_ == other.n_pack_ ); - - size_t t = this_target * n_pack_; - size_t l = this_left * n_pack_; - size_t r = other_right * n_pack_; - - size_t j = n_pack_; - while(j--) - data_[t++] = ( data_[l++] & other.data_[r++] ); - } -// ========================================================================== -}; // END_CLASS_PACK_SETVEC -// ========================================================================== - - -// ========================================================================= -class pack_setvec_const_iterator { // BEGIN_CLASS_PACK_SETVEC_CONST_ITERATOR -// ========================================================================= - -/* -$begin pack_setvec_const_iterator_member_data$$ -$spell - setvec - const_iterator -$$ - -$section class pack_setvec_const_iterator private: Member Data$$ - -$head Pack$$ -This is the same type as -$cref/pack_setvec Pack/pack_setvec_member_data/Pack/$$. - -$head n_bit_$$ -This is a reference to -$cref/pack_setvec n_bit_/pack_setvec_member_data/n_bit_/$$. - -$head one_$$ -This is a reference to -$cref/pack_setvec one_/pack_setvec_member_data/one_/$$. - -$head n_pack_$$ -This is a reference to -$cref/pack_setvec n_pack_/pack_setvec_member_data/n_pack_/$$. - -$head end_$$ -This is a reference to -$cref/pack_setvec end_/pack_setvec_member_data/end_/$$. - -$head data_$$ -This is a reference to -$cref/pack_setvec data_/pack_setvec_member_data/data_/$$. - -$head data_index_$$ -Index in $code data_$$ where the next element is located. - -$head next_element$$ -Value of the next element in this set -If $code next_element_$$ equals $code end_$$, -no next element exists; i.e., past end of the set. - -$head Source Code$$ -$srccode%hpp% */ -private: - typedef pack_setvec::Pack Pack; - const size_t& n_bit_; - const Pack& one_; - const size_t& n_pack_; - const size_t& end_; - const pod_vector& data_; - size_t data_index_; - size_t next_element_; -public: -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_const_iterator_ctor$$ -$spell - setvec - const_iterator -$$ - -$section class pack_setvec_const_iterator: Constructor$$ - -$head SetVector Concept$$ -$cref/iterator constructor/SetVector/const_iterator/Constructor/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - pack_setvec_const_iterator (const pack_setvec& pack, size_t set_index) -/* %$$ -$end -*/ - : - n_bit_ ( pack.n_bit_ ) , - one_ ( pack.one_ ) , - n_pack_ ( pack.n_pack_ ) , - end_ ( pack.end_ ) , - data_ ( pack.data_ ) , - data_index_ ( set_index * n_pack_ ) - { CPPAD_ASSERT_UNKNOWN( set_index < pack.n_set_ ); - CPPAD_ASSERT_UNKNOWN( 0 < end_ ); - // - next_element_ = 0; - if( data_[data_index_] & one_ ) - return; - // - // element with index zero is not in this set of integers, - // advance to first element or end - ++(*this); - } -/* -------------------------------------------------------------------------------- -$begin pack_setvec_const_iterator_dereference$$ -$spell - setvec - const_iterator - Dereference -$$ - -$section class pack_setvec_const_iterator: Dereference$$ - -$head SetVector Concept$$ -$cref/iterator deference/SetVector/const_iterator/Dereference/$$ - -$head Implementation$$ -$srccode%hpp% */ - size_t operator*(void) const - { return next_element_; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin pack_setvec_const_iterator_increment$$ -$spell - setvec - const_iterator -$$ - -$section class pack_setvec_const_iterator: Increment$$ - -$head SetVector Concept$$ -$cref/iterator increment/SetVector/const_iterator/Increment/$$ - -$head Prototype$$ -$srccode%hpp% */ -public: - pack_setvec_const_iterator& operator++(void) -/* %$$ -$end -*/ - { CPPAD_ASSERT_UNKNOWN( next_element_ <= end_ ); - if( next_element_ == end_ ) - return *this; - // - ++next_element_; - if( next_element_ == end_ ) - return *this; - // - // bit index corresponding to next element - size_t bit = next_element_ % n_bit_; - // - // check if we have advanced to the next data index - if( bit == 0 ) - ++data_index_; - // - // initialize mask - size_t mask = one_ << bit; - // - while( next_element_ < end_ ) - { // check if this element is in the set - if( data_[data_index_] & mask ) - return *this; - // - // try next larger element - ++next_element_; - ++bit; - mask <<= 1; - // - // check if we must go to next packed data index - CPPAD_ASSERT_UNKNOWN( bit <= n_bit_ ); - if( bit == n_bit_ ) - { // get next packed value - bit = 0; - mask = one_; - ++data_index_; - } - } - CPPAD_ASSERT_UNKNOWN( next_element_ == end_ ); - return *this; - } -// ========================================================================= -}; // END_CLASS_PACK_SETVEC_CONST_ITERATOR -// ========================================================================= - -// Implemented after pack_setvec_const_iterator so can use it -inline void pack_setvec::print(void) const -{ std::cout << "pack_setvec:\n"; - for(size_t i = 0; i < n_set(); i++) - { std::cout << "set[" << i << "] = {"; - const_iterator itr(*this, i); - while( *itr != end() ) - { std::cout << *itr; - if( *(++itr) != end() ) - std::cout << ","; - } - std::cout << "}\n"; - } - return; -} - -// ---------------------------------------------------------------------------- -/* -$begin sparsity_user2internal_pack_setvec$$ -$spell - setvec - bool -$$ - -$section Copy A Boolean Sparsity Pattern To A pack_setvec Object$$ - -$head SetVector$$ -is a $cref/simple vector/SimpleVector/$$ type with elements of type -$code bool$$ containing the input sparsity pattern. - -$head internal$$ -The input value of this object does not matter. -Upon return it contains the same sparsity pattern as $icode user$$ -(or its transpose). - -$head user$$ -is the sparsity pattern we are copying to $icode internal$$. - -$head n_set$$ -is the number of sets in the output sparsity pattern $icode internal$$. - -$head end$$ -is the end value for the output sparsity pattern $icode internal$$. - -$head transpose$$ -If $icode transpose$$ is false, -element $icode j$$ is in the $th i$$ $icode internal$$ set if -$codei% - %user%[ %i% * %end% + %j% ] -%$$ -Otherwise, -element $icode j$$ is in the $th i$$ $icode internal$$ set if -$codei% - %user%[ %i% * %n_set% + %j% ] -%$$ - -$head error_msg$$ -is the error message to display if -$codei% - %n_set% * %end% != %user%.size() -%$$ - -$head Prototype$$ -$srccode%hpp% */ -template -void sparsity_user2internal( - pack_setvec& internal , - const SetVector& user , - size_t n_set , - size_t end , - bool transpose , - const char* error_msg ) -/* %$$ -$end -*/ -{ CPPAD_ASSERT_KNOWN(size_t( user.size() ) == n_set * end, error_msg ); - - // size of internal sparsity pattern - internal.resize(n_set, end); - - if( transpose ) - { // transposed pattern case - for(size_t j = 0; j < end; j++) - { for(size_t i = 0; i < n_set; i++) - { // no advantage to using post_element for pack_setvec - if( user[ j * n_set + i ] ) - internal.add_element(i, j); - } - } - return; - } - else - { for(size_t i = 0; i < n_set; i++) - { for(size_t j = 0; j < end; j++) - { // no advantage to using post_element for pack_setvec - if( user[ i * end + j ] ) - internal.add_element(i, j); - } - } - } - return; -} - -} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sparse/pack_setvec.omh b/build-config/cppad/include/cppad/local/sparse/pack_setvec.omh deleted file mode 100644 index e68d041d..00000000 --- a/build-config/cppad/include/cppad/local/sparse/pack_setvec.omh +++ /dev/null @@ -1,32 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------- -$begin pack_setvec$$ -$spell - Namespace - CppAD - setvec -$$ - -$section Implement SetVector Using Packed Boolean Values$$ - -$head Namespace$$ -This class is in the $code CppAD::local::sparse$$ namespace. - -$head Public$$ -The public member function for the $code list_setvec$$ class implement the -$cref SetVector$$ concept. - -$childtable% - include/cppad/local/sparse/pack_setvec.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/local/sparse/setvector.omh b/build-config/cppad/include/cppad/local/sparse/setvector.omh deleted file mode 100644 index fb5885c7..00000000 --- a/build-config/cppad/include/cppad/local/sparse/setvector.omh +++ /dev/null @@ -1,254 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -$begin SetVector$$ -$spell - dereference - itr - iterator - const - resize - vec - CppAD - bool -$$ - -$section C++ Concept: Vector of Sets With size_t Elements$$ - -$head Purpose$$ -The main CppAD use of this C++ Concept is to compute sparsity patterns -as fast as possible. -It is also used for conditional expression optimization. -We refer to a type that supports this concept as $icode SetVector$$ below. - -$head Vector Operations$$ - -$subhead Constructor$$ -In the specifications below, $icode vec$$ and $icode other$$ -are $icode SetVector$$ objects created using the default constructor; e.g., -$codei% - %SetVector% %vec%, %other%; -%$$ -After this constructor the vectors are empty; i.e., -there are no sets in either vector. -The $code resize$$ for $icode vec$$ and $icode other$$ can -have different $cref/n_set/SetVector/Vector Operations/n_set/$$ values, -but must have the same $cref/end/SetVector/Vector Operations/end/$$ value. - -$subhead resize$$ -This operation has the following syntax: -$codei% - %vec%.resize(%n_set%, %end%) -%$$ -The argument $icode n_set$$ has type $code size_t$$ and is the -number of sets in $icode vec$$. -The argument $icode end$$ has type $code size_t$$ and is greater than -any element allowed in any set in $icode vec$$. -Any information in $icode vec$$ before this operation is lost. -After this operation, all the sets in $icode vec$$ are empty. -If $icode n_set$$ is zero, -any allocated memory to keep track of this vector of sets is freed. - -$subhead n_set$$ -The syntax -$codei% - %n_set% = %vec%.n_set() -%$$ -sets the $code size_t$$ value $icode n_set$$ equal to the -number of sets in $icode vec$$. -The $icode vec$$ object is $code const$$ for this operation. - -$subhead end$$ -The syntax -$codei% - %end% = %vec%.end() -%$$ -sets the $code size_t$$ value $icode end$$ equal to the -end value for the sets in $icode vec$$. -(This is one greater than the maximum value for any element -in any set in $icode vec$$.) -The $icode vec$$ object is $code const$$ for this operation. - -$subhead Assignment$$ -The following -makes $icode vec$$ into a separate copy of $icode other$$: -$codei% - %vec% = %other% -%$$ -The $icode other$$ object is $code const$$ for this operation. - -$subhead swap$$ -The following -exchanges to vector of sets in $icode vec$$ and $icode other$$: -$codei% - %vec%.swap(%other%) -%$$ - -$head number_elements$$ -If $icode i$$ is a $code size_t$$ value less than $icode n_set$$, -$codei% - %count% = %vec%.number_elements(%i%) -%$$ -returns the $code size_t$$ value $icode count$$ -equal to the number of elements in the $th i$$ set. -The $icode vec$$ object is $code const$$ for this operation. -It is an error to have postings to $th i$$ that have not been processed. - -$head add_element$$ -If $icode i$$ is a $code size_t$$ value less than $icode n_set$$ -and $icode element$$ is a $code size_t$$ value less than $icode end$$, -$codei% - %vec%.add_element(%i%, %element%) -%$$ -adds the specified element to the $th i$$ set. - -$head post_element$$ -If $icode i$$ is a $code size_t$$ value less than $icode n_set$$ -and $icode element$$ is a $code size_t$$ value less than $icode end$$, -$codei% - %vec%.post_element(%i%, %element%) -%$$ -post the specified element for addition to the $th i$$ set. -Posting multiple elements to one set and then processing them may be faster -than adding one element at a time. -It is an error to use $icode vec$$, -in a way that depends on the values in the $th i$$ set, -between a $code post_element$$ and the corresponding $code process_post$$. - -$head process_post$$ -If $icode i$$ is a $code size_t$$ value less than $icode n_set$$, -$codei% - %vec%.process_post(%i%) -%$$ -Processes all of the posts that have been made for the $th i$$ set; i.e., -adds the posted elements to the set. - -$head is_element$$ -If $icode i$$ is a $code size_t$$ value less than $icode n_set$$ -and $icode element$$ is a $code size_t$$ value less than $icode end$$, -$codei% - %find% = %vec%.is_element(%i%, %element%) -%$$ -returns the $code bool$$ value $icode find$$ -which is true (false) if the specified element is in -(is not in) the $th i$$ set. -The $icode vec$$ object is $code const$$ for this operation. - -$head clear$$ -If $icode i$$ is a $code size_t$$ value less than $icode n_set$$, -$codei% - %vec%.clear(%i%) -%$$ -assigns the empty set to the $th i$$ set. -It is OK to have postings to $th i$$ that have not been processed -(they are removed). - -$head assignment$$ -If $icode this_target$$ and $icode other_source$$ -are $code size_t$$ with value less than the end value, -$codei% - %vec%.assignment(%this_target%, %other_source%, %other%) -%$$ -sets the $icode this_target$$ set in $icode vec$$ -equal to the $icode other_source$$ set in $icode other$$. -If $icode vec$$ and $icode other$$ are the same object, -this operation may save memory and time using smart pointers. -The $icode other$$ object is $code const$$ for this operation. -It is OK (is an error) to have postings to $icode this_target$$ -($icode other_source$$) that have not been processed. - -$head binary_union$$ -If $icode this_target$$, $icode this_left$$, and $icode other_right$$ -are $code size_t$$ with value less than the end value, -$codei% - %vec%.binary_union( - %this_target%, %this_left%, %other_right%, %other% - ) -%$$ -sets the $icode this_target$$ set in $icode vec$$ equal to the union of -the $icode this_left$$ set in $icode vec$$ and -the $icode other_right$$ set in $icode other$$. -If the resulting set is equal to the left set (right set), -this operation may use save memory and time using smart pointers -(provided $icode vec$$ and $icode other$$ are the same object), -The $icode other$$ object is $code const$$ for this operation. -It is OK (is an error) to have postings to $icode this_target$$ -($icode this_left$$ and $code other_right$$) that have not been processed. - -$head binary_intersection$$ -If $icode this_target$$, $icode this_left$$, and $icode other_right$$ -are $code size_t$$ with value less than the end value, -$codei% - %vec%.binary_intersection( - %this_target%, %this_left%, %other_right%, %other% - ) -%$$ -sets the $icode this_target$$ set in $icode vec$$ equal to the intersection of -the $icode this_left$$ set in $icode vec$$ and -the $icode other_right$$ set in $icode other$$. -If the resulting set is equal to the left set (right set), -this operation may use save memory and time using smart pointers -(provided $icode vec$$ and $icode other$$ are the same object), -The $icode other$$ object is $code const$$ for this operation. -It is OK (is an error) to have postings to $icode this_target$$ -($icode this_left$$ and $code other_right$$) that have not been processed. - - -$head const_iterator$$ - -$subhead Constructor$$ -Given a $icode SetVector$$ object $icode vec$$, -and a $code size_t$$ index $icode i$$, -a constant iterator $icode itr$$ is constructed as follows: -$codei% - %SetVector%::const_iterator %itr%(%vec%, %i%) -%$$ -After this constructor, $icode itr$$ points to the first -(smallest) element in the $th i$$ set. -The $icode vec$$ object is $code const$$ for this operation. -It is an error to have postings to $th i$$ that have not been processed. - -$subhead Dereference$$ -The operation -$codei% - %element% = *%itr -%$$ -sets the $code size_t$$ value $icode element$$ to the current element value. -If $icode element$$ is equal to value $icode%vec%.end()%$$, -we have iterated through all the elements of the set -($icode element$$ is not in the set). -It is an error to have postings to $th i$$ that have not been processed. - -$subhead Increment$$ -The operation $codei%++%itr%$$ points $icode itr$$ to the next larger -element in the set. -The increment operation is not defined when the value of -$codei%*%itr%$$ is equal to $icode%vec%.end()%$$. -The operation -$codei% - %element% = *(++%itr%) -%$$ -increments the iterator $icode itr$$ and sets $icode element$$ -to the deference after the increment (see dereference above). -It is an error to have postings to $th i$$ that have not been processed. - -$head Implementation$$ -$children% - include/cppad/local/sparse/list_setvec.omh% - include/cppad/local/sparse/pack_setvec.omh -%$$ -$table -$rref list_setvec$$ -$rref pack_setvec$$ -$tend - -$end diff --git a/build-config/cppad/include/cppad/local/sparse/svec_setvec.hpp b/build-config/cppad/include/cppad/local/sparse/svec_setvec.hpp deleted file mode 100644 index 60f58268..00000000 --- a/build-config/cppad/include/cppad/local/sparse/svec_setvec.hpp +++ /dev/null @@ -1,1506 +0,0 @@ -# ifndef CPPAD_LOCAL_SPARSE_SVEC_SETVEC_HPP -# define CPPAD_LOCAL_SPARSE_SVEC_SETVEC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE -namespace CppAD { namespace local { namespace sparse { - -/*! -\file svec_setvec.hpp -Vector of sets of positive integers stored as size_t vector -with the element values strictly increasing. - -Testing indicates this does not work as well as using sparse::list_setvec -(not currently being used except by test_more/general/local/vector_set.cpp). -*/ -class svec_setvec_const_iterator; - -// ========================================================================= -/*! -Vector of sets of positive integers, each set stored as a size_t vector. - -All the public members for this class are also in the -sparse::pack_setvec and sparse::list_setvec classes. -This defines the CppAD vector_of_sets concept. -*/ -class svec_setvec { - friend class svec_setvec_const_iterator; -private: - /// Possible elements in each set are 0, 1, ..., end_ - 1; - size_t end_; - - /// number of elements in data_ that have been allocated - /// and are no longer being used. - size_t data_not_used_; - - /// The data for all the singly linked lists. - pod_vector data_; - - /*! - Starting point for i-th set is start_[i]. - - \li - If the i-th set has no elements, start_[i] is zero. - Othersize the conditions below hold. - - \li - data_[ start_[i] ] is the reference count for this set - - \li - data_[ start_[i] + 1 ] is the first element in this set. - - \li - data_[ start_[i] + 2 ] is the first element in this set. - - \li - data_[ start_[i] + 2 + n ] = end_ where n is the number of - elements in this set - */ - pod_vector start_; - - /*! - Vectors of elements that have not yet been added to corresponding sets. - - \li - If all the post_element calls for the i-th set have been added, - post_[i] is zero. Otherwise the conditions below hold. - - \li - data_[ post_[i] ] the number of elements that have been posted, - but not yet added, to set i. - - \li - data_[ post_[i] + 1 ] is the capacity for holding elements - which is greater than or equal the number of elements. - - \li - data_[ post_[i] + 2 ] is the first element that has been posted, - but not yet added, to set i. - - \li - data_[ post_[i] + 1 + n] is the last element that has been posted, - but not yet added, to set i. - Here n is the number of elements that are posted and not yet added - to set i. - */ - pod_vector post_; - // ----------------------------------------------------------------- - /*! - Counts references to a set. - - \param i - is the index of the set that we are counting the references to. - - \return - if the set is empty, the return value is zero. - Otherwise it is the number of sets that share the same vector. - */ - size_t reference_count(size_t i) const - { // start data index - size_t start = start_[i]; - if( start == 0 ) - return 0; - // - // reference count - return data_[start]; - } - // ----------------------------------------------------------------- - /*! - drop a set. - - \param i - is the index of the set that will be dropped. - - \par reference_count - if the set is non-empty, - the reference count corresponding to index will be decremented. - - \return - is the number of elements of data_ that will be lost when the set is - dropped. This is non-zero when the initial reference count is one. - */ - size_t drop(size_t i) - { - // reference count - size_t ref_count = reference_count(i); - - // empty set case - if( ref_count == 0 ) - return 0; - - // start - size_t start = start_[i]; - CPPAD_ASSERT_UNKNOWN( data_[start] == ref_count ); - - // decrement reference counter - data_[start]--; - - // nothing lost unless new reference count is zero - if( ref_count != 1 ) - return 0; - - // number of elements in the set - size_t length = data_[start + 1]; - - // reference count, length, end marker, plus elements in set - size_t number_lost = 3 + length; - - // number_lost - return number_lost; - } - // ----------------------------------------------------------------- - /*! - Checks data structure - (effectively const, but modifies and restores values) - */ -# ifdef NDEBUG - void check_data_structure(void) - { return; } -# else - void check_data_structure(void) - { // number of sets - CPPAD_ASSERT_UNKNOWN( post_.size() == start_.size() ); - size_t n_set = start_.size(); - if( n_set == 0 ) - { CPPAD_ASSERT_UNKNOWN( end_ == 0 ); - CPPAD_ASSERT_UNKNOWN( data_not_used_ == 0 ); - CPPAD_ASSERT_UNKNOWN( data_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( start_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( post_.size() == 0 ); - return; - } - // ------------------------------------------------------------------ - // save the reference counters - pod_vector ref_count(n_set); - for(size_t i = 0; i < n_set; i++) - ref_count[i] = reference_count(i); - // ------------------------------------------------------------------ - - // ------------------------------------------------------------------ - // count the number of entries in data_ that are used by sets - size_t data_used_by_sets = 0; - for(size_t i = 0; i < n_set; i++) - { size_t start = start_[i]; - if( start > 0 ) - { // check structure for this non-empty set - size_t reference_count = data_[start + 0]; - size_t length = data_[start + 1]; - size_t first = data_[start + 2]; - size_t last = data_[start + 2 + length]; - CPPAD_ASSERT_UNKNOWN( reference_count > 0 ); - CPPAD_ASSERT_UNKNOWN( length > 0 ); - CPPAD_ASSERT_UNKNOWN( first < end_); - CPPAD_ASSERT_UNKNOWN( last == end_); - // - // decrement the reference counter - data_[start]--; - // - // count the entries when find last reference - if( data_[start] == 0 ) - { - // restore reference count - data_[start] = ref_count[i]; - - // number of data_ entries used for this set - data_used_by_sets += number_elements(i) + 3; - } - } - } - // ------------------------------------------------------------------ - // count the number of entries in data_ that are used by posts - size_t data_used_by_posts = 0; - for(size_t i = 0; i < n_set; i++) - { size_t post = post_[i]; - if( post > 0 ) - { CPPAD_ASSERT_UNKNOWN( data_[post] > 0 ); - CPPAD_ASSERT_UNKNOWN( data_[post + 1] > 0 ); - CPPAD_ASSERT_UNKNOWN( data_[post + 2] < end_ ); - // - size_t capacity = data_[post + 1]; - data_used_by_posts += capacity + 2; - } - } - // ------------------------------------------------------------------ - size_t data_used = data_used_by_sets + data_used_by_posts; - CPPAD_ASSERT_UNKNOWN( - data_used + data_not_used_ == data_.size() - ); - return; - } -# endif - // ----------------------------------------------------------------- - /*! - Check if one of two sets is a subset of the other set - - \param one_this - is the index in this svec_setvec object of the first set. - - \param two_other - is the index in other svec_setvec object of the second set. - - \param other - is the other svec_setvec object which may be the same as this object. - - \return - If zero, niether set is a subset of the other. - If one, then one is a subset of two and they are not equal. - If two, then two is a subset of one and they are not equal. - If three, then the sets are equal. - */ - size_t is_subset( - size_t one_this , - size_t two_other , - const svec_setvec& other ) const - { - CPPAD_ASSERT_UNKNOWN( one_this < start_.size() ); - CPPAD_ASSERT_UNKNOWN( two_other < other.start_.size() ); - CPPAD_ASSERT_UNKNOWN( end_ == other.end_ ); - // - // start - size_t start_one = start_[one_this]; - size_t start_two = other.start_[two_other]; - // - if( start_one == 0 ) - { // set one is empty - if( start_two == 0 ) - { // set two is empty - return 3; - } - // set one is empty and two is not empty - return 1; - } - if( start_two == 0 ) - { // set two is empty and one is not empty - return 2; - } - // - // data index - size_t index_one = start_one + 2; - size_t index_two = start_two + 2; - // - // value - size_t value_one = data_[index_one]; - size_t value_two = other.data_[index_two]; - // - bool one_subset = true; - bool two_subset = true; - // - size_t value_union = std::min(value_one, value_two); - while( (one_subset | two_subset) & (value_union < end_) ) - { // - if( value_one > value_union ) - two_subset = false; - else - { // value_one <= value_two and value_one < end_ - value_one = data_[++index_one]; - } - // - if( value_two > value_union ) - one_subset = false; - else - { // value_two <= value_one and value_two < end_ - value_two = other.data_[++index_two]; - } - value_union = std::min(value_one, value_two); - } - if( one_subset ) - { if( two_subset ) - { // sets are equal - return 3; - } - // one is a subset of two - return 1; - } - if( two_subset ) - { // two is a subset of one - return 2; - } - // - // neither is a subset - return 0; - } - // ----------------------------------------------------------------- - /*! - Does garbage collection when indicated. - - This routine should be called when more entries are not being used. - If a significant propotion are not being used, the data structure - will be compacted. - - The size of data_ should equal the number of entries used by the sets - plus the number of entries that are not being used data_not_used_. - Note that data_[0] never gets used. - */ - void collect_garbage(void) - { if( data_not_used_ < data_.size() / 2 + 100) - return; - check_data_structure(); - // - // number of sets including empty ones - size_t n_set = start_.size(); - // - // use temporary to hold copy of data_ and start_ - pod_vector data_tmp(1); // data_tmp[0] will not be used - pod_vector start_tmp(n_set); - // - for(size_t i = 0; i < n_set; i++) - { size_t start = start_[i]; - if( start == 0 ) - start_tmp[i] = 0; - else - { // check if this set has already been copied - if( data_[start] == 0 ) - { // starting address in data_tmp has been stored here - start_tmp[i] = data_[start + 1]; - } - else - { size_t tmp_start = data_tmp.extend(2); - start_tmp[i] = tmp_start; - data_tmp[tmp_start + 0] = data_[start + 0]; - data_tmp[tmp_start + 1] = data_[start + 1]; - // - for(size_t j = 2; data_[start + j] != end_; ++j) - data_tmp.push_back( data_[start + j] ); - data_tmp.push_back(end_); - // - // flag that indicates this set already copied - data_[start] = 0; - // - // store the starting address here - data_[start + 1] = tmp_start; - } - } - } - - // swap the tmp and old data vectors - start_.swap(start_tmp); - data_.swap(data_tmp); - - // all of the elements, except the first, are used - data_not_used_ = 1; - } - // ----------------------------------------------------------------- - /*! - Assign a set equal to the union of a set and a vector; - - \param target - is the index in this svec_setvec object of the set being assinged. - - \param left - is the index in this svec_setvec object of the - left operand for the union operation. - It is OK for target and left to be the same value. - - \param right - is a vector of size_t, sorted in accending order. - right operand for the union operation. - Elements can be repeated in right, but are not be repeated in the - resulting set. - All of the elements must have value less than end(); - */ - void binary_union( - size_t target , - size_t left , - const pod_vector& right ) - { CPPAD_ASSERT_UNKNOWN( post_[left] == 0 ); - // - CPPAD_ASSERT_UNKNOWN( target < start_.size() ); - CPPAD_ASSERT_UNKNOWN( left < start_.size() ); - - size_t start_left = start_[left]; - // ------------------------------------------------------------------- - // Check if right is a subset of left so that we used reference count - // and not make copies of identical sets. - // - // initialize index for left and right sets - size_t current_left = start_left; - size_t current_right = 0; - // - // initialize value_left - size_t value_left = end_; - if( current_left > 0 ) - { // advance from reference counter to data - current_left = current_left + 2; - value_left = data_[current_left]; - CPPAD_ASSERT_UNKNOWN( value_left < end_); - } - // - // initialize value_right - size_t value_right = end_; - if( right.size() > 0 ) - value_right = right[current_right]; - // - bool subset = true; - while( subset & (value_right < end_) ) - { while( value_left < value_right ) - { // advance left - value_left = data_[++current_left]; - } - if( value_right < value_left ) - subset = false; - else - { // advance right - ++current_right; - if( current_right == right.size() ) - value_right = end_; - else - value_right = right[current_right]; - } - } - // - if( subset ) - { // target = left will use reference count for identical sets - assignment(target, left, *this); - return; - } - - // ------------------------------------------------------------------- - // number of elements that will be deleted by removing old version - // of target - size_t number_lost = drop(target); - - // drop any posting for the target set - size_t post = post_[target]; - if( post > 0 ) - { CPPAD_ASSERT_UNKNOWN( target != left ); - size_t capacity = data_[post + 1]; - number_lost += capacity + 2; - post_[target] = 0; - } - // - // start new version of target - size_t start = data_.extend(2); - start_[target] = start; - data_[start] = 1; // reference count - // data_[start + 1] = length is not yet known - // - // initialize value_left - current_left = start_left; - value_left = end_; - if( current_left > 0 ) - { // advance from reference counter to data - current_left = current_left + 2; - value_left = data_[current_left]; - CPPAD_ASSERT_UNKNOWN( value_left < end_); - } - // - // initialize value_right - value_right = end_; - if( right.size() > 0 ) - value_right = right[current_right]; - // - // merge - while( (value_left < end_) | (value_right < end_) ) - { if( value_left == value_right) - { // advance left so left and right are no longer equal - ++current_left; - value_left = data_[current_left]; - CPPAD_ASSERT_UNKNOWN( value_right < value_left ); - } - // - if( value_left < value_right ) - { // value_left case - CPPAD_ASSERT_UNKNOWN( value_left < end_ ); - data_.push_back( value_left ); - // - // advance left - ++current_left; - value_left = data_[current_left]; - } - else - { CPPAD_ASSERT_UNKNOWN( value_right < value_left ) - // value_right case - CPPAD_ASSERT_UNKNOWN( value_right < end_); - data_.push_back( value_right ); - // - // advance right (skip values equal to this one) - size_t previous_value = value_right; - while( value_right == previous_value ) - { ++current_right; - if( current_right == right.size() ) - value_right = end_; - else - { value_right = right[current_right]; - CPPAD_ASSERT_UNKNOWN( value_right < end_ ); - } - } - } - } - // make end of target list - data_.push_back( end_ ); - // - // reference count, length, and end_ are not elements of set - CPPAD_ASSERT_UNKNOWN( data_.size() > start + 3 ); - size_t length = data_.size() - (start + 3); - data_[start + 1] = length; - // - - // adjust data_not_used_ - data_not_used_ += number_lost; - collect_garbage(); - } -public: - /// declare a const iterator - typedef svec_setvec_const_iterator const_iterator; - // ----------------------------------------------------------------- - /*! - Default constructor (no sets) - */ - svec_setvec(void) : - end_(0) , - data_not_used_(0) , - data_(0) , - start_(0) , - post_(0) - { } - // ----------------------------------------------------------------- - /// Destructor - ~svec_setvec(void) - { check_data_structure(); - } - // ----------------------------------------------------------------- - /*! - Using copy constructor is a programing (not user) error - - \param v - vector of sets that we are attempting to make a copy of. - */ - svec_setvec(const svec_setvec& v) - { // Error: Probably a svec_setvec argument has been passed by value - CPPAD_ASSERT_UNKNOWN(false); - } - // ----------------------------------------------------------------- - /*! - Assignement operator. - - \param other - this svec_setvec with be set to a deep copy of other. - */ - void operator=(const svec_setvec& other) - { end_ = other.end_; - data_not_used_ = other.data_not_used_; - data_ = other.data_; - start_ = other.start_; - post_ = other.post_; - } - // ----------------------------------------------------------------- - /*! - swap (used by move semantics version of ADFun assignment operator) - - \param other - this sparse::list_setvec with be swapped with other. - - \par vector_of_sets - This public member function is not yet part of - the vector_of_sets concept. - */ - void swap(svec_setvec& other) - { // size_t objects - std::swap(end_ , other.end_); - std::swap(data_not_used_ , other.data_not_used_); - - // pod_vectors - data_.swap( other.data_); - start_.swap( other.start_); - post_.swap( other.post_); - } - // ----------------------------------------------------------------- - /*! - Start a new vector of sets. - - \param n_set - is the number of sets in this vector of sets. - \li - If n_set is zero, any memory currently allocated for this object - is freed. - \li - If n_set is non-zero, a vector of n_set sets is created and all - the sets are initilaized as empty. - - \param end - is the maximum element plus one (the minimum element is 0). - If n_set is zero, end must also be zero. - */ - void resize(size_t n_set, size_t end) - { check_data_structure(); - - if( n_set == 0 ) - { CPPAD_ASSERT_UNKNOWN(end == 0 ); - // - // restore object to start after constructor - // (no memory allocated for this object) - data_.clear(); - start_.clear(); - post_.clear(); - data_not_used_ = 0; - end_ = 0; - // - return; - } - end_ = end; - // - start_.resize(n_set); - post_.resize(n_set); - for(size_t i = 0; i < n_set; i++) - { start_[i] = 0; - post_[i] = 0; - } - // - data_.resize(1); // first element is not used - data_not_used_ = 1; - } - // ----------------------------------------------------------------- - /*! - Return number of elements in a set. - - \param i - is the index of the set we are checking number of the elements of. - */ - size_t number_elements(size_t i) const - { CPPAD_ASSERT_UNKNOWN( post_[i] == 0 ); - // - size_t start = start_[i]; - if( start == 0 ) - return 0; - return data_[start + 1]; - } - // ------------------------------------------------------------------ - /*! - Post an element for delayed addition to a set. - - \param i - is the index for this set in the vector of sets. - - \param element - is the value of the element that we are posting. - The same element may be posted multiple times. - - \par - It is faster to post multiple elements to set i and then call - process_post(i) then to add each element individually. - It is an error to call any member function, - that depends on the value of set i, - before processing the posts to set i. - */ - void post_element(size_t i, size_t element) - { CPPAD_ASSERT_UNKNOWN( i < start_.size() ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - - size_t post = post_[i]; - if( post == 0 ) - { // minimum capacity for an post vector - size_t min_capacity = 10; - size_t post_new = data_.extend(min_capacity + 2); - data_[post_new] = 1; // length - data_[post_new + 1] = min_capacity; // capacity - data_[post_new + 2] = element; - post_[i] = post_new; - } - else - { size_t length = data_[post]; - size_t capacity = data_[post + 1]; - if( length == capacity ) - { - size_t post_new = data_.extend( 2 * capacity ); - // - data_[post_new] = length + 1; - data_[post_new + 1] = 2 * capacity; - // - for(size_t j = 0; j < length; j++) - data_[post_new + 2 + j] = data_[post + 2 + j]; - data_[post_new + 2 + length] = element; - // - post_[i] = post_new; - size_t number_lost = length + 2; - data_not_used_ += number_lost; - } - else - { data_[post] = length + 1; - data_[post + 2 + length] = element; - } - } - - // check amount of data_not_used_ - collect_garbage(); - - return; - } - // ----------------------------------------------------------------- - /*! - process post entries for a specific set. - - \param i - index of the set for which we are processing the post entries. - - \par post_ - Upon call, post_[i] is location in data_ of the elements that get - added to the i-th set. Upon return, post_[i] is zero. - */ - void process_post(size_t i) - { // start - size_t start = start_[i]; - // post - size_t post = post_[i]; - // - // check if there are no elements to process - if( post == 0 ) - return; - // - // sort the elements that need to be processed - size_t length_post = data_[post]; - size_t capacity_post = data_[post + 1]; - size_t* first_post = data_.data() + post + 2; - size_t* last_post = first_post + length_post; - std::sort(first_post, last_post); - // ------------------------------------------------------------------- - // check if posted elements are a subset of set - // - // first element of the set - size_t current_set = start; - size_t value_set = end_; - if( start > 0 ) - { current_set = start + 2; - value_set = data_[current_set]; - } - // - // first element to post - size_t* current_post = first_post; - size_t value_post = *current_post; - // - bool subset = true; - while( subset & (value_post != end_) ) - { while( value_set < value_post ) - value_set = data_[++current_set]; - if( value_post < value_set ) - subset = false; - else - { ++current_post; - if( current_post == last_post ) - value_post = end_; - else - value_post = *current_post; - } - } - // - if( subset ) - { // drop the post_ elements - post_[i] = 0; - // - size_t number_lost = capacity_post + 2; - data_not_used_ += number_lost; - collect_garbage(); - // - // nothing else to do - return; - } - // ------------------------------------------------------------------- - // number of element that will be lost by removing old i-th set - size_t number_lost = drop(i); - - // start new version of i-th set - size_t start_new = data_.extend(2); - start_[i] = start_new; - data_[start_new] = 1; // reference count - // data[start_new + 1] = length_new is not yet known - // - // first element of the set - current_set = start; - value_set = end_; - if( start > 0 ) - { current_set = start + 2; - value_set = data_[current_set]; - } - // - // first element to process - current_post = first_post; - value_post = *current_post; - // - // merge - while( (value_set < end_) | (current_post != last_post ) ) - { if( value_set == value_post ) - { // advance left so left and right are no longer equal - ++current_set; - value_set = data_[current_set]; - CPPAD_ASSERT_UNKNOWN( value_post < value_set ); - } - // - if( value_set < value_post ) - { // add value_set - CPPAD_ASSERT_UNKNOWN( value_set < end_ ); - data_.push_back( value_set ); - // - // advance set - ++current_set; - value_set = data_[current_set]; - } - else - { CPPAD_ASSERT_UNKNOWN( value_post < value_set ) - // add value_post - CPPAD_ASSERT_UNKNOWN( value_post < end_); - data_.push_back( value_post ); - // - // advance post (skip values equal to this one) - size_t value_previous = value_post; - while( value_post == value_previous ) - { ++current_post; - if( current_post == last_post ) - value_post = end_; - else - value_post = *current_post; - } - } - } - // make end of target list - data_.push_back( end_ ); - // - // reference count, length, and end_ are not elements of set - CPPAD_ASSERT_UNKNOWN( data_.size() > start_new + 3 ); - size_t length_new = data_.size() - (start_new + 3); - data_[start_new + 1] = length_new; - CPPAD_ASSERT_UNKNOWN( data_[start_new + length_new + 2] == end_ ); - // - // drop to post_ elements for this set - post_[i] = 0; - // - number_lost += capacity_post + 2; - data_not_used_ += number_lost; - collect_garbage(); - // - return; - } - // ----------------------------------------------------------------- - /*! - Add one element to a set. - - \param i - is the index for this set in the vector of sets. - - \param element - is the element we are adding to the set. - */ - void add_element(size_t i, size_t element) - { CPPAD_ASSERT_UNKNOWN( i < start_.size() ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - - // check if element is already in the set - if( is_element(i, element) ) - return; - - // check for case where old set is empty - size_t start = start_[i]; - if( start == 0 ) - { start = data_.extend(4); - start_[i] = start; - data_[start] = 1; // reference count - data_[start + 1] = 1; // length - data_[start + 2] = element; // the element - data_[start + 3] = end_; // end marker - return; - } - // - size_t number_lost = drop(i); - // - // start of new set - size_t length = data_[start + 1]; - size_t new_start = data_.extend(2); - data_[new_start] = 1; // reference count - data_[new_start + 1] = length + 1; // new length - // - size_t count = 0; - size_t value = data_[start + 2 + count]; - // before new element - while( value < element) - { data_.push_back( value ); - ++count; - value = data_[start + 2 + count]; - } - CPPAD_ASSERT_UNKNOWN( element < value ) - // new element - data_.push_back( element ); - // after new element - while( value < end_ ) - { data_.push_back( value ); - ++count; - value = data_[start + 2 + count]; - } - data_.push_back( end_ ); - - // - // connect up new set - start_[i] = new_start; - - // adjust data_not_used_ - data_not_used_ += number_lost; - collect_garbage(); - // - return; - } - // ----------------------------------------------------------------- - /*! - Check if an element is in a set. - - \param i - is the index for this set in the vector of sets. - - \param element - is the element we are checking to see if it is in the set. - */ - bool is_element(size_t i, size_t element) const - { CPPAD_ASSERT_UNKNOWN( post_[i] == 0 ); - CPPAD_ASSERT_UNKNOWN( element < end_ ); - // - size_t start = start_[i]; - if( start == 0 ) - return false; - // - size_t length = data_[start + 1]; - const size_t* first = data_.data() + start + 2; - const size_t* last = first + length; - if( length < 10 ) - { bool result = false; - while( last > first ) - result |= *(--last) == element; - return result; - } - // - return std::binary_search(first, last, element); - } - // ----------------------------------------------------------------- - /*! - Assign the empty set to one of the sets. - - \param target - is the index of the set we are setting to the empty set. - - \par data_not_used_ - increments this value by number of data_ elements that are lost - (unlinked) by this operation. - */ - void clear(size_t target) - { - // number of data_ elements used for this set - size_t number_lost = drop( target ); - - // set target to empty set - start_[target] = 0; - - // drop the posted elements - if( post_[target] != 0 ) - { size_t capacity = post_[target + 1]; - number_lost += capacity + 2; - // - post_[target] = 0; - } - - // adjust data_not_used_ - data_not_used_ += number_lost; - collect_garbage(); - } - // ----------------------------------------------------------------- - /*! - Assign one set equal to another set. - - \param this_target - is the index in this svec_setvec object of the set being assinged. - - \param other_source - is the index in the other svec_setvec object of the - set that we are using as the value to assign to the target set. - - \param other - is the other svec_setvec object (which may be the same as this - svec_setvec object). This must have the same value for end_. - - \par data_not_used_ - increments this value by number of elements lost. - */ - void assignment( - size_t this_target , - size_t other_source , - const svec_setvec& other ) - { CPPAD_ASSERT_UNKNOWN( other.post_[ other_source ] == 0 ); - // - CPPAD_ASSERT_UNKNOWN( this_target < start_.size() ); - CPPAD_ASSERT_UNKNOWN( other_source < other.start_.size() ); - CPPAD_ASSERT_UNKNOWN( end_ == other.end_ ); - - // check if we are assigning a set to itself - if( (this == &other) & (this_target == other_source) ) - return; - - // number of elements that will be deleted by this operation - size_t number_lost = drop(this_target); - - // drop any posting for the target set - size_t post = post_[this_target]; - if( post > 0 ) - { // do not need to worry about target being same as source - size_t capacity = data_[post + 1]; - number_lost += capacity + 2; - post_[this_target] = 0; - } - - // If this and other are the same, use another reference to same list - size_t other_start = other.start_[other_source]; - if( this == &other ) - { CPPAD_ASSERT_UNKNOWN( this_target != other_source ); - start_[this_target] = other_start; - if( other_start != 0 ) - { // increment reference count - data_[other_start]++; - } - } - else if( other_start == 0 ) - { // the target list is empty - start_[this_target] = 0; - } - else - { // make a copy of the other list in this svec_setvec - size_t length = other.data_[other_start + 1]; - size_t this_start = data_.extend(2); - start_[this_target] = this_start; - data_[this_start] = 1; // reference count - data_[this_start + 1] = length; // length - for(size_t j = 0; j < length; ++j) - data_.push_back( other.data_[other_start + 2 + j] ); - data_.push_back(end_); - } - - // adjust data_not_used_ - data_not_used_ += number_lost; - collect_garbage(); - } - // ----------------------------------------------------------------- - /*! - Assign a set equal to the union of two other sets. - - \param this_target - is the index in this svec_setvec object of the set being assinged. - - \param this_left - is the index in this svec_setvec object of the - left operand for the union operation. - It is OK for this_target and this_left to be the same value. - - \param other_right - is the index in the other svec_setvec object of the - right operand for the union operation. - It is OK for this_target and other_right to be the same value. - - \param other - is the other svec_setvec object (which may be the same as this - svec_setvec object). - */ - void binary_union( - size_t this_target , - size_t this_left , - size_t other_right , - const svec_setvec& other ) - { CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 ); - CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 ); - // - CPPAD_ASSERT_UNKNOWN( this_target < start_.size() ); - CPPAD_ASSERT_UNKNOWN( this_left < start_.size() ); - CPPAD_ASSERT_UNKNOWN( other_right < other.start_.size() ); - CPPAD_ASSERT_UNKNOWN( end_ == other.end_ ); - - // check if one of the two operands is a subset of the the other - size_t subset = is_subset(this_left, other_right, other); - - // case where right is a subset of left or right and left are equal - if( subset == 2 || subset == 3 ) - { assignment(this_target, this_left, *this); - return; - } - // case where the left is a subset of right and they are not equal - if( subset == 1 ) - { assignment(this_target, other_right, other); - return; - } - // if niether case holds, then both left and right are non-empty - CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 ); - CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 ); - - // must get all the start indices before modify start_this - // (in case start_this is the same as start_left or start_right) - size_t start_left = start_[this_left]; - size_t start_right = other.start_[other_right]; - - // number of list elements that will be deleted by this operation - size_t number_lost = drop(this_target); - - // drop any posting for the target set - size_t post = post_[this_target]; - if( post > 0 ) - { // do not need to worry about target being same as left or right - size_t capacity = data_[post + 1]; - number_lost += capacity + 2; - post_[this_target] = 0; - } - - // start the new list - size_t start = data_.extend(2); - start_[this_target] = start; - data_[start] = 1; // reference count - // data_[start + 1] = length is not yet known - - // initilaize left - CPPAD_ASSERT_UNKNOWN( start_left != 0 ); - size_t current_left = start_left + 2; - size_t value_left = data_[current_left]; - CPPAD_ASSERT_UNKNOWN( value_left < end_ ); - - // initilaize right - CPPAD_ASSERT_UNKNOWN( start_right != 0 ); - size_t current_right = start_right + 2; - size_t value_right = other.data_[current_right]; - CPPAD_ASSERT_UNKNOWN( value_right < end_ ); - - - CPPAD_ASSERT_UNKNOWN( value_left < end_ && value_right < end_ ); - while( (value_left < end_) | (value_right < end_) ) - { if( value_left == value_right ) - { // advance right so left and right are no longer equal - ++current_right; - value_right = other.data_[current_right]; - } - if( value_left < value_right ) - { data_.push_back( value_left ); - // advance left to its next element - ++current_left; - value_left = data_[current_left]; - } - else - { CPPAD_ASSERT_UNKNOWN( value_right < value_left ) - data_.push_back( value_right ); - // advance right to its next element - ++current_right; - value_right = other.data_[current_right]; - } - } - // make end of target list - data_.push_back( end_ ); - // - // reference count, length, and end_ are not elements of set - CPPAD_ASSERT_UNKNOWN( data_.size() > start + 3 ); - size_t length = data_.size() - (start + 3); - data_[start + 1] = length; - - // adjust data_not_used_ - data_not_used_ += number_lost; - collect_garbage(); - } - // ----------------------------------------------------------------- - /*! - Assign a set equal to the intersection of two other sets. - - \param this_target - is the index in this svec_setvec object of the set being assinged. - - \param this_left - is the index in this svec_setvec object of the - left operand for the intersection operation. - It is OK for this_target and this_left to be the same value. - - \param other_right - is the index in the other svec_setvec object of the - right operand for the intersection operation. - It is OK for this_target and other_right to be the same value. - - \param other - is the other svec_setvec object (which may be the same as this - svec_setvec object). - */ - void binary_intersection( - size_t this_target , - size_t this_left , - size_t other_right , - const svec_setvec& other ) - { CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 ); - CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 ); - // - CPPAD_ASSERT_UNKNOWN( this_target < start_.size() ); - CPPAD_ASSERT_UNKNOWN( this_left < start_.size() ); - CPPAD_ASSERT_UNKNOWN( other_right < other.start_.size() ); - CPPAD_ASSERT_UNKNOWN( end_ == other.end_ ); - // - // check if one of the two operands is a subset of the the other - size_t subset = is_subset(this_left, other_right, other); - - // case where left is a subset of right or left and right are equal - if( subset == 1 || subset == 3 ) - { assignment(this_target, this_left, *this); - return; - } - // case where the right is a subset of left and they are not equal - if( subset == 2 ) - { assignment(this_target, other_right, other); - return; - } - // if niether case holds, then both left and right are non-empty - CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 ); - CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 ); - - // must get all the start indices before modify start_this - // (in case start_this is the same as start_left or start_right) - size_t start_left = start_[this_left]; - size_t start_right = other.start_[other_right]; - - - // number of list elements that will be deleted by this operation - size_t number_lost = drop(this_target); - - // drop any posting for the target set - size_t post = post_[this_target]; - if( post > 0 ) - { // do not need to worry about target being same as left or right - size_t capacity = data_[post + 1]; - number_lost += capacity + 2; - post_[this_target] = 0; - } - - // initialize intersection as empty - size_t start = 0; - start_[this_target] = start; - - // initilaize left - CPPAD_ASSERT_UNKNOWN( start_left != 0 ); - size_t current_left = start_left + 2; - size_t value_left = data_[current_left]; - CPPAD_ASSERT_UNKNOWN( value_left < end_ ); - - // initilaize right - CPPAD_ASSERT_UNKNOWN( start_right != 0 ); - size_t current_right = start_right + 2; - size_t value_right = other.data_[current_right]; - CPPAD_ASSERT_UNKNOWN( value_right < end_ ); - - while( (value_left < end_) & (value_right < end_) ) - { if( value_left == value_right ) - { if( start == 0 ) - { // this is the first element in the intersection - start = data_.extend(2); - start_[this_target] = start; - data_[start] = 1; // reference count - // data_[start + 1] = length is not yet known - } - data_.push_back( value_left ); - // - // advance left to its next element - ++current_left; - value_left = data_[current_left]; - } - if( value_left > value_right ) - { // advance right - ++current_right; - value_right = other.data_[current_right]; - } - if( value_right > value_left ) - { // advance left - ++current_left; - value_left = data_[current_left]; - } - } - if( start != 0 ) - { data_.push_back(end_); - CPPAD_ASSERT_UNKNOWN( data_.size() > start + 3 ); - size_t length = data_.size() - (start + 3); - data_[start + 1] = length; - } - - // adjust data_not_used_ - data_not_used_ += number_lost; - collect_garbage(); - } - // ----------------------------------------------------------------- - /*! Fetch n_set for vector of sets object. - - \return - Number of from sets for this vector of sets object - */ - size_t n_set(void) const - { return start_.size(); } - // ----------------------------------------------------------------- - /*! Fetch end for this vector of sets object. - - \return - is the maximum element value plus one (the minimum element value is 0). - */ - size_t end(void) const - { return end_; } - // ----------------------------------------------------------------- - /*! Amount of memory used by this vector of sets - - \return - The amount of memory in units of type unsigned char memory. - */ - size_t memory(void) const - { return data_.capacity() * sizeof(size_t); - } - /*! - Print the vector of sets (used for debugging) - */ - void print(void) const; -}; -// ========================================================================= -/*! -cons_iterator for one set of positive integers in a svec_setvec object. - -All the public member functions for this class are also in the -sparse::pack_setvec_const_iterator and sparse::list_setvec_const_iterator classes. -This defines the CppAD vector_of_sets iterator concept. -*/ -class svec_setvec_const_iterator { -private: - /// data for the entire vector of sets - const pod_vector& data_; - - /// Possible elements in a list are 0, 1, ..., end_ - 1; - const size_t end_; - - /// data index of next entry, zero for no more entries - size_t data_index_; -public: - /// construct a const_iterator for a set in a svec_setvec object - svec_setvec_const_iterator (const svec_setvec& vec_set, size_t i) - : - data_( vec_set.data_ ) , - end_ ( vec_set.end_ ) - { CPPAD_ASSERT_UNKNOWN( vec_set.post_[i] == 0 ); - // - size_t start = vec_set.start_[i]; - if( start == 0 ) - { data_index_ = 0; - } - else - { // data index of the first element in the set - data_index_ = start + 2; - CPPAD_ASSERT_UNKNOWN( data_[data_index_] < end_ ); - } - } - - /// advance to next element in this list - svec_setvec_const_iterator& operator++(void) - { if( data_index_ != 0 ) - { ++data_index_; - if( data_[data_index_] == end_ ) - data_index_ = 0; - } - return *this; - } - - /// obtain value of this element of the set of positive integers - /// (end_ for no such element) - size_t operator*(void) - { if( data_index_ == 0 ) - return end_; - return data_[data_index_]; - } -}; -// ========================================================================= -/*! -Print the vector of sets (used for debugging) -*/ -inline void svec_setvec::print(void) const -{ std::cout << "svec_setvec:\n"; - for(size_t i = 0; i < n_set(); i++) - { std::cout << "set[" << i << "] = {"; - const_iterator itr(*this, i); - while( *itr != end() ) - { std::cout << *itr; - if( *(++itr) != end() ) - std::cout << ","; - } - std::cout << "}\n"; - } - return; -} - -/*! -Copy a user vector of sets sparsity pattern to an internal svec_setvec object. - -\tparam SetVector -is a simple vector with elements of type std::set. - -\param internal -The input value of sparisty does not matter. -Upon return it contains the same sparsity pattern as user -(or the transposed sparsity pattern). - -\param user -sparsity pattern that we are placing internal. - -\param n_set -number of sets (rows) in the internal sparsity pattern. - -\param end -end of set value (number of columns) in the interanl sparsity pattern. - -\param transpose -if true, the user sparsity patter is the transposed. - -\param error_msg -is the error message to display if some values in the user sparstiy -pattern are not valid. -*/ -template -void sparsity_user2internal( - svec_setvec& internal , - const SetVector& user , - size_t n_set , - size_t end , - bool transpose , - const char* error_msg ) -{ -# ifndef NDEBUG - if( transpose ) - CPPAD_ASSERT_KNOWN( end == size_t( user.size() ), error_msg); - if( ! transpose ) - CPPAD_ASSERT_KNOWN( n_set == size_t( user.size() ), error_msg); -# endif - - // iterator for user set - std::set::const_iterator itr; - - // size of internal sparsity pattern - internal.resize(n_set, end); - - if( transpose ) - { // transposed pattern case - for(size_t j = 0; j < end; j++) - { itr = user[j].begin(); - while(itr != user[j].end()) - { size_t i = *itr++; - CPPAD_ASSERT_KNOWN(i < n_set, error_msg); - internal.add_element(i, j); - } - } - } - else - { for(size_t i = 0; i < n_set; i++) - { itr = user[i].begin(); - while(itr != user[i].end()) - { size_t j = *itr++; - CPPAD_ASSERT_KNOWN( j < end, error_msg); - internal.add_element(i, j); - } - } - } - return; -} - -} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sparse/unary_op.hpp b/build-config/cppad/include/cppad/local/sparse/unary_op.hpp deleted file mode 100644 index f2e5383a..00000000 --- a/build-config/cppad/include/cppad/local/sparse/unary_op.hpp +++ /dev/null @@ -1,317 +0,0 @@ -# ifndef CPPAD_LOCAL_SPARSE_UNARY_OP_HPP -# define CPPAD_LOCAL_SPARSE_UNARY_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE -namespace CppAD { namespace local { namespace sparse { -/*! -\file sparse_unary_op.hpp -Forward and reverse mode sparsity patterns for unary operators. -*/ - - -/*! -Forward mode Jacobian sparsity pattern for all unary operators. - -The C++ source code corresponding to a unary operation has the form -\verbatim - z = fun(x) -\endverbatim -where fun is a C++ unary function, or it has the form -\verbatim - z = x op q -\endverbatim -where op is a C++ binary unary operator and q is a parameter. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param i_z -variable index corresponding to the result for this operation; -i.e., z. - -\param i_x -variable index corresponding to the argument for this operator; -i.e., x. - - -\param sparsity -\b Input: The set with index arg[0] in sparsity -is the sparsity bit pattern for x. -This identifies which of the independent variables the variable x -depends on. -\n -\n -\b Output: The set with index i_z in sparsity -is the sparsity bit pattern for z. -This identifies which of the independent variables the variable z -depends on. -\n - -\par Checked Assertions: -\li i_x < i_z -*/ - -template -void for_jac_unary_op( - size_t i_z , - size_t i_x , - Vector_set& sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( i_x < i_z ); - - sparsity.assignment(i_z, i_x, sparsity); -} -/*! -Reverse mode Jacobian sparsity pattern for all unary operators. - -The C++ source code corresponding to a unary operation has the form -\verbatim - z = fun(x) -\endverbatim -where fun is a C++ unary function, or it has the form -\verbatim - z = x op q -\endverbatim -where op is a C++ bianry operator and q is a parameter. - -This routine is given the sparsity patterns -for a function G(z, y, ... ) -and it uses them to compute the sparsity patterns for -\verbatim - H( x , w , u , ... ) = G[ z(x) , x , w , u , ... ] -\endverbatim - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - - -\param i_z -variable index corresponding to the result for this operation; -i.e. the row index in sparsity corresponding to z. - -\param i_x -variable index corresponding to the argument for this operator; -i.e. the row index in sparsity corresponding to x. - -\param sparsity -\b Input: -The set with index i_z in sparsity -is the sparsity bit pattern for G with respect to the variable z. -\n -\b Input: -The set with index i_x in sparsity -is the sparsity bit pattern for G with respect to the variable x. -\n -\b Output: -The set with index i_x in sparsity -is the sparsity bit pattern for H with respect to the variable x. - -\par Checked Assertions: -\li i_x < i_z -*/ - -template -void rev_jac_unary_op( - size_t i_z , - size_t i_x , - Vector_set& sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( i_x < i_z ); - - sparsity.binary_union(i_x, i_x, i_z, sparsity); - - return; -} -// --------------------------------------------------------------------------- -/*! -Reverse mode Hessian sparsity pattern for linear unary operators. - -The C++ source code corresponding to this operation is -\verbatim - z = fun(x) -\endverbatim -where fun is a linear functions; e.g. abs, or -\verbatim - z = x op q -\endverbatim -where op is a C++ binary operator and q is a parameter. - -\copydetails CppAD::local::reverse_sparse_hessian_unary_op -*/ -template -void rev_hes_lin_unary_op( - size_t i_z , - size_t i_x , - bool* rev_jacobian , - const Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( i_x < i_z ); - - // check for no effect - if( ! rev_jacobian[i_z] ) - return; - - rev_hes_sparsity.binary_union(i_x, i_x, i_z, rev_hes_sparsity); - - rev_jacobian[i_x] = true; - return; -} - -/*! -Reverse mode Hessian sparsity pattern for non-linear unary operators. - -The C++ source code corresponding to this operation is -\verbatim - z = fun(x) -\endverbatim -where fun is a non-linear functions; e.g. sin. or -\verbatim - z = q / x -\endverbatim -where q is a parameter. - - -\copydetails CppAD::local::reverse_sparse_hessian_unary_op -*/ -template -void rev_hes_nl_unary_op( - size_t i_z , - size_t i_x , - bool* rev_jacobian , - const Vector_set& for_jac_sparsity , - Vector_set& rev_hes_sparsity ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( i_x < i_z ); - - // check for no effect - if( ! rev_jacobian[i_z] ) - return; - - rev_hes_sparsity.binary_union(i_x, i_x, i_z, rev_hes_sparsity); - rev_hes_sparsity.binary_union(i_x, i_x, i_x, for_jac_sparsity); - - rev_jacobian[i_x] = true; - return; -} -// --------------------------------------------------------------------------- -/* -$begin for_hes_nl_unary_op$$ -$spell - hes - nl - op - np - numvar - Jacobian -$$ - -$section Forward Hessian Sparsity for Non-linear Unary Operators$$ - -$head Syntax$$ -$codei%local::for_hes_nl_unary_op( - %np1%, %numvar%, %i_v%, %for_sparsity% -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_for_hes_nl_unary_op%// END_for_hes_nl_unary_op%1 -%$$ - -$head C++ Source$$ -The C++ source code corresponding to this operation is -$codei% - %w% = %fun%( %v% ) -%$$ -where $icode fun$$ is a non-linear function. - -$head np1$$ -This is the number of independent variables plus one; -i.e. size of $icode x$$ plus one. - -$head numvar$$ -This is the total number of variables in the tape. - -$head i_w$$ -is the index of the variable corresponding to the result $icode w$$. - -$head i_v$$ -is the index of the variable corresponding to the argument $icode v$$. - -$head for_sparsity$$ -We have the conditions $icode%np1% = %for_sparsity%.end()%$$ -and $icode%for_sparsity%.n_set() = %np1% + %numvar%$$. - -$subhead Input Jacobian Sparsity$$ -For $icode%i%= 0, ..., %i_w%-1%$$, -the $icode%np1%+%i%$$ row of $icode for_sparsity$$ is the Jacobian sparsity -for the $th i$$ variable. These values do not change. -Note that $icode%i%=0%$$ corresponds to a parameter and -the corresponding Jacobian sparsity is empty. - -$subhead Input Hessian Sparsity$$ -For $icode%j%=1, ..., %n%$$, -the $th j$$ row of $icode for_sparsity$$ is the Hessian sparsity -before including the function $latex w(x)$$. - -$subhead Output Jacobian Sparsity$$ -the $icode i_w$$ row of $icode for_sparsity$$ is the Jacobian sparsity -for the variable $icode w$$. - -$subhead Output Hessian Sparsity$$ -For $icode%j%=1, ..., %n%$$, -the $th j$$ row of $icode for_sparsity$$ is the Hessian sparsity -after including the function $latex w(x)$$. - -$end -*/ -// BEGIN_for_hes_nl_unary_op -template -void for_hes_nl_unary_op( - size_t np1 , - size_t numvar , - size_t i_w , - size_t i_v , - Vector_set& for_sparsity ) -// END_for_hes_nl_unary_op -{ CPPAD_ASSERT_UNKNOWN( i_v < i_w ); - CPPAD_ASSERT_UNKNOWN( i_w < numvar ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.number_elements(np1) == 0 ); - - // set Jacobian sparsity J(i_w) - for_sparsity.assignment(np1 + i_w, np1 + i_v, for_sparsity); - - // set of independent variables that v depends on - typename Vector_set::const_iterator itr(for_sparsity, i_v + np1); - - // loop over independent variables with non-zero partial for v - size_t i_x = *itr; - while( i_x < np1 ) - { // N(i_x) = N(i_x) union J(i_v) - for_sparsity.binary_union(i_x, i_x, i_v + np1, for_sparsity); - i_x = *(++itr); - } - return; -} - -} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sqrt_op.hpp b/build-config/cppad/include/cppad/local/sqrt_op.hpp deleted file mode 100644 index a99ea5e9..00000000 --- a/build-config/cppad/include/cppad/local/sqrt_op.hpp +++ /dev/null @@ -1,193 +0,0 @@ -# ifndef CPPAD_LOCAL_SQRT_OP_HPP -# define CPPAD_LOCAL_SQRT_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file sqrt_op.hpp -Forward and reverse mode calculations for z = sqrt(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = SqrtOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sqrt(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op -*/ -template -void forward_sqrt_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - size_t k; - if( p == 0 ) - { z[0] = sqrt( x[0] ); - p++; - } - for(size_t j = p; j <= q; j++) - { - z[j] = Base(0.0); - for(k = 1; k < j; k++) - z[j] -= Base(double(k)) * z[k] * z[j-k]; - z[j] /= Base(double(j)); - z[j] += x[j] / Base(2.0); - z[j] /= z[0]; - } -} - -/*! -Multiple direction forward mode Taylor coefficient for op = SqrtOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sqrt(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_dir -*/ -template -void forward_sqrt_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* z = taylor + i_z * num_taylor_per_var; - Base* x = taylor + i_x * num_taylor_per_var; - - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = Base(0.0); - for(size_t k = 1; k < q; k++) - z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell]; - z[m+ell] /= Base(double(q)); - z[m+ell] += x[m+ell] / Base(2.0); - z[m+ell] /= z[0]; - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = SqrtOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sqrt(x) -\endverbatim - -\copydetails CppAD::local::forward_unary1_op_0 -*/ -template -void forward_sqrt_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = sqrt( x[0] ); -} -/*! -Compute reverse mode partial derivatives for result of op = SqrtOp. - -The C++ source code corresponding to this operation is -\verbatim - z = sqrt(x) -\endverbatim - -\copydetails CppAD::local::reverse_unary1_op -*/ - -template -void reverse_sqrt_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to result - const Base* z = taylor + i_z * cap_order; - Base* pz = partial + i_z * nc_partial; - - - Base inv_z0 = Base(1.0) / z[0]; - - // number of indices to access - size_t j = d; - size_t k; - while(j) - { - - // scale partial w.r.t. z[j] - pz[j] = azmul(pz[j], inv_z0); - - pz[0] -= azmul(pz[j], z[j]); - px[j] += pz[j] / Base(2.0); - for(k = 1; k < j; k++) - pz[k] -= azmul(pz[j], z[j-k]); - --j; - } - px[0] += azmul(pz[0], inv_z0) / Base(2.0); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/std_set.hpp b/build-config/cppad/include/cppad/local/std_set.hpp deleted file mode 100644 index a894fe3b..00000000 --- a/build-config/cppad/include/cppad/local/std_set.hpp +++ /dev/null @@ -1,52 +0,0 @@ -# ifndef CPPAD_LOCAL_STD_SET_HPP -# define CPPAD_LOCAL_STD_SET_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file std_set.hpp -Two constant standard sets (currently used for concept checking). -*/ - -/*! -A standard set with one element. -*/ -template -const std::set& one_element_std_set(void) -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - static std::set one; - if( one.empty() ) - one.insert(1); - return one; -} -/*! -A standard set with a two elements. -*/ -template -const std::set& two_element_std_set(void) -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - static std::set two; - if( two.empty() ) - { two.insert(1); - two.insert(2); - } - return two; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/store_op.hpp b/build-config/cppad/include/cppad/local/store_op.hpp deleted file mode 100644 index f7989bbb..00000000 --- a/build-config/cppad/include/cppad/local/store_op.hpp +++ /dev/null @@ -1,489 +0,0 @@ -# ifndef CPPAD_LOCAL_STORE_OP_HPP -# define CPPAD_LOCAL_STORE_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/* -$begin store_op_var$$ -$spell - pv - vp - vv - Vec - op - var - isvar - ind - Taylor - arg - num - Addr -$$ -$section Changing an Element in a Variable VecAD Vector$$ - -$head See Also$$ -$cref/op_code_var store/op_code_var/Store/$$. - -$head Syntax$$ -$codei%forward_store_%IV%_op_0( - %i_z%, - %arg%, - %num_par%, - %parameter%, - %cap_order%, - %taylor%, - %vec_ad2isvar%, - %vec_ad2index% -) -%$$ -where the index type $icode I$$ and the value being stored type $icode V$$ -are $code p$$ (for parameter) or $code v$$ (for variable). - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_FORWARD_STORE_PP_OP_0%// END_FORWARD_STORE_PP_OP_0%1 -%$$ -The prototype for -$code forward_store_pv_op_0$$, -$code forward_store_vp_op_0$$, and -$code forward_store_vv_op_0$$, -are the same except for the function name. - -$head Notation$$ - -$subhead v$$ -We use $icode v$$ to denote the $cref VecAD$$ vector for this operation. - -$subhead x$$ -We use $icode x$$ to denote the $codei%AD%<%Base%>%$$ -index for this operation. - -$subhead i_vec$$ -We use $icode i_vec$$ to denote the $code size_t$$ value -corresponding to $icode x$$. - -$subhead n_load$$ -This is the number of load instructions in this recording. - -$subhead n_all$$ -This is the number of values in the single array that includes -all the vectors together with the size of each vector. - -$head Base$$ -base type for the operator; i.e., this operation was recorded -using AD and computations by this routine are done using type Base. - -$head i_z$$ -is the AD variable index corresponding to the result of this load operation. - -$head arg$$ - -$subhead arg[0]$$ -is the offset of this VecAD vector relative to the beginning -of the $icode vec_ad2isvar$$ and $icode vec_ad2index$$ arrays. - -$subhead arg[1]$$ -If this is -$code forward_load_p_op_0$$ ($code forward_load_v_op_0$$) -$icode%arg%[%1%]%$$ is the parameter index (variable index) -corresponding to $cref/i_vec/load_op_var/Notation/i_vec/$$. - -$subhead arg[2]$$ -Is the index of this VecAD load instruction in the -$icode load_op2var$$ array. - -$head num_par$$ -is the number of parameters in this recording. - -$head parameter$$ -This is the vector of parameters for this recording which has size -$icode num_par$$. - -$head cap_order$$ -number of columns in the matrix containing the Taylor coefficients. - -$head taylor$$ -Is the matrix of Taylor coefficients for all the variables. - -$head vec_ad2isvar$$ -This vector has size $icode n_all$$ and -the input values of its elements does not matter. -If the value being stored is a parameter (variable), -$icode%vec_ad2isvar%[ %arg%[0] + %i_vec% ]%$$ -is set to false (true). - -$head vec_ad2index$$ -This array has size $icode n_all$$ -and the input value of its elements does not matter. -If the value being stored is a parameter (variable), -$icode%vec_ad2index%[ %arg%[0] + %i_vec% ]%$$ -is set to the parameter (variable) index -corresponding to the value being stored. - -$end -*/ -// BEGIN_FORWARD_STORE_PP_OP_0 -template -void forward_store_pp_op_0( - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - const Base* taylor , - bool* vec_ad2isvar , - size_t* vec_ad2index ) -// END_FORWARD_STORE_PP_OP_0 -{ addr_t i_vec = addr_t( Integer( parameter[ arg[1] ] ) ); - CPPAD_ASSERT_KNOWN( - size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] , - "VecAD: zero order forward dynamic parameter index out of range" - ); - CPPAD_ASSERT_UNKNOWN( NumArg(StppOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(StppOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); - - vec_ad2isvar[ arg[0] + i_vec ] = false; - vec_ad2index[ arg[0] + i_vec ] = size_t(arg[2]); -} -template -void forward_store_pv_op_0( - size_t i_z , - const addr_t* arg , - size_t num_par , - const Base* parameter , - size_t cap_order , - const Base* taylor , - bool* vec_ad2isvar , - size_t* vec_ad2index ) -{ addr_t i_vec = addr_t( Integer( parameter[ arg[1] ] ) ); - CPPAD_ASSERT_KNOWN( - size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] , - "VecAD: zero order forward dynamic parameter index out of range" - ); - CPPAD_ASSERT_UNKNOWN( NumArg(StpvOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(StpvOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - - vec_ad2isvar[ arg[0] + i_vec ] = true; - vec_ad2index[ arg[0] + i_vec ] = size_t(arg[2]); -} -template -void forward_store_vp_op_0( - size_t i_z , - const addr_t* arg , - size_t num_par , - size_t cap_order , - const Base* taylor , - bool* vec_ad2isvar , - size_t* vec_ad2index ) -{ - addr_t i_vec = addr_t(Integer( taylor[ size_t(arg[1]) * cap_order + 0 ] )); - CPPAD_ASSERT_KNOWN( - size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] , - "VecAD: zero order forward variable index out of range" - ); - - CPPAD_ASSERT_UNKNOWN( NumArg(StvpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(StvpOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par ); - - vec_ad2isvar[ arg[0] + i_vec ] = false; - vec_ad2index[ arg[0] + i_vec ] = size_t(arg[2]); -} -template -void forward_store_vv_op_0( - size_t i_z , - const addr_t* arg , - size_t num_par , - size_t cap_order , - const Base* taylor , - bool* vec_ad2isvar , - size_t* vec_ad2index ) -{ - addr_t i_vec = addr_t(Integer( taylor[ size_t(arg[1]) * cap_order + 0 ] )); - CPPAD_ASSERT_KNOWN( - size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] , - "VecAD: index during zero order forward sweep is out of range" - ); - - CPPAD_ASSERT_UNKNOWN( NumArg(StvpOp) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(StvpOp) == 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - - vec_ad2isvar[ arg[0] + i_vec ] = true; - vec_ad2index[ arg[0] + i_vec ] = size_t(arg[2]); -} -// --------------------------------------------------------------------------- -/* -============================================================================== - -The C++ source code corresponding to this operation is -\verbatim - v[x] = y -\endverbatim -where v is a VecAD vector, x is an AD object, -and y is AD or Base objects. -We define the index corresponding to v[x] by -\verbatim - i_v_x = vec_ad2index[ arg[0] + i_vec ] -\endverbatim -where i_vec is defined under the heading arg[1] below: - -============================================================================== -*/ -/*! -Shared documnetation for sparsity operations corresponding to -op = StpvOp or StvvOp (not called). - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param op -is the code corresponding to this operator; -i.e., StpvOp, StvpOp, or StvvOp. - -\param arg -\n - arg[0] -is the offset corresponding to this VecAD vector in the combined array. -\n -\n - arg[2] -\n -The set with index arg[2] in var_sparsity -is the sparsity pattern corresponding to y. -(Note that arg[2] > 0 because y is a variable.) - -\param num_combined -is the total number of elements in the VecAD address array. - -\param combined - combined [ arg[0] - 1 ] -is the index of the set in vecad_sparsity corresponding -to the sparsity pattern for the vector v. -We use the notation i_v below which is defined by -\verbatim - i_v = combined[ arg[0] - 1 ] -\endverbatim - -\param var_sparsity -The set with index arg[2] in var_sparsity -is the sparsity pattern for y. -This is an input for forward mode operations. -For reverse mode operations: -The sparsity pattern for v is added to the spartisy pattern for y. - -\param vecad_sparsity -The set with index i_v in vecad_sparsity -is the sparsity pattern for v. -This is an input for reverse mode operations. -For forward mode operations, the sparsity pattern for y is added -to the sparsity pattern for the vector v. - -\par Checked Assertions -\li NumArg(op) == 3 -\li NumRes(op) == 0 -\li 0 < arg[0] -\li arg[0] < num_combined -\li arg[2] < var_sparsity.n_set() -\li i_v < vecad_sparsity.n_set() -*/ -template -void sparse_store_op( - OpCode op , - const addr_t* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity ) -{ - // This routine is only for documentaiton, it should not be used - CPPAD_ASSERT_UNKNOWN( false ); -} - - - -/*! -Forward mode sparsity operations for StpvOp and StvvOp - - -The C++ source code corresponding to this operation is -\verbatim - v[x] = y -\endverbatim -where v is a VecAD vector, x is an AD object, -and y is AD or Base objects. -We define the index corresponding to v[x] by -\verbatim - i_v_x = vec_ad2index[ arg[0] + i_vec ] -\endverbatim -where i_vec is defined under the heading arg[1] below: - - -\param dependency -is this a dependency (or sparsity) calculation. - -\copydetails CppAD::local::sparse_store_op -*/ -template -void forward_sparse_store_op( - bool dependency , - OpCode op , - const addr_t* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity ) -{ - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); - size_t i_v = combined[ arg[0] - 1 ]; - CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() ); - - if( dependency & ( (op == StvvOp) | (op == StvpOp) ) ) - vecad_sparsity.binary_union(i_v, i_v, size_t(arg[1]), var_sparsity); - - if( (op == StpvOp) | (op == StvvOp ) ) - vecad_sparsity.binary_union(i_v, i_v, size_t(arg[2]), var_sparsity); - - return; -} - -/*! -Reverse mode sparsity operations for StpvOp, StvpOp, and StvvOp - - -The C++ source code corresponding to this operation is -\verbatim - v[x] = y -\endverbatim -where v is a VecAD vector, x is an AD object, -and y is AD or Base objects. -We define the index corresponding to v[x] by -\verbatim - i_v_x = vec_ad2index[ arg[0] + i_vec ] -\endverbatim -where i_vec is defined under the heading arg[1] below: - - -This routine is given the sparsity patterns for -G(v[x], y , w , u ... ) and it uses them to compute the -sparsity patterns for -\verbatim - H(y , w , u , ... ) = G[ v[x], y , w , u , ... ] -\endverbatim - -\param dependency -is this a dependency (or sparsity) calculation. - -\copydetails CppAD::local::sparse_store_op -*/ -template -void reverse_sparse_jacobian_store_op( - bool dependency , - OpCode op , - const addr_t* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity ) -{ - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); - size_t i_v = combined[ arg[0] - 1 ]; - CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() ); - - if( dependency & ( (op == StvpOp) | (op == StvvOp) ) ) - var_sparsity.binary_union( size_t(arg[1]), size_t(arg[1]), i_v, vecad_sparsity); - if( (op == StpvOp) | (op == StvvOp) ) - var_sparsity.binary_union( size_t(arg[2]), size_t(arg[2]), i_v, vecad_sparsity); - - return; -} - -/*! -Reverse mode sparsity operations for StpvOp and StvvOp - - -The C++ source code corresponding to this operation is -\verbatim - v[x] = y -\endverbatim -where v is a VecAD vector, x is an AD object, -and y is AD or Base objects. -We define the index corresponding to v[x] by -\verbatim - i_v_x = vec_ad2index[ arg[0] + i_vec ] -\endverbatim -where i_vec is defined under the heading arg[1] below: - - -This routine is given the sparsity patterns for -G(v[x], y , w , u ... ) -and it uses them to compute the sparsity patterns for -\verbatim - H(y , w , u , ... ) = G[ v[x], y , w , u , ... ] -\endverbatim - -\copydetails CppAD::local::sparse_store_op - -\param var_jacobian - var_jacobian[ arg[2] ] -is false (true) if the Jacobian of G with respect to y is always zero -(may be non-zero). - -\param vecad_jacobian - vecad_jacobian[i_v] -is false (true) if the Jacobian with respect to x is always zero -(may be non-zero). -On input, it corresponds to the function G, -and on output it corresponds to the function H. -*/ -template -void reverse_sparse_hessian_store_op( - OpCode op , - const addr_t* arg , - size_t num_combined , - const size_t* combined , - Vector_set& var_sparsity , - Vector_set& vecad_sparsity , - bool* var_jacobian , - bool* vecad_jacobian ) -{ - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 ); - CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 ); - CPPAD_ASSERT_UNKNOWN( 0 < arg[0] ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined ); - size_t i_v = combined[ arg[0] - 1 ]; - CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() ); - CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() ); - - var_sparsity.binary_union( size_t(arg[2]), size_t(arg[2]), i_v, vecad_sparsity); - - var_jacobian[ arg[2] ] |= vecad_jacobian[i_v]; - - return; -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sub_op.hpp b/build-config/cppad/include/cppad/local/sub_op.hpp deleted file mode 100644 index 23c373ef..00000000 --- a/build-config/cppad/include/cppad/local/sub_op.hpp +++ /dev/null @@ -1,500 +0,0 @@ -# ifndef CPPAD_LOCAL_SUB_OP_HPP -# define CPPAD_LOCAL_SUB_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file sub_op.hpp -Forward and reverse mode calculations for z = x - y. -*/ - -// --------------------------- Subvv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = SubvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_subvv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - for(size_t d = p; d <= q; d++) - z[d] = x[d] - y[d]; -} -/*! -Multiple directions forward mode Taylor coefficients for op = SubvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_subvv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var + m; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m; - Base* z = taylor + i_z * num_taylor_per_var + m; - - for(size_t ell = 0; ell < r; ell++) - z[ell] = x[ell] - y[ell]; -} - -/*! -Compute zero order forward mode Taylor coefficients for result of op = SubvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_subvv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x[0] - y[0]; -} - -/*! -Compute reverse mode partial derivatives for result of op = SubvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_subvv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t i = d + 1; - while(i) - { --i; - px[i] += pz[i]; - py[i] -= pz[i]; - } -} - -// --------------------------- Subpv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = SubpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_subpv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - // Paraemter value - Base x = parameter[ arg[0] ]; - if( p == 0 ) - { z[0] = x - y[0]; - p++; - } - for(size_t d = p; d <= q; d++) - z[d] = - y[d]; -} -/*! -Multiple directions forward mode Taylor coefficients for op = SubpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_subpv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q-1) * r + 1; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m; - Base* z = taylor + i_z * num_taylor_per_var + m; - - // Paraemter value - for(size_t ell = 0; ell < r; ell++) - z[ell] = - y[ell]; -} -/*! -Compute zero order forward mode Taylor coefficient for result of op = SubpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_subpv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubpvOp) == 1 ); - - // Paraemter value - Base x = parameter[ arg[0] ]; - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x - y[0]; -} - -/*! -Compute reverse mode partial derivative for result of op = SubpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_subpv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Partial derivatives corresponding to arguments and result - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t i = d + 1; - while(i) - { --i; - py[i] -= pz[i]; - } -} - -// --------------------------- Subvp ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = SubvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_subvp_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z = taylor + i_z * cap_order; - - // Parameter value - Base y = parameter[ arg[1] ]; - if( p == 0 ) - { z[0] = x[0] - y; - p++; - } - for(size_t d = p; d <= q; d++) - z[d] = x[d]; -} -/*! -Multiple directions forward mode Taylor coefficients for op = SubvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_subvp_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - // Parameter value - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - z[m+ell] = x[m+ell]; -} - -/*! -Compute zero order forward mode Taylor coefficients for result of op = SubvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_subvp_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 ); - - // Parameter value - Base y = parameter[ arg[1] ]; - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = x[0] - y; -} - -/*! -Compute reverse mode partial derivative for result of op = SubvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = x - y -\endverbatim -In the documentation below, -this operations is for the case where x is a variable and y is a parameter. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_subvp_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t i = d + 1; - while(i) - { --i; - px[i] += pz[i]; - } -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/subgraph/arg_variable.hpp b/build-config/cppad/include/cppad/local/subgraph/arg_variable.hpp deleted file mode 100644 index 1ec1f8c2..00000000 --- a/build-config/cppad/include/cppad/local/subgraph/arg_variable.hpp +++ /dev/null @@ -1,112 +0,0 @@ -# ifndef CPPAD_LOCAL_SUBGRAPH_ARG_VARIABLE_HPP -# define CPPAD_LOCAL_SUBGRAPH_ARG_VARIABLE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE -namespace CppAD { namespace local { namespace subgraph { -/*! -\file arg_variable.hpp -Determine arguments that are variables. -*/ - -/*! -Determine the set of arguments, for an operator, that are variables. - -\tparam Addr -Type used for indices in random iterator. - -\param random_itr -is a random iterator for this operation sequence. - -\param i_op -is the operator index. If this operator is part of a atomic function call, -it must be the first AFunOp in the call. (There is a AFunOp at the -beginning and end of each call.) - -\param variable -is the set of argument variables corresponding to this operator. -If the operator is a AFunOp, the arguments are the variables -that are passed into the function call. - -\param work -this is work space used by arg_variable to make subsequent calls -faster. It should not be used by the calling routine. In addition, -it is better if work does not drop out of scope between calls. -*/ -template -void get_argument_variable( - const play::const_random_iterator& random_itr , - size_t i_op , - pod_vector& variable , - pod_vector& work ) -{ - // reset to size zero, but keep allocated memory - variable.resize(0); - // - // operator corresponding to i_op - OpCode op; - const addr_t* op_arg; - size_t i_var; - random_itr.op_info(i_op, op, op_arg, i_var); - // - // partial check of assumptions on atomic function calls - CPPAD_ASSERT_UNKNOWN( - op != FunapOp && op != FunavOp && op != FunrpOp && op != FunrvOp - ); - // - // we assume this is the first AFunOp of the call - if( op == AFunOp ) - { random_itr.op_info(++i_op, op, op_arg, i_var); - while( op != AFunOp ) - { switch(op) - { - case FunavOp: - { CPPAD_ASSERT_NARG_NRES(op, 1, 0); - size_t j_var = size_t( op_arg[0] ); - variable.push_back(j_var); - } - break; - - case FunrvOp: - case FunrpOp: - case FunapOp: - break; - - default: - // cannot find second AFunOp in this call - CPPAD_ASSERT_UNKNOWN(false); - break; - } - random_itr.op_info(++i_op, op, op_arg, i_var); - } - CPPAD_ASSERT_UNKNOWN( variable.size() > 0 ); - return; - } - // is_variable is a reference to work with a better name - pod_vector& is_variable(work); - arg_is_variable(op, op_arg, is_variable); - size_t num_arg = is_variable.size(); - for(size_t j = 0; j < num_arg; ++j) - { if( is_variable[j] ) - { size_t j_var = size_t( op_arg[j] ); - variable.push_back(j_var); - } - } - return; -} - -} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/subgraph/entire_call.hpp b/build-config/cppad/include/cppad/local/subgraph/entire_call.hpp deleted file mode 100644 index c448837f..00000000 --- a/build-config/cppad/include/cppad/local/subgraph/entire_call.hpp +++ /dev/null @@ -1,76 +0,0 @@ -# ifndef CPPAD_LOCAL_SUBGRAPH_ENTIRE_CALL_HPP -# define CPPAD_LOCAL_SUBGRAPH_ENTIRE_CALL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE -namespace CppAD { namespace local { namespace subgraph { -/*! -\file entire_call.hpp -include entire function call in a subgraph -*/ -// =========================================================================== -/*! -Convert from just firt AFunOp to entire atomic function call in a subgraph. - -\tparam Addr -Type used for indices in the random iterator. - -\param random_itr -is a random iterator for this operation sequence. - -\param subgraph -It a set of operator indices in this recording. -If the corresponding operator is a AFunOp, it assumed to be the -first one in the corresponding atomic function call. -The other call operators are included in the subgraph. -*/ -template -void entire_call( - const play::const_random_iterator& random_itr , - pod_vector& subgraph ) -{ - // add extra operators corresponding to rest of atomic function calls - size_t n_sub = subgraph.size(); - for(size_t k = 0; k < n_sub; ++k) - { size_t i_op = size_t( subgraph[k] ); - // - if( random_itr.get_op(i_op) == AFunOp ) - { // This is the first AFunOp of this atomic function call - while( random_itr.get_op(++i_op) != AFunOp ) - { switch(random_itr.get_op(i_op)) - { - case FunavOp: - case FunrvOp: - case FunrpOp: - case FunapOp: - subgraph.push_back( addr_t(i_op) ); - break; - - default: - // cannot find second AFunOp in this call - CPPAD_ASSERT_UNKNOWN(false); - break; - } - } - // THis is the second AFunOp of this atomic function call - subgraph.push_back( addr_t(i_op) ); - } - } - -} - -} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/subgraph/get_rev.hpp b/build-config/cppad/include/cppad/local/subgraph/get_rev.hpp deleted file mode 100644 index 4f99660b..00000000 --- a/build-config/cppad/include/cppad/local/subgraph/get_rev.hpp +++ /dev/null @@ -1,165 +0,0 @@ -# ifndef CPPAD_LOCAL_SUBGRAPH_GET_REV_HPP -# define CPPAD_LOCAL_SUBGRAPH_GET_REV_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE -namespace CppAD { namespace local { namespace subgraph { -/*! -\file get_rev.hpp -Get subgraph corresponding to a dependent variable. -*/ - -// =========================================================================== -/*! -Get the subgraph corresponding to a dependent variables -(and a selected set of independent variables). - -\tparam Addr -Type used for indices in the random iterator. - -\param random_itr -is a random iterator for this operation sequence. - -\param dep_taddr -is the vector mapping user dependent variable indices -to the correpsonding variable in the recording. - -\param i_dep -is the user index for his dependent variable; -that i_dep < n_dep_. - -\param subgraph -the input size and contents of this vector do not matter. -Repeated calls with the same subgraph vector should reduce -the amount of memory allocation. -Upon return it contains the operator indices for the subgraph -corresponding to the dependent and the selected independent variables. -Only selected independent variable operators InvOp are included -in the subgraph. -Furthermore the operator indices in subgraph are unique; i.e., -if i_op != j_op then subgraph[i_op] != subgraph[j_op]. - -\par map_user_op_ -This vector must be set. - -\par in_subgraph_ -has size equal to the number of operators in play. -If in_subgraph[i_op] <= n_dep_, -the result for this operator depends on the selected independent variables. -In addition, upon input, there is no i_op such that in_subgraph[i_op] == i_dep. -Note that for atomic function call operators i_op, -\code - n_dep_ < in_subgraph[i_op] -\endcode -except for the first AFunOp in the atomic function call sequence. -For the first AFunOp, -\code - in_subgraph[i_op] <= n_dep_ -\endcode -if any result for the atomic function call -depends on the selected independent variables. -Except for UserOP, only operators with NumRes(op) > 0 are included -in the dependency; e.g., comparison operators are not included. -Upon return, some of the i_op for which in_subgraph[i_op] <= n_dep_, -will be changed to in_subgraph[i_op] = i_dep. - -\par process_range_ -The value process_range_[i_dep] is checked to make sure it is false. -It is then set to have value true. -*/ -template -void subgraph_info::get_rev( - const play::const_random_iterator& random_itr , - const pod_vector& dep_taddr , - addr_t i_dep , - pod_vector& subgraph ) -{ // check sizes - CPPAD_ASSERT_UNKNOWN( map_user_op_.size() == n_op_ ); - - // process_range_ - CPPAD_ASSERT_UNKNOWN( process_range_[i_dep] == false ); - process_range_[i_dep] = true; - - // special value; see init_rev_in_subgraph - addr_t depend_yes = addr_t( n_dep_ ); - - // assumption on i_dep - CPPAD_ASSERT_UNKNOWN( i_dep < depend_yes ); - - // start with an empty subgraph for this dependent variable - subgraph.resize(0); - - // tape index corresponding to this dependent variable - size_t i_var = dep_taddr[i_dep]; - - // operator corresponding to this dependent variable - size_t i_op = random_itr.var2op(i_var); - i_op = size_t( map_user_op_[i_op] ); - - // if this variable depends on the selected indepent variables - // process its subgraph - CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] != i_dep ) - if( in_subgraph_[i_op] <= depend_yes ) - { subgraph.push_back( addr_t(i_op) ); - in_subgraph_[i_op] = i_dep; - } - - // space used to return set of arguments that are variables - pod_vector argument_variable; - - // temporary space used by get_argument_variable - pod_vector work; - - // scan all the operators in this subgraph - size_t sub_index = 0; - while(sub_index < subgraph.size() ) - { // this operator connected to this dependent and selected independent - i_op = size_t( subgraph[sub_index] ); - CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] == i_dep ); - // - // There must be a result for this operator -# ifndef NDEBUG - OpCode op = random_itr.get_op(i_op); - CPPAD_ASSERT_UNKNOWN(op == AFunOp || NumRes(op) > 0 ); -# endif - // - // which variables are connected to this operator - get_argument_variable(random_itr, i_op, argument_variable, work); - for(size_t j = 0; j < argument_variable.size(); ++j) - { // add the corresponding operators to the subgraph - size_t j_var = argument_variable[j]; - size_t j_op = random_itr.var2op(j_var); - j_op = size_t( map_user_op_[j_op] ); - bool add = in_subgraph_[j_op] <= depend_yes; - add &= in_subgraph_[j_op] != i_dep; - if( random_itr.get_op(j_op) == InvOp ) - { CPPAD_ASSERT_UNKNOWN( j_op == j_var ); - add &= select_domain_[j_var - 1]; - } - if( add ) - { subgraph.push_back( addr_t(j_op) ); - in_subgraph_[j_op] = i_dep; - } - } - // we are done scaning this subgraph operator - ++sub_index; - } -} - -} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/subgraph/info.hpp b/build-config/cppad/include/cppad/local/subgraph/info.hpp deleted file mode 100644 index d0a8fea8..00000000 --- a/build-config/cppad/include/cppad/local/subgraph/info.hpp +++ /dev/null @@ -1,334 +0,0 @@ -# ifndef CPPAD_LOCAL_SUBGRAPH_INFO_HPP -# define CPPAD_LOCAL_SUBGRAPH_INFO_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE -namespace CppAD { namespace local { namespace subgraph { -/*! -\file info.hpp -subgraph information attached to a operation sequence -*/ - -/// class for maintaining subgraph information attached to on ADFun object. -class subgraph_info { -private: - // ----------------------------------------------------------------------- - // private member data set by constructor, resize, and assign - // ----------------------------------------------------------------------- - /// number of independent variables for this function - size_t n_ind_; - - /// number of dependent variables for this function - size_t n_dep_; - - /// number of operatros in operation sequence - size_t n_op_; - - /// number of variables in operation sequence - size_t n_var_; - - // ----------------------------------------------------------------------- - // private member data set by set_map_user_op - // ----------------------------------------------------------------------- - - /// Mapping atomic call operators to AFunOp that begins call sequence, - /// other operators are not changed by the map. - /// (size zero after construtor or resize) - pod_vector map_user_op_; - - // ----------------------------------------------------------------------- - // other private member data - // ----------------------------------------------------------------------- - - /// flags which operatiors are in subgraph - /// (size zero or n_op_). - pod_vector in_subgraph_; - - /// flags which dependent variables are selected - pod_vector select_domain_; - - /// flags which dependent variables have been processed since - /// the previous init_rev - pod_vector process_range_; - -public: - // ----------------------------------------------------------------------- - // const public functions - // ----------------------------------------------------------------------- - /// number of independent variables - size_t n_ind(void) const - { return n_ind_; } - - /// number of dependent variables - size_t n_dep(void) const - { return n_dep_; } - - /// number of operators - size_t n_op(void) const - { return n_op_; } - - // number of variables - size_t n_var(void) const - { return n_var_; } - - /// map atomic function calls to first operator in the call - const pod_vector& map_user_op(void) const - { return map_user_op_; } - - /// previous select_domain argument to init_rev - const pod_vector& select_domain(void) const - { return select_domain_; } - - /// dependent variables that have been processed since previous init_rev - const pod_vector& process_range(void) const - { return process_range_; } - - /// amount of memory corresonding to this object - size_t memory(void) const - { size_t sum = map_user_op_.size() * sizeof(addr_t); - sum += in_subgraph_.size() * sizeof(addr_t); - sum += select_domain_.size() * sizeof(bool); - sum += process_range_.size() * sizeof(bool); - return sum; - } - - /// free memory used for calculating subgraph - void clear(void) - { map_user_op_.clear(); - in_subgraph_.clear(); - select_domain_.clear(); - process_range_.clear(); - } - // ----------------------------------------------------------------------- - /*! - check that the value of map_user_op is OK for this operation sequence - - \param play - is the player for this operation sequence. - - \return - is true, if map_user_op has the correct value for this operation sequence - (is the same as it would be after a set_map_user_op). - */ - template - bool check_map_user_op(const player* play) const - { if( map_user_op_.size() != n_op_ ) - return false; - bool ok = true; - size_t i_op = 0; - while( i_op < n_op_ ) - { OpCode op = play->GetOp(i_op); - ok &= map_user_op_[i_op] == addr_t( i_op ); - if( op == AFunOp ) - { addr_t begin = addr_t( i_op ); - op = play->GetOp(++i_op); - while( op != AFunOp ) - { CPPAD_ASSERT_UNKNOWN( - op==FunapOp || op==FunavOp || op==FunrpOp || op==FunrvOp - ); - ok &= map_user_op_[i_op] == begin; - op = play->GetOp(++i_op); - } - ok &= map_user_op_[i_op] == begin; - } - ++i_op; - } - return ok; - } - // ----------------------------------------------------------------------- - // non const public functions - // ----------------------------------------------------------------------- - - /// flag which operators that are in the subgraph - pod_vector& in_subgraph(void) - { return in_subgraph_; } - - - /// default constructor (all sizes are zero) - subgraph_info(void) - : n_ind_(0), n_dep_(0), n_op_(0), n_var_(0) - { CPPAD_ASSERT_UNKNOWN( map_user_op_.size() == 0 ); - CPPAD_ASSERT_UNKNOWN( in_subgraph_.size() == 0 ); - } - // ----------------------------------------------------------------------- - /// assignment operator - void operator=(const subgraph_info& info) - { n_ind_ = info.n_ind_; - n_dep_ = info.n_dep_; - n_op_ = info.n_op_; - n_var_ = info.n_var_; - map_user_op_ = info.map_user_op_; - in_subgraph_ = info.in_subgraph_; - select_domain_ = info.select_domain_; - process_range_ = info.process_range_; - return; - } - // ----------------------------------------------------------------------- - /// swap - /// (used for move semantics version of ADFun assignment) - void swap(subgraph_info& info) - { // size_t objects - std::swap(n_ind_ , info.n_ind_); - std::swap(n_dep_ , info.n_dep_); - std::swap(n_op_ , info.n_op_); - std::swap(n_var_ , info.n_var_); - // - // pod_vectors - map_user_op_.swap( info.map_user_op_); - in_subgraph_.swap( info.in_subgraph_); - select_domain_.swap( info.select_domain_); - process_range_.swap( info.process_range_); - // - return; - } - // ----------------------------------------------------------------------- - /*! - set sizes for this object (the default sizes are zero) - - \param n_ind - number of indepent variables. - - \param n_dep - number of dependent variables. - - \param n_op - number of operators. - - \param n_var - number of variables. - - \par map_user_op_ - is resized to zero. - - \par in_subgraph_ - is resized to zero. - */ - void resize(size_t n_ind, size_t n_dep, size_t n_op, size_t n_var) - { CPPAD_ASSERT_UNKNOWN( - n_op <= size_t( std::numeric_limits::max() ) - ); - // n_ind_ - n_ind_ = n_ind; - // n_dep_ - n_dep_ = n_dep; - // n_op_ - n_op_ = n_op; - // n_var_ - n_var_ = n_var; - - // - // map_user_op_ - map_user_op_.resize(0); - // - // in_subgraph_ - in_subgraph_.resize(0); - // - return; - } - // ----------------------------------------------------------------------- - /*! - set the value of map_user_op for this operation sequence - - \param play - is the player for this operation sequence. It must same number of - operators and variables as this subgraph_info object. - - \par map_user_op_ - This size of map_user_op_ must be zero when this function is called - (which is true after a resize operation). - This function sets its size to the number of operations in play. - We use the term user OpCocde for the any one of the following: - AFunOp, FunapOp, FunavOp, FunrpOp, or FunrvOp. Suppose - \code - OpCodce op_i = play->GetOp(i_op); - size_t j_op = map_user_op[i_op]; - OpCode op_j = play->GetOP(j_op); - \endcode - If op is a user OpCode, j_op is the index of the first operator - in the corresponding atomic function call and op_j == AFunOp. - Otherwise j_op == i_op; - - */ - template - void set_map_user_op(const player* play) - { CPPAD_ASSERT_UNKNOWN( map_user_op_.size() == 0 ); - // - CPPAD_ASSERT_UNKNOWN( n_op_ == play->num_op_rec() ); - CPPAD_ASSERT_UNKNOWN( n_var_ == play->num_var_rec() ); - // - // resize map_user_op_ - map_user_op_.resize(n_op_); - // - // set map_user_op for each operator - for(size_t i_op = 0; i_op < n_op_; ++i_op) - { // this operator - OpCode op = play->GetOp(i_op); - // - // value of map_user_op when op is not in atomic function call) - map_user_op_[i_op] = addr_t( i_op ); - // - if( op == AFunOp ) - { // first AFunOp in an atomic function call sequence - // - // All operators in this atomic call sequence will be - // mapped to the AFunOp that begins this call. - addr_t begin = addr_t( i_op ); - op = play->GetOp(++i_op); - while( op != AFunOp ) - { CPPAD_ASSERT_UNKNOWN( - op==FunapOp || op==FunavOp || op==FunrpOp || op==FunrvOp - ); - // map this operator to the beginning of the call - map_user_op_[i_op] = begin; - op = play->GetOp(++i_op); - } - // map the second AFunOp to the beginning of the call - map_user_op_[i_op] = begin; - } - } - return; - } - // ----------------------------------------------------------------------- - // see init_rev.hpp - template - void init_rev( - const play::const_random_iterator& random_itr , - const BoolVector& select_domain - ); - template - void init_rev( - player* play , - const BoolVector& select_domain - ); - // ----------------------------------------------------------------------- - // see get_rev.hpp - template - void get_rev( - const play::const_random_iterator& random_itr , - const pod_vector& dep_taddr , - addr_t i_dep , - pod_vector& subgraph - ); -}; - -} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE - -// routines that operate on in_subgraph -# include -# include - -# endif diff --git a/build-config/cppad/include/cppad/local/subgraph/init_rev.hpp b/build-config/cppad/include/cppad/local/subgraph/init_rev.hpp deleted file mode 100644 index 9d7b65c7..00000000 --- a/build-config/cppad/include/cppad/local/subgraph/init_rev.hpp +++ /dev/null @@ -1,225 +0,0 @@ -# ifndef CPPAD_LOCAL_SUBGRAPH_INIT_REV_HPP -# define CPPAD_LOCAL_SUBGRAPH_INIT_REV_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE -namespace CppAD { namespace local { namespace subgraph { -/*! -\file init_rev.hpp -initialize for a reverse mode subgraph calculation -*/ - -// ----------------------------------------------------------------------- -/*! -Initialize in_subgraph corresponding to a single dependent variable -(and a selected set of independent variables). - -\tparam Addr -is the type used for indices in the random iterator. - -\param random_itr -Is a random iterator for this operation sequence. - -\param select_domain -is a vector with, size equal to the number of independent variables -in the recording. It determines the selected independent variables. - -\par in_subgraph_ -We use depend_yes (depend_no) for the value n_dep_ (n_dep_ + 1). -The important properties are that depend_yes < depend_no and -for a valid indpendent variable index i_ind < depend_yes. -The input size and elements of in_subgraph_ do not matter. -If in_subgraph_[i_op] == depend_yes (depend_no), -the result for this operator depends (does not depend) -on the selected independent variables. -Note that for atomic function call operators i_op, -in_subgraph[i_op] is depend_no except for the first AFunOp in the -atomic function call sequence. For the first AFunOp, -it is depend_yes (depend_no) if any of the results for the call sequence -depend (do not depend) on the selected independent variables. -Except for UserOP, only operators with NumRes(op) > 0 have in_subgraph_ -value depend_yes; -e.g., comparison operators have in_subgraph_ value depend_no. - -\par select_domain_ -This vector is is set equal to the select_domain argument. - -\par process_range_ -This vector is to to size n_dep_ and its values are set to false -*/ -template -void subgraph_info::init_rev( - const local::play::const_random_iterator& random_itr , - const BoolVector& select_domain ) -{ - // check sizes - CPPAD_ASSERT_UNKNOWN( map_user_op_.size() == n_op_ ); - CPPAD_ASSERT_UNKNOWN( random_itr.num_op() == n_op_ ); - CPPAD_ASSERT_UNKNOWN( size_t( select_domain.size() ) == n_ind_ ); - - // depend_yes and depend_no - addr_t depend_yes = addr_t( n_dep_ ); - addr_t depend_no = addr_t( n_dep_ + 1 ); - - // select_domain_ - select_domain_.resize(n_ind_); - for(size_t j = 0; j < n_ind_; ++j) - select_domain_[j] = select_domain[j]; - - // process_range_ - process_range_.resize(n_dep_); - for(size_t i = 0; i < n_dep_; ++i) - process_range_[i] = false; - - // set in_subgraph to have proper size - in_subgraph_.resize(n_op_); - - // space used to return set of arguments that are variables - pod_vector argument_variable; - - // temporary space used by get_argument_variable - pod_vector work; - -# ifndef NDEBUG - size_t count_independent = 0; -# endif - bool begin_atomic_call = false; - for(size_t i_op = 0; i_op < n_op_; ++i_op) - { OpCode op = random_itr.get_op(i_op); - // - // default value for this operator - in_subgraph_[i_op] = depend_no; - // - switch(op) - { case InvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - CPPAD_ASSERT_UNKNOWN( i_op > 0 ); - { // get user index for this independent variable - size_t j = i_op - 1; - CPPAD_ASSERT_UNKNOWN( j < n_ind_ ); - // - // set in_subgraph_[i_op] - if( select_domain[j] ) - in_subgraph_[i_op] = depend_yes; - } -# ifndef NDEBUG - ++count_independent; -# endif - break; - - // only mark both first AFunOp for each call as depending - // on the selected independent variables - case AFunOp: - begin_atomic_call = ! begin_atomic_call; - if( begin_atomic_call ) - { get_argument_variable(random_itr, i_op, argument_variable, work); - for(size_t j = 0; j < argument_variable.size(); ++j) - { size_t j_var = argument_variable[j]; - size_t j_op = random_itr.var2op(j_var); - j_op = size_t( map_user_op_[j_op] ); - CPPAD_ASSERT_UNKNOWN( j_op < i_op ); - if( in_subgraph_[j_op] == depend_yes ) - in_subgraph_[i_op] = depend_yes; - } - } - break; - - // skip FunrvOp (gets mapped to first AFunOp in this call) - case FunrvOp: - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 ); - break; - - default: - // Except for AFunOp, only include when NumRes(op) > 0. - if( NumRes(op) > 0 ) - { get_argument_variable(random_itr, i_op, argument_variable, work); - for(size_t j = 0; j < argument_variable.size(); ++j) - { size_t j_var = argument_variable[j]; - size_t j_op = random_itr.var2op(j_var); - j_op = size_t( map_user_op_[j_op] ); - CPPAD_ASSERT_UNKNOWN( j_op < i_op ); - if( in_subgraph_[j_op] == depend_yes ) - in_subgraph_[i_op] = depend_yes; - } - } - break; - } - } - CPPAD_ASSERT_UNKNOWN( - count_independent == size_t(select_domain.size()) - ); - // - return; -} -// ----------------------------------------------------------------------- -/*! -Initialize in_subgraph corresponding to a single dependent variable -(and a selected set of independent variables). - -\tparam Addr -is the type used for indices in the random iterator. - -\tparam Base -this recording was made using ADFun - -\param play -is a player for this ADFun object. - -\param select_domain -is a vector with, size equal to the number of independent variables -in the recording. It determines the selected independent variables. - -\par in_subgraph_ -We use depend_yes (depend_no) for the value n_dep_ (n_dep_ + 1). -The important properties are that depend_yes < depend_no and -for a valid indpendent variable index i_ind < depend_yes. -The input size and elements of in_subgraph_ do not matter. -If in_subgraph_[i_op] == depend_yes (depend_no), -the result for this operator depends (does not depend) -on the selected independent variables. -Note that for atomic function call operators i_op, -in_subgraph[i_op] is depend_no except for the first AFunOp in the -atomic function call sequence. For the first AFunOp, -it is depend_yes (depend_no) if any of the results for the call sequence -depend (do not depend) on the selected independent variables. -Except for UserOP, only operators with NumRes(op) > 0 have in_subgraph_ -value depend_yes; -e.g., comparison operators have in_subgraph_ value depend_no. - -\par select_domain_ -This vector is is set equal to the select_domain argument. - -\par process_range_ -This vector is to to size n_dep_ and its values are set to false -*/ -template -void subgraph_info::init_rev( - player* play , - const BoolVector& select_domain ) -{ - // get random access iterator for this player - play->template setup_random(); - local::play::const_random_iterator random_itr = - play->template get_random(); - // - init_rev(random_itr, select_domain); - // - return; -} - - -} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/subgraph/sparsity.hpp b/build-config/cppad/include/cppad/local/subgraph/sparsity.hpp deleted file mode 100644 index 1d2b8a07..00000000 --- a/build-config/cppad/include/cppad/local/subgraph/sparsity.hpp +++ /dev/null @@ -1,191 +0,0 @@ -# ifndef CPPAD_LOCAL_SUBGRAPH_SPARSITY_HPP -# define CPPAD_LOCAL_SUBGRAPH_SPARSITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE -namespace CppAD { namespace local { namespace subgraph { -/*! -\file sparsity.hpp -Compute dependency sparsity pattern using subgraph technique. -*/ -// =========================================================================== -/*! -Compute dependency sparsity pattern for an ADFun function. - -\tparam Addr -type used for indices in random iterator -(must correspond to play->addr_type()) - -\tparam Base -the operation sequence was recorded using AD. - -\tparam BoolVector -a simple vector class with elements of type bool. - -\param play -is the operation sequence corresponding to the ADFun function. -It is effectively const except that play->setup_random() is called. - - -\param sub_info -is the subgraph information for this ADFun object. - -\param dep_taddr -mapping from user dependent variable index to variable index in play -(must have size sub_info.n_dep()). - -\param select_domain -only the selected independent variables will be included in the sparsity -pattern (must have size sub_info.n_ind()). - -\param select_range -only the selected dependent variables will be included in the sparsity pattern -(must have size sub_info.n_dep()). - -\param row_out -The input size and elements of row_out do not matter. -We use number of non-zeros (nnz) to denote the number of elements -in row_out. For k = 0 , ... , nnz-1, row_out[k] is the row index -of the k-th no-zero element of the dependency sparsitiy pattern for -the function corresponding to the recording. -\code - 0 <= row_out[k] < dep_taddr.size() - select_range[ row_out[k] ] == true -\endcode - -\param col_out -The input size and elements of col_out do not matter. -Upon return is has the same size as row_out; i.e., nnz. -For k = 0 , ... , nnz-1, col_out[k] is the column index -of the k-th no-zero element of the dependency sparsitiy pattern for -the function corresponding to the recording. -\code - 0 <= col_out[k] < sub_info.n_ind() - select_domain[ col_out[k] ] == true -\endcode - -\par AFunOp -All of the inputs and outputs for an atomic function call are considered -to be connected. -2DO: It would be good to use the sparsity patters for atomic function calls -to to make the sparsity pattern more efficient. -*/ - -template -void subgraph_sparsity( - player* play , - subgraph_info& sub_info , - const pod_vector& dep_taddr , - const BoolVector& select_domain , - const BoolVector& select_range , - pod_vector& row_out , - pod_vector& col_out ) -{ - // get random access iterator for this player - play->template setup_random(); - local::play::const_random_iterator random_itr = - play->template get_random(); - - // check dimension assumptions - CPPAD_ASSERT_UNKNOWN( - dep_taddr.size() == sub_info.n_dep() - ); - CPPAD_ASSERT_UNKNOWN( - size_t(select_domain.size()) == sub_info.n_ind() - ); - CPPAD_ASSERT_UNKNOWN( - size_t(select_range.size()) == sub_info.n_dep() - ); - - // number of dependent variables - size_t n_dep = dep_taddr.size(); - CPPAD_ASSERT_UNKNOWN( size_t(select_range.size()) == n_dep ); - - // start with an empty sparsity pattern - row_out.resize(0); - col_out.resize(0); - - // map_user_op - if( sub_info.map_user_op().size() == 0 ) - sub_info.set_map_user_op(play); - else - { CPPAD_ASSERT_UNKNOWN( sub_info.check_map_user_op(play) ); - } - CPPAD_ASSERT_UNKNOWN( - sub_info.map_user_op().size() == play->num_op_rec() - ); - - // subgraph of operators that are are connected to one of the selected - // dependent variables and depend on the selected independent variables - pod_vector subgraph; - - // initialize a reverse mode subgraph calculation - sub_info.init_rev(random_itr, select_domain); - CPPAD_ASSERT_UNKNOWN( - sub_info.in_subgraph().size() == play->num_op_rec() - ); - // -# ifndef NDEBUG - addr_t depend_yes = addr_t( n_dep ); -# endif - - // for each of the selected dependent variables -# ifndef NDEBUG - addr_t depend_no = addr_t( n_dep + 1 ); -# endif - CPPAD_ASSERT_UNKNOWN( depend_yes < depend_no ); - CPPAD_ASSERT_UNKNOWN( NumRes(BeginOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(InvOp) == 1 ); - for(size_t i_dep = 0; i_dep < n_dep; ++i_dep) if( select_range[i_dep] ) - { CPPAD_ASSERT_UNKNOWN( i_dep < size_t( depend_yes ) ); - // - // subgraph of operators connected to i_dep - sub_info.get_rev( - random_itr, dep_taddr, addr_t(i_dep), subgraph - ); - // - for(size_t k = 0; k < subgraph.size(); k++) - { size_t i_op = size_t( subgraph[k] ); - // - // operator corresponding to this index - OpCode op = play->GetOp(i_op); - // - // This version of the subgraph only has first AFunOp - // for each atomic functionc all. - CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 || op == AFunOp ); - // - // independent variable entries correspond to sparsity pattern - if( op == InvOp ) - { CPPAD_ASSERT_NARG_NRES(op, 0, 1); - // i_var is equal i_op becasue BeginOp and InvOp have 1 result - size_t i_var = i_op; // tape index for this variable - size_t i_ind = i_var - 1; // user index for this variable - CPPAD_ASSERT_UNKNOWN( random_itr.var2op(i_var) == i_op ); - CPPAD_ASSERT_UNKNOWN( select_domain[i_ind] ); - // - // put this pair in the sparsity pattern - row_out.push_back(i_dep); - col_out.push_back(i_ind); - } - } - } -} - -} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/call_atomic.hpp b/build-config/cppad/include/cppad/local/sweep/call_atomic.hpp deleted file mode 100644 index 39f9a8e0..00000000 --- a/build-config/cppad/include/cppad/local/sweep/call_atomic.hpp +++ /dev/null @@ -1,902 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_CALL_ATOMIC_HPP -# define CPPAD_LOCAL_SWEEP_CALL_ATOMIC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - -// BEGIN_CPAPD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file call_atomic.hpp -Callbacks to atomic functions corresponding to atomic_index. -*/ -// ---------------------------------------------------------------------------- -/*! -Forward mode callback to atomic functions. - -\tparam Base -Is the type corresponding to the Taylor coefficients. - -\tparam RecBase -Is the type corresponding to this atomic function. - -\param parameter_x [in] -contains the values, in afun(ax, ay), for arguments that are parameters. - -\param type_x [in] -what is the type, in afun(ax, ay), for each component of x. - -\param need_y -specifies which components of taylor_y are necessary. - -\param order_low [in] -lowerest order for this forward mode calculation. - -\param order_up [in] -highest order for this forward mode calculation. - -\param atom_index [in] -is the index, in local::atomic_index, corresponding to this atomic function. - -\param atom_old [in] -is the extra id information for this atomic function in the atomic_one case. - -\param taylor_x [in] -Taylor coefficients corresponding to x. - -\param taylor_y [out] -Taylor coefficient corresponding to y. -*/ -template -void call_atomic_forward( - const vector& parameter_x , - const vector& type_x , - size_t need_y , - size_t order_low , - size_t order_up , - size_t atom_index , - size_t atom_old , - const vector& taylor_x , - vector& taylor_y ) -{ CPPAD_ASSERT_UNKNOWN( 0 < atom_index ); - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); -# ifndef NDEBUG - bool ok = v_ptr != nullptr; - if( ok ) - { - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - vector empty; - ok = afun->forward( - order_low, order_up, empty, empty, taylor_x, taylor_y - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - ok = afun->forward( - parameter_x, type_x, - need_y, order_low, order_up, taylor_x, taylor_y - ); - } - } - if( ! ok ) - { // now take the extra time to copy the name - std::string name; - local::atomic_index(set_null, atom_index, type, &name, v_ptr); - std::string msg = name; - if( v_ptr == nullptr ) - msg += ": this atomic_three function has been deleted"; - else - msg += ": atomic forward returned false"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# else - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - vector empty; - afun->set_old(atom_old); - afun->forward( - order_low, order_up, empty, empty, taylor_x, taylor_y - ); - } - else - { atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - afun->forward( - parameter_x, type_x, - need_y, order_low, order_up, taylor_x, taylor_y - ); - } -# endif -} -// ---------------------------------------------------------------------------- -/*! -Reverse mode callback to atomic functions. - -\tparam Base -Is the type corresponding to the Taylor coefficients. - -\tparam RecBase -Is the type corresponding to this atomic function. - -\param parameter_x [in] -value of the parameter arguments to the atomic function -(other arguments have the value nan). - -\param type_x [in] -type for each component of x (not used by atomic_two interface). - -\param order_up [in] -highest order for this reverse mode calculation. - -\param atom_index [in] -is the index, in local::atomic_index, corresponding to this atomic function. - -\param atom_old [in] -is the extra id information for this atomic function in the atomic_one case. - -\param taylor_x [in] -Taylor coefficients corresponding to x. - -\param taylor_y [in] -Taylor coefficient corresponding to y. - -\param partial_x [out] -Partials w.r.t the x Taylor coefficients. - -\param partial_y [in] -Partials w.r.t the y Taylor coefficients. -*/ -template -void call_atomic_reverse( - const vector& parameter_x , - const vector& type_x , - size_t order_up , - size_t atom_index , - size_t atom_old , - const vector& taylor_x , - const vector& taylor_y , - vector& partial_x , - const vector& partial_y ) -{ CPPAD_ASSERT_UNKNOWN( 0 < atom_index ); - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); -# ifndef NDEBUG - bool ok = v_ptr != nullptr; - if( ok ) - { - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - ok = afun->reverse( - order_up, taylor_x, taylor_y, partial_x, partial_y - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - ok = afun->reverse( - parameter_x, type_x, - order_up, taylor_x, taylor_y, partial_x, partial_y - ); - } - } - if( ! ok ) - { // now take the extra time to copy the name - std::string name; - local::atomic_index(set_null, atom_index, type, &name, v_ptr); - std::string msg = name; - if( v_ptr == nullptr ) - msg += ": this atomic_three function has been deleted"; - else - msg += ": atomic reverse returned false"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# else - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - afun->reverse( - order_up, taylor_x, taylor_y, partial_x, partial_y - ); - } - else - { atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - afun->reverse( - parameter_x, type_x, - order_up, taylor_x, taylor_y, partial_x, partial_y - ); - } -# endif -} -// ---------------------------------------------------------------------------- -/*! -Forward Jacobian sparsity callback to atomic functions. - -\tparam Base -is the type corresponding to parameter_x -and to this atomic function. - -\tparam InternalSparsity -is the internal type used to represent sparsity; i.e., -sparse::pack_setvec or sparse::list_setvec. - -\param atom_index [in] -is the index, in local::atomic_index, corresponding to this atomic function. - -\param atom_old [in] -is the extra id information for this atomic function in the atomic_one case. - -\param dependency [in] -is this a dependency or sparsity calculation. - -\param parameter_x [in] -value of the parameter arguments to the atomic function -(other arguments have the value nan). - -\param type_x [in] -type for each component of x (not used by atomic_two interface). - -\param x_index [in] -is a mapping from the index of an atomic function argument -to the corresponding variable on the tape. - -\param y_index [in] -is a mapping from the index of an atomic function result -to the corresponding variable on the tape. - -\param var_sparsity [in/out] -On input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the sparsity for the j-th argument to this atomic function. -On output, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the sparsity for the j-th result for this atomic function. -*/ -template -void call_atomic_for_jac_sparsity( - size_t atom_index , - size_t atom_old , - bool dependency , - const vector& parameter_x , - const vector& type_x , - const pod_vector& x_index , - const pod_vector& y_index , - InternalSparsity& var_sparsity ) -{ CPPAD_ASSERT_UNKNOWN( 0 < atom_index ); - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); -# ifndef NDEBUG - bool ok = v_ptr != nullptr; - if ( ok ) - { - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - ok = afun->for_sparse_jac( - parameter_x, x_index, y_index, var_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - ok = afun->for_jac_sparsity( - dependency, parameter_x, type_x, x_index, y_index, var_sparsity - ); - } - } - if( ! ok ) - { // now take the extra time to copy the name - std::string name; - local::atomic_index( - set_null, atom_index, type, &name, v_ptr - ); - std::string msg = name; - if( v_ptr == nullptr ) - msg += ": this atomic_three function has been deleted"; - else - msg += ": atomic jac_sparsity returned false"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# else - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - afun->for_sparse_jac( - parameter_x, x_index, y_index, var_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - afun->for_jac_sparsity( - dependency, parameter_x, type_x, x_index, y_index, var_sparsity - ); - } -# endif -} -// ---------------------------------------------------------------------------- -/*! -Reverse Jacobian sparsity callback to atomic functions. - -\tparam Base -is the type corresponding to parameter_x -and to this atomic function. - -\tparam InternalSparsity -is the internal type used to represent sparsity; i.e., -sparse::pack_setvec or sparse::list_setvec. - -\param atom_index [in] -is the index, in local::atomic_index, corresponding to this atomic function. - -\param atom_old [in] -is the extra id information for this atomic function in the atomic_one case. - -\param dependency [in] -is this a dependency or sparsity calculation. - -\param parameter_x [in] -value of the parameter arguments to the atomic function -(other arguments have the value nan). - -\param type_x [in] -type for each component of x (not used by atomic_two interface). - -\param x_index [in] -is a mapping from the index of an atomic function argument -to the corresponding variable on the tape. - -\param y_index [in] -is a mapping from the index of an atomic function result -to the corresponding variable on the tape. - -\param var_sparsity [in/out] -On input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the sparsity for the i-th argument to this atomic function. -On output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j], -the sparsity has been updated to remove y as a function of x. -*/ -template -void call_atomic_rev_jac_sparsity( - size_t atom_index , - size_t atom_old , - bool dependency , - const vector& parameter_x , - const vector& type_x , - const pod_vector& x_index , - const pod_vector& y_index , - InternalSparsity& var_sparsity ) -{ CPPAD_ASSERT_UNKNOWN( 0 < atom_index ); - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); -# ifndef NDEBUG - bool ok = v_ptr != nullptr; - if( ok ) - { - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - ok = afun->rev_sparse_jac( - parameter_x, x_index, y_index, var_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - ok = afun->rev_jac_sparsity( - dependency, parameter_x, type_x, x_index, y_index, var_sparsity - ); - } - } - if( ! ok ) - { // now take the extra time to copy the name - std::string name; - local::atomic_index( - set_null, atom_index, type, &name, v_ptr - ); - std::string msg = name; - if( v_ptr == nullptr ) - msg += ": this atomic_three function has been deleted"; - else - msg += ": atomic jac_sparsity returned false"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# else - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - afun->rev_sparse_jac( - parameter_x, x_index, y_index, var_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - afun->rev_jac_sparsity( - dependency, parameter_x, type_x, x_index, y_index, var_sparsity - ); - } -# endif -} -// ---------------------------------------------------------------------------- -/* -$begin call_atomic_for_hes_sparsiy$$ -$spell - hes - np - numvar - jac - Jacobian - afun - setvec -$$ - -$section Forward Hessian Sparsity Callback to Atomic Functions.$$ - -$head Syntax$$ -$codei%call_atomic_for_hes_sparsity( - %atom_index%, %atom_old%, %parameter_x%, %type_x%, %x_index%, %y_index%, - %np1%, %numvar%, %rev_jac_sparsity%, %for_sparsity% -)%$$ - -$head Prototype$$ -$srcthisfile% -0%// BEGIN_call_atomic_for_hes_sparsity%// END_call_atomic_for_hes_sparsity%1 -%$$ - -$head C++ Source$$ -The C++ source code corresponding to this operation is a -$cref/atomic function call/atomic_three/Syntax/Use Atomic Function/$$ -$codei% - %afun%(%ax%, %ay%) -%$$ -We refer to the corresponding function using $latex y = f(x)$$. - -$head Base$$ -is the type corresponding to $icode parameter_x$$ -and to this atomic function. - -$head InternalSparsity$$ -is the internal type used to represent sparsity; i.e., -$code sparse::pack_setvec$$ or $code sparse::list_setvec$$. - -$head atom_index$$ -is the index, in local::atomic_index, corresponding to this atomic function. - -$head atom_old$$ -is the extra id information for this atomic function in the atomic_one case. - -$head parameter_x$$ -value of the parameter arguments to the atomic function -(other arguments have the value nan). - -$head type_x$$ -type for each component of x (not used by atomic_two interface). - -$head x_index$$ -is a mapping from the index of an atomic function argument -to the corresponding variable on the tape. -We use $icode m_x$$ to denote the maximum value w.r.t $icode i$$ of -$icode%x_index%[%i%]%$$. - -$head y_index$$ -is a mapping from the index of an atomic function result -to the corresponding variable on the tape. -It should hold that $icode%m_i% < y_index%[%i%]%$$ for all $icode i$$. - -$head np1$$ -This is the number of independent variables plus one; -i.e. size of $icode x$$ plus one. - -$head numvar$$ -This is the total number of variables in the tape. - -$head rev_jac_sparsity$$ -For i = 0, ... , m-1, the sparsity pattern with index y_index[i], -is the reverse Jacobian sparsity for the i-th result to this atomic function. -This shows which components of the result affect the function we are -computing the Hessian of. - -$head for_sparsity$$ -We have the conditions $icode%np1% = %for_sparsity%.end()%$$ -and $icode%for_sparsity%.n_set() = %np1% + %numvar%$$. - -$subhead Input Jacobian Sparsity$$ -For $icode%i%= 0, ..., %m_x%$$, -the $icode%np1%+%i%$$ row of $icode for_sparsity$$ is the Jacobian sparsity -for the $th i$$ variable. These values do not change. -Note that $icode%i%=0%$$ corresponds to a parameter and -the corresponding Jacobian sparsity is empty. - -$subhead Input Hessian Sparsity$$ -For $icode%i%=1, ..., %n%$$, -the $th i$$ row of $icode for_sparsity$$ is the Hessian sparsity -before including the function $latex y = f(x)$$. - -$subhead Output Jacobian Sparsity$$ -For $icode%i%=0, ..., %y_index%.size()%$$, -row $icode%np1%+%y_index%[%i%]%$$ -of $icode for_sparsity$$ is the Jacobian sparsity -for the variable with index $icode%y_index%[%i%]%$$. - -$subhead Output Hessian Sparsity$$ -For $icode%i%=1, ..., %n%$$, -the $th i$$ row of $icode for_sparsity$$ is the Hessian sparsity -after including the function $latex y = f(x)$$. - -$end -*/ -// BEGIN_call_atomic_for_hes_sparsity -template -void call_atomic_for_hes_sparsity( - size_t atom_index , - size_t atom_old , - const vector& parameter_x , - const vector& type_x , - const pod_vector& x_index , - const pod_vector& y_index , - size_t np1 , - size_t numvar , - const InternalSparsity& rev_jac_sparsity , - InternalSparsity& for_sparsity ) -// END_call_atomic_for_hes_sparsity -{ CPPAD_ASSERT_UNKNOWN( 0 < atom_index ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 ); - CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar ); - - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); -# ifndef NDEBUG - bool ok = v_ptr != nullptr; - if( ok ) - { - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - ok = afun->for_sparse_hes( - parameter_x, - x_index, - y_index, - np1, - numvar, - rev_jac_sparsity, - for_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - ok = afun->for_hes_sparsity( - parameter_x, - type_x, - x_index, - y_index, - np1, - numvar, - rev_jac_sparsity, - for_sparsity - ); - } - } - if( ! ok ) - { // now take the extra time to copy the name - std::string name; - local::atomic_index( - set_null, atom_index, type, &name, v_ptr - ); - std::string msg = name; - if( v_ptr == nullptr ) - msg += ": this atomic_three function has been deleted"; - else - msg += ": atomic hes_sparsity returned false"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# else - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - afun->for_sparse_hes( - parameter_x, - x_index, - y_index, - np1, - numvar, - rev_jac_sparsity, - for_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - afun->for_hes_sparsity( - parameter_x, - type_x, - x_index, - y_index, - np1, - numvar, - rev_jac_sparsity, - for_sparsity - ); - } -# endif -} -// ---------------------------------------------------------------------------- -/*! -Reverse Hessian sparsity callback to atomic functions. - -\tparam Base -is the type corresponding to parameter_x -and to this atomic function. - -\tparam InternalSparsity -is the internal type used to represent sparsity; i.e., -sparse::pack_setvec or sparse::list_setvec. - -\param atom_index [in] -is the index, in local::atomic_index, corresponding to this atomic function. - -\param atom_old [in] -is the extra id information for this atomic function in the atomic_one case. - -\param parameter_x [in] -value of the parameter arguments to the atomic function -(other arguments have the value nan). - -\param type_x [in] -type for each component of x (not used by atomic_two interface). - -\param x_index [in] -is a mapping from the index of an atomic function argument -to the corresponding variable on the tape. - -\param y_index [in] -is a mapping from the index of an atomic function result -to the corresponding variable on the tape. - -\param for_jac_sparsity -For j = 0, ... , n-1, the sparsity pattern with index x_index[j], -is the forward Jacobian sparsity for the j-th argument to this atomic function. - -\param rev_jac_flag -On input, for i = 0, ... , m-1, rev_jac_flag[ y_index[i] ] is true -if the fuction (we are computing the sparsity for) -depends on the variable y_index[i]. -Upon return, for j = 0, ..., n-1, rev_jac_flag[ x_index[j] ] has been set to -true any of the y_index variables are flagged depnend on x_index[j]. -Otherwise, rev_jac_flag[ x_index[j] ] is not modified. - -\param rev_hes_sparsity -This is the sparsity pattern for the Hessian. -On input, for i = 0, ... , m-1, row y_index[i] is the reverse Hessian sparsity -with one of the partials with respect to to y_index[i]. -Upon return, for j = 0, ..., n-1, the row x_index[j] has been -modified to include components that have a non-zero hessian through -the atomic fucntion with one of the partials w.r.t. x_index[j]. -*/ -template -void call_atomic_rev_hes_sparsity( - size_t atom_index , - size_t atom_old , - const vector& parameter_x , - const vector& type_x , - const pod_vector& x_index , - const pod_vector& y_index , - const InternalSparsity& for_jac_sparsity , - bool* rev_jac_flag , - InternalSparsity& rev_hes_sparsity ) -{ CPPAD_ASSERT_UNKNOWN( 0 < atom_index ); - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); -# ifndef NDEBUG - bool ok = v_ptr != nullptr; - if( ok ) - { - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - ok = afun->rev_sparse_hes( - parameter_x, - x_index, - y_index, - for_jac_sparsity, - rev_jac_flag, - rev_hes_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - ok = afun->rev_hes_sparsity( - parameter_x, - type_x, - x_index, - y_index, - for_jac_sparsity, - rev_jac_flag, - rev_hes_sparsity - ); - } - } - if( ! ok ) - { // now take the extra time to copy the name - std::string name; - local::atomic_index( - set_null, atom_index, type, &name, v_ptr - ); - std::string msg = name; - if( v_ptr == nullptr ) - msg += ": this atomic_three function has been deleted"; - else - msg += ": atomic hes_sparsity returned false"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# else - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - afun->rev_sparse_hes( - parameter_x, - x_index, - y_index, - for_jac_sparsity, - rev_jac_flag, - rev_hes_sparsity - ); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - afun->rev_hes_sparsity( - parameter_x, - type_x, - x_index, - y_index, - for_jac_sparsity, - rev_jac_flag, - rev_hes_sparsity - ); - } -# endif -} -// ---------------------------------------------------------------------------- -/*! -Reverse dependency callback to atomic functions. - -\param atom_index [in] -is the index, in local::atomic_index, corresponding to this atomic function. - -\param atom_old [in] -is the extra id information for this atomic function in the atomic_one case. - -\param parameter_x [in] -is the value of the parameters in the corresponding function call -afun(ax, ay). - -\param type_x [in] -is the type for each x component in the corresponding function call -afun(ax, ay). - -\param depend_x [out] -specifies which components of x affect values we are interested in. - -\param depend_y [in] -specifies which components of y affect values we are interested in. -*/ -template -void call_atomic_rev_depend( - size_t atom_index , - size_t atom_old , - const vector& parameter_x , - const vector& type_x , - vector& depend_x , - const vector& depend_y ) -{ CPPAD_ASSERT_UNKNOWN( 0 < atom_index ); - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string* name_ptr = nullptr; - void* v_ptr = nullptr; // set to avoid warning - local::atomic_index(set_null, atom_index, type, name_ptr, v_ptr); -# ifndef NDEBUG - bool ok = v_ptr != nullptr; - if( ok ) - { - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - afun->set_old(atom_old); - vector empty; - ok = afun->rev_depend(parameter_x, type_x, depend_x, depend_y); - } - else - { CPPAD_ASSERT_UNKNOWN( type == 3 ); - atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - ok = afun->rev_depend(parameter_x, type_x, depend_x, depend_y); - } - } - if( ! ok ) - { // now take the extra time to copy the name - std::string name; - local::atomic_index(set_null, atom_index, type, &name, v_ptr); - std::string msg = name; - if( v_ptr == nullptr ) - msg += ": this atomic_three function has been deleted"; - else - msg += ": atomic rev_depend returned false"; - CPPAD_ASSERT_KNOWN(false, msg.c_str() ); - } -# else - if( type == 2 ) - { atomic_base* afun = - reinterpret_cast< atomic_base* >(v_ptr); - vector empty; - afun->set_old(atom_old); - afun->rev_depend(parameter_x, type_x, depend_x, depend_y); - } - else - { atomic_three* afun = - reinterpret_cast< atomic_three* >(v_ptr); - afun->rev_depend(parameter_x, type_x, depend_x, depend_y); - } -# endif -} - - -} } } // END_CPAPD_LOCAL_SWEEP_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/dev_sweep.omh b/build-config/cppad/include/cppad/local/sweep/dev_sweep.omh deleted file mode 100644 index 6ff99178..00000000 --- a/build-config/cppad/include/cppad/local/sweep/dev_sweep.omh +++ /dev/null @@ -1,24 +0,0 @@ ------------------------------------------------------------------------------ -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ------------------------------------------------------------------------------ -$begin dev_sweep$$ - -$section Developer Sweep Documentation$$ - -$childtable% - include/cppad/local/sweep/forward0.hpp% - include/cppad/local/sweep/for_hes.hpp% - include/cppad/local/sweep/rev_jac.hpp% - include/cppad/local/sweep/call_atomic.hpp -%$$ - - -$end diff --git a/build-config/cppad/include/cppad/local/sweep/dynamic.hpp b/build-config/cppad/include/cppad/local/sweep/dynamic.hpp deleted file mode 100644 index a63a42f9..00000000 --- a/build-config/cppad/include/cppad/local/sweep/dynamic.hpp +++ /dev/null @@ -1,549 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_DYNAMIC_HPP -# define CPPAD_LOCAL_SWEEP_DYNAMIC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file sweep/dynamic.hpp -Under Consruction -*/ - -/*! -\def CPPAD_DYNAMIC_TRACE -This value is either zero or one. -Zero is the normal operational value. -If it is one, a trace for each dynamic parameter is compuation is printed. -Sometimes it is usefull to trace f.new_dynamic with the same -dynamic parameter values as during the recording -(to debug the recording process). -*/ -# define CPPAD_DYNAMIC_TRACE 0 - -/*! -Compute dynamic parameters. - -\tparam Base -The type of the parameters. - -\tparam BaseVector -is a simple vector class with elements of type Base. - -\param ind_dynamic -new value for the independent dynamic parameter vector. - -\param all_par_vec -is the vector of all the parameters. -Ths constant parameters are inputs and the dynamic parameters are outputs. - -\param dyn_par_is -is a vector with the same length as par_vec. -The i-th parameter is dynamic if and only if dyn_par_is[i] is true. - -\param dyn_ind2par_ind -is a vector with length equal to the number of dynamic parameters. -The element dyn_ind2par_ind[j] is the index in all_par_vec corresponding -to the j-th dynamic parameter. -Note that if dyn_par_is[i] is false, the i-th parameter does not -appear in this vector. - -\param dyn_par_op -is a vector with length equal to the number of dynamic parameters. -The element dyn_par_op_[j] is the operator for the j-th dynamic parameter. -Note that if dyn_par_is[i] is false, the i-th parameter does not -have a parameter in this list. - -\param dyn_par_arg -is a vector containing the arguments for the dynamic parameters. -The first argument for the j-th dynamic parameter is dyn_par_arg[k] -where -\code - k = NumArg( dyn_par_op[0] ) + ... + NumArg( dyn_par_op[j-1] ) -\endcode -The arguments for each dynamic parameter have index value -lower than the index value for the parameter. - -\param not_used_rec_base -Specifies RecBase for this call. -*/ -template -void dynamic( - pod_vector_maybe& all_par_vec , - const BaseVector& ind_dynamic , - const pod_vector& dyn_par_is , - const pod_vector& dyn_ind2par_ind , - const pod_vector& dyn_par_op , - const pod_vector& dyn_par_arg , - const RecBase& not_used_rec_base ) -{ - // number of dynamic parameters - size_t num_dynamic_par = dyn_ind2par_ind.size(); - - // vectors used in call to atomic fuctions - vector type_x; - vector taylor_x, taylor_y; -# ifndef NDEBUG - for(size_t j = 0; j < ind_dynamic.size(); ++j) - CPPAD_ASSERT_UNKNOWN( - dyn_par_is[j+1] && op_code_dyn( dyn_par_op[j] ) == ind_dyn - ); -# endif -# if CPPAD_DYNAMIC_TRACE - const char* cond_exp_name[] = { - "CondExpLt", - "CondExpLe", - "CondExpEq", - "CondExpGe", - "CondExpGt", - "CondExpNe" - }; - std::cout - << std::endl - << std::setw(10) << std::left << "index" - << std::setw(10) << std::left << "old" - << std::setw(10) << std::left << "new" - << std::setw(11) << std::left << "op" - << std::setw(26) << std::right << "dynamic i=, constant v=" - << std::endl; -# endif - // used to hold the first two parameter arguments - const Base* par[2]; - for(size_t j = 0; j < 2; ++j) - par[j] = nullptr; - // - // Initialize index in dyn_par_arg - size_t i_arg = 0; - // - // Loop throubh the dynamic parameters - size_t i_dyn = 0; - while(i_dyn < num_dynamic_par) - { // number of dynamic parameters created by this operator - size_t n_dyn = 1; - // - // parameter index for this dynamic parameter - size_t i_par = size_t( dyn_ind2par_ind[i_dyn] ); - // -# if CPPAD_DYNAMIC_TRACE - Base old_value = all_par_vec[i_par]; -# endif - // - // operator for this dynamic parameter - op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] ); - // - // number of arguments for this operator - size_t n_arg = num_arg_dyn(op); - // - // for unary or binary operators - bool unary_or_binary = true; - unary_or_binary &= op != atom_dyn; - unary_or_binary &= op != cond_exp_dyn; - unary_or_binary &= op != dis_dyn; - unary_or_binary &= op != ind_dyn; - unary_or_binary &= op != result_dyn; - if( unary_or_binary ) - { CPPAD_ASSERT_UNKNOWN( n_arg == 1 || n_arg == 2 ); - for(size_t j = 0; j < n_arg; ++j) - par[j] = & all_par_vec[ dyn_par_arg[i_arg + j] ]; - } - // - switch(op) - { - // --------------------------------------------------------------- - // standard_math_98 - // acos - case acos_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = acos( *par[0] ); - break; - - // asin - case asin_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = asin( *par[0] ); - break; - - // atan - case atan_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = atan( *par[0] ); - break; - - // cos - case cos_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = cos( *par[0] ); - break; - - // cosh - case cosh_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = cosh( *par[0] ); - break; - - // ind - case ind_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 0 ); - CPPAD_ASSERT_UNKNOWN( i_par == i_dyn + 1 ); - all_par_vec[i_par] = ind_dynamic[i_dyn]; - break; - - // exp - case exp_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = exp( *par[0] ); - break; - - // fabs - case fabs_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = fabs( *par[0] ); - break; - - // log - case log_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = log( *par[0] ); - break; - - // sin - case sin_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = sin( *par[0] ); - break; - - // sinh - case sinh_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = sinh( *par[0] ); - break; - - // sqrt - case sqrt_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = sqrt( *par[0] ); - break; - - // tan - case tan_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = tan( *par[0] ); - break; - - // tanh - case tanh_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = tanh( *par[0] ); - break; - - // --------------------------------------------------------------- - // asinh - case asinh_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = asinh( *par[0] ); - break; - - // acosh - case acosh_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = acosh( *par[0] ); - break; - - // atanh - case atanh_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = atanh( *par[0] ); - break; - - // expm1 - case expm1_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = expm1( *par[0] ); - break; - - // erf - case erf_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = erf( *par[0] ); - break; - - // erfc - case erfc_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = erfc( *par[0] ); - break; - - // log1p - case log1p_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = log1p( *par[0] ); - break; - // --------------------------------------------------------------- - // abs - case abs_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = fabs( *par[0] ); - break; - - // add - case add_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - all_par_vec[i_par] = *par[0] + *par[1]; - break; - - // div - case div_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - all_par_vec[i_par] = *par[0] / *par[1]; - break; - - // mul - case mul_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - all_par_vec[i_par] = *par[0] * *par[1]; - break; - - // pow - case pow_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - all_par_vec[i_par] = pow( *par[0], *par[1] ); - break; - - // sign - case sign_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 1 ); - all_par_vec[i_par] = sign( *par[0] ); - break; - - // sub - case sub_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - all_par_vec[i_par] = *par[0] - *par[1]; - break; - - // zmul - case zmul_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - all_par_vec[i_par] = azmul( *par[0], *par[1] ); - break; - - // --------------------------------------------------------------- - // discrete(index, argument) - case dis_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 2 ); - all_par_vec[i_par] = discrete::eval( - size_t( dyn_par_arg[i_arg + 0] ) , // index - all_par_vec[ dyn_par_arg[i_arg + 1] ] // argument - ); -# if CPPAD_DYNAMIC_TRACE - std::cout - << std::setw(10) << std::left << i_par - << std::setw(10) << std::left << old_value - << std::setw(10) << std::left << all_par_vec[i_par] - << "=" - << std::setw(10) << std::right << op_name_dyn(op) - << "(" - << std::setw(12) << std::right << - discrete::name( size_t( dyn_par_arg[i_arg + 0] ) ); - if( dyn_par_is[ dyn_par_arg[i_arg + 1] ] ) - { std::cout << ", i=" << std::setw(10) << std::right - << dyn_par_arg[i_arg + 1]; - } - else - { std::cout << ", v=" << std::setw(10) << std::right - << all_par_vec[ dyn_par_arg[i_arg + 1] ]; - } - std::cout << ")" << std::endl; -# endif - break; - - // --------------------------------------------------------------- - // cond_exp(cop, left, right, if_true, if_false) - // (not yet implemented) - case cond_exp_dyn: - CPPAD_ASSERT_UNKNOWN( n_arg == 5 ); - all_par_vec[i_par] = CondExpOp( - CompareOp( dyn_par_arg[i_arg + 0] ) , // cop - all_par_vec[ dyn_par_arg[i_arg + 1] ] , // left - all_par_vec[ dyn_par_arg[i_arg + 2] ] , // right - all_par_vec[ dyn_par_arg[i_arg + 3] ] , // if_true - all_par_vec[ dyn_par_arg[i_arg + 4] ] // if_false - ); -# if CPPAD_DYNAMIC_TRACE - std::cout - << std::setw(10) << std::left << i_par - << std::setw(10) << std::left << old_value - << std::setw(10) << std::left << all_par_vec[i_par] - << "=" - << std::setw(10) << std::right - << cond_exp_name[ dyn_par_arg[i_arg + 0] ] - << "("; - for(size_t i = 1; i < 5; ++i) - { if( dyn_par_is[ dyn_par_arg[i_arg + i] ] ) - { std::cout << "i=" << std::setw(10) << std::right - << dyn_par_arg[i_arg + i]; - } - else - { std::cout << "v=" << std::setw(10) << std::right - << all_par_vec[ dyn_par_arg[i_arg + i] ]; - } - if( i < 4 ) - std::cout << ","; - } - std::cout << ")" << std::endl; -# endif - break; - // --------------------------------------------------------------- - // atomic function results - case result_dyn: - break; - - // atomic function call - case atom_dyn: - { size_t atom_index = size_t( dyn_par_arg[i_arg + 0] ); - size_t n = size_t( dyn_par_arg[i_arg + 1] ); - size_t m = size_t( dyn_par_arg[i_arg + 2] ); - n_dyn = size_t( dyn_par_arg[i_arg + 3] ); - n_arg = 5 + n + m; - CPPAD_ASSERT_UNKNOWN( - size_t( dyn_par_arg[i_arg + 4 + n + m] ) == n_arg - ); - // - size_t need_y = size_t(dynamic_enum); - size_t order_low = 0; - size_t order_up = 0; - size_t atom_old = 0; // not used - type_x.resize(n); - taylor_x.resize(n); - taylor_y.resize(m); - for(size_t j = 0; j < n; ++j) - { addr_t arg_j = dyn_par_arg[i_arg + 4 + j]; - taylor_x[j] = all_par_vec[ arg_j ]; - if( arg_j == 0 ) - type_x[j] = variable_enum; - else if ( dyn_par_is[arg_j] ) - type_x[j] = dynamic_enum; - else - type_x[j] = constant_enum; - } - call_atomic_forward( - taylor_x, - type_x, - need_y, - order_low, - order_up, - atom_index, - atom_old, - taylor_x, - taylor_y - ); -# if CPPAD_DYNAMIC_TRACE - // get the name of this atomic function - bool set_null = false; - size_t type = 0; // set to avoid warning - std::string name; - void* v_ptr = nullptr; // set to avoid warning - atomic_index( - set_null, atom_index, type, &name, v_ptr - ); - std::cout << "atom_dyn " << name << " arguments\n"; - for(size_t j = 0; j < n; ++j) - { std::cout << "index = " << j - << ", value = " << taylor_x[j] << std::endl; - } - std::cout << "atom_dyn " << name << " results\n"; -# endif -# ifndef NDEBUG - size_t count_dyn = 0; -# endif - for(size_t i = 0; i < m; ++i) - { i_par = size_t( dyn_par_arg[i_arg + 4 + n + i] ); - if( dyn_par_is[i_par] ) - { CPPAD_ASSERT_UNKNOWN( i_par != 0 ); - all_par_vec[i_par] = taylor_y[i]; -# ifndef NDEBUG - ++count_dyn; -# endif -# if CPPAD_DYNAMIC_TRACE - std::cout - << std::setw(10) << std::left << i_par - << std::setw(10) << std::left << old_value - << std::setw(10) << std::left << all_par_vec[i_par] - << "= " << name << "_" << i << std::endl; -# endif - } - } - CPPAD_ASSERT_UNKNOWN( count_dyn == n_dyn ); -# if CPPAD_DYNAMIC_TRACE - std::cout << "end atomic dynamic parameter results\n"; -# endif - } - break; - - // --------------------------------------------------------------- - default: - std::cerr << "op_code_dyn = " << op_name_dyn(op) << std::endl; - CPPAD_ASSERT_UNKNOWN(false); - break; - } -# if CPPAD_DYNAMIC_TRACE - if( - (op != cond_exp_dyn) & - (op != dis_dyn ) & - (op != atom_dyn ) & - (op != result_dyn ) ) - { - std::cout - << std::setw(10) << std::left << i_par - << std::setw(10) << std::left << old_value - << std::setw(10) << std::left << all_par_vec[i_par] - << "=" - << std::setw(10) << std::right << op_name_dyn(op) - << "("; - if( 0 < n_arg ) - { if( dyn_par_is[ dyn_par_arg[i_arg + 0] ] ) - { std::cout << "i=" << std::setw(10) << std::right - << dyn_par_arg[i_arg + 0]; - } - else - { std::cout << "v=" << std::setw(10) << std::right - << all_par_vec[ dyn_par_arg[i_arg + 0] ]; - } - } - if( 1 < n_arg ) - { if( dyn_par_is[ dyn_par_arg[i_arg + 1] ] ) - { std::cout << ", i=" << std::setw(10) << std::right - << dyn_par_arg[i_arg + 1]; - } - else - { std::cout << ", v=" << std::setw(10) << std::right - << all_par_vec[ dyn_par_arg[i_arg + 1] ]; - } - } - std::cout << ")" << std::endl; - } -# endif - i_arg += n_arg; - i_dyn += n_dyn; - } - CPPAD_ASSERT_UNKNOWN( i_arg == dyn_par_arg.size() ) - return; -} - -// preprocessor symbols that are local to this file -# undef CPPAD_DYNAMIC_TRACE - -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/for_hes.hpp b/build-config/cppad/include/cppad/local/sweep/for_hes.hpp deleted file mode 100644 index b9474674..00000000 --- a/build-config/cppad/include/cppad/local/sweep/for_hes.hpp +++ /dev/null @@ -1,670 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_FOR_HES_HPP -# define CPPAD_LOCAL_SWEEP_FOR_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -/* -$begin local_sweep_for_hes$$ -$spell - hes - numvar - jac - Jacobian - num_var - Addr - InvOp - setvec -$$ - -$section Forward Mode Hessian Sparsity Patterns$$ - -$head Syntax$$ -$codei%local::sweep::for_hes( - %play% , - %n% , - %numvar% , - %select_domain% , - %rev_jac_sparse% , - %for_hes_sparse% , - %not_used_rec_base -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN PROTOTYPE%// END PROTOTYPE%1 -%$$ - - -$head Purpose$$ -Given the forward Jacobian sparsity pattern for all the variables, -and the reverse Jacobian sparsity pattern for the dependent variables, -$code for_hes$$ computes the Hessian sparsity pattern for all the independent -variables. - -$head Tracing$$ -This value is either zero or one. Zero is the normal operational value. -If it is one, a trace of Jacobian and Hessian sparsity result for every -operation for every $code for_hes$$ sweep is printed. -The sparsity patterns are printed as binary numbers with 1 (0) meaning that -the corresponding index is (is not) in the set. -$codep */ -# define CPPAD_FOR_HES_TRACE 0 -/* $$ - -$head Addr$$ -Is the type used to record address on this tape -This is allows for smaller tapes when address are smaller. - -$head Base$$ -The operation sequence in $icode play$$ was recorded using -$codei%AD<%Base%>%$$. - -$head RecBase$$ -Is the base type when this function was recorded. -This is different from $icode Base$$ if -this function object was created by $cref base2ad$$. - -$head SetVector$$ -This is a $cref SetVector$$ type. - -$head play$$ -The information stored in play -is a recording of the operations corresponding to a function -$latex F : \B{R}^n \rightarrow \B{R}^m$$ -where $icode m$$ is the number of dependent variables. - -$head n$$ -is the number of independent variables in the tape. - -$head numvar$$ -is the total number of variables in the tape; i.e., -$icode%play%->num_var_rec()%$$. -This is also the number of sets in all the sparsity patterns. - -$head select_domain$$ -is a vector with size $icode n$$ that specifies -which components of the domain to include in the Hessian sparsity pattern. -For $icode%j%= 0, ..., %n%-1%$$, the $th j$$ independent variable -will be included if and only if $icode%select_domain%[%j%]%$$ is true. -This assumes that the order of the independent variables is the same -as the order of the InvOp operators. - -$head rev_jac_sparse$$ -Is a sparsity pattern with size $icode numvar$$ by one. -For $icode%i%=1, %...%, %numvar%-1%$$, -the if the function we are computing the Hessian for has a non-zero -derivative w.r.t. variable with index $icode i$$, -the set with index $icode i$$ has the element zero. -Otherwise it has no elements. - -$head for_hes_sparse$$ -Is a sparsity pattern with size $icode%n%+1+%numvar%$$ by $icode%n%+1%$$. -The set with index zero and the element zero are not used. -The sets with index greater than $icode n$$ -are used for forward Jacobian sparsity. -The forward Hessian sparsity pattern for the variable with index $icode i$$ -corresponds to the set with index $icode i$$ in $icode for_hes_sparse$$. -The number of sets in this sparsity pattern is $icode%n%+1%$$ and the set -with index zero is not used. - -$subhead On Input$$ -For $icode%j%=1, %...%, %n%$$, -the forward Hessian sparsity pattern for the variable with index -$icode i$$ is empty. - -$subhead On Output$$ -For $icode%j%=1, %...%, %n%$$, -the forward Hessian sparsity pattern for the independent dependent variable -with index $icode%j%-1%$$ is given by the set with index $icode j$$ -in $icode for_hes_sparse$$. - -$head not_used_rec_base$$ -This argument is only used to specify the type $icode RecBase$$ for this call. - -$end -*/ - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { - -// BEGIN PROTOTYPE -template -void for_hes( - const local::player* play , - size_t n , - size_t numvar , - const pod_vector& select_domain , - const SetVector& rev_jac_sparse , - SetVector& for_hes_sparse , - const RecBase& not_used_rec_base ) -// END PROTOTYPE -{ - // length of the parameter vector (used by CppAD assert macros) -# ifndef NDEBUG - const size_t num_par = play->num_par_rec(); -# endif - - // check arguments - size_t np1 = n+1; - CPPAD_ASSERT_UNKNOWN( select_domain.size() == n ); - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - CPPAD_ASSERT_UNKNOWN( rev_jac_sparse.n_set() == numvar ); - CPPAD_ASSERT_UNKNOWN( for_hes_sparse.n_set() == np1+numvar ); - // - CPPAD_ASSERT_UNKNOWN( rev_jac_sparse.end() == 1 ); - CPPAD_ASSERT_UNKNOWN( for_hes_sparse.end() == np1 ); - // - CPPAD_ASSERT_UNKNOWN( numvar > 0 ); - // - // vecad_sparsity contains a sparsity pattern for each VecAD object. - // vecad_ind maps a VecAD index (beginning of the VecAD object) - // to the index for the corresponding set in vecad_sparsity. - size_t num_vecad_ind = play->num_var_vecad_ind_rec(); - size_t num_vecad_vec = play->num_var_vecad_rec(); - SetVector vecad_sparse; - pod_vector vecad_ind; - pod_vector vecad_jac; - if( num_vecad_vec > 0 ) - { size_t length; - vecad_sparse.resize(num_vecad_vec, np1); - vecad_ind.extend(num_vecad_ind); - vecad_jac.extend(num_vecad_vec); - size_t j = 0; - for(size_t i = 0; i < num_vecad_vec; i++) - { // length of this VecAD - length = play->GetVecInd(j); - // set vecad_ind to proper index for this VecAD - vecad_ind[j] = i; - // make all other values for this vector invalid - for(size_t k = 1; k <= length; k++) - vecad_ind[j+k] = num_vecad_vec; - // start of next VecAD - j += length + 1; - // initialize this vector's reverse jacobian value - vecad_jac[i] = false; - } - CPPAD_ASSERT_UNKNOWN( j == play->num_var_vecad_ind_rec() ); - } - // ------------------------------------------------------------------------ - // work space used by AFunOp. - vector atom_x; //// value of parameter arguments to function - vector type_x; // argument types - pod_vector atom_ix; // variable index (on tape) for each argument - pod_vector atom_iy; // variable index (on tape) for each result - // - // information set by atomic forward (initialization to avoid warnings) - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - // information set by atomic forward (necessary initialization) - enum_atom_state atom_state = start_atom; - // ------------------------------------------------------------------------- - // - // pointer to the beginning of the parameter vector - // (used by atomic functions) - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - // - // which parametes are dynamic - const pod_vector& dyn_par_is( play->dyn_par_is() ); - // - // skip the BeginOp at the beginning of the recording - play::const_sequential_iterator itr = play->begin(); - // op_info - OpCode op; - size_t i_var; - const Addr* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); -# if CPPAD_FOR_HES_TRACE - vector atom_funrp; // parameter index for FunrpOp operators - std::cout << std::endl; - CppAD::vectorBool zf_value(np1); - CppAD::vectorBool zh_value(np1 * np1); -# endif - bool flag; // temporary for use in switch cases below - bool more_operators = true; - size_t count_independent = 0; - while(more_operators) - { - // next op - (++itr).op_info(op, arg, i_var); - - // does the Hessian in question have a non-zero derivative - // with respect to this variable - bool include = NumRes(op) > 0; - if( include ) - include = rev_jac_sparse.is_element(i_var, 0); - // - // operators to include even if derivative is zero - include |= op == EndOp; - include |= op == CSkipOp; - include |= op == CSumOp; - include |= op == AFunOp; - include |= op == FunapOp; - include |= op == FunavOp; - include |= op == FunrpOp; - include |= op == FunrvOp; - // - if( include ) switch( op ) - { // operators that should not occurr - // case BeginOp - - // operators that do not affect Jacobian or Hessian - // and where with a fixed number of arguments and results - case CExpOp: - case DisOp: - case LdpOp: - case LdvOp: - case ParOp: - case PriOp: - case SignOp: - case StppOp: - case StpvOp: - case StvpOp: - case StvvOp: - break; - // ------------------------------------------------- - - // independent variable operator: set J(i_var) = { i_var } - case InvOp: - CPPAD_ASSERT_UNKNOWN( for_hes_sparse.number_elements(i_var) == 0 ); - if( select_domain[count_independent] ) - { // Not using post_element becasue only adding one element - // per set - for_hes_sparse.add_element(np1 + i_var, i_var); - } - ++count_independent; - break; - - // ------------------------------------------------- - // linear operators where arg[0] is the only variable - // only assign Jacobian term J(i_var) - case AbsOp: - case DivvpOp: - case SubvpOp: - case ZmulvpOp: - for_hes_sparse.assignment( - np1 + i_var, np1 + size_t(arg[0]), for_hes_sparse - ); - break; - - // ------------------------------------------------- - // linear operators where arg[1] is the only variable - // only assign Jacobian term J(i_var) - case AddpvOp: - case MulpvOp: - case SubpvOp: - for_hes_sparse.assignment( - np1 + i_var, np1 + size_t(arg[1]), for_hes_sparse - ); - break; - - // ------------------------------------------------- - // linear operators where arg[0] and arg[1] are variables - // only assign Jacobian term J(i_var) - case AddvvOp: - case SubvvOp: - for_hes_sparse.binary_union( - np1 + i_var , - np1 + size_t(arg[0]) , - np1 + size_t(arg[1]) , - for_hes_sparse - ); - break; - - // nonlinear unary operators - case AcosOp: - case AsinOp: - case AtanOp: - case CosOp: - case CoshOp: - case ExpOp: - case LogOp: - case SinOp: - case SinhOp: - case SqrtOp: - case TanOp: - case TanhOp: - case AcoshOp: - case AsinhOp: - case AtanhOp: - case Expm1Op: - case Log1pOp: - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ) - sparse::for_hes_nl_unary_op( - np1, numvar, i_var, size_t(arg[0]), for_hes_sparse - ); - break; - // ------------------------------------------------- - - case CSkipOp: - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case CSumOp: - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case DivvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::for_hes_div_op( - np1, numvar, i_var, arg, for_hes_sparse - ); - break; - // ------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::for_hes_nl_unary_op( - np1, numvar, i_var, size_t(arg[1]), for_hes_sparse - ); - break; - // ------------------------------------------------- - - case EndOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 0); - more_operators = false; - break; - // ------------------------------------------------- - - case ErfOp: - case ErfcOp: - // arg[1] is always the parameter 0 - // arg[2] is always the parameter 2 / sqrt(pi) - CPPAD_ASSERT_NARG_NRES(op, 3, 5); - sparse::for_hes_nl_unary_op( - np1, numvar, i_var, size_t(arg[0]), for_hes_sparse - ); - break; - // ------------------------------------------------- - - // ------------------------------------------------- - // logical comparison operators - case EqppOp: - case EqpvOp: - case EqvvOp: - case LtppOp: - case LtpvOp: - case LtvpOp: - case LtvvOp: - case LeppOp: - case LepvOp: - case LevpOp: - case LevvOp: - case NepvOp: - case NeppOp: - case NevvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 0); - break; - // ------------------------------------------------- - - case MulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::for_hes_mul_op( - np1, numvar, i_var, arg, for_hes_sparse - ); - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3) - sparse::for_hes_nl_unary_op( - np1, numvar, i_var, size_t(arg[1]), for_hes_sparse - ); - break; - // ------------------------------------------------- - - case PowvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3) - sparse::for_hes_nl_unary_op( - np1, numvar, i_var, size_t(arg[0]), for_hes_sparse - ); - break; - // ------------------------------------------------- - - case PowvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3) - sparse::for_hes_pow_op( - np1, numvar, i_var, arg, for_hes_sparse - ); - break; - // ------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - CPPAD_ASSERT_UNKNOWN( - atom_state == start_atom || atom_state == end_atom - ); - flag = atom_state == start_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = arg_atom; - atom_i = 0; - atom_j = 0; - // - atom_x.resize( atom_n ); - type_x.resize( atom_n ); - atom_ix.resize( atom_n ); - atom_iy.resize( atom_m ); -# if CPPAD_FOR_HES_TRACE - atom_funrp.resize( atom_m ); -# endif - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - atom_state = start_atom; - // - call_atomic_for_hes_sparsity( - atom_index, atom_old, atom_x, type_x, atom_ix, atom_iy, - np1, numvar, rev_jac_sparse, for_hes_sparse - ); - } - break; - - case FunapOp: - // parameter argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - atom_x[atom_j] = parameter[arg[0]]; - // argument type - if( dyn_par_is[arg[0]] ) - type_x[atom_j] = dynamic_enum; - else - type_x[atom_j] = constant_enum; - atom_ix[atom_j] = 0; // special variable used for parameters - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunavOp: - // variable argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - // - // arguemnt variables not avaialbe during sparisty calculations - atom_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - type_x[atom_j] = variable_enum; - atom_ix[atom_j] = size_t(arg[0]); // variable for this argument - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - atom_iy[atom_i] = 0; // special variable used for parameters -# if CPPAD_FOR_HES_TRACE - // remember argument for delayed tracing - atom_funrp[atom_i] = arg[0]; -# endif - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - atom_iy[atom_i] = i_var; // variable index for this result - // - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - // ------------------------------------------------- - - case ZmulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::for_hes_mul_op( - np1, numvar, i_var, arg, for_hes_sparse - ); - break; - - // ------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(0); - } -# if CPPAD_FOR_HES_TRACE - typedef typename SetVector::const_iterator const_iterator; - if( op == AFunOp && atom_state == start_atom ) - { // print operators that have been delayed - CPPAD_ASSERT_UNKNOWN( atom_m == atom_iy.size() ); - CPPAD_ASSERT_UNKNOWN( itr.op_index() > atom_m ); - CPPAD_ASSERT_NARG_NRES(FunrpOp, 1, 0); - CPPAD_ASSERT_NARG_NRES(FunrvOp, 0, 1); - addr_t arg_tmp[1]; - for(size_t k = 0; k < atom_m; k++) - { size_t k_var = atom_iy[k]; - // value for this variable - for(size_t i = 0; i < np1; i++) - { zf_value[i] = false; - for(size_t j = 0; j < np1; j++) - zh_value[i * np1 + j] = false; - } - const_iterator itr_1(for_hes_sparse, np1 + i_var); - size_t j = *itr_1; - while( j < np1 ) - { zf_value[j] = true; - j = *(++itr_1); - } - for(size_t i = 0; i < np1; i++) - { const_iterator itr_2(for_hes_sparse, i); - j = *itr_2; - while( j < np1 ) - { zh_value[i * np1 + j] = true; - j = *(++itr_2); - } - } - OpCode op_tmp = FunrvOp; - if( k_var == 0 ) - { op_tmp = FunrpOp; - arg_tmp[0] = atom_funrp[k]; - } - // k_var is zero when there is no result - printOp( - std::cout, - play, - itr.op_index() - atom_m + k, - k_var, - op_tmp, - arg_tmp - ); - if( k_var > 0 ) printOpResult( - std::cout, - 1, - &zf_value, - 1, - &zh_value - ); - std::cout << std::endl; - } - } - for(size_t i = 0; i < np1; i++) - { zf_value[i] = false; - for(size_t j = 0; j < np1; j++) - zh_value[i * np1 + j] = false; - } - const_iterator itr_1(for_hes_sparse, np1 + i_var); - size_t j = *itr_1; - while( j < np1 ) - { zf_value[j] = true; - j = *(++itr_1); - } - for(size_t i = 0; i < np1; i++) - { const_iterator itr_2(for_hes_sparse, i); - j = *itr_2; - while( j < np1 ) - { zh_value[i * np1 + j] = true; - j = *(++itr_2); - } - } - // must delay print for these cases till after atomic function call - bool delay_print = op == FunrpOp; - delay_print |= op == FunrvOp; - if( ! delay_print ) - { printOp( - std::cout, - play, - itr.op_index(), - i_var, - op, - arg - ); - if( NumRes(op) > 0 && (! delay_print) ) printOpResult( - std::cout, - 1, - &zf_value, - 1, - &zh_value - ); - std::cout << std::endl; - } - } - std::cout << std::endl; -# else - } -# endif - - return; -} -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE - -// preprocessor symbols that are local to this file -# undef CPPAD_FOR_HES_TRACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/for_jac.hpp b/build-config/cppad/include/cppad/local/sweep/for_jac.hpp deleted file mode 100644 index 228f1047..00000000 --- a/build-config/cppad/include/cppad/local/sweep/for_jac.hpp +++ /dev/null @@ -1,836 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_FOR_JAC_HPP -# define CPPAD_LOCAL_SWEEP_FOR_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include -# include - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file sweep/for_jac.hpp -Compute Forward mode Jacobian sparsity patterns. -*/ - -/*! -\def CPPAD_FOR_JAC_TRACE -This value is either zero or one. -Zero is the normal operational value. -If it is one, a trace of every for_jac_sweep computation is printed. -*/ -# define CPPAD_FOR_JAC_TRACE 0 - -/*! -Given the sparsity pattern for the independent variables, -ForJacSweep computes the sparsity pattern for all the other variables. - -\tparam Base -this operation sequence was recorded using AD. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\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 n -is the number of independent variables on the tape. - -\param numvar -is the total number of variables on the tape; i.e., - play->num_var_rec(). - -\param play -The information stored in play -is a recording of the operations corresponding to a function -\f[ - F : {\bf R}^n \rightarrow {\bf R}^m -\f] -where \f$ n \f$ is the number of independent variables -and \f$ m \f$ is the number of dependent variables. - -\param var_sparsity -\b Input: For j = 1 , ... , n, -the sparsity pattern for the independent variable with index (j-1) -corresponds to the set with index j in var_sparsity. -\n -\n -\b Output: For i = n + 1 , ... , numvar - 1, -the sparsity pattern for the variable with index i on the tape -corresponds to the set with index i in var_sparsity. - -\par Checked Assertions: -\li numvar == var_sparsity.n_set() -\li numvar == play->num_var_rec() - -\param not_used_rec_base -Specifies RecBase for this call. -*/ - -template -void for_jac( - const local::player* play, - bool dependency , - size_t n , - size_t numvar , - Vector_set& var_sparsity, - const RecBase& not_used_rec_base -) -{ - size_t i, j, k; - - // check numvar argument - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - CPPAD_ASSERT_UNKNOWN( var_sparsity.n_set() == numvar ); - - // length of the parameter vector (used by CppAD assert macros) - const size_t num_par = play->num_par_rec(); - - // cum_sparsity accumulates sparsity pattern a cumulative sum - size_t limit = var_sparsity.end(); - - // vecad_sparsity contains a sparsity pattern from each VecAD object - // to all the other variables. - // vecad_ind maps a VecAD index (the beginning of the - // VecAD object) to its from index in vecad_sparsity - size_t num_vecad_ind = play->num_var_vecad_ind_rec(); - size_t num_vecad_vec = play->num_var_vecad_rec(); - Vector_set vecad_sparsity; - pod_vector vecad_ind; - if( num_vecad_vec > 0 ) - { size_t length; - vecad_sparsity.resize(num_vecad_vec, limit); - vecad_ind.extend(num_vecad_ind); - j = 0; - for(i = 0; i < num_vecad_vec; i++) - { // length of this VecAD - length = play->GetVecInd(j); - // set to proper index for this VecAD - vecad_ind[j] = i; - for(k = 1; k <= length; k++) - vecad_ind[j+k] = num_vecad_vec; // invalid index - // start of next VecAD - j += length + 1; - } - CPPAD_ASSERT_UNKNOWN( j == play->num_var_vecad_ind_rec() ); - } - - // -------------------------------------------------------------- - // work space used by AFunOp. - vector atom_x; //// value of parameter arguments to function - vector type_x; // argument types - pod_vector atom_ix; // variable index (on tape) for each argument - pod_vector atom_iy; // variable index (on tape) for each result - // - // information set by atomic forward (initialization to avoid warnings) - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - // information set by atomic forward (necessary initialization) - enum_atom_state atom_state = start_atom; - // -------------------------------------------------------------- - // - // pointer to the beginning of the parameter vector - // (used by atomic functions) - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - // - // which parametes are dynamic - const pod_vector& dyn_par_is( play->dyn_par_is() ); - // -# if CPPAD_FOR_JAC_TRACE - vector atom_funrp; // parameter index for FunrpOp operators - std::cout << std::endl; - CppAD::vectorBool z_value(limit); -# endif - - // skip the BeginOp at the beginning of the recording - play::const_sequential_iterator itr = play->begin(); - // op_info - OpCode op; - size_t i_var; - const Addr* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); - // - bool more_operators = true; - while(more_operators) - { bool flag; // temporary for use in switch cases. - - // this op - (++itr).op_info(op, arg, i_var); - - // rest of information depends on the case - switch( op ) - { - case AbsOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AddvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case AddpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AcosOp: - // sqrt(1 - x * x), acos(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AcoshOp: - // sqrt(x * x - 1), acosh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AsinOp: - // sqrt(1 - x * x), asin(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AsinhOp: - // sqrt(1 + x * x), asinh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AtanOp: - // 1 + x * x, atan(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AtanhOp: - // 1 - x * x, atanh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case CSkipOp: - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case CSumOp: - forward_sparse_jacobian_csum_op( - i_var, arg, var_sparsity - ); - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case CExpOp: - forward_sparse_jacobian_cond_op( - dependency, i_var, arg, num_par, var_sparsity - ); - break; - // -------------------------------------------------- - - case CosOp: - // sin(x), cos(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // --------------------------------------------------- - - case CoshOp: - // sinh(x), cosh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case DisOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - // derivative is identically zero but dependency is not - if( dependency ) sparse::for_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - else - var_sparsity.clear(i_var); - break; - // ------------------------------------------------- - - case DivvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case DivvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case EndOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 0); - more_operators = false; - break; - // ------------------------------------------------- - - case ErfOp: - case ErfcOp: - // arg[1] is always the parameter 0 - // arg[0] is always the parameter 2 / sqrt(pi) - CPPAD_ASSERT_NARG_NRES(op, 3, 5); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case ExpOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case Expm1Op: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case InvOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - // sparsity pattern is already defined - break; - // ------------------------------------------------- - - case LdpOp: - forward_sparse_load_op( - dependency, - op, - i_var, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case LdvOp: - forward_sparse_load_op( - dependency, - op, - i_var, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case EqppOp: - case EqpvOp: - case EqvvOp: - case LtppOp: - case LtpvOp: - case LtvpOp: - case LtvvOp: - case LeppOp: - case LepvOp: - case LevpOp: - case LevvOp: - case NeppOp: - case NepvOp: - case NevvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 0); - break; - // ------------------------------------------------- - - case LogOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case Log1pOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case MulpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case MulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case ParOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - var_sparsity.clear(i_var); - break; - // ------------------------------------------------- - - case PowvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3); - sparse::for_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case PowvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3); - sparse::for_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case PriOp: - CPPAD_ASSERT_NARG_NRES(op, 5, 0); - break; - // ------------------------------------------------- - - case SignOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - // derivative is identically zero but dependency is not - if( dependency ) sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - else - var_sparsity.clear(i_var); - break; - // ------------------------------------------------- - - case SinOp: - // cos(x), sin(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case SinhOp: - // cosh(x), sinh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case SqrtOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case StppOp: - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - // if both arguments are parameters does not affect sparsity - // or dependency - break; - // ------------------------------------------------- - - case StpvOp: - forward_sparse_store_op( - dependency, - op, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case StvpOp: - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - forward_sparse_store_op( - dependency, - op, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case StvvOp: - forward_sparse_store_op( - dependency, - op, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case SubvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case SubpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case SubvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case TanOp: - // tan(x)^2, tan(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case TanhOp: - // tanh(x)^2, tanh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - CPPAD_ASSERT_UNKNOWN( - atom_state == start_atom || atom_state == end_atom - ); - flag = atom_state == start_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = arg_atom; - atom_i = 0; - atom_j = 0; - // - atom_x.resize( atom_n ); - type_x.resize( atom_n ); - atom_ix.resize( atom_n ); - atom_iy.resize( atom_m ); -# if CPPAD_FOR_JAC_TRACE - atom_funrp.resize( atom_m ); -# endif - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - atom_state = start_atom; - // - call_atomic_for_jac_sparsity( - atom_index, - atom_old, - dependency, - atom_x, - type_x, - atom_ix, - atom_iy, - var_sparsity - ); - } - break; - - case FunapOp: - // parameter argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - atom_x[atom_j] = parameter[arg[0]]; - // argument type - if( dyn_par_is[arg[0]] ) - type_x[atom_j] = dynamic_enum; - else - type_x[atom_j] = constant_enum; - atom_ix[atom_j] = 0; // special variable used for parameters - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunavOp: - // variable argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - // - // argument variables not avaiable during sparsity calculations - atom_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - type_x[atom_j] = variable_enum; - atom_ix[atom_j] = size_t(arg[0]); // variable for this argument - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - atom_iy[atom_i] = 0; // special value for parameters -# if CPPAD_FOR_JAC_TRACE - // remember argument for delayed tracing - atom_funrp[atom_i] = arg[0]; -# endif - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - atom_iy[atom_i] = i_var; // variable index for this result - // - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - // ------------------------------------------------- - - case ZmulpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case ZmulvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case ZmulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::for_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(0); - } -# if CPPAD_FOR_JAC_TRACE - if( op == AFunOp && atom_state == start_atom ) - { // print operators that have been delayed - CPPAD_ASSERT_UNKNOWN( atom_m == atom_iy.size() ); - CPPAD_ASSERT_UNKNOWN( itr.op_index() > atom_m ); - CPPAD_ASSERT_NARG_NRES(FunrpOp, 1, 0); - CPPAD_ASSERT_NARG_NRES(FunrvOp, 0, 1); - addr_t arg_tmp[1]; - for(i = 0; i < atom_m; i++) - { size_t j_var = atom_iy[i]; - // value for this variable - for(j = 0; j < limit; j++) - z_value[j] = false; - typename Vector_set::const_iterator itr(var_sparsity, j_var); - j = *itr; - while( j < limit ) - { z_value[j] = true; - j = *(++itr); - } - OpCode op_tmp = FunrvOp; - if( j_var == 0 ) - { op_tmp = FunrpOp; - arg_tmp[0] = atom_funrp[i]; - } - // j_var is zero when there is no result. - printOp( - std::cout, - play, - itr.op_index() - atom_m + i, - j_var, - op_tmp, - arg_tmp - ); - if( j_var > 0 ) printOpResult( - std::cout, - 1, - &z_value, - 0, - (CppAD::vectorBool *) nullptr - ); - std::cout << std::endl; - } - } - // value for this variable - for(j = 0; j < limit; j++) - z_value[j] = false; - typename Vector_set::const_iterator itr(var_sparsity, i_var); - j = *itr; - while( j < limit ) - { z_value[j] = true; - j = *(++itr); - } - // must delay print for these cases till after atomic function call - bool delay_print = op == FunrpOp; - delay_print |= op == FunrvOp; - if( ! delay_print ) - { printOp( - std::cout, - play, - itr.op_index(), - i_var, - op, - arg - ); - if( NumRes(op) > 0 && (! delay_print) ) printOpResult( - std::cout, - 1, - &z_value, - 0, - (CppAD::vectorBool *) nullptr - ); - std::cout << std::endl; - } - } - std::cout << std::endl; -# else - } -# endif - - return; -} - -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE - -// preprocessor symbols that are local to this file -# undef CPPAD_FOR_JAC_TRACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/forward0.hpp b/build-config/cppad/include/cppad/local/sweep/forward0.hpp deleted file mode 100644 index 44397dd8..00000000 --- a/build-config/cppad/include/cppad/local/sweep/forward0.hpp +++ /dev/null @@ -1,995 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_FORWARD0_HPP -# define CPPAD_LOCAL_SWEEP_FORWARD0_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file sweep/forward0.hpp -Compute zero order forward mode Taylor coefficients. -*/ - -/* - ------------------------------------------------------------------------------ -$begin sweep_forward0$$ -$spell - Taylor - numvar - cskip - op - var - Pri - num - Vec -$$ -$section Compute Zero Order Forward Mode Taylor Coefficients$$ - -$head Syntax$$ -$codei% forward0( - %play%, - %s_out%, - %print%, - %n%, - %numvar%, - %J%, - %taylor%, - %cskip_op%, - %load_op2var%, - %compare_change_count%, - %compare_change_number%, - %compare_change_op_index%, - %not_used_rec_base% -)%$$ - -$head CPPAD_FORWARD0_TRACE$$ -This value is either zero or one. -Zero is the normal operational value. -If it is one, a trace of every zero order forward mode computation is printed. -$srccode%hpp% */ -# define CPPAD_FORWARD0_TRACE 0 -/* %$$ - -$head Base$$ -The type used during the forward mode computations; i.e., the corresponding -recording of operations used the type $codei%AD<%Base%>%$$. - -$head s_out$$ -Is the stream where output corresponding to PriOp operations will -be written. - -$head print$$ -If print is false, -suppress the output that is otherwise generated by the PriOp instructions. - -$head n$$ -is the number of independent variables on the tape. - -$head numvar$$ -is the total number of variables on the tape. -This is also equal to the number of rows in the matrix taylor; i.e., -$icode%play%->num_var_rec()%$$. - -$head play$$ -The information stored in play -is a recording of the operations corresponding to a function -$latex \[ - f : \B{R}^n \rightarrow \B{R}^m -\] $$ -where $icode n$$ is the number of independent variables and -$icode m$$ is the number of dependent variables. - -$head J$$ -Is the number of columns in the coefficient matrix taylor. -This must be greater than or equal one. - -$head taylor$$ -Is the matrix of Taylor coefficients. - -$subhead Input$$ -For $icode%i% = 1 , %...% , %n%$$, -$icode taylor [%i% * %J% + 0]%$$ -is the zero order Taylor coefficient for variable with index -$icode j$$ on the tape (these are the independent variables). - -$subhead Output$$ -For $icode%i% = %n%+1 , %...% , %numvar%-1%$$, -$icode taylor [%i% * %J% + 0]%$$ -is the zero order Taylor coefficient for the variable with -index i on the tape. - -$head cskip_op$$ -Is a vector with size $icode%play%->num_op_rec()%$$. -The input value of the elements does not matter. -Upon return, if $icode%cskip_op%[%i%]%$$ is true, -the operator index $icode i$$ does not affect any of the dependent variable -(given the value of the independent variables). - -$head load_op2var$$ -Is a vector with size $icode%play%->num_var_load_rec()%$$. -The input value of the elements does not matter. -Upon return, -$icode%load_op2var%[%i%]%$$ -is the variable corresponding to the $th i$$ variable VecAD -$cref/load/op_code_var/Load/$$ operator. -Note that even though the VecAD vector is a variable, the load -can correspond to an element that is a parameter in which case -$icode%load_op2var%[%i%]%$$ is zero. - -$head compare_change_count$$ -Is the compare change count value at which $icode compare_change_op_index$$ -is returned. If it is zero, the comparison changes are not counted. - -$head compare_change_number$$ -If $icode compare_change_count$$ is zero, this value is set to zero. -Otherwise, the return value is the number of comparison operations -that have a different result from when the information in -$icode play$$ was recorded. - -$head compare_change_op_index$$ -If $icode compare_change_count$$ is zero, this value is set to zero. -Otherwise it is the operator index (see forward_next) for the -comparison operation that has a different result from when the information in -play was recorded. -This is not the first comparison that is different, -but rather the $icode compare_change_count$$ comparison. - -$head not_used_rec_base$$ -Specifies $icode RecBase$$ for this call. - -$end -*/ - -template -void forward0( - const local::player* play, - std::ostream& s_out, - bool print, - size_t n, - size_t numvar, - size_t J, - Base* taylor, - bool* cskip_op, - pod_vector& load_op2var, - size_t compare_change_count, - size_t& compare_change_number, - size_t& compare_change_op_index, - const RecBase& not_used_rec_base -) -{ CPPAD_ASSERT_UNKNOWN( J >= 1 ); - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - - // use p, q, r so other forward sweeps can use code defined here - size_t p = 0; - size_t q = 0; - size_t r = 1; - - // initialize the comparison operator counter - if( p == 0 ) - { compare_change_number = 0; - compare_change_op_index = 0; - } - - // If this includes a zero calculation, initialize this information - pod_vector vec_ad2isvar; - pod_vector vec_ad2index; - if( p == 0 ) - { size_t i; - - // this includes order zero calculation, initialize vector indices - size_t num = play->num_var_vecad_ind_rec(); - if( num > 0 ) - { vec_ad2isvar.extend(num); - vec_ad2index.extend(num); - for(i = 0; i < num; i++) - { vec_ad2index[i] = play->GetVecInd(i); - vec_ad2isvar[i] = false; - } - } - // includes zero order, so initialize conditional skip flags - num = play->num_op_rec(); - for(i = 0; i < num; i++) - cskip_op[i] = false; - } - - // information used by atomic function operators - const pod_vector& dyn_par_is( play->dyn_par_is() ); - const size_t need_y = size_t( variable_enum ); - const size_t order_low = p; - const size_t order_up = q; - - // vectors used by atomic function operators - vector atom_par_x; // argument parameter values - vector atom_type_x; // argument type - vector atom_tx; // argument vector Taylor coefficients - vector atom_ty; // result vector Taylor coefficients - // - // information defined by atomic function operators - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - enum_atom_state atom_state = start_atom; // proper initialization - - // length of the parameter vector (used by CppAD assert macros) - const size_t num_par = play->num_par_rec(); - - // pointer to the beginning of the parameter vector - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - - // length of the text vector (used by CppAD assert macros) - const size_t num_text = play->num_text_rec(); - - // pointer to the beginning of the text vector - const char* text = nullptr; - if( num_text > 0 ) - text = play->GetTxt(0); - -# if CPPAD_FORWARD0_TRACE - // flag as to when to trace atomic function values - bool atom_trace = false; - - // variable indices for results vector - // (done differently for order zero). - vector atom_iy; -# endif - - // skip the BeginOp at the beginning of the recording - play::const_sequential_iterator itr = play->begin(); - // op_info - OpCode op; - size_t i_var; - const Addr* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); - // -# if CPPAD_FORWARD0_TRACE - std::cout << std::endl; -# endif - bool flag; // a temporary flag to use in switch cases - bool more_operators = true; - while(more_operators) - { - // next op - (++itr).op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_op_rec() ); - - // check if we are skipping this operation - while( cskip_op[itr.op_index()] ) - { switch(op) - { - case AFunOp: - { // get information for this atomic function call - CPPAD_ASSERT_UNKNOWN( atom_state == start_atom ); - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - // - // skip to the second AFunOp - for(size_t i = 0; i < atom_m + atom_n + 1; ++i) - ++itr; -# ifndef NDEBUG - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); -# endif - } - break; - - case CSkipOp: - case CSumOp: - itr.correct_before_increment(); - break; - - default: - break; - } - (++itr).op_info(op, arg, i_var); - } - - // action to take depends on the case - switch( op ) - { - case AbsOp: - forward_abs_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AddvvOp: - forward_addvv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case AddpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_addpv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case AcosOp: - // sqrt(1 - x * x), acos(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_acos_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AcoshOp: - // sqrt(x * x - 1), acosh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_acosh_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AsinOp: - // sqrt(1 - x * x), asin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_asin_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AsinhOp: - // sqrt(1 + x * x), asinh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_asinh_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AtanOp: - // 1 + x * x, atan(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_atan_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AtanhOp: - // 1 - x * x, atanh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_atanh_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case CExpOp: - // Use the general case with d == 0 - // (could create an optimzied verison for this case) - forward_cond_op_0( - i_var, arg, num_par, parameter, J, taylor - ); - break; - // --------------------------------------------------- - - case CosOp: - // sin(x), cos(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_cos_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // --------------------------------------------------- - - case CoshOp: - // sinh(x), cosh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_cosh_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case CSkipOp: - forward_cskip_op_0( - i_var, arg, num_par, parameter, J, taylor, cskip_op - ); - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case CSumOp: - forward_csum_op( - 0, 0, i_var, arg, num_par, parameter, J, taylor - ); - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case DisOp: - forward_dis_op(p, q, r, i_var, arg, J, taylor); - break; - // ------------------------------------------------- - - case DivvvOp: - forward_divvv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_divpv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case DivvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_divvp_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case EndOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 0); - more_operators = false; - break; - // ------------------------------------------------- - - case EqppOp: - if( compare_change_count ) - { forward_eqpp_op_0( - compare_change_number, arg, parameter - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case EqpvOp: - if( compare_change_count ) - { forward_eqpv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case EqvvOp: - if( compare_change_count ) - { forward_eqvv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case ErfOp: - case ErfcOp: - forward_erf_op_0(op, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ExpOp: - forward_exp_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case Expm1Op: - forward_expm1_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case InvOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - break; - // --------------------------------------------------- - - case LdpOp: - forward_load_p_op_0( - play, - i_var, - arg, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data(), - load_op2var.data() - ); - break; - // ------------------------------------------------- - - case LdvOp: - forward_load_v_op_0( - play, - i_var, - arg, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data(), - load_op2var.data() - ); - break; - // ------------------------------------------------- - - case LeppOp: - if( compare_change_count ) - { forward_lepp_op_0( - compare_change_number, arg, parameter - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - case LepvOp: - if( compare_change_count ) - { forward_lepv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case LevpOp: - if( compare_change_count ) - { forward_levp_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case LevvOp: - if( compare_change_count ) - { forward_levv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case LogOp: - forward_log_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case Log1pOp: - forward_log1p_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case LtppOp: - if( compare_change_count ) - { forward_ltpp_op_0( - compare_change_number, arg, parameter - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - case LtpvOp: - if( compare_change_count ) - { forward_ltpv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case LtvpOp: - if( compare_change_count ) - { forward_ltvp_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case LtvvOp: - if( compare_change_count ) - { forward_ltvv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case MulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_mulpv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case MulvvOp: - forward_mulvv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case NeppOp: - if( compare_change_count ) - { forward_nepp_op_0( - compare_change_number, arg, parameter - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case NepvOp: - if( compare_change_count ) - { forward_nepv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case NevvOp: - if( compare_change_count ) - { forward_nevv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case ParOp: - forward_par_op_0( - i_var, arg, num_par, parameter, J, taylor - ); - break; - // ------------------------------------------------- - - case PowvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_powvp_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_powpv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PowvvOp: - forward_powvv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PriOp: - if( print ) forward_pri_0(s_out, - arg, num_text, text, num_par, parameter, J, taylor - ); - break; - // ------------------------------------------------- - - case SignOp: - // cos(x), sin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sign_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SinOp: - // cos(x), sin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sin_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SinhOp: - // cosh(x), sinh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sinh_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SqrtOp: - forward_sqrt_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case StppOp: - forward_store_pp_op_0( - i_var, - arg, - num_par, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - break; - // ------------------------------------------------- - - case StpvOp: - forward_store_pv_op_0( - i_var, - arg, - num_par, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - break; - // ------------------------------------------------- - - case StvpOp: - forward_store_vp_op_0( - i_var, - arg, - num_par, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - break; - // ------------------------------------------------- - - case StvvOp: - forward_store_vv_op_0( - i_var, - arg, - num_par, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - break; - // ------------------------------------------------- - - case SubvvOp: - forward_subvv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case SubpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_subpv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case SubvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_subvp_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case TanOp: - // tan(x)^2, tan(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_tan_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case TanhOp: - // tanh(x)^2, tanh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_tanh_op_0(i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - flag = atom_state == start_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = arg_atom; - atom_i = 0; - atom_j = 0; - // - atom_par_x.resize(atom_n); - atom_type_x.resize(atom_n); - atom_tx.resize(atom_n); - atom_ty.resize(atom_m); -# if CPPAD_FORWARD0_TRACE - atom_iy.resize(atom_m); -# endif - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - atom_state = start_atom; -# if CPPAD_FORWARD0_TRACE - atom_trace = true; -# endif - } - break; - - case FunapOp: - // parameter argument for an atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - if( dyn_par_is[ arg[0] ] ) - atom_type_x[atom_j] = dynamic_enum; - else - atom_type_x[atom_j] = constant_enum; - atom_par_x[atom_j] = parameter[ arg[0] ]; - atom_tx[atom_j++] = parameter[ arg[0] ]; - // - if( atom_j == atom_n ) - { // call atomic function for this operation - call_atomic_forward( - atom_par_x, atom_type_x, need_y, - order_low, order_up, atom_index, atom_old, atom_tx, atom_ty - ); - atom_state = ret_atom; - } - break; - - case FunavOp: - // variable argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - // - atom_type_x[atom_j] = variable_enum; - atom_par_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - atom_tx[atom_j++] = taylor[ size_t(arg[0]) * J + 0 ]; - // - if( atom_j == atom_n ) - { // call atomic function for this operation - call_atomic_forward( - atom_par_x, atom_type_x, need_y, - order_low, order_up, atom_index, atom_old, atom_tx, atom_ty - ); - atom_state = ret_atom; - } - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); -# if CPPAD_FORWARD0_TRACE - atom_iy[atom_i] = 0; -# endif - atom_i++; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); -# if CPPAD_FORWARD0_TRACE - atom_iy[atom_i] = i_var; -# endif - taylor[ i_var * J + 0 ] = atom_ty[atom_i++]; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - // ------------------------------------------------- - - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_zmulpv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_zmulvp_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ZmulvvOp: - forward_zmulvv_op_0(i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(false); - } -# if CPPAD_FORWARD0_TRACE - size_t d = 0; - if( atom_trace ) - { atom_trace = false; - - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); - CPPAD_ASSERT_UNKNOWN( NumArg(FunrvOp) == 0 ); - for(size_t i = 0; i < atom_m; i++) if( atom_iy[i] > 0 ) - { size_t i_tmp = (itr.op_index() + i) - atom_m; - printOp( - std::cout, - play, - i_tmp, - atom_iy[i], - FunrvOp, - nullptr - ); - Base* Z_tmp = taylor + atom_iy[i] * J; - printOpResult( - std::cout, - d + 1, - Z_tmp, - 0, - (Base *) nullptr - ); - std::cout << std::endl; - } - } - Base* Z_tmp = taylor + i_var * J; - if( op != FunrvOp ) - { - printOp( - std::cout, - play, - itr.op_index(), - i_var, - op, - arg - ); - if( NumRes(op) > 0 ) printOpResult( - std::cout, - d + 1, - Z_tmp, - 0, - (Base *) nullptr - ); - std::cout << std::endl; - } - } - std::cout << std::endl; -# else - } -# endif - CPPAD_ASSERT_UNKNOWN( atom_state == start_atom ); - - return; -} - -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE - -// preprocessor symbols that are local to this file -# undef CPPAD_FORWARD0_TRACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/forward1.hpp b/build-config/cppad/include/cppad/local/sweep/forward1.hpp deleted file mode 100644 index 4ce8d932..00000000 --- a/build-config/cppad/include/cppad/local/sweep/forward1.hpp +++ /dev/null @@ -1,1086 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_FORWARD1_HPP -# define CPPAD_LOCAL_SWEEP_FORWARD1_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file sweep/forward1.hpp -Compute one Taylor coefficient for each order requested. -*/ - -/*! -\def CPPAD_FORWARD1_TRACE -This value is either zero or one. -Zero is the normal operational value. -If it is one, a trace of every forward1sweep computation is printed. -*/ -# define CPPAD_FORWARD1_TRACE 0 - -/*! -Compute arbitrary order forward mode Taylor coefficients. - - -\tparam Base -The type used during the forward mode computations; i.e., the corresponding -recording of operations used the type AD. - -\param s_out -Is the stream where output corresponding to PriOp operations will -be written. - -\param print -If print is false, -suppress the output that is otherwise generated by the c PriOp instructions. - -\param n -is the number of independent variables on the tape. - -\param numvar -is the total number of variables on the tape. -This is also equal to the number of rows in the matrix taylor; i.e., -play->num_var_rec(). - -\param play -The information stored in play -is a recording of the operations corresponding to the function -\f[ - F : {\bf R}^n \rightarrow {\bf R}^m -\f] -where \f$ n \f$ is the number of independent variables and -\f$ m \f$ is the number of dependent variables. - -\param J -Is the number of columns in the coefficient matrix taylor. -This must be greater than or equal one. - - - -\param cskip_op -Is a vector with size play->num_op_rec(). -\n -\n -p = 0 -\n -In this case, -the input value of the elements does not matter. -Upon return, if cskip_op[i] is true, the operator with index i -does not affect any of the dependent variable -(given the value of the independent variables). -\n -\n -p > 0 -\n -In this case cskip_op is not modified and has the same meaning -as its return value above. - -\param load_op2var -is a vector with size play->num_var_load_rec(). -\n -\n -p == 0 -\n -In this case, -The input value of the elements does not matter. -Upon return, -it is the variable index corresponding the result for each load operator. -In the case where the index is zero, -the load operator results in a parameter (not a variable). -Note that the is no variable with index zero on the tape. -\n -\n -p > 0 -\n -In this case load_op2var is not modified and has the meaning -as its return value above. - -\param p -is the lowest order of the Taylor coefficients -that are computed during this call. - -\param q -is the highest order of the Taylor coefficients -that are computed during this call. - -\param taylor -\n -\b Input: -For i = 1 , ... , numvar-1, -k = 0 , ... , p-1, -taylor[ J*i + k] -is the k-th order Taylor coefficient corresponding to -the i-th variable. -\n -\n -\b Input: -For i = 1 , ... , n, -k = p , ... , q, -taylor[ J*j + k] -is the k-th order Taylor coefficient corresponding to -the i-th variable -(these are the independent varaibles). -\n -\n -\b Output: -For i = n+1 , ... , numvar-1, and -k = 0 , ... , p-1, -taylor[ J*i + k] -is the k-th order Taylor coefficient corresponding to -the i-th variable. - - -\param compare_change_count -Is the count value for changing number and op_index during -zero order foward mode. - -\param compare_change_number -If p is non-zero, this value is not changed, otherwise: -If compare_change_count is zero, this value is set to zero, otherwise: -this value is set to the number of comparison operations -that have a different result from when the information in -play was recorded. - -\param compare_change_op_index -if p is non-zero, this value is not changed, otherwise: -If compare_change_count is zero, this value is set to zero. -Otherwise it is the operator index (see forward_next) for the count-th -comparison operation that has a different result from when the information in -play was recorded. - -\param not_used_rec_base -Specifies RecBase for this call. -*/ - -template -void forward1( - const local::player* play, - std::ostream& s_out, - const bool print, - const size_t p, - const size_t q, - const size_t n, - const size_t numvar, - const size_t J, - Base* taylor, - bool* cskip_op, - pod_vector& load_op2var, - size_t compare_change_count, - size_t& compare_change_number, - size_t& compare_change_op_index, - const RecBase& not_used_rec_base -) -{ - // number of directions - const size_t r = 1; - - CPPAD_ASSERT_UNKNOWN( p <= q ); - CPPAD_ASSERT_UNKNOWN( J >= q + 1 ); - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - - /* - - */ - - // initialize the comparison operator counter - if( p == 0 ) - { compare_change_number = 0; - compare_change_op_index = 0; - } - - // If this includes a zero calculation, initialize this information - pod_vector vec_ad2isvar; - pod_vector vec_ad2index; - if( p == 0 ) - { size_t i; - - // this includes order zero calculation, initialize vector indices - size_t num = play->num_var_vecad_ind_rec(); - if( num > 0 ) - { vec_ad2isvar.extend(num); - vec_ad2index.extend(num); - for(i = 0; i < num; i++) - { vec_ad2index[i] = play->GetVecInd(i); - vec_ad2isvar[i] = false; - } - } - // includes zero order, so initialize conditional skip flags - num = play->num_op_rec(); - for(i = 0; i < num; i++) - cskip_op[i] = false; - } - - // information used by atomic function operators - const pod_vector& dyn_par_is( play->dyn_par_is() ); - const size_t need_y = size_t( variable_enum ); - const size_t order_low = p; - const size_t order_up = q; - - // vectors used by atomic function operators - vector atom_par_x; // argument parameter values - vector atom_type_x; // argument type - vector atom_tx; // argument vector Taylor coefficients - vector atom_ty; // result vector Taylor coefficients - // - // information defined by atomic function operators - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - enum_atom_state atom_state = start_atom; // proper initialization - - // length of the parameter vector (used by CppAD assert macros) - const size_t num_par = play->num_par_rec(); - - // pointer to the beginning of the parameter vector - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - - // length of the text vector (used by CppAD assert macros) - const size_t num_text = play->num_text_rec(); - - // pointer to the beginning of the text vector - const char* text = nullptr; - if( num_text > 0 ) - text = play->GetTxt(0); - /* - - */ - // temporary indices - size_t i, k; - - // number of orders for this atomic calculation - // (not needed for order zero) - const size_t atom_q1 = q+1; - - // variable indices for results vector - // (done differently for order zero). - vector atom_iy; - - // skip the BeginOp at the beginning of the recording - play::const_sequential_iterator itr = play->begin(); - // op_info - OpCode op; - size_t i_var; - const Addr* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); - // -# if CPPAD_FORWARD1_TRACE - bool atom_trace = false; - std::cout << std::endl; -# endif - // - bool flag; // a temporary flag to use in switch cases - bool more_operators = true; - while(more_operators) - { - // next op - (++itr).op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_op_rec() ); - - // check if we are skipping this operation - while( cskip_op[itr.op_index()] ) - { switch(op) - { - case AFunOp: - { // get information for this atomic function call - CPPAD_ASSERT_UNKNOWN( atom_state == start_atom ); - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - // - // skip to the second AFunOp - for(i = 0; i < atom_m + atom_n + 1; ++i) - ++itr; -# ifndef NDEBUG - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); -# endif - } - break; - - case CSkipOp: - case CSumOp: - itr.correct_before_increment(); - break; - - default: - break; - } - (++itr).op_info(op, arg, i_var); - } - - // action depends on the operator - switch( op ) - { - case AbsOp: - forward_abs_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AddvvOp: - forward_addvv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case AddpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_addpv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case AcosOp: - // sqrt(1 - x * x), acos(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_acos_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AcoshOp: - // sqrt(x * x - 1), acosh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_acosh_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AsinOp: - // sqrt(1 - x * x), asin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_asin_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AsinhOp: - // sqrt(1 + x * x), asinh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_asinh_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AtanOp: - // 1 + x * x, atan(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_atan_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AtanhOp: - // 1 - x * x, atanh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_atanh_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case CExpOp: - forward_cond_op( - p, q, i_var, arg, num_par, parameter, J, taylor - ); - break; - // --------------------------------------------------- - - case CosOp: - // sin(x), cos(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_cos_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // --------------------------------------------------- - - case CoshOp: - // sinh(x), cosh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_cosh_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case CSkipOp: - if( p == 0 ) - { forward_cskip_op_0( - i_var, arg, num_par, parameter, J, taylor, cskip_op - ); - } - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case CSumOp: - forward_csum_op( - p, q, i_var, arg, num_par, parameter, J, taylor - ); - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case DisOp: - forward_dis_op(p, q, r, i_var, arg, J, taylor); - break; - // ------------------------------------------------- - - case DivvvOp: - forward_divvv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_divpv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case DivvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_divvp_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case EndOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 0); - more_operators = false; - break; - // ------------------------------------------------- - - case EqppOp: - if( compare_change_count ) - { forward_eqpp_op_0( - compare_change_number, arg, parameter - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case EqpvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_eqpv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case EqvvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_eqvv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case ErfOp: - case ErfcOp: - forward_erf_op(op, p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ExpOp: - forward_exp_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // --------------------------------------------------- - - case Expm1Op: - forward_expm1_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // --------------------------------------------------- - - case InvOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - break; - // ------------------------------------------------- - - case LdpOp: - if( p == 0 ) - { forward_load_p_op_0( - play, - i_var, - arg, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data(), - load_op2var.data() - ); - if( p < q ) forward_load_op( - play, - op, - p+1, - q, - r, - J, - i_var, - arg, - load_op2var.data(), - taylor - ); - } - else - forward_load_op( - play, - op, - p, - q, - r, - J, - i_var, - arg, - load_op2var.data(), - taylor - ); - break; - // ------------------------------------------------- - - case LdvOp: - if( p == 0 ) - { forward_load_v_op_0( - play, - i_var, - arg, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data(), - load_op2var.data() - ); - if( p < q ) forward_load_op( - play, - op, - p+1, - q, - r, - J, - i_var, - arg, - load_op2var.data(), - taylor - ); - } - else - forward_load_op( - play, - op, - p, - q, - r, - J, - i_var, - arg, - load_op2var.data(), - taylor - ); - break; - // ------------------------------------------------- - - case LeppOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_lepp_op_0( - compare_change_number, arg, parameter - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case LepvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_lepv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case LevpOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_levp_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case LevvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_levv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case LogOp: - forward_log_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case Log1pOp: - forward_log1p_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case LtppOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_ltpp_op_0( - compare_change_number, arg, parameter - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case LtpvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_ltpv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case LtvpOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_ltvp_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case LtvvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_ltvv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case MulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case MulvvOp: - forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case NeppOp: - if( compare_change_count ) - { forward_nepp_op_0( - compare_change_number, arg, parameter - ); - { if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - } - break; - // ------------------------------------------------- - - case NepvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_nepv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case NevvOp: - if( ( p == 0 ) & ( compare_change_count > 0 ) ) - { forward_nevv_op_0( - compare_change_number, arg, parameter, J, taylor - ); - if( compare_change_count == compare_change_number ) - compare_change_op_index = itr.op_index(); - } - break; - // ------------------------------------------------- - - case ParOp: - i = p; - if( i == 0 ) - { forward_par_op_0( - i_var, arg, num_par, parameter, J, taylor - ); - i++; - } - while(i <= q) - { taylor[ i_var * J + i] = Base(0.0); - i++; - } - break; - // ------------------------------------------------- - - case PowvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_powvp_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_powpv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PowvvOp: - forward_powvv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PriOp: - if( (p == 0) & print ) forward_pri_0(s_out, - arg, num_text, text, num_par, parameter, J, taylor - ); - break; - // ------------------------------------------------- - - case SignOp: - // sign(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sign_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SinOp: - // cos(x), sin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sin_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SinhOp: - // cosh(x), sinh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sinh_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SqrtOp: - forward_sqrt_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case StppOp: - if( p == 0 ) - { forward_store_pp_op_0( - i_var, - arg, - num_par, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - } - break; - // ------------------------------------------------- - - case StpvOp: - if( p == 0 ) - { forward_store_pv_op_0( - i_var, - arg, - num_par, - parameter, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - } - break; - // ------------------------------------------------- - - case StvpOp: - if( p == 0 ) - { forward_store_vp_op_0( - i_var, - arg, - num_par, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - } - break; - // ------------------------------------------------- - - case StvvOp: - if( p == 0 ) - { forward_store_vv_op_0( - i_var, - arg, - num_par, - J, - taylor, - vec_ad2isvar.data(), - vec_ad2index.data() - ); - } - break; - // ------------------------------------------------- - - case SubvvOp: - forward_subvv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case SubpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_subpv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case SubvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_subvp_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case TanOp: - // tan(x)^2, tan(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_tan_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case TanhOp: - // tanh(x)^2, tanh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_tanh_op(p, q, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - flag = atom_state == start_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = arg_atom; - atom_i = 0; - atom_j = 0; - // - atom_par_x.resize(atom_n); - atom_type_x.resize(atom_n); - atom_tx.resize(atom_n * atom_q1); - atom_ty.resize(atom_m * atom_q1); - atom_iy.resize(atom_m); - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - atom_state = start_atom; - // - // call atomic function for this operation - call_atomic_forward( - atom_par_x, atom_type_x, need_y, - order_low, order_up, atom_index, atom_old, atom_tx, atom_ty - ); - for(i = 0; i < atom_m; i++) - if( atom_iy[i] > 0 ) - for(k = p; k <= q; k++) - taylor[ atom_iy[i] * J + k ] = - atom_ty[ i * atom_q1 + k ]; -# if CPPAD_FORWARD1_TRACE - atom_trace = true; -# endif - } - break; - - case FunapOp: - // parameter argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - if( dyn_par_is[ arg[0] ] ) - atom_type_x[atom_j] = dynamic_enum; - else - atom_type_x[atom_j] = constant_enum; - atom_par_x[atom_j] = parameter[ arg[0] ]; - atom_tx[atom_j * atom_q1 + 0] = parameter[ arg[0]]; - for(k = 1; k < atom_q1; k++) - atom_tx[atom_j * atom_q1 + k] = Base(0.0); - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunavOp: - // variable argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - // - atom_type_x[atom_j] = variable_enum; - atom_par_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - for(k = 0; k < atom_q1; k++) - atom_tx[atom_j * atom_q1 + k] = taylor[ size_t(arg[0]) * J + k]; - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - atom_iy[atom_i] = 0; - atom_ty[atom_i * atom_q1 + 0] = parameter[ arg[0]]; - for(k = 1; k < p; k++) - atom_ty[atom_i * atom_q1 + k] = Base(0.0); - // - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - atom_iy[atom_i] = i_var; - for(k = 0; k < p; k++) - atom_ty[atom_i * atom_q1 + k] = taylor[ i_var * J + k]; - // - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - // ------------------------------------------------- - - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_zmulpv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_zmulvp_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ZmulvvOp: - forward_zmulvv_op(p, q, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(0); - } -# if CPPAD_FORWARD1_TRACE - if( atom_trace ) - { atom_trace = false; - - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); - CPPAD_ASSERT_UNKNOWN( NumArg(FunrvOp) == 0 ); - for(i = 0; i < atom_m; i++) if( atom_iy[i] > 0 ) - { size_t i_tmp = (itr.op_index() + i) - atom_m; - printOp( - std::cout, - play, - i_tmp, - atom_iy[i], - FunrvOp, - nullptr - ); - Base* Z_tmp = taylor + atom_iy[i] * J; - printOpResult( - std::cout, - q + 1, - Z_tmp, - 0, - (Base *) nullptr - ); - std::cout << std::endl; - } - } - Base* Z_tmp = taylor + J * i_var; - if( op != FunrvOp ) - { - printOp( - std::cout, - play, - itr.op_index(), - i_var, - op, - arg - ); - if( NumRes(op) > 0 ) printOpResult( - std::cout, - q + 1, - Z_tmp, - 0, - (Base *) nullptr - ); - std::cout << std::endl; - } - } - std::cout << std::endl; -# else - } -# endif - CPPAD_ASSERT_UNKNOWN( atom_state == start_atom ); - - if( (p == 0) & (compare_change_count == 0) ) - compare_change_number = 0; - return; -} - -// preprocessor symbols that are local to this file -# undef CPPAD_FORWARD1_TRACE - -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/forward2.hpp b/build-config/cppad/include/cppad/local/sweep/forward2.hpp deleted file mode 100644 index 39d32a94..00000000 --- a/build-config/cppad/include/cppad/local/sweep/forward2.hpp +++ /dev/null @@ -1,786 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_FORWARD2_HPP -# define CPPAD_LOCAL_SWEEP_FORWARD2_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file sweep/forward2.hpp -Compute one Taylor coefficient for each direction requested. -*/ - -/*! -\def CPPAD_FORWARD2_TRACE -This value is either zero or one. -Zero is the normal operational value. -If it is one, a trace of every forward2sweep computation is printed. -*/ -# define CPPAD_FORWARD2_TRACE 0 - -/*! -Compute multiple directions forward mode Taylor coefficients. - -\tparam Base -The type used during the forward mode computations; i.e., the corresponding -recording of operations used the type AD. - -\param q -is the order of the Taylor coefficients -that are computed during this call; -q > 0. - -\param r -is the number of Taylor coefficients -that are computed during this call. - -\param n -is the number of independent variables on the tape. - -\param numvar -is the total number of variables on the tape. -This is also equal to the number of rows in the matrix taylor; i.e., -play->num_var_rec(). - -\param play -The information stored in play -is a recording of the operations corresponding to the function -\f[ - F : {\bf R}^n \rightarrow {\bf R}^m -\f] -where \f$ n \f$ is the number of independent variables and -\f$ m \f$ is the number of dependent variables. - -\param J -Is the number of columns in the coefficient matrix taylor. -This must be greater than or equal one. - -\param taylor -\n -\b Input: -For i = 1 , ... , numvar-1, -taylor[ (J-1)*r*i + i + 0 ] -is the zero order Taylor coefficient corresponding to -the i-th variable and all directions. -For i = 1 , ... , numvar-1, -For k = 1 , ... , q-1, -ell = 0 , ... , r-1, -taylor[ (J-1)*r*i + i + (k-1)*r + ell + 1 ] -is the k-th order Taylor coefficient corresponding to -the i-th variabel and ell-th direction. -\n -\n -\b Input: -For i = 1 , ... , n, -ell = 0 , ... , r-1, -taylor[ (J-1)*r*i + i + (q-1)*r + ell + 1 ] -is the q-th order Taylor coefficient corresponding to -the i-th variable and ell-th direction -(these are the independent varaibles). -\n -\n -\b Output: -For i = n+1 , ... , numvar-1, -ell = 0 , ... , r-1, -taylor[ (J-1)*r*i + i + (q-1)*r + ell + 1 ] -is the q-th order Taylor coefficient corresponding to -the i-th variable and ell-th direction. - -\param cskip_op -Is a vector with size play->num_op_rec(). -If cskip_op[i] is true, the operator with index i -does not affect any of the dependent variable (given the value -of the independent variables). - -\param load_op2var -is a vector with size play->num_var_load_rec(). -It is the variable index corresponding to each the -load instruction. -In the case where the index is zero, -the instruction corresponds to a parameter (not variable). - -\param not_used_rec_base -Specifies RecBase for this call. - -*/ - -template -void forward2( - const local::player* play, - const size_t q, - const size_t r, - const size_t n, - const size_t numvar, - const size_t J, - Base* taylor, - const bool* cskip_op, - const pod_vector& load_op2var, - const RecBase& not_used_rec_base -) -{ - CPPAD_ASSERT_UNKNOWN( q > 0 ); - CPPAD_ASSERT_UNKNOWN( J >= q + 1 ); - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - - // only compute one order at a time when using multi-direction forward - size_t p = q; - - // information used by atomic function operators - const pod_vector& dyn_par_is( play->dyn_par_is() ); - const size_t need_y = size_t( variable_enum ); - const size_t order_low = p; - const size_t order_up = q; - - // vectors used by atomic function operators - vector atom_par_x; // argument parameter values - vector atom_type_x; // argument type - vector atom_tx_one; // argument vector Taylor coefficients - vector atom_tx_all; - vector atom_ty_one; // result vector Taylor coefficients - vector atom_ty_all; - // - // information defined by atomic function operators - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - enum_atom_state atom_state = start_atom; // proper initialization - // - // length of the parameter vector (used by CppAD assert macros) - const size_t num_par = play->num_par_rec(); - - // pointer to the beginning of the parameter vector - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - - // temporary indices - size_t i, j, k, ell; - - // number of orders for this atomic calculation - // (not needed for order zero) - const size_t atom_q1 = q+1; - - // variable indices for results vector - // (done differently for order zero). - vector atom_iy; - - // skip the BeginOp at the beginning of the recording - play::const_sequential_iterator itr = play->begin(); - // op_info - OpCode op; - size_t i_var; - const Addr* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == BeginOp ); -# if CPPAD_FORWARD2_TRACE - bool atom_trace = false; - std::cout << std::endl; - CppAD::vector Z_vec(q+1); -# endif - bool flag; // a temporary flag to use in switch cases - bool more_operators = true; - while(more_operators) - { - // next op - (++itr).op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_op_rec() ); - - // check if we are skipping this operation - while( cskip_op[itr.op_index()] ) - { switch(op) - { - case AFunOp: - { // get information for this atomic function call - CPPAD_ASSERT_UNKNOWN( atom_state == start_atom ); - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - // - // skip to the second AFunOp - for(i = 0; i < atom_m + atom_n + 1; ++i) - ++itr; -# ifndef NDEBUG - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); -# endif - } - break; - - case CSkipOp: - case CSumOp: - itr.correct_before_increment(); - break; - - default: - break; - } - (++itr).op_info(op, arg, i_var); - } - - // action depends on the operator - switch( op ) - { - case AbsOp: - forward_abs_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AddvvOp: - forward_addvv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case AddpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_addpv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case AcosOp: - // sqrt(1 - x * x), acos(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_acos_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AcoshOp: - // sqrt(x * x - 1), acosh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_acosh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AsinOp: - // sqrt(1 - x * x), asin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_asin_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AsinhOp: - // sqrt(1 + x * x), asinh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_asinh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AtanOp: - // 1 + x * x, atan(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_atan_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AtanhOp: - // 1 - x * x, atanh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_atanh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case CExpOp: - forward_cond_op_dir( - q, r, i_var, arg, num_par, parameter, J, taylor - ); - break; - // --------------------------------------------------- - - case CosOp: - // sin(x), cos(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_cos_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // --------------------------------------------------- - - case CoshOp: - // sinh(x), cosh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_cosh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case CSkipOp: - // CSkipOp only does somthing on order zero. - CPPAD_ASSERT_UNKNOWN( p > 0 ); - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case CSumOp: - forward_csum_op_dir( - q, r, i_var, arg, num_par, parameter, J, taylor - ); - itr.correct_before_increment(); - break; - // ------------------------------------------------- - - case DisOp: - forward_dis_op(p, q, r, i_var, arg, J, taylor); - break; - // ------------------------------------------------- - - case DivvvOp: - forward_divvv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_divpv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case DivvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_divvp_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case EndOp: - // needed for sparse_jacobian test - CPPAD_ASSERT_NARG_NRES(op, 0, 0); - more_operators = false; - break; - // ------------------------------------------------- - - case ErfOp: - case ErfcOp: - forward_erf_op_dir(op, q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ExpOp: - forward_exp_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case Expm1Op: - forward_expm1_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case InvOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - break; - // ------------------------------------------------- - - case LdpOp: - case LdvOp: - forward_load_op( - play, - op, - p, - q, - r, - J, - i_var, - arg, - load_op2var.data(), - taylor - ); - break; - // --------------------------------------------------- - - case EqppOp: - case EqpvOp: - case EqvvOp: - case LtppOp: - case LtpvOp: - case LtvpOp: - case LtvvOp: - case LeppOp: - case LepvOp: - case LevpOp: - case LevvOp: - case NeppOp: - case NepvOp: - case NevvOp: - CPPAD_ASSERT_UNKNOWN(q > 0 ); - break; - // ------------------------------------------------- - - case LogOp: - forward_log_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // --------------------------------------------------- - - case Log1pOp: - forward_log1p_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // --------------------------------------------------- - - case MulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_mulpv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case MulvvOp: - forward_mulvv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ParOp: - k = i_var*(J-1)*r + i_var + (q-1)*r + 1; - for(ell = 0; ell < r; ell++) - taylor[k + ell] = Base(0.0); - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_powpv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PowvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_powvp_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PowvvOp: - forward_powvv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case PriOp: - CPPAD_ASSERT_UNKNOWN(q > 0); - break; - // ------------------------------------------------- - - case SignOp: - // sign(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sign_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SinOp: - // cos(x), sin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sin_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SinhOp: - // cosh(x), sinh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_sinh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case SqrtOp: - forward_sqrt_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case StppOp: - case StpvOp: - case StvpOp: - case StvvOp: - CPPAD_ASSERT_UNKNOWN(q > 0 ); - break; - // ------------------------------------------------- - - case SubvvOp: - forward_subvv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case SubpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_subpv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case SubvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_subvp_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case TanOp: - // tan(x)^2, tan(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_tan_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case TanhOp: - // tanh(x)^2, tanh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - forward_tanh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor); - break; - // ------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - flag = atom_state == start_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = arg_atom; - atom_i = 0; - atom_j = 0; - // - atom_par_x.resize(atom_n); - atom_type_x.resize(atom_n); - // - atom_tx_one.resize(atom_n * atom_q1); - atom_tx_all.resize(atom_n * (q * r + 1)); - // - atom_ty_one.resize(atom_m * atom_q1); - atom_ty_all.resize(atom_m * (q * r + 1)); - // - atom_iy.resize(atom_m); - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - atom_state = start_atom; - // - // call atomic function for this operation - for(ell = 0; ell < r; ell++) - { // set atom_tx - for(j = 0; j < atom_n; j++) - { size_t j_all = j * (q * r + 1); - size_t j_one = j * atom_q1; - atom_tx_one[j_one+0] = atom_tx_all[j_all+0]; - for(k = 1; k < atom_q1; k++) - { size_t k_all = j_all + (k-1)*r+1+ell; - size_t k_one = j_one + k; - atom_tx_one[k_one] = atom_tx_all[k_all]; - } - } - // set atom_ty - for(i = 0; i < atom_m; i++) - { size_t i_all = i * (q * r + 1); - size_t i_one = i * atom_q1; - atom_ty_one[i_one+0] = atom_ty_all[i_all+0]; - for(k = 1; k < q; k++) - { size_t k_all = i_all + (k-1)*r+1+ell; - size_t k_one = i_one + k; - atom_ty_one[k_one] = atom_ty_all[k_all]; - } - } - call_atomic_forward( - atom_par_x, - atom_type_x, - need_y, - order_low, - order_up, - atom_index, - atom_old, - atom_tx_one, - atom_ty_one - ); - for(i = 0; i < atom_m; i++) - { if( atom_iy[i] > 0 ) - { size_t i_taylor = atom_iy[i]*((J-1)*r+1); - size_t q_taylor = i_taylor + (q-1)*r+1+ell; - size_t q_one = i * atom_q1 + q; - taylor[q_taylor] = atom_ty_one[q_one]; - } - } - } -# if CPPAD_FORWARD2_TRACE - atom_trace = true; -# endif - } - break; - - case FunapOp: - // parameter argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - if( dyn_par_is[ arg[0] ] ) - atom_type_x[atom_j] = dynamic_enum; - else - atom_type_x[atom_j] = constant_enum; - atom_par_x[atom_j] = parameter[ arg[0] ]; - atom_tx_all[atom_j*(q*r+1) + 0] = parameter[ arg[0]]; - for(ell = 0; ell < r; ell++) - for(k = 1; k < atom_q1; k++) - atom_tx_all[atom_j*(q*r+1) + (k-1)*r+1+ell] = Base(0.0); - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunavOp: - // variable argument for a atomic function - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j < atom_n ); - // - atom_type_x[atom_j] = variable_enum; - atom_par_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - atom_tx_all[atom_j*(q*r+1)+0] = - taylor[size_t(arg[0])*((J-1)*r+1)+0]; - for(ell = 0; ell < r; ell++) - { for(k = 1; k < atom_q1; k++) - { atom_tx_all[atom_j*(q*r+1) + (k-1)*r+1+ell] = - taylor[size_t(arg[0])*((J-1)*r+1) + (k-1)*r+1+ell]; - } - } - // - ++atom_j; - if( atom_j == atom_n ) - atom_state = ret_atom; - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - atom_iy[atom_i] = 0; - atom_ty_all[atom_i*(q*r+1) + 0] = parameter[ arg[0]]; - for(ell = 0; ell < r; ell++) - for(k = 1; k < atom_q1; k++) - atom_ty_all[atom_i*(q*r+1) + (k-1)*r+1+ell] = Base(0.0); - // - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i < atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - atom_iy[atom_i] = i_var; - atom_ty_all[atom_i*(q*r+1)+0] = taylor[i_var*((J-1)*r+1)+0]; - for(ell = 0; ell < r; ell++) - { for(k = 1; k < atom_q1; k++) - { atom_ty_all[atom_i*(q*r+1) + (k-1)*r+1+ell] = - taylor[i_var*((J-1)*r+1) + (k-1)*r+1+ell]; - } - } - ++atom_i; - if( atom_i == atom_m ) - atom_state = end_atom; - break; - // ------------------------------------------------- - - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - forward_zmulpv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - forward_zmulvp_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - case ZmulvvOp: - forward_zmulvv_op_dir(q, r, i_var, arg, parameter, J, taylor); - break; - // ------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(0); - } -# if CPPAD_FORWARD2_TRACE - if( atom_trace ) - { atom_trace = false; - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); - CPPAD_ASSERT_UNKNOWN( NumArg(FunrvOp) == 0 ); - for(i = 0; i < atom_m; i++) if( atom_iy[i] > 0 ) - { size_t i_tmp = (itr.op_index() + i) - atom_m; - printOp( - std::cout, - play, - i_tmp, - atom_iy[i], - FunrvOp, - nullptr - ); - Base* Z_tmp = taylor + atom_iy[i]*((J-1) * r + 1); - { Z_vec[0] = Z_tmp[0]; - for(ell = 0; ell < r; ell++) - { std::cout << std::endl << " "; - for(size_t p_tmp = 1; p_tmp <= q; p_tmp++) - Z_vec[p_tmp] = Z_tmp[(p_tmp-1)*r+ell+1]; - printOpResult( - std::cout, - q + 1, - Z_vec.data(), - 0, - (Base *) nullptr - ); - } - } - std::cout << std::endl; - } - } - if( op != FunrvOp ) - { printOp( - std::cout, - play, - itr.op_index(), - i_var, - op, - arg - ); - Base* Z_tmp = nullptr; - if( op == FunavOp ) - Z_tmp = taylor + size_t(arg[0])*((J-1) * r + 1); - else if( NumRes(op) > 0 ) - Z_tmp = taylor + i_var*((J-1)*r + 1); - if( Z_tmp != nullptr ) - { Z_vec[0] = Z_tmp[0]; - for(ell = 0; ell < r; ell++) - { std::cout << std::endl << " "; - for(size_t p_tmp = 1; p_tmp <= q; p_tmp++) - Z_vec[p_tmp] = Z_tmp[ (p_tmp-1)*r + ell + 1]; - printOpResult( - std::cout, - q + 1, - Z_vec.data(), - 0, - (Base *) nullptr - ); - } - } - std::cout << std::endl; - } - } - std::cout << std::endl; -# else - } -# endif - CPPAD_ASSERT_UNKNOWN( atom_state == start_atom ); - - return; -} - -// preprocessor symbols that are local to this file -# undef CPPAD_FORWARD2_TRACE - -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/rev_hes.hpp b/build-config/cppad/include/cppad/local/sweep/rev_hes.hpp deleted file mode 100644 index 2ce3e443..00000000 --- a/build-config/cppad/include/cppad/local/sweep/rev_hes.hpp +++ /dev/null @@ -1,802 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_REV_HES_HPP -# define CPPAD_LOCAL_SWEEP_REV_HES_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file sweep/rev_hes.hpp -Compute Reverse mode Hessian sparsity patterns. -*/ - -/*! -\def CPPAD_REV_HES_TRACE -This value is either zero or one. -Zero is the normal operational value. -If it is one, a trace of every rev_hes_sweep computation is printed. -*/ -# define CPPAD_REV_HES_TRACE 0 - -/*! -Given the forward Jacobian sparsity pattern for all the variables, -and the reverse Jacobian sparsity pattern for the dependent variables, -RevHesSweep computes the Hessian sparsity pattern for all the independent -variables. - -\tparam Base -this operation sequence was recorded using AD. - -\tparam Vector_set -is the type used for vectors of sets. It can be either -sparse::pack_setvec or sparse::list_setvec. - -\param n -is the number of independent variables on the tape. - -\param numvar -is the total number of variables on the tape; i.e., - play->num_var_rec(). -This is also the number of rows in the entire sparsity pattern - rev_hes_sparse. - -\param play -The information stored in play -is a recording of the operations corresponding to a function -\f[ - F : {\bf R}^n \rightarrow {\bf R}^m -\f] -where \f$ n \f$ is the number of independent variables -and \f$ m \f$ is the number of dependent variables. - -\param for_jac_sparse -For i = 0 , ... , numvar - 1, -(for all the variables on the tape), -the forward Jacobian sparsity pattern for the variable with index i -corresponds to the set with index i in for_jac_sparse. - -\param RevJac -\b Input: -For i = 0, ... , numvar - 1 -the if the variable with index i on the tape is an dependent variable and -included in the Hessian, RevJac[ i ] is equal to true, -otherwise it is equal to false. -\n -\n -\b Output: The values in RevJac upon return are not specified; i.e., -it is used for temporary work space. - -\param rev_hes_sparse -The reverse Hessian sparsity pattern for the variable with index i -corresponds to the set with index i in rev_hes_sparse. -\n -\n -\b Input: For i = 0 , ... , numvar - 1 -the reverse Hessian sparsity pattern for the variable with index i is empty. -\n -\n -\b Output: For j = 1 , ... , n, -the reverse Hessian sparsity pattern for the independent dependent variable -with index (j-1) is given by the set with index j -in rev_hes_sparse. -The values in the rest of rev_hes_sparse are not specified; i.e., -they are used for temporary work space. - -\param not_used_rec_base -Specifies RecBase for this call. -*/ - -template -void rev_hes( - const local::player* play, - size_t n, - size_t numvar, - const Vector_set& for_jac_sparse, - bool* RevJac, - Vector_set& rev_hes_sparse, - const RecBase& not_used_rec_base -) -{ - // length of the parameter vector (used by CppAD assert macros) - const size_t num_par = play->num_par_rec(); - - size_t i, j, k; - - // check numvar argument - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse.n_set() == numvar ); - CPPAD_ASSERT_UNKNOWN( rev_hes_sparse.n_set() == numvar ); - CPPAD_ASSERT_UNKNOWN( numvar > 0 ); - - // upper limit exclusive for set elements - size_t limit = rev_hes_sparse.end(); - CPPAD_ASSERT_UNKNOWN( for_jac_sparse.end() == limit ); - - // check number of sets match - CPPAD_ASSERT_UNKNOWN( - for_jac_sparse.n_set() == rev_hes_sparse.n_set() - ); - - // vecad_sparsity contains a sparsity pattern for each VecAD object. - // vecad_ind maps a VecAD index (beginning of the VecAD object) - // to the index for the corresponding set in vecad_sparsity. - size_t num_vecad_ind = play->num_var_vecad_ind_rec(); - size_t num_vecad_vec = play->num_var_vecad_rec(); - Vector_set vecad_sparse; - pod_vector vecad_ind; - pod_vector vecad_jac; - if( num_vecad_vec > 0 ) - { size_t length; - vecad_sparse.resize(num_vecad_vec, limit); - vecad_ind.extend(num_vecad_ind); - vecad_jac.extend(num_vecad_vec); - j = 0; - for(i = 0; i < num_vecad_vec; i++) - { // length of this VecAD - length = play->GetVecInd(j); - // set vecad_ind to proper index for this VecAD - vecad_ind[j] = i; - // make all other values for this vector invalid - for(k = 1; k <= length; k++) - vecad_ind[j+k] = num_vecad_vec; - // start of next VecAD - j += length + 1; - // initialize this vector's reverse jacobian value - vecad_jac[i] = false; - } - CPPAD_ASSERT_UNKNOWN( j == play->num_var_vecad_ind_rec() ); - } - - // ---------------------------------------------------------------------- - // work space used by AFunOp. - vector atom_x; // value of parameter arguments to function - vector type_x; // argument types - pod_vector atom_ix; // variable indices for argument vector - pod_vector atom_iy; // variable indices for result vector - // - // information set by atomic forward (initialization to avoid warnings) - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - // information set by atomic forward (necessary initialization) - enum_atom_state atom_state = end_atom; // proper initialization - // ---------------------------------------------------------------------- - // - // pointer to the beginning of the parameter vector - // (used by atomic functions - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - // - // which parametes are dynamic - const pod_vector& dyn_par_is( play->dyn_par_is() ); - // - // skip the EndOp at the end of the recording - play::const_sequential_iterator itr = play->end(); - // op_info - OpCode op; - size_t i_var; - const Addr* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == EndOp ); -# if CPPAD_REV_HES_TRACE - std::cout << std::endl; - CppAD::vectorBool zf_value(limit); - CppAD::vectorBool zh_value(limit); -# endif - bool more_operators = true; - while(more_operators) - { bool flag; // temporary for use in switch cases - // - // next op - (--itr).op_info(op, arg, i_var); - - // rest of information depends on the case - switch( op ) - { - case AbsOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AddvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_addsub_op( - i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AddpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[1]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AcosOp: - // sqrt(1 - x * x), acos(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AcoshOp: - // sqrt(x * x - 1), acosh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AsinOp: - // sqrt(1 - x * x), asin(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AsinhOp: - // sqrt(1 + x * x), asinh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AtanOp: - // 1 + x * x, atan(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AtanhOp: - // 1 - x * x, atanh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case BeginOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - more_operators = false; - break; - // ------------------------------------------------- - - case CSkipOp: - itr.correct_after_decrement(arg); - break; - // ------------------------------------------------- - - case CSumOp: - itr.correct_after_decrement(arg); - reverse_sparse_hessian_csum_op( - i_var, arg, RevJac, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case CExpOp: - reverse_sparse_hessian_cond_op( - i_var, arg, num_par, RevJac, rev_hes_sparse - ); - break; - // --------------------------------------------------- - - case CosOp: - // sin(x), cos(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // --------------------------------------------------- - - case CoshOp: - // sinh(x), cosh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case DisOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - // derivativve is identically zero - break; - // ------------------------------------------------- - - case DivvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_div_op( - i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[1]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case DivvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case ErfOp: - case ErfcOp: - // arg[1] is always the parameter 0 - // arg[2] is always the parameter 2 / sqrt(pi) - CPPAD_ASSERT_NARG_NRES(op, 3, 5); - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case ExpOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case Expm1Op: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case InvOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 1) - // Z is already defined - break; - // ------------------------------------------------- - - case LdpOp: - reverse_sparse_hessian_load_op( - op, - i_var, - arg, - num_vecad_ind, - vecad_ind.data(), - rev_hes_sparse, - vecad_sparse, - RevJac, - vecad_jac.data() - ); - break; - // ------------------------------------------------- - - case LdvOp: - reverse_sparse_hessian_load_op( - op, - i_var, - arg, - num_vecad_ind, - vecad_ind.data(), - rev_hes_sparse, - vecad_sparse, - RevJac, - vecad_jac.data() - ); - break; - // ------------------------------------------------- - - case EqppOp: - case EqpvOp: - case EqvvOp: - case LtppOp: - case LtpvOp: - case LtvpOp: - case LtvvOp: - case LeppOp: - case LepvOp: - case LevpOp: - case LevvOp: - case NeppOp: - case NepvOp: - case NevvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 0); - break; - // ------------------------------------------------- - - case LogOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case Log1pOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case MulpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[1]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case MulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_mul_op( - i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case ParOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[1]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case PowvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case PowvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3) - sparse::rev_hes_pow_op( - i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case PriOp: - CPPAD_ASSERT_NARG_NRES(op, 5, 0); - break; - // ------------------------------------------------- - - case SignOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - // Derivative is identiaclly zero - break; - // ------------------------------------------------- - - case SinOp: - // cos(x), sin(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case SinhOp: - // cosh(x), sinh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case SqrtOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case StppOp: - // sparsity cannot propagate through a parameter - CPPAD_ASSERT_NARG_NRES(op, 3, 0) - break; - // ------------------------------------------------- - - case StpvOp: - reverse_sparse_hessian_store_op( - op, - arg, - num_vecad_ind, - vecad_ind.data(), - rev_hes_sparse, - vecad_sparse, - RevJac, - vecad_jac.data() - ); - break; - // ------------------------------------------------- - - case StvpOp: - // sparsity cannot propagate through a parameter - CPPAD_ASSERT_NARG_NRES(op, 3, 0) - break; - // ------------------------------------------------- - - case StvvOp: - reverse_sparse_hessian_store_op( - op, - arg, - num_vecad_ind, - vecad_ind.data(), - rev_hes_sparse, - vecad_sparse, - RevJac, - vecad_jac.data() - ); - break; - // ------------------------------------------------- - - case SubvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_addsub_op( - i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case SubpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[1]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case SubvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case TanOp: - // tan(x)^2, tan(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case TanhOp: - // tanh(x)^2, tanh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2) - sparse::rev_hes_nl_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - CPPAD_ASSERT_UNKNOWN( - atom_state == start_atom || atom_state == end_atom - ); - flag = atom_state == end_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = ret_atom; - atom_i = atom_m; - atom_j = atom_n; - // - atom_x.resize(atom_n); - type_x.resize(atom_n); - atom_ix.resize(atom_n); - atom_iy.resize(atom_m); - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j == 0 ); - atom_state = end_atom; - // - // call atomic function for this operation - call_atomic_rev_hes_sparsity( - atom_index, atom_old, atom_x, type_x, atom_ix, atom_iy, - for_jac_sparse, RevJac, rev_hes_sparse - ); - } - break; - - case FunapOp: - // parameter argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j <= atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - --atom_j; - // argument parameter value - atom_x[atom_j] = parameter[arg[0]]; - // argument type - if( dyn_par_is[arg[0]] ) - type_x[atom_j] = dynamic_enum; - else - type_x[atom_j] = constant_enum; - // special variable index used for parameters - atom_ix[atom_j] = 0; - // - if( atom_j == 0 ) - atom_state = start_atom; - break; - - case FunavOp: - // variable argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j <= atom_n ); - // - --atom_j; - // argument variables not available during sparsity calculations - atom_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - type_x[atom_j] = variable_enum; - // variable index for this argument - atom_ix[atom_j] = size_t(arg[0]); - // - if( atom_j == 0 ) - atom_state = start_atom; - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i <= atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - --atom_i; - atom_iy[atom_i] = 0; // special variable used for parameters - // - if( atom_i == 0 ) - atom_state = arg_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i <= atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - --atom_i; - atom_iy[atom_i] = i_var; // variable for this result - // - if( atom_i == 0 ) - atom_state = arg_atom; - break; - // ------------------------------------------------- - - case ZmulpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[1]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case ZmulvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_lin_unary_op( - i_var, size_t(arg[0]), RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - // ------------------------------------------------- - - case ZmulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1) - sparse::rev_hes_mul_op( - i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse - ); - break; - - // ------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(0); - } -# if CPPAD_REV_HES_TRACE - for(j = 0; j < limit; j++) - { zf_value[j] = false; - zh_value[j] = false; - } - typename Vector_set::const_iterator itr_jac(for_jac_sparse, i_var); - j = *itr_jac; - while( j < limit ) - { zf_value[j] = true; - j = *(++itr_jac); - } - typename Vector_set::const_iterator itr_hes(rev_hes_sparse, i_var); - j = *itr_hes; - while( j < limit ) - { zh_value[j] = true; - j = *(++itr_hes); - } - printOp( - std::cout, - play, - itr.op_index(), - i_var, - op, - arg - ); - // should also print RevJac[i_var], but printOpResult does not - // yet allow for this - if( NumRes(op) > 0 && op != BeginOp ) printOpResult( - std::cout, - 1, - &zf_value, - 1, - &zh_value - ); - std::cout << std::endl; - } - std::cout << std::endl; -# else - } -# endif - // values corresponding to BeginOp - CPPAD_ASSERT_UNKNOWN( itr.op_index() == 0 ); - CPPAD_ASSERT_UNKNOWN( i_var == 0 ); - - return; -} -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE - -// preprocessor symbols that are local to this file -# undef CPPAD_REV_HES_TRACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/rev_jac.hpp b/build-config/cppad/include/cppad/local/sweep/rev_jac.hpp deleted file mode 100644 index 5b344dc5..00000000 --- a/build-config/cppad/include/cppad/local/sweep/rev_jac.hpp +++ /dev/null @@ -1,815 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_REV_JAC_HPP -# define CPPAD_LOCAL_SWEEP_REV_JAC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include - -// This value is either zero or one. Zero is the normal operational value. -// If it is one, a trace of every rev_jac_sweep computation is printed. -# define CPPAD_REV_JAC_TRACE 0 - -/* -$begin local_sweep_rev_jac$$ -$spell - Jacobian - jac - Jacobian - numvar - var - Addr - CondExpRel - optimizer - num - setvec -$$ - -$section Reverse Mode Jacobian Sparsity Patterns$$ - -$head Syntax$$ -$codei%local::sweep::rev_jac( - %play% , - %dependency% , - %n% , - %numvar% , - %var_sparsity% , - %not_used_rec_base -)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PROTOTYPE%// END_PROTOTYPE%1 -%$$ - -$head Addr$$ -Is the type used to record address on this tape -This is allows for smaller tapes when address are smaller. - -$head Base$$ -this operation sequence was recorded using $codei%AD<%Base%>%$$. - -$head Vector_set$$ -is the type used for vectors of sets. It can be either -$code sparse::pack_setvec$$ or $code sparse::list_setvec$$. -$comment 2DO: in previous line change code to cref$$ - -$head RecBase$$ -Is the base type when this function was recorded. -This is different from $icode Base$$ if -this function object was created by $cref base2ad$$. - -$head play$$ -The information stored in play -is a recording of the operations corresponding to a function -$latex F : \B{R}^n \rightarrow \B{R}^m$$ -where $icode m$$ is the number of dependent variables. - -$head dependency$$ -Are we computing dependency relations, or only concerned with -possibly non-zero derivatives. For example, -are the derivatives with respect to -$icode left$$ and $icode right$$ of the expression below -considered to be non-zero: -$codei% - CondExpRel(%left%, %right%, %if_true%, %if_false%) -%$$ -This is used by the optimizer to obtain the correct dependency relations. - -$head n$$ -is the number of independent variables in the tape. - -$head numvar$$ -is the total number of variables in the tape; i.e., -$icode%play%->num_var_rec()%$$. -This is also the number of rows in all the sparsity patterns. - -$head var_sparsity$$ - -$subhead On Input$$ -For $icode%i% = 0 , ... , %numvar%-1%$$, -if $icode i$$ corresponds to a dependent variables, -the set with index $icode i$$ is an input. -Otherwise the set with index $icode i$$ is empty. - -$subhead On Output$$ -For $icode%i% = 0 , ... , %numvar%-1%$$, -the sparsity pattern for the variable with index $icode%j%-1%$$ -is given by the set with index $icode j$$ in $icode var_sparsity$$. -Note that one dependent variable may depend on the value of another, -in which case its output sparsity pattern may be different than its -input pattern. - -$head not_used_rec_base$$ -Specifies $icode RecBase$$ for this call. - -$end -*/ - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { - -// BEGIN_PROTOTYPE -template -void rev_jac( - const local::player* play , - bool dependency , - size_t n , - size_t numvar , - Vector_set& var_sparsity , - const RecBase& not_used_rec_base ) -// END_PROTOTYPE -{ - size_t i, j, k; - - // length of the parameter vector (used by CppAD assert macros) - const size_t num_par = play->num_par_rec(); - - // check numvar argument - CPPAD_ASSERT_UNKNOWN( numvar > 0 ); - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - CPPAD_ASSERT_UNKNOWN( var_sparsity.n_set() == numvar ); - - // upper limit (exclusive) for elements in the set - size_t limit = var_sparsity.end(); - - // vecad_sparsity contains a sparsity pattern for each VecAD object. - // vecad_ind maps a VecAD index (beginning of the VecAD object) - // to the index of the corresponding set in vecad_sparsity. - size_t num_vecad_ind = play->num_var_vecad_ind_rec(); - size_t num_vecad_vec = play->num_var_vecad_rec(); - Vector_set vecad_sparsity; - pod_vector vecad_ind; - if( num_vecad_vec > 0 ) - { size_t length; - vecad_sparsity.resize(num_vecad_vec, limit); - vecad_ind.extend(num_vecad_ind); - j = 0; - for(i = 0; i < num_vecad_vec; i++) - { // length of this VecAD - length = play->GetVecInd(j); - // set to proper index for this VecAD - vecad_ind[j] = i; - for(k = 1; k <= length; k++) - vecad_ind[j+k] = num_vecad_vec; // invalid index - // start of next VecAD - j += length + 1; - } - CPPAD_ASSERT_UNKNOWN( j == play->num_var_vecad_ind_rec() ); - } - - // ---------------------------------------------------------------------- - // work space used by AFunOp. - vector atom_x; // value of parameter arguments to function - vector type_x; // argument types - pod_vector atom_ix; // variable indices for argument vector - pod_vector atom_iy; // variable indices for result vector - // - // information set by atomic forward (initialization to avoid warnings) - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - // information set by atomic forward (necessary initialization) - enum_atom_state atom_state = end_atom; // proper initialization - // ---------------------------------------------------------------------- - // - // pointer to the beginning of the parameter vector - // (used by atomic functions - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - // - // which parametes are dynamic - const pod_vector& dyn_par_is( play->dyn_par_is() ); - // - // skip the EndOp at the end of the recording - play::const_sequential_iterator itr = play->end(); - // op_info - OpCode op; - size_t i_var; - const Addr* arg; - itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == EndOp ); -# if CPPAD_REV_JAC_TRACE - std::cout << std::endl; - CppAD::vectorBool z_value(limit); -# endif - bool more_operators = true; - while(more_operators) - { bool flag; // temporary for use in switch cases - // - // next op - (--itr).op_info(op, arg, i_var); - - // rest of information depends on the case - switch( op ) - { - case AbsOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AddvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case AddpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AcosOp: - // sqrt(1 - x * x), acos(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AcoshOp: - // sqrt(x * x - 1), acosh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AsinOp: - // sqrt(1 - x * x), asin(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AsinhOp: - // sqrt(1 + x * x), asinh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AtanOp: - // 1 + x * x, atan(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AtanhOp: - // 1 - x * x, atanh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case BeginOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - more_operators = false; - break; - // ------------------------------------------------- - - case CSkipOp: - itr.correct_after_decrement(arg); - break; - // ------------------------------------------------- - - case CSumOp: - itr.correct_after_decrement(arg); - reverse_sparse_jacobian_csum_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case CExpOp: - reverse_sparse_jacobian_cond_op( - dependency, i_var, arg, num_par, var_sparsity - ); - break; - // --------------------------------------------------- - - case CosOp: - // sin(x), cos(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // --------------------------------------------------- - - case CoshOp: - // sinh(x), cosh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case DisOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - // derivative is identically zero but dependency is not - if( dependency ) sparse::rev_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case DivvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case DivvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case ErfOp: - case ErfcOp: - // arg[1] is always the parameter 0 - // arg[0] is always the parameter 2 / sqrt(pi) - CPPAD_ASSERT_NARG_NRES(op, 3, 5); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case ExpOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case Expm1Op: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case InvOp: - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - break; - // ------------------------------------------------- - - case LdpOp: - reverse_sparse_jacobian_load_op( - dependency, - op, - i_var, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case LdvOp: - reverse_sparse_jacobian_load_op( - dependency, - op, - i_var, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case EqppOp: - case EqpvOp: - case EqvvOp: - case LtppOp: - case LtpvOp: - case LtvpOp: - case LtvvOp: - case LeppOp: - case LepvOp: - case LevpOp: - case LevvOp: - case NeppOp: - case NepvOp: - case NevvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 0); - break; - // ------------------------------------------------- - - case LogOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case Log1pOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case MulpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case MulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case ParOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - - break; - // ------------------------------------------------- - - case PowvpOp: - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3); - sparse::rev_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case PowvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 3); - sparse::rev_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case PriOp: - CPPAD_ASSERT_NARG_NRES(op, 5, 0); - break; - // ------------------------------------------------- - - case SignOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - // derivative is identically zero but dependency is not - if( dependency ) sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case SinOp: - // cos(x), sin(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case SinhOp: - // cosh(x), sinh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case SqrtOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case StppOp: - // does not affect sparsity or dependency when both are parameters - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - break; - // ------------------------------------------------- - - case StpvOp: - reverse_sparse_jacobian_store_op( - dependency, - op, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case StvpOp: - CPPAD_ASSERT_NARG_NRES(op, 3, 0); - // storing a parameter only affects dependency - reverse_sparse_jacobian_store_op( - dependency, - op, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case StvvOp: - reverse_sparse_jacobian_store_op( - dependency, - op, - arg, - num_vecad_ind, - vecad_ind.data(), - var_sparsity, - vecad_sparsity - ); - break; - // ------------------------------------------------- - - case SubvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - case SubpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case SubvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case TanOp: - // tan(x)^2, tan(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case TanhOp: - // tanh(x)^2, tanh(x) - CPPAD_ASSERT_NARG_NRES(op, 1, 2); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - CPPAD_ASSERT_UNKNOWN( - atom_state == start_atom || atom_state == end_atom - ); - flag = atom_state == end_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = ret_atom; - atom_i = atom_m; - atom_j = atom_n; - // - atom_x.resize( atom_n ); - type_x.resize( atom_n ); - atom_ix.resize( atom_n ); - atom_iy.resize( atom_m ); - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j == 0 ); - atom_state = end_atom; - // - call_atomic_rev_jac_sparsity( - atom_index, - atom_old, - dependency, - atom_x, - type_x, - atom_ix, - atom_iy, - var_sparsity - ); - } - break; - - case FunapOp: - // parameter argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j <= atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - --atom_j; - // argument parameter value - atom_x[atom_j] = parameter[arg[0]]; - // argument type - if( dyn_par_is[arg[0]] ) - type_x[atom_j] = dynamic_enum; - else - type_x[atom_j] = constant_enum; - // special variable index used for parameters - atom_ix[atom_j] = 0; - // - if( atom_j == 0 ) - atom_state = start_atom; - break; - - case FunavOp: - // variable argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j <= atom_n ); - // - --atom_j; - // argument variables not available during sparsity calculations - atom_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - type_x[atom_j] = variable_enum; - // variable index for this argument - atom_ix[atom_j] = size_t(arg[0]); - // - if( atom_j == 0 ) - atom_state = start_atom; - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i <= atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - --atom_i; - atom_iy[atom_i] = 0; // special variable used for parameters - // - if( atom_i == 0 ) - atom_state = arg_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i <= atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - --atom_i; - atom_iy[atom_i] = i_var; // variable for this result - // - if( atom_i == 0 ) - atom_state = arg_atom; - break; - // ------------------------------------------------- - - case ZmulpvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[1]), var_sparsity - ); - break; - // ------------------------------------------------- - - case ZmulvpOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_unary_op( - i_var, size_t(arg[0]), var_sparsity - ); - break; - // ------------------------------------------------- - - case ZmulvvOp: - CPPAD_ASSERT_NARG_NRES(op, 2, 1); - sparse::rev_jac_binary_op( - i_var, arg, var_sparsity - ); - break; - // ------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(0); - } -# if CPPAD_REV_JAC_TRACE - for(j = 0; j < limit; j++) - z_value[j] = false; - typename Vector_set::const_iterator itr(var_sparsity, i_var); - j = *itr; - while( j < limit ) - { z_value[j] = true; - j = *(++itr); - } - printOp( - std::cout, - play, - itr.op_index(), - i_var, - op, - arg - ); - // Note that sparsity for FunrvOp are computed before call to - // atomic function so no need to delay printing (as in forward mode) - if( NumRes(op) > 0 && op != BeginOp ) printOpResult( - std::cout, - 0, - (CppAD::vectorBool *) nullptr, - 1, - &z_value - ); - std::cout << std::endl; - } - std::cout << std::endl; -# else - } -# endif - // values corresponding to BeginOp - CPPAD_ASSERT_UNKNOWN( itr.op_index() == 0 ); - CPPAD_ASSERT_UNKNOWN( i_var == 0 ); - - return; -} - -// preprocessor symbols that are local to this file -# undef CPPAD_REV_JAC_TRACE - -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/local/sweep/reverse.hpp b/build-config/cppad/include/cppad/local/sweep/reverse.hpp deleted file mode 100644 index 84957d0a..00000000 --- a/build-config/cppad/include/cppad/local/sweep/reverse.hpp +++ /dev/null @@ -1,809 +0,0 @@ -# ifndef CPPAD_LOCAL_SWEEP_REVERSE_HPP -# define CPPAD_LOCAL_SWEEP_REVERSE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -# include - -// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE -namespace CppAD { namespace local { namespace sweep { -/*! -\file sweep/reverse.hpp -Compute derivatives of arbitrary order Taylor coefficients. -*/ - -/*! -\def CPPAD_REVERSE_TRACE -This value is either zero or one. -Zero is the normal operational value. -If it is one, a trace of every reverse_sweep computation is printed. -*/ -# define CPPAD_REVERSE_TRACE 0 - -/*! -Compute derivative of arbitrary order forward mode Taylor coefficients. - -\tparam Base -this operation sequence was recorded using AD -and computations by this routine are done using type Base. - -\param d -is the highest order Taylor coefficients that -we are computing the derivative of. - -\param n -is the number of independent variables on the tape. - -\param numvar -is the total number of variables on the tape. -This is also equal to the number of rows in the matrix Taylor; i.e., -play->num_var_rec(). - -\param play -The information stored in play -is a recording of the operations corresponding to the function -\f[ - F : {\bf R}^n \rightarrow {\bf R}^m -\f] -where \f$ n \f$ is the number of independent variables and -\f$ m \f$ is the number of dependent variables. -We define \f$ u^{(k)} \f$ as the value of x_k in the previous call -of the form - - f.Forward(k, x_k) - -We define -\f$ X : {\bf R}^{n \times d} \rightarrow {\bf R}^n \f$ by -\f[ - X(t, u) = u^{(0)} + u^{(1)} t + \cdots + u^{(d)} t^d -\f] -We define -\f$ Y : {\bf R}^{n \times d} \rightarrow {\bf R}^m \f$ by -\f[ - Y(t, u) = F[ X(t, u) ] -\f] -We define the function -\f$ W : {\bf R}^{n \times d} \rightarrow {\bf R} \f$ by -\f[ -W(u) -= -\sum_{k=0}^{d} ( w^{(k)} )^{\rm T} - \frac{1}{k !} \frac{\partial^k}{\partial t^k} Y(0, u) -\f] -(The matrix \f$ w \in {\bf R}^m \f$, -is defined below under the heading Partial.) -Note that the scale factor 1 / k converts -the k-th partial derivative to the k-th order Taylor coefficient. -This routine computes the derivative of \f$ W(u) \f$ -with respect to all the Taylor coefficients -\f$ u^{(k)} \f$ for \f$ k = 0 , ... , d \f$. - -\param J -Is the number of columns in the coefficient matrix Taylor. -This must be greater than or equal d + 1. - -\param Taylor -For i = 1 , ... , numvar, and for k = 0 , ... , d, - Taylor [ i * J + k ] -is the k-th order Taylor coefficient corresponding to -variable with index i on the tape. -The value \f$ u \in {\bf R}^{n \times d} \f$, -at which the derivative is computed, -is defined by -\f$ u_j^{(k)} \f$ = Taylor [ j * J + k ] -for j = 1 , ... , n, and for k = 0 , ... , d. - -\param K -Is the number of columns in the partial derivative matrix Partial. -It must be greater than or equal d + 1. - -\param Partial -\b Input: -The last \f$ m \f$ rows of Partial are inputs. -The matrix \f$ w \f$, used to define \f$ W(u) \f$, -is specified by these rows. -For i = 0 , ... , m - 1, -for k = 0 , ... , d, -Partial [ (numvar - m + i ) * K + k ] = w[i,k]. -\n -\n -\b Temporary: -For i = n+1 , ... , numvar - 1 and for k = 0 , ... , d, -the value of Partial [ i * K + k ] is used for temporary work space -and its output value is not defined. -\n -\n -\b Output: -For j = 1 , ... , n and for k = 0 , ... , d, - Partial [ j * K + k ] -is the partial derivative of \f$ W( u ) \f$ with -respect to \f$ u_j^{(k)} \f$. - -\param cskip_op -Is a vector with size play->num_op_rec(). -If cskip_op[i] is true, the operator index i in the recording -does not affect any of the dependent variable (given the value -of the independent variables). -Note that all the operators in an atomic function call are skipped as a block, -so only the last AFunOp fore each call needs to have cskip_op[i] true. - -\param load_op2var -is a vector with size play->num_var_load_rec(). -It contains the variable index corresponding to each load instruction. -In the case where the index is zero, -the instruction corresponds to a parameter (not variable). - -\tparam Iterator -This is either player::const_iteratoror player::const_subgraph_iterator. - -\param play_itr -On input this is either play->end(), for the entire graph, -or play->end(subgraph), for a subgraph. -This routine mode will use --play_itr to iterate over the graph or subgraph. -It is assumes that the iterator starts just past the EndOp and it will -continue until it reaches the BeginOp. -If i_var is a variable index, and the corresponding operator -is not in the subgraph, -then the partials with respect to i_var are not modified and need to be -initialized as zero. Note that this means the partial for the independent -varaibles, that are not in the subgraph are not calculated. -If part of an atomic function call is in the subgraph, -the entire atomic function call must be in the subgraph. - -\param not_used_rec_base -Specifies RecBase for this call. - -\par Assumptions -The first operator on the tape is a BeginOp, -and the next n operators are InvOp operations for the -corresponding independent variables; see play->check_inv_op(n_ind). -*/ -template -void reverse( - size_t d, - size_t n, - size_t numvar, - const local::player* play, - size_t J, - const Base* Taylor, - size_t K, - Base* Partial, - bool* cskip_op, - const pod_vector& load_op2var, - Iterator& play_itr, - const RecBase& not_used_rec_base -) -{ - // check numvar argument - CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar ); - CPPAD_ASSERT_UNKNOWN( numvar > 0 ); - - // length of the parameter vector (used by CppAD assert macros) - const size_t num_par = play->num_par_rec(); - - // pointer to the beginning of the parameter vector - CPPAD_ASSERT_UNKNOWN( num_par > 0 ) - const Base* parameter = play->GetPar(); - - // work space used by AFunOp. - const size_t atom_k = d; // highest order we are differentiating - const size_t atom_k1 = d+1; // number orders for this calculation - vector atom_par_x; // argument parameter values - vector atom_type_x; // argument type - vector atom_ix; // variable indices for argument vector - vector atom_tx; // argument vector Taylor coefficients - vector atom_ty; // result vector Taylor coefficients - vector atom_px; // partials w.r.t argument vector - vector atom_py; // partials w.r.t. result vector - // - // information defined by atomic forward - size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0; - enum_atom_state atom_state = end_atom; // proper initialization - - // temporary indices - size_t j, ell; - - // Initialize -# if CPPAD_REVERSE_TRACE - std::cout << std::endl; -# endif - OpCode op; - const Addr* arg; - size_t i_var; - play_itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == EndOp ); - while(op != BeginOp ) - { bool flag; // temporary for use in switch cases - // - // next op - (--play_itr).op_info(op, arg, i_var); - - // check if we are skipping this operation - size_t i_op = play_itr.op_index(); - while( cskip_op[i_op] ) - { switch(op) - { - case AFunOp: - { // get information for this atomic function call - CPPAD_ASSERT_UNKNOWN( atom_state == end_atom ); - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - // - // skip to the first AFunOp - for(size_t i = 0; i < atom_m + atom_n + 1; ++i) - --play_itr; - play_itr.op_info(op, arg, i_var); - CPPAD_ASSERT_UNKNOWN( op == AFunOp ); - } - break; - - default: - break; - } - (--play_itr).op_info(op, arg, i_var); - i_op = play_itr.op_index(); - } -# if CPPAD_REVERSE_TRACE - size_t i_tmp = i_var; - const Base* Z_tmp = Taylor + i_var * J; - const Base* pZ_tmp = Partial + i_var * K; - printOp( - std::cout, - play, - i_op, - i_tmp, - op, - arg - ); - if( NumRes(op) > 0 && op != BeginOp ) printOpResult( - std::cout, - d + 1, - Z_tmp, - d + 1, - pZ_tmp - ); - std::cout << std::endl; -# endif - switch( op ) - { - case AbsOp: - reverse_abs_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AcosOp: - // sqrt(1 - x * x), acos(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_acos_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AcoshOp: - // sqrt(x * x - 1), acosh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_acosh_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AddvvOp: - reverse_addvv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AddpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - reverse_addpv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AsinOp: - // sqrt(1 - x * x), asin(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_asin_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AsinhOp: - // sqrt(1 + x * x), asinh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_asinh_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AtanOp: - // 1 + x * x, atan(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_atan_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case AtanhOp: - // 1 - x * x, atanh(x) - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_atanh_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case BeginOp: - CPPAD_ASSERT_NARG_NRES(op, 1, 1); - CPPAD_ASSERT_UNKNOWN( i_op == 0 ); - break; - // -------------------------------------------------- - - case CSkipOp: - // CSkipOp has a zero order forward action. - play_itr.correct_after_decrement(arg); - break; - // ------------------------------------------------- - - case CSumOp: - play_itr.correct_after_decrement(arg); - reverse_csum_op( - d, i_var, arg, K, Partial - ); - // end of a cumulative summation - break; - // ------------------------------------------------- - - case CExpOp: - reverse_cond_op( - d, - i_var, - arg, - num_par, - parameter, - J, - Taylor, - K, - Partial - ); - break; - // -------------------------------------------------- - - case CosOp: - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_cos_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case CoshOp: - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_cosh_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case DisOp: - // Derivative of discrete operation is zero so no - // contribution passes through this operation. - break; - // -------------------------------------------------- - - case DivvvOp: - reverse_divvv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case DivpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - reverse_divpv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case DivvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - reverse_divvp_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - case EndOp: - CPPAD_ASSERT_UNKNOWN( - i_op == play->num_op_rec() - 1 - ); - break; - - // -------------------------------------------------- - - case ErfOp: - case ErfcOp: - reverse_erf_op( - op, d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case ExpOp: - reverse_exp_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case Expm1Op: - reverse_expm1_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case InvOp: - break; - // -------------------------------------------------- - - case LdpOp: - reverse_load_op( - op, d, i_var, arg, J, Taylor, K, Partial, load_op2var.data() - ); - break; - // ------------------------------------------------- - - case LdvOp: - reverse_load_op( - op, d, i_var, arg, J, Taylor, K, Partial, load_op2var.data() - ); - break; - // -------------------------------------------------- - - case EqppOp: - case EqpvOp: - case EqvvOp: - case LtppOp: - case LtpvOp: - case LtvpOp: - case LtvvOp: - case LeppOp: - case LepvOp: - case LevpOp: - case LevvOp: - case NeppOp: - case NepvOp: - case NevvOp: - break; - // ------------------------------------------------- - - case LogOp: - reverse_log_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case Log1pOp: - reverse_log1p_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case MulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - reverse_mulpv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case MulvvOp: - reverse_mulvv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case ParOp: - break; - // -------------------------------------------------- - - case PowvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - reverse_powvp_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case PowpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - reverse_powpv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case PowvvOp: - reverse_powvv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case PriOp: - // no result so nothing to do - break; - // -------------------------------------------------- - - case SignOp: - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_sign_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case SinOp: - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_sin_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case SinhOp: - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_sinh_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case SqrtOp: - reverse_sqrt_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case StppOp: - break; - // -------------------------------------------------- - - case StpvOp: - break; - // ------------------------------------------------- - - case StvpOp: - break; - // ------------------------------------------------- - - case StvvOp: - break; - // -------------------------------------------------- - - case SubvvOp: - reverse_subvv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case SubpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - reverse_subpv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case SubvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - reverse_subvp_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case TanOp: - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_tan_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // ------------------------------------------------- - - case TanhOp: - CPPAD_ASSERT_UNKNOWN( i_var < numvar ); - reverse_tanh_op( - d, i_var, size_t(arg[0]), J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case AFunOp: - // start or end an atomic function call - flag = atom_state == end_atom; - play::atom_op_info( - op, arg, atom_index, atom_old, atom_m, atom_n - ); - if( flag ) - { atom_state = ret_atom; - atom_i = atom_m; - atom_j = atom_n; - // - atom_ix.resize(atom_n); - atom_par_x.resize(atom_n); - atom_type_x.resize(atom_n); - atom_tx.resize(atom_n * atom_k1); - atom_px.resize(atom_n * atom_k1); - atom_ty.resize(atom_m * atom_k1); - atom_py.resize(atom_m * atom_k1); - } - else - { CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j == 0 ); - atom_state = end_atom; - // - // call atomic function for this operation - call_atomic_reverse( - atom_par_x, - atom_type_x, - atom_k, - atom_index, - atom_old, - atom_tx, - atom_ty, - atom_px, - atom_py - ); - for(j = 0; j < atom_n; j++) if( atom_ix[j] > 0 ) - { for(ell = 0; ell < atom_k1; ell++) - Partial[atom_ix[j] * K + ell] += - atom_px[j * atom_k1 + ell]; - } - } - break; - - case FunapOp: - // parameter argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j <= atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - --atom_j; - atom_ix[atom_j] = 0; - if( play->dyn_par_is()[ arg[0] ] ) - atom_type_x[atom_j] = dynamic_enum; - else - atom_type_x[atom_j] = constant_enum; - atom_par_x[atom_j] = parameter[ arg[0] ]; - atom_tx[atom_j * atom_k1 + 0] = parameter[ arg[0] ]; - for(ell = 1; ell < atom_k1; ell++) - atom_tx[atom_j * atom_k1 + ell] = Base(0.); - // - if( atom_j == 0 ) - atom_state = start_atom; - break; - - case FunavOp: - // variable argument in an atomic operation sequence - CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 ); - CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i == 0 ); - CPPAD_ASSERT_UNKNOWN( atom_j <= atom_n ); - // - --atom_j; - atom_ix[atom_j] = size_t( arg[0] ); - atom_type_x[atom_j] = variable_enum; - atom_par_x[atom_j] = CppAD::numeric_limits::quiet_NaN(); - for(ell = 0; ell < atom_k1; ell++) - atom_tx[atom_j*atom_k1 + ell] = - Taylor[ size_t(arg[0]) * J + ell]; - // - if( atom_j == 0 ) - atom_state = start_atom; - break; - - case FunrpOp: - // parameter result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 1, 0); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i <= atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par ); - // - --atom_i; - for(ell = 0; ell < atom_k1; ell++) - { atom_py[atom_i * atom_k1 + ell] = Base(0.); - atom_ty[atom_i * atom_k1 + ell] = Base(0.); - } - atom_ty[atom_i * atom_k1 + 0] = parameter[ arg[0] ]; - // - if( atom_i == 0 ) - atom_state = arg_atom; - break; - - case FunrvOp: - // variable result for a atomic function - CPPAD_ASSERT_NARG_NRES(op, 0, 1); - CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom ); - CPPAD_ASSERT_UNKNOWN( atom_i <= atom_m ); - CPPAD_ASSERT_UNKNOWN( atom_j == atom_n ); - // - --atom_i; - for(ell = 0; ell < atom_k1; ell++) - { atom_py[atom_i * atom_k1 + ell] = - Partial[i_var * K + ell]; - atom_ty[atom_i * atom_k1 + ell] = - Taylor[i_var * J + ell]; - } - if( atom_i == 0 ) - atom_state = arg_atom; - break; - // ------------------------------------------------------------ - - case ZmulpvOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par ); - reverse_zmulpv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case ZmulvpOp: - CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par ); - reverse_zmulvp_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - case ZmulvvOp: - reverse_zmulvv_op( - d, i_var, arg, parameter, J, Taylor, K, Partial - ); - break; - // -------------------------------------------------- - - default: - CPPAD_ASSERT_UNKNOWN(false); - } - } -# if CPPAD_REVERSE_TRACE - std::cout << std::endl; -# endif -} - -} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE - -// preprocessor symbols that are local to this file -# undef CPPAD_REVERSE_TRACE - -# endif diff --git a/build-config/cppad/include/cppad/local/tan_op.hpp b/build-config/cppad/include/cppad/local/tan_op.hpp deleted file mode 100644 index fba7dc83..00000000 --- a/build-config/cppad/include/cppad/local/tan_op.hpp +++ /dev/null @@ -1,231 +0,0 @@ -# ifndef CPPAD_LOCAL_TAN_OP_HPP -# define CPPAD_LOCAL_TAN_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file tan_op.hpp -Forward and reverse mode calculations for z = tan(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tan(x) -\endverbatim -The auxillary result is -\verbatim - y = tan(x)^2 -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_tan_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* y = z - cap_order; - - size_t k; - if( p == 0 ) - { z[0] = tan( x[0] ); - y[0] = z[0] * z[0]; - p++; - } - for(size_t j = p; j <= q; j++) - { Base base_j = static_cast(double(j)); - - z[j] = x[j]; - for(k = 1; k <= j; k++) - z[j] += Base(double(k)) * x[k] * y[j-k] / base_j; - - y[j] = z[0] * z[j]; - for(k = 1; k <= j; k++) - y[j] += z[k] * z[j-k]; - } -} - -/*! -Multiple directions forward mode Taylor coefficient for op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tan(x) -\endverbatim -The auxillary result is -\verbatim - y = tan(x)^2 -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_tan_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* y = z - num_taylor_per_var; - - size_t k; - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = Base(double(q)) * ( x[m+ell] + x[m+ell] * y[0]); - for(k = 1; k < q; k++) - z[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * y[(q-k-1)*r+1+ell]; - z[m+ell] /= Base(double(q)); - // - y[m+ell] = Base(2.0) * z[m+ell] * z[0]; - for(k = 1; k < q; k++) - y[m+ell] += z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell]; - } -} - - -/*! -Compute zero order forward mode Taylor coefficient for result of op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tan(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_tan_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; // called z in documentation - Base* y = z - cap_order; // called y in documentation - - z[0] = tan( x[0] ); - y[0] = z[0] * z[0]; -} - -/*! -Compute reverse mode partial derivatives for result of op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tan(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_tan_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; // called z in doc - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* y = z - cap_order; // called y in documentation - Base* py = pz - nc_partial; - - - size_t j = d; - size_t k; - Base base_two(2); - while(j) - { - px[j] += pz[j]; - pz[j] /= Base(double(j)); - for(k = 1; k <= j; k++) - { px[k] += azmul(pz[j], y[j-k]) * Base(double(k)); - py[j-k] += azmul(pz[j], x[k]) * Base(double(k)); - } - for(k = 0; k < j; k++) - pz[k] += azmul(py[j-1], z[j-k-1]) * base_two; - - --j; - } - px[0] += azmul(pz[0], Base(1.0) + y[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/tanh_op.hpp b/build-config/cppad/include/cppad/local/tanh_op.hpp deleted file mode 100644 index a2ade1fa..00000000 --- a/build-config/cppad/include/cppad/local/tanh_op.hpp +++ /dev/null @@ -1,230 +0,0 @@ -# ifndef CPPAD_LOCAL_TANH_OP_HPP -# define CPPAD_LOCAL_TANH_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file tanh_op.hpp -Forward and reverse mode calculations for z = tanh(x). -*/ - - -/*! -Compute forward mode Taylor coefficient for result of op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tanh(x) -\endverbatim -The auxillary result is -\verbatim - y = tanh(x)^2 -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op -*/ -template -void forward_tanh_op( - size_t p , - size_t q , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; - Base* y = z - cap_order; - - size_t k; - if( p == 0 ) - { z[0] = tanh( x[0] ); - y[0] = z[0] * z[0]; - p++; - } - for(size_t j = p; j <= q; j++) - { Base base_j = static_cast(double(j)); - - z[j] = x[j]; - for(k = 1; k <= j; k++) - z[j] -= Base(double(k)) * x[k] * y[j-k] / base_j; - - y[j] = z[0] * z[j]; - for(k = 1; k <= j; k++) - y[j] += z[k] * z[j-k]; - } -} - -/*! -Multiple directions forward mode Taylor coefficient for op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tanh(x) -\endverbatim -The auxillary result is -\verbatim - y = tanh(x)^2 -\endverbatim -The value of y, and its derivatives, are computed along with the value -and derivatives of z. - -\copydetails CppAD::local::forward_unary2_op_dir -*/ -template -void forward_tanh_op_dir( - size_t q , - size_t r , - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to argument and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + i_x * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - Base* y = z - num_taylor_per_var; - - size_t k; - size_t m = (q-1) * r + 1; - for(size_t ell = 0; ell < r; ell++) - { z[m+ell] = Base(double(q)) * ( x[m+ell] - x[m+ell] * y[0] ); - for(k = 1; k < q; k++) - z[m+ell] -= Base(double(k)) * x[(k-1)*r+1+ell] * y[(q-k-1)*r+1+ell]; - z[m+ell] /= Base(double(q)); - // - y[m+ell] = Base(2.0) * z[m+ell] * z[0]; - for(k = 1; k < q; k++) - y[m+ell] += z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell]; - } -} - -/*! -Compute zero order forward mode Taylor coefficient for result of op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tanh(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::forward_unary2_op_0 -*/ -template -void forward_tanh_op_0( - size_t i_z , - size_t i_x , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( 0 < cap_order ); - - // Taylor coefficients corresponding to argument and result - Base* x = taylor + i_x * cap_order; - Base* z = taylor + i_z * cap_order; // called z in documentation - Base* y = z - cap_order; // called y in documentation - - z[0] = tanh( x[0] ); - y[0] = z[0] * z[0]; -} - -/*! -Compute reverse mode partial derivatives for result of op = TanOp. - -The C++ source code corresponding to this operation is -\verbatim - z = tanh(x) -\endverbatim -The auxillary result is -\verbatim - y = cos(x) -\endverbatim -The value of y is computed along with the value of z. - -\copydetails CppAD::local::reverse_unary2_op -*/ - -template -void reverse_tanh_op( - size_t d , - size_t i_z , - size_t i_x , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Taylor coefficients and partials corresponding to argument - const Base* x = taylor + i_x * cap_order; - Base* px = partial + i_x * nc_partial; - - // Taylor coefficients and partials corresponding to first result - const Base* z = taylor + i_z * cap_order; // called z in doc - Base* pz = partial + i_z * nc_partial; - - // Taylor coefficients and partials corresponding to auxillary result - const Base* y = z - cap_order; // called y in documentation - Base* py = pz - nc_partial; - - - size_t j = d; - size_t k; - Base base_two(2); - while(j) - { - px[j] += pz[j]; - pz[j] /= Base(double(j)); - for(k = 1; k <= j; k++) - { px[k] -= azmul(pz[j], y[j-k]) * Base(double(k)); - py[j-k] -= azmul(pz[j], x[k]) * Base(double(k)); - } - for(k = 0; k < j; k++) - pz[k] += azmul(py[j-1], z[j-k-1]) * base_two; - - --j; - } - px[0] += azmul(pz[0], Base(1.0) - y[0]); -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/utility/cppad_vector_itr.hpp b/build-config/cppad/include/cppad/local/utility/cppad_vector_itr.hpp deleted file mode 100644 index b4415d9c..00000000 --- a/build-config/cppad/include/cppad/local/utility/cppad_vector_itr.hpp +++ /dev/null @@ -1,444 +0,0 @@ -# ifndef CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP -# define CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -/* ------------------------------------------------------------------------------- -$begin cppad_vector_itr_define$$ -$spell - Iterator - cppad - itr - undef - const - endif - hpp -$$ - -$section Vector Class Iterator Preprocessor Definitions$$ - -$head Syntax$$ -$codep -# define CPPAD_CONST 0 -# include -# undef CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP -# define CPPAD_CONST 1 -# include -%$$ - -$head Beginning of cppad_vector_itr.hpp$$ -The following preprocessor definition appears at the beginning of -$code cppad_vector_itr.hpp$$ and is used for the class definition in this file: -$codep -# if CPPAD_CONST -# define CPPAD_VECTOR_ITR const_cppad_vector_itr -# else -# define CPPAD_VECTOR_ITR cppad_vector_itr -# endif -$$ - -$head End of cppad_vector_itr.hpp$$ -The following preprocessor definition appears at the end of -$code cppad_vector_itr.hpp$$ so that it can be included with a different -value for $code CPPAD_CONST$$: -$codep -# undef CPPAD_CONST -# undef CPPAD_VECTOR_ITR -$$ - -$end -*/ -# if CPPAD_CONST -# define CPPAD_VECTOR_ITR const_cppad_vector_itr -# else -# define CPPAD_VECTOR_ITR cppad_vector_itr -# endif - - -// BEGIN_CPPAD_LOCAL_UTILITY_NAMESPACE -namespace CppAD { namespace local { namespace utility { - -// so can be declared friend in cppad_vector_itr -template class const_cppad_vector_itr; - -// ========================================================================== -template class CPPAD_VECTOR_ITR { -// ========================================================================== -/* ------------------------------------------------------------------------------ -$begin cppad_vector_itr_traits$$ -$spell - Iterator -$$ - -$section Vector Class Iterator Traits and Friends$$ - -$srccode%hpp% */ -# if ! CPPAD_CONST - friend class const_cppad_vector_itr; -# endif -public: - typedef std::random_access_iterator_tag iterator_category; - typedef Type value_type; - typedef std::ptrdiff_t difference_type; - typedef Type* pointer; - typedef Type& reference; -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cppad_vector_itr_ctor$$ -$spell - Iterator - ptr - cppad - Namespace - CppAD - const - iterators - itr -$$ - -$section Vector Class Iterator Member Data and Constructors$$ - -$head Constructors$$ - -$subhead Constant$$ -$codei%const_cppad_vector_itr %itr%() -%$$ -$codei%const_cppad_vector_itr %itr%(%data%, %length%, %index%) -%$$ -$codei%const_cppad_vector_itr %itr%(%other%) -%$$ -$codei%const_cppad_vector_itr %itr%(%non_const_other%) -%$$ - -$subhead Not Constant$$ -$codei%cppad_vector_itr %itr%() -%$$ -$codei%cppad_vector_itr %itr%(%data%, %length%, %index%) -%$$ -$codei%cppad_vector_itr %itr%(%other%) -%$$ - -$head Namespace$$ -These definitions are in the $code CppAD::local::utility$$ namespace. - -$head Indirection$$ -We use an extra level of indirection in this routine so that -the iterator has the same values as the vector even if the vector changes. - -$head data_$$ -is a pointer to a constant pointer to data for this vector -(used by operations that are not supported by constant iterators). - -$head length_$$ -is a pointer to the length of the corresponding vector. - -$head index_$$ -is the current vector index corresponding to this iterator. - -$head check_element$$ -generates an assert with a known cause when the $code index_$$ -does not correspond go a valid element and -$code NDEBUG$$ is not defined. - -$head check_cop$$ -Generates an assert with a known cause when the $code data_$$ -for this vector is different from the other vector and -$code NDEBUG$$ is not defined. -This should be used by operators that compare iterators. - - -$head Source$$ -$srccode%hpp% */ -private: -# if CPPAD_CONST - const Type* const* data_; -# else - Type* const* data_; -# endif - const size_t* length_; - difference_type index_; - void check_element(void) const CPPAD_NDEBUG_NOEXCEPT - { CPPAD_ASSERT_KNOWN( 0 <= index_ && size_t(index_) < *length_, - "CppAD vector iterator: accessing element out of range" - ); - } - void check_cop(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT - { CPPAD_ASSERT_KNOWN( data_ == other.data_, - "CppAD vector iterator: comparing indices from different vectors" - ); - } -public: - CPPAD_VECTOR_ITR(void) noexcept - : data_(nullptr), length_(nullptr), index_(0) - { } -# if CPPAD_CONST - const_cppad_vector_itr( - const Type* const* data, const size_t* length, difference_type index - ) noexcept - : data_(data), length_(length), index_( difference_type(index) ) - { } - // ctor a const_iterator from an iterator - const_cppad_vector_itr( - const cppad_vector_itr& non_const_other - ) noexcept - { data_ = non_const_other.data_; - length_ = non_const_other.length_; - index_ = non_const_other.index_; - } -# else - cppad_vector_itr( - Type* const* data, const size_t* length, difference_type index - ) noexcept - : data_(data), length_(length), index_( difference_type(index) ) - { } -# endif - void operator=(const CPPAD_VECTOR_ITR& other) noexcept - { data_ = other.data_; - length_ = other.length_; - index_ = other.index_; - } - CPPAD_VECTOR_ITR(const CPPAD_VECTOR_ITR& other) noexcept - { *this = other; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cppad_vector_itr_inc$$ -$spell - Iterator - itr -$$ - -$section Vector Class Iterator Increment Operators$$ - -$head Syntax$$ -$codei%++%itr% -%$$ -$codei%--%itr% -%$$ -$icode%itr%++ -%$$ -$icode%itr%-- -%$$ - -$head Source$$ -$srccode%hpp% */ -public: - CPPAD_VECTOR_ITR& operator++(void) noexcept - { ++index_; - return *this; - } - CPPAD_VECTOR_ITR& operator--(void) noexcept - { --index_; - return *this; - } - CPPAD_VECTOR_ITR operator++(int) noexcept - { CPPAD_VECTOR_ITR ret(*this); - ++index_; - return ret; - } - CPPAD_VECTOR_ITR operator--(int) noexcept - { CPPAD_VECTOR_ITR ret(*this); - --index_; - return ret; - } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cppad_vector_itr_equal$$ -$spell - itr - Iterator -$$ - -$section Vector Class Iterator Equality Operators$$ -$spell - iterators -$$ - -$head Syntax$$ -$icode%itr% == %other% -%$$ -$icode%itr% != %other% -%$$ - -$head Restrictions$$ -It is an error to compare iterators corresponding to different -$code data_$$ vectors - -$head Source$$ -$srccode%hpp% */ -public: - bool operator==(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT - { check_cop(other); - return index_ == other.index_; - } - bool operator!=(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT - { check_cop(other); - return index_ != other.index_; - } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cppad_vector_itr_element$$ -$spell - itr - Iterator -$$ - -$section Vector Class Iterator Access Elements$$ - -$head Syntax$$ -$icode%element% = *%itr% -%$$ -$codei%*%itr% = %element% -%$$ - -$head Source$$ -$srccode%hpp% */ -public: - const Type& operator*(void) const - { check_element(); - return (*data_)[index_]; - } -# if ! CPPAD_CONST - Type& operator*(void) - { check_element(); - return (*data_)[index_]; - } -# endif -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cppad_vector_itr_random$$ -$spell - itr - Iterator - bool - iterators -$$ - -$section Vector Class Iterator Random Access$$ - -$head Syntax$$ -$icode%element% = %itr%[%n%] -%$$ -$icode%itr%[%n%] = %element% -%$$ -$icode%itr% %+-% = %n% -%$$ -$icode%itr% = %other% %+-% %n% -%$$ -$icode%itr% = %n% %+-% %other% -%$$ -$icode%n% = %itr% - %other% -%$$ -$code%b% = %itr% %cop% %other% -%$$ - -$subhead +-$$ -The notation $icode +-$$ above is either $code +$$ or $code -$$. - -$subhead cop$$ -is one of the following: -$code <$$, $code <=$$, -$code >$$, $code >=$$. - -$head itr, other$$ -are iterators of the same type. - -$head n$$ -is a $code difference_type$$ object. - -$head b$$ -is a $code bool$$. - -$head Restrictions$$ -It is an error to use a $icode cop$$ with iterators corresponding to different -$code data_$$ vectors - -$head Source$$ -$srccode%hpp% */ -public: - CPPAD_VECTOR_ITR operator[](difference_type n) - { return *(*this + n); - } - // sum and difference operators - CPPAD_VECTOR_ITR& operator+=(difference_type n) noexcept - { index_ += n; - return *this; - } - CPPAD_VECTOR_ITR& operator-=(difference_type n) noexcept - { index_ -= n; - return *this; - } - CPPAD_VECTOR_ITR operator+(difference_type n) const noexcept - { return CPPAD_VECTOR_ITR(data_, length_, index_ + n); - } - CPPAD_VECTOR_ITR operator-(difference_type n) const noexcept - { return CPPAD_VECTOR_ITR(data_, length_, index_ - n); - } - difference_type operator-(const CPPAD_VECTOR_ITR& other) const - noexcept - { return index_ - other.index_; - } - // comparison operators - bool operator<(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT - { check_cop(other); - return index_ < other.index_; - } - bool operator<=(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT - { check_cop(other); - return index_ <= other.index_; - } - bool operator>(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT - { check_cop(other); - return index_ > other.index_; - } - bool operator>=(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT - { check_cop(other); - return index_ >= other.index_; - } -/* %$$ -$srcthisfile% - 0%// BEGIN_BINARY_OP%// END_BINARY_OP%1 -%$$ -$end -*/ -// ========================================================================== -}; // END_TEMPLATE_CLASS_CPPAD_VECTOR_ITR -// ========================================================================== - -// BEGIN_BINARY_OP -template CPPAD_VECTOR_ITR operator+( - typename CPPAD_VECTOR_ITR::difference_type n , - const CPPAD_VECTOR_ITR& other ) noexcept -{ return - CPPAD_VECTOR_ITR(other.data_, other.length_, n + other.index_ ); -} -template CPPAD_VECTOR_ITR operator-( - typename CPPAD_VECTOR_ITR::difference_type n , - const CPPAD_VECTOR_ITR& other ) noexcept -{ return - CPPAD_VECTOR_ITR(other.data_, other.length_, n - other.index_ ); -} -// END_BINARY_OP - -} } } // END_CPPAD_LOCAL_UTILITY_NAMESPACE - -# undef CPPAD_CONST -# undef CPPAD_VECTOR_ITR -# endif diff --git a/build-config/cppad/include/cppad/local/utility/vector_bool.hpp b/build-config/cppad/include/cppad/local/utility/vector_bool.hpp deleted file mode 100644 index 48d5d147..00000000 --- a/build-config/cppad/include/cppad/local/utility/vector_bool.hpp +++ /dev/null @@ -1,84 +0,0 @@ -# ifndef CPPAD_LOCAL_UTILITY_VECTOR_BOOL_HPP -# define CPPAD_LOCAL_UTILITY_VECTOR_BOOL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include - -// BEGIN_CPPAD_LOCAL_UTILITY_NAMESPACE -namespace CppAD { namespace local { namespace utility { -/* -$begin vector_bool_element$$ -$spell - Bool -$$ - -$section vectorBoolElement Class$$ - -$head Syntax$$ -$codei%local::utility::vectorBoolElement %element%(%unit%, %mask%) -%$$ -$codei%local::utility::vectorBoolElement %element%(%other%) -%$$ -$icode%value% = %element% -%$$ -$icode%element% = %value% -%$$ -$icode%element% = %element% -%$$ - -$head unit_t$$ -Type used to pack multiple boolean (bit) values into one unit. -Logical operations are preformed one unit at a time. - -$head unit_$$ -pointer to the unit that holds the value for this element. - -$head mask_$$ -mask for the bit corresponding to this element; i.e., all the bits -are zero except for bit that corresponds to this element which is one. - -$head value$$ -is a $code bool$$. - -$head Source$$ -$srccode%hpp% */ -class vectorBoolElement { -private: - typedef size_t unit_t; - unit_t* unit_; - unit_t mask_; -public: - vectorBoolElement(unit_t* unit, unit_t mask ) - : unit_(unit) , mask_(mask) - { } - vectorBoolElement(const vectorBoolElement& other) - : unit_(other.unit_) , mask_(other.mask_) - { } - operator bool() const - { return (*unit_ & mask_) != 0; } - vectorBoolElement& operator=(bool value) - { if(value) *unit_ |= mask_; - else *unit_ &= ~mask_; - return *this; - } - vectorBoolElement& operator=(const vectorBoolElement& element) - { if( *(element.unit_) & element.mask_ ) *unit_ |= mask_; - else *unit_ &= ~mask_; - return *this; - } -}; -/* %$$ -$end -*/ -} } } // END_CPPAD_LOCAL_UTILITY_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/local/zmul_op.hpp b/build-config/cppad/include/cppad/local/zmul_op.hpp deleted file mode 100644 index 13f9049e..00000000 --- a/build-config/cppad/include/cppad/local/zmul_op.hpp +++ /dev/null @@ -1,517 +0,0 @@ -# ifndef CPPAD_LOCAL_ZMUL_OP_HPP -# define CPPAD_LOCAL_ZMUL_OP_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE -/*! -\file mul_op.hpp -Forward and reverse mode calculations for z = azmul(x, y). -*/ - -// --------------------------- Zmulvv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = ZmulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_zmulvv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - size_t k; - for(size_t d = p; d <= q; d++) - { z[d] = Base(0.0); - for(k = 0; k <= d; k++) - z[d] += azmul(x[d-k], y[k]); - } -} -/*! -Multiple directions forward mode Taylor coefficients for op = ZmulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_zmulvv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var; - Base* z = taylor + i_z * num_taylor_per_var; - - size_t k, ell, m; - for(ell = 0; ell < r; ell++) - { m = (q-1)*r + ell + 1; - z[m] = azmul(x[0], y[m]) + azmul(x[m], y[0]); - for(k = 1; k < q; k++) - z[m] += azmul(x[(q-k-1)*r + ell + 1], y[(k-1)*r + ell + 1]); - } -} - -/*! -Compute zero order forward mode Taylor coefficients for result of op = ZmulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_zmulvv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = azmul(x[0], y[0]); -} - -/*! -Compute reverse mode partial derivatives for result of op = ZmulvvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where both x and y are variables -and the argument parameter is not used. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_zmulvv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Arguments - const Base* x = taylor + size_t(arg[0]) * cap_order; - const Base* y = taylor + size_t(arg[1]) * cap_order; - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t j = d + 1; - size_t k; - while(j) - { --j; - for(k = 0; k <= j; k++) - { - px[j-k] += azmul(pz[j], y[k]); - py[k] += azmul(pz[j], x[j-k]); - } - } -} -// --------------------------- Zmulpv ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = ZmulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_zmulpv_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - // Paraemter value - Base x = parameter[ arg[0] ]; - - for(size_t d = p; d <= q; d++) - z[d] = azmul(x, y[d]); -} -/*! -Multiple directions forward mode Taylor coefficients for op = ZmulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_zmulpv_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q-1) * r + 1; - Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m; - Base* z = taylor + i_z * num_taylor_per_var + m; - - // Paraemter value - Base x = parameter[ arg[0] ]; - - for(size_t ell = 0; ell < r; ell++) - z[ell] = azmul(x, y[ell]); -} -/*! -Compute zero order forward mode Taylor coefficient for result of op = ZmulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_zmulpv_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 ); - - // Paraemter value - Base x = parameter[ arg[0] ]; - - // Taylor coefficients corresponding to arguments and result - Base* y = taylor + size_t(arg[1]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = azmul(x, y[0]); -} - -/*! -Compute reverse mode partial derivative for result of op = ZmulpvOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_zmulpv_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Arguments - Base x = parameter[ arg[0] ]; - - // Partial derivatives corresponding to arguments and result - Base* py = partial + size_t(arg[1]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t j = d + 1; - while(j) - { --j; - py[j] += azmul(pz[j], x); - } -} -// --------------------------- Zmulvp ----------------------------------------- -/*! -Compute forward mode Taylor coefficients for result of op = ZmulvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op -*/ - -template -void forward_zmulvp_op( - size_t p , - size_t q , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - CPPAD_ASSERT_UNKNOWN( p <= q ); - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z = taylor + i_z * cap_order; - - // Paraemter value - Base y = parameter[ arg[1] ]; - - for(size_t d = p; d <= q; d++) - z[d] = azmul(x[d], y); -} -/*! -Multiple directions forward mode Taylor coefficients for op = ZmulvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_dir -*/ - -template -void forward_zmulvp_op_dir( - size_t q , - size_t r , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( 0 < q ); - CPPAD_ASSERT_UNKNOWN( q < cap_order ); - - // Taylor coefficients corresponding to arguments and result - size_t num_taylor_per_var = (cap_order-1) * r + 1; - size_t m = (q-1) * r + 1; - Base* x = taylor + size_t(arg[0]) * num_taylor_per_var + m; - Base* z = taylor + i_z * num_taylor_per_var + m; - - // Paraemter value - Base y = parameter[ arg[1] ]; - - for(size_t ell = 0; ell < r; ell++) - z[ell] = azmul(x[ell], y); -} -/*! -Compute zero order forward mode Taylor coefficient for result of op = ZmulvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::forward_binary_op_0 -*/ - -template -void forward_zmulvp_op_0( - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - Base* taylor ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 ); - - // Paraemter value - Base y = parameter[ arg[1] ]; - - // Taylor coefficients corresponding to arguments and result - Base* x = taylor + size_t(arg[0]) * cap_order; - Base* z = taylor + i_z * cap_order; - - z[0] = azmul(x[0], y); -} - -/*! -Compute reverse mode partial derivative for result of op = ZmulvpOp. - -The C++ source code corresponding to this operation is -\verbatim - z = azmul(x, y) -\endverbatim -In the documentation below, -this operations is for the case where x is a parameter and y is a variable. - -\copydetails CppAD::local::reverse_binary_op -*/ - -template -void reverse_zmulvp_op( - size_t d , - size_t i_z , - const addr_t* arg , - const Base* parameter , - size_t cap_order , - const Base* taylor , - size_t nc_partial , - Base* partial ) -{ - // check assumptions - CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 ); - CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 ); - CPPAD_ASSERT_UNKNOWN( d < cap_order ); - CPPAD_ASSERT_UNKNOWN( d < nc_partial ); - - // Arguments - Base y = parameter[ arg[1] ]; - - // Partial derivatives corresponding to arguments and result - Base* px = partial + size_t(arg[0]) * nc_partial; - Base* pz = partial + i_z * nc_partial; - - // number of indices to access - size_t j = d + 1; - while(j) - { --j; - px[j] += azmul(pz[j], y); - } -} - -} } // END_CPPAD_LOCAL_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/speed/det_33.hpp b/build-config/cppad/include/cppad/speed/det_33.hpp deleted file mode 100644 index 6a59fd2a..00000000 --- a/build-config/cppad/include/cppad/speed/det_33.hpp +++ /dev/null @@ -1,113 +0,0 @@ -# ifndef CPPAD_SPEED_DET_33_HPP -# define CPPAD_SPEED_DET_33_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin det_33$$ -$spell - cppad - CppAD - det - namespace - const - bool - hpp -$$ - -$section Check Determinant of 3 by 3 matrix$$ - - -$head Syntax$$ -$codei%# include -%$$ -$icode%ok% = det_33(%x%, %d%)%$$ - -$head Purpose$$ -This routine can be used to check a method for computing -the determinant of a matrix. - -$head Inclusion$$ -The template function $code det_33$$ is defined in the $code CppAD$$ -namespace by including -the file $code cppad/speed/det_33.hpp$$ -(relative to the CppAD distribution directory). - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %Vector% &%x% -%$$. -It contains the elements of the matrix $latex X$$ in row major order; i.e., -$latex \[ - X_{i,j} = x [ i * 3 + j ] -\] $$ - -$head d$$ -The argument $icode d$$ has prototype -$codei% - const %Vector% &%d% -%$$. -It is tested to see if $icode%d%[0]%$$ it is equal to $latex \det ( X )$$. - -$head Vector$$ -If $icode y$$ is a $icode Vector$$ object, -it must support the syntax -$codei% - %y%[%i%] -%$$ -where $icode i$$ has type $code size_t$$ with value less than 9. -This must return a $code double$$ value corresponding to the $th i$$ -element of the vector $icode y$$. -This is the only requirement of the type $icode Vector$$. -(Note that only the first element of the vector $icode d$$ is used.) - -$head ok$$ -The return value $icode ok$$ has prototype -$codei% - bool %ok% -%$$ -It is true, if the determinant $icode%d%[0]%$$ -passes the test and false otherwise. - -$children% - omh/det_33_hpp.omh -%$$ - -$head Source Code$$ -The file -$cref det_33.hpp$$ -contains the source code for this template function. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -namespace CppAD { -template - bool det_33(const Vector &x, const Vector &d) - { bool ok = true; - double eps99 = 99.0 * std::numeric_limits::epsilon(); - - // use expansion by minors to compute the determinant by hand - double check = 0.; - check += x[0] * ( x[4] * x[8] - x[5] * x[7] ); - check -= x[1] * ( x[3] * x[8] - x[5] * x[6] ); - check += x[2] * ( x[3] * x[7] - x[4] * x[6] ); - - ok &= CppAD::NearEqual(check, d[0], eps99, eps99); - - return ok; - } -} -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/det_by_lu.hpp b/build-config/cppad/include/cppad/speed/det_by_lu.hpp deleted file mode 100644 index 25ed10f5..00000000 --- a/build-config/cppad/include/cppad/speed/det_by_lu.hpp +++ /dev/null @@ -1,182 +0,0 @@ -# ifndef CPPAD_SPEED_DET_BY_LU_HPP -# define CPPAD_SPEED_DET_BY_LU_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin det_by_lu$$ -$spell - CppAD - cppad - lu - hpp - typedef - const - hpp - Det - CPPAD_TESTVECTOR - namespace -$$ - -$section Determinant Using Expansion by Lu Factorization$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%det_by_lu<%Scalar%> %det%(%n%) -%$$ -$icode%d% = %det%(%a%) -%$$ - -$head Inclusion$$ -The template class $code det_by_lu$$ is defined in the $code CppAD$$ -namespace by including -the file $code cppad/speed/det_by_lu.hpp$$ -(relative to the CppAD distribution directory). - -$head Constructor$$ -The syntax -$codei% - det_by_lu<%Scalar%> %det%(%n%) -%$$ -constructs the object $icode det$$ which can be used for -evaluating the determinant of $icode n$$ by $icode n$$ matrices -using LU factorization. - -$head Scalar$$ -The type $icode Scalar$$ can be any -$cref NumericType$$ - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ - -$head det$$ -The syntax -$codei% - %d% = %det%(%a%) -%$$ -returns the determinant of the matrix $latex A$$ using LU factorization. - -$subhead a$$ -The argument $icode a$$ has prototype -$codei% - const %Vector% &%a% -%$$ -It must be a $icode Vector$$ with length $latex n * n$$ and with -It must be a $icode Vector$$ with length $latex n * n$$ and with -elements of type $icode Scalar$$. -The elements of the $latex n \times n$$ matrix $latex A$$ are defined, -for $latex i = 0 , \ldots , n-1$$ and $latex j = 0 , \ldots , n-1$$, by -$latex \[ - A_{i,j} = a[ i * m + j] -\] $$ - -$subhead d$$ -The return value $icode d$$ has prototype -$codei% - %Scalar% %d% -%$$ - -$head Vector$$ -If $icode y$$ is a $icode Vector$$ object, -it must support the syntax -$codei% - %y%[%i%] -%$$ -where $icode i$$ has type $code size_t$$ with value less than $latex n * n$$. -This must return a $icode Scalar$$ value corresponding to the $th i$$ -element of the vector $icode y$$. -This is the only requirement of the type $icode Vector$$. - -$children% - speed/example/det_by_lu.cpp% - omh/det_by_lu_hpp.omh -%$$ - - -$head Example$$ -The file -$cref det_by_lu.cpp$$ -contains an example and test of $code det_by_lu.hpp$$. - -$head Source Code$$ -The file -$cref det_by_lu.hpp$$ -contains the source for this template function. - - -$end ---------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include - -// BEGIN CppAD namespace -namespace CppAD { - -template -class det_by_lu { -private: - const size_t m_; - const size_t n_; - CppAD::vector A_; - CppAD::vector B_; - CppAD::vector X_; -public: - det_by_lu(size_t n) : m_(0), n_(n), A_(n * n) - { } - - template - Scalar operator()(const Vector &x) - { - - Scalar logdet; - Scalar det; - int signdet; - size_t i; - - // copy matrix so it is not overwritten - for(i = 0; i < n_ * n_; i++) - A_[i] = x[i]; - - // comput log determinant - signdet = CppAD::LuSolve( - n_, m_, A_, B_, X_, logdet); - -/* - // Do not do this for speed test because it makes floating - // point operation sequence very simple. - if( signdet == 0 ) - det = 0; - else - det = Scalar( signdet ) * exp( logdet ); -*/ - - // convert to determinant - det = Scalar( signdet ) * exp( logdet ); - -# ifdef FADBAD - // Fadbad requires tempories to be set to constants - for(i = 0; i < n_ * n_; i++) - A_[i] = 0; -# endif - - return det; - } -}; -} // END CppAD namespace -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/det_by_minor.hpp b/build-config/cppad/include/cppad/speed/det_by_minor.hpp deleted file mode 100644 index 88724a2a..00000000 --- a/build-config/cppad/include/cppad/speed/det_by_minor.hpp +++ /dev/null @@ -1,165 +0,0 @@ -# ifndef CPPAD_SPEED_DET_BY_MINOR_HPP -# define CPPAD_SPEED_DET_BY_MINOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin det_by_minor$$ -$spell - CppAD - cppad - typedef - const - hpp - Det - namespace -$$ - -$section Determinant Using Expansion by Minors$$ - - - -$head Syntax$$ -$codei%# include -%$$ -$codei%det_by_minor<%Scalar%> %det%(%n%) -%$$ -$icode%d% = %det%(%a%) -%$$ - -$head Inclusion$$ -The template class $code det_by_minor$$ is defined in the $code CppAD$$ -namespace by including -the file $code cppad/speed/det_by_minor.hpp$$ -(relative to the CppAD distribution directory). - -$head Constructor$$ -The syntax -$codei% - det_by_minor<%Scalar%> %det%(%n%) -%$$ -constructs the object $icode det$$ which can be used for -evaluating the determinant of $icode n$$ by $icode n$$ matrices -using expansion by minors. - -$head Scalar$$ -The type $icode Scalar$$ must satisfy the same conditions -as in the function $cref/det_of_minor/det_of_minor/Scalar/$$. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ - -$head det$$ -The syntax -$codei% - %d% = %det%(%a%) -%$$ -returns the determinant of the matrix $icode A$$ using expansion by minors. - -$subhead a$$ -The argument $icode a$$ has prototype -$codei% - const %Vector% &%a% -%$$ -It must be a $icode Vector$$ with length $latex n * n$$ and with -elements of type $icode Scalar$$. -The elements of the $latex n \times n$$ matrix $latex A$$ are defined, -for $latex i = 0 , \ldots , n-1$$ and $latex j = 0 , \ldots , n-1$$, by -$latex \[ - A_{i,j} = a[ i * m + j] -\] $$ - -$subhead d$$ -The return value $icode d$$ has prototype -$codei% - %Scalar% %d% -%$$ -It is equal to the determinant of $latex A$$. - -$head Vector$$ -If $icode y$$ is a $icode Vector$$ object, -it must support the syntax -$codei% - %y%[%i%] -%$$ -where $icode i$$ has type $code size_t$$ with value less than $latex n * n$$. -This must return a $icode Scalar$$ value corresponding to the $th i$$ -element of the vector $icode y$$. -This is the only requirement of the type $icode Vector$$. - -$children% - speed/example/det_by_minor.cpp% - omh/det_by_minor_hpp.omh -%$$ - - -$head Example$$ -The file -$cref det_by_minor.cpp$$ -contains an example and test of $code det_by_minor.hpp$$. - -$head Source Code$$ -The file -$cref det_by_minor.hpp$$ -contains the source for this template function. - - -$end ---------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include - -// BEGIN CppAD namespace -namespace CppAD { - -template -class det_by_minor { -private: - size_t m_; - - // made mutable because modified and then restored - mutable std::vector r_; - mutable std::vector c_; - - // make mutable because its value does not matter - mutable std::vector a_; -public: - det_by_minor(size_t m) : m_(m) , r_(m + 1) , c_(m + 1), a_(m * m) - { - size_t i; - - // values for r and c that correspond to entire matrix - for(i = 0; i < m; i++) - { r_[i] = i+1; - c_[i] = i+1; - } - r_[m] = 0; - c_[m] = 0; - } - - template - Scalar operator()(const Vector &x) const - { size_t i = m_ * m_; - while(i--) - a_[i] = x[i]; - return det_of_minor(a_, m_, m_, r_, c_); - } - -}; - -} // END CppAD namespace -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/det_grad_33.hpp b/build-config/cppad/include/cppad/speed/det_grad_33.hpp deleted file mode 100644 index 74dc3136..00000000 --- a/build-config/cppad/include/cppad/speed/det_grad_33.hpp +++ /dev/null @@ -1,127 +0,0 @@ -# ifndef CPPAD_SPEED_DET_GRAD_33_HPP -# define CPPAD_SPEED_DET_GRAD_33_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin det_grad_33$$ -$spell - cppad - CppAD - det - namespace - const - bool - hpp -$$ - -$section Check Gradient of Determinant of 3 by 3 matrix$$ - - -$head Syntax$$ -$codei%# include -%$$ -$icode%ok% = det_grad_33(%x%, %g%)%$$ - -$head Purpose$$ -This routine can be used to check a method for computing the -gradient of the determinant of a matrix. - -$head Inclusion$$ -The template function $code det_grad_33$$ is defined in the $code CppAD$$ -namespace by including -the file $code cppad/speed/det_grad_33.hpp$$ -(relative to the CppAD distribution directory). - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %Vector% &%x% -%$$. -It contains the elements of the matrix $latex X$$ in row major order; i.e., -$latex \[ - X_{i,j} = x [ i * 3 + j ] -\] $$ - -$head g$$ -The argument $icode g$$ has prototype -$codei% - const %Vector% &%g% -%$$. -It contains the elements of the gradient of -$latex \det ( X )$$ in row major order; i.e., -$latex \[ - \D{\det (X)}{X(i,j)} = g [ i * 3 + j ] -\] $$ - -$head Vector$$ -If $icode y$$ is a $icode Vector$$ object, -it must support the syntax -$codei% - %y%[%i%] -%$$ -where $icode i$$ has type $code size_t$$ with value less than 9. -This must return a $code double$$ value corresponding to the $th i$$ -element of the vector $icode y$$. -This is the only requirement of the type $icode Vector$$. - -$head ok$$ -The return value $icode ok$$ has prototype -$codei% - bool %ok% -%$$ -It is true, if the gradient $icode g$$ -passes the test and false otherwise. - -$children% - omh/det_grad_33_hpp.omh -%$$ - -$head Source Code$$ -The file -$cref det_grad_33.hpp$$ -contains the source code for this template function. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include -namespace CppAD { -template - bool det_grad_33(const Vector &x, const Vector &g) - { bool ok = true; - typedef typename Vector::value_type Float; - Float eps = 10. * Float( std::numeric_limits::epsilon() ); - - // use expansion by minors to compute the derivative by hand - double check[9]; - check[0] = + ( x[4] * x[8] - x[5] * x[7] ); - check[1] = - ( x[3] * x[8] - x[5] * x[6] ); - check[2] = + ( x[3] * x[7] - x[4] * x[6] ); - // - check[3] = - ( x[1] * x[8] - x[2] * x[7] ); - check[4] = + ( x[0] * x[8] - x[2] * x[6] ); - check[5] = - ( x[0] * x[7] - x[1] * x[6] ); - // - check[6] = + ( x[1] * x[5] - x[2] * x[4] ); - check[7] = - ( x[0] * x[5] - x[2] * x[3] ); - check[8] = + ( x[0] * x[4] - x[1] * x[3] ); - // - for(size_t i = 0; i < 3 * 3; i++) - ok &= CppAD::NearEqual(check[i], g[i], eps, eps); - - return ok; - } -} -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/det_of_minor.hpp b/build-config/cppad/include/cppad/speed/det_of_minor.hpp deleted file mode 100644 index 10878142..00000000 --- a/build-config/cppad/include/cppad/speed/det_of_minor.hpp +++ /dev/null @@ -1,274 +0,0 @@ -# ifndef CPPAD_SPEED_DET_OF_MINOR_HPP -# define CPPAD_SPEED_DET_OF_MINOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin det_of_minor$$ -$spell - CppAD - hpp - std - Det - const - namespace - cppad -$$ - - -$section Determinant of a Minor$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%d% = det_of_minor(%a%, %m%, %n%, %r%, %c%)%$$ - - -$head Inclusion$$ -The template function $code det_of_minor$$ is defined in the $code CppAD$$ -namespace by including -the file $code cppad/speed/det_of_minor.hpp$$ -(relative to the CppAD distribution directory). - -$head Purpose$$ -This template function -returns the determinant of a minor of the matrix $latex A$$ -using expansion by minors. -The elements of the $latex n \times n$$ minor $latex M$$ -of the matrix $latex A$$ are defined, -for $latex i = 0 , \ldots , n-1$$ and $latex j = 0 , \ldots , n-1$$, by -$latex \[ - M_{i,j} = A_{R(i), C(j)} -\]$$ -where the functions -$latex R(i)$$ is defined by the $cref/argument r/det_of_minor/r/$$ and -$latex C(j)$$ is defined by the $cref/argument c/det_of_minor/c/$$. -$pre - -$$ -This template function -is for example and testing purposes only. -Expansion by minors is chosen as an example because it uses -a lot of floating point operations yet does not require much source code -(on the order of $icode m$$ factorial floating point operations and -about 70 lines of source code including comments). -This is not an efficient method for computing a determinant; -for example, using an LU factorization would be better. - -$head Determinant of A$$ -If the following conditions hold, the minor is the -entire matrix $latex A$$ and hence $code det_of_minor$$ -will return the determinant of $latex A$$: - -$list number$$ -$latex n = m$$. -$lnext -for $latex i = 0 , \ldots , m-1$$, $latex r[i] = i+1$$, -and $latex r[m] = 0$$. -$lnext -for $latex j = 0 , \ldots , m-1$$, $latex c[j] = j+1$$, -and $latex c[m] = 0$$. -$lend - -$head a$$ -The argument $icode a$$ has prototype -$codei% - const std::vector<%Scalar%>& %a% -%$$ -and is a vector with size $latex m * m$$ -(see description of $cref/Scalar/det_of_minor/Scalar/$$ below). -The elements of the $latex m \times m$$ matrix $latex A$$ are defined, -for $latex i = 0 , \ldots , m-1$$ and $latex j = 0 , \ldots , m-1$$, by -$latex \[ - A_{i,j} = a[ i * m + j] -\] $$ - -$head m$$ -The argument $icode m$$ has prototype -$codei% - size_t %m% -%$$ -and is the number of rows (and columns) in the square matrix $latex A$$. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ -and is the number of rows (and columns) in the square minor $latex M$$. - -$head r$$ -The argument $icode r$$ has prototype -$codei% - std::vector& %r% -%$$ -and is a vector with $latex m + 1$$ elements. -This vector defines the function $latex R(i)$$ -which specifies the rows of the minor $latex M$$. -To be specific, the function $latex R(i)$$ -for $latex i = 0, \ldots , n-1$$ is defined by -$latex \[ -\begin{array}{rcl} - R(0) & = & r[m] - \\ - R(i+1) & = & r[ R(i) ] -\end{array} -\] $$ -All the elements of $icode r$$ must have value -less than or equal $icode m$$. -The elements of vector $icode r$$ are modified during the computation, -and restored to their original value before the return from -$code det_of_minor$$. - -$head c$$ -The argument $icode c$$ has prototype -$codei% - std::vector& %c% -%$$ -and is a vector with $latex m + 1$$ elements -This vector defines the function $latex C(i)$$ -which specifies the rows of the minor $latex M$$. -To be specific, the function $latex C(i)$$ -for $latex j = 0, \ldots , n-1$$ is defined by -$latex \[ -\begin{array}{rcl} - C(0) & = & c[m] - \\ - C(j+1) & = & c[ C(j) ] -\end{array} -\] $$ -All the elements of $icode c$$ must have value -less than or equal $icode m$$. -The elements of vector $icode c$$ are modified during the computation, -and restored to their original value before the return from -$code det_of_minor$$. - -$head d$$ -The result $icode d$$ has prototype -$codei% - %Scalar% %d% -%$$ -and is equal to the determinant of the minor $latex M$$. - -$head Scalar$$ -If $icode x$$ and $icode y$$ are objects of type $icode Scalar$$ -and $icode i$$ is an object of type $code int$$, -the $icode Scalar$$ must support the following operations: -$table -$bold Syntax$$ - $cnext $bold Description$$ - $cnext $bold Result Type$$ -$rnext -$icode%Scalar% %x%$$ - $cnext default constructor for $icode Scalar$$ object. -$rnext -$icode%x% = %i%$$ - $cnext set value of $icode x$$ to current value of $icode i$$ -$rnext -$icode%x% = %y%$$ - $cnext set value of $icode x$$ to current value of $icode y$$ -$rnext -$icode%x% + %y%$$ - $cnext value of $icode x$$ plus $icode y$$ - $cnext $icode Scalar$$ -$rnext -$icode%x% - %y%$$ - $cnext value of $icode x$$ minus $icode y$$ - $cnext $icode Scalar$$ -$rnext -$icode%x% * %y%$$ - $cnext value of $icode x$$ times value of $icode y$$ - $cnext $icode Scalar$$ -$tend - -$children% - speed/example/det_of_minor.cpp% - omh/det_of_minor_hpp.omh -%$$ - -$head Example$$ -The file -$cref det_of_minor.cpp$$ -contains an example and test of $code det_of_minor.hpp$$. - -$head Source Code$$ -The file -$cref det_of_minor.hpp$$ -contains the source for this template function. - - -$end ---------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include - -namespace CppAD { // BEGIN CppAD namespace -template -Scalar det_of_minor( - const std::vector& a , - size_t m , - size_t n , - std::vector& r , - std::vector& c ) -{ - const size_t R0 = r[m]; // R(0) - size_t Cj = c[m]; // C(j) (case j = 0) - size_t Cj1 = m; // C(j-1) (case j = 0) - - // check for 1 by 1 case - if( n == 1 ) return a[ R0 * m + Cj ]; - - // initialize determinant of the minor M - Scalar detM = Scalar(0); - - // initialize sign of factor for next sub-minor - int s = 1; - - // remove row with index 0 in M from all the sub-minors of M - r[m] = r[R0]; - - // for each column of M - for(size_t j = 0; j < n; j++) - { // element with index (0,j) in the minor M - Scalar M0j = a[ R0 * m + Cj ]; - - // remove column with index j in M to form next sub-minor S of M - c[Cj1] = c[Cj]; - - // compute determinant of the current sub-minor S - Scalar detS = det_of_minor(a, m, n - 1, r, c); - - // restore column Cj to represenation of M as a minor of A - c[Cj1] = Cj; - - // include this sub-minor term in the summation - if( s > 0 ) - detM = detM + M0j * detS; - else - detM = detM - M0j * detS; - - // advance to next column of M - Cj1 = Cj; - Cj = c[Cj]; - s = - s; - } - - // restore row zero to the minor representation for M - r[m] = R0; - - // return the determinant of the minor M - return detM; -} -} // END CppAD namespace -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/mat_sum_sq.hpp b/build-config/cppad/include/cppad/speed/mat_sum_sq.hpp deleted file mode 100644 index 14a174d9..00000000 --- a/build-config/cppad/include/cppad/speed/mat_sum_sq.hpp +++ /dev/null @@ -1,152 +0,0 @@ -# ifndef CPPAD_SPEED_MAT_SUM_SQ_HPP -# define CPPAD_SPEED_MAT_SUM_SQ_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin mat_sum_sq$$ -$spell - sq - namespace - const - CppAD - sq - cppad - hpp -$$ - -$section Sum Elements of a Matrix Times Itself$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%mat_sum_sq(%n%, %x%, %y%, %z%)%$$ - -$head Purpose$$ -This routine is intended for use with the matrix multiply speed tests; -to be specific, it computes -$latex \[ -\begin{array}{rcl} - y_{i,j} & = & \sum_{k=0}^{n-1} x_{i,k} x_{k,j} - \\ - z_0 & = & \sum_{i=0}^{n-1} \sum_{j=0}^{n-1} y_{i,j} -\end{array} -\] $$ -see $cref link_mat_mul$$. - -$head Inclusion$$ -The template function $code mat_sum_sq$$ is defined in the $code CppAD$$ -namespace by including -the file $code cppad/speed/mat_sum_sq.hpp$$ -(relative to the CppAD distribution directory). - -$head n$$ -This argument has prototype -$codei% - size_t %n% -%$$ -It specifies the size of the matrices. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %Vector% &%x% -%$$ -and $icode%x%.size() == %n% * %n%$$. -It contains the elements of $latex x$$ in row major order; i.e., -$latex \[ - x_{i,j} = x [ i * n + j ] -\] $$ - -$head y$$ -The argument $icode y$$ has prototype -$codei% - %Vector%& %y% -%$$ -and $icode%y%.size() == %n% * %n%$$. -The input value of its elements does not matter. -Upon return, -$latex \[ -\begin{array}{rcl} - y_{i,j} & = & \sum_{k=0}^{n-1} x_{i,k} x_{k,j} - \\ - y[ i * n + j ] & = & y_{i,j} -\end{array} -\] $$ - - -$head z$$ -The argument $icode d$$ has prototype -$codei% - %Vector%& %z% -%$$. -The input value of its element does not matter. -Upon return -$latex \[ -\begin{array}{rcl} - z_0 & = & \sum_{i=0}^{n-1} \sum_{j=0}^n y_{i,j} - \\ - z[0] & = & z_0 -\end{array} -\] $$ - -$head Vector$$ -The type $icode Vector$$ is any -$cref SimpleVector$$, or it can be a raw pointer to the vector elements. -The element type must support -addition, multiplication, and assignment to both its own type -and to a double value. - -$children% - speed/example/mat_sum_sq.cpp% - omh/mat_sum_sq_hpp.omh -%$$ - - -$head Example$$ -The file -$cref mat_sum_sq.cpp$$ -contains an example and test of $code mat_sum_sq.hpp$$. - -$head Source Code$$ -The file -$cref mat_sum_sq.hpp$$ -contains the source for this template function. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -// -namespace CppAD { - template - void mat_sum_sq(size_t n, Vector& x , Vector& y , Vector& z) - { size_t i, j, k; - // Very simple computation of y = x * x for speed comparison - for(i = 0; i < n; i++) - { for(j = 0; j < n; j++) - { y[i * n + j] = 0.; - for(k = 0; k < n; k++) - y[i * n + j] += x[i * n + k] * x[k * n + j]; - } - } - z[0] = 0.; - for(i = 0; i < n; i++) - { for(j = 0; j < n; j++) - z[0] += y[i * n + j]; - } - return; - } - -} -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/ode_evaluate.hpp b/build-config/cppad/include/cppad/speed/ode_evaluate.hpp deleted file mode 100644 index 1d670212..00000000 --- a/build-config/cppad/include/cppad/speed/ode_evaluate.hpp +++ /dev/null @@ -1,236 +0,0 @@ -# ifndef CPPAD_SPEED_ODE_EVALUATE_HPP -# define CPPAD_SPEED_ODE_EVALUATE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin ode_evaluate$$ -$spell - Runge - fabs - retaped - Jacobian - const - Cpp - cppad - hpp - fp - namespace - exp -$$ - -$section Evaluate a Function Defined in Terms of an ODE$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%ode_evaluate(%x%, %p%, %fp%)%$$ - -$head Purpose$$ -This routine evaluates a function $latex f : \B{R}^n \rightarrow \B{R}^n$$ -defined by -$latex \[ - f(x) = y(x, 1) -\] $$ -where $latex y(x, t)$$ solves the ordinary differential equation -$latex \[ -\begin{array}{rcl} - y(x, 0) & = & x - \\ - \partial_t y (x, t ) & = & g[ y(x,t) , t ] -\end{array} -\] $$ -where $latex g : \B{R}^n \times \B{R} \rightarrow \B{R}^n$$ -is an unspecified function. - -$head Inclusion$$ -The template function $code ode_evaluate$$ -is defined in the $code CppAD$$ namespace by including -the file $code cppad/speed/ode_evaluate.hpp$$ -(relative to the CppAD distribution directory). - -$head Float$$ - -$subhead Operation Sequence$$ -The type $icode Float$$ must be a $cref NumericType$$. -The $icode Float$$ -$cref/operation sequence/glossary/Operation/Sequence/$$ -for this routine does not depend on the value of the argument $icode x$$, -hence it does not need to be retaped for each value of $latex x$$. - -$subhead fabs$$ -If $icode y$$ and $icode z$$ are $icode Float$$ objects, the syntax -$codei% - %y% = fabs(%z%) -%$$ -must be supported. Note that it does not matter if the operation -sequence for $code fabs$$ depends on $icode z$$ because the -corresponding results are not actually used by $code ode_evaluate$$; -see $code fabs$$ in $cref/Runge45/Runge45/Scalar/fabs/$$. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const CppAD::vector<%Float%>& %x% -%$$ -It contains he argument value for which the function, -or its derivative, is being evaluated. -The value $latex n$$ is determined by the size of the vector $icode x$$. - -$head p$$ -The argument $icode p$$ has prototype -$codei% - size_t %p% -%$$ - -$subhead p == 0$$ -In this case a numerical method is used to solve the ode -and obtain an accurate approximation for $latex y(x, 1)$$. -This numerical method has a fixed -that does not depend on $icode x$$. - -$subhead p = 1$$ -In this case an analytic solution for the partial derivative -$latex \partial_x y(x, 1)$$ is returned. - -$head fp$$ -The argument $icode fp$$ has prototype -$codei% - CppAD::vector<%Float%>& %fp% -%$$ -The input value of the elements of $icode fp$$ does not matter. - -$subhead Function$$ -If $icode p$$ is zero, $icode fp$$ has size equal to $latex n$$ -and contains the value of $latex y(x, 1)$$. - -$subhead Gradient$$ -If $icode p$$ is one, $icode fp$$ has size equal to $icode n^2$$ -and for $latex i = 0 , \ldots 1$$, $latex j = 0 , \ldots , n-1$$ -$latex \[ - \D{y[i]}{x[j]} (x, 1) = fp [ i \cdot n + j ] -\] $$ - -$children% - speed/example/ode_evaluate.cpp% - omh/ode_evaluate.omh -%$$ - -$head Example$$ -The file -$cref ode_evaluate.cpp$$ -contains an example and test of $code ode_evaluate.hpp$$. - - -$head Source Code$$ -The file -$cref ode_evaluate.hpp$$ -contains the source code for this template function. - -$end -*/ -// BEGIN C++ -# include -# include -# include - -namespace CppAD { - - template - class ode_evaluate_fun { - public: - // Given that y_i (0) = x_i, - // the following y_i (t) satisfy the ODE below: - // y_0 (t) = x[0] - // y_1 (t) = x[1] + x[0] * t - // y_2 (t) = x[2] + x[1] * t + x[0] * t^2/2 - // y_3 (t) = x[3] + x[2] * t + x[1] * t^2/2 + x[0] * t^3 / 3! - // ... - void Ode( - const Float& t, - const CppAD::vector& y, - CppAD::vector& f) - { size_t n = y.size(); - f[0] = 0.; - for(size_t k = 1; k < n; k++) - f[k] = y[k-1]; - } - }; - // - template - void ode_evaluate( - const CppAD::vector& x , - size_t p , - CppAD::vector& fp ) - { using CppAD::vector; - typedef vector FloatVector; - - size_t n = x.size(); - CPPAD_ASSERT_KNOWN( p == 0 || p == 1, - "ode_evaluate: p is not zero or one" - ); - CPPAD_ASSERT_KNOWN( - ((p==0) & (fp.size()==n)) || ((p==1) & (fp.size()==n*n)), - "ode_evaluate: the size of fp is not correct" - ); - if( p == 0 ) - { // function that defines the ode - ode_evaluate_fun F; - - // number of Runge45 steps to use - size_t M = 10; - - // initial and final time - Float ti = 0.0; - Float tf = 1.0; - - // initial value for y(x, t); i.e. y(x, 0) - // (is a reference to x) - const FloatVector& yi = x; - - // final value for y(x, t); i.e., y(x, 1) - // (is a reference to fp) - FloatVector& yf = fp; - - // Use fourth order Runge-Kutta to solve ODE - yf = CppAD::Runge45(F, M, ti, tf, yi); - - return; - } - /* Compute derivaitve of y(x, 1) w.r.t x - y_0 (x, t) = x[0] - y_1 (x, t) = x[1] + x[0] * t - y_2 (x, t) = x[2] + x[1] * t + x[0] * t^2/2 - y_3 (x, t) = x[3] + x[2] * t + x[1] * t^2/2 + x[0] * t^3 / 3! - ... - */ - size_t i, j, k; - for(i = 0; i < n; i++) - { for(j = 0; j < n; j++) - fp[ i * n + j ] = 0.0; - } - size_t factorial = 1; - for(k = 0; k < n; k++) - { if( k > 1 ) - factorial *= k; - for(i = k; i < n; i++) - { // partial w.r.t x[i-k] of x[i-k] * t^k / k! - j = i - k; - fp[ i * n + j ] += 1.0 / Float(factorial); - } - } - } -} -// END C++ - -# endif diff --git a/build-config/cppad/include/cppad/speed/sparse_hes_fun.hpp b/build-config/cppad/include/cppad/speed/sparse_hes_fun.hpp deleted file mode 100644 index bf40dbda..00000000 --- a/build-config/cppad/include/cppad/speed/sparse_hes_fun.hpp +++ /dev/null @@ -1,265 +0,0 @@ -# ifndef CPPAD_SPEED_SPARSE_HES_FUN_HPP -# define CPPAD_SPEED_SPARSE_HES_FUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin sparse_hes_fun$$ -$spell - hes - cppad - hpp - fp - CppAD - namespace - const - bool - exp - arg -$$ - -$section Evaluate a Function That Has a Sparse Hessian$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%sparse_hes_fun(%n%, %x%, %row%, %col%, %p%, %fp%)%$$ - -$head Purpose$$ -This routine evaluates -$latex f(x)$$, $latex f^{(1)} (x)$$, or $latex f^{(2)} (x)$$ -where the Hessian $latex f^{(2)} (x)$$ is sparse. -The function $latex f : \B{R}^n \rightarrow \B{R}$$ only depends on the -size and contents of the index vectors $icode row$$ and $icode col$$. -The non-zero entries in the Hessian of this function have -one of the following forms: -$latex \[ - \DD{f}{x[row[k]]}{x[row[k]]} - \; , \; - \DD{f}{x[row[k]]}{x[col[k]]} - \; , \; - \DD{f}{x[col[k]]}{x[row[k]]} - \; , \; - \DD{f}{x[col[k]]}{x[col[k]]} -\] $$ -for some $latex k $$ between zero and $latex K-1 $$. -All the other terms of the Hessian are zero. - -$head Inclusion$$ -The template function $code sparse_hes_fun$$ -is defined in the $code CppAD$$ namespace by including -the file $code cppad/speed/sparse_hes_fun.hpp$$ -(relative to the CppAD distribution directory). - -$head Float$$ -The type $icode Float$$ must be a $cref NumericType$$. -In addition, if $icode y$$ and $icode z$$ are $icode Float$$ objects, -$codei% - %y% = exp(%z%) -%$$ -must set the $icode y$$ equal the exponential of $icode z$$, i.e., -the derivative of $icode y$$ with respect to $icode z$$ is equal to $icode y$$. - -$head FloatVector$$ -The type $icode FloatVector$$ is any -$cref SimpleVector$$, or it can be a raw pointer, -with elements of type $icode Float$$. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ -It specifies the dimension for the domain space for $latex f(x)$$. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %FloatVector%& %x% -%$$ -It contains the argument value for which the function, -or its derivative, is being evaluated. -We use $latex n$$ to denote the size of the vector $icode x$$. - -$head row$$ -The argument $icode row$$ has prototype -$codei% - const CppAD::vector& %row% -%$$ -It specifies one of the first -index of $latex x$$ for each non-zero Hessian term -(see $cref/purpose/sparse_hes_fun/Purpose/$$ above). -All the elements of $icode row$$ must be between zero and $icode%n%-1%$$. -The value $latex K$$ is defined by $icode%K% = %row%.size()%$$. - -$head col$$ -The argument $icode col$$ has prototype -$codei% - const CppAD::vector& %col% -%$$ -and its size must be $latex K$$; i.e., the same as for $icode col$$. -It specifies the second -index of $latex x$$ for the non-zero Hessian terms. -All the elements of $icode col$$ must be between zero and $icode%n%-1%$$. -There are no duplicated entries requested, to be specific, -if $icode%k1% != %k2%$$ then -$codei% - ( %row%[%k1%] , %col%[%k1%] ) != ( %row%[%k2%] , %col%[%k2%] ) -%$$ - -$head p$$ -The argument $icode p$$ has prototype -$codei% - size_t %p% -%$$ -It is either zero or two and -specifies the order of the derivative of $latex f$$ -that is being evaluated, i.e., $latex f^{(p)} (x)$$ is evaluated. - -$head fp$$ -The argument $icode fp$$ has prototype -$codei% - %FloatVector%& %fp% -%$$ -The input value of the elements of $icode fp$$ does not matter. - -$subhead Function$$ -If $icode p$$ is zero, $icode fp$$ has size one and -$icode%fp%[0]%$$ is the value of $latex f(x)$$. - -$subhead Hessian$$ -If $icode p$$ is two, $icode fp$$ has size $icode K$$ and -for $latex k = 0 , \ldots , K-1$$, -$latex \[ - \DD{f}{ x[ \R{row}[k] ] }{ x[ \R{col}[k] ]} = fp [k] -\] $$ - -$children% - speed/example/sparse_hes_fun.cpp% - omh/sparse_hes_fun.omh -%$$ - -$head Example$$ -The file -$cref sparse_hes_fun.cpp$$ -contains an example and test of $code sparse_hes_fun.hpp$$. - -$head Source Code$$ -The file -$cref sparse_hes_fun.hpp$$ -contains the source code for this template function. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include -# include - -// following needed by gcc under fedora 17 so that exp(double) is defined -# include - -namespace CppAD { - template - void sparse_hes_fun( - size_t n , - const FloatVector& x , - const CppAD::vector& row , - const CppAD::vector& col , - size_t p , - FloatVector& fp ) - { - // check numeric type specifications - CheckNumericType(); - - // check value of p - CPPAD_ASSERT_KNOWN( - p == 0 || p == 2, - "sparse_hes_fun: p != 0 and p != 2" - ); - - size_t K = row.size(); - size_t i, j, k; - if( p == 0 ) - fp[0] = Float(0); - else - { for(k = 0; k < K; k++) - fp[k] = Float(0); - } - - // determine which diagonal entries are present in row[k], col[k] - CppAD::vector diagonal(n); - for(i = 0; i < n; i++) - diagonal[i] = K; // no diagonal entry for this row - for(k = 0; k < K; k++) - { if( row[k] == col[k] ) - { CPPAD_ASSERT_UNKNOWN( diagonal[row[k]] == K ); - // index of the diagonal entry - diagonal[ row[k] ] = k; - } - } - - // determine which entries must be multiplied by a factor of two - CppAD::vector factor(K); - for(k = 0; k < K; k++) - { factor[k] = Float(1); - for(size_t k1 = 0; k1 < K; k1++) - { bool reflected = true; - reflected &= k != k1; - reflected &= row[k] != col[k]; - reflected &= row[k] == col[k1]; - reflected &= col[k] == row[k1]; - if( reflected ) - factor[k] = Float(2); - } - } - - Float t; - for(k = 0; k < K; k++) - { i = row[k]; - j = col[k]; - t = exp( x[i] * x[j] ); - switch(p) - { - case 0: - fp[0] += t; - break; - - case 2: - if( i == j ) - { // second partial of t w.r.t. x[i], x[i] - fp[k] += ( Float(2) + Float(4) * x[i] * x[i] ) * t; - } - else // (i != j) - { // - // second partial of t w.r.t x[i], x[j] - fp[k] += factor[k] * ( Float(1) + x[i] * x[j] ) * t; - if( diagonal[i] != K ) - { // second partial of t w.r.t x[i], x[i] - size_t ki = diagonal[i]; - fp[ki] += x[j] * x[j] * t; - } - if( diagonal[j] != K ) - { // second partial of t w.r.t x[j], x[j] - size_t kj = diagonal[j]; - fp[kj] += x[i] * x[i] * t; - } - } - break; - } - } - - } -} -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/sparse_jac_fun.hpp b/build-config/cppad/include/cppad/speed/sparse_jac_fun.hpp deleted file mode 100644 index f1f6e84b..00000000 --- a/build-config/cppad/include/cppad/speed/sparse_jac_fun.hpp +++ /dev/null @@ -1,219 +0,0 @@ -# ifndef CPPAD_SPEED_SPARSE_JAC_FUN_HPP -# define CPPAD_SPEED_SPARSE_JAC_FUN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin sparse_jac_fun$$ -$spell - Jacobian - jac - cppad - hpp - fp - CppAD - namespace - const - bool - exp - arg -$$ - -$section Evaluate a Function That Has a Sparse Jacobian$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%sparse_jac_fun(%m%, %n%, %x%, %row%, %col%, %p%, %fp%)%$$ - -$head Purpose$$ -This routine evaluates -$latex f(x)$$ and $latex f^{(1)} (x)$$ -where the Jacobian $latex f^{(1)} (x)$$ is sparse. -The function $latex f : \B{R}^n \rightarrow \B{R}^m$$ only depends on the -size and contents of the index vectors $icode row$$ and $icode col$$. -The non-zero entries in the Jacobian of this function have -one of the following forms: -$latex \[ - \D{ f[row[k]]}{x[col[k]]} -\] $$ -for some $latex k $$ between zero and $latex K-1$$. -All the other terms of the Jacobian are zero. - -$head Inclusion$$ -The template function $code sparse_jac_fun$$ -is defined in the $code CppAD$$ namespace by including -the file $code cppad/speed/sparse_jac_fun.hpp$$ -(relative to the CppAD distribution directory). - -$head Float$$ -The type $icode Float$$ must be a $cref NumericType$$. -In addition, if $icode y$$ and $icode z$$ are $icode Float$$ objects, -$codei% - %y% = exp(%z%) -%$$ -must set the $icode y$$ equal the exponential of $icode z$$, i.e., -the derivative of $icode y$$ with respect to $icode z$$ is equal to $icode y$$. - -$head FloatVector$$ -The type $icode FloatVector$$ is any -$cref SimpleVector$$, or it can be a raw pointer, -with elements of type $icode Float$$. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ -It specifies the dimension for the domain space for $latex f(x)$$. - -$head m$$ -The argument $icode m$$ has prototype -$codei% - size_t %m% -%$$ -It specifies the dimension for the range space for $latex f(x)$$. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %FloatVector%& %x% -%$$ -It contains the argument value for which the function, -or its derivative, is being evaluated. -We use $latex n$$ to denote the size of the vector $icode x$$. - -$head row$$ -The argument $icode row$$ has prototype -$codei% - const CppAD::vector& %row% -%$$ -It specifies indices in the range of $latex f(x)$$ for non-zero components -of the Jacobian -(see $cref/purpose/sparse_hes_fun/Purpose/$$ above). -The value $latex K$$ is defined by $icode%K% = %row%.size()%$$. -All the elements of $icode row$$ must be between zero and $icode%m%-1%$$. - -$head col$$ -The argument $icode col$$ has prototype -$codei% - const CppAD::vector& %col% -%$$ -and its size must be $latex K$$; i.e., the same as $icode row$$. -It specifies the component of $latex x$$ for -the non-zero Jacobian terms. -All the elements of $icode col$$ must be between zero and $icode%n%-1%$$. - -$head p$$ -The argument $icode p$$ has prototype -$codei% - size_t %p% -%$$ -It is either zero or one and -specifies the order of the derivative of $latex f$$ -that is being evaluated, i.e., $latex f^{(p)} (x)$$ is evaluated. - -$head fp$$ -The argument $icode fp$$ has prototype -$codei% - %FloatVector%& %fp% -%$$ -If $icode%p% = 0%$$, it size is $icode m$$ -otherwise its size is $icode K$$. -The input value of the elements of $icode fp$$ does not matter. - -$subhead Function$$ -If $icode p$$ is zero, $icode fp$$ has size $latex m$$ and -$codei%(%fp%[0]%, ... , %fp%[%m%-1])%$$ is the value of $latex f(x)$$. - -$subhead Jacobian$$ -If $icode p$$ is one, $icode fp$$ has size $icode K$$ and -for $latex k = 0 , \ldots , K-1$$, -$latex \[ - \D{f[ \R{row}[i] ]}{x[ \R{col}[j] ]} = fp [k] -\] $$ - -$children% - speed/example/sparse_jac_fun.cpp% - omh/sparse_jac_fun.omh -%$$ - -$head Example$$ -The file -$cref sparse_jac_fun.cpp$$ -contains an example and test of $code sparse_jac_fun.hpp$$. - -$head Source Code$$ -The file -$cref sparse_jac_fun.hpp$$ -contains the source code for this template function. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include -# include - -// following needed by gcc under fedora 17 so that exp(double) is defined -# include - -namespace CppAD { - template - void sparse_jac_fun( - size_t m , - size_t n , - const FloatVector& x , - const CppAD::vector& row , - const CppAD::vector& col , - size_t p , - FloatVector& fp ) - { - // check numeric type specifications - CheckNumericType(); - // check value of p - CPPAD_ASSERT_KNOWN( - p == 0 || p == 1, - "sparse_jac_fun: p != 0 and p != 1" - ); - size_t K = row.size(); - CPPAD_ASSERT_KNOWN( - K >= m, - "sparse_jac_fun: row.size() < m" - ); - size_t i, j, k; - - if( p == 0 ) - for(i = 0; i < m; i++) - fp[i] = Float(0); - - Float t; - for(k = 0; k < K; k++) - { i = row[k]; - j = col[k]; - t = exp( x[j] * x[j] / 2.0 ); - switch(p) - { - case 0: - fp[i] += t; - break; - - case 1: - fp[k] = t * x[j]; - break; - } - } - } -} -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/speed/uniform_01.hpp b/build-config/cppad/include/cppad/speed/uniform_01.hpp deleted file mode 100644 index 1ea4b1ce..00000000 --- a/build-config/cppad/include/cppad/speed/uniform_01.hpp +++ /dev/null @@ -1,103 +0,0 @@ -# ifndef CPPAD_SPEED_UNIFORM_01_HPP -# define CPPAD_SPEED_UNIFORM_01_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin uniform_01$$ -$spell - CppAD - namespace - cppad - hpp -$$ - -$section Simulate a [0,1] Uniform Random Variate$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%uniform_01(%seed%) -%$$ -$codei%uniform_01(%n%, %x%)%$$ - -$head Purpose$$ -This routine is used to create random values for speed testing purposes. - -$head Inclusion$$ -The template function $code uniform_01$$ is defined in the $code CppAD$$ -namespace by including -the file $code cppad/speed/uniform_01.hpp$$ -(relative to the CppAD distribution directory). - -$head seed$$ -The argument $icode seed$$ has prototype -$codei% - size_t %seed% -%$$ -It specifies a seed -for the uniform random number generator. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ -It specifies the number of elements in the random vector $icode x$$. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - %Vector% &%x% -%$$. -The input value of the elements of $icode x$$ does not matter. -Upon return, the elements of $icode x$$ are set to values -randomly sampled over the interval [0,1]. - -$head Vector$$ -If $icode y$$ is a $code double$$ value, -the object $icode x$$ must support the syntax -$codei% - %x%[%i%] = %y% -%$$ -where $icode i$$ has type $code size_t$$ with value less than -or equal $latex n-1$$. -This is the only requirement of the type $icode Vector$$. - -$children% - omh/uniform_01_hpp.omh -%$$ - -$head Source Code$$ -The file -$cref uniform_01.hpp$$ -constraints the source code for this template function. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include - -namespace CppAD { - inline void uniform_01(size_t seed) - { std::srand( (unsigned int) seed); } - - template - void uniform_01(size_t n, Vector &x) - { static double factor = 1. / double(RAND_MAX); - while(n--) - x[n] = std::rand() * factor; - } -} -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/utility.hpp b/build-config/cppad/include/cppad/utility.hpp deleted file mode 100644 index 01c96a15..00000000 --- a/build-config/cppad/include/cppad/utility.hpp +++ /dev/null @@ -1,52 +0,0 @@ -# ifndef CPPAD_UTILITY_HPP -# define CPPAD_UTILITY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -// BEGIN_SORT_THIS_LINE_PLUS_1 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -// END_SORT_THIS_LINE_MINUS_1 - -# if CPPAD_HAS_EIGEN -# include -# endif - -# endif diff --git a/build-config/cppad/include/cppad/utility/check_numeric_type.hpp b/build-config/cppad/include/cppad/utility/check_numeric_type.hpp deleted file mode 100644 index 32488771..00000000 --- a/build-config/cppad/include/cppad/utility/check_numeric_type.hpp +++ /dev/null @@ -1,174 +0,0 @@ -# ifndef CPPAD_UTILITY_CHECK_NUMERIC_TYPE_HPP -# define CPPAD_UTILITY_CHECK_NUMERIC_TYPE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin CheckNumericType$$ -$spell - alloc - cppad.hpp - CppAD -$$ - -$section Check NumericType Class Concept$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%CheckNumericType<%NumericType%>()%$$ - - -$head Purpose$$ -The syntax -$codei% - CheckNumericType<%NumericType%>() -%$$ -preforms compile and run time checks that the type specified -by $icode NumericType$$ satisfies all the requirements for -a $cref NumericType$$ class. -If a requirement is not satisfied, -a an error message makes it clear what condition is not satisfied. - -$head Include$$ -The file $code cppad/utility/check_numeric_type.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest -if the CppAD include files. - -$head Parallel Mode$$ -The routine $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$ -must be called before it -can be used in $cref/parallel/ta_in_parallel/$$ mode. - -$head Example$$ -$children% - example/utility/check_numeric_type.cpp -%$$ -The file $cref check_numeric_type.cpp$$ -contains an example and test of this function. -The comments in this example suggest a way to change the example -so an error message occurs. - -$end ---------------------------------------------------------------------------- -*/ - -# include -# include - -namespace CppAD { - -# ifdef NDEBUG - template - void CheckNumericType(void) - { } -# else - template - NumericType CheckNumericType(void) - { // Section 3.6.2 of ISO/IEC 14882:1998(E) states: "The storage for - // objects with static storage duration (3.7.1) shall be zero- - // initialized (8.5) before any other initialization takes place." - static size_t count[CPPAD_MAX_NUM_THREADS]; - size_t thread = thread_alloc::thread_num(); - if( count[thread] > 0 ) - return NumericType(0); - count[thread]++; - /* - contructors - */ - NumericType check_NumericType_default_constructor; - NumericType check_NumericType_constructor_from_int(1); - - const NumericType x(1); - - NumericType check_NumericType_copy_constructor(x); - - // assignment - NumericType check_NumericType_assignment; - check_NumericType_assignment = x; - - /* - unary operators - */ - const NumericType check_NumericType_unary_plus(1); - NumericType check_NumericType_unary_plus_result = - + check_NumericType_unary_plus; - - const NumericType check_NumericType_unary_minus(1); - NumericType check_NumericType_unary_minus_result = - - check_NumericType_unary_minus; - - /* - binary operators - */ - const NumericType check_NumericType_binary_addition(1); - NumericType check_NumericType_binary_addition_result = - check_NumericType_binary_addition + x; - - const NumericType check_NumericType_binary_subtraction(1); - NumericType check_NumericType_binary_subtraction_result = - check_NumericType_binary_subtraction - x; - - const NumericType check_NumericType_binary_multiplication(1); - NumericType check_NumericType_binary_multiplication_result = - check_NumericType_binary_multiplication * x; - - const NumericType check_NumericType_binary_division(1); - NumericType check_NumericType_binary_division_result = - check_NumericType_binary_division / x; - - /* - compound assignment operators - */ - NumericType - check_NumericType_computed_assignment_addition(1); - check_NumericType_computed_assignment_addition += x; - - NumericType - check_NumericType_computed_assignment_subtraction(1); - check_NumericType_computed_assignment_subtraction -= x; - - NumericType - check_NumericType_computed_assignment_multiplication(1); - check_NumericType_computed_assignment_multiplication *= x; - - NumericType - check_NumericType_computed_assignment_division(1); - check_NumericType_computed_assignment_division /= x; - - /* - use all values so as to avoid warnings - */ - check_NumericType_default_constructor = x; - return - + check_NumericType_default_constructor - + check_NumericType_constructor_from_int - + check_NumericType_copy_constructor - + check_NumericType_assignment - + check_NumericType_unary_plus_result - + check_NumericType_unary_minus_result - + check_NumericType_binary_addition_result - + check_NumericType_binary_subtraction_result - + check_NumericType_binary_multiplication_result - + check_NumericType_binary_division_result - + check_NumericType_computed_assignment_addition - + check_NumericType_computed_assignment_subtraction - + check_NumericType_computed_assignment_multiplication - + check_NumericType_computed_assignment_division - ; - } -# endif - -} // end namespace CppAD - -# endif diff --git a/build-config/cppad/include/cppad/utility/check_simple_vector.hpp b/build-config/cppad/include/cppad/utility/check_simple_vector.hpp deleted file mode 100644 index 638ada3e..00000000 --- a/build-config/cppad/include/cppad/utility/check_simple_vector.hpp +++ /dev/null @@ -1,199 +0,0 @@ -# ifndef CPPAD_UTILITY_CHECK_SIMPLE_VECTOR_HPP -# define CPPAD_UTILITY_CHECK_SIMPLE_VECTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin CheckSimpleVector$$ -$spell - alloc - const - cppad.hpp - CppAD -$$ - -$section Check Simple Vector Concept$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%CheckSimpleVector<%Scalar%, %Vector%>()%$$ -$pre -$$ -$codei%CheckSimpleVector<%Scalar%, %Vector%>(%x%, %y%)%$$ - - -$head Purpose$$ -Preforms compile and run time checks that the type specified -by $icode Vector$$ satisfies all the requirements for -a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$icode Scalar$$. -If a requirement is not satisfied, -a an error message makes it clear what condition is not satisfied. - -$head x, y$$ -If the arguments $icode x$$ and $icode y$$ are present, -they have prototype -$codei% - const %Scalar%& %x% - const %Scalar%& %y% -%$$ -In addition, the check -$codei% - %x% == %x% -%$$ -will return the boolean value $code true$$, and -$codei% - %x% == %y% -%$$ -will return $code false$$. - -$head Restrictions$$ -If the arguments $icode x$$ and $icode y$$ are not present, -the following extra assumption is made by $code CheckSimpleVector$$: -If $icode x$$ is a $icode Scalar$$ object -$codei% - %x% = 0 - %y% = 1 -%$$ -assigns values to the objects $icode x$$ and $icode y$$. -In addition, -$icode%x% == %x%$$ would return the boolean value $code true$$ and -$icode%x% == %y%$$ would return $code false$$. - -$head Include$$ -The file $code cppad/utility/check_simple_vector.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest -if the CppAD include files. - -$head Parallel Mode$$ -The routine $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$ -must be called before it -can be used in $cref/parallel/ta_in_parallel/$$ mode. - -$head Example$$ -$children% - example/utility/check_simple_vector.cpp -%$$ -The file $cref check_simple_vector.cpp$$ -contains an example and test of this function where $icode S$$ -is the same as $icode T$$. -The comments in this example suggest a way to change the example -so $icode S$$ is not the same as $icode T$$. - -$end ---------------------------------------------------------------------------- -*/ - -# include -# include -# include -# include - -namespace CppAD { - -# ifdef NDEBUG - template - inline void CheckSimpleVector(const Scalar& x, const Scalar& y) - { } - template - inline void CheckSimpleVector(void) - { } -# else - template - struct ok_if_S_same_as_T { }; - - template - struct ok_if_S_same_as_T { T value; }; - - template - void CheckSimpleVector(const Scalar& x, const Scalar& y) - { CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL - static size_t count; - if( count > 0 ) - return; - count++; - - // value_type must be type of elements of Vector - typedef typename Vector::value_type value_type; - - // check that elements of Vector have type Scalar - struct ok_if_S_same_as_T x_copy; - x_copy.value = x; - - // check default constructor - Vector d; - - // size member function - CPPAD_ASSERT_KNOWN( - d.size() == 0, - "default construtor result does not have size zero" - ); - - // resize to same size as other vectors in test - d.resize(1); - - // check sizing constructor - Vector s(1); - - // check element assignment - s[0] = y; - CPPAD_ASSERT_KNOWN( - s[0] == y, - "element assignment failed" - ); - - // check copy constructor - s[0] = x_copy.value; - const Vector c(s); - s[0] = y; - CPPAD_ASSERT_KNOWN( - c[0] == x, - "copy constructor is shallow" - ); - - // vector assignment operator - d[0] = x; - s = d; - s[0] = y; - CPPAD_ASSERT_KNOWN( - d[0] == x, - "assignment operator is shallow" - ); - - // element access, right side const - // element assignment, left side not const - d[0] = c[0]; - CPPAD_ASSERT_KNOWN( - d[0] == x, - "element assignment from const failed" - ); - } - template - void CheckSimpleVector(void) - { Scalar x; - Scalar y; - - // use assignment and not constructor - x = 0; - y = 1; - - CheckSimpleVector(x, y); - } - -# endif - -} // end namespace CppAD - -# endif diff --git a/build-config/cppad/include/cppad/utility/elapsed_seconds.hpp b/build-config/cppad/include/cppad/utility/elapsed_seconds.hpp deleted file mode 100644 index 4e689014..00000000 --- a/build-config/cppad/include/cppad/utility/elapsed_seconds.hpp +++ /dev/null @@ -1,121 +0,0 @@ -# ifndef CPPAD_UTILITY_ELAPSED_SECONDS_HPP -# define CPPAD_UTILITY_ELAPSED_SECONDS_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin elapsed_seconds$$ -$spell - cppad.hpp - Microsoft - gettimeofday - std - chrono -$$ - -$section Returns Elapsed Number of Seconds$$ - - -$head Syntax$$ -$codei%# include -%$$ -$icode%s% = elapsed_seconds()%$$ - -$head Purpose$$ -This routine is accurate to within .02 seconds -(see $cref elapsed_seconds.cpp$$). -It does not necessary work for time intervals that are greater than a day. -$list number$$ -If the C++11 $code std::chrono::steady_clock$$ is available, -it will be used for timing. -$lnext -Otherwise, if running under the Microsoft compiler, -$code ::GetSystemTime$$ will be used for timing. -$lnext -Otherwise, if $code gettimeofday$$ is available, it is used for timing. -$lnext -Otherwise, $code std::clock()$$ will be used for timing. -$lend - -$head s$$ -is a $code double$$ equal to the -number of seconds since the first call to $code elapsed_seconds$$. - -$children% - speed/example/elapsed_seconds.cpp -%$$ -$head Example$$ -The routine $cref elapsed_seconds.cpp$$ is -an example and test of this routine. - - -$end ------------------------------------------------------------------------ -*/ - -// For some unknown reason under Fedora (which needs to be understood), -// if you move this include for cppad_assert.hpp below include for define.hpp, -// cd work/speed/example -// make test.sh -// fails with the error message 'gettimeofday' not defined. -# include - -// define nullptr -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -// c++11 time function -# include - - - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file elapsed_seconds.hpp -\brief Function that returns the elapsed seconds from first call. -*/ - -/*! -Returns the elapsed number since the first call to this function. - -This routine tries is accurate to within .02 seconds. -It does not necessary work for time intervals that are less than a day. -\li -If running under the Microsoft system, it uses ::%GetSystemTime for timing. -\li -Otherwise, if gettimeofday is available, it is used. -\li -Otherwise, std::clock() is used. - -\return -The number of seconds since the first call to elapsed_seconds. -*/ -inline double elapsed_seconds(void) -// -------------------------------------------------------------------------- -{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - static bool first_ = true; - static std::chrono::time_point start_; - if( first_ ) - { start_ = std::chrono::steady_clock::now(); - first_ = false; - return 0.0; - } - std::chrono::time_point now; - now = std::chrono::steady_clock::now(); - std::chrono::duration difference = now - start_; - return difference.count(); -} -// -------------------------------------------------------------------------- -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/utility/error_handler.hpp b/build-config/cppad/include/cppad/utility/error_handler.hpp deleted file mode 100644 index cc45afe4..00000000 --- a/build-config/cppad/include/cppad/utility/error_handler.hpp +++ /dev/null @@ -1,235 +0,0 @@ -# ifndef CPPAD_UTILITY_ERROR_HANDLER_HPP -# define CPPAD_UTILITY_ERROR_HANDLER_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin ErrorHandler$$ -$spell - cppad.hpp - CppAD - exp - bool - const -$$ - -$section Replacing the CppAD Error Handler$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%ErrorHandler %info%(%handler%) -%$$ -$codei%ErrorHandler::Call(%known%, %line%, %file%, %exp%, %msg%) -%$$ - -$head Constructor$$ -When you construct a $code ErrorHandler$$ object, -the current CppAD error handler is replaced by $icode handler$$. -When the object is destructed, the previous CppAD error handler is restored. - -$subhead Parallel Mode$$ -The $code ErrorHandler$$ constructor and destructor cannot be called in -$cref/parallel/ta_in_parallel/$$ execution mode. -If this rule is not abided by, a raw C++ $code assert$$, -instead of one that uses this error handler, will be generated. - -$head Call$$ -When $code ErrorHandler::Call$$ is called, -the current CppAD error handler is used to report an error. -This starts out as a default error handler and can be replaced -using the $code ErrorHandler$$ constructor. - -$head info$$ -The object $icode info$$ is used to store information -that is necessary to restore the previous CppAD error handler. -This restoration is done when the destructor for $icode info$$ is called. - - -$head handler$$ -The argument $icode handler$$ has prototype -$codei% - void (*%handler%) - (bool, int, const char *, const char *, const char *); -%$$ -When an error is detected, -it is called with the syntax -$codei% - %handler% (%known%, %line%, %file%, %exp%, %msg%) -%$$ -This routine should not return; i.e., upon detection of the error, -the routine calling $icode handler$$ does not know how to proceed. - -$head known$$ -The $icode handler$$ argument $icode known$$ has prototype -$codei% - bool %known% -%$$ -If it is true, the error being reported is from a know problem. - -$head line$$ -The $icode handler$$ argument $icode line$$ has prototype -$codei% - int %line% -%$$ -It reports the source code line number where the error is detected. - -$head file$$ -The $icode handler$$ argument $icode file$$ has prototype -$codei% - const char *%file% -%$$ -and is a $code '\0'$$ terminated character vector. -It reports the source code file where the error is detected. - -$head exp$$ -The $icode handler$$ argument $icode exp$$ has prototype -$codei% - const char *%exp% -%$$ -and is a $code '\0'$$ terminated character vector. -It is a source code boolean expression that should have been true, -but is false, -and thereby causes this call to $icode handler$$. - -$head msg$$ -The $icode handler$$ argument $icode msg$$ has prototype -$codei% - const char *%msg% -%$$ -and is a $code '\0'$$ terminated character vector. -It reports the meaning of the error from the C++ programmers point of view. - -$children% - example/utility/error_handler.cpp% - include/cppad/core/cppad_assert.hpp -%$$ -$head Example$$ -The file -$cref error_handler.cpp$$ -contains an example and test a test of using this routine. - -$end ---------------------------------------------------------------------------- -*/ - -# include - -# include -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -class ErrorHandler { - template - friend void parallel_ad(void); -public: - typedef void (*Handler) - (bool, int, const char *, const char *, const char *); - - // construct a new handler - ErrorHandler(Handler handler) : previous( Current() ) - { if( local::set_get_in_parallel(0) ) - { bool known = true; - int line = __LINE__; - const char* file = __FILE__; - const char* exp = "! local::set_get_in_parallel(0)"; - const char* msg = - "Using ErrorHandler constructor in parallel mode."; - Call(known, line, file, exp, msg); - } - Current() = handler; - } - - // destructor for an error handler - ~ErrorHandler(void) - { if( local::set_get_in_parallel(0) ) - { bool known = true; - int line = __LINE__; - const char* file = __FILE__; - const char* exp = "! local::set_get_in_parallel(0)"; - const char* msg = - "Using ErrorHandler destructor in parallel mode."; - Call(known, line, file, exp, msg); - } - Current() = previous; - } - - // report an error - static void Call( - bool known, - int line , - const char *file , - const char *exp , - const char *msg ) - { Handler handler = Current(); - handler(known, line, file, exp, msg); - } - -private: - const Handler previous; - - // The default error handler - static void Default( - bool known, - int line , - const char *file , - const char *exp , - const char *msg ) - { using std::cerr; - using std::endl; - - cerr << CPPAD_PACKAGE_STRING; - if( known ) - cerr << " error from a known source:" << endl; - else - cerr << " error from unknown source" << endl; - if( msg[0] != '\0' ) - cerr << msg << endl; - cerr << "Error detected by false result for" << endl; - cerr << " " << exp << endl; - cerr << "at line " << line << " in the file " << endl; - cerr << " " << file << endl; - - // terminate program execution - assert(false); - - // termination when NDEBUG is defined - std::exit(1); - } - - // current error handler - static Handler &Current(void) - { static bool first_call = true; - static Handler current = Default; - if( first_call ) - { if( local::set_get_in_parallel(0) ) - { bool known = false; - int line = __LINE__; - const char* file = __FILE__; - const char* exp = ""; - const char* msg = ""; - Call(known, line, file, exp, msg); - } - first_call = false; - } - return current; - } -}; - -} // END CppAD namespace - - - -# endif diff --git a/build-config/cppad/include/cppad/utility/index_sort.hpp b/build-config/cppad/include/cppad/utility/index_sort.hpp deleted file mode 100644 index 983d396d..00000000 --- a/build-config/cppad/include/cppad/utility/index_sort.hpp +++ /dev/null @@ -1,177 +0,0 @@ -# ifndef CPPAD_UTILITY_INDEX_SORT_HPP -# define CPPAD_UTILITY_INDEX_SORT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin index_sort$$ -$spell - cppad.hpp - ind - const -$$ - -$section Returns Indices that Sort a Vector$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%index_sort(%keys%, %ind%)%$$ - -$head keys$$ -The argument $icode keys$$ has prototype -$codei% - const %KeyVector%& %keys% -%$$ -where $icode KeyVector$$ is -a $cref SimpleVector$$ class with elements that support the $code <$$ -operation. - -$head ind$$ -The argument $icode ind$$ has prototype -$codei% - %SizeVector%& %ind% -%$$ -where $icode SizeVector$$ is -a $cref SimpleVector$$ class with elements of type $code size_t$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$subhead Input$$ -The size of $icode ind$$ must be the same as the size of $icode keys$$ -and the value of its input elements does not matter. - -$subhead Return$$ -Upon return, $icode ind$$ is a permutation of the set of indices -that yields increasing order for $icode keys$$. -In other words, for all $icode%i% != %j%$$, -$codei% - %ind%[%i%] != %ind%[%j%] -%$$ -and for $icode%i% = 0 , %...% , %size%-2%$$, -$codei% - ( %keys%[ %ind%[%i%+1] ] < %keys%[ %ind%[%i%] ] ) == false -%$$ - - -$head Example$$ -$children% - example/utility/index_sort.cpp -%$$ -The file $cref index_sort.cpp$$ contains an example -and test of this routine. -It return true if it succeeds and false otherwise. - -$end -*/ -# include -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file index_sort.hpp -File used to implement the CppAD index sort utility -*/ - -/*! -Helper class used by index_sort -*/ -template -class index_sort_element { -private: - /// key used to determine position of this element - Compare key_; - /// index vlaue corresponding to this key - size_t index_; -public: - /// operator requried by std::sort - bool operator<(const index_sort_element& other) const - { return key_ < other.key_; } - /// set the key for this element - void set_key(const Compare& value) - { key_ = value; } - /// set the index for this element - void set_index(const size_t& index) - { index_ = index; } - /// get the key for this element - Compare get_key(void) const - { return key_; } - /// get the index for this element - size_t get_index(void) const - { return index_; } -}; - -/*! -Compute the indices that sort a vector of keys - -\tparam KeyVector -Simple vector type that deterimene the sorting order by < operator -on its elements. - -\tparam SizeVector -Simple vector type with elements of size_t -that is used to return index values. - -\param keys [in] -values that determine the sorting order. - -\param ind [out] -must have the same size as keys. -The input value of its elements does not matter. -The output value of its elements satisfy -\code -( keys[ ind[i] ] < keys[ ind[i+1] ] ) == false -\endcode -*/ -template -void index_sort(const KeyVector& keys, SizeVector& ind) -{ typedef typename KeyVector::value_type Compare; - CheckSimpleVector(); - - typedef index_sort_element element; - - CPPAD_ASSERT_KNOWN( - size_t(keys.size()) == size_t(ind.size()), - "index_sort: vector sizes do not match" - ); - - size_t size_work = size_t(keys.size()); - size_t size_out; - element* work = - thread_alloc::create_array(size_work, size_out); - - // copy initial order into work - size_t i; - for(i = 0; i < size_work; i++) - { work[i].set_key( keys[i] ); - work[i].set_index( i ); - } - - // sort the work array - std::sort(work, work+size_work); - - // copy the indices to the output vector - for(i = 0; i < size_work; i++) - ind[i] = work[i].get_index(); - - // we are done with this work array - thread_alloc::delete_array(work); - - return; -} - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/utility/lu_factor.hpp b/build-config/cppad/include/cppad/utility/lu_factor.hpp deleted file mode 100644 index 2e6fd8fc..00000000 --- a/build-config/cppad/include/cppad/utility/lu_factor.hpp +++ /dev/null @@ -1,392 +0,0 @@ -# ifndef CPPAD_UTILITY_LU_FACTOR_HPP -# define CPPAD_UTILITY_LU_FACTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin LuFactor$$ -$spell - cppad.hpp - Cpp - Geq - Lu - bool - const - ip - jp - namespace - std - typename -$$ - - -$section LU Factorization of A Square Matrix$$ - -$pre -$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%sign% = LuFactor(%ip%, %jp%, %LU%)%$$ - - -$head Description$$ -Computes an LU factorization of the matrix $icode A$$ -where $icode A$$ is a square matrix. - -$head Include$$ -The file $code cppad/utility/lu_factor.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$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% - %FloatVector% &%LU% -%$$ -and the size of $icode LU$$ must equal $latex n * n$$ -(see description of $cref/FloatVector/LuFactor/FloatVector/$$ 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 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 FloatVector$$ -The type $icode FloatVector$$ must be a -$cref/simple vector class/SimpleVector/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Float$$ -This notation is used to denote the type corresponding -to the elements of a $icode FloatVector$$. -The type $icode Float$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, the following operations must be defined for any pair -of $icode Float$$ objects $icode x$$ and $icode y$$: - -$table -$bold Operation$$ $cnext $bold Description$$ $rnext -$codei%log(%x%)%$$ $cnext - returns the logarithm of $icode x$$ as a $icode Float$$ object -$tend - -$head AbsGeq$$ -Including the file $code lu_factor.hpp$$ defines the template function -$codei% - template - bool AbsGeq<%Float%>(const %Float% &%x%, const %Float% &%y%) -%$$ -in the $code CppAD$$ namespace. -This function returns true if the absolute value of -$icode x$$ is greater than or equal the absolute value of $icode y$$. -It is used by $code LuFactor$$ to choose the pivot elements. -This template function definition uses the operator -$code <=$$ to obtain the absolute value for $icode Float$$ objects. -If this operator is not defined for your use of $icode Float$$, -you will need to specialize this template so that it works for your -use of $code LuFactor$$. -$pre - -$$ -Complex numbers do not have the operation $code <=$$ defined. -The specializations -$codei% -bool AbsGeq< std::complex > - (const std::complex &%x%, const std::complex &%y%) -bool AbsGeq< std::complex > - (const std::complex &%x%, const std::complex &%y%) -%$$ -are define by including $code lu_factor.hpp$$ -These return true if the sum of the square of the real and imaginary parts -of $icode x$$ is greater than or equal the -sum of the square of the real and imaginary parts of $icode y$$. - -$children% - example/utility/lu_factor.cpp% - omh/lu_factor_hpp.omh -%$$ -$head Example$$ -The file -$cref lu_factor.cpp$$ -contains an example and test of using $code LuFactor$$ by itself. -$pre - -$$ -The file $cref lu_solve.hpp$$ provides a useful example usage of -$code LuFactor$$ with $code LuInvert$$. - -$head Source$$ -The file $cref lu_factor.hpp$$ contains the -current source code that implements these specifications. - -$end --------------------------------------------------------------------------- -*/ -// BEGIN C++ - -# include -# include - -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -// AbsGeq -template -bool AbsGeq(const Float &x, const Float &y) -{ Float xabs = x; - if( xabs <= Float(0) ) - xabs = - xabs; - Float yabs = y; - if( yabs <= Float(0) ) - yabs = - yabs; - return xabs >= yabs; -} -inline bool AbsGeq( - const std::complex &x, - const std::complex &y) -{ double xsq = x.real() * x.real() + x.imag() * x.imag(); - double ysq = y.real() * y.real() + y.imag() * y.imag(); - - return xsq >= ysq; -} -inline bool AbsGeq( - const std::complex &x, - const std::complex &y) -{ float xsq = x.real() * x.real() + x.imag() * x.imag(); - float ysq = y.real() * y.real() + y.imag() * y.imag(); - - return xsq >= ysq; -} - -// Lines that are different from code in cppad/core/lu_ratio.hpp end with // -template // -int LuFactor(SizeVector &ip, SizeVector &jp, FloatVector &LU) // -{ - // type of the elements of LU // - typedef typename FloatVector::value_type Float; // - - // check numeric type specifications - CheckNumericType(); - - // check simple vector class specifications - CheckSimpleVector(); - CheckSimpleVector(); - - 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 = 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; - // --------------------------------------------------------- - - // 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; - } - } - } - CPPAD_ASSERT_KNOWN( - (imax < n) & (jmax < n) , - "LuFactor can't determine an element with " - "maximum absolute value.\n" - "Perhaps original matrix contains not a number or infinity.\n" - "Perhaps your specialization of AbsGeq is not correct." - ); - 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 -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/utility/lu_invert.hpp b/build-config/cppad/include/cppad/utility/lu_invert.hpp deleted file mode 100644 index 746d5336..00000000 --- a/build-config/cppad/include/cppad/utility/lu_invert.hpp +++ /dev/null @@ -1,238 +0,0 @@ -# ifndef CPPAD_UTILITY_LU_INVERT_HPP -# define CPPAD_UTILITY_LU_INVERT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin LuInvert$$ -$spell - cppad.hpp - Lu - Cpp - jp - ip - const - namespace - typename - etmp -$$ - - -$section Invert an LU Factored Equation$$ - -$pre -$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%LuInvert(%ip%, %jp%, %LU%, %X%)%$$ - - -$head Description$$ -Solves the matrix equation $icode%A% * %X% = %B%$$ -using an LU factorization computed by $cref LuFactor$$. - -$head Include$$ -The file $code cppad/utility/lu_invert.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$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 ip$$ -The argument $icode ip$$ has prototype -$codei% - const %SizeVector% &%ip% -%$$ -(see description for $icode SizeVector$$ in -$cref/LuFactor/LuFactor/SizeVector/$$ specifications). -The size of $icode ip$$ is referred to as $icode n$$ in the -specifications below. -The elements of $icode ip$$ determine -the order of the rows in the permuted matrix. - -$head jp$$ -The argument $icode jp$$ has prototype -$codei% - const %SizeVector% &%jp% -%$$ -(see description for $icode SizeVector$$ in -$cref/LuFactor/LuFactor/SizeVector/$$ specifications). -The size of $icode jp$$ must be equal to $icode n$$. -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% - const %FloatVector% &%LU% -%$$ -and the size of $icode LU$$ must equal $latex n * n$$ -(see description for $icode FloatVector$$ in -$cref/LuFactor/LuFactor/FloatVector/$$ specifications). - -$subhead L$$ -We define the lower triangular matrix $icode L$$ in terms 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 $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 P$$ -We define the permuted matrix $icode P$$ in terms of -the matrix $icode L$$ and the matrix $icode U$$ -by $icode%P% = %L% * %U%$$. - -$subhead A$$ -The matrix $icode A$$, -which defines the linear equations that we are solving, is given by -$codei% - %P%(%i%, %j%) = %A%[ %ip%[%i%] * %n% + %jp%[%j%] ] -%$$ -(Hence -$icode LU$$ contains a permuted factorization of the matrix $icode A$$.) - - -$head X$$ -The argument $icode X$$ has prototype -$codei% - %FloatVector% &%X% -%$$ -(see description for $icode FloatVector$$ in -$cref/LuFactor/LuFactor/FloatVector/$$ specifications). -The matrix $icode X$$ -must have the same number of rows as the matrix $icode A$$. -The input value of $icode X$$ is the matrix $icode B$$ and the -output value solves the matrix equation $icode%A% * %X% = %B%$$. - - -$children% - example/utility/lu_invert.cpp% - omh/lu_invert_hpp.omh -%$$ -$head Example$$ -The file $cref lu_solve.hpp$$ is a good example usage of -$code LuFactor$$ with $code LuInvert$$. -The file -$cref lu_invert.cpp$$ -contains an example and test of using $code LuInvert$$ by itself. - -$head Source$$ -The file $cref lu_invert.hpp$$ contains the -current source code that implements these specifications. - -$end --------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -// LuInvert -template -void LuInvert( - const SizeVector &ip, - const SizeVector &jp, - const FloatVector &LU, - FloatVector &B ) -{ size_t k; // column index in X - size_t p; // index along diagonal in LU - size_t i; // row index in LU and X - - typedef typename FloatVector::value_type Float; - - // check numeric type specifications - CheckNumericType(); - - // check simple vector class specifications - CheckSimpleVector(); - CheckSimpleVector(); - - Float etmp; - - size_t n = ip.size(); - CPPAD_ASSERT_KNOWN( - size_t(jp.size()) == n, - "Error in LuInvert: jp must have size equal to n * n" - ); - CPPAD_ASSERT_KNOWN( - size_t(LU.size()) == n * n, - "Error in LuInvert: Lu must have size equal to n * m" - ); - size_t m = size_t(B.size()) / n; - CPPAD_ASSERT_KNOWN( - size_t(B.size()) == n * m, - "Error in LuSolve: B must have size equal to a multiple of n" - ); - - // temporary storage for reordered solution - FloatVector x(n); - - // loop over equations - for(k = 0; k < m; k++) - { // invert the equation c = L * b - for(p = 0; p < n; p++) - { // solve for c[p] - etmp = B[ ip[p] * m + k ] / LU[ ip[p] * n + jp[p] ]; - B[ ip[p] * m + k ] = etmp; - // subtract off effect on other variables - for(i = p+1; i < n; i++) - B[ ip[i] * m + k ] -= - etmp * LU[ ip[i] * n + jp[p] ]; - } - - // invert the equation x = U * c - p = n; - while( p > 0 ) - { --p; - etmp = B[ ip[p] * m + k ]; - x[ jp[p] ] = etmp; - for(i = 0; i < p; i++ ) - B[ ip[i] * m + k ] -= - etmp * LU[ ip[i] * n + jp[p] ]; - } - - // copy reordered solution into B - for(i = 0; i < n; i++) - B[i * m + k] = x[i]; - } - return; -} -} // END CppAD namespace -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/utility/lu_solve.hpp b/build-config/cppad/include/cppad/utility/lu_solve.hpp deleted file mode 100644 index 65ce3b45..00000000 --- a/build-config/cppad/include/cppad/utility/lu_solve.hpp +++ /dev/null @@ -1,345 +0,0 @@ -# ifndef CPPAD_UTILITY_LU_SOLVE_HPP -# define CPPAD_UTILITY_LU_SOLVE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin LuSolve$$ -$spell - cppad.hpp - det - exp - Leq - typename - bool - const - namespace - std - Geq - Lu - CppAD - signdet - logdet -$$ - - -$section Compute Determinant and Solve Linear Equations$$ - -$pre -$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%signdet% = LuSolve(%n%, %m%, %A%, %B%, %X%, %logdet%)%$$ - - -$head Description$$ -Use an LU factorization of the matrix $icode A$$ to -compute its determinant -and solve for $icode X$$ in the linear of equation -$latex \[ - A * X = B -\] $$ -where $icode A$$ is an -$icode n$$ by $icode n$$ matrix, -$icode X$$ is an -$icode n$$ by $icode m$$ matrix, and -$icode B$$ is an $latex n x m$$ matrix. - -$head Include$$ -The file $code cppad/utility/lu_solve.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head Factor and Invert$$ -This routine is an easy to user interface to -$cref LuFactor$$ and $cref LuInvert$$ for computing determinants and -solutions of linear equations. -These separate routines should be used if -one right hand side $icode B$$ -depends on the solution corresponding to another -right hand side (with the same value of $icode A$$). -In this case only one call to $code LuFactor$$ is required -but there will be multiple calls to $code LuInvert$$. - - -$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 signdet$$ -The return value $icode signdet$$ is a $code int$$ value -that specifies the sign factor for the determinant of $icode A$$. -This determinant of $icode A$$ is zero if and only if $icode signdet$$ -is zero. - -$head n$$ -The argument $icode n$$ has type $code size_t$$ -and specifies the number of rows in the matrices -$icode A$$, -$icode X$$, -and $icode B$$. -The number of columns in $icode A$$ is also equal to $icode n$$. - -$head m$$ -The argument $icode m$$ has type $code size_t$$ -and specifies the number of columns in the matrices -$icode X$$ -and $icode B$$. -If $icode m$$ is zero, -only the determinant of $icode A$$ is computed and -the matrices $icode X$$ and $icode B$$ are not used. - -$head A$$ -The argument $icode A$$ has the prototype -$codei% - const %FloatVector% &%A% -%$$ -and the size of $icode A$$ must equal $latex n * n$$ -(see description of $cref/FloatVector/LuSolve/FloatVector/$$ below). -This is the $latex n$$ by $icode n$$ matrix that -we are computing the determinant of -and that defines the linear equation. - -$head B$$ -The argument $icode B$$ has the prototype -$codei% - const %FloatVector% &%B% -%$$ -and the size of $icode B$$ must equal $latex n * m$$ -(see description of $cref/FloatVector/LuSolve/FloatVector/$$ below). -This is the $latex n$$ by $icode m$$ matrix that -defines the right hand side of the linear equations. -If $icode m$$ is zero, $icode B$$ is not used. - -$head X$$ -The argument $icode X$$ has the prototype -$codei% - %FloatVector% &%X% -%$$ -and the size of $icode X$$ must equal $latex n * m$$ -(see description of $cref/FloatVector/LuSolve/FloatVector/$$ below). -The input value of $icode X$$ does not matter. -On output, the elements of $icode X$$ contain the solution -of the equation we wish to solve -(unless $icode signdet$$ is equal to zero). -If $icode m$$ is zero, $icode X$$ is not used. - -$head logdet$$ -The argument $icode logdet$$ has prototype -$codei% - %Float% &%logdet% -%$$ -On input, the value of $icode logdet$$ does not matter. -On output, it has been set to the -log of the determinant of $icode A$$ -(but not quite). -To be more specific, -the determinant of $icode A$$ is given by the formula -$codei% - %det% = %signdet% * exp( %logdet% ) -%$$ -This enables $code LuSolve$$ to use logs of absolute values -in the case where $icode Float$$ corresponds to a real number. - -$head Float$$ -The type $icode Float$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, the following operations must be defined for any pair -of $icode Float$$ objects $icode x$$ and $icode y$$: - -$table -$bold Operation$$ $cnext $bold Description$$ $rnext -$codei%log(%x%)%$$ $cnext - returns the logarithm of $icode x$$ as a $icode Float$$ object -$tend - -$head FloatVector$$ -The type $icode FloatVector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type Float/SimpleVector/Elements of Specified Type/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head LeqZero$$ -Including the file $code lu_solve.hpp$$ defines the template function -$codei% - template - bool LeqZero<%Float%>(const %Float% &%x%) -%$$ -in the $code CppAD$$ namespace. -This function returns true if $icode x$$ is less than or equal to zero -and false otherwise. -It is used by $code LuSolve$$ to avoid taking the log of -zero (or a negative number if $icode Float$$ corresponds to real numbers). -This template function definition assumes that the operator -$code <=$$ is defined for $icode Float$$ objects. -If this operator is not defined for your use of $icode Float$$, -you will need to specialize this template so that it works for your -use of $code LuSolve$$. -$pre - -$$ -Complex numbers do not have the operation or $code <=$$ defined. -In addition, in the complex case, -one can take the log of a negative number. -The specializations -$codei% - bool LeqZero< std::complex > (const std::complex &%x%) - bool LeqZero< std::complex >(const std::complex &%x%) -%$$ -are defined by including $code lu_solve.hpp$$. -These return true if $icode x$$ is zero and false otherwise. - -$head AbsGeq$$ -Including the file $code lu_solve.hpp$$ defines the template function -$codei% - template - bool AbsGeq<%Float%>(const %Float% &%x%, const %Float% &%y%) -%$$ -If the type $icode Float$$ does not support the $code <=$$ operation -and it is not $code std::complex$$ or $code std::complex$$, -see the documentation for $code AbsGeq$$ in $cref/LuFactor/LuFactor/AbsGeq/$$. - -$children% - example/utility/lu_solve.cpp% - omh/lu_solve_hpp.omh -%$$ -$head Example$$ -The file -$cref lu_solve.cpp$$ -contains an example and test of using this routine. - -$head Source$$ -The file $cref lu_solve.hpp$$ contains the -current source code that implements these specifications. - -$end --------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include -# include - -// link exp for float and double cases -# include - -# include -# include -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -// LeqZero -template -bool LeqZero(const Float &x) -{ return x <= Float(0); } -inline bool LeqZero( const std::complex &x ) -{ return x == std::complex(0); } -inline bool LeqZero( const std::complex &x ) -{ return x == std::complex(0); } - -// LuSolve -template -int LuSolve( - size_t n , - size_t m , - const FloatVector &A , - const FloatVector &B , - FloatVector &X , - Float &logdet ) -{ - // check numeric type specifications - CheckNumericType(); - - // check simple vector class specifications - CheckSimpleVector(); - - size_t p; // index of pivot element (diagonal of L) - int signdet; // sign of the determinant - Float pivot; // pivot element - - // the value zero - const Float zero(0); - - // pivot row and column order in the matrix - std::vector ip(n); - std::vector jp(n); - - // ------------------------------------------------------- - CPPAD_ASSERT_KNOWN( - size_t(A.size()) == n * n, - "Error in LuSolve: A must have size equal to n * n" - ); - CPPAD_ASSERT_KNOWN( - size_t(B.size()) == n * m, - "Error in LuSolve: B must have size equal to n * m" - ); - CPPAD_ASSERT_KNOWN( - size_t(X.size()) == n * m, - "Error in LuSolve: X must have size equal to n * m" - ); - // ------------------------------------------------------- - - // copy A so that it does not change - FloatVector Lu(A); - - // copy B so that it does not change - X = B; - - // Lu factor the matrix A - signdet = LuFactor(ip, jp, Lu); - - // compute the log of the determinant - logdet = Float(0); - for(p = 0; p < n; p++) - { // 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 - logdet = Float(0); - return 0; - } - - // update the determinant - if( LeqZero ( pivot ) ) - { logdet += log( - pivot ); - signdet = - signdet; - } - else - logdet += log( pivot ); - - } - - // solve the linear equations - LuInvert(ip, jp, Lu, X); - - // return the sign factor for the determinant - return signdet; -} -} // END CppAD namespace -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/utility/memory_leak.hpp b/build-config/cppad/include/cppad/utility/memory_leak.hpp deleted file mode 100644 index be7d59a3..00000000 --- a/build-config/cppad/include/cppad/utility/memory_leak.hpp +++ /dev/null @@ -1,213 +0,0 @@ -# ifndef CPPAD_UTILITY_MEMORY_LEAK_HPP -# define CPPAD_UTILITY_MEMORY_LEAK_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin memory_leak$$ -$spell - cppad - num - alloc - hpp - bool - inuse -$$ - -$section Memory Leak Detection$$ - -$head Deprecated 2012-04-06$$ -This routine has been deprecated. -You should instead use the routine $cref ta_free_all$$. - -$head Syntax$$ -$codei%# include -%$$ -$icode%flag% = %memory_leak() -%$$ -$icode%flag% = %memory_leak%(%add_static%)%$$ - -$head Purpose$$ -This routine checks that the are no memory leaks -caused by improper use of $cref thread_alloc$$ memory allocator. -The deprecated memory allocator $cref TrackNewDel$$ is also checked. -Memory errors in the deprecated $cref omp_alloc$$ allocator are -reported as being in $code thread_alloc$$. - -$head thread$$ -It is assumed that $cref/in_parallel()/ta_in_parallel/$$ is false -and $cref/thread_num/ta_thread_num/$$ is zero when -$code memory_leak$$ is called. - -$head add_static$$ -This argument has prototype -$codei% - size_t %add_static% -%$$ -and its default value is zero. -Static variables hold onto memory forever. -If the argument $icode add_static$$ is present (and non-zero), -$code memory_leak$$ adds this amount of memory to the -$cref/inuse/ta_inuse/$$ sum that corresponds to -static variables in the program. -A call with $icode add_static$$ should be make after -a routine that has static variables which -use $cref/get_memory/ta_get_memory/$$ to allocate memory. -The value of $icode add_static$$ should be the difference of -$codei% - thread_alloc::inuse(0) -%$$ -before and after the call. -Since multiple statics may be allocated in different places in the program, -it is expected that there will be multiple calls -that use this option. - -$head flag$$ -The return value $icode flag$$ has prototype -$codei% - bool %flag% -%$$ -If $icode add_static$$ is non-zero, -the return value for $code memory_leak$$ is false. -Otherwise, the return value for $code memory_leak$$ should be false -(indicating that the only allocated memory corresponds to static variables). - -$head inuse$$ -It is assumed that, when $code memory_leak$$ is called, -there should not be any memory -$cref/inuse/ta_inuse/$$ or $cref omp_inuse$$ for any thread -(except for inuse memory corresponding to static variables). -If there is, a message is printed and $code memory_leak$$ returns false. - -$head available$$ -It is assumed that, when $code memory_leak$$ is called, -there should not be any memory -$cref/available/ta_available/$$ or $cref omp_available$$ for any thread; -i.e., it all has been returned to the system. -If there is memory still available for any thread, -$code memory_leak$$ returns false. - -$head TRACK_COUNT$$ -It is assumed that, when $code memory_leak$$ is called, -$cref/TrackCount/TrackNewDel/TrackCount/$$ will return a zero value. -If it returns a non-zero value, -$code memory_leak$$ returns false. - -$head Error Message$$ -If this is the first call to $code memory_leak$$, no message is printed. -Otherwise, if it returns true, an error message is printed -to standard output describing the memory leak that was detected. - -$end -*/ -# include -# include -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file memory_leak.hpp -File that implements a memory check at end of a CppAD program -*/ - -/*! -Function that checks -allocator thread_alloc for misuse that results in memory leaks. -Deprecated routines in track_new_del.hpp and omp_alloc.hpp are also checked. - -\param add_static [in] -The amount specified by add_static is added to the amount -of memory that is expected to be used by thread zero for static variables. - -\return -If add_static is non-zero, the return value is false. -Otherwise, if one of the following errors is detected, -the return value is true: - -\li -Thread zero does not have the expected amount of inuse memory -(for static variables). -\li -A thread, other than thread zero, has any inuse memory. -\li -Any thread has available memory. - -\par -If an error is detected, diagnostic information is printed to standard -output. -*/ -inline bool memory_leak(size_t add_static = 0) -{ // CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL not necessary given asserts below - static size_t thread_zero_static_inuse = 0; - using std::cout; - using std::endl; - using CppAD::thread_alloc; - using CppAD::omp_alloc; - // -------------------------------------------------------------------- - CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel(), - "memory_leak: in_parallel() is true." - ); - CPPAD_ASSERT_KNOWN( - thread_alloc::thread_num() == 0, - "memory_leak: thread_num() is not zero." - ); - if( add_static != 0 ) - { thread_zero_static_inuse += add_static; - return false; - } - bool leak = false; - size_t thread = 0; - - // check that memory in use for thread zero corresponds to statics - size_t num_bytes = thread_alloc::inuse(thread); - if( num_bytes != thread_zero_static_inuse ) - { leak = true; - cout << "thread zero: static inuse = " << thread_zero_static_inuse; - cout << ", current inuse(0)= " << num_bytes << endl; - } - // check that no memory is currently available for this thread - num_bytes = thread_alloc::available(thread); - if( num_bytes != 0 ) - { leak = true; - cout << "thread zero: available = "; - cout << num_bytes << endl; - } - for(thread = 1; thread < CPPAD_MAX_NUM_THREADS; thread++) - { - // check that no memory is currently in use for this thread - num_bytes = thread_alloc::inuse(thread); - if( num_bytes != 0 ) - { leak = true; - cout << "thread " << thread << ": inuse(thread) = "; - cout << num_bytes << endl; - } - // check that no memory is currently available for this thread - num_bytes = thread_alloc::available(thread); - if( num_bytes != 0 ) - { leak = true; - cout << "thread " << thread << ": available(thread) = "; - cout << num_bytes << endl; - } - } - // ---------------------------------------------------------------------- - // check track_new_del - if( CPPAD_TRACK_COUNT() != 0 ) - { leak = true; - CppAD::TrackElement::Print(); - } - return leak; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/utility/nan.hpp b/build-config/cppad/include/cppad/utility/nan.hpp deleted file mode 100644 index e0940ea3..00000000 --- a/build-config/cppad/include/cppad/utility/nan.hpp +++ /dev/null @@ -1,193 +0,0 @@ -# ifndef CPPAD_UTILITY_NAN_HPP -# define CPPAD_UTILITY_NAN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin nan$$ -$spell - hasnan - cppad - hpp - CppAD - isnan - bool - const -$$ - -$section Obtain Nan or Determine if a Value is Nan$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%b% = isnan(%s%) -%$$ -$icode%b% = hasnan(%v%)%$$ - -$head Purpose$$ -It obtain and check for the value not a number $code nan$$. -The IEEE standard specifies that a floating point value $icode a$$ -is $code nan$$ if and only if the following returns true -$codei% - %a% != %a% -%$$ - -$head Include$$ -The file $code cppad/utility/nan.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$subhead Macros$$ -Some C++ compilers use preprocessor symbols called $code nan$$ -and $code isnan$$. -These preprocessor symbols will no longer be defined after -this file is included. - -$head isnan$$ -This routine determines if a scalar value is $code nan$$. - -$subhead s$$ -The argument $icode s$$ has prototype -$codei% - const %Scalar% %s% -%$$ - -$subhead b$$ -The return value $icode b$$ has prototype -$codei% - bool %b% -%$$ -It is true if the value $icode s$$ is $code nan$$. - -$head hasnan$$ -This routine determines if a -$cref SimpleVector$$ has an element that is $code nan$$. - -$subhead v$$ -The argument $icode v$$ has prototype -$codei% - const %Vector% &%v% -%$$ -(see $cref/Vector/nan/Vector/$$ for the definition of $icode Vector$$). - -$subhead b$$ -The return value $icode b$$ has prototype -$codei% - bool %b% -%$$ -It is true if the vector $icode v$$ has a $code nan$$. - - -$head nan(zero)$$ - -$subhead Deprecated 2015-10-04$$ -This routine has been deprecated, use CppAD numeric limits -$cref/quiet_NaN/numeric_limits/quiet_NaN/$$ in its place. - -$subhead Syntax$$ -$icode%s% = nan(%z%) -%$$ - -$subhead z$$ -The argument $icode z$$ has prototype -$codei% - const %Scalar% &%z% -%$$ -and its value is zero -(see $cref/Scalar/nan/Scalar/$$ for the definition of $icode Scalar$$). - -$subhead s$$ -The return value $icode s$$ has prototype -$codei% - %Scalar% %s% -%$$ -It is the value $code nan$$ for this floating point type. - -$head Scalar$$ -The type $icode Scalar$$ must support the following operations; -$table -$bold Operation$$ $cnext $bold Description$$ $rnext -$icode%a% / %b%$$ $cnext - division operator (returns a $icode Scalar$$ object) -$rnext -$icode%a% == %b%$$ $cnext - equality operator (returns a $code bool$$ object) -$rnext -$icode%a% != %b%$$ $cnext - not equality operator (returns a $code bool$$ object) -$tend -Note that the division operator will be used with $icode a$$ and $icode b$$ -equal to zero. For some types (e.g. $code int$$) this may generate -an exception. No attempt is made to catch any such exception. - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -elements of type $icode Scalar$$. - -$children% - example/utility/nan.cpp -%$$ -$head Example$$ -The file $cref nan.cpp$$ -contains an example and test of this routine. - -$end -*/ - -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -/* -# define nan There must be a define for every CppAD undef -*/ -# ifdef nan -# undef nan -# endif - -/* -# define isnan There must be a define for every CppAD undef -*/ -# ifdef isnan -# undef isnan -# endif - -namespace CppAD { // BEGIN CppAD namespace - -template -bool isnan(const Scalar &s) -{ return (s != s); -} - -template -bool hasnan(const Vector &v) -{ - bool found_nan; - size_t i; - i = v.size(); - found_nan = false; - // on MS Visual Studio 2012, CppAD required in front of isnan ? - while(i--) - found_nan |= CppAD::isnan(v[i]); - return found_nan; -} - -template -Scalar nan(const Scalar &zero) -{ return zero / zero; -} - -} // End CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/near_equal.hpp b/build-config/cppad/include/cppad/utility/near_equal.hpp deleted file mode 100644 index b9ecca72..00000000 --- a/build-config/cppad/include/cppad/utility/near_equal.hpp +++ /dev/null @@ -1,271 +0,0 @@ -# ifndef CPPAD_UTILITY_NEAR_EQUAL_HPP -# define CPPAD_UTILITY_NEAR_EQUAL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin NearEqual$$ -$spell - cppad.hpp - sqrt - cout - endl - Microsoft - std - Cpp - namespace - const - bool -$$ - -$section Determine if Two Values Are Nearly Equal$$ - - -$head Syntax$$ - -$codei%# include -%$$ -$icode%b% = NearEqual(%x%, %y%, %r%, %a%)%$$ - - -$head Purpose$$ -Returns true, -if $icode x$$ and $icode y$$ are nearly equal, -and false otherwise. - -$head x$$ -The argument $icode x$$ -has one of the following possible prototypes -$codei% - const %Type% &%x%, - const std::complex<%Type%> &%x%, -%$$ - -$head y$$ -The argument $icode y$$ -has one of the following possible prototypes -$codei% - const %Type% &%y%, - const std::complex<%Type%> &%y%, -%$$ - -$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 \[ - | x - y | \leq r ( |x| + |y| ) -\] $$ - -$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. -In addition, the following operations must be defined objects -$icode a$$ and $icode b$$ of type $icode Type$$: -$table -$bold Operation$$ $cnext - $bold Description$$ $rnext -$icode%a% <= %b%$$ $cnext - less that or equal operator (returns a $code bool$$ object) -$tend - -$head Include Files$$ -The file $code cppad/utility/near_equal.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head Example$$ -$children% - example/utility/near_equal.cpp -%$$ -The file $cref near_equal.cpp$$ contains an example -and test of $code NearEqual$$. -It return true if it succeeds and false otherwise. - -$head Exercise$$ -Create and run a program that contains the following code: -$codep - using std::complex; - using std::cout; - using std::endl; - - complex one(1., 0), i(0., 1); - complex x = one / i; - complex y = - i; - double r = 1e-12; - double a = 0; - bool ok = CppAD::NearEqual(x, y, r, a); - if( ok ) - cout << "Ok" << endl; - else - cout << "Error" << endl; -$$ - -$end - -*/ - -# include -# include -# include -# include - -namespace CppAD { // Begin CppAD namespace - -// determine if both x and y are finite values -template -bool near_equal_isfinite(const Type &x , const Type &y) -{ Type infinity = Type( std::numeric_limits::infinity() ); - - // handle bug where some compilers return true for nan == nan - bool xNan = x != x; - bool yNan = y != y; - - // infinite cases - bool xInf = (x == infinity || x == - infinity); - bool yInf = (x == infinity || x == - infinity); - - return ! (xNan | yNan | xInf | yInf); -} - -template -bool NearEqual(const Type &x, const Type &y, const Type &r, const Type &a) -{ - CheckNumericType(); - Type zero(0); - - CPPAD_ASSERT_KNOWN( - zero <= r, - "Error in NearEqual: relative error is less than zero" - ); - CPPAD_ASSERT_KNOWN( - zero <= a, - "Error in NearEqual: absolute error is less than zero" - ); - - // check for special cases - if( ! CppAD::near_equal_isfinite(x, y) ) - return false; - - Type ax = x; - if( ax <= zero ) - ax = - ax; - - Type ay = y; - if( ay <= zero ) - ay = - ay; - - Type ad = x - y; - if( ad <= zero ) - ad = - ad; - - if( ad <= a ) - return true; - - if( ad <= r * (ax + ay) ) - return true; - - return false; -} - -template -bool NearEqual( - const std::complex &x , - const std::complex &y , - const Type &r , - const Type & a ) -{ - CheckNumericType(); -# ifndef NDEBUG - Type zero(0); -# endif - - CPPAD_ASSERT_KNOWN( - zero <= r, - "Error in NearEqual: relative error is less than zero" - ); - CPPAD_ASSERT_KNOWN( - zero <= a, - "Error in NearEqual: absolute error is less than zero" - ); - - // check for special cases - if( ! CppAD::near_equal_isfinite(x.real(), x.imag()) ) - return false; - if( ! CppAD::near_equal_isfinite(y.real(), y.imag()) ) - return false; - - std::complex d = x - y; - - Type ad = std::abs(d); - if( ad <= a ) - return true; - - Type ax = std::abs(x); - Type ay = std::abs(y); - if( ad <= r * (ax + ay) ) - return true; - - return false; -} - -template -bool NearEqual( - const std::complex &x , - const Type &y , - const Type &r , - const Type & a ) -{ - return NearEqual(x, std::complex(y, Type(0)), r, a); -} - -template -bool NearEqual( - const Type &x , - const std::complex &y , - const Type &r , - const Type & a ) -{ - return NearEqual(std::complex(x, Type(0)), y, r, a); -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/ode_err_control.hpp b/build-config/cppad/include/cppad/utility/ode_err_control.hpp deleted file mode 100644 index 0e731bff..00000000 --- a/build-config/cppad/include/cppad/utility/ode_err_control.hpp +++ /dev/null @@ -1,598 +0,0 @@ -# ifndef CPPAD_UTILITY_ODE_ERR_CONTROL_HPP -# define CPPAD_UTILITY_ODE_ERR_CONTROL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin OdeErrControl$$ -$spell - cppad.hpp - nstep - maxabs - exp - scur - CppAD - xf - tf - xi - smin - smax - eabs - erel - ef - ta - tb - xa - xb - const - eb -$$ - - - -$section An Error Controller for ODE Solvers$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%xf% = OdeErrControl(%method%, %ti%, %tf%, %xi%, - %smin%, %smax%, %scur%, %eabs%, %erel%, %ef% , %maxabs%, %nstep% )%$$ - - -$head Description$$ -Let $latex \B{R}$$ denote the real numbers -and let $latex F : \B{R} \times \B{R}^n \rightarrow \B{R}^n$$ be a smooth function. -We define $latex X : [ti , tf] \rightarrow \B{R}^n$$ by -the following initial value problem: -$latex \[ -\begin{array}{rcl} - X(ti) & = & xi \\ - X'(t) & = & F[t , X(t)] -\end{array} -\] $$ -The routine $code OdeErrControl$$ can be used to adjust the step size -used an arbitrary integration methods in order to be as fast as possible -and still with in a requested error bound. - -$head Include$$ -The file $code cppad/utility/ode_err_control.hpp$$ is included by -$code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head Notation$$ -The template parameter types $cref/Scalar/OdeErrControl/Scalar/$$ and -$cref/Vector/OdeErrControl/Vector/$$ are documented below. - -$head xf$$ -The return value $icode xf$$ has the prototype -$codei% - %Vector% %xf% -%$$ -(see description of $cref/Vector/OdeErrControl/Vector/$$ below). -and the size of $icode xf$$ is equal to $icode n$$. -If $icode xf$$ contains not a number $cref nan$$, -see the discussion of $cref/step/OdeErrControl/Method/Nan/$$. - -$head Method$$ -The class $icode Method$$ -and the object $icode method$$ satisfy the following syntax -$codei% - %Method% &%method% -%$$ -The object $icode method$$ must support $code step$$ and -$code order$$ member functions defined below: - -$subhead step$$ -The syntax -$codei% - %method%.step(%ta%, %tb%, %xa%, %xb%, %eb%) -%$$ -executes one step of the integration method. -$codei% - -%ta% -%$$ -The argument $icode ta$$ has prototype -$codei% - const %Scalar% &%ta% -%$$ -It specifies the initial time for this step in the -ODE integration. -(see description of $cref/Scalar/OdeErrControl/Scalar/$$ below). -$codei% - -%tb% -%$$ -The argument $icode tb$$ has prototype -$codei% - const %Scalar% &%tb% -%$$ -It specifies the final time for this step in the -ODE integration. -$codei% - -%xa% -%$$ -The argument $icode xa$$ has prototype -$codei% - const %Vector% &%xa% -%$$ -and size $icode n$$. -It specifies the value of $latex X(ta)$$. -(see description of $cref/Vector/OdeErrControl/Vector/$$ below). -$codei% - -%xb% -%$$ -The argument value $icode xb$$ has prototype -$codei% - %Vector% &%xb% -%$$ -and size $icode n$$. -The input value of its elements does not matter. -On output, -it contains the approximation for $latex X(tb)$$ that the method obtains. -$codei% - -%eb% -%$$ -The argument value $icode eb$$ has prototype -$codei% - %Vector% &%eb% -%$$ -and size $icode n$$. -The input value of its elements does not matter. -On output, -it contains an estimate for the error in the approximation $icode xb$$. -It is assumed (locally) that the error bound in this approximation -nearly equal to $latex K (tb - ta)^m$$ -where $icode K$$ is a fixed constant and $icode m$$ -is the corresponding argument to $code CodeControl$$. - -$subhead Nan$$ -If any element of the vector $icode eb$$ or $icode xb$$ are -not a number $code nan$$, -the current step is considered to large. -If this happens with the current step size equal to $icode smin$$, -$code OdeErrControl$$ returns with $icode xf$$ and $icode ef$$ as vectors -of $code nan$$. - -$subhead order$$ -If $icode m$$ is $code size_t$$, -the object $icode method$$ must also support the following syntax -$codei% - %m% = %method%.order() -%$$ -The return value $icode m$$ is the order of the error estimate; -i.e., there is a constant K such that if $latex ti \leq ta \leq tb \leq tf$$, -$latex \[ - | eb(tb) | \leq K | tb - ta |^m -\] $$ -where $icode ta$$, $icode tb$$, and $icode eb$$ are as in -$icode%method%.step(%ta%, %tb%, %xa%, %xb%, %eb%)%$$ - - -$head ti$$ -The argument $icode ti$$ has prototype -$codei% - const %Scalar% &%ti% -%$$ -It specifies the initial time for the integration of -the differential equation. - - -$head tf$$ -The argument $icode tf$$ has prototype -$codei% - const %Scalar% &%tf% -%$$ -It specifies the final time for the integration of -the differential equation. - -$head xi$$ -The argument $icode xi$$ has prototype -$codei% - const %Vector% &%xi% -%$$ -and size $icode n$$. -It specifies value of $latex X(ti)$$. - -$head smin$$ -The argument $icode smin$$ has prototype -$codei% - const %Scalar% &%smin% -%$$ -The step size during a call to $icode method$$ is defined as -the corresponding value of $latex tb - ta$$. -If $latex tf - ti \leq smin$$, -the integration will be done in one step of size $icode tf - ti$$. -Otherwise, -the minimum value of $icode tb - ta$$ will be $latex smin$$ -except for the last two calls to $icode method$$ where it may be -as small as $latex smin / 2$$. - -$head smax$$ -The argument $icode smax$$ has prototype -$codei% - const %Scalar% &%smax% -%$$ -It specifies the maximum step size to use during the integration; -i.e., the maximum value for $latex tb - ta$$ in a call to $icode method$$. -The value of $icode smax$$ must be greater than or equal $icode smin$$. - -$head scur$$ -The argument $icode scur$$ has prototype -$codei% - %Scalar% &%scur% -%$$ -The value of $icode scur$$ is the suggested next step size, -based on error criteria, to try in the next call to $icode method$$. -On input it corresponds to the first call to $icode method$$, -in this call to $code OdeErrControl$$ (where $latex ta = ti$$). -On output it corresponds to the next call to $icode method$$, -in a subsequent call to $code OdeErrControl$$ (where $icode ta = tf$$). - -$head eabs$$ -The argument $icode eabs$$ has prototype -$codei% - const %Vector% &%eabs% -%$$ -and size $icode n$$. -Each of the elements of $icode eabs$$ must be -greater than or equal zero. -It specifies a bound for the absolute -error in the return value $icode xf$$ as an approximation for $latex X(tf)$$. -(see the -$cref/error criteria discussion/OdeErrControl/Error Criteria Discussion/$$ -below). - -$head erel$$ -The argument $icode erel$$ has prototype -$codei% - const %Scalar% &%erel% -%$$ -and is greater than or equal zero. -It specifies a bound for the relative -error in the return value $icode xf$$ as an approximation for $latex X(tf)$$ -(see the -$cref/error criteria discussion/OdeErrControl/Error Criteria Discussion/$$ -below). - -$head ef$$ -The argument value $icode ef$$ has prototype -$codei% - %Vector% &%ef% -%$$ -and size $icode n$$. -The input value of its elements does not matter. -On output, -it contains an estimated bound for the -absolute error in the approximation $icode xf$$; i.e., -$latex \[ - ef_i > | X( tf )_i - xf_i | -\] $$ -If on output $icode ef$$ contains not a number $code nan$$, -see the discussion of $cref/step/OdeErrControl/Method/Nan/$$. - -$head maxabs$$ -The argument $icode maxabs$$ is optional in the call to $code OdeErrControl$$. -If it is present, it has the prototype -$codei% - %Vector% &%maxabs% -%$$ -and size $icode n$$. -The input value of its elements does not matter. -On output, -it contains an estimate for the -maximum absolute value of $latex X(t)$$; i.e., -$latex \[ - maxabs[i] \approx \max \left\{ - | X( t )_i | \; : \; t \in [ti, tf] - \right\} -\] $$ - -$head nstep$$ -The argument $icode nstep$$ is optional in the call to $code OdeErrControl$$. -If it is present, it has the prototype -$codei% - %size_t% &%nstep% -%$$ -Its input value does not matter and its output value -is the number of calls to $icode%method%.step%$$ -used by $code OdeErrControl$$. - -$head Error Criteria Discussion$$ -The relative error criteria $icode erel$$ and -absolute error criteria $icode eabs$$ are enforced during each step of the -integration of the ordinary differential equations. -In addition, they are inversely scaled by the step size so that -the total error bound is less than the sum of the error bounds. -To be specific, if $latex \tilde{X} (t)$$ is the approximate solution -at time $latex t$$, -$icode ta$$ is the initial step time, -and $icode tb$$ is the final step time, -$latex \[ -\left| \tilde{X} (tb)_j - X (tb)_j \right| -\leq -\frac{tf - ti}{tb - ta} -\left[ eabs[j] + erel \; | \tilde{X} (tb)_j | \right] -\] $$ -If $latex X(tb)_j$$ is near zero for some $latex tb \in [ti , tf]$$, -and one uses an absolute error criteria $latex eabs[j]$$ of zero, -the error criteria above will force $code OdeErrControl$$ -to use step sizes equal to -$cref/smin/OdeErrControl/smin/$$ -for steps ending near $latex tb$$. -In this case, the error relative to $icode maxabs$$ can be judged after -$code OdeErrControl$$ returns. -If $icode ef$$ is to large relative to $icode maxabs$$, -$code OdeErrControl$$ can be called again -with a smaller value of $icode smin$$. - -$head Scalar$$ -The type $icode Scalar$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, the following operations must be defined for -$icode Scalar$$ objects $icode a$$ and $icode b$$: - -$table -$bold Operation$$ $cnext $bold Description$$ $rnext -$icode%a% <= %b%$$ $cnext - returns true (false) if $icode a$$ is less than or equal - (greater than) $icode b$$. -$rnext -$icode%a% == %b%$$ $cnext - returns true (false) if $icode a$$ is equal to $icode b$$. -$rnext -$codei%log(%a%)%$$ $cnext - returns a $icode Scalar$$ equal to the logarithm of $icode a$$ -$rnext -$codei%exp(%a%)%$$ $cnext - returns a $icode Scalar$$ equal to the exponential of $icode a$$ -$tend - - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type Scalar/SimpleVector/Elements of Specified Type/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Example$$ -$children% - example/utility/ode_err_control.cpp% - example/utility/ode_err_maxabs.cpp -%$$ -The files -$cref ode_err_control.cpp$$ -and -$cref ode_err_maxabs.cpp$$ -contain examples and tests of using this routine. -They return true if they succeed and false otherwise. - -$head Theory$$ -Let $latex e(s)$$ be the error as a function of the -step size $latex s$$ and suppose that there is a constant -$latex K$$ such that $latex e(s) = K s^m$$. -Let $latex a$$ be our error bound. -Given the value of $latex e(s)$$, a step of size $latex \lambda s$$ -would be ok provided that -$latex \[ -\begin{array}{rcl} - a & \geq & e( \lambda s ) (tf - ti) / ( \lambda s ) \\ - a & \geq & K \lambda^m s^m (tf - ti) / ( \lambda s ) \\ - a & \geq & \lambda^{m-1} s^{m-1} (tf - ti) e(s) / s^m \\ - a & \geq & \lambda^{m-1} (tf - ti) e(s) / s \\ - \lambda^{m-1} & \leq & \frac{a}{e(s)} \frac{s}{tf - ti} -\end{array} -\] $$ -Thus if the right hand side of the last inequality is greater -than or equal to one, the step of size $latex s$$ is ok. - -$head Source Code$$ -The source code for this routine is in the file -$code cppad/ode_err_control.hpp$$. - -$end --------------------------------------------------------------------------- -*/ - -// link exp and log for float and double -# include - -# include -# include -# include - -namespace CppAD { // Begin CppAD namespace - -template -Vector OdeErrControl( - Method &method, - const Scalar &ti , - const Scalar &tf , - const Vector &xi , - const Scalar &smin , - const Scalar &smax , - Scalar &scur , - const Vector &eabs , - const Scalar &erel , - Vector &ef , - Vector &maxabs, - size_t &nstep ) -{ - // check simple vector class specifications - CheckSimpleVector(); - - size_t n = size_t(xi.size()); - - CPPAD_ASSERT_KNOWN( - smin <= smax, - "Error in OdeErrControl: smin > smax" - ); - CPPAD_ASSERT_KNOWN( - size_t(eabs.size()) == n, - "Error in OdeErrControl: size of eabs is not equal to n" - ); - CPPAD_ASSERT_KNOWN( - size_t(maxabs.size()) == n, - "Error in OdeErrControl: size of maxabs is not equal to n" - ); - size_t m = method.order(); - CPPAD_ASSERT_KNOWN( - m > 1, - "Error in OdeErrControl: m is less than or equal one" - ); - - bool ok; - bool minimum_step; - size_t i; - Vector xa(n), xb(n), eb(n), nan_vec(n); - - // initialization - Scalar zero(0.0); - Scalar one(1.0); - Scalar two(2.0); - Scalar three(3.0); - Scalar m1(double(m-1)); - Scalar ta = ti; - for(i = 0; i < n; i++) - { nan_vec[i] = nan(zero); - ef[i] = zero; - xa[i] = xi[i]; - if( zero <= xi[i] ) - maxabs[i] = xi[i]; - else - maxabs[i] = - xi[i]; - - } - nstep = 0; - - Scalar tb, step, lambda, axbi, a, r, root; - while( ! (ta == tf) ) - { // start with value suggested by error criteria - step = scur; - - // check maximum - if( smax <= step ) - step = smax; - - // check minimum - minimum_step = step <= smin; - if( minimum_step ) - step = smin; - - // check if near the end - if( tf <= ta + step * three / two ) - tb = tf; - else - tb = ta + step; - - // try using this step size - nstep++; - method.step(ta, tb, xa, xb, eb); - step = tb - ta; - - // check if this steps error estimate is ok - ok = ! (hasnan(xb) || hasnan(eb)); - if( (! ok) && minimum_step ) - { ef = nan_vec; - return nan_vec; - } - - // compute value of lambda for this step - lambda = Scalar(10) * scur / step; - for(i = 0; i < n; i++) - { if( zero <= xb[i] ) - axbi = xb[i]; - else - axbi = - xb[i]; - a = eabs[i] + erel * axbi; - if( ! (eb[i] == zero) ) - { r = ( a / eb[i] ) * step / (tf - ti); - root = exp( log(r) / m1 ); - if( root <= lambda ) - lambda = root; - } - } - if( ok && ( one <= lambda || step <= smin * three / two) ) - { // this step is within error limits or - // close to the minimum size - ta = tb; - for(i = 0; i < n; i++) - { xa[i] = xb[i]; - ef[i] = ef[i] + eb[i]; - if( zero <= xb[i] ) - axbi = xb[i]; - else - axbi = - xb[i]; - if( axbi > maxabs[i] ) - maxabs[i] = axbi; - } - } - if( ! ok ) - { // decrease step an see if method will work this time - scur = step / two; - } - else if( ! (ta == tf) ) - { // step suggested by the error criteria is not used - // on the last step because it may be very small. - scur = lambda * step / two; - } - } - return xa; -} - -template -Vector OdeErrControl( - Method &method, - const Scalar &ti , - const Scalar &tf , - const Vector &xi , - const Scalar &smin , - const Scalar &smax , - Scalar &scur , - const Vector &eabs , - const Scalar &erel , - Vector &ef ) -{ Vector maxabs(xi.size()); - size_t nstep; - return OdeErrControl( - method, ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep - ); -} - -template -Vector OdeErrControl( - Method &method, - const Scalar &ti , - const Scalar &tf , - const Vector &xi , - const Scalar &smin , - const Scalar &smax , - Scalar &scur , - const Vector &eabs , - const Scalar &erel , - Vector &ef , - Vector &maxabs) -{ size_t nstep; - return OdeErrControl( - method, ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep - ); -} - -} // End CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/ode_gear.hpp b/build-config/cppad/include/cppad/utility/ode_gear.hpp deleted file mode 100644 index 1f4901a7..00000000 --- a/build-config/cppad/include/cppad/utility/ode_gear.hpp +++ /dev/null @@ -1,521 +0,0 @@ -# ifndef CPPAD_UTILITY_ODE_GEAR_HPP -# define CPPAD_UTILITY_ODE_GEAR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin OdeGear$$ -$spell - cppad.hpp - Jan - bool - const - CppAD - dep -$$ - - -$section An Arbitrary Order Gear Method$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%OdeGear(%F%, %m%, %n%, %T%, %X%, %e%)%$$ - - -$head Purpose$$ -This routine applies -$cref/Gear's Method/OdeGear/Gear's Method/$$ -to solve an explicit set of ordinary differential equations. -We are given -$latex f : \B{R} \times \B{R}^n \rightarrow \B{R}^n$$ be a smooth function. -This routine solves the following initial value problem -$latex \[ -\begin{array}{rcl} - x( t_{m-1} ) & = & x^0 \\ - x^\prime (t) & = & f[t , x(t)] -\end{array} -\] $$ -for the value of $latex x( t_m )$$. -If your set of ordinary differential equations are not stiff -an explicit method may be better (perhaps $cref Runge45$$.) - -$head Include$$ -The file $code cppad/utility/ode_gear.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head Fun$$ -The class $icode Fun$$ -and the object $icode F$$ satisfy the prototype -$codei% - %Fun% &%F% -%$$ -This must support the following set of calls -$codei% - %F%.Ode(%t%, %x%, %f%) - %F%.Ode_dep(%t%, %x%, %f_x%) -%$$ - -$subhead t$$ -The argument $icode t$$ has prototype -$codei% - const %Scalar% &%t% -%$$ -(see description of $cref/Scalar/OdeGear/Scalar/$$ below). - -$subhead x$$ -The argument $icode x$$ has prototype -$codei% - const %Vector% &%x% -%$$ -and has size $icode n$$ -(see description of $cref/Vector/OdeGear/Vector/$$ below). - -$subhead f$$ -The argument $icode f$$ to $icode%F%.Ode%$$ has prototype -$codei% - %Vector% &%f% -%$$ -On input and output, $icode f$$ is a vector of size $icode n$$ -and the input values of the elements of $icode f$$ do not matter. -On output, -$icode f$$ is set equal to $latex f(t, x)$$ -(see $icode f(t, x)$$ in $cref/Purpose/OdeGear/Purpose/$$). - -$subhead f_x$$ -The argument $icode f_x$$ has prototype -$codei% - %Vector% &%f_x% -%$$ -On input and output, $icode f_x$$ is a vector of size $latex n * n$$ -and the input values of the elements of $icode f_x$$ do not matter. -On output, -$latex \[ - f\_x [i * n + j] = \partial_{x(j)} f_i ( t , x ) -\] $$ - -$subhead Warning$$ -The arguments $icode f$$, and $icode f_x$$ -must have a call by reference in their prototypes; i.e., -do not forget the $code &$$ in the prototype for -$icode f$$ and $icode f_x$$. - -$head m$$ -The argument $icode m$$ has prototype -$codei% - size_t %m% -%$$ -It specifies the order (highest power of $latex t$$) -used to represent the function $latex x(t)$$ in the multi-step method. -Upon return from $code OdeGear$$, -the $th i$$ component of the polynomial is defined by -$latex \[ - p_i ( t_j ) = X[ j * n + i ] -\] $$ -for $latex j = 0 , \ldots , m$$ (where $latex 0 \leq i < n$$). -The value of $latex m$$ must be greater than or equal one. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ -It specifies the range space dimension of the -vector valued function $latex x(t)$$. - -$head T$$ -The argument $icode T$$ has prototype -$codei% - const %Vector% &%T% -%$$ -and size greater than or equal to $latex m+1$$. -For $latex j = 0 , \ldots m$$, $latex T[j]$$ is the time -corresponding to time corresponding -to a previous point in the multi-step method. -The value $latex T[m]$$ is the time -of the next point in the multi-step method. -The array $latex T$$ must be monotone increasing; i.e., -$latex T[j] < T[j+1]$$. -Above and below we often use the shorthand $latex t_j$$ for $latex T[j]$$. - - -$head X$$ -The argument $icode X$$ has the prototype -$codei% - %Vector% &%X% -%$$ -and size greater than or equal to $latex (m+1) * n$$. -On input to $code OdeGear$$, -for $latex j = 0 , \ldots , m-1$$, and -$latex i = 0 , \ldots , n-1$$ -$latex \[ - X[ j * n + i ] = x_i ( t_j ) -\] $$ -Upon return from $code OdeGear$$, -for $latex i = 0 , \ldots , n-1$$ -$latex \[ - X[ m * n + i ] \approx x_i ( t_m ) -\] $$ - -$head e$$ -The vector $icode e$$ is an approximate error bound for the result; i.e., -$latex \[ - e[i] \geq | X[ m * n + i ] - x_i ( t_m ) | -\] $$ -The order of this approximation is one less than the order of -the solution; i.e., -$latex \[ - e = O ( h^m ) -\] $$ -where $latex h$$ is the maximum of $latex t_{j+1} - t_j$$. - -$head Scalar$$ -The type $icode Scalar$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, the following operations must be defined for -$icode Scalar$$ objects $icode a$$ and $icode b$$: - -$table -$bold Operation$$ $cnext $bold Description$$ $rnext -$icode%a% < %b%$$ $cnext - less than operator (returns a $code bool$$ object) -$tend - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type Scalar/SimpleVector/Elements of Specified Type/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Example$$ -$children% - example/utility/ode_gear.cpp -%$$ -The file -$cref ode_gear.cpp$$ -contains an example and test a test of using this routine. - -$head Source Code$$ -The source code for this routine is in the file -$code cppad/ode_gear.hpp$$. - -$head Theory$$ -For this discussion we use the shorthand $latex x_j$$ -for the value $latex x ( t_j ) \in \B{R}^n$$ which is not to be confused -with $latex x_i (t) \in \B{R}$$ in the notation above. -The interpolating polynomial $latex p(t)$$ is given by -$latex \[ -p(t) = -\sum_{j=0}^m -x_j -\frac{ - \prod_{i \neq j} ( t - t_i ) -}{ - \prod_{i \neq j} ( t_j - t_i ) -} -\] $$ -The derivative $latex p^\prime (t)$$ is given by -$latex \[ -p^\prime (t) = -\sum_{j=0}^m -x_j -\frac{ - \sum_{i \neq j} \prod_{k \neq i,j} ( t - t_k ) -}{ - \prod_{k \neq j} ( t_j - t_k ) -} -\] $$ -Evaluating the derivative at the point $latex t_\ell$$ we have -$latex \[ -\begin{array}{rcl} -p^\prime ( t_\ell ) & = & -x_\ell -\frac{ - \sum_{i \neq \ell} \prod_{k \neq i,\ell} ( t_\ell - t_k ) -}{ - \prod_{k \neq \ell} ( t_\ell - t_k ) -} -+ -\sum_{j \neq \ell} -x_j -\frac{ - \sum_{i \neq j} \prod_{k \neq i,j} ( t_\ell - t_k ) -}{ - \prod_{k \neq j} ( t_j - t_k ) -} -\\ -& = & -x_\ell -\sum_{i \neq \ell} -\frac{ 1 }{ t_\ell - t_i } -+ -\sum_{j \neq \ell} -x_j -\frac{ - \prod_{k \neq \ell,j} ( t_\ell - t_k ) -}{ - \prod_{k \neq j} ( t_j - t_k ) -} -\\ -& = & -x_\ell -\sum_{k \neq \ell} ( t_\ell - t_k )^{-1} -+ -\sum_{j \neq \ell} -x_j -( t_j - t_\ell )^{-1} -\prod_{k \neq \ell ,j} ( t_\ell - t_k ) / ( t_j - t_k ) -\end{array} -\] $$ -We define the vector $latex \alpha \in \B{R}^{m+1}$$ by -$latex \[ -\alpha_j = \left\{ \begin{array}{ll} -\sum_{k \neq m} ( t_m - t_k )^{-1} - & {\rm if} \; j = m -\\ -( t_j - t_m )^{-1} -\prod_{k \neq m,j} ( t_m - t_k ) / ( t_j - t_k ) - & {\rm otherwise} -\end{array} \right. -\] $$ -It follows that -$latex \[ - p^\prime ( t_m ) = \alpha_0 x_0 + \cdots + \alpha_m x_m -\] $$ -Gear's method determines $latex x_m$$ by solving the following -nonlinear equation -$latex \[ - f( t_m , x_m ) = \alpha_0 x_0 + \cdots + \alpha_m x_m -\] $$ -Newton's method for solving this equation determines iterates, -which we denote by $latex x_m^k$$, by solving the following affine -approximation of the equation above -$latex \[ -\begin{array}{rcl} -f( t_m , x_m^{k-1} ) + \partial_x f( t_m , x_m^{k-1} ) ( x_m^k - x_m^{k-1} ) -& = & -\alpha_0 x_0^k + \alpha_1 x_1 + \cdots + \alpha_m x_m -\\ -\left[ \alpha_m I - \partial_x f( t_m , x_m^{k-1} ) \right] x_m -& = & -\left[ -f( t_m , x_m^{k-1} ) - \partial_x f( t_m , x_m^{k-1} ) x_m^{k-1} -- \alpha_0 x_0 - \cdots - \alpha_{m-1} x_{m-1} -\right] -\end{array} -\] $$ -In order to initialize Newton's method; i.e. choose $latex x_m^0$$ -we define the vector $latex \beta \in \B{R}^{m+1}$$ by -$latex \[ -\beta_j = \left\{ \begin{array}{ll} -\sum_{k \neq m-1} ( t_{m-1} - t_k )^{-1} - & {\rm if} \; j = m-1 -\\ -( t_j - t_{m-1} )^{-1} -\prod_{k \neq m-1,j} ( t_{m-1} - t_k ) / ( t_j - t_k ) - & {\rm otherwise} -\end{array} \right. -\] $$ -It follows that -$latex \[ - p^\prime ( t_{m-1} ) = \beta_0 x_0 + \cdots + \beta_m x_m -\] $$ -We solve the following approximation of the equation above to determine -$latex x_m^0$$: -$latex \[ - f( t_{m-1} , x_{m-1} ) = - \beta_0 x_0 + \cdots + \beta_{m-1} x_{m-1} + \beta_m x_m^0 -\] $$ - - -$head Gear's Method$$ -C. W. Gear, -``Simultaneous Numerical Solution of Differential-Algebraic Equations,'' -IEEE Transactions on Circuit Theory, -vol. 18, no. 1, pp. 89-95, Jan. 1971. - - -$end --------------------------------------------------------------------------- -*/ - -# include -# include -# include -# include -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -template -void OdeGear( - Fun &F , - size_t m , - size_t n , - const Vector &T , - Vector &X , - Vector &e ) -{ - // temporary indices - size_t i, j, k; - - typedef typename Vector::value_type Scalar; - - // check numeric type specifications - CheckNumericType(); - - // check simple vector class specifications - CheckSimpleVector(); - - CPPAD_ASSERT_KNOWN( - m >= 1, - "OdeGear: m is less than one" - ); - CPPAD_ASSERT_KNOWN( - n > 0, - "OdeGear: n is equal to zero" - ); - CPPAD_ASSERT_KNOWN( - size_t(T.size()) >= (m+1), - "OdeGear: size of T is not greater than or equal (m+1)" - ); - CPPAD_ASSERT_KNOWN( - size_t(X.size()) >= (m+1) * n, - "OdeGear: size of X is not greater than or equal (m+1) * n" - ); - for(j = 0; j < m; j++) CPPAD_ASSERT_KNOWN( - T[j] < T[j+1], - "OdeGear: the array T is not monotone increasing" - ); - - // some constants - Scalar zero(0); - Scalar one(1); - - // vectors required by method - Vector alpha(m + 1); - Vector beta(m + 1); - Vector f(n); - Vector f_x(n * n); - Vector x_m0(n); - Vector x_m(n); - Vector b(n); - Vector A(n * n); - - // compute alpha[m] - alpha[m] = zero; - for(k = 0; k < m; k++) - alpha[m] += one / (T[m] - T[k]); - - // compute beta[m-1] - beta[m-1] = one / (T[m-1] - T[m]); - for(k = 0; k < m-1; k++) - beta[m-1] += one / (T[m-1] - T[k]); - - - // compute other components of alpha - for(j = 0; j < m; j++) - { // compute alpha[j] - alpha[j] = one / (T[j] - T[m]); - for(k = 0; k < m; k++) - { if( k != j ) - { alpha[j] *= (T[m] - T[k]); - alpha[j] /= (T[j] - T[k]); - } - } - } - - // compute other components of beta - for(j = 0; j <= m; j++) - { if( j != m-1 ) - { // compute beta[j] - beta[j] = one / (T[j] - T[m-1]); - for(k = 0; k <= m; k++) - { if( k != j && k != m-1 ) - { beta[j] *= (T[m-1] - T[k]); - beta[j] /= (T[j] - T[k]); - } - } - } - } - - // evaluate f(T[m-1], x_{m-1} ) - for(i = 0; i < n; i++) - x_m[i] = X[(m-1) * n + i]; - F.Ode(T[m-1], x_m, f); - - // solve for x_m^0 - for(i = 0; i < n; i++) - { x_m[i] = f[i]; - for(j = 0; j < m; j++) - x_m[i] -= beta[j] * X[j * n + i]; - x_m[i] /= beta[m]; - } - x_m0 = x_m; - - // evaluate partial w.r.t x of f(T[m], x_m^0) - F.Ode_dep(T[m], x_m, f_x); - - // compute the matrix A = ( alpha[m] * I - f_x ) - for(i = 0; i < n; i++) - { for(j = 0; j < n; j++) - A[i * n + j] = - f_x[i * n + j]; - A[i * n + i] += alpha[m]; - } - - // LU factor (and overwrite) the matrix A - CppAD::vector ip(n) , jp(n); -# ifndef NDEBUG - int sign = -# endif - LuFactor(ip, jp, A); - CPPAD_ASSERT_KNOWN( - sign != 0, - "OdeGear: step size is to large" - ); - - // Iterations of Newton's method - for(k = 0; k < 3; k++) - { - // only evaluate f( T[m] , x_m ) keep f_x during iteration - F.Ode(T[m], x_m, f); - - // b = f + f_x x_m - alpha[0] x_0 - ... - alpha[m-1] x_{m-1} - for(i = 0; i < n; i++) - { b[i] = f[i]; - for(j = 0; j < n; j++) - b[i] -= f_x[i * n + j] * x_m[j]; - for(j = 0; j < m; j++) - b[i] -= alpha[j] * X[ j * n + i ]; - } - LuInvert(ip, jp, A, b); - x_m = b; - } - - // return estimate for x( t[k] ) and the estimated error bound - for(i = 0; i < n; i++) - { X[m * n + i] = x_m[i]; - e[i] = x_m[i] - x_m0[i]; - if( e[i] < zero ) - e[i] = - e[i]; - } -} - -} // End CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/ode_gear_control.hpp b/build-config/cppad/include/cppad/utility/ode_gear_control.hpp deleted file mode 100644 index 68f75ec9..00000000 --- a/build-config/cppad/include/cppad/utility/ode_gear_control.hpp +++ /dev/null @@ -1,544 +0,0 @@ -# ifndef CPPAD_UTILITY_ODE_GEAR_CONTROL_HPP -# define CPPAD_UTILITY_ODE_GEAR_CONTROL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin OdeGearControl$$ -$spell - cppad.hpp - CppAD - xf - xi - smin - smax - eabs - ef - maxabs - nstep - tf - sini - erel - dep - const - tb - ta - exp -$$ - - - -$section An Error Controller for Gear's Ode Solvers$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%xf% = OdeGearControl(%F%, %M%, %ti%, %tf%, %xi%, - %smin%, %smax%, %sini%, %eabs%, %erel%, %ef% , %maxabs%, %nstep% )%$$ - - -$head Purpose$$ -Let $latex \B{R}$$ denote the real numbers -and let $latex f : \B{R} \times \B{R}^n \rightarrow \B{R}^n$$ be a smooth function. -We define $latex X : [ti , tf] \rightarrow \B{R}^n$$ by -the following initial value problem: -$latex \[ -\begin{array}{rcl} - X(ti) & = & xi \\ - X'(t) & = & f[t , X(t)] -\end{array} -\] $$ -The routine $cref OdeGear$$ is a stiff multi-step method that -can be used to approximate the solution to this equation. -The routine $code OdeGearControl$$ sets up this multi-step method -and controls the error during such an approximation. - -$head Include$$ -The file $code cppad/utility/ode_gear_control.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head Notation$$ -The template parameter types $cref/Scalar/OdeGearControl/Scalar/$$ and -$cref/Vector/OdeGearControl/Vector/$$ are documented below. - -$head xf$$ -The return value $icode xf$$ has the prototype -$codei% - %Vector% %xf% -%$$ -and the size of $icode xf$$ is equal to $icode n$$ -(see description of $cref/Vector/OdeGear/Vector/$$ below). -It is the approximation for $latex X(tf)$$. - -$head Fun$$ -The class $icode Fun$$ -and the object $icode F$$ satisfy the prototype -$codei% - %Fun% &%F% -%$$ -This must support the following set of calls -$codei% - %F%.Ode(%t%, %x%, %f%) - %F%.Ode_dep(%t%, %x%, %f_x%) -%$$ - -$subhead t$$ -The argument $icode t$$ has prototype -$codei% - const %Scalar% &%t% -%$$ -(see description of $cref/Scalar/OdeGear/Scalar/$$ below). - -$subhead x$$ -The argument $icode x$$ has prototype -$codei% - const %Vector% &%x% -%$$ -and has size $icode N$$ -(see description of $cref/Vector/OdeGear/Vector/$$ below). - -$subhead f$$ -The argument $icode f$$ to $icode%F%.Ode%$$ has prototype -$codei% - %Vector% &%f% -%$$ -On input and output, $icode f$$ is a vector of size $icode N$$ -and the input values of the elements of $icode f$$ do not matter. -On output, -$icode f$$ is set equal to $latex f(t, x)$$ -(see $icode f(t, x)$$ in $cref/Purpose/OdeGear/Purpose/$$). - -$subhead f_x$$ -The argument $icode f_x$$ has prototype -$codei% - %Vector% &%f_x% -%$$ -On input and output, $icode f_x$$ is a vector of size $latex N * N$$ -and the input values of the elements of $icode f_x$$ do not matter. -On output, -$latex \[ - f\_x [i * n + j] = \partial_{x(j)} f_i ( t , x ) -\] $$ - -$subhead Warning$$ -The arguments $icode f$$, and $icode f_x$$ -must have a call by reference in their prototypes; i.e., -do not forget the $code &$$ in the prototype for -$icode f$$ and $icode f_x$$. - -$head M$$ -The argument $icode M$$ has prototype -$codei% - size_t %M% -%$$ -It specifies the order of the multi-step method; i.e., -the order of the approximating polynomial -(after the initialization process). -The argument $icode M$$ must greater than or equal one. - -$head ti$$ -The argument $icode ti$$ has prototype -$codei% - const %Scalar% &%ti% -%$$ -It specifies the initial time for the integration of -the differential equation. - -$head tf$$ -The argument $icode tf$$ has prototype -$codei% - const %Scalar% &%tf% -%$$ -It specifies the final time for the integration of -the differential equation. - -$head xi$$ -The argument $icode xi$$ has prototype -$codei% - const %Vector% &%xi% -%$$ -and size $icode n$$. -It specifies value of $latex X(ti)$$. - -$head smin$$ -The argument $icode smin$$ has prototype -$codei% - const %Scalar% &%smin% -%$$ -The minimum value of $latex T[M] - T[M-1]$$ in a call to $code OdeGear$$ -will be $latex smin$$ except for the last two calls where it may be -as small as $latex smin / 2$$. -The value of $icode smin$$ must be less than or equal $icode smax$$. - -$head smax$$ -The argument $icode smax$$ has prototype -$codei% - const %Scalar% &%smax% -%$$ -It specifies the maximum step size to use during the integration; -i.e., the maximum value for $latex T[M] - T[M-1]$$ -in a call to $code OdeGear$$. - -$head sini$$ -The argument $icode sini$$ has prototype -$codei% - %Scalar% &%sini% -%$$ -The value of $icode sini$$ is the minimum -step size to use during initialization of the multi-step method; i.e., -for calls to $code OdeGear$$ where $latex m < M$$. -The value of $icode sini$$ must be less than or equal $icode smax$$ -(and can also be less than $icode smin$$). - -$head eabs$$ -The argument $icode eabs$$ has prototype -$codei% - const %Vector% &%eabs% -%$$ -and size $icode n$$. -Each of the elements of $icode eabs$$ must be -greater than or equal zero. -It specifies a bound for the absolute -error in the return value $icode xf$$ as an approximation for $latex X(tf)$$. -(see the -$cref/error criteria discussion/OdeGearControl/Error Criteria Discussion/$$ -below). - -$head erel$$ -The argument $icode erel$$ has prototype -$codei% - const %Scalar% &%erel% -%$$ -and is greater than or equal zero. -It specifies a bound for the relative -error in the return value $icode xf$$ as an approximation for $latex X(tf)$$ -(see the -$cref/error criteria discussion/OdeGearControl/Error Criteria Discussion/$$ -below). - -$head ef$$ -The argument value $icode ef$$ has prototype -$codei% - %Vector% &%ef% -%$$ -and size $icode n$$. -The input value of its elements does not matter. -On output, -it contains an estimated bound for the -absolute error in the approximation $icode xf$$; i.e., -$latex \[ - ef_i > | X( tf )_i - xf_i | -\] $$ - -$head maxabs$$ -The argument $icode maxabs$$ is optional in the call to $code OdeGearControl$$. -If it is present, it has the prototype -$codei% - %Vector% &%maxabs% -%$$ -and size $icode n$$. -The input value of its elements does not matter. -On output, -it contains an estimate for the -maximum absolute value of $latex X(t)$$; i.e., -$latex \[ - maxabs[i] \approx \max \left\{ - | X( t )_i | \; : \; t \in [ti, tf] - \right\} -\] $$ - -$head nstep$$ -The argument $icode nstep$$ has the prototype -$codei% - %size_t% &%nstep% -%$$ -Its input value does not matter and its output value -is the number of calls to $cref OdeGear$$ -used by $code OdeGearControl$$. - -$head Error Criteria Discussion$$ -The relative error criteria $icode erel$$ and -absolute error criteria $icode eabs$$ are enforced during each step of the -integration of the ordinary differential equations. -In addition, they are inversely scaled by the step size so that -the total error bound is less than the sum of the error bounds. -To be specific, if $latex \tilde{X} (t)$$ is the approximate solution -at time $latex t$$, -$icode ta$$ is the initial step time, -and $icode tb$$ is the final step time, -$latex \[ -\left| \tilde{X} (tb)_j - X (tb)_j \right| -\leq -\frac{tf - ti}{tb - ta} -\left[ eabs[j] + erel \; | \tilde{X} (tb)_j | \right] -\] $$ -If $latex X(tb)_j$$ is near zero for some $latex tb \in [ti , tf]$$, -and one uses an absolute error criteria $latex eabs[j]$$ of zero, -the error criteria above will force $code OdeGearControl$$ -to use step sizes equal to -$cref/smin/OdeGearControl/smin/$$ -for steps ending near $latex tb$$. -In this case, the error relative to $icode maxabs$$ can be judged after -$code OdeGearControl$$ returns. -If $icode ef$$ is to large relative to $icode maxabs$$, -$code OdeGearControl$$ can be called again -with a smaller value of $icode smin$$. - -$head Scalar$$ -The type $icode Scalar$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, the following operations must be defined for -$icode Scalar$$ objects $icode a$$ and $icode b$$: - -$table -$bold Operation$$ $cnext $bold Description$$ $rnext -$icode%a% <= %b%$$ $cnext - returns true (false) if $icode a$$ is less than or equal - (greater than) $icode b$$. -$rnext -$icode%a% == %b%$$ $cnext - returns true (false) if $icode a$$ is equal to $icode b$$. -$rnext -$codei%log(%a%)%$$ $cnext - returns a $icode Scalar$$ equal to the logarithm of $icode a$$ -$rnext -$codei%exp(%a%)%$$ $cnext - returns a $icode Scalar$$ equal to the exponential of $icode a$$ -$tend - - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type Scalar/SimpleVector/Elements of Specified Type/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Example$$ -$children% - example/utility/ode_gear_control.cpp -%$$ -The file -$cref ode_gear_control.cpp$$ -contains an example and test a test of using this routine. - -$head Theory$$ -Let $latex e(s)$$ be the error as a function of the -step size $latex s$$ and suppose that there is a constant -$latex K$$ such that $latex e(s) = K s^m$$. -Let $latex a$$ be our error bound. -Given the value of $latex e(s)$$, a step of size $latex \lambda s$$ -would be ok provided that -$latex \[ -\begin{array}{rcl} - a & \geq & e( \lambda s ) (tf - ti) / ( \lambda s ) \\ - a & \geq & K \lambda^m s^m (tf - ti) / ( \lambda s ) \\ - a & \geq & \lambda^{m-1} s^{m-1} (tf - ti) e(s) / s^m \\ - a & \geq & \lambda^{m-1} (tf - ti) e(s) / s \\ - \lambda^{m-1} & \leq & \frac{a}{e(s)} \frac{s}{tf - ti} -\end{array} -\] $$ -Thus if the right hand side of the last inequality is greater -than or equal to one, the step of size $latex s$$ is ok. - -$head Source Code$$ -The source code for this routine is in the file -$code cppad/ode_gear_control.hpp$$. - -$end --------------------------------------------------------------------------- -*/ - -// link exp and log for float and double -# include - -# include - -namespace CppAD { // Begin CppAD namespace - -template -Vector OdeGearControl( - Fun &F , - size_t M , - const Scalar &ti , - const Scalar &tf , - const Vector &xi , - const Scalar &smin , - const Scalar &smax , - Scalar &sini , - const Vector &eabs , - const Scalar &erel , - Vector &ef , - Vector &maxabs, - size_t &nstep ) -{ - // check simple vector class specifications - CheckSimpleVector(); - - // dimension of the state space - size_t n = size_t(xi.size()); - - CPPAD_ASSERT_KNOWN( - M >= 1, - "Error in OdeGearControl: M is less than one" - ); - CPPAD_ASSERT_KNOWN( - smin <= smax, - "Error in OdeGearControl: smin is greater than smax" - ); - CPPAD_ASSERT_KNOWN( - sini <= smax, - "Error in OdeGearControl: sini is greater than smax" - ); - CPPAD_ASSERT_KNOWN( - size_t(eabs.size()) == n, - "Error in OdeGearControl: size of eabs is not equal to n" - ); - CPPAD_ASSERT_KNOWN( - size_t(maxabs.size()) == n, - "Error in OdeGearControl: size of maxabs is not equal to n" - ); - - // some constants - const Scalar zero(0); - const Scalar one(1); - const Scalar one_plus( Scalar(3) / Scalar(2) ); - const Scalar two(2); - const Scalar ten(10); - - // temporary indices - size_t i, k; - - // temporary Scalars - Scalar step, sprevious, lambda, axi, a, root, r; - - // vectors of Scalars - Vector T (M + 1); - Vector X( (M + 1) * n ); - Vector e(n); - Vector xf(n); - - // initial integer values - size_t m = 1; - nstep = 0; - - // initialize T - T[0] = ti; - - // initialize X, ef, maxabs - for(i = 0; i < n; i++) - for(i = 0; i < n; i++) - { X[i] = xi[i]; - ef[i] = zero; - X[i] = xi[i]; - if( zero <= xi[i] ) - maxabs[i] = xi[i]; - else - maxabs[i] = - xi[i]; - - } - - // initial step size - step = smin; - - while( T[m-1] < tf ) - { sprevious = step; - - // check maximum - if( smax <= step ) - step = smax; - - // check minimum - if( m < M ) - { if( step <= sini ) - step = sini; - } - else - if( step <= smin ) - step = smin; - - // check if near the end - if( tf <= T[m-1] + one_plus * step ) - T[m] = tf; - else - T[m] = T[m-1] + step; - - // try using this step size - nstep++; - OdeGear(F, m, n, T, X, e); - step = T[m] - T[m-1]; - - // compute value of lambda for this step - lambda = Scalar(10) * sprevious / step; - for(i = 0; i < n; i++) - { axi = X[m * n + i]; - if( axi <= zero ) - axi = - axi; - a = eabs[i] + erel * axi; - if( e[i] > zero ) - { if( m == 1 ) - root = (a / e[i]) / ten; - else - { r = ( a / e[i] ) * step / (tf - ti); - root = exp( log(r) / Scalar(m-1) ); - } - if( root <= lambda ) - lambda = root; - } - } - - bool advance; - if( m == M ) - advance = one <= lambda || step <= one_plus * smin; - else - advance = one <= lambda || step <= one_plus * sini; - - - if( advance ) - { // accept the results of this time step - CPPAD_ASSERT_UNKNOWN( m <= M ); - if( m == M ) - { // shift for next step - for(k = 0; k < m; k++) - { T[k] = T[k+1]; - for(i = 0; i < n; i++) - X[k*n + i] = X[(k+1)*n + i]; - } - } - // update ef and maxabs - for(i = 0; i < n; i++) - { ef[i] = ef[i] + e[i]; - axi = X[m * n + i]; - if( axi <= zero ) - axi = - axi; - if( axi > maxabs[i] ) - maxabs[i] = axi; - } - if( m != M ) - m++; // all we need do in this case - } - - // new step suggested by error criteria - step = std::min(lambda , ten) * step / two; - } - for(i = 0; i < n; i++) - xf[i] = X[(m-1) * n + i]; - - return xf; -} - -} // End CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/omh/cppad_vector.omh b/build-config/cppad/include/cppad/utility/omh/cppad_vector.omh deleted file mode 100644 index 21aa56af..00000000 --- a/build-config/cppad/include/cppad/utility/omh/cppad_vector.omh +++ /dev/null @@ -1,408 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -$begin CppAD_vector$$ -$spell - rvalues - thread_alloc - cppad.hpp - Bool - resize - cout - endl - std - Cpp - const - vec - ostream - elem - Iterators - typename - iterator - resized - dereference -$$ - - -$section The CppAD::vector Template Class$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%# include -%$$ -$codei%CppAD::vector<%Scalar%> %vec%, %other% -%$$ - -$head Description$$ -The include file $code cppad/vector.hpp$$ defines the -vector template class $code CppAD::vector$$. -This is a $cref SimpleVector$$ template class and in addition -it has the features listed below. -The purposes for this template vector class are as follows: -$list number$$ -If $code NDEBUG$$ is not defined, it checks for all -memory accesses to make sure the corresponding index is valid. -This includes when using its -$cref/iterators/CppAD_vector/Iterators/$$ -$lnext -It has a simple set of private member variables that make it -easy to understand when viewing its values in a C++ debugger. -$lnext -It uses the $cref thread_alloc$$ memory allocator which makes it fast -in a multi-threading environment; see -$cref/memory and parallel mode/CppAD_vector/Memory and Parallel Mode/$$. -$lnext -The operations it has are like the corresponding $code std::vector$$ -operation so it is easy to use. -$lend - -$head Include$$ -The files -$code cppad/utility/vector.hpp$$ and $code cppad/utility/vector_bool.hpp$$ are -included by $code cppad/cppad.hpp$$. -They can also be included separately with out the rest of the -CppAD include files. - -$subhead Deprecated 2019-08-19$$ -The file $code cppad/utility/vector.hpp$$ -includes the $code cppad/utility/vector_bool.hpp$$ -because they used to be one file. -If you want $cref/vectorBool/CppAD_vector/vectorBool/$$, -and not the rest of CppAD, you should include -$code cppad/utility/vector_bool.hpp$$. - -$head Integer Size$$ -The size $icode n$$ in the constructor syntax below can be an -$code int$$ (all simple vectors support $code size_t$$): -$codei% - CppAD::vector<%Scalar%> %vec%(%n%) -%$$ - -$head capacity$$ -If $icode cap$$ is a $code size_t$$ object, -$codei% - %cap% = %vec%.capacity() -%$$ -set $icode cap$$ to the number of $icode Scalar$$ objects that -could fit in the memory currently allocated for $icode vec$$. -Note that -$codei% - %vec%.size() <= %vec%.capacity() -%$$ - -$head swap$$ -$icode%vec%.swap(%other%) -%$$ -exchanges the contents of $icode vec$$ and $icode other$$. -For example $cref/vec.data()/CppAD_vector/data/$$ after the $code swap$$ -is equal to $icode%other%.data()%$$ before $code swap$$. - - -$head Assignment$$ -$icode%vec% = %other% -%$$ -has all the properties listed for a -$cref/simple vector assignment/SimpleVector/Assignment/$$ -plus the following: - -$subhead Check Size$$ -The size of $icode vec$$ must be either zero -or the same size as $icode other$$ before doing the assignment. -If this is not the case, and $code NDEBUG$$ is not defined, -$code CppAD::vector$$ will use -$cref ErrorHandler$$ -to generate an appropriate error report. -Requiring the sizes to agree checks that memory will not need to -be allocated to do the assignment (except when $icode vec$$ is empty). -Allowing for assignment to a vector with size zero makes the following -code work: -$codei% - CppAD::vector<%Scalar%> %vec%; - %vec% = %other%; -%$$ - -$subhead Return Reference$$ -A reference to the vector $icode vec$$ is returned. -An example use of this reference is in multiple assignments of the form -$codei% - %vec% = %other% = %another% -%$$ -where $icode another$$ is a $codei%CppAD::vector<%Scalar%>%$$ object. - -$subhead Move Semantics$$ -If the C++ compiler supports move semantic rvalues using the $code &&$$ -syntax, then it will be used during the vector assignment statement. -This means that return values and other temporaries are not be copied, -but rather pointers are transferred. - -$head Element Access$$ -If $icode i$$ has type $code size_t$$, -$codei% - %vec%[%i%] -%$$ -has all the properties listed for a -$cref/simple vector element access/SimpleVector/Element Access/$$ -plus the following: - -$subhead i$$ -This operation is defined for any $icode i$$ -that has a conversion to $code size_t$$. -The object $icode%vec%[%i%]%$$ has type $icode Scalar$$ -(is not possibly a different type that can be converted to $icode Scalar$$). - -$subhead Error Checking$$ -If $icode i$$ is not less than the size of the $icode vec$$, -and $code NDEBUUG$$ is not defined, -$code CppAD::vector$$ will use -$cref ErrorHandler$$ -to generate an appropriate error report. - -$head push_back$$ -If $icode vec$$ has size $icode n$$ and -$icode scalar$$ has type $icode Scalar$$, -$codei% - %vec%.push_back(%scalar%) -%$$ -extends the vector so that its new size is $icode%n%+1%$$ -and $icode%vec%[%n%]%$$ is equal to $icode s$$ -(equal in the sense of the $icode Scalar$$ assignment operator). - -$head push_vector$$ -If $icode vec$$ has size $icode n$$ and -$icode simple_vec$$ is a $cref/simple vector/SimpleVector/$$ -with elements of type $icode Scalar$$ and size $icode m$$, -$codei% - %vec%.push_vector(%simple_vec%) -%$$ -extends the vector $icode vec$$ so that its new size is $icode%n%+%m%$$ -and $icode%vec%[%n% + %i%]%$$ is equal to $icode%simple_vec%[%i%]%$$ -for $icode%i = 1 , ... , m-1%$$ -(equal in the sense of the $icode Scalar$$ assignment operator). - -$head Output$$ -If $icode os$$ is an $code std::ostream$$, the operation -$codei% - %os% << %vec% -%$$ -will output $icode vec$$ to the standard output stream $icode os$$. -The elements of $icode vec$$ are enclosed at the beginning by a -$code {$$ character, -they are separated by $code ,$$ characters, -and they are enclosed at the end by $code }$$ character. -It is assumed by this operation that if $icode scalar$$ -is an object with type $icode Scalar$$, -$codei% - %os% << %scalar% -%$$ -will output the value $icode scalar$$ to $icode os$$. - -$head resize$$ -If $icode n$$ is a $code size_t$$, -$codei% - %vec%.resize(%n%) -%$$ -sets the size of $icode vec$$ equal to $icode n$$. - -$subhead data$$ -The elements in $icode vec$$ before the resize operation are preserved. - -$subhead memory$$ -If before the resize, $icode%n% <= %vec%.capacity()%$$, -no memory is freed or allocated and -the capacity of $icode vec$$ does not change. -Otherwise, new memory is allocated and the elements before the resize -are copied to the new memory. -If you do not need to the elements previously in the vector, -you can resize to zero and then to the new size to avoid the copy. - -$head clear$$ -$icode%vec%.clear() -%$$ -frees all memory allocated for $icode vec$$ -and both its size and capacity are set to zero. -This can be useful when using very large vectors -and when checking for memory leaks (and there are global vectors) -see the $cref/memory/CppAD_vector/Memory and Parallel Mode/$$ discussion. - -$head data$$ -$icode%vec%.data() -%$$ -returns a pointer to a $icode Scalar$$ object such that for -$codei%0 <= %i% < %vec%.size()%$$, -$icode%vec%[%i%]%$$ and $icode%vec%.data()[%i%]%$$ -are the same $icode Scalar$$ object. -If $icode vec$$ is $code const$$, the pointer is $code const$$. -If $icode%vec%.capacity()%$$ is zero, the value of the pointer is not defined. -The pointer may no longer be valid after the following operations on -$icode vec$$: -its destructor, -$code clear$$, -$code resize$$, -$code push_back$$, -$code push_vector$$, -assignment to another vector when original size of $icode vec$$ is zero. - -$head Iterators$$ - -$subhead Syntax$$ -$codei%typename CppAD::vector<%Scalar%>::iterator -%$$ -$codei%typename CppAD::vector<%Scalar%>::const_iterator -%$$ -$icode%vec%.begin() -%$$ -$icode%vec%.end() -%$$ - -$subhead iterator$$ -is a random access iterator type for non $code const$$ objects. - -$subhead const_iterator$$ -is a random access iterator type for a $code const$$ objects. -An $code iterator$$ can be converted to a $code const_iterator$$, -but not the other way around. - -$subhead begin$$ -is an iterator corresponding to the first element of the vector. -It is a $code const_iterator$$ ($code iterator$$) -depending on if $icode vec$$ is $code const$$ (not $code const$$) - -$subhead end$$ -is an iterator corresponding to just beyond the last element of the vector. -It is a $code const_iterator$$ ($code iterator$$) -depending on if $icode vec$$ is $code const$$ (not $code const$$) - -$subhead Error Checking$$ -Each element access (dereference of the iterator) -does an error check similar to the element access -$cref/error checking/CppAD_vector/Element Access/Error Checking/$$ above. -The error handler will also be called, -if $code NDEBUG$$ is not defined and -a comparison operator (e.g. $code >$$) is used between -two iterators that correspond to different vectors. - -$head vectorBool$$ -The file $code $$ defines the class -$code CppAD::vectorBool$$. -This has the same specifications as $code CppAD::vector$$ -with the following exceptions: - -$subhead Memory$$ -The class $code vectorBool$$ conserves on memory, -on the other hand, $code CppAD::vector$$ is expected to be faster -than $code vectorBool$$. - -$subhead bit_per_unit$$ -The static function call -$codei% - %size% = vectorBool::bit_per_unit() -%$$ -returns the $code size_t$$ value $icode s$$ -which is equal to the number of boolean values (bits) that are -packed into one operation unit. -Bits are accessed using a mask with the size of an operation unit. - -$subhead data$$ -The $cref/data/CppAD_vector/data/$$ function is not supported by -$code vectorBool$$. - -$subhead Iterators$$ -The $cref/Iterators/CppAD_vector/Iterators/$$ are not supported by -$code vectorBool$$. - -$subhead Output$$ -The $code CppAD::vectorBool$$ output operator -prints each boolean value as -a $code 0$$ for false, -a $code 1$$ for true, -and does not print any other output; i.e., -the vector is written a long sequence of zeros and ones with no -surrounding $code {$$, $code }$$ and with no separating commas or spaces. - -$subhead Element Type$$ -If $icode vec_bool$$ has type $code vectorBool$$ -and $icode i$$ has type $code size_t$$, -the element access value $icode%vec_bool%[%i%]%$$ has an unspecified type, -referred to here as $icode element_t$$, that supports the following -operations: - -$list number$$ -$icode element_t$$ can be converted to $code bool$$; e.g. -the following syntax is supported: -$codei% - static_cast( %vec_bool%[%i%] ) -%$$ - -$lnext -$icode element_t$$ supports the assignment operator $code =$$ where the -right hand side is a $code bool$$ or an $icode element_t$$ object; e.g., -if $icode flag$$ has type $code bool$$, the following syntax is supported: -$codei% - %vec_bool%[%i%] = %flag% -%$$ - -$lnext -The result of an assignment to an $icode element_t$$ -also has type $icode element_t$$. -For example, if $icode other_flag$$ has type $code bool$$, -the following syntax is supported: -$codei% - %other_flag% = %vec_bool%[%i%] = %flag% -%$$ -$lend - -$head Memory and Parallel Mode$$ -These vectors use the multi-threaded fast memory allocator -$cref thread_alloc$$: - -$list number$$ -The $cref/hold_memory/ta_hold_memory/$$ routine can be used -to make memory allocation faster. -$lnext -The routine $cref/parallel_setup/ta_parallel_setup/$$ must -be called before these vectors can be used -$cref/in parallel/ta_in_parallel/$$. -$lnext -Using these vectors affects the amount of memory -$cref/in_use/ta_inuse/$$ and $cref/available/ta_available/$$. -$lnext -Calling $cref/clear/CppAD_vector/clear/$$, -makes the corresponding memory available (though $code thread_alloc$$) -to the current thread. -$lnext -Available memory -can then be completely freed using $cref/free_available/ta_free_available/$$. -$lend - -$head Example$$ -$children% - example/utility/cppad_vector.cpp% - example/utility/vector_bool.cpp -%$$ -The files -$cref cppad_vector.cpp$$ and -$cref vector_bool.cpp$$ each -contain an example and test of this template class. -They return true if they succeed and false otherwise. - -$head Exercise$$ -Create and run a program that contains the following code: -$codep - CppAD::vector x(3); - size_t i; - for(i = 0; i < 3; i++) - x[i] = 4. - i; - std::cout << "x = " << x << std::endl; -$$ - -$end diff --git a/build-config/cppad/include/cppad/utility/omh/dev_cppad_vector.omh b/build-config/cppad/include/cppad/utility/omh/dev_cppad_vector.omh deleted file mode 100644 index 21843232..00000000 --- a/build-config/cppad/include/cppad/utility/omh/dev_cppad_vector.omh +++ /dev/null @@ -1,29 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -$begin dev_cppad_vector$$ -$spell - CppAD -$$ - - -$section The CppAD Vector Template Class Developer Documentation$$ - -$head User API$$ -$cref cppad_vector$$ - -$childtable% - include/cppad/local/utility/cppad_vector_itr.hpp% - include/cppad/utility/vector.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/utility/omh/dev_utility.omh b/build-config/cppad/include/cppad/utility/omh/dev_utility.omh deleted file mode 100644 index 7b803bdf..00000000 --- a/build-config/cppad/include/cppad/utility/omh/dev_utility.omh +++ /dev/null @@ -1,25 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ - -$begin dev_utility$$ -$spell -$$ - - -$section General Purpose Utilities Developer Documentation$$ - -$childtable% - include/cppad/utility/omh/dev_cppad_vector.omh% - include/cppad/utility/omh/dev_vector_bool.omh -%$$ - -$end diff --git a/build-config/cppad/include/cppad/utility/omh/dev_vector_bool.omh b/build-config/cppad/include/cppad/utility/omh/dev_vector_bool.omh deleted file mode 100644 index 587eb822..00000000 --- a/build-config/cppad/include/cppad/utility/omh/dev_vector_bool.omh +++ /dev/null @@ -1,30 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -$begin dev_vector_bool$$ -$spell - CppAD - Bool -$$ - - -$section vectorBool Developer Documentation$$ - -$head User API$$ -$cref/vectorBool/CppAD_vector/vectorBool/$$ - -$childtable% - include/cppad/local/utility/vector_bool.hpp% - include/cppad/utility/vector_bool.hpp -%$$ - -$end diff --git a/build-config/cppad/include/cppad/utility/omh/utility.omh b/build-config/cppad/include/cppad/utility/omh/utility.omh deleted file mode 100644 index 769093c3..00000000 --- a/build-config/cppad/include/cppad/utility/omh/utility.omh +++ /dev/null @@ -1,156 +0,0 @@ -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - - CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - - This Source Code may also be made available under the following - Secondary License when the conditions for such availability set forth - in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. --------------------------------------------------------------------------- */ - -$begin utility$$ -$spell - CppAD - namespace - alloc - cppad.hpp -$$ - - -$section Some General Purpose Utilities$$ -These routines can be include individually; for example, -$codep - # include -$$ -only includes the definitions necessary for the $code CppAD::vector$$ class. -They can also be included as a group, separate from the rest of CppAD, using -$codep - # include -$$ -They will also be included, along with the rest of CppAD, using -$codep - # include -$$ - -$children% - include/cppad/utility/error_handler.hpp% - - include/cppad/utility/near_equal.hpp% - include/cppad/utility/speed_test.hpp% - include/cppad/utility/time_test.hpp% - include/cppad/utility/test_boolofvoid.hpp% - - omh/numeric_type.omh% - include/cppad/utility/check_numeric_type.hpp% - omh/simple_vector.omh% - include/cppad/utility/check_simple_vector.hpp% - - include/cppad/utility/nan.hpp% - include/cppad/utility/pow_int.hpp% - include/cppad/utility/poly.hpp% - omh/lu_det_and_solve.omh% - include/cppad/utility/romberg_one.hpp% - include/cppad/utility/romberg_mul.hpp% - include/cppad/utility/runge_45.hpp% - include/cppad/utility/rosen_34.hpp% - include/cppad/utility/ode_err_control.hpp% - include/cppad/utility/ode_gear.hpp% - include/cppad/utility/ode_gear_control.hpp% - - include/cppad/utility/omh/cppad_vector.omh% - omh/thread_alloc.omh% - include/cppad/utility/index_sort.hpp% - include/cppad/utility/to_string.hpp% - include/cppad/utility/set_union.hpp% - include/cppad/utility/sparse_rc.hpp% - include/cppad/utility/sparse_rcv.hpp% - include/cppad/utility/sparse2eigen.hpp -%$$ - -$head Testing$$ -The routines listed below support numerical correctness and speed testing: -$table -$rref NearEqual$$ -$rref time_test$$ -$rref speed_test$$ -$rref SpeedTest$$ -$rref test_boolofvoid$$ -$tend - -$head C++ Concepts$$ -We refer to a the set of classes that satisfy certain conditions -as a C++ concept. -The following concepts are used by the CppAD Template library: -$table -$rref NumericType$$ -$rref CheckNumericType$$ -$rref SimpleVector$$ -$rref CheckSimpleVector$$ -$tend - - -$head General Numerical Routines$$ -The routines listed below are general purpose numerical routines -written with the floating point type a C++ template parameter. -This enables them to be used with algorithmic differentiation types, -as well as for other purposes. -$table -$rref nan$$ -$rref pow_int$$ -$rref Poly$$ -$rref LuDetAndSolve$$ -$rref RombergOne$$ -$rref RombergMul$$ -$rref Runge45$$ -$rref Rosen34$$ -$rref OdeErrControl$$ -$rref OdeGear$$ -$rref OdeGearControl$$ -$tend - -$head Miscellaneous$$ - -$subhead Error Handler$$ -All of the routines in the CppAD namespace use the following -general purpose error handler: -$table -$rref ErrorHandler$$ -$tend - -$subhead The CppAD Vector Template Class$$ -This is a simple implementation of a template vector class -(that is easy to view in a C++ debugger): -$table -$rref CppAD_vector$$ -$tend - -$subhead Multi-Threading Memory Allocation$$ -$table -$rref thread_alloc$$ -$tend - -$subhead Sorting Indices$$ -$table -$rref index_sort$$ -$tend - -$subhead to_string$$ -$table -$rref to_string$$ -$tend - -$subhead set_union$$ -$table -$rref set_union$$ -$tend - -$subhead Sparse Matrices$$ -$table -$rref sparse_rc$$ -$rref sparse_rcv$$ -$rref sparse2eigen$$ -$tend - -$end diff --git a/build-config/cppad/include/cppad/utility/omp_alloc.hpp b/build-config/cppad/include/cppad/utility/omp_alloc.hpp deleted file mode 100644 index 2b305f3f..00000000 --- a/build-config/cppad/include/cppad/utility/omp_alloc.hpp +++ /dev/null @@ -1,747 +0,0 @@ -# ifndef CPPAD_UTILITY_OMP_ALLOC_HPP -# define CPPAD_UTILITY_OMP_ALLOC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -# include -# ifdef _OPENMP -# include -# endif - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -class omp_alloc{ -// ============================================================================ -public: -/* -$begin omp_max_num_threads$$ -$spell - cppad.hpp - inv - CppAD - num - omp_alloc -$$ -$section Set and Get Maximum Number of Threads for omp_alloc Allocator$$ - -$head Deprecated 2011-08-31$$ -Use the functions $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$ -and $cref/thread_alloc:num_threads/ta_num_threads/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$codei%omp_alloc::set_max_num_threads(%number%) -%$$ -$icode%number% = omp_alloc::get_max_num_threads() -%$$ - -$head Purpose$$ -By default there is only one thread and all execution is in sequential mode -(not $cref/parallel/omp_in_parallel/$$). - -$head number$$ -The argument and return value $icode number$$ has prototype -$codei% - size_t %number% -%$$ -and must be greater than zero. - -$head set_max_num_threads$$ -Informs $cref omp_alloc$$ of the maximum number of OpenMP threads. - -$head get_max_num_threads$$ -Returns the valued used in the previous call to $code set_max_num_threads$$. -If there was no such previous call, the value one is returned -(and only thread number zero can use $cref omp_alloc$$). - -$head Restrictions$$ -The function $code set_max_num_threads$$ must be called before -the program enters $cref/parallel/omp_in_parallel/$$ execution mode. -In addition, this function cannot be called while in parallel mode. - -$end -*/ - /*! - Inform omp_alloc of the maximum number of OpenMP threads and enable - parallel execution mode by initializing all statics in this file. - - \param number [in] - maximum number of OpenMP threads. - */ - static void set_max_num_threads(size_t number) - { thread_alloc::parallel_setup( - number, omp_alloc::in_parallel, omp_alloc::get_thread_num - ); - thread_alloc::hold_memory(number > 1); - } - /*! - Get the current maximum number of OpenMP threads that omp_alloc can use. - - \return - maximum number of OpenMP threads. - */ - static size_t get_max_num_threads(void) - { return thread_alloc::num_threads(); } - -/* ----------------------------------------------------------------------- -$begin omp_in_parallel$$ - -$section Is The Current Execution in OpenMP Parallel Mode$$ -$spell - cppad.hpp - omp_alloc - bool -$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::in_parallel/ta_in_parallel/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$icode%flag% = omp_alloc::in_parallel()%$$ - -$head Purpose$$ -Some of the $cref omp_alloc$$ allocation routines have different -specifications for parallel (not sequential) execution mode. -This routine enables you to determine if the current execution mode -is sequential or parallel. - -$head flag$$ -The return value has prototype -$codei% - bool %flag% -%$$ -It is true if the current execution is in parallel mode -(possibly multi-threaded) and false otherwise (sequential mode). - -$end -*/ - /// Are we in a parallel execution state; i.e., is it possible that - /// other threads are currently executing. - static bool in_parallel(void) - { -# ifdef _OPENMP - return omp_in_parallel() != 0; -# else - return false; -# endif - } - -/* ----------------------------------------------------------------------- -$begin omp_get_thread_num$$ -$spell - cppad.hpp - CppAD - num - omp_alloc - cppad.hpp -$$ - -$section Get the Current OpenMP Thread Number$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::thread_num/ta_thread_num/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$icode%thread% = omp_alloc::get_thread_num()%$$ - -$head Purpose$$ -Some of the $cref omp_alloc$$ allocation routines have a thread number. -This routine enables you to determine the current thread. - -$head thread$$ -The return value $icode thread$$ has prototype -$codei% - size_t %thread% -%$$ -and is the currently executing thread number. -If $code _OPENMP$$ is not defined, $icode thread$$ is zero. - -$end -*/ - /// Get current OpenMP thread number (zero if _OpenMP not defined). - static size_t get_thread_num(void) - { -# ifdef _OPENMP - size_t thread = static_cast( omp_get_thread_num() ); - return thread; -# else - return 0; -# endif - } -/* ----------------------------------------------------------------------- -$begin omp_get_memory$$ -$spell - cppad.hpp - num - ptr - omp_alloc -$$ - -$section Get At Least A Specified Amount of Memory$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::get_memory/ta_get_memory/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$icode%v_ptr% = omp_alloc::get_memory(%min_bytes%, %cap_bytes%)%$$ - -$head Purpose$$ -Use $cref omp_alloc$$ to obtain a minimum number of bytes of memory -(for use by the $cref/current thread/omp_get_thread_num/$$). - -$head min_bytes$$ -This argument has prototype -$codei% - size_t %min_bytes% -%$$ -It specifies the minimum number of bytes to allocate. - -$head cap_bytes$$ -This argument has prototype -$codei% - size_t& %cap_bytes% -%$$ -It's input value does not matter. -Upon return, it is the actual number of bytes (capacity) -that have been allocated for use, -$codei% - %min_bytes% <= %cap_bytes% -%$$ - -$head v_ptr$$ -The return value $icode v_ptr$$ has prototype -$codei% - void* %v_ptr% -%$$ -It is the location where the $icode cap_bytes$$ of memory -that have been allocated for use begins. - -$head Allocation Speed$$ -This allocation should be faster if the following conditions hold: -$list number$$ -The memory allocated by a previous call to $code get_memory$$ -is currently available for use. -$lnext -The current $icode min_bytes$$ is between -the previous $icode min_bytes$$ and previous $icode cap_bytes$$. -$lend - -$end -*/ - /*! - Use omp_alloc to get a specified amount of memory. - - If the memory allocated by a previous call to get_memory is now - avaialable, and min_bytes is between its previous value - and the previous cap_bytes, this memory allocation will have - optimal speed. Otherwise, the memory allocation is more complicated and - may have to wait for other threads to complete an allocation. - - \param min_bytes [in] - The minimum number of bytes of memory to be obtained for use. - - \param cap_bytes [out] - The actual number of bytes of memory obtained for use. - - \return - pointer to the beginning of the memory allocted for use. - */ - static void* get_memory(size_t min_bytes, size_t& cap_bytes) - { return thread_alloc::get_memory(min_bytes, cap_bytes); } - -/* ----------------------------------------------------------------------- -$begin omp_return_memory$$ -$spell - cppad.hpp - ptr - omp_alloc -$$ - -$section Return Memory to omp_alloc$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::return_memory/ta_return_memory/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$codei%omp_alloc::return_memory(%v_ptr%)%$$ - -$head Purpose$$ -If $cref omp_max_num_threads$$ is one, -the memory is returned to the system. -Otherwise, the memory is retained by $cref omp_alloc$$ for quick future use -by the thread that allocated to memory. - -$head v_ptr$$ -This argument has prototype -$codei% - void* %v_ptr% -%$$. -It must be a pointer to memory that is currently in use; i.e. -obtained by a previous call to $cref omp_get_memory$$ and not yet returned. - -$head Thread$$ -Either the $cref/current thread/omp_get_thread_num/$$ must be the same as during -the corresponding call to $cref omp_get_memory$$, -or the current execution mode must be sequential -(not $cref/parallel/omp_in_parallel/$$). - -$head NDEBUG$$ -If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster). -Otherwise, a list of in use pointers is searched to make sure -that $icode v_ptr$$ is in the list. - -$end -*/ - /*! - Return memory that was obtained by get_memory. - If max_num_threads(0) == 1, - the memory is returned to the system. - Otherwise, it is retained by omp_alloc and available for use by - get_memory for this thread. - - \param v_ptr [in] - Value of the pointer returned by get_memory and still in use. - After this call, this pointer will available (and not in use). - - \par - We must either be in sequential (not parallel) execution mode, - or the current thread must be the same as for the corresponding call - to get_memory. - */ - static void return_memory(void* v_ptr) - { thread_alloc::return_memory(v_ptr); } -/* ----------------------------------------------------------------------- -$begin omp_free_available$$ -$spell - cppad.hpp - omp_alloc -$$ - -$section Free Memory Currently Available for Quick Use by a Thread$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::free_available/ta_free_available/$$ -instead. - -$head Syntax$$ -$codei%# include -%$$ -$codei%omp_alloc::free_available(%thread%)%$$ - -$head Purpose$$ -Free memory, currently available for quick use by a specific thread, -for general future use. - -$head thread$$ -This argument has prototype -$codei% - size_t %thread% -%$$ -Either $cref omp_get_thread_num$$ must be the same as $icode thread$$, -or the current execution mode must be sequential -(not $cref/parallel/omp_in_parallel/$$). - -$end -*/ - /*! - Return all the memory being held as available for a thread to the system. - - \param thread [in] - this thread that will no longer have any available memory after this call. - This must either be the thread currently executing, or we must be - in sequential (not parallel) execution mode. - */ - static void free_available(size_t thread) - { thread_alloc::free_available(thread); } -/* ----------------------------------------------------------------------- -$begin omp_inuse$$ -$spell - cppad.hpp - num - inuse - omp_alloc -$$ - -$section Amount of Memory a Thread is Currently Using$$ - -$head Deprecated 2011-08-31$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%num_bytes% = omp_alloc::inuse(%thread%)%$$ -Use the function $cref/thread_alloc::inuse/ta_inuse/$$ instead. - -$head Purpose$$ -Memory being managed by $cref omp_alloc$$ has two states, -currently in use by the specified thread, -and quickly available for future use by the specified thread. -This function informs the program how much memory is in use. - -$head thread$$ -This argument has prototype -$codei% - size_t %thread% -%$$ -Either $cref omp_get_thread_num$$ must be the same as $icode thread$$, -or the current execution mode must be sequential -(not $cref/parallel/omp_in_parallel/$$). - -$head num_bytes$$ -The return value has prototype -$codei% - size_t %num_bytes% -%$$ -It is the number of bytes currently in use by the specified thread. - -$end -*/ - /*! - Determine the amount of memory that is currently inuse. - - \param thread [in] - Thread for which we are determining the amount of memory - (must be < CPPAD_MAX_NUM_THREADS). - Durring parallel execution, this must be the thread - that is currently executing. - - \return - The amount of memory in bytes. - */ - static size_t inuse(size_t thread) - { return thread_alloc::inuse(thread); } -/* ----------------------------------------------------------------------- -$begin omp_available$$ -$spell - cppad.hpp - num - omp_alloc -$$ - -$section Amount of Memory Available for Quick Use by a Thread$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::available/ta_available/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$icode%num_bytes% = omp_alloc::available(%thread%)%$$ - -$head Purpose$$ -Memory being managed by $cref omp_alloc$$ has two states, -currently in use by the specified thread, -and quickly available for future use by the specified thread. -This function informs the program how much memory is available. - -$head thread$$ -This argument has prototype -$codei% - size_t %thread% -%$$ -Either $cref omp_get_thread_num$$ must be the same as $icode thread$$, -or the current execution mode must be sequential -(not $cref/parallel/omp_in_parallel/$$). - -$head num_bytes$$ -The return value has prototype -$codei% - size_t %num_bytes% -%$$ -It is the number of bytes currently available for use by the specified thread. - -$end -*/ - /*! - Determine the amount of memory that is currently available for use. - - \copydetails inuse - */ - static size_t available(size_t thread) - { return thread_alloc::available(thread); } -/* ----------------------------------------------------------------------- -$begin omp_create_array$$ -$spell - cppad.hpp - omp_alloc - sizeof -$$ - -$section Allocate Memory and Create A Raw Array$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::create_array/ta_create_array/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$icode%array% = omp_alloc::create_array<%Type%>(%size_min%, %size_out%)%$$. - -$head Purpose$$ -Create a new raw array using $cref omp_alloc$$ a fast memory allocator -that works well in a multi-threading OpenMP environment. - -$head Type$$ -The type of the elements of the array. - -$head size_min$$ -This argument has prototype -$codei% - size_t %size_min% -%$$ -This is the minimum number of elements that there can be -in the resulting $icode array$$. - -$head size_out$$ -This argument has prototype -$codei% - size_t& %size_out% -%$$ -The input value of this argument does not matter. -Upon return, it is the actual number of elements -in $icode array$$ -($icode% size_min %<=% size_out%$$). - -$head array$$ -The return value $icode array$$ has prototype -$codei% - %Type%* %array% -%$$ -It is array with $icode size_out$$ elements. -The default constructor for $icode Type$$ is used to initialize the -elements of $icode array$$. -Note that $cref omp_delete_array$$ -should be used to destroy the array when it is no longer needed. - -$head Delta$$ -The amount of memory $cref omp_inuse$$ by the current thread, -will increase $icode delta$$ where -$codei% - sizeof(%Type%) * (%size_out% + 1) > %delta% >= sizeof(%Type%) * %size_out% -%$$ -The $cref omp_available$$ memory will decrease by $icode delta$$, -(and the allocation will be faster) -if a previous allocation with $icode size_min$$ between its current value -and $icode size_out$$ is available. - -$end -*/ - /*! - Use omp_alloc to Create a Raw Array. - - \tparam Type - The type of the elements of the array. - - \param size_min [in] - The minimum number of elements in the array. - - \param size_out [out] - The actual number of elements in the array. - - \return - pointer to the first element of the array. - The default constructor is used to initialize - all the elements of the array. - - \par - The extra_ field, in the omp_alloc node before the return value, - is set to size_out. - */ - template - static Type* create_array(size_t size_min, size_t& size_out) - { return thread_alloc::create_array(size_min, size_out); } -/* ----------------------------------------------------------------------- -$begin omp_delete_array$$ -$spell - cppad.hpp - omp_alloc - sizeof -$$ - -$section Return A Raw Array to The Available Memory for a Thread$$ - -$head Deprecated 2011-08-31$$ -Use the function $cref/thread_alloc::delete_array/ta_delete_array/$$ instead. - -$head Syntax$$ -$codei%# include -%$$ -$codei%omp_alloc::delete_array(%array%)%$$. - -$head Purpose$$ -Returns memory corresponding to a raw array -(create by $cref omp_create_array$$) to the -$cref omp_available$$ memory pool for the current thread. - -$head Type$$ -The type of the elements of the array. - -$head array$$ -The argument $icode array$$ has prototype -$codei% - %Type%* %array% -%$$ -It is a value returned by $cref omp_create_array$$ and not yet deleted. -The $icode Type$$ destructor is called for each element in the array. - -$head Thread$$ -The $cref/current thread/omp_get_thread_num/$$ must be the -same as when $cref omp_create_array$$ returned the value $icode array$$. -There is an exception to this rule: -when the current execution mode is sequential -(not $cref/parallel/omp_in_parallel/$$) the current thread number does not matter. - -$head Delta$$ -The amount of memory $cref omp_inuse$$ will decrease by $icode delta$$, -and the $cref omp_available$$ memory will increase by $icode delta$$, -where $cref/delta/omp_create_array/Delta/$$ -is the same as for the corresponding call to $code create_array$$. - -$end -*/ - /*! - Return Memory Used for a Raw Array to the Available Pool. - - \tparam Type - The type of the elements of the array. - - \param array [in] - A value returned by create_array that has not yet been deleted. - The Type destructor is used to destroy each of the elements - of the array. - - \par - Durring parallel execution, the current thread must be the same - as during the corresponding call to create_array. - */ - template - static void delete_array(Type* array) - { thread_alloc::delete_array(array); } -}; -/* -------------------------------------------------------------------------- -$begin omp_efficient$$ -$spell - cppad.hpp - omp_alloc - ptr - num - bool - const -$$ - -$section Check If A Memory Allocation is Efficient for Another Use$$ - -$head Removed$$ -This function has been removed because speed tests seem to indicate -it is just as fast, or faster, to free and then reallocate the memory. - -$head Syntax$$ -$codei%# include -%$$ -$icode%flag% = omp_alloc::efficient(%v_ptr%, %num_bytes%)%$$ - -$head Purpose$$ -Check if memory that is currently in use is an efficient -allocation for a specified number of bytes. - -$head v_ptr$$ -This argument has prototype -$codei% - const void* %v_ptr% -%$$. -It must be a pointer to memory that is currently in use; i.e. -obtained by a previous call to $cref omp_get_memory$$ and not yet returned. - -$head num_bytes$$ -This argument has prototype -$codei% - size_t %num_bytes% -%$$ -It specifies the number of bytes of the memory allocated by $icode v_ptr$$ -that we want to use. - -$head flag$$ -The return value has prototype -$codei% - bool %flag% -%$$ -It is true, -a call to $code get_memory$$ with -$cref/min_bytes/omp_get_memory/min_bytes/$$ -equal to $icode num_bytes$$ would result in a value for -$cref/cap_bytes/omp_get_memory/cap_bytes/$$ that is the same as when $code v_ptr$$ -was returned by $code get_memory$$; i.e., -$icode v_ptr$$ is an efficient memory block for $icode num_bytes$$ -bytes of information. - -$head Thread$$ -Either the $cref/current thread/omp_get_thread_num/$$ must be the same as during -the corresponding call to $cref omp_get_memory$$, -or the current execution mode must be sequential -(not $cref/parallel/omp_in_parallel/$$). - -$head NDEBUG$$ -If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster). -Otherwise, a list of in use pointers is searched to make sure -that $icode v_ptr$$ is in the list. - -$end ---------------------------------------------------------------------------- -$begin old_max_num_threads$$ -$spell - cppad.hpp - inv - CppAD - num - omp_alloc -$$ -$section Set Maximum Number of Threads for omp_alloc Allocator$$ - -$head Removed$$ -This function has been removed from the CppAD API. -Use the function $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$ -in its place. - -$head Syntax$$ -$codei%# include -%$$ -$codei%omp_alloc::max_num_threads(%number%)%$$ - -$head Purpose$$ -By default there is only one thread and all execution is in sequential mode -(not $cref/parallel/omp_in_parallel/$$). - -$head number$$ -The argument $icode number$$ has prototype -$codei% - size_t %number% -%$$ -It must be greater than zero and specifies the maximum number of -OpenMP threads that will be active at one time. - -$head Restrictions$$ -This function must be called before the program enters -$cref/parallel/omp_in_parallel/$$ execution mode. - -$end -------------------------------------------------------------------------------- -*/ -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/utility/poly.hpp b/build-config/cppad/include/cppad/utility/poly.hpp deleted file mode 100644 index 13588bbf..00000000 --- a/build-config/cppad/include/cppad/utility/poly.hpp +++ /dev/null @@ -1,192 +0,0 @@ -# ifndef CPPAD_UTILITY_POLY_HPP -# define CPPAD_UTILITY_POLY_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin Poly$$ -$spell - cppad.hpp - CppAD - namespace - cstddef - ifndef - endif - deg - const - std - da -$$ - - -$section Evaluate a Polynomial or its Derivative$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%p% = Poly(%k%, %a%, %z%)%$$ - - -$head Description$$ -Computes the $th k$$ derivative of the polynomial -$latex \[ - P(z) = a_0 + a_1 z^1 + \cdots + a_d z^d -\] $$ -If $icode k$$ is equal to zero, the return value is $latex P(z)$$. - -$head Include$$ -The file $code cppad/utility/poly.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. -Including this file defines -$code Poly$$ within the $code CppAD$$ namespace. - -$head k$$ -The argument $icode k$$ has prototype -$codei% - size_t %k% -%$$ -It specifies the order of the derivative to calculate. - -$head a$$ -The argument $icode a$$ has prototype -$codei% - const %Vector% &%a% -%$$ -(see $cref/Vector/Poly/Vector/$$ below). -It specifies the vector corresponding to the polynomial $latex P(z)$$. - -$head z$$ -The argument $icode z$$ has prototype -$codei% - const %Type% &%z% -%$$ -(see $icode Type$$ below). -It specifies the point at which to evaluate the polynomial - -$head p$$ -The result $icode p$$ has prototype -$codei% - %Type% %p% -%$$ -(see $cref/Type/Poly/Type/$$ below) -and it is equal to the $th k$$ derivative of $latex P(z)$$; i.e., -$latex \[ -p = \frac{k !}{0 !} a_k - + \frac{(k+1) !}{1 !} a_{k+1} z^1 - + \ldots - + \frac{d !}{(d - k) !} a_d z^{d - k} -\] -$$ -If $latex k > d$$, $icode%p% = %Type%(0)%$$. - -$head Type$$ -The type $icode Type$$ is determined by the argument $icode z$$. -It is assumed that -multiplication and addition of $icode Type$$ objects -are commutative. - -$subhead Operations$$ -The following operations must be supported where -$icode x$$ and $icode y$$ are objects of type $icode Type$$ -and $icode i$$ is an $code int$$: -$table -$icode%x% = %i%$$ $cnext assignment $rnext -$icode%x% = %y%$$ $cnext assignment $rnext -$icode%x% *= %y%$$ $cnext multiplication compound assignment $rnext -$icode%x% += %y%$$ $cnext addition compound assignment - -$tend - - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type/SimpleVector/Elements of Specified Type/$$ -$icode Type$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Operation Sequence$$ -The $icode Type$$ operation sequence used to calculate $icode p$$ is -$cref/independent/glossary/Operation/Independent/$$ -of $icode z$$ and the elements of $icode a$$ -(it does depend on the size of the vector $icode a$$). - - -$children% - example/utility/poly.cpp% - omh/poly_hpp.omh -%$$ - -$head Example$$ -The file -$cref poly.cpp$$ -contains an example and test of this routine. - -$head Source$$ -The file $cref poly.hpp$$ contains the -current source code that implements these specifications. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN C++ -# include // used to defined size_t -# include - -namespace CppAD { // BEGIN CppAD namespace - -template -Type Poly(size_t k, const Vector &a, const Type &z) -{ size_t i; - size_t d = a.size() - 1; - - Type tmp; - - // check Vector is Simple Vector class with Type elements - CheckSimpleVector(); - - // case where derivative order greater than degree of polynomial - if( k > d ) - { tmp = 0; - return tmp; - } - // case where we are evaluating a derivative - if( k > 0 ) - { // initialize factor as (k-1) ! - size_t factor = 1; - for(i = 2; i < k; i++) - factor *= i; - - // set b to coefficient vector corresponding to derivative - Vector b(d - k + 1); - for(i = k; i <= d; i++) - { factor *= i; - tmp = double( factor ); - b[i - k] = a[i] * tmp; - factor /= (i - k + 1); - } - // value of derivative polynomial - return Poly(0, b, z); - } - // case where we are evaluating the original polynomial - Type sum = a[d]; - i = d; - while(i > 0) - { sum *= z; - sum += a[--i]; - } - return sum; -} -} // END CppAD namespace -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/utility/pow_int.hpp b/build-config/cppad/include/cppad/utility/pow_int.hpp deleted file mode 100644 index 2150fbc8..00000000 --- a/build-config/cppad/include/cppad/utility/pow_int.hpp +++ /dev/null @@ -1,140 +0,0 @@ -# ifndef CPPAD_UTILITY_POW_INT_HPP -# define CPPAD_UTILITY_POW_INT_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------------- -$begin pow_int$$ -$spell - cppad.hpp - CppAD - namespace - const -$$ - - -$section The Integer Power Function$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%z% = pow(%x%, %y%)%$$ - -$head See Also$$ -$cref pow$$ - -$head Purpose$$ -Determines the value of the power function -$latex \[ - {\rm pow} (x, y) = x^y -\] $$ -for integer exponents $icode n$$ -using multiplication and possibly division to compute the value. -The other CppAD $cref pow$$ function may use logarithms and exponentiation -to compute derivatives of the same value -(which will not work if $icode x$$ is less than or equal zero). - -$head Include$$ -The file $code cppad/utility/pow_int.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. -Including this file defines -this version of the $code pow$$ within the $code CppAD$$ namespace. - -$head x$$ -The argument $icode x$$ has prototype -$codei% - const %Type%& %x% -%$$ - -$head y$$ -The argument $icode y$$ has prototype -$codei% - const int& %y% -%$$ - -$head z$$ -The result $icode z$$ has prototype -$codei% - %Type% %z% -%$$ - -$head Type$$ -The type $icode Type$$ must support the following operations -where $icode a$$ and $icode b$$ are $icode Type$$ objects -and $icode i$$ is an $code int$$: -$table -$bold Operation$$ $pre $$ - $cnext $bold Description$$ - $cnext $bold Result Type$$ -$rnext -$icode%Type% %a%(%i%)%$$ - $cnext construction of a $icode Type$$ object from an $code int$$ - $cnext $icode Type$$ -$rnext -$icode%a% * %b%$$ - $cnext binary multiplication of $icode Type$$ objects - $cnext $icode Type$$ -$rnext -$icode%a% / %b%$$ - $cnext binary division of $icode Type$$ objects - $cnext $icode Type$$ -$tend - -$head Operation Sequence$$ -The $icode Type$$ operation sequence used to calculate $icode z$$ is -$cref/independent/glossary/Operation/Independent/$$ -of $icode x$$. - -$head Example$$ -$children% - example/utility/pow_int.cpp -%$$ -The file $cref pow_int.cpp$$ -is an example and test of this function. - - -$end -------------------------------------------------------------------------------- -*/ - -namespace CppAD { - - template - inline Type pow (const Type& x, const int& n) - { - Type p(1); - int n2 = n / 2; - - if( n == 0 ) - return p; - if( n < 0 ) - return p / pow(x, -n); - if( n == 1 ) - return x; - - // p = (x^2)^(n/2) - p = pow( x * x , n2 ); - - // n is even case - if( n % 2 == 0 ) - return p; - - // n is odd case - return p * x; - } - -} - -# endif diff --git a/build-config/cppad/include/cppad/utility/romberg_mul.hpp b/build-config/cppad/include/cppad/utility/romberg_mul.hpp deleted file mode 100644 index e4575382..00000000 --- a/build-config/cppad/include/cppad/utility/romberg_mul.hpp +++ /dev/null @@ -1,325 +0,0 @@ -# ifndef CPPAD_UTILITY_ROMBERG_MUL_HPP -# define CPPAD_UTILITY_ROMBERG_MUL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin RombergMul$$ -$spell - cppad.hpp - bool - const - Cpp - RombergMulMul -$$ - -$section Multi-dimensional Romberg Integration$$ - - -$head Syntax$$ -$codei%# include -%$$ -$codei%RombergMul<%Fun%, %SizeVector%, %FloatVector%, %m%> %R%$$ -$pre -$$ -$icode%r% = %R%(%F%, %a%, %b%, %n%, %p%, %e%)%$$ - - -$head Description$$ -Returns the Romberg integration estimate -$latex r$$ for the multi-dimensional integral -$latex \[ -r = -\int_{a[0]}^{b[0]} \cdots \int_{a[m-1]}^{b[m-1]} -\; F(x) \; -{\bf d} x_0 \cdots {\bf d} x_{m-1} -\; + \; -\sum_{i=0}^{m-1} -O \left[ ( b[i] - a[i] ) / 2^{n[i]-1} \right]^{2(p[i]+1)} -\] $$ - -$head Include$$ -The file $code cppad/utility/romberg_mul.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head m$$ -The template parameter $icode m$$ must be convertible to a $code size_t$$ -object with a value that can be determined at compile time; for example -$code 2$$. -It determines the dimension of the domain space for the integration. - -$head r$$ -The return value $icode r$$ has prototype -$codei% - %Float% %r% -%$$ -It is the estimate computed by $code RombergMul$$ for the integral above -(see description of $cref/Float/RombergMul/Float/$$ below). - -$head F$$ -The object $icode F$$ has the prototype -$codei% - %Fun% &%F% -%$$ -It must support the operation -$codei% - %F%(%x%) -%$$ -The argument $icode x$$ to $icode F$$ has prototype -$codei% - const %Float% &%x% -%$$ -The return value of $icode F$$ is a $icode Float$$ object - -$head a$$ -The argument $icode a$$ has prototype -$codei% - const %FloatVector% &%a% -%$$ -It specifies the lower limit for the integration -(see description of $cref/FloatVector/RombergMul/FloatVector/$$ below). - -$head b$$ -The argument $icode b$$ has prototype -$codei% - const %FloatVector% &%b% -%$$ -It specifies the upper limit for the integration. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - const %SizeVector% &%n% -%$$ -A total number of $latex 2^{n[i]-1} + 1$$ -evaluations of $icode%F%(%x%)%$$ are used to estimate the integral -with respect to $latex {\bf d} x_i$$. - -$head p$$ -The argument $icode p$$ has prototype -$codei% - const %SizeVector% &%p% -%$$ -For $latex i = 0 , \ldots , m-1$$, -$latex n[i]$$ determines the accuracy order in the -approximation for the integral -that is returned by $code RombergMul$$. -The values in $icode p$$ must be less than or equal $icode n$$; i.e., -$icode%p%[%i%] <= %n%[%i%]%$$. - -$head e$$ -The argument $icode e$$ has prototype -$codei% - %Float% &%e% -%$$ -The input value of $icode e$$ does not matter -and its output value is an approximation for the absolute error in -the integral estimate. - -$head Float$$ -The type $icode Float$$ is defined as the type of the elements of -$cref/FloatVector/RombergMul/FloatVector/$$. -The type $icode Float$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, if $icode x$$ and $icode y$$ are $icode Float$$ objects, -$codei% - %x% < %y% -%$$ -returns the $code bool$$ value true if $icode x$$ is less than -$icode y$$ and false otherwise. - -$head FloatVector$$ -The type $icode FloatVector$$ must be a $cref SimpleVector$$ class. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - - -$children% - example/utility/romberg_mul.cpp -%$$ -$head Example$$ -$comment% - example/utility/romberg_mul.cpp -%$$ -The file -$cref Rombergmul.cpp$$ -contains an example and test a test of using this routine. - -$head Source Code$$ -The source code for this routine is in the file -$code cppad/romberg_mul.hpp$$. - -$end -*/ - -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -template -class SliceLast { - typedef typename FloatVector::value_type Float; -private: - Fun *F; - size_t last; - FloatVector x; -public: - SliceLast( Fun *F_, size_t last_, const FloatVector &x_ ) - : F(F_) , last(last_), x(last + 1) - { size_t i; - for(i = 0; i < last; i++) - x[i] = x_[i]; - } - double operator()(const Float &xlast) - { x[last] = xlast; - return (*F)(x); - } -}; - -template -class IntegrateLast { -private: - Fun *F; - const size_t last; - const FloatVector a; - const FloatVector b; - const SizeVector n; - const SizeVector p; - Float esum; - size_t ecount; - -public: - IntegrateLast( - Fun *F_ , - size_t last_ , - const FloatVector &a_ , - const FloatVector &b_ , - const SizeVector &n_ , - const SizeVector &p_ ) - : F(F_) , last(last_), a(a_) , b(b_) , n(n_) , p(p_) - { } - Float operator()(const FloatVector &x) - { Float r, e; - SliceLast S(F, last, x); - r = CppAD::RombergOne( - S, a[last], b[last], n[last], p[last], e - ); - esum = esum + e; - ecount++; - return r; - } - void ClearEsum(void) - { esum = 0.; } - Float GetEsum(void) - { return esum; } - - void ClearEcount(void) - { ecount = 0; } - size_t GetEcount(void) - { return ecount; } -}; - -template -class RombergMul { - typedef typename FloatVector::value_type Float; -public: - RombergMul(void) - { } - Float operator() ( - Fun &F , - const FloatVector &a , - const FloatVector &b , - const SizeVector &n , - const SizeVector &p , - Float &e ) - { Float r; - - typedef IntegrateLast< - Fun , - SizeVector , - FloatVector , - Float > IntegrateOne; - - IntegrateOne Fm1(&F, m-1, a, b, n, p); - RombergMul< - IntegrateOne, - SizeVector , - FloatVector , - m-1 > RombergMulM1; - - Fm1.ClearEsum(); - Fm1.ClearEcount(); - - r = RombergMulM1(Fm1, a, b, n, p, e); - - size_t i, j; - Float prod = 1; - size_t pow2 = 1; - for(i = 0; i < m-1; i++) - { prod *= (b[i] - a[i]); - for(j = 0; j < (n[i] - 1); j++) - pow2 *= 2; - } - assert( Fm1.GetEcount() == (pow2+1) ); - - e = e + Fm1.GetEsum() * prod / Float( double(Fm1.GetEcount()) ); - - return r; - } -}; - -template -class RombergMul { - typedef typename FloatVector::value_type Float; -public: - Float operator() ( - Fun &F , - const FloatVector &a , - const FloatVector &b , - const SizeVector &n , - const SizeVector &p , - Float &e ) - { Float r; - typedef IntegrateLast< - Fun , - SizeVector , - FloatVector , - Float > IntegrateOne; - - // check simple vector class specifications - CheckSimpleVector(); - - // check numeric type specifications - CheckNumericType(); - - IntegrateOne F0(&F, 0, a, b, n, p); - - F0.ClearEsum(); - F0.ClearEcount(); - - r = F0(a); - - assert( F0.GetEcount() == 1 ); - e = F0.GetEsum(); - - return r; - } -}; - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/romberg_one.hpp b/build-config/cppad/include/cppad/utility/romberg_one.hpp deleted file mode 100644 index 8255d329..00000000 --- a/build-config/cppad/include/cppad/utility/romberg_one.hpp +++ /dev/null @@ -1,213 +0,0 @@ -# ifndef CPPAD_UTILITY_ROMBERG_ONE_HPP -# define CPPAD_UTILITY_ROMBERG_ONE_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin RombergOne$$ -$spell - cppad.hpp - bool - const - Cpp - RombergOne -$$ - -$section One DimensionalRomberg Integration$$ - - -$head Syntax$$ -$codei%# include -%$$ -$icode%r% = RombergOne(%F%, %a%, %b%, %n%, %e%)%$$ - - -$head Description$$ -Returns the Romberg integration estimate -$latex r$$ for a one dimensional integral -$latex \[ -r = \int_a^b F(x) {\bf d} x + O \left[ (b - a) / 2^{n-1} \right]^{2(p+1)} -\] $$ - -$head Include$$ -The file $code cppad/utility/romberg_one.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head r$$ -The return value $icode r$$ has prototype -$codei% - %Float% %r% -%$$ -It is the estimate computed by $code RombergOne$$ for the integral above. - -$head F$$ -The object $icode F$$ can be of any type, but it must support -the operation -$codei% - %F%(%x%) -%$$ -The argument $icode x$$ to $icode F$$ has prototype -$codei% - const %Float% &%x% -%$$ -The return value of $icode F$$ is a $icode Float$$ object -(see description of $cref/Float/RombergOne/Float/$$ below). - -$head a$$ -The argument $icode a$$ has prototype -$codei% - const %Float% &%a% -%$$ -It specifies the lower limit for the integration. - -$head b$$ -The argument $icode b$$ has prototype -$codei% - const %Float% &%b% -%$$ -It specifies the upper limit for the integration. - -$head n$$ -The argument $icode n$$ has prototype -$codei% - size_t %n% -%$$ -A total number of $latex 2^{n-1} + 1$$ evaluations of $icode%F%(%x%)%$$ -are used to estimate the integral. - -$head p$$ -The argument $icode p$$ has prototype -$codei% - size_t %p% -%$$ -It must be less than or equal $latex n$$ -and determines the accuracy order in the approximation for the integral -that is returned by $code RombergOne$$. -To be specific -$latex \[ -r = \int_a^b F(x) {\bf d} x + O \left[ (b - a) / 2^{n-1} \right]^{2(p+1)} -\] $$ - - -$head e$$ -The argument $icode e$$ has prototype -$codei% - %Float% &%e% -%$$ -The input value of $icode e$$ does not matter -and its output value is an approximation for the error in -the integral estimates; i.e., -$latex \[ - e \approx \left| r - \int_a^b F(x) {\bf d} x \right| -\] $$ - -$head Float$$ -The type $icode Float$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, if $icode x$$ and $icode y$$ are $icode Float$$ objects, -$codei% - %x% < %y% -%$$ -returns the $code bool$$ value true if $icode x$$ is less than -$icode y$$ and false otherwise. - -$children% - example/utility/romberg_one.cpp -%$$ -$head Example$$ -$comment% - example/utility/romberg_one.cpp -%$$ -The file -$cref romberg_one.cpp$$ -contains an example and test a test of using this routine. - -$head Source Code$$ -The source code for this routine is in the file -$code cppad/romberg_one.hpp$$. - -$end -*/ - -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -template -Float RombergOne( - Fun &F , - const Float &a , - const Float &b , - size_t n , - size_t p , - Float &e ) -{ - size_t ipow2 = 1; - size_t k, i; - Float pow2, sum, x; - - Float zero = Float(0); - Float two = Float(2); - - // check specifications for a NumericType - CheckNumericType(); - - CPPAD_ASSERT_KNOWN( - n >= 2, - "RombergOne: n must be greater than or equal 2" - ); - CppAD::vector r(n); - - // set r[i] = trapazoidal rule with 2^i intervals in [a, b] - r[0] = ( F(a) + F(b) ) * (b - a) / two; - for(i = 1; i < n; i++) - { ipow2 *= 2; - // there must be a conversion from int to any numeric type - pow2 = Float(int(ipow2)); - sum = zero; - for(k = 1; k < ipow2; k += 2) - { // start = a + (b-a)/pow2, increment = 2*(b-a)/pow2 - x = ( (pow2 - Float(double(k))) * a + double(k) * b ) / pow2; - sum = sum + F(x); - } - // combine function evaluations in sum with those in T[i-1] - r[i] = r[i-1] / two + sum * (b - a) / pow2; - } - - // now compute the higher order estimates - size_t ipow4 = 1; // order of accuract for previous estimate - Float pow4, pow4minus; - for(i = 0; i < p; i++) - { // compute estimate accurate to O[ step^(2*(i+1)) ] - // put resutls in r[n-1], r[n-2], ... , r[n-i+1] - ipow4 *= 4; - pow4 = Float(int(ipow4)); - pow4minus = Float(ipow4-1); - for(k = n-1; k > i; k--) - r[k] = ( pow4 * r[k] - r[k-1] ) / pow4minus; - } - - // error estimate for r[n] - e = r[n-1] - r[n-2]; - if( e < zero ) - e = - e; - return r[n-1]; -} - -} // END CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/rosen_34.hpp b/build-config/cppad/include/cppad/utility/rosen_34.hpp deleted file mode 100644 index 467fd486..00000000 --- a/build-config/cppad/include/cppad/utility/rosen_34.hpp +++ /dev/null @@ -1,497 +0,0 @@ -# ifndef CPPAD_UTILITY_ROSEN_34_HPP -# define CPPAD_UTILITY_ROSEN_34_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin Rosen34$$ -$spell - cppad.hpp - bool - xf - templated - const - Rosenbrock - CppAD - xi - ti - tf - Karp - Rosen - Shampine - ind - dep -$$ - - -$section A 3rd and 4th Order Rosenbrock ODE Solver$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%xf% = Rosen34(%F%, %M%, %ti%, %tf%, %xi%) -%$$ -$icode%xf% = Rosen34(%F%, %M%, %ti%, %tf%, %xi%, %e%) -%$$ - - -$head Description$$ -This is an embedded 3rd and 4th order Rosenbrock ODE solver -(see Section 16.6 of $cref/Numerical Recipes/Bib/Numerical Recipes/$$ -for a description of Rosenbrock ODE solvers). -In particular, we use the formulas taken from page 100 of -$cref/Shampine, L.F./Bib/Shampine, L.F./$$ -(except that the fraction 98/108 has been correction to be 97/108). -$pre - -$$ -We use $latex n$$ for the size of the vector $icode xi$$. -Let $latex \B{R}$$ denote the real numbers -and let $latex F : \B{R} \times \B{R}^n \rightarrow \B{R}^n$$ be a smooth function. -The return value $icode xf$$ contains a 5th order -approximation for the value $latex X(tf)$$ where -$latex X : [ti , tf] \rightarrow \B{R}^n$$ is defined by -the following initial value problem: -$latex \[ -\begin{array}{rcl} - X(ti) & = & xi \\ - X'(t) & = & F[t , X(t)] -\end{array} -\] $$ -If your set of ordinary differential equations are not stiff -an explicit method may be better (perhaps $cref Runge45$$.) - -$head Include$$ -The file $code cppad/utility/rosen_34.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head xf$$ -The return value $icode xf$$ has the prototype -$codei% - %Vector% %xf% -%$$ -and the size of $icode xf$$ is equal to $icode n$$ -(see description of $cref/Vector/Rosen34/Vector/$$ below). -$latex \[ - X(tf) = xf + O( h^5 ) -\] $$ -where $latex h = (tf - ti) / M$$ is the step size. -If $icode xf$$ contains not a number $cref nan$$, -see the discussion of $cref/f/Rosen34/Fun/Nan/$$. - -$head Fun$$ -The class $icode Fun$$ -and the object $icode F$$ satisfy the prototype -$codei% - %Fun% &%F% -%$$ -This must support the following set of calls -$codei% - %F%.Ode(%t%, %x%, %f%) - %F%.Ode_ind(%t%, %x%, %f_t%) - %F%.Ode_dep(%t%, %x%, %f_x%) -%$$ - -$subhead t$$ -In all three cases, -the argument $icode t$$ has prototype -$codei% - const %Scalar% &%t% -%$$ -(see description of $cref/Scalar/Rosen34/Scalar/$$ below). - -$subhead x$$ -In all three cases, -the argument $icode x$$ has prototype -$codei% - const %Vector% &%x% -%$$ -and has size $icode n$$ -(see description of $cref/Vector/Rosen34/Vector/$$ below). - -$subhead f$$ -The argument $icode f$$ to $icode%F%.Ode%$$ has prototype -$codei% - %Vector% &%f% -%$$ -On input and output, $icode f$$ is a vector of size $icode n$$ -and the input values of the elements of $icode f$$ do not matter. -On output, -$icode f$$ is set equal to $latex F(t, x)$$ -(see $icode F(t, x)$$ in $cref/Description/Rosen34/Description/$$). - -$subhead f_t$$ -The argument $icode f_t$$ to $icode%F%.Ode_ind%$$ has prototype -$codei% - %Vector% &%f_t% -%$$ -On input and output, $icode f_t$$ is a vector of size $icode n$$ -and the input values of the elements of $icode f_t$$ do not matter. -On output, the $th i$$ element of -$icode f_t$$ is set equal to $latex \partial_t F_i (t, x)$$ -(see $icode F(t, x)$$ in $cref/Description/Rosen34/Description/$$). - -$subhead f_x$$ -The argument $icode f_x$$ to $icode%F%.Ode_dep%$$ has prototype -$codei% - %Vector% &%f_x% -%$$ -On input and output, $icode f_x$$ is a vector of size $icode%n%*%n%$$ -and the input values of the elements of $icode f_x$$ do not matter. -On output, the [$icode%i%*%n%+%j%$$] element of -$icode f_x$$ is set equal to $latex \partial_{x(j)} F_i (t, x)$$ -(see $icode F(t, x)$$ in $cref/Description/Rosen34/Description/$$). - -$subhead Nan$$ -If any of the elements of $icode f$$, $icode f_t$$, or $icode f_x$$ -have the value not a number $code nan$$, -the routine $code Rosen34$$ returns with all the -elements of $icode xf$$ and $icode e$$ equal to $code nan$$. - -$subhead Warning$$ -The arguments $icode f$$, $icode f_t$$, and $icode f_x$$ -must have a call by reference in their prototypes; i.e., -do not forget the $code &$$ in the prototype for -$icode f$$, $icode f_t$$ and $icode f_x$$. - -$subhead Optimization$$ -Every call of the form -$codei% - %F%.Ode_ind(%t%, %x%, %f_t%) -%$$ -is directly followed by a call of the form -$codei% - %F%.Ode_dep(%t%, %x%, %f_x%) -%$$ -where the arguments $icode t$$ and $icode x$$ have not changed between calls. -In many cases it is faster to compute the values of $icode f_t$$ -and $icode f_x$$ together and then pass them back one at a time. - -$head M$$ -The argument $icode M$$ has prototype -$codei% - size_t %M% -%$$ -It specifies the number of steps -to use when solving the differential equation. -This must be greater than or equal one. -The step size is given by $latex h = (tf - ti) / M$$, thus -the larger $icode M$$, the more accurate the -return value $icode xf$$ is as an approximation -for $latex X(tf)$$. - -$head ti$$ -The argument $icode ti$$ has prototype -$codei% - const %Scalar% &%ti% -%$$ -(see description of $cref/Scalar/Rosen34/Scalar/$$ below). -It specifies the initial time for $icode t$$ in the -differential equation; i.e., -the time corresponding to the value $icode xi$$. - -$head tf$$ -The argument $icode tf$$ has prototype -$codei% - const %Scalar% &%tf% -%$$ -It specifies the final time for $icode t$$ in the -differential equation; i.e., -the time corresponding to the value $icode xf$$. - -$head xi$$ -The argument $icode xi$$ has the prototype -$codei% - const %Vector% &%xi% -%$$ -and the size of $icode xi$$ is equal to $icode n$$. -It specifies the value of $latex X(ti)$$ - -$head e$$ -The argument $icode e$$ is optional and has the prototype -$codei% - %Vector% &%e% -%$$ -If $icode e$$ is present, -the size of $icode e$$ must be equal to $icode n$$. -The input value of the elements of $icode e$$ does not matter. -On output -it contains an element by element -estimated bound for the absolute value of the error in $icode xf$$ -$latex \[ - e = O( h^4 ) -\] $$ -where $latex h = (tf - ti) / M$$ is the step size. - -$head Scalar$$ -The type $icode Scalar$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. -In addition, the following operations must be defined for -$icode Scalar$$ objects $icode a$$ and $icode b$$: - -$table -$bold Operation$$ $cnext $bold Description$$ $rnext -$icode%a% < %b%$$ $cnext - less than operator (returns a $code bool$$ object) -$tend - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type Scalar/SimpleVector/Elements of Specified Type/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Parallel Mode$$ -For each set of types -$cref/Scalar/Rosen34/Scalar/$$, -$cref/Vector/Rosen34/Vector/$$, and -$cref/Fun/Rosen34/Fun/$$, -the first call to $code Rosen34$$ -must not be $cref/parallel/ta_in_parallel/$$ execution mode. - -$head Example$$ -$children% - example/utility/rosen_34.cpp -%$$ -The file -$cref rosen_34.cpp$$ -contains an example and test a test of using this routine. - -$head Source Code$$ -The source code for this routine is in the file -$code cppad/rosen_34.hpp$$. - -$end --------------------------------------------------------------------------- -*/ - -# include -# include -# include -# include -# include -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -namespace CppAD { // BEGIN CppAD namespace - -template -Vector Rosen34( - Fun &F , - size_t M , - const Scalar &ti , - const Scalar &tf , - const Vector &xi ) -{ Vector e( xi.size() ); - return Rosen34(F, M, ti, tf, xi, e); -} - -template -Vector Rosen34( - Fun &F , - size_t M , - const Scalar &ti , - const Scalar &tf , - const Vector &xi , - Vector &e ) -{ - CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - // check numeric type specifications - CheckNumericType(); - - // check simple vector class specifications - CheckSimpleVector(); - - // Parameters for Shampine's Rosenbrock method - // are static to avoid recalculation on each call and - // do not use Vector to avoid possible memory leak - static Scalar a[3] = { - Scalar(0), - Scalar(1), - Scalar(3) / Scalar(5) - }; - static Scalar b[2 * 2] = { - Scalar(1), - Scalar(0), - Scalar(24) / Scalar(25), - Scalar(3) / Scalar(25) - }; - static Scalar ct[4] = { - Scalar(1) / Scalar(2), - - Scalar(3) / Scalar(2), - Scalar(121) / Scalar(50), - Scalar(29) / Scalar(250) - }; - static Scalar cg[3 * 3] = { - - Scalar(4), - Scalar(0), - Scalar(0), - Scalar(186) / Scalar(25), - Scalar(6) / Scalar(5), - Scalar(0), - - Scalar(56) / Scalar(125), - - Scalar(27) / Scalar(125), - - Scalar(1) / Scalar(5) - }; - static Scalar d3[3] = { - Scalar(97) / Scalar(108), - Scalar(11) / Scalar(72), - Scalar(25) / Scalar(216) - }; - static Scalar d4[4] = { - Scalar(19) / Scalar(18), - Scalar(1) / Scalar(4), - Scalar(25) / Scalar(216), - Scalar(125) / Scalar(216) - }; - CPPAD_ASSERT_KNOWN( - M >= 1, - "Error in Rosen34: the number of steps is less than one" - ); - CPPAD_ASSERT_KNOWN( - e.size() == xi.size(), - "Error in Rosen34: size of e not equal to size of xi" - ); - size_t i, j, k, l, m; // indices - - size_t n = xi.size(); // number of components in X(t) - Scalar ns = Scalar(double(M)); // number of steps as Scalar object - Scalar h = (tf - ti) / ns; // step size - Scalar zero = Scalar(0); // some constants - Scalar one = Scalar(1); - Scalar two = Scalar(2); - - // permutation vectors needed for LU factorization routine - CppAD::vector ip(n), jp(n); - - // vectors used to store values returned by F - Vector E(n * n), Eg(n), f_t(n); - Vector g(n * 3), x3(n), x4(n), xf(n), ftmp(n), xtmp(n), nan_vec(n); - - // initialize e = 0, nan_vec = nan - for(i = 0; i < n; i++) - { e[i] = zero; - nan_vec[i] = nan(zero); - } - - xf = xi; // initialize solution - for(m = 0; m < M; m++) - { // time at beginning of this interval - Scalar t = ti * (Scalar(int(M - m)) / ns) - + tf * (Scalar(int(m)) / ns); - - // value of x at beginning of this interval - x3 = x4 = xf; - - // evaluate partial derivatives at beginning of this interval - F.Ode_ind(t, xf, f_t); - F.Ode_dep(t, xf, E); // E = f_x - if( hasnan(f_t) || hasnan(E) ) - { e = nan_vec; - return nan_vec; - } - - // E = I - f_x * h / 2 - for(i = 0; i < n; i++) - { for(j = 0; j < n; j++) - E[i * n + j] = - E[i * n + j] * h / two; - E[i * n + i] += one; - } - - // LU factor the matrix E -# ifndef NDEBUG - int sign = LuFactor(ip, jp, E); -# else - LuFactor(ip, jp, E); -# endif - CPPAD_ASSERT_KNOWN( - sign != 0, - "Error in Rosen34: I - f_x * h / 2 not invertible" - ); - - // loop over integration steps - for(k = 0; k < 3; k++) - { // set location for next function evaluation - xtmp = xf; - for(l = 0; l < k; l++) - { // loop over previous function evaluations - Scalar bkl = b[(k-1)*2 + l]; - for(i = 0; i < n; i++) - { // loop over elements of x - xtmp[i] += bkl * g[i*3 + l] * h; - } - } - // ftmp = F(t + a[k] * h, xtmp) - F.Ode(t + a[k] * h, xtmp, ftmp); - if( hasnan(ftmp) ) - { e = nan_vec; - return nan_vec; - } - - // Form Eg for this integration step - for(i = 0; i < n; i++) - Eg[i] = ftmp[i] + ct[k] * f_t[i] * h; - for(l = 0; l < k; l++) - { for(i = 0; i < n; i++) - Eg[i] += cg[(k-1)*3 + l] * g[i*3 + l]; - } - - // Solve the equation E * g = Eg - LuInvert(ip, jp, E, Eg); - - // save solution and advance x3, x4 - for(i = 0; i < n; i++) - { g[i*3 + k] = Eg[i]; - x3[i] += h * d3[k] * Eg[i]; - x4[i] += h * d4[k] * Eg[i]; - } - } - // Form Eg for last update to x4 only - for(i = 0; i < n; i++) - Eg[i] = ftmp[i] + ct[3] * f_t[i] * h; - for(l = 0; l < 3; l++) - { for(i = 0; i < n; i++) - Eg[i] += cg[2*3 + l] * g[i*3 + l]; - } - - // Solve the equation E * g = Eg - LuInvert(ip, jp, E, Eg); - - // advance x4 and accumulate error bound - for(i = 0; i < n; i++) - { x4[i] += h * d4[3] * Eg[i]; - - // cant use abs because cppad.hpp may not be included - Scalar diff = x4[i] - x3[i]; - if( diff < zero ) - e[i] -= diff; - else - e[i] += diff; - } - - // advance xf for this step using x4 - xf = x4; - } - return xf; -} - -} // End CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/runge_45.hpp b/build-config/cppad/include/cppad/utility/runge_45.hpp deleted file mode 100644 index 9392de70..00000000 --- a/build-config/cppad/include/cppad/utility/runge_45.hpp +++ /dev/null @@ -1,427 +0,0 @@ -# ifndef CPPAD_UTILITY_RUNGE_45_HPP -# define CPPAD_UTILITY_RUNGE_45_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin Runge45$$ -$spell - std - fabs - cppad.hpp - bool - xf - templated - const - Runge-Kutta - CppAD - xi - ti - tf - Karp -$$ - - -$section An Embedded 4th and 5th Order Runge-Kutta ODE Solver$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%xf% = Runge45(%F%, %M%, %ti%, %tf%, %xi%) -%$$ -$icode%xf% = Runge45(%F%, %M%, %ti%, %tf%, %xi%, %e%) -%$$ - - -$head Purpose$$ -This is an implementation of the -Cash-Karp embedded 4th and 5th order Runge-Kutta ODE solver -described in Section 16.2 of $cref/Numerical Recipes/Bib/Numerical Recipes/$$. -We use $latex n$$ for the size of the vector $icode xi$$. -Let $latex \B{R}$$ denote the real numbers -and let $latex F : \B{R} \times \B{R}^n \rightarrow \B{R}^n$$ -be a smooth function. -The return value $icode xf$$ contains a 5th order -approximation for the value $latex X(tf)$$ where -$latex X : [ti , tf] \rightarrow \B{R}^n$$ is defined by -the following initial value problem: -$latex \[ -\begin{array}{rcl} - X(ti) & = & xi \\ - X'(t) & = & F[t , X(t)] -\end{array} -\] $$ -If your set of ordinary differential equations -are stiff, an implicit method may be better -(perhaps $cref Rosen34$$.) - -$head Operation Sequence$$ -The $cref/operation sequence/glossary/Operation/Sequence/$$ for $icode Runge$$ -does not depend on any of its $icode Scalar$$ input values provided that -the operation sequence for -$codei% - %F%.Ode(%t%, %x%, %f%) -%$$ -does not on any of its $icode Scalar$$ inputs (see below). - -$head Include$$ -The file $code cppad/utility/runge_45.hpp$$ -is included by $code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head xf$$ -The return value $icode xf$$ has the prototype -$codei% - %Vector% %xf% -%$$ -and the size of $icode xf$$ is equal to $icode n$$ -(see description of $cref/Vector/Runge45/Vector/$$ below). -$latex \[ - X(tf) = xf + O( h^6 ) -\] $$ -where $latex h = (tf - ti) / M$$ is the step size. -If $icode xf$$ contains not a number $cref nan$$, -see the discussion for $cref/f/Runge45/Fun/f/$$. - -$head Fun$$ -The class $icode Fun$$ -and the object $icode F$$ satisfy the prototype -$codei% - %Fun% &%F% -%$$ -The object $icode F$$ (and the class $icode Fun$$) -must have a member function named $code Ode$$ -that supports the syntax -$codei% - %F%.Ode(%t%, %x%, %f%) -%$$ - -$subhead t$$ -The argument $icode t$$ to $icode%F%.Ode%$$ has prototype -$codei% - const %Scalar% &%t% -%$$ -(see description of $cref/Scalar/Runge45/Scalar/$$ below). - -$subhead x$$ -The argument $icode x$$ to $icode%F%.Ode%$$ has prototype -$codei% - const %Vector% &%x% -%$$ -and has size $icode n$$ -(see description of $cref/Vector/Runge45/Vector/$$ below). - -$subhead f$$ -The argument $icode f$$ to $icode%F%.Ode%$$ has prototype -$codei% - %Vector% &%f% -%$$ -On input and output, $icode f$$ is a vector of size $icode n$$ -and the input values of the elements of $icode f$$ do not matter. -On output, -$icode f$$ is set equal to $latex F(t, x)$$ in the differential equation. -If any of the elements of $icode f$$ have the value not a number $code nan$$ -the routine $code Runge45$$ returns with all the -elements of $icode xf$$ and $icode e$$ equal to $code nan$$. - -$subhead Warning$$ -The argument $icode f$$ to $icode%F%.Ode%$$ -must have a call by reference in its prototype; i.e., -do not forget the $code &$$ in the prototype for $icode f$$. - -$head M$$ -The argument $icode M$$ has prototype -$codei% - size_t %M% -%$$ -It specifies the number of steps -to use when solving the differential equation. -This must be greater than or equal one. -The step size is given by $latex h = (tf - ti) / M$$, thus -the larger $icode M$$, the more accurate the -return value $icode xf$$ is as an approximation -for $latex X(tf)$$. - -$head ti$$ -The argument $icode ti$$ has prototype -$codei% - const %Scalar% &%ti% -%$$ -(see description of $cref/Scalar/Runge45/Scalar/$$ below). -It specifies the initial time for $icode t$$ in the -differential equation; i.e., -the time corresponding to the value $icode xi$$. - -$head tf$$ -The argument $icode tf$$ has prototype -$codei% - const %Scalar% &%tf% -%$$ -It specifies the final time for $icode t$$ in the -differential equation; i.e., -the time corresponding to the value $icode xf$$. - -$head xi$$ -The argument $icode xi$$ has the prototype -$codei% - const %Vector% &%xi% -%$$ -and the size of $icode xi$$ is equal to $icode n$$. -It specifies the value of $latex X(ti)$$ - -$head e$$ -The argument $icode e$$ is optional and has the prototype -$codei% - %Vector% &%e% -%$$ -If $icode e$$ is present, -the size of $icode e$$ must be equal to $icode n$$. -The input value of the elements of $icode e$$ does not matter. -On output -it contains an element by element -estimated bound for the absolute value of the error in $icode xf$$ -$latex \[ - e = O( h^5 ) -\] $$ -where $latex h = (tf - ti) / M$$ is the step size. -If on output, $icode e$$ contains not a number $code nan$$, -see the discussion for $cref/f/Runge45/Fun/f/$$. - -$head Scalar$$ -The type $icode Scalar$$ must satisfy the conditions -for a $cref NumericType$$ type. -The routine $cref CheckNumericType$$ will generate an error message -if this is not the case. - -$subhead fabs$$ -In addition, the following function must be defined for -$icode Scalar$$ objects $icode a$$ and $icode b$$ -$codei% - %a% = fabs(%b%) -%$$ -Note that this operation is only used for computing $icode e$$; hence -the operation sequence for $icode xf$$ can still be independent of -the arguments to $code Runge45$$ even if -$codei% - fabs(%b%) = std::max(-%b%, %b%) -%$$. - -$head Vector$$ -The type $icode Vector$$ must be a $cref SimpleVector$$ class with -$cref/elements of type Scalar/SimpleVector/Elements of Specified Type/$$. -The routine $cref CheckSimpleVector$$ will generate an error message -if this is not the case. - -$head Parallel Mode$$ -For each set of types -$cref/Scalar/Runge45/Scalar/$$, -$cref/Vector/Runge45/Vector/$$, and -$cref/Fun/Runge45/Fun/$$, -the first call to $code Runge45$$ -must not be $cref/parallel/ta_in_parallel/$$ execution mode. - - -$head Example$$ -$children% - example/utility/runge45_1.cpp% - example/utility/runge_45.cpp -%$$ -The file -$cref runge45_1.cpp$$ -contains a simple example and test of $code Runge45$$. -$pre - -$$ -The file -$cref runge_45.cpp$$ contains an example using $code Runge45$$ -in the context of algorithmic differentiation. -It also returns true if it succeeds and false otherwise. - -$head Source Code$$ -The source code for this routine is in the file -$code cppad/runge_45.hpp$$. - -$end --------------------------------------------------------------------------- -*/ -# include -# include -# include -# include -# include - -// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL -# include - -namespace CppAD { // BEGIN CppAD namespace - -template -Vector Runge45( - Fun &F , - size_t M , - const Scalar &ti , - const Scalar &tf , - const Vector &xi ) -{ Vector e( xi.size() ); - return Runge45(F, M, ti, tf, xi, e); -} - -template -Vector Runge45( - Fun &F , - size_t M , - const Scalar &ti , - const Scalar &tf , - const Vector &xi , - Vector &e ) -{ - CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - // check numeric type specifications - CheckNumericType(); - - // check simple vector class specifications - CheckSimpleVector(); - - // Cash-Karp parameters for embedded Runge-Kutta method - // are static to avoid recalculation on each call and - // do not use Vector to avoid possible memory leak - static Scalar a[6] = { - Scalar(0), - Scalar(1) / Scalar(5), - Scalar(3) / Scalar(10), - Scalar(3) / Scalar(5), - Scalar(1), - Scalar(7) / Scalar(8) - }; - static Scalar b[5 * 5] = { - Scalar(1) / Scalar(5), - Scalar(0), - Scalar(0), - Scalar(0), - Scalar(0), - - Scalar(3) / Scalar(40), - Scalar(9) / Scalar(40), - Scalar(0), - Scalar(0), - Scalar(0), - - Scalar(3) / Scalar(10), - -Scalar(9) / Scalar(10), - Scalar(6) / Scalar(5), - Scalar(0), - Scalar(0), - - -Scalar(11) / Scalar(54), - Scalar(5) / Scalar(2), - -Scalar(70) / Scalar(27), - Scalar(35) / Scalar(27), - Scalar(0), - - Scalar(1631) / Scalar(55296), - Scalar(175) / Scalar(512), - Scalar(575) / Scalar(13824), - Scalar(44275) / Scalar(110592), - Scalar(253) / Scalar(4096) - }; - static Scalar c4[6] = { - Scalar(2825) / Scalar(27648), - Scalar(0), - Scalar(18575) / Scalar(48384), - Scalar(13525) / Scalar(55296), - Scalar(277) / Scalar(14336), - Scalar(1) / Scalar(4), - }; - static Scalar c5[6] = { - Scalar(37) / Scalar(378), - Scalar(0), - Scalar(250) / Scalar(621), - Scalar(125) / Scalar(594), - Scalar(0), - Scalar(512) / Scalar(1771) - }; - - CPPAD_ASSERT_KNOWN( - M >= 1, - "Error in Runge45: the number of steps is less than one" - ); - CPPAD_ASSERT_KNOWN( - e.size() == xi.size(), - "Error in Runge45: size of e not equal to size of xi" - ); - size_t i, j, k, m; // indices - - size_t n = xi.size(); // number of components in X(t) - Scalar ns = Scalar(int(M)); // number of steps as Scalar object - Scalar h = (tf - ti) / ns; // step size - Scalar zero_or_nan = Scalar(0); // zero (nan if Ode returns has a nan) - for(i = 0; i < n; i++) // initialize e = 0 - e[i] = zero_or_nan; - - // vectors used to store values returned by F - Vector fh(6 * n), xtmp(n), ftmp(n), x4(n), x5(n), xf(n); - - xf = xi; // initialize solution - for(m = 0; m < M; m++) - { // time at beginning of this interval - // (convert to int to avoid MS compiler warning) - Scalar t = ti * (Scalar(int(M - m)) / ns) - + tf * (Scalar(int(m)) / ns); - - // loop over integration steps - x4 = x5 = xf; // start x4 and x5 at same point for each step - for(j = 0; j < 6; j++) - { // loop over function evaluations for this step - xtmp = xf; // location for next function evaluation - for(k = 0; k < j; k++) - { // loop over previous function evaluations - Scalar bjk = b[ (j-1) * 5 + k ]; - for(i = 0; i < n; i++) - { // loop over elements of x - xtmp[i] += bjk * fh[i * 6 + k]; - } - } - // ftmp = F(t + a[j] * h, xtmp) - F.Ode(t + a[j] * h, xtmp, ftmp); - - // if ftmp has a nan, set zero_or_nan to nan - for(i = 0; i < n; i++) - zero_or_nan *= ftmp[i]; - - for(i = 0; i < n; i++) - { // loop over elements of x - Scalar fhi = ftmp[i] * h; - fh[i * 6 + j] = fhi; - x4[i] += c4[j] * fhi; - x5[i] += c5[j] * fhi; - x5[i] += zero_or_nan; - } - } - // accumulate error bound - for(i = 0; i < n; i++) - { // cant use abs because cppad.hpp may not be included - Scalar diff = x5[i] - x4[i]; - e[i] += fabs(diff); - e[i] += zero_or_nan; - } - - // advance xf for this step using x5 - xf = x5; - } - return xf; -} - -} // End CppAD namespace - -# endif diff --git a/build-config/cppad/include/cppad/utility/set_union.hpp b/build-config/cppad/include/cppad/utility/set_union.hpp deleted file mode 100644 index e8987fb0..00000000 --- a/build-config/cppad/include/cppad/utility/set_union.hpp +++ /dev/null @@ -1,91 +0,0 @@ -# ifndef CPPAD_UTILITY_SET_UNION_HPP -# define CPPAD_UTILITY_SET_UNION_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin set_union$$ -$spell - set - const - std - cppad - hpp -$$ - -$section Union of Standard Sets$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%result% = set_union(%left%, %right%)%$$ - -$head Purpose$$ -This is a simplified (and restricted) interface to -the $code std::union$$ operation. - -$head Element$$ -This is the type of the elements of the sets. - -$head left$$ -This argument has prototype -$codei% - const std::set<%Element%>& %left% -%$$ - -$head right$$ -This argument has prototype -$codei% - const std::set<%Element%>& %right% -%$$ - -$head result$$ -The return value has prototype -$codei% - std::set<%Element%>& %result% -%$$ -It contains the union of $icode left$$ and $icode right$$. -Note that C++11 detects that the return value is a temporary -and uses it for the result instead of making a separate copy. - -$children% - example/utility/set_union.cpp -%$$ -$head Example$$ -The file $cref set_union.cpp$$ contains an example and test of this - - -$end -*/ - -# include -# include -# include - -namespace CppAD { - template - std::set set_union( - const std::set& left , - const std::set& right ) - { std::set result; - std::set_union( - left.begin() , - left.end() , - right.begin() , - right.end() , - std::inserter(result, result.begin()) - ); - return result; - } -} - -# endif diff --git a/build-config/cppad/include/cppad/utility/sparse2eigen.hpp b/build-config/cppad/include/cppad/utility/sparse2eigen.hpp deleted file mode 100644 index e6e5e28c..00000000 --- a/build-config/cppad/include/cppad/utility/sparse2eigen.hpp +++ /dev/null @@ -1,138 +0,0 @@ -# ifndef CPPAD_UTILITY_SPARSE2EIGEN_HPP -# define CPPAD_UTILITY_SPARSE2EIGEN_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin sparse2eigen$$ -$spell - CppAD - Eigen - cppad.hpp - const - Ptr - nnz - cmake - namespace -$$ - -$section Convert A CppAD Sparse Matrix to an Eigen Sparse Matrix$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%sparse2eigen(%source%, %destination%)%$$ - -$head Prototype$$ -$srcthisfile%0 - %// BEGIN_PROTOTYPE%// END_PROTOTYPE% -1%$$ - -$head Include$$ -If $cref/include_eigen/cmake/include_eigen/$$ is specified on the cmake command line, -the file $code cppad/utility/sparse2eigen.hpp$$ -is included by $code cppad/cppad.hpp$$. -In any case, -it can also be included separately with out the rest of -the $code CppAD$$ routines. -Including this file defines -this version of the $code sparse2eigen$$ within the $code CppAD$$ namespace. - -$head SizeVector$$ -We use $cref/SizeVector/sparse_rc/SizeVector/$$ to denote a -$cref SimpleVector$$ class with elements of $code size_t$$. - -$head ValueVector$$ -We use $icode ValueVector$$ to denote a -$cref SimpleVector$$ class with elements of type $icode value_type$$. - -$head Options$$ -We use $icode Options$$ to denote either -$code Eigen::RowMajor$$ of $code Eigen::ColMajor$$. - -$head value_type$$ -The type of elements of elements in $icode source$$ and $icode destination$$ -must be the same. We use $icode value_type$$ to denote this type. - -$head source$$ -This is the CppAD sparse matrix that is being converted to eigen format. - -$head destination$$ -This is the Eigen sparse matrix that is the result of the conversion. - -$head Compressed$$ -The result matrix $icode destination$$ -is in compressed format. For example, let -$codei% - size_t %% %nnz% = %source%.nnz(); - const %s_vector%& %s_value% = %source%.val(); - const %value_type%* %d_value% = %destination%.valuePtr(); - const %s_vector%& %row_major% = %source%.row_major(); - const %s_vector%& %col_major% = %source%.col_major(); -%$$ -It follows that, for $icode%k% = 0 , %...%, %nnz%$$: -If $icode Options$$ is $code Eigen::RowMajor$$, -$codei% - %d_value%[%k%] == %s_value%[ %row_major%[%k%] ] -%$$ -If $icode Options$$ is $code Eigen::ColMajor$$, -$codei% - %d_value%[%k%] == %s_value%[ %col_major%[%k%] ] -%$$ - -$children%example/sparse/sparse2eigen.cpp -%$$ - -$head Example$$ -The file $cref sparse2eigen.cpp$$ contains an example and test -of $code sparse2eigen.cpp$$ It return true if the test passes -and false otherwise. - -$end -*/ -# include -# include -# include -# include - -namespace CppAD { // BEGIN CPPAD_NAMESPACE - -// BEGIN_PROTOTYPE -template -void sparse2eigen( -const CppAD::sparse_rcv& source , -Eigen::SparseMatrix& destination ) -// END_PROTOTYPE -{ using Eigen::Index; - typedef typename ValueVector::value_type value_type; - typedef Eigen::Triplet triplet; - std::vector vec( source.nnz() ); - // - const SizeVector& row = source.row(); - const SizeVector& col = source.col(); - const ValueVector& val = source.val(); - // - for(size_t k = 0; k < source.nnz(); k++) - vec[k] = triplet( int(row[k]), int(col[k]), val[k] ); - // - size_t nr = source.nr(); - size_t nc = source.nc(); - destination.resize( Index(nr), Index(nc) ); - destination.setFromTriplets(vec.begin(), vec.end()); - // - CPPAD_ASSERT_UNKNOWN( destination.isCompressed() ); - // - return; -} - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/utility/sparse_rc.hpp b/build-config/cppad/include/cppad/utility/sparse_rc.hpp deleted file mode 100644 index 3936988c..00000000 --- a/build-config/cppad/include/cppad/utility/sparse_rc.hpp +++ /dev/null @@ -1,380 +0,0 @@ -# ifndef CPPAD_UTILITY_SPARSE_RC_HPP -# define CPPAD_UTILITY_SPARSE_RC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin sparse_rc$$ -$spell - CppAD - const - nnz - cppad - hpp - rc - nr - nc - resize -$$ -$section Row and Column Index Sparsity Patterns$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%sparse_rc<%SizeVector%> %empty% -%$$ -$codei%sparse_rc<%SizeVector%> %pattern%(%nr%, %nc%, %nnz%) -%$$ -$icode%pattern% = %other% -%$$ -$icode%pattern%.swap(%other%) -%$$ -$icode%resize%(%nr%, %nc%, %nnz%) -%$$ -$icode%pattern%.set(%k%, %r%, %c%) -%$$ -$icode%pattern%.nr() -%$$ -$icode%pattern%.nc() -%$$ -$icode%pattern%.nnz() -%$$ -$codei%const %SizeVector%& %row%( %pattern%.row() ) -%$$ -$codei%const %SizeVector%& %col%( %pattern%.col() ) -%$$ -$icode%row_major% = %pattern%.row_major() -%$$ -$icode%col_major% = %pattern%.col_major() -%$$ - -$head SizeVector$$ -We use $icode SizeVector$$ to denote $cref SimpleVector$$ class -$cref/with elements of type/SimpleVector/Elements of Specified Type/$$ -$code size_t$$. -In addition, $icode SimpleVector$$ must support the $code swap$$ operation -between two of its vectors. - -$head empty$$ -This is an empty sparsity pattern. To be specific, -the corresponding number of rows $icode nr$$, -number of columns $icode nc$$, -and number of possibly non-zero values $icode nnz$$, -are all zero. - -$head pattern$$ -This object is used to hold a sparsity pattern for a matrix. -The sparsity $icode pattern$$ is $code const$$ -except during its constructor, $code resize$$, and $code set$$. - -$head other$$ -The $icode other$$ variable has prototype -$codei% - sparse_rc<%SizeVector%> %other% -%$$ - -$subhead Assignment$$ -After the assignment statement, $icode other$$ is an independent copy -of $icode pattern$$; i.e. it has all the same values as $icode pattern$$ -and changes to $icode other$$ do not affect $icode pattern$$. -A move semantics version of the assignment operator is defined; e.g., -it is used when $icode other$$ in the assignment syntax -is a function return value. - -$subhead swap$$ -After the swap operation $icode other$$ ($icode pattern$$) is equivalent -to $icode pattern$$ ($icode other$$) before the operation. - -$head nr$$ -This argument has prototype -$codei% - size_t %nr% -%$$ -It specifies the number of rows in the sparsity pattern. -The function call $code nr()$$ returns the value of $icode nr$$. - -$head nc$$ -This argument has prototype -$codei% - size_t %nc% -%$$ -It specifies the number of columns in the sparsity pattern. -The function call $code nc()$$ returns the value of $icode nc$$. - -$head nnz$$ -This argument has prototype -$codei% - size_t %nnz% -%$$ -It specifies the number of possibly non-zero -index pairs in the sparsity pattern. -The function call $code nnz()$$ returns the value of $icode nnz$$. - -$head resize$$ -The current sparsity pattern is lost and a new one is started -with the specified parameters. The elements in the $icode row$$ -and $icode col$$ vectors should be assigned using $code set$$. - -$head set$$ -This function sets the values -$codei% - %row%[%k%] = %r% - %col%[%k%] = %c% -%$$ - -$subhead k$$ -This argument has type -$codei% - size_t %k% -%$$ -and must be less than $icode nnz$$. - -$subhead r$$ -This argument has type -$codei% - size_t %r% -%$$ -It specifies the value assigned to $icode%row%[%k%]%$$ and must -be less than $icode nr$$. - -$subhead c$$ -This argument has type -$codei% - size_t %c% -%$$ -It specifies the value assigned to $icode%col%[%k%]%$$ and must -be less than $icode nc$$. - -$head row$$ -This vector has size $icode nnz$$ and -$icode%row%[%k%]%$$ -is the row index of the $th k$$ possibly non-zero -index pair in the sparsity pattern. - -$head col$$ -This vector has size $icode nnz$$ and -$icode%col%[%k%]%$$ is the column index of the $th k$$ possibly non-zero -index pair in the sparsity pattern. - -$head row_major$$ -This vector has prototype -$codei% - %SizeVector% %row_major% -%$$ -and its size $icode nnz$$. -It sorts the sparsity pattern in row-major order. -To be specific, -$codei% - %col%[ %row_major%[%k%] ] <= %col%[ %row_major%[%k%+1] ] -%$$ -and if $icode%col%[ %row_major%[%k%] ] == %col%[ %row_major%[%k%+1] ]%$$, -$codei% - %row%[ %row_major%[%k%] ] < %row%[ %row_major%[%k%+1] ] -%$$ -This routine generates an assert if there are two entries with the same -row and column values (if $code NDEBUG$$ is not defined). - -$head col_major$$ -This vector has prototype -$codei% - %SizeVector% %col_major% -%$$ -and its size $icode nnz$$. -It sorts the sparsity pattern in column-major order. -To be specific, -$codei% - %row%[ %col_major%[%k%] ] <= %row%[ %col_major%[%k%+1] ] -%$$ -and if $icode%row%[ %col_major%[%k%] ] == %row%[ %col_major%[%k%+1] ]%$$, -$codei% - %col%[ %col_major%[%k%] ] < %col%[ %col_major%[%k%+1] ] -%$$ -This routine generates an assert if there are two entries with the same -row and column values (if $code NDEBUG$$ is not defined). - -$children% - example/utility/sparse_rc.cpp -%$$ -$head Example$$ -The file $cref sparse_rc.cpp$$ -contains an example and test of this class. - -$end -*/ -/*! -\file sparse_rc.hpp -A Matrix sparsity pattern class. -*/ -# include // for size_t -# include // for CPPAD_ASSERT -# include // for row and column major ordering - -namespace CppAD { // BEGIN CPPAD_NAMESPACE - -/// sparsity pattern for a matrix with indices of type size_t -template -class sparse_rc { -private: - /// number of rows in the sparsity pattern - size_t nr_; - /// number of columns in the sparsity pattern - size_t nc_; - /// number of possibly non-zero index pairs - size_t nnz_; - /// row_[k] is the row index for the k-th possibly non-zero entry - SizeVector row_; - /// col_[k] is the column index for the k-th possibly non-zero entry - SizeVector col_; -public: - /// default constructor - /// Eigen vector is ambiguous for row_(0), col_(0) so use default ctor - sparse_rc(void) - : nr_(0), nc_(0), nnz_(0) - { } - /// move semantics constructor - /// (none of the default constructor values are used by destructor) - sparse_rc(sparse_rc&& other) - { swap(other); } - /// destructor - ~sparse_rc(void) - { } - /// move semantics assignment - /// sizing constructor - /// Eigen vector is ambiguous for row_(0), col_(0) so use default ctor - sparse_rc(size_t nr, size_t nc, size_t nnz) - : nr_(nr), nc_(nc), nnz_(nnz) - { row_.resize(nnz); - col_.resize(nnz); - } - /// copy constructor - sparse_rc(const sparse_rc& other) - : - nr_(other.nr_) , - nc_(other.nc_) , - nnz_(other.nnz_) , - row_(other.row_) , - col_(other.col_) - { } - /// assignment - void operator=(const sparse_rc& other) - { nr_ = other.nr_; - nc_ = other.nc_; - nnz_ = other.nnz_; - // simple vector assignment requires vectors to have same size - row_.resize(nnz_); - col_.resize(nnz_); - row_ = other.row_; - col_ = other.col_; - } - /// swap - void swap(sparse_rc& other) - { std::swap( nr_ , other.nr_ ); - std::swap( nc_ , other.nc_ ); - std::swap( nnz_ , other.nnz_ ); - // - row_.swap( other.row_ ); - col_.swap( other.col_ ); - } - void operator=(sparse_rc&& other) - { swap(other); } - /// resize - void resize(size_t nr, size_t nc, size_t nnz) - { nr_ = nr; - nc_ = nc; - nnz_ = nnz; - row_.resize(nnz); - col_.resize(nnz); - } - /// set row and column for a possibly non-zero element - void set(size_t k, size_t r, size_t c) - { CPPAD_ASSERT_KNOWN( - k < nnz_, - "The index k is not less than nnz in sparse_rc::set" - ); - CPPAD_ASSERT_KNOWN( - r < nr_, - "The index r is not less than nr in sparse_rc::set" - ); - CPPAD_ASSERT_KNOWN( - c < nc_, - "The index c is to not less than nc in sparse_rc::set" - ); - row_[k] = r; - col_[k] = c; - // - } - /// number of rows in matrix - size_t nr(void) const - { return nr_; } - /// number of columns in matrix - size_t nc(void) const - { return nc_; } - /// number of possibly non-zero elements in matrix - size_t nnz(void) const - { return nnz_; } - /// row indices - const SizeVector& row(void) const - { return row_; } - /// column indices - const SizeVector& col(void) const - { return col_; } - /// row-major order - SizeVector row_major(void) const - { SizeVector keys(nnz_), row_major(nnz_); - for(size_t k = 0; k < nnz_; k++) - { CPPAD_ASSERT_UNKNOWN( row_[k] < nr_ ); - keys[k] = row_[k] * nc_ + col_[k]; - } - index_sort(keys, row_major); -# ifndef NDEBUG - for(size_t ell = 0; ell + 1 < nnz_; ell++) - { size_t k = row_major[ ell ]; - size_t kp = row_major[ ell + 1 ]; - CPPAD_ASSERT_KNOWN( - row_[k] != row_[kp] || col_[k] != col_[kp], - "sparse_rc: row_major: duplicate entry in this pattern" - ); - CPPAD_ASSERT_UNKNOWN( - row_[k] -%$$ -$codei%sparse_rcv<%SizeVector%, %ValueVector%> %empty% -%$$ -$codei%sparse_rcv<%SizeVector%, %ValueVector%> %matrix%(%pattern%) -%$$ -$icode%matrix% = %other% -%$$ -$icode%matrix%.swap( %other% ) -%$$ -$icode%matrix%.set(%k%, %v%) -%$$ -$icode%nr% = %matrix%.nr() -%$$ -$icode%nc% = %matrix%.nc() -%$$ -$icode%nnz% = %matrix%.nnz() -%$$ -$codei%const %SizeVector%& %row%( %matrix%.row() ) -%$$ -$codei%const %SizeVector%& %col%( %matrix%.col() ) -%$$ -$codei%const %ValueVector%& %val%( %matrix%.val() ) -%$$ -$codei%const sparse_rc<%SizeVector%>& %pat%( %matrix%.pat() ) -%$$ -$icode%row_major% = %matrix%.row_major() -%$$ -$icode%col_major% = %matrix%.col_major() -%$$ - -$head SizeVector$$ -We use $cref/SizeVector/sparse_rc/SizeVector/$$ to denote the -$cref SimpleVector$$ class corresponding to $icode pattern$$. - -$head ValueVector$$ -We use $icode ValueVector$$ to denote the -$cref SimpleVector$$ class corresponding to $icode val$$. - -$head empty$$ -This is an empty sparse matrix object. To be specific, -the corresponding number of rows $icode nr$$, -number of columns $icode nc$$, -and number of possibly non-zero values $icode nnz$$, -are all zero. - - -$head pattern$$ -This constructor argument has prototype -$codei% - const sparse_rc<%SizeVector%>& %pattern% -%$$ -It specifies the number of rows, number of columns and -the possibly non-zero entries in the $icode matrix$$. - -$head matrix$$ -This is a sparse matrix object with the sparsity specified by $icode pattern$$. -Only the $icode val$$ vector can be changed. All other values returned by -$icode matrix$$ are fixed during the constructor and constant there after. -The $icode val$$ vector is only changed by the constructor -and the $code set$$ function. -There are two exceptions to this rule, where $icode other$$ appears in the -assignment and swap syntax. - -$head other$$ -The $icode other$$ variable has prototype -$codei% - sparse_rcv<%SizeVector%, %ValueVector%> %other% -%$$ - -$subhead Assignment$$ -After this assignment statement, $icode other$$ is an independent copy -of $icode matrix$$; i.e. it has all the same values as $icode matrix$$ -and changes to $icode other$$ do not affect $icode matrix$$. -A move semantics version of the assignment operator is defined; e.g., -it is used when $icode other$$ in the assignment syntax -is a function return value; - -$subhead swap$$ -After the swap operation $icode other$$ ($icode matrix$$) is equivalent -to $icode matrix$$ ($icode other$$) before the operation. - -$head nr$$ -This return value has prototype -$codei% - size_t %nr% -%$$ -and is the number of rows in $icode matrix$$. - -$head nc$$ -This argument and return value has prototype -$codei% - size_t %nc% -%$$ -and is the number of columns in $icode matrix$$. - -$head nnz$$ -We use the notation $icode nnz$$ to denote the number of -possibly non-zero entries in $icode matrix$$. - -$head set$$ -This function sets the value -$codei% - %val%[%k%] = %v% -%$$ - -$subhead k$$ -This argument has type -$codei% - size_t %k% -%$$ -and must be less than $icode nnz$$. - -$subhead v$$ -This argument has type -$codei% - const %ValueVector%::value_type& %v% -%$$ -It specifies the value assigned to $icode%val%[%k%]%$$. - - -$head row$$ -This vector has size $icode nnz$$ and -$icode%row%[%k%]%$$ -is the row index of the $th k$$ possibly non-zero -element in $icode matrix$$. - -$head col$$ -This vector has size $icode nnz$$ and -$icode%col[%k%]%$$ is the column index of the $th k$$ possibly non-zero -element in $icode matrix$$ - -$head val$$ -This vector has size $icode nnz$$ and -$icode%val[%k%]%$$ is value of the $th k$$ possibly non-zero entry -in the sparse matrix (the value may be zero). - -$head pat$$ -This is equal to the sparsity pattern; i.e., -$icode pattern$$ in the constructor. - -$head row_major$$ -This vector has prototype -$codei% - %SizeVector% %row_major% -%$$ -and its size $icode nnz$$. -It sorts the sparsity pattern in row-major order. -To be specific, -$codei% - %col%[ %row_major%[%k%] ] <= %col%[ %row_major%[%k%+1] ] -%$$ -and if $icode%col%[ %row_major%[%k%] ] == %col%[ %row_major%[%k%+1] ]%$$, -$codei% - %row%[ %row_major%[%k%] ] < %row%[ %row_major%[%k%+1] ] -%$$ -This routine generates an assert if there are two entries with the same -row and column values (if $code NDEBUG$$ is not defined). - -$head col_major$$ -This vector has prototype -$codei% - %SizeVector% %col_major% -%$$ -and its size $icode nnz$$. -It sorts the sparsity pattern in column-major order. -To be specific, -$codei% - %row%[ %col_major%[%k%] ] <= %row%[ %col_major%[%k%+1] ] -%$$ -and if $icode%row%[ %col_major%[%k%] ] == %row%[ %col_major%[%k%+1] ]%$$, -$codei% - %col%[ %col_major%[%k%] ] < %col%[ %col_major%[%k%+1] ] -%$$ -This routine generates an assert if there are two entries with the same -row and column values (if $code NDEBUG$$ is not defined). - -$head Eigen Matrix$$ -If you have the $cref/eigen package/eigen/$$ in your include path, -you can use $cref sparse2eigen$$ to convert a sparse matrix to eigen format. - -$children% - example/utility/sparse_rcv.cpp -%$$ -$head Example$$ -The file $cref sparse_rcv.cpp$$ -contains an example and test of this class. - -$end -*/ -/*! -\file sparse_rcv.hpp -A sparse matrix class. -*/ -# include - -namespace CppAD { // BEGIN CPPAD_NAMESPACE - -/// Sparse matrices with elements of type Scalar -template -class sparse_rcv { -private: - /// sparsity pattern - sparse_rc pattern_; - /// value_type - typedef typename ValueVector::value_type value_type; - /// val_[k] is the value for the k-th possibly non-zero entry in the matrix - ValueVector val_; -public: - // ------------------------------------------------------------------------ - /// default constructor - sparse_rcv(void) - : pattern_(0, 0, 0) - { } - /// move semantics constructor - /// (none of the default constructor values are used by destructor) - sparse_rcv(sparse_rcv&& other) - { swap(other); } - /// destructor - ~sparse_rcv(void) - { } - /// constructor - sparse_rcv(const sparse_rc& pattern ) - : - pattern_(pattern) , - val_(pattern_.nnz()) - { } - /// assignment - void operator=(const sparse_rcv& other) - { pattern_ = other.pattern_; - // simple vector assignment requires vectors to have same size - val_.resize( other.nnz() ); - val_ = other.val(); - } - /// swap - void swap(sparse_rcv& other) - { pattern_.swap( other.pattern_ ); - val_.swap( other.val_ ); - } - /// move semantics assignment - void operator=(sparse_rcv&& other) - { swap(other); } - // ------------------------------------------------------------------------ - void set(size_t k, const value_type& v) - { CPPAD_ASSERT_KNOWN( - pattern_.nnz(), - "The index k is not less than nnz in sparse_rcv::set" - ); - val_[k] = v; - } - /// number of rows in matrix - size_t nr(void) const - { return pattern_.nr(); } - /// number of columns in matrix - size_t nc(void) const - { return pattern_.nc(); } - /// number of possibly non-zero elements in matrix - size_t nnz(void) const - { return pattern_.nnz(); } - /// row indices - const SizeVector& row(void) const - { return pattern_.row(); } - /// column indices - const SizeVector& col(void) const - { return pattern_.col(); } - /// value for possibly non-zero elements - const ValueVector& val(void) const - { return val_; } - /// sparsity pattern - const sparse_rc& pat(void) const - { return pattern_; } - /// row-major order - SizeVector row_major(void) const - { return pattern_.row_major(); } - /// column-major indices - SizeVector col_major(void) const - { return pattern_.col_major(); } -}; - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/utility/speed_test.hpp b/build-config/cppad/include/cppad/utility/speed_test.hpp deleted file mode 100644 index 535f0971..00000000 --- a/build-config/cppad/include/cppad/utility/speed_test.hpp +++ /dev/null @@ -1,477 +0,0 @@ -# ifndef CPPAD_UTILITY_SPEED_TEST_HPP -# define CPPAD_UTILITY_SPEED_TEST_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin speed_test$$ -$spell - gettimeofday - vec - cppad.hpp - Microsoft - namespace - std - const - cout - ctime - ifdef - const - endif - cpp -$$ - - -$section Run One Speed Test and Return Results$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%rate_vec% = speed_test(%test%, %size_vec%, %time_min%)%$$ - -$head See Also$$ -$cref time_test$$ - -$head Purpose$$ -The $code speed_test$$ function executes a speed test -for various sized problems -and reports the rate of execution. - -$head Motivation$$ -It is important to separate small calculation units -and test them individually. -This way individual changes can be tested in the context of the -routine that they are in. -On many machines, accurate timing of a very short execution -sequences is not possible. -In addition, -there may be set up and tear down time for a test that -we do not really want included in the timing. -For this reason $code speed_test$$ -automatically determines how many times to -repeat the section of the test that we wish to time. - - -$head Include$$ -The file $code cppad/utility/speed_test.hpp$$ defines the -$code speed_test$$ function. -This file is included by $code cppad/cppad.hpp$$ -and it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head Vector$$ -We use $icode Vector$$ to denote a -$cref/simple vector class/SimpleVector/$$ with elements -of type $code size_t$$. - -$head test$$ -The $code speed_test$$ argument $icode test$$ is a function with the syntax -$codei% - %test%(%size%, %repeat%) -%$$ -and its return value is $code void$$. - -$subhead size$$ -The $icode test$$ argument $icode size$$ has prototype -$codei% - size_t %size% -%$$ -It specifies the size for this test. - -$subhead repeat$$ -The $icode test$$ argument $icode repeat$$ has prototype -$codei% - size_t %repeat% -%$$ -It specifies the number of times to repeat the test. - -$head size_vec$$ -The $code speed_test$$ argument $icode size_vec$$ has prototype -$codei% - const %Vector%& %size_vec% -%$$ -This vector determines the size for each of the tests problems. - -$head time_min$$ -The argument $icode time_min$$ has prototype -$codei% - double %time_min% -%$$ -It specifies the minimum amount of time in seconds -that the $icode test$$ routine should take. -The $icode repeat$$ argument to $icode test$$ is increased -until this amount of execution time is reached. - -$head rate_vec$$ -The return value $icode rate_vec$$ has prototype -$codei% - %Vector%& %rate_vec% -%$$ -We use $latex n$$ to denote its size which is the same as -the vector $icode size_vec$$. -For $latex i = 0 , \ldots , n-1$$, -$codei% - %rate_vec%[%i%] -%$$ -is the ratio of $icode repeat$$ divided by time in seconds -for the problem with size $icode%size_vec%[%i%]%$$. - -$head Timing$$ -If your system supports the unix $code gettimeofday$$ function, -it will be used to measure time. -Otherwise, -time is measured by the difference in -$codep - (double) clock() / (double) CLOCKS_PER_SEC -$$ -in the context of the standard $code $$ definitions. - -$children% - speed/example/speed_test.cpp -%$$ -$head Example$$ -The routine $cref speed_test.cpp$$ is an example and test -of $code speed_test$$. - -$end ------------------------------------------------------------------------ -*/ - -# include -# include - -# include -# include - - -namespace CppAD { // BEGIN CppAD namespace - -// implemented as an inline so that can include in multiple link modules -// with this same file -template -Vector speed_test( - void test(size_t size, size_t repeat), - const Vector& size_vec , - double time_min ) -{ - // check that size_vec is a simple vector with size_t elements - CheckSimpleVector(); - - size_t n = size_vec.size(); - Vector rate_vec(n); - size_t i; - for(i = 0; i < n; i++) - { size_t size = size_vec[i]; - size_t repeat = 1; - double s0 = elapsed_seconds(); - double s1 = elapsed_seconds(); - while( s1 - s0 < time_min ) - { repeat = 2 * repeat; - s0 = elapsed_seconds(); - test(size, repeat); - s1 = elapsed_seconds(); - } - double rate = .5 + double(repeat) / (s1 - s0); - // first convert to float to avoid warning with g++ -Wconversion - rate_vec[i] = static_cast( static_cast(rate) ); - } - return rate_vec; -} - -} // END CppAD namespace - -/* -$begin SpeedTest$$ -$spell - cppad.hpp - Microsoft - namespace - std - const - cout - ctime - ifdef - const - endif - cpp -$$ - - -$section Run One Speed Test and Print Results$$ - -$head Syntax$$ - -$codei%# include -%$$ -$codei%SpeedTest(%Test%, %first%, %inc%, %last%)%$$ - -$head See Also$$ -$cref time_test$$ - -$head Purpose$$ -The $code SpeedTest$$ function executes a speed test -for various sized problems -and reports the results on standard output; i.e. $code std::cout$$. -The size of each test problem is included in its report -(unless $icode first$$ is equal to $icode last$$). - -$head Motivation$$ -It is important to separate small calculation units -and test them individually. -This way individual changes can be tested in the context of the -routine that they are in. -On many machines, accurate timing of a very short execution -sequences is not possible. -In addition, -there may be set up time for a test that -we do not really want included in the timing. -For this reason $code SpeedTest$$ -automatically determines how many times to -repeat the section of the test that we wish to time. - - -$head Include$$ -The file $code speed_test.hpp$$ contains the -$code SpeedTest$$ function. -This file is included by $code cppad/utility/cppad.hpp$$ -but it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head Test$$ -The $code SpeedTest$$ argument $icode Test$$ is a function with the syntax -$codei% - %name% = %Test%(%size%, %repeat%) -%$$ - -$subhead size$$ -The $icode Test$$ argument $icode size$$ has prototype -$codei% - size_t %size% -%$$ -It specifies the size for this test. - -$subhead repeat$$ -The $icode Test$$ argument $icode repeat$$ has prototype -$codei% - size_t %repeat% -%$$ -It specifies the number of times to repeat the test. - -$subhead name$$ -The $icode Test$$ result $icode name$$ has prototype -$codei% - std::string %name% -%$$ -The results for this test are reported on $code std::cout$$ -with $icode name$$ as an identifier for the test. -It is assumed that, -for the duration of this call to $code SpeedTest$$, -$icode Test$$ will always return -the same value for $icode name$$. -If $icode name$$ is the empty string, -no test name is reported by $code SpeedTest$$. - -$head first$$ -The $code SpeedTest$$ argument $icode first$$ has prototype -$codei% - size_t %first% -%$$ -It specifies the size of the first test problem reported by this call to -$code SpeedTest$$. - -$head last$$ -The $code SpeedTest$$ argument $icode last$$ has prototype -$codei% - size_t %last% -%$$ -It specifies the size of the last test problem reported by this call to -$code SpeedTest$$. - -$head inc$$ -The $code SpeedTest$$ argument $icode inc$$ has prototype -$codei% - int %inc% -%$$ -It specifies the increment between problem sizes; i.e., -all values of $icode size$$ in calls to $icode Test$$ are given by -$codei% - %size% = %first% + %j% * %inc% -%$$ -where $icode j$$ is a positive integer. -The increment can be positive or negative but it cannot be zero. -The values $icode first$$, $icode last$$ and $icode inc$$ must -satisfy the relation -$latex \[ - inc * ( last - first ) \geq 0 -\] $$ - -$head rate$$ -The value displayed in the $code rate$$ column on $code std::cout$$ -is defined as the value of $icode repeat$$ divided by the -corresponding elapsed execution time in seconds. -The elapsed execution time is measured by the difference in -$codep - (double) clock() / (double) CLOCKS_PER_SEC -$$ -in the context of the standard $code $$ definitions. - - -$head Errors$$ -If one of the restrictions above is violated, -the CppAD error handler is used to report the error. -You can redefine this action using the instructions in -$cref ErrorHandler$$ - -$head Example$$ -$children% - speed/example/speed_program.cpp -%$$ -The program $cref speed_program.cpp$$ is an example usage -of $code SpeedTest$$. - -$end ------------------------------------------------------------------------ -*/ -// BEGIN C++ - - -# include -# include -# include -# include - -namespace CppAD { // BEGIN CppAD namespace - -inline void SpeedTestNdigit(size_t value, size_t &ndigit, size_t &pow10) -{ pow10 = 10; - ndigit = 1; - while( pow10 <= value ) - { pow10 *= 10; - ndigit += 1; - } -} - -// implemented as an inline so that can include in multiple link modules -// with this same file -inline void SpeedTest( - std::string Test(size_t size, size_t repeat), - size_t first, - int inc, - size_t last -) -{ - - using std::cout; - using std::endl; - - size_t size; - size_t repeat; - size_t rate; - size_t digit; - size_t ndigit; - size_t pow10; - size_t maxSize; - size_t maxSizeDigit; - - double s0; - double s1; - - std::string name; - - CPPAD_ASSERT_KNOWN( - inc != 0 && first != 0 && last != 0, - "inc, first, or last is zero in call to SpeedTest" - ); - CPPAD_ASSERT_KNOWN( - (inc > 0 && first <= last) || (inc < 0 && first >= last), - "SpeedTest: increment is positive and first > last or " - "increment is negative and first < last" - ); - - // compute maxSize - maxSize = size = first; - while( (inc > 0 && size <= last) || (inc < 0 && size >= last) ) - { - if( size > maxSize ) - maxSize = size; - - // next size - if( int(size) + inc > 0 ) - size = size_t( int(size) + inc ); - else - size = 0; - } - SpeedTestNdigit(maxSize, maxSizeDigit, pow10); - - size = first; - while( (inc > 0 && size <= last) || (inc < 0 && size >= last) ) - { - repeat = 1; - s0 = elapsed_seconds(); - s1 = elapsed_seconds(); - while( s1 - s0 < 1. ) - { repeat = 2 * repeat; - s0 = elapsed_seconds(); - name = Test(size, repeat); - s1 = elapsed_seconds(); - } - double r = .5 + double(repeat) / (s1 - s0); - // first convert to float to avoid warning with g++ -Wconversion - rate = static_cast( static_cast( r ) ); - - if( size == first && name != "" ) - cout << name << endl; - - if( first != last ) - { - // convert int(size_t) to avoid warning on _MSC_VER sys - std::cout << "size = " << int(size); - - SpeedTestNdigit(size, ndigit, pow10); - while( ndigit < maxSizeDigit ) - { cout << " "; - ndigit++; - } - cout << " "; - } - - cout << "rate = "; - SpeedTestNdigit(rate, ndigit, pow10); - while( ndigit > 0 ) - { - pow10 /= 10; - digit = rate / pow10; - - // convert int(size_t) to avoid warning on _MSC_VER sys - std::cout << int(digit); - - rate = rate % pow10; - ndigit -= 1; - - if( (ndigit > 0) && (ndigit % 3 == 0) ) - cout << ","; - } - cout << endl; - - // next size - if( int(size) + inc > 0 ) - size = size_t( int(size) + inc ); - else - size = 0; - } - return; -} - -} // END CppAD namespace - -// END C++ -# endif diff --git a/build-config/cppad/include/cppad/utility/test_boolofvoid.hpp b/build-config/cppad/include/cppad/utility/test_boolofvoid.hpp deleted file mode 100644 index 903e1f3d..00000000 --- a/build-config/cppad/include/cppad/utility/test_boolofvoid.hpp +++ /dev/null @@ -1,172 +0,0 @@ -# ifndef CPPAD_UTILITY_TEST_BOOLOFVOID_HPP -# define CPPAD_UTILITY_TEST_BOOLOFVOID_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin test_boolofvoid$$ -$spell - boolofvoid - const - std - bool - ipopt - cpp - cppad - hpp -$$ - -$section Object that Runs a Group of Tests$$ - -$head Syntax$$ -$codei%# include -%$$ -$codei%test_boolofvoid %Run%(%group%, %width%) -%$$ -$icode%Run%(%test%, %name%) -%$$ -$icode%ok% = %Run%.summary(%memory_ok%)%$$ - -$head Purpose$$ -The object $icode Run$$ is used to run a group of tests functions -and report the results on standard output. - -$head group$$ -The argument has prototype -$codei% - const std::string& %group% -%$$ -It is the name for this group of tests. - -$head width$$ -The argument has prototype -$codei% - size_t %width% -%$$ -It is the number of columns used to display the name of each test. -It must be greater than the maximum number of characters in a test name. - -$head test$$ -The argument has prototype -$codei% - bool %test%(void) -%$$ -It is a function that returns true (when the test passes) and false -otherwise. - -$head name$$ -The argument has prototype -$codei% - const std::string& %name% -%$$ -It is the name for the corresponding $icode test$$. - -$head memory_ok$$ -The argument has prototype -$codei% - bool %memory_ok% -%$$ -It is false if a memory leak is detected (and true otherwise). - -$head ok$$ -This is true if all of the tests pass (including the memory leak test), -otherwise it is false. - -$head Example$$ -See any of the main programs in the example directory; e.g., -$code example/ipopt_solve.cpp$$. - -$end -*/ - -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -/// One class object is used to run a group of tests -class test_boolofvoid { -private: - /// name for the group of test this object will run - const std::string group_; - /// number of characters used to display the name for each indiviual test - /// (must be larger than the number of characters in name for each test) - const size_t width_; - /// number of tests that have passed - size_t n_ok_; - /// number of tests that have failed - size_t n_error_; - -public: - /// ctor - test_boolofvoid(const std::string& group, size_t width) : - group_(group) , - width_(width) , - n_ok_(0) , - n_error_(0) - { std::cout << "Begin test group " << group_ << std::endl; } - /// destructor - ~test_boolofvoid(void) - { std::cout << "End test group " << group_ << std::endl; } - /// run one test - bool operator()(bool test(void), const std::string& name) - { CPPAD_ASSERT_KNOWN( - name.size() < width_ , - "test_boolofvoid: name does not have less characters than width" - ); - std::cout.width( int(width_) ); - std::cout.setf( std::ios_base::left ); - std::cout << name; - // - bool ok = test(); - if( ok ) - { std::cout << "OK" << std::endl; - n_ok_++; - } - else - { std::cout << "Error" << std::endl; - n_error_++; - } - return ok; - } - /// nuber of tests that passed - size_t n_ok(void) const - { return n_ok_; } - /// nuber of tests that failed - size_t n_error(void) const - { return n_error_; } - /// summary - bool summary(bool memory_ok ) - { - std::cout.width( int(width_) ); - std::cout.setf( std::ios_base::left ); - std::cout << "memory_leak"; - // - if( memory_ok ) - { std::cout << "OK" << std::endl; - n_ok_++; - } - else - { std::cout << "Error" << std::endl; - n_error_++; - } - if( n_error_ == 0 ) - std::cout << "All " << n_ok_ << " tests passed." << std::endl; - else - std::cout << n_error_ << " tests failed." << std::endl; - // - return n_error_ == 0; - } -}; - -} // END_CPPAD_NAMESPACE - -# endif diff --git a/build-config/cppad/include/cppad/utility/thread_alloc.hpp b/build-config/cppad/include/cppad/utility/thread_alloc.hpp deleted file mode 100644 index 50b9a1be..00000000 --- a/build-config/cppad/include/cppad/utility/thread_alloc.hpp +++ /dev/null @@ -1,1515 +0,0 @@ -# ifndef CPPAD_UTILITY_THREAD_ALLOC_HPP -# define CPPAD_UTILITY_THREAD_ALLOC_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -# include -# include -# include - - -# ifdef _MSC_VER -// Supress warning that Microsoft compiler changed its behavior and is now -// doing the correct thing at the statement: -// new(array + i) Type(); -# pragma warning(disable:4345) -# endif - -# include -# include -# include -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file thread_alloc.hpp -File used to define the CppAD multi-threading allocator class -*/ - -/*! -\def CPPAD_MAX_NUM_CAPACITY -Maximum number of different capacities the allocator will attempt. -This must be larger than the log base two of numeric_limit::max(). -*/ -# define CPPAD_MAX_NUM_CAPACITY 100 - -/*! -\def CPPAD_MIN_DOUBLE_CAPACITY -Minimum number of double values that will fit in an allocation. -*/ -# define CPPAD_MIN_DOUBLE_CAPACITY 16 - -/*! -\def CPPAD_TRACE_CAPACITY -If NDEBUG is not defined, print all calls to get_memory and return_memory -that correspond to this capacity and thread CPPAD_TRACE_THREAD. -(Note that if CPPAD_TRACE_CAPACITY is zero, or any other value not in the list -of capacities, no tracing will be done.) -*/ -# define CPPAD_TRACE_CAPACITY 0 - -/*! -\def CPPAD_TRACE_THREAD -If NDEBUG is not defined, print all calls to get_memory and return_memory -that correspond to this thead and capacity CPPAD_TRACE_CAPACITY. -*/ -# define CPPAD_TRACE_THREAD 0 - -/* -Note that Section 3.6.2 of ISO/IEC 14882:1998(E) states: "The storage for -objects with static storage duration (3.7.1) shall be zero-initialized -(8.5) before any other initialization takes place." -*/ - -/*! -Capacity vector for memory allocation block sizes. - -Only one of these objects should be created and used as a -static variable inside of the thread_alloc::capacity_info function. -*/ - -/*! -Allocator class that works well with an multi-threading environment. -*/ -class thread_alloc{ -// ============================================================================ -private: - - class capacity_t { - public: - /// number of capacity values actually used - size_t number; - /// the different capacity values - size_t value[CPPAD_MAX_NUM_CAPACITY]; - /// ctor - capacity_t(void) - { // Cannot figure out how to call thread_alloc::in_parallel here. - // CPPAD_ASSERT_UNKNOWN( - // ! thread_alloc::in_parallel() , "thread_alloc: " - // "parallel mode and parallel_setup not yet called." - // ); - number = 0; - size_t capacity = CPPAD_MIN_DOUBLE_CAPACITY * sizeof(double); - while( capacity < std::numeric_limits::max() / 2 ) - { CPPAD_ASSERT_UNKNOWN( number < CPPAD_MAX_NUM_CAPACITY ); - value[number++] = capacity; - // next capactiy is 3/2 times the current one - capacity = 3 * ( (capacity + 1) / 2 ); - } - CPPAD_ASSERT_UNKNOWN( number > 0 ); - } - }; - - class block_t { - public: - /// extra information (currently used by create and delete array) - size_t extra_; - /// an index that uniquely idenfifies both thread and capacity - size_t tc_index_; - /// pointer to the next memory allocation with the same tc_index_ - void* next_; - // ----------------------------------------------------------------- - /// make default constructor private. It is only used by constructor - /// for `root arrays below. - block_t(void) : extra_(0), tc_index_(0), next_(nullptr) - { } - }; - - // --------------------------------------------------------------------- - /// Vector of fixed capacity values for this allocator - static const capacity_t* capacity_info(void) - { CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - static const capacity_t capacity; - return &capacity; - } - // --------------------------------------------------------------------- - /// Structure of information for each thread - struct thread_alloc_info { - /// count of available bytes for this thread - size_t count_inuse_; - /// count of inuse bytes for this thread - size_t count_available_; - /// root of available list for this thread and each capacity - block_t root_available_[CPPAD_MAX_NUM_CAPACITY]; - /*! - root of inuse list for this thread and each capacity - If NDEBUG or CPPAD_DEBUG_AND_RELEASE is defined, this memory is not - used, but it still helps to separate this structure from the structure - for the next thread. - */ - block_t root_inuse_[CPPAD_MAX_NUM_CAPACITY]; - }; - // --------------------------------------------------------------------- - /*! - Set and Get hold available memory flag. - - \param set [in] - if true, the value returned by this return is changed. - - \param new_value [in] - if set is true, this is the new value returned by this routine. - Otherwise, new_value is ignored. - - \return - the current setting for this routine (which is initially false). - */ - static bool set_get_hold_memory(bool set, bool new_value = false) - { static bool value = false; - if( set ) - value = new_value; - return value; - } - // --------------------------------------------------------------------- - /*! - Get pointer to the information for this thread. - - \param thread [in] - Is the thread number for this information pointer. - - \param clear - If clear is true, then the information pointer for this thread - is deleted and the nullptr pointer is returned. - There must be no memory currently in either the inuse or avaialble - lists when this routine is called. - - \return - is the current informaiton pointer for this thread. - If clear is false, and the current pointer is nullptr, - a new infromation record is allocated and its pointer returned. - In this case, if info is the retured pointer, - info->count_inuse == 0 and - info->count_available == 0. - In addition, - for c = 0 , ... , CPPAD_MAX_NUM_CAPACITY-1 - info->root_inuse_[c].next_ == nullptr and - info->root_available_[c].next_ == nullptr. - */ - static thread_alloc_info* thread_info( - size_t thread , - bool clear = false ) - { static thread_alloc_info* all_info[CPPAD_MAX_NUM_THREADS]; - static thread_alloc_info zero_info; - - CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS ); - - thread_alloc_info* info = all_info[thread]; - if( clear ) - { if( info != nullptr ) - { -# ifndef NDEBUG - CPPAD_ASSERT_UNKNOWN( - info->count_inuse_ == 0 && - info->count_available_ == 0 - ); - for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++) - { CPPAD_ASSERT_UNKNOWN( - info->root_inuse_[c].next_ == nullptr && - info->root_available_[c].next_ == nullptr - ); - } -# endif - if( thread != 0 ) - ::operator delete( reinterpret_cast(info) ); - info = nullptr; - all_info[thread] = info; - } - } - else if( info == nullptr ) - { if( thread == 0 ) - info = &zero_info; - else - { size_t size = sizeof(thread_alloc_info); - void* v_ptr = ::operator new(size); - info = reinterpret_cast(v_ptr); - } - all_info[thread] = info; - - // initialize the information record - for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++) - { info->root_inuse_[c].next_ = nullptr; - info->root_available_[c].next_ = nullptr; - } - info->count_inuse_ = 0; - info->count_available_ = 0; - } - return info; - } - // ----------------------------------------------------------------------- - /*! - Increase the number of bytes of memory that are currently in use; i.e., - that been obtained with get_memory and not yet returned. - - \param inc [in] - amount to increase memory in use. - - \param thread [in] - Thread for which we are increasing the number of bytes in use - (must be less than num_threads). - Durring parallel execution, this must be the thread - that is currently executing. - */ - static void inc_inuse(size_t inc, size_t thread) - { - CPPAD_ASSERT_UNKNOWN( thread < num_threads() ); - CPPAD_ASSERT_UNKNOWN( - thread == thread_num() || (! in_parallel()) - ); - thread_alloc_info* info = thread_info(thread); - - // do the addition - size_t result = info->count_inuse_ + inc; - CPPAD_ASSERT_UNKNOWN( result >= info->count_inuse_ ); - - info->count_inuse_ = result; - } - // ----------------------------------------------------------------------- - /*! - Increase the number of bytes of memory that are currently avaialble; i.e., - have been obtained obtained from the system and are being held future use. - - \copydetails inc_inuse - */ - static void inc_available(size_t inc, size_t thread) - { - CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS); - CPPAD_ASSERT_UNKNOWN( - thread == thread_num() || (! in_parallel()) - ); - thread_alloc_info* info = thread_info(thread); - // do the addition - size_t result = info->count_available_ + inc; - CPPAD_ASSERT_UNKNOWN( result >= info->count_available_ ); - - info->count_available_ = result; - } - // ----------------------------------------------------------------------- - /*! - Decrease the number of bytes of memory that are currently in use; i.e., - that been obtained with get_memory and not yet returned. - - \param dec [in] - amount to decrease number of bytes in use. - - \param thread [in] - Thread for which we are decreasing the number of bytes in use - (must be less than num_threads). - Durring parallel execution, this must be the thread - that is currently executing. - */ - static void dec_inuse(size_t dec, size_t thread) - { - CPPAD_ASSERT_UNKNOWN( - thread < num_threads() || (! in_parallel()) - ); - CPPAD_ASSERT_UNKNOWN( - thread == thread_num() || (! in_parallel()) - ); - thread_alloc_info* info = thread_info(thread); - - // do the subtraction - CPPAD_ASSERT_UNKNOWN( info->count_inuse_ >= dec ); - info->count_inuse_ = info->count_inuse_ - dec; - } - // ----------------------------------------------------------------------- - /*! - Decrease the number of bytes of memory that are currently avaialble; i.e., - have been obtained obtained from the system and are being held future use. - - \copydetails dec_inuse - */ - static void dec_available(size_t dec, size_t thread) - { - CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS); - CPPAD_ASSERT_UNKNOWN( - thread == thread_num() || (! in_parallel()) - ); - thread_alloc_info* info = thread_info(thread); - // do the subtraction - CPPAD_ASSERT_UNKNOWN( info->count_available_ >= dec ); - info->count_available_ = info->count_available_ - dec; - } - - // ---------------------------------------------------------------------- - /*! - Set and get the number of threads that are sharing memory. - - \param number_new - If number is zero, we are only retreiving the current maximum - number of threads. Otherwise, we are setting and retreiving - maximum number of threads. - - \return - the number of threads that are sharing memory. - If number_new is non-zero, the return value is equal to - number_new. - */ - static size_t set_get_num_threads(size_t number_new) - { static size_t number_user = 1; - - CPPAD_ASSERT_UNKNOWN( number_new <= CPPAD_MAX_NUM_THREADS ); - CPPAD_ASSERT_UNKNOWN( ! in_parallel() || (number_new == 0) ); - - // case where we are changing the number of threads - if( number_new != 0 ) - number_user = number_new; - - return number_user; - } - /*! - Set and call the routine that determine the current thread number. - - \return - returns value for the most recent setting for thread_num_new. - If set is true, - or the most recent setting is nullptr (its initial value), - the return value is zero. - Otherwise the routine corresponding to the most recent setting - is called and its value returned by set_get_thread_num. - - \param thread_num_new [in] - If set is false, thread_num_new it is not used. - Otherwise, the current value of thread_num_new becomes the - most recent setting for thread_num. - - \param set - If set is true, then thread_num_new is becomes the most - recent setting for this set_get_thread_num. - */ - static size_t set_get_thread_num( - size_t (*thread_num_new)(void) , - bool set = false ) - { static size_t (*thread_num_user)(void) = nullptr; - - if( set ) - { thread_num_user = thread_num_new; - return 0; - } - - if( thread_num_user == nullptr ) - return 0; - - size_t thread = thread_num_user(); - CPPAD_ASSERT_KNOWN( - thread < set_get_num_threads(0) , - "parallel_setup: thread_num() >= num_threads" - ); - return thread; - } -// ============================================================================ -public: -/* -$begin ta_parallel_setup$$ -$spell - alloc - num - bool -$$ -$section Setup thread_alloc For Use in Multi-Threading Environment$$ - - - - -$head Syntax$$ -$codei%thread_alloc::parallel_setup(%num_threads%, %in_parallel%, %thread_num%) -%$$ - -$head Purpose$$ -By default there is only one thread and all execution is in sequential mode, -i.e., multiple threads are not sharing the same memory; i.e. -not in parallel mode. - -$head Speed$$ -It should be faster, even when $icode num_thread$$ is equal to one, -for $code thread_alloc$$ to hold onto memory. -This can be accomplished using the function call -$codei% - thread_alloc::hold_memory(true) -%$$ -see $cref/hold_memory/ta_hold_memory/$$. - -$head num_threads$$ -This argument has prototype -$codei% - size_t %num_threads% -%$$ -and must be greater than zero. -It specifies the number of threads that are sharing memory. -The case $icode%num_threads% == 1%$$ is a special case that is -used to terminate a multi-threading environment. - -$head in_parallel$$ -This function has prototype -$codei% - bool %in_parallel%(void) -%$$ -It must return $code true$$ if there is more than one thread -currently executing. -Otherwise it can return false. -$pre - -$$ -In the special case where $icode%num_threads% == 1%$$, -the routine $icode in_parallel$$ is not used. - -$head thread_num$$ -This function has prototype -$codei% - size_t %thread_num%(void) -%$$ -It must return a thread number that uniquely identifies the -currently executing thread. -Furthermore -$codei% - 0 <= %thread_num%() < %num_threads% -%$$. -In the special case where $icode%num_threads% == 1%$$, -the routine $icode thread_num$$ is not used. -$pre - -$$ -Note that this function is called by other routines so, -as soon as a new thread is executing, -one must be certain that $icode thread_num()$$ will -work for that thread. - -$head Restrictions$$ -The function $code parallel_setup$$ must be called before -the program enters $cref/parallel/ta_in_parallel/$$ execution mode. -In addition, this function cannot be called while in parallel mode. - -$head Example$$ -The files -$cref simple_ad_openmp.cpp$$, -$cref simple_ad_bthread.cpp$$, and -$cref simple_ad_pthread.cpp$$, -contain examples and tests that use this function. - -$end -*/ - /*! - Set thread_alloc up for parallel mode usage. - - \param num_threads [in] - Is the number of thread that may be executing at the same time. - - \param in_parallel [in] - Is the routine that determines if we are in parallel mode or not. - - \param thread_num [in] - Is the routine that determines the current thread number - (between zero and num_threads minus one). - */ - static void parallel_setup( - size_t num_threads , - bool (*in_parallel)(void) , - size_t (*thread_num)(void) ) - { - // Special case where we go back to single thread mode right away - // (previous settings may no longer be valid) - if( num_threads == 1 ) - { bool set = true; - set_get_num_threads(num_threads); - // emphasize that this routine is outside thread_alloc class - CppAD::local::set_get_in_parallel(nullptr, set); - set_get_thread_num(nullptr, set); - return; - } - - CPPAD_ASSERT_KNOWN( - num_threads <= CPPAD_MAX_NUM_THREADS , - "parallel_setup: num_threads is too large" - ); - CPPAD_ASSERT_KNOWN( - num_threads != 0 , - "parallel_setup: num_threads == zero" - ); - CPPAD_ASSERT_KNOWN( - in_parallel != nullptr , - "parallel_setup: num_threads != 1 and in_parallel == nullptr" - ); - CPPAD_ASSERT_KNOWN( - thread_num != nullptr , - "parallel_setup: num_threads != 1 and thread_num == nullptr" - ); - - // Make sure that constructors for all static variables in this file - // are called in sequential mode. - for(size_t thread = 0; thread < num_threads; thread++) - thread_info(thread); - capacity_info(); - size_t cap_bytes; - void* v_ptr = get_memory(0, cap_bytes); - - // free memory allocated by call to get_memory above - return_memory(v_ptr); - free_available( set_get_thread_num(nullptr) ); - - // delay this so thread_num() call above is in previous mode - // (current setings may not yet be valid) - if( num_threads > 1 ) - { bool set = true; - set_get_num_threads(num_threads); - // emphasize that this routine is outside thread_alloc class - CppAD::local::set_get_in_parallel(in_parallel, set); - set_get_thread_num(thread_num, set); - } - } -/* -$begin ta_num_threads$$ -$spell - inv - CppAD - num - alloc -$$ -$section Get Number of Threads$$ - - -$head Syntax$$ -$icode%number% = thread_alloc::num_threads()%$$ - -$head Purpose$$ -Determine the number of threads as set during $cref/parallel_setup/ta_parallel_setup/$$. - -$head number$$ -The return value $icode number$$ has prototype -$codei% - size_t %number% -%$$ -and is equal to the value of -$cref/num_threads/ta_parallel_setup/num_threads/$$ -in the previous call to $icode parallel_setup$$. -If there was no such previous call, the value one is returned. - -$head Example$$ -The example and test $cref thread_alloc.cpp$$ uses this routine. - -$end -*/ - /*! - Get the current number of threads that thread_alloc can use. - */ - static size_t num_threads(void) - { return set_get_num_threads(0); } -/* ----------------------------------------------------------------------- -$begin ta_in_parallel$$ - -$section Is The Current Execution in Parallel Mode$$ -$spell - thread_alloc - bool -$$ - - -$head Syntax$$ -$icode%flag% = thread_alloc::in_parallel()%$$ - -$head Purpose$$ -Some of the $cref thread_alloc$$ allocation routines have different -specifications for parallel (not sequential) execution mode. -This routine enables you to determine if the current execution mode -is sequential or parallel. - -$head flag$$ -The return value has prototype -$codei% - bool %flag% -%$$ -It is true if the current execution is in parallel mode -(possibly multi-threaded) and false otherwise (sequential mode). - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /// Are we in a parallel execution state; i.e., is it possible that - /// other threads are currently executing. - static bool in_parallel(void) - { // emphasize that this routine is outside thread_alloc class - return CppAD::local::set_get_in_parallel(0); - } -/* ----------------------------------------------------------------------- -$begin ta_thread_num$$ -$spell - CppAD - num - thread_alloc - cppad.hpp -$$ - -$section Get the Current Thread Number$$ - - -$head Syntax$$ -$icode%thread% = thread_alloc::thread_num()%$$ - -$head Purpose$$ -Some of the $cref thread_alloc$$ allocation routines have a thread number. -This routine enables you to determine the current thread. - -$head thread$$ -The return value $icode thread$$ has prototype -$codei% - size_t %thread% -%$$ -and is the currently executing thread number. - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /// Get current thread number - static size_t thread_num(void) - { return set_get_thread_num(nullptr); } -/* ----------------------------------------------------------------------- -$begin ta_get_memory$$ -$spell - std - num - ptr - thread_alloc -$$ - -$section Get At Least A Specified Amount of Memory$$ - - -$head Syntax$$ -$icode%v_ptr% = thread_alloc::get_memory(%min_bytes%, %cap_bytes%)%$$ - -$head Purpose$$ -Use $cref thread_alloc$$ to obtain a minimum number of bytes of memory -(for use by the $cref/current thread/ta_thread_num/$$). - -$head min_bytes$$ -This argument has prototype -$codei% - size_t %min_bytes% -%$$ -It specifies the minimum number of bytes to allocate. -This value must be less than -$codep - std::numeric_limits::max() / 2 -$$ - -$head cap_bytes$$ -This argument has prototype -$codei% - size_t& %cap_bytes% -%$$ -It's input value does not matter. -Upon return, it is the actual number of bytes (capacity) -that have been allocated for use, -$codei% - %min_bytes% <= %cap_bytes% -%$$ - -$head v_ptr$$ -The return value $icode v_ptr$$ has prototype -$codei% - void* %v_ptr% -%$$ -It is the location where the $icode cap_bytes$$ of memory -that have been allocated for use begins. - -$head Allocation Speed$$ -This allocation should be faster if the following conditions hold: -$list number$$ -The memory allocated by a previous call to $code get_memory$$ -is currently available for use. -$lnext -The current $icode min_bytes$$ is between -the previous $icode min_bytes$$ and previous $icode cap_bytes$$. -$lend - -$head Alignment$$ -We call a memory allocation aligned if the address is a multiple -of the number of bytes in a $code size_t$$ value. -If the system $code new$$ allocator is aligned, then $icode v_ptr$$ -pointer is also aligned. - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /*! - Use thread_alloc to get a specified amount of memory. - - If the memory allocated by a previous call to get_memory is now - avaialable, and min_bytes is between its previous value - and the previous cap_bytes, this memory allocation will have - optimal speed. Otherwise, the memory allocation is more complicated and - may have to wait for other threads to complete an allocation. - - \param min_bytes [in] - The minimum number of bytes of memory to be obtained for use. - - \param cap_bytes [out] - The actual number of bytes of memory obtained for use. - - \return - pointer to the beginning of the memory allocated for use. - */ - static void* get_memory(size_t min_bytes, size_t& cap_bytes) - { // see first_trace below - CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; - - // check that number of requested bytes is not to large - CPPAD_ASSERT_KNOWN( - min_bytes < std::numeric_limits::max() / 2 , - "get_memory(min_bytes, cap_bytes): min_bytes is too large" - ); - - size_t num_cap = capacity_info()->number; - using std::cout; - using std::endl; - - // determine the capacity for this request - size_t c_index = 0; - const size_t* capacity_vec = capacity_info()->value; - while( capacity_vec[c_index] < min_bytes ) - { ++c_index; - CPPAD_ASSERT_UNKNOWN(c_index < num_cap ); - } - cap_bytes = capacity_vec[c_index]; - - // determine the thread, capacity, and info for this thread - size_t thread = thread_num(); - size_t tc_index = thread * num_cap + c_index; - thread_alloc_info* info = thread_info(thread); - -# ifndef NDEBUG - // trace allocation - static bool first_trace = true; - if( cap_bytes == CPPAD_TRACE_CAPACITY && - thread == CPPAD_TRACE_THREAD && first_trace ) - { cout << endl; - cout << "thread_alloc: Trace for Thread = " << thread; - cout << " and capacity = " << cap_bytes << endl; - if( first_trace ) - first_trace = false; - } - -# ifndef CPPAD_DEBUG_AND_RELEASE - // Root nodes for both lists. Note these are different for different - // threads because tc_index is different for different threads. - block_t* inuse_root = info->root_inuse_ + c_index; -# endif -# endif - block_t* available_root = info->root_available_ + c_index; - - // check if we already have a node we can use - void* v_node = available_root->next_; - block_t* node = reinterpret_cast(v_node); - if( node != nullptr ) - { CPPAD_ASSERT_UNKNOWN( node->tc_index_ == tc_index ); - - // remove node from available list - available_root->next_ = node->next_; - - // return value for get_memory - void* v_ptr = reinterpret_cast(node + 1); -# ifndef NDEBUG -# ifndef CPPAD_DEBUG_AND_RELEASE - // add node to inuse list - node->next_ = inuse_root->next_; - inuse_root->next_ = v_node; -# endif - - // trace allocation - if( cap_bytes == CPPAD_TRACE_CAPACITY && - thread == CPPAD_TRACE_THREAD ) - { cout << "get_memory: v_ptr = " << v_ptr << endl; } -# endif - - // adjust counts - inc_inuse(cap_bytes, thread); - dec_available(cap_bytes, thread); - - // return pointer to memory, do not inclue thread_alloc information - return v_ptr; - } - - // Create a new node with thread_alloc information at front. - // This uses the system allocator, which is thread safe, but slower, - // because the thread might wait for a lock on the allocator. - v_node = ::operator new(sizeof(block_t) + cap_bytes); - node = reinterpret_cast(v_node); - node->tc_index_ = tc_index; - void* v_ptr = reinterpret_cast(node + 1); - -# ifndef NDEBUG -# ifndef CPPAD_DEBUG_AND_RELEASE - // add node to inuse list - node->next_ = inuse_root->next_; - inuse_root->next_ = v_node; -# endif - - // trace allocation - if( cap_bytes == CPPAD_TRACE_CAPACITY && - thread == CPPAD_TRACE_THREAD ) - { cout << "get_memory: v_ptr = " << v_ptr << endl; } -# endif - - // adjust counts - inc_inuse(cap_bytes, thread); - - return v_ptr; - } - -/* ----------------------------------------------------------------------- -$begin ta_return_memory$$ -$spell - num - ptr - thread_alloc -$$ - -$section Return Memory to thread_alloc$$ - - -$head Syntax$$ -$codei%thread_alloc::return_memory(%v_ptr%)%$$ - -$head Purpose$$ -If $cref/hold_memory/ta_hold_memory/$$ is false, -the memory is returned to the system. -Otherwise, the memory is retained by $cref thread_alloc$$ for quick future use -by the thread that allocated to memory. - -$head v_ptr$$ -This argument has prototype -$codei% - void* %v_ptr% -%$$. -It must be a pointer to memory that is currently in use; i.e. -obtained by a previous call to -$cref/get_memory/ta_get_memory/$$ and not yet returned. - -$head Thread$$ -Either the $cref/current thread/ta_thread_num/$$ must be the same as during -the corresponding call to $cref/get_memory/ta_get_memory/$$, -or the current execution mode must be sequential -(not $cref/parallel/ta_in_parallel/$$). - -$head NDEBUG$$ -If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster). -Otherwise, a list of in use pointers is searched to make sure -that $icode v_ptr$$ is in the list. - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /*! - Return memory that was obtained by get_memory. - If num_threads() == 1, - the memory is returned to the system. - Otherwise, it is retained by thread_alloc and available for use by - get_memory for this thread. - - \param v_ptr [in] - Value of the pointer returned by get_memory and still in use. - After this call, this pointer will available (and not in use). - - \par - We must either be in sequential (not parallel) execution mode, - or the current thread must be the same as for the corresponding call - to get_memory. - */ - static void return_memory(void* v_ptr) - { size_t num_cap = capacity_info()->number; - - block_t* node = reinterpret_cast(v_ptr) - 1; - size_t tc_index = node->tc_index_; - size_t thread = tc_index / num_cap; - size_t c_index = tc_index % num_cap; - size_t capacity = capacity_info()->value[c_index]; - - CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS ); - CPPAD_ASSERT_KNOWN( - thread == thread_num() || (! in_parallel()), - "Attempt to return memory for a different thread " - "while in parallel mode" - ); - - thread_alloc_info* info = thread_info(thread); -# ifndef NDEBUG -# ifndef CPPAD_DEBUG_AND_RELEASE - // remove node from inuse list - void* v_node = reinterpret_cast(node); - block_t* inuse_root = info->root_inuse_ + c_index; - block_t* previous = inuse_root; - while( (previous->next_ != nullptr) & (previous->next_ != v_node) ) - previous = reinterpret_cast(previous->next_); - - // check that v_ptr is valid - if( previous->next_ != v_node ) - { using std::endl; - std::ostringstream oss; - oss << "return_memory: attempt to return memory not in use"; - oss << endl; - oss << "v_ptr = " << v_ptr << endl; - oss << "thread = " << thread << endl; - oss << "capacity = " << capacity << endl; - oss << "See CPPAD_TRACE_THREAD & CPPAD_TRACE_CAPACITY in"; - oss << endl << "# include " << endl; - // oss.str() returns a string object with a copy of the current - // contents in the stream buffer. - std::string msg_str = oss.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(false, msg_char_star ); - } - // remove v_ptr from inuse list - previous->next_ = node->next_; -# endif - // trace option - if( capacity==CPPAD_TRACE_CAPACITY && thread==CPPAD_TRACE_THREAD ) - { std::cout << "return_memory: v_ptr = " << v_ptr << std::endl; } - -# endif - // capacity bytes are removed from the inuse pool - dec_inuse(capacity, thread); - - // check for case where we just return the memory to the system - if( ! set_get_hold_memory(false) ) - { ::operator delete( reinterpret_cast(node) ); - return; - } - - // add this node to available list for this thread and capacity - block_t* available_root = info->root_available_ + c_index; - node->next_ = available_root->next_; - available_root->next_ = reinterpret_cast(node); - - // capacity bytes are added to the available pool - inc_available(capacity, thread); - } -/* ----------------------------------------------------------------------- -$begin ta_free_available$$ -$spell - num - thread_alloc -$$ - -$section Free Memory Currently Available for Quick Use by a Thread$$ -$spell - inuse -$$ - - -$head Syntax$$ -$codei%thread_alloc::free_available(%thread%)%$$ - -$head Purpose$$ -Return to the system all the memory that is currently being -$cref/held/ta_hold_memory/$$ for quick use by the specified thread. - -$subhead Extra Memory$$ -In the case where $icode%thread% > 0%$$, -some extra memory is used to track allocations by the specified thread. -If -$codei% - thread_alloc::inuse(%thread%) == 0 -%$$ -the extra memory is also returned to the system. - -$head thread$$ -This argument has prototype -$codei% - size_t %thread% -%$$ -Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$, -or the current execution mode must be sequential -(not $cref/parallel/ta_in_parallel/$$). - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /*! - Return all the memory being held as available for a thread to the system. - - \param thread [in] - this thread that will no longer have any available memory after this call. - This must either be the thread currently executing, or we must be - in sequential (not parallel) execution mode. - */ - static void free_available(size_t thread) - { CPPAD_ASSERT_KNOWN( - thread < CPPAD_MAX_NUM_THREADS, - "Attempt to free memory for a thread >= CPPAD_MAX_NUM_THREADS" - ); - CPPAD_ASSERT_KNOWN( - thread == thread_num() || (! in_parallel()), - "Attempt to free memory for a different thread " - "while in parallel mode" - ); - - size_t num_cap = capacity_info()->number; - if( num_cap == 0 ) - return; - const size_t* capacity_vec = capacity_info()->value; - size_t c_index; - thread_alloc_info* info = thread_info(thread); - for(c_index = 0; c_index < num_cap; c_index++) - { size_t capacity = capacity_vec[c_index]; - block_t* available_root = info->root_available_ + c_index; - void* v_ptr = available_root->next_; - while( v_ptr != nullptr ) - { block_t* node = reinterpret_cast(v_ptr); - void* next = node->next_; - ::operator delete(v_ptr); - v_ptr = next; - - dec_available(capacity, thread); - } - available_root->next_ = nullptr; - } - CPPAD_ASSERT_UNKNOWN( available(thread) == 0 ); - if( inuse(thread) == 0 ) - { // clear the information for this thread - thread_info(thread, true); - } - } -/* ----------------------------------------------------------------------- -$begin ta_hold_memory$$ -$spell - alloc - num -$$ - -$section Control When Thread Alloc Retains Memory For Future Use$$ - -$head Syntax$$ -$codei%thread_alloc::hold_memory(%value%)%$$ - -$head Purpose$$ -It should be faster, even when $icode num_thread$$ is equal to one, -for $code thread_alloc$$ to hold onto memory. -Calling $icode hold_memory$$ with $icode value$$ equal to true, -instructs $code thread_alloc$$ to hold onto memory, -and put it in the $cref/available/ta_available/$$ pool, -after each call to $cref/return_memory/ta_return_memory/$$. - -$head value$$ -If $icode value$$ is true, -$code thread_alloc$$ with hold onto memory for future quick use. -If it is false, future calls to $cref/return_memory/ta_return_memory/$$ -will return the corresponding memory to the system. -By default (when $code hold_memory$$ has not been called) -$code thread_alloc$$ does not hold onto memory. - -$head free_available$$ -Memory that is being held by $code thread_alloc$$ can be returned -to the system using $cref/free_available/ta_free_available/$$. - -$end -*/ - /*! - Change the thread_alloc hold memory setting. - - \param value [in] - New value for the thread_alloc hold memory setting. - */ - static void hold_memory(bool value) - { bool set = true; - set_get_hold_memory(set, value); - } - -/* ----------------------------------------------------------------------- -$begin ta_inuse$$ -$spell - num - inuse - thread_alloc -$$ - -$section Amount of Memory a Thread is Currently Using$$ - - -$head Syntax$$ -$icode%num_bytes% = thread_alloc::inuse(%thread%)%$$ - -$head Purpose$$ -Memory being managed by $cref thread_alloc$$ has two states, -currently in use by the specified thread, -and quickly available for future use by the specified thread. -This function informs the program how much memory is in use. - -$head thread$$ -This argument has prototype -$codei% - size_t %thread% -%$$ -Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$, -or the current execution mode must be sequential -(not $cref/parallel/ta_in_parallel/$$). - -$head num_bytes$$ -The return value has prototype -$codei% - size_t %num_bytes% -%$$ -It is the number of bytes currently in use by the specified thread. - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /*! - Determine the amount of memory that is currently inuse. - - \param thread [in] - Thread for which we are determining the amount of memory - (must be < CPPAD_MAX_NUM_THREADS). - Durring parallel execution, this must be the thread - that is currently executing. - - \return - The amount of memory in bytes. - */ - static size_t inuse(size_t thread) - { - CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS); - CPPAD_ASSERT_UNKNOWN( - thread == thread_num() || (! in_parallel()) - ); - thread_alloc_info* info = thread_info(thread); - return info->count_inuse_; - } -/* ----------------------------------------------------------------------- -$begin ta_available$$ -$spell - num - thread_alloc -$$ - -$section Amount of Memory Available for Quick Use by a Thread$$ - - -$head Syntax$$ -$icode%num_bytes% = thread_alloc::available(%thread%)%$$ - -$head Purpose$$ -Memory being managed by $cref thread_alloc$$ has two states, -currently in use by the specified thread, -and quickly available for future use by the specified thread. -This function informs the program how much memory is available. - -$head thread$$ -This argument has prototype -$codei% - size_t %thread% -%$$ -Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$, -or the current execution mode must be sequential -(not $cref/parallel/ta_in_parallel/$$). - -$head num_bytes$$ -The return value has prototype -$codei% - size_t %num_bytes% -%$$ -It is the number of bytes currently available for use by the specified thread. - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /*! - Determine the amount of memory that is currently available for use. - - \copydetails inuse - */ - static size_t available(size_t thread) - { - CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS); - CPPAD_ASSERT_UNKNOWN( - thread == thread_num() || (! in_parallel()) - ); - thread_alloc_info* info = thread_info(thread); - return info->count_available_; - } -/* ----------------------------------------------------------------------- -$begin ta_create_array$$ -$spell - inuse - thread_alloc - sizeof -$$ - -$section Allocate An Array and Call Default Constructor for its Elements$$ - - -$head Syntax$$ -$icode%array% = thread_alloc::create_array<%Type%>(%size_min%, %size_out%)%$$. - -$head Purpose$$ -Create a new raw array using $cref thread_alloc$$ memory allocator -(works well in a multi-threading environment) -and call default constructor for each element. - -$head Type$$ -The type of the elements of the array. - -$head size_min$$ -This argument has prototype -$codei% - size_t %size_min% -%$$ -This is the minimum number of elements that there can be -in the resulting $icode array$$. - -$head size_out$$ -This argument has prototype -$codei% - size_t& %size_out% -%$$ -The input value of this argument does not matter. -Upon return, it is the actual number of elements -in $icode array$$ -($icode% size_min %<=% size_out%$$). - -$head array$$ -The return value $icode array$$ has prototype -$codei% - %Type%* %array% -%$$ -It is array with $icode size_out$$ elements. -The default constructor for $icode Type$$ is used to initialize the -elements of $icode array$$. -Note that $cref/delete_array/ta_delete_array/$$ -should be used to destroy the array when it is no longer needed. - -$head Delta$$ -The amount of memory $cref/inuse/ta_inuse/$$ by the current thread, -will increase $icode delta$$ where -$codei% - sizeof(%Type%) * (%size_out% + 1) > %delta% >= sizeof(%Type%) * %size_out% -%$$ -The $cref/available/ta_available/$$ memory will decrease by $icode delta$$, -(and the allocation will be faster) -if a previous allocation with $icode size_min$$ between its current value -and $icode size_out$$ is available. - -$head Alignment$$ -We call a memory allocation aligned if the address is a multiple -of the number of bytes in a $code size_t$$ value. -If the system $code new$$ allocator is aligned, then $icode array$$ -pointer is also aligned. - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /*! - Use thread_alloc to allocate an array, then call default construtor - for each element. - - \tparam Type - The type of the elements of the array. - - \param size_min [in] - The minimum number of elements in the array. - - \param size_out [out] - The actual number of elements in the array. - - \return - pointer to the first element of the array. - The default constructor is used to initialize - all the elements of the array. - - \par - The extra_ field, in the thread_alloc node before the return value, - is set to size_out. - */ - template - static Type* create_array(size_t size_min, size_t& size_out) - { // minimum number of bytes to allocate - size_t min_bytes = size_min * sizeof(Type); - // do the allocation - size_t num_bytes; - void* v_ptr = get_memory(min_bytes, num_bytes); - // This is where the array starts - Type* array = reinterpret_cast(v_ptr); - // number of Type values in the allocation - size_out = num_bytes / sizeof(Type); - // store this number in the extra field - block_t* node = reinterpret_cast(v_ptr) - 1; - node->extra_ = size_out; - - // call default constructor for each element - size_t i; - for(i = 0; i < size_out; i++) - new(array + i) Type(); - - return array; - } -/* ----------------------------------------------------------------------- -$begin ta_delete_array$$ -$spell - inuse - thread_alloc - sizeof - deallocate -$$ - -$section Deallocate An Array and Call Destructor for its Elements$$ - - -$head Syntax$$ -$codei%thread_alloc::delete_array(%array%)%$$. - -$head Purpose$$ -Returns memory corresponding to an array created by -(create by $cref/create_array/ta_create_array/$$) to the -$cref/available/ta_available/$$ memory pool for the current thread. - -$head Type$$ -The type of the elements of the array. - -$head array$$ -The argument $icode array$$ has prototype -$codei% - %Type%* %array% -%$$ -It is a value returned by $cref/create_array/ta_create_array/$$ and not yet deleted. -The $icode Type$$ destructor is called for each element in the array. - -$head Thread$$ -The $cref/current thread/ta_thread_num/$$ must be the -same as when $cref/create_array/ta_create_array/$$ returned the value $icode array$$. -There is an exception to this rule: -when the current execution mode is sequential -(not $cref/parallel/ta_in_parallel/$$) the current thread number does not matter. - -$head Delta$$ -The amount of memory $cref/inuse/ta_inuse/$$ will decrease by $icode delta$$, -and the $cref/available/ta_available/$$ memory will increase by $icode delta$$, -where $cref/delta/ta_create_array/Delta/$$ -is the same as for the corresponding call to $code create_array$$. - -$head Example$$ -$cref thread_alloc.cpp$$ - -$end -*/ - /*! - Return Memory Used for an Array to the Available Pool - (include destructor call for each element). - - \tparam Type - The type of the elements of the array. - - \param array [in] - A value returned by create_array that has not yet been deleted. - The Type destructor is used to destroy each of the elements - of the array. - - \par - Durring parallel execution, the current thread must be the same - as during the corresponding call to create_array. - */ - template - static void delete_array(Type* array) - { // determine the number of values in the array - block_t* node = reinterpret_cast(array) - 1; - size_t size = node->extra_; - - // call destructor for each element - size_t i; - for(i = 0; i < size; i++) - (array + i)->~Type(); - - // return the memory to the available pool for this thread - thread_alloc::return_memory( reinterpret_cast(array) ); - } -/* ----------------------------------------------------------------------- -$begin ta_free_all$$ -$spell - alloc - bool - inuse -$$ - -$section Free All Memory That Was Allocated for Use by thread_alloc$$ - - -$head Syntax$$ -$icode%ok% = thread_alloc::free_all()%$$. - -$head Purpose$$ -Returns all memory that was used by $code thread_alloc$$ to the system. - -$head ok$$ -The return value $icode ok$$ has prototype -$codei% - bool %ok% -%$$ -Its value will be $code true$$ if all the memory can be freed. -This requires that for all $icode thread$$ indices, there is no memory -$cref/inuse/ta_inuse/$$; i.e., -$codei% - 0 == thread_alloc::inuse(%thread%) -%$$ -Otherwise, the return value will be false. - -$head Restrictions$$ -This function cannot be called while in parallel mode. - -$head Example$$ -$cref thread_alloc.cpp$$ -$end -*/ - /*! - Return to the system all thread_alloc memory that is not currently inuse. - - \return - If no thread_alloc memory is currently inuse, - all memory is returned to the system and the return value is true. - Otherwise the return value is false. - */ - static bool free_all(void) - { CPPAD_ASSERT_KNOWN( - ! in_parallel(), - "free_all cannot be used while in parallel execution" - ); - bool ok = true; - size_t thread = CPPAD_MAX_NUM_THREADS; - while(thread--) - { ok &= inuse(thread) == 0; - free_available(thread); - } - return ok; - } -}; - - -} // END_CPPAD_NAMESPACE - -// preprocessor symbols local to this file -# undef CPPAD_MAX_NUM_CAPACITY -# undef CPPAD_MIN_DOUBLE_CAPACITY -# undef CPPAD_TRACE_CAPACITY -# undef CPPAD_TRACE_THREAD -# endif diff --git a/build-config/cppad/include/cppad/utility/time_test.hpp b/build-config/cppad/include/cppad/utility/time_test.hpp deleted file mode 100644 index 8a3c1d16..00000000 --- a/build-config/cppad/include/cppad/utility/time_test.hpp +++ /dev/null @@ -1,300 +0,0 @@ -# ifndef CPPAD_UTILITY_TIME_TEST_HPP -# define CPPAD_UTILITY_TIME_TEST_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin time_test$$ -$spell - gettimeofday - vec - cppad.hpp - Microsoft - namespace - std - const - cout - ctime - ifdef - const - endif - cpp -$$ - - -$section Determine Amount of Time to Execute a Test$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%time% = time_test(%test%, %time_min%) -%$$ -$icode%time% = time_test(%test%, %time_min%, %test_size%) -%$$ -$icode%time% = time_test(%test%, %time_min%, %test_size%, %repeat_out%) -%$$ - -$head Purpose$$ -The $code time_test$$ function executes a timing test -and reports the amount of wall clock time for execution. - -$head Motivation$$ -It is important to separate small calculation units -and test them individually. -This way individual changes can be tested in the context of the -routine that they are in. -On many machines, accurate timing of a very short execution -sequences is not possible. -In addition, -there may be set up and tear down time for a test that -we do not really want included in the timing. -For this reason $code time_test$$ -automatically determines how many times to -repeat the section of the test that we wish to time. - -$head Include$$ -The file $code cppad/utility/time_test.hpp$$ defines the -$code time_test$$ function. -This file is included by $code cppad/cppad.hpp$$ -and it can also be included separately with out the rest of -the $code CppAD$$ routines. - -$head test$$ -The $code time_test$$ argument $icode test$$ is a function, -or function object. -In the case where $icode test_size$$ is not present, -$icode test$$ supports the syntax -$codei% - %test%(%repeat%) -%$$ -In the case where $icode test_size$$ is present, -$icode test$$ supports the syntax -$codei% - %test%(%size%, %repeat%) -%$$ -In either case, the return value for $icode test$$ is $code void$$. - -$subhead size$$ -If the argument $icode size$$ is present, -it has prototype -$codei% - size_t %size% -%$$ -and is equal to the $icode test_size$$ argument to $code time_test$$. - -$subhead repeat$$ -The $icode test$$ argument $icode repeat$$ has prototype -$codei% - size_t %repeat% -%$$ -It specifies the number of times to repeat the test. - -$head time_min$$ -The argument $icode time_min$$ has prototype -$codei% - double %time_min% -%$$ -It specifies the minimum amount of time in seconds -that the $icode test$$ routine should take. -The $icode repeat$$ argument to $icode test$$ is increased -until this amount of execution time (or more) is reached. - -$head test_size$$ -If this argument is present, it argument has prototype -$codei% - size_t %test_size% -%$$ -In this case $icode test_size$$ will be present, and have the same value, -in each call to $icode test$$. - -$head repeat_out$$ -If this argument is present, it has prototype -$codei% - size_t& %repeat_out% -%$$ -This input value of this argument does not matter. -Upon return, it is the value of $cref/repeat/time_test/test/repeat/$$ -that corresponds to the return value $icode time$$; i.e., -the actual total time of the test is -$codei% - %total_time% = %repeat% * %time% -%$$ - -$head time$$ -The return value $icode time$$ has prototype -$codei% - double %time% -%$$ -and is the number of wall clock seconds that it took -to execute $icode test$$ divided by the value used for $icode repeat$$. - -$head Timing$$ -The routine $cref elapsed_seconds$$ will be used to determine the -amount of time it took to execute the test. - -$children% - include/cppad/utility/elapsed_seconds.hpp% - speed/example/time_test.cpp -%$$ -$head Example$$ -The routine $cref time_test.cpp$$ is an example and test -of $code time_test$$. - -$end ------------------------------------------------------------------------ -*/ - -# include -# include -# include -# include -# include - -# define CPPAD_EXTRA_RUN_BEFORE_TIMING 0 - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE -/*! -\file time_test.hpp -\brief Function that preforms one timing test (for speed of execution). -*/ - -/*! -Preform one wall clock execution timing test. - -\tparam Test -Either the type void (*)(size_t) -or a function object type that supports the same syntax. - -\param test -The function, or function object, that supports the operation -test(repeat) where repeat is the number of times -to repeat the tests operaiton that is being timed. - -\param time_min -is the minimum amount of time that test should take to preform -the repetitions of the operation being timed. - -\return -is the time for each execution of the test. -*/ -template -double time_test(Test test, double time_min ) -{ -# if CPPAD_EXTRA_RUN_BEFORE_TIMING - test(1); -# endif - size_t repeat = 0; - double s0 = elapsed_seconds(); - double s1 = s0; - while( s1 - s0 < time_min ) - { repeat = std::max(size_t(1), 2 * repeat); - s0 = elapsed_seconds(); - test(repeat); - s1 = elapsed_seconds(); - } - double time = (s1 - s0) / double(repeat); - return time; -} -/*! -Preform one wall clock execution timing test. - -\tparam Test -Either the type void (*)(size_t, size_t) -or a function object type that supports the same syntax. - -\param test -The function, or function object, that supports the operation -test(size, repeat) where size -is the size for this test and repeat is the number of times -to repeat the tests operaiton that is being timed. - -\param time_min -is the minimum amount of time that test should take to preform -the repetitions of the operation being timed. - -\param test_size -will be used for the value of size in the call to test. - -\return -is the time for each execution of the test. -*/ -template -double time_test(Test test, double time_min, size_t test_size) -{ -# if CPPAD_EXTRA_RUN_BEFORE_TIMING - test(test_size, 1); -# endif - size_t repeat = 0; - double s0 = elapsed_seconds(); - double s1 = s0; - while( s1 - s0 < time_min ) - { repeat = std::max(size_t(1), 2 * repeat); - s0 = elapsed_seconds(); - test(test_size, repeat); - s1 = elapsed_seconds(); - } - double time = (s1 - s0) / double(repeat); - return time; -} -/*! -Preform one wall clock execution timing test. - -\tparam Test -Either the type void (*)(size_t, size_t) -or a function object type that supports the same syntax. - -\param test -The function, or function object, that supports the operation -test(size, repeat) where size -is the size for this test and repeat is the number of times -to repeat the tests operaiton that is being timed. - -\param time_min -is the minimum amount of time that test should take to preform -the repetitions of the operation being timed. - -\param test_size -will be used for the value of size in the call to test. - -\param repeat_out -the return value is the number of times the test was repeated; -i.e., the return value is the total time divided by repeat. - -\return -is the time for each execution of the test. -*/ -template -double time_test( - Test test, double time_min, size_t test_size, size_t& repeat_out -) -{ -# if CPPAD_EXTRA_RUN_BEFORE_TIMING - test(test_size, 1); -# endif - repeat_out = 0; - double s0 = elapsed_seconds(); - double s1 = s0; - while( s1 - s0 < time_min ) - { repeat_out = std::max(size_t(1), 2 * repeat_out); - s0 = elapsed_seconds(); - test(test_size, repeat_out); - s1 = elapsed_seconds(); - } - double time = (s1 - s0) / double(repeat_out); - return time; -} - -} // END_CPPAD_NAMESPACE - -# undef CPPAD_EXTRA_RUN_BEFORE_TIMING -// END PROGRAM -# endif diff --git a/build-config/cppad/include/cppad/utility/to_string.hpp b/build-config/cppad/include/cppad/utility/to_string.hpp deleted file mode 100644 index 8df0865c..00000000 --- a/build-config/cppad/include/cppad/utility/to_string.hpp +++ /dev/null @@ -1,172 +0,0 @@ -# ifndef CPPAD_UTILITY_TO_STRING_HPP -# define CPPAD_UTILITY_TO_STRING_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin to_string$$ -$spell - cppad.hpp - long long - std - const - ostringstream -$$ - -$section Convert Certain Types to a String$$ - -$head Syntax$$ -$codei%# include -%$$ -$icode%s% = to_string(%value%)%$$. - -$head See Also$$ -$cref base_to_string$$, $cref ad_to_string$$ - -$head Purpose$$ -This routine is similar to the C++11 routine $code std::to_string$$ -with the following differences: -$list number$$ -It works with C++98. -$lnext -It has been extended to the fundamental floating point types. -$lnext -It has specifications for extending to an arbitrary type; see -$cref base_to_string$$. -$lnext -If $code $$ is included, -and it has been extended to a $icode Base$$ type, -it automatically extends to the -$cref/AD types above Base/glossary/AD Type Above Base/$$. -$lnext -For integer types, conversion to a string is exact. -For floating point types, conversion to a string yields a value -that has relative error within machine epsilon. -$lend - -$head value$$ - -$subhead Integer$$ -The argument $icode value$$ can have the following prototype -$codei% - const %Integer%& %value% -%$$ -where $icode Integer$$ is any of the fundamental integer types; e.g., -$code short int$$ and $code unsigned long$$. -Note that if C++11 is supported by this compilation, -$code unsigned long long$$ is also a fundamental integer type. - -$subhead Float$$ -The argument $icode value$$ can have the following prototype -$codei% - const %Float%& %value% -%$$ -where $icode Float$$ is any of the fundamental floating point types; i.e., -$code float$$, $code double$$, and $code long double$$. - -$head s$$ -The return value has prototype -$codei% - std::string %s% -%$$ -and contains a representation of the specified $icode value$$. - -$subhead Integer$$ -If $icode value$$ is an $codei Integer$$, -the representation is equivalent to $codei%os% << %value%$$ -where $icode os$$ is an $code std::ostringstream$$. - -$subhead Float$$ -If $icode value$$ is a $codei Float$$, -enough digits are used in the representation so that -the result is accurate to withing round off error. - -$children% - example/utility/to_string.cpp -%$$ -$head Example$$ -The file $cref to_string.cpp$$ -contains an example and test of this routine. - -$end -*/ -# include -# include -# include -# include -# include - -# define CPPAD_SPECIALIZE_TO_STRING_INTEGER(Type) \ -template <> struct to_string_struct\ -{ std::string operator()(const Type& value) \ - { std::stringstream os;\ - os << value;\ - return os.str();\ - }\ -}; - -# define CPPAD_SPECIALIZE_TO_STRING_FLOAT(Float) \ -template <> struct to_string_struct\ -{ std::string operator()(const Float& value) \ - { std::stringstream os;\ - int n_digits = 1 + std::numeric_limits::digits10;\ - os << std::setprecision(n_digits);\ - os << value;\ - return os.str();\ - }\ -}; - -namespace CppAD { - - // Default implementation, - // each type must define its own specilization. - template - struct to_string_struct - { std::string operator()(const Type& value) - { CPPAD_ASSERT_KNOWN( - false, - "to_string is not implemented for this type" - ); - // return empty string - return std::string(""); - } - }; - - // specialization for the fundamental integer types - CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed short) - CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned short) - // - CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed int) - CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned int) - // - CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed long) - CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned long) - // - CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed long long) - CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned long long) - - // specialization for the fundamental floating point types - CPPAD_SPECIALIZE_TO_STRING_FLOAT(float) - CPPAD_SPECIALIZE_TO_STRING_FLOAT(double) - CPPAD_SPECIALIZE_TO_STRING_FLOAT(long double) - - // link from function to function object in structure - template - std::string to_string(const Type& value) - { to_string_struct to_str; - return to_str(value); - } -} - -# undef CPPAD_SPECIALIZE_TO_STRING_FLOAT -# undef CPPAD_SPECIALIZE_TO_STRING_INTEGER -# endif diff --git a/build-config/cppad/include/cppad/utility/track_new_del.hpp b/build-config/cppad/include/cppad/utility/track_new_del.hpp deleted file mode 100644 index 143ba32a..00000000 --- a/build-config/cppad/include/cppad/utility/track_new_del.hpp +++ /dev/null @@ -1,533 +0,0 @@ -# ifndef CPPAD_UTILITY_TRACK_NEW_DEL_HPP -# define CPPAD_UTILITY_TRACK_NEW_DEL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ -/* -$begin TrackNewDel$$ -$spell - cppad.hpp - Cpp - newptr - Vec - oldptr - newlen - ncopy - const -$$ - -$section Routines That Track Use of New and Delete$$ - -$head Deprecated 2007-07-23$$ -All these routines have been deprecated. -You should use the $cref thread_alloc$$ memory allocator instead -(which works better in both a single thread and -properly in multi-threading environment). - -$head Syntax$$ -$codei%# include -%$$ -$icode%newptr% = TrackNewVec(%file%, %line%, %newlen%, %oldptr%) -%$$ -$codei%TrackDelVec(%file%, %line%, %oldptr%) -%$$ -$icode%newptr% = TrackExtend(%file%, %line%, %newlen%, %ncopy%, %oldptr%) -%$$ -$icode%count% = TrackCount(%file%, %line%)%$$ - - -$head Purpose$$ -These routines -aid in the use of $code new[]$$ and $code delete[]$$ -during the execution of a C++ program. - -$head Include$$ -The file $code cppad/utility/track_new_del.hpp$$ is included by -$code cppad/cppad.hpp$$ -but it can also be included separately with out the rest of the -CppAD include files. - - -$head file$$ -The argument $icode file$$ has prototype -$codei% - const char *%file% -%$$ -It should be the source code file name -where the call to $code TrackNew$$ is located. -The best way to accomplish this is the use the preprocessor symbol -$code __FILE__$$ for this argument. - -$head line$$ -The argument $icode line$$ has prototype -$codei% - int %line% -%$$ -It should be the source code file line number -where the call to $code TrackNew$$ is located. -The best way to accomplish this is the use the preprocessor symbol -$code __LINE__$$ for this argument. - -$head oldptr$$ -The argument $icode oldptr$$ has prototype -$codei% - %Type% *%oldptr% -%$$ -This argument is used to identify the type $icode Type$$. - -$head newlen$$ -The argument $icode newlen$$ has prototype -$codei% - size_t %newlen% -%$$ - -$head head newptr$$ -The return value $icode newptr$$ has prototype -$codei% - %Type% *%newptr% -%$$ -It points to the newly allocated vector of objects -that were allocated using -$codei% - new Type[%newlen%] -%$$ - -$head ncopy$$ -The argument $icode ncopy$$ has prototype -$codei% - size_t %ncopy% -%$$ -This specifies the number of elements that are copied from -the old array to the new array. -The value of $icode ncopy$$ -must be less than or equal $icode newlen$$. - -$head TrackNewVec$$ -If $code NDEBUG$$ is defined, this routine only sets -$codei% - %newptr% = %Type% new[%newlen%] -%$$ -The value of $icode oldptr$$ does not matter -(except that it is used to identify $icode Type$$). -If $code NDEBUG$$ is not defined, $code TrackNewVec$$ also -tracks the this memory allocation. -In this case, if memory cannot be allocated -$cref ErrorHandler$$ is used to generate a message -stating that there was not sufficient memory. - -$subhead Macro$$ -The preprocessor macro call -$codei% - CPPAD_TRACK_NEW_VEC(%newlen%, %oldptr%) -%$$ -expands to -$codei% - CppAD::TrackNewVec(__FILE__, __LINE__, %newlen%, %oldptr%) -%$$ - -$subhead Previously Deprecated$$ -The preprocessor macro $code CppADTrackNewVec$$ is the -same as $code CPPAD_TRACK_NEW_VEC$$ and was previously deprecated. - -$head TrackDelVec$$ -This routine is used to a vector of objects -that have been allocated using $code TrackNew$$ or $code TrackExtend$$. -If $code NDEBUG$$ is defined, this routine only frees memory with -$codei% - delete [] %oldptr% -%$$ -If $code NDEBUG$$ is not defined, $code TrackDelete$$ also checks that -$icode oldptr$$ was allocated by $code TrackNew$$ or $code TrackExtend$$ -and has not yet been freed. -If this is not the case, -$cref ErrorHandler$$ is used to generate an error message. - -$subhead Macro$$ -The preprocessor macro call -$codei% - CPPAD_TRACK_DEL_VEC(%oldptr%) -%$$ -expands to -$codei% - CppAD::TrackDelVec(__FILE__, __LINE__, %oldptr%) -%$$ - -$subhead Previously Deprecated$$ -The preprocessor macro $code CppADTrackDelVec$$ is the -same as $code CPPAD_TRACK_DEL_VEC$$ was previously deprecated. - -$head TrackExtend$$ -This routine is used to -allocate a new vector (using $code TrackNewVec$$), -copy $icode ncopy$$ elements from the old vector to the new vector. -If $icode ncopy$$ is greater than zero, $icode oldptr$$ -must have been allocated using $code TrackNewVec$$ or $code TrackExtend$$. -In this case, the vector pointed to by $icode oldptr$$ -must be have at least $icode ncopy$$ elements -and it will be deleted (using $code TrackDelVec$$). -Note that the dependence of $code TrackExtend$$ on $code NDEBUG$$ -is indirectly through the routines $code TrackNewVec$$ and -$code TrackDelVec$$. - -$subhead Macro$$ -The preprocessor macro call -$codei% - CPPAD_TRACK_EXTEND(%newlen%, %ncopy%, %oldptr%) -%$$ -expands to -$codei% - CppAD::TrackExtend(__FILE__, __LINE__, %newlen%, %ncopy%, %oldptr%) -%$$ - -$subhead Previously Deprecated$$ -The preprocessor macro $code CppADTrackExtend$$ is the -same as $code CPPAD_TRACK_EXTEND$$ and was previously deprecated. - -$head TrackCount$$ -The return value $icode count$$ has prototype -$codei% - size_t %count% -%$$ -If $code NDEBUG$$ is defined, $icode count$$ will be zero. -Otherwise, it will be -the number of vectors that -have been allocated -(by $code TrackNewVec$$ or $code TrackExtend$$) -and not yet freed -(by $code TrackDelete$$). - -$subhead Macro$$ -The preprocessor macro call -$codei% - CPPAD_TRACK_COUNT() -%$$ -expands to -$codei% - CppAD::TrackCount(__FILE__, __LINE__) -%$$ - -$subhead Previously Deprecated$$ -The preprocessor macro $code CppADTrackCount$$ is the -same as $code CPPAD_TRACK_COUNT$$ and was previously deprecated. - -$head Multi-Threading$$ -These routines cannot be used $cref/in_parallel/ta_in_parallel/$$ -execution mode. -Use the $cref thread_alloc$$ routines instead. - -$end ------------------------------------------------------------------------------- -*/ -# include -# include -# include -# include -# include - -# ifndef CPPAD_TRACK_DEBUG -# define CPPAD_TRACK_DEBUG 0 -# endif - -// ------------------------------------------------------------------------- -# define CPPAD_TRACK_NEW_VEC(newlen, oldptr) \ - CppAD::TrackNewVec(__FILE__, __LINE__, newlen, oldptr) - -# define CPPAD_TRACK_DEL_VEC(oldptr) \ - CppAD::TrackDelVec(__FILE__, __LINE__, oldptr) - -# define CPPAD_TRACK_EXTEND(newlen, ncopy, oldptr) \ - CppAD::TrackExtend(__FILE__, __LINE__, newlen, ncopy, oldptr) - -# define CPPAD_TRACK_COUNT() \ - CppAD::TrackCount(__FILE__, __LINE__) -// ------------------------------------------------------------------------- -# define CppADTrackNewVec CPPAD_TRACK_NEW_VEC -# define CppADTrackDelVec CPPAD_TRACK_DEL_VEC -# define CppADTrackExtend CPPAD_TRACK_EXTEND -# define CppADTrackCount CPPAD_TRACK_COUNT -// ------------------------------------------------------------------------- -namespace CppAD { // Begin CppAD namespace - -// TrackElement ------------------------------------------------------------ -class TrackElement { - -public: - std::string file; // corresponding file name - int line; // corresponding line number - void *ptr; // value returned by TrackNew - TrackElement *next; // next element in linked list - - // default contructor (used to initialize root) - TrackElement(void) - : file(""), line(0), ptr(nullptr), next(nullptr) - { } - - TrackElement(const char *f, int l, void *p) - : file(f), line(l), ptr(p), next(nullptr) - { CPPAD_ASSERT_UNKNOWN( p != nullptr); - } - - // There is only one tracking list and it starts it here - static TrackElement *Root(void) - { CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() ); - static TrackElement root; - return &root; - } - - // Print one tracking element - static void Print(TrackElement* E) - { - CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() ); - using std::cout; - cout << "E = " << E; - cout << ", E->next = " << E->next; - cout << ", E->ptr = " << E->ptr; - cout << ", E->line = " << E->line; - cout << ", E->file = " << E->file; - cout << std::endl; - } - - // Print the linked list for a thread - static void Print(void) - { - CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() ); - using std::cout; - using std::endl; - TrackElement *E = Root(); - // convert int(size_t) to avoid warning on _MSC_VER systems - cout << "Begin Track List" << endl; - while( E->next != nullptr ) - { E = E->next; - Print(E); - } - cout << "End Track List:" << endl; - cout << endl; - } -}; - - -// TrackError ---------------------------------------------------------------- -inline void TrackError( - const char *routine, - const char *file, - int line, - const char *msg ) -{ - CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() ); - std::ostringstream buf; - buf << routine - << ": at line " - << line - << " in file " - << file - << std::endl - << msg; - std::string str = buf.str(); - size_t n = str.size(); - size_t i; - char *message = new char[n + 1]; - for(i = 0; i < n; i++) - message[i] = str[i]; - message[n] = '\0'; - CPPAD_ASSERT_KNOWN( false , message); -} - -// TrackNewVec --------------------------------------------------------------- -# ifdef NDEBUG -template -Type *TrackNewVec( - const char *file, int line, size_t len, Type * /* oldptr */ ) -{ -# if CPPAD_TRACK_DEBUG - static bool first = true; - if( first ) - { std::cout << "NDEBUG is defined for TrackNewVec" << std::endl; - first = false; - } -# endif - return (new Type[len]); -} - -# else - -template -Type *TrackNewVec( - const char *file , - int line , - size_t len , - Type * /* oldptr */ ) -{ - CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "attempt to use TrackNewVec in parallel execution mode." - ); - // try to allocate the new memrory - Type *newptr = nullptr; - try - { newptr = new Type[len]; - } - catch(...) - { TrackError("TrackNewVec", file, line, - "Cannot allocate sufficient memory" - ); - } - // create tracking element - void *vptr = static_cast(newptr); - TrackElement *E = new TrackElement(file, line, vptr); - - // get the root - TrackElement *root = TrackElement::Root(); - - // put this elemenent at the front of linked list - E->next = root->next; - root->next = E; - -# if CPPAD_TRACK_DEBUG - std::cout << "TrackNewVec: "; - TrackElement::Print(E); -# endif - - return newptr; -} - -# endif - -// TrackDelVec -------------------------------------------------------------- -# ifdef NDEBUG -template -void TrackDelVec(const char *file, int line, Type *oldptr) -{ -# if CPPAD_TRACK_DEBUG - static bool first = true; - if( first ) - { std::cout << "NDEBUG is defined in TrackDelVec" << std::endl; - first = false; - } -# endif - delete [] oldptr; -} - -# else - -template -void TrackDelVec( - const char *file , - int line , - Type *oldptr ) -{ - CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "attempt to use TrackDelVec in parallel execution mode." - ); - TrackElement *P; - TrackElement *E; - - // search list for pointer - P = TrackElement::Root(); - E = P->next; - void *vptr = static_cast(oldptr); - while(E != nullptr && E->ptr != vptr) - { P = E; - E = E->next; - } - - // check if pointer was not in list - if( E == nullptr || E->ptr != vptr ) TrackError( - "TrackDelVec", file, line, - "Invalid value for the argument oldptr.\n" - "Possible linking of debug and NDEBUG compilations of CppAD." - ); - -# if CPPAD_TRACK_DEBUG - std::cout << "TrackDelVec: "; - TrackElement::Print(E); -# endif - - // remove tracking element from list - P->next = E->next; - - // delete allocated pointer - delete [] oldptr; - - // delete tracking element - delete E; - - return; -} - -# endif - -// TrackExtend -------------------------------------------------------------- -template -Type *TrackExtend( - const char *file , - int line , - size_t newlen , - size_t ncopy , - Type *oldptr ) -{ - CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "attempt to use TrackExtend in parallel execution mode." - ); - -# if CPPAD_TRACK_DEBUG - using std::cout; - cout << "TrackExtend: file = " << file; - cout << ", line = " << line; - cout << ", newlen = " << newlen; - cout << ", ncopy = " << ncopy; - cout << ", oldptr = " << oldptr; - cout << std::endl; -# endif - CPPAD_ASSERT_KNOWN( - ncopy <= newlen, - "TrackExtend: ncopy is greater than newlen." - ); - - // allocate the new memrory - Type *newptr = TrackNewVec(file, line, newlen, oldptr); - - // copy the data - size_t i; - for(i = 0; i < ncopy; i++) - newptr[i] = oldptr[i]; - - // delete the old vector - if( ncopy > 0 ) - TrackDelVec(file, line, oldptr); - - return newptr; -} - -// TrackCount -------------------------------------------------------------- -inline size_t TrackCount(const char *file, int line) -{ - CPPAD_ASSERT_KNOWN( - ! thread_alloc::in_parallel() , - "attempt to use TrackCount in parallel execution mode." - ); - size_t count = 0; - TrackElement *E = TrackElement::Root(); - while( E->next != nullptr ) - { ++count; - E = E->next; - } - return count; -} -// --------------------------------------------------------------------------- - -} // End CppAD namespace - -// preprocessor symbols local to this file -# undef CPPAD_TRACK_DEBUG - -# endif diff --git a/build-config/cppad/include/cppad/utility/vector.hpp b/build-config/cppad/include/cppad/utility/vector.hpp deleted file mode 100644 index 1b55b1c6..00000000 --- a/build-config/cppad/include/cppad/utility/vector.hpp +++ /dev/null @@ -1,543 +0,0 @@ -# ifndef CPPAD_UTILITY_VECTOR_HPP -# define CPPAD_UTILITY_VECTOR_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -# include -# include -# include -# include -# include - -// Note that CPPAD_CONST is undefined by cppad_vector_itr.hpp -# define CPPAD_CONST 0 -# include -# undef CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP -# define CPPAD_CONST 1 -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -// ========================================================================== -template class vector { -// ========================================================================== -/* -$begin cppad_vector_member$$ -$spell - vec -$$ - -$section Vector Class: Member Data$$ - -$head Syntax$$ -$icode%vec%.capacity() -%$$ -$icode%vec%.size() -%$$ -$icode%vec%.data() -%$$ - -$head Type$$ -is the type of the elements in the array. - -$head capacity_$$ -Number of $icode Type$$ elements in $code data_$$ that have been allocated -(and constructor has been called). - -$head length_$$ -Number of $icode Type$$ elements currently in this vector. - -$head data_$$ -Pointer to the first element of the vector -(not defined and should not be used when $code capacity_$$ is 0). - -$head Source$$ -$srccode%hpp% */ -private: - size_t capacity_; - size_t length_; - Type* data_; -public: - size_t capacity(void) const noexcept - { return capacity_; } - size_t size(void) const noexcept - { return length_; } - const Type* data(void) const noexcept - { return data_; } - Type* data(void) noexcept - { return data_; } -/* %$$ -$end ------------------------------------------------------------------------------ -$begin cppad_vector_typedef$$ -$spell - const_iterator -$$ - -$section Vector Class: Type Definitions$$ - -$head value_type$$ -type corresponding to an element of a vector. - -$head iterator$$ -type corresponding to an iterator for a vector. - -$head const_iterator$$ -type corresponding to an iterator for a vector when -the vector is $code const$$. - -$srccode%hpp% */ -public: - typedef Type value_type; - typedef local::utility::cppad_vector_itr iterator; - typedef local::utility::const_cppad_vector_itr const_iterator; -/* %$$ -$end ------------------------------------------------------------------------------ -$begin cppad_vector_ctor$$ -$spell - vec -$$ - -$section Vector Class: Constructors and Destructor$$ - -$head Default$$ -$codei%vector<%Type%> %vec% -%$$ -creates an empty vector no elements and capacity zero. - -$head Sizing$$ -$codei%vector<%Type%> %vec%(%n%) -%$$ -where $icode n$$ is a $code size_t$$ or $code int$$, -creates the vector $icode vec$$ with $icode n$$ elements and capacity -greater than or equal $icode n$$. - -$head Copy$$ -$codei%vector<%Type%> %vec%(%other%) -%$$ -where $icode other$$ is a $codei%vector<%Type%>%$$, -creates the vector $icode vec$$ -with $icode%n% = %other%.size()%$$ elements and capacity -greater than or equal $icode n$$. - -$head Move Semantics$$ -A move semantics version of the copy operator -is implemented using $code swap$$. - -$head Destructor$$ -If $code capacity_$$ is non-zero, call the destructor -for all the corresponding elements and then frees the corresponding memory. - -$head delete_data$$ -Call destructor and free all the allocated elements -(there are $code capacity_$$ such elements). - -$head Source$$ -$srccode%hpp% */ -public: - vector(void) noexcept - : capacity_(0), length_(0), data_(nullptr) - { } - vector(size_t n) : capacity_(0), length_(0), data_(nullptr) - { resize(n); } - vector(int n) : capacity_(0), length_(0), data_(nullptr) - { CPPAD_ASSERT_KNOWN( - n >= 0, - "CppAD::vector: attempt to create a vector with a negative size." - ); - resize( size_t(n) ); - } - vector(const vector& other) : capacity_(0), length_(0), data_(nullptr) - { resize(other.length_); - for(size_t i = 0; i < length_; i++) - data_[i] = other.data_[i]; - } - // capacity_ is only value required to make destructor work for other - // after this move semantics constuctor - vector(vector&& other) : capacity_(0), length_(0), data_(nullptr) - { swap(other); } - ~vector(void) - { if( capacity_ > 0 ) delete_data(data_); } -private: - void delete_data(Type* data_ptr) - { thread_alloc::delete_array(data_ptr); } -/* %$$ -$end ------------------------------------------------------------------------------ -$begin cppad_vector_size$$ -$spell - resize - vec -$$ - -$section Vector Class: Change Size$$ - -$head Syntax$$ -$icode%vec%.resize(%n%) -%$$ -$icode%vec%.clear()%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_RESIZE%// END_RESIZE%1 -%$$ -$srcthisfile% - 0%// BEGIN_CLEAR%// END_CLEAR%1 -%$$ - -$head n$$ -is the number of elements in the new version of the vector. - -$head resize$$ -If $icode n$$ is less than or equal the input value of -$icode%vec%.capacity_%$$, -the only change is that $icode%vec%.length_%$$ is set to $icode n$$. -Otherwise, new memory is allocated for the vector and -$icode%vec%.length_%$$ elements are copied from the old vector -to the new one. I you do not need the old elements, you can first resize -to zero and then the $icode n$$ to avoid copying the elements. - -$head clear$$ -The destructor is called for all the elements of $icode vec$$ -and then $icode%vec.length_%$$ and $icode%vec%.capacity_%$$ are set to zero. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN_RESIZE -public: - void resize(size_t n) -// END_RESIZE - { if( capacity_ < n ) - { if( capacity_ == 0 ) - { // get new memory and set capacity - data_ = thread_alloc::create_array(n, capacity_); - } - else - { // save old information - Type* old_data = data_; - - // get new memory and set capacity - data_ = thread_alloc::create_array(n, capacity_); - - // copy old data - for(size_t i = 0; i < length_; ++i) - data_[i] = old_data[i]; - - // free old memory - thread_alloc::delete_array(old_data); - } - } - length_ = n; - } -// BEGIN_CLEAR - void clear(void) -// END_CLEAR - { length_ = 0; - // check if there is old memory to be freed - if( capacity_ > 0 ) - delete_data(data_); - capacity_ = 0; - } -/* -------------------------------------------------------------------------------- -$begin cppad_vector_assign$$ -$spell - resize - vec - cppad -$$ - -$section Vector Class: Assignment Operators$$ - -$head Syntax$$ -$icode%vec%.swap(%other%) -%$$ -$icode%vec% = %other%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_SWAP%// END_SWAP%1 -%$$ -$srcthisfile% - 0%// BEGIN_MOVE_ASSIGN%// END_MOVE_ASSIGN%1 -%$$ -$srcthisfile% - 0%// BEGIN_ASSIGN%// END_ASSIGN%1 -%$$ - -$head swap$$ -Swaps $code length_$$, $code capacity_$$ and $code data_$$ -between $icode vec$$ and $icode other$$. - -$head Assignment$$ -see $cref/user API assignment/CppAD_vector/Assignment/$$ - -$head Move Semantics$$ -A move semantics version of the assignment operator -is implemented using $code swap$$. - -$end -------------------------------------------------------------------------------- -*/ -// BEGIN_SWAP -public: - void swap(vector& other) noexcept -// END_SWAP - { // special case where vec and other are the same vector - if( this == &other ) - return; - // - std::swap(length_, other.length_ ); - std::swap(capacity_, other.capacity_ ); - std::swap(data_, other.data_ ); - return; - } - -// BEGIN_MOVE_ASSIGN - // Move semantics should not do any allocation. - // If NDEBUG is defined, this should not throw an exception. - vector& operator=(vector&& other) CPPAD_NDEBUG_NOEXCEPT -// END_MOVE_ASSIGN - { CPPAD_ASSERT_KNOWN( - length_ == other.length_ || (length_ == 0), - "vector: size miss match in assignment operation" - ); - swap(other); - return *this; - } - -// BEGIN_ASSIGN - vector& operator=(const vector& other) -// END_ASSIGN - { if( length_ == 0 ) - resize( other.length_ ); - CPPAD_ASSERT_KNOWN( - length_ == other.length_ , - "vector: size miss match in assignment operation" - ); - for(size_t i = 0; i < length_; i++) - data_[i] = other.data_[i]; - return *this; - } -/* -------------------------------------------------------------------------------- -$begin cppad_vector_subscript$$ -$spell - vec -$$ - -$section Vector Class: Subscript Operator$$ - -$head Syntax$$ -$icode%element% = %vec%[%i%] -%$$ -$icode%vec%[%i%] = %element% -%$$ - -$head Source$$ -$srccode%hpp% */ - const Type& operator[]( size_t i) const - { CPPAD_ASSERT_KNOWN( i < length_, - "vector: index greater than or equal vector size" - ); - return data_[i]; - } - Type& operator[](size_t i) - { CPPAD_ASSERT_KNOWN(i < length_, - "vector: index greater than or equal vector size" - ); - return data_[i]; - } - template const Type& operator[]( Index i) const - { return (*this)[size_t(i)]; } - template Type& operator[](Index i) - { return (*this)[size_t(i)]; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cppad_vector_push_back$$ -$spell - vec -$$ - -$section Vector Class: push_back$$ - -$head Syntax$$ -$icode%vec%.push_back(%element%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUSH_BACK%// END_PUSH_BACK%1 -%$$ - -$head Documentation$$ -see $cref/use API push_back/cppad_vector_push_back/$$ - -$end -*/ -// BEGIN_PUSH_BACK - void push_back(const Type& element) -// END_PUSH_BACK - { // case where no allocation is necessary - if( length_ < capacity_ ) - { data_[length_++] = element; - return; - } - CPPAD_ASSERT_UNKNOWN( length_ == capacity_ ); - - // create new vector with required size - vector vec(length_ + 1); - - // copy old data values - for(size_t i = 0; i < length_; ++i) - vec.data_[i] = data_[i]; - - // put the new element in the new vector - CPPAD_ASSERT_UNKNOWN( vec.length_ == length_ + 1); - vec.data_[length_] = element; - - // swap old and new vectors - swap(vec); - } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin cppad_vector_push_vector$$ -$spell - vec -$$ - -$section Vector Class: push_vector$$ - -$head Syntax$$ -$icode%vec%.push_vector(%other%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUSH_VECTOR%// END_PUSH_VECTOR%1 -%$$ - - -$head Documentation$$ -see $cref/use API push_vector/cppad_vector_push_vector/$$ - -$end -*/ -// BEGIN_PUSH_VECTOR - template void push_vector(const Vector& other) -// END_PUSH_VECTOR - { // can not use push_back because MS V++ 7.1 did not resolve - // to non-template member function when scalar is used. - // - CheckSimpleVector(); - size_t m = other.size(); - - // case where no allcoation is necessary - if( length_ + m <= capacity_ ) - { for(size_t i = 0; i < m; i++) - data_[length_++] = other[i]; - return; - } - - // create new vector with required size - vector vec(length_ + m); - - // copy old data values - for(size_t i = 0; i < length_; ++i) - vec.data_[i] = data_[i]; - - // put the new elements in the new vector - CPPAD_ASSERT_UNKNOWN( vec.length_ == length_ + m ); - for(size_t i = 0; i < m; i++) - vec.data_[length_ + i] = other[i]; - - // swap old and new vectors - swap(vec); - } -/* ------------------------------------------------------------------------------- -$begin cppad_vector_itr_fun$$ -$spell - vec - iterator -$$ - -$section Vector Class: Iterator Functions$$ - -$head Syntax$$ -$icode%os%vec%.begin() -%$$ -$icode%os%vec%.end() -%$$ - -$head Source$$ -$srccode%hpp% */ - const_iterator begin(void) const noexcept - { return const_iterator(&data_, &length_, 0); } - const_iterator end(void) const noexcept - { typedef typename const_iterator::difference_type difference_type; - difference_type index = static_cast(length_); - return const_iterator(&data_, &length_, index); - } - // - iterator begin(void) noexcept - { return iterator(&data_, &length_, 0); } - iterator end(void) noexcept - { typedef typename iterator::difference_type difference_type; - difference_type index = static_cast(length_); - return iterator(&data_, &length_, index); - } -/* %$$ -$end -*/ - -// ========================================================================= -}; // END_TEMPLATE_CLASS_VECTOR -// ========================================================================= - -/* -$begin cppad_vector_output$$ -$spell - vec -$$ - -$section Vector Class: Output$$ - -$head Syntax$$ -$icode%os% << vec%$$ - -$head Source$$ -$srccode%hpp% */ -template -std::ostream& operator << (std::ostream& os , const CppAD::vector& vec ) -{ os << "{ "; - for(size_t i = 0; i < vec.size(); ++i) - { os << vec[i]; - if( i + 1 < vec.size() ) - os << ", "; - } - os << " }"; - return os; -} -/* %$$ -$end -*/ - -} // END_CPPAD_NAMESPACE - -// user API specifies that vector_bool.hpp is included by vector.hpp -# include - -# endif diff --git a/build-config/cppad/include/cppad/utility/vector_bool.hpp b/build-config/cppad/include/cppad/utility/vector_bool.hpp deleted file mode 100644 index 57e4a15f..00000000 --- a/build-config/cppad/include/cppad/utility/vector_bool.hpp +++ /dev/null @@ -1,521 +0,0 @@ -# ifndef CPPAD_UTILITY_VECTOR_BOOL_HPP -# define CPPAD_UTILITY_VECTOR_BOOL_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - - -# include -# include -# include -# include -# include -# include -# include - -namespace CppAD { // BEGIN_CPPAD_NAMESPACE - -// ============================================================================ -class vectorBool { -// ============================================================================ -/* -$begin vector_bool_member$$ -$spell - Bool - vec -$$ - -$section vectorBool: Member Data$$ - -$head Syntax$$ -$icode%vec%.unit_min() -%$$ -$icode%vec%.bit_per_unit() -%$$ - - -$head unit_t$$ -Type used to pack multiple boolean (bit) values into one unit. -Logical operations are preformed one unit at a time. - -$head bit_per_unit_$$ -number of bits packed into each unit value in $code data_$$. - -$head n_unit_$$ -Number of unit values in $code data_$$. - -$head length_$$ -number of bits currently stored in this vector. - -$head data_$$ -pointer to where the bits are stored. - -$head unit_min$$ -minimum number of $code unit_t$$ values that can store $code length_$$ bits. -Note that this is really a function of $code length_$$. - -$head size$$ -is the number of boolean elements in the vector. - -$head capacity$$ -is the maximum number of boolean elements that will fit in the -current allocation for $code data_$$. - -$head Source$$ -$srccode%hpp% */ -private: - typedef size_t unit_t; - static const size_t bit_per_unit_ = std::numeric_limits::digits; - size_t n_unit_; - size_t length_; - unit_t *data_; - // - size_t unit_min(void) const - { if( length_ == 0 ) - return 0; - return (length_ - 1) / bit_per_unit_ + 1; - } -public: - static size_t bit_per_unit(void) - { return bit_per_unit_; } - size_t size(void) const - { return length_; } - size_t capacity(void) const - { return n_unit_ * bit_per_unit_; } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin vector_bool_typedef$$ -$spell - vec - Bool - const -$$ - -$section vectorBool Type Definitions$$ - -$head value_type$$ -type corresponding to the elements of this vector -(note that non-const elements actually use -$cref/vectorBoolElement/vector_bool_element/$$). - -$head Source$$ -$srccode%hpp% */ -public: - typedef bool value_type; -/* %$$ -$end ----------------------------------------------------------------------------- -$begin vector_bool_ctor$$ -$spell - Bool - vec - alloc -$$ -$section vectorBool: Constructors and Destructor$$ - -$head Default$$ -$codei%vectorBool %vec% -%$$ -creates an empty vector with no elements and $code n_unit_$$ zero. - -$head Sizing$$ -$codei%vectorBool %vec%(%n%) -%$$ -where $icode n$$ is a $code size_t$$, -creates the vector $icode vec$$ with $icode n$$ elements and $code n_unit_$$ -greater than or equal $code unit_min()$$. - -$head Copy$$ -$codei%vector<%Type%> %vec%(%other%) -%$$ -where $icode other$$ is a $codei%vector<%Type%>%$$, -creates the vector $icode vec$$ -with $icode%n% = %other%.size()%$$ elements and $code n_unit_$$ -greater than or equal $code unit_min()$$. - -$head Destructor$$ -If $code n_unit_$$ is non-zero, the memory corresponding to data_ -is returned to thread_alloc. - -$head Source$$ -$srccode%hpp%: -*/ - vectorBool(void) : n_unit_(0), length_(0), data_(nullptr) - { } - vectorBool(size_t n) : n_unit_(0), length_(n), data_(nullptr) - { resize(n); } - vectorBool(const vectorBool& other) - : n_unit_(0), length_(0), data_(nullptr) - { resize(other.length_); - size_t n_used = unit_min(); - CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ ); - for(size_t i = 0; i < n_used; ++i) - data_[i] = other.data_[i]; - } - // n_unit_ is the only value necessary to make destructor work - // for other after this move semantics constructor - vectorBool(vectorBool&& other) - : n_unit_(0), length_(0), data_(nullptr) - { swap(other); } - ~vectorBool(void) - { clear(); } -/* %$$ -$end ------------------------------------------------------------------------------ -$begin vector_bool_size$$ -$spell - Bool - resize - vec -$$ - -$section vectorBool: Change Size$$ - -$head Syntax$$ -$icode%vec%.resize(%n%) -%$$ -$icode%vec%.clear()%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_RESIZE%// END_RESIZE%1 -%$$ -$srcthisfile% - 0%// BEGIN_CLEAR%// END_CLEAR%1 -%$$ - -$head n$$ -is the number of elements in the new version of the vector. - -$head resize$$ -If $icode n$$ is less than or equal the input value of -$icode%vec%.n_unit_%$$ times $icode%vec%.bit_per_unit_%$$, -the only change is that $icode%vec%.length_%$$ is set to $icode n$$. -Otherwise the old elements are freed and a new vector is created -with $icode%vec%.length_%$$ equal to $icode n$$. - -$head clear$$ -the memory allocated for this vector is freed and -$icode%vec.length_%$$ and $icode%vec%.n_unit_%$$ are set to zero. - -$end ------------------------------------------------------------------------------- -*/ -// BEGIN_RESIZE -public: - void resize(size_t n) -// END_RESIZE - { length_ = n; - // check if we can use the current memory - size_t min_unit = unit_min(); - if( n_unit_ >= min_unit ) - return; - // check if there is old memory to be freed - if( n_unit_ > 0 ) - { void* v_ptr = reinterpret_cast(data_); - thread_alloc::return_memory(v_ptr); - } - // get new memory and set n_unit - size_t min_bytes = min_unit * sizeof(unit_t); - size_t cap_bytes; - void* v_ptr = thread_alloc::get_memory(min_bytes, cap_bytes); - data_ = reinterpret_cast(v_ptr); - n_unit_ = cap_bytes / sizeof(unit_t); - CPPAD_ASSERT_UNKNOWN( n_unit_ >= min_unit ); - } -// BEGIN_CLEAR - void clear(void) -// END_CLEAR - { - // check if there is old memory to be freed - if( n_unit_ > 0 ) - { void* v_ptr = reinterpret_cast(data_); - thread_alloc::return_memory(v_ptr); - } - length_ = 0; - n_unit_ = 0; - } -/* -------------------------------------------------------------------------------- -$begin vector_bool_assign$$ -$spell - Bool - resize - vec -$$ - -$section vectorBool: Assignment Operators$$ - -$head Syntax$$ -$icode%vec%.swap(%other%) -%$$ -$icode%vec% = %other%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_SWAP%// END_SWAP%1 -%$$ -$srcthisfile% - 0%// BEGIN_ASSIGN%// END_ASSIGN%1 -%$$ -$srcthisfile% - 0%// BEGIN_MOVE_SEMANTICS%// END_MOVE_SEMANTICS%1 -%$$ - -$head swap$$ -Swaps $code n_unit_$$, $code length_$$ and $code data_$$ -between $icode vec$$ and $icode other$$. - -$head Assignment$$ -If the input value of $icode%vec%.length_%$$ is zero, -$cref/resize/vector_bool_size/resize/$$ is used to change its size to -be the same as other. -The size of $icode vec$$ and $icode other$$ are then compared and if -different, an assert with a know cause is generated. -The elements of $icode vec$$ are then individually assigned -to have the value of the corresponding elements of $icode other$$. - -$head Move Semantics$$ -A move semantics version of the assignment operator, implemented using -$code swap$$, is defined. - -$end -------------------------------------------------------------------------------- -*/ -// BEGIN_SWAP - void swap(vectorBool& other) -// END_SWAP - { // swap with self case - if( this == &other ) - return; - std::swap(n_unit_, other.n_unit_ ); - std::swap(length_, other.length_ ); - std::swap(data_, other.data_ ); - return; - } -// BEGIN_ASSIGN - vectorBool& operator=(const vectorBool& other) -// END_ASSIGN - { // If original length is zero, then resize it to other. - // Otherwise a length mismatch is an error. - if( length_ == 0 ) - resize( other.length_ ); - CPPAD_ASSERT_KNOWN( - length_ == other.length_ , - "vectorBool: size miss match in assignment operation" - ); - size_t n_used = unit_min(); - CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ ); - for(size_t i = 0; i < n_used; i++) - data_[i] = other.data_[i]; - return *this; - } -// BEGIN_MOVE_SEMANTICS - vectorBool& operator=(vectorBool&& other) -// END_MOVE_SEMANTICS - { CPPAD_ASSERT_KNOWN( - length_ == other.length_ || (length_ == 0), - "vectorBool: size miss match in assignment operation" - ); - swap(other); - return *this; - } -/* -------------------------------------------------------------------------------- -$begin vector_bool_subscript$$ -$spell - vec - Bool - const -$$ - -$section vectorBool: Subscript Operator$$ - -$head Syntax$$ -$icode%target% = %vec%[%i%] -%$$ -$icode%vec%[%i%] = %source% -%$$ - -$head target$$ -In this syntax $icode vec$$ is $code const$$ -and the value $icode%vec%[%i%]%$$ is a $code bool$$. - -$head source$$ -In this syntax $icode vec$$ is not $code const$$ -and the value $icode%vec%[%i%]%$$ is a -$cref/vectorBoolElement/vector_bool_element/$$. - -$head Source$$ -$srccode%hpp% */ - bool operator[](size_t i) const - { CPPAD_ASSERT_KNOWN( i < length_, - "vectorBool: index greater than or equal vector size" - ); - size_t unit_index = i / bit_per_unit_; - size_t bit_index = i - unit_index * bit_per_unit_; - unit_t unit = data_[unit_index]; - unit_t mask = unit_t(1) << bit_index; - return (unit & mask) != 0; - } - local::utility::vectorBoolElement operator[](size_t i) - { CPPAD_ASSERT_KNOWN( i < length_, - "vectorBool: index greater than or equal vector size" - ); - size_t unit_index = i / bit_per_unit_; - size_t bit_index = i - unit_index * bit_per_unit_; - unit_t mask = unit_t(1) << bit_index; - return local::utility::vectorBoolElement(data_ + unit_index , mask); - } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin vector_bool_push_back$$ -$spell - Bool - vec -$$ - -$section vectorBool: push_back$$ - -$head Syntax$$ -$icode%vec%.push_back(%element%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUSH_BACK%// END_PUSH_BACK%1 -%$$ - -$head Documentation$$ -see $cref/use API push_back/cppad_vector_push_back/$$ - -$end -*/ -// BEGIN_PUSH_BACK - void push_back(bool element) -// END_PUSH_BACK - { CPPAD_ASSERT_UNKNOWN( unit_min() <= n_unit_ ); - size_t old_length = length_; - if( length_ + 1 > n_unit_ * bit_per_unit_ ) - { CPPAD_ASSERT_UNKNOWN( unit_min() == n_unit_ ); - - // create new vector with requuired size - vectorBool vec(length_ + 1); - - // copy old data values - size_t n_used = unit_min(); - CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ ); - for(size_t i = 0; i < n_used; ++i) - vec.data_[i] = data_[i]; - - // swap old and new vectors - swap(vec); - } - else - ++length_; - CPPAD_ASSERT_UNKNOWN( length_ <= n_unit_ * bit_per_unit_ ) - size_t unit_index = old_length / bit_per_unit_; - size_t bit_index = old_length - unit_index * bit_per_unit_; - unit_t mask = unit_t(1) << bit_index; - if( element ) - data_[unit_index] |= mask; - else - data_[unit_index] &= ~mask; - } -/* %$$ -$end -------------------------------------------------------------------------------- -$begin vector_bool_push_vector$$ -$spell - Bool - vec -$$ - -$section vectorBool: push_vector$$ - -$head Syntax$$ -$icode%vec%.push_vector(%other%)%$$ - -$head Prototype$$ -$srcthisfile% - 0%// BEGIN_PUSH_VECTOR%// END_PUSH_VECTOR%1 -%$$ - - -$head Documentation$$ -see $cref/use API push_vector/cppad_vector_push_vector/$$ - -$end -*/ -// BEGIN_PUSH_VECTOR - template void push_vector(const Vector& other) -// END_PUSH_VECTOR - { CPPAD_ASSERT_UNKNOWN( unit_min() <= n_unit_ ); - CheckSimpleVector(); - size_t old_length = length_; - size_t m = other.size(); - if( length_ + m > n_unit_ * bit_per_unit_ ) - { - // create new vector with requuired size - vectorBool vec(length_ + m); - - // copy old data values - size_t n_used = unit_min(); - CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ ); - for(size_t i = 0; i < n_used; ++i) - vec.data_[i] = data_[i]; - - // swap old and new vectors - swap(vec); - } - else - length_ += m; - // - // put the new elements in this vector - CPPAD_ASSERT_UNKNOWN( length_ <= n_unit_ * bit_per_unit_ ) - for(size_t k = 0; k < m; k++) - { size_t unit_index = (old_length + k) / bit_per_unit_; - size_t bit_index = (old_length + k) - unit_index * bit_per_unit_; - unit_t mask = unit_t(1) << bit_index; - if( other[k] ) - data_[unit_index] |= mask; - else - data_[unit_index] &= ~mask; - } - } -}; - -/* -$begin vector_bool_output$$ -$spell - Bool - vec -$$ - -$section vectorBool: Output$$ - -$head Syntax$$ -$icode%os% << vec%$$ - -$head Source$$ -$srccode%hpp% */ -inline std::ostream& operator << (std::ostream& os , const vectorBool& vec ) -{ for(size_t i = 0; i < vec.size(); ++i) - os << vec[i]; - return os; -} -/* %$$ -$end -*/ - -} // END_CPPAD_NAMESPACE -# endif diff --git a/build-config/cppad/include/cppad/wno_conversion.hpp b/build-config/cppad/include/cppad/wno_conversion.hpp deleted file mode 100644 index 30d02d17..00000000 --- a/build-config/cppad/include/cppad/wno_conversion.hpp +++ /dev/null @@ -1,45 +0,0 @@ -# ifndef CPPAD_WNO_CONVERSION_HPP -# define CPPAD_WNO_CONVERSION_HPP -/* -------------------------------------------------------------------------- -CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell - -CppAD is distributed under the terms of the - Eclipse Public License Version 2.0. - -This Source Code may also be made available under the following -Secondary License when the conditions for such availability set forth -in the Eclipse Public License, Version 2.0 are satisfied: - GNU General Public License, Version 2.0 or later. ----------------------------------------------------------------------------- */ - -/* -$begin wno_conversion$$ -$spell - cppad - wno - cpp - hpp -$$ - -$section Suppress Suspect Implicit Conversion Warnings$$ - -$head Syntax$$ -$codei%# include %$$ - -$head Purpose$$ -In many cases it is good to have warnings for implicit conversions -that may loose range or precision. -The include command above, before any other includes, suppresses -these warning for a particular compilation unit (which usually corresponds -to a $icode%*%.cpp%$$ file). - -$end -*/ - -# include -# if CPPAD_COMPILER_HAS_CONVERSION_WARN -# pragma GCC diagnostic ignored "-Wfloat-conversion" -# pragma GCC diagnostic ignored "-Wconversion" -# endif - -# endif diff --git a/build-config/cppad/include/makefile.am b/build-config/cppad/include/makefile.am deleted file mode 100644 index 1bb5f23c..00000000 --- a/build-config/cppad/include/makefile.am +++ /dev/null @@ -1,348 +0,0 @@ -# ----------------------------------------------------------------------------- -# CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell -# -# CppAD is distributed under the terms of the -# Eclipse Public License Version 2.0. -# -# This Source Code may also be made available under the following -# Secondary License when the conditions for such availability set forth -# in the Eclipse Public License, Version 2.0 are satisfied: -# GNU General Public License, Version 2.0 or later. -# ----------------------------------------------------------------------------- -# -if CppAD_POSTFIX -postfix_dir = $(POSTFIX_DIR) -else -postfix_dir = . -endif -# -myincludedir = $(includedir)/$(postfix_dir) -# -# BEGIN_SORT_THIS_LINE_PLUS_2 -nobase_myinclude_HEADERS = \ - cppad/base_require.hpp \ - cppad/configure.hpp \ - cppad/core/abort_recording.hpp \ - cppad/core/abs.hpp \ - cppad/core/abs_normal_fun.hpp \ - cppad/core/ad.hpp \ - cppad/core/ad_assign.hpp \ - cppad/core/ad_binary.hpp \ - cppad/core/ad_ctor.hpp \ - cppad/core/ad_fun.hpp \ - cppad/core/ad_io.hpp \ - cppad/core/ad_to_string.hpp \ - cppad/core/ad_type.hpp \ - cppad/core/ad_valued.hpp \ - cppad/core/add.hpp \ - cppad/core/add_eq.hpp \ - cppad/core/arithmetic.hpp \ - cppad/core/atan2.hpp \ - cppad/core/atomic/atomic_one.hpp \ - cppad/core/atomic/atomic_three.hpp \ - cppad/core/atomic/atomic_two.hpp \ - cppad/core/atomic/three_afun.hpp \ - cppad/core/atomic/three_ctor.hpp \ - cppad/core/atomic/three_for_type.hpp \ - cppad/core/atomic/three_forward.hpp \ - cppad/core/atomic/three_hes_sparsity.hpp \ - cppad/core/atomic/three_jac_sparsity.hpp \ - cppad/core/atomic/three_rev_depend.hpp \ - cppad/core/atomic/three_reverse.hpp \ - cppad/core/atomic/two_afun.hpp \ - cppad/core/atomic/two_clear.hpp \ - cppad/core/atomic/two_ctor.hpp \ - cppad/core/atomic/two_for_sparse_hes.hpp \ - cppad/core/atomic/two_for_sparse_jac.hpp \ - cppad/core/atomic/two_forward.hpp \ - cppad/core/atomic/two_option.hpp \ - cppad/core/atomic/two_rev_depend.hpp \ - cppad/core/atomic/two_rev_sparse_hes.hpp \ - cppad/core/atomic/two_rev_sparse_jac.hpp \ - cppad/core/atomic/two_reverse.hpp \ - cppad/core/azmul.hpp \ - cppad/core/base2ad.hpp \ - cppad/core/base_complex.hpp \ - cppad/core/base_cond_exp.hpp \ - cppad/core/base_double.hpp \ - cppad/core/base_float.hpp \ - cppad/core/base_hash.hpp \ - cppad/core/base_limits.hpp \ - cppad/core/base_std_math.hpp \ - cppad/core/base_to_string.hpp \ - cppad/core/bender_quad.hpp \ - cppad/core/bool_fun.hpp \ - cppad/core/bool_valued.hpp \ - cppad/core/capacity_order.hpp \ - cppad/core/check_for_nan.hpp \ - cppad/core/chkpoint_one/chkpoint_one.hpp \ - cppad/core/chkpoint_one/ctor.hpp \ - cppad/core/chkpoint_one/for_sparse_jac.hpp \ - cppad/core/chkpoint_one/forward.hpp \ - cppad/core/chkpoint_one/rev_sparse_hes.hpp \ - cppad/core/chkpoint_one/rev_sparse_jac.hpp \ - cppad/core/chkpoint_one/reverse.hpp \ - cppad/core/chkpoint_one/set_hes_sparse_bool.hpp \ - cppad/core/chkpoint_one/set_hes_sparse_set.hpp \ - cppad/core/chkpoint_one/set_jac_sparse_bool.hpp \ - cppad/core/chkpoint_one/set_jac_sparse_set.hpp \ - cppad/core/chkpoint_two/chkpoint_two.hpp \ - cppad/core/chkpoint_two/ctor.hpp \ - cppad/core/chkpoint_two/dynamic.hpp \ - cppad/core/chkpoint_two/for_type.hpp \ - cppad/core/chkpoint_two/forward.hpp \ - cppad/core/chkpoint_two/hes_sparsity.hpp \ - cppad/core/chkpoint_two/jac_sparsity.hpp \ - cppad/core/chkpoint_two/rev_depend.hpp \ - cppad/core/chkpoint_two/reverse.hpp \ - cppad/core/compare.hpp \ - cppad/core/compound_assign.hpp \ - cppad/core/con_dyn_var.hpp \ - cppad/core/cond_exp.hpp \ - cppad/core/convert.hpp \ - cppad/core/cppad_assert.hpp \ - cppad/core/dependent.hpp \ - cppad/core/discrete/discrete.hpp \ - cppad/core/div.hpp \ - cppad/core/div_eq.hpp \ - cppad/core/drivers.hpp \ - cppad/core/epsilon.hpp \ - cppad/core/equal_op_seq.hpp \ - cppad/core/for_hes_sparsity.hpp \ - cppad/core/for_jac_sparsity.hpp \ - cppad/core/for_one.hpp \ - cppad/core/for_sparse_hes.hpp \ - cppad/core/for_sparse_jac.hpp \ - cppad/core/for_two.hpp \ - cppad/core/forward/forward.hpp \ - cppad/core/fun_check.hpp \ - cppad/core/fun_construct.hpp \ - cppad/core/fun_eval.hpp \ - cppad/core/hash_code.hpp \ - cppad/core/hessian.hpp \ - cppad/core/identical.hpp \ - cppad/core/independent/independent.hpp \ - cppad/core/integer.hpp \ - cppad/core/jacobian.hpp \ - cppad/core/graph/from_json.hpp \ - cppad/core/graph/graph_op_enum.hpp \ - cppad/core/graph/to_json.hpp \ - cppad/core/lu_ratio.hpp \ - cppad/core/mul.hpp \ - cppad/core/mul_eq.hpp \ - cppad/core/near_equal_ext.hpp \ - cppad/core/new_dynamic.hpp \ - cppad/core/num_skip.hpp \ - cppad/core/numeric_limits.hpp \ - cppad/core/omp_max_thread.hpp \ - cppad/core/opt_val_hes.hpp \ - cppad/core/optimize.hpp \ - cppad/core/ordered.hpp \ - cppad/core/parallel_ad.hpp \ - cppad/core/pow.hpp \ - cppad/core/print_for.hpp \ - cppad/core/rev_hes_sparsity.hpp \ - cppad/core/rev_jac_sparsity.hpp \ - cppad/core/rev_one.hpp \ - cppad/core/rev_sparse_hes.hpp \ - cppad/core/rev_sparse_jac.hpp \ - cppad/core/rev_two.hpp \ - cppad/core/reverse.hpp \ - cppad/core/sign.hpp \ - cppad/core/sparse.hpp \ - cppad/core/sparse_hes.hpp \ - cppad/core/sparse_hessian.hpp \ - cppad/core/sparse_jac.hpp \ - cppad/core/sparse_jacobian.hpp \ - cppad/core/standard_math.hpp \ - cppad/core/std_math_11.hpp \ - cppad/core/sub.hpp \ - cppad/core/sub_eq.hpp \ - cppad/core/subgraph_jac_rev.hpp \ - cppad/core/subgraph_reverse.hpp \ - cppad/core/subgraph_sparsity.hpp \ - cppad/core/tape_link.hpp \ - cppad/core/test_vector.hpp \ - cppad/core/testvector.hpp \ - cppad/core/unary_minus.hpp \ - cppad/core/unary_plus.hpp \ - cppad/core/undef.hpp \ - cppad/core/user_ad.hpp \ - cppad/core/value.hpp \ - cppad/core/var2par.hpp \ - cppad/core/vec_ad/vec_ad.hpp \ - cppad/core/zdouble.hpp \ - cppad/cppad.hpp \ - cppad/example/atomic_three/mat_mul.hpp \ - cppad/example/atomic_two/eigen_cholesky.hpp \ - cppad/example/atomic_two/eigen_mat_inv.hpp \ - cppad/example/atomic_two/eigen_mat_mul.hpp \ - cppad/example/base_adolc.hpp \ - cppad/example/code_gen_fun.hpp \ - cppad/example/cppad_eigen.hpp \ - cppad/example/eigen_plugin.hpp \ - cppad/ipopt/solve.hpp \ - cppad/ipopt/solve_callback.hpp \ - cppad/ipopt/solve_result.hpp \ - cppad/local/abs_op.hpp \ - cppad/local/acos_op.hpp \ - cppad/local/acosh_op.hpp \ - cppad/local/ad_tape.hpp \ - cppad/local/add_op.hpp \ - cppad/local/asin_op.hpp \ - cppad/local/asinh_op.hpp \ - cppad/local/atan_op.hpp \ - cppad/local/atanh_op.hpp \ - cppad/local/atom_state.hpp \ - cppad/local/atomic_index.hpp \ - cppad/local/color_general.hpp \ - cppad/local/color_symmetric.hpp \ - cppad/local/comp_op.hpp \ - cppad/local/cond_op.hpp \ - cppad/local/cos_op.hpp \ - cppad/local/cosh_op.hpp \ - cppad/local/cppad_colpack.hpp \ - cppad/local/cskip_op.hpp \ - cppad/local/csum_op.hpp \ - cppad/local/declare_ad.hpp \ - cppad/local/define.hpp \ - cppad/local/discrete_op.hpp \ - cppad/local/div_op.hpp \ - cppad/local/erf_op.hpp \ - cppad/local/exp_op.hpp \ - cppad/local/expm1_op.hpp \ - cppad/local/hash_code.hpp \ - cppad/local/independent.hpp \ - cppad/local/is_pod.hpp \ - cppad/core/graph/from_graph.hpp \ - cppad/local/graph/json_lexer.hpp \ - cppad/core/graph/to_graph.hpp \ - cppad/core/graph/cpp_graph.hpp \ - cppad/local/graph/cpp_graph_itr.hpp \ - cppad/local/graph/cpp_graph_op.hpp \ - cppad/local/graph/json_parser.hpp \ - cppad/local/graph/json_writer.hpp \ - cppad/local/load_op.hpp \ - cppad/local/log1p_op.hpp \ - cppad/local/log_op.hpp \ - cppad/local/mul_op.hpp \ - cppad/local/op.hpp \ - cppad/local/op_code_dyn.hpp \ - cppad/local/op_code_var.hpp \ - cppad/local/optimize/cexp_info.hpp \ - cppad/local/optimize/csum_op_info.hpp \ - cppad/local/optimize/csum_stacks.hpp \ - cppad/local/optimize/get_cexp_info.hpp \ - cppad/local/optimize/get_dyn_previous.hpp \ - cppad/local/optimize/get_op_previous.hpp \ - cppad/local/optimize/get_op_usage.hpp \ - cppad/local/optimize/get_par_usage.hpp \ - cppad/local/optimize/hash_code.hpp \ - cppad/local/optimize/match_op.hpp \ - cppad/local/optimize/optimize_run.hpp \ - cppad/local/optimize/record_csum.hpp \ - cppad/local/optimize/record_pv.hpp \ - cppad/local/optimize/record_vp.hpp \ - cppad/local/optimize/record_vv.hpp \ - cppad/local/optimize/size_pair.hpp \ - cppad/local/optimize/usage.hpp \ - cppad/local/parameter_op.hpp \ - cppad/local/play/addr_enum.hpp \ - cppad/local/play/atom_op_info.hpp \ - cppad/local/play/player.hpp \ - cppad/local/play/random_iterator.hpp \ - cppad/local/play/random_setup.hpp \ - cppad/local/play/sequential_iterator.hpp \ - cppad/local/play/subgraph_iterator.hpp \ - cppad/local/pod_vector.hpp \ - cppad/local/pow_op.hpp \ - cppad/local/print_op.hpp \ - cppad/local/prototype_op.hpp \ - cppad/local/record/cond_exp.hpp \ - cppad/local/record/comp_op.hpp \ - cppad/local/record/put_dyn_atomic.hpp \ - cppad/local/record/put_var_atomic.hpp \ - cppad/local/record/put_var_vecad.hpp \ - cppad/local/record/recorder.hpp \ - cppad/local/set_get_in_parallel.hpp \ - cppad/local/sign_op.hpp \ - cppad/local/sin_op.hpp \ - cppad/local/sinh_op.hpp \ - cppad/local/sparse/binary_op.hpp \ - cppad/local/sparse/internal.hpp \ - cppad/local/sparse/list_setvec.hpp \ - cppad/local/sparse/pack_setvec.hpp \ - cppad/local/sparse/svec_setvec.hpp \ - cppad/local/sparse/unary_op.hpp \ - cppad/local/sqrt_op.hpp \ - cppad/local/std_set.hpp \ - cppad/local/store_op.hpp \ - cppad/local/sub_op.hpp \ - cppad/local/subgraph/arg_variable.hpp \ - cppad/local/subgraph/entire_call.hpp \ - cppad/local/subgraph/get_rev.hpp \ - cppad/local/subgraph/info.hpp \ - cppad/local/subgraph/init_rev.hpp \ - cppad/local/subgraph/sparsity.hpp \ - cppad/local/sweep/call_atomic.hpp \ - cppad/local/sweep/dynamic.hpp \ - cppad/local/sweep/for_hes.hpp \ - cppad/local/sweep/for_jac.hpp \ - cppad/local/sweep/forward0.hpp \ - cppad/local/sweep/forward1.hpp \ - cppad/local/sweep/forward2.hpp \ - cppad/local/sweep/rev_hes.hpp \ - cppad/local/sweep/rev_jac.hpp \ - cppad/local/sweep/reverse.hpp \ - cppad/local/tan_op.hpp \ - cppad/local/tanh_op.hpp \ - cppad/local/utility/cppad_vector_itr.hpp \ - cppad/local/utility/vector_bool.hpp \ - cppad/local/zmul_op.hpp \ - cppad/speed/det_33.hpp \ - cppad/speed/det_by_lu.hpp \ - cppad/speed/det_by_minor.hpp \ - cppad/speed/det_grad_33.hpp \ - cppad/speed/det_of_minor.hpp \ - cppad/speed/mat_sum_sq.hpp \ - cppad/speed/ode_evaluate.hpp \ - cppad/speed/sparse_hes_fun.hpp \ - cppad/speed/sparse_jac_fun.hpp \ - cppad/speed/uniform_01.hpp \ - cppad/utility.hpp \ - cppad/utility/check_numeric_type.hpp \ - cppad/utility/check_simple_vector.hpp \ - cppad/utility/elapsed_seconds.hpp \ - cppad/utility/error_handler.hpp \ - cppad/utility/index_sort.hpp \ - cppad/utility/lu_factor.hpp \ - cppad/utility/lu_invert.hpp \ - cppad/utility/lu_solve.hpp \ - cppad/utility/memory_leak.hpp \ - cppad/utility/nan.hpp \ - cppad/utility/near_equal.hpp \ - cppad/utility/ode_err_control.hpp \ - cppad/utility/ode_gear.hpp \ - cppad/utility/ode_gear_control.hpp \ - cppad/utility/omp_alloc.hpp \ - cppad/utility/poly.hpp \ - cppad/utility/pow_int.hpp \ - cppad/utility/romberg_mul.hpp \ - cppad/utility/romberg_one.hpp \ - cppad/utility/rosen_34.hpp \ - cppad/utility/runge_45.hpp \ - cppad/utility/set_union.hpp \ - cppad/utility/sparse2eigen.hpp \ - cppad/utility/sparse_rc.hpp \ - cppad/utility/sparse_rcv.hpp \ - cppad/utility/speed_test.hpp \ - cppad/utility/test_boolofvoid.hpp \ - cppad/utility/thread_alloc.hpp \ - cppad/utility/time_test.hpp \ - cppad/utility/to_string.hpp \ - cppad/utility/track_new_del.hpp \ - cppad/utility/vector.hpp \ - cppad/utility/vector_bool.hpp \ - cppad/wno_conversion.hpp -# End nobase_myinclude_HEADERS (check_makefile.sh uses this comment) -# END_SORT_THIS_LINE_MINUS_2 diff --git a/build-config/cppad/include/makefile.in b/build-config/cppad/include/makefile.in deleted file mode 100644 index 7a7f349a..00000000 --- a/build-config/cppad/include/makefile.in +++ /dev/null @@ -1,941 +0,0 @@ -# makefile.in generated by automake 1.16.2 from makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2020 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = include -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/makefile.am $(nobase_myinclude_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(myincludedir)" -HEADERS = $(nobase_myinclude_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ABS_TOP_BUILDDIR = @ABS_TOP_BUILDDIR@ -ABS_TOP_SRCDIR = @ABS_TOP_SRCDIR@ -ACLOCAL = @ACLOCAL@ -ADOLC_DIR = @ADOLC_DIR@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BOOST_DIR = @BOOST_DIR@ -BOOST_INCLUDE = @BOOST_INCLUDE@ -BTHREAD_LIB = @BTHREAD_LIB@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPAD_IPOPT_LD_PATH = @CPPAD_IPOPT_LD_PATH@ -CPPAD_IPOPT_LIBS = @CPPAD_IPOPT_LIBS@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CXX_FLAGS = @CXX_FLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DL_LIB = @DL_LIB@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EIGEN_DIR = @EIGEN_DIR@ -EIGEN_INCLUDE = @EIGEN_INCLUDE@ -EXEEXT = @EXEEXT@ -FADBAD_DIR = @FADBAD_DIR@ -FC = @FC@ -FCFLAGS = @FCFLAGS@ -FCLIBS = @FCLIBS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -IPOPT_DIR = @IPOPT_DIR@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MAX_NUM_THREADS = @MAX_NUM_THREADS@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -OPENMP_FLAGS = @OPENMP_FLAGS@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -POSTFIX_DIR = @POSTFIX_DIR@ -PTHREAD_LIB = @PTHREAD_LIB@ -RANLIB = @RANLIB@ -SACADO_DIR = @SACADO_DIR@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TAPE_ADDR_TYPE = @TAPE_ADDR_TYPE@ -TAPE_ID_TYPE = @TAPE_ID_TYPE@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_FC = @ac_ct_FC@ -adolc_prefix = @adolc_prefix@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -compiler_has_conversion_warn = @compiler_has_conversion_warn@ -cppad_boostvector = @cppad_boostvector@ -cppad_cplusplus_201100_ok = @cppad_cplusplus_201100_ok@ -cppad_cppadvector = @cppad_cppadvector@ -cppad_cxx_flags = @cppad_cxx_flags@ -cppad_description = @cppad_description@ -cppad_eigenvector = @cppad_eigenvector@ -cppad_has_adolc = @cppad_has_adolc@ -cppad_has_boost = @cppad_has_boost@ -cppad_has_colpack = @cppad_has_colpack@ -cppad_has_eigen = @cppad_has_eigen@ -cppad_has_fadbad = @cppad_has_fadbad@ -cppad_has_gettimeofday = @cppad_has_gettimeofday@ -cppad_has_ipopt = @cppad_has_ipopt@ -cppad_has_mkstemp = @cppad_has_mkstemp@ -cppad_has_sacado = @cppad_has_sacado@ -cppad_has_tmpnam_s = @cppad_has_tmpnam_s@ -cppad_max_num_threads = @cppad_max_num_threads@ -cppad_pkgconfig_cflags = @cppad_pkgconfig_cflags@ -cppad_pkgconfig_cflags_uninstalled = @cppad_pkgconfig_cflags_uninstalled@ -cppad_pkgconfig_libs = @cppad_pkgconfig_libs@ -cppad_pkgconfig_libs_uninstalled = @cppad_pkgconfig_libs_uninstalled@ -cppad_pkgconfig_requires = @cppad_pkgconfig_requires@ -cppad_pkgconfig_requires_uninstalled = @cppad_pkgconfig_requires_uninstalled@ -cppad_stdvector = @cppad_stdvector@ -cppad_tape_addr_type = @cppad_tape_addr_type@ -cppad_tape_id_type = @cppad_tape_id_type@ -cppad_url = @cppad_url@ -cppad_version = @cppad_version@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -eigen_prefix = @eigen_prefix@ -exec_prefix = @exec_prefix@ -have_pkg_config = @have_pkg_config@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -ipopt_prefix = @ipopt_prefix@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -@CppAD_POSTFIX_FALSE@postfix_dir = . - -# ----------------------------------------------------------------------------- -# CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell -# -# CppAD is distributed under the terms of the -# Eclipse Public License Version 2.0. -# -# This Source Code may also be made available under the following -# Secondary License when the conditions for such availability set forth -# in the Eclipse Public License, Version 2.0 are satisfied: -# GNU General Public License, Version 2.0 or later. -# ----------------------------------------------------------------------------- -# -@CppAD_POSTFIX_TRUE@postfix_dir = $(POSTFIX_DIR) -# -myincludedir = $(includedir)/$(postfix_dir) -# -# BEGIN_SORT_THIS_LINE_PLUS_2 -nobase_myinclude_HEADERS = \ - cppad/base_require.hpp \ - cppad/configure.hpp \ - cppad/core/abort_recording.hpp \ - cppad/core/abs.hpp \ - cppad/core/abs_normal_fun.hpp \ - cppad/core/ad.hpp \ - cppad/core/ad_assign.hpp \ - cppad/core/ad_binary.hpp \ - cppad/core/ad_ctor.hpp \ - cppad/core/ad_fun.hpp \ - cppad/core/ad_io.hpp \ - cppad/core/ad_to_string.hpp \ - cppad/core/ad_type.hpp \ - cppad/core/ad_valued.hpp \ - cppad/core/add.hpp \ - cppad/core/add_eq.hpp \ - cppad/core/arithmetic.hpp \ - cppad/core/atan2.hpp \ - cppad/core/atomic/atomic_one.hpp \ - cppad/core/atomic/atomic_three.hpp \ - cppad/core/atomic/atomic_two.hpp \ - cppad/core/atomic/three_afun.hpp \ - cppad/core/atomic/three_ctor.hpp \ - cppad/core/atomic/three_for_type.hpp \ - cppad/core/atomic/three_forward.hpp \ - cppad/core/atomic/three_hes_sparsity.hpp \ - cppad/core/atomic/three_jac_sparsity.hpp \ - cppad/core/atomic/three_rev_depend.hpp \ - cppad/core/atomic/three_reverse.hpp \ - cppad/core/atomic/two_afun.hpp \ - cppad/core/atomic/two_clear.hpp \ - cppad/core/atomic/two_ctor.hpp \ - cppad/core/atomic/two_for_sparse_hes.hpp \ - cppad/core/atomic/two_for_sparse_jac.hpp \ - cppad/core/atomic/two_forward.hpp \ - cppad/core/atomic/two_option.hpp \ - cppad/core/atomic/two_rev_depend.hpp \ - cppad/core/atomic/two_rev_sparse_hes.hpp \ - cppad/core/atomic/two_rev_sparse_jac.hpp \ - cppad/core/atomic/two_reverse.hpp \ - cppad/core/azmul.hpp \ - cppad/core/base2ad.hpp \ - cppad/core/base_complex.hpp \ - cppad/core/base_cond_exp.hpp \ - cppad/core/base_double.hpp \ - cppad/core/base_float.hpp \ - cppad/core/base_hash.hpp \ - cppad/core/base_limits.hpp \ - cppad/core/base_std_math.hpp \ - cppad/core/base_to_string.hpp \ - cppad/core/bender_quad.hpp \ - cppad/core/bool_fun.hpp \ - cppad/core/bool_valued.hpp \ - cppad/core/capacity_order.hpp \ - cppad/core/check_for_nan.hpp \ - cppad/core/chkpoint_one/chkpoint_one.hpp \ - cppad/core/chkpoint_one/ctor.hpp \ - cppad/core/chkpoint_one/for_sparse_jac.hpp \ - cppad/core/chkpoint_one/forward.hpp \ - cppad/core/chkpoint_one/rev_sparse_hes.hpp \ - cppad/core/chkpoint_one/rev_sparse_jac.hpp \ - cppad/core/chkpoint_one/reverse.hpp \ - cppad/core/chkpoint_one/set_hes_sparse_bool.hpp \ - cppad/core/chkpoint_one/set_hes_sparse_set.hpp \ - cppad/core/chkpoint_one/set_jac_sparse_bool.hpp \ - cppad/core/chkpoint_one/set_jac_sparse_set.hpp \ - cppad/core/chkpoint_two/chkpoint_two.hpp \ - cppad/core/chkpoint_two/ctor.hpp \ - cppad/core/chkpoint_two/dynamic.hpp \ - cppad/core/chkpoint_two/for_type.hpp \ - cppad/core/chkpoint_two/forward.hpp \ - cppad/core/chkpoint_two/hes_sparsity.hpp \ - cppad/core/chkpoint_two/jac_sparsity.hpp \ - cppad/core/chkpoint_two/rev_depend.hpp \ - cppad/core/chkpoint_two/reverse.hpp \ - cppad/core/compare.hpp \ - cppad/core/compound_assign.hpp \ - cppad/core/con_dyn_var.hpp \ - cppad/core/cond_exp.hpp \ - cppad/core/convert.hpp \ - cppad/core/cppad_assert.hpp \ - cppad/core/dependent.hpp \ - cppad/core/discrete/discrete.hpp \ - cppad/core/div.hpp \ - cppad/core/div_eq.hpp \ - cppad/core/drivers.hpp \ - cppad/core/epsilon.hpp \ - cppad/core/equal_op_seq.hpp \ - cppad/core/for_hes_sparsity.hpp \ - cppad/core/for_jac_sparsity.hpp \ - cppad/core/for_one.hpp \ - cppad/core/for_sparse_hes.hpp \ - cppad/core/for_sparse_jac.hpp \ - cppad/core/for_two.hpp \ - cppad/core/forward/forward.hpp \ - cppad/core/fun_check.hpp \ - cppad/core/fun_construct.hpp \ - cppad/core/fun_eval.hpp \ - cppad/core/hash_code.hpp \ - cppad/core/hessian.hpp \ - cppad/core/identical.hpp \ - cppad/core/independent/independent.hpp \ - cppad/core/integer.hpp \ - cppad/core/jacobian.hpp \ - cppad/core/graph/from_json.hpp \ - cppad/core/graph/graph_op_enum.hpp \ - cppad/core/graph/to_json.hpp \ - cppad/core/lu_ratio.hpp \ - cppad/core/mul.hpp \ - cppad/core/mul_eq.hpp \ - cppad/core/near_equal_ext.hpp \ - cppad/core/new_dynamic.hpp \ - cppad/core/num_skip.hpp \ - cppad/core/numeric_limits.hpp \ - cppad/core/omp_max_thread.hpp \ - cppad/core/opt_val_hes.hpp \ - cppad/core/optimize.hpp \ - cppad/core/ordered.hpp \ - cppad/core/parallel_ad.hpp \ - cppad/core/pow.hpp \ - cppad/core/print_for.hpp \ - cppad/core/rev_hes_sparsity.hpp \ - cppad/core/rev_jac_sparsity.hpp \ - cppad/core/rev_one.hpp \ - cppad/core/rev_sparse_hes.hpp \ - cppad/core/rev_sparse_jac.hpp \ - cppad/core/rev_two.hpp \ - cppad/core/reverse.hpp \ - cppad/core/sign.hpp \ - cppad/core/sparse.hpp \ - cppad/core/sparse_hes.hpp \ - cppad/core/sparse_hessian.hpp \ - cppad/core/sparse_jac.hpp \ - cppad/core/sparse_jacobian.hpp \ - cppad/core/standard_math.hpp \ - cppad/core/std_math_11.hpp \ - cppad/core/sub.hpp \ - cppad/core/sub_eq.hpp \ - cppad/core/subgraph_jac_rev.hpp \ - cppad/core/subgraph_reverse.hpp \ - cppad/core/subgraph_sparsity.hpp \ - cppad/core/tape_link.hpp \ - cppad/core/test_vector.hpp \ - cppad/core/testvector.hpp \ - cppad/core/unary_minus.hpp \ - cppad/core/unary_plus.hpp \ - cppad/core/undef.hpp \ - cppad/core/user_ad.hpp \ - cppad/core/value.hpp \ - cppad/core/var2par.hpp \ - cppad/core/vec_ad/vec_ad.hpp \ - cppad/core/zdouble.hpp \ - cppad/cppad.hpp \ - cppad/example/atomic_three/mat_mul.hpp \ - cppad/example/atomic_two/eigen_cholesky.hpp \ - cppad/example/atomic_two/eigen_mat_inv.hpp \ - cppad/example/atomic_two/eigen_mat_mul.hpp \ - cppad/example/base_adolc.hpp \ - cppad/example/code_gen_fun.hpp \ - cppad/example/cppad_eigen.hpp \ - cppad/example/eigen_plugin.hpp \ - cppad/ipopt/solve.hpp \ - cppad/ipopt/solve_callback.hpp \ - cppad/ipopt/solve_result.hpp \ - cppad/local/abs_op.hpp \ - cppad/local/acos_op.hpp \ - cppad/local/acosh_op.hpp \ - cppad/local/ad_tape.hpp \ - cppad/local/add_op.hpp \ - cppad/local/asin_op.hpp \ - cppad/local/asinh_op.hpp \ - cppad/local/atan_op.hpp \ - cppad/local/atanh_op.hpp \ - cppad/local/atom_state.hpp \ - cppad/local/atomic_index.hpp \ - cppad/local/color_general.hpp \ - cppad/local/color_symmetric.hpp \ - cppad/local/comp_op.hpp \ - cppad/local/cond_op.hpp \ - cppad/local/cos_op.hpp \ - cppad/local/cosh_op.hpp \ - cppad/local/cppad_colpack.hpp \ - cppad/local/cskip_op.hpp \ - cppad/local/csum_op.hpp \ - cppad/local/declare_ad.hpp \ - cppad/local/define.hpp \ - cppad/local/discrete_op.hpp \ - cppad/local/div_op.hpp \ - cppad/local/erf_op.hpp \ - cppad/local/exp_op.hpp \ - cppad/local/expm1_op.hpp \ - cppad/local/hash_code.hpp \ - cppad/local/independent.hpp \ - cppad/local/is_pod.hpp \ - cppad/core/graph/from_graph.hpp \ - cppad/local/graph/json_lexer.hpp \ - cppad/core/graph/to_graph.hpp \ - cppad/core/graph/cpp_graph.hpp \ - cppad/local/graph/cpp_graph_itr.hpp \ - cppad/local/graph/cpp_graph_op.hpp \ - cppad/local/graph/json_parser.hpp \ - cppad/local/graph/json_writer.hpp \ - cppad/local/load_op.hpp \ - cppad/local/log1p_op.hpp \ - cppad/local/log_op.hpp \ - cppad/local/mul_op.hpp \ - cppad/local/op.hpp \ - cppad/local/op_code_dyn.hpp \ - cppad/local/op_code_var.hpp \ - cppad/local/optimize/cexp_info.hpp \ - cppad/local/optimize/csum_op_info.hpp \ - cppad/local/optimize/csum_stacks.hpp \ - cppad/local/optimize/get_cexp_info.hpp \ - cppad/local/optimize/get_dyn_previous.hpp \ - cppad/local/optimize/get_op_previous.hpp \ - cppad/local/optimize/get_op_usage.hpp \ - cppad/local/optimize/get_par_usage.hpp \ - cppad/local/optimize/hash_code.hpp \ - cppad/local/optimize/match_op.hpp \ - cppad/local/optimize/optimize_run.hpp \ - cppad/local/optimize/record_csum.hpp \ - cppad/local/optimize/record_pv.hpp \ - cppad/local/optimize/record_vp.hpp \ - cppad/local/optimize/record_vv.hpp \ - cppad/local/optimize/size_pair.hpp \ - cppad/local/optimize/usage.hpp \ - cppad/local/parameter_op.hpp \ - cppad/local/play/addr_enum.hpp \ - cppad/local/play/atom_op_info.hpp \ - cppad/local/play/player.hpp \ - cppad/local/play/random_iterator.hpp \ - cppad/local/play/random_setup.hpp \ - cppad/local/play/sequential_iterator.hpp \ - cppad/local/play/subgraph_iterator.hpp \ - cppad/local/pod_vector.hpp \ - cppad/local/pow_op.hpp \ - cppad/local/print_op.hpp \ - cppad/local/prototype_op.hpp \ - cppad/local/record/cond_exp.hpp \ - cppad/local/record/comp_op.hpp \ - cppad/local/record/put_dyn_atomic.hpp \ - cppad/local/record/put_var_atomic.hpp \ - cppad/local/record/put_var_vecad.hpp \ - cppad/local/record/recorder.hpp \ - cppad/local/set_get_in_parallel.hpp \ - cppad/local/sign_op.hpp \ - cppad/local/sin_op.hpp \ - cppad/local/sinh_op.hpp \ - cppad/local/sparse/binary_op.hpp \ - cppad/local/sparse/internal.hpp \ - cppad/local/sparse/list_setvec.hpp \ - cppad/local/sparse/pack_setvec.hpp \ - cppad/local/sparse/svec_setvec.hpp \ - cppad/local/sparse/unary_op.hpp \ - cppad/local/sqrt_op.hpp \ - cppad/local/std_set.hpp \ - cppad/local/store_op.hpp \ - cppad/local/sub_op.hpp \ - cppad/local/subgraph/arg_variable.hpp \ - cppad/local/subgraph/entire_call.hpp \ - cppad/local/subgraph/get_rev.hpp \ - cppad/local/subgraph/info.hpp \ - cppad/local/subgraph/init_rev.hpp \ - cppad/local/subgraph/sparsity.hpp \ - cppad/local/sweep/call_atomic.hpp \ - cppad/local/sweep/dynamic.hpp \ - cppad/local/sweep/for_hes.hpp \ - cppad/local/sweep/for_jac.hpp \ - cppad/local/sweep/forward0.hpp \ - cppad/local/sweep/forward1.hpp \ - cppad/local/sweep/forward2.hpp \ - cppad/local/sweep/rev_hes.hpp \ - cppad/local/sweep/rev_jac.hpp \ - cppad/local/sweep/reverse.hpp \ - cppad/local/tan_op.hpp \ - cppad/local/tanh_op.hpp \ - cppad/local/utility/cppad_vector_itr.hpp \ - cppad/local/utility/vector_bool.hpp \ - cppad/local/zmul_op.hpp \ - cppad/speed/det_33.hpp \ - cppad/speed/det_by_lu.hpp \ - cppad/speed/det_by_minor.hpp \ - cppad/speed/det_grad_33.hpp \ - cppad/speed/det_of_minor.hpp \ - cppad/speed/mat_sum_sq.hpp \ - cppad/speed/ode_evaluate.hpp \ - cppad/speed/sparse_hes_fun.hpp \ - cppad/speed/sparse_jac_fun.hpp \ - cppad/speed/uniform_01.hpp \ - cppad/utility.hpp \ - cppad/utility/check_numeric_type.hpp \ - cppad/utility/check_simple_vector.hpp \ - cppad/utility/elapsed_seconds.hpp \ - cppad/utility/error_handler.hpp \ - cppad/utility/index_sort.hpp \ - cppad/utility/lu_factor.hpp \ - cppad/utility/lu_invert.hpp \ - cppad/utility/lu_solve.hpp \ - cppad/utility/memory_leak.hpp \ - cppad/utility/nan.hpp \ - cppad/utility/near_equal.hpp \ - cppad/utility/ode_err_control.hpp \ - cppad/utility/ode_gear.hpp \ - cppad/utility/ode_gear_control.hpp \ - cppad/utility/omp_alloc.hpp \ - cppad/utility/poly.hpp \ - cppad/utility/pow_int.hpp \ - cppad/utility/romberg_mul.hpp \ - cppad/utility/romberg_one.hpp \ - cppad/utility/rosen_34.hpp \ - cppad/utility/runge_45.hpp \ - cppad/utility/set_union.hpp \ - cppad/utility/sparse2eigen.hpp \ - cppad/utility/sparse_rc.hpp \ - cppad/utility/sparse_rcv.hpp \ - cppad/utility/speed_test.hpp \ - cppad/utility/test_boolofvoid.hpp \ - cppad/utility/thread_alloc.hpp \ - cppad/utility/time_test.hpp \ - cppad/utility/to_string.hpp \ - cppad/utility/track_new_del.hpp \ - cppad/utility/vector.hpp \ - cppad/utility/vector_bool.hpp \ - cppad/wno_conversion.hpp - -all: all-am - -.SUFFIXES: -$(srcdir)/makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign include/makefile -makefile: $(srcdir)/makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-nobase_myincludeHEADERS: $(nobase_myinclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(nobase_myinclude_HEADERS)'; test -n "$(myincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(myincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(myincludedir)" || exit 1; \ - fi; \ - $(am__nobase_list) | while read dir files; do \ - xfiles=; for file in $$files; do \ - if test -f "$$file"; then xfiles="$$xfiles $$file"; \ - else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ - test -z "$$xfiles" || { \ - test "x$$dir" = x. || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(myincludedir)/$$dir'"; \ - $(MKDIR_P) "$(DESTDIR)$(myincludedir)/$$dir"; }; \ - echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(myincludedir)/$$dir'"; \ - $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(myincludedir)/$$dir" || exit $$?; }; \ - done - -uninstall-nobase_myincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(nobase_myinclude_HEADERS)'; test -n "$(myincludedir)" || list=; \ - $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ - dir='$(DESTDIR)$(myincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: makefile $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(myincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-nobase_myincludeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-nobase_myincludeHEADERS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - cscopelist-am ctags ctags-am distclean distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-nobase_myincludeHEADERS install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-nobase_myincludeHEADERS - -.PRECIOUS: makefile - -# End nobase_myinclude_HEADERS (check_makefile.sh uses this comment) -# END_SORT_THIS_LINE_MINUS_2 - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/build-config/cppad/meson.build b/build-config/cppad/meson.build index ce6bc39f..7cbb3682 100644 --- a/build-config/cppad/meson.build +++ b/build-config/cppad/meson.build @@ -1,10 +1,28 @@ -cppad_inc = include_directories('include', is_system: true) -cppad_dep = declare_dependency( - include_directories: cppad_inc, +#cppad_inc = include_directories('include', is_system: true) +#cppad_dep = declare_dependency( +# include_directories: cppad_inc, +#) +# +#message('Registering CppAD headers for installation...') +#install_subdir('include/cppad', install_dir: get_option('includedir')) +#message('Done registering CppAD headers for installation!') +# + + +cppad_cmake_options = cmake.subproject_options() + +cppad_cmake_options.add_cmake_defines({ + 'cppad_static_lib': 'true', + 'cpp_mas_num_threads': '10', + 'cppad_debug_and_release': 'false', + 'include_doc': 'false' +}) + +cppad_cmake_options.set_install(false) + +cppad_sp = cmake.subproject( + 'cppad', + options: cppad_cmake_options, ) -message('Registering CppAD headers for installation...') -install_subdir('include/cppad', install_dir: get_option('includedir')) -message('Done registering CppAD headers for installation!') - - +cppad_dep = cppad_sp.dependency('cppad_lib').as_system() \ No newline at end of file diff --git a/build-config/cppad/readme.md b/build-config/cppad/readme.md deleted file mode 100644 index d10a83ba..00000000 --- a/build-config/cppad/readme.md +++ /dev/null @@ -1,50 +0,0 @@ -# Title -CppAD: A Package for Differentiation of C++ Algorithms - -# Links - -- [docmentation](https://coin-or.github.io/CppAD/doc) - -- [News](https://coin-or.github.io/CppAD/doc/whats_new.htm) - -- [Install](https://coin-or.github.io/CppAD/doc/install.htm) - -- [Directories](https://coin-or.github.io/CppAD/doc/directory.htm) - -- [Coin-OR Download](https://www.coin-or.org/download/source/CppAD/) - - -# License -
-CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-18 Bradley M. Bell
-
-CppAD is distributed under the terms of the
-             Eclipse Public License Version 2.0.
-
-This Source Code may also be made available under the following
-Secondary License when the conditions for such availability set forth
-in the Eclipse Public License, Version 2.0 are satisfied:
-      GNU General Public License, Version 2.0 or later.
-
- - -# Autotools -The preferred method to test and install CppAD uses cmake. -The deprecated autotools procedure can be used for this purpose, -but it will eventually be removed. -For any sub-directory *dir*, -files of the form *dir*/`makefile.am` and *dir*/`makefile.in` -are used to support the autotools test and install procedure. -In addition, -the following files, in this directory, are also for this purpose: -`compile`, -`config.guess`, -`config.sub`, -`configure.ac`, -`depcomp`, -`install-sh`, -`missing`. - - -# Copyright: -See the file `authors` in this directory. diff --git a/build-config/cppad/version b/build-config/cppad/version deleted file mode 100644 index ca03bea3..00000000 --- a/build-config/cppad/version +++ /dev/null @@ -1,2 +0,0 @@ -checked out on June 19th, 2025 -Tag: stable/20210000 diff --git a/build-config/meson.build b/build-config/meson.build index a433637d..18e455bf 100644 --- a/build-config/meson.build +++ b/build-config/meson.build @@ -13,5 +13,9 @@ subdir('eigen') subdir('json') - subdir('CLI11') +subdir('unordered_dense') + +if get_option('use_mimalloc') + subdir('mimalloc') +endif diff --git a/build-config/mimalloc/meson.build b/build-config/mimalloc/meson.build new file mode 100644 index 00000000..09819469 --- /dev/null +++ b/build-config/mimalloc/meson.build @@ -0,0 +1,2 @@ +mimalloc_proj = subproject('mimalloc') +mimalloc_dep = mimalloc_proj.get_variable('mi_dep') diff --git a/build-config/sundials/cvode/meson.build b/build-config/sundials/cvode/meson.build index 4b19f6ad..90596bf9 100644 --- a/build-config/sundials/cvode/meson.build +++ b/build-config/sundials/cvode/meson.build @@ -7,7 +7,8 @@ cvode_cmake_options.add_cmake_defines({ 'BUILD_SHARED_LIBS' : 'OFF', 'BUILD_STATIC_LIBS' : 'ON', 'EXAMPLES_ENABLE_C' : 'OFF', - 'CMAKE_POSITION_INDEPENDENT_CODE': true + 'CMAKE_POSITION_INDEPENDENT_CODE': true, + 'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON' }) @@ -16,6 +17,8 @@ cvode_cmake_options.add_cmake_defines({ 'CMAKE_INSTALL_INCLUDEDIR': get_option('includedir') }) +cvode_cmake_options.set_install(false) + if meson.is_cross_build() and host_machine.system() == 'emscripten' cvode_cmake_options.add_cmake_defines({ 'CMAKE_C_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1', diff --git a/build-config/sundials/kinsol/meson.build b/build-config/sundials/kinsol/meson.build index b14cbe74..fd795ef2 100644 --- a/build-config/sundials/kinsol/meson.build +++ b/build-config/sundials/kinsol/meson.build @@ -8,7 +8,8 @@ kinsol_cmake_options.add_cmake_defines({ 'BUILD_SHARED_LIBS' : 'OFF', 'BUILD_STATIC_LIBS' : 'ON', 'EXAMPLES_ENABLE_C' : 'OFF', - 'CMAKE_POSITION_INDEPENDENT_CODE': true + 'CMAKE_POSITION_INDEPENDENT_CODE': true, + 'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON' }) kinsol_cmake_options.add_cmake_defines({ @@ -16,6 +17,8 @@ kinsol_cmake_options.add_cmake_defines({ 'CMAKE_INSTALL_INCLUDEDIR': get_option('includedir') }) +kinsol_cmake_options.set_install(false) + kinsol_sp = cmake.subproject( 'kinsol', options: kinsol_cmake_options, diff --git a/build-config/unordered_dense/meson.build b/build-config/unordered_dense/meson.build new file mode 100644 index 00000000..cd055293 --- /dev/null +++ b/build-config/unordered_dense/meson.build @@ -0,0 +1,5 @@ +uod_sp = cmake.subproject( + 'unordered_dense' +) + +uod_dep = uod_sp.dependency('unordered_dense') \ No newline at end of file diff --git a/build-python/meson.build b/build-python/meson.build index 87234f3b..74960332 100644 --- a/build-python/meson.build +++ b/build-python/meson.build @@ -28,6 +28,8 @@ if get_option('build_python') meson.project_source_root() + '/src/python/policy/bindings.cpp', meson.project_source_root() + '/src/python/policy/trampoline/py_policy.cpp', meson.project_source_root() + '/src/python/utils/bindings.cpp', + meson.project_source_root() + '/src/python/config/bindings.cpp', + meson.project_source_root() + '/src/python/engine/scratchpads/bindings.cpp', ] @@ -56,6 +58,7 @@ if get_option('build_python') files( meson.project_source_root() + '/src/python/gridfire/__init__.py', meson.project_source_root() + '/stubs/gridfire/_gridfire/__init__.pyi', + meson.project_source_root() + '/stubs/gridfire/_gridfire/config.pyi', meson.project_source_root() + '/stubs/gridfire/_gridfire/exceptions.pyi', meson.project_source_root() + '/stubs/gridfire/_gridfire/partition.pyi', meson.project_source_root() + '/stubs/gridfire/_gridfire/reaction.pyi', @@ -72,6 +75,7 @@ if get_option('build_python') files( meson.project_source_root() + '/stubs/gridfire/_gridfire/engine/__init__.pyi', meson.project_source_root() + '/stubs/gridfire/_gridfire/engine/diagnostics.pyi', + meson.project_source_root() + '/stubs/gridfire/_gridfire/engine/scratchpads.pyi' ), subdir: 'gridfire/engine', ) diff --git a/meson.build b/meson.build index b7e88d36..c7e707d3 100644 --- a/meson.build +++ b/meson.build @@ -18,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # *********************************************************************** # -project('GridFire', ['c', 'cpp'], version: 'v0.7.4_rc2', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0') +project('GridFire', ['c', 'cpp'], version: 'v0.7.4rc3', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0') # Start by running the code which validates the build environment subdir('build-check') @@ -35,11 +35,15 @@ subdir('src') # Build the Python bindings subdir('build-python') -# Buil the test suite +# Build the test suite subdir('tests') +# Build the tool suite subdir('tools') +# Build the benchmark suite +subdir('benchmarks') + # Build the pkg-config file subdir('build-extra/pkg-config') diff --git a/meson_options.txt b/meson_options.txt index cbee156c..0d7a71d1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -9,4 +9,7 @@ option('plugin_support', type: 'boolean', value: false, description: 'Enable sup option('python_target_version', type: 'string', value: '3.13', description: 'Target version for python compilation, only used for cross compilation') option('build_c_api', type: 'boolean', value: true, description: 'compile the C API') option('build_tools', type: 'boolean', value: true, description: 'build the GridFire command line tools') -option('openmp_support', type: 'boolean', value: false, description: 'Enable OpenMP support for parallelization') \ No newline at end of file +option('openmp_support', type: 'boolean', value: false, description: 'Enable OpenMP support for parallelization') +option('use_mimalloc', type: 'boolean', value: true, description: 'Use mimalloc as the memory allocator for GridFire. Generally this is ~10% faster than the system allocator.') +option('build_benchmarks', type: 'boolean', value: false, description: 'build the benchmark suite') +option('asan', type: 'boolean', value: false, description: 'Enable AddressSanitizer (ASan) support for detecting memory errors') \ No newline at end of file diff --git a/pip_install_mac_patch.sh b/pip_install_mac_patch.sh index fd0747b0..66491797 100755 --- a/pip_install_mac_patch.sh +++ b/pip_install_mac_patch.sh @@ -56,7 +56,7 @@ echo "Site packages: $SITE_PACKAGES" echo "" echo -e "${GREEN}Step 2: Installing fourdst with pip...${NC}" -$PYTHON_BIN -m pip install . -v +$PYTHON_BIN -m pip install . -v --no-build-isolation if [ $? -ne 0 ]; then echo -e "${RED}Error: pip install failed${NC}" diff --git a/pyproject.toml b/pyproject.toml index bedbcdc0..6fbb15f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "mesonpy" [project] name = "gridfire" # Choose your Python package name -version = "0.7.4_rc2" # Your project's version +version = "v0.7.4rc3" # Your project's version description = "Python interface to the GridFire nuclear network code" readme = "README.md" license = { file = "LICENSE.txt" } # Reference your license file [cite: 2] @@ -22,4 +22,4 @@ maintainers = [ ] [tool.meson-python.args] -setup = ['-Dpkg-config=false'] +setup = ['-Dpkg_config=false', '-Dbuildtype=release', '-Dopenmp_support=true', '-Dasan=false', '-Dlog_level=error', '-Dbuild_tests=false', '-Dbuild_c_api=false', '-Dbuild_examples=false', '-Dbuild_benchmarks=false', '-Dbuild_tools=false', '-Dplugin_support=false', '-Duse_mimalloc=false', '-Dbuild_python=true'] diff --git a/src/extern/fortran/gridfire_mod.f90 b/src/extern/fortran/gridfire_mod.f90 index 1c4c3253..38d0889b 100644 --- a/src/extern/fortran/gridfire_mod.f90 +++ b/src/extern/fortran/gridfire_mod.f90 @@ -2,6 +2,14 @@ module gridfire_mod use iso_c_binding implicit none + type, public :: GF_TYPE + integer(c_int) :: value + end type GF_TYPE + + type(GF_TYPE), parameter, public :: & + SINGLE_ZONE = GF_TYPE(1001), & + MULTI_ZONE = GF_TYPE(1002) + enum, bind (C) enumerator :: FDSSE_NON_4DSTAR_ERROR = -102 enumerator :: FDSSE_UNKNOWN_ERROR = -101 @@ -50,24 +58,46 @@ module gridfire_mod enumerator :: GF_DEBUG_ERRROR = 30 enumerator :: GF_GRIDFIRE_ERROR = 31 + enumerator :: GF_UNINITIALIZED_INPUT_MEMORY_ERROR = 32 + enumerator :: GF_UNINITIALIZED_OUTPUT_MEMORY_ERROR = 33 + + enumerator :: GF_INVALD_NUM_SPECIES = 34 + enumerator :: GF_INVALID_TIMESTEPS = 35 + enumerator :: GF_UNKNONWN_FREE_TYPE = 36 + + enumerator :: GF_INVALID_TYPE = 37 + + enumerator :: GF_SINGLE_ZONE = 1001 + enumerator :: GF_MULTI_ZONE = 1002 end enum interface ! void* gf_init() - function gf_init() bind(C, name="gf_init") - import :: c_ptr + function gf_init(ctx_type) bind(C, name="gf_init") + import :: c_ptr, c_int type(c_ptr) :: gf_init + integer(c_int), value :: ctx_type end function gf_init - ! void gf_free(void* gf) - subroutine gf_free(gf) bind(C, name="gf_free") - import :: c_ptr - type(c_ptr), value :: gf - end subroutine gf_free + ! int gf_free(void* gf) + function gf_free(ctx_type, ptr) result(c_res) bind(C, name="gf_free") + import :: c_ptr, c_int + type(c_ptr), value :: ptr + integer(c_int), value :: ctx_type + integer(c_int) :: c_res + end function gf_free + + function gf_set_num_zones(ctx_type, ptr, num_zones) result(c_res) bind(C, name="gf_set_num_zones") + import :: c_ptr, c_int, c_size_t + type(c_ptr), value :: ptr + integer(c_int), value :: ctx_type + integer(c_size_t), value :: num_zones + integer(c_int) :: c_res + end function gf_set_num_zones ! char* gf_get_last_error_message(void* ptr); function gf_get_last_error_message(ptr) result(c_msg) bind(C, name="gf_get_last_error_message") - import + import :: c_ptr, c_int type(c_ptr), value :: ptr type(c_ptr) :: c_msg end function @@ -102,49 +132,116 @@ module gridfire_mod end function ! int gf_evolve(...) - function gf_evolve(ptr, Y_in, num_species, T, rho, dt, Y_out, energy_out, dEps_dT, dEps_dRho, specific_neutrino_loss, specific_neutrino_flux, mass_lost) result(ierr) & + function gf_evolve_c_scalar(ctx_type, ptr, Y_in, num_species, T, rho, tMax, dt0, & + Y_out, energy, dedt, dedrho, & + nue_loss, nu_flux, mass_lost) result(ierr) & bind(C, name="gf_evolve") - import + import :: c_ptr, c_int, c_double, c_size_t type(c_ptr), value :: ptr - real(c_double), dimension(*), intent(in) :: Y_in + integer(c_int), value :: ctx_type integer(c_size_t), value :: num_species - real(c_double), value :: T, rho, dt + + ! Arrays + real(c_double), dimension(*), intent(in) :: Y_in real(c_double), dimension(*), intent(out) :: Y_out - real(c_double), intent(out) :: energy_out, dEps_dT, dEps_dRho, specific_neutrino_loss, specific_neutrino_flux, mass_lost + + ! Scalars (Passed by Reference -> matches void*) + real(c_double), intent(in) :: T, rho + real(c_double), intent(out) :: energy, dedt, dedrho, nue_loss, nu_flux, mass_lost + + ! Scalars (Passed by Value) + real(c_double), value :: tMax, dt0 + + integer(c_int) :: ierr + end function + + ! 2. Interface for Multi Zone (Arrays) + function gf_evolve_c_array(ctx_type, ptr, Y_in, num_species, T, rho, tMax, dt0, & + Y_out, energy, dedt, dedrho, & + nue_loss, nu_flux, mass_lost) result(ierr) & + bind(C, name="gf_evolve") + import :: c_ptr, c_int, c_double, c_size_t + type(c_ptr), value :: ptr + integer(c_int), value :: ctx_type + integer(c_size_t), value :: num_species + + ! All Arrays (dimension(*)) + real(c_double), dimension(*), intent(in) :: Y_in + real(c_double), dimension(*), intent(in) :: T, rho + + real(c_double), dimension(*), intent(out) :: Y_out + real(c_double), dimension(*), intent(out) :: energy, dedt, dedrho, nue_loss, nu_flux, mass_lost + + ! Scalars (Passed by Value) + real(c_double), value :: tMax, dt0 + integer(c_int) :: ierr end function end interface type :: GridFire type(c_ptr) :: ctx = c_null_ptr + integer(c_int) :: ctx_type = SINGLE_ZONE%value integer(c_size_t) :: num_species = 0 + integer(c_size_t) :: num_zones = 1 contains procedure :: gff_init procedure :: gff_free - procedure :: register_species - procedure :: setup_policy - procedure :: setup_solver - procedure :: evolve - procedure :: get_last_error + procedure :: gff_register_species + procedure :: gff_setup_policy + procedure :: gff_setup_solver + procedure :: gff_get_last_error + + procedure :: gff_evolve_single + procedure :: gff_evolve_multi + + generic :: gff_evolve => gff_evolve_single, gff_evolve_multi end type GridFire contains - subroutine gff_init(self) + subroutine gff_init(self, type, zones) class(GridFire), intent(out) :: self + type(GF_TYPE), intent(in) :: type + integer(c_size_t), intent(in), optional :: zones + integer(c_int) :: ierr - self%ctx = gf_init() + if (type%value==1002) then + if (.not. present(zones)) then + print *, "GridFire Error: Multi-zone type requires number of zones to be specficied in the GridFire init method (i.e. GridFire(MULTI_ZONE, 10) for 10 zones)." + error stop + end if + + self%num_zones = zones + end if + + self%ctx_type = type%value + + self%ctx = gf_init(self%ctx_type) + + if (type%value==1002) then + ierr = gf_set_num_zones(self%ctx_type, self%ctx, self%num_zones) + if (ierr /= GF_SUCCESS .AND. ierr /= FDSSE_SUCCESS) then + print *, "GridFire Multi-Zone Error: ", self%gff_get_last_error() + error stop + end if + end if end subroutine gff_init subroutine gff_free(self) class(GridFire), intent(inout) :: self + integer(c_int) :: ierr if (c_associated(self%ctx)) then - call gf_free(self%ctx) + ierr = gf_free(self%ctx_type, self%ctx) + if (ierr /= GF_SUCCESS .AND. ierr /= FDSSE_SUCCESS) then + print *, "GridFire Free Error: ", self%gff_get_last_error() + error stop + end if self%ctx = c_null_ptr end if end subroutine gff_free - function get_last_error(self) result(msg) + function gff_get_last_error(self) result(msg) class(GridFire), intent(in) :: self character(len=:), allocatable :: msg type(c_ptr) :: c_msg_ptr @@ -169,9 +266,9 @@ module gridfire_mod do i = 1, len_str msg(i+10:i+10) = char_ptr(i) end do - end function get_last_error + end function gff_get_last_error - subroutine register_species(self, species_list) + subroutine gff_register_species(self, species_list) class(GridFire), intent(inout) :: self character(len=*), dimension(:), intent(in) :: species_list @@ -179,7 +276,6 @@ module gridfire_mod character(kind=c_char, len=:), allocatable, target :: temp_strs(:) integer :: i, n, ierr - print *, "Registering ", size(species_list), " species." n = size(species_list) self%num_species = int(n, c_size_t) @@ -191,17 +287,14 @@ module gridfire_mod c_ptrs(i) = c_loc(temp_strs(i)) end do - print *, "Calling gf_register_species..." ierr = gf_register_species(self%ctx, int(n, c_int), c_ptrs) - print *, "gf_register_species returned with code: ", ierr - if (ierr /= GF_SUCCESS .AND. ierr /= FDSSE_SUCCESS) then - print *, "GridFire: ", self%get_last_error() + print *, "GridFire: ", self%gff_get_last_error() error stop end if - end subroutine register_species + end subroutine gff_register_species - subroutine setup_policy(self, policy_name, abundances) + subroutine gff_setup_policy(self, policy_name, abundances) class(GridFire), intent(in) :: self character(len=*), intent(in) :: policy_name real(c_double), dimension(:), intent(in) :: abundances @@ -218,41 +311,59 @@ module gridfire_mod self%num_species) if (ierr /= GF_SUCCESS .AND. ierr /= FDSSE_SUCCESS) then - print *, "GridFire Policy Error: ", self%get_last_error() + print *, "GridFire Policy Error: ", self%gff_get_last_error() error stop end if - end subroutine setup_policy + end subroutine gff_setup_policy - subroutine setup_solver(self, solver_name) + subroutine gff_setup_solver(self, solver_name) class(GridFire), intent(in) :: self character(len=*), intent(in) :: solver_name integer(c_int) :: ierr ierr = gf_construct_solver_from_engine(self%ctx, trim(solver_name) // c_null_char) if (ierr /= GF_SUCCESS .AND. ierr /= FDSSE_SUCCESS) then - print *, "GridFire Solver Error: ", self%get_last_error() + print *, "GridFire Solver Error: ", self%gff_get_last_error() error stop end if - end subroutine setup_solver + end subroutine gff_setup_solver - subroutine evolve(self, Y_in, T, rho, dt, Y_out, energy, dedt, dedrho, nu_e_loss, nu_flux, mass_lost, ierr) + subroutine gff_evolve_single(self, Y_in, T, rho, tMax, dt0, Y_out, energy, dedt, dedrho, nu_e_loss, nu_flux, mass_lost, ierr) class(GridFire), intent(in) :: self real(c_double), dimension(:), intent(in) :: Y_in - real(c_double), value :: T, rho, dt + real(c_double), intent(in) :: T, rho + real(c_double), value :: tMax, dt0 + real(c_double), dimension(:), intent(out) :: Y_out real(c_double), intent(out) :: energy, dedt, dedrho, nu_e_loss, nu_flux, mass_lost integer, intent(out) :: ierr integer(c_int) :: c_ierr - c_ierr = gf_evolve(self%ctx, & + c_ierr = gf_evolve_c_scalar(self%ctx_type, self%ctx, & Y_in, self%num_species, & - T, rho, dt, & + T, rho, tMax, dt0, & Y_out, & energy, dedt, dedrho, nu_e_loss, nu_flux, mass_lost) - ierr = int(c_ierr) - if (ierr /= GF_SUCCESS .AND. ierr /= FDSSE_SUCCESS) then - print *, "GridFire Evolve Error: ", self%get_last_error() - end if - end subroutine evolve -end module gridfire_mod \ No newline at end of file + end subroutine gff_evolve_single + + subroutine gff_evolve_multi(self, Y_in, T, rho, tMax, dt0, Y_out, energy, dedt, dedrho, nu_e_loss, nu_flux, mass_lost, ierr) + class(GridFire), intent(in) :: self + real(c_double), dimension(:,:), intent(in) :: Y_in + real(c_double), dimension(:), intent(in) :: T, rho + real(c_double), value :: tMax, dt0 + + real(c_double), dimension(:,:), intent(out) :: Y_out + real(c_double), dimension(:), intent(out) :: energy, dedt, dedrho, nu_e_loss, nu_flux, mass_lost + integer, intent(out) :: ierr + integer(c_int) :: c_ierr + + c_ierr = gf_evolve_c_array(self%ctx_type, self%ctx, & + Y_in, self%num_species, & + T, rho, tMax, dt0, & + Y_out, & + energy, dedt, dedrho, nu_e_loss, nu_flux, mass_lost) + ierr = int(c_ierr) + end subroutine gff_evolve_multi + +end module gridfire_mod diff --git a/src/extern/include/gridfire/extern/gridfire_context.h b/src/extern/include/gridfire/extern/gridfire_context.h index a33904e6..72fc2651 100644 --- a/src/extern/include/gridfire/extern/gridfire_context.h +++ b/src/extern/include/gridfire/extern/gridfire_context.h @@ -7,19 +7,32 @@ #include #include -struct GridFireContext { +enum class GFContextType { + POINT, + GRID +}; + +struct GFContext { + virtual ~GFContext() = default; + std::unique_ptr policy; - gridfire::engine::DynamicEngine* engine; - std::unique_ptr solver; - + const gridfire::engine::DynamicEngine* engine; + std::unique_ptr engine_ctx; std::vector speciesList; - fourdst::composition::Composition working_comp; - void init_species_map(const std::vector& species_names); - void init_engine_from_policy(const std::string& policy_name, const double *abundances, size_t num_species); - void init_solver_from_engine(const std::string& solver_name); + virtual void init_species_map(const std::vector& species_names); + virtual void init_engine_from_policy(const std::string& policy_name, const double *abundances, size_t num_species); + virtual void init_solver_from_engine() = 0; - void init_composition_from_abundance_vector(const double* abundances, size_t num_species); + fourdst::composition::Composition init_composition_from_abundance_vector(const std::vector &abundances, size_t num_species) const; + std::string last_error; +}; + +struct GFPointContext final: GFContext{ + std::unique_ptr solver; + std::unique_ptr solver_ctx; + + void init_solver_from_engine() override; int evolve( const double* Y_in, @@ -35,9 +48,45 @@ struct GridFireContext { double& specific_neutrino_energy_loss, double& specific_neutrino_flux, double& mass_lost - ); + ) const; - std::string last_error; }; +struct GFGridContext final : GFContext { + std::unique_ptr local_solver; + std::unique_ptr solver; + std::unique_ptr solver_ctx; + + void init_solver_from_engine() override; + + size_t zones; + + void set_zones(const size_t num_zones) { + zones = num_zones; + } + + [[nodiscard]] size_t get_zones() const { + return zones; + } + + int evolve( + const double* Y_in, + size_t num_species, + const double* T, + const double* rho, + double tMax, + double dt0, + double* Y_out, + double* energy_out, + double* dEps_dT, + double* dEps_dRho, + double* specific_neutrino_energy_loss, + double* specific_neutrino_flux, + double* mass_lost + ) const; + +}; + +std::unique_ptr make_gf_context(const GFContextType& type); + #endif \ No newline at end of file diff --git a/src/extern/include/gridfire/extern/gridfire_extern.h b/src/extern/include/gridfire/extern/gridfire_extern.h index 7fa9e753..0f58d38e 100644 --- a/src/extern/include/gridfire/extern/gridfire_extern.h +++ b/src/extern/include/gridfire/extern/gridfire_extern.h @@ -6,6 +6,12 @@ #ifdef __cplusplus extern "C" { #endif + enum GF_TYPE { + SINGLE_ZONE = 1001, + MULTI_ZONE = 1002 + }; + + enum FDSSE_ERROR_CODES { FDSSE_NON_4DSTAR_ERROR = -102, FDSSE_UNKNOWN_ERROR = -101, @@ -54,37 +60,49 @@ extern "C" { GF_DEBUG_ERROR = 30, GF_GRIDFIRE_ERROR = 31, + GF_UNINITIALIZED_INPUT_MEMORY_ERROR = 32, + GF_UNINITIALIZED_OUTPUT_MEMORY_ERROR = 33, + + GF_INVALID_NUM_SPECIES = 34, + + GF_INVALID_TIMESTEPS = 35, + GF_UNKNOWN_FREE_TYPE = 36, + + GF_INVALID_TYPE = 37, }; char* gf_get_last_error_message(void* ptr); char* gf_error_code_to_string(int error_code); - void* gf_init(); + void* gf_init(const enum GF_TYPE type); - void gf_free(void* ctx); + int gf_free(const enum GF_TYPE type, void *ctx); + + int gf_set_num_zones(const enum GF_TYPE type, void* ptr, const size_t num_zones); int gf_register_species(void* ptr, const int num_species, const char** species_names); int gf_construct_engine_from_policy(void* ptr, const char* policy_name, const double *abundances, size_t num_species); - int gf_construct_solver_from_engine(void* ptr, const char* solver_name); + int gf_construct_solver_from_engine(void* ptr); int gf_evolve( + enum GF_TYPE type, void* ptr, - const double* Y_in, + const void* Y_in, size_t num_species, - double T, - double rho, + const void* T, + const void* rho, double tMax, double dt0, - double* Y_out, - double* energy_out, - double* dEps_dT, - double* dEps_dRho, - double* specific_neutrino_energy_loss, - double* specific_neutrino_flux, - double* mass_lost + void* Y_out, + void* energy_out, + void* dEps_dT, + void* dEps_dRho, + void* specific_neutrino_energy_loss, + void* specific_neutrino_flux, + void* mass_lost ); #ifdef __cplusplus diff --git a/src/extern/lib/gridfire_context.cpp b/src/extern/lib/gridfire_context.cpp index 41f81fc1..3c74f695 100644 --- a/src/extern/lib/gridfire_context.cpp +++ b/src/extern/lib/gridfire_context.cpp @@ -3,11 +3,10 @@ #include "fourdst/atomic/species.h" #include "fourdst/composition/exceptions/exceptions_composition.h" +#include "gridfire/exceptions/error_policy.h" +#include "gridfire/utils/logging.h" -void GridFireContext::init_species_map(const std::vector &species_names) { - for (const auto& name: species_names) { - working_comp.registerSymbol(name); - } +void GFContext::init_species_map(const std::vector &species_names) { this->speciesList.clear(); this->speciesList.reserve(species_names.size()); @@ -24,8 +23,9 @@ void GridFireContext::init_species_map(const std::vector &species_n } -void GridFireContext::init_engine_from_policy(const std::string &policy_name, const double *abundances, const size_t num_species) { - init_composition_from_abundance_vector(abundances, num_species); +void GFContext::init_engine_from_policy(const std::string &policy_name, const double *abundances, const size_t num_species) { + const std::vector Y_scratch(abundances, abundances + num_species); + fourdst::composition::Composition comp = init_composition_from_abundance_vector(Y_scratch, num_species); enum class EnginePolicy { MAIN_SEQUENCE_POLICY @@ -47,71 +47,53 @@ void GridFireContext::init_engine_from_policy(const std::string &policy_name, co switch (engine_map.at(policy_name)) { case EnginePolicy::MAIN_SEQUENCE_POLICY: { - this->policy = std::make_unique(this->working_comp); - this->engine = &policy->construct(); + this->policy = std::make_unique(comp); + const auto& [e, ctx] = policy->construct(); + this->engine = &e; + this->engine_ctx = ctx->clone_structure(); + break; } default: throw gridfire::exceptions::PolicyError( - "Unhandled engine policy in GridFireContext::init_engine_from_policy" + "Unhandled engine policy in GFPointContext::init_engine_from_policy" ); } } -void GridFireContext::init_solver_from_engine(const std::string &solver_name) { - enum class SolverType { - CVODE - }; - - static const std::unordered_map solver_map = { - {"CVODE", SolverType::CVODE} - }; - - if (!solver_map.contains(solver_name)) { - throw gridfire::exceptions::SolverError( - std::format( - "Solver {} is not recognized. Valid solvers are: {}", - solver_name, - gridfire::utils::iterable_to_delimited_string(solver_map, ", ", [](const auto& pair){ return pair.first; }) - ) - ); - } - - switch (solver_map.at(solver_name)) { - case SolverType::CVODE: { - this->solver = std::make_unique(*this->engine); - break; - } - default: - throw gridfire::exceptions::SolverError( - "Unhandled solver type in GridFireContext::init_solver_from_engine" - ); - } - -} - -void GridFireContext::init_composition_from_abundance_vector(const double *abundances, size_t num_species) { +fourdst::composition::Composition GFContext::init_composition_from_abundance_vector(const std::vector &abundances, size_t num_species) const { if (num_species == 0) { throw fourdst::composition::exceptions::InvalidCompositionError("Cannot initialize composition with zero species."); } - if (num_species != working_comp.size()) { + if (num_species != speciesList.size()) { throw fourdst::composition::exceptions::InvalidCompositionError( std::format( "Number of species provided ({}) does not match the registered species count ({}).", num_species, - working_comp.size() + speciesList.size() ) ); } + fourdst::composition::Composition comp; for (size_t i = 0; i < num_species; i++) { - this->working_comp.setMolarAbundance(this->speciesList[i], abundances[i]); + comp.registerSpecies(this->speciesList[i]); + comp.setMolarAbundance(this->speciesList[i], abundances[i]); } + + return comp; } -int GridFireContext::evolve( + +void GFPointContext::init_solver_from_engine() { + this->solver = std::make_unique(*this->engine); + this->solver_ctx = std::make_unique(*engine_ctx); +} + + +int GFPointContext::evolve( const double* Y_in, const size_t num_species, const double T, @@ -125,17 +107,19 @@ int GridFireContext::evolve( double& specific_neutrino_energy_loss, double& specific_neutrino_flux, double& mass_lost -) { - init_composition_from_abundance_vector(Y_in, num_species); +) const { + + const std::vector Y_scratch(Y_in, Y_in + num_species); + const fourdst::composition::Composition comp = init_composition_from_abundance_vector(Y_scratch, num_species); gridfire::NetIn netIn; netIn.temperature = T; netIn.density = rho; netIn.dt0 = dt0; netIn.tMax = tMax; - netIn.composition = this->working_comp; + netIn.composition = comp; - const gridfire::NetOut result = this->solver->evaluate(netIn); + const gridfire::NetOut result = this->solver->evaluate(*solver_ctx, netIn); energy_out = result.energy; dEps_dT = result.dEps_dT; @@ -158,4 +142,100 @@ int GridFireContext::evolve( } return 0; -} \ No newline at end of file +} + +void GFGridContext::init_solver_from_engine() { + this->local_solver = std::make_unique(*this->engine); + this->solver = std::make_unique(*this->engine, *this->local_solver); + this->solver_ctx = std::make_unique(*engine_ctx); +} + +int GFGridContext::evolve( + const double* Y_in, + size_t num_species, + const double *T, + const double *rho, + double tMax, + double dt0, + double *Y_out, + double *energy_out, + double *dEps_dT, + double *dEps_dRho, + double *specific_neutrino_energy_loss, + double *specific_neutrino_flux, + double *mass_lost +) const { + if (this->get_zones() == 0) { + throw gridfire::exceptions::GridFireError("GFGridContext has zero zones configured for evolution."); + } + + if (Y_in == nullptr || T == nullptr || rho == nullptr) { + throw gridfire::exceptions::GridFireError("Input abundance, temperature, or density pointers are null."); + } + + if (Y_out == nullptr) { + throw gridfire::exceptions::GridFireError("Output abundance pointer is null."); + } + + std::vector zone_compositions; + + zone_compositions.reserve(this->get_zones()); + + std::vector Y_scratch; + Y_scratch.resize(num_species); + + for (size_t i = 0; i < this->get_zones(); ++i) { + for (size_t j = 0; j < num_species; ++j) { + Y_scratch[j] = Y_in[i * num_species + j]; + } + zone_compositions.push_back(init_composition_from_abundance_vector(Y_scratch, num_species)); + } + + std::vector netIns; + netIns.reserve(this->get_zones()); + for (size_t i = 0; i < this->get_zones(); ++i) { + gridfire::NetIn netIn; + netIn.temperature = T[i]; + netIn.density = rho[i]; + netIn.dt0 = dt0; + netIn.tMax = tMax; + netIn.composition = zone_compositions[i]; + netIns.push_back(netIn); + } + + std::vector results = this->solver->evaluate(*this->solver_ctx, netIns); + + for (size_t zone_idx = 0; zone_idx < this->get_zones(); ++zone_idx) { + const gridfire::NetOut& netOut = results[zone_idx]; + energy_out[zone_idx] = netOut.energy; + dEps_dT[zone_idx] = netOut.dEps_dT;; + dEps_dRho[zone_idx] = netOut.dEps_dRho; + specific_neutrino_energy_loss[zone_idx] = netOut.specific_neutrino_energy_loss; + specific_neutrino_flux[zone_idx] = netOut.specific_neutrino_flux; + + std::set seen_species; + for (size_t i = 0; i < num_species; ++i) { + fourdst::atomic::Species species = this->speciesList[i]; + Y_out[zone_idx * num_species + i] = netOut.composition.getMolarAbundance(species); + seen_species.insert(species); + } + mass_lost[zone_idx] = 0.0; + for (const auto& species : netOut.composition.getRegisteredSpecies()) { + if (!seen_species.contains(species)) { + mass_lost[zone_idx] += species.mass() * netOut.composition.getMolarAbundance(species); + } + } + } + return 0; +} + +std::unique_ptr make_gf_context(const GFContextType &type) { + switch (type) { + case GFContextType::POINT: + return std::make_unique(); + case GFContextType::GRID: + return std::make_unique(); + default: + throw gridfire::exceptions::GridFireError("Unhandled GFContextType in make_gf_context"); + } +} diff --git a/src/extern/lib/gridfire_extern.cpp b/src/extern/lib/gridfire_extern.cpp index 54aaef22..4bc4be64 100644 --- a/src/extern/lib/gridfire_extern.cpp +++ b/src/extern/lib/gridfire_extern.cpp @@ -3,120 +3,18 @@ #include "gridfire/extern/gridfire_context.h" #include "gridfire/extern/gridfire_extern.h" -extern "C" { - void* gf_init() { - return new GridFireContext(); - } +namespace { - void gf_free(void* ctx) { - delete static_cast(ctx); - } + template + concept ErrorTrackable = requires(T a) { + { a.last_error } -> std::convertible_to; + }; - int gf_register_species(void* ptr, const int num_species, const char** species_names) { - auto* ctx = static_cast(ptr); + template + int execute_guarded(Context* ctx, Func&& action) { try { - std::vector names; - for(int i=0; iinit_species_map(names); - return FDSSE_SUCCESS; - } catch (const fourdst::composition::exceptions::UnknownSymbolError& e) { - ctx->last_error = e.what(); - return FDSSE_UNKNOWN_SYMBOL_ERROR; - } catch (const fourdst::composition::exceptions::SpeciesError& e) { - ctx->last_error = e.what(); - return FDSSE_SPECIES_ERROR; - } catch (const std::exception& e) { - ctx->last_error = e.what(); - return FDSSE_NON_4DSTAR_ERROR; - } catch (...) { - ctx->last_error = "Unknown error occurred during species registration."; - return FDSSE_UNKNOWN_ERROR; - } - } + const int result = action(); - int gf_construct_engine_from_policy( - void* ptr, - const char* policy_name, - const double *abundances, - const size_t num_species - ) { - auto* ctx = static_cast(ptr); - try { - ctx->init_engine_from_policy(std::string(policy_name), abundances, num_species); - return GF_SUCCESS; - } catch (const gridfire::exceptions::MissingBaseReactionError& e) { - ctx->last_error = e.what(); - return GF_MISSING_BASE_REACTION_ERROR; - } catch (const gridfire::exceptions::MissingSeedSpeciesError& e) { - ctx->last_error = e.what(); - return GF_MISSING_SEED_SPECIES_ERROR; - } catch (const gridfire::exceptions::MissingKeyReactionError& e) { - ctx->last_error = e.what(); - return GF_MISSING_KEY_REACTION_ERROR; - } catch (const gridfire::exceptions::PolicyError& e) { - ctx->last_error = e.what(); - return GF_POLICY_ERROR; - } catch (std::exception& e) { - ctx->last_error = e.what(); - return GF_NON_GRIDFIRE_ERROR; - } catch (...) { - ctx->last_error = "Unknown error occurred during engine construction."; - return GF_UNKNOWN_ERROR; - } - } - - int gf_construct_solver_from_engine( - void* ptr, - const char* solver_name - ) { - auto* ctx = static_cast(ptr); - try { - ctx->init_solver_from_engine(std::string(solver_name)); - return GF_SUCCESS; - } catch (std::exception& e) { - ctx->last_error = e.what(); - return GF_NON_GRIDFIRE_ERROR; - } catch (...) { - ctx->last_error = "Unknown error occurred during solver construction."; - return GF_UNKNOWN_ERROR; - } - } - - int gf_evolve( - void* ptr, - const double* Y_in, - const size_t num_species, - const double T, - const double rho, - const double tMax, - const double dt0, - double* Y_out, - double* energy_out, - double* dEps_dT, - double* dEps_dRho, - double* specific_neutrino_energy_loss, - double* specific_neutrino_flux, - double* mass_lost - ) { - auto* ctx = static_cast(ptr); - try { - const int result = ctx->evolve( - Y_in, - num_species, - T, - rho, - tMax, - dt0, - Y_out, - *energy_out, - *dEps_dT, - *dEps_dRho, - *specific_neutrino_energy_loss, - *specific_neutrino_flux, - *mass_lost - ); if (result != 0) { return result; } @@ -211,8 +109,230 @@ extern "C" { } } +} + +extern "C" { + + + void* gf_init(const enum GF_TYPE type) { + if (type == MULTI_ZONE) { + return new GFGridContext(); + } + if (type == SINGLE_ZONE) { + return new GFPointContext(); + } + return nullptr; + } + + int gf_free(const enum GF_TYPE type, void *ctx) { + if (!ctx) { + return GF_UNINITIALIZED_INPUT_MEMORY_ERROR; + } + if (type == MULTI_ZONE) { + delete static_cast(ctx); + return GF_SUCCESS; + } + if (type == SINGLE_ZONE) { + delete static_cast(ctx); + return GF_SUCCESS; + } + return GF_UNKNOWN_FREE_TYPE; + } + + int gf_set_num_zones(const enum GF_TYPE type, void* ptr, const size_t num_zones) { + if (type != MULTI_ZONE) { + return GF_INVALID_TYPE; + } + + if (!ptr) { + return GF_UNINITIALIZED_INPUT_MEMORY_ERROR; + } + + auto* ctx = static_cast(ptr); + return execute_guarded(ctx, [&]() { + ctx->set_zones(num_zones); + return GF_SUCCESS; + }); + } + + int gf_register_species(void* ptr, const int num_species, const char** species_names) { + if (num_species < 0) return GF_INVALID_NUM_SPECIES; + + if (num_species == 0) return GF_SUCCESS; + + if (!ptr || !species_names) { + return GF_UNINITIALIZED_INPUT_MEMORY_ERROR; + } + + for (int i=0; i < num_species; ++i) { + if (!species_names[i]) { + return GF_UNINITIALIZED_INPUT_MEMORY_ERROR; + } + } + + auto* ctx = static_cast(ptr); + return execute_guarded(ctx, [&]() { + std::vector names; + for (int i=0; iinit_species_map(names); + return FDSSE_SUCCESS; + }); + } + + int gf_construct_engine_from_policy( + void* ptr, + const char* policy_name, + const double *abundances, + const size_t num_species + ) { + auto* ctx = static_cast(ptr); + return execute_guarded(ctx, [&]() { + ctx->init_engine_from_policy(std::string(policy_name), abundances, num_species); + return GF_SUCCESS; + }); + } + + int gf_construct_solver_from_engine( + void* ptr + ) { + auto* ctx = static_cast(ptr); + return execute_guarded(ctx, [&]() { + ctx->init_solver_from_engine(); + return GF_SUCCESS; + }); + } + + int gf_evolve( + const enum GF_TYPE type, + void* ptr, + const void* Y_in, + const size_t num_species, + const void* T, + const void* rho, + const double tMax, + const double dt0, + void* Y_out, + void* energy_out, + void* dEps_dT, + void* dEps_dRho, + void* specific_neutrino_energy_loss, + void* specific_neutrino_flux, + void* mass_lost + ) { + + printf("In C Starting gf_evolve with type %d\n", type); + printf("In C num_species: %zu, tMax: %e, dt0: %e\n", num_species, tMax, dt0); + printf("In C Y_in ptr: %p, T ptr: %p, rho ptr: %p\n", Y_in, T, rho); + // values + printf("In C Y_in first 5 values: "); + const auto* Y_in_ptr = static_cast(Y_in); + for (size_t i = 0; i < std::min(num_species, size_t(5)); ++i) { + printf("%e ", Y_in_ptr[i]); + } + printf("\n"); + printf("In C T value: %e\n", *(static_cast(T))); + printf("In C rho value: %e\n", *(static_cast(rho))); + printf("In C tMax value: %e\n", tMax); + printf("In C dt0 value: %e\n", dt0); + + if (!ptr || !Y_in || !T || !rho) { + return GF_UNINITIALIZED_INPUT_MEMORY_ERROR; + } + + if (!Y_out || !energy_out || !dEps_dT || !dEps_dRho || !specific_neutrino_energy_loss || !specific_neutrino_flux || !mass_lost) { + return GF_UNINITIALIZED_OUTPUT_MEMORY_ERROR; + } + + if (tMax <= 0 || dt0 <= 0) { + return GF_INVALID_TIMESTEPS; + } + + if (num_species <= 0) { + return GF_INVALID_NUM_SPECIES; + } + + switch (type) { + case SINGLE_ZONE : { + auto* ctx = static_cast(ptr); + const auto T_ptr = static_cast(T); + const auto *rho_ptr = static_cast(rho); + + auto* Y_out_local = static_cast(Y_out); + auto* energy_out_local = static_cast(energy_out); + auto* dEps_dT_local = static_cast(dEps_dT); + auto* dEps_dRho_local = static_cast(dEps_dRho); + auto* specific_neutrino_energy_loss_local = static_cast(specific_neutrino_energy_loss); + auto* specific_neutrino_flux_local = static_cast(specific_neutrino_flux); + auto* mass_lost_local = static_cast(mass_lost); + + printf("Evolving single zone with T = %e, rho = %e for tMax = %e and dt0 = %e\n", *T_ptr, *rho_ptr, tMax, dt0); + + return execute_guarded(ctx, [&]() { + return ctx->evolve( + static_cast(Y_in), + num_species, + *T_ptr, + *rho_ptr, + tMax, + dt0, + Y_out_local, + *energy_out_local, + *dEps_dT_local, + *dEps_dRho_local, + *specific_neutrino_energy_loss_local, + *specific_neutrino_flux_local, + *mass_lost_local + ); + }); + } + case MULTI_ZONE : { + auto* ctx = static_cast(ptr); + const auto *T_ptr = static_cast(T); + const auto *rho_ptr = static_cast(rho); + + auto* Y_out_local = static_cast(Y_out); + auto* energy_out_local = static_cast(energy_out); + auto* dEps_dT_local = static_cast(dEps_dT); + auto* dEps_dRho_local = static_cast(dEps_dRho); + auto* specific_neutrino_energy_loss_local = static_cast(specific_neutrino_energy_loss); + auto* specific_neutrino_flux_local = static_cast(specific_neutrino_flux); + auto* mass_lost_local = static_cast(mass_lost); + + printf("Evolving multi zone for tMax = %e and dt0 = %e\n", tMax, dt0); + + return execute_guarded(ctx, [&]() { + return ctx->evolve( + static_cast(Y_in), + num_species, + T_ptr, // T pointer + rho_ptr, // rho pointer + tMax, + dt0, + Y_out_local, + energy_out_local, + dEps_dT_local, + dEps_dRho_local, + specific_neutrino_energy_loss_local, + specific_neutrino_flux_local, + mass_lost_local + ); + }); + } + default : + return GF_UNKNOWN_ERROR; + } + + + + } + char* gf_get_last_error_message(void* ptr) { - const auto* ctx = static_cast(ptr); + if (!ptr) { + return const_cast("GF_UNINITIALIZED_INPUT_MEMORY_ERROR"); + } + const auto* ctx = static_cast(ptr); return const_cast(ctx->last_error.c_str()); } @@ -278,6 +398,18 @@ extern "C" { return const_cast("GF_DEBUG_ERROR"); case GF_GRIDFIRE_ERROR: return const_cast("GF_GRIDFIRE_ERROR"); + case GF_UNINITIALIZED_INPUT_MEMORY_ERROR: + return const_cast("GF_UNINITIALIZED_INPUT_MEMORY_ERROR"); + case GF_UNINITIALIZED_OUTPUT_MEMORY_ERROR: + return const_cast("GF_UNINITIALIZED_OUTPUT_MEMORY_ERROR"); + case GF_INVALID_NUM_SPECIES: + return const_cast("GF_INVALID_NUM_SPECIES"); + case GF_INVALID_TIMESTEPS: + return const_cast("GF_INVALID_TIMESTEPS"); + case GF_UNKNOWN_FREE_TYPE: + return const_cast("GF_UNKNOWN_FREE_TYPE"); + case GF_INVALID_TYPE: + return const_cast("GF_INVALID_TYPE"); case FDSSE_NON_4DSTAR_ERROR: return const_cast("FDSSE_NON_4DSTAR_ERROR"); case FDSSE_UNKNOWN_ERROR: diff --git a/src/include/gridfire/config/config.h b/src/include/gridfire/config/config.h index 9c807503..13380ba5 100644 --- a/src/include/gridfire/config/config.h +++ b/src/include/gridfire/config/config.h @@ -31,5 +31,4 @@ namespace gridfire::config { }; - } \ No newline at end of file diff --git a/src/include/gridfire/engine/diagnostics/dynamic_engine_diagnostics.h b/src/include/gridfire/engine/diagnostics/dynamic_engine_diagnostics.h index bd89686f..d80d5907 100644 --- a/src/include/gridfire/engine/diagnostics/dynamic_engine_diagnostics.h +++ b/src/include/gridfire/engine/diagnostics/dynamic_engine_diagnostics.h @@ -29,6 +29,7 @@ #pragma once #include "gridfire/engine/engine_abstract.h" +#include "gridfire/engine/scratchpads/blob.h" #include #include @@ -49,6 +50,7 @@ namespace gridfire::engine::diagnostics { * @return std::optional JSON object containing the limiting species report if `json` is true; otherwise, std::nullopt. */ std::optional report_limiting_species( + scratch::StateBlob& ctx, const DynamicEngine &engine, const std::vector &Y_full, const std::vector &E_full, @@ -71,6 +73,7 @@ namespace gridfire::engine::diagnostics { * @return std::optional JSON object containing the species balance report if `json` is true; otherwise, std::nullopt. */ std::optional inspect_species_balance( + scratch::StateBlob& ctx, const DynamicEngine& engine, const std::string& species_name, const fourdst::composition::Composition &comp, @@ -89,6 +92,7 @@ namespace gridfire::engine::diagnostics { * @return std::optional JSON object containing the Jacobian stiffness report if `json` is true; otherwise, std::nullopt. */ std::optional inspect_jacobian_stiffness( + scratch::StateBlob& ctx, const DynamicEngine &engine, const fourdst::composition::Composition &comp, double T9, diff --git a/src/include/gridfire/engine/engine.h b/src/include/gridfire/engine/engine.h index 3be40c1c..b5776269 100644 --- a/src/include/gridfire/engine/engine.h +++ b/src/include/gridfire/engine/engine.h @@ -180,4 +180,6 @@ #include "gridfire/engine/views/engine_views.h" #include "gridfire/engine/procedures/engine_procedures.h" #include "gridfire/engine/types/engine_types.h" -#include "gridfire/engine/diagnostics/dynamic_engine_diagnostics.h" \ No newline at end of file +#include "gridfire/engine/diagnostics/dynamic_engine_diagnostics.h" + +#include "gridfire/engine/scratchpads/scratchpads.h" \ No newline at end of file diff --git a/src/include/gridfire/engine/engine_abstract.h b/src/include/gridfire/engine/engine_abstract.h index e372afd9..e12f75a0 100644 --- a/src/include/gridfire/engine/engine_abstract.h +++ b/src/include/gridfire/engine/engine_abstract.h @@ -6,9 +6,10 @@ #include "gridfire/screening/screening_types.h" #include "gridfire/engine/types/reporting.h" -#include "gridfire/engine/types/building.h" #include "gridfire/engine/types/jacobian.h" +#include "gridfire/engine/scratchpads/blob.h" + #include "fourdst/composition/composition_abstract.h" #include @@ -136,7 +137,9 @@ namespace gridfire::engine { * @brief Get the list of species in the network. * @return Vector of Species objects representing all network species. */ - [[nodiscard]] virtual const std::vector& getNetworkSpecies() const = 0; + [[nodiscard]] virtual const std::vector& getNetworkSpecies( + scratch::StateBlob& ctx + ) const = 0; /** * @brief Calculate the right-hand side (dY/dt) and energy generation. @@ -144,6 +147,7 @@ namespace gridfire::engine { * @param comp Composition object containing current abundances. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. + * @param trust If true, indicates that the engine should trust the passed composition has already been collected. * @return expected> containing either dY/dt and energy generation rate or a stale engine * error indicating that the engine must be updated * @@ -152,9 +156,11 @@ namespace gridfire::engine { * rate for the current state. */ [[nodiscard]] virtual std::expected, EngineStatus> calculateRHSAndEnergy( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const = 0; }; @@ -185,6 +191,7 @@ namespace gridfire::engine { * for the current state. The matrix can then be accessed via getJacobianMatrixEntry(). */ [[nodiscard]] virtual NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -203,6 +210,7 @@ namespace gridfire::engine { * The matrix can then be accessed via getJacobianMatrixEntry(). */ [[nodiscard]] virtual NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -226,6 +234,7 @@ namespace gridfire::engine { * @see getJacobianMatrixEntry() */ [[nodiscard]] virtual NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -233,28 +242,6 @@ namespace gridfire::engine { ) const = 0; - /** - * @brief Generate the stoichiometry matrix for the network. - * - * This method must compute and store the stoichiometry matrix, - * which encodes the net change of each species in each reaction. - */ - virtual void generateStoichiometryMatrix() = 0; - - /** - * @brief Get an entry from the stoichiometry matrix. - * - * @param species species to look up stoichiometry for. - * @param reaction reaction to find - * @return Stoichiometric coefficient for the species in the reaction. - * - * The stoichiometry matrix must have been generated by generateStoichiometryMatrix(). - */ - [[nodiscard]] virtual int getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const reaction::Reaction& reaction - ) const = 0; - /** * @brief Calculate the molar reaction flow for a given reaction. * @@ -268,6 +255,7 @@ namespace gridfire::engine { * under the current state. */ [[nodiscard]] virtual double calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction& reaction, const fourdst::composition::CompositionAbstract &comp, double T9, @@ -286,6 +274,7 @@ namespace gridfire::engine { * generation rate with respect to temperature and density for the current state. */ [[nodiscard]] virtual EnergyDerivatives calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -296,18 +285,10 @@ namespace gridfire::engine { * * @return Reference to the LogicalReactionSet containing all reactions. */ - [[nodiscard]] virtual const reaction::ReactionSet& getNetworkReactions() const = 0; + [[nodiscard]] virtual const reaction::ReactionSet& getNetworkReactions( + scratch::StateBlob& ctx + ) const = 0; - /** - * @brief Set the reactions for the network. - * - * @param reactions The set of reactions to use in the network. - * - * This method replaces the current set of reactions in the network - * with the provided set. It marks the engine as stale, requiring - * regeneration of matrices and recalculation of rates. - */ - virtual void setNetworkReactions(const reaction::ReactionSet& reactions) = 0; /** * @brief Compute timescales for all species in the network. @@ -321,6 +302,7 @@ namespace gridfire::engine { * which can be used for timestep control, diagnostics, and reaction network culling. */ [[nodiscard]] virtual std::expected, EngineStatus> getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -338,13 +320,14 @@ namespace gridfire::engine { * which can be useful for understanding reaction flows and equilibrium states. */ [[nodiscard]] virtual std::expected, EngineStatus> getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho ) const = 0; /** - * @brief Update the internal state of the engine. + * @brief Update the thread local scratch pad state of a network. * * @param netIn A struct containing the current network input, such as * temperature, density, and composition. @@ -363,47 +346,10 @@ namespace gridfire::engine { * * @post The internal state of the engine is updated to reflect the new conditions. */ - virtual fourdst::composition::Composition update(const NetIn &netIn) = 0; - - /** - * @brief Check if the engine's internal state is stale. - * - * @param netIn A struct containing the current network input, such as - * temperature, density, and composition. - * @return True if the engine's state is stale and needs to be updated; false otherwise. - * - * This method allows derived classes to determine if their internal state - * is out-of-date with respect to the provided network conditions. If the engine - * is stale, it may require a call to `update()` before performing calculations. - * - * @par Usage Example: - * @code - * NetIn input = { ... }; - * if (myEngine.isStale(input)) { - * // Update the engine before proceeding - * } - * @endcode - */ - [[nodiscard]] - virtual bool isStale(const NetIn& netIn) = 0; - - /** - * @brief Set the electron screening model. - * - * @param model The type of screening model to use for reaction rate calculations. - * - * This method allows changing the screening model at runtime. Screening corrections - * account for the electrostatic shielding of nuclei by electrons, which affects - * reaction rates in dense stellar plasmas. - * - * @par Usage Example: - * @code - * myEngine.setScreeningModel(screening::ScreeningType::WEAK); - * @endcode - * - * @post The engine will use the specified screening model for subsequent rate calculations. - */ - virtual void setScreeningModel(screening::ScreeningType model) = 0; + [[nodiscard]] virtual fourdst::composition::Composition project( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const = 0; /** * @brief Get the current electron screening model. @@ -415,7 +361,9 @@ namespace gridfire::engine { * screening::ScreeningType currentModel = myEngine.getScreeningModel(); * @endcode */ - [[nodiscard]] virtual screening::ScreeningType getScreeningModel() const = 0; + [[nodiscard]] virtual screening::ScreeningType getScreeningModel( + scratch::StateBlob& ctx + ) const = 0; /** * @brief Get the index of a species in the network. @@ -426,18 +374,10 @@ namespace gridfire::engine { * engine's internal representation. It is useful for accessing species * data efficiently. */ - [[nodiscard]] virtual size_t getSpeciesIndex(const fourdst::atomic::Species &species) const = 0; - - /** - * @brief Map a NetIn object to a vector of molar abundances. - * - * @param netIn The input conditions for the network. - * @return A vector of molar abundances corresponding to the species in the network. - * - * This method converts the input conditions into a vector of molar abundances, - * which can be used for further calculations or diagnostics. - */ - [[nodiscard]] virtual std::vector mapNetInToMolarAbundanceVector(const NetIn &netIn) const = 0; + [[nodiscard]] virtual size_t getSpeciesIndex( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const = 0; /** * @brief Prime the engine with initial conditions. @@ -450,36 +390,10 @@ namespace gridfire::engine { * rates, initializing internal data structures, and performing any necessary * pre-computation. */ - [[nodiscard]] virtual PrimingReport primeEngine(const NetIn &netIn) = 0; - - /** - * @brief Get the depth of the network. - * - * @return The depth of the network, which may indicate the level of detail or - * complexity in the reaction network. - * - * This method is intended to provide information about the network's structure, - * such as how many layers of reactions or species are present. It can be useful - * for diagnostics and understanding the network's complexity. - */ - [[nodiscard]] virtual BuildDepthType getDepth() const { - throw std::logic_error("Network depth not supported by this engine."); - } - - /** - * @brief Rebuild the network with a specified depth. - * - * @param comp The composition to rebuild the network with. - * @param depth The desired depth of the network. - * - * This method is intended to allow dynamic adjustment of the network's depth, - * which may involve adding or removing species and reactions based on the - * specified depth. However, not all engines support this operation. - */ - virtual void rebuild(const fourdst::composition::CompositionAbstract &comp, BuildDepthType depth) { - throw std::logic_error("Setting network depth not supported by this engine."); - // ReSharper disable once CppDFAUnreachableCode - } + [[nodiscard]] virtual PrimingReport primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const = 0; /** * @brief Recursively collect composition from current engine and any sub engines if they exist. @@ -495,7 +409,8 @@ namespace gridfire::engine { * @return An updated composition which is a superset of comp. This may contain species which were culled, for * example, by either QSE partitioning or reaction flow rate culling */ - virtual fourdst::composition::Composition collectComposition( + [[nodiscard]] virtual fourdst::composition::Composition collectComposition( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -510,7 +425,14 @@ namespace gridfire::engine { * This method allows querying the current status of a specific species * within the engine's network. */ - [[nodiscard]] virtual SpeciesStatus getSpeciesStatus(const fourdst::atomic::Species& species) const = 0; + [[nodiscard]] virtual SpeciesStatus getSpeciesStatus( + scratch::StateBlob& ctx, + const fourdst::atomic::Species& species + ) const = 0; + + [[nodiscard]] virtual std::optional> getMostRecentRHSCalculation( + scratch::StateBlob& ctx + ) const = 0; }; } \ No newline at end of file diff --git a/src/include/gridfire/engine/engine_graph.h b/src/include/gridfire/engine/engine_graph.h index 5698cd47..25c374a1 100644 --- a/src/include/gridfire/engine/engine_graph.h +++ b/src/include/gridfire/engine/engine_graph.h @@ -14,6 +14,10 @@ #include "gridfire/engine/procedures/construction.h" #include "gridfire/config/config.h" +#include "gridfire/engine/scratchpads/blob.h" + +#include "ankerl/unordered_dense.h" + #include #include #include @@ -29,10 +33,6 @@ #include "gridfire/reaction/weak/weak_interpolator.h" #include "gridfire/reaction/weak/weak_rate_library.h" -// PERF: The function getNetReactionStoichiometry returns a map of species to their stoichiometric coefficients for a given reaction. -// this makes extra copies of the species, which is not ideal and could be optimized further. -// Even more relevant is the member m_reactionIDMap which makes copies of a REACLIBReaction for each reaction ID. -// REACLIBReactions are quite large data structures, so this could be a performance bottleneck. namespace gridfire::engine { /** * @brief Alias for CppAD AD type for double precision. @@ -143,6 +143,7 @@ namespace gridfire::engine { * @param comp Composition object containing current abundances. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. + * @param trust * @return StepDerivatives containing dY/dt and energy generation rate. * * This method calculates the time derivatives of all species and the @@ -151,9 +152,11 @@ namespace gridfire::engine { * @see StepDerivatives */ [[nodiscard]] std::expected, engine::EngineStatus> calculateRHSAndEnergy( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const override; /** @@ -173,6 +176,7 @@ namespace gridfire::engine { * @see StepDerivatives */ [[nodiscard]] std::expected, EngineStatus> calculateRHSAndEnergy( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract& comp, double T9, double rho, @@ -194,6 +198,7 @@ namespace gridfire::engine { * @see EnergyDerivatives */ [[nodiscard]] EnergyDerivatives calculateEpsDerivatives( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -218,12 +223,15 @@ namespace gridfire::engine { * @see EnergyDerivatives */ [[nodiscard]] EnergyDerivatives calculateEpsDerivatives( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, const reaction::ReactionSet &activeReactions ) const; + void generate_jacobian_sparsity_pattern(); + /** * @brief Generates the Jacobian matrix for the current state. * @@ -238,6 +246,7 @@ namespace gridfire::engine { * @see getJacobianMatrixEntry() */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -256,6 +265,7 @@ namespace gridfire::engine { * @see generateJacobianMatrix() */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -278,20 +288,13 @@ namespace gridfire::engine { * @see getJacobianMatrixEntry() */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, const SparsityPattern &sparsityPattern ) const override; - /** - * @brief Generates the stoichiometry matrix for the network. - * - * This method computes and stores the stoichiometry matrix, - * which encodes the net change of each species in each reaction. - */ - void generateStoichiometryMatrix() override; - /** * @brief Calculates the molar reaction flow for a given reaction. * @@ -306,6 +309,7 @@ namespace gridfire::engine { * */ [[nodiscard]] double calculateMolarReactionFlow( + scratch::StateBlob&, const reaction::Reaction& reaction, const fourdst::composition::CompositionAbstract &comp, double T9, @@ -316,51 +320,19 @@ namespace gridfire::engine { * @brief Gets the list of species in the network. * @return Vector of Species objects representing all network species. */ - [[nodiscard]] const std::vector& getNetworkSpecies() const override; + [[nodiscard]] const std::vector& getNetworkSpecies( + scratch::StateBlob &ctx + ) const override; /** * @brief Gets the set of logical reactions in the network. * @return Reference to the LogicalReactionSet containing all reactions. */ - [[nodiscard]] const reaction::ReactionSet& getNetworkReactions() const override; - - /** - * @brief Sets the reactions for the network. - * - * @param reactions The set of reactions to use in the network. - * - * This method replaces the current set of reactions in the network - * with the provided set. It marks the engine as stale, requiring - * regeneration of matrices and recalculation of rates. - */ - void setNetworkReactions(const reaction::ReactionSet& reactions) override; - - /** - * @brief Gets the net stoichiometry for a given reaction. - * - * @param reaction The reaction for which to get the stoichiometry. - * @return Map of species to their stoichiometric coefficients. - */ - [[nodiscard]] static std::unordered_map getNetReactionStoichiometry( - const reaction::Reaction& reaction - ); - - /** - * @brief Gets an entry from the stoichiometry matrix. - * - * @param species Species to look up stoichiometry for. - * @param reaction Reaction to find. - * @return Stoichiometric coefficient for the species in the reaction. - * - * The stoichiometry matrix must have been generated by `generateStoichiometryMatrix()`. - * - * @see generateStoichiometryMatrix() - */ - [[nodiscard]] int getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const reaction::Reaction& reaction + [[nodiscard]] const reaction::ReactionSet& getNetworkReactions( + scratch::StateBlob& ) const override; + /** * @brief Computes timescales for all species in the network. * @@ -372,8 +344,8 @@ namespace gridfire::engine { * This method estimates the timescale for abundance change of each species, * which can be used for timestep control or diagnostics. */ - [[nodiscard]] std::expected, engine::EngineStatus> - getSpeciesTimescales( + [[nodiscard]] std::expected, EngineStatus> getSpeciesTimescales( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -393,6 +365,7 @@ namespace gridfire::engine { * calculations with different reaction sets without modifying the engine's internal state. */ [[nodiscard]] std::expected, EngineStatus> getSpeciesTimescales( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -411,8 +384,8 @@ namespace gridfire::engine { * This method estimates the destruction timescale for each species, * which can be useful for understanding reaction flows and equilibrium states. */ - [[nodiscard]] std::expected, engine::EngineStatus> - getSpeciesDestructionTimescales( + [[nodiscard]] std::expected, EngineStatus> getSpeciesDestructionTimescales( + scratch::StateBlob&, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -432,6 +405,7 @@ namespace gridfire::engine { * calculations with different reaction sets without modifying the engine's internal state. */ [[nodiscard]] std::expected, EngineStatus> getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -448,24 +422,10 @@ namespace gridfire::engine { * * @return The updated composition that includes all species in the network. */ - fourdst::composition::Composition update( + fourdst::composition::Composition project( + scratch::StateBlob& ctx, const NetIn &netIn - ) override; - - - /** - * @brief Checks if the engine view is stale and needs to be updated. - * - * @param netIn The current network input (unused). - * @return True if the view is stale, false otherwise. - * - * @deprecated This method is deprecated and will be removed in future versions. - * Stale states are returned as part of the results of methods that - * require the ability to report them. - */ - [[deprecated]] bool isStale( - const NetIn &netIn - ) override; + ) const override; /** * @brief Checks if a given species is involved in the network. @@ -474,6 +434,7 @@ namespace gridfire::engine { * @return True if the species is involved in the network, false otherwise. */ [[nodiscard]] bool involvesSpecies( + scratch::StateBlob& ctx, const fourdst::atomic::Species& species ) const; @@ -494,6 +455,7 @@ namespace gridfire::engine { * @endcode */ void exportToDot( + scratch::StateBlob& ctx, const std::string& filename ) const; @@ -514,21 +476,10 @@ namespace gridfire::engine { * @endcode */ void exportToCSV( + scratch::StateBlob& ctx, const std::string& filename ) const; - /** - * @brief Sets the electron screening model for reaction rate calculations. - * - * @param model The type of screening model to use. - * - * This method allows changing the screening model at runtime. Screening corrections - * account for the electrostatic shielding of nuclei by electrons, which affects - * reaction rates in dense stellar plasmas. - */ - void setScreeningModel( - screening::ScreeningType model - ) override; /** * @brief Gets the current electron screening model. @@ -540,23 +491,9 @@ namespace gridfire::engine { * screening::ScreeningType currentModel = engine.getScreeningModel(); * @endcode */ - [[nodiscard]] screening::ScreeningType getScreeningModel() const override; - - /** - * @brief Sets whether to precompute reaction rates. - * - * @param precompute True to enable precomputation, false to disable. - * - * This method allows enabling or disabling precomputation of reaction rates - * for performance optimization. When enabled, reaction rates are computed - * once and stored for later use. - * - * @post If precomputation is enabled, reaction rates will be precomputed and cached. - * If disabled, reaction rates will be computed on-the-fly as needed. - */ - void setPrecomputation( - bool precompute - ); + [[nodiscard]] screening::ScreeningType getScreeningModel( + scratch::StateBlob& ctx + ) const override; /** * @brief Checks if precomputation of reaction rates is enabled. @@ -566,7 +503,9 @@ namespace gridfire::engine { * This method allows checking the current state of precomputation for * reaction rates in the engine. */ - [[nodiscard]] bool isPrecomputationEnabled() const; + [[nodiscard]] bool isPrecomputationEnabled( + scratch::StateBlob& ctx + ) const; /** * @brief Gets the partition function used for reaction rate calculations. @@ -576,7 +515,9 @@ namespace gridfire::engine { * This method provides access to the partition function used in the engine, * which is essential for calculating thermodynamic properties and reaction rates. */ - [[nodiscard]] const partition::PartitionFunction& getPartitionFunction() const; + [[nodiscard]] const partition::PartitionFunction& getPartitionFunction( + scratch::StateBlob& ctx + ) const; /** * @brief Calculates the reverse rate for a given reaction. @@ -644,23 +585,10 @@ namespace gridfire::engine { * This method allows checking whether the engine is configured to use * reverse reactions in its calculations. */ - [[nodiscard]] bool isUsingReverseReactions() const; + [[nodiscard]] bool isUsingReverseReactions( + scratch::StateBlob& ctx + ) const; - /** - * @brief Sets whether to use reverse reactions in the engine. - * - * @param useReverse True to enable reverse reactions, false to disable. - * - * This method allows enabling or disabling reverse reactions in the engine. - * If disabled, only forward reactions will be considered in calculations. - * - * @post If reverse reactions are enabled, the engine will consider both - * forward and reverse reactions in its calculations. If disabled, - * only forward reactions will be considered. - */ - void setUseReverseReactions( - bool useReverse - ); /** * @brief Gets the index of a species in the network. @@ -672,22 +600,10 @@ namespace gridfire::engine { * species vector. If the species is not found, it returns -1. */ [[nodiscard]] size_t getSpeciesIndex( + scratch::StateBlob& ctx, const fourdst::atomic::Species &species ) const override; - /** - * @brief Maps the NetIn object to a vector of molar abundances. - * - * @param netIn The NetIn object containing the input conditions. - * @return Vector of molar abundances corresponding to the species in the network. - * - * This method converts the NetIn object into a vector of molar abundances - * for each species in the network, which can be used for further calculations. - */ - [[deprecated]] [[nodiscard]] std::vector mapNetInToMolarAbundanceVector( - const NetIn &netIn - ) const override; - /** * @brief Prepares the engine for calculations with initial conditions. * @@ -698,32 +614,10 @@ namespace gridfire::engine { * setting up reactions, species, and precomputing necessary data. */ [[nodiscard]] PrimingReport primeEngine( + scratch::StateBlob& ctx, const NetIn &netIn - ) override; + ) const override; - /** - * @brief Gets the depth of the network. - * - * @return The build depth of the network. - * - * This method returns the current build depth of the reaction network, - * which indicates how many levels of reactions are included in the network. - */ - [[nodiscard]] BuildDepthType getDepth() const override; - - /** - * @brief Rebuilds the reaction network based on a new composition. - * - * @param comp The new composition to use for rebuilding the network. - * @param depth The build depth to use for the network. - * - * This method rebuilds the reaction network using the provided composition - * and build depth. It updates all internal data structures accordingly. - */ - void rebuild( - const fourdst::composition::CompositionAbstract &comp, - BuildDepthType depth - ) override; /** * @brief This will return the input comp with the molar abundances of any species not registered in that but @@ -740,7 +634,12 @@ namespace gridfire::engine { * have a molar abundance set to 0. * @throws BadCollectionError If the input composition contains species not present in the network species set */ - fourdst::composition::Composition collectComposition(const fourdst::composition::CompositionAbstract &comp, double T9, double rho) const override; + fourdst::composition::Composition collectComposition( + scratch::StateBlob&, + const fourdst::composition::CompositionAbstract &comp, + double T9, + double rho + ) const override; /** * @brief Gets the status of a species in the network. @@ -752,7 +651,10 @@ namespace gridfire::engine { * returns its status (e.g., Active, Inactive, NotFound). */ [[nodiscard]] - SpeciesStatus getSpeciesStatus(const fourdst::atomic::Species &species) const override; + SpeciesStatus getSpeciesStatus( + scratch::StateBlob&, + const fourdst::atomic::Species &species + ) const override; [[nodiscard]] bool get_store_intermediate_reaction_contributions() const { return m_store_intermediate_reaction_contributions; @@ -762,6 +664,12 @@ namespace gridfire::engine { m_store_intermediate_reaction_contributions = value; } + [[nodiscard]] std::optional> getMostRecentRHSCalculation( + scratch::StateBlob& + ) const override; + + [[nodiscard]] const CppAD::ADFun& getAuthoritativeADFun() const { return m_authoritativeADFun; } + private: struct PrecomputedReaction { @@ -781,6 +689,7 @@ namespace gridfire::engine { double reverse_symmetry_factor{}; ///< Symmetry factor for reverse reactions. }; + struct constants { const double u = Constants::getInstance().get("u").value; ///< Atomic mass unit in g. const double Na = Constants::getInstance().get("N_a").value; ///< Avogadro's number. @@ -877,13 +786,7 @@ namespace gridfire::engine { std::unordered_map m_speciesToIndexMap; ///< Map from species to their index in the stoichiometry matrix. std::unordered_map m_indexToSpeciesMap; ///< Map from index to species in the stoichiometry matrix. - - mutable CppAD::ADFun m_rhsADFun; ///< CppAD function for the right-hand side of the ODE. - mutable CppAD::ADFun m_epsADFun; ///< CppAD function for the energy generation rate. - mutable CppAD::sparse_jac_work m_jac_work; ///< Work object for sparse Jacobian calculations. - mutable std::vector m_local_abundance_cache; - - bool m_has_been_primed = false; ///< Flag indicating if the engine has been primed. + std::unique_ptr m_partitionFunction; ///< Partition function for the network. CppAD::sparse_rc> m_full_jacobian_sparsity_pattern; ///< Full sparsity pattern for the Jacobian matrix. std::set> m_full_sparsity_set; ///< For quick lookups of the base sparsity pattern @@ -894,14 +797,15 @@ namespace gridfire::engine { std::unique_ptr m_screeningModel = screening::selectScreeningModel(m_screeningType); bool m_usePrecomputation = true; ///< Flag to enable or disable using precomputed reactions for efficiency. Mathematically, this should not change the results. Generally end users should not need to change this. - bool m_useReverseReactions = true; ///< Flag to enable or disable reverse reactions. If false, only forward reactions are considered. + std::vector m_precomputed_reactions; + std::unordered_map m_precomputed_reaction_index_map; + + bool m_useReverseReactions = false; ///< Flag to enable or disable reverse reactions. If false, only forward reactions are considered. bool m_store_intermediate_reaction_contributions = false; ///< Flag to enable or disable storing intermediate reaction contributions for debugging. BuildDepthType m_depth; - std::vector m_precomputedReactions; ///< Precomputed reactions for efficiency. - std::unordered_map m_precomputedReactionIndexMap; ///< Set of hashed precomputed reactions for quick lookup. - std::unique_ptr m_partitionFunction; ///< Partition function for the network. + CppAD::ADFun m_authoritativeADFun; private: /** @@ -947,25 +851,14 @@ namespace gridfire::engine { * * @throws std::runtime_error If there are no species in the network. */ - void recordADTape() const; + void recordADTape(); void collectAtomicReverseRateAtomicBases(); void precomputeNetwork(); - - /** - * @brief Validates mass and charge conservation across all reactions. - * - * @return True if all reactions conserve mass and charge, false otherwise. - * - * This method checks that all reactions in the network conserve mass - * and charge. If any reaction does not conserve mass or charge, an - * error message is logged and false is returned. - */ - [[nodiscard]] bool validateConservation() const; - double compute_reaction_flow( + scratch::StateBlob& ctx, const std::vector &local_abundances, const std::vector &screening_factors, const std::vector &bare_rates, @@ -978,10 +871,12 @@ namespace gridfire::engine { ) const; std::pair compute_neutrino_fluxes( + scratch::StateBlob& ctx, double netFlow, const reaction::Reaction &reaction) const; PrecomputationKernelResults accumulate_flows_serial( + scratch::StateBlob& ctx, const std::vector& local_abundances, const std::vector& screening_factors, const std::vector& bare_rates, @@ -990,19 +885,9 @@ namespace gridfire::engine { const reaction::ReactionSet& activeReactions ) const; -#ifdef GRIDFIRE_USE_OPENMP - PrecomputationKernelResults accumulate_flows_parallel( - const std::vector& local_abundances, - const std::vector& screening_factors, - const std::vector& bare_rates, - const std::vector& bare_reverse_rates, - double rho, - const reaction::ReactionSet& activeReactions - ) const; -#endif - [[nodiscard]] StepDerivatives calculateAllDerivativesUsingPrecomputation( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const std::vector &bare_rates, const std::vector &bare_reverse_rates, @@ -1298,7 +1183,7 @@ namespace gridfire::engine { const T k_reaction = reaction.calculate_rate(T9, rho, Ye, mue, Y, m_indexToSpeciesMap); // --- Cound the number of each reactant species to account for species multiplicity --- - std::unordered_map reactant_counts; + std::unordered_map reactant_counts; reactant_counts.reserve(reaction.reactants().size()); for (const auto& reactant : reaction.reactants()) { reactant_counts[reactant] = reaction.countReactantOccurrences(reactant); diff --git a/src/include/gridfire/engine/procedures/priming.h b/src/include/gridfire/engine/procedures/priming.h index 65988270..2aa42330 100644 --- a/src/include/gridfire/engine/procedures/priming.h +++ b/src/include/gridfire/engine/procedures/priming.h @@ -6,6 +6,8 @@ #include "fourdst/atomic/atomicSpecies.h" +#include "gridfire/engine/scratchpads/blob.h" + namespace gridfire::engine { @@ -18,6 +20,7 @@ namespace gridfire::engine { * * Refer to priming.cpp for implementation details on logging, algorithmic steps, and error handling. * + * @param ctx * @param netIn Input network data containing initial composition, temperature, and density. * @param engine DynamicEngine used to build and evaluate the reaction network. * @param ignoredReactionTypes Types of reactions to ignore during priming (e.g., weak reactions). @@ -27,8 +30,8 @@ namespace gridfire::engine { * @return PrimingReport encapsulating the results of the priming operation. */ PrimingReport primeNetwork( + scratch::StateBlob &ctx, const NetIn& netIn, - GraphEngine& engine, - const std::optional>& ignoredReactionTypes + const GraphEngine& engine, const std::optional>& ignoredReactionTypes ); } \ No newline at end of file diff --git a/src/include/gridfire/engine/scratchpads/blob.h b/src/include/gridfire/engine/scratchpads/blob.h new file mode 100644 index 00000000..03cc8e37 --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/blob.h @@ -0,0 +1,499 @@ +/** + * @file blob.h + * @brief Container class for managing multiple scratchpad instances. + * + * This header defines the StateBlob class, which serves as a centralized + * registry for managing multiple scratchpad instances used by computational + * engines. It provides type-safe enrollment, retrieval, and cloning of + * scratchpads using compile-time type checking via C++20 concepts. + * + * @par Purpose + * The StateBlob provides: + * - A fixed-size array of scratchpad slots indexed by ScratchPadType + * - Type-safe enrollment ensuring one instance per scratchpad type + * - Compile-time verified retrieval with optional initialization checks + * - Deep cloning of all enrolled scratchpads for parallel execution + * - Status tracking for each scratchpad slot + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/blob.h" + * #include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" + * + * using namespace gridfire::engine::scratch; + * + * // Create a StateBlob and enroll scratchpads + * StateBlob blob; + * blob.enroll(); + * + * // Retrieve a scratchpad (returns std::expected) + * auto result = blob.get(); + * if (result.has_value()) { + * GraphEngineScratchPad* scratch = result.value(); + * scratch->initialize(engine); + * } + * + * // Retrieve with initialization check + * auto checked = blob.get(); + * if (!checked.has_value()) { + * if (checked.error() == StateBlob::Error::SCRATCHPAD_NOT_INITIALIZED) { + * // Handle uninitialized scratchpad + * } + * } + * + * // Clone for parallel execution + * auto worker_blob = blob.clone_structure(); + * @endcode + * + * @par Thread Safety + * The StateBlob class is **not thread-safe**. Each thread should have its own + * StateBlob instance. Use clone_structure() to create independent copies for + * parallel workers. The cloned blob contains deep copies of all enrolled + * scratchpads. + * + * @see AbstractScratchPad + * @see ScratchPadType + */ + +#pragma once + +#include "gridfire/engine/scratchpads/scratchpad_abstract.h" +#include "gridfire/engine/scratchpads/types.h" +#include "gridfire/exceptions/error_scratchpad.h" + +#include +#include +#include +#include + +namespace gridfire::engine::scratch { + +/** + * @brief Concept that constrains types to valid scratchpad implementations. + * + * A type satisfies IsScratchPad if: + * - It derives from AbstractScratchPad + * - It has a static ID member convertible to ScratchPadType + * + * @tparam T The type to check against the concept. + * + * @par Examples + * @code{.cpp} + * // This will compile only if MyScratchPad satisfies IsScratchPad + * template + * void process_scratchpad(T& scratch) { + * // Use scratch... + * } + * @endcode + */ +template +concept IsScratchPad = std::is_base_of_v + && requires { { T::ID } -> std::convertible_to; }; + + +/** + * @brief Container for managing a collection of typed scratchpad instances. + * + * StateBlob provides a centralized registry for scratchpads used by engines. + * It uses a fixed-size array indexed by ScratchPadType for O(1) access, with + * compile-time type safety enforced through the IsScratchPad concept. + * + * The blob supports: + * - Enrolling new scratchpad types (one instance per type) + * - Type-safe retrieval with optional initialization validation + * - Runtime retrieval by ScratchPadType enum value + * - Deep cloning for parallel execution contexts + * - Status queries for monitoring scratchpad states + * + * @par Thread Safety + * This class is **not thread-safe**. Each thread should have its own StateBlob + * instance. Use clone_structure() to create independent copies for parallel + * workers. Concurrent access to the same StateBlob instance requires external + * synchronization. + */ +class StateBlob { +public: + /** + * @brief Error codes for scratchpad operations. + */ + enum class Error : uint8_t { + SCRATCHPAD_NOT_FOUND, ///< Requested scratchpad type is not enrolled. + SCRATCHPAD_BAD_CAST, ///< Dynamic cast to requested type failed. + SCRATCHPAD_NOT_INITIALIZED, ///< Scratchpad exists but is not initialized. + SCRATCHPAD_TYPE_COLLISION, ///< Attempted to enroll duplicate type. + SCRATCHPAD_OUT_OF_BOUNDS, ///< ScratchPadType index exceeds array bounds. + SCRATCHPAD_UNKNOWN_ERROR ///< Unspecified error condition. + }; + + /** + * @brief Convert an Error enum value to a human-readable string. + * + * @param error The error code to convert. + * @return A string representation of the error. + * + * @par Examples + * @code{.cpp} + * auto result = blob.get(); + * if (!result.has_value()) { + * std::cerr << "Error: " << StateBlob::error_to_string(result.error()); + * } + * @endcode + */ + static std::string error_to_string(const Error error) { + switch (error) { + case Error::SCRATCHPAD_NOT_FOUND: + return "SCRATCHPAD_NOT_FOUND"; + case Error::SCRATCHPAD_BAD_CAST: + return "SCRATCHPAD_BAD_CAST"; + case Error::SCRATCHPAD_NOT_INITIALIZED: + return "SCRATCHPAD_NOT_INITIALIZED"; + case Error::SCRATCHPAD_TYPE_COLLISION: + return "SCRATCHPAD_TYPE_COLLISION"; + case Error::SCRATCHPAD_OUT_OF_BOUNDS: + return "SCRATCHPAD_OUT_OF_BOUNDS"; + default: + return "SCRATCHPAD_UNKNOWN_ERROR"; + } + } + + /** + * @brief Status codes for scratchpad slots. + */ + enum class ScratchPadStatus : uint8_t { + NOT_ENROLLED, ///< No scratchpad has been enrolled for this slot. + ENROLLED_NOT_INITIALIZED,///< Scratchpad enrolled but not yet initialized. + ENROLLED_INITIALIZED ///< Scratchpad enrolled and fully initialized. + }; + +public: + /// @brief Default constructor. + StateBlob() = default; + + /// @brief Default destructor. + ~StateBlob() = default; + + /** + * @brief Enroll a new scratchpad type into the blob. + * + * Creates a new instance of the specified scratchpad type and registers it + * in the appropriate slot. Only one instance per type is allowed. + * + * @tparam CTX The scratchpad type to enroll (must satisfy IsScratchPad). + * + * @throws exceptions::ScratchPadError if a scratchpad of this type is already enrolled. + * + * @par Examples + * @code{.cpp} + * StateBlob blob; + * blob.enroll(); + * blob.enroll(); + * + * // This would throw - duplicate enrollment + * // blob.enroll(); + * @endcode + */ + template + void enroll() { + constexpr auto index = static_cast(CTX::ID); + static_assert(index < MAX_SCRATCHPADS, "ScratchPadType ID exceeds (maximum) allowed scratchpads."); + if (scratchpad_enrolled_flags[index]) { + throw exceptions::ScratchPadError("ScratchPad of this type has already been enrolled. Only one instance per type is allowed."); + } + scratchpads[index] = std::make_unique(); + scratchpad_enrolled_flags[index] = true; + } + + /** + * @brief Retrieve a scratchpad by type. + * + * Returns a pointer to the enrolled scratchpad of the specified type. + * In debug builds, performs a dynamic_cast for type safety; in release + * builds, uses static_cast for performance. + * + * @tparam CTX The scratchpad type to retrieve (must satisfy IsScratchPad). + * + * @return std::expected containing the scratchpad pointer, or an Error if not found/invalid. + * + * @par Examples + * @code{.cpp} + * auto result = blob.get(); + * if (result.has_value()) { + * GraphEngineScratchPad* scratch = result.value(); + * // Use scratch... + * } else { + * // Handle error + * std::cerr << StateBlob::error_to_string(result.error()); + * } + * @endcode + */ + template + std::expected get() const { + constexpr auto index = static_cast(CTX::ID); + static_assert(index < MAX_SCRATCHPADS, "ScratchPadType ID exceeds maximum allowed scratchpads."); + AbstractScratchPad* scratchpad = scratchpads[index].get(); + if (!scratchpad) { + return std::unexpected(Error::SCRATCHPAD_NOT_FOUND); + } +#if !defined(NDEBUG) + if (auto* cast_ptr = dynamic_cast(scratchpad)) { + return cast_ptr; + } else { + return std::unexpected(Error::SCRATCHPAD_BAD_CAST); + } +#else + return static_cast(scratchpad); +#endif + } + + /** + * @brief Retrieve a scratchpad by type with optional initialization check. + * + * Returns a pointer to the enrolled scratchpad of the specified type. + * When MUST_BE_INITIALIZED is true, also verifies that the scratchpad + * has been initialized before returning it. + * + * @tparam CTX The scratchpad type to retrieve (must satisfy IsScratchPad). + * @tparam MUST_BE_INITIALIZED If true, returns an error for uninitialized scratchpads. + * + * @return std::expected containing the scratchpad pointer, or an Error if not found/invalid/uninitialized. + * + * @par Examples + * @code{.cpp} + * // Get only if initialized + * auto result = blob.get(); + * if (!result.has_value()) { + * if (result.error() == StateBlob::Error::SCRATCHPAD_NOT_INITIALIZED) { + * // Need to initialize first + * } + * } + * @endcode + */ + template + std::expected get() const { + constexpr auto index = static_cast(CTX::ID); + static_assert(index < MAX_SCRATCHPADS, "ScratchPadType ID exceeds maximum allowed scratchpads."); + AbstractScratchPad* scratchpad = scratchpads[index].get(); + if (!scratchpad) { + return std::unexpected(Error::SCRATCHPAD_NOT_FOUND); + } +#if !defined(NDEBUG) + if (auto* cast_ptr = dynamic_cast(scratchpad)) { + if constexpr (MUST_BE_INITIALIZED) { + if (!cast_ptr->is_initialized()) { + return std::unexpected(Error::SCRATCHPAD_NOT_INITIALIZED); + } + } + return cast_ptr; + } else { + return std::unexpected(Error::SCRATCHPAD_BAD_CAST); + } +#else + CTX* cast_ptr = static_cast(scratchpad); + if constexpr (MUST_BE_INITIALIZED) { + if (!cast_ptr->is_initialized()) { + return std::unexpected(Error::SCRATCHPAD_NOT_INITIALIZED); + } + } + return cast_ptr; +#endif + } + + /** + * @brief Retrieve a scratchpad by runtime ScratchPadType value. + * + * Returns a pointer to the abstract base class for the scratchpad at + * the specified type index. Useful when the concrete type is not known + * at compile time. + * + * @param type The ScratchPadType enum value identifying the scratchpad. + * + * @return std::expected containing the AbstractScratchPad pointer, or an Error. + * + * @par Examples + * @code{.cpp} + * ScratchPadType type = ScratchPadType::GRAPH_ENGINE_SCRATCHPAD; + * auto result = blob.get(type); + * if (result.has_value()) { + * AbstractScratchPad* scratch = result.value(); + * if (scratch->is_initialized()) { + * // Use scratch... + * } + * } + * @endcode + */ + [[nodiscard]] std::expected get(const ScratchPadType type) const { // NOLINT(*-convert-member-functions-to-static) + const auto index = static_cast(type); + if (index >= MAX_SCRATCHPADS) { + return std::unexpected(Error::SCRATCHPAD_OUT_OF_BOUNDS); + } + AbstractScratchPad* scratchpad = scratchpads[index].get(); + if (!scratchpad) { + return std::unexpected(Error::SCRATCHPAD_NOT_FOUND); + } + return scratchpad; + } + + /** + * @brief Create a deep copy of this blob with all enrolled scratchpads. + * + * Clones the blob structure and all enrolled scratchpads using their + * clone() methods. The resulting blob is independent and can be used + * in a separate thread. + * + * @return A unique pointer to the cloned StateBlob. + * + * @par Examples + * @code{.cpp} + * StateBlob blob; + * blob.enroll(); + * + * // Initialize the scratchpad + * auto scratch = blob.get().value(); + * scratch->initialize(engine); + * + * // Clone for parallel workers + * std::vector> worker_blobs; + * for (int i = 0; i < num_threads; ++i) { + * worker_blobs.push_back(blob.clone_structure()); + * } + * @endcode + */ + [[nodiscard]] std::unique_ptr clone_structure() const { // NOLINT(*-convert-member-functions-to-static) + auto new_blob = std::make_unique(); + for (size_t i = 0; i < MAX_SCRATCHPADS; ++i) { + if (scratchpad_enrolled_flags[i]) { + new_blob->scratchpads[i] = scratchpads[i]->clone(); + new_blob->scratchpad_enrolled_flags[i] = true; + } + } + return new_blob; + } + + /** + * @brief Get the set of all registered scratchpad types. + * + * @return An unordered set of ScratchPadType values for all enrolled scratchpads. + * + * @par Examples + * @code{.cpp} + * auto registered = blob.get_registered_scratchpads(); + * for (auto type : registered) { + * std::cout << "Registered: " << static_cast(type) << "\n"; + * } + * @endcode + */ + [[nodiscard]] std::unordered_set get_registered_scratchpads() const { // NOLINT(*-convert-member-functions-to-static) + std::unordered_set sset; + for (size_t i = 0; i < MAX_SCRATCHPADS; ++i) { + if (scratchpad_enrolled_flags[i]) { + sset.insert(static_cast(i)); + } + } + return sset; + } + + /** + * @brief Check if a specific scratchpad type is initialized. + * + * @tparam CTX The scratchpad type to check (must satisfy IsScratchPad). + * + * @return true if the scratchpad is enrolled and initialized. + * + * @throws exceptions::ScratchPadError if the scratchpad type is not enrolled. + * + * @par Examples + * @code{.cpp} + * if (blob.initialized()) { + * // Safe to use the scratchpad + * } + * @endcode + */ + template + [[nodiscard]] bool initialized() const { + constexpr auto index = static_cast(CTX::ID); + static_assert(index < MAX_SCRATCHPADS, "ScratchPadType ID exceeds maximum allowed scratchpads."); + if (!scratchpad_enrolled_flags[index]) { + throw exceptions::ScratchPadError("Cannot check initialization status: ScratchPad of this type is not enrolled."); + } + return scratchpads[index]->is_initialized(); + } + + /** + * @brief Get the status of a specific scratchpad type. + * + * @tparam CTX The scratchpad type to query (must satisfy IsScratchPad). + * + * @return The ScratchPadStatus indicating enrollment and initialization state. + * + * @par Examples + * @code{.cpp} + * auto status = blob.get_status(); + * switch (status) { + * case StateBlob::ScratchPadStatus::NOT_ENROLLED: + * blob.enroll(); + * break; + * case StateBlob::ScratchPadStatus::ENROLLED_NOT_INITIALIZED: + * // Need to initialize + * break; + * case StateBlob::ScratchPadStatus::ENROLLED_INITIALIZED: + * // Ready to use + * break; + * } + * @endcode + */ + template + [[nodiscard]] ScratchPadStatus get_status() const { + constexpr auto index = static_cast(CTX::ID); + static_assert(index < MAX_SCRATCHPADS, "ScratchPadType ID exceeds maximum allowed scratchpads."); + if (!scratchpad_enrolled_flags[index]) { + return ScratchPadStatus::NOT_ENROLLED; + } + if (scratchpads[index]->is_initialized()) { + return ScratchPadStatus::ENROLLED_INITIALIZED; + } else { + return ScratchPadStatus::ENROLLED_NOT_INITIALIZED; + } + } + + /** + * @brief Get a map of all scratchpad types to their current status. + * + * @return An unordered map from ScratchPadType to ScratchPadStatus for all slots. + * + * @par Examples + * @code{.cpp} + * auto status_map = blob.get_status_map(); + * for (const auto& [type, status] : status_map) { + * if (status == StateBlob::ScratchPadStatus::ENROLLED_NOT_INITIALIZED) { + * std::cout << "Scratchpad " << static_cast(type) << " needs initialization\n"; + * } + * } + * @endcode + */ + [[nodiscard]] std::unordered_map get_status_map() const { // NOLINT(*-convert-member-functions-to-static) + std::unordered_map status_map; + for (size_t i = 0; i < MAX_SCRATCHPADS; ++i) { + auto type = static_cast(i); + if (!scratchpad_enrolled_flags[i]) { + status_map[type] = ScratchPadStatus::NOT_ENROLLED; + } else if (scratchpads[i]->is_initialized()) { + status_map[type] = ScratchPadStatus::ENROLLED_INITIALIZED; + } else { + status_map[type] = ScratchPadStatus::ENROLLED_NOT_INITIALIZED; + } + } + return status_map; + } + +private: + /// @brief Maximum number of scratchpad slots, derived from ScratchPadType::_COUNT. + static constexpr size_t MAX_SCRATCHPADS = static_cast(ScratchPadType::_COUNT); + + /// @brief Array of scratchpad instances indexed by ScratchPadType. + std::array, MAX_SCRATCHPADS> scratchpads{}; + + /// @brief Flags indicating which scratchpad slots have been enrolled. + std::array scratchpad_enrolled_flags{false}; +}; + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/scratchpads/engine_adaptive_scratchpad.h b/src/include/gridfire/engine/scratchpads/engine_adaptive_scratchpad.h new file mode 100644 index 00000000..a9a9317b --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/engine_adaptive_scratchpad.h @@ -0,0 +1,135 @@ +/** + * @file engine_adaptive_scratchpad.h + * @brief Scratchpad implementation for the AdaptiveEngineView. + * + * This header defines the AdaptiveEngineViewScratchPad, a concrete implementation + * of AbstractScratchPad designed for use with the AdaptiveEngineView. It provides + * thread-local storage for active species and reactions that are dynamically + * determined during adaptive network computations. + * + * @par Purpose + * The AdaptiveEngineViewScratchPad stores: + * - The set of currently active species in the adaptive network + * - The set of currently active reactions based on network topology + * - Initialization state to track whether the scratchpad is ready for use + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/engine_adaptive_scratchpad.h" + * #include "gridfire/engine/views/engine_adaptive.h" + * + * // Create and initialize the scratchpad from an AdaptiveEngineView + * gridfire::engine::scratch::AdaptiveEngineViewScratchPad scratch; + * AdaptiveEngineView engine = create_adaptive_engine(); + * scratch.initialize(engine); + * + * if (scratch.is_initialized()) { + * // Access active species for computation + * for (const auto& species : scratch.active_species) { + * // Process each active species + * } + * } + * + * // Clone for parallel execution + * auto worker_scratch = scratch.clone(); + * @endcode + * + * @par Thread Safety + * This class is **not thread-safe**. Each thread should have its own instance + * of AdaptiveEngineViewScratchPad. Use clone() to create independent copies + * for parallel workers. + * + * @see AbstractScratchPad + * @see AdaptiveEngineView + */ + +#pragma once + +#include "gridfire/engine/scratchpads/scratchpad_abstract.h" +#include "gridfire/engine/scratchpads/types.h" + +#include "gridfire/engine/views/engine_adaptive.h" + +namespace gridfire::engine::scratch { + +/** + * @brief Scratchpad for storing working memory used by AdaptiveEngineView computations. + * + * AdaptiveEngineViewScratchPad provides temporary storage for the active species + * and reactions determined by the adaptive network algorithm. This allows the + * engine to avoid recalculating network topology on every evaluation. + * + * @par Thread Safety + * This class is **not thread-safe**. Each thread should operate on its own + * independent instance. Use clone() to create copies for parallel execution. + */ +struct AdaptiveEngineViewScratchPad final : AbstractScratchPad { + /// @brief Unique identifier for this scratchpad type. + static constexpr auto ID = ScratchPadType::ADAPTIVE_ENGINE_VIEW_SCRATCHPAD; + + /// @brief Flag indicating whether the scratchpad has been initialized. + bool has_initialized = false; + + /// @brief Vector of species currently active in the adaptive network. + std::vector active_species; + + /// @brief Set of reactions currently active in the adaptive network. + reaction::ReactionSet active_reactions; + + /** + * @brief Check whether the scratchpad has been initialized. + * @return true if initialized, false otherwise. + */ + [[nodiscard]] bool is_initialized() const override { return has_initialized; } + + /** + * @brief Initialize the scratchpad from an AdaptiveEngineView. + * + * Clears any existing state and prepares the scratchpad for use. + * This method is idempotent; calling it multiple times has no effect + * after the first successful initialization. + * + * @param engine The AdaptiveEngineView to initialize from. + * + * @par Examples + * @code{.cpp} + * AdaptiveEngineViewScratchPad scratch; + * AdaptiveEngineView engine = create_engine(); + * scratch.initialize(engine); + * @endcode + */ + void initialize(const AdaptiveEngineView& engine) { + if (has_initialized) return; + active_species.clear(); + active_reactions.clear(); + has_initialized = true; + } + + /** + * @brief Create a deep copy of this scratchpad. + * + * Creates an independent copy of all internal state, including + * active species and reactions. The clone can be modified without + * affecting the original. + * + * @return A unique pointer to the cloned scratchpad. + * + * @par Examples + * @code{.cpp} + * auto original = std::make_unique(); + * original->initialize(engine); + * + * // Create independent copy for a worker thread + * auto worker_copy = original->clone(); + * @endcode + */ + std::unique_ptr clone() const override { + auto ptr = std::make_unique(); + ptr->has_initialized = has_initialized; + ptr->active_species = active_species; + ptr->active_reactions = active_reactions; + return ptr; + } +}; + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/scratchpads/engine_defined_scratchpad.h b/src/include/gridfire/engine/scratchpads/engine_defined_scratchpad.h new file mode 100644 index 00000000..12fb60b4 --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/engine_defined_scratchpad.h @@ -0,0 +1,140 @@ +/** + * @file engine_defined_scratchpad.h + * @brief Scratchpad implementation for the DefinedEngineView. + * + * This header defines the DefinedEngineViewScratchPad, a concrete implementation + * of AbstractScratchPad designed for use with engines that have a statically + * defined reaction network. It provides storage for the active species, reactions, + * and index mappings that enable efficient lookups during computations. + * + * @par Purpose + * The DefinedEngineViewScratchPad stores: + * - The set of active species in the defined network + * - The set of active reactions in the defined network + * - Index mappings for efficient species and reaction lookups + * - A cached vector representation of active species for performance + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/engine_defined_scratchpad.h" + * + * // Create a scratchpad for a defined engine + * gridfire::engine::scratch::DefinedEngineViewScratchPad scratch; + * + * // Populate active species + * scratch.active_species.insert(species1); + * scratch.active_species.insert(species2); + * + * // Set up index mappings for efficient lookups + * scratch.species_index_map = {0, 1, 2, 3}; + * scratch.reaction_index_map = {0, 1}; + * + * if (scratch.is_initialized()) { + * // Use the scratchpad for computations + * for (size_t idx : scratch.species_index_map) { + * // Process species by index + * } + * } + * + * // Clone for parallel execution + * auto worker_scratch = scratch.clone(); + * @endcode + * + * @par Thread Safety + * This class is **not thread-safe**. Each thread should have its own instance + * of DefinedEngineViewScratchPad. Use clone() to create independent copies + * for parallel workers. + * + * @see AbstractScratchPad + * @see DefinedEngineView + */ + +#pragma once + +#include "gridfire/engine/scratchpads/types.h" +#include "gridfire/engine/scratchpads/scratchpad_abstract.h" +#include "gridfire/reaction/reaction.h" + +#include "fourdst/atomic/atomicSpecies.h" +#include +#include +#include + +namespace gridfire::engine::scratch { + +/** + * @brief Scratchpad for storing working memory used by defined reaction network engines. + * + * DefinedEngineViewScratchPad provides storage for species and reaction data + * in engines with statically defined reaction networks. It includes index mappings + * for efficient lookups and an optional cache for the active species vector. + * + * Unlike adaptive scratchpads, the defined scratchpad is considered initialized + * by default (has_initialized = true), as the network structure is known at + * construction time. + * + * @par Thread Safety + * This class is **not thread-safe**. Each thread should operate on its own + * independent instance. Use clone() to create copies for parallel execution. + */ +struct DefinedEngineViewScratchPad final : AbstractScratchPad { + /// @brief Unique identifier for this scratchpad type. + constexpr static auto ID = ScratchPadType::DEFINED_ENGINE_VIEW_SCRATCHPAD; + + /// @brief Flag indicating whether the scratchpad is initialized (default: true). + bool has_initialized = true; + + /// @brief Set of species active in the defined network. + std::set active_species; + + /// @brief Set of reactions active in the defined network. + reaction::ReactionSet active_reactions; + + /// @brief Mapping from local indices to global species indices. + std::vector species_index_map; + + /// @brief Mapping from local indices to global reaction indices. + std::vector reaction_index_map; + + /// @brief Cached vector of active species for performance optimization. + /// @details This optional cache avoids repeated conversion from set to vector. + std::optional> active_species_vector_cache = std::nullopt; + + /** + * @brief Check whether the scratchpad has been initialized. + * @return true if initialized (always true by default for defined networks). + */ + bool is_initialized() const override { return has_initialized; } + + /** + * @brief Create a deep copy of this scratchpad. + * + * Creates an independent copy of all internal state, including + * active species, reactions, index mappings, and the species vector cache. + * The clone can be modified without affecting the original. + * + * @return A unique pointer to the cloned scratchpad. + * + * @par Examples + * @code{.cpp} + * DefinedEngineViewScratchPad scratch; + * scratch.active_species.insert(species); + * scratch.species_index_map = {0, 1, 2}; + * + * // Create independent copy for a worker thread + * auto worker_copy = scratch.clone(); + * @endcode + */ + std::unique_ptr clone() const override { + auto pad = std::make_unique(); + pad->has_initialized = this->has_initialized; + pad->active_species = this->active_species; + pad->active_reactions = this->active_reactions; + pad->species_index_map = this->species_index_map; + pad->reaction_index_map = this->reaction_index_map; + pad->active_species_vector_cache = this->active_species_vector_cache; + return pad; + } +}; + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/scratchpads/engine_graph_scratchpad.h b/src/include/gridfire/engine/scratchpads/engine_graph_scratchpad.h new file mode 100644 index 00000000..b6bce44b --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/engine_graph_scratchpad.h @@ -0,0 +1,205 @@ +/** + * @file engine_graph_scratchpad.h + * @brief Scratchpad implementation for the GraphEngine using CppAD automatic differentiation. + * + * This header defines the GraphEngineScratchPad, a concrete implementation of + * AbstractScratchPad designed for use with the GraphEngine. It provides thread-local + * storage for CppAD automatic differentiation functions, Jacobian computation work + * structures, and cached derivatives used during ODE integration. + * + * @par Purpose + * The GraphEngineScratchPad stores: + * - A local copy of the CppAD ADFun for RHS evaluation + * - Work structures for sparse Jacobian calculations + * - Cached abundance values for efficient reuse + * - Cached step derivatives and Jacobian subsets by timestep + * - The most recent RHS calculation for warm-starting + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" + * #include "gridfire/engine/engine_graph.h" + * + * // Create and initialize the scratchpad from a GraphEngine + * gridfire::engine::scratch::GraphEngineScratchPad scratch; + * GraphEngine engine = create_graph_engine(); + * scratch.initialize(engine); + * + * if (scratch.is_initialized()) { + * // Access the local ADFun for thread-safe evaluation + * auto& adfun = scratch.rhsADFun.value(); + * + * // Use cached Jacobian work for efficient sparse computations + * auto& jac_work = scratch.jac_work; + * } + * + * // Clone for parallel execution + * auto worker_scratch = scratch.clone(); + * @endcode + * + * @par Thread Safety + * This class is **not thread-safe**. Each thread must have its own instance + * of GraphEngineScratchPad because CppAD ADFun objects maintain internal state + * that is modified during evaluation. Use clone() to create independent copies + * for parallel workers, ensuring each thread has its own ADFun instance. + * + * @see AbstractScratchPad + * @see GraphEngine + * @see CppAD::ADFun + */ + +#pragma once +#include + +#include "gridfire/engine/scratchpads/scratchpad_abstract.h" +#include "gridfire/engine/scratchpads/types.h" +#include "gridfire/engine/engine_graph.h" +#include "gridfire/engine/engine_abstract.h" + +#include "cppad/cppad.hpp" + +#include + + +namespace gridfire::engine::scratch { + +/** + * @brief Scratchpad for storing CppAD automatic differentiation state for GraphEngine. + * + * GraphEngineScratchPad provides thread-local storage for all CppAD-related + * objects needed during ODE integration with the GraphEngine. This includes + * the ADFun object for evaluating the right-hand side of the ODE and computing + * Jacobians, as well as various caches to improve performance. + * + * @par Thread Safety + * This class is **not thread-safe**. CppAD ADFun objects maintain internal + * state that is modified during Forward and Reverse mode operations. Each + * thread must have its own scratchpad instance. Use clone() to create + * independent copies for parallel execution. + * + * @note When cloning, if the rhsADFun has not been initialized, the clone + * will also be uninitialized and has_initialized will be false. + */ +struct GraphEngineScratchPad final : AbstractScratchPad { + /** + * @brief Result codes for ADFun registration operations. + */ + enum class ADFunRegistrationResult : uint8_t { + SUCCESS, ///< Registration completed successfully. + ALREADY_REGISTERED ///< ADFun was already registered; no action taken. + }; + + /// @brief CppAD function object for evaluating the ODE right-hand side. + /// @details Contains the computational graph for automatic differentiation. + std::optional> rhsADFun; + + /// @brief Work structure for sparse Jacobian calculations. + /// @details Reused across Jacobian evaluations to avoid reallocation. + CppAD::sparse_jac_work jac_work; + + /// @brief Local cache of abundance values for efficient RHS evaluation. + std::vector local_abundance_cache; + + /// @brief Cache of step derivatives indexed by timestep identifier. + std::unordered_map> stepDerivativesCache; + + /// @brief Cache of sparse Jacobian subsets indexed by timestep identifier. + std::unordered_map, std::vector>> jacobianSubsetCache; + + /// @brief Cache of Jacobian work structures indexed by timestep identifier. + std::unordered_map jacWorkCache; + + /// @brief The most recent RHS calculation result for warm-starting. + std::optional> most_recent_rhs_calculation; + + /// @brief Flag indicating whether the scratchpad has been initialized. + bool has_initialized = false; + + /// @brief Unique identifier for this scratchpad type. + static constexpr auto ID = ScratchPadType::GRAPH_ENGINE_SCRATCHPAD; + + /** + * @brief Check whether the scratchpad has been initialized. + * @return true if initialized with a valid ADFun, false otherwise. + */ + [[nodiscard]] bool is_initialized() const override { return has_initialized; } + + /** + * @brief Initialize the scratchpad from a GraphEngine. + * + * Copies the authoritative ADFun from the engine and clears all caches. + * This method is idempotent; calling it multiple times has no effect + * after the first successful initialization. + * + * @param engine The GraphEngine to initialize from. + * + * @par Examples + * @code{.cpp} + * GraphEngineScratchPad scratch; + * GraphEngine engine = create_engine(); + * scratch.initialize(engine); + * + * // Now safe to use for thread-local computations + * auto& adfun = scratch.rhsADFun.value(); + * @endcode + */ + void initialize(const GraphEngine& engine) { + if (has_initialized) return; + + const auto& sourceTape = engine.getAuthoritativeADFun(); + rhsADFun.emplace(); + *rhsADFun = sourceTape; + jac_work.clear(); + local_abundance_cache.clear(); + stepDerivativesCache.clear(); + jacobianSubsetCache.clear(); + jacWorkCache.clear(); + most_recent_rhs_calculation = std::nullopt; + has_initialized = true; + } + + /** + * @brief Create a deep copy of this scratchpad. + * + * Creates an independent copy of all internal state, including the + * CppAD ADFun object and all caches. The clone can be safely used + * in a separate thread without affecting the original. + * + * @return A unique pointer to the cloned scratchpad. + * + * @note If rhsADFun is not initialized, the clone will also be + * uninitialized (has_initialized = false). + * + * @par Examples + * @code{.cpp} + * GraphEngineScratchPad scratch; + * scratch.initialize(engine); + * + * // Create independent copies for parallel workers + * std::vector> worker_pads; + * for (int i = 0; i < num_threads; ++i) { + * worker_pads.push_back(scratch.clone()); + * } + * @endcode + */ + [[nodiscard]] std::unique_ptr clone() const override { + auto ptr = std::make_unique(); + if (!rhsADFun.has_value()) { + ptr->rhsADFun = std::nullopt; + ptr->has_initialized = false; + } else { + ptr->rhsADFun.emplace(); + *ptr->rhsADFun = rhsADFun.value(); + ptr->has_initialized = true; + } + ptr->jac_work = jac_work; + ptr->local_abundance_cache = local_abundance_cache; + ptr->stepDerivativesCache = stepDerivativesCache; + ptr->jacobianSubsetCache = jacobianSubsetCache; + ptr->jacWorkCache = jacWorkCache; + ptr->most_recent_rhs_calculation = most_recent_rhs_calculation; + return ptr; + } +}; + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/scratchpads/engine_multiscale_scratchpad.h b/src/include/gridfire/engine/scratchpads/engine_multiscale_scratchpad.h new file mode 100644 index 00000000..6a203d7f --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/engine_multiscale_scratchpad.h @@ -0,0 +1,212 @@ +/** + * @file engine_multiscale_scratchpad.h + * @brief Scratchpad implementation for the MultiscalePartitioningEngineView. + * + * This header defines the MultiscalePartitioningEngineViewScratchPad, a concrete + * implementation of AbstractScratchPad designed for use with multiscale partitioning + * algorithms. It provides thread-local storage for QSE (Quasi-Static Equilibrium) + * groups, solvers, species classifications, and SUNDIALS contexts required for + * solving stiff subsystems. + * + * @par Purpose + * The MultiscalePartitioningEngineViewScratchPad stores: + * - QSE groups representing clusters of species in quasi-static equilibrium + * - QSE solvers for each group (managed via unique_ptr) + * - Classification of species into dynamic vs. algebraic categories + * - A composition cache for efficient lookup of computed compositions + * - A SUNDIALS context for numerical solver operations + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/engine_multiscale_scratchpad.h" + * + * // Create and initialize the scratchpad + * gridfire::engine::scratch::MultiscalePartitioningEngineViewScratchPad scratch; + * scratch.initialize(); + * + * if (scratch.is_initialized()) { + * // Add QSE groups and species classifications + * scratch.dynamic_species.push_back(hydrogen); + * scratch.dynamic_species.push_back(helium); + * scratch.algebraic_species.push_back(carbon); + * + * // Use the SUNDIALS context for solver operations + * SUNContext ctx = scratch.sun_ctx; + * } + * + * // Clone for parallel execution (note: solvers not cloned) + * auto worker_scratch = scratch.clone(); + * worker_scratch->initialize(); // Must re-initialize for new SUNContext + * @endcode + * + * @par Thread Safety + * This class is **not thread-safe**. Each thread must have its own instance + * because SUNDIALS contexts and QSE solvers maintain internal state. When + * cloning, the QSE solvers are not copied and the SUNContext is not cloned; + * the new instance must call initialize() to create its own context. + * + * @see AbstractScratchPad + * @see MultiscalePartitioningEngineView + * @see SUNContext + */ + +#pragma once + +#include "gridfire/engine/views/engine_multiscale.h" +#include "gridfire/engine/scratchpads/scratchpad_abstract.h" +#include "gridfire/engine/scratchpads/types.h" + +#include "fourdst/atomic/atomicSpecies.h" + +#include +#include +#include + +#include "sundials/sundials_context.h" + +namespace gridfire::engine::scratch { + +/** + * @brief Scratchpad for multiscale partitioning engine computations with QSE groups. + * + * MultiscalePartitioningEngineViewScratchPad provides thread-local storage for + * the multiscale partitioning algorithm, which separates species into fast + * (algebraic/QSE) and slow (dynamic) timescale groups. This enables efficient + * integration of stiff reaction networks by solving QSE subsystems separately. + * + * @par Thread Safety + * This class is **not thread-safe**. SUNDIALS contexts and QSE solver objects + * maintain internal state that cannot be shared across threads. Each thread + * must have its own scratchpad instance with its own SUNContext. When using + * clone(), the new instance starts uninitialized and must call initialize() + * to create a new SUNContext. + * + * @note The destructor properly cleans up SUNDIALS resources by freeing the + * SUNContext after clearing all solvers that depend on it. + * + * @warning QSE solvers are **not cloned** - they must be re-created in the + * cloned scratchpad as needed. + */ +struct MultiscalePartitioningEngineViewScratchPad final : AbstractScratchPad { + /// @brief Type alias for QSE group from the multiscale engine view. + using QSEGroup = MultiscalePartitioningEngineView::QSEGroup; + + /// @brief Type alias for QSE solver from the multiscale engine view. + using QSESolver = MultiscalePartitioningEngineView::QSESolver; + + /// @brief Type alias for atomic species. + using Species = fourdst::atomic::Species; + + /// @brief Unique identifier for this scratchpad type. + static constexpr auto ID = ScratchPadType::MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD; + + /// @brief Flag indicating whether the scratchpad has been initialized. + bool has_initialized = false; + + /// @brief Vector of QSE groups representing equilibrium clusters. + std::vector qse_groups; + + /// @brief Vector of QSE solvers, one per QSE group. + /// @note These are not cloned; new instances must create their own solvers. + std::vector> qse_solvers; + + /// @brief Species that evolve on the dynamic (slow) timescale. + std::vector dynamic_species; + + /// @brief Species that are solved algebraically (fast timescale/QSE). + std::vector algebraic_species; + + /// @brief Cache of computed compositions indexed by a hash key. + std::unordered_map composition_cache; + + /// @brief SUNDIALS context for solver operations. + /// @note Must be freed in destructor after clearing solvers. + SUNContext sun_ctx = nullptr; + + /** + * @brief Check whether the scratchpad has been initialized. + * @return true if initialized with a valid SUNContext, false otherwise. + */ + [[nodiscard]] bool is_initialized() const override { return has_initialized; } + + /** + * @brief Initialize the scratchpad by creating a SUNDIALS context. + * + * Creates a new SUNContext for use with SUNDIALS solvers. This method + * is idempotent; calling it multiple times has no effect after the + * first successful initialization. + * + * @throws std::runtime_error if SUNContext creation fails. + * + * @par Examples + * @code{.cpp} + * MultiscalePartitioningEngineViewScratchPad scratch; + * scratch.initialize(); + * + * // Now safe to use SUNContext for solver creation + * SUNContext ctx = scratch.sun_ctx; + * @endcode + */ + void initialize() { + if (has_initialized) return; + + const int flag = SUNContext_Create(SUN_COMM_NULL, &sun_ctx); + if (flag != 0) { + throw std::runtime_error("Failed to create SUNContext in MultiscalePartitioningEngineViewScratchPad."); + } + + has_initialized = true; + } + + /** + * @brief Destructor that properly releases SUNDIALS resources. + * + * Clears all QSE solvers before freeing the SUNContext to ensure + * proper cleanup order and avoid dangling references. + */ + ~MultiscalePartitioningEngineViewScratchPad() override { + qse_solvers.clear(); + if (sun_ctx != nullptr) { + SUNContext_Free(&sun_ctx); + sun_ctx = nullptr; + } + } + + /** + * @brief Create a partial copy of this scratchpad. + * + * Creates a copy with the QSE groups, species classifications, and + * composition cache. + * + * @return A unique pointer to the cloned scratchpad. + * + * @note The new instance will automatically initialize a new SUNContext and clone the QSE solvers. + * + * @par Examples + * @code{.cpp} + * MultiscalePartitioningEngineViewScratchPad scratch; + * scratch.initialize(); + * scratch.dynamic_species = {hydrogen, helium}; + * + * // Clone for a worker thread + * auto worker = scratch.clone(); + * + * @endcode + */ + [[nodiscard]] std::unique_ptr clone() const override { + auto clone_pad = std::make_unique(); + clone_pad->qse_groups = this->qse_groups; + clone_pad->dynamic_species = this->dynamic_species; + clone_pad->algebraic_species = this->algebraic_species; + clone_pad->composition_cache = this->composition_cache; + + clone_pad->initialize(); + clone_pad->qse_solvers.reserve(this->qse_solvers.size()); + for (const auto& solver : qse_solvers) { + clone_pad->qse_solvers.push_back(solver->clone(clone_pad->sun_ctx)); // Must rebind context to new SUNContext + } + return clone_pad; + } +}; + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/scratchpads/formatters.h b/src/include/gridfire/engine/scratchpads/formatters.h new file mode 100644 index 00000000..c4b9e492 --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/formatters.h @@ -0,0 +1,138 @@ +#pragma once + +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/scratchpad_abstract.h" +#include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_adaptive_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_multiscale_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_defined_scratchpad.h" +#include "gridfire/engine/scratchpads/types.h" +#include "gridfire/utils/logging.h" + +#include +#include +#include + +// 1. ScratchPadType: Inherit from string_view formatter for efficiency +template <> +struct std::formatter : std::formatter { + // Note: NOT static, marked const + auto format(gridfire::engine::scratch::ScratchPadType type, auto& ctx) const { + // Convert to string_view + std::string_view name = gridfire::engine::scratch::get_scratchpad_type_name(type); + // Delegate to the base class to handle width/fill/alignment + return std::formatter::format(name, ctx); + } +}; + +// 2. AbstractScratchPad +template <> +struct std::formatter : std::formatter { + auto format(const gridfire::engine::scratch::AbstractScratchPad& pad, auto& ctx) const { + std::string str = std::format("AbstractScratchPad(Initialized: {})", + pad.is_initialized()); + return std::formatter::format(str, ctx); + } +}; + +// 3. GraphEngineScratchPad +template <> +struct std::formatter : std::formatter { + auto format(const gridfire::engine::scratch::GraphEngineScratchPad& pad, auto& ctx) const { + std::string str = std::format("GraphEngineScratchPad(Initialized: {}, HasADFun: {}, CachedStepDerivatives: {}, CachedJacobians: {})", + pad.has_initialized, + pad.rhsADFun.has_value(), + pad.stepDerivativesCache.size(), + pad.jacobianSubsetCache.size()); + return std::formatter::format(str, ctx); + } +}; + +// 4. AdaptiveEngineViewScratchPad +template<> +struct std::formatter : std::formatter { + auto format(const gridfire::engine::scratch::AdaptiveEngineViewScratchPad& pad, auto& ctx) const { + std::string str = std::format("AdaptiveEngineViewScratchPad(Initialized: {}, Active Species: {}, Active Reactions: {})", + pad.has_initialized, + pad.active_species.size(), + pad.active_reactions.size()); + return std::formatter::format(str, ctx); + } +}; + +// 5. MultiscalePartitioningEngineViewScratchPad +template <> +struct std::formatter : std::formatter { + auto format(const gridfire::engine::scratch::MultiscalePartitioningEngineViewScratchPad& pad, auto& ctx) const { + std::string str = std::format("MultiscalePartitioningEngineViewScratchPad(Initialized: {}, QSE Groups: {}, Dynamic Species: {}, Algebraic Species: {}, Cached Compositions: {})", + pad.has_initialized, + pad.qse_groups.size(), + pad.dynamic_species.size(), + pad.algebraic_species.size(), + pad.composition_cache.size()); + return std::formatter::format(str, ctx); + } +}; + +// 6. DefinedEngineViewScratchPad +template <> +struct std::formatter : std::formatter { + auto format(const gridfire::engine::scratch::DefinedEngineViewScratchPad& pad, auto& ctx) const { + std::string str = std::format("DefinedEngineViewScratchPad(Initialized: {}, Active Species: {}, Active Reactions: {})", + pad.has_initialized, + pad.active_species.size(), + pad.active_reactions.size()); + return std::formatter::format(str, ctx); + } +}; + +// 7. StateBlob +template <> +struct std::formatter : std::formatter { + auto format(const gridfire::engine::scratch::StateBlob& blob, auto& ctx) const { + // Construct the full string representation + std::string str = std::format("StateBlob(Enrolled: {})", + gridfire::utils::iterable_to_delimited_string( + blob.get_registered_scratchpads(), + ", ", + [&blob](const auto& type) { + auto result = blob.get(type); + if (!result.has_value()) { + return std::format("{}(Error: {})", + gridfire::engine::scratch::get_scratchpad_type_name(type), + gridfire::engine::scratch::StateBlob::error_to_string(result.error())); + } + + gridfire::engine::scratch::AbstractScratchPad* scratchpad = result.value(); + + // We can reuse the formatters we defined above by dereferencing the cast pointers! + switch (type) { + case gridfire::engine::scratch::ScratchPadType::GRAPH_ENGINE_SCRATCHPAD : { + auto* cast_pad = dynamic_cast(scratchpad); + // This works because we defined a formatter for GraphEngineScratchPad above + return std::format("{}", *cast_pad); + } + case gridfire::engine::scratch::ScratchPadType::MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD : { + auto* cast_pad = dynamic_cast(scratchpad); + return std::format("{}", *cast_pad); + } + case gridfire::engine::scratch::ScratchPadType::ADAPTIVE_ENGINE_VIEW_SCRATCHPAD : { + auto* cast_pad = dynamic_cast(scratchpad); + return std::format("{}", *cast_pad); + } + case gridfire::engine::scratch::ScratchPadType::DEFINED_ENGINE_VIEW_SCRATCHPAD : { + auto* cast_pad = dynamic_cast(scratchpad); + return std::format("{}", *cast_pad); + } + default: { + return std::format("{}(Unknown ScratchPad Type)", gridfire::engine::scratch::get_scratchpad_type_name(type)); + } + } + } + ) + ); + + // Delegate to base class to write the string to the context + return std::formatter::format(str, ctx); + } +}; \ No newline at end of file diff --git a/src/include/gridfire/engine/scratchpads/scratchpad_abstract.h b/src/include/gridfire/engine/scratchpads/scratchpad_abstract.h new file mode 100644 index 00000000..efbc401b --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/scratchpad_abstract.h @@ -0,0 +1,137 @@ +/** + * @file scratchpad_abstract.h + * @brief Abstract base class for scratchpad memory used during engine computations. + * + * This header defines the AbstractScratchPad interface, which provides a common + * contract for temporary working memory (scratchpads) used by computational engines. + * Scratchpads are designed to store intermediate results, cached computations, or + * pre-allocated buffers that can be reused across multiple computational steps, + * improving performance by avoiding repeated memory allocations. + * + * @par Purpose + * The scratchpad pattern allows engines to: + * - Pre-allocate working memory once and reuse it across iterations + * - Store intermediate computational results between solver steps + * - Enable efficient cloning for parallel execution contexts + * - Provide a type-erased interface for heterogeneous scratchpad management + * + * @par Examples + * @code{.cpp} + * // Define a concrete scratchpad for a specific engine + * class MyScratchPad : public gridfire::engine::scratch::AbstractScratchPad { + * public: + * MyScratchPad() : initialized_(false) {} + * + * void initialize(size_t size) { + * buffer_.resize(size); + * initialized_ = true; + * } + * + * [[nodiscard]] bool is_initialized() const override { + * return initialized_; + * } + * + * [[nodiscard]] std::unique_ptr clone() const override { + * auto copy = std::make_unique(); + * copy->buffer_ = buffer_; + * copy->initialized_ = initialized_; + * return copy; + * } + * + * private: + * std::vector buffer_; + * bool initialized_; + * }; + * + * // Usage in an engine context + * auto scratch = std::make_unique(); + * scratch->initialize(1024); + * + * if (scratch->is_initialized()) { + * // Use scratchpad for computations + * auto parallel_scratch = scratch->clone(); // Clone for parallel worker + * } + * @endcode + */ + +#pragma once +#include + +namespace gridfire::engine::scratch { + +/** + * @brief Abstract base struct for engine scratchpad memory. + * + * AbstractScratchPad defines the interface for temporary working memory + * containers used by computational engines. Implementations should provide + * storage for intermediate results, cached values, or pre-allocated buffers + * that persist across multiple computational steps. + * + * This interface enables polymorphic handling of different scratchpad types + * while ensuring proper resource management through virtual destruction and + * deep cloning capabilities. + * + * @par Thread Safety + * This interface is **not thread-safe** by design. Scratchpads are intended + * to be used as thread-local working memory. Each thread should operate on + * its own independent scratchpad instance. Use the clone() method to create + * separate copies for each thread in parallel execution contexts. Sharing a + * single scratchpad instance across multiple threads without external + * synchronization will result in undefined behavior. + */ +struct AbstractScratchPad { + /** + * @brief Virtual destructor for proper cleanup of derived classes. + * + * Ensures that resources held by concrete scratchpad implementations + * are properly released when the scratchpad is destroyed through a + * base class pointer. + */ + virtual ~AbstractScratchPad() = default; + + /** + * @brief Check whether the scratchpad has been properly initialized. + * + * Derived classes should return true only after all necessary memory + * allocations and setup operations have been completed successfully. + * + * @return true if the scratchpad is initialized and ready for use. + * @return false if the scratchpad has not been initialized or initialization failed. + * + * @par Examples + * @code{.cpp} + * auto scratch = create_scratchpad(); + * if (!scratch->is_initialized()) { + * throw std::runtime_error("Scratchpad not ready for computation"); + * } + * @endcode + */ + [[nodiscard]] virtual bool is_initialized() const = 0; + + /** + * @brief Create a deep copy of this scratchpad. + * + * Produces an independent clone of the scratchpad, including all internal + * state and allocated memory. This is essential for parallel execution + * scenarios where each thread requires its own working memory. + * + * @return A unique pointer to a newly allocated copy of this scratchpad. + * + * @note The returned clone should be fully independent; modifications to + * the clone must not affect the original, and vice versa. + * + * @par Examples + * @code{.cpp} + * std::unique_ptr original = create_scratchpad(); + * + * // Create independent copies for parallel workers + * std::vector> worker_scratches; + * for (int i = 0; i < num_threads; ++i) { + * worker_scratches.push_back(original->clone()); + * } + * @endcode + */ + [[nodiscard]] virtual std::unique_ptr clone() const = 0; +}; + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/scratchpads/scratchpads.h b/src/include/gridfire/engine/scratchpads/scratchpads.h new file mode 100644 index 00000000..76c090e4 --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/scratchpads.h @@ -0,0 +1,167 @@ +/** + * @file scratchpads.h + * @brief Unified header for the scratchpad memory management system. + * + * This is the main include file for the scratchpad subsystem. It provides + * a single include point for all scratchpad-related functionality, including + * the abstract base class, concrete implementations, type definitions, + * the StateBlob container, utility functions, and formatters for debugging. + * + * @par What are Scratchpads? + * Scratchpads are temporary working memory containers used by computational + * engines during ODE integration and reaction network calculations. They serve + * several critical purposes: + * + * - **Performance**: Pre-allocate memory once and reuse across iterations, + * avoiding repeated heap allocations during time-critical computations. + * - **Caching**: Store intermediate results (Jacobians, derivatives, etc.) + * that can be reused across solver steps. + * - **Thread Safety**: Provide thread-local storage for parallel execution, + * where each thread operates on its own independent scratchpad instance. + * - **State Management**: Encapsulate engine-specific working state separate + * from the engine's persistent configuration. + * + * @par Architecture Overview + * The scratchpad system consists of: + * + * - **AbstractScratchPad**: Base interface defining `is_initialized()` and `clone()` + * - **Concrete Scratchpads**: Engine-specific implementations + * - `GraphEngineScratchPad`: CppAD ADFun and Jacobian caches + * - `AdaptiveEngineViewScratchPad`: Active species/reactions for adaptive networks + * - `DefinedEngineViewScratchPad`: Species/reactions for static networks + * - `MultiscalePartitioningEngineViewScratchPad`: QSE groups and SUNDIALS context + * - **StateBlob**: Container managing multiple scratchpads with type-safe access + * - **Utilities**: Helper functions for exception-based retrieval + * - **Formatters**: std::format specializations for debugging output + * + * @par Why Use Scratchpads? + * During numerical integration of stiff reaction networks, engines must: + * 1. Evaluate right-hand side functions (species derivatives) + * 2. Compute sparse Jacobian matrices + * 3. Solve linear systems within Newton iterations + * + * These operations require substantial temporary memory. Without scratchpads, + * each evaluation would allocate and deallocate working buffers, causing: + * - Memory fragmentation + * - Cache thrashing + * - Unnecessary allocation overhead + * + * Scratchpads solve this by providing persistent, reusable working memory + * that lives for the duration of an integration step (or longer). + * + * @par Thread Safety Model + * The scratchpad system is designed for thread-local usage: + * + * - Scratchpads are **not thread-safe** by design + * - Each thread must have its own scratchpad instances + * - Use `StateBlob::clone_structure()` to create independent copies for workers + * - The original scratchpad/blob remains usable by the main thread + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/scratchpads.h" + * + * using namespace gridfire::engine::scratch; + * + * // === Basic Usage === + * // Create a StateBlob and enroll scratchpads + * StateBlob blob; + * blob.enroll(); + * blob.enroll(); + * + * // Initialize scratchpads + * auto* graph_scratch = get_state(blob); + * graph_scratch->initialize(engine); + * + * // Use initialized scratchpad + * auto* scratch = get_state(blob); // Throws if not initialized + * auto& adfun = scratch->rhsADFun.value(); + * + * // === Parallel Execution === + * // Clone for worker threads + * std::vector> worker_blobs; + * for (int i = 0; i < num_threads; ++i) { + * worker_blobs.push_back(blob.clone_structure()); + * } + * + * // Each worker uses its own blob + * #pragma omp parallel for + * for (int i = 0; i < work_items; ++i) { + * int tid = omp_get_thread_num(); + * StateBlob& my_blob = *worker_blobs[tid]; + * auto* my_scratch = get_state(my_blob); + * // Thread-safe: each thread has its own scratchpad + * compute_with_scratchpad(*my_scratch); + * } + * + * // === Debugging === + * // Use formatters for logging + * std::cout << std::format("Blob state: {}\n", blob); + * // Output: StateBlob(Enrolled: GraphEngineScratchPad(...), AdaptiveEngineViewScratchPad(...)) + * + * // Check status + * auto status = blob.get_status(); + * if (status == StateBlob::ScratchPadStatus::ENROLLED_NOT_INITIALIZED) { + * // Need to initialize before use + * } + * @endcode + * + * @par Included Headers + * This header includes: + * - scratchpad_abstract.h - AbstractScratchPad base class + * - engine_graph_scratchpad.h - GraphEngineScratchPad + * - engine_adaptive_scratchpad.h - AdaptiveEngineViewScratchPad + * - engine_multiscale_scratchpad.h - MultiscalePartitioningEngineViewScratchPad + * - engine_defined_scratchpad.h - DefinedEngineViewScratchPad + * - types.h - ScratchPadType enumeration + * - blob.h - StateBlob container + * - utils.h - get_state() helper functions + * - formatters.h - std::format specializations + * + * @see AbstractScratchPad + * @see StateBlob + * @see ScratchPadType + */ + +/** + * @namespace gridfire::engine::scratch + * @brief Scratchpad memory management for computational engines. + * + * The scratch namespace contains all components related to temporary working + * memory management for GridFire's computational engines. This includes the + * abstract scratchpad interface, concrete implementations for each engine type, + * the StateBlob container for managing multiple scratchpads, and utilities + * for convenient access. + * + * @par Key Components + * - AbstractScratchPad: Interface for all scratchpad types + * - GraphEngineScratchPad: Working memory for CppAD-based graph engines + * - AdaptiveEngineViewScratchPad: Storage for adaptive network computations + * - DefinedEngineViewScratchPad: Storage for static network computations + * - MultiscalePartitioningEngineViewScratchPad: QSE solver state management + * - StateBlob: Type-safe container for multiple scratchpads + * - ScratchPadType: Enumeration of registered scratchpad types + * - IsScratchPad: Concept constraining valid scratchpad types + * - get_state(): Utility functions for exception-based retrieval + * + * @par Design Philosophy + * The scratchpad system follows these design principles: + * + * 1. **Separation of Concerns**: Working memory is separate from engine configuration + * 2. **Type Safety**: Compile-time verification of scratchpad types via concepts + * 3. **Performance**: O(1) access via enum-indexed arrays + * 4. **Thread Locality**: Each thread owns its scratchpad instances + * 5. **Clonability**: Deep copying enables parallel execution patterns + */ + +#pragma once + +#include "gridfire/engine/scratchpads/scratchpad_abstract.h" +#include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_adaptive_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_multiscale_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_defined_scratchpad.h" +#include "gridfire/engine/scratchpads/types.h" +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/utils.h" +#include "gridfire/engine/scratchpads/formatters.h" \ No newline at end of file diff --git a/src/include/gridfire/engine/scratchpads/types.h b/src/include/gridfire/engine/scratchpads/types.h new file mode 100644 index 00000000..c30d185a --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/types.h @@ -0,0 +1,141 @@ +/** + * @file types.h + * @brief Type definitions and utilities for the scratchpad system. + * + * This header defines the ScratchPadType enumeration which identifies all + * registered scratchpad types in the system, along with utility functions + * for querying scratchpad type information at compile-time and runtime. + * + * @par Purpose + * The types header provides: + * - A centralized enumeration of all scratchpad types + * - Compile-time constant for the maximum number of scratchpad types + * - Runtime conversion of scratchpad types to human-readable names + * + * @par Adding New Scratchpad Types + * To add a new scratchpad type: + * 1. Add a new enumerator before `_COUNT` in ScratchPadType + * 2. Add a corresponding case in get_scratchpad_type_name() + * 3. Create the concrete scratchpad class with a static `ID` member set to the new type + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/types.h" + * + * using namespace gridfire::engine::scratch; + * + * // Get the maximum number of scratchpad types at compile time + * constexpr size_t max_types = get_max_scratchpad_types(); + * std::array enrolled_flags{}; + * + * // Get a human-readable name for a scratchpad type + * ScratchPadType type = ScratchPadType::GRAPH_ENGINE_SCRATCHPAD; + * std::string_view name = get_scratchpad_type_name(type); + * // name == "GraphEngineScratchPad" + * + * // Iterate over all scratchpad types + * for (size_t i = 0; i < get_max_scratchpad_types(); ++i) { + * auto type = static_cast(i); + * std::cout << get_scratchpad_type_name(type) << "\n"; + * } + * @endcode + * + * @see AbstractScratchPad + * @see StateBlob + */ + +#pragma once +#include +#include + +namespace gridfire::engine::scratch { + +/** + * @brief Enumeration of all registered scratchpad types. + * + * Each scratchpad implementation must have a unique type identifier in this + * enumeration. The concrete scratchpad class should define a static `ID` + * member initialized to its corresponding ScratchPadType value. + * + * @note The `_COUNT` enumerator is a sentinel value used to determine the + * total number of scratchpad types. It must always be the last entry. + * Do not use `_COUNT` as an actual scratchpad type. + */ +enum class ScratchPadType : uint8_t { + GRAPH_ENGINE_SCRATCHPAD, ///< GraphEngineScratchPad for CppAD-based engines. + MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD, ///< MultiscalePartitioningEngineViewScratchPad for QSE partitioning. + ADAPTIVE_ENGINE_VIEW_SCRATCHPAD, ///< AdaptiveEngineViewScratchPad for adaptive networks. + DEFINED_ENGINE_VIEW_SCRATCHPAD, ///< DefinedEngineViewScratchPad for static networks. + PRIMING_ENGINE_VIEW_SCRATCHPAD, ///< PrimingEngineViewScratchPad for engine priming. + + _COUNT ///< Sentinel value representing the total number of scratchpad types. Do not use as a type. +}; + +/** + * @brief Get the maximum number of scratchpad types at compile time. + * + * Returns the total count of registered scratchpad types, derived from + * the ScratchPadType::_COUNT sentinel value. This is useful for sizing + * fixed-size arrays that need a slot for each scratchpad type. + * + * @return The number of valid scratchpad types (excluding _COUNT). + * + * @par Examples + * @code{.cpp} + * // Use at compile time for array sizing + * constexpr size_t NUM_TYPES = get_max_scratchpad_types(); + * std::array, NUM_TYPES> scratchpads; + * + * // Use in static_assert + * static_assert(get_max_scratchpad_types() > 0, "No scratchpad types defined"); + * @endcode + */ +consteval size_t get_max_scratchpad_types() { + return static_cast(ScratchPadType::_COUNT); +} + +/** + * @brief Convert a ScratchPadType to a human-readable name. + * + * Returns a string view containing the class name associated with + * the given scratchpad type. Useful for logging, debugging, and + * error messages. + * + * @param scratchpad_type The scratchpad type to convert. + * + * @return A string view containing the scratchpad class name, or + * "UnknownScratchPadType" for unrecognized values. + * + * @par Examples + * @code{.cpp} + * ScratchPadType type = ScratchPadType::GRAPH_ENGINE_SCRATCHPAD; + * std::cout << "Using: " << get_scratchpad_type_name(type) << "\n"; + * // Output: "Using: GraphEngineScratchPad" + * + * // Use in error messages + * throw std::runtime_error( + * std::format("Failed to initialize {}", get_scratchpad_type_name(type)) + * ); + * @endcode + */ +constexpr std::string_view get_scratchpad_type_name(const ScratchPadType scratchpad_type) { + if constexpr (get_max_scratchpad_types() == 0) { + return {""}; + } + switch (scratchpad_type) { + case ScratchPadType::GRAPH_ENGINE_SCRATCHPAD: + return "GraphEngineScratchPad"; + case ScratchPadType::MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD: + return "MultiscalePartitioningEngineViewScratchPad"; + case ScratchPadType::ADAPTIVE_ENGINE_VIEW_SCRATCHPAD: + return "AdaptiveEngineViewScratchPad"; + case ScratchPadType::DEFINED_ENGINE_VIEW_SCRATCHPAD: + return "DefinedEngineViewScratchPad"; + case ScratchPadType::PRIMING_ENGINE_VIEW_SCRATCHPAD: + return "PrimingEngineViewScratchPad"; + default: + return "UnknownScratchPadType"; + } +} + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/scratchpads/utils.h b/src/include/gridfire/engine/scratchpads/utils.h new file mode 100644 index 00000000..86ec3650 --- /dev/null +++ b/src/include/gridfire/engine/scratchpads/utils.h @@ -0,0 +1,240 @@ +/** + * @file utils.h + * @brief Utility functions for convenient scratchpad retrieval with exception handling. + * + * This header provides helper functions that wrap StateBlob's get() methods, + * converting error codes into exceptions for simpler error handling. These + * utilities eliminate the need to manually check std::expected results and + * switch on error codes at every call site. + * + * @par Purpose + * The utility functions provide: + * - Exception-based error handling instead of std::expected + * - Consistent error messages across the codebase + * - Both mutable and const-correct overloads + * - Optional initialization checking via template parameter + * + * @par Examples + * @code{.cpp} + * #include "gridfire/engine/scratchpads/utils.h" + * #include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" + * + * using namespace gridfire::engine::scratch; + * + * void compute(StateBlob& blob) { + * // Simple retrieval - throws if not found + * GraphEngineScratchPad* scratch = get_state(blob); + * scratch->initialize(engine); + * + * // Retrieval with initialization check - throws if not initialized + * auto* initialized_scratch = get_state(blob); + * // Safe to use - guaranteed to be initialized + * } + * + * void read_only_access(const StateBlob& blob) { + * // Const overload for read-only access + * const GraphEngineScratchPad* scratch = get_state(blob); + * bool ready = scratch->is_initialized(); + * } + * @endcode + * + * @par Thread Safety + * These functions inherit the thread safety characteristics of StateBlob. + * They are **not thread-safe** - each thread should operate on its own + * StateBlob instance. + * + * @see StateBlob + * @see IsScratchPad + * @see exceptions::ScratchPadError + */ + +#pragma once +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/exceptions/error_scratchpad.h" + +namespace gridfire::engine::scratch { + +/** + * @brief Retrieve a scratchpad from a StateBlob, throwing on error. + * + * Convenience wrapper around StateBlob::get() that converts error codes + * into exceptions. Use this when you expect the scratchpad to exist and + * want exception-based error handling. + * + * @tparam CTX The scratchpad type to retrieve (must satisfy IsScratchPad). + * + * @param ctx The StateBlob to retrieve the scratchpad from. + * + * @return Pointer to the requested scratchpad. + * + * @throws exceptions::ScratchPadError if the scratchpad is not found, + * cannot be cast to the requested type, or any other error occurs. + * + * @par Examples + * @code{.cpp} + * StateBlob blob; + * blob.enroll(); + * + * // Retrieve the scratchpad - throws if not enrolled + * GraphEngineScratchPad* scratch = get_state(blob); + * scratch->initialize(engine); + * @endcode + */ +template +CTX* get_state(StateBlob& ctx) { + auto result = ctx.get(); + if (!result.has_value()) { + switch (result.error()) { + case StateBlob::Error::SCRATCHPAD_NOT_FOUND: + throw exceptions::ScratchPadError("Requested scratchpad not found in StateBlob."); + case StateBlob::Error::SCRATCHPAD_BAD_CAST: + throw exceptions::ScratchPadError("Failed to cast scratchpad to the requested type."); + case StateBlob::Error::SCRATCHPAD_TYPE_COLLISION: + throw exceptions::ScratchPadError("Scratchpad type collision detected in StateBlob."); + default: + throw exceptions::ScratchPadError("Unknown error occurred while retrieving scratchpad from StateBlob."); + } + } + return result.value(); +} + +/** + * @brief Retrieve a const scratchpad from a const StateBlob, throwing on error. + * + * Const-correct overload of get_state() for read-only access to scratchpads. + * Use this when you have a const reference to the StateBlob and only need + * to read from the scratchpad. + * + * @tparam CTX The scratchpad type to retrieve (must satisfy IsScratchPad). + * + * @param ctx The const StateBlob to retrieve the scratchpad from. + * + * @return Const pointer to the requested scratchpad. + * + * @throws exceptions::ScratchPadError if the scratchpad is not found, + * cannot be cast to the requested type, or any other error occurs. + * + * @par Examples + * @code{.cpp} + * void inspect(const StateBlob& blob) { + * const GraphEngineScratchPad* scratch = get_state(blob); + * if (scratch->is_initialized()) { + * // Read from scratch... + * } + * } + * @endcode + */ +template +const CTX* get_state(const StateBlob& ctx) { + auto result = ctx.get(); + if (!result.has_value()) { + switch (result.error()) { + case StateBlob::Error::SCRATCHPAD_NOT_FOUND: + throw exceptions::ScratchPadError("Requested scratchpad not found in StateBlob."); + case StateBlob::Error::SCRATCHPAD_BAD_CAST: + throw exceptions::ScratchPadError("Failed to cast scratchpad to the requested type."); + case StateBlob::Error::SCRATCHPAD_TYPE_COLLISION: + throw exceptions::ScratchPadError("Scratchpad type collision detected in StateBlob."); + default: + throw exceptions::ScratchPadError("Unknown error occurred while retrieving scratchpad from StateBlob."); + } + } + return result.value(); +} + +/** + * @brief Retrieve a scratchpad with optional initialization check, throwing on error. + * + * Extended version of get_state() that can optionally verify the scratchpad + * is initialized before returning it. When MUST_BE_INITIALIZED is true, an + * exception is thrown if the scratchpad exists but hasn't been initialized. + * + * @tparam CTX The scratchpad type to retrieve (must satisfy IsScratchPad). + * @tparam MUST_BE_INITIALIZED If true, throws when the scratchpad is not initialized. + * + * @param ctx The StateBlob to retrieve the scratchpad from. + * + * @return Pointer to the requested scratchpad (guaranteed initialized if MUST_BE_INITIALIZED is true). + * + * @throws exceptions::ScratchPadError if the scratchpad is not found, + * cannot be cast, is not initialized (when required), or any other error. + * + * @par Examples + * @code{.cpp} + * // Ensure scratchpad is initialized before use + * try { + * auto* scratch = get_state(blob); + * // Guaranteed to be initialized here + * use_scratchpad(*scratch); + * } catch (const exceptions::ScratchPadError& e) { + * // Handle missing or uninitialized scratchpad + * } + * @endcode + */ +template +CTX* get_state(StateBlob& ctx) { + auto result = ctx.get(); + if (!result.has_value()) { + switch (result.error()) { + case StateBlob::Error::SCRATCHPAD_NOT_FOUND: + throw exceptions::ScratchPadError("Requested scratchpad not found in StateBlob."); + case StateBlob::Error::SCRATCHPAD_BAD_CAST: + throw exceptions::ScratchPadError("Failed to cast scratchpad to the requested type."); + case StateBlob::Error::SCRATCHPAD_TYPE_COLLISION: + throw exceptions::ScratchPadError("Scratchpad type collision detected in StateBlob."); + case StateBlob::Error::SCRATCHPAD_NOT_INITIALIZED: + throw exceptions::ScratchPadError("Requested scratchpad not initialized in StateBlob. If this is acceptable behavior, use scratch::get_state<>() without the MUST_BE_INITIALIZED template parameter."); + default: + throw exceptions::ScratchPadError("Unknown error occurred while retrieving scratchpad from StateBlob."); + } + } + return result.value(); +} + +/** + * @brief Retrieve a const scratchpad with optional initialization check, throwing on error. + * + * Const-correct overload of the initialization-checking get_state(). Combines + * read-only access with optional initialization verification. + * + * @tparam CTX The scratchpad type to retrieve (must satisfy IsScratchPad). + * @tparam MUST_BE_INITIALIZED If true, throws when the scratchpad is not initialized. + * + * @param ctx The const StateBlob to retrieve the scratchpad from. + * + * @return Const pointer to the requested scratchpad (guaranteed initialized if MUST_BE_INITIALIZED is true). + * + * @throws exceptions::ScratchPadError if the scratchpad is not found, + * cannot be cast, is not initialized (when required), or any other error. + * + * @par Examples + * @code{.cpp} + * void validate(const StateBlob& blob) { + * // Get const access, ensuring initialization + * const auto* scratch = get_state(blob); + * // Safe to read - guaranteed initialized + * const auto& adfun = scratch->rhsADFun.value(); + * } + * @endcode + */ +template +const CTX* get_state(const StateBlob& ctx) { + auto result = ctx.get(); + if (!result.has_value()) { + switch (result.error()) { + case StateBlob::Error::SCRATCHPAD_NOT_FOUND: + throw exceptions::ScratchPadError("Requested scratchpad not found in StateBlob."); + case StateBlob::Error::SCRATCHPAD_BAD_CAST: + throw exceptions::ScratchPadError("Failed to cast scratchpad to the requested type."); + case StateBlob::Error::SCRATCHPAD_TYPE_COLLISION: + throw exceptions::ScratchPadError("Scratchpad type collision detected in StateBlob."); + case StateBlob::Error::SCRATCHPAD_NOT_INITIALIZED: + throw exceptions::ScratchPadError("Requested scratchpad is not initialized. If this is acceptable behavior, use scratch::get_state<>() without the MUST_BE_INITIALIZED template parameter."); + default: + throw exceptions::ScratchPadError("Unknown error occurred while retrieving scratchpad from StateBlob."); + } + } + return result.value(); +} + +} // namespace gridfire::engine::scratch diff --git a/src/include/gridfire/engine/views/engine_adaptive.h b/src/include/gridfire/engine/views/engine_adaptive.h index 59d461cc..40c2a7de 100644 --- a/src/include/gridfire/engine/views/engine_adaptive.h +++ b/src/include/gridfire/engine/views/engine_adaptive.h @@ -11,6 +11,7 @@ #include "fourdst/logging/logging.h" #include "gridfire/engine/procedures/construction.h" +#include "gridfire/engine/scratchpads/blob.h" #include "quill/Logger.h" @@ -62,6 +63,7 @@ namespace gridfire::engine { /** * @brief Updates the active species and reactions based on the current conditions. * + * @param ctx The scratchpad context for storing thread-local data. * @param netIn The current network input, containing temperature, density, and composition. * * This method performs the reaction flow calculation, reaction culling, connectivity analysis, @@ -76,22 +78,27 @@ namespace gridfire::engine { * @see AdaptiveEngineView::constructSpeciesIndexMap() * @see AdaptiveEngineView::constructReactionIndexMap() */ - fourdst::composition::Composition update(const NetIn &netIn) override; - - bool isStale(const NetIn& netIn) override; + fourdst::composition::Composition project( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const override; /** * @brief Gets the list of active species in the network. * @return A const reference to the vector of active species. */ - [[nodiscard]] const std::vector& getNetworkSpecies() const override; + [[nodiscard]] const std::vector& getNetworkSpecies( + scratch::StateBlob& ctx + ) const override; /** * @brief Calculates the right-hand side (dY/dt) and energy generation for the active species. * + * @param ctx The scratchpad context for storing thread-local data. * @param comp The current composition of the system. * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. + * @param trust * @return A StepDerivatives struct containing the derivatives of the active species and the * nuclear energy generation rate. * @@ -102,21 +109,25 @@ namespace gridfire::engine { * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). * @see AdaptiveEngineView::update() */ - [[nodiscard]] std::expected, engine::EngineStatus> calculateRHSAndEnergy( + [[nodiscard]] std::expected, EngineStatus> calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const override; /** * + * @param ctx The scratchpad context for storing thread-local data. * @param comp The current composition of the system. * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. * @return A struct containing the derivatives of the energy generation rate with respect to temperature and density. */ [[nodiscard]] EnergyDerivatives calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -125,6 +136,7 @@ namespace gridfire::engine { /** * @brief Generates the Jacobian matrix for the active species. * + * @param ctx The scratchpad context for storing thread-local data. * @param comp The current composition of the system. * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. @@ -136,6 +148,7 @@ namespace gridfire::engine { * @see AdaptiveEngineView::update() */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -144,6 +157,7 @@ namespace gridfire::engine { /** * @brief Generates the Jacobian matrix for some set of active species such that that set is a subset of the active species in the view. * + * @param ctx The scratchpad context for storing thread-local data. * @param comp The current composition of the system. * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. @@ -156,6 +170,7 @@ namespace gridfire::engine { * @see AdaptiveEngineView::update() */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -165,6 +180,7 @@ namespace gridfire::engine { /** * @brief Generates the Jacobian matrix for the active species with a given sparsity pattern. * + * @param ctx The scratchpad context for storing thread-local data. * @param comp The current composition of the system. * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. @@ -177,45 +193,18 @@ namespace gridfire::engine { * @see AdaptiveEngineView::update() */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, const SparsityPattern &sparsityPattern ) const override; - /** - * @brief Generates the stoichiometry matrix for the active reactions and species. - * - * This method calls the base engine to generate the stoichiometry matrix. - * - * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). - * @note The stoichiometry matrix generated by the base engine is assumed to be consistent with - * the active species and reactions in this view. - */ - void generateStoichiometryMatrix() override; - - /** - * @brief Gets an entry from the stoichiometry matrix for the active species and reactions. - * - * @param species The species for which to get the stoichiometric coefficient. - * @param reaction The reaction for which to get the stoichiometric coefficient. - * @return The stoichiometric coefficient for the given species and reaction. - * - * This method maps the culled indices to the full network indices and calls the base engine - * to get the stoichiometry matrix entry. - * - * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). - * @throws std::out_of_range If the culled index is out of bounds for the species or reaction index map. - * @see AdaptiveEngineView::update() - */ - [[nodiscard]] int getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const reaction::Reaction& reaction - ) const override; /** * @brief Calculates the molar reaction flow for a given reaction in the active network. * + * @param ctx The scratchpad context for storing thread-local data. * @param reaction The reaction for which to calculate the flow. * @param comp Composition object containing current abundances. * @param T9 Temperature in units of 10^9 K. @@ -229,6 +218,7 @@ namespace gridfire::engine { * @throws std::runtime_error If the reaction is not part of the active reactions in the adaptive engine view. */ [[nodiscard]] double calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, double T9, @@ -240,22 +230,14 @@ namespace gridfire::engine { * * @return Reference to the LogicalReactionSet containing all active reactions. */ - [[nodiscard]] const reaction::ReactionSet& getNetworkReactions() const override; - - /** - * @brief Sets the reaction set for the base engine. - * - * This method delegates the call to the base engine to set the reaction set. - * - * @param reactions The ReactionSet to set in the base engine. - * - * @post The reaction set of the base engine is updated. - */ - void setNetworkReactions(const reaction::ReactionSet& reactions) override; + [[nodiscard]] const reaction::ReactionSet& getNetworkReactions( + scratch::StateBlob& ctx + ) const override; /** * @brief Computes timescales for all active species in the network. * + * @param ctx The scratchpad context for storing thread-local data. * @param comp Composition object containing current abundances. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -267,6 +249,7 @@ namespace gridfire::engine { * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). */ [[nodiscard]] std::expected, EngineStatus> getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -275,6 +258,7 @@ namespace gridfire::engine { /** * @brief Computes destruction timescales for all active species in the network. * + * @param ctx The scratchpad context for storing thread-local data. * @param comp Composition object containing current abundances. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -286,6 +270,7 @@ namespace gridfire::engine { * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). */ [[nodiscard]] std::expected, EngineStatus> getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -295,24 +280,9 @@ namespace gridfire::engine { * @brief Gets the base engine. * @return A const reference to the base engine. */ - [[nodiscard]] const DynamicEngine& getBaseEngine() const override { return m_baseEngine; } - - /** - * @brief Sets the screening model for the base engine. - * - * This method delegates the call to the base engine to set the electron screening model. - * - * @param model The electron screening model to set. - * - * @par Usage Example: - * @code - * AdaptiveEngineView engineView(...); - * engineView.setScreeningModel(screening::ScreeningType::WEAK); - * @endcode - * - * @post The screening model of the base engine is updated. - */ - void setScreeningModel(screening::ScreeningType model) override; + [[nodiscard]] const DynamicEngine& getBaseEngine() const override { + return m_baseEngine; + } /** * @brief Gets the screening model from the base engine. @@ -327,32 +297,24 @@ namespace gridfire::engine { * screening::ScreeningType model = engineView.getScreeningModel(); * @endcode */ - [[nodiscard]] screening::ScreeningType getScreeningModel() const override; + [[nodiscard]] screening::ScreeningType getScreeningModel( + scratch::StateBlob& ctx + ) const override; /** * @brief Gets the index of a species in the active species list. * + * @param ctx The scratchpad context for storing thread-local data. * @param species The species for which to get the index. * @return The index of the species in the active species list. * * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). * @throws std::out_of_range If the species is not part of the active species in the adaptive engine view. */ - [[nodiscard]] size_t getSpeciesIndex(const fourdst::atomic::Species &species) const override; - - /** - * @brief Maps the molar abundance vector from the active species to the full network species. - * - * @param netIn The current network input, containing temperature, density, and composition. - * @return A vector of molar abundances for all species in the full network. - * - * This method constructs a molar abundance vector for the full network by mapping the - * abundances from the active species in `netIn` to their corresponding indices in the - * full network. Species not present in `netIn` are assigned an abundance of zero. - * - * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). - */ - [[nodiscard]] std::vector mapNetInToMolarAbundanceVector(const NetIn &netIn) const override; + [[nodiscard]] size_t getSpeciesIndex( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const override; /** * @brief Primes the engine with the given network input. @@ -362,12 +324,16 @@ namespace gridfire::engine { * * This method delegates the priming operation to the base engine. */ - [[nodiscard]] PrimingReport primeEngine(const NetIn &netIn) override; + [[nodiscard]] PrimingReport primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const override; /** * @brief Collect the composition of the base engine, ensure all active species are registered, and pass * the composition back to the caller. * + * @param ctx The scratchpad context for storing thread-local data. * @param comp The current composition of the system. * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. @@ -375,17 +341,32 @@ namespace gridfire::engine { * @note This function ensures that the state of both the base engine and the adaptive view are synchronized in the * result back to the caller */ - [[nodiscard]] fourdst::composition::Composition collectComposition(const fourdst::composition::CompositionAbstract &comp, double T9, double rho) const override; + [[nodiscard]] fourdst::composition::Composition collectComposition( + scratch::StateBlob& ctx, + const fourdst::composition::CompositionAbstract &comp, + double T9, + double rho + ) const override; /** * @brief Gets the status of a species in the network. * + * @param ctx The scratchpad context for storing thread-local data. * @param species The species for which to get the status. * @return The SpeciesStatus indicating the status of the species. * - * This method delegates the call to the base engine to get the species status. If the base engine says that the species is active but it is not in the active species list of this view, the status is returned as INACTIVE_FLOW. + * This method delegates the call to the base engine to get the species status. If the base engine says that + * the species is active, but it is not in the active species list of this view, the status is returned as + * INACTIVE_FLOW. */ - [[nodiscard]] SpeciesStatus getSpeciesStatus(const fourdst::atomic::Species &species) const override; + [[nodiscard]] SpeciesStatus getSpeciesStatus( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const override; + + [[nodiscard]] std::optional>getMostRecentRHSCalculation( + scratch::StateBlob &ctx + ) const override; private: using LogManager = fourdst::logging::LogManager; @@ -397,15 +378,6 @@ namespace gridfire::engine { /** @brief The underlying engine to which this view delegates calculations. */ DynamicEngine& m_baseEngine; - /** @brief The set of species that are currently active in the network. */ - std::vector m_activeSpecies; - - /** @brief The set of reactions that are currently active in the network. */ - reaction::ReactionSet m_activeReactions; - - /** @brief A flag indicating whether the view is stale and needs to be updated. */ - bool m_isStale = true; - private: /** * @brief A struct to hold a reaction and its flow rate. @@ -415,14 +387,6 @@ namespace gridfire::engine { double flowRate; }; private: - - /** - * @brief Validates that the AdaptiveEngineView is not stale. - * - * @throws std::runtime_error If the AdaptiveEngineView is stale (i.e., `update()` has not been called). - */ - void validateState() const; - /** * @brief Calculates the molar reaction flow rate for all reactions in the full network. * @@ -431,8 +395,11 @@ namespace gridfire::engine { * and composition). It also constructs a vector of molar abundances for all species in the * full network. * + * @param ctx The scratchpad context for storing thread-local data. * @param netIn The current network input, containing temperature, density, and composition. - * @return A pair with the first element a vector of ReactionFlow structs, each containing a pointer to a reaction and its calculated flow rate and the second being a composition object where species which were not present in netIn but are present in the definition of the base engine are registered but have 0 mass fraction. + * @return A pair with the first element a vector of ReactionFlow structs, each containing a pointer to a + * reaction and its calculated flow rate and the second being a composition object where species which were not + * present in netIn but are present in the definition of the base engine are registered but have 0 mass fraction * * @par Algorithm: * 1. Iterates through all species in the base engine's network. @@ -443,6 +410,7 @@ namespace gridfire::engine { * 6. Stores the reaction pointer and its flow rate in a `ReactionFlow` struct and adds it to the returned vector. */ [[nodiscard]] std::pair, fourdst::composition::Composition> calculateAllReactionFlows( + scratch::StateBlob& ctx, const NetIn& netIn ) const; /** @@ -452,6 +420,7 @@ namespace gridfire::engine { * starting from the initial fuel species. A species is considered part of the initial fuel if its * mass fraction is above a certain threshold (`ABUNDANCE_FLOOR`). * + * @param ctx The scratchpad context for storing thread-local data. * @param netIn The current network input, containing the initial composition. * @return An unordered set of all reachable species. * @@ -463,6 +432,7 @@ namespace gridfire::engine { * 5. The process continues until a full pass over all reactions does not add any new species to the `reachable` set. */ [[nodiscard]] std::unordered_set findReachableSpecies( + scratch::StateBlob& ctx, const NetIn& netIn ) const; /** @@ -472,6 +442,7 @@ namespace gridfire::engine { * above an absolute culling threshold. The threshold is calculated by multiplying the * maximum flow rate by a relative culling threshold read from the configuration. * + * @param ctx The scratchpad context for storing thread-local data. * @param allFlows A vector of all reactions and their flow rates. * @param reachableSpecies A set of all species reachable from the initial fuel. * @param comp The current composition of the system. @@ -486,6 +457,7 @@ namespace gridfire::engine { * 5. The pointers to the kept reactions are stored in a vector and returned. */ [[nodiscard]] std::vector cullReactionsByFlow( + scratch::StateBlob& ctx, const std::vector& allFlows, const std::unordered_set& reachableSpecies, const fourdst::composition::Composition& comp, @@ -494,11 +466,10 @@ namespace gridfire::engine { typedef std::pair, std::unordered_set> RescueSet; [[nodiscard]] RescueSet rescueEdgeSpeciesDestructionChannel( + scratch::StateBlob& ctx, const fourdst::composition::Composition& comp, double T9, - double rho, - const std::vector& activeSpecies, - const reaction::ReactionSet& activeReactions + double rho ) const; /** * @brief Finalizes the set of active species and reactions. @@ -508,6 +479,7 @@ namespace gridfire::engine { * determined by collecting all reactants and products from the final reactions. * The active species list is then sorted by mass. * + * @param ctx The scratchpad context for storing thread-local data. * @param finalReactions A vector of pointers to the reactions to be included in the active set. * * @post @@ -516,7 +488,8 @@ namespace gridfire::engine { * - `m_activeSpecies` is sorted by atomic mass. */ void finalizeActiveSet( + scratch::StateBlob& ctx, const std::vector& finalReactions - ); + ) const; }; } diff --git a/src/include/gridfire/engine/views/engine_defined.h b/src/include/gridfire/engine/views/engine_defined.h index 16da8efd..39479037 100644 --- a/src/include/gridfire/engine/views/engine_defined.h +++ b/src/include/gridfire/engine/views/engine_defined.h @@ -8,6 +8,8 @@ #include "gridfire/config/config.h" +#include "gridfire/engine/scratchpads/blob.h" + #include "fourdst/config/config.h" #include "fourdst/logging/logging.h" @@ -30,7 +32,9 @@ namespace gridfire::engine { * @brief Gets the list of active species in the network defined by the file. * @return A const reference to the vector of active species. */ - [[nodiscard]] const std::vector& getNetworkSpecies() const override; + [[nodiscard]] const std::vector& getNetworkSpecies( + scratch::StateBlob& ctx + ) const override; // --- DynamicEngine Interface --- /** @@ -39,18 +43,22 @@ namespace gridfire::engine { * @param comp A Composition object containing the current composition of the system * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. + * @param trust * @return A StepDerivatives struct containing the derivatives of the active species and the * nuclear energy generation rate. * * @throws std::runtime_error If the view is stale (i.e., `update()` has not been called after `setNetworkFile()`). */ - [[nodiscard]] std::expected, engine::EngineStatus> calculateRHSAndEnergy( + [[nodiscard]] std::expected, EngineStatus> calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const override; [[nodiscard]] EnergyDerivatives calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -66,6 +74,7 @@ namespace gridfire::engine { * @throws std::runtime_error If the view is stale. */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -82,6 +91,7 @@ namespace gridfire::engine { * @throws std::runtime_error If the view is stale. */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -99,33 +109,13 @@ namespace gridfire::engine { * @throws std::runtime_error If the view is stale. */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, const SparsityPattern &sparsityPattern ) const override; - /** - * @brief Generates the stoichiometry matrix for the active reactions and species. - * - * @throws std::runtime_error If the view is stale. - */ - void generateStoichiometryMatrix() override; - - /** - * @brief Gets an entry from the stoichiometry matrix for the active species and reactions. - * - * @param species The species for which to get the stoichiometric coefficient. - * @param reaction The reaction for which to get the stoichiometric coefficient. - * @return The stoichiometric coefficient for the given species and reaction. - * - * @throws std::runtime_error If the view is stale. - * @throws std::out_of_range If an index is out of bounds. - */ - [[nodiscard]] int getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const reaction::Reaction& reaction - ) const override; /** * @brief Calculates the molar reaction flow for a given reaction in the active network. * @@ -138,6 +128,7 @@ namespace gridfire::engine { * @throws std::runtime_error If the view is stale or if the reaction is not in the active set. */ [[nodiscard]] double calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction& reaction, const fourdst::composition::CompositionAbstract &comp, double T9, @@ -150,16 +141,9 @@ namespace gridfire::engine { * * @throws std::runtime_error If the view is stale. */ - [[nodiscard]] const reaction::ReactionSet& getNetworkReactions() const override; - - /** - * @brief Sets the active reactions in the network. - * - * @param reactions The ReactionSet containing the reactions to set as active. - * - * @post The view is marked as stale and will need to be updated. - */ - void setNetworkReactions(const reaction::ReactionSet& reactions) override; + [[nodiscard]] const reaction::ReactionSet& getNetworkReactions( + scratch::StateBlob& ctx + ) const override; /** * @brief Computes timescales for all active species in the network. @@ -171,8 +155,8 @@ namespace gridfire::engine { * * @throws std::runtime_error If the view is stale. */ - [[nodiscard]] std::expected, engine::EngineStatus> - getSpeciesTimescales( + [[nodiscard]] std::expected, EngineStatus>getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -188,8 +172,8 @@ namespace gridfire::engine { * * @throws std::runtime_error If the view is stale. */ - [[nodiscard]] std::expected, engine::EngineStatus> - getSpeciesDestructionTimescales( + [[nodiscard]] std::expected, EngineStatus> getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -206,29 +190,19 @@ namespace gridfire::engine { * * @post If the view was stale, it is rebuilt and is no longer stale. */ - fourdst::composition::Composition update(const NetIn &netIn) override; - - /** - * @brief Checks if the engine view is stale. - * - * @param netIn The current network input (unused). - * @return True if the view is stale and needs to be updated; false otherwise. - */ - [[deprecated]] bool isStale(const NetIn& netIn) override; - - /** - * @brief Sets the screening model for the base engine. - * - * @param model The screening model to set. - */ - void setScreeningModel(screening::ScreeningType model) override; + fourdst::composition::Composition project( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const override; /** * @brief Gets the screening model from the base engine. * * @return The current screening model type. */ - [[nodiscard]] screening::ScreeningType getScreeningModel() const override; + [[nodiscard]] screening::ScreeningType getScreeningModel( + scratch::StateBlob& ctx + ) const override; /** @brief Maps a species from the full network to its index in the defined active network. * @@ -237,21 +211,20 @@ namespace gridfire::engine { * * @throws std::runtime_error If the species is not in the active set. */ - [[nodiscard]] size_t getSpeciesIndex(const fourdst::atomic::Species &species) const override; - - /** - * @brief Map from a NetIn object to a vector of molar abundances for the active species. - * @param netIn The NetIn object containing the full network abundances. - * @return A vector of molar abundances for the active species. - */ - [[nodiscard]] std::vector mapNetInToMolarAbundanceVector(const NetIn &netIn) const override; + [[nodiscard]] size_t getSpeciesIndex( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const override; /** * @brief Prime the engine view for calculations. This will delegate to the base engine. * @param netIn The current network input. * @return The PrimingReport from the base engine. */ - [[nodiscard]] PrimingReport primeEngine(const NetIn &netIn) override; + [[nodiscard]] PrimingReport primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const override; /** * @brief Collects a Composition object from the base engine. @@ -261,7 +234,12 @@ namespace gridfire::engine { * @param rho The density in g/cm^3. * @return A composition object representing the state of the engine stack and the current view. */ - [[nodiscard]] fourdst::composition::Composition collectComposition(const fourdst::composition::CompositionAbstract &comp, double T9, double rho) const override; + [[nodiscard]] fourdst::composition::Composition collectComposition( + scratch::StateBlob& ctx, + const fourdst::composition::CompositionAbstract &comp, + double T9, + double rho + ) const override; /** * @brief Gets the status of a species in the active network. @@ -269,25 +247,19 @@ namespace gridfire::engine { * @param species The species for which to get the status. * @return The SpeciesStatus indicating if the species is active, inactive, or not present. */ - [[nodiscard]] SpeciesStatus getSpeciesStatus(const fourdst::atomic::Species &species) const override; + [[nodiscard]] SpeciesStatus getSpeciesStatus( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const override; + + [[nodiscard]] std::optional>getMostRecentRHSCalculation( + scratch::StateBlob &ctx + ) const override; protected: bool m_isStale = true; GraphEngine& m_baseEngine; private: - quill::Logger* m_logger = fourdst::logging::LogManager::getInstance().getLogger("log"); ///< Logger instance for trace and debug information. - ///< Active species in the defined engine. - std::set m_activeSpecies; - - ///< Cache for the active species vector to avoid dangling references. - mutable std::optional> m_activeSpeciesVectorCache = std::nullopt; - - ///< Active reactions in the defined engine. - reaction::ReactionSet m_activeReactions; - - ///< Maps indices of active species to indices in the full network. - std::vector m_speciesIndexMap; - ///< Maps indices of active reactions to indices in the full network. - std::vector m_reactionIndexMap; + quill::Logger* m_logger = LogManager::getInstance().getLogger("log"); ///< Logger instance for trace and debug information. private: /** * @brief Constructs the species index map. @@ -299,7 +271,9 @@ namespace gridfire::engine { * * @throws std::runtime_error If an active species is not found in the base engine's species list. */ - [[nodiscard]] std::vector constructSpeciesIndexMap() const; + [[nodiscard]] std::vector constructSpeciesIndexMap( + scratch::StateBlob& ctx + ) const; /** * @brief Constructs the reaction index map. @@ -311,7 +285,9 @@ namespace gridfire::engine { * * @throws std::runtime_error If an active reaction is not found in the base engine's reaction list. */ - [[nodiscard]] std::vector constructReactionIndexMap() const; + [[nodiscard]] std::vector constructReactionIndexMap( + scratch::StateBlob& ctx + ) const; /** * @brief Maps a vector of culled abundances to a vector of full abundances. @@ -320,7 +296,10 @@ namespace gridfire::engine { * @return A vector of abundances for the full network, with the abundances of the active * species copied from the defined vector. */ - [[nodiscard]] std::vector mapViewToFull(const std::vector& defined) const; + [[nodiscard]] std::vector mapViewToFull( + scratch::StateBlob& ctx, + const std::vector& defined + ) const; /** * @brief Maps a vector of full abundances to a vector of culled abundances. @@ -329,7 +308,10 @@ namespace gridfire::engine { * @return A vector of abundances for the active species, with the abundances of the active * species copied from the full vector. */ - [[nodiscard]] std::vector mapFullToView(const std::vector& full) const; + [[nodiscard]] static std::vector mapFullToView( + scratch::StateBlob& ctx, + const std::vector& full + ); /** * @brief Maps a culled species index to a full species index. @@ -339,7 +321,10 @@ namespace gridfire::engine { * * @throws std::out_of_range If the defined index is out of bounds for the species index map. */ - [[nodiscard]] size_t mapViewToFullSpeciesIndex(size_t definedSpeciesIndex) const; + [[nodiscard]] size_t mapViewToFullSpeciesIndex( + scratch::StateBlob& ctx, + size_t definedSpeciesIndex + ) const; /** * @brief Maps a culled reaction index to a full reaction index. @@ -349,11 +334,15 @@ namespace gridfire::engine { * * @throws std::out_of_range If the defined index is out of bounds for the reaction index map. */ - [[nodiscard]] size_t mapViewToFullReactionIndex(size_t definedReactionIndex) const; + [[nodiscard]] size_t mapViewToFullReactionIndex( + scratch::StateBlob& ctx, + size_t definedReactionIndex + ) const; - void validateNetworkState() const; - - void collect(const std::vector& peNames); + void collect( + scratch::StateBlob& ctx, + const std::vector& peNames + ) const; }; @@ -366,6 +355,9 @@ namespace gridfire::engine { ); [[nodiscard]] std::string getNetworkFile() const { return m_fileName; } [[nodiscard]] const io::NetworkFileParser& getParser() const { return m_parser; } + + + private: using LogManager = LogManager; Config m_config; diff --git a/src/include/gridfire/engine/views/engine_multiscale.h b/src/include/gridfire/engine/views/engine_multiscale.h index 8565763e..23e7921e 100644 --- a/src/include/gridfire/engine/views/engine_multiscale.h +++ b/src/include/gridfire/engine/views/engine_multiscale.h @@ -4,6 +4,8 @@ #include "gridfire/engine/views/engine_view_abstract.h" #include "gridfire/engine/engine_graph.h" +#include "gridfire/engine/scratchpads/blob.h" + #include "sundials/sundials_linearsolver.h" #include "sundials/sundials_matrix.h" #include "sundials/sundials_nvector.h" @@ -81,22 +83,24 @@ namespace gridfire::engine { */ explicit MultiscalePartitioningEngineView(DynamicEngine& baseEngine); - ~MultiscalePartitioningEngineView() override; - /** * @brief Gets the list of species in the network. * @return A const reference to the vector of `Species` objects representing all species * in the underlying base engine. This view does not alter the species list itself, * only how their abundances are evolved. */ - [[nodiscard]] const std::vector & getNetworkSpecies() const override; + [[nodiscard]] const std::vector & getNetworkSpecies( + scratch::StateBlob& ctx + ) const override; /** * @brief Calculates the right-hand side (dY/dt) and energy generation. * + * @param ctx The scratch data for thread-local storage. * @param comp The current composition. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. + * @param trust * @return A `std::expected` containing `StepDerivatives` on success, or a * `StaleEngineError` if the engine's QSE cache does not contain a solution * for the given state. @@ -119,19 +123,23 @@ namespace gridfire::engine { * (T9, rho, Y_full). This indicates `update()` was not called recently enough. */ [[nodiscard]] std::expected, engine::EngineStatus> calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const override; /** * @brief Calculates the energy generation rate derivatives with respect to abundances. + * @param ctx The scratch data for thread-local storage. * @param comp The current composition. * @param T9 The temperature in units of 10^9 K. * @param rho The density in g/cm^3. * @return The energy generation rate derivatives (dEps/dT and dEps/drho). */ [[nodiscard]] EnergyDerivatives calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -140,6 +148,7 @@ namespace gridfire::engine { /** * @brief Generates the Jacobian matrix for the current state. * + * @param ctx The scratch data for thread-local storage. * @param comp The current composition. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -161,6 +170,7 @@ namespace gridfire::engine { * without a valid partition. */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -169,6 +179,7 @@ namespace gridfire::engine { /** * @brief Generates the Jacobian matrix for a subset of active species. * + * @param ctx The scratch data for thread-local storage. * @param comp The current composition. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -190,6 +201,7 @@ namespace gridfire::engine { * @throws exceptions::StaleEngineError If the QSE cache misses. */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -199,6 +211,7 @@ namespace gridfire::engine { /** * @brief Generates the Jacobian matrix using a sparsity pattern. * + * @param ctx The scratch data for thread-local storage. * @param comp The current composition. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -218,47 +231,17 @@ namespace gridfire::engine { * @throws exceptions::StaleEngineError If the QSE cache misses. */ [[nodiscard]] NetworkJacobian generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, const SparsityPattern &sparsityPattern ) const override; - /** - * @brief Generates the stoichiometry matrix for the network. - * - * @par Purpose - * To prepare the stoichiometry matrix for later queries. - * - * @par How - * This method delegates directly to the base engine's `generateStoichiometryMatrix()`. - * The stoichiometry is based on the full, unpartitioned network. - */ - void generateStoichiometryMatrix() override; - - /** - * @brief Gets an entry from the stoichiometry matrix. - * - * @param species Species to look up stoichiometry for. - * @param reaction Reaction to find. - * @return Stoichiometric coefficient for the species in the reaction. - * - * @par Purpose - * To query the stoichiometric relationship between a species and a reaction. - * - * @par How - * This method delegates directly to the base engine's `getStoichiometryMatrixEntry()`. - * - * @pre `generateStoichiometryMatrix()` must have been called. - */ - [[nodiscard]] int getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const reaction::Reaction& reaction - ) const override; - /** * @brief Calculates the molar reaction flow for a given reaction. * + * @param ctx The scratch data for thread-local storage. * @param reaction The reaction for which to calculate the flow. * @param comp The current composition. * @param T9 Temperature in units of 10^9 K. @@ -279,6 +262,7 @@ namespace gridfire::engine { * @throws StaleEngineError If the QSE cache misses. */ [[nodiscard]] double calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, double T9, @@ -291,31 +275,14 @@ namespace gridfire::engine { * @return A const reference to the `LogicalReactionSet` from the base engine, * containing all reactions in the full network. */ - [[nodiscard]] const reaction::ReactionSet & getNetworkReactions() const override; - - /** - * @brief Sets the set of logical reactions in the network. - * - * @param reactions The set of logical reactions to use. - * - * @par Purpose - * To modify the reaction network. - * - * @par How - * This operation is not supported by the `MultiscalePartitioningEngineView` as it - * would invalidate the partitioning logic. It logs a critical error and throws an - * exception. Network modifications should be done on the base engine before it is - * wrapped by this view. - * - * @throws exceptions::UnableToSetNetworkReactionsError Always. - */ - void setNetworkReactions( - const reaction::ReactionSet &reactions - ) override; + [[nodiscard]] const reaction::ReactionSet & getNetworkReactions( + scratch::StateBlob& ctx + ) const override; /** * @brief Computes timescales for all species in the network. * + * @param ctx The scratch data for thread-local storage. * @param comp The current composition. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -333,8 +300,8 @@ namespace gridfire::engine { * @pre The engine must have a valid QSE cache entry for the given state. * @throws StaleEngineError If the QSE cache misses. */ - [[nodiscard]] std::expected, engine::EngineStatus> - getSpeciesTimescales( + [[nodiscard]] std::expected, EngineStatus> getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -343,6 +310,7 @@ namespace gridfire::engine { /** * @brief Computes destruction timescales for all species in the network. * + * @param ctx The scratch data for thread-local storage. * @param comp The current composition. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -360,8 +328,8 @@ namespace gridfire::engine { * @pre The engine must have a valid QSE cache entry for the given state. * @throws StaleEngineError If the QSE cache misses. */ - [[nodiscard]] std::expected, engine::EngineStatus> - getSpeciesDestructionTimescales( + [[nodiscard]] std::expected, EngineStatus> getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -370,6 +338,7 @@ namespace gridfire::engine { /** * @brief Updates the internal state of the engine, performing partitioning and QSE equilibration. * + * @param ctx The scratch data for thread-local storage. * @param netIn A struct containing the current network input: temperature, density, and composition. * @return The new composition after QSE species have been brought to equilibrium. * @@ -394,38 +363,11 @@ namespace gridfire::engine { * The `m_qse_abundance_cache` is populated with the QSE solution for the given state. * The returned composition reflects the new equilibrium. */ - fourdst::composition::Composition update( + fourdst::composition::Composition project( + scratch::StateBlob& ctx, const NetIn &netIn - ) override; + ) const override; - /** - * @brief Checks if the engine's internal state is stale relative to the provided conditions. - * - * @param netIn A struct containing the current network input. - * @return `true` if the engine is stale, `false` otherwise. - * - * @par Purpose - * To determine if `update()` needs to be called. - * - * @par How - * It creates a `QSECacheKey` from the `netIn` data and checks for its - * existence in the `m_qse_abundance_cache`. A cache miss indicates the engine is - * stale because it does not have a valid QSE partition for the current conditions. - * It also queries the base engine's `isStale()` method. - */ - bool isStale(const NetIn& netIn) override; - - /** - * @brief Sets the electron screening model. - * - * @param model The type of screening model to use for reaction rate calculations. - * - * @par How - * This method delegates directly to the base engine's `setScreeningModel()`. - */ - void setScreeningModel( - screening::ScreeningType model - ) override; /** * @brief Gets the current electron screening model. @@ -435,20 +377,23 @@ namespace gridfire::engine { * @par How * This method delegates directly to the base engine's `getScreeningModel()`. */ - [[nodiscard]] screening::ScreeningType getScreeningModel() const override; + [[nodiscard]] screening::ScreeningType getScreeningModel( + scratch::StateBlob& ctx + ) const override; /** * @brief Gets the base engine. * * @return A const reference to the base engine. */ - const DynamicEngine & getBaseEngine() const override; + [[nodiscard]] const DynamicEngine & getBaseEngine() const override; /** * @brief Partitions the network based on timescales from a `NetIn` struct. * + * @param ctx The scratch data for thread-local storage. * @param netIn A struct containing the current network input. * * @par Purpose @@ -459,12 +404,14 @@ namespace gridfire::engine { * primary `partitionNetwork` method. */ fourdst::composition::Composition partitionNetwork( + scratch::StateBlob& ctx, const NetIn &netIn - ); + ) const; /** * @brief Exports the network to a DOT file for visualization. * + * @param ctx The scratch data for thread-local storage. * @param filename The name of the DOT file to create. * @param comp Composition object * @param T9 Temperature in units of 10^9 K. @@ -478,6 +425,7 @@ namespace gridfire::engine { * currently add any partitioning information to the output graph. */ void exportToDot( + scratch::StateBlob &ctx, const std::string& filename, const fourdst::composition::Composition &comp, double T9, @@ -487,24 +435,17 @@ namespace gridfire::engine { /** * @brief Gets the index of a species in the full network. * + * @param ctx The scratch data for thread-local storage. * @param species The species to get the index of. * @return The index of the species in the base engine's network. * * @par How * This method delegates directly to the base engine's `getSpeciesIndex()`. */ - [[nodiscard]] size_t getSpeciesIndex(const fourdst::atomic::Species &species) const override; - - /** - * @brief Maps a `NetIn` struct to a molar abundance vector for the full network. - * - * @param netIn A struct containing the current network input. - * @return A vector of molar abundances corresponding to the species order in the base engine. - * - * @par How - * This method delegates directly to the base engine's `mapNetInToMolarAbundanceVector()`. - */ - [[nodiscard]] std::vector mapNetInToMolarAbundanceVector(const NetIn &netIn) const override; + [[nodiscard]] size_t getSpeciesIndex( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const override; /** * @brief Primes the engine with a specific species. @@ -519,7 +460,10 @@ namespace gridfire::engine { * This method delegates directly to the base engine's `primeEngine()`. The * multiscale view does not currently interact with the priming process. */ - [[nodiscard]] PrimingReport primeEngine(const NetIn &netIn) override; + [[nodiscard]] PrimingReport primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const override; /** * @brief Gets the fast species in the network. @@ -534,7 +478,10 @@ namespace gridfire::engine { * * @pre `partitionNetwork()` must have been called. */ - [[nodiscard]] std::vector getFastSpecies() const; + [[nodiscard]] std::vector getFastSpecies( + scratch::StateBlob& ctx + ) const; + /** * @brief Gets the dynamic species in the network. * @@ -548,11 +495,14 @@ namespace gridfire::engine { * * @pre `partitionNetwork()` must have been called. */ - [[nodiscard]] const std::vector& getDynamicSpecies() const; + [[nodiscard]] static const std::vector& getDynamicSpecies( + scratch::StateBlob& ctx + ); /** * @brief Checks if a species is involved in the partitioned network. * + * @param ctx The scratch data for thread-local storage. * @param species The species to check. * @return `true` if the species is in either the dynamic or algebraic sets, `false` otherwise. * @@ -564,28 +514,41 @@ namespace gridfire::engine { * * @pre `partitionNetwork()` must have been called. */ - bool involvesSpecies(const fourdst::atomic::Species &species) const; + static bool involvesSpecies( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ); /** * @brief Check if a species is involved in the QSE (algebraic) set. + * @param ctx The scratch data for thread-local storage. * @param species The species to check. * @return Boolean indicating if the species is in the algebraic set. */ - bool involvesSpeciesInQSE(const fourdst::atomic::Species &species) const; + static bool involvesSpeciesInQSE( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ); /** * @brief Check if a species is involved in the dynamic set. + * @param ctx The scratch data for thread-local storage. * @param species The species to check. * @return Boolean indicating if the species is in the dynamic set. */ - bool involvesSpeciesInDynamic(const fourdst::atomic::Species &species) const; + static bool involvesSpeciesInDynamic( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ); /** * @brief Gets a normalized composition with QSE species equilibrated. * + * @param ctx The scratch data for thread-local storage. * @param comp The input composition. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. + * @param trust * @return A new `Composition` object with algebraic species set to their equilibrium values. * * @par Purpose @@ -598,23 +561,36 @@ namespace gridfire::engine { * @pre The engine must have a valid QSE partition for the given state. * @throws StaleEngineError If the QSE cache misses. */ - fourdst::composition::Composition getNormalizedEquilibratedComposition(const fourdst::composition::CompositionAbstract& comp, double T9, double rho) const; + fourdst::composition::Composition getNormalizedEquilibratedComposition( + scratch::StateBlob& ctx, + const fourdst::composition::CompositionAbstract& comp, + double T9, + double rho, + bool trust + ) const; /** * @brief Collect the composition from this and sub engines. * @details This method operates by injecting the current equilibrium abundances for algebraic species into * the composition object so that they can be bubbled up to the caller. + * @param ctx The scratch data for thread-local storage. * @param comp Input Composition * @param T9 * @param rho * @return New composition which is comp + any edits from lower levels + the equilibrium abundances of all algebraic species. * @throws BadCollectionError: if there is a species in the algebraic species set which does not show up in the reported composition from the base engine.:w */ - fourdst::composition::Composition collectComposition(const fourdst::composition::CompositionAbstract &comp, double T9, double rho) const override; + fourdst::composition::Composition collectComposition( + scratch::StateBlob& ctx, + const fourdst::composition::CompositionAbstract &comp, + double T9, + double rho + ) const override; /** * @brief Gets the status of a species in the network. * + * @param ctx The scratch data for thread-local storage. * @param species The species to query. * @return The `SpeciesStatus` indicating if the species is dynamic, algebraic, or not involved. * @@ -627,9 +603,15 @@ namespace gridfire::engine { * * @pre `partitionNetwork()` must have been called. */ - SpeciesStatus getSpeciesStatus(const fourdst::atomic::Species &species) const override; + SpeciesStatus getSpeciesStatus( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const override; - private: + [[nodiscard]] std::optional>getMostRecentRHSCalculation( + scratch::StateBlob & + ) const override; + public: /** * @brief Struct representing a QSE group. * @@ -675,9 +657,9 @@ namespace gridfire::engine { return os; } - bool contains(const fourdst::atomic::Species& species) const; - bool containsAlgebraic(const fourdst::atomic::Species &species) const; - bool containsSeed(const fourdst::atomic::Species &species) const; + [[nodiscard]] bool contains(const fourdst::atomic::Species& species) const; + [[nodiscard]] bool containsAlgebraic(const fourdst::atomic::Species &species) const; + [[nodiscard]] bool containsSeed(const fourdst::atomic::Species &species) const; }; class QSESolver { @@ -698,6 +680,7 @@ namespace gridfire::engine { ~QSESolver(); fourdst::composition::Composition solve( + scratch::StateBlob& ctx, const fourdst::composition::Composition& comp, double T9, double rho @@ -706,6 +689,9 @@ namespace gridfire::engine { size_t solves() const; void log_diagnostics(const QSEGroup &group, const fourdst::composition::Composition &comp) const; + + std::unique_ptr clone() const; + std::unique_ptr clone(SUNContext sun_ctx) const; private: static int sys_func( @@ -730,8 +716,7 @@ namespace gridfire::engine { const std::unordered_map& qse_solve_species_index_map; const std::vector& qse_solve_species; const QSESolver& instance; - std::vector row_scaling_factors; - const double initial_group_mass; + scratch::StateBlob& ctx; }; private: @@ -780,46 +765,12 @@ namespace gridfire::engine { * @brief The base engine to which this view delegates calculations. */ DynamicEngine& m_baseEngine; - /** - * @brief The list of identified equilibrium groups. - */ - std::vector m_qse_groups; - - /** - * @brief A set of solvers, one for each QSE group - */ - std::vector> m_qse_solvers; - /** - * @brief The simplified set of species presented to the solver (the "slow" species). - */ - std::vector m_dynamic_species; - /** - * @brief Species that are treated as algebraic (in QSE) in the QSE groups. - */ - std::vector m_algebraic_species; - - /** - * @brief Map from species to their calculated abundances in the QSE state. - */ - std::unordered_map m_algebraic_abundances; - - /** - * @brief Indices of all species considered active in the current partition (dynamic + algebraic). - */ - std::vector m_activeSpeciesIndices; - /** - * @brief Indices of all reactions involving only active species. - */ - std::vector m_activeReactionIndices; - - mutable std::unordered_map m_composition_cache; - - SUNContext m_sun_ctx = nullptr; private: /** * @brief Partitions the network by timescale. * + * @param ctx The scratch data for thread-local storage. * @param comp Vector of current molar abundances for all species. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -836,12 +787,14 @@ namespace gridfire::engine { * (e.g., a factor of 100). */ std::vector> partitionByTimescale( + scratch::StateBlob& ctx, const fourdst::composition::Composition &comp, double T9, double rho ) const; std::pair group_is_a_qse_cluster( + scratch::StateBlob& ctx, const fourdst::composition::Composition &comp, double T9, double rho, @@ -849,6 +802,7 @@ namespace gridfire::engine { ) const; bool group_is_a_qse_pipeline( + scratch::StateBlob& ctx, const fourdst::composition::Composition &comp, double T9, double rho, @@ -858,6 +812,7 @@ namespace gridfire::engine { /** * @brief Validates candidate QSE groups using flux analysis. * + * @param ctx The scratch data for thread-local storage. * @param candidate_groups A vector of candidate QSE groups. * @param comp Vector of current molar abundances for the full network. * @param T9 Temperature in units of 10^9 K. @@ -876,6 +831,7 @@ namespace gridfire::engine { * to the returned vector. */ FluxValidationResult validateGroupsWithFluxAnalysis( + scratch::StateBlob& ctx, const std::vector &candidate_groups, const fourdst::composition::Composition &comp, double T9, @@ -885,6 +841,7 @@ namespace gridfire::engine { /** * @brief Solves for the QSE abundances of the algebraic species in a given state. * + * @param ctx The scratch data for thread-local storage. * @param comp Vector of current molar abundances for all species in the base engine. * @param T9 Temperature in units of 10^9 K. * @param rho Density in g/cm^3. @@ -902,15 +859,17 @@ namespace gridfire::engine { * @pre The input state (Y_full, T9, rho) must be a valid physical state. * @post The algebraic species in the QSE cache are updated with the new equilibrium abundances. */ - fourdst::composition::Composition solveQSEAbundances( + auto solveQSEAbundances( + scratch::StateBlob &ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho - ) const; + ) const -> fourdst::composition::Composition; /** * @brief Identifies the pool with the slowest mean timescale. * + * @param ctx The scratch data for thread-local storage. * @param pools A vector of vectors of species indices, where each inner vector represents a * timescale pool. * @param comp Vector of current molar abundances for the full network. @@ -926,6 +885,7 @@ namespace gridfire::engine { * pool and returns the index of the pool with the maximum mean timescale. */ size_t identifyMeanSlowestPool( + scratch::StateBlob& ctx, const std::vector>& pools, const fourdst::composition::Composition &comp, double T9, @@ -935,6 +895,7 @@ namespace gridfire::engine { /** * @brief Builds a connectivity graph from a species pool. * + * @param ctx The scratch data for thread-local storage. * @param species_pool A vector of species indices representing a species pool. * @param comp * @param T9 @@ -951,13 +912,17 @@ namespace gridfire::engine { * that reaction that are also in the pool. */ std::unordered_map> buildConnectivityGraph( - const std::vector& species_pool, const fourdst::composition::Composition &comp, double T9, double - rho + scratch::StateBlob& ctx, + const std::vector& species_pool, + const fourdst::composition::Composition &comp, + double T9, + double rho ) const; /** * @brief Constructs candidate QSE groups from connected timescale pools. * + * @param ctx The scratch data for thread-local storage. * @param candidate_pools A vector of vectors of species indices, where each inner vector * represents a connected pool of species with similar fast timescales. * @param comp Vector of current molar abundances. @@ -975,6 +940,7 @@ namespace gridfire::engine { * @post A list of candidate `QSEGroup` objects is returned. */ std::vector constructCandidateGroups( + scratch::StateBlob& ctx, const std::vector>& candidate_pools, const fourdst::composition::Composition &comp, double T9, @@ -984,6 +950,7 @@ namespace gridfire::engine { /** * @brief Analyzes the connectivity of timescale pools. * + * @param ctx The scratch data for thread-local storage. * @param timescale_pools A vector of vectors of species indices, where each inner vector * represents a timescale pool. * @param comp @@ -1002,11 +969,15 @@ namespace gridfire::engine { * The resulting components from all pools are collected and returned. */ std::vector> analyzeTimescalePoolConnectivity( - const std::vector> ×cale_pools, const fourdst::composition::Composition & - comp, double T9, double rho + scratch::StateBlob& ctx, + const std::vector> ×cale_pools, + const fourdst::composition::Composition &comp, + double T9, + double rho ) const; std::vector pruneValidatedGroups( + scratch::StateBlob& ctx, const std::vector &groups, const std::vector &groupReactions, const fourdst::composition::Composition &comp, @@ -1015,9 +986,13 @@ namespace gridfire::engine { ) const; static std::vector merge_coupled_groups( + scratch::StateBlob& ctx, const std::vector &groups, const std::vector &groupReactions ); + + public: + }; } diff --git a/src/include/gridfire/engine/views/engine_priming.h b/src/include/gridfire/engine/views/engine_priming.h index 14cbb11d..d607bdc0 100644 --- a/src/include/gridfire/engine/views/engine_priming.h +++ b/src/include/gridfire/engine/views/engine_priming.h @@ -1,10 +1,13 @@ #pragma once #include "gridfire/engine/views/engine_defined.h" +#include "gridfire/engine/scratchpads/blob.h" + #include "fourdst/logging/logging.h" #include "fourdst/atomic/atomicSpecies.h" + #include "quill/Logger.h" #include @@ -35,7 +38,11 @@ namespace gridfire::engine { * @throws std::out_of_range If primingSymbol is not found in the species registry. * @throws std::runtime_error If no reactions contain the priming species. */ - NetworkPrimingEngineView(const std::string& primingSymbol, GraphEngine& baseEngine); + NetworkPrimingEngineView( + scratch::StateBlob& ctx, + const std::string& primingSymbol, + GraphEngine& baseEngine + ); /** * @brief Constructs the view using an existing Species object. * @@ -45,7 +52,11 @@ namespace gridfire::engine { * @post The view will contain only reactions that involve the priming species. * @throws std::runtime_error If no reactions contain the priming species. */ - NetworkPrimingEngineView(const fourdst::atomic::Species& primingSpecies, GraphEngine& baseEngine); + NetworkPrimingEngineView( + scratch::StateBlob& ctx, + const fourdst::atomic::Species& primingSpecies, + GraphEngine& baseEngine + ); private: @@ -63,6 +74,7 @@ namespace gridfire::engine { * @throws std::runtime_error If no reactions involve the priming species. */ [[nodiscard]] std::vector constructPrimingReactionSet( + scratch::StateBlob& ctx, const fourdst::atomic::Species& primingSpecies, const GraphEngine& baseEngine ) const; diff --git a/src/include/gridfire/exceptions/error_scratchpad.h b/src/include/gridfire/exceptions/error_scratchpad.h new file mode 100644 index 00000000..ac69a384 --- /dev/null +++ b/src/include/gridfire/exceptions/error_scratchpad.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +#include "gridfire/exceptions/error_gridfire.h" + +namespace gridfire::exceptions { + class ScratchPadError : public GridFireError { + public: + explicit ScratchPadError(const std::string& msg) + : GridFireError("ScratchPadError: " + msg) {} + }; +} \ No newline at end of file diff --git a/src/include/gridfire/io/generative/python.h b/src/include/gridfire/io/generative/python.h index e45976e6..f7c986df 100644 --- a/src/include/gridfire/io/generative/python.h +++ b/src/include/gridfire/io/generative/python.h @@ -5,6 +5,7 @@ #include "gridfire/reaction/reaction.h" #include "gridfire/engine/engine_abstract.h" +#include "gridfire/engine/scratchpads/blob.h" /** * @brief Namespace for generative input/output functionalities. @@ -49,16 +50,17 @@ namespace gridfire::io::gen { * This function converts the given dynamic engine into a Python script * that can be used to recreate the engine's functionality in Python. */ - std::string exportEngineToPy(const engine::DynamicEngine& engine); + std::string exportEngineToPy(engine::scratch::StateBlob& ctx, engine::DynamicEngine& engine); /** * @brief Exports a dynamic engine to a Python file. * + * @param ctx * @param engine The dynamic engine to export. * @param fileName The name of the file to write the Python script to. * * This function writes the Python script representation of the given * dynamic engine to the specified file. */ - void exportEngineToPy(const engine::DynamicEngine& engine, const std::string& fileName); + void exportEngineToPy(engine::scratch::StateBlob &ctx, const engine::DynamicEngine& engine, const std::string& fileName); } diff --git a/src/include/gridfire/policy/policy_abstract.h b/src/include/gridfire/policy/policy_abstract.h index e89fb202..d04f44dc 100644 --- a/src/include/gridfire/policy/policy_abstract.h +++ b/src/include/gridfire/policy/policy_abstract.h @@ -19,11 +19,13 @@ #include "gridfire/reaction/reaction.h" #include "gridfire/engine/engine_abstract.h" #include "gridfire/partition/partition.h" +#include "gridfire/utils/logging.h" #include #include #include "gridfire/engine/types/engine_types.h" +#include "gridfire/engine/scratchpads/blob.h" namespace gridfire::policy { @@ -43,6 +45,28 @@ namespace gridfire::policy { INITIALIZED_VERIFIED }; + inline std::string NetworkPolicyStatusToString(NetworkPolicyStatus status) { + switch (status) { + case NetworkPolicyStatus::UNINITIALIZED: + return "UNINITIALIZED"; + case NetworkPolicyStatus::INITIALIZED_UNVERIFIED: + return "INITIALIZED_UNVERIFIED"; + case NetworkPolicyStatus::MISSING_KEY_REACTION: + return "MISSING_KEY_REACTION"; + case NetworkPolicyStatus::MISSING_KEY_SPECIES: + return "MISSING_KEY_SPECIES"; + case NetworkPolicyStatus::INITIALIZED_VERIFIED: + return "INITIALIZED_VERIFIED"; + default: + return "UNKNOWN_STATUS"; + } + } + + struct ConstructionResults { + const engine::DynamicEngine& engine; + std::unique_ptr scratch_blob; + }; + /** * @class NetworkPolicy * @brief Abstract interface for policies that construct DynamicEngine networks from a seed composition. @@ -139,7 +163,7 @@ namespace gridfire::policy { * NetOut out = solver.evaluate(netIn, true); * @endcode */ - [[nodiscard]] virtual engine::DynamicEngine& construct() = 0; + [[nodiscard]] virtual ConstructionResults construct() = 0; /** * @brief Returns the current verification/construction status of the policy. @@ -160,6 +184,8 @@ namespace gridfire::policy { [[nodiscard]] virtual std::vector get_engine_types_stack() const = 0; [[nodiscard]] virtual const std::unique_ptr& get_partition_function() const = 0; + + [[nodiscard]] virtual std::unique_ptr get_stack_scratch_blob() const = 0; }; /** @@ -217,3 +243,27 @@ namespace gridfire::policy { }; } +// 1. Define the BASE specialization first +template<> +struct std::formatter { + static constexpr auto parse(const format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const gridfire::policy::NetworkPolicy& policy, FormatContext& ctx) const { + std::vector engine_types = policy.get_engine_types_stack(); + std::ranges::reverse(engine_types); + + return format_to( + ctx.out(), + "{}(Status: {}, Engine Stack Size: {}, Engine Stack: <(TOP) [{}] (BOTTOM)>)", + policy.name(), + gridfire::policy::NetworkPolicyStatusToString(policy.get_status()), + policy.get_engine_stack().size(), + gridfire::utils::iterable_to_delimited_string( + engine_types, + " -> ", + [](const auto& type) { return gridfire::engine::engine_type_to_string(type); } + ) + ); + } +}; \ No newline at end of file diff --git a/src/include/gridfire/policy/stellar_policy.h b/src/include/gridfire/policy/stellar_policy.h index 89b2de39..3894c723 100644 --- a/src/include/gridfire/policy/stellar_policy.h +++ b/src/include/gridfire/policy/stellar_policy.h @@ -26,7 +26,6 @@ #include "fourdst/composition/composition.h" #include "fourdst/atomic/atomicSpecies.h" -#include "gridfire/partition/composite/partition_composite.h" #include "gridfire/policy/chains.h" @@ -135,7 +134,7 @@ namespace gridfire::policy { * // ... run solver ... * @endcode */ - engine::DynamicEngine& construct() override; + ConstructionResults construct() override; /** * @brief Gets the current status of the policy. @@ -148,6 +147,8 @@ namespace gridfire::policy { [[nodiscard]] std::vector get_engine_types_stack() const override; [[nodiscard]] const std::unique_ptr& get_partition_function() const override; + [[nodiscard]] std::unique_ptr get_stack_scratch_blob() const override; + private: std::set m_seed_species; ///< The set of seed species required by this policy. These are H-1, He-3, He-4, C-12, N-14, O-16, Ne-20, Mg-24. @@ -159,12 +160,12 @@ namespace gridfire::policy { NetworkPolicyStatus m_status = NetworkPolicyStatus::UNINITIALIZED; ///< The current status of the policy. private: static std::unique_ptr build_partition_function(); - [[nodiscard]] NetworkPolicyStatus check_status() const; + [[nodiscard]] NetworkPolicyStatus check_status(engine::scratch::StateBlob& ctx) const; public: }; +} - - -} \ No newline at end of file +template<> +struct std::formatter : std::formatter {}; \ No newline at end of file diff --git a/src/include/gridfire/reaction/reaction.h b/src/include/gridfire/reaction/reaction.h index b6ce7345..c01f1621 100644 --- a/src/include/gridfire/reaction/reaction.h +++ b/src/include/gridfire/reaction/reaction.h @@ -637,6 +637,7 @@ namespace gridfire::reaction { mutable std::optional> m_reactantsVec; mutable std::optional> m_productsVec; + mutable std::optional m_hashCache = std::nullopt; ///< Cached hash value for the reaction. std::string m_sourceLabel; ///< Source label for the rate data (e.g., "wc12w", "st08"). RateCoefficientSet m_rateCoefficients; ///< The seven rate coefficients. @@ -1006,6 +1007,7 @@ namespace gridfire::reaction { std::string m_id; std::unordered_map m_reactionNameMap; ///< Maps reaction IDs to Reaction objects for quick lookup. std::unordered_set m_reactionHashes; + mutable std::optional m_hashCache = std::nullopt; }; diff --git a/src/include/gridfire/solver/strategies/GridSolver.h b/src/include/gridfire/solver/strategies/GridSolver.h new file mode 100644 index 00000000..416d35c6 --- /dev/null +++ b/src/include/gridfire/solver/strategies/GridSolver.h @@ -0,0 +1,46 @@ +#pragma once + +#include "gridfire/solver/strategies/strategy_abstract.h" + +#include + +namespace gridfire::solver { + struct GridSolverContext final : SolverContextBase { + std::vector> solver_workspaces; + std::vector> timestep_callbacks; + const engine::scratch::StateBlob& ctx_template; + + bool zone_completion_logging = true; + bool zone_stdout_logging = false; + bool zone_detailed_logging = false; + + void init() override; + void reset(); + + void set_callback(const std::function &callback); + void set_callback(const std::function &callback, size_t zone_idx); + + void clear_callback(); + void clear_callback(size_t zone_idx); + + void set_stdout_logging(bool enable) override; + void set_detailed_logging(bool enable) override; + + explicit GridSolverContext(const engine::scratch::StateBlob& ctx_template); + }; + + class GridSolver final : public MultiZoneDynamicNetworkSolver { + public: + GridSolver( + const engine::DynamicEngine& engine, + const SingleZoneDynamicNetworkSolver& solver + ); + + ~GridSolver() override = default; + + std::vector evaluate( + SolverContextBase& ctx, + const std::vector& netIns + ) const override; + }; +} \ No newline at end of file diff --git a/src/include/gridfire/solver/strategies/CVODE_solver_strategy.h b/src/include/gridfire/solver/strategies/PointSolver.h similarity index 70% rename from src/include/gridfire/solver/strategies/CVODE_solver_strategy.h rename to src/include/gridfire/solver/strategies/PointSolver.h index 42c41580..480aebf7 100644 --- a/src/include/gridfire/solver/strategies/CVODE_solver_strategy.h +++ b/src/include/gridfire/solver/strategies/PointSolver.h @@ -37,7 +37,6 @@ #ifdef SUNDIALS_HAVE_PTHREADS #include #endif -// Default to serial if no parallelism is enabled #ifndef SUNDIALS_HAVE_OPENMP #ifndef SUNDIALS_HAVE_PTHREADS #include @@ -45,8 +44,88 @@ #endif namespace gridfire::solver { + struct PointSolverTimestepContext final : TimestepContextBase { + const double t; ///< Current integration time [s]. + const N_Vector& state; ///< Current CVODE state vector (N_Vector). + const double dt; ///< Last step size [s]. + const double last_step_time; ///< Time at last callback [s]. + const double T9; ///< Temperature in GK. + const double rho; ///< Density [g cm^-3]. + const size_t num_steps; ///< Number of CVODE steps taken so far. + const engine::DynamicEngine& engine; ///< Reference to the engine. + const std::vector& networkSpecies; ///< Species layout. + const size_t currentConvergenceFailures; ///< Total number of convergence failures + const size_t currentNonlinearIterations; ///< Total number of non-linear iterations + const std::map>& reactionContributionMap; ///< Map of reaction contributions for the current step + engine::scratch::StateBlob& state_ctx; ///< Reference to the engine scratch state blob + + PointSolverTimestepContext( + double t, + const N_Vector& state, + double dt, + double last_step_time, + double t9, + double rho, + size_t num_steps, + const engine::DynamicEngine& engine, + const std::vector& networkSpecies, + size_t currentConvergenceFailure, + size_t currentNonlinearIterations, + const std::map> &reactionContributionMap, + engine::scratch::StateBlob& state_ctx + ); + + [[nodiscard]] std::vector> describe() const override; + }; + + using TimestepCallback = std::function; ///< Type alias for a timestep callback function. + + struct PointSolverContext final : SolverContextBase { + SUNContext sun_ctx = nullptr; ///< SUNDIALS context (lifetime of the solver). + void* cvode_mem = nullptr; ///< CVODE memory block. + N_Vector Y = nullptr; ///< CVODE state vector (species + energy accumulator). + N_Vector YErr = nullptr; ///< Estimated local errors. + SUNMatrix J = nullptr; ///< Dense Jacobian matrix. + SUNLinearSolver LS = nullptr; ///< Dense linear solver. + + std::unique_ptr engine_ctx; + + + std::optional callback; ///< Optional per-step callback. + int num_steps = 0; ///< CVODE step counter (used for diagnostics and triggers). + + bool stdout_logging = true; ///< If true, print per-step logs and use CV_ONE_STEP. + + N_Vector constraints = nullptr; ///< CVODE constraints vector (>= 0 for species entries). + + std::optional abs_tol; ///< User-specified absolute tolerance. + std::optional rel_tol; ///< User-specified relative tolerance. + + bool detailed_step_logging = false; ///< If true, log detailed step diagnostics (error ratios, Jacobian, species balance). + + size_t last_size = 0; + size_t last_composition_hash = 0ULL; + sunrealtype last_good_time_step = 0ULL; + + void init() override; + void set_stdout_logging(bool enable) override; + void set_detailed_logging(bool enable) override; + + void reset_all(); + void reset_user(); + void reset_cvode(); + void clear_context(); + void init_context(); + + [[nodiscard]] bool has_context() const; + + explicit PointSolverContext(const engine::scratch::StateBlob& engine_ctx); + ~PointSolverContext() override; + + }; + /** - * @class CVODESolverStrategy + * @class PointSolver * @brief Stiff ODE integrator backed by SUNDIALS CVODE (BDF) for network + energy. * * Integrates the nuclear network abundances along with a final accumulator entry for specific @@ -79,24 +158,16 @@ namespace gridfire::solver { * std::cout << "Final energy: " << out.energy << " erg/g\n"; * @endcode */ - class CVODESolverStrategy final : public DynamicNetworkSolverStrategy { + class PointSolver final : public SingleZoneDynamicNetworkSolver { public: /** * @brief Construct the CVODE strategy and create a SUNDIALS context. * @param engine DynamicEngine used for RHS/Jacobian evaluation and network access. * @throws std::runtime_error If SUNContext_Create fails. */ - explicit CVODESolverStrategy(engine::DynamicEngine& engine); - /** - * @brief Destructor: cleans CVODE/SUNDIALS resources and frees SUNContext. - */ - ~CVODESolverStrategy() override; - - // Make the class non-copyable and non-movable to prevent shallow copies of CVODE pointers - CVODESolverStrategy(const CVODESolverStrategy&) = delete; - CVODESolverStrategy& operator=(const CVODESolverStrategy&) = delete; - CVODESolverStrategy(CVODESolverStrategy&&) = delete; - CVODESolverStrategy& operator=(CVODESolverStrategy&&) = delete; + explicit PointSolver( + const engine::DynamicEngine& engine + ); /** * @brief Integrate from t=0 to netIn.tMax and return final composition and energy. @@ -112,6 +183,7 @@ namespace gridfire::solver { * - At the end, converts molar abundances to mass fractions and assembles NetOut, * including derivatives of energy w.r.t. T and rho from the engine. * + * @param solver_ctx * @param netIn Inputs: temperature [K], density [g cm^-3], tMax [s], composition. * @return NetOut containing final Composition, accumulated energy [erg/g], step count, * and dEps/dT, dEps/dRho. @@ -120,12 +192,17 @@ namespace gridfire::solver { * @throws exceptions::StaleEngineTrigger Propagated if the engine signals a stale state * during RHS evaluation (captured in the wrapper then rethrown here). */ - NetOut evaluate(const NetIn& netIn) override; + NetOut evaluate( + SolverContextBase& solver_ctx, + const NetIn& netIn + ) const override; /** * @brief Call to evaluate which will let the user control if the trigger reasoning is displayed + * @param solver_ctx * @param netIn Inputs: temperature [K], density [g cm^-3], tMax [s], composition. * @param displayTrigger Boolean flag to control if trigger reasoning is displayed + * @param forceReinitialize Boolean flag to force reinitialization of CVODE resources at the start * @return NetOut containing final Composition, accumulated energy [erg/g], step count, * and dEps/dT, dEps/dRho. * @throws std::runtime_error If any CVODE or SUNDIALS call fails (negative return codes), @@ -133,87 +210,13 @@ namespace gridfire::solver { * @throws exceptions::StaleEngineTrigger Propagated if the engine signals a stale state * during RHS evaluation (captured in the wrapper then rethrown here). */ - NetOut evaluate(const NetIn& netIn, bool displayTrigger); + NetOut evaluate( + SolverContextBase& solver_ctx, + const NetIn& netIn, + bool displayTrigger, + bool forceReinitialize = false + ) const; - /** - * @brief Install a timestep callback. - * @param callback std::any containing TimestepCallback (std::function). - * @throws std::bad_any_cast If callback is not of the expected type. - */ - void set_callback(const std::any &callback) override; - - /** - * @brief Whether per-step logs are printed to stdout and CVode is stepped with CV_ONE_STEP. - */ - [[nodiscard]] bool get_stdout_logging_enabled() const; - - /** - * @brief Enable/disable per-step stdout logging. - * @param logging_enabled Flag to control if a timestep summary is written to standard output or not - */ - void set_stdout_logging_enabled(bool logging_enabled); - - void set_absTol(double absTol); - void set_relTol(double relTol); - - double get_absTol() const; - double get_relTol() const; - - /** - * @brief Schema of fields exposed to the timestep callback context. - */ - [[nodiscard]] std::vector> describe_callback_context() const override; - - /** - * @struct TimestepContext - * @brief Immutable view of the current integration state passed to callbacks. - * - * Fields capture CVODE time/state, step size, thermodynamic state, the engine reference, - * and the list of network species used to interpret the state vector layout. - */ - struct TimestepContext final : public SolverContextBase { - // This struct can be identical to the one in DirectNetworkSolver - const double t; ///< Current integration time [s]. - const N_Vector& state; ///< Current CVODE state vector (N_Vector). - const double dt; ///< Last step size [s]. - const double last_step_time; ///< Time at last callback [s]. - const double T9; ///< Temperature in GK. - const double rho; ///< Density [g cm^-3]. - const size_t num_steps; ///< Number of CVODE steps taken so far. - const engine::DynamicEngine& engine; ///< Reference to the engine. - const std::vector& networkSpecies; ///< Species layout. - const size_t currentConvergenceFailures; ///< Total number of convergence failures - const size_t currentNonlinearIterations; ///< Total number of non-linear iterations - const std::map>& reactionContributionMap; ///< Map of reaction contributions for the current step - - /** - * @brief Construct a context snapshot. - */ - TimestepContext( - double t, - const N_Vector& state, - double dt, - double last_step_time, - double t9, - double rho, - size_t num_steps, - const engine::DynamicEngine& engine, - const std::vector& networkSpecies, - size_t currentConvergenceFailure, - size_t currentNonlinearIterations, - const std::map> &reactionContributionMap - ); - - /** - * @brief Human-readable description of the context fields. - */ - [[nodiscard]] std::vector> describe() const override; - }; - - /** - * @brief Type alias for a timestep callback. - */ - using TimestepCallback = std::function; ///< Type alias for a timestep callback function. private: /** * @struct CVODEUserData @@ -225,8 +228,10 @@ namespace gridfire::solver { * to CVODE, then the driver loop inspects and rethrows. */ struct CVODEUserData { - CVODESolverStrategy* solver_instance{}; // Pointer back to the class instance - engine::DynamicEngine* engine{}; + const PointSolver* solver_instance{}; // Pointer back to the class instance + PointSolverContext* sctx; // Pointer to the solver context + engine::scratch::StateBlob& ctx; + const engine::DynamicEngine* engine{}; double T9{}; double rho{}; double energy{}; @@ -277,6 +282,7 @@ namespace gridfire::solver { * step size, creates a dense matrix and dense linear solver, and registers the Jacobian. */ void initialize_cvode_integration_resources( + PointSolverContext* ctx, uint64_t N, size_t numSpecies, double current_time, @@ -284,15 +290,7 @@ namespace gridfire::solver { double absTol, double relTol, double accumulatedEnergy - ); - - /** - * @brief Destroy CVODE vectors/linear algebra and optionally the CVODE memory block. - * @param memFree If true, also calls CVodeFree on m_cvode_mem. - */ - void cleanup_cvode_resources(bool memFree); - - void set_detailed_step_logging(bool enabled); + ) const; /** @@ -302,27 +300,13 @@ namespace gridfire::solver { * sorted table of species with the highest error ratios; then invokes diagnostic routines to * inspect Jacobian stiffness and species balance. */ - void log_step_diagnostics(const CVODEUserData& user_data, bool displayJacobianStiffness, bool - displaySpeciesBalance, bool to_file, std::optional filename) const; - private: - SUNContext m_sun_ctx = nullptr; ///< SUNDIALS context (lifetime of the solver). - void* m_cvode_mem = nullptr; ///< CVODE memory block. - N_Vector m_Y = nullptr; ///< CVODE state vector (species + energy accumulator). - N_Vector m_YErr = nullptr; ///< Estimated local errors. - SUNMatrix m_J = nullptr; ///< Dense Jacobian matrix. - SUNLinearSolver m_LS = nullptr; ///< Dense linear solver. - - - std::optional m_callback; ///< Optional per-step callback. - int m_num_steps = 0; ///< CVODE step counter (used for diagnostics and triggers). - - bool m_stdout_logging_enabled = true; ///< If true, print per-step logs and use CV_ONE_STEP. - - N_Vector m_constraints = nullptr; ///< CVODE constraints vector (>= 0 for species entries). - - std::optional m_absTol; ///< User-specified absolute tolerance. - std::optional m_relTol; ///< User-specified relative tolerance. - - bool m_detailed_step_logging = false; ///< If true, log detailed step diagnostics (error ratios, Jacobian, species balance). + void log_step_diagnostics( + PointSolverContext* sctx_p, + engine::scratch::StateBlob &ctx, + const CVODEUserData& user_data, + bool displayJacobianStiffness, + bool displaySpeciesBalance, + bool to_file, std::optional filename + ) const; }; } \ No newline at end of file diff --git a/src/include/gridfire/solver/strategies/strategies.h b/src/include/gridfire/solver/strategies/strategies.h index 3e59d2ef..c902dba4 100644 --- a/src/include/gridfire/solver/strategies/strategies.h +++ b/src/include/gridfire/solver/strategies/strategies.h @@ -2,4 +2,5 @@ #include "gridfire/solver/strategies/triggers/triggers.h" #include "gridfire/solver/strategies/strategy_abstract.h" -#include "gridfire/solver/strategies/CVODE_solver_strategy.h" \ No newline at end of file +#include "gridfire/solver/strategies/PointSolver.h" +#include "gridfire/solver/strategies/GridSolver.h" \ No newline at end of file diff --git a/src/include/gridfire/solver/strategies/strategy_abstract.h b/src/include/gridfire/solver/strategies/strategy_abstract.h index 3562012e..8d3d29f4 100644 --- a/src/include/gridfire/solver/strategies/strategy_abstract.h +++ b/src/include/gridfire/solver/strategies/strategy_abstract.h @@ -10,17 +10,27 @@ #include namespace gridfire::solver { + template + concept IsEngine = std::is_base_of_v; + + struct SolverContextBase { + virtual void init() = 0; + virtual void set_stdout_logging(bool enable) = 0; + virtual void set_detailed_logging(bool enable) = 0; + virtual ~SolverContextBase() = default; + }; + /** - * @struct SolverContextBase + * @struct TimestepContextBase * @brief Base class for solver callback contexts. * * This struct serves as a base class for contexts that can be passed to solver callbacks, it enforces * that derived classes implement a `describe` method that returns a vector of tuples describing * the context that a callback will receive when called. */ - class SolverContextBase { + class TimestepContextBase { public: - virtual ~SolverContextBase() = default; + virtual ~TimestepContextBase() = default; /** * @brief Describe the context for callback functions. @@ -34,7 +44,7 @@ namespace gridfire::solver { [[nodiscard]] virtual std::vector> describe() const = 0; }; /** - * @class NetworkSolverStrategy + * @class SingleZoneNetworkSolver * @brief Abstract base class for network solver strategies. * * This class defines the interface for network solver strategies, which are responsible @@ -43,57 +53,63 @@ namespace gridfire::solver { * * @tparam EngineT The type of engine to use with this solver strategy. Must inherit from Engine. */ - template - class NetworkSolverStrategy { + template + class SingleZoneNetworkSolver { public: /** * @brief Constructor for the NetworkSolverStrategy. * @param engine The engine to use for evaluating the network. */ - explicit NetworkSolverStrategy(EngineT& engine) : m_engine(engine) {}; + explicit SingleZoneNetworkSolver( + const EngineT& engine + ) : + m_engine(engine) {}; /** * @brief Virtual destructor. */ - virtual ~NetworkSolverStrategy() = default; + virtual ~SingleZoneNetworkSolver() = default; /** * @brief Evaluates the network for a given timestep. + * @param solver_ctx + * @param engine_ctx * @param netIn The input conditions for the network. * @return The output conditions after the timestep. */ - virtual NetOut evaluate(const NetIn& netIn) = 0; + virtual NetOut evaluate( + SolverContextBase& solver_ctx, + const NetIn& netIn + ) const = 0; - /** - * @brief set the callback function to be called at the end of each timestep. - * - * This function allows the user to set a callback function that will be called at the end of each timestep. - * The callback function will receive a gridfire::solver::::TimestepContext object. Note that - * depending on the solver, this context may contain different information. Further, the exact - * signature of the callback function is left up to each solver. Every solver should provide a type or type alias - * TimestepCallback that defines the signature of the callback function so that the user can easily - * get that type information. - * - * @param callback The callback function to be called at the end of each timestep. - */ - virtual void set_callback(const std::any& callback) = 0; - - /** - * @brief Describe the context that will be passed to the callback function. - * @return A vector of tuples, each containing a string for the parameter's name and a string for its type. - * - * This method should be overridden by derived classes to provide a description of the context - * that will be passed to the callback function. The intent of this method is that an end user can investigate - * the context that will be passed to the callback function, and use this information to craft their own - * callback function. - */ - [[nodiscard]] virtual std::vector> describe_callback_context() const = 0; protected: - EngineT& m_engine; ///< The engine used by this solver strategy. + const EngineT& m_engine; ///< The engine used by this solver strategy. + }; + + template + class MultiZoneNetworkSolver { + public: + explicit MultiZoneNetworkSolver( + const EngineT& engine, + const SingleZoneNetworkSolver& solver + ) : + m_engine(engine), + m_solver(solver) {}; + + virtual ~MultiZoneNetworkSolver() = default; + + virtual std::vector evaluate( + SolverContextBase& solver_ctx, + const std::vector& netIns + ) const = 0; + protected: + const EngineT& m_engine; ///< The engine used by this solver strategy. + const SingleZoneNetworkSolver& m_solver; }; /** * @brief Type alias for a network solver strategy that uses a DynamicEngine. */ - using DynamicNetworkSolverStrategy = NetworkSolverStrategy; + using SingleZoneDynamicNetworkSolver = SingleZoneNetworkSolver; + using MultiZoneDynamicNetworkSolver = MultiZoneNetworkSolver; } diff --git a/src/include/gridfire/solver/strategies/triggers/engine_partitioning_trigger.h b/src/include/gridfire/solver/strategies/triggers/engine_partitioning_trigger.h index 93088596..98b7f0e2 100644 --- a/src/include/gridfire/solver/strategies/triggers/engine_partitioning_trigger.h +++ b/src/include/gridfire/solver/strategies/triggers/engine_partitioning_trigger.h @@ -2,7 +2,7 @@ #include "gridfire/trigger/trigger_abstract.h" #include "gridfire/trigger/trigger_result.h" -#include "gridfire/solver/strategies/CVODE_solver_strategy.h" +#include "gridfire/solver/strategies/PointSolver.h" #include "fourdst/logging/logging.h" #include @@ -47,7 +47,7 @@ namespace gridfire::trigger::solver::CVODE { * * See also: engine_partitioning_trigger.cpp for the concrete logic and logging. */ - class SimulationTimeTrigger final : public Trigger { + class SimulationTimeTrigger final : public Trigger { public: /** * @brief Construct with a positive time interval between firings. @@ -62,7 +62,7 @@ namespace gridfire::trigger::solver::CVODE { * * @post increments hit/miss counters and may emit trace logs. */ - bool check(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + bool check(const gridfire::solver::PointSolverTimestepContext &ctx) const override; /** * @brief Update internal state; if check(ctx) is true, advance last_trigger_time. * @param ctx CVODE timestep context. @@ -70,9 +70,9 @@ namespace gridfire::trigger::solver::CVODE { * @note update() calls check(ctx) and, on success, records the overshoot delta * (ctx.t - last_trigger_time) - interval for diagnostics. */ - void update(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; + void update(const gridfire::solver::PointSolverTimestepContext &ctx) override; - void step(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; + void step(const gridfire::solver::PointSolverTimestepContext &ctx) override; /** * @brief Reset counters and last trigger bookkeeping (time and delta) to zero. */ @@ -85,7 +85,7 @@ namespace gridfire::trigger::solver::CVODE { * @param ctx CVODE timestep context. * @return TriggerResult including name, value, and description. */ - TriggerResult why(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + TriggerResult why(const gridfire::solver::PointSolverTimestepContext &ctx) const override; /** @brief Textual description including configured interval. */ std::string describe() const override; /** @brief Number of true evaluations since last reset. */ @@ -130,7 +130,7 @@ namespace gridfire::trigger::solver::CVODE { * @par See also * - engine_partitioning_trigger.cpp for concrete logic and trace logging. */ - class OffDiagonalTrigger final : public Trigger { + class OffDiagonalTrigger final : public Trigger { public: /** * @brief Construct with a non-negative magnitude threshold. @@ -145,13 +145,13 @@ namespace gridfire::trigger::solver::CVODE { * * @post increments hit/miss counters and may emit trace logs. */ - bool check(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + bool check(const gridfire::solver::PointSolverTimestepContext &ctx) const override; /** * @brief Record an update; does not mutate any Jacobian-related state. * @param ctx CVODE timestep context (unused except for symmetry with interface). */ - void update(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; - void step(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; + void update(const gridfire::solver::PointSolverTimestepContext &ctx) override; + void step(const gridfire::solver::PointSolverTimestepContext &ctx) override; /** @brief Reset counters to zero. */ void reset() override; @@ -161,7 +161,7 @@ namespace gridfire::trigger::solver::CVODE { * @brief Structured explanation of the evaluation outcome. * @param ctx CVODE timestep context. */ - TriggerResult why(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + TriggerResult why(const gridfire::solver::PointSolverTimestepContext &ctx) const override; /** @brief Textual description including configured threshold. */ std::string describe() const override; /** @brief Number of true evaluations since last reset. */ @@ -206,7 +206,7 @@ namespace gridfire::trigger::solver::CVODE { * * See also: engine_partitioning_trigger.cpp for exact logic and logging. */ - class TimestepCollapseTrigger final : public Trigger { + class TimestepCollapseTrigger final : public Trigger { public: /** * @brief Construct with threshold and relative/absolute mode; window size defaults to 1. @@ -230,20 +230,20 @@ namespace gridfire::trigger::solver::CVODE { * * @post increments hit/miss counters and may emit trace logs. */ - bool check(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + bool check(const gridfire::solver::PointSolverTimestepContext &ctx) const override; /** * @brief Update sliding window with the most recent dt and increment update counter. * @param ctx CVODE timestep context. */ - void update(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; - void step(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; + void update(const gridfire::solver::PointSolverTimestepContext &ctx) override; + void step(const gridfire::solver::PointSolverTimestepContext &ctx) override; /** @brief Reset counters and clear the dt window. */ void reset() override; /** @brief Stable human-readable name. */ std::string name() const override; /** @brief Structured explanation of the evaluation outcome. */ - TriggerResult why(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + TriggerResult why(const gridfire::solver::PointSolverTimestepContext &ctx) const override; /** @brief Textual description including threshold, mode, and window size. */ std::string describe() const override; /** @brief Number of true evaluations since last reset. */ @@ -272,15 +272,15 @@ namespace gridfire::trigger::solver::CVODE { std::deque m_timestep_window; }; - class ConvergenceFailureTrigger final : public Trigger { + class ConvergenceFailureTrigger final : public Trigger { public: explicit ConvergenceFailureTrigger(size_t totalFailures, float relativeFailureRate, size_t windowSize); - bool check(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + bool check(const gridfire::solver::PointSolverTimestepContext &ctx) const override; - void update(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; + void update(const gridfire::solver::PointSolverTimestepContext &ctx) override; - void step(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) override; + void step(const gridfire::solver::PointSolverTimestepContext &ctx) override; void reset() override; @@ -288,7 +288,7 @@ namespace gridfire::trigger::solver::CVODE { [[nodiscard]] std::string describe() const override; - [[nodiscard]] TriggerResult why(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const override; + [[nodiscard]] TriggerResult why(const gridfire::solver::PointSolverTimestepContext &ctx) const override; [[nodiscard]] size_t numTriggers() const override; @@ -312,8 +312,8 @@ namespace gridfire::trigger::solver::CVODE { private: float current_mean() const; - bool abs_failure(const gridfire::solver::CVODESolverStrategy::TimestepContext& ctx) const; - bool rel_failure(const gridfire::solver::CVODESolverStrategy::TimestepContext& ctx) const; + bool abs_failure(const gridfire::solver::PointSolverTimestepContext& ctx) const; + bool rel_failure(const gridfire::solver::PointSolverTimestepContext& ctx) const; }; /** @@ -337,10 +337,10 @@ namespace gridfire::trigger::solver::CVODE { * * @note The exact policy is subject to change; this function centralizes that decision. */ - std::unique_ptr> makeEnginePartitioningTrigger( - const double simulationTimeInterval, - const double offDiagonalThreshold, - const double timestepCollapseRatio, - const size_t maxConvergenceFailures + std::unique_ptr> makeEnginePartitioningTrigger( + double simulationTimeInterval, + double offDiagonalThreshold, + double timestepCollapseRatio, + size_t maxConvergenceFailures ); } diff --git a/src/include/gridfire/types/types.h b/src/include/gridfire/types/types.h index 64ef6f3a..f573bbff 100644 --- a/src/include/gridfire/types/types.h +++ b/src/include/gridfire/types/types.h @@ -59,3 +59,26 @@ namespace gridfire { concept IsArithmeticOrAD = std::is_same_v || std::is_same_v>; } // namespace nuclearNetwork + +template<> +struct std::formatter : std::formatter { + auto format(const gridfire::NetIn& netIn, auto& ctx) { + std::string output = "NetIn(, tMax=" + std::to_string(netIn.tMax) + + ", dt0=" + std::to_string(netIn.dt0) + + ", temperature=" + std::to_string(netIn.temperature) + + ", density=" + std::to_string(netIn.density) + + ", energy=" + std::to_string(netIn.energy) + ")"; + return std::formatter::format(output, ctx); + } +}; + +template <> +struct std::formatter : std::formatter { + auto format(const gridfire::NetOut& netOut, auto& ctx) { + std::string output = "NetOut(, num_steps=" + std::to_string(netOut.num_steps) + + ", energy=" + std::to_string(netOut.energy) + + ", dEps_dT=" + std::to_string(netOut.dEps_dT) + + ", dEps_dRho=" + std::to_string(netOut.dEps_dRho) + ")"; + return std::formatter::format(output, ctx); + } +}; diff --git a/src/include/gridfire/utils/gf_omp.h b/src/include/gridfire/utils/gf_omp.h new file mode 100644 index 00000000..07b645ec --- /dev/null +++ b/src/include/gridfire/utils/gf_omp.h @@ -0,0 +1,51 @@ +#pragma once +#include "fourdst/logging/logging.h" +#include "quill/LogMacros.h" + +#if defined(GF_USE_OPENMP) + +#include + +namespace gridfire::omp { + static bool s_par_mode_initialized = false; + + inline unsigned long get_thread_id() { + return static_cast(omp_get_thread_num()); + } + + inline bool in_parallel() { + return omp_in_parallel() != 0; + } + + inline void init_parallel_mode() { + if (s_par_mode_initialized) { + return; // Only initialize once + } + quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); + LOG_INFO(logger, "Initializing OpenMP parallel mode with {} threads", static_cast(omp_get_max_threads())); + CppAD::thread_alloc::parallel_setup( + static_cast(omp_get_max_threads()), // Max threads + []() -> bool { return in_parallel(); }, // Function to get thread ID + []() -> size_t { return get_thread_id(); } // Function to check parallel state + ); + + CppAD::thread_alloc::hold_memory(true); + CppAD::CheckSimpleVector>(0, 1); + s_par_mode_initialized = true; + } +} + +#define GF_PAR_INIT() gridfire::omp::init_parallel_mode(); + +#else + +namespace gridfire::omp { + inline void log_not_in_parallel_mode() { + quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); + LOG_INFO(logger, "This is not an error! Note: OpenMP parallel mode is not enabled. GF_USE_OPENMP is not defined. Pass -DGF_USE_OPENMP when compiling to enable OpenMP support. When using meson use the option -Dopenmp_support=true"); + } +} + +#define GF_PAR_INIT() gridfire::omp::log_not_in_parallel_mode(); + +#endif \ No newline at end of file diff --git a/src/include/gridfire/utils/hashing.h b/src/include/gridfire/utils/hashing.h index 0905ada9..7017ab55 100644 --- a/src/include/gridfire/utils/hashing.h +++ b/src/include/gridfire/utils/hashing.h @@ -3,6 +3,7 @@ #include #include +#include "fourdst/composition/utils/composition_hash.h" #include "gridfire/exceptions/exceptions.h" #include "gridfire/reaction/reaction.h" @@ -69,4 +70,33 @@ namespace gridfire::utils { seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); return seed; } + + inline std::size_t fast_mix(std::size_t h) noexcept { + h ^= h >> 33; + h *= 0xff51afd7ed558ccdULL; + h ^= h >> 33; + h *= 0xc4ceb9fe1a85ec53ULL; + h ^= h >> 33; + return h; + } + + inline std::size_t hash_state( + const fourdst::composition::CompositionAbstract& comp, + const double T9, + const double rho, + const reaction::ReactionSet& reactions + ) noexcept { + std::size_t hash = comp.hash(); + const std::size_t topology_hash = reactions.hash(0); + + hash ^= topology_hash + 0x517cc1b727220a95 + (hash << 6) + (hash >> 2); + + const std::uint64_t t9_bits = std::bit_cast(T9); + const std::uint64_t rho_bits = std::bit_cast(rho); + + hash ^= fast_mix(t9_bits) + 0x9e3779b9 + (hash << 6) + (hash >> 2); + hash ^= fast_mix(rho_bits) + 0x9e3779b9 + (hash << 6) + (hash >> 2); + + return hash; + } } diff --git a/src/include/gridfire/utils/logging.h b/src/include/gridfire/utils/logging.h index 30ed1104..be09f470 100644 --- a/src/include/gridfire/utils/logging.h +++ b/src/include/gridfire/utils/logging.h @@ -2,6 +2,7 @@ #include "gridfire/engine/engine_abstract.h" #include "fourdst/composition/composition.h" +#include "gridfire/engine/scratchpads/blob.h" #include #include @@ -15,6 +16,7 @@ namespace gridfire::utils { * It then formats this information into a neatly aligned ASCII table, which * is suitable for logging or printing to the console. * + * @param ctx * @param engine A constant reference to a `DynamicEngine` object, used to * calculate the species timescales. * @param composition The current composition of the plasma @@ -58,10 +60,10 @@ namespace gridfire::utils { * @endcode */ std::string formatNuclearTimescaleLogString( + engine::scratch::StateBlob &ctx, const engine::DynamicEngine& engine, const fourdst::composition::Composition& composition, - double T9, - double rho + double T9, double rho ); template diff --git a/src/include/gridfire/utils/macros.h b/src/include/gridfire/utils/macros.h new file mode 100644 index 00000000..22add6c8 --- /dev/null +++ b/src/include/gridfire/utils/macros.h @@ -0,0 +1,13 @@ +#pragma once + + +#if defined(GF_USE_OPENMP) + #define GF_OMP_PRAGMA(x) _Pragma(#x) + #define GF_OMP(omp_args, extra) GF_OMP_PRAGMA(omp omp_args) extra + #define GF_OMP_MAX_THREADS omp_get_max_threads() + #define GF_OMP_THREAD_NUM omp_get_thread_num() +#else + #define GF_OMP(_,fallback_args) fallback_args + #define GF_OMP_MAX_THREADS 1 + #define GF_OMP_THREAD_NUM 0 +#endif \ No newline at end of file diff --git a/src/include/gridfire/utils/utils.h b/src/include/gridfire/utils/utils.h index 3f5685cc..7bdfe8e2 100644 --- a/src/include/gridfire/utils/utils.h +++ b/src/include/gridfire/utils/utils.h @@ -5,3 +5,4 @@ #include "gridfire/utils/logging.h" #include "gridfire/utils/sundials.h" #include "gridfire/utils/table_format.h" +#include "gridfire/utils/macros.h" diff --git a/src/lib/engine/diagnostics/dynamic_engine_diagnostics.cpp b/src/lib/engine/diagnostics/dynamic_engine_diagnostics.cpp index 69719e09..67876736 100644 --- a/src/lib/engine/diagnostics/dynamic_engine_diagnostics.cpp +++ b/src/lib/engine/diagnostics/dynamic_engine_diagnostics.cpp @@ -3,12 +3,15 @@ #include "gridfire/utils/table_format.h" #include "fourdst/atomic/species.h" +#include "gridfire/engine/scratchpads/blob.h" + #include #include #include namespace gridfire::engine::diagnostics { std::optional report_limiting_species( + scratch::StateBlob& ctx, const DynamicEngine &engine, const std::vector &Y_full, const std::vector &E_full, @@ -24,7 +27,7 @@ namespace gridfire::engine::diagnostics { double abundance; }; - const auto& species_list = engine.getNetworkSpecies(); + const auto& species_list = engine.getNetworkSpecies(ctx); std::vector errors; for (size_t i = 0; i < species_list.size(); ++i) { @@ -75,6 +78,7 @@ namespace gridfire::engine::diagnostics { } std::optional inspect_species_balance( + scratch::StateBlob& ctx, const DynamicEngine& engine, const std::string& species_name, const fourdst::composition::Composition &comp, @@ -90,11 +94,11 @@ namespace gridfire::engine::diagnostics { double total_creation_flow = 0.0; double total_destruction_flow = 0.0; - for (const auto& reaction : engine.getNetworkReactions()) { + for (const auto& reaction : engine.getNetworkReactions(ctx)) { const int stoichiometry = reaction->stoichiometry(species_obj); if (stoichiometry == 0) continue; - const double flow = engine.calculateMolarReactionFlow(*reaction, comp, T9, rho); + const double flow = engine.calculateMolarReactionFlow(ctx, *reaction, comp, T9, rho); if (stoichiometry > 0) { creation_ids.emplace_back(reaction->id()); @@ -157,17 +161,18 @@ namespace gridfire::engine::diagnostics { } std::optional inspect_jacobian_stiffness( + scratch::StateBlob& ctx, const DynamicEngine &engine, const fourdst::composition::Composition &comp, const double T9, const double rho, const bool json ) { - NetworkJacobian jac = engine.generateJacobianMatrix(comp, T9, rho); + NetworkJacobian jac = engine.generateJacobianMatrix(ctx, comp, T9, rho); jac = regularize_jacobian(jac, comp); - const auto& species_list = engine.getNetworkSpecies(); + const auto& species_list = engine.getNetworkSpecies(ctx); double max_diag = 0.0; double max_off_diag = 0.0; diff --git a/src/lib/engine/engine_graph.cpp b/src/lib/engine/engine_graph.cpp index e1999e87..de8195f2 100644 --- a/src/lib/engine/engine_graph.cpp +++ b/src/lib/engine/engine_graph.cpp @@ -8,11 +8,16 @@ #include "gridfire/utils/hashing.h" #include "gridfire/utils/table_format.h" +#include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/utils.h" + #include "fourdst/atomic/species.h" #include "fourdst/atomic/atomicSpecies.h" #include "quill/LogMacros.h" +// ReSharper disable once CppUnusedIncludeDirective #include #include #include @@ -28,9 +33,6 @@ #include "cppad/utility/sparse_rc.hpp" #include "cppad/utility/sparse_rcv.hpp" -#ifdef GRIDFIRE_USE_OPENMP - #include -#endif namespace { @@ -115,8 +117,8 @@ namespace gridfire::engine { const NetworkConstructionFlags reactionTypes ) : m_weakRateInterpolator(rates::weak::UNIFIED_WEAK_DATA), m_reactions(build_nuclear_network(composition, m_weakRateInterpolator, buildDepth, reactionTypes)), - m_depth(buildDepth), - m_partitionFunction(partitionFunction.clone()) + m_partitionFunction(partitionFunction.clone()), + m_depth(buildDepth) { syncInternalMaps(); } @@ -131,31 +133,41 @@ namespace gridfire::engine { } std::expected, EngineStatus> GraphEngine::calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, - const double rho + const double rho, + bool trust ) const { - return calculateRHSAndEnergy(comp, T9, rho, m_reactions); + return calculateRHSAndEnergy(ctx, comp, T9, rho, m_reactions); } std::expected, EngineStatus> GraphEngine::calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const reaction::ReactionSet &activeReactions ) const { + auto* state = scratch::get_state(ctx); LOG_TRACE_L3(m_logger, "Calculating RHS and Energy in GraphEngine at T9 = {}, rho = {}.", T9, rho); const double Ye = comp.getElectronAbundance(); + const std::vector molarAbundances = comp.getMolarAbundanceVector(); if (m_usePrecomputation) { + const std::size_t state_hash = utils::hash_state(comp, T9, rho, activeReactions); + if (state->stepDerivativesCache.contains(state_hash)) { + return state->stepDerivativesCache.at(state_hash); + } LOG_TRACE_L3(m_logger, "Using precomputation for reaction rates in GraphEngine calculateRHSAndEnergy."); std::vector bare_rates; std::vector bare_reverse_rates; bare_rates.reserve(activeReactions.size()); bare_reverse_rates.reserve(activeReactions.size()); + for (const auto& reaction: activeReactions) { assert(m_reactions.contains(*reaction)); // A bug which results in this failing indicates a serious internal inconsistency and should only be present during development. - bare_rates.push_back(reaction->calculate_rate(T9, rho, Ye, 0.0, comp.getMolarAbundanceVector(), m_indexToSpeciesMap)); + bare_rates.push_back(reaction->calculate_rate(T9, rho, Ye, 0.0, molarAbundances, m_indexToSpeciesMap)); if (reaction->type() != reaction::ReactionType::WEAK) { bare_reverse_rates.push_back(calculateReverseRate(*reaction, T9, rho, comp)); } @@ -164,11 +176,14 @@ namespace gridfire::engine { LOG_TRACE_L3(m_logger, "Precomputed {} forward and {} reverse reaction rates for active reactions.", bare_rates.size(), bare_reverse_rates.size()); // --- The public facing interface can always use the precomputed version since taping is done internally --- - return calculateAllDerivativesUsingPrecomputation(comp, bare_rates, bare_reverse_rates, T9, rho, activeReactions); + StepDerivatives result = calculateAllDerivativesUsingPrecomputation(ctx, comp, bare_rates, bare_reverse_rates, T9, rho, activeReactions); + state->stepDerivativesCache.insert(std::make_pair(state_hash, result)); + state->most_recent_rhs_calculation = result; + return result; } else { LOG_TRACE_L2(m_logger, "Not using precomputation for reaction rates in GraphEngine calculateRHSAndEnergy."); StepDerivatives result = calculateAllDerivatives( - comp.getMolarAbundanceVector(), + molarAbundances, T9, rho, Ye, @@ -184,24 +199,28 @@ namespace gridfire::engine { return false; } ); + state->most_recent_rhs_calculation = result; return result; } } EnergyDerivatives GraphEngine::calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - return calculateEpsDerivatives(comp, T9, rho, m_reactions); + return calculateEpsDerivatives(ctx, comp, T9, rho, m_reactions); } EnergyDerivatives GraphEngine::calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const reaction::ReactionSet &activeReactions ) const { + auto* state = scratch::get_state(ctx); const size_t numSpecies = m_networkSpecies.size(); const size_t numADInputs = numSpecies + 2; // +2 for T9 and rho @@ -225,10 +244,11 @@ namespace gridfire::engine { w[numSpecies] = 1.0; // We want the derivative of the energy generation rate // Sweep the tape forward to record the function value at x - m_rhsADFun.Forward(0, x); + assert(state->rhsADFun.has_value() && "AD tape for energy derivatives has not been recorded."); + state->rhsADFun.value().Forward(0, x); // Extract the gradient at the previously evaluated point x using reverse mode - const std::vector eps_derivatives = m_rhsADFun.Reverse(1, w); + const std::vector eps_derivatives = state->rhsADFun.value().Reverse(1, w); const double dEps_dT9 = eps_derivatives[numSpecies]; const double dEps_dRho = eps_derivatives[numSpecies + 1]; @@ -241,19 +261,8 @@ namespace gridfire::engine { return {dEps_dT, dEps_dRho}; } - void GraphEngine::syncInternalMaps() { - - LOG_INFO(m_logger, "Synchronizing internal maps for REACLIB graph network (serif::network::GraphNetwork)..."); - collectNetworkSpecies(); - populateReactionIDMap(); - populateSpeciesToIndexMap(); - collectAtomicReverseRateAtomicBases(); - generateStoichiometryMatrix(); - - recordADTape(); // Record the AD tape for the RHS of the ODE (dY/di and dEps/di) for all independent variables i - - [[maybe_unused]] const size_t inputSize = m_rhsADFun.Domain(); - const size_t outputSize = m_rhsADFun.Range(); + void GraphEngine::generate_jacobian_sparsity_pattern() { + const size_t outputSize = m_authoritativeADFun.Range(); // Create a range x range identity pattern CppAD::sparse_rc> patternIn(outputSize, outputSize, outputSize); @@ -261,9 +270,8 @@ namespace gridfire::engine { patternIn.set(i, i, i); } - m_rhsADFun.rev_jac_sparsity(patternIn, false, false, false, m_full_jacobian_sparsity_pattern); + m_authoritativeADFun.rev_jac_sparsity(patternIn, false, false, false, m_full_jacobian_sparsity_pattern); - m_jac_work.clear(); m_full_sparsity_set.clear(); const auto& rows = m_full_jacobian_sparsity_pattern.row(); const auto& cols = m_full_jacobian_sparsity_pattern.col(); @@ -274,6 +282,17 @@ namespace gridfire::engine { m_full_sparsity_set.insert(std::make_pair(rows[k], cols[k])); } } + } + + void GraphEngine::syncInternalMaps() { + LOG_INFO(m_logger, "Synchronizing internal maps for REACLIB graph network (serif::network::GraphNetwork)..."); + collectNetworkSpecies(); + populateReactionIDMap(); + populateSpeciesToIndexMap(); + collectAtomicReverseRateAtomicBases(); + + recordADTape(); // Record the AD tape for the RHS of the ODE (dY/di and dEps/di) for all independent variables i + generate_jacobian_sparsity_pattern(); precomputeNetwork(); LOG_INFO(m_logger, "Internal maps synchronized. Network contains {} species and {} reactions.", @@ -333,81 +352,26 @@ namespace gridfire::engine { } // --- Basic Accessors and Queries --- - const std::vector& GraphEngine::getNetworkSpecies() const { + const std::vector& GraphEngine::getNetworkSpecies(scratch::StateBlob &ctx) const { return m_networkSpecies; } - const reaction::ReactionSet& GraphEngine::getNetworkReactions() const { + const reaction::ReactionSet& GraphEngine::getNetworkReactions( + scratch::StateBlob& ctx + ) const { return m_reactions; } - void GraphEngine::setNetworkReactions(const reaction::ReactionSet &reactions) { - m_reactions = reactions; - syncInternalMaps(); - } - - bool GraphEngine::involvesSpecies(const fourdst::atomic::Species& species) const { + bool GraphEngine::involvesSpecies( + scratch::StateBlob& ctx, + const fourdst::atomic::Species& species + ) const { const bool found = m_networkSpeciesMap.contains(species.name()); return found; } - // --- Validation Methods --- - bool GraphEngine::validateConservation() const { - LOG_TRACE_L1(m_logger, "Validating mass (A) and charge (Z) conservation across all reactions in the network."); - - for (const auto& reaction : m_reactions) { - uint64_t totalReactantA = 0; - uint64_t totalReactantZ = 0; - uint64_t totalProductA = 0; - uint64_t totalProductZ = 0; - - // Calculate total A and Z for reactants - for (const auto& reactant : reaction->reactants()) { - auto it = m_networkSpeciesMap.find(reactant.name()); - if (it != m_networkSpeciesMap.end()) { - totalReactantA += it->second.a(); - totalReactantZ += it->second.z(); - } else { - // This scenario indicates a severe data integrity issue: - // a reactant is part of a reaction but not in the network's species map. - LOG_ERROR(m_logger, "CRITICAL ERROR: Reactant species '{}' in reaction '{}' not found in network species map during conservation validation.", - reactant.name(), reaction->id()); - return false; - } - } - - // Calculate total A and Z for products - for (const auto& product : reaction->products()) { - auto it = m_networkSpeciesMap.find(product.name()); - if (it != m_networkSpeciesMap.end()) { - totalProductA += it->second.a(); - totalProductZ += it->second.z(); - } else { - // Similar critical error for product species - LOG_ERROR(m_logger, "CRITICAL ERROR: Product species '{}' in reaction '{}' not found in network species map during conservation validation.", - product.name(), reaction->id()); - return false; - } - } - - // Compare totals for conservation - if (totalReactantA != totalProductA) { - LOG_ERROR(m_logger, "Mass number (A) not conserved for reaction '{}': Reactants A={} vs Products A={}.", - reaction->id(), totalReactantA, totalProductA); - return false; - } - if (totalReactantZ != totalProductZ) { - LOG_ERROR(m_logger, "Atomic number (Z) not conserved for reaction '{}': Reactants Z={} vs Products Z={}.", - reaction->id(), totalReactantZ, totalProductZ); - return false; - } - } - - LOG_TRACE_L1(m_logger, "Mass (A) and charge (Z) conservation validated successfully for all reactions."); - return true; // All reactions passed the conservation check - } - double GraphEngine::compute_reaction_flow( + scratch::StateBlob& ctx, const std::vector &local_abundances, const std::vector &screening_factors, const std::vector &bare_rates, @@ -428,11 +392,14 @@ namespace gridfire::engine { double factor; if (power == 1) { factor = abundance; } else if (power == 2) { factor = abundance * abundance; } - else { factor = std::pow(abundance, power); } + else if (power == 3) { factor = abundance * abundance * abundance; } + else { factor = std::pow(abundance, static_cast(power)); } if (!std::isfinite(factor)) { - LOG_CRITICAL(m_logger, "Non-finite factor encountered in forward abundance product for reaction '{}'. Check input abundances for validity.", reaction.id()); - throw exceptions::BadRHSEngineError("Non-finite factor encountered in forward abundance product."); + const auto& sp = m_indexToSpeciesMap.at(reactantIndex); + std::string error_msg = std::format("Non-finite factor encountered in forward abundance product in reaction {} for species {} (Abundance: {}). Check input abundances for validity.", reaction.id(), sp.name(), abundance); + LOG_CRITICAL(m_logger, "{}", error_msg); + throw exceptions::BadRHSEngineError(error_msg); } forwardAbundanceProduct *= factor; @@ -476,6 +443,7 @@ namespace gridfire::engine { } std::pair GraphEngine::compute_neutrino_fluxes( + scratch::StateBlob& ctx, const double netFlow, const reaction::Reaction &reaction ) const { @@ -506,6 +474,7 @@ namespace gridfire::engine { } GraphEngine::PrecomputationKernelResults GraphEngine::accumulate_flows_serial( + scratch::StateBlob& ctx, const std::vector &local_abundances, const std::vector &screening_factors, const std::vector &bare_rates, @@ -517,16 +486,20 @@ namespace gridfire::engine { results.dydt_vector.resize(m_networkSpecies.size(), 0.0); std::vector molarReactionFlows; - molarReactionFlows.reserve(m_precomputedReactions.size()); + molarReactionFlows.reserve(m_precomputed_reactions.size()); size_t reactionCounter = 0; + std::vector reactionIndices; + reactionIndices.reserve(m_precomputed_reactions.size()); for (const auto& reaction : activeReactions) { - uint64_t reactionHash = utils::hash_reaction(*reaction); - const size_t reactionIndex = m_precomputedReactionIndexMap.at(reactionHash); - const PrecomputedReaction& precomputedReaction = m_precomputedReactions[reactionIndex]; + uint64_t reactionHash = reaction->hash(0); + const size_t reactionIndex = m_precomputed_reaction_index_map.at(reactionHash); + reactionIndices.push_back(reactionIndex); + const PrecomputedReaction& precomputedReaction = m_precomputed_reactions[reactionIndex]; double netFlow = compute_reaction_flow( + ctx, local_abundances, screening_factors, bare_rates, @@ -539,7 +512,7 @@ namespace gridfire::engine { molarReactionFlows.push_back(netFlow); - auto [local_neutrino_loss, local_neutrino_flux] = compute_neutrino_fluxes(netFlow, *reaction); + auto [local_neutrino_loss, local_neutrino_flux] = compute_neutrino_fluxes(ctx, netFlow, *reaction); results.total_neutrino_energy_loss_rate += local_neutrino_loss; results.total_neutrino_flux += local_neutrino_flux; @@ -549,9 +522,8 @@ namespace gridfire::engine { LOG_TRACE_L3(m_logger, "Computed {} molar reaction flows for active reactions. Assembling these into RHS", molarReactionFlows.size()); reactionCounter = 0; - for (const auto& reaction: activeReactions) { - const size_t j = m_precomputedReactionIndexMap.at(utils::hash_reaction(*reaction)); - const auto& precomp = m_precomputedReactions[j]; + for (const auto& [reaction, j]: std::views::zip(activeReactions, reactionIndices)) { + const auto& precomp = m_precomputed_reactions[j]; const double R_j = molarReactionFlows[reactionCounter]; for (size_t i = 0; i < precomp.affected_species_indices.size(); ++i) { @@ -732,27 +704,24 @@ namespace gridfire::engine { } - bool GraphEngine::isUsingReverseReactions() const { + bool GraphEngine::isUsingReverseReactions( + scratch::StateBlob& ctx + ) const { return m_useReverseReactions; } - void GraphEngine::setUseReverseReactions(const bool useReverse) { - m_useReverseReactions = useReverse; - } - - size_t GraphEngine::getSpeciesIndex(const fourdst::atomic::Species &species) const { + size_t GraphEngine::getSpeciesIndex( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const { return m_speciesToIndexMap.at(species); // Returns the index of the species in the stoichiometry matrix } - std::vector GraphEngine::mapNetInToMolarAbundanceVector(const NetIn &netIn) const { - std::vector Y(m_networkSpecies.size(), 0.0); // Initialize with zeros - for (const auto& [sp, y] : netIn.composition) { - Y[getSpeciesIndex(sp)] = y; // Map species to their molar abundance - } - return Y; // Return the vector of molar abundances - } + PrimingReport GraphEngine::primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { - PrimingReport GraphEngine::primeEngine(const NetIn &netIn) { NetIn fullNetIn; fourdst::composition::Composition composition; @@ -772,27 +741,13 @@ namespace gridfire::engine { reactionTypesToIgnore = {reaction::ReactionType::WEAK}; } - auto primingReport = primeNetwork(fullNetIn, *this, reactionTypesToIgnore); + auto primingReport = primeNetwork(ctx, fullNetIn, *this, reactionTypesToIgnore); - m_has_been_primed = true; return primingReport; } - BuildDepthType GraphEngine::getDepth() const { - return m_depth; - } - - void GraphEngine::rebuild(const fourdst::composition::CompositionAbstract &comp, const BuildDepthType depth) { - if (depth != m_depth) { - m_depth = depth; - m_reactions = build_nuclear_network(comp, m_weakRateInterpolator, m_depth); - syncInternalMaps(); // Resync internal maps after changing the depth - } else { - LOG_DEBUG(m_logger, "Rebuild requested with the same depth. No changes made to the network."); - } - } - fourdst::composition::Composition GraphEngine::collectComposition( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -812,7 +767,10 @@ namespace gridfire::engine { return result; } - SpeciesStatus GraphEngine::getSpeciesStatus(const fourdst::atomic::Species &species) const { + SpeciesStatus GraphEngine::getSpeciesStatus( + scratch::StateBlob& ctx, + const fourdst::atomic::Species &species + ) const { if (m_networkSpeciesMap.contains(species.name())) { return SpeciesStatus::ACTIVE; } @@ -820,8 +778,18 @@ namespace gridfire::engine { } + std::optional> GraphEngine::getMostRecentRHSCalculation( + scratch::StateBlob& ctx + ) const { + const auto *state = scratch::get_state(ctx); + if (!state->most_recent_rhs_calculation.has_value()) { + return std::nullopt; + } + return state->most_recent_rhs_calculation.value(); + } StepDerivatives GraphEngine::calculateAllDerivativesUsingPrecomputation( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const std::vector &bare_rates, const std::vector &bare_reverse_rates, @@ -829,6 +797,7 @@ namespace gridfire::engine { const double rho, const reaction::ReactionSet &activeReactions ) const { + auto *state = scratch::get_state(ctx); LOG_TRACE_L3(m_logger, "Computing screening factors for {} active reactions.", activeReactions.size()); // --- Calculate screening factors --- const std::vector screeningFactors = m_screeningModel->calculateScreeningFactors( @@ -838,17 +807,17 @@ namespace gridfire::engine { T9, rho ); - m_local_abundance_cache.clear(); + state->local_abundance_cache.clear(); for (const auto& species: m_networkSpecies) { - m_local_abundance_cache.push_back(comp.contains(species) ? comp.getMolarAbundance(species) : 0.0); + state->local_abundance_cache.push_back(comp.contains(species) ? comp.getMolarAbundance(species) : 0.0); } StepDerivatives result; std::vector dydt_scratch(m_networkSpecies.size(), 0.0); -#ifndef GRIDFIRE_USE_OPENMP const auto [dydt_vector, total_neutrino_energy_loss_rate, total_neutrino_flux] = accumulate_flows_serial( - m_local_abundance_cache, + ctx, + state->local_abundance_cache, screeningFactors, bare_rates, bare_reverse_rates, @@ -858,19 +827,6 @@ namespace gridfire::engine { dydt_scratch = dydt_vector; result.neutrinoEnergyLossRate = total_neutrino_energy_loss_rate; result.totalNeutrinoFlux = total_neutrino_flux; -#else - const auto [dydt_vector, total_neutrino_energy_loss_rate, total_neutrino_flux] = accumulate_flows_parallel( - m_local_abundance_cache, - screeningFactors, - bare_rates, - bare_reverse_rates, - rho, - activeReactions - ); - dydt_scratch = dydt_vector; - result.neutrinoEnergyLossRate = total_neutrino_energy_loss_rate; - result.totalNeutrinoFlux = total_neutrino_flux; -#endif // load scratch into result.dydt for (size_t i = 0; i < m_networkSpecies.size(); ++i) { @@ -888,33 +844,26 @@ namespace gridfire::engine { } - // --- Generate Stoichiometry Matrix --- - void GraphEngine::generateStoichiometryMatrix() { - return; // Deprecated - } - - void GraphEngine::setScreeningModel(const screening::ScreeningType model) { - m_screeningModel = screening::selectScreeningModel(model); - m_screeningType = model; - } - - screening::ScreeningType GraphEngine::getScreeningModel() const { + screening::ScreeningType GraphEngine::getScreeningModel( + scratch::StateBlob& ctx + ) const { return m_screeningType; } - void GraphEngine::setPrecomputation(const bool precompute) { - m_usePrecomputation = precompute; - } - - bool GraphEngine::isPrecomputationEnabled() const { + bool GraphEngine::isPrecomputationEnabled( + scratch::StateBlob& ctx + ) const { return m_usePrecomputation; } - const partition::PartitionFunction & GraphEngine::getPartitionFunction() const { + const partition::PartitionFunction & GraphEngine::getPartitionFunction( + scratch::StateBlob& ctx + ) const { return *m_partitionFunction; } double GraphEngine::calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, const double T9, @@ -940,10 +889,12 @@ namespace gridfire::engine { } NetworkJacobian GraphEngine::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { + auto *state = scratch::get_state(ctx); fourdst::composition::Composition mutableComp; for (const auto& species : m_networkSpecies) { mutableComp.registerSpecies(species); @@ -964,10 +915,11 @@ namespace gridfire::engine { adInput[numSpecies + 1] = rho; // rho // 2. Calculate the full jacobian - const std::vector dotY = m_rhsADFun.Jacobian(adInput); + assert(state->rhsADFun.has_value() && "RHS ADFun not recorded before Jacobian generation."); + const std::vector dotY = state->rhsADFun.value().Jacobian(adInput); // 3. Pack jacobian vector into sparse matrix - Eigen::SparseMatrix jacobianMatrix(numSpecies, numSpecies); + Eigen::SparseMatrix jacobianMatrix(static_cast(numSpecies), static_cast(numSpecies)); std::vector > triplets; for (size_t i = 0; i < numSpecies; ++i) { for (size_t j = 0; j < numSpecies; ++j) { @@ -991,12 +943,12 @@ namespace gridfire::engine { } NetworkJacobian GraphEngine::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const std::vector &activeSpecies ) const { - // PERF: For small k it may make sense to implement a purley forward mode AD computation, some heuristic could be used to switch between the two methods based on k and total network species const size_t k_active = activeSpecies.size(); // --- 1. Get the list of global indices --- @@ -1004,8 +956,8 @@ namespace gridfire::engine { active_indices.reserve(k_active); for (const auto& species : activeSpecies) { - assert(involvesSpecies(species)); - active_indices.push_back(getSpeciesIndex(species)); + assert(involvesSpecies(ctx, species)); + active_indices.push_back(getSpeciesIndex(ctx, species)); } // --- 2. Build the k x k sparsity pattern --- @@ -1019,15 +971,18 @@ namespace gridfire::engine { } // --- 3. Call the sparse reverse-mode implementation --- - return generateJacobianMatrix(comp, T9, rho, sparsityPattern); + return generateJacobianMatrix(ctx, comp, T9, rho, sparsityPattern); } NetworkJacobian GraphEngine::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const SparsityPattern &sparsityPattern ) const { + auto *state = scratch::get_state(ctx); + // --- Compute the intersection of the requested sparsity pattern with the full sparsity pattern --- SparsityPattern intersectionSparsityPattern; for (const auto& entry : sparsityPattern) { if (m_full_sparsity_set.contains(entry)) { @@ -1038,10 +993,6 @@ namespace gridfire::engine { // --- Pack the input variables into a vector for CppAD --- const size_t numSpecies = m_networkSpecies.size(); std::vector x(numSpecies + 2, 0.0); - // const std::vector& Y_dynamic = comp.getMolarAbundanceVector(); - // for (size_t i = 0; i < numSpecies; ++i) { - // x[i] = Y_dynamic[i]; - // } size_t i = 0; for (const auto& species: m_networkSpecies) { double Yi = 0.0; // Small floor to avoid issues with zero abundances @@ -1069,27 +1020,41 @@ namespace gridfire::engine { const size_t num_cols_jac = numSpecies + 2; // +2 for T9 and rho CppAD::sparse_rc> CppAD_sparsity_pattern(num_rows_jac, num_cols_jac, nnz); + std::size_t sparsity_hash = 0; for (size_t k = 0; k < nnz; ++k) { + size_t local_intersection_hash = utils::hash_combine(intersectionSparsityPattern[k].first, intersectionSparsityPattern[k].second); + sparsity_hash = utils::hash_combine(sparsity_hash, local_intersection_hash); + CppAD_sparsity_pattern.set(k, intersectionSparsityPattern[k].first, intersectionSparsityPattern[k].second); } - CppAD::sparse_rcv, std::vector> jac_subset(CppAD_sparsity_pattern); + // --- Check cache for existing subset --- + if (!state->jacobianSubsetCache.contains(sparsity_hash)) { + state->jacobianSubsetCache.emplace(sparsity_hash, CppAD_sparsity_pattern); + state->jac_work.clear(); + } else { + if (state->jacWorkCache.contains(sparsity_hash)) { + state->jac_work.clear(); + state->jac_work = state->jacWorkCache.at(sparsity_hash); + } + } + auto& jac_subset = state->jacobianSubsetCache.at(sparsity_hash); - // PERF: one of *the* most pressing things that needs to be done is remove the need for this call every - // time the jacobian is needed since coloring is expensive and we are throwing away the caching - // power of CppAD by clearing the work vector each time. We do this since we make a new subset every - // time. However, a better solution would be to make the subset stateful so it only changes if the requested - // sparsity pattern changes. This way we could reuse the work vector. - m_jac_work.clear(); - m_rhsADFun.sparse_jac_rev( + assert(state->rhsADFun.has_value() && "RHS ADFun not recorded before Jacobian generation."); + state->rhsADFun.value().sparse_jac_rev( x, jac_subset, // Sparse Jacobian output m_full_jacobian_sparsity_pattern, "cppad", - m_jac_work // Work vector for CppAD + state->jac_work // Work vector for CppAD ); - Eigen::SparseMatrix jacobianMatrix(numSpecies, numSpecies); + // --- Stash the now populated work vector in the cache if not already present --- + if (!state->jacWorkCache.contains(sparsity_hash)) { + state->jacWorkCache.emplace(sparsity_hash, state->jac_work); + } + + Eigen::SparseMatrix jacobianMatrix(static_cast(numSpecies), static_cast(numSpecies)); std::vector > triplets; for (size_t k = 0; k < nnz; ++k) { const size_t row = jac_subset.row()[k]; @@ -1111,20 +1076,10 @@ namespace gridfire::engine { return jac; } - std::unordered_map GraphEngine::getNetReactionStoichiometry( - const reaction::Reaction &reaction - ) { - return reaction.stoichiometry(); - } - - int GraphEngine::getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const reaction::Reaction &reaction + void GraphEngine::exportToDot( + scratch::StateBlob& ctx, + const std::string &filename ) const { - return reaction.stoichiometry(species); - } - - void GraphEngine::exportToDot(const std::string &filename) const { LOG_TRACE_L1(m_logger, "Exporting network graph to DOT file: {}", filename); std::ofstream dotFile(filename); @@ -1172,7 +1127,10 @@ namespace gridfire::engine { LOG_TRACE_L1(m_logger, "Successfully exported network to {}", filename); } - void GraphEngine::exportToCSV(const std::string &filename) const { + void GraphEngine::exportToCSV( + scratch::StateBlob& ctx, + const std::string &filename + ) const { LOG_TRACE_L1(m_logger, "Exporting network graph to CSV file: {}", filename); std::ofstream csvFile(filename, std::ios::out | std::ios::trunc); @@ -1210,14 +1168,16 @@ namespace gridfire::engine { } std::expected, EngineStatus> GraphEngine::getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - return getSpeciesTimescales(comp, T9, rho, m_reactions); + return getSpeciesTimescales(ctx, comp, T9, rho, m_reactions); } std::expected, EngineStatus> GraphEngine::getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, @@ -1256,14 +1216,16 @@ namespace gridfire::engine { } std::expected, EngineStatus> GraphEngine::getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - return getSpeciesDestructionTimescales(comp, T9, rho, m_reactions); + return getSpeciesDestructionTimescales(ctx, comp, T9, rho, m_reactions); } std::expected, EngineStatus> GraphEngine::getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, @@ -1306,7 +1268,10 @@ namespace gridfire::engine { return speciesDestructionTimescales; } - fourdst::composition::Composition GraphEngine::update(const NetIn &netIn) { + fourdst::composition::Composition GraphEngine::project( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { fourdst::composition::Composition baseUpdatedComposition = netIn.composition; for (const auto& species : m_networkSpecies) { if (!netIn.composition.contains(species)) { @@ -1316,11 +1281,8 @@ namespace gridfire::engine { return baseUpdatedComposition; } - bool GraphEngine::isStale(const NetIn &netIn) { - return false; - } + void GraphEngine::recordADTape() { - void GraphEngine::recordADTape() const { LOG_TRACE_L1(m_logger, "Recording AD tape for the RHS calculation..."); // Task 1: Set dimensions and initialize the matrix @@ -1384,17 +1346,19 @@ namespace gridfire::engine { ); dependentVector.push_back(result.nuclearEnergyGenerationRate); - m_rhsADFun.Dependent(adInput, dependentVector); + m_authoritativeADFun.Dependent(adInput, dependentVector); + m_authoritativeADFun.optimize(); LOG_TRACE_L1(m_logger, "AD tape recorded successfully for the RHS and Eps calculation. Number of independent variables: {}.", adInput.size()); } - void GraphEngine::collectAtomicReverseRateAtomicBases() { + void GraphEngine::collectAtomicReverseRateAtomicBases( + ) { m_atomicReverseRates.clear(); m_atomicReverseRates.reserve(m_reactions.size()); for (const auto& reaction: m_reactions) { - if (reaction->qValue() != 0.0) { + if (reaction->qValue() != 0.0 and m_useReverseReactions) { m_atomicReverseRates.push_back(std::make_unique(*reaction, *this)); } else { m_atomicReverseRates.push_back(nullptr); @@ -1402,7 +1366,7 @@ namespace gridfire::engine { } } - void GraphEngine::precomputeNetwork() { + void GraphEngine::precomputeNetwork() { LOG_TRACE_L1(m_logger, "Pre-computing constant components of GraphNetwork state..."); // --- Reverse map for fast species lookups --- @@ -1411,20 +1375,20 @@ namespace gridfire::engine { speciesIndexMap[m_networkSpecies[i]] = i; } - m_precomputedReactions.clear(); - m_precomputedReactions.reserve(m_reactions.size()); - m_precomputedReactionIndexMap.clear(); - m_precomputedReactionIndexMap.reserve(m_reactions.size()); + m_precomputed_reactions.clear(); + m_precomputed_reactions.reserve(m_reactions.size()); + m_precomputed_reaction_index_map.clear(); + m_precomputed_reaction_index_map.reserve(m_reactions.size()); for (size_t i = 0; i < m_reactions.size(); ++i) { const auto& reaction = m_reactions[i]; PrecomputedReaction precomp; precomp.reaction_index = i; precomp.reaction_type = reaction.type(); - uint64_t reactionHash = utils::hash_reaction(reaction); + uint64_t reactionHash = reaction.hash(0); precomp.reaction_hash = reactionHash; - m_precomputedReactionIndexMap[reactionHash] = i; + m_precomputed_reaction_index_map[reactionHash] = i; // --- Precompute forward reaction information --- // Count occurrences for each reactant to determine powers and symmetry @@ -1474,9 +1438,9 @@ namespace gridfire::engine { precomp.stoichiometric_coefficients.push_back(coeff); } - m_precomputedReactions.push_back(std::move(precomp)); + m_precomputed_reactions.push_back(std::move(precomp)); } - LOG_TRACE_L1(m_logger, "Pre-computation complete. Precomputed data for {} reactions.", m_precomputedReactions.size()); + LOG_TRACE_L1(m_logger, "Pre-computation complete. Precomputed data for {} reactions.", m_precomputed_reactions.size()); } bool GraphEngine::AtomicReverseRate::forward( @@ -1491,6 +1455,7 @@ namespace gridfire::engine { if ( p != 0) { return false; } const double T9 = tx[0]; + // We can pass a dummy comp and rho because reverse rates should only be calculated for strong reactions whose // rates of progression do not depend on composition or density. const fourdst::composition::Composition dummyComp; @@ -1580,68 +1545,4 @@ namespace gridfire::engine { return true; } -#ifdef GRIDFIRE_USE_OPENMP - GraphEngine::PrecomputationKernelResults GraphEngine::accumulate_flows_parallel( - const std::vector &local_abundances, - const std::vector &screening_factors, - const std::vector &bare_rates, - const std::vector &bare_reverse_rates, - const double rho, - const reaction::ReactionSet &activeReactions - ) const { - int n_threads = omp_get_max_threads(); - std::vector> thread_local_dydt(n_threads, std::vector(m_networkSpecies.size(), 0.0)); - - double total_neutrino_energy_loss_rate = 0.0; - double total_neutrino_flux = 0.0; - - #pragma omp parallel for schedule(static) reduction(+:total_neutrino_energy_loss_rate, total_neutrino_flux) - for (size_t k = 0; k < activeReactions.size(); ++k) { - int t_id = omp_get_thread_num(); - const auto& reaction = activeReactions[k]; - const size_t reactionIndex = m_precomputedReactionIndexMap.at(utils::hash_reaction(reaction)); - const PrecomputedReaction& precomputedReaction = m_precomputedReactions[reactionIndex]; - - double netFlow = compute_reaction_flow( - local_abundances, - screening_factors, - bare_rates, - bare_reverse_rates, - rho, - reactionIndex, - reaction, - reactionIndex, - precomputedReaction - ); - - auto [neutrinoEnergyLossRate, neutrinoFlux] = compute_neutrino_fluxes( - netFlow, - reaction - ); - - total_neutrino_energy_loss_rate += neutrinoEnergyLossRate; - total_neutrino_flux += neutrinoFlux; - - for (size_t i = 0; i < precomputedReaction.affected_species_indices.size(); ++i) { - thread_local_dydt[t_id][precomputedReaction.affected_species_indices[i]] += - netFlow * precomputedReaction.stoichiometric_coefficients[i]; - } - - } - PrecomputationKernelResults results; - results.total_neutrino_energy_loss_rate = total_neutrino_energy_loss_rate; - results.total_neutrino_flux = total_neutrino_flux; - - results.dydt_vector.resize(m_networkSpecies.size(), 0.0); - #pragma omp parallel for schedule(static) - for (size_t i = 0; i < m_networkSpecies.size(); ++i) { - double sum = 0.0; - for (int t = 0; t < n_threads; ++t) sum += thread_local_dydt[t][i]; - results.dydt_vector[i] = sum; - } - - return results; - } -#endif - } diff --git a/src/lib/engine/procedures/priming.cpp b/src/lib/engine/procedures/priming.cpp index 2f6dcac5..547f1630 100644 --- a/src/lib/engine/procedures/priming.cpp +++ b/src/lib/engine/procedures/priming.cpp @@ -2,15 +2,17 @@ #include "fourdst/atomic/species.h" #include "fourdst/composition/utils.h" -#include "gridfire/engine/views/engine_priming.h" #include "gridfire/solver/solver.h" #include "gridfire/engine/engine_abstract.h" #include "gridfire/types/types.h" #include "gridfire/exceptions/error_solver.h" +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" + #include "fourdst/logging/logging.h" -#include "gridfire/solver/strategies/CVODE_solver_strategy.h" +#include "gridfire/solver/strategies/PointSolver.h" #include "quill/Logger.h" #include "quill/LogMacros.h" @@ -20,18 +22,17 @@ namespace gridfire::engine { using fourdst::atomic::Species; PrimingReport primeNetwork( - const NetIn& netIn, - GraphEngine& engine, - const std::optional>& ignoredReactionTypes + scratch::StateBlob &ctx, + const NetIn& netIn, + const GraphEngine& engine, const std::optional>& ignoredReactionTypes ) { const auto logger = LogManager::getInstance().getLogger("log"); - solver::CVODESolverStrategy integrator(engine); + solver::PointSolver integrator(engine); + solver::PointSolverContext solverCtx(ctx); + solverCtx.abs_tol = 1e-3; + solverCtx.rel_tol = 1e-3; + solverCtx.stdout_logging = false; - // Do not need high precision for priming - integrator.set_absTol(1e-3); - integrator.set_relTol(1e-3); - - integrator.set_stdout_logging_enabled(false); NetIn solverInput(netIn); solverInput.tMax = 1e-15; @@ -40,7 +41,7 @@ namespace gridfire::engine { LOG_INFO(logger, "Short timescale ({}) network ignition started.", solverInput.tMax); PrimingReport report; try { - const NetOut netOut = integrator.evaluate(solverInput, false); + const NetOut netOut = integrator.evaluate(solverCtx, solverInput); LOG_INFO(logger, "Network ignition completed."); LOG_TRACE_L2( logger, @@ -70,7 +71,7 @@ namespace gridfire::engine { minAbundance = y; } } - double abundanceForUnprimedSpecies = minAbundance / 1e10; + const double abundanceForUnprimedSpecies = minAbundance / 1e10; for (const auto& sp : unprimedSpecies) { LOG_TRACE_L1(logger, "Clamping Species {}: initial abundance {}, primed abundance {} to {}", sp.name(), netIn.composition.getMolarAbundance(sp), report.primedComposition.getMolarAbundance(sp), abundanceForUnprimedSpecies); report.primedComposition.setMolarAbundance(sp, abundanceForUnprimedSpecies); diff --git a/src/lib/engine/views/engine_adaptive.cpp b/src/lib/engine/views/engine_adaptive.cpp index a1956d3e..108959c5 100644 --- a/src/lib/engine/views/engine_adaptive.cpp +++ b/src/lib/engine/views/engine_adaptive.cpp @@ -7,6 +7,11 @@ #include "gridfire/types/types.h" #include "gridfire/exceptions/error_engine.h" +#include "gridfire/utils/hashing.h" + +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/utils.h" +#include "gridfire/engine/scratchpads/engine_adaptive_scratchpad.h" #include "quill/LogMacros.h" #include "quill/Logger.h" @@ -16,23 +21,24 @@ namespace gridfire::engine { AdaptiveEngineView::AdaptiveEngineView( DynamicEngine &baseEngine ) : - m_baseEngine(baseEngine), - m_activeSpecies(baseEngine.getNetworkSpecies()), - m_activeReactions(baseEngine.getNetworkReactions()) - {} + m_baseEngine(baseEngine) {} - fourdst::composition::Composition AdaptiveEngineView::update(const NetIn &netIn) { - m_activeReactions.clear(); - m_activeSpecies.clear(); + fourdst::composition::Composition AdaptiveEngineView::project( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { + auto *state = scratch::get_state(ctx); + state->active_reactions.clear(); + state->active_species.clear(); - fourdst::composition::Composition baseUpdatedComposition = m_baseEngine.update(netIn); + fourdst::composition::Composition baseUpdatedComposition = m_baseEngine.project(ctx, netIn); NetIn updatedNetIn = netIn; updatedNetIn.composition = baseUpdatedComposition; LOG_TRACE_L1(m_logger, "Updating AdaptiveEngineView with new network input..."); - auto [allFlows, composition] = calculateAllReactionFlows(updatedNetIn); + auto [allFlows, composition] = calculateAllReactionFlows(ctx, updatedNetIn); double maxFlow = 0.0; @@ -43,82 +49,50 @@ namespace gridfire::engine { } LOG_DEBUG(m_logger, "Maximum reaction flow rate in adaptive engine view: {:0.3E} [mol/s]", maxFlow); - const std::unordered_set reachableSpecies = findReachableSpecies(updatedNetIn); + const std::unordered_set reachableSpecies = findReachableSpecies(ctx, updatedNetIn); LOG_DEBUG(m_logger, "Found {} reachable species in adaptive engine view.", reachableSpecies.size()); - const std::vector finalReactions = cullReactionsByFlow(allFlows, reachableSpecies, composition, maxFlow); + const std::vector finalReactions = cullReactionsByFlow(ctx, allFlows, reachableSpecies, composition, maxFlow); - finalizeActiveSet(finalReactions); + finalizeActiveSet(ctx, finalReactions); - auto [rescuedReactions, rescuedSpecies] = rescueEdgeSpeciesDestructionChannel(composition, netIn.temperature/1e9, netIn.density, m_activeSpecies, m_activeReactions); + auto [rescuedReactions, rescuedSpecies] = rescueEdgeSpeciesDestructionChannel( + ctx, + composition, + netIn.temperature/1e9, + netIn.density + ); for (const auto& reactionPtr : rescuedReactions) { - m_activeReactions.add_reaction(*reactionPtr); + state->active_reactions.add_reaction(*reactionPtr); } for (const auto& species : rescuedSpecies) { - if (!std::ranges::contains(m_activeSpecies, species) && m_baseEngine.getSpeciesStatus(species) == SpeciesStatus::ACTIVE) { - m_activeSpecies.push_back(species); + if (!std::ranges::contains(state->active_species, species) && m_baseEngine.getSpeciesStatus(ctx, species) == SpeciesStatus::ACTIVE) { + state->active_species.push_back(species); } } - m_isStale = false; - - LOG_INFO(m_logger, "AdaptiveEngineView updated successfully with {} active species and {} active reactions.", m_activeSpecies.size(), m_activeReactions.size()); + LOG_INFO(m_logger, "AdaptiveEngineView updated successfully with {} active species and {} active reactions.", state->active_species.size(), state->active_reactions.size()); return updatedNetIn.composition; } - bool AdaptiveEngineView::isStale(const NetIn &netIn) { - return m_isStale || m_baseEngine.isStale(netIn); - } - - const std::vector & AdaptiveEngineView::getNetworkSpecies() const { - return m_activeSpecies; + const std::vector & AdaptiveEngineView::getNetworkSpecies(scratch::StateBlob& ctx) const { + return scratch::get_state(ctx)->active_species; } std::expected, EngineStatus> AdaptiveEngineView::calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, - const double rho + const double rho, bool trust ) const { LOG_TRACE_L2(m_logger, "Calculating RHS and Energy in AdaptiveEngineView at T9 = {}, rho = {}.", T9, rho); - validateState(); - LOG_TRACE_L2( - m_logger, - "Adaptive engine view state validated prior to composition collection. Input Composition: {}", - [&comp]() -> std::string { - std::stringstream ss; - size_t i = 0; - for (const auto& [species, abundance] : comp) { - ss << species.name() << ": " << abundance; - if (i < comp.size() - 1) { - ss << ", "; - } - i++; - } - return ss.str(); - }()); - fourdst::composition::Composition collectedComp = collectComposition(comp, T9, rho); - LOG_TRACE_L2( - m_logger, - "Composition Collected prior to passing to base engine. Collected Composition: {}", - [&comp, &collectedComp]() -> std::string { - std::stringstream ss; - size_t i = 0; - for (const auto& [species, abundance] : collectedComp) { - ss << species.name() << ": " << abundance; - if (comp.contains(species)) { - ss << " (input: " << comp.getMolarAbundance(species) << ")"; - } - if (i < collectedComp.size() - 1) { - ss << ", "; - } - i++; - } - return ss.str(); - }()); - auto result = m_baseEngine.calculateRHSAndEnergy(collectedComp, T9, rho); + + const fourdst::composition::Composition collectedComp = collectComposition(ctx, comp, T9, rho); + + auto result = m_baseEngine.calculateRHSAndEnergy(ctx, collectedComp, T9, rho, true); LOG_TRACE_L2(m_logger, "Base engine calculation of RHS and Energy complete."); if (!result) { @@ -130,99 +104,88 @@ namespace gridfire::engine { } EnergyDerivatives AdaptiveEngineView::calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateState(); - return m_baseEngine.calculateEpsDerivatives(comp, T9, rho); + return m_baseEngine.calculateEpsDerivatives(ctx, comp, T9, rho); } NetworkJacobian AdaptiveEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - return generateJacobianMatrix(comp, T9, rho, m_activeSpecies); + const auto *state = scratch::get_state(ctx); + return generateJacobianMatrix(ctx, comp, T9, rho, state->active_species); } NetworkJacobian AdaptiveEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const std::vector &activeSpecies ) const { - validateState(); - return m_baseEngine.generateJacobianMatrix(comp, T9, rho, activeSpecies); + return m_baseEngine.generateJacobianMatrix(ctx, comp, T9, rho, activeSpecies); } NetworkJacobian AdaptiveEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const SparsityPattern &sparsityPattern ) const { - validateState(); - return m_baseEngine.generateJacobianMatrix(comp, T9, rho, sparsityPattern); - } - - void AdaptiveEngineView::generateStoichiometryMatrix() { - validateState(); - m_baseEngine.generateStoichiometryMatrix(); - } - - int AdaptiveEngineView::getStoichiometryMatrixEntry( - const Species &species, - const reaction::Reaction& reaction - ) const { - validateState(); - return m_baseEngine.getStoichiometryMatrixEntry(species, reaction); + return m_baseEngine.generateJacobianMatrix(ctx, comp, T9, rho, sparsityPattern); } double AdaptiveEngineView::calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateState(); - if (!m_activeReactions.contains(reaction)) { + const auto *state = scratch::get_state(ctx); + if (!state->active_reactions.contains(reaction)) { LOG_ERROR(m_logger, "Reaction '{}' is not part of the active reactions in the adaptive engine view.", reaction.id()); m_logger -> flush_log(); throw std::runtime_error("Reaction not found in active reactions: " + std::string(reaction.id())); } - return m_baseEngine.calculateMolarReactionFlow(reaction, comp, T9, rho); + return m_baseEngine.calculateMolarReactionFlow(ctx, reaction, comp, T9, rho); } - const reaction::ReactionSet & AdaptiveEngineView::getNetworkReactions() const { - return m_activeReactions; - } - - void AdaptiveEngineView::setNetworkReactions(const reaction::ReactionSet &reactions) { - LOG_CRITICAL(m_logger, "AdaptiveEngineView does not support setting network reactions directly. Use update() with NetIn instead. Perhaps you meant to call this on the base engine?"); - throw exceptions::UnableToSetNetworkReactionsError("AdaptiveEngineView does not support setting network reactions directly. Use update() with NetIn instead. Perhaps you meant to call this on the base engine?"); + const reaction::ReactionSet & AdaptiveEngineView::getNetworkReactions( + scratch::StateBlob& ctx + ) const { + return scratch::get_state(ctx) -> active_reactions; } std::expected, EngineStatus> AdaptiveEngineView::getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateState(); - const auto result = m_baseEngine.getSpeciesTimescales(comp, T9, rho); + + const auto result = m_baseEngine.getSpeciesTimescales(ctx, comp, T9, rho); if (!result) { return std::unexpected{result.error()}; } + const auto* state = scratch::get_state(ctx); const std::unordered_map& fullTimescales = result.value(); std::unordered_map culledTimescales; - culledTimescales.reserve(m_activeSpecies.size()); - for (const auto& active_species : m_activeSpecies) { + culledTimescales.reserve(state->active_species.size()); + for (const auto& active_species : state->active_species) { if (fullTimescales.contains(active_species)) { culledTimescales[active_species] = fullTimescales.at(active_species); } @@ -232,21 +195,23 @@ namespace gridfire::engine { } std::expected, EngineStatus> AdaptiveEngineView::getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateState(); - const auto result = m_baseEngine.getSpeciesDestructionTimescales(comp, T9, rho); + const auto result = m_baseEngine.getSpeciesDestructionTimescales(ctx, comp, T9, rho); if (!result) { return std::unexpected{result.error()}; } + + const auto* state = scratch::get_state(ctx); const std::unordered_map& destructionTimescales = result.value(); std::unordered_map culledTimescales; - culledTimescales.reserve(m_activeSpecies.size()); - for (const auto& active_species : m_activeSpecies) { + culledTimescales.reserve(state->active_species.size()); + for (const auto& active_species : state->active_species) { if (destructionTimescales.contains(active_species)) { culledTimescales[active_species] = destructionTimescales.at(active_species); } @@ -254,34 +219,29 @@ namespace gridfire::engine { return culledTimescales; } - void AdaptiveEngineView::setScreeningModel(const screening::ScreeningType model) { - m_baseEngine.setScreeningModel(model); + screening::ScreeningType AdaptiveEngineView::getScreeningModel( + scratch::StateBlob& ctx + ) const { + return m_baseEngine.getScreeningModel(ctx); } - screening::ScreeningType AdaptiveEngineView::getScreeningModel() const { - return m_baseEngine.getScreeningModel(); - } - - std::vector AdaptiveEngineView::mapNetInToMolarAbundanceVector(const NetIn &netIn) const { - std::vector Y(m_activeSpecies.size(), 0.0); // Initialize with zeros - for (const auto& [species, y] : netIn.composition) { - Y[getSpeciesIndex(species)] = y; // Map species to their molar abundance - } - return Y; // Return the vector of molar abundances - } - - PrimingReport AdaptiveEngineView::primeEngine(const NetIn &netIn) { - return m_baseEngine.primeEngine(netIn); + PrimingReport AdaptiveEngineView::primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { + return m_baseEngine.primeEngine(ctx, netIn); } fourdst::composition::Composition AdaptiveEngineView::collectComposition( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - fourdst::composition::Composition result = m_baseEngine.collectComposition(comp, T9, rho); + const auto* state = scratch::get_state(ctx); + fourdst::composition::Composition result = m_baseEngine.collectComposition(ctx, comp, T9, rho); - for (const auto& species : m_activeSpecies) { + for (const auto& species : state->active_species) { if (!result.contains(species)) { result.registerSpecies(species); } @@ -290,18 +250,32 @@ namespace gridfire::engine { return result; } - SpeciesStatus AdaptiveEngineView::getSpeciesStatus(const fourdst::atomic::Species &species) const { - const SpeciesStatus status = m_baseEngine.getSpeciesStatus(species); - if (status == SpeciesStatus::ACTIVE && std::ranges::find(m_activeSpecies, species) == m_activeSpecies.end()) { + SpeciesStatus AdaptiveEngineView::getSpeciesStatus( + scratch::StateBlob& ctx, + const Species &species + ) const { + const auto* state = scratch::get_state(ctx); + const SpeciesStatus status = m_baseEngine.getSpeciesStatus(ctx, species); + if (status == SpeciesStatus::ACTIVE && std::ranges::find(state->active_species, species) == state->active_species.end()) { return SpeciesStatus::INACTIVE_FLOW; } return status; } - size_t AdaptiveEngineView::getSpeciesIndex(const fourdst::atomic::Species &species) const { - const auto it = std::ranges::find(m_activeSpecies, species); - if (it != m_activeSpecies.end()) { - return static_cast(std::distance(m_activeSpecies.begin(), it)); + std::optional> AdaptiveEngineView::getMostRecentRHSCalculation( + scratch::StateBlob &ctx + ) const { + return m_baseEngine.getMostRecentRHSCalculation(ctx); + } + + size_t AdaptiveEngineView::getSpeciesIndex( + scratch::StateBlob& ctx, + const Species &species + ) const { + const auto *state = scratch::get_state(ctx); + const auto it = std::ranges::find(state->active_species, species); + if (it != state->active_species.end()) { + return static_cast(std::distance(state->active_species.begin(), it)); } else { LOG_ERROR(m_logger, "Species '{}' not found in active species list.", species.name()); m_logger->flush_log(); @@ -309,18 +283,11 @@ namespace gridfire::engine { } } - void AdaptiveEngineView::validateState() const { - if (m_isStale) { - LOG_ERROR(m_logger, "AdaptiveEngineView is stale. Please call update() before calculating RHS and energy."); - m_logger->flush_log(); - throw std::runtime_error("AdaptiveEngineView is stale. Please call update() before calculating RHS and energy."); - } - } - std::pair, fourdst::composition::Composition> AdaptiveEngineView::calculateAllReactionFlows( + scratch::StateBlob& ctx, const NetIn &netIn ) const { - const auto& fullSpeciesList = m_baseEngine.getNetworkSpecies(); + const auto& fullSpeciesList = m_baseEngine.getNetworkSpecies(ctx); fourdst::composition::Composition composition = netIn.composition; for (const auto& species: fullSpeciesList) { @@ -334,10 +301,10 @@ namespace gridfire::engine { const double rho = netIn.density; // Density in g/cm^3 std::vector reactionFlows; - const auto& fullReactionSet = m_baseEngine.getNetworkReactions(); + const auto& fullReactionSet = m_baseEngine.getNetworkReactions(ctx); reactionFlows.reserve(fullReactionSet.size()); for (const auto& reaction : fullReactionSet) { - const double flow = m_baseEngine.calculateMolarReactionFlow(*reaction, composition, T9, rho); + const double flow = m_baseEngine.calculateMolarReactionFlow(ctx, *reaction, composition, T9, rho); reactionFlows.push_back({reaction.get(), flow}); LOG_TRACE_L3(m_logger, "Reaction '{}' has flow rate: {:0.3E} [mol/s/g]", reaction->id(), flow); } @@ -345,13 +312,14 @@ namespace gridfire::engine { } std::unordered_set AdaptiveEngineView::findReachableSpecies( + scratch::StateBlob& ctx, const NetIn &netIn ) const { std::unordered_set reachable; std::queue to_vist; constexpr double ABUNDANCE_FLOOR = 1e-12; // Abundance floor for a species to be considered part of the initial fuel - for (const auto& species: m_baseEngine.getNetworkSpecies()) { + for (const auto& species: m_baseEngine.getNetworkSpecies(ctx)) { if (netIn.composition.contains(species) && netIn.composition.getMassFraction(std::string(species.name())) > ABUNDANCE_FLOOR) { if (!reachable.contains(species)) { to_vist.push(species); @@ -364,7 +332,7 @@ namespace gridfire::engine { bool new_species_found_in_pass = true; while (new_species_found_in_pass) { new_species_found_in_pass = false; - for (const auto& reaction: m_baseEngine.getNetworkReactions()) { + for (const auto& reaction: m_baseEngine.getNetworkReactions(ctx)) { bool all_reactants_reachable = true; for (const auto& reactant: reaction->reactants()) { if (!reachable.contains(reactant)) { @@ -388,6 +356,7 @@ namespace gridfire::engine { } std::vector AdaptiveEngineView::cullReactionsByFlow( + scratch::StateBlob& ctx, const std::vector &allFlows, const std::unordered_set &reachableSpecies, const fourdst::composition::Composition &comp, @@ -431,21 +400,22 @@ namespace gridfire::engine { } AdaptiveEngineView::RescueSet AdaptiveEngineView::rescueEdgeSpeciesDestructionChannel( + scratch::StateBlob& ctx, const fourdst::composition::Composition &comp, const double T9, - const double rho, - const std::vector &activeSpecies, - const reaction::ReactionSet &activeReactions + const double rho ) const { - const auto result = m_baseEngine.getSpeciesTimescales(comp, T9, rho); + const auto result = m_baseEngine.getSpeciesTimescales(ctx, comp, T9, rho); if (!result) { LOG_CRITICAL(m_logger, "Failed to get species timescales due to base engine failure"); m_logger->flush_log(); throw exceptions::EngineError("Failed to get species timescales due base engine failure"); } + + const auto* state = scratch::get_state(ctx); std::unordered_map timescales = result.value(); std::set onlyProducedSpecies; - for (const auto& reaction : activeReactions) { + for (const auto& reaction : state->active_reactions) { const std::vector& products = reaction->products(); onlyProducedSpecies.insert(products.begin(), products.end()); } @@ -454,7 +424,7 @@ namespace gridfire::engine { std::erase_if( onlyProducedSpecies, [&](const Species &species) { - for (const auto& reaction : activeReactions) { + for (const auto& reaction : state->active_reactions) { if (reaction->contains_reactant(species)) { return true; // If any active reaction consumes the species then erase it from the set. } @@ -474,14 +444,14 @@ namespace gridfire::engine { std::unordered_map reactionsToRescue; for (const auto& species : onlyProducedSpecies) { double maxSpeciesConsumptionRate = 0.0; - for (const auto& reaction : m_baseEngine.getNetworkReactions()) { + for (const auto& reaction : m_baseEngine.getNetworkReactions(ctx)) { const bool speciesToCheckIsConsumed = reaction->contains_reactant(species); if (!speciesToCheckIsConsumed) { continue; // If the species is not consumed by this reaction, skip it. } bool allOtherReactantsAreAvailable = true; for (const auto& reactant : reaction->reactants()) { - const bool reactantIsAvailable = std::ranges::contains(activeSpecies, reactant); + const bool reactantIsAvailable = std::ranges::contains(state->active_species, reactant); if (!reactantIsAvailable && reactant != species) { allOtherReactantsAreAvailable = false; } @@ -577,31 +547,33 @@ namespace gridfire::engine { } void AdaptiveEngineView::finalizeActiveSet( + scratch::StateBlob& ctx, const std::vector &finalReactions - ) { + ) const { + auto* state = scratch::get_state(ctx); std::unordered_setfinalSpeciesSet; - m_activeReactions.clear(); + state->active_reactions.clear(); for (const auto* reactionPtr: finalReactions) { - m_activeReactions.add_reaction(*reactionPtr); + state->active_reactions.add_reaction(*reactionPtr); for (const auto& reactant : reactionPtr->reactants()) { - const SpeciesStatus reactantStatus = m_baseEngine.getSpeciesStatus(reactant); + const SpeciesStatus reactantStatus = m_baseEngine.getSpeciesStatus(ctx, reactant); if (!finalSpeciesSet.contains(reactant) && (reactantStatus == SpeciesStatus::ACTIVE || reactantStatus == SpeciesStatus::EQUILIBRIUM)) { LOG_TRACE_L3(m_logger, "Adding reactant '{}' to active species set through reaction {}.", reactant.name(), reactionPtr->id()); finalSpeciesSet.insert(reactant); } } for (const auto& product : reactionPtr->products()) { - const SpeciesStatus productStatus = m_baseEngine.getSpeciesStatus(product); + const SpeciesStatus productStatus = m_baseEngine.getSpeciesStatus(ctx, product); if (!finalSpeciesSet.contains(product) && (productStatus == SpeciesStatus::ACTIVE || productStatus == SpeciesStatus::EQUILIBRIUM)) { LOG_TRACE_L3(m_logger, "Adding product '{}' to active species set through reaction {}.", product.name(), reactionPtr->id()); finalSpeciesSet.insert(product); } } } - m_activeSpecies.clear(); - m_activeSpecies = std::vector(finalSpeciesSet.begin(), finalSpeciesSet.end()); + state->active_species.clear(); + state->active_species = std::vector(finalSpeciesSet.begin(), finalSpeciesSet.end()); std::ranges::sort( - m_activeSpecies, + state->active_species, [](const Species &a, const Species &b) { return a.mass() < b.mass(); } ); } diff --git a/src/lib/engine/views/engine_defined.cpp b/src/lib/engine/views/engine_defined.cpp index fd318b3f..290951fb 100644 --- a/src/lib/engine/views/engine_defined.cpp +++ b/src/lib/engine/views/engine_defined.cpp @@ -5,6 +5,10 @@ #include "fourdst/atomic/atomicSpecies.h" #include "fourdst/composition/decorators/composition_masked.h" +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/engine_defined_scratchpad.h" +#include "gridfire/engine/scratchpads/utils.h" + #include "quill/LogMacros.h" #include @@ -15,8 +19,6 @@ #include #include -#include "fourdst/composition/exceptions/exceptions_composition.h" - namespace gridfire::engine { using fourdst::atomic::Species; @@ -25,30 +27,34 @@ namespace gridfire::engine { GraphEngine& baseEngine ) : m_baseEngine(baseEngine) { - collect(peNames); + // collect(peNames); } const DynamicEngine & DefinedEngineView::getBaseEngine() const { return m_baseEngine; } - const std::vector & DefinedEngineView::getNetworkSpecies() const { - if (m_activeSpeciesVectorCache.has_value()) { - return m_activeSpeciesVectorCache.value(); + const std::vector & DefinedEngineView::getNetworkSpecies( + scratch::StateBlob& ctx + ) const { + auto* state = scratch::get_state(ctx); + if (state->active_species_vector_cache.has_value()) { + return state->active_species_vector_cache.value(); } - m_activeSpeciesVectorCache = std::vector(m_activeSpecies.begin(), m_activeSpecies.end()); - return m_activeSpeciesVectorCache.value(); + state->active_species_vector_cache = std::vector(state->active_species.begin(), state->active_species.end()); + return state->active_species_vector_cache.value(); } std::expected, EngineStatus> DefinedEngineView::calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, - const double rho + const double rho, bool trust ) const { - validateNetworkState(); + auto *state = scratch::get_state(ctx); - const fourdst::composition::MaskedComposition masked(comp, m_activeSpecies); - const auto result = m_baseEngine.calculateRHSAndEnergy(masked, T9, rho, m_activeReactions); + const fourdst::composition::MaskedComposition masked(comp, state->active_species | std::ranges::to()); + const auto result = m_baseEngine.calculateRHSAndEnergy(ctx, masked, T9, rho, state->active_reactions); if (!result) { return std::unexpected{result.error()}; @@ -58,134 +64,105 @@ namespace gridfire::engine { } EnergyDerivatives DefinedEngineView::calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateNetworkState(); + auto* state = scratch::get_state(ctx); + const fourdst::composition::MaskedComposition masked(comp, state->active_species | std::ranges::to()); - const fourdst::composition::MaskedComposition masked(comp, m_activeSpecies); - - return m_baseEngine.calculateEpsDerivatives(masked, T9, rho, m_activeReactions); + return m_baseEngine.calculateEpsDerivatives(ctx, masked, T9, rho, state->active_reactions); } NetworkJacobian DefinedEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateNetworkState(); - if (!m_activeSpeciesVectorCache.has_value()) { - m_activeSpeciesVectorCache = std::vector(m_activeSpecies.begin(), m_activeSpecies.end()); + auto* state = scratch::get_state(ctx); + + if (!state->active_species_vector_cache.has_value()) { + state->active_species_vector_cache = std::vector(state->active_species.begin(), state->active_species.end()); } - const fourdst::composition::MaskedComposition masked(comp, m_activeSpecies); - return m_baseEngine.generateJacobianMatrix(masked, T9, rho, m_activeSpeciesVectorCache.value()); + const fourdst::composition::MaskedComposition masked(comp, state->active_species | std::ranges::to()); + return m_baseEngine.generateJacobianMatrix(ctx, masked, T9, rho, state->active_species_vector_cache.value()); } NetworkJacobian DefinedEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, - const std::vector &activeSpecies + const std::vector &activeSpecies ) const { - validateNetworkState(); const std::set activeSpeciesSet( activeSpecies.begin(), activeSpecies.end() ); - const fourdst::composition::MaskedComposition masked(comp, activeSpeciesSet); - return m_baseEngine.generateJacobianMatrix(masked, T9, rho, activeSpecies); + const fourdst::composition::MaskedComposition masked(comp, activeSpeciesSet | std::ranges::to()); + return m_baseEngine.generateJacobianMatrix(ctx, masked, T9, rho, activeSpecies); } NetworkJacobian DefinedEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const SparsityPattern &sparsityPattern ) const { - validateNetworkState(); - const fourdst::composition::MaskedComposition masked(comp, m_activeSpecies); - return m_baseEngine.generateJacobianMatrix(masked, T9, rho, sparsityPattern); - } - - void DefinedEngineView::generateStoichiometryMatrix() { - validateNetworkState(); - - m_baseEngine.generateStoichiometryMatrix(); - } - - int DefinedEngineView::getStoichiometryMatrixEntry( - const Species& species, - const reaction::Reaction& reaction - ) const { - validateNetworkState(); - - if (!m_activeSpecies.contains(species)) { - LOG_ERROR(m_logger, "Species '{}' is not part of the active species in the DefinedEngineView.", species.name()); - m_logger -> flush_log(); - throw std::runtime_error("Species not found in active species: " + std::string(species.name())); - } - - if (!m_activeReactions.contains(reaction)) { - LOG_ERROR(m_logger, "Reaction '{}' is not part of the active reactions in the DefinedEngineView.", reaction.id()); - m_logger -> flush_log(); - throw std::runtime_error("Reaction not found in active reactions: " + std::string(reaction.id())); - } - - return m_baseEngine.getStoichiometryMatrixEntry(species, reaction); + auto* state = scratch::get_state(ctx); + const fourdst::composition::MaskedComposition masked(comp, state->active_species | std::ranges::to()); + return m_baseEngine.generateJacobianMatrix(ctx, masked, T9, rho, sparsityPattern); } double DefinedEngineView::calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateNetworkState(); + auto* state = scratch::get_state(ctx); - if (!m_activeReactions.contains(reaction)) { + if (!state->active_reactions.contains(reaction)) { LOG_ERROR(m_logger, "Reaction '{}' is not part of the active reactions in the DefinedEngineView.", reaction.id()); m_logger -> flush_log(); throw std::runtime_error("Reaction not found in active reactions: " + std::string(reaction.id())); } - const fourdst::composition::MaskedComposition masked(comp, m_activeSpecies); - return m_baseEngine.calculateMolarReactionFlow(reaction, masked, T9, rho); + const fourdst::composition::MaskedComposition masked(comp, state->active_species | std::ranges::to()); + return m_baseEngine.calculateMolarReactionFlow(ctx, reaction, masked, T9, rho); } - const reaction::ReactionSet & DefinedEngineView::getNetworkReactions() const { - validateNetworkState(); + const reaction::ReactionSet & DefinedEngineView::getNetworkReactions( + scratch::StateBlob& ctx + ) const { - return m_activeReactions; - } - - void DefinedEngineView::setNetworkReactions(const reaction::ReactionSet &reactions) { - std::vector peNames; - for (const auto& reaction : reactions) { - peNames.emplace_back(reaction->id()); - } - collect(peNames); - m_activeSpeciesVectorCache = std::nullopt; // Invalidate species vector cache + auto* state = scratch::get_state(ctx); + return state->active_reactions; } std::expected, EngineStatus> DefinedEngineView::getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateNetworkState(); - const fourdst::composition::MaskedComposition masked(comp, m_activeSpecies); + auto* state = scratch::get_state(ctx); + const fourdst::composition::MaskedComposition masked(comp, state->active_species | std::ranges::to()); - const auto result = m_baseEngine.getSpeciesTimescales(masked, T9, rho, m_activeReactions); + const auto result = m_baseEngine.getSpeciesTimescales(ctx, masked, T9, rho, state->active_reactions); if (!result) { return std::unexpected{result.error()}; } const auto& fullTimescales = result.value(); std::unordered_map definedTimescales; - for (const auto& active_species : m_activeSpecies) { + for (const auto& active_species : state->active_species) { if (fullTimescales.contains(active_species)) { definedTimescales[active_species] = fullTimescales.at(active_species); } @@ -194,14 +171,15 @@ namespace gridfire::engine { } std::expected, EngineStatus> DefinedEngineView::getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - validateNetworkState(); - const fourdst::composition::MaskedComposition masked(comp, m_activeSpecies); + auto* state = scratch::get_state(ctx); + const fourdst::composition::MaskedComposition masked(comp, state->active_species| std::ranges::to()); - const auto result = m_baseEngine.getSpeciesDestructionTimescales(masked, T9, rho, m_activeReactions); + const auto result = m_baseEngine.getSpeciesDestructionTimescales(ctx, masked, T9, rho, state->active_reactions); if (!result) { return std::unexpected{result.error()}; @@ -210,7 +188,7 @@ namespace gridfire::engine { const auto& destructionTimescales = result.value(); std::unordered_map definedTimescales; - for (const auto& active_species : m_activeSpecies) { + for (const auto& active_species : state->active_species){ if (destructionTimescales.contains(active_species)) { definedTimescales[active_species] = destructionTimescales.at(active_species); } @@ -218,29 +196,28 @@ namespace gridfire::engine { return definedTimescales; } - fourdst::composition::Composition DefinedEngineView::update(const NetIn &netIn) { - return m_baseEngine.update(netIn); + fourdst::composition::Composition DefinedEngineView::project( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { + return m_baseEngine.project(ctx, netIn); } - bool DefinedEngineView::isStale(const NetIn &netIn) { - return m_baseEngine.isStale(netIn); + screening::ScreeningType DefinedEngineView::getScreeningModel( + scratch::StateBlob& ctx + ) const { + return m_baseEngine.getScreeningModel(ctx); } - void DefinedEngineView::setScreeningModel(const screening::ScreeningType model) { - m_baseEngine.setScreeningModel(model); - } + size_t DefinedEngineView::getSpeciesIndex( + scratch::StateBlob& ctx, + const Species &species + ) const { + auto* state = scratch::get_state(ctx); - screening::ScreeningType DefinedEngineView::getScreeningModel() const { - return m_baseEngine.getScreeningModel(); - } - - size_t DefinedEngineView::getSpeciesIndex(const Species &species) const { - // TODO: We are working to phase out all of these methods, its probably broken but it also should no longer be used and will be removed soon - validateNetworkState(); - - const auto it = std::ranges::find(m_activeSpecies, species); - if (it != m_activeSpecies.end()) { - return static_cast(std::distance(m_activeSpecies.begin(), it)); + const auto it = std::ranges::find(state->active_species, species); + if (it != state->active_species.end()) { + return static_cast(std::distance(state->active_species.begin(), it)); } else { LOG_ERROR(m_logger, "Species '{}' not found in active species list.", species.name()); m_logger->flush_log(); @@ -248,29 +225,23 @@ namespace gridfire::engine { } } - std::vector DefinedEngineView::mapNetInToMolarAbundanceVector(const NetIn &netIn) const { - std::vector Y(m_activeSpecies.size(), 0.0); // Initialize with zeros - for (const auto& [sp, y] : netIn.composition) { - auto it = std::ranges::find(m_activeSpecies, sp); - if (it != m_activeSpecies.end()) { - Y[getSpeciesIndex(sp)] = y; // Map species to their molar abundance - } - } - return Y; // Return the vector of molar abundances - } - - PrimingReport DefinedEngineView::primeEngine(const NetIn &netIn) { - return m_baseEngine.primeEngine(netIn); + PrimingReport DefinedEngineView::primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { + return m_baseEngine.primeEngine(ctx, netIn); } fourdst::composition::Composition DefinedEngineView::collectComposition( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - fourdst::composition::Composition result = m_baseEngine.collectComposition(comp, T9, rho); + fourdst::composition::Composition result = m_baseEngine.collectComposition(ctx, comp, T9, rho); + auto* state = scratch::get_state(ctx); - for (const auto& species : m_activeSpecies) { + for (const auto& species : state->active_species) { if (!result.contains(species)) { result.registerSpecies(species); } @@ -278,18 +249,30 @@ namespace gridfire::engine { return result; } - SpeciesStatus DefinedEngineView::getSpeciesStatus(const Species &species) const { - const SpeciesStatus status = m_baseEngine.getSpeciesStatus(species); - if (status == SpeciesStatus::ACTIVE && !m_activeSpecies.contains(species)) { + SpeciesStatus DefinedEngineView::getSpeciesStatus( + scratch::StateBlob& ctx, + const Species &species + ) const { + const auto *state = scratch::get_state(ctx); + const SpeciesStatus status = m_baseEngine.getSpeciesStatus(ctx, species); + if (status == SpeciesStatus::ACTIVE && !state->active_species.contains(species)) { return SpeciesStatus::INACTIVE_FLOW; } return status; } - std::vector DefinedEngineView::constructSpeciesIndexMap() const { + std::optional> DefinedEngineView::getMostRecentRHSCalculation( + scratch::StateBlob &ctx + ) const { + return m_baseEngine.getMostRecentRHSCalculation(ctx); + } + + std::vector DefinedEngineView::constructSpeciesIndexMap( + scratch::StateBlob& ctx + ) const { LOG_TRACE_L3(m_logger, "Constructing species index map for DefinedEngineView..."); std::unordered_map fullSpeciesReverseMap; - const auto& fullSpeciesList = m_baseEngine.getNetworkSpecies(); + const auto& fullSpeciesList = m_baseEngine.getNetworkSpecies(ctx); fullSpeciesReverseMap.reserve(fullSpeciesList.size()); @@ -298,9 +281,10 @@ namespace gridfire::engine { } std::vector speciesIndexMap; - speciesIndexMap.reserve(m_activeSpecies.size()); + auto* state = scratch::get_state(ctx); + speciesIndexMap.reserve(state->active_species.size()); - for (const auto& active_species : m_activeSpecies) { + for (const auto& active_species : state->active_species) { auto it = fullSpeciesReverseMap.find(active_species); if (it != fullSpeciesReverseMap.end()) { speciesIndexMap.push_back(it->second); @@ -315,12 +299,15 @@ namespace gridfire::engine { } - std::vector DefinedEngineView::constructReactionIndexMap() const { + std::vector DefinedEngineView::constructReactionIndexMap( + scratch::StateBlob& ctx + ) const { + auto* state = scratch::get_state(ctx); LOG_TRACE_L3(m_logger, "Constructing reaction index map for DefinedEngineView..."); // --- Step 1: Create a reverse map using the reaction's unique ID as the key. --- std::unordered_map fullReactionReverseMap; - const auto& fullReactionSet = m_baseEngine.getNetworkReactions(); + const auto& fullReactionSet = m_baseEngine.getNetworkReactions(ctx); fullReactionReverseMap.reserve(fullReactionSet.size()); for (size_t i_full = 0; i_full < fullReactionSet.size(); ++i_full) { @@ -329,9 +316,9 @@ namespace gridfire::engine { // --- Step 2: Build the final index map using the active reaction set. --- std::vector reactionIndexMap; - reactionIndexMap.reserve(m_activeReactions.size()); + reactionIndexMap.reserve(state->active_reactions.size()); - for (const auto& active_reaction_ptr : m_activeReactions) { + for (const auto& active_reaction_ptr : state->active_reactions) { auto it = fullReactionReverseMap.find(active_reaction_ptr->id()); if (it != fullReactionReverseMap.end()) { @@ -347,54 +334,66 @@ namespace gridfire::engine { return reactionIndexMap; } - std::vector DefinedEngineView::mapViewToFull(const std::vector& culled) const { - std::vector full(m_baseEngine.getNetworkSpecies().size(), 0.0); + std::vector DefinedEngineView::mapViewToFull( + scratch::StateBlob& ctx, + const std::vector& culled + ) const { + auto* state = scratch::get_state(ctx); + std::vector full(m_baseEngine.getNetworkSpecies(ctx).size(), 0.0); for (size_t i_culled = 0; i_culled < culled.size(); ++i_culled) { - const size_t i_full = m_speciesIndexMap[i_culled]; + const size_t i_full = state->species_index_map[i_culled]; full[i_full] += culled[i_culled]; } return full; } - std::vector DefinedEngineView::mapFullToView(const std::vector& full) const { - std::vector culled(m_activeSpecies.size(), 0.0); - for (size_t i_culled = 0; i_culled < m_activeSpecies.size(); ++i_culled) { - const size_t i_full = m_speciesIndexMap[i_culled]; + std::vector DefinedEngineView::mapFullToView( + scratch::StateBlob& ctx, + const std::vector& full + ) { + auto* state = scratch::get_state(ctx); + std::vector culled(state->active_species.size(), 0.0); + for (size_t i_culled = 0; i_culled < state->active_species.size(); ++i_culled) { + const size_t i_full = state->species_index_map[i_culled]; culled[i_culled] = full[i_full]; } return culled; } - size_t DefinedEngineView::mapViewToFullSpeciesIndex(size_t culledSpeciesIndex) const { - if (culledSpeciesIndex >= m_speciesIndexMap.size()) { - LOG_ERROR(m_logger, "Defined index {} is out of bounds for species index map of size {}.", culledSpeciesIndex, m_speciesIndexMap.size()); + size_t DefinedEngineView::mapViewToFullSpeciesIndex( + scratch::StateBlob& ctx, + size_t culledSpeciesIndex + ) const { + auto* state = scratch::get_state(ctx); + if (culledSpeciesIndex >= state->species_index_map.size()) { + LOG_ERROR(m_logger, "Defined index {} is out of bounds for species index map of size {}.", culledSpeciesIndex, state->species_index_map.size()); m_logger->flush_log(); - throw std::out_of_range("Defined index " + std::to_string(culledSpeciesIndex) + " is out of bounds for species index map of size " + std::to_string(m_speciesIndexMap.size()) + "."); + throw std::out_of_range("Defined index " + std::to_string(culledSpeciesIndex) + " is out of bounds for species index map of size " + std::to_string(state->species_index_map.size()) + "."); } - return m_speciesIndexMap[culledSpeciesIndex]; + return state->species_index_map[culledSpeciesIndex]; } - size_t DefinedEngineView::mapViewToFullReactionIndex(size_t culledReactionIndex) const { - if (culledReactionIndex >= m_reactionIndexMap.size()) { - LOG_ERROR(m_logger, "Defined index {} is out of bounds for reaction index map of size {}.", culledReactionIndex, m_reactionIndexMap.size()); + size_t DefinedEngineView::mapViewToFullReactionIndex( + scratch::StateBlob& ctx, + size_t culledReactionIndex + ) const { + auto* state = scratch::get_state(ctx); + if (culledReactionIndex >= state->reaction_index_map.size()) { + LOG_ERROR(m_logger, "Defined index {} is out of bounds for reaction index map of size {}.", culledReactionIndex, state->reaction_index_map.size()); m_logger->flush_log(); - throw std::out_of_range("Defined index " + std::to_string(culledReactionIndex) + " is out of bounds for reaction index map of size " + std::to_string(m_reactionIndexMap.size()) + "."); + throw std::out_of_range("Defined index " + std::to_string(culledReactionIndex) + " is out of bounds for reaction index map of size " + std::to_string(state->reaction_index_map.size()) + "."); } - return m_reactionIndexMap[culledReactionIndex]; + return state->reaction_index_map[culledReactionIndex]; } - void DefinedEngineView::validateNetworkState() const { - if (m_isStale) { - LOG_ERROR(m_logger, "DefinedEngineView is stale. Please call update() with a valid NetIn object."); - m_logger->flush_log(); - throw std::runtime_error("DefinedEngineView is stale. Please call update() with a valid NetIn object."); - } - } - - void DefinedEngineView::collect(const std::vector &peNames) { + void DefinedEngineView::collect( + scratch::StateBlob& ctx, + const std::vector &peNames + ) const { + auto* state = scratch::get_state(ctx); std::unordered_set seenSpecies; - const auto& fullNetworkReactionSet = m_baseEngine.getNetworkReactions(); + const auto& fullNetworkReactionSet = m_baseEngine.getNetworkReactions(ctx); for (const auto& peName : peNames) { if (!fullNetworkReactionSet.contains(peName)) { LOG_ERROR(m_logger, "Reaction with name '{}' not found in the base engine's network reactions. Aborting...", peName); @@ -405,16 +404,16 @@ namespace gridfire::engine { for (const auto& reactant : reaction->reactants()) { if (!seenSpecies.contains(reactant)) { seenSpecies.insert(reactant); - m_activeSpecies.emplace(reactant); + state->active_species.emplace(reactant); } } for (const auto& product : reaction->products()) { if (!seenSpecies.contains(product)) { seenSpecies.insert(product); - m_activeSpecies.emplace(product); + state->active_species.emplace(product); } } - m_activeReactions.add_reaction(*reaction); + state->active_reactions.add_reaction(*reaction); } LOG_TRACE_L3(m_logger, "DefinedEngineView built with {} active species and {} active reactions.", m_activeSpecies.size(), m_activeReactions.size()); LOG_TRACE_L3(m_logger, "Active species: {}", [this]() -> std::string { @@ -439,9 +438,8 @@ namespace gridfire::engine { } return result; }()); - m_speciesIndexMap = constructSpeciesIndexMap(); - m_reactionIndexMap = constructReactionIndexMap(); - m_isStale = false; + state->species_index_map = constructSpeciesIndexMap(ctx); + state->reaction_index_map = constructReactionIndexMap(ctx); } diff --git a/src/lib/engine/views/engine_multiscale.cpp b/src/lib/engine/views/engine_multiscale.cpp index 3bab8b9c..ec3d1a7c 100644 --- a/src/lib/engine/views/engine_multiscale.cpp +++ b/src/lib/engine/views/engine_multiscale.cpp @@ -4,6 +4,10 @@ #include "gridfire/utils/sundials.h" #include "gridfire/utils/logging.h" +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/utils.h" +#include "gridfire/engine/scratchpads/engine_multiscale_scratchpad.h" + #include #include #include @@ -151,18 +155,6 @@ namespace { return reactantSample != productSample; } - void QuietErrorRouter(int line, const char *func, const char *file, const char *msg, - SUNErrCode err_code, void *err_user_data, SUNContext sunctx) { - - // LIST OF ERRORS TO IGNORE - if (err_code == KIN_LINESEARCH_NONCONV) { - return; - } - - // For everything else, use the default SUNDIALS logger (or your own) - SUNLogErrHandlerFn(line, func, file, msg, err_code, err_user_data, sunctx); - } - struct DisjointSet { std::vector parent; explicit DisjointSet(const size_t n) { @@ -170,7 +162,7 @@ namespace { std::iota(parent.begin(), parent.end(), 0); } - size_t find(const size_t i) { + size_t find(const size_t i) { // NOLINT(*-no-recursion) if (parent.at(i) == i) return i; return parent.at(i) = find(parent.at(i)); // Path compression } @@ -192,31 +184,20 @@ namespace gridfire::engine { MultiscalePartitioningEngineView::MultiscalePartitioningEngineView( DynamicEngine& baseEngine ) : m_baseEngine(baseEngine) { - const int flag = SUNContext_Create(SUN_COMM_NULL, &m_sun_ctx); - if (flag != 0) { - LOG_CRITICAL(m_logger, "Error while creating SUNContext in MultiscalePartitioningEngineView"); - throw std::runtime_error("Error creating SUNContext in MultiscalePartitioningEngineView"); - } - SUNContext_PushErrHandler(m_sun_ctx, QuietErrorRouter, nullptr); } - MultiscalePartitioningEngineView::~MultiscalePartitioningEngineView() { - LOG_TRACE_L1(m_logger, "Cleaning up MultiscalePartitioningEngineView..."); - m_qse_solvers.clear(); - if (m_sun_ctx) { - SUNContext_Free(&m_sun_ctx); - m_sun_ctx = nullptr; - } - } - - const std::vector & MultiscalePartitioningEngineView::getNetworkSpecies() const { - return m_baseEngine.getNetworkSpecies(); + const std::vector & MultiscalePartitioningEngineView::getNetworkSpecies( + scratch::StateBlob& ctx + ) const { + return m_baseEngine.getNetworkSpecies(ctx); } std::expected, EngineStatus> MultiscalePartitioningEngineView::calculateRHSAndEnergy( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, - const double rho + const double rho, + bool trust ) const { LOG_TRACE_L2(m_logger, "Calculating RHS and Energy in MultiscalePartitioningEngineView at T9 = {}, rho = {}.", T9, rho); LOG_TRACE_L2(m_logger, "Input composition is {}", [&comp]() -> std::string { @@ -231,7 +212,7 @@ namespace gridfire::engine { } return ss.str(); }()); - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, trust); LOG_TRACE_L2(m_logger, "Equilibrated composition prior to calling base engine is {}", [&qseComposition, &comp]() -> std::string { std::stringstream ss; size_t i = 0; @@ -248,7 +229,7 @@ namespace gridfire::engine { return ss.str(); }()); - const auto result = m_baseEngine.calculateRHSAndEnergy(qseComposition, T9, rho); + const auto result = m_baseEngine.calculateRHSAndEnergy(ctx, qseComposition, T9, rho, false); LOG_TRACE_L2(m_logger, "Base engine calculation of RHS and Energy complete."); if (!result) { @@ -257,9 +238,10 @@ namespace gridfire::engine { } auto deriv = result.value(); + const auto* state = scratch::get_state(ctx); LOG_TRACE_L2(m_logger, "Zeroing out algebraic species derivatives."); - for (const auto& species : m_algebraic_species) { + for (const auto& species : state->algebraic_species) { deriv.dydt[species] = 0.0; // Fix the algebraic species to the equilibrium abundances we calculate. } LOG_TRACE_L2(m_logger, "Done Zeroing out algebraic species derivatives."); @@ -267,24 +249,28 @@ namespace gridfire::engine { } EnergyDerivatives MultiscalePartitioningEngineView::calculateEpsDerivatives( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); - return m_baseEngine.calculateEpsDerivatives(qseComposition, T9, rho); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); + return m_baseEngine.calculateEpsDerivatives(ctx, qseComposition, T9, rho); } NetworkJacobian MultiscalePartitioningEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); - return m_baseEngine.generateJacobianMatrix(qseComposition, T9, rho, m_dynamic_species); + const auto* state = scratch::get_state(ctx); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); + return m_baseEngine.generateJacobianMatrix(ctx, qseComposition, T9, rho, state->dynamic_species); } NetworkJacobian MultiscalePartitioningEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, @@ -292,7 +278,7 @@ namespace gridfire::engine { ) const { bool activeSpeciesIsSubset = true; for (const auto& species : activeSpecies) { - if (!involvesSpecies(species)) activeSpeciesIsSubset = false; + if (!involvesSpecies(ctx, species)) activeSpeciesIsSubset = false; } if (!activeSpeciesIsSubset) { std::string msg = std::format( @@ -300,7 +286,7 @@ namespace gridfire::engine { [&]() -> std::string { std::stringstream ss; for (const auto& species : activeSpecies) { - if (!this->involvesSpecies(species)) { + if (!involvesSpecies(ctx, species)) { ss << species << " "; } } @@ -313,114 +299,104 @@ namespace gridfire::engine { std::vector dynamicActiveSpeciesIntersection; for (const auto& species : activeSpecies) { - if (involvesSpeciesInDynamic(species)) { + if (involvesSpeciesInDynamic(ctx, species)) { dynamicActiveSpeciesIntersection.push_back(species); } } - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); - return m_baseEngine.generateJacobianMatrix(qseComposition, T9, rho, dynamicActiveSpeciesIntersection); + return m_baseEngine.generateJacobianMatrix(ctx, qseComposition, T9, rho, dynamicActiveSpeciesIntersection); } NetworkJacobian MultiscalePartitioningEngineView::generateJacobianMatrix( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, const SparsityPattern &sparsityPattern ) const { - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); - return m_baseEngine.generateJacobianMatrix(qseComposition, T9, rho, sparsityPattern); - } - - void MultiscalePartitioningEngineView::generateStoichiometryMatrix() { - m_baseEngine.generateStoichiometryMatrix(); - } - - int MultiscalePartitioningEngineView::getStoichiometryMatrixEntry( - const Species& species, - const reaction::Reaction& reaction - ) const { - return m_baseEngine.getStoichiometryMatrixEntry(species, reaction); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); + return m_baseEngine.generateJacobianMatrix(ctx, qseComposition, T9, rho, sparsityPattern); } double MultiscalePartitioningEngineView::calculateMolarReactionFlow( + scratch::StateBlob& ctx, const reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); - return m_baseEngine.calculateMolarReactionFlow(reaction, qseComposition, T9, rho); + return m_baseEngine.calculateMolarReactionFlow(ctx, reaction, qseComposition, T9, rho); } - const reaction::ReactionSet & MultiscalePartitioningEngineView::getNetworkReactions() const { - return m_baseEngine.getNetworkReactions(); - } - - void MultiscalePartitioningEngineView::setNetworkReactions(const reaction::ReactionSet &reactions) { - LOG_CRITICAL(m_logger, "setNetworkReactions is not supported in MultiscalePartitioningEngineView. Did you mean to call this on the base engine?"); - throw exceptions::UnableToSetNetworkReactionsError("setNetworkReactions is not supported in MultiscalePartitioningEngineView. Did you mean to call this on the base engine?"); + const reaction::ReactionSet & MultiscalePartitioningEngineView::getNetworkReactions( + scratch::StateBlob& ctx + ) const { + return m_baseEngine.getNetworkReactions(ctx); } std::expected, EngineStatus> MultiscalePartitioningEngineView::getSpeciesTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); - const auto result = m_baseEngine.getSpeciesTimescales(qseComposition, T9, rho); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); + const auto result = m_baseEngine.getSpeciesTimescales(ctx, qseComposition, T9, rho); if (!result) { return std::unexpected{result.error()}; } + + const auto* state = scratch::get_state(ctx); std::unordered_map speciesTimescales = result.value(); - for (const auto& algebraicSpecies : m_algebraic_species) { + for (const auto& algebraicSpecies : state->algebraic_species) { speciesTimescales[algebraicSpecies] = std::numeric_limits::infinity(); // Algebraic species have infinite timescales. } return speciesTimescales; } std::expected, EngineStatus> MultiscalePartitioningEngineView::getSpeciesDestructionTimescales( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); - const auto result = m_baseEngine.getSpeciesDestructionTimescales(qseComposition, T9, rho); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); + const auto result = m_baseEngine.getSpeciesDestructionTimescales(ctx, qseComposition, T9, rho); if (!result) { return std::unexpected{result.error()}; } std::unordered_map speciesDestructionTimescales = result.value(); - for (const auto& algebraicSpecies : m_algebraic_species) { + const auto* state = scratch::get_state(ctx); + for (const auto& algebraicSpecies : state->algebraic_species) { speciesDestructionTimescales[algebraicSpecies] = std::numeric_limits::infinity(); // Algebraic species have infinite destruction timescales. } return speciesDestructionTimescales; } - fourdst::composition::Composition MultiscalePartitioningEngineView::update(const NetIn &netIn) { - const fourdst::composition::Composition baseUpdatedComposition = m_baseEngine.update(netIn); + fourdst::composition::Composition MultiscalePartitioningEngineView::project( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { + const fourdst::composition::Composition baseUpdatedComposition = m_baseEngine.project(ctx, netIn); NetIn baseUpdatedNetIn = netIn; baseUpdatedNetIn.composition = baseUpdatedComposition; - fourdst::composition::Composition equilibratedComposition = partitionNetwork(baseUpdatedNetIn); - m_composition_cache.clear(); + fourdst::composition::Composition equilibratedComposition = partitionNetwork(ctx, baseUpdatedNetIn); + + auto* state = scratch::get_state(ctx); + state->composition_cache.clear(); return equilibratedComposition; } - bool MultiscalePartitioningEngineView::isStale(const NetIn &netIn) { - return m_baseEngine.isStale(netIn); - } - - void MultiscalePartitioningEngineView::setScreeningModel( - const screening::ScreeningType model - ) { - m_baseEngine.setScreeningModel(model); - } - - screening::ScreeningType MultiscalePartitioningEngineView::getScreeningModel() const { - return m_baseEngine.getScreeningModel(); + screening::ScreeningType MultiscalePartitioningEngineView::getScreeningModel( + scratch::StateBlob& ctx + ) const { + return m_baseEngine.getScreeningModel(ctx); } const DynamicEngine & MultiscalePartitioningEngineView::getBaseEngine() const { @@ -428,8 +404,11 @@ namespace gridfire::engine { } std::vector> MultiscalePartitioningEngineView::analyzeTimescalePoolConnectivity( - const std::vector> ×cale_pools, const fourdst::composition::Composition &comp, double T9, double - rho + scratch::StateBlob& ctx, + const std::vector> ×cale_pools, + const fourdst::composition::Composition &comp, + double T9, + double rho ) const { std::vector> final_connected_pools; @@ -439,7 +418,7 @@ namespace gridfire::engine { } // For each timescale pool, we need to analyze connectivity. - auto connectivity_graph = buildConnectivityGraph(pool, comp, T9, rho); + auto connectivity_graph = buildConnectivityGraph(ctx, pool, comp, T9, rho); auto components = findConnectedComponentsBFS(connectivity_graph, pool); final_connected_pools.insert(final_connected_pools.end(), components.begin(), components.end()); } @@ -448,20 +427,21 @@ namespace gridfire::engine { } std::vector MultiscalePartitioningEngineView::pruneValidatedGroups( + scratch::StateBlob& ctx, const std::vector &groups, const std::vector &groupReactions, const fourdst::composition::Composition &comp, const double T9, const double rho ) const { - const auto result = m_baseEngine.getSpeciesTimescales(comp, T9, rho); + const auto result = m_baseEngine.getSpeciesTimescales(ctx, comp, T9, rho); if (!result) { throw std::runtime_error("Base engine returned stale error during pruneValidatedGroups timescale retrieval."); } - std::unordered_map speciesTimescales = result.value(); + const std::unordered_map& speciesTimescales = result.value(); std::vector newGroups; for (const auto &[group, reactions] : std::views::zip(groups, groupReactions)) { - if (reactions.size() == 0) { // If a QSE group has gotten here it should have reactions associated with it. If it doesn't that is a serious error. + if (reactions.empty()) { // If a QSE group has gotten here it should have reactions associated with it. If it doesn't that is a serious error. LOG_CRITICAL(m_logger, "No reactions specified for QSE group {} during pruning analysis.", group.toString(false)); throw std::runtime_error("No reactions specified for QSE group " + group.toString(false) + " during pruneValidatedGroups flux analysis."); } @@ -474,7 +454,7 @@ namespace gridfire::engine { for (const auto& species : group.algebraic_species) { mean_molar_abundance += comp.getMolarAbundance(species); } - mean_molar_abundance /= group.algebraic_species.size(); + mean_molar_abundance /= static_cast(group.algebraic_species.size()); { // Safety Valve to ensure valid log scaling if (mean_molar_abundance <= 0) { LOG_CRITICAL(m_logger, "Non-positive mean molar abundance {} calculated for QSE group during pruning analysis.", mean_molar_abundance); @@ -483,7 +463,7 @@ namespace gridfire::engine { } for (const auto& reaction : reactions) { - const double flux = m_baseEngine.calculateMolarReactionFlow(*reaction, comp, T9, rho); + const double flux = m_baseEngine.calculateMolarReactionFlow(ctx, *reaction, comp, T9, rho); size_t hash = reaction->hash(0); if (reactionFluxes.contains(hash)) { throw std::runtime_error("Duplicate reaction hash found during pruneValidatedGroups flux analysis."); @@ -623,7 +603,7 @@ namespace gridfire::engine { for (const auto &species : g.algebraic_species) { meanTimescale += speciesTimescales.at(species); } - meanTimescale /= g.algebraic_species.size(); + meanTimescale /= static_cast(g.algebraic_species.size()); g.mean_timescale = meanTimescale; newGroups.push_back(g); } @@ -633,6 +613,7 @@ namespace gridfire::engine { } std::vector MultiscalePartitioningEngineView::merge_coupled_groups( + scratch::StateBlob& ctx, const std::vector &groups, const std::vector &groupReactions ) { @@ -687,10 +668,12 @@ namespace gridfire::engine { } fourdst::composition::Composition MultiscalePartitioningEngineView::partitionNetwork( + scratch::StateBlob& ctx, const NetIn &netIn - ) { + ) const { + auto* state = scratch::get_state(ctx); // --- Step 0. Prime the network --- - const PrimingReport primingReport = m_baseEngine.primeEngine(netIn); + const PrimingReport primingReport = m_baseEngine.primeEngine(ctx, netIn); const fourdst::composition::Composition& comp = primingReport.primedComposition; const double T9 = netIn.temperature / 1e9; const double rho = netIn.density; @@ -698,25 +681,25 @@ namespace gridfire::engine { // --- Step 0.5 Clear previous state --- LOG_TRACE_L1(m_logger, "Partitioning network..."); LOG_TRACE_L1(m_logger, "Clearing previous state..."); - m_qse_groups.clear(); - m_qse_solvers.clear(); - m_dynamic_species.clear(); - m_algebraic_species.clear(); - m_composition_cache.clear(); // We need to clear the cache now cause the same comp, temp, and density may result in a different value + state->qse_groups.clear(); + state->qse_solvers.clear(); + state->dynamic_species.clear(); + state->algebraic_species.clear(); + state->composition_cache.clear(); // We need to clear the cache now cause the same comp, temp, and density may result in a different value // --- Step 1. Identify distinct timescale regions --- LOG_TRACE_L1(m_logger, "Identifying fast reactions..."); - const std::vector> timescale_pools = partitionByTimescale(comp, T9, rho); + const std::vector> timescale_pools = partitionByTimescale(ctx, comp, T9, rho); LOG_TRACE_L1(m_logger, "Found {} timescale pools.", timescale_pools.size()); // --- Step 2. Select the mean slowest pool as the base dynamical group --- LOG_TRACE_L1(m_logger, "Identifying mean slowest pool..."); - const size_t mean_slowest_pool_index = identifyMeanSlowestPool(timescale_pools, comp, T9, rho); + const size_t mean_slowest_pool_index = identifyMeanSlowestPool(ctx, timescale_pools, comp, T9, rho); LOG_TRACE_L1(m_logger, "Mean slowest pool index: {}", mean_slowest_pool_index); // --- Step 3. Push the slowest pool into the dynamic species list --- for (const auto& slowSpecies : timescale_pools[mean_slowest_pool_index]) { - m_dynamic_species.push_back(slowSpecies); + state->dynamic_species.push_back(slowSpecies); } // --- Step 4. Pack Candidate QSE Groups --- @@ -728,88 +711,89 @@ namespace gridfire::engine { } LOG_TRACE_L1(m_logger, "Preforming connectivity analysis on timescale pools..."); - const std::vector> connected_pools = analyzeTimescalePoolConnectivity(candidate_pools, comp, T9, rho); + const std::vector> connected_pools = analyzeTimescalePoolConnectivity(ctx, candidate_pools, comp, T9, rho); LOG_TRACE_L1(m_logger, "Found {} connected pools (compared to {} timescale pools) for QSE analysis.", connected_pools.size(), timescale_pools.size()); // --- Step 5. Identify potential seed species for each candidate pool --- LOG_TRACE_L1(m_logger, "Identifying potential seed species for candidate pools..."); - const std::vector candidate_groups = constructCandidateGroups(connected_pools, comp, T9, rho); + const std::vector candidate_groups = constructCandidateGroups(ctx, connected_pools, comp, T9, rho); LOG_TRACE_L1(m_logger, "Found {} candidate QSE groups for further analysis ({})", candidate_groups.size(), utils::iterable_to_delimited_string(candidate_groups)); LOG_TRACE_L1(m_logger, "Validating candidate groups with flux analysis..."); - const auto [validated_groups, invalidate_groups, validated_group_reactions] = validateGroupsWithFluxAnalysis(candidate_groups, comp, T9, rho); + const auto [validated_groups, invalidate_groups, validated_group_reactions] = validateGroupsWithFluxAnalysis(ctx, candidate_groups, comp, T9, rho); LOG_TRACE_L1(m_logger, "Validated {} group(s) QSE groups. {}", validated_groups.size(), utils::iterable_to_delimited_string(validated_groups)); LOG_TRACE_L1(m_logger, "Pruning groups based on log abundance-normalized flux analysis..."); - const std::vector prunedGroups = pruneValidatedGroups(validated_groups, validated_group_reactions, comp, T9, rho); + const std::vector prunedGroups = pruneValidatedGroups(ctx, validated_groups, validated_group_reactions, comp, T9, rho); LOG_TRACE_L1(m_logger, "After Pruning remaining groups are: {}", utils::iterable_to_delimited_string(prunedGroups)); LOG_TRACE_L1(m_logger, "Re-validating pruned groups with flux analysis..."); - auto [pruned_validated_groups, _, pruned_validated_reactions] = validateGroupsWithFluxAnalysis(prunedGroups, comp, T9, rho); + auto [pruned_validated_groups, _, pruned_validated_reactions] = validateGroupsWithFluxAnalysis(ctx, prunedGroups, comp, T9, rho); LOG_TRACE_L1(m_logger, "After re-validation, {} QSE groups remain. ({})",pruned_validated_groups.size(), utils::iterable_to_delimited_string(pruned_validated_groups)); LOG_TRACE_L1(m_logger, "Merging coupled QSE groups..."); - const std::vector merged_groups = merge_coupled_groups(pruned_validated_groups, pruned_validated_reactions); + const std::vector merged_groups = merge_coupled_groups(ctx, pruned_validated_groups, pruned_validated_reactions); LOG_TRACE_L1(m_logger, "After merging, {} QSE groups remain. ({})", merged_groups.size(), utils::iterable_to_delimited_string(merged_groups)); - m_qse_groups = pruned_validated_groups; + state->qse_groups = pruned_validated_groups; LOG_TRACE_L1(m_logger, "Pushing all identified algebraic species into algebraic set..."); - for (const auto& group : m_qse_groups) { + for (const auto& group : state->qse_groups) { // Add algebraic species to the algebraic set for (const auto& species : group.algebraic_species) { - if (std::ranges::find(m_algebraic_species, species) == m_algebraic_species.end()) { - m_algebraic_species.push_back(species); + if (std::ranges::find(state->algebraic_species, species) == state->algebraic_species.end()) { + state->algebraic_species.push_back(species); } } } - LOG_TRACE_L1(m_logger, "Algebraic species identified: {}", utils::iterable_to_delimited_string(m_algebraic_species)); + LOG_TRACE_L1(m_logger, "Algebraic species identified: {}", utils::iterable_to_delimited_string(state->algebraic_species)); LOG_INFO( m_logger, "Partitioning complete. Found {} dynamic species, {} algebraic (QSE) species ({}) spread over {} QSE group{}.", - m_dynamic_species.size(), - m_algebraic_species.size(), - utils::iterable_to_delimited_string(m_algebraic_species), - m_qse_groups.size(), - m_qse_groups.size() == 1 ? "" : "s" + state->dynamic_species.size(), + state->algebraic_species.size(), + utils::iterable_to_delimited_string(state->algebraic_species), + state->qse_groups.size(), + state->qse_groups.size() == 1 ? "" : "s" ); // Sort the QSE groups by mean timescale so that fastest groups get equilibrated first (as these may feed slower groups) LOG_TRACE_L1(m_logger, "Sorting algebraic set by mean timescale..."); - std::ranges::sort(m_qse_groups, [](const QSEGroup& a, const QSEGroup& b) { + std::ranges::sort(state->qse_groups, [](const QSEGroup& a, const QSEGroup& b) { return a.mean_timescale < b.mean_timescale; }); LOG_TRACE_L1(m_logger, "Finalizing dynamic species list..."); - for (const auto& species : m_baseEngine.getNetworkSpecies()) { - const bool involvesAlgebraic = involvesSpeciesInQSE(species); - if (std::ranges::find(m_dynamic_species, species) == m_dynamic_species.end() && !involvesAlgebraic) { - m_dynamic_species.push_back(species); + for (const auto& species : m_baseEngine.getNetworkSpecies(ctx)) { + const bool involvesAlgebraic = involvesSpeciesInQSE(ctx, species); + if (std::ranges::find(state->dynamic_species, species) == state->dynamic_species.end() && !involvesAlgebraic) { + state->dynamic_species.push_back(species); } } - LOG_TRACE_L1(m_logger, "Final dynamic species set: {}", utils::iterable_to_delimited_string(m_dynamic_species)); + LOG_TRACE_L1(m_logger, "Final dynamic species set: {}", utils::iterable_to_delimited_string(state->dynamic_species)); LOG_TRACE_L1(m_logger, "Creating QSE solvers for each identified QSE group..."); - for (const auto& group : m_qse_groups) { + for (const auto& group : state->qse_groups) { std::vector groupAlgebraicSpecies; for (const auto& species : group.algebraic_species) { groupAlgebraicSpecies.push_back(species); } - m_qse_solvers.push_back(std::make_unique(groupAlgebraicSpecies, m_baseEngine, m_sun_ctx)); + state->qse_solvers.push_back(std::make_unique(groupAlgebraicSpecies, m_baseEngine, state->sun_ctx)); } - LOG_TRACE_L1(m_logger, "{} QSE solvers created.", m_qse_solvers.size()); + LOG_TRACE_L1(m_logger, "{} QSE solvers created.", state->qse_solvers.size()); LOG_TRACE_L1(m_logger, "Calculating final equilibrated composition..."); - fourdst::composition::Composition result = getNormalizedEquilibratedComposition(comp, T9, rho); + fourdst::composition::Composition result = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); LOG_TRACE_L1(m_logger, "Final equilibrated composition calculated..."); return result; } void MultiscalePartitioningEngineView::exportToDot( + scratch::StateBlob &ctx, const std::string &filename, const fourdst::composition::Composition &comp, const double T9, @@ -821,22 +805,24 @@ namespace gridfire::engine { throw std::runtime_error("Failed to open file for writing: " + filename); } - const auto& all_species = m_baseEngine.getNetworkSpecies(); - const auto& all_reactions = m_baseEngine.getNetworkReactions(); + const auto* state = scratch::get_state(ctx); + + const auto& all_species = m_baseEngine.getNetworkSpecies(ctx); + const auto& all_reactions = m_baseEngine.getNetworkReactions(ctx); // --- 1. Pre-computation and Categorization --- // Categorize species into algebraic, seed, and core dynamic std::unordered_set algebraic_species; std::unordered_set seed_species; - for (const auto& group : m_qse_groups) { + for (const auto& group : state->qse_groups) { if (group.is_in_equilibrium) { algebraic_species.insert(group.algebraic_species.begin(), group.algebraic_species.end()); seed_species.insert(group.seed_species.begin(), group.seed_species.end()); } } - const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(comp, T9, rho); + const fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); // Calculate reaction flows and find min/max for logarithmic scaling of transparency std::vector reaction_flows; reaction_flows.reserve(all_reactions.size()); @@ -844,7 +830,7 @@ namespace gridfire::engine { double max_log_flow = std::numeric_limits::lowest(); for (const auto& reaction : all_reactions) { - double flow = std::abs(m_baseEngine.calculateMolarReactionFlow(*reaction, qseComposition, T9, rho)); + double flow = std::abs(m_baseEngine.calculateMolarReactionFlow(ctx, *reaction, qseComposition, T9, rho)); reaction_flows.push_back(flow); if (flow > 1e-99) { // Avoid log(0) double log_flow = std::log10(flow); @@ -874,7 +860,7 @@ namespace gridfire::engine { fillcolor = "#e0f2fe"; // Light Blue: Algebraic (in QSE) } else if (seed_species.contains(species)) { fillcolor = "#a7f3d0"; // Light Green: Seed (Dynamic, feeds a QSE group) - } else if (std::ranges::contains(m_dynamic_species, species)) { + } else if (std::ranges::contains(state->dynamic_species, species)) { fillcolor = "#dcfce7"; // Pale Green: Core Dynamic } dotFile << " \"" << species.name() << "\" [label=\"" << species.name() << "\", fillcolor=\"" << fillcolor << "\"];\n"; @@ -917,7 +903,7 @@ namespace gridfire::engine { // Draw a prominent box around the algebraic species of each valid QSE group. dotFile << " // --- QSE Group Clusters ---\n"; int group_counter = 0; - for (const auto& group : m_qse_groups) { + for (const auto& group : state->qse_groups) { if (!group.is_in_equilibrium || group.algebraic_species.empty()) { continue; } @@ -1018,62 +1004,72 @@ namespace gridfire::engine { dotFile.close(); } - - std::vector MultiscalePartitioningEngineView::mapNetInToMolarAbundanceVector(const NetIn &netIn) const { - std::vector Y(netIn.composition.size(), 0.0); // Initialize with zeros - for (const auto& [sp, y] : netIn.composition) { - Y[getSpeciesIndex(sp)] = y; // Map species to their molar abundance - } - return Y; // Return the vector of molar abundances - } - - std::vector MultiscalePartitioningEngineView::getFastSpecies() const { - const auto& all_species = m_baseEngine.getNetworkSpecies(); + std::vector MultiscalePartitioningEngineView::getFastSpecies( + scratch::StateBlob& ctx + ) const { + const auto& all_species = m_baseEngine.getNetworkSpecies(ctx); + const auto* state = scratch::get_state(ctx); std::vector fast_species; - fast_species.reserve(all_species.size() - m_dynamic_species.size()); + fast_species.reserve(all_species.size() - state->dynamic_species.size()); for (const auto& species : all_species) { - auto it = std::ranges::find(m_dynamic_species, species); - if (it == m_dynamic_species.end()) { + auto it = std::ranges::find(state->dynamic_species, species); + if (it == state->dynamic_species.end()) { fast_species.push_back(species); } } return fast_species; } - const std::vector & MultiscalePartitioningEngineView::getDynamicSpecies() const { - return m_dynamic_species; + const std::vector & MultiscalePartitioningEngineView::getDynamicSpecies( + scratch::StateBlob& ctx + ) { + const auto* state = scratch::get_state(ctx); + return state->dynamic_species; } - PrimingReport MultiscalePartitioningEngineView::primeEngine(const NetIn &netIn) { - return m_baseEngine.primeEngine(netIn); + PrimingReport MultiscalePartitioningEngineView::primeEngine( + scratch::StateBlob& ctx, + const NetIn &netIn + ) const { + return m_baseEngine.primeEngine(ctx, netIn); } bool MultiscalePartitioningEngineView::involvesSpecies( + scratch::StateBlob& ctx, const Species &species - ) const { - if (involvesSpeciesInQSE(species)) return true; // check this first since the vector is likely to be smaller so short circuit cost is less on average - if (involvesSpeciesInDynamic(species)) return true; + ) { + if (involvesSpeciesInQSE(ctx, species)) return true; // check this first since the vector is likely to be smaller so short circuit cost is less on average + if (involvesSpeciesInDynamic(ctx, species)) return true; return false; } bool MultiscalePartitioningEngineView::involvesSpeciesInQSE( + scratch::StateBlob& ctx, const Species &species - ) const { - return std::ranges::find(m_algebraic_species, species) != m_algebraic_species.end(); + ) { + const auto* state = scratch::get_state(ctx); + return std::ranges::find(state->algebraic_species, species) != state->algebraic_species.end(); } bool MultiscalePartitioningEngineView::involvesSpeciesInDynamic( + scratch::StateBlob& ctx, const Species &species - ) const { - return std::ranges::find(m_dynamic_species, species) != m_dynamic_species.end(); + ) { + const auto* state = scratch::get_state(ctx); + return std::ranges::find(state->dynamic_species, species) != state->dynamic_species.end(); } fourdst::composition::Composition MultiscalePartitioningEngineView::getNormalizedEquilibratedComposition( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract& comp, const double T9, - const double rho + const double rho, + const bool trust ) const { + if (trust) { + return fourdst::composition::Composition(comp); + } // Caching mechanism to avoid redundant QSE solves const std::array hashes = { fourdst::composition::utils::CompositionHash::hash_exact(comp), @@ -1081,59 +1077,69 @@ namespace gridfire::engine { std::hash()(rho) }; + auto* state = scratch::get_state(ctx); const uint64_t composite_hash = XXHash64::hash(hashes.begin(), sizeof(uint64_t) * 3, 0); - if (m_composition_cache.contains(composite_hash)) { + if (state->composition_cache.contains(composite_hash)) { LOG_TRACE_L3(m_logger, "Cache Hit in Multiscale Partitioning Engine View for composition at T9 = {}, rho = {}.", T9, rho); - return m_composition_cache.at(composite_hash); + return state->composition_cache.at(composite_hash); } LOG_TRACE_L3(m_logger, "Cache Miss in Multiscale Partitioning Engine View for composition at T9 = {}, rho = {}. Solving QSE abundances...", T9, rho); // Only solve if the composition and thermodynamic conditions have not been cached yet - fourdst::composition::Composition qseComposition = solveQSEAbundances(comp, T9, rho); + fourdst::composition::Composition qseComposition(solveQSEAbundances(ctx, comp, T9, rho)); - for (const auto &[sp, y]: qseComposition) { - if (y < 0.0 && std::abs(y) < 1e-20) { - qseComposition.setMolarAbundance(sp, 0.0); // normalize small negative abundances to zero - } - } - m_composition_cache[composite_hash] = qseComposition; + state->composition_cache[composite_hash] = qseComposition; return qseComposition; } fourdst::composition::Composition MultiscalePartitioningEngineView::collectComposition( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { - const fourdst::composition::Composition result = m_baseEngine.collectComposition(comp, T9, rho); + const fourdst::composition::Composition result = m_baseEngine.collectComposition(ctx, comp, T9, rho); - fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(result, T9, rho); + fourdst::composition::Composition qseComposition = getNormalizedEquilibratedComposition(ctx, result, T9, rho, false); return qseComposition; } - SpeciesStatus MultiscalePartitioningEngineView::getSpeciesStatus(const Species &species) const { - const SpeciesStatus status = m_baseEngine.getSpeciesStatus(species); - if (status == SpeciesStatus::ACTIVE && involvesSpeciesInQSE(species)) { + SpeciesStatus MultiscalePartitioningEngineView::getSpeciesStatus( + scratch::StateBlob& ctx, + const Species &species + ) const { + const SpeciesStatus status = m_baseEngine.getSpeciesStatus(ctx, species); + if (status == SpeciesStatus::ACTIVE && involvesSpeciesInQSE(ctx, species)) { return SpeciesStatus::EQUILIBRIUM; } return status; } - size_t MultiscalePartitioningEngineView::getSpeciesIndex(const Species &species) const { - return m_baseEngine.getSpeciesIndex(species); + std::optional> MultiscalePartitioningEngineView::getMostRecentRHSCalculation( + scratch::StateBlob& ctx + ) const { + return m_baseEngine.getMostRecentRHSCalculation(ctx); + } + + size_t MultiscalePartitioningEngineView::getSpeciesIndex( + scratch::StateBlob& ctx, + const Species &species + ) const { + return m_baseEngine.getSpeciesIndex(ctx, species); } std::vector> MultiscalePartitioningEngineView::partitionByTimescale( + scratch::StateBlob& ctx, const fourdst::composition::Composition &comp, const double T9, const double rho ) const { LOG_TRACE_L1(m_logger, "Partitioning by timescale..."); - const auto destructionTimescale= m_baseEngine.getSpeciesDestructionTimescales(comp, T9, rho); - const auto netTimescale = m_baseEngine.getSpeciesTimescales(comp, T9, rho); + const auto destructionTimescale= m_baseEngine.getSpeciesDestructionTimescales(ctx, comp, T9, rho); + const auto netTimescale = m_baseEngine.getSpeciesTimescales(ctx, comp, T9, rho); if (!destructionTimescale || !netTimescale) { LOG_CRITICAL(m_logger, "Failed to compute species timescales for partitioning due to base engine error."); @@ -1155,7 +1161,7 @@ namespace gridfire::engine { }() ); - const auto& all_species = m_baseEngine.getNetworkSpecies(); + const auto& all_species = m_baseEngine.getNetworkSpecies(ctx); std::vector> sorted_destruction_timescales; for (const auto & species : all_species) { @@ -1311,6 +1317,7 @@ namespace gridfire::engine { } std::pair MultiscalePartitioningEngineView::group_is_a_qse_cluster( + scratch::StateBlob& ctx, const fourdst::composition::Composition &comp, const double T9, const double rho, @@ -1332,8 +1339,8 @@ namespace gridfire::engine { double coupling_flux = 0.0; double leakage_flux = 0.0; - for (const auto& reaction: m_baseEngine.getNetworkReactions()) { - const double flow = std::abs(m_baseEngine.calculateMolarReactionFlow(*reaction, comp, T9, rho)); + for (const auto& reaction: m_baseEngine.getNetworkReactions(ctx)) { + const double flow = std::abs(m_baseEngine.calculateMolarReactionFlow(ctx, *reaction, comp, T9, rho)); if (flow == 0.0) { continue; // Skip reactions with zero flow } @@ -1422,10 +1429,11 @@ namespace gridfire::engine { } bool MultiscalePartitioningEngineView::group_is_a_qse_pipeline( - const fourdst::composition::Composition &comp, - const double T9, - const double rho, - const QSEGroup &group + scratch::StateBlob& ctx, + const fourdst::composition::Composition &comp, + const double T9, + const double rho, + const QSEGroup &group ) const { // Total fluxes (Standard check) double total_prod = 0.0; @@ -1435,8 +1443,8 @@ namespace gridfire::engine { double charged_prod = 0.0; double charged_dest = 0.0; - for (const auto& reaction : m_baseEngine.getNetworkReactions()) { - const double flow = m_baseEngine.calculateMolarReactionFlow(*reaction, comp, T9, rho); + for (const auto& reaction : m_baseEngine.getNetworkReactions(ctx)) { + const double flow = m_baseEngine.calculateMolarReactionFlow(ctx, *reaction, comp, T9, rho); if (std::abs(flow) < 1.0e-99) continue; int groupNetStoichiometry = 0; @@ -1476,6 +1484,7 @@ namespace gridfire::engine { MultiscalePartitioningEngineView::FluxValidationResult MultiscalePartitioningEngineView::validateGroupsWithFluxAnalysis( + scratch::StateBlob& ctx, const std::vector &candidate_groups, const fourdst::composition::Composition &comp, const double T9, const double rho @@ -1487,10 +1496,10 @@ namespace gridfire::engine { group_reactions.reserve(candidate_groups.size()); for (auto& group : candidate_groups) { // Values for measuring the flux coupling vs leakage - auto [leakage_coupled, group_reaction_set] = group_is_a_qse_cluster(comp, T9, rho, group); + auto [leakage_coupled, group_reaction_set] = group_is_a_qse_cluster(ctx, comp, T9, rho, group); - bool is_flow_balanced = group_is_a_qse_pipeline(comp, T9, rho, group); + bool is_flow_balanced = group_is_a_qse_pipeline(ctx, comp, T9, rho, group); if (leakage_coupled) { LOG_TRACE_L1(m_logger, "{} is in equilibrium due to high coupling flux", group.toString(false)); @@ -1516,16 +1525,23 @@ namespace gridfire::engine { } fourdst::composition::Composition MultiscalePartitioningEngineView::solveQSEAbundances( + scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho ) const { LOG_TRACE_L2(m_logger, "Solving for QSE abundances..."); + auto* state = scratch::get_state(ctx); fourdst::composition::Composition outputComposition(comp); - for (const auto& [group, solver]: std::views::zip(m_qse_groups, m_qse_solvers)) { - const fourdst::composition::Composition groupResult = solver->solve(outputComposition, T9, rho); + std::vector species; + std::vector abundances; + species.reserve(state->algebraic_species.size()); + abundances.reserve(state->algebraic_species.size()); + + for (const auto& [group, solver]: std::views::zip(state->qse_groups, state->qse_solvers)) { + const fourdst::composition::Composition& groupResult = solver->solve(ctx, outputComposition, T9, rho); for (const auto& [sp, y] : groupResult) { if (!std::isfinite(y)) { LOG_CRITICAL(m_logger, "Non-finite abundance {} computed for species {} in QSE group solve at T9 = {}, rho = {}.", @@ -1533,21 +1549,28 @@ namespace gridfire::engine { m_logger->flush_log(); throw exceptions::EngineError("Non-finite abundance computed for species " + std::string(sp.name()) + " in QSE group solve."); } - outputComposition.setMolarAbundance(sp, y); + if (y < 0.0 && std::abs(y) < 1e-20) { + abundances.push_back(0.0); + } else { + abundances.push_back(y); + } + species.emplace_back(sp); } - solver->log_diagnostics(group, outputComposition); + // solver->log_diagnostics(group, outputComposition); } + outputComposition.setMolarAbundance(species, abundances); LOG_TRACE_L2(m_logger, "Done solving for QSE abundances!"); return outputComposition; } size_t MultiscalePartitioningEngineView::identifyMeanSlowestPool( + scratch::StateBlob& ctx, const std::vector> &pools, const fourdst::composition::Composition &comp, const double T9, const double rho ) const { - const auto& result = m_baseEngine.getSpeciesDestructionTimescales(comp, T9, rho); + const auto& result = m_baseEngine.getSpeciesDestructionTimescales(ctx, comp, T9, rho); if (!result) { LOG_CRITICAL(m_logger, "Failed to get species destruction timescales due base engine failure"); m_logger->flush_log(); @@ -1592,6 +1615,7 @@ namespace gridfire::engine { } std::unordered_map> MultiscalePartitioningEngineView::buildConnectivityGraph( + scratch::StateBlob& ctx, const std::vector &species_pool, const fourdst::composition::Composition &comp, double T9, @@ -1611,7 +1635,7 @@ namespace gridfire::engine { std::map> speciesReactionMap; std::vector candidate_reactions; - for (const auto& reaction : m_baseEngine.getNetworkReactions()) { + for (const auto& reaction : m_baseEngine.getNetworkReactions(ctx)) { const std::vector &reactants = reaction->reactants(); const std::vector &products = reaction->products(); @@ -1649,13 +1673,14 @@ namespace gridfire::engine { } std::vector MultiscalePartitioningEngineView::constructCandidateGroups( + scratch::StateBlob& ctx, const std::vector> &candidate_pools, const fourdst::composition::Composition &comp, const double T9, const double rho ) const { - const auto& all_reactions = m_baseEngine.getNetworkReactions(); - const auto& result = m_baseEngine.getSpeciesDestructionTimescales(comp, T9, rho); + const auto& all_reactions = m_baseEngine.getNetworkReactions(ctx); + const auto& result = m_baseEngine.getSpeciesDestructionTimescales(ctx, comp, T9, rho); if (!result) { LOG_ERROR(m_logger, "Failed to get species destruction timescales due base engine failure"); m_logger->flush_log(); @@ -1683,7 +1708,7 @@ namespace gridfire::engine { } } if (has_external_reactant) { - double flow = std::abs(m_baseEngine.calculateMolarReactionFlow(*reaction, comp, T9, rho)); + double flow = std::abs(m_baseEngine.calculateMolarReactionFlow(ctx, *reaction, comp, T9, rho)); LOG_TRACE_L3(m_logger, "Found bridge reaction {} with flow {} for species {}.", reaction->id(), flow, ash.name()); bridge_reactions.emplace_back(reaction.get(), flow); } @@ -1815,7 +1840,7 @@ namespace gridfire::engine { utils::check_sundials_flag(KINSetMaxSetupCalls(m_kinsol_mem, 20), "KINSetMaxSetupCalls", utils::SUNDIALS_RET_CODE_TYPES::KINSOL); - utils::check_sundials_flag(KINSetFuncNormTol(m_kinsol_mem, 1e-6), "KINSetFuncNormTol", utils::SUNDIALS_RET_CODE_TYPES::KINSOL); + utils::check_sundials_flag(KINSetFuncNormTol(m_kinsol_mem, 1e-8), "KINSetFuncNormTol", utils::SUNDIALS_RET_CODE_TYPES::KINSOL); utils::check_sundials_flag(KINSetNumMaxIters(m_kinsol_mem, 200), "KINSetNumMaxIters", utils::SUNDIALS_RET_CODE_TYPES::KINSOL); utils::check_sundials_flag(KINSetScaledStepTol(m_kinsol_mem, 1e-10), "KINSetScaledStepTol", utils::SUNDIALS_RET_CODE_TYPES::KINSOL); @@ -1861,6 +1886,7 @@ namespace gridfire::engine { } fourdst::composition::Composition MultiscalePartitioningEngineView::QSESolver::solve( + scratch::StateBlob& ctx, const fourdst::composition::Composition &comp, const double T9, const double rho @@ -1874,7 +1900,8 @@ namespace gridfire::engine { result, m_speciesMap, m_species, - *this + *this, + ctx }; utils::check_sundials_flag(KINSetUserData(m_kinsol_mem, &data), "KINSetUserData", utils::SUNDIALS_RET_CODE_TYPES::KINSOL); @@ -1893,15 +1920,22 @@ namespace gridfire::engine { scale_data[i] = 1.0 / Y; } - auto initial_rhs = m_engine.calculateRHSAndEnergy(result, T9, rho); - if (!initial_rhs) { - throw std::runtime_error("In QSE solver failed to calculate initial RHS"); + StepDerivatives rhsGuess; + auto cached_rhs = m_engine.getMostRecentRHSCalculation(ctx); + if (!cached_rhs) { + const auto initial_rhs = m_engine.calculateRHSAndEnergy(ctx, result, T9, rho, false); + if (!initial_rhs) { + throw std::runtime_error("In QSE solver failed to calculate initial RHS for caching"); + } + rhsGuess = initial_rhs.value(); + } else { + rhsGuess = cached_rhs.value(); } sunrealtype* f_scale_data = N_VGetArrayPointer(m_f_scale); for (size_t i = 0; i < m_N; ++i) { const auto& species = m_species[i]; - double dydt = std::abs(initial_rhs.value().dydt.at(species)); + double dydt = std::abs(rhsGuess.dydt.at(species)); f_scale_data[i] = 1.0 / (dydt + 1e-15); } @@ -1915,7 +1949,7 @@ namespace gridfire::engine { LOG_TRACE_L2( getLogger(), "Starting KINSol QSE solver with initial state: {}", - [&comp, &initial_rhs, &data]() -> std::string { + [&comp, &rhsGuess, &data]() -> std::string { std::ostringstream oss; oss << "Solve species: <"; size_t count = 0; @@ -1929,7 +1963,7 @@ namespace gridfire::engine { oss << "> | Initial abundances and rates: "; count = 0; for (const auto& [species, abundance] : comp) { - oss << species.name() << ": Y = " << abundance << ", dY/dt = " << initial_rhs.value().dydt.at(species); + oss << species.name() << ": Y = " << abundance << ", dY/dt = " << rhsGuess.dydt.at(species); if (count < comp.size() - 1) { oss << ", "; } @@ -1971,7 +2005,32 @@ namespace gridfire::engine { LOG_INFO(getLogger(), "KINSol failed to converge within the maximum number of iterations, but achieved acceptable accuracy with function norm {} < {}. Proceeding with solution.", fnorm, ACCEPTABLE_FTOL); } else { - LOG_WARNING(getLogger(), "KINSol failed to converge while solving QSE abundances with flag {}. Error {}", utils::kinsol_ret_code_map.at(flag), fnorm); + LOG_CRITICAL(getLogger(), "KINSol failed to converge while solving QSE abundances with flag {}. Flag No.: {}, Error (fNorm): {}", utils::kinsol_ret_code_map.at(flag), flag, fnorm); + LOG_CRITICAL(getLogger(), "State prior to failure: {}", + [&comp, &data]() -> std::string { + std::ostringstream oss; + oss << "Solve species: <"; + size_t count = 0; + for (const auto& species : data.qse_solve_species) { + oss << species.name(); + if (count < data.qse_solve_species.size() - 1) { + oss << ", "; + } + count++; + } + oss << "> | Abundances and rates at failure: "; + count = 0; + for (const auto& [species, abundance] : comp) { + oss << species.name() << ": Y = " << abundance; + if (count < comp.size() - 1) { + oss << ", "; + } + count++; + } + oss << " | Temperature: " << data.T9 << ", Density: " << data.rho; + return oss.str(); + }() + ); throw exceptions::InvalidQSESolutionError("KINSol failed to converge while solving QSE abundances. " + utils::kinsol_ret_code_map.at(flag)); } } @@ -2045,6 +2104,16 @@ namespace gridfire::engine { getLogger()->flush_log(true); } + std::unique_ptr MultiscalePartitioningEngineView::QSESolver::clone() const { + auto new_solver = std::make_unique(m_species, m_engine, m_sun_ctx); + return new_solver; + } + + std::unique_ptr MultiscalePartitioningEngineView::QSESolver::clone(SUNContext sun_ctx) const { + auto new_solver = std::make_unique(m_species, m_engine, sun_ctx); + return new_solver; + } + int MultiscalePartitioningEngineView::QSESolver::sys_func( const N_Vector y, @@ -2068,7 +2137,7 @@ namespace gridfire::engine { data->comp.setMolarAbundance(species, y_data[index]); } - const auto result = data->engine.calculateRHSAndEnergy(data->comp, data->T9, data->rho); + const auto result = data->engine.calculateRHSAndEnergy(data->ctx, data->comp, data->T9, data->rho, false); if (!result) { return 1; // Potentially recoverable error @@ -2084,7 +2153,7 @@ namespace gridfire::engine { for (const auto &s: map | std::views::keys) { const double v = dydt.at(s); if (!std::isfinite(v)) { - invalid_species.push_back(std::make_pair(s, v)); + invalid_species.emplace_back(s, v); } } std::string msg = std::format("Non-finite dydt values encountered for species: {}", @@ -2132,6 +2201,7 @@ namespace gridfire::engine { } const NetworkJacobian jac = data->engine.generateJacobianMatrix( + data->ctx, data->comp, data->T9, data->rho, @@ -2141,9 +2211,6 @@ namespace gridfire::engine { sunrealtype* J_data = SUNDenseMatrix_Data(J); const sunindextype N = SUNDenseMatrix_Columns(J); - if (data->row_scaling_factors.size() != static_cast(N)) { - data->row_scaling_factors.resize(N, 0.0); - } for (const auto& [row_species, row_idx]: map) { double max_value = std::numeric_limits::lowest(); diff --git a/src/lib/engine/views/engine_priming.cpp b/src/lib/engine/views/engine_priming.cpp index 83769912..728c18b6 100644 --- a/src/lib/engine/views/engine_priming.cpp +++ b/src/lib/engine/views/engine_priming.cpp @@ -1,5 +1,5 @@ #include "gridfire/engine/views/engine_priming.h" -#include "gridfire/solver/solver.h" +#include "gridfire/engine/scratchpads/blob.h" #include "fourdst/atomic/species.h" @@ -11,16 +11,17 @@ #include #include - namespace gridfire::engine { using fourdst::atomic::species; NetworkPrimingEngineView::NetworkPrimingEngineView( + scratch::StateBlob& ctx, const std::string &primingSymbol, GraphEngine &baseEngine ) : DefinedEngineView( constructPrimingReactionSet( + ctx, species.at(primingSymbol), baseEngine ), @@ -29,26 +30,27 @@ namespace gridfire::engine { m_primingSpecies(species.at(primingSymbol)) {} NetworkPrimingEngineView::NetworkPrimingEngineView( + scratch::StateBlob& ctx, const fourdst::atomic::Species &primingSpecies, GraphEngine &baseEngine ) : DefinedEngineView( constructPrimingReactionSet( + ctx, primingSpecies, baseEngine ), baseEngine ), - m_primingSpecies(primingSpecies) { - } - + m_primingSpecies(primingSpecies) {} std::vector NetworkPrimingEngineView::constructPrimingReactionSet( + scratch::StateBlob& ctx, const fourdst::atomic::Species &primingSpecies, const GraphEngine &baseEngine ) const { std::unordered_set primeReactions; - for (const auto &reaction : baseEngine.getNetworkReactions()) { + for (const auto &reaction : baseEngine.getNetworkReactions(ctx)) { if (reaction->contains(primingSpecies)) { primeReactions.insert(std::string(reaction->id())); } diff --git a/src/lib/io/generative/python.cpp b/src/lib/io/generative/python.cpp index a36c0c13..89c32bd7 100644 --- a/src/lib/io/generative/python.cpp +++ b/src/lib/io/generative/python.cpp @@ -9,6 +9,7 @@ #include #include "gridfire/engine/engine_abstract.h" +#include "gridfire/engine/scratchpads/blob.h" namespace { template @@ -137,8 +138,11 @@ namespace gridfire::io::gen { } - std::string exportEngineToPy(const engine::DynamicEngine& engine) { - auto reactions = engine.getNetworkReactions(); + std::string exportEngineToPy( + engine::scratch::StateBlob& ctx, + const engine::DynamicEngine& engine + ) { + auto reactions = engine.getNetworkReactions(ctx); std::vector functions; functions.emplace_back(R"(import numpy as np from typing import Dict, List, Tuple, Callable)"); @@ -150,8 +154,8 @@ from typing import Dict, List, Tuple, Callable)"); return join(functions, "\n\n"); } - void exportEngineToPy(const engine::DynamicEngine &engine, const std::string &fileName) { - const std::string funcCode = exportEngineToPy(engine); + void exportEngineToPy(engine::scratch::StateBlob &ctx, const engine::DynamicEngine &engine, const std::string &fileName) { + const std::string funcCode = exportEngineToPy(ctx, engine); std::ofstream outFile(fileName); outFile << funcCode; outFile.close(); diff --git a/src/lib/policy/stellar_policy.cpp b/src/lib/policy/stellar_policy.cpp index 22dbcc32..56dbeec5 100644 --- a/src/lib/policy/stellar_policy.cpp +++ b/src/lib/policy/stellar_policy.cpp @@ -5,6 +5,13 @@ #include "gridfire/engine/engine_abstract.h" #include "gridfire/engine/engine_graph.h" #include "gridfire/engine/views/engine_views.h" +#include "gridfire/utils/logging.h" + +#include "gridfire/engine/scratchpads/blob.h" +#include "gridfire/engine/scratchpads/utils.h" +#include "gridfire/engine/scratchpads/engine_graph_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_adaptive_scratchpad.h" +#include "gridfire/engine/scratchpads/engine_multiscale_scratchpad.h" #include "fourdst/atomic/species.h" #include "fourdst/composition/utils.h" @@ -47,17 +54,13 @@ namespace gridfire::policy { m_partition_function = build_partition_function(); } - engine::DynamicEngine& MainSequencePolicy::construct() { + ConstructionResults MainSequencePolicy::construct() { m_network_stack.clear(); m_network_stack.emplace_back( std::make_unique(m_initializing_composition, *m_partition_function, engine::NetworkBuildDepth::ThirdOrder, engine::NetworkConstructionFlags::DEFAULT) ); - auto& graphRepr = dynamic_cast(*m_network_stack.back().get()); - graphRepr.setUseReverseReactions(false); - - m_network_stack.emplace_back( std::make_unique(*m_network_stack.back().get()) ); @@ -65,8 +68,9 @@ namespace gridfire::policy { std::make_unique(*m_network_stack.back().get()) ); + std::unique_ptr scratch_blob = get_stack_scratch_blob(); m_status = NetworkPolicyStatus::INITIALIZED_UNVERIFIED; - m_status = check_status(); + m_status = check_status(*scratch_blob); switch (m_status) { case NetworkPolicyStatus::MISSING_KEY_REACTION: @@ -80,7 +84,7 @@ namespace gridfire::policy { case NetworkPolicyStatus::INITIALIZED_VERIFIED: break; } - return *m_network_stack.back(); + return {.engine = *m_network_stack.back(), .scratch_blob = std::move(scratch_blob)}; } inline std::unique_ptr MainSequencePolicy::build_partition_function() { @@ -115,13 +119,49 @@ namespace gridfire::policy { return m_partition_function; } - inline NetworkPolicyStatus MainSequencePolicy::check_status() const { + std::unique_ptr MainSequencePolicy::get_stack_scratch_blob() const { + if (m_network_stack.empty()) { + throw exceptions::PolicyError("Cannot get stack scratch blob from MainSequencePolicy: Engine stack is empty. Call construct() first."); + } + auto blob = std::make_unique(); + blob->enroll(); + blob->enroll(); + blob->enroll(); + + + const engine::GraphEngine* graph_engine = dynamic_cast(m_network_stack.front().get()); + if (!graph_engine) { + throw exceptions::PolicyError("Cannot get stack scratch blob from MainSequencePolicy: The base engine is not a GraphEngine. This indicates a serious internal inconsistency and should be reported to the GridFire developers, thank you."); + } + + const engine::MultiscalePartitioningEngineView* multiscale_engine = dynamic_cast(m_network_stack[1].get()); + if (!multiscale_engine) { + throw exceptions::PolicyError("Cannot get stack scratch blob from MainSequencePolicy: The middle engine is not a MultiscalePartitioningEngineView. This indicates a serious internal inconsistency and should be reported to the GridFire developers, thank you."); + } + + const engine::AdaptiveEngineView* adaptive_engine = dynamic_cast(m_network_stack.back().get()); + if (!adaptive_engine) { + throw exceptions::PolicyError("Cannot get stack scratch blob from MainSequencePolicy: The top engine is not an AdaptiveEngineView. This indicates a serious internal inconsistency and should be reported to the GridFire developers, thank you."); + } + + + auto* graph_engine_state = engine::scratch::get_state(*blob); + graph_engine_state->initialize(*graph_engine); + auto* multiscale_engine_state = engine::scratch::get_state(*blob); + multiscale_engine_state->initialize(); + auto* adaptive_engine_state = engine::scratch::get_state(*blob); + adaptive_engine_state->initialize(*adaptive_engine); + + return blob; + } + + inline NetworkPolicyStatus MainSequencePolicy::check_status(engine::scratch::StateBlob& ctx) const { for (const auto& species : m_seed_species) { if (!m_initializing_composition.contains(species)) { return NetworkPolicyStatus::MISSING_KEY_SPECIES; } } - const reaction::ReactionSet& baseReactions = m_network_stack.front()->getNetworkReactions(); + const reaction::ReactionSet& baseReactions = m_network_stack.front()->getNetworkReactions(ctx); for (const auto& reaction : m_reaction_policy->get_reactions()) { const bool result = baseReactions.contains(*reaction); if (!result) { @@ -130,4 +170,4 @@ namespace gridfire::policy { } return NetworkPolicyStatus::INITIALIZED_VERIFIED; } -} \ No newline at end of file +} diff --git a/src/lib/reaction/reaction.cpp b/src/lib/reaction/reaction.cpp index 2cb9ef2e..49cbc0b9 100644 --- a/src/lib/reaction/reaction.cpp +++ b/src/lib/reaction/reaction.cpp @@ -185,7 +185,11 @@ namespace gridfire::reaction { } uint64_t ReaclibReaction::hash(const uint64_t seed) const { - return XXHash64::hash(m_id.data(), m_id.size(), seed); + if (m_hashCache.has_value()) { + return m_hashCache.value(); + } + m_hashCache = XXHash64::hash(m_id.data(), m_id.size(), seed); + return m_hashCache.value(); } std::unique_ptr ReaclibReaction::clone() const { @@ -278,11 +282,11 @@ namespace gridfire::reaction { double Ye, double mue, const std::vector &Y, const std::unordered_map& index_to_species_map ) const { - if (m_cached_rates.contains(T9)) { - return m_cached_rates.at(T9); - } + // if (m_cached_rates.contains(T9)) { + // return m_cached_rates.at(T9); + // } const double rate = calculate_rate(T9); - m_cached_rates[T9] = rate; + // m_cached_rates[T9] = rate; return rate; } @@ -416,6 +420,7 @@ namespace gridfire::reaction { std::swap(m_reactions, temp.m_reactions); std::swap(m_reactionNameMap, temp.m_reactionNameMap); } + m_hashCache = std::nullopt; return *this; } @@ -430,6 +435,7 @@ namespace gridfire::reaction { m_reactionNameMap.emplace(std::move(reaction_id), new_index); m_reactionHashes.insert(reaction.hash(0)); + m_hashCache = std::nullopt; } void ReactionSet::add_reaction(std::unique_ptr&& reaction) { @@ -445,6 +451,7 @@ namespace gridfire::reaction { m_reactionNameMap.emplace(std::move(reaction_id), new_index); m_reactionHashes.insert(reaction_hash); + m_hashCache = std::nullopt; } void ReactionSet::extend(const ReactionSet &other) { @@ -482,6 +489,7 @@ namespace gridfire::reaction { } m_reactionHashes.erase(rh); + m_hashCache = std::nullopt; } bool ReactionSet::contains(const std::string_view& id) const { @@ -496,6 +504,7 @@ namespace gridfire::reaction { void ReactionSet::clear() { m_reactions.clear(); m_reactionNameMap.clear(); + m_hashCache = std::nullopt; } bool ReactionSet::contains_species(const Species& species) const { @@ -554,6 +563,9 @@ namespace gridfire::reaction { } uint64_t ReactionSet::hash(const uint64_t seed) const { + if (m_hashCache.has_value()) { + return m_hashCache.value(); + } if (m_reactions.empty()) { return XXHash64::hash(nullptr, 0, seed); } @@ -567,7 +579,8 @@ namespace gridfire::reaction { const auto data = static_cast(individualReactionHashes.data()); const size_t sizeInBytes = individualReactionHashes.size() * sizeof(uint64_t); - return XXHash64::hash(data, sizeInBytes, seed); + m_hashCache = XXHash64::hash(data, sizeInBytes, seed); + return m_hashCache.value(); } std::unordered_set ReactionSet::getReactionSetSpecies() const { diff --git a/src/lib/solver/strategies/GridSolver.cpp b/src/lib/solver/strategies/GridSolver.cpp new file mode 100644 index 00000000..8729be4e --- /dev/null +++ b/src/lib/solver/strategies/GridSolver.cpp @@ -0,0 +1,107 @@ +#include "gridfire/solver/strategies/GridSolver.h" + +#include "gridfire/exceptions/error_solver.h" +#include "gridfire/solver/strategies/PointSolver.h" +#include "gridfire/utils/macros.h" +#include "gridfire/utils/gf_omp.h" + +#include +#include + +namespace gridfire::solver { + void GridSolverContext::init() {} + void GridSolverContext::reset() { + solver_workspaces.clear(); + timestep_callbacks.clear(); + } + + void GridSolverContext::set_callback(const std::function &callback) { + for (auto &cb : timestep_callbacks) { + cb = callback; + } + } + + void GridSolverContext::set_callback(const std::function &callback, const size_t zone_idx) { + if (zone_idx >= timestep_callbacks.size()) { + throw exceptions::SolverError("GridSolverContext::set_callback: zone_idx out of range."); + } + timestep_callbacks[zone_idx] = callback; + } + + void GridSolverContext::clear_callback() { + for (auto &cb : timestep_callbacks) { + cb = nullptr; + } + } + + void GridSolverContext::clear_callback(const size_t zone_idx) { + if (zone_idx >= timestep_callbacks.size()) { + throw exceptions::SolverError("GridSolverContext::clear_callback: zone_idx out of range."); + } + timestep_callbacks[zone_idx] = nullptr; + } + + void GridSolverContext::set_stdout_logging(const bool enable) { + zone_stdout_logging = enable; + } + + void GridSolverContext::set_detailed_logging(const bool enable) { + zone_detailed_logging = enable; + } + + GridSolverContext::GridSolverContext( + const engine::scratch::StateBlob &ctx_template + ) : + ctx_template(ctx_template) {} + + + GridSolver::GridSolver( + const engine::DynamicEngine &engine, + const SingleZoneDynamicNetworkSolver &solver + ) : + MultiZoneNetworkSolver(engine, solver) { + GF_PAR_INIT(); + } + + std::vector GridSolver::evaluate( + SolverContextBase& ctx, + const std::vector& netIns + ) const { + auto* sctx_p = dynamic_cast(&ctx); + if (!sctx_p) { + throw exceptions::SolverError("GridSolver::evaluate: SolverContextBase is not of type GridSolverContext."); + } + + const size_t n_zones = netIns.size(); + if (n_zones == 0) { return {}; } + + std::vector results(n_zones); + + sctx_p->solver_workspaces.resize(n_zones); + + GF_OMP( + parallel for default(none) shared(sctx_p, n_zones), + for (size_t zone_idx = 0; zone_idx < n_zones; ++zone_idx)) { + sctx_p->solver_workspaces[zone_idx] = std::make_unique(sctx_p->ctx_template); + sctx_p->solver_workspaces[zone_idx]->set_stdout_logging(sctx_p->zone_stdout_logging); + sctx_p->solver_workspaces[zone_idx]->set_detailed_logging(sctx_p->zone_detailed_logging); + } + + GF_OMP( + parallel for default(none) shared(results, sctx_p, netIns, n_zones), + for (size_t zone_idx = 0; zone_idx < n_zones; ++zone_idx)) { + try { + results[zone_idx] = m_solver.evaluate( + *sctx_p->solver_workspaces[zone_idx], + netIns[zone_idx] + ); + } catch (exceptions::GridFireError& e) { + std::println("CVODE Solver Failure in zone {}: {}", zone_idx, e.what()); + } + if (sctx_p->zone_completion_logging) { + std::println("Thread {} completed zone {}", GF_OMP_THREAD_NUM, zone_idx); + } + } + return results; + } +} diff --git a/src/lib/solver/strategies/CVODE_solver_strategy.cpp b/src/lib/solver/strategies/PointSolver.cpp similarity index 72% rename from src/lib/solver/strategies/CVODE_solver_strategy.cpp rename to src/lib/solver/strategies/PointSolver.cpp index 01e2727e..01d3aa59 100644 --- a/src/lib/solver/strategies/CVODE_solver_strategy.cpp +++ b/src/lib/solver/strategies/PointSolver.cpp @@ -1,4 +1,4 @@ -#include "gridfire/solver/strategies/CVODE_solver_strategy.h" +#include "gridfire/solver/strategies/PointSolver.h" #include "gridfire/types/types.h" #include "gridfire/utils/table_format.h" @@ -19,7 +19,6 @@ #include "fourdst/atomic/species.h" #include "fourdst/composition/exceptions/exceptions_composition.h" #include "gridfire/engine/engine_graph.h" -#include "gridfire/engine/types/engine_types.h" #include "gridfire/solver/strategies/triggers/engine_partitioning_trigger.h" #include "gridfire/trigger/procedures/trigger_pprint.h" #include "gridfire/exceptions/error_solver.h" @@ -29,7 +28,7 @@ namespace gridfire::solver { using namespace gridfire::engine; - CVODESolverStrategy::TimestepContext::TimestepContext( + PointSolverTimestepContext::PointSolverTimestepContext( const double t, const N_Vector &state, const double dt, @@ -41,7 +40,8 @@ namespace gridfire::solver { const std::vector &networkSpecies, const size_t currentConvergenceFailure, const size_t currentNonlinearIterations, - const std::map> &reactionContributionMap + const std::map> &reactionContributionMap, + scratch::StateBlob& ctx ) : t(t), state(state), @@ -54,10 +54,11 @@ namespace gridfire::solver { networkSpecies(networkSpecies), currentConvergenceFailures(currentConvergenceFailure), currentNonlinearIterations(currentNonlinearIterations), - reactionContributionMap(reactionContributionMap) + reactionContributionMap(reactionContributionMap), + state_ctx(ctx) {} - std::vector> CVODESolverStrategy::TimestepContext::describe() const { + std::vector> PointSolverTimestepContext::describe() const { std::vector> description; description.emplace_back("t", "Current Time"); description.emplace_back("state", "Current State Vector (N_Vector)"); @@ -73,32 +74,112 @@ namespace gridfire::solver { return description; } + void PointSolverContext::init() { + reset_all(); + init_context(); + } - CVODESolverStrategy::CVODESolverStrategy(DynamicEngine &engine): NetworkSolverStrategy(engine) { - // TODO: In order to support MPI this function must be changed - const int flag = SUNContext_Create(SUN_COMM_NULL, &m_sun_ctx); - if (flag < 0) { - throw std::runtime_error("Failed to create SUNDIALS context (SUNDIALS Errno: " + std::to_string(flag) + ")"); + void PointSolverContext::set_stdout_logging(const bool enable) { + stdout_logging = enable; + } + + void PointSolverContext::set_detailed_logging(const bool enable) { + detailed_step_logging = enable; + } + + void PointSolverContext::reset_all() { + reset_user(); + reset_cvode(); + } + + void PointSolverContext::reset_user() { + callback.reset(); + num_steps = 0; + stdout_logging = true; + abs_tol.reset(); + rel_tol.reset(); + detailed_step_logging = false; + last_size = 0; + last_composition_hash = 0ULL; + } + + void PointSolverContext::reset_cvode() { + if (LS) { + SUNLinSolFree(LS); + LS = nullptr; + } + if (J) { + SUNMatDestroy(J); + J = nullptr; + } + if (Y) { + N_VDestroy(Y); + Y = nullptr; + } + if (YErr) { + N_VDestroy(YErr); + YErr = nullptr; + } + if (constraints) { + N_VDestroy(constraints); + constraints = nullptr; + } + if (cvode_mem) { + CVodeFree(&cvode_mem); + cvode_mem = nullptr; } } - CVODESolverStrategy::~CVODESolverStrategy() { - LOG_TRACE_L1(m_logger, "Cleaning up CVODE resources..."); - cleanup_cvode_resources(true); - - if (m_sun_ctx) { - SUNContext_Free(&m_sun_ctx); + void PointSolverContext::clear_context() { + if (sun_ctx) { + SUNContext_Free(&sun_ctx); + sun_ctx = nullptr; } } - NetOut CVODESolverStrategy::evaluate(const NetIn& netIn) { - return evaluate(netIn, false); + void PointSolverContext::init_context() { + if (!sun_ctx) { + utils::check_sundials_flag(SUNContext_Create(SUN_COMM_NULL, &sun_ctx), "SUNContext_Create", utils::SUNDIALS_RET_CODE_TYPES::CVODE); + } } - NetOut CVODESolverStrategy::evaluate( + bool PointSolverContext::has_context() const { + return sun_ctx != nullptr; + } + + PointSolverContext::PointSolverContext( + const scratch::StateBlob& engine_ctx + ) : + engine_ctx(engine_ctx.clone_structure()) + { + utils::check_sundials_flag(SUNContext_Create(SUN_COMM_NULL, &sun_ctx), "SUNContext_Create", utils::SUNDIALS_RET_CODE_TYPES::CVODE); + } + + PointSolverContext::~PointSolverContext() { + reset_cvode(); + clear_context(); + } + + + PointSolver::PointSolver( + const DynamicEngine &engine + ): SingleZoneNetworkSolver(engine) {} + + NetOut PointSolver::evaluate( + SolverContextBase& solver_ctx, + const NetIn& netIn + ) const { + return evaluate(solver_ctx, netIn, false); + } + + NetOut PointSolver::evaluate( + SolverContextBase& solver_ctx, const NetIn &netIn, - bool displayTrigger - ) { + bool displayTrigger, + bool forceReinitialize + ) const { + auto* sctx_p = dynamic_cast(&solver_ctx); + LOG_TRACE_L1(m_logger, "Starting solver evaluation with T9: {} and rho: {}", netIn.temperature/1e9, netIn.density); LOG_TRACE_L1(m_logger, "Building engine update trigger...."); auto trigger = trigger::solver::CVODE::makeEnginePartitioningTrigger(1e12, 1e10, 0.5, 2); @@ -112,39 +193,75 @@ namespace gridfire::solver { // 2. If the user has set tolerances in code, those override the config // 3. If the user has not set tolerances in code and the config does not have them, use hardcoded defaults - auto absTol = m_config->solver.cvode.absTol; - auto relTol = m_config->solver.cvode.relTol; - - if (m_absTol) { - absTol = *m_absTol; + if (!sctx_p->abs_tol.has_value()) { + sctx_p->abs_tol = m_config->solver.cvode.absTol; } - if (m_relTol) { - relTol = *m_relTol; + if (!sctx_p->rel_tol.has_value()) { + sctx_p->rel_tol = m_config->solver.cvode.relTol; } - LOG_TRACE_L1(m_logger, "Starting engine update chain..."); - fourdst::composition::Composition equilibratedComposition = m_engine.update(netIn); - LOG_TRACE_L1(m_logger, "Engine updated and equilibrated composition found!"); - size_t numSpecies = m_engine.getNetworkSpecies().size(); - uint64_t N = numSpecies + 1; + bool resourcesExist = (sctx_p->cvode_mem != nullptr) && (sctx_p->Y != nullptr); - LOG_TRACE_L1(m_logger, "Number of species: {} ({} independent variables)", numSpecies, N); - LOG_TRACE_L1(m_logger, "Initializing CVODE resources"); - m_cvode_mem = CVodeCreate(CV_BDF, m_sun_ctx); - utils::check_cvode_flag(m_cvode_mem == nullptr ? -1 : 0, "CVodeCreate"); + bool inconsistentComposition = netIn.composition.hash() != sctx_p->last_composition_hash; + fourdst::composition::Composition equilibratedComposition; - initialize_cvode_integration_resources(N, numSpecies, 0.0, equilibratedComposition, absTol, relTol, 0.0); + if (forceReinitialize || !resourcesExist || inconsistentComposition) { + sctx_p->reset_cvode(); + if (!sctx_p->has_context()) { + sctx_p->init_context(); + } + LOG_INFO( + m_logger, + "Preforming full CVODE initialization (Reason: {})", + forceReinitialize ? "Forced reinitialization" : + (!resourcesExist ? "CVODE resources do not exist" : + "Input composition inconsistent with previous state")); + LOG_TRACE_L1(m_logger, "Starting engine update chain..."); + equilibratedComposition = m_engine.project(*sctx_p->engine_ctx, netIn); + LOG_TRACE_L1(m_logger, "Engine updated and equilibrated composition found!"); - CVODEUserData user_data; - user_data.solver_instance = this; - user_data.engine = &m_engine; + size_t numSpecies = m_engine.getNetworkSpecies(*sctx_p->engine_ctx).size(); + uint64_t N = numSpecies + 1; + + LOG_TRACE_L1(m_logger, "Number of species: {} ({} independent variables)", numSpecies, N); + LOG_TRACE_L1(m_logger, "Initializing CVODE resources"); + + initialize_cvode_integration_resources(sctx_p, N, numSpecies, 0.0, equilibratedComposition, sctx_p->abs_tol.value(), sctx_p->rel_tol.value(), 0.0); + sctx_p->last_size = N; + } else { + LOG_INFO(m_logger, "Reusing existing CVODE resources (size: {})", sctx_p->last_size); + + const size_t numSpecies = m_engine.getNetworkSpecies(*sctx_p->engine_ctx).size(); + sunrealtype *y_data = N_VGetArrayPointer(sctx_p->Y); + for (size_t i = 0; i < numSpecies; i++) { + const auto& species = m_engine.getNetworkSpecies(*sctx_p->engine_ctx)[i]; + if (netIn.composition.contains(species)) { + y_data[i] = netIn.composition.getMolarAbundance(species); + } else { + y_data[i] = std::numeric_limits::min(); + } + } + y_data[numSpecies] = 0.0; // Reset energy accumulator + utils::check_cvode_flag(CVodeSStolerances(sctx_p->cvode_mem, sctx_p->rel_tol.value(), sctx_p->abs_tol.value()), "CVodeSStolerances"); + utils::check_cvode_flag(CVodeReInit(sctx_p->cvode_mem, 0.0, sctx_p->Y), "CVodeReInit"); + + equilibratedComposition = netIn.composition; // Use the provided composition as-is if we already have validated CVODE resources and that the composition is consistent with the previous state + } + + size_t numSpecies = m_engine.getNetworkSpecies(*sctx_p->engine_ctx).size(); + CVODEUserData user_data { + .solver_instance = this, + .sctx = sctx_p, + .ctx = *sctx_p->engine_ctx, + .engine = &m_engine, + }; LOG_TRACE_L1(m_logger, "CVODE resources successfully initialized!"); double current_time = 0; // ReSharper disable once CppTooWideScope [[maybe_unused]] double last_callback_time = 0; - m_num_steps = 0; + sctx_p->num_steps = 0; double accumulated_energy = 0.0; double accumulated_neutrino_energy_loss = 0.0; @@ -159,18 +276,18 @@ namespace gridfire::solver { size_t total_steps = 0; - LOG_TRACE_L1(m_logger, "Starting CVODE iteration"); + LOG_TRACE_L1(m_logger, "Starting CVODE iteration..."); fourdst::composition::Composition postStep = equilibratedComposition; while (current_time < netIn.tMax) { user_data.T9 = T9; user_data.rho = netIn.density; - user_data.networkSpecies = &m_engine.getNetworkSpecies(); + user_data.networkSpecies = &m_engine.getNetworkSpecies(*sctx_p->engine_ctx); user_data.captured_exception.reset(); - utils::check_cvode_flag(CVodeSetUserData(m_cvode_mem, &user_data), "CVodeSetUserData"); + utils::check_cvode_flag(CVodeSetUserData(sctx_p->cvode_mem, &user_data), "CVodeSetUserData"); LOG_TRACE_L2(m_logger, "Taking one CVODE step..."); - int flag = CVode(m_cvode_mem, netIn.tMax, m_Y, ¤t_time, CV_ONE_STEP); + int flag = CVode(sctx_p->cvode_mem, netIn.tMax, sctx_p->Y, ¤t_time, CV_ONE_STEP); LOG_TRACE_L2(m_logger, "CVODE step complete. Current time: {}, step status: {}", current_time, utils::cvode_ret_code_map.at(flag)); if (user_data.captured_exception){ @@ -182,13 +299,13 @@ namespace gridfire::solver { long int n_steps; double last_step_size; - CVodeGetNumSteps(m_cvode_mem, &n_steps); - CVodeGetLastStep(m_cvode_mem, &last_step_size); + CVodeGetNumSteps(sctx_p->cvode_mem, &n_steps); + CVodeGetLastStep(sctx_p->cvode_mem, &last_step_size); long int nliters, nlcfails; - CVodeGetNumNonlinSolvIters(m_cvode_mem, &nliters); - CVodeGetNumNonlinSolvConvFails(m_cvode_mem, &nlcfails); + CVodeGetNumNonlinSolvIters(sctx_p->cvode_mem, &nliters); + CVodeGetNumNonlinSolvConvFails(sctx_p->cvode_mem, &nlcfails); - sunrealtype* y_data = N_VGetArrayPointer(m_Y); + sunrealtype* y_data = N_VGetArrayPointer(sctx_p->Y); const double current_energy = y_data[numSpecies]; // Specific energy rate // TODO: Accumulate neutrino loss through the state vector directly which will allow CVODE to properly integrate it @@ -197,7 +314,7 @@ namespace gridfire::solver { size_t iter_diff = (total_nonlinear_iterations + nliters) - prev_nonlinear_iterations; size_t convFail_diff = (total_convergence_failures + nlcfails) - prev_convergence_failures; - if (m_stdout_logging_enabled) { + if (sctx_p->stdout_logging) { std::println( "Step: {:6} | Updates: {:3} | Epoch Steps: {:4} | t: {:.3e} [s] | dt: {:15.6E} [s] | Iterations: {:6} (+{:2}) | Total Convergence Failures: {:2} (+{:2})", total_steps + n_steps, @@ -212,21 +329,17 @@ namespace gridfire::solver { ); } for (size_t i = 0; i < numSpecies; ++i) { - const auto& species = m_engine.getNetworkSpecies()[i]; + const auto& species = m_engine.getNetworkSpecies(*sctx_p->engine_ctx)[i]; if (y_data[i] > 0.0) { postStep.setMolarAbundance(species, y_data[i]); } } - fourdst::composition::Composition collectedComposition = m_engine.collectComposition(postStep, netIn.temperature/1e9, netIn.density); - for (size_t i = 0; i < numSpecies; ++i) { - y_data[i] = collectedComposition.getMolarAbundance(m_engine.getNetworkSpecies()[i]); - } LOG_INFO(m_logger, "Completed {:5} steps to time {:10.4E} [s] (dt = {:15.6E} [s]). Current specific energy: {:15.6E} [erg/g]", total_steps + n_steps, current_time, last_step_size, current_energy); LOG_DEBUG(m_logger, "Current composition (molar abundance): {}", [&]() -> std::string { std::stringstream ss; for (size_t i = 0; i < numSpecies; ++i) { - const auto& species = m_engine.getNetworkSpecies()[i]; - ss << species.name() << ": (y_data = " << y_data[i] << ", collected = " << collectedComposition.getMolarAbundance(species) << ")"; + const auto& species = m_engine.getNetworkSpecies(*sctx_p->engine_ctx)[i]; + ss << species.name() << ": (y_data = " << y_data[i] << ", collected = " << postStep.getMolarAbundance(species) << ")"; if (i < numSpecies - 1) { ss << ", "; } @@ -241,35 +354,44 @@ namespace gridfire::solver { ? user_data.reaction_contribution_map.value() : kEmptyMap; - auto ctx = TimestepContext( + auto ctx = PointSolverTimestepContext( current_time, - m_Y, + sctx_p->Y, last_step_size, last_callback_time, T9, netIn.density, n_steps, m_engine, - m_engine.getNetworkSpecies(), + m_engine.getNetworkSpecies(*sctx_p->engine_ctx), convFail_diff, iter_diff, - rcMap + rcMap, + *sctx_p->engine_ctx ); prev_nonlinear_iterations = nliters + total_nonlinear_iterations; prev_convergence_failures = nlcfails + total_convergence_failures; - if (m_callback.has_value()) { - m_callback.value()(ctx); + if (sctx_p->callback.has_value()) { + sctx_p->callback.value()(ctx); } trigger->step(ctx); - if (m_detailed_step_logging) { - log_step_diagnostics(user_data, true, true, true, "step_" + std::to_string(total_steps + n_steps) + ".json"); + if (sctx_p->detailed_step_logging) { + log_step_diagnostics( + sctx_p, + *sctx_p->engine_ctx, + user_data, + true, + true, + true, + "step_" + std::to_string(total_steps + n_steps) + ".json" + ); } if (trigger->check(ctx)) { - if (m_stdout_logging_enabled && displayTrigger) { + if (sctx_p->stdout_logging && displayTrigger) { trigger::printWhy(trigger->why(ctx)); } trigger->update(ctx); @@ -291,20 +413,20 @@ namespace gridfire::solver { fourdst::composition::Composition temp_comp; std::vector mass_fractions; - auto num_species_at_stop = static_cast(m_engine.getNetworkSpecies().size()); + auto num_species_at_stop = static_cast(m_engine.getNetworkSpecies(*sctx_p->engine_ctx).size()); - if (num_species_at_stop > m_Y->ops->nvgetlength(m_Y) - 1) { + if (num_species_at_stop > sctx_p->Y->ops->nvgetlength(sctx_p->Y) - 1) { LOG_ERROR( m_logger, "Number of species at engine update ({}) exceeds the number of species in the CVODE solver ({}). This should never happen.", num_species_at_stop, - m_Y->ops->nvgetlength(m_Y) - 1 // -1 due to energy in the last index + sctx_p->Y->ops->nvgetlength(sctx_p->Y) - 1 // -1 due to energy in the last index ); throw std::runtime_error("Number of species at engine update exceeds the number of species in the CVODE solver. This should never happen."); } - for (const auto& species: m_engine.getNetworkSpecies()) { - const size_t sid = m_engine.getSpeciesIndex(species); + for (const auto& species: m_engine.getNetworkSpecies(*sctx_p->engine_ctx)) { + const size_t sid = m_engine.getSpeciesIndex(*sctx_p->engine_ctx, species); temp_comp.registerSpecies(species); double y = end_of_step_abundances[sid]; if (y > 0.0) { @@ -314,7 +436,7 @@ namespace gridfire::solver { #ifndef NDEBUG for (long int i = 0; i < num_species_at_stop; ++i) { - const auto& species = m_engine.getNetworkSpecies()[i]; + const auto& species = m_engine.getNetworkSpecies(*sctx_p->engine_ctx)[i]; if (std::abs(temp_comp.getMolarAbundance(species) - y_data[i]) > 1e-12) { throw exceptions::UtilityError("Conversion from solver state to composition molar abundance failed verification."); } @@ -349,7 +471,7 @@ namespace gridfire::solver { "Prior to Engine Update active reactions are: {}", [&]() -> std::string { std::stringstream ss; - const gridfire::reaction::ReactionSet& reactions = m_engine.getNetworkReactions(); + const gridfire::reaction::ReactionSet& reactions = m_engine.getNetworkReactions(*sctx_p->engine_ctx); size_t count = 0; for (const auto& reaction : reactions) { ss << reaction -> id(); @@ -361,7 +483,7 @@ namespace gridfire::solver { return ss.str(); }() ); - fourdst::composition::Composition currentComposition = m_engine.update(netInTemp); + fourdst::composition::Composition currentComposition = m_engine.project(*sctx_p->engine_ctx, netInTemp); LOG_DEBUG( m_logger, "After to Engine update composition is (molar abundance) {}", @@ -408,7 +530,7 @@ namespace gridfire::solver { "After Engine Update active reactions are: {}", [&]() -> std::string { std::stringstream ss; - const gridfire::reaction::ReactionSet& reactions = m_engine.getNetworkReactions(); + const gridfire::reaction::ReactionSet& reactions = m_engine.getNetworkReactions(*sctx_p->engine_ctx); size_t count = 0; for (const auto& reaction : reactions) { ss << reaction -> id(); @@ -424,46 +546,41 @@ namespace gridfire::solver { m_logger, "Due to a triggered engine update the composition was updated from size {} to {} species.", num_species_at_stop, - m_engine.getNetworkSpecies().size() + m_engine.getNetworkSpecies(*sctx_p->engine_ctx).size() ); - numSpecies = m_engine.getNetworkSpecies().size(); - N = numSpecies + 1; + numSpecies = m_engine.getNetworkSpecies(*sctx_p->engine_ctx).size(); + size_t N = numSpecies + 1; LOG_INFO(m_logger, "Starting CVODE reinitialization after engine update..."); - cleanup_cvode_resources(true); + sctx_p->reset_cvode(); + initialize_cvode_integration_resources(sctx_p, N, numSpecies, current_time, currentComposition, sctx_p->abs_tol.value(), sctx_p->rel_tol.value(), accumulated_energy); - m_cvode_mem = CVodeCreate(CV_BDF, m_sun_ctx); - utils::check_cvode_flag(m_cvode_mem == nullptr ? -1 : 0, "CVodeCreate"); - - initialize_cvode_integration_resources(N, numSpecies, current_time, currentComposition, absTol, relTol, accumulated_energy); - - utils::check_cvode_flag(CVodeReInit(m_cvode_mem, current_time, m_Y), "CVodeReInit"); - // throw exceptions::DebugException("Debug"); + utils::check_cvode_flag(CVodeReInit(sctx_p->cvode_mem, current_time, sctx_p->Y), "CVodeReInit"); LOG_INFO(m_logger, "Done reinitializing CVODE after engine update. The next log messages will be from the first step after reinitialization..."); } } - if (m_stdout_logging_enabled) { // Flush the buffer if standard out logging is enabled + if (sctx_p->stdout_logging) { // Flush the buffer if standard out logging is enabled std::cout << std::flush; } LOG_INFO(m_logger, "CVODE iteration complete"); - sunrealtype* y_data = N_VGetArrayPointer(m_Y); + sunrealtype* y_data = N_VGetArrayPointer(sctx_p->Y); accumulated_energy += y_data[numSpecies]; std::vector y_vec(y_data, y_data + numSpecies); - for (size_t i = 0; i < y_vec.size(); ++i) { - if (y_vec[i] < 0 && std::abs(y_vec[i]) < 1e-16) { - y_vec[i] = 0.0; // Regularize tiny negative abundances to zero + for (double & i : y_vec) { + if (i < 0 && std::abs(i) < 1e-16) { + i = 0.0; // Regularize tiny negative abundances to zero } } LOG_INFO(m_logger, "Constructing final composition= with {} species", numSpecies); - fourdst::composition::Composition topLevelComposition(m_engine.getNetworkSpecies(), y_vec); + fourdst::composition::Composition topLevelComposition(m_engine.getNetworkSpecies(*sctx_p->engine_ctx), y_vec); LOG_INFO(m_logger, "Final composition constructed from solver state successfully! ({})", [&topLevelComposition]() -> std::string { std::ostringstream ss; size_t i = 0; @@ -478,7 +595,7 @@ namespace gridfire::solver { }()); LOG_INFO(m_logger, "Collecting final composition..."); - fourdst::composition::Composition outputComposition = m_engine.collectComposition(topLevelComposition, netIn.temperature/1e9, netIn.density); + fourdst::composition::Composition outputComposition = m_engine.collectComposition(*sctx_p->engine_ctx, topLevelComposition, netIn.temperature/1e9, netIn.density); assert(outputComposition.getRegisteredSymbols().size() == equilibratedComposition.getRegisteredSymbols().size()); @@ -499,10 +616,11 @@ namespace gridfire::solver { NetOut netOut; netOut.composition = outputComposition; netOut.energy = accumulated_energy; - utils::check_cvode_flag(CVodeGetNumSteps(m_cvode_mem, reinterpret_cast(&netOut.num_steps)), "CVodeGetNumSteps"); + utils::check_cvode_flag(CVodeGetNumSteps(sctx_p->cvode_mem, reinterpret_cast(&netOut.num_steps)), "CVodeGetNumSteps"); LOG_TRACE_L2(m_logger, "generating final nuclear energy generation rate derivatives..."); auto [dEps_dT, dEps_dRho] = m_engine.calculateEpsDerivatives( + *sctx_p->engine_ctx, outputComposition, T9, netIn.density @@ -516,51 +634,13 @@ namespace gridfire::solver { LOG_TRACE_L2(m_logger, "Output data built!"); LOG_TRACE_L2(m_logger, "Solver evaluation complete!."); - + sctx_p->last_composition_hash = netOut.composition.hash(); + sctx_p->last_size = netOut.composition.size() + 1; + CVodeGetLastStep(sctx_p->cvode_mem, &sctx_p->last_good_time_step); return netOut; } - void CVODESolverStrategy::set_callback(const std::any &callback) { - m_callback = std::any_cast(callback); - } - - bool CVODESolverStrategy::get_stdout_logging_enabled() const { - return m_stdout_logging_enabled; - } - - void CVODESolverStrategy::set_stdout_logging_enabled(const bool logging_enabled) { - m_stdout_logging_enabled = logging_enabled; - } - - void CVODESolverStrategy::set_absTol(double absTol) { - m_absTol = absTol; - } - - void CVODESolverStrategy::set_relTol(double relTol) { - m_relTol = relTol; - } - - double CVODESolverStrategy::get_absTol() const { - if (m_absTol.has_value()) { - return m_absTol.value(); - } else { - return -1.0; - } - } - - double CVODESolverStrategy::get_relTol() const { - if (m_relTol.has_value()) { - return m_relTol.value(); - } else { - return -1.0; - } - } - - std::vector> CVODESolverStrategy::describe_callback_context() const { - return {}; - } - - int CVODESolverStrategy::cvode_rhs_wrapper( + int PointSolver::cvode_rhs_wrapper( const sunrealtype t, const N_Vector y, const N_Vector ydot, @@ -588,7 +668,7 @@ namespace gridfire::solver { } } - int CVODESolverStrategy::cvode_jac_wrapper( + int PointSolver::cvode_jac_wrapper( sunrealtype t, N_Vector y, N_Vector ydot, @@ -603,7 +683,7 @@ namespace gridfire::solver { const auto* solver_instance = data->solver_instance; LOG_TRACE_L2(solver_instance->m_logger, "CVODE Jacobian wrapper starting"); - const size_t numSpecies = engine->getNetworkSpecies().size(); + const size_t numSpecies = engine->getNetworkSpecies(data->ctx).size(); sunrealtype* y_data = N_VGetArrayPointer(y); @@ -616,7 +696,7 @@ namespace gridfire::solver { } } std::vector y_vec(y_data, y_data + numSpecies); - fourdst::composition::Composition composition(engine->getNetworkSpecies(), y_vec); + fourdst::composition::Composition composition(engine->getNetworkSpecies(data->ctx), y_vec); LOG_TRACE_L2(solver_instance->m_logger, "Generating Jacobian matrix at time {} with {} species in composition (mean molecular mass: {})", t, composition.size(), composition.getMeanParticleMass()); LOG_TRACE_L2(solver_instance->m_logger, "Composition is {}", [&composition]() -> std::string { std::stringstream ss; @@ -632,11 +712,11 @@ namespace gridfire::solver { }()); LOG_TRACE_L2(solver_instance->m_logger, "Generating Jacobian matrix at time {}", t); - NetworkJacobian jac = engine->generateJacobianMatrix(composition, data->T9, data->rho); + NetworkJacobian jac = engine->generateJacobianMatrix(data->ctx, composition, data->T9, data->rho); LOG_TRACE_L2(solver_instance->m_logger, "Regularizing Jacobian matrix at time {}", t); jac = regularize_jacobian(jac, composition, solver_instance->m_logger); LOG_TRACE_L2(solver_instance->m_logger, "Done regularizing Jacobian matrix at time {}", t); - if (jac.infs().size() != 0 || jac.nans().size() != 0) { + if (!jac.infs().empty() || !jac.nans().empty()) { auto infString = [&jac]() -> std::string { std::stringstream ss; size_t i = 0; @@ -648,7 +728,7 @@ namespace gridfire::solver { } i++; } - if (entries.size() == 0) { + if (entries.empty()) { ss << "None"; } return ss.str(); @@ -664,7 +744,7 @@ namespace gridfire::solver { } i++; } - if (entries.size() == 0) { + if (entries.empty()) { ss << "None"; } return ss.str(); @@ -687,9 +767,9 @@ namespace gridfire::solver { LOG_TRACE_L2(solver_instance->m_logger, "Transferring Jacobian matrix data to SUNDenseMatrix format at time {}", t); for (size_t j = 0; j < numSpecies; ++j) { - const fourdst::atomic::Species& species_j = engine->getNetworkSpecies()[j]; + const fourdst::atomic::Species& species_j = engine->getNetworkSpecies(data->ctx)[j]; for (size_t i = 0; i < numSpecies; ++i) { - const fourdst::atomic::Species& species_i = engine->getNetworkSpecies()[i]; + const fourdst::atomic::Species& species_i = engine->getNetworkSpecies(data->ctx)[i]; // J(i,j) = d(f_i)/d(y_j) // Column-major order format for SUNDenseMatrix: J_data[j*N + i] indexes J(i,j) const double dYi_dt = jac(species_i, species_j); @@ -709,13 +789,13 @@ namespace gridfire::solver { return 0; } - CVODESolverStrategy::CVODERHSOutputData CVODESolverStrategy::calculate_rhs( + PointSolver::CVODERHSOutputData PointSolver::calculate_rhs( const sunrealtype t, N_Vector y, N_Vector ydot, const CVODEUserData *data ) const { - const size_t numSpecies = m_engine.getNetworkSpecies().size(); + const size_t numSpecies = m_engine.getNetworkSpecies(data->ctx).size(); sunrealtype* y_data = N_VGetArrayPointer(y); // Solver constraints should keep these values very close to 0 but floating point noise can still result in very @@ -727,10 +807,10 @@ namespace gridfire::solver { } } std::vector y_vec(y_data, y_data + numSpecies); - fourdst::composition::Composition composition(m_engine.getNetworkSpecies(), y_vec); + fourdst::composition::Composition composition(m_engine.getNetworkSpecies(data->ctx), y_vec); LOG_TRACE_L2(m_logger, "Calculating RHS at time {} with {} species in composition", t, composition.size()); - const auto result = m_engine.calculateRHSAndEnergy(composition, data->T9, data->rho); + const auto result = m_engine.calculateRHSAndEnergy(data->ctx, composition, data->T9, data->rho, false); if (!result) { LOG_CRITICAL(m_logger, "Failed to calculate RHS at time {}: {}", t, EngineStatus_to_string(result.error())); throw exceptions::BadRHSEngineError(std::format("Failed to calculate RHS at time {}: {}", t, EngineStatus_to_string(result.error()))); @@ -760,7 +840,7 @@ namespace gridfire::solver { }()); for (size_t i = 0; i < numSpecies; ++i) { - fourdst::atomic::Species species = m_engine.getNetworkSpecies()[i]; + fourdst::atomic::Species species = m_engine.getNetworkSpecies(data->ctx)[i]; ydot_data[i] = dydt.at(species); } ydot_data[numSpecies] = nuclearEnergyGenerationRate; // Set the last element to the specific energy rate @@ -768,7 +848,8 @@ namespace gridfire::solver { return {reactionContributions, result.value().neutrinoEnergyLossRate, result.value().totalNeutrinoFlux}; } - void CVODESolverStrategy::initialize_cvode_integration_resources( + void PointSolver::initialize_cvode_integration_resources( + PointSolverContext* sctx_p, const uint64_t N, const size_t numSpecies, const double current_time, @@ -776,16 +857,18 @@ namespace gridfire::solver { const double absTol, const double relTol, const double accumulatedEnergy - ) { + ) const { LOG_TRACE_L2(m_logger, "Initializing CVODE integration resources with N: {}, current_time: {}, absTol: {}, relTol: {}", N, current_time, absTol, relTol); - cleanup_cvode_resources(false); // Cleanup any existing resources before initializing new ones + sctx_p->reset_cvode(); - m_Y = utils::init_sun_vector(N, m_sun_ctx); - m_YErr = N_VClone(m_Y); + sctx_p->cvode_mem = CVodeCreate(CV_BDF, sctx_p->sun_ctx); + utils::check_cvode_flag(sctx_p->cvode_mem == nullptr ? -1 : 0, "CVodeCreate"); + sctx_p->Y = utils::init_sun_vector(N, sctx_p->sun_ctx); + sctx_p->YErr = N_VClone(sctx_p->Y); - sunrealtype *y_data = N_VGetArrayPointer(m_Y); + sunrealtype *y_data = N_VGetArrayPointer(sctx_p->Y); for (size_t i = 0; i < numSpecies; i++) { - const auto& species = m_engine.getNetworkSpecies()[i]; + const auto& species = m_engine.getNetworkSpecies(*sctx_p->engine_ctx)[i]; if (composition.contains(species)) { y_data[i] = composition.getMolarAbundance(species); } else { @@ -795,8 +878,8 @@ namespace gridfire::solver { y_data[numSpecies] = accumulatedEnergy; // Specific energy rate, initialized to zero - utils::check_cvode_flag(CVodeInit(m_cvode_mem, cvode_rhs_wrapper, current_time, m_Y), "CVodeInit"); - utils::check_cvode_flag(CVodeSStolerances(m_cvode_mem, relTol, absTol), "CVodeSStolerances"); + utils::check_cvode_flag(CVodeInit(sctx_p->cvode_mem, cvode_rhs_wrapper, current_time, sctx_p->Y), "CVodeInit"); + utils::check_cvode_flag(CVodeSStolerances(sctx_p->cvode_mem, relTol, absTol), "CVodeSStolerances"); // Constraints // We constrain the solution vector using CVODE's built in constraint flags as outlines on page 53 of the CVODE manual @@ -809,58 +892,35 @@ namespace gridfire::solver { // -2.0: The corresponding component of y is constrained to be < 0 // Here we use 1.0 for all species to ensure they remain non-negative. - m_constraints = N_VClone(m_Y); - if (m_constraints == nullptr) { + sctx_p->constraints = N_VClone(sctx_p->Y); + if (sctx_p->constraints == nullptr) { LOG_ERROR(m_logger, "Failed to create constraints vector for CVODE"); throw std::runtime_error("Failed to create constraints vector for CVODE"); } - N_VConst(1.0, m_constraints); // Set all constraints to >= 0 (note this is where the flag values are set) + N_VConst(1.0, sctx_p->constraints); // Set all constraints to >= 0 (note this is where the flag values are set) - utils::check_cvode_flag(CVodeSetConstraints(m_cvode_mem, m_constraints), "CVodeSetConstraints"); + utils::check_cvode_flag(CVodeSetConstraints(sctx_p->cvode_mem, sctx_p->constraints), "CVodeSetConstraints"); - utils::check_cvode_flag(CVodeSetMaxStep(m_cvode_mem, 1.0e20), "CVodeSetMaxStep"); + utils::check_cvode_flag(CVodeSetMaxStep(sctx_p->cvode_mem, 1.0e20), "CVodeSetMaxStep"); - m_J = SUNDenseMatrix(static_cast(N), static_cast(N), m_sun_ctx); - utils::check_cvode_flag(m_J == nullptr ? -1 : 0, "SUNDenseMatrix"); - m_LS = SUNLinSol_Dense(m_Y, m_J, m_sun_ctx); - utils::check_cvode_flag(m_LS == nullptr ? -1 : 0, "SUNLinSol_Dense"); + sctx_p->J = SUNDenseMatrix(static_cast(N), static_cast(N), sctx_p->sun_ctx); + utils::check_cvode_flag(sctx_p->J == nullptr ? -1 : 0, "SUNDenseMatrix"); + sctx_p->LS = SUNLinSol_Dense(sctx_p->Y, sctx_p->J, sctx_p->sun_ctx); + utils::check_cvode_flag(sctx_p->LS == nullptr ? -1 : 0, "SUNLinSol_Dense"); - utils::check_cvode_flag(CVodeSetLinearSolver(m_cvode_mem, m_LS, m_J), "CVodeSetLinearSolver"); - utils::check_cvode_flag(CVodeSetJacFn(m_cvode_mem, cvode_jac_wrapper), "CVodeSetJacFn"); + utils::check_cvode_flag(CVodeSetLinearSolver(sctx_p->cvode_mem, sctx_p->LS, sctx_p->J), "CVodeSetLinearSolver"); + utils::check_cvode_flag(CVodeSetJacFn(sctx_p->cvode_mem, cvode_jac_wrapper), "CVodeSetJacFn"); LOG_TRACE_L2(m_logger, "CVODE solver initialized"); } - void CVODESolverStrategy::cleanup_cvode_resources(const bool memFree) { - LOG_TRACE_L2(m_logger, "Cleaning up cvode resources"); - if (m_LS) SUNLinSolFree(m_LS); - if (m_J) SUNMatDestroy(m_J); - if (m_Y) N_VDestroy(m_Y); - if (m_YErr) N_VDestroy(m_YErr); - if (m_constraints) N_VDestroy(m_constraints); - m_LS = nullptr; - m_J = nullptr; - m_Y = nullptr; - m_YErr = nullptr; - m_constraints = nullptr; - - if (memFree) { - if (m_cvode_mem) CVodeFree(&m_cvode_mem); - m_cvode_mem = nullptr; - } - LOG_TRACE_L2(m_logger, "Done Cleaning up cvode resources"); - } - - void CVODESolverStrategy::set_detailed_step_logging(const bool enabled) { - m_detailed_step_logging = enabled; - } - - void CVODESolverStrategy::log_step_diagnostics( + void PointSolver::log_step_diagnostics( + PointSolverContext* sctx_p, + scratch::StateBlob &ctx, const CVODEUserData &user_data, bool displayJacobianStiffness, bool displaySpeciesBalance, - bool to_file, - std::optional filename + bool to_file, std::optional filename ) const { if (to_file && !filename.has_value()) { LOG_ERROR(m_logger, "Filename must be provided when logging diagnostics to file."); @@ -871,10 +931,10 @@ namespace gridfire::solver { sunrealtype hlast, hcur, tcur; int qlast; - utils::check_cvode_flag(CVodeGetLastStep(m_cvode_mem, &hlast), "CVodeGetLastStep"); - utils::check_cvode_flag(CVodeGetCurrentStep(m_cvode_mem, &hcur), "CVodeGetCurrentStep"); - utils::check_cvode_flag(CVodeGetLastOrder(m_cvode_mem, &qlast), "CVodeGetLastOrder"); - utils::check_cvode_flag(CVodeGetCurrentTime(m_cvode_mem, &tcur), "CVodeGetCurrentTime"); + utils::check_cvode_flag(CVodeGetLastStep(sctx_p->cvode_mem, &hlast), "CVodeGetLastStep"); + utils::check_cvode_flag(CVodeGetCurrentStep(sctx_p->cvode_mem, &hcur), "CVodeGetCurrentStep"); + utils::check_cvode_flag(CVodeGetLastOrder(sctx_p->cvode_mem, &qlast), "CVodeGetLastOrder"); + utils::check_cvode_flag(CVodeGetCurrentTime(sctx_p->cvode_mem, &tcur), "CVodeGetCurrentTime"); nlohmann::json j; { @@ -896,13 +956,13 @@ namespace gridfire::solver { // These are the CRITICAL counters for diagnosing your problem long int nsteps, nfevals, nlinsetups, netfails, nniters, nconvfails, nsetfails; - utils::check_cvode_flag(CVodeGetNumSteps(m_cvode_mem, &nsteps), "CVodeGetNumSteps"); - utils::check_cvode_flag(CVodeGetNumRhsEvals(m_cvode_mem, &nfevals), "CVodeGetNumRhsEvals"); - utils::check_cvode_flag(CVodeGetNumLinSolvSetups(m_cvode_mem, &nlinsetups), "CVodeGetNumLinSolvSetups"); - utils::check_cvode_flag(CVodeGetNumErrTestFails(m_cvode_mem, &netfails), "CVodeGetNumErrTestFails"); - utils::check_cvode_flag(CVodeGetNumNonlinSolvIters(m_cvode_mem, &nniters), "CVodeGetNumNonlinSolvIters"); - utils::check_cvode_flag(CVodeGetNumNonlinSolvConvFails(m_cvode_mem, &nconvfails), "CVodeGetNumNonlinSolvConvFails"); - utils::check_cvode_flag(CVodeGetNumLinConvFails(m_cvode_mem, &nsetfails), "CVodeGetNumLinConvFails"); + utils::check_cvode_flag(CVodeGetNumSteps(sctx_p->cvode_mem, &nsteps), "CVodeGetNumSteps"); + utils::check_cvode_flag(CVodeGetNumRhsEvals(sctx_p->cvode_mem, &nfevals), "CVodeGetNumRhsEvals"); + utils::check_cvode_flag(CVodeGetNumLinSolvSetups(sctx_p->cvode_mem, &nlinsetups), "CVodeGetNumLinSolvSetups"); + utils::check_cvode_flag(CVodeGetNumErrTestFails(sctx_p->cvode_mem, &netfails), "CVodeGetNumErrTestFails"); + utils::check_cvode_flag(CVodeGetNumNonlinSolvIters(sctx_p->cvode_mem, &nniters), "CVodeGetNumNonlinSolvIters"); + utils::check_cvode_flag(CVodeGetNumNonlinSolvConvFails(sctx_p->cvode_mem, &nconvfails), "CVodeGetNumNonlinSolvConvFails"); + utils::check_cvode_flag(CVodeGetNumLinConvFails(sctx_p->cvode_mem, &nsetfails), "CVodeGetNumLinConvFails"); { @@ -930,22 +990,26 @@ namespace gridfire::solver { } // --- 3. Get Estimated Local Errors (Your Original Logic) --- - utils::check_cvode_flag(CVodeGetEstLocalErrors(m_cvode_mem, m_YErr), "CVodeGetEstLocalErrors"); + utils::check_cvode_flag(CVodeGetEstLocalErrors(sctx_p->cvode_mem, sctx_p->YErr), "CVodeGetEstLocalErrors"); - sunrealtype *y_data = N_VGetArrayPointer(m_Y); - sunrealtype *y_err_data = N_VGetArrayPointer(m_YErr); - - const auto absTol = m_config->solver.cvode.absTol; - const auto relTol = m_config->solver.cvode.relTol; + sunrealtype *y_data = N_VGetArrayPointer(sctx_p->Y); + sunrealtype *y_err_data = N_VGetArrayPointer(sctx_p->YErr); std::vector err_ratios; - const size_t num_components = N_VGetLength(m_Y); + const size_t num_components = N_VGetLength(sctx_p->Y); err_ratios.resize(num_components - 1); // Assuming -1 is for Energy or similar std::vector Y_full(y_data, y_data + num_components - 1); std::vector E_full(y_err_data, y_err_data + num_components - 1); - auto result = diagnostics::report_limiting_species(*user_data.engine, Y_full, E_full, relTol, absTol, 10, to_file); + if (!sctx_p->abs_tol.has_value()) { + sctx_p->abs_tol = m_config->solver.cvode.absTol; + } + if (!sctx_p->rel_tol.has_value()) { + sctx_p->rel_tol = m_config->solver.cvode.relTol; + } + + auto result = diagnostics::report_limiting_species(ctx, *user_data.engine, Y_full, E_full, sctx_p->rel_tol.value(), sctx_p->abs_tol.value(), 10, to_file); if (to_file && result.has_value()) { j["Limiting_Species"] = result.value(); } @@ -958,8 +1022,9 @@ namespace gridfire::solver { 0.0 ); + for (size_t i = 0; i < num_components - 1; i++) { - const double weight = relTol * std::abs(y_data[i]) + absTol; + const double weight = sctx_p->rel_tol.value() * std::abs(y_data[i]) + sctx_p->abs_tol.value(); if (weight == 0.0) { err_ratios[i] = 0.0; // Avoid division by zero continue; @@ -968,11 +1033,11 @@ namespace gridfire::solver { err_ratios[i] = err_ratio; } - fourdst::composition::Composition composition(user_data.engine->getNetworkSpecies(), Y_full); - fourdst::composition::Composition collectedComposition = user_data.engine->collectComposition(composition, user_data.T9, user_data.rho); + fourdst::composition::Composition composition(user_data.engine->getNetworkSpecies(*sctx_p->engine_ctx), Y_full); + fourdst::composition::Composition collectedComposition = user_data.engine->collectComposition(*sctx_p->engine_ctx, composition, user_data.T9, user_data.rho); - auto destructionTimescales = user_data.engine->getSpeciesDestructionTimescales(collectedComposition, user_data.T9, user_data.rho); - auto netTimescales = user_data.engine->getSpeciesTimescales(collectedComposition, user_data.T9, user_data.rho); + auto destructionTimescales = user_data.engine->getSpeciesDestructionTimescales(*sctx_p->engine_ctx, collectedComposition, user_data.T9, user_data.rho); + auto netTimescales = user_data.engine->getSpeciesTimescales(*sctx_p->engine_ctx, collectedComposition, user_data.T9, user_data.rho); bool timescaleOkay = false; if (destructionTimescales && netTimescales) timescaleOkay = true; @@ -992,7 +1057,7 @@ namespace gridfire::solver { if (destructionTimescales.value().contains(sp)) destructionTimescales_list.emplace_back(destructionTimescales.value().at(sp)); else destructionTimescales_list.emplace_back(std::numeric_limits::infinity()); - speciesStatus_list.push_back(SpeciesStatus_to_string(user_data.engine->getSpeciesStatus(sp))); + speciesStatus_list.push_back(SpeciesStatus_to_string(user_data.engine->getSpeciesStatus(*sctx_p->engine_ctx, sp))); } utils::Column speciesColumn("Species", species_list); @@ -1056,7 +1121,7 @@ namespace gridfire::solver { // --- 4. Call Your Jacobian and Balance Diagnostics --- if (displayJacobianStiffness) { - auto jStiff = diagnostics::inspect_jacobian_stiffness(*user_data.engine, composition, user_data.T9, user_data.rho, to_file); + auto jStiff = diagnostics::inspect_jacobian_stiffness(ctx, *user_data.engine, composition, user_data.T9, user_data.rho, to_file); if (to_file && jStiff.has_value()) { j["Jacobian_Stiffness_Diagnostics"] = jStiff.value(); } @@ -1066,7 +1131,7 @@ namespace gridfire::solver { const size_t num_species_to_inspect = std::min(sorted_species.size(), static_cast(5)); for (size_t i = 0; i < num_species_to_inspect; ++i) { const auto& species = sorted_species[i]; - auto sbr = diagnostics::inspect_species_balance(*user_data.engine, std::string(species.name()), composition, user_data.T9, user_data.rho, to_file); + auto sbr = diagnostics::inspect_species_balance(ctx, *user_data.engine, std::string(species.name()), composition, user_data.T9, user_data.rho, to_file); if (to_file && sbr.has_value()) { j[std::string("Species_Balance_Diagnostics_") + species.name().data()] = sbr.value(); } diff --git a/src/lib/solver/strategies/triggers/engine_partitioning_trigger.cpp b/src/lib/solver/strategies/triggers/engine_partitioning_trigger.cpp index 763782ec..0bbb7878 100644 --- a/src/lib/solver/strategies/triggers/engine_partitioning_trigger.cpp +++ b/src/lib/solver/strategies/triggers/engine_partitioning_trigger.cpp @@ -1,5 +1,5 @@ #include "gridfire/solver/strategies/triggers/engine_partitioning_trigger.h" -#include "gridfire/solver/strategies/CVODE_solver_strategy.h" +#include "gridfire/solver/strategies/PointSolver.h" #include "gridfire/trigger/trigger_logical.h" #include "gridfire/trigger/trigger_abstract.h" @@ -28,7 +28,7 @@ namespace gridfire::trigger::solver::CVODE { } } - bool SimulationTimeTrigger::check(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const { + bool SimulationTimeTrigger::check(const gridfire::solver::PointSolverTimestepContext &ctx) const { if (ctx.t - m_last_trigger_time >= m_interval) { m_hits++; LOG_TRACE_L2(m_logger, "SimulationTimeTrigger triggered at t = {}, last trigger time was {}, delta = {}", ctx.t, m_last_trigger_time, m_last_trigger_time_delta); @@ -38,7 +38,7 @@ namespace gridfire::trigger::solver::CVODE { return false; } - void SimulationTimeTrigger::update(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) { + void SimulationTimeTrigger::update(const gridfire::solver::PointSolverTimestepContext &ctx) { if (check(ctx)) { m_last_trigger_time_delta = (ctx.t - m_last_trigger_time) - m_interval; m_last_trigger_time = ctx.t; @@ -47,7 +47,7 @@ namespace gridfire::trigger::solver::CVODE { } void SimulationTimeTrigger::step( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) { // --- SimulationTimeTrigger::step does nothing and is intentionally left blank --- // } @@ -65,7 +65,7 @@ namespace gridfire::trigger::solver::CVODE { return "Simulation Time Trigger"; } - TriggerResult SimulationTimeTrigger::why(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const { + TriggerResult SimulationTimeTrigger::why(const gridfire::solver::PointSolverTimestepContext &ctx) const { TriggerResult result; result.name = name(); if (check(ctx)) { @@ -99,18 +99,18 @@ namespace gridfire::trigger::solver::CVODE { } } - bool OffDiagonalTrigger::check(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const { + bool OffDiagonalTrigger::check(const gridfire::solver::PointSolverTimestepContext &ctx) const { //TODO : This currently does nothing return false; } - void OffDiagonalTrigger::update(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) { + void OffDiagonalTrigger::update(const gridfire::solver::PointSolverTimestepContext &ctx) { m_updates++; } void OffDiagonalTrigger::step( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) { // --- OffDiagonalTrigger::step does nothing and is intentionally left blank --- // } @@ -126,7 +126,7 @@ namespace gridfire::trigger::solver::CVODE { return "Off-Diagonal Trigger"; } - TriggerResult OffDiagonalTrigger::why(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const { + TriggerResult OffDiagonalTrigger::why(const gridfire::solver::PointSolverTimestepContext &ctx) const { TriggerResult result; result.name = name(); @@ -173,7 +173,7 @@ namespace gridfire::trigger::solver::CVODE { } } - bool TimestepCollapseTrigger::check(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const { + bool TimestepCollapseTrigger::check(const gridfire::solver::PointSolverTimestepContext &ctx) const { if (m_timestep_window.size() < m_windowSize) { m_misses++; return false; @@ -201,13 +201,13 @@ namespace gridfire::trigger::solver::CVODE { return false; } - void TimestepCollapseTrigger::update(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) { + void TimestepCollapseTrigger::update(const gridfire::solver::PointSolverTimestepContext &ctx) { m_updates++; m_timestep_window.clear(); } void TimestepCollapseTrigger::step( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) { push_to_fixed_deque(m_timestep_window, ctx.dt, m_windowSize); // --- TimestepCollapseTrigger::step does nothing and is intentionally left blank --- // @@ -226,7 +226,7 @@ namespace gridfire::trigger::solver::CVODE { } TriggerResult TimestepCollapseTrigger::why( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) const { TriggerResult result; result.name = name(); @@ -263,7 +263,7 @@ namespace gridfire::trigger::solver::CVODE { m_windowSize(windowSize) {} bool ConvergenceFailureTrigger::check( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) const { if (m_window.size() != m_windowSize) { m_misses++; @@ -278,13 +278,13 @@ namespace gridfire::trigger::solver::CVODE { } void ConvergenceFailureTrigger::update( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) { m_window.clear(); } void ConvergenceFailureTrigger::step( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) { push_to_fixed_deque(m_window, ctx.currentConvergenceFailures, m_windowSize); m_updates++; @@ -306,7 +306,7 @@ namespace gridfire::trigger::solver::CVODE { return "ConvergenceFailureTrigger(abs_failure_threshold=" + std::to_string(m_totalFailures) + ", rel_failure_threshold=" + std::to_string(m_relativeFailureRate) + ", windowSize=" + std::to_string(m_windowSize) + ")"; } - TriggerResult ConvergenceFailureTrigger::why(const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx) const { + TriggerResult ConvergenceFailureTrigger::why(const gridfire::solver::PointSolverTimestepContext &ctx) const { TriggerResult result; result.name = name(); @@ -348,7 +348,7 @@ namespace gridfire::trigger::solver::CVODE { } bool ConvergenceFailureTrigger::abs_failure( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) const { if (ctx.currentConvergenceFailures > m_totalFailures) { return true; @@ -357,7 +357,7 @@ namespace gridfire::trigger::solver::CVODE { } bool ConvergenceFailureTrigger::rel_failure( - const gridfire::solver::CVODESolverStrategy::TimestepContext &ctx + const gridfire::solver::PointSolverTimestepContext &ctx ) const { const float mean = current_mean(); if (mean < 10) { @@ -369,13 +369,13 @@ namespace gridfire::trigger::solver::CVODE { return false; } - std::unique_ptr> makeEnginePartitioningTrigger( + std::unique_ptr> makeEnginePartitioningTrigger( const double simulationTimeInterval, const double offDiagonalThreshold, const double timestepCollapseRatio, const size_t maxConvergenceFailures ) { - using ctx_t = gridfire::solver::CVODESolverStrategy::TimestepContext; + using ctx_t = gridfire::solver::PointSolverTimestepContext; // 1. INSTABILITY TRIGGERS (High Priority) auto convergenceFailureTrigger = std::make_unique( diff --git a/src/lib/utils/logging.cpp b/src/lib/utils/logging.cpp index 7373a029..58e706bd 100644 --- a/src/lib/utils/logging.cpp +++ b/src/lib/utils/logging.cpp @@ -1,5 +1,6 @@ #include "gridfire/utils/logging.h" #include "gridfire/engine/engine_abstract.h" +#include "gridfire/engine/scratchpads/blob.h" #include #include @@ -9,12 +10,12 @@ #include std::string gridfire::utils::formatNuclearTimescaleLogString( + engine::scratch::StateBlob &ctx, const engine::DynamicEngine& engine, const fourdst::composition::Composition& composition, - const double T9, - const double rho + const double T9, const double rho ) { - auto const& result = engine.getSpeciesTimescales(composition, T9, rho); + auto const& result = engine.getSpeciesTimescales(ctx, composition, T9, rho); if (!result) { std::ostringstream ss; ss << "Failed to get species timescales: " << engine::EngineStatus_to_string(result.error()); diff --git a/src/meson.build b/src/meson.build index 4fa4fcea..ecc7115e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,7 +15,8 @@ gridfire_sources = files( 'lib/reaction/weak/weak_interpolator.cpp', 'lib/io/network_file.cpp', 'lib/io/generative/python.cpp', - 'lib/solver/strategies/CVODE_solver_strategy.cpp', + 'lib/solver/strategies/PointSolver.cpp', + 'lib/solver/strategies/GridSolver.cpp', 'lib/solver/strategies/triggers/engine_partitioning_trigger.cpp', 'lib/screening/screening_types.cpp', 'lib/screening/screening_weak.cpp', @@ -40,8 +41,13 @@ gridfire_build_dependencies = [ eigen_dep, sundials_dep, json_dep, + uod_dep, ] +if get_option('use_mimalloc') + gridfire_build_dependencies += [mimalloc_dep] +endif + if get_option('plugin_support') gridfire_build_dependencies += [plugin_dep] endif @@ -52,12 +58,21 @@ if get_option('openmp_support') endif # Define the libnetwork library so it can be linked against by other parts of the build system -libgridfire = library('gridfire', - gridfire_sources, - include_directories: include_directories('include'), - dependencies: gridfire_build_dependencies, - objects: [cvode_objs, kinsol_objs], - install : true) +if get_option('build_python') + libgridfire = static_library('gridfire', + gridfire_sources, + include_directories: include_directories('include'), + dependencies: gridfire_build_dependencies, + objects: [cvode_objs, kinsol_objs], + install : false) +else + libgridfire = library('gridfire', + gridfire_sources, + include_directories: include_directories('include'), + dependencies: gridfire_build_dependencies, + objects: [cvode_objs, kinsol_objs], + install : true) +endif gridfire_dep = declare_dependency( include_directories: include_directories('include'), diff --git a/src/python/bindings.cpp b/src/python/bindings.cpp index b0d88baa..0103831f 100644 --- a/src/python/bindings.cpp +++ b/src/python/bindings.cpp @@ -4,6 +4,7 @@ #include "types/bindings.h" #include "partition/bindings.h" #include "engine/bindings.h" +#include "engine/scratchpads/bindings.h" #include "exceptions/bindings.h" #include "io/bindings.h" #include "reaction/bindings.h" @@ -11,6 +12,7 @@ #include "solver/bindings.h" #include "utils/bindings.h" #include "policy/bindings.h" +#include "config/bindings.h" PYBIND11_MODULE(_gridfire, m) { m.doc() = "Python bindings for the fourdst utility modules which are a part of the 4D-STAR project."; @@ -20,6 +22,9 @@ PYBIND11_MODULE(_gridfire, m) { pybind11::module::import("fourdst.config"); pybind11::module::import("fourdst.atomic"); + auto configMod = m.def_submodule("config", "GridFire configuration bindings"); + register_config_bindings(configMod); + auto typeMod = m.def_submodule("type", "GridFire type bindings"); register_type_bindings(typeMod); @@ -39,6 +44,12 @@ PYBIND11_MODULE(_gridfire, m) { register_exception_bindings(exceptionMod); auto engineMod = m.def_submodule("engine", "Engine and Engine View bindings"); + auto scratchpadMod = engineMod.def_submodule("scratchpads", "Engine ScratchPad bindings"); + + register_scratchpad_types_bindings(scratchpadMod); + register_scratchpad_bindings(scratchpadMod); + register_state_blob_bindings(scratchpadMod); + register_engine_bindings(engineMod); auto solverMod = m.def_submodule("solver", "GridFire numerical solver bindings"); diff --git a/src/python/config/bindings.cpp b/src/python/config/bindings.cpp new file mode 100644 index 00000000..0b88ead5 --- /dev/null +++ b/src/python/config/bindings.cpp @@ -0,0 +1,34 @@ +#include "bindings.h" + +#include "gridfire/config/config.h" +#include + +namespace py = pybind11; + +void register_config_bindings(pybind11::module &m) { + py::class_(m, "CVODESolverConfig") + .def(py::init<>()) + .def_readwrite("absTol", &gridfire::config::CVODESolverConfig::absTol) + .def_readwrite("relTol", &gridfire::config::CVODESolverConfig::relTol); + + py::class_(m, "SolverConfig") + .def(py::init<>()) + .def_readwrite("cvode", &gridfire::config::SolverConfig::cvode); + + py::class_(m, "AdaptiveEngineViewConfig") + .def(py::init<>()) + .def_readwrite("relativeCullingThreshold", &gridfire::config::AdaptiveEngineViewConfig::relativeCullingThreshold); + + py::class_(m, "EngineViewConfig") + .def(py::init<>()) + .def_readwrite("adaptiveEngineView", &gridfire::config::EngineViewConfig::adaptiveEngineView); + + py::class_(m, "EngineConfig") + .def(py::init<>()) + .def_readwrite("views", &gridfire::config::EngineConfig::views); + + py::class_(m, "GridFireConfig") + .def(py::init<>()) + .def_readwrite("solver", &gridfire::config::GridFireConfig::solver) + .def_readwrite("engine", &gridfire::config::GridFireConfig::engine); +} \ No newline at end of file diff --git a/src/python/config/bindings.h b/src/python/config/bindings.h new file mode 100644 index 00000000..2c0e1a05 --- /dev/null +++ b/src/python/config/bindings.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +void register_config_bindings(pybind11::module &m); diff --git a/src/python/engine/bindings.cpp b/src/python/engine/bindings.cpp index 93675194..e01ff1e6 100644 --- a/src/python/engine/bindings.cpp +++ b/src/python/engine/bindings.cpp @@ -12,6 +12,7 @@ namespace py = pybind11; +namespace sp = gridfire::engine::scratch; namespace { template @@ -23,16 +24,18 @@ namespace { "calculateRHSAndEnergy", []( const gridfire::engine::DynamicEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& comp, const double T9, const double rho ) { - auto result = self.calculateRHSAndEnergy(comp, T9, rho); + auto result = self.calculateRHSAndEnergy(ctx, comp, T9, rho, false); if (!result.has_value()) { throw gridfire::exceptions::EngineError(std::format("calculateRHSAndEnergy returned a potentially recoverable error {}", gridfire::engine::EngineStatus_to_string(result.error()))); } return result.value(); }, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), @@ -40,6 +43,7 @@ namespace { ) .def("calculateEpsDerivatives", &gridfire::engine::DynamicEngine::calculateEpsDerivatives, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), @@ -47,11 +51,13 @@ namespace { ) .def("generateJacobianMatrix", [](const gridfire::engine::DynamicEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& comp, const double T9, const double rho) -> gridfire::engine::NetworkJacobian { - return self.generateJacobianMatrix(comp, T9, rho); + return self.generateJacobianMatrix(ctx, comp, T9, rho); }, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), @@ -59,12 +65,14 @@ namespace { ) .def("generateJacobianMatrix", [](const gridfire::engine::DynamicEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& comp, const double T9, const double rho, const std::vector& activeSpecies) -> gridfire::engine::NetworkJacobian { - return self.generateJacobianMatrix(comp, T9, rho, activeSpecies); + return self.generateJacobianMatrix(ctx, comp, T9, rho, activeSpecies); }, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), @@ -73,31 +81,32 @@ namespace { ) .def("generateJacobianMatrix", [](const gridfire::engine::DynamicEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& comp, const double T9, const double rho, const gridfire::engine::SparsityPattern& sparsityPattern) -> gridfire::engine::NetworkJacobian { - return self.generateJacobianMatrix(comp, T9, rho, sparsityPattern); + return self.generateJacobianMatrix(ctx, comp, T9, rho, sparsityPattern); }, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), py::arg("sparsityPattern"), "Generate the jacobian matrix for the given sparsity pattern" ) - .def("generateStoichiometryMatrix", - &T::generateStoichiometryMatrix - ) .def("calculateMolarReactionFlow", []( const gridfire::engine::DynamicEngine& self, + sp::StateBlob& ctx, const gridfire::reaction::Reaction& reaction, const fourdst::composition::Composition& comp, const double T9, const double rho ) -> double { - return self.calculateMolarReactionFlow(reaction, comp, T9, rho); + return self.calculateMolarReactionFlow(ctx, reaction, comp, T9, rho); }, + py::arg("ctx"), py::arg("reaction"), py::arg("comp"), py::arg("T9"), @@ -110,28 +119,21 @@ namespace { .def("getNetworkReactions", &T::getNetworkReactions, "Get the set of logical reactions in the network." ) - .def ("setNetworkReactions", &T::setNetworkReactions, - py::arg("reactions"), - "Set the network reactions to a new set of reactions." - ) - .def("getStoichiometryMatrixEntry", &T::getStoichiometryMatrixEntry, - py::arg("species"), - py::arg("reaction"), - "Get an entry from the stoichiometry matrix." - ) .def("getSpeciesTimescales", []( const gridfire::engine::DynamicEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& comp, const double T9, const double rho ) -> std::unordered_map { - const auto result = self.getSpeciesTimescales(comp, T9, rho); + const auto result = self.getSpeciesTimescales(ctx, comp, T9, rho); if (!result.has_value()) { throw gridfire::exceptions::EngineError(std::format("getSpeciesTimescales has returned a potentially recoverable error {}", gridfire::engine::EngineStatus_to_string(result.error()))); } return result.value(); }, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), @@ -140,67 +142,48 @@ namespace { .def("getSpeciesDestructionTimescales", []( const gridfire::engine::DynamicEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& comp, const double T9, const double rho ) -> std::unordered_map { - const auto result = self.getSpeciesDestructionTimescales(comp, T9, rho); + const auto result = self.getSpeciesDestructionTimescales(ctx, comp, T9, rho); if (!result.has_value()) { throw gridfire::exceptions::EngineError(std::format("getSpeciesDestructionTimescales has returned a potentially recoverable error {}", gridfire::engine::EngineStatus_to_string(result.error()))); } return result.value(); }, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), "Get the destruction timescales for each species in the network." ) - .def("update", - &T::update, + .def("project", + &T::project, + py::arg("ctx"), py::arg("netIn"), "Update the engine state based on the provided NetIn object." ) - .def("setScreeningModel", - &T::setScreeningModel, - py::arg("screeningModel"), - "Set the screening model for the engine." - ) .def("getScreeningModel", &T::getScreeningModel, "Get the current screening model of the engine." ) .def("getSpeciesIndex", &T::getSpeciesIndex, + py::arg("ctx"), py::arg("species"), "Get the index of a species in the network." ) - .def("mapNetInToMolarAbundanceVector", - &T::mapNetInToMolarAbundanceVector, - py::arg("netIn"), - "Map a NetIn object to a vector of molar abundances." - ) .def("primeEngine", &T::primeEngine, + py::arg("ctx"), py::arg("netIn"), "Prime the engine with a NetIn object to prepare for calculations." ) - .def("getDepth", - &T::getDepth, - "Get the current build depth of the engine." - ) - .def("rebuild", - &T::rebuild, - py::arg("composition"), - py::arg("depth") = gridfire::engine::NetworkBuildDepth::Full, - "Rebuild the engine with a new composition and build depth." - ) - .def("isStale", - &T::isStale, - py::arg("netIn"), - "Check if the engine is stale based on the provided NetIn object." - ) .def("collectComposition", &T::collectComposition, + py::arg("ctx"), py::arg("composition"), py::arg("T9"), py::arg("rho"), @@ -208,6 +191,7 @@ namespace { ) .def("getSpeciesStatus", &T::getSpeciesStatus, + py::arg("ctx"), py::arg("species"), "Get the status of a species in the network." ); @@ -253,6 +237,7 @@ void register_engine_diagnostic_bindings(pybind11::module &m) { auto diagnostics = m.def_submodule("diagnostics", "A submodule for engine diagnostics"); diagnostics.def("report_limiting_species", &gridfire::engine::diagnostics::report_limiting_species, + py::arg("ctx"), py::arg("engine"), py::arg("Y_full"), py::arg("E_full"), @@ -264,6 +249,7 @@ void register_engine_diagnostic_bindings(pybind11::module &m) { diagnostics.def("inspect_species_balance", &gridfire::engine::diagnostics::inspect_species_balance, + py::arg("ctx"), py::arg("engine"), py::arg("species_name"), py::arg("comp"), @@ -274,6 +260,7 @@ void register_engine_diagnostic_bindings(pybind11::module &m) { diagnostics.def("inspect_jacobian_stiffness", &gridfire::engine::diagnostics::inspect_jacobian_stiffness, + py::arg("ctx"), py::arg("engine"), py::arg("comp"), py::arg("T9"), @@ -311,6 +298,7 @@ void register_engine_construction_bindings(pybind11::module &m) { void register_engine_priming_bindings(pybind11::module &m) { m.def("primeNetwork", &gridfire::engine::primeNetwork, + py::arg("ctx"), py::arg("netIn"), py::arg("engine"), py::arg("ignoredReactionTypes") = std::nullopt, @@ -456,19 +444,16 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) { py::arg("reactions"), "Initialize GraphEngine with a set of reactions." ); - py_graph_engine_bindings.def_static("getNetReactionStoichiometry", - &gridfire::engine::GraphEngine::getNetReactionStoichiometry, - py::arg("reaction"), - "Get the net stoichiometry for a given reaction." - ); py_graph_engine_bindings.def("getSpeciesTimescales", [](const gridfire::engine::GraphEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& composition, const double T9, const double rho, const gridfire::reaction::ReactionSet& activeReactions) { - return self.getSpeciesTimescales(composition, T9, rho, activeReactions); + return self.getSpeciesTimescales(ctx, composition, T9, rho, activeReactions); }, + py::arg("ctx"), py::arg("composition"), py::arg("T9"), py::arg("rho"), @@ -476,12 +461,14 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) { ); py_graph_engine_bindings.def("getSpeciesDestructionTimescales", [](const gridfire::engine::GraphEngine& self, + sp::StateBlob& ctx, const fourdst::composition::Composition& composition, const double T9, const double rho, const gridfire::reaction::ReactionSet& activeReactions) { - return self.getSpeciesDestructionTimescales(composition, T9, rho, activeReactions); + return self.getSpeciesDestructionTimescales(ctx, composition, T9, rho, activeReactions); }, + py::arg("ctx"), py::arg("composition"), py::arg("T9"), py::arg("rho"), @@ -489,24 +476,22 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) { ); py_graph_engine_bindings.def("involvesSpecies", &gridfire::engine::GraphEngine::involvesSpecies, + py::arg("ctx"), py::arg("species"), "Check if a given species is involved in the network." ); py_graph_engine_bindings.def("exportToDot", &gridfire::engine::GraphEngine::exportToDot, + py::arg("ctx"), py::arg("filename"), "Export the network to a DOT file for visualization." ); py_graph_engine_bindings.def("exportToCSV", &gridfire::engine::GraphEngine::exportToCSV, + py::arg("ctx"), py::arg("filename"), "Export the network to a CSV file for analysis." ); - py_graph_engine_bindings.def("setPrecomputation", - &gridfire::engine::GraphEngine::setPrecomputation, - py::arg("precompute"), - "Enable or disable precomputation for the engine." - ); py_graph_engine_bindings.def("isPrecomputationEnabled", &gridfire::engine::GraphEngine::isPrecomputationEnabled, "Check if precomputation is enabled for the engine." @@ -544,11 +529,6 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) { &gridfire::engine::GraphEngine::isUsingReverseReactions, "Check if the engine is using reverse reactions." ); - py_graph_engine_bindings.def("setUseReverseReactions", - &gridfire::engine::GraphEngine::setUseReverseReactions, - py::arg("useReverse"), - "Enable or disable the use of reverse reactions in the engine." - ); // Register the general dynamic engine bindings registerDynamicEngineDefs(py_graph_engine_bindings); @@ -587,11 +567,13 @@ void register_engine_view_bindings(const pybind11::module &m) { registerDynamicEngineDefs(py_file_defined_engine_view_bindings); auto py_priming_engine_view_bindings = py::class_(m, "NetworkPrimingEngineView"); - py_priming_engine_view_bindings.def(py::init(), + py_priming_engine_view_bindings.def(py::init(), + py::arg("ctx"), py::arg("primingSymbol"), py::arg("baseEngine"), "Construct a priming engine view with a priming symbol and a base engine."); - py_priming_engine_view_bindings.def(py::init(), + py_priming_engine_view_bindings.def(py::init(), + py::arg("ctx"), py::arg("primingSpecies"), py::arg("baseEngine"), "Construct a priming engine view with a priming species and a base engine."); @@ -622,15 +604,12 @@ void register_engine_view_bindings(const pybind11::module &m) { ); py_multiscale_engine_view_bindings.def("partitionNetwork", &gridfire::engine::MultiscalePartitioningEngineView::partitionNetwork, + py::arg("ctx"), py::arg("netIn"), "Partition the network based on species timescales and connectivity."); - py_multiscale_engine_view_bindings.def("partitionNetwork", - py::overload_cast(&gridfire::engine::MultiscalePartitioningEngineView::partitionNetwork), - py::arg("netIn"), - "Partition the network based on a NetIn object." - ); py_multiscale_engine_view_bindings.def("exportToDot", &gridfire::engine::MultiscalePartitioningEngineView::exportToDot, + py::arg("ctx"), py::arg("filename"), py::arg("comp"), py::arg("T9"), @@ -661,7 +640,16 @@ void register_engine_view_bindings(const pybind11::module &m) { "Check if a given species is involved in the network's dynamic set." ); py_multiscale_engine_view_bindings.def("getNormalizedEquilibratedComposition", - &gridfire::engine::MultiscalePartitioningEngineView::getNormalizedEquilibratedComposition, + []( + const gridfire::engine::MultiscalePartitioningEngineView& self, + sp::StateBlob& ctx, + const fourdst::composition::Composition& comp, + const double T9, + const double rho + ) { + return self.getNormalizedEquilibratedComposition(ctx, comp, T9, rho, false); + }, + py::arg("ctx"), py::arg("comp"), py::arg("T9"), py::arg("rho"), diff --git a/src/python/engine/meson.build b/src/python/engine/meson.build deleted file mode 100644 index e1b412a7..00000000 --- a/src/python/engine/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -subdir('trampoline') - -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -message('⏳ Python bindings for GridFire Engine are being registered...') -shared_module('py_gf_engine', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) -message('✅ Python bindings for GridFire Engine registered successfully!') \ No newline at end of file diff --git a/src/python/engine/scratchpads/bindings.cpp b/src/python/engine/scratchpads/bindings.cpp new file mode 100644 index 00000000..1d1c4ca1 --- /dev/null +++ b/src/python/engine/scratchpads/bindings.cpp @@ -0,0 +1,152 @@ +#include +#include // Needed for vectors, maps, sets, strings +#include // Needed for binding std::vector, std::map etc. if needed directly + +#include "gridfire/engine/scratchpads/scratchpads.h" + +#include "bindings.h" + +namespace py = pybind11; +namespace sp = gridfire::engine::scratch; + +template +void build_state_getter(py::module& m) { + +} + +void register_scratchpad_types_bindings(pybind11::module &m) { + py::enum_(m, "ScratchPadType") + .value("GRAPH_ENGINE_SCRATCHPAD", sp::ScratchPadType::GRAPH_ENGINE_SCRATCHPAD) + .value("MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD", sp::ScratchPadType::MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD) + .value("ADAPTIVE_ENGINE_VIEW_SCRATCHPAD", sp::ScratchPadType::ADAPTIVE_ENGINE_VIEW_SCRATCHPAD) + .value("DEFINED_ENGINE_VIEW_SCRATCHPAD", sp::ScratchPadType::DEFINED_ENGINE_VIEW_SCRATCHPAD) + .export_values(); +} + +void register_scratchpad_bindings(pybind11::module_ &m) { + py::enum_(m, "ADFunRegistrationResult") + .value("SUCCESS", sp::GraphEngineScratchPad::ADFunRegistrationResult::SUCCESS) + .value("ALREADY_REGISTERED", sp::GraphEngineScratchPad::ADFunRegistrationResult::ALREADY_REGISTERED) + .export_values(); + + py::class_(m, "GraphEngineScratchPad") + .def(py::init<>()) + .def("initialize", &sp::GraphEngineScratchPad::initialize, py::arg("engine")) + .def("clone", &sp::GraphEngineScratchPad::clone) + .def("is_initialized", &sp::GraphEngineScratchPad::is_initialized) + .def_readonly("most_recent_rhs_calculation", &sp::GraphEngineScratchPad::most_recent_rhs_calculation) + .def_readonly("local_abundance_cache", &sp::GraphEngineScratchPad::local_abundance_cache) + .def_readonly("has_initialized", &sp::GraphEngineScratchPad::has_initialized) + .def_readonly("stepDerivativesCache", &sp::GraphEngineScratchPad::stepDerivativesCache) + .def_readonly_static("ID", &sp::GraphEngineScratchPad::ID) + .def("__repr__", [](const sp::GraphEngineScratchPad &self) { + return std::format("{}", self); + }); + + py::class_(m, "MultiscalePartitioningEngineViewScratchPad") + .def(py::init<>()) + .def("initialize", &sp::MultiscalePartitioningEngineViewScratchPad::initialize) + .def("clone", &sp::MultiscalePartitioningEngineViewScratchPad::clone) + .def("is_initialized", &sp::MultiscalePartitioningEngineViewScratchPad::is_initialized) + .def_readonly("qse_groups", &sp::MultiscalePartitioningEngineViewScratchPad::qse_groups) + .def_readonly("dynamic_species", &sp::MultiscalePartitioningEngineViewScratchPad::dynamic_species) + .def_readonly("algebraic_species", &sp::MultiscalePartitioningEngineViewScratchPad::algebraic_species) + .def_readonly("composition_cache", &sp::MultiscalePartitioningEngineViewScratchPad::composition_cache) + .def_readonly("has_initialized", &sp::MultiscalePartitioningEngineViewScratchPad::has_initialized) + .def_readonly_static("ID", &sp::MultiscalePartitioningEngineViewScratchPad::ID) + .def("__repr__", [](const sp::MultiscalePartitioningEngineViewScratchPad &self) { + return std::format("{}", self); + }); + + py::class_(m, "AdaptiveEngineViewScratchPad") + .def(py::init<>()) + .def("initialize", &sp::AdaptiveEngineViewScratchPad::initialize) + .def("clone", &sp::AdaptiveEngineViewScratchPad::clone) + .def("is_initialized", &sp::AdaptiveEngineViewScratchPad::is_initialized) + .def_readonly("active_species", &sp::AdaptiveEngineViewScratchPad::active_species) + .def_readonly("active_reactions", &sp::AdaptiveEngineViewScratchPad::active_reactions) + .def_readonly("has_initialized", &sp::AdaptiveEngineViewScratchPad::has_initialized) + .def_readonly_static("ID", &sp::AdaptiveEngineViewScratchPad::ID) + .def("__repr__", [](const sp::AdaptiveEngineViewScratchPad &self) { + return std::format("{}", self); + }); + + py::class_(m, "DefinedEngineViewScratchPad") + .def(py::init<>()) + .def("clone", &sp::DefinedEngineViewScratchPad::clone) + .def("is_initialized", &sp::DefinedEngineViewScratchPad::is_initialized) + .def_readonly("active_species", &sp::DefinedEngineViewScratchPad::active_species) + .def_readonly("active_reactions", &sp::DefinedEngineViewScratchPad::active_reactions) + .def_readonly("species_index_map", &sp::DefinedEngineViewScratchPad::species_index_map) + .def_readonly("reaction_index_map", &sp::DefinedEngineViewScratchPad::reaction_index_map) + .def_readonly("has_initialized", &sp::DefinedEngineViewScratchPad::has_initialized) + .def_readonly_static("ID", &sp::DefinedEngineViewScratchPad::ID) + .def("__repr__", [](const sp::DefinedEngineViewScratchPad &self) { + return std::format("{}", self); + }); +} + +void register_state_blob_bindings(pybind11::module_ &m) { + py::enum_(m, "StateBlobError") + .value("SCRATCHPAD_OUT_OF_BOUNDS", sp::StateBlob::Error::SCRATCHPAD_OUT_OF_BOUNDS) + .value("SCRATCHPAD_NOT_FOUND", sp::StateBlob::Error::SCRATCHPAD_NOT_FOUND) + .value("SCRATCHPAD_BAD_CAST", sp::StateBlob::Error::SCRATCHPAD_BAD_CAST) + .value("SCRATCHPAD_NOT_INITIALIZED", sp::StateBlob::Error::SCRATCHPAD_NOT_INITIALIZED) + .value("SCRATCHPAD_TYPE_COLLISION", sp::StateBlob::Error::SCRATCHPAD_TYPE_COLLISION) + .value("SCRATCHPAD_UNKNOWN_ERROR", sp::StateBlob::Error::SCRATCHPAD_UNKNOWN_ERROR) + .export_values(); + + py::class_(m, "StateBlob") + .def(py::init<>()) + .def("enroll", [](sp::StateBlob &self, const sp::ScratchPadType type) { + switch (type) { + case sp::ScratchPadType::GRAPH_ENGINE_SCRATCHPAD: + self.enroll(); + break; + case sp::ScratchPadType::MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD: + self.enroll(); + break; + case sp::ScratchPadType::ADAPTIVE_ENGINE_VIEW_SCRATCHPAD: + self.enroll(); + break; + case sp::ScratchPadType::DEFINED_ENGINE_VIEW_SCRATCHPAD: + self.enroll(); + break; + default: + throw std::invalid_argument("Unknown ScratchPadType for enrollment."); + } + }) + .def("get", [](const sp::StateBlob &self, const sp::ScratchPadType type) { + auto result = self.get(type); + if (!result.has_value()) { + throw std::runtime_error("Error retrieving scratchpad: " + sp::StateBlob::error_to_string(result.error())); + } + return result.value(); + }, + pybind11::return_value_policy::reference_internal + ) + .def("clone_structure", &sp::StateBlob::clone_structure) + .def("get_registered_scratchpads", &sp::StateBlob::get_registered_scratchpads) + .def("get_status", [](const sp::StateBlob &self, const sp::ScratchPadType type) -> sp::StateBlob::ScratchPadStatus { + switch (type) { + case sp::ScratchPadType::GRAPH_ENGINE_SCRATCHPAD: + return self.get_status(); + case sp::ScratchPadType::MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD: + return self.get_status(); + case sp::ScratchPadType::ADAPTIVE_ENGINE_VIEW_SCRATCHPAD: + return self.get_status(); + case sp::ScratchPadType::DEFINED_ENGINE_VIEW_SCRATCHPAD: + return self.get_status(); + default: + throw std::invalid_argument("Unknown ScratchPadType for status retrieval."); + } + }) + .def("get_status_map", &sp::StateBlob::get_status_map) + .def_static("error_to_string", &sp::StateBlob::error_to_string) + .def("__repr__", [](const sp::StateBlob &self) { + return std::format("{}", self); + }); +} + + + diff --git a/src/python/engine/scratchpads/bindings.h b/src/python/engine/scratchpads/bindings.h new file mode 100644 index 00000000..d9799e5b --- /dev/null +++ b/src/python/engine/scratchpads/bindings.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +void register_scratchpad_types_bindings(pybind11::module_& m); +void register_scratchpad_bindings(pybind11::module_& m); +void register_state_blob_bindings(pybind11::module_& m); \ No newline at end of file diff --git a/src/python/engine/trampoline/meson.build b/src/python/engine/trampoline/meson.build deleted file mode 100644 index 78472541..00000000 --- a/src/python/engine/trampoline/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -gf_engine_trampoline_sources = files('py_engine.cpp') - -gf_engine_trapoline_dependencies = [ - gridfire_dep, - pybind11_dep, - python3_dep, -] - -gf_engine_trampoline_lib = static_library( - 'engine_trampolines', - gf_engine_trampoline_sources, - include_directories: include_directories('.'), - dependencies: gf_engine_trapoline_dependencies, - install: false, -) - -gr_engine_trampoline_dep = declare_dependency( - link_with: gf_engine_trampoline_lib, - include_directories: ('.'), - dependencies: gf_engine_trapoline_dependencies, -) diff --git a/src/python/engine/trampoline/py_engine.cpp b/src/python/engine/trampoline/py_engine.cpp index 76da9ea4..c54d0f94 100644 --- a/src/python/engine/trampoline/py_engine.cpp +++ b/src/python/engine/trampoline/py_engine.cpp @@ -13,36 +13,29 @@ namespace py = pybind11; -const std::vector& PyEngine::getNetworkSpecies() const { - /* - * Acquire the GIL (Global Interpreter Lock) for thread safety - * with the Python interpreter. - */ - py::gil_scoped_acquire gil; - - /* - * get_override() looks for a Python method that overrides this C++ one. - */ - - if (const py::function override = py::get_override(this, "getNetworkSpecies")) { - const py::object result = override(); - m_species_cache = result.cast>(); - return m_species_cache; - } - - py::pybind11_fail("Tried to call pure virtual function \"DynamicEngine::getNetworkSpecies\""); +const std::vector& PyEngine::getNetworkSpecies( + gridfire::engine::scratch::StateBlob& ctx +) const { + PYBIND11_OVERRIDE_PURE( + const std::vector&, + gridfire::engine::Engine, + getNetworkSpecies, + ctx + ); } std::expected, gridfire::engine::EngineStatus> PyEngine::calculateRHSAndEnergy( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const { PYBIND11_OVERRIDE_PURE( PYBIND11_TYPE(std::expected, gridfire::engine::EngineStatus>), gridfire::engine::Engine, calculateRHSAndEnergy, - comp, T9, rho + ctx, comp, T9, rho, trust ); } @@ -50,41 +43,35 @@ std::expected, gridfire::engine::Engin /// PyDynamicEngine Implementation /// ///////////////////////////////////// -const std::vector& PyDynamicEngine::getNetworkSpecies() const { - /* - * Acquire the GIL (Global Interpreter Lock) for thread safety - * with the Python interpreter. - */ - py::gil_scoped_acquire gil; - - /* - * get_override() looks for a Python method that overrides this C++ one. - */ - - if (const py::function override = py::get_override(this, "getNetworkSpecies")) { - const py::object result = override(); - m_species_cache = result.cast>(); - return m_species_cache; - } - - py::pybind11_fail("Tried to call pure virtual function \"DynamicEngine::getNetworkSpecies\""); +const std::vector& PyDynamicEngine::getNetworkSpecies( + gridfire::engine::scratch::StateBlob& ctx +) const { + PYBIND11_OVERRIDE_PURE( + const std::vector&, + gridfire::engine::DynamicEngine, + getNetworkSpecies, + ctx + ); } std::expected, gridfire::engine::EngineStatus> PyDynamicEngine::calculateRHSAndEnergy( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const { PYBIND11_OVERRIDE_PURE( PYBIND11_TYPE(std::expected, gridfire::engine::EngineStatus>), gridfire::engine::DynamicEngine, calculateRHSAndEnergy, - comp, T9, rho + ctx, comp, T9, rho, trust ); } gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract& comp, double T9, double rho @@ -100,6 +87,7 @@ gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( } gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho, @@ -109,6 +97,7 @@ gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( gridfire::engine::NetworkJacobian, gridfire::engine::DynamicEngine, generateJacobianMatrix, + ctx, comp, T9, rho, @@ -117,6 +106,7 @@ gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( } gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -126,6 +116,7 @@ gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( gridfire::engine::NetworkJacobian, gridfire::engine::DynamicEngine, generateJacobianMatrix, + ctx, comp, T9, rho, @@ -133,28 +124,8 @@ gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix( ); } -void PyDynamicEngine::generateStoichiometryMatrix() { - PYBIND11_OVERRIDE_PURE( - void, - gridfire::engine::DynamicEngine, - generateStoichiometryMatrix - ); -} - -int PyDynamicEngine::getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const gridfire::reaction::Reaction& reaction -) const { - PYBIND11_OVERRIDE_PURE( - int, - gridfire::engine::DynamicEngine, - getStoichiometryMatrixEntry, - species, - reaction - ); -} - double PyDynamicEngine::calculateMolarReactionFlow( + gridfire::engine::scratch::StateBlob& ctx, const gridfire::reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, double T9, @@ -164,6 +135,7 @@ double PyDynamicEngine::calculateMolarReactionFlow( double, gridfire::engine::DynamicEngine, calculateMolarReactionFlow, + ctx, reaction, comp, T9, @@ -171,24 +143,19 @@ double PyDynamicEngine::calculateMolarReactionFlow( ); } -const gridfire::reaction::ReactionSet& PyDynamicEngine::getNetworkReactions() const { +const gridfire::reaction::ReactionSet& PyDynamicEngine::getNetworkReactions( + gridfire::engine::scratch::StateBlob& ctx +) const { PYBIND11_OVERRIDE_PURE( const gridfire::reaction::ReactionSet&, gridfire::engine::DynamicEngine, - getNetworkReactions - ); -} - -void PyDynamicEngine::setNetworkReactions(const gridfire::reaction::ReactionSet& reactions) { - PYBIND11_OVERRIDE_PURE( - void, - gridfire::engine::DynamicEngine, - setNetworkReactions, - reactions + getNetworkReactions, + ctx ); } std::expected, gridfire::engine::EngineStatus> PyDynamicEngine::getSpeciesTimescales( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -197,6 +164,7 @@ std::expected, gridfire::en PYBIND11_TYPE(std::expected, gridfire::engine::EngineStatus>), gridfire::engine::DynamicEngine, getSpeciesTimescales, + ctx, comp, T9, rho @@ -204,6 +172,7 @@ std::expected, gridfire::en } std::expected, gridfire::engine::EngineStatus> PyDynamicEngine::getSpeciesDestructionTimescales( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho @@ -212,80 +181,71 @@ std::expected, gridfire::en PYBIND11_TYPE(std::expected, gridfire::engine::EngineStatus>), gridfire::engine::DynamicEngine, getSpeciesDestructionTimescales, - comp, T9, rho + ctx, comp, T9, rho ); } -fourdst::composition::Composition PyDynamicEngine::update(const gridfire::NetIn &netIn) { +fourdst::composition::Composition PyDynamicEngine::project( + gridfire::engine::scratch::StateBlob& ctx, + const gridfire::NetIn &netIn +) const { PYBIND11_OVERRIDE_PURE( fourdst::composition::Composition, gridfire::engine::DynamicEngine, - update, + project, + ctx, netIn ); } -bool PyDynamicEngine::isStale(const gridfire::NetIn &netIn) { - PYBIND11_OVERRIDE_PURE( - bool, - gridfire::engine::DynamicEngine, - isStale, - netIn - ); -} - -void PyDynamicEngine::setScreeningModel(gridfire::screening::ScreeningType model) { - PYBIND11_OVERRIDE_PURE( - void, - gridfire::engine::DynamicEngine, - setScreeningModel, - model - ); -} - -gridfire::screening::ScreeningType PyDynamicEngine::getScreeningModel() const { +gridfire::screening::ScreeningType PyDynamicEngine::getScreeningModel( + gridfire::engine::scratch::StateBlob& ctx +) const { PYBIND11_OVERRIDE_PURE( gridfire::screening::ScreeningType, gridfire::engine::DynamicEngine, - getScreeningModel + getScreeningModel, + ctx ); } -size_t PyDynamicEngine::getSpeciesIndex(const fourdst::atomic::Species &species) const { +size_t PyDynamicEngine::getSpeciesIndex( + gridfire::engine::scratch::StateBlob& ctx, + const fourdst::atomic::Species &species +) const { PYBIND11_OVERRIDE_PURE( int, gridfire::engine::DynamicEngine, getSpeciesIndex, + ctx, species ); } -std::vector PyDynamicEngine::mapNetInToMolarAbundanceVector(const gridfire::NetIn &netIn) const { - PYBIND11_OVERRIDE_PURE( - std::vector, - gridfire::engine::DynamicEngine, - mapNetInToMolarAbundanceVector, - netIn - ); -} - -gridfire::engine::PrimingReport PyDynamicEngine::primeEngine(const gridfire::NetIn &netIn) { +gridfire::engine::PrimingReport PyDynamicEngine::primeEngine( + gridfire::engine::scratch::StateBlob& ctx, + const gridfire::NetIn &netIn +) const { PYBIND11_OVERRIDE_PURE( gridfire::engine::PrimingReport, gridfire::engine::DynamicEngine, primeEngine, + ctx, netIn ); } gridfire::engine::EnergyDerivatives PyDynamicEngine::calculateEpsDerivatives( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, - const double rho) const { + const double rho +) const { PYBIND11_OVERRIDE_PURE( gridfire::engine::EnergyDerivatives, gridfire::engine::DynamicEngine, calculateEpsDerivatives, + ctx, comp, T9, rho @@ -293,6 +253,7 @@ gridfire::engine::EnergyDerivatives PyDynamicEngine::calculateEpsDerivatives( } fourdst::composition::Composition PyDynamicEngine::collectComposition( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, const double T9, const double rho @@ -301,21 +262,37 @@ fourdst::composition::Composition PyDynamicEngine::collectComposition( fourdst::composition::Composition, gridfire::engine::DynamicEngine, collectComposition, + ctx, comp, T9, rho ); } -gridfire::engine::SpeciesStatus PyDynamicEngine::getSpeciesStatus(const fourdst::atomic::Species &species) const { +gridfire::engine::SpeciesStatus PyDynamicEngine::getSpeciesStatus( + gridfire::engine::scratch::StateBlob& ctx, + const fourdst::atomic::Species &species +) const { PYBIND11_OVERRIDE_PURE( gridfire::engine::SpeciesStatus, gridfire::engine::DynamicEngine, getSpeciesStatus, + ctx, species ); } +std::optional> PyDynamicEngine::getMostRecentRHSCalculation( + gridfire::engine::scratch::StateBlob &ctx +) const { + PYBIND11_OVERRIDE_PURE( + PYBIND11_TYPE(std::optional>), + gridfire::engine::DynamicEngine, + getMostRecentRHSCalculation, + ctx + ); +} + const gridfire::engine::Engine& PyEngineView::getBaseEngine() const { PYBIND11_OVERRIDE_PURE( const gridfire::engine::Engine&, diff --git a/src/python/engine/trampoline/py_engine.h b/src/python/engine/trampoline/py_engine.h index 3eaaf3ff..6c0cf8cf 100644 --- a/src/python/engine/trampoline/py_engine.h +++ b/src/python/engine/trampoline/py_engine.h @@ -10,12 +10,16 @@ class PyEngine final : public gridfire::engine::Engine { public: - const std::vector& getNetworkSpecies() const override; + const std::vector& getNetworkSpecies( + gridfire::engine::scratch::StateBlob& ctx + ) const override; std::expected, gridfire::engine::EngineStatus> calculateRHSAndEnergy( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const override; private: mutable std::vector m_species_cache; @@ -23,21 +27,27 @@ private: class PyDynamicEngine final : public gridfire::engine::DynamicEngine { public: - const std::vector& getNetworkSpecies() const override; + const std::vector& getNetworkSpecies( + gridfire::engine::scratch::StateBlob& ctx + ) const override; std::expected, gridfire::engine::EngineStatus> calculateRHSAndEnergy( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, - double rho + double rho, + bool trust ) const override; gridfire::engine::NetworkJacobian generateJacobianMatrix( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract& comp, double T9, double rho ) const override; gridfire::engine::NetworkJacobian generateJacobianMatrix( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho, @@ -45,96 +55,81 @@ public: ) const override; gridfire::engine::NetworkJacobian generateJacobianMatrix( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract& comp, double T9, double rho, const gridfire::engine::SparsityPattern &sparsityPattern ) const override; - void generateStoichiometryMatrix() override; - - int getStoichiometryMatrixEntry( - const fourdst::atomic::Species& species, - const gridfire::reaction::Reaction& reaction - ) const override; - double calculateMolarReactionFlow( + gridfire::engine::scratch::StateBlob& ctx, const gridfire::reaction::Reaction &reaction, const fourdst::composition::CompositionAbstract &comp, double T9, double rho ) const override; - const gridfire::reaction::ReactionSet& getNetworkReactions() const override; - - void setNetworkReactions( - const gridfire::reaction::ReactionSet& reactions - ) override; + const gridfire::reaction::ReactionSet& getNetworkReactions( + gridfire::engine::scratch::StateBlob& ctx + ) const override; std::expected, gridfire::engine::EngineStatus> getSpeciesTimescales( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho ) const override; std::expected, gridfire::engine::EngineStatus> getSpeciesDestructionTimescales( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho ) const override; - fourdst::composition::Composition update( + fourdst::composition::Composition project( + gridfire::engine::scratch::StateBlob& ctx, const gridfire::NetIn &netIn - ) override; + ) const override; - bool isStale( - const gridfire::NetIn &netIn - ) override; - - void setScreeningModel( - gridfire::screening::ScreeningType model - ) override; - - gridfire::screening::ScreeningType getScreeningModel() const override; + gridfire::screening::ScreeningType getScreeningModel( + gridfire::engine::scratch::StateBlob& ctx + ) const override; size_t getSpeciesIndex( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::atomic::Species &species ) const override; - std::vector mapNetInToMolarAbundanceVector( + gridfire::engine::PrimingReport primeEngine( + gridfire::engine::scratch::StateBlob& ctx, const gridfire::NetIn &netIn ) const override; - gridfire::engine::PrimingReport primeEngine( - const gridfire::NetIn &netIn - ) override; - - gridfire::engine::BuildDepthType getDepth() const override { - throw std::logic_error("Network depth not supported by this engine."); - } - void rebuild( - const fourdst::composition::CompositionAbstract &comp, - gridfire::engine::BuildDepthType depth - ) override { - throw std::logic_error("Setting network depth not supported by this engine."); - } - [[nodiscard]] gridfire::engine::EnergyDerivatives calculateEpsDerivatives( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho ) const override; fourdst::composition::Composition collectComposition( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::composition::CompositionAbstract &comp, double T9, double rho ) const override; gridfire::engine::SpeciesStatus getSpeciesStatus( + gridfire::engine::scratch::StateBlob& ctx, const fourdst::atomic::Species &species ) const override; + std::optional> getMostRecentRHSCalculation( + gridfire::engine::scratch::StateBlob &ctx + ) const override; + private: mutable std::vector m_species_cache; }; diff --git a/src/python/exceptions/bindings.cpp b/src/python/exceptions/bindings.cpp index 14110dce..9575b1b3 100644 --- a/src/python/exceptions/bindings.cpp +++ b/src/python/exceptions/bindings.cpp @@ -2,6 +2,8 @@ #include "bindings.h" +#include "gridfire/exceptions/error_scratchpad.h" + namespace py = pybind11; #include "gridfire/exceptions/exceptions.h" @@ -44,4 +46,6 @@ void register_exception_bindings(const py::module &m) { py::register_exception(m, "CVODESolverFailureError", m.attr("SUNDIALSError")); py::register_exception(m, "KINSolSolverFailureError", m.attr("SUNDIALSError")); + py::register_exception(m, "ScratchPadError", m.attr("GridFireError")); + } diff --git a/src/python/exceptions/meson.build b/src/python/exceptions/meson.build deleted file mode 100644 index e644dce6..00000000 --- a/src/python/exceptions/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_exceptions', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/gridfire/__init__.py b/src/python/gridfire/__init__.py index 65d6e5e5..b0d38784 100644 --- a/src/python/gridfire/__init__.py +++ b/src/python/gridfire/__init__.py @@ -1,7 +1,7 @@ from ._gridfire import * import sys -from ._gridfire import type, utils, engine, solver, exceptions, partition, reaction, screening, io, policy +from ._gridfire import type, utils, engine, solver, exceptions, partition, reaction, screening, io, policy, config sys.modules['gridfire.type'] = type sys.modules['gridfire.utils'] = utils @@ -13,8 +13,61 @@ sys.modules['gridfire.reaction'] = reaction sys.modules['gridfire.screening'] = screening sys.modules['gridfire.policy'] = policy sys.modules['gridfire.io'] = io +sys.modules['gridfire.config'] = config -__all__ = ['type', 'utils', 'engine', 'solver', 'exceptions', 'partition', 'reaction', 'screening', 'io', 'policy'] +__all__ = ['type', 'utils', 'engine', 'solver', 'exceptions', 'partition', 'reaction', 'screening', 'io', 'policy', 'config'] -__version__ = "v0.7.4_rc2" +import importlib.metadata +try: + _meta = importlib.metadata.metadata('gridfire') + __version__ = _meta['Version'] + __author__ = _meta['Author'] + __license__ = _meta['License'] + __email__ = _meta['Author-email'] + __url__ = _meta['Home-page'] or _meta.get('Project-URL', '').split(',')[0].split(' ')[-1].strip() + __description__ = _meta['Summary'] +except importlib.metadata.PackageNotFoundError : + __version__ = 'unknown - Package not installed' + __author__ = 'Emily M. Boudreaux' + __license__ = 'GNU General Public License v3.0' + __email__ = 'emily.boudreaux@dartmouth.edu' + __url__ = 'https://github.com/4D-STAR/GridFire' + +def gf_metadata(): + return { + 'version': __version__, + 'author': __author__, + 'license': __license__, + 'email': __email__, + 'url': __url__, + 'description': __description__ + } + +def gf_version(): + return __version__ + +def gf_author(): + return __author__ + +def gf_license(): + return __license__ + +def gf_email(): + return __email__ + +def gf_url(): + return __url__ + +def gf_description(): + return __description__ + +def gf_collaboration(): + return "4D-STAR Collaboration" + +def gf_credits(): + return [ + "Emily M. Boudreaux - Lead Developer", + "Aaron Dotter - Co-Developer", + "4D-STAR Collaboration - Contributors" + ] \ No newline at end of file diff --git a/src/python/io/meson.build b/src/python/io/meson.build deleted file mode 100644 index 998cd712..00000000 --- a/src/python/io/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_io', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/io/trampoline/meson.build b/src/python/io/trampoline/meson.build deleted file mode 100644 index 8fc8552c..00000000 --- a/src/python/io/trampoline/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -gf_io_trampoline_sources = files('py_io.cpp') - -gf_io_trapoline_dependencies = [ - gridfire_dep, - pybind11_dep, - python3_dep, -] - -gf_io_trampoline_lib = static_library( - 'io_trampolines', - gf_io_trampoline_sources, - include_directories: include_directories('.'), - dependencies: gf_io_trapoline_dependencies, - install: false, -) - -gr_io_trampoline_dep = declare_dependency( - link_with: gf_io_trampoline_lib, - include_directories: ('.'), - dependencies: gf_io_trapoline_dependencies, -) diff --git a/src/python/meson.build b/src/python/meson.build deleted file mode 100644 index c38cfbed..00000000 --- a/src/python/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -subdir('types') -subdir('utils') -subdir('exceptions') -subdir('io') -subdir('partition') -subdir('reaction') -subdir('screening') -subdir('engine') -subdir('policy') -subdir('solver') diff --git a/src/python/partition/meson.build b/src/python/partition/meson.build deleted file mode 100644 index 2dc31349..00000000 --- a/src/python/partition/meson.build +++ /dev/null @@ -1,19 +0,0 @@ -subdir('trampoline') - -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_partition', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/partition/trampoline/meson.build b/src/python/partition/trampoline/meson.build deleted file mode 100644 index 1115b683..00000000 --- a/src/python/partition/trampoline/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -gf_partition_trampoline_sources = files('py_partition.cpp') - -gf_partition_trapoline_dependencies = [ - gridfire_dep, - pybind11_dep, - python3_dep, -] - -gf_partition_trampoline_lib = static_library( - 'partition_trampolines', - gf_partition_trampoline_sources, - include_directories: include_directories('.'), - dependencies: gf_partition_trapoline_dependencies, - install: false, -) - -gr_partition_trampoline_dep = declare_dependency( - link_with: gf_partition_trampoline_lib, - include_directories: ('.'), - dependencies: gf_partition_trapoline_dependencies, -) diff --git a/src/python/policy/bindings.cpp b/src/python/policy/bindings.cpp index 175936a9..d82897f6 100644 --- a/src/python/policy/bindings.cpp +++ b/src/python/policy/bindings.cpp @@ -8,7 +8,6 @@ #include "gridfire/policy/policy.h" -PYBIND11_DECLARE_HOLDER_TYPE(T, std::unique_ptr, true) // Declare unique_ptr as a holder type for pybind11 namespace py = pybind11; @@ -103,9 +102,30 @@ namespace { .def( "construct", &T::construct, - py::return_value_policy::reference, "Construct the network according to the policy." + ) + .def( + "get_engine_stack", + [](const T &self) { + const auto& stack = self.get_engine_stack(); + std::vector engine_ptrs; + engine_ptrs.reserve(stack.size()); + for (const auto& engine_uptr : stack) { + engine_ptrs.push_back(engine_uptr.get()); + } + + return engine_ptrs; + }, + py::return_value_policy::reference_internal + ) + .def( + "get_stack_scratch_blob", + &T::get_stack_scratch_blob + ) + .def( + "get_partition_function", + &T::get_partition_function ); } } @@ -215,6 +235,26 @@ void register_network_policy_bindings(pybind11::module &m) { .value("INITIALIZED_VERIFIED", gridfire::policy::NetworkPolicyStatus::INITIALIZED_VERIFIED) .export_values(); + m.def("network_policy_status_to_string", + &gridfire::policy::NetworkPolicyStatusToString, + py::arg("status"), + "Convert a NetworkPolicyStatus enum value to its string representation." + ); + + py::class_(m, "ConstructionResults") + .def_property_readonly("engine", + [](const gridfire::policy::ConstructionResults &self) -> const gridfire::engine::DynamicEngine& { + return self.engine; + }, + py::return_value_policy::reference + ) + .def_property_readonly("scratch_blob", + [](const gridfire::policy::ConstructionResults &self) { + return self.scratch_blob.get(); + }, + py::return_value_policy::reference_internal + ); + py::class_ py_networkPolicy(m, "NetworkPolicy"); py::class_ py_mainSeqPolicy(m, "MainSequencePolicy"); py_mainSeqPolicy.def( diff --git a/src/python/policy/meson.build b/src/python/policy/meson.build deleted file mode 100644 index 9913850e..00000000 --- a/src/python/policy/meson.build +++ /dev/null @@ -1,19 +0,0 @@ -# Define the library -subdir('trampoline') - -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_policy', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/policy/trampoline/meson.build b/src/python/policy/trampoline/meson.build deleted file mode 100644 index e0cf7622..00000000 --- a/src/python/policy/trampoline/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -gf_policy_trampoline_sources = files('py_policy.cpp') - -gf_policy_trapoline_dependencies = [ - gridfire_dep, - pybind11_dep, - python3_dep, -] - -gf_policy_trampoline_lib = static_library( - 'policy_trampolines', - gf_policy_trampoline_sources, - include_directories: include_directories('.'), - dependencies: gf_policy_trapoline_dependencies, - install: false, -) - -gr_policy_trampoline_dep = declare_dependency( - link_with: gf_policy_trampoline_lib, - include_directories: ('.'), - dependencies: gf_policy_trapoline_dependencies, -) diff --git a/src/python/policy/trampoline/py_policy.cpp b/src/python/policy/trampoline/py_policy.cpp index 600f4186..2c934e70 100644 --- a/src/python/policy/trampoline/py_policy.cpp +++ b/src/python/policy/trampoline/py_policy.cpp @@ -39,9 +39,9 @@ const gridfire::reaction::ReactionSet& PyNetworkPolicy::get_seed_reactions() con ); } -gridfire::engine::DynamicEngine& PyNetworkPolicy::construct() { +gridfire::policy::ConstructionResults PyNetworkPolicy::construct() { PYBIND11_OVERRIDE_PURE( - gridfire::engine::DynamicEngine&, + gridfire::policy::ConstructionResults, gridfire::policy::NetworkPolicy, construct ); @@ -79,6 +79,14 @@ const std::unique_ptr& PyNetworkPolicy:: ); } +std::unique_ptr PyNetworkPolicy::get_stack_scratch_blob() const { + PYBIND11_OVERRIDE_PURE( + std::unique_ptr, + gridfire::policy::NetworkPolicy, + get_stack_scratch_blob + ); +} + const gridfire::reaction::ReactionSet &PyReactionChainPolicy::get_reactions() const { PYBIND11_OVERRIDE_PURE( const gridfire::reaction::ReactionSet &, diff --git a/src/python/policy/trampoline/py_policy.h b/src/python/policy/trampoline/py_policy.h index 91c6692b..43b67ea4 100644 --- a/src/python/policy/trampoline/py_policy.h +++ b/src/python/policy/trampoline/py_policy.h @@ -13,7 +13,7 @@ public: [[nodiscard]] const gridfire::reaction::ReactionSet& get_seed_reactions() const override; - [[nodiscard]] gridfire::engine::DynamicEngine& construct() override; + [[nodiscard]] gridfire::policy::ConstructionResults construct() override; [[nodiscard]] gridfire::policy::NetworkPolicyStatus get_status() const override; @@ -22,6 +22,8 @@ public: [[nodiscard]] std::vector get_engine_types_stack() const override; [[nodiscard]] const std::unique_ptr& get_partition_function() const override; + + [[nodiscard]] std::unique_ptr get_stack_scratch_blob() const override; }; class PyReactionChainPolicy final : public gridfire::policy::ReactionChainPolicy { diff --git a/src/python/reaction/meson.build b/src/python/reaction/meson.build deleted file mode 100644 index ca4dc8ee..00000000 --- a/src/python/reaction/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_reaction', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/screening/meson.build b/src/python/screening/meson.build deleted file mode 100644 index 99f7dd89..00000000 --- a/src/python/screening/meson.build +++ /dev/null @@ -1,19 +0,0 @@ -subdir('trampoline') - -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_screening', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/screening/trampoline/meson.build b/src/python/screening/trampoline/meson.build deleted file mode 100644 index 45552332..00000000 --- a/src/python/screening/trampoline/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -gf_screening_trampoline_sources = files('py_screening.cpp') - -gf_screening_trapoline_dependencies = [ - gridfire_dep, - pybind11_dep, - python3_dep, -] - -gf_screening_trampoline_lib = static_library( - 'screening_trampolines', - gf_screening_trampoline_sources, - include_directories: include_directories('.'), - dependencies: gf_screening_trapoline_dependencies, - install: false, -) - -gr_screening_trampoline_dep = declare_dependency( - link_with: gf_screening_trampoline_lib, - include_directories: ('.'), - dependencies: gf_screening_trapoline_dependencies, -) diff --git a/src/python/solver/bindings.cpp b/src/python/solver/bindings.cpp index dd4e85f3..ec706ecd 100644 --- a/src/python/solver/bindings.cpp +++ b/src/python/solver/bindings.cpp @@ -7,125 +7,226 @@ #include "bindings.h" -#include "gridfire/solver/strategies/CVODE_solver_strategy.h" +#include "gridfire/solver/strategies/PointSolver.h" +#include "gridfire/engine/scratchpads/blob.h" #include "trampoline/py_solver.h" namespace py = pybind11; void register_solver_bindings(const py::module &m) { - auto py_solver_context_base = py::class_(m, "SolverContextBase"); - - auto py_cvode_timestep_context = py::class_(m, "CVODETimestepContext"); - py_cvode_timestep_context.def_readonly("t", &gridfire::solver::CVODESolverStrategy::TimestepContext::t); + auto py_cvode_timestep_context = py::class_(m, "PointSolverTimestepContext"); + py_cvode_timestep_context.def_readonly("t", &gridfire::solver::PointSolverTimestepContext::t); py_cvode_timestep_context.def_property_readonly( "state", - [](const gridfire::solver::CVODESolverStrategy::TimestepContext& self) -> std::vector { + [](const gridfire::solver::PointSolverTimestepContext& self) -> std::vector { const sunrealtype* nvec_data = N_VGetArrayPointer(self.state); const sunindextype length = N_VGetLength(self.state); - return std::vector(nvec_data, nvec_data + length); + return {nvec_data, nvec_data + length}; } ); - py_cvode_timestep_context.def_readonly("dt", &gridfire::solver::CVODESolverStrategy::TimestepContext::dt); - py_cvode_timestep_context.def_readonly("last_step_time", &gridfire::solver::CVODESolverStrategy::TimestepContext::last_step_time); - py_cvode_timestep_context.def_readonly("T9", &gridfire::solver::CVODESolverStrategy::TimestepContext::T9); - py_cvode_timestep_context.def_readonly("rho", &gridfire::solver::CVODESolverStrategy::TimestepContext::rho); - py_cvode_timestep_context.def_readonly("num_steps", &gridfire::solver::CVODESolverStrategy::TimestepContext::num_steps); - py_cvode_timestep_context.def_readonly("currentConvergenceFailures", &gridfire::solver::CVODESolverStrategy::TimestepContext::currentConvergenceFailures); - py_cvode_timestep_context.def_readonly("currentNonlinearIterations", &gridfire::solver::CVODESolverStrategy::TimestepContext::currentNonlinearIterations); + py_cvode_timestep_context.def_readonly("dt", &gridfire::solver::PointSolverTimestepContext::dt); + py_cvode_timestep_context.def_readonly("last_step_time", &gridfire::solver::PointSolverTimestepContext::last_step_time); + py_cvode_timestep_context.def_readonly("T9", &gridfire::solver::PointSolverTimestepContext::T9); + py_cvode_timestep_context.def_readonly("rho", &gridfire::solver::PointSolverTimestepContext::rho); + py_cvode_timestep_context.def_readonly("num_steps", &gridfire::solver::PointSolverTimestepContext::num_steps); + py_cvode_timestep_context.def_readonly("currentConvergenceFailures", &gridfire::solver::PointSolverTimestepContext::currentConvergenceFailures); + py_cvode_timestep_context.def_readonly("currentNonlinearIterations", &gridfire::solver::PointSolverTimestepContext::currentNonlinearIterations); py_cvode_timestep_context.def_property_readonly( "engine", - [](const gridfire::solver::CVODESolverStrategy::TimestepContext& self) -> const gridfire::engine::DynamicEngine& { + [](const gridfire::solver::PointSolverTimestepContext& self) -> const gridfire::engine::DynamicEngine& { return self.engine; } ); py_cvode_timestep_context.def_property_readonly( "networkSpecies", - [](const gridfire::solver::CVODESolverStrategy::TimestepContext& self) -> std::vector { + [](const gridfire::solver::PointSolverTimestepContext& self) -> std::vector { return self.networkSpecies; } ); + py_cvode_timestep_context.def_property_readonly( + "state_ctx", + [](const gridfire::solver::PointSolverTimestepContext& self) { + return &(self.state_ctx); + }, + py::return_value_policy::reference_internal + ); - auto py_dynamic_network_solver_strategy = py::class_(m, "DynamicNetworkSolverStrategy"); - py_dynamic_network_solver_strategy.def( + + auto py_solver_context_base = py::class_(m, "SolverContextBase"); + auto py_point_solver_context = py::class_(m, "PointSolverContext"); + + py_point_solver_context + .def_readonly( + "sun_ctx", &gridfire::solver::PointSolverContext::sun_ctx + ) + .def_readonly( + "cvode_mem", &gridfire::solver::PointSolverContext::cvode_mem + ) + .def_readonly( + "Y", &gridfire::solver::PointSolverContext::Y + ) + .def_readonly( + "YErr", &gridfire::solver::PointSolverContext::YErr + ) + .def_readonly( + "J", &gridfire::solver::PointSolverContext::J + ) + .def_readonly( + "LS", &gridfire::solver::PointSolverContext::LS + ) + .def_property_readonly( + "engine_ctx", + [](const gridfire::solver::PointSolverContext& self) -> gridfire::engine::scratch::StateBlob& { + return *(self.engine_ctx); + }, + py::return_value_policy::reference + ) + .def_readonly( + "num_steps", &gridfire::solver::PointSolverContext::num_steps + ) + .def_property( + "abs_tol", + [](const gridfire::solver::PointSolverContext& self) -> double { + return self.abs_tol.value(); + }, + [](gridfire::solver::PointSolverContext& self, double abs_tol) -> void { + self.abs_tol = abs_tol; + } + ) + .def_property( + "rel_tol", + [](const gridfire::solver::PointSolverContext& self) -> double { + return self.rel_tol.value(); + }, + [](gridfire::solver::PointSolverContext& self, double rel_tol) -> void { + self.rel_tol = rel_tol; + } + ) + .def_property( + "stdout_logging", + [](const gridfire::solver::PointSolverContext& self) -> bool { + return self.stdout_logging; + }, + [](gridfire::solver::PointSolverContext& self, const bool enable) -> void { + self.stdout_logging = enable; + } + ) + .def_property( + "detailed_logging", + [](const gridfire::solver::PointSolverContext& self) -> bool { + return self.detailed_step_logging; + }, + [](gridfire::solver::PointSolverContext& self, const bool enable) -> void { + self.detailed_step_logging = enable; + } + ) + .def_property( + "callback", + [](const gridfire::solver::PointSolverContext& self) -> std::optional> { + return self.callback; + }, + [](gridfire::solver::PointSolverContext& self, const std::optional>& cb) { + self.callback = cb; + } + ) + .def("reset_all", &gridfire::solver::PointSolverContext::reset_all) + .def("reset_user", &gridfire::solver::PointSolverContext::reset_user) + .def("reset_cvode", &gridfire::solver::PointSolverContext::reset_cvode) + .def("clear_context", &gridfire::solver::PointSolverContext::clear_context) + .def("init_context", &gridfire::solver::PointSolverContext::init_context) + .def("has_context", &gridfire::solver::PointSolverContext::has_context) + .def("init", &gridfire::solver::PointSolverContext::init) + .def(py::init(), py::arg("engine_ctx")); + + + + auto py_single_zone_dynamic_network_solver = py::class_(m, "SingleZoneDynamicNetworkSolver"); + py_single_zone_dynamic_network_solver.def( "evaluate", - &gridfire::solver::DynamicNetworkSolverStrategy::evaluate, + &gridfire::solver::SingleZoneDynamicNetworkSolver::evaluate, + py::arg("solver_ctx"), py::arg("netIn"), - "evaluate the dynamic engine using the dynamic engine class" + "evaluate the dynamic engine using the dynamic engine class for a single zone" + ); + auto py_multi_zone_dynamic_network_solver = py::class_(m, "MultiZoneDynamicNetworkSolver"); + py_multi_zone_dynamic_network_solver.def( + "evaluate", + &gridfire::solver::MultiZoneDynamicNetworkSolver::evaluate, + py::arg("solver_ctx"), + py::arg("netIns"), + "evaluate the dynamic engine using the dynamic engine class for multiple zones (using openmp if available)" ); + auto py_point_solver = py::class_(m, "PointSolver"); - py_dynamic_network_solver_strategy.def( - "describe_callback_context", - &gridfire::solver::DynamicNetworkSolverStrategy::describe_callback_context, - "Get a structure representing what data is in the callback context in a human readable format" - ); - - auto py_cvode_solver_strategy = py::class_(m, "CVODESolverStrategy"); - - py_cvode_solver_strategy.def( + py_point_solver.def( py::init(), py::arg("engine"), - "Initialize the CVODESolverStrategy object." + "Initialize the PointSolver object." ); - py_cvode_solver_strategy.def( + py_point_solver.def( "evaluate", - py::overload_cast(&gridfire::solver::CVODESolverStrategy::evaluate), + py::overload_cast(&gridfire::solver::PointSolver::evaluate, py::const_), + py::arg("solver_ctx"), py::arg("netIn"), py::arg("display_trigger") = false, + py::arg("force_reinitialization") = false, "evaluate the dynamic engine using the dynamic engine class" ); - py_cvode_solver_strategy.def( - "get_stdout_logging_enabled", - &gridfire::solver::CVODESolverStrategy::get_stdout_logging_enabled, - "Check if solver logging to standard output is enabled." + auto py_grid_solver_context = py::class_(m, "GridSolverContext"); + py_grid_solver_context.def(py::init(), py::arg("ctx_template")); + py_grid_solver_context.def("init", &gridfire::solver::GridSolverContext::init); + py_grid_solver_context.def("reset", &gridfire::solver::GridSolverContext::reset); + py_grid_solver_context.def("set_callback", py::overload_cast&>(&gridfire::solver::GridSolverContext::set_callback) , py::arg("callback")); + py_grid_solver_context.def("set_callback", py::overload_cast&, size_t>(&gridfire::solver::GridSolverContext::set_callback) , py::arg("callback"), py::arg("zone_idx")); + py_grid_solver_context.def("clear_callback", py::overload_cast<>(&gridfire::solver::GridSolverContext::clear_callback)); + py_grid_solver_context.def("clear_callback", py::overload_cast(&gridfire::solver::GridSolverContext::clear_callback), py::arg("zone_idx")); + py_grid_solver_context.def_property( + "stdout_logging", + [](const gridfire::solver::GridSolverContext& self) -> bool { + return self.zone_stdout_logging; + }, + [](gridfire::solver::GridSolverContext& self, const bool enable) -> void { + self.zone_stdout_logging = enable; + } + ) + .def_property( + "detailed_logging", + [](const gridfire::solver::GridSolverContext& self) -> bool { + return self.zone_detailed_logging; + }, + [](gridfire::solver::GridSolverContext& self, const bool enable) -> void { + self.zone_detailed_logging = enable; + } + ) + .def_property( + "zone_completion_logging", + [](const gridfire::solver::GridSolverContext& self) -> bool { + return self.zone_completion_logging; + }, + [](gridfire::solver::GridSolverContext& self, const bool enable) -> void { + self.zone_completion_logging = enable; + } ); - py_cvode_solver_strategy.def( - "set_stdout_logging_enabled", - &gridfire::solver::CVODESolverStrategy::set_stdout_logging_enabled, - py::arg("logging_enabled"), - "Enable logging to standard output." + auto py_grid_solver = py::class_(m, "GridSolver"); + py_grid_solver.def( + py::init(), + py::arg("engine"), + py::arg("solver"), + "Initialize the GridSolver object." ); - py_cvode_solver_strategy.def( - "set_absTol", - &gridfire::solver::CVODESolverStrategy::set_absTol, - py::arg("absTol"), - "Set the absolute tolerance for the CVODE solver." + py_grid_solver.def( + "evaluate", + &gridfire::solver::GridSolver::evaluate, + py::arg("solver_ctx"), + py::arg("netIns"), + "evaluate the dynamic engine using the dynamic engine class" ); - py_cvode_solver_strategy.def( - "set_relTol", - &gridfire::solver::CVODESolverStrategy::set_relTol, - py::arg("relTol"), - "Set the relative tolerance for the CVODE solver." - ); - - py_cvode_solver_strategy.def( - "get_absTol", - &gridfire::solver::CVODESolverStrategy::get_absTol, - "Get the absolute tolerance for the CVODE solver." - ); - - py_cvode_solver_strategy.def( - "get_relTol", - &gridfire::solver::CVODESolverStrategy::get_relTol, - "Get the relative tolerance for the CVODE solver." - ); - - py_cvode_solver_strategy.def( - "set_callback", - []( - gridfire::solver::CVODESolverStrategy& self, - std::function cb - ) { - self.set_callback(std::any(cb)); - }, - py::arg("cb"), - "Set a callback function which will run at the end of every successful timestep" - ); } diff --git a/src/python/solver/meson.build b/src/python/solver/meson.build deleted file mode 100644 index e21ee519..00000000 --- a/src/python/solver/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_solver', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/solver/trampoline/meson.build b/src/python/solver/trampoline/meson.build deleted file mode 100644 index b252dba6..00000000 --- a/src/python/solver/trampoline/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -gf_solver_trampoline_sources = files('py_solver.cpp') - -gf_solver_trapoline_dependencies = [ - gridfire_dep, - pybind11_dep, - python3_dep, -] - -gf_solver_trampoline_lib = static_library( - 'solver_trampolines', - gf_solver_trampoline_sources, - include_directories: include_directories('.'), - dependencies: gf_solver_trapoline_dependencies, - install: false, -) - -gr_solver_trampoline_dep = declare_dependency( - link_with: gf_solver_trampoline_lib, - include_directories: ('.'), - dependencies: gf_solver_trapoline_dependencies, -) diff --git a/src/python/solver/trampoline/py_solver.cpp b/src/python/solver/trampoline/py_solver.cpp index 2b735571..abdc5622 100644 --- a/src/python/solver/trampoline/py_solver.cpp +++ b/src/python/solver/trampoline/py_solver.cpp @@ -13,38 +13,63 @@ namespace py = pybind11; -gridfire::NetOut PyDynamicNetworkSolverStrategy::evaluate(const gridfire::NetIn &netIn) { +gridfire::NetOut PySingleZoneDynamicNetworkSolver::evaluate( + gridfire::solver::SolverContextBase &solver_ctx, + const gridfire::NetIn &netIn +) const { PYBIND11_OVERRIDE_PURE( - gridfire::NetOut, // Return type - gridfire::solver::DynamicNetworkSolverStrategy, // Base class - evaluate, // Method name - netIn // Arguments + gridfire::NetOut, + gridfire::solver::SingleZoneDynamicNetworkSolver, + evaluate, + solver_ctx, + netIn ); } -void PyDynamicNetworkSolverStrategy::set_callback(const std::any &callback) { +std::vector PyMultiZoneDynamicNetworkSolver::evaluate( + gridfire::solver::SolverContextBase &solver_ctx, + const std::vector &netIns +) const { PYBIND11_OVERRIDE_PURE( - void, - gridfire::solver::DynamicNetworkSolverStrategy, // Base class - set_callback, // Method name - callback // Arguments + std::vector, + gridfire::solver::MultiZoneDynamicNetworkSolver, + evaluate, + solver_ctx, + netIns ); } -std::vector> PyDynamicNetworkSolverStrategy::describe_callback_context() const { - using DescriptionVector = std::vector>; +std::vector> PyTimestepContextBase::describe() const { + using ReturnType = std::vector>; PYBIND11_OVERRIDE_PURE( - DescriptionVector, // Return type - gridfire::solver::DynamicNetworkSolverStrategy, // Base class - describe_callback_context // Method name - ); -} - -std::vector> PySolverContextBase::describe() const { - using DescriptionVector = std::vector>; - PYBIND11_OVERRIDE_PURE( - DescriptionVector, - gridfire::solver::SolverContextBase, + ReturnType, + gridfire::solver::TimestepContextBase, describe ); } + +void PySolverContextBase::init() { + PYBIND11_OVERRIDE_PURE( + void, + gridfire::solver::SolverContextBase, + init + ); +} + +void PySolverContextBase::set_stdout_logging(bool enable) { + PYBIND11_OVERRIDE_PURE( + void, + gridfire::solver::SolverContextBase, + set_stdout_logging, + enable + ); +} + +void PySolverContextBase::set_detailed_logging(bool enable) { + PYBIND11_OVERRIDE_PURE( + void, + gridfire::solver::SolverContextBase, + set_detailed_logging, + enable + ); +} \ No newline at end of file diff --git a/src/python/solver/trampoline/py_solver.h b/src/python/solver/trampoline/py_solver.h index ef0713de..98a17414 100644 --- a/src/python/solver/trampoline/py_solver.h +++ b/src/python/solver/trampoline/py_solver.h @@ -7,14 +7,37 @@ #include #include -class PyDynamicNetworkSolverStrategy final : public gridfire::solver::DynamicNetworkSolverStrategy { - explicit PyDynamicNetworkSolverStrategy(gridfire::engine::DynamicEngine &engine) : gridfire::solver::DynamicNetworkSolverStrategy(engine) {} - gridfire::NetOut evaluate(const gridfire::NetIn &netIn) override; - void set_callback(const std::any &callback) override; - [[nodiscard]] std::vector> describe_callback_context() const override; +class PySingleZoneDynamicNetworkSolver final : public gridfire::solver::SingleZoneDynamicNetworkSolver { +public: + explicit PySingleZoneDynamicNetworkSolver(const gridfire::engine::DynamicEngine &engine) : gridfire::solver::SingleZoneDynamicNetworkSolver(engine) {} + + gridfire::NetOut evaluate( + gridfire::solver::SolverContextBase &solver_ctx, + const gridfire::NetIn &netIn + ) const override; +}; + +class PyMultiZoneDynamicNetworkSolver final : public gridfire::solver::MultiZoneDynamicNetworkSolver { +public: + explicit PyMultiZoneDynamicNetworkSolver( + const gridfire::engine::DynamicEngine &engine, + const gridfire::solver::SingleZoneDynamicNetworkSolver &local_solver + ) : gridfire::solver::MultiZoneDynamicNetworkSolver(engine, local_solver) {} + + std::vector evaluate( + gridfire::solver::SolverContextBase &solver_ctx, + const std::vector &netIns + ) const override; +}; + +class PyTimestepContextBase final : public gridfire::solver::TimestepContextBase { +public: + [[nodiscard]] std::vector> describe() const override; }; class PySolverContextBase final : public gridfire::solver::SolverContextBase { public: - [[nodiscard]] std::vector> describe() const override; -}; \ No newline at end of file + void init() override; + void set_stdout_logging(bool enable) override; + void set_detailed_logging(bool enable) override; +}; diff --git a/src/python/types/meson.build b/src/python/types/meson.build deleted file mode 100644 index d76e8b6e..00000000 --- a/src/python/types/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_types', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/src/python/utils/bindings.cpp b/src/python/utils/bindings.cpp index fabcf2dd..a7a081cb 100644 --- a/src/python/utils/bindings.cpp +++ b/src/python/utils/bindings.cpp @@ -12,6 +12,7 @@ namespace py = pybind11; void register_utils_bindings(py::module &m) { m.def("formatNuclearTimescaleLogString", &gridfire::utils::formatNuclearTimescaleLogString, + py::arg("ctx"), py::arg("engine"), py::arg("Y"), py::arg("T9"), diff --git a/src/python/utils/meson.build b/src/python/utils/meson.build deleted file mode 100644 index 5c97a3a5..00000000 --- a/src/python/utils/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Define the library -bindings_sources = files('bindings.cpp') -bindings_headers = files('bindings.h') - -dependencies = [ - gridfire_dep, - python3_dep, - pybind11_dep, -] - -shared_module('py_gf_utils', - bindings_sources, - cpp_args: ['-fvisibility=default'], - install : true, - dependencies: dependencies, - include_directories: include_directories('.') -) diff --git a/stubs/gridfire/__init__.pyi b/stubs/gridfire/__init__.pyi index e15f3ac9..a5db9463 100644 --- a/stubs/gridfire/__init__.pyi +++ b/stubs/gridfire/__init__.pyi @@ -1,4 +1,5 @@ from __future__ import annotations +from gridfire._gridfire import config from gridfire._gridfire import engine from gridfire._gridfire import exceptions from gridfire._gridfire import io @@ -9,7 +10,33 @@ from gridfire._gridfire import screening from gridfire._gridfire import solver from gridfire._gridfire import type from gridfire._gridfire import utils +import importlib as importlib import sys as sys from . import _gridfire -__all__: list = ['type', 'utils', 'engine', 'solver', 'exceptions', 'partition', 'reaction', 'screening', 'io', 'core', 'cli'] -__version__: str = 'v0.7.0_alpha_2025_10_25' +__all__: list = ['type', 'utils', 'engine', 'solver', 'exceptions', 'partition', 'reaction', 'screening', 'io', 'policy', 'config'] +def gf_author(): + ... +def gf_collaboration(): + ... +def gf_credits(): + ... +def gf_description(): + ... +def gf_email(): + ... +def gf_license(): + ... +def gf_metadata(): + ... +def gf_url(): + ... +def gf_version(): + ... +__author__ = None +__description__: str = 'Python interface to the GridFire nuclear network code' +__email__: str = '"Emily M. Boudreaux" , Aaron Dotter ' +__license__: str = 'GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. \n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n Preamble\n\n The GNU General Public License is a free, copyleft license for\n software and other kinds of works.\n\n The licenses for most software and other practical works are designed\n to take away your freedom to share and change the works. By contrast,\n the GNU General Public License is intended to guarantee your freedom to\n share and change all versions of a program--to make sure it remains free\n software for all its users. We, the Free Software Foundation, use the\n GNU General Public License for most of our software; it applies also to\n any other work released this way by its authors. You can apply it to\n your programs, too.\n\n When we speak of free software, we are referring to freedom, not\n price. Our General Public Licenses are designed to make sure that you\n have the freedom to distribute copies of free software (and charge for\n them if you wish), that you receive source code or can get it if you\n want it, that you can change the software or use pieces of it in new\n free programs, and that you know you can do these things.\n\n To protect your rights, we need to prevent others from denying you\n these rights or asking you to surrender the rights. Therefore, you have\n certain responsibilities if you distribute copies of the software, or if\n you modify it: responsibilities to respect the freedom of others.\n\n For example, if you distribute copies of such a program, whether\n gratis or for a fee, you must pass on to the recipients the same\n freedoms that you received. You must make sure that they, too, receive\n or can get the source code. And you must show them these terms so they\n know their rights.\n\n Developers that use the GNU GPL protect your rights with two steps:\n (1) assert copyright on the software, and (2) offer you this License\n giving you legal permission to copy, distribute and/or modify it.\n\n For the developers\' and authors\' protection, the GPL clearly explains\n that there is no warranty for this free software. For both users\' and\n authors\' sake, the GPL requires that modified versions be marked as\n changed, so that their problems will not be attributed erroneously to\n authors of previous versions.\n\n Some devices are designed to deny users access to install or run\n modified versions of the software inside them, although the manufacturer\n can do so. This is fundamentally incompatible with the aim of\n protecting users\' freedom to change the software. The systematic\n pattern of such abuse occurs in the area of products for individuals to\n use, which is precisely where it is most unacceptable. Therefore, we\n have designed this version of the GPL to prohibit the practice for those\n products. If such problems arise substantially in other domains, we\n stand ready to extend this provision to those domains in future versions\n of the GPL, as needed to protect the freedom of users.\n\n Finally, every program is threatened constantly by software patents.\n States should not allow patents to restrict development and use of\n software on general-purpose computers, but in those that do, we wish to\n avoid the special danger that patents applied to a free program could\n make it effectively proprietary. To prevent this, the GPL assures that\n patents cannot be used to render the program non-free.\n\n The precise terms and conditions for copying, distribution and\n modification follow.\n\n TERMS AND CONDITIONS\n\n 0. Definitions.\n\n "This License" refers to version 3 of the GNU General Public License.\n\n "Copyright" also means copyright-like laws that apply to other kinds of\n works, such as semiconductor masks.\n\n "The Program" refers to any copyrightable work licensed under this\n License. Each licensee is addressed as "you". "Licensees" and\n "recipients" may be individuals or organizations.\n\n To "modify" a work means to copy from or adapt all or part of the work\n in a fashion requiring copyright permission, other than the making of an\n exact copy. The resulting work is called a "modified version" of the\n earlier work or a work "based on" the earlier work.\n\n A "covered work" means either the unmodified Program or a work based\n on the Program.\n\n To "propagate" a work means to do anything with it that, without\n permission, would make you directly or secondarily liable for\n infringement under applicable copyright law, except executing it on a\n computer or modifying a private copy. Propagation includes copying,\n distribution (with or without modification), making available to the\n public, and in some countries other activities as well.\n\n To "convey" a work means any kind of propagation that enables other\n parties to make or receive copies. Mere interaction with a user through\n a computer network, with no transfer of a copy, is not conveying.\n\n An interactive user interface displays "Appropriate Legal Notices"\n to the extent that it includes a convenient and prominently visible\n feature that (1) displays an appropriate copyright notice, and (2)\n tells the user that there is no warranty for the work (except to the\n extent that warranties are provided), that licensees may convey the\n work under this License, and how to view a copy of this License. If\n the interface presents a list of user commands or options, such as a\n menu, a prominent item in the list meets this criterion.\n\n 1. Source Code.\n\n The "source code" for a work means the preferred form of the work\n for making modifications to it. "Object code" means any non-source\n form of a work.\n\n A "Standard Interface" means an interface that either is an official\n standard defined by a recognized standards body, or, in the case of\n interfaces specified for a particular programming language, one that\n is widely used among developers working in that language.\n\n The "System Libraries" of an executable work include anything, other\n than the work as a whole, that (a) is included in the normal form of\n packaging a Major Component, but which is not part of that Major\n Component, and (b) serves only to enable use of the work with that\n Major Component, or to implement a Standard Interface for which an\n implementation is available to the public in source code form. A\n "Major Component", in this context, means a major essential component\n (kernel, window system, and so on) of the specific operating system\n (if any) on which the executable work runs, or a compiler used to\n produce the work, or an object code interpreter used to run it.\n\n The "Corresponding Source" for a work in object code form means all\n the source code needed to generate, install, and (for an executable\n work) run the object code and to modify the work, including scripts to\n control those activities. However, it does not include the work\'s\n System Libraries, or general-purpose tools or generally available free\n programs which are used unmodified in performing those activities but\n which are not part of the work. For example, Corresponding Source\n includes interface definition files associated with source files for\n the work, and the source code for shared libraries and dynamically\n linked subprograms that the work is specifically designed to require,\n such as by intimate data communication or control flow between those\n subprograms and other parts of the work.\n\n The Corresponding Source need not include anything that users\n can regenerate automatically from other parts of the Corresponding\n Source.\n\n The Corresponding Source for a work in source code form is that\n same work.\n\n 2. Basic Permissions.\n\n All rights granted under this License are granted for the term of\n copyright on the Program, and are irrevocable provided the stated\n conditions are met. This License explicitly affirms your unlimited\n permission to run the unmodified Program. The output from running a\n covered work is covered by this License only if the output, given its\n content, constitutes a covered work. This License acknowledges your\n rights of fair use or other equivalent, as provided by copyright law.\n\n You may make, run and propagate covered works that you do not\n convey, without conditions so long as your license otherwise remains\n in force. You may convey covered works to others for the sole purpose\n of having them make modifications exclusively for you, or provide you\n with facilities for running those works, provided that you comply with\n the terms of this License in conveying all material for which you do\n not control copyright. Those thus making or running the covered works\n for you must do so exclusively on your behalf, under your direction\n and control, on terms that prohibit them from making any copies of\n your copyrighted material outside their relationship with you.\n\n Conveying under any other circumstances is permitted solely under\n the conditions stated below. Sublicensing is not allowed; section 10\n makes it unnecessary.\n\n 3. Protecting Users\' Legal Rights From Anti-Circumvention Law.\n\n No covered work shall be deemed part of an effective technological\n measure under any applicable law fulfilling obligations under article\n 11 of the WIPO copyright treaty adopted on 20 December 1996, or\n similar laws prohibiting or restricting circumvention of such\n measures.\n\n When you convey a covered work, you waive any legal power to forbid\n circumvention of technological measures to the extent such circumvention\n is effected by exercising rights under this License with respect to\n the covered work, and you disclaim any intention to limit operation or\n modification of the work as a means of enforcing, against the work\'s\n users, your or third parties\' legal rights to forbid circumvention of\n technological measures.\n\n 4. Conveying Verbatim Copies.\n\n You may convey verbatim copies of the Program\'s source code as you\n receive it, in any medium, provided that you conspicuously and\n appropriately publish on each copy an appropriate copyright notice;\n keep intact all notices stating that this License and any\n non-permissive terms added in accord with section 7 apply to the code;\n keep intact all notices of the absence of any warranty; and give all\n recipients a copy of this License along with the Program.\n\n You may charge any price or no price for each copy that you convey,\n and you may offer support or warranty protection for a fee.\n\n 5. Conveying Modified Source Versions.\n\n You may convey a work based on the Program, or the modifications to\n produce it from the Program, in the form of source code under the\n terms of section 4, provided that you also meet all of these conditions:\n\n a) The work must carry prominent notices stating that you modified\n it, and giving a relevant date.\n\n b) The work must carry prominent notices stating that it is\n released under this License and any conditions added under section\n 7. This requirement modifies the requirement in section 4 to\n "keep intact all notices".\n\n c) You must license the entire work, as a whole, under this\n License to anyone who comes into possession of a copy. This\n License will therefore apply, along with any applicable section 7\n additional terms, to the whole of the work, and all its parts,\n regardless of how they are packaged. This License gives no\n permission to license the work in any other way, but it does not\n invalidate such permission if you have separately received it.\n\n d) If the work has interactive user interfaces, each must display\n Appropriate Legal Notices; however, if the Program has interactive\n interfaces that do not display Appropriate Legal Notices, your\n work need not make them do so.\n\n A compilation of a covered work with other separate and independent\n works, which are not by their nature extensions of the covered work,\n and which are not combined with it such as to form a larger program,\n in or on a volume of a storage or distribution medium, is called an\n "aggregate" if the compilation and its resulting copyright are not\n used to limit the access or legal rights of the compilation\'s users\n beyond what the individual works permit. Inclusion of a covered work\n in an aggregate does not cause this License to apply to the other\n parts of the aggregate.\n\n 6. Conveying Non-Source Forms.\n\n You may convey a covered work in object code form under the terms\n of sections 4 and 5, provided that you also convey the\n machine-readable Corresponding Source under the terms of this License,\n in one of these ways:\n\n a) Convey the object code in, or embodied in, a physical product\n (including a physical distribution medium), accompanied by the\n Corresponding Source fixed on a durable physical medium\n customarily used for software interchange.\n\n b) Convey the object code in, or embodied in, a physical product\n (including a physical distribution medium), accompanied by a\n written offer, valid for at least three years and valid for as\n long as you offer spare parts or customer support for that product\n model, to give anyone who possesses the object code either (1) a\n copy of the Corresponding Source for all the software in the\n product that is covered by this License, on a durable physical\n medium customarily used for software interchange, for a price no\n more than your reasonable cost of physically performing this\n conveying of source, or (2) access to copy the\n Corresponding Source from a network server at no charge.\n\n c) Convey individual copies of the object code with a copy of the\n written offer to provide the Corresponding Source. This\n alternative is allowed only occasionally and noncommercially, and\n only if you received the object code with such an offer, in accord\n with subsection 6b.\n\n d) Convey the object code by offering access from a designated\n place (gratis or for a charge), and offer equivalent access to the\n Corresponding Source in the same way through the same place at no\n further charge. You need not require recipients to copy the\n Corresponding Source along with the object code. If the place to\n copy the object code is a network server, the Corresponding Source\n may be on a different server (operated by you or a third party)\n that supports equivalent copying facilities, provided you maintain\n clear directions next to the object code saying where to find the\n Corresponding Source. Regardless of what server hosts the\n Corresponding Source, you remain obligated to ensure that it is\n available for as long as needed to satisfy these requirements.\n\n e) Convey the object code using peer-to-peer transmission, provided\n you inform other peers where the object code and Corresponding\n Source of the work are being offered to the general public at no\n charge under subsection 6d.\n\n A separable portion of the object code, whose source code is excluded\n from the Corresponding Source as a System Library, need not be\n included in conveying the object code work.\n\n A "User Product" is either (1) a "consumer product", which means any\n tangible personal property which is normally used for personal, family,\n or household purposes, or (2) anything designed or sold for incorporation\n into a dwelling. In determining whether a product is a consumer product,\n doubtful cases shall be resolved in favor of coverage. For a particular\n product received by a particular user, "normally used" refers to a\n typical or common use of that class of product, regardless of the status\n of the particular user or of the way in which the particular user\n actually uses, or expects or is expected to use, the product. A product\n is a consumer product regardless of whether the product has substantial\n commercial, industrial or non-consumer uses, unless such uses represent\n the only significant mode of use of the product.\n\n "Installation Information" for a User Product means any methods,\n procedures, authorization keys, or other information required to install\n and execute modified versions of a covered work in that User Product from\n a modified version of its Corresponding Source. The information must\n suffice to ensure that the continued functioning of the modified object\n code is in no case prevented or interfered with solely because\n modification has been made.\n\n If you convey an object code work under this section in, or with, or\n specifically for use in, a User Product, and the conveying occurs as\n part of a transaction in which the right of possession and use of the\n User Product is transferred to the recipient in perpetuity or for a\n fixed term (regardless of how the transaction is characterized), the\n Corresponding Source conveyed under this section must be accompanied\n by the Installation Information. But this requirement does not apply\n if neither you nor any third party retains the ability to install\n modified object code on the User Product (for example, the work has\n been installed in ROM).\n\n The requirement to provide Installation Information does not include a\n requirement to continue to provide support service, warranty, or updates\n for a work that has been modified or installed by the recipient, or for\n the User Product in which it has been modified or installed. Access to a\n network may be denied when the modification itself materially and\n adversely affects the operation of the network or violates the rules and\n protocols for communication across the network.\n\n Corresponding Source conveyed, and Installation Information provided,\n in accord with this section must be in a format that is publicly\n documented (and with an implementation available to the public in\n source code form), and must require no special password or key for\n unpacking, reading or copying.\n\n 7. Additional Terms.\n\n "Additional permissions" are terms that supplement the terms of this\n License by making exceptions from one or more of its conditions.\n Additional permissions that are applicable to the entire Program shall\n be treated as though they were included in this License, to the extent\n that they are valid under applicable law. If additional permissions\n apply only to part of the Program, that part may be used separately\n under those permissions, but the entire Program remains governed by\n this License without regard to the additional permissions.\n\n When you convey a copy of a covered work, you may at your option\n remove any additional permissions from that copy, or from any part of\n it. (Additional permissions may be written to require their own\n removal in certain cases when you modify the work.) You may place\n additional permissions on material, added by you to a covered work,\n for which you have or can give appropriate copyright permission.\n\n Notwithstanding any other provision of this License, for material you\n add to a covered work, you may (if authorized by the copyright holders of\n that material) supplement the terms of this License with terms:\n\n a) Disclaiming warranty or limiting liability differently from the\n terms of sections 15 and 16 of this License; or\n\n b) Requiring preservation of specified reasonable legal notices or\n author attributions in that material or in the Appropriate Legal\n Notices displayed by works containing it; or\n\n c) Prohibiting misrepresentation of the origin of that material, or\n requiring that modified versions of such material be marked in\n reasonable ways as different from the original version; or\n\n d) Limiting the use for publicity purposes of names of licensors or\n authors of the material; or\n\n e) Declining to grant rights under trademark law for use of some\n trade names, trademarks, or service marks; or\n\n f) Requiring indemnification of licensors and authors of that\n material by anyone who conveys the material (or modified versions of\n it) with contractual assumptions of liability to the recipient, for\n any liability that these contractual assumptions directly impose on\n those licensors and authors.\n\n All other non-permissive additional terms are considered "further\n restrictions" within the meaning of section 10. If the Program as you\n received it, or any part of it, contains a notice stating that it is\n governed by this License along with a term that is a further\n restriction, you may remove that term. If a license document contains\n a further restriction but permits relicensing or conveying under this\n License, you may add to a covered work material governed by the terms\n of that license document, provided that the further restriction does\n not survive such relicensing or conveying.\n\n If you add terms to a covered work in accord with this section, you\n must place, in the relevant source files, a statement of the\n additional terms that apply to those files, or a notice indicating\n where to find the applicable terms.\n\n Additional terms, permissive or non-permissive, may be stated in the\n form of a separately written license, or stated as exceptions;\n the above requirements apply either way.\n\n 8. Termination.\n\n You may not propagate or modify a covered work except as expressly\n provided under this License. Any attempt otherwise to propagate or\n modify it is void, and will automatically terminate your rights under\n this License (including any patent licenses granted under the third\n paragraph of section 11).\n\n However, if you cease all violation of this License, then your\n license from a particular copyright holder is reinstated (a)\n provisionally, unless and until the copyright holder explicitly and\n finally terminates your license, and (b) permanently, if the copyright\n holder fails to notify you of the violation by some reasonable means\n prior to 60 days after the cessation.\n\n Moreover, your license from a particular copyright holder is\n reinstated permanently if the copyright holder notifies you of the\n violation by some reasonable means, this is the first time you have\n received notice of violation of this License (for any work) from that\n copyright holder, and you cure the violation prior to 30 days after\n your receipt of the notice.\n\n Termination of your rights under this section does not terminate the\n licenses of parties who have received copies or rights from you under\n this License. If your rights have been terminated and not permanently\n reinstated, you do not qualify to receive new licenses for the same\n material under section 10.\n\n 9. Acceptance Not Required for Having Copies.\n\n You are not required to accept this License in order to receive or\n run a copy of the Program. Ancillary propagation of a covered work\n occurring solely as a consequence of using peer-to-peer transmission\n to receive a copy likewise does not require acceptance. However,\n nothing other than this License grants you permission to propagate or\n modify any covered work. These actions infringe copyright if you do\n not accept this License. Therefore, by modifying or propagating a\n covered work, you indicate your acceptance of this License to do so.\n\n 10. Automatic Licensing of Downstream Recipients.\n\n Each time you convey a covered work, the recipient automatically\n receives a license from the original licensors, to run, modify and\n propagate that work, subject to this License. You are not responsible\n for enforcing compliance by third parties with this License.\n\n An "entity transaction" is a transaction transferring control of an\n organization, or substantially all assets of one, or subdividing an\n organization, or merging organizations. If propagation of a covered\n work results from an entity transaction, each party to that\n transaction who receives a copy of the work also receives whatever\n licenses to the work the party\'s predecessor in interest had or could\n give under the previous paragraph, plus a right to possession of the\n Corresponding Source of the work from the predecessor in interest, if\n the predecessor has it or can get it with reasonable efforts.\n\n You may not impose any further restrictions on the exercise of the\n rights granted or affirmed under this License. For example, you may\n not impose a license fee, royalty, or other charge for exercise of\n rights granted under this License, and you may not initiate litigation\n (including a cross-claim or counterclaim in a lawsuit) alleging that\n any patent claim is infringed by making, using, selling, offering for\n sale, or importing the Program or any portion of it.\n\n 11. Patents.\n\n A "contributor" is a copyright holder who authorizes use under this\n License of the Program or a work on which the Program is based. The\n work thus licensed is called the contributor\'s "contributor version".\n\n A contributor\'s "essential patent claims" are all patent claims\n owned or controlled by the contributor, whether already acquired or\n hereafter acquired, that would be infringed by some manner, permitted\n by this License, of making, using, or selling its contributor version,\n but do not include claims that would be infringed only as a\n consequence of further modification of the contributor version. For\n purposes of this definition, "control" includes the right to grant\n patent sublicenses in a manner consistent with the requirements of\n this License.\n\n Each contributor grants you a non-exclusive, worldwide, royalty-free\n patent license under the contributor\'s essential patent claims, to\n make, use, sell, offer for sale, import and otherwise run, modify and\n propagate the contents of its contributor version.\n\n In the following three paragraphs, a "patent license" is any express\n agreement or commitment, however denominated, not to enforce a patent\n (such as an express permission to practice a patent or covenant not to\n sue for patent infringement). To "grant" such a patent license to a\n party means to make such an agreement or commitment not to enforce a\n patent against the party.\n\n If you convey a covered work, knowingly relying on a patent license,\n and the Corresponding Source of the work is not available for anyone\n to copy, free of charge and under the terms of this License, through a\n publicly available network server or other readily accessible means,\n then you must either (1) cause the Corresponding Source to be so\n available, or (2) arrange to deprive yourself of the benefit of the\n patent license for this particular work, or (3) arrange, in a manner\n consistent with the requirements of this License, to extend the patent\n license to downstream recipients. "Knowingly relying" means you have\n actual knowledge that, but for the patent license, your conveying the\n covered work in a country, or your recipient\'s use of the covered work\n in a country, would infringe one or more identifiable patents in that\n country that you have reason to believe are valid.\n\n If, pursuant to or in connection with a single transaction or\n arrangement, you convey, or propagate by procuring conveyance of, a\n covered work, and grant a patent license to some of the parties\n receiving the covered work authorizing them to use, propagate, modify\n or convey a specific copy of the covered work, then the patent license\n you grant is automatically extended to all recipients of the covered\n work and works based on it.\n\n A patent license is "discriminatory" if it does not include within\n the scope of its coverage, prohibits the exercise of, or is\n conditioned on the non-exercise of one or more of the rights that are\n specifically granted under this License. You may not convey a covered\n work if you are a party to an arrangement with a third party that is\n in the business of distributing software, under which you make payment\n to the third party based on the extent of your activity of conveying\n the work, and under which the third party grants, to any of the\n parties who would receive the covered work from you, a discriminatory\n patent license (a) in connection with copies of the covered work\n conveyed by you (or copies made from those copies), or (b) primarily\n for and in connection with specific products or compilations that\n contain the covered work, unless you entered into that arrangement,\n or that patent license was granted, prior to 28 March 2007.\n\n Nothing in this License shall be construed as excluding or limiting\n any implied license or other defenses to infringement that may\n otherwise be available to you under applicable patent law.\n\n 12. No Surrender of Others\' Freedom.\n\n If conditions are imposed on you (whether by court order, agreement or\n otherwise) that contradict the conditions of this License, they do not\n excuse you from the conditions of this License. If you cannot convey a\n covered work so as to satisfy simultaneously your obligations under this\n License and any other pertinent obligations, then as a consequence you may\n not convey it at all. For example, if you agree to terms that obligate you\n to collect a royalty for further conveying from those to whom you convey\n the Program, the only way you could satisfy both those terms and this\n License would be to refrain entirely from conveying the Program.\n\n 13. Use with the GNU Affero General Public License.\n\n Notwithstanding any other provision of this License, you have\n permission to link or combine any covered work with a work licensed\n under version 3 of the GNU Affero General Public License into a single\n combined work, and to convey the resulting work. The terms of this\n License will continue to apply to the part which is the covered work,\n but the special requirements of the GNU Affero General Public License,\n section 13, concerning interaction through a network will apply to the\n combination as such.\n\n 14. Revised Versions of this License.\n\n The Free Software Foundation may publish revised and/or new versions of\n the GNU General Public License from time to time. Such new versions will\n be similar in spirit to the present version, but may differ in detail to\n address new problems or concerns.\n\n Each version is given a distinguishing version number. If the\n Program specifies that a certain numbered version of the GNU General\n Public License "or any later version" applies to it, you have the\n option of following the terms and conditions either of that numbered\n version or of any later version published by the Free Software\n Foundation. If the Program does not specify a version number of the\n GNU General Public License, you may choose any version ever published\n by the Free Software Foundation.\n\n If the Program specifies that a proxy can decide which future\n versions of the GNU General Public License can be used, that proxy\'s\n public statement of acceptance of a version permanently authorizes you\n to choose that version for the Program.\n\n Later license versions may give you additional or different\n permissions. However, no additional obligations are imposed on any\n author or copyright holder as a result of your choosing to follow a\n later version.\n\n 15. Disclaimer of Warranty.\n\n THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\n APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\n HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY\n OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\n THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\n IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\n ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n 16. Limitation of Liability.\n\n IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\n THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\n GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\n USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\n DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\n PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\n EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\n SUCH DAMAGES.\n\n 17. Interpretation of Sections 15 and 16.\n\n If the disclaimer of warranty and limitation of liability provided\n above cannot be given local legal effect according to their terms,\n reviewing courts shall apply local law that most closely approximates\n an absolute waiver of all civil liability in connection with the\n Program, unless a warranty or assumption of liability accompanies a\n copy of the Program in return for a fee.\n\n END OF TERMS AND CONDITIONS\n\n How to Apply These Terms to Your New Programs\n\n If you develop a new program, and you want it to be of the greatest\n possible use to the public, the best way to achieve this is to make it\n free software which everyone can redistribute and change under these terms.\n\n To do so, attach the following notices to the program. It is safest\n to attach them to the start of each source file to most effectively\n state the exclusion of warranty; and each file should have at least\n the "copyright" line and a pointer to where the full notice is found.\n\n \n Copyright (C) \n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see .\n\n Also add information on how to contact you by electronic and paper mail.\n\n If the program does terminal interaction, make it output a short\n notice like this when it starts in an interactive mode:\n\n Copyright (C) \n This program comes with ABSOLUTELY NO WARRANTY; for details type `show w\'.\n This is free software, and you are welcome to redistribute it\n under certain conditions; type `show c\' for details.\n\n The hypothetical commands `show w\' and `show c\' should show the appropriate\n parts of the General Public License. Of course, your program\'s commands\n might be different; for a GUI interface, you would use an "about box".\n\n You should also get your employer (if you work as a programmer) or school,\n if any, to sign a "copyright disclaimer" for the program, if necessary.\n For more information on this, and how to apply and follow the GNU GPL, see\n .\n\n The GNU General Public License does not permit incorporating your program\n into proprietary programs. If your program is a subroutine library, you\n may consider it more useful to permit linking proprietary applications with\n the library. If this is what you want to do, use the GNU Lesser General\n Public License instead of this License. But first, please read\n .' +__url__: str = '' +__version__: str = '0.7.4rc3' +__warningregistry__: dict = {'version': 0} +_meta: importlib.metadata._adapters.Message # value = diff --git a/stubs/gridfire/_gridfire/__init__.pyi b/stubs/gridfire/_gridfire/__init__.pyi index 23b26003..58a175d8 100644 --- a/stubs/gridfire/_gridfire/__init__.pyi +++ b/stubs/gridfire/_gridfire/__init__.pyi @@ -2,6 +2,7 @@ Python bindings for the fourdst utility modules which are a part of the 4D-STAR project. """ from __future__ import annotations +from . import config from . import engine from . import exceptions from . import io @@ -12,4 +13,4 @@ from . import screening from . import solver from . import type from . import utils -__all__: list[str] = ['engine', 'exceptions', 'io', 'partition', 'policy', 'reaction', 'screening', 'solver', 'type', 'utils'] +__all__: list[str] = ['config', 'engine', 'exceptions', 'io', 'partition', 'policy', 'reaction', 'screening', 'solver', 'type', 'utils'] diff --git a/stubs/gridfire/_gridfire/config.pyi b/stubs/gridfire/_gridfire/config.pyi new file mode 100644 index 00000000..57eb9940 --- /dev/null +++ b/stubs/gridfire/_gridfire/config.pyi @@ -0,0 +1,47 @@ +""" +GridFire configuration bindings +""" +from __future__ import annotations +import typing +__all__: list[str] = ['AdaptiveEngineViewConfig', 'CVODESolverConfig', 'EngineConfig', 'EngineViewConfig', 'GridFireConfig', 'SolverConfig'] +class AdaptiveEngineViewConfig: + def __init__(self) -> None: + ... + @property + def relativeCullingThreshold(self) -> float: + ... + @relativeCullingThreshold.setter + def relativeCullingThreshold(self, arg0: typing.SupportsFloat) -> None: + ... +class CVODESolverConfig: + def __init__(self) -> None: + ... + @property + def absTol(self) -> float: + ... + @absTol.setter + def absTol(self, arg0: typing.SupportsFloat) -> None: + ... + @property + def relTol(self) -> float: + ... + @relTol.setter + def relTol(self, arg0: typing.SupportsFloat) -> None: + ... +class EngineConfig: + views: EngineViewConfig + def __init__(self) -> None: + ... +class EngineViewConfig: + adaptiveEngineView: AdaptiveEngineViewConfig + def __init__(self) -> None: + ... +class GridFireConfig: + engine: EngineConfig + solver: SolverConfig + def __init__(self) -> None: + ... +class SolverConfig: + cvode: CVODESolverConfig + def __init__(self) -> None: + ... diff --git a/stubs/gridfire/_gridfire/engine/__init__.pyi b/stubs/gridfire/_gridfire/engine/__init__.pyi index b652bc70..bda6579c 100644 --- a/stubs/gridfire/_gridfire/engine/__init__.pyi +++ b/stubs/gridfire/_gridfire/engine/__init__.pyi @@ -14,110 +14,81 @@ import numpy import numpy.typing import typing from . import diagnostics -__all__: list[str] = ['ACTIVE', 'ADAPTIVE_ENGINE_VIEW', 'AdaptiveEngineView', 'BuildDepthType', 'DEFAULT', 'DEFINED_ENGINE_VIEW', 'DefinedEngineView', 'DynamicEngine', 'EQUILIBRIUM', 'Engine', 'EngineTypes', 'FILE_DEFINED_ENGINE_VIEW', 'FULL_SUCCESS', 'FifthOrder', 'FileDefinedEngineView', 'FourthOrder', 'Full', 'GRAPH_ENGINE', 'GraphEngine', 'INACTIVE_FLOW', 'MAX_ITERATIONS_REACHED', 'MULTISCALE_PARTITIONING_ENGINE_VIEW', 'MultiscalePartitioningEngineView', 'NONE', 'NOT_PRESENT', 'NO_SPECIES_TO_PRIME', 'NetworkBuildDepth', 'NetworkConstructionFlags', 'NetworkJacobian', 'NetworkPrimingEngineView', 'PRIMING_ENGINE_VIEW', 'PrimingReport', 'PrimingReportStatus', 'REACLIB', 'REACLIB_STRONG', 'REACLIB_WEAK', 'SecondOrder', 'Shallow', 'SparsityPattern', 'SpeciesStatus', 'StepDerivatives', 'ThirdOrder', 'WRL_BETA_MINUS', 'WRL_BETA_PLUS', 'WRL_ELECTRON_CAPTURE', 'WRL_POSITRON_CAPTURE', 'WRL_WEAK', 'build_nuclear_network', 'diagnostics', 'primeNetwork', 'regularize_jacobian'] +from . import scratchpads +__all__: list[str] = ['ACTIVE', 'ADAPTIVE_ENGINE_VIEW', 'AdaptiveEngineView', 'BuildDepthType', 'DEFAULT', 'DEFINED_ENGINE_VIEW', 'DefinedEngineView', 'DynamicEngine', 'EQUILIBRIUM', 'Engine', 'EngineTypes', 'FILE_DEFINED_ENGINE_VIEW', 'FULL_SUCCESS', 'FifthOrder', 'FileDefinedEngineView', 'FourthOrder', 'Full', 'GRAPH_ENGINE', 'GraphEngine', 'INACTIVE_FLOW', 'MAX_ITERATIONS_REACHED', 'MULTISCALE_PARTITIONING_ENGINE_VIEW', 'MultiscalePartitioningEngineView', 'NONE', 'NOT_PRESENT', 'NO_SPECIES_TO_PRIME', 'NetworkBuildDepth', 'NetworkConstructionFlags', 'NetworkJacobian', 'NetworkPrimingEngineView', 'PRIMING_ENGINE_VIEW', 'PrimingReport', 'PrimingReportStatus', 'REACLIB', 'REACLIB_STRONG', 'REACLIB_WEAK', 'SecondOrder', 'Shallow', 'SparsityPattern', 'SpeciesStatus', 'StepDerivatives', 'ThirdOrder', 'WRL_BETA_MINUS', 'WRL_BETA_PLUS', 'WRL_ELECTRON_CAPTURE', 'WRL_POSITRON_CAPTURE', 'WRL_WEAK', 'build_nuclear_network', 'diagnostics', 'primeNetwork', 'regularize_jacobian', 'scratchpads'] class AdaptiveEngineView(DynamicEngine): def __init__(self, baseEngine: DynamicEngine) -> None: """ Construct an adaptive engine view with a base engine. """ - def calculateEpsDerivatives(self, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: """ Calculate deps/dT and deps/drho """ - def calculateMolarReactionFlow(self: DynamicEngine, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: """ Calculate the molar reaction flow for a given reaction. """ - def calculateRHSAndEnergy(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: """ Calculate the right-hand side (dY/dt) and energy generation rate. """ - def collectComposition(self, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: """ Recursively collect composition from current engine and any sub engines if they exist. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: """ Generate the Jacobian matrix for the current state. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: """ Generate the jacobian matrix only for the subset of the matrix representing the active species. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: """ Generate the jacobian matrix for the given sparsity pattern """ - def generateStoichiometryMatrix(self) -> None: - ... def getBaseEngine(self) -> DynamicEngine: """ Get the base engine associated with this adaptive engine view. """ - def getDepth(self) -> gridfire._gridfire.engine.NetworkBuildDepth | int: - """ - Get the current build depth of the engine. - """ - def getNetworkReactions(self) -> gridfire._gridfire.reaction.ReactionSet: + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: """ Get the set of logical reactions in the network. """ - def getNetworkSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of species in the network. """ - def getScreeningModel(self) -> gridfire._gridfire.screening.ScreeningType: + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: """ Get the current screening model of the engine. """ - def getSpeciesDestructionTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the destruction timescales for each species in the network. """ - def getSpeciesIndex(self, species: fourdst._phys.atomic.Species) -> int: + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: """ Get the index of a species in the network. """ - def getSpeciesStatus(self, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: """ Get the status of a species in the network. """ - def getSpeciesTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the timescales for each species in the network. """ - def getStoichiometryMatrixEntry(self, species: fourdst._phys.atomic.Species, reaction: ...) -> int: - """ - Get an entry from the stoichiometry matrix. - """ - def isStale(self, netIn: gridfire._gridfire.type.NetIn) -> bool: - """ - Check if the engine is stale based on the provided NetIn object. - """ - def mapNetInToMolarAbundanceVector(self, netIn: gridfire._gridfire.type.NetIn) -> list[float]: - """ - Map a NetIn object to a vector of molar abundances. - """ - def primeEngine(self, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: """ Prime the engine with a NetIn object to prepare for calculations. """ - def rebuild(self, composition: ..., depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: - """ - Rebuild the engine with a new composition and build depth. - """ - def setNetworkReactions(self, reactions: gridfire._gridfire.reaction.ReactionSet) -> None: - """ - Set the network reactions to a new set of reactions. - """ - def setScreeningModel(self, screeningModel: gridfire._gridfire.screening.ScreeningType) -> None: - """ - Set the screening model for the engine. - """ - def update(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: """ Update the engine state based on the provided NetIn object. """ @@ -128,104 +99,74 @@ class DefinedEngineView(DynamicEngine): """ Construct a defined engine view with a list of tracked reactions and a base engine. """ - def calculateEpsDerivatives(self, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: """ Calculate deps/dT and deps/drho """ - def calculateMolarReactionFlow(self: DynamicEngine, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: """ Calculate the molar reaction flow for a given reaction. """ - def calculateRHSAndEnergy(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: """ Calculate the right-hand side (dY/dt) and energy generation rate. """ - def collectComposition(self, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: """ Recursively collect composition from current engine and any sub engines if they exist. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: """ Generate the Jacobian matrix for the current state. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: """ Generate the jacobian matrix only for the subset of the matrix representing the active species. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: """ Generate the jacobian matrix for the given sparsity pattern """ - def generateStoichiometryMatrix(self) -> None: - ... def getBaseEngine(self) -> DynamicEngine: """ Get the base engine associated with this defined engine view. """ - def getDepth(self) -> gridfire._gridfire.engine.NetworkBuildDepth | int: - """ - Get the current build depth of the engine. - """ - def getNetworkReactions(self) -> gridfire._gridfire.reaction.ReactionSet: + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: """ Get the set of logical reactions in the network. """ - def getNetworkSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of species in the network. """ - def getScreeningModel(self) -> gridfire._gridfire.screening.ScreeningType: + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: """ Get the current screening model of the engine. """ - def getSpeciesDestructionTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the destruction timescales for each species in the network. """ - def getSpeciesIndex(self, species: fourdst._phys.atomic.Species) -> int: + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: """ Get the index of a species in the network. """ - def getSpeciesStatus(self, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: """ Get the status of a species in the network. """ - def getSpeciesTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the timescales for each species in the network. """ - def getStoichiometryMatrixEntry(self, species: fourdst._phys.atomic.Species, reaction: ...) -> int: - """ - Get an entry from the stoichiometry matrix. - """ - def isStale(self, netIn: gridfire._gridfire.type.NetIn) -> bool: - """ - Check if the engine is stale based on the provided NetIn object. - """ - def mapNetInToMolarAbundanceVector(self, netIn: gridfire._gridfire.type.NetIn) -> list[float]: - """ - Map a NetIn object to a vector of molar abundances. - """ - def primeEngine(self, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: """ Prime the engine with a NetIn object to prepare for calculations. """ - def rebuild(self, composition: ..., depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: - """ - Rebuild the engine with a new composition and build depth. - """ - def setNetworkReactions(self, reactions: gridfire._gridfire.reaction.ReactionSet) -> None: - """ - Set the network reactions to a new set of reactions. - """ - def setScreeningModel(self, screeningModel: gridfire._gridfire.screening.ScreeningType) -> None: - """ - Set the screening model for the engine. - """ - def update(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: """ Update the engine state based on the provided NetIn object. """ @@ -293,56 +234,50 @@ class FileDefinedEngineView(DefinedEngineView): """ Construct a defined engine view from a file and a base engine. """ - def calculateEpsDerivatives(self, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: """ Calculate deps/dT and deps/drho """ - def calculateMolarReactionFlow(self: DynamicEngine, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: """ Calculate the molar reaction flow for a given reaction. """ - def calculateRHSAndEnergy(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: """ Calculate the right-hand side (dY/dt) and energy generation rate. """ - def collectComposition(self, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: """ Recursively collect composition from current engine and any sub engines if they exist. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: """ Generate the Jacobian matrix for the current state. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: """ Generate the jacobian matrix only for the subset of the matrix representing the active species. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: """ Generate the jacobian matrix for the given sparsity pattern """ - def generateStoichiometryMatrix(self) -> None: - ... def getBaseEngine(self) -> DynamicEngine: """ Get the base engine associated with this file defined engine view. """ - def getDepth(self) -> gridfire._gridfire.engine.NetworkBuildDepth | int: - """ - Get the current build depth of the engine. - """ def getNetworkFile(self) -> str: """ Get the network file associated with this defined engine view. """ - def getNetworkReactions(self) -> gridfire._gridfire.reaction.ReactionSet: + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: """ Get the set of logical reactions in the network. """ - def getNetworkSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of species in the network. """ @@ -350,64 +285,35 @@ class FileDefinedEngineView(DefinedEngineView): """ Get the parser used for this defined engine view. """ - def getScreeningModel(self) -> gridfire._gridfire.screening.ScreeningType: + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: """ Get the current screening model of the engine. """ - def getSpeciesDestructionTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the destruction timescales for each species in the network. """ - def getSpeciesIndex(self, species: fourdst._phys.atomic.Species) -> int: + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: """ Get the index of a species in the network. """ - def getSpeciesStatus(self, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: """ Get the status of a species in the network. """ - def getSpeciesTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the timescales for each species in the network. """ - def getStoichiometryMatrixEntry(self, species: fourdst._phys.atomic.Species, reaction: ...) -> int: - """ - Get an entry from the stoichiometry matrix. - """ - def isStale(self, netIn: gridfire._gridfire.type.NetIn) -> bool: - """ - Check if the engine is stale based on the provided NetIn object. - """ - def mapNetInToMolarAbundanceVector(self, netIn: gridfire._gridfire.type.NetIn) -> list[float]: - """ - Map a NetIn object to a vector of molar abundances. - """ - def primeEngine(self, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: """ Prime the engine with a NetIn object to prepare for calculations. """ - def rebuild(self, composition: ..., depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: - """ - Rebuild the engine with a new composition and build depth. - """ - def setNetworkReactions(self, reactions: gridfire._gridfire.reaction.ReactionSet) -> None: - """ - Set the network reactions to a new set of reactions. - """ - def setScreeningModel(self, screeningModel: gridfire._gridfire.screening.ScreeningType) -> None: - """ - Set the screening model for the engine. - """ - def update(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: """ Update the engine state based on the provided NetIn object. """ class GraphEngine(DynamicEngine): - @staticmethod - def getNetReactionStoichiometry(reaction: ...) -> dict[fourdst._phys.atomic.Species, int]: - """ - Get the net stoichiometry for a given reaction. - """ @typing.overload def __init__(self, composition: fourdst._phys.composition.Composition, depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: """ @@ -423,15 +329,15 @@ class GraphEngine(DynamicEngine): """ Initialize GraphEngine with a set of reactions. """ - def calculateEpsDerivatives(self, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: """ Calculate deps/dT and deps/drho """ - def calculateMolarReactionFlow(self: DynamicEngine, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: """ Calculate the molar reaction flow for a given reaction. """ - def calculateRHSAndEnergy(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: """ Calculate the right-hand side (dY/dt) and energy generation rate. """ @@ -447,128 +353,90 @@ class GraphEngine(DynamicEngine): """ Calculate the derivative of the reverse rate for a two-body reaction at a specific temperature. """ - def collectComposition(self, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: """ Recursively collect composition from current engine and any sub engines if they exist. """ - def exportToCSV(self, filename: str) -> None: + def exportToCSV(self, ctx: scratchpads.StateBlob, filename: str) -> None: """ Export the network to a CSV file for analysis. """ - def exportToDot(self, filename: str) -> None: + def exportToDot(self, ctx: scratchpads.StateBlob, filename: str) -> None: """ Export the network to a DOT file for visualization. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: """ Generate the Jacobian matrix for the current state. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: """ Generate the jacobian matrix only for the subset of the matrix representing the active species. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: """ Generate the jacobian matrix for the given sparsity pattern """ - def generateStoichiometryMatrix(self) -> None: - ... - def getDepth(self) -> gridfire._gridfire.engine.NetworkBuildDepth | int: - """ - Get the current build depth of the engine. - """ - def getNetworkReactions(self) -> gridfire._gridfire.reaction.ReactionSet: + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: """ Get the set of logical reactions in the network. """ - def getNetworkSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of species in the network. """ - def getPartitionFunction(self) -> gridfire._gridfire.partition.PartitionFunction: + def getPartitionFunction(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.partition.PartitionFunction: """ Get the partition function used by the engine. """ - def getScreeningModel(self) -> gridfire._gridfire.screening.ScreeningType: + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: """ Get the current screening model of the engine. """ @typing.overload - def getSpeciesDestructionTimescales(self, composition: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeReactions: gridfire._gridfire.reaction.ReactionSet) -> ...: + def getSpeciesDestructionTimescales(self, ctx: scratchpads.StateBlob, composition: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeReactions: gridfire._gridfire.reaction.ReactionSet) -> ...: ... @typing.overload - def getSpeciesDestructionTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the destruction timescales for each species in the network. """ - def getSpeciesIndex(self, species: fourdst._phys.atomic.Species) -> int: + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: """ Get the index of a species in the network. """ - def getSpeciesStatus(self, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: """ Get the status of a species in the network. """ @typing.overload - def getSpeciesTimescales(self, composition: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeReactions: gridfire._gridfire.reaction.ReactionSet) -> ...: + def getSpeciesTimescales(self, ctx: scratchpads.StateBlob, composition: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeReactions: gridfire._gridfire.reaction.ReactionSet) -> ...: ... @typing.overload - def getSpeciesTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the timescales for each species in the network. """ - def getStoichiometryMatrixEntry(self, species: fourdst._phys.atomic.Species, reaction: ...) -> int: - """ - Get an entry from the stoichiometry matrix. - """ - def involvesSpecies(self, species: fourdst._phys.atomic.Species) -> bool: + def involvesSpecies(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: """ Check if a given species is involved in the network. """ - def isPrecomputationEnabled(self) -> bool: + def isPrecomputationEnabled(self, arg0: scratchpads.StateBlob) -> bool: """ Check if precomputation is enabled for the engine. """ - def isStale(self, netIn: gridfire._gridfire.type.NetIn) -> bool: - """ - Check if the engine is stale based on the provided NetIn object. - """ - def isUsingReverseReactions(self) -> bool: + def isUsingReverseReactions(self, arg0: scratchpads.StateBlob) -> bool: """ Check if the engine is using reverse reactions. """ - def mapNetInToMolarAbundanceVector(self, netIn: gridfire._gridfire.type.NetIn) -> list[float]: - """ - Map a NetIn object to a vector of molar abundances. - """ - def primeEngine(self, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: """ Prime the engine with a NetIn object to prepare for calculations. """ - def rebuild(self, composition: ..., depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: - """ - Rebuild the engine with a new composition and build depth. - """ - def setNetworkReactions(self, reactions: gridfire._gridfire.reaction.ReactionSet) -> None: - """ - Set the network reactions to a new set of reactions. - """ - def setPrecomputation(self, precompute: bool) -> None: - """ - Enable or disable precomputation for the engine. - """ - def setScreeningModel(self, screeningModel: gridfire._gridfire.screening.ScreeningType) -> None: - """ - Set the screening model for the engine. - """ - def setUseReverseReactions(self, useReverse: bool) -> None: - """ - Enable or disable the use of reverse reactions in the engine. - """ - def update(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: """ Update the engine state based on the provided NetIn object. """ @@ -577,142 +445,106 @@ class MultiscalePartitioningEngineView(DynamicEngine): """ Construct a multiscale partitioning engine view with a base engine. """ - def calculateEpsDerivatives(self, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: """ Calculate deps/dT and deps/drho """ - def calculateMolarReactionFlow(self: DynamicEngine, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: """ Calculate the molar reaction flow for a given reaction. """ - def calculateRHSAndEnergy(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: """ Calculate the right-hand side (dY/dt) and energy generation rate. """ - def collectComposition(self, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: """ Recursively collect composition from current engine and any sub engines if they exist. """ - def exportToDot(self, filename: str, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> None: + def exportToDot(self, ctx: scratchpads.StateBlob, filename: str, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> None: """ Export the network to a DOT file for visualization. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: """ Generate the Jacobian matrix for the current state. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: """ Generate the jacobian matrix only for the subset of the matrix representing the active species. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: """ Generate the jacobian matrix for the given sparsity pattern """ - def generateStoichiometryMatrix(self) -> None: - ... def getBaseEngine(self) -> DynamicEngine: """ Get the base engine associated with this multiscale partitioning engine view. """ - def getDepth(self) -> gridfire._gridfire.engine.NetworkBuildDepth | int: - """ - Get the current build depth of the engine. - """ - def getDynamicSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getDynamicSpecies(self: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of dynamic species in the network. """ - def getFastSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getFastSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of fast species in the network. """ - def getNetworkReactions(self) -> gridfire._gridfire.reaction.ReactionSet: + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: """ Get the set of logical reactions in the network. """ - def getNetworkSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of species in the network. """ - def getNormalizedEquilibratedComposition(self, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + def getNormalizedEquilibratedComposition(self, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: """ Get the normalized equilibrated composition for the algebraic species. """ - def getScreeningModel(self) -> gridfire._gridfire.screening.ScreeningType: + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: """ Get the current screening model of the engine. """ - def getSpeciesDestructionTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the destruction timescales for each species in the network. """ - def getSpeciesIndex(self, species: fourdst._phys.atomic.Species) -> int: + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: """ Get the index of a species in the network. """ - def getSpeciesStatus(self, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: """ Get the status of a species in the network. """ - def getSpeciesTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the timescales for each species in the network. """ - def getStoichiometryMatrixEntry(self, species: fourdst._phys.atomic.Species, reaction: ...) -> int: - """ - Get an entry from the stoichiometry matrix. - """ - def involvesSpecies(self, species: fourdst._phys.atomic.Species) -> bool: + def involvesSpecies(self: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: """ Check if a given species is involved in the network (in either the algebraic or dynamic set). """ - def involvesSpeciesInDynamic(self, species: fourdst._phys.atomic.Species) -> bool: + def involvesSpeciesInDynamic(self: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: """ Check if a given species is involved in the network's dynamic set. """ - def involvesSpeciesInQSE(self, species: fourdst._phys.atomic.Species) -> bool: + def involvesSpeciesInQSE(self: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: """ Check if a given species is involved in the network's algebraic set. """ - def isStale(self, netIn: gridfire._gridfire.type.NetIn) -> bool: - """ - Check if the engine is stale based on the provided NetIn object. - """ - def mapNetInToMolarAbundanceVector(self, netIn: gridfire._gridfire.type.NetIn) -> list[float]: - """ - Map a NetIn object to a vector of molar abundances. - """ - @typing.overload - def partitionNetwork(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + def partitionNetwork(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: """ Partition the network based on species timescales and connectivity. """ - @typing.overload - def partitionNetwork(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: - """ - Partition the network based on a NetIn object. - """ - def primeEngine(self, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: """ Prime the engine with a NetIn object to prepare for calculations. """ - def rebuild(self, composition: ..., depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: - """ - Rebuild the engine with a new composition and build depth. - """ - def setNetworkReactions(self, reactions: gridfire._gridfire.reaction.ReactionSet) -> None: - """ - Set the network reactions to a new set of reactions. - """ - def setScreeningModel(self, screeningModel: gridfire._gridfire.screening.ScreeningType) -> None: - """ - Set the screening model for the engine. - """ - def update(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: """ Update the engine state based on the provided NetIn object. """ @@ -893,113 +725,83 @@ class NetworkJacobian: """ class NetworkPrimingEngineView(DefinedEngineView): @typing.overload - def __init__(self, primingSymbol: str, baseEngine: GraphEngine) -> None: + def __init__(self, ctx: scratchpads.StateBlob, primingSymbol: str, baseEngine: GraphEngine) -> None: """ Construct a priming engine view with a priming symbol and a base engine. """ @typing.overload - def __init__(self, primingSpecies: fourdst._phys.atomic.Species, baseEngine: GraphEngine) -> None: + def __init__(self, ctx: scratchpads.StateBlob, primingSpecies: fourdst._phys.atomic.Species, baseEngine: GraphEngine) -> None: """ Construct a priming engine view with a priming species and a base engine. """ - def calculateEpsDerivatives(self, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: """ Calculate deps/dT and deps/drho """ - def calculateMolarReactionFlow(self: DynamicEngine, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: """ Calculate the molar reaction flow for a given reaction. """ - def calculateRHSAndEnergy(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: """ Calculate the right-hand side (dY/dt) and energy generation rate. """ - def collectComposition(self, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: """ Recursively collect composition from current engine and any sub engines if they exist. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: """ Generate the Jacobian matrix for the current state. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: """ Generate the jacobian matrix only for the subset of the matrix representing the active species. """ @typing.overload - def generateJacobianMatrix(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: """ Generate the jacobian matrix for the given sparsity pattern """ - def generateStoichiometryMatrix(self) -> None: - ... def getBaseEngine(self) -> DynamicEngine: """ Get the base engine associated with this priming engine view. """ - def getDepth(self) -> gridfire._gridfire.engine.NetworkBuildDepth | int: - """ - Get the current build depth of the engine. - """ - def getNetworkReactions(self) -> gridfire._gridfire.reaction.ReactionSet: + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: """ Get the set of logical reactions in the network. """ - def getNetworkSpecies(self) -> list[fourdst._phys.atomic.Species]: + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: """ Get the list of species in the network. """ - def getScreeningModel(self) -> gridfire._gridfire.screening.ScreeningType: + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: """ Get the current screening model of the engine. """ - def getSpeciesDestructionTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the destruction timescales for each species in the network. """ - def getSpeciesIndex(self, species: fourdst._phys.atomic.Species) -> int: + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: """ Get the index of a species in the network. """ - def getSpeciesStatus(self, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: """ Get the status of a species in the network. """ - def getSpeciesTimescales(self: DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: """ Get the timescales for each species in the network. """ - def getStoichiometryMatrixEntry(self, species: fourdst._phys.atomic.Species, reaction: ...) -> int: - """ - Get an entry from the stoichiometry matrix. - """ - def isStale(self, netIn: gridfire._gridfire.type.NetIn) -> bool: - """ - Check if the engine is stale based on the provided NetIn object. - """ - def mapNetInToMolarAbundanceVector(self, netIn: gridfire._gridfire.type.NetIn) -> list[float]: - """ - Map a NetIn object to a vector of molar abundances. - """ - def primeEngine(self, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: """ Prime the engine with a NetIn object to prepare for calculations. """ - def rebuild(self, composition: ..., depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: - """ - Rebuild the engine with a new composition and build depth. - """ - def setNetworkReactions(self, reactions: gridfire._gridfire.reaction.ReactionSet) -> None: - """ - Set the network reactions to a new set of reactions. - """ - def setScreeningModel(self, screeningModel: gridfire._gridfire.screening.ScreeningType) -> None: - """ - Set the screening model for the engine. - """ - def update(self, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: """ Update the engine state based on the provided NetIn object. """ @@ -1131,7 +933,7 @@ def build_nuclear_network(composition: ..., weakInterpolator: ..., maxLayers: gr """ Build a nuclear network from a composition using all archived reaction data. """ -def primeNetwork(netIn: gridfire._gridfire.type.NetIn, engine: ..., ignoredReactionTypes: collections.abc.Sequence[...] | None = None) -> PrimingReport: +def primeNetwork(ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn, engine: ..., ignoredReactionTypes: collections.abc.Sequence[...] | None = None) -> PrimingReport: """ Prime a network with a short timescale ignition """ diff --git a/stubs/gridfire/_gridfire/engine/diagnostics.pyi b/stubs/gridfire/_gridfire/engine/diagnostics.pyi index 5e25cf40..e0955a9e 100644 --- a/stubs/gridfire/_gridfire/engine/diagnostics.pyi +++ b/stubs/gridfire/_gridfire/engine/diagnostics.pyi @@ -5,11 +5,12 @@ from __future__ import annotations import collections.abc import fourdst._phys.composition import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads import typing __all__: list[str] = ['inspect_jacobian_stiffness', 'inspect_species_balance', 'report_limiting_species'] -def inspect_jacobian_stiffness(engine: gridfire._gridfire.engine.DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, json: bool) -> ... | None: +def inspect_jacobian_stiffness(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, json: bool) -> ... | None: ... -def inspect_species_balance(engine: gridfire._gridfire.engine.DynamicEngine, species_name: str, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, json: bool) -> ... | None: +def inspect_species_balance(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, species_name: str, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, json: bool) -> ... | None: ... -def report_limiting_species(engine: gridfire._gridfire.engine.DynamicEngine, Y_full: collections.abc.Sequence[typing.SupportsFloat], E_full: collections.abc.Sequence[typing.SupportsFloat], relTol: typing.SupportsFloat, absTol: typing.SupportsFloat, top_n: typing.SupportsInt, json: bool) -> ... | None: +def report_limiting_species(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, Y_full: collections.abc.Sequence[typing.SupportsFloat], E_full: collections.abc.Sequence[typing.SupportsFloat], relTol: typing.SupportsFloat, absTol: typing.SupportsFloat, top_n: typing.SupportsInt, json: bool) -> ... | None: ... diff --git a/stubs/gridfire/_gridfire/engine/scratchpads.pyi b/stubs/gridfire/_gridfire/engine/scratchpads.pyi new file mode 100644 index 00000000..6509bc84 --- /dev/null +++ b/stubs/gridfire/_gridfire/engine/scratchpads.pyi @@ -0,0 +1,267 @@ +""" +Engine ScratchPad bindings +""" +from __future__ import annotations +import fourdst._phys.atomic +import fourdst._phys.composition +import gridfire._gridfire.reaction +import typing +__all__: list[str] = ['ADAPTIVE_ENGINE_VIEW_SCRATCHPAD', 'ADFunRegistrationResult', 'ALREADY_REGISTERED', 'AdaptiveEngineViewScratchPad', 'DEFINED_ENGINE_VIEW_SCRATCHPAD', 'DefinedEngineViewScratchPad', 'GRAPH_ENGINE_SCRATCHPAD', 'GraphEngineScratchPad', 'MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD', 'MultiscalePartitioningEngineViewScratchPad', 'SCRATCHPAD_BAD_CAST', 'SCRATCHPAD_NOT_FOUND', 'SCRATCHPAD_NOT_INITIALIZED', 'SCRATCHPAD_OUT_OF_BOUNDS', 'SCRATCHPAD_TYPE_COLLISION', 'SCRATCHPAD_UNKNOWN_ERROR', 'SUCCESS', 'ScratchPadType', 'StateBlob', 'StateBlobError'] +class ADFunRegistrationResult: + """ + Members: + + SUCCESS + + ALREADY_REGISTERED + """ + ALREADY_REGISTERED: typing.ClassVar[ADFunRegistrationResult] # value = + SUCCESS: typing.ClassVar[ADFunRegistrationResult] # value = + __members__: typing.ClassVar[dict[str, ADFunRegistrationResult]] # value = {'SUCCESS': , 'ALREADY_REGISTERED': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class AdaptiveEngineViewScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def initialize(self, arg0: ...) -> None: + ... + def is_initialized(self) -> bool: + ... + @property + def active_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + ... + @property + def active_species(self) -> list[fourdst._phys.atomic.Species]: + ... + @property + def has_initialized(self) -> bool: + ... +class DefinedEngineViewScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def is_initialized(self) -> bool: + ... + @property + def active_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + ... + @property + def active_species(self) -> set[fourdst._phys.atomic.Species]: + ... + @property + def has_initialized(self) -> bool: + ... + @property + def reaction_index_map(self) -> list[int]: + ... + @property + def species_index_map(self) -> list[int]: + ... +class GraphEngineScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def initialize(self, engine: ...) -> None: + ... + def is_initialized(self) -> bool: + ... + @property + def has_initialized(self) -> bool: + ... + @property + def local_abundance_cache(self) -> list[float]: + ... + @property + def most_recent_rhs_calculation(self) -> ... | None: + ... + @property + def stepDerivativesCache(self) -> dict[int, ...]: + ... +class MultiscalePartitioningEngineViewScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def initialize(self) -> None: + ... + def is_initialized(self) -> bool: + ... + @property + def algebraic_species(self) -> list[fourdst._phys.atomic.Species]: + ... + @property + def composition_cache(self) -> dict[int, fourdst._phys.composition.Composition]: + ... + @property + def dynamic_species(self) -> list[fourdst._phys.atomic.Species]: + ... + @property + def has_initialized(self) -> bool: + ... + @property + def qse_groups(self) -> list[...]: + ... +class ScratchPadType: + """ + Members: + + GRAPH_ENGINE_SCRATCHPAD + + MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD + + ADAPTIVE_ENGINE_VIEW_SCRATCHPAD + + DEFINED_ENGINE_VIEW_SCRATCHPAD + """ + ADAPTIVE_ENGINE_VIEW_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + DEFINED_ENGINE_VIEW_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + GRAPH_ENGINE_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + __members__: typing.ClassVar[dict[str, ScratchPadType]] # value = {'GRAPH_ENGINE_SCRATCHPAD': , 'MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD': , 'ADAPTIVE_ENGINE_VIEW_SCRATCHPAD': , 'DEFINED_ENGINE_VIEW_SCRATCHPAD': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class StateBlob: + @staticmethod + def error_to_string(arg0: StateBlobError) -> str: + ... + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone_structure(self) -> StateBlob: + ... + def enroll(self, arg0: ScratchPadType) -> None: + ... + def get(self, arg0: ScratchPadType) -> ...: + ... + def get_registered_scratchpads(self) -> set[ScratchPadType]: + ... + def get_status(self, arg0: ScratchPadType) -> ...: + ... + def get_status_map(self) -> dict[ScratchPadType, ...]: + ... +class StateBlobError: + """ + Members: + + SCRATCHPAD_OUT_OF_BOUNDS + + SCRATCHPAD_NOT_FOUND + + SCRATCHPAD_BAD_CAST + + SCRATCHPAD_NOT_INITIALIZED + + SCRATCHPAD_TYPE_COLLISION + + SCRATCHPAD_UNKNOWN_ERROR + """ + SCRATCHPAD_BAD_CAST: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_NOT_FOUND: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_NOT_INITIALIZED: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_OUT_OF_BOUNDS: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_TYPE_COLLISION: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_UNKNOWN_ERROR: typing.ClassVar[StateBlobError] # value = + __members__: typing.ClassVar[dict[str, StateBlobError]] # value = {'SCRATCHPAD_OUT_OF_BOUNDS': , 'SCRATCHPAD_NOT_FOUND': , 'SCRATCHPAD_BAD_CAST': , 'SCRATCHPAD_NOT_INITIALIZED': , 'SCRATCHPAD_TYPE_COLLISION': , 'SCRATCHPAD_UNKNOWN_ERROR': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +ADAPTIVE_ENGINE_VIEW_SCRATCHPAD: ScratchPadType # value = +ALREADY_REGISTERED: ADFunRegistrationResult # value = +DEFINED_ENGINE_VIEW_SCRATCHPAD: ScratchPadType # value = +GRAPH_ENGINE_SCRATCHPAD: ScratchPadType # value = +MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD: ScratchPadType # value = +SCRATCHPAD_BAD_CAST: StateBlobError # value = +SCRATCHPAD_NOT_FOUND: StateBlobError # value = +SCRATCHPAD_NOT_INITIALIZED: StateBlobError # value = +SCRATCHPAD_OUT_OF_BOUNDS: StateBlobError # value = +SCRATCHPAD_TYPE_COLLISION: StateBlobError # value = +SCRATCHPAD_UNKNOWN_ERROR: StateBlobError # value = +SUCCESS: ADFunRegistrationResult # value = diff --git a/stubs/gridfire/_gridfire/exceptions.pyi b/stubs/gridfire/_gridfire/exceptions.pyi index bfcb1ea1..92796a95 100644 --- a/stubs/gridfire/_gridfire/exceptions.pyi +++ b/stubs/gridfire/_gridfire/exceptions.pyi @@ -2,7 +2,7 @@ GridFire exceptions bindings """ from __future__ import annotations -__all__: list[str] = ['BadCollectionError', 'BadRHSEngineError', 'CVODESolverFailureError', 'DebugException', 'EngineError', 'FailedToPartitionEngineError', 'GridFireError', 'HashingError', 'IllConditionedJacobianError', 'InvalidQSESolutionError', 'JacobianError', 'KINSolSolverFailureError', 'MissingBaseReactionError', 'MissingKeyReactionError', 'MissingSeedSpeciesError', 'NetworkResizedError', 'PolicyError', 'ReactionError', 'ReactionParsingError', 'SUNDIALSError', 'SingularJacobianError', 'SolverError', 'StaleJacobianError', 'UnableToSetNetworkReactionsError', 'UninitializedJacobianError', 'UnknownJacobianError', 'UtilityError'] +__all__: list[str] = ['BadCollectionError', 'BadRHSEngineError', 'CVODESolverFailureError', 'DebugException', 'EngineError', 'FailedToPartitionEngineError', 'GridFireError', 'HashingError', 'IllConditionedJacobianError', 'InvalidQSESolutionError', 'JacobianError', 'KINSolSolverFailureError', 'MissingBaseReactionError', 'MissingKeyReactionError', 'MissingSeedSpeciesError', 'NetworkResizedError', 'PolicyError', 'ReactionError', 'ReactionParsingError', 'SUNDIALSError', 'ScratchPadError', 'SingularJacobianError', 'SolverError', 'StaleJacobianError', 'UnableToSetNetworkReactionsError', 'UninitializedJacobianError', 'UnknownJacobianError', 'UtilityError'] class BadCollectionError(EngineError): pass class BadRHSEngineError(EngineError): @@ -43,6 +43,8 @@ class ReactionParsingError(ReactionError): pass class SUNDIALSError(SolverError): pass +class ScratchPadError(GridFireError): + pass class SingularJacobianError(SolverError): pass class SolverError(GridFireError): diff --git a/stubs/gridfire/_gridfire/policy.pyi b/stubs/gridfire/_gridfire/policy.pyi index b5bf1af1..3a5c89b9 100644 --- a/stubs/gridfire/_gridfire/policy.pyi +++ b/stubs/gridfire/_gridfire/policy.pyi @@ -6,9 +6,11 @@ import collections.abc import fourdst._phys.atomic import fourdst._phys.composition import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads +import gridfire._gridfire.partition import gridfire._gridfire.reaction import typing -__all__: list[str] = ['CNOChainPolicy', 'CNOIChainPolicy', 'CNOIIChainPolicy', 'CNOIIIChainPolicy', 'CNOIVChainPolicy', 'HotCNOChainPolicy', 'HotCNOIChainPolicy', 'HotCNOIIChainPolicy', 'HotCNOIIIChainPolicy', 'INITIALIZED_UNVERIFIED', 'INITIALIZED_VERIFIED', 'MISSING_KEY_REACTION', 'MISSING_KEY_SPECIES', 'MainSequencePolicy', 'MainSequenceReactionChainPolicy', 'MultiReactionChainPolicy', 'NetworkPolicy', 'NetworkPolicyStatus', 'ProtonProtonChainPolicy', 'ProtonProtonIChainPolicy', 'ProtonProtonIIChainPolicy', 'ProtonProtonIIIChainPolicy', 'ReactionChainPolicy', 'TemperatureDependentChainPolicy', 'TripleAlphaChainPolicy', 'UNINITIALIZED'] +__all__: list[str] = ['CNOChainPolicy', 'CNOIChainPolicy', 'CNOIIChainPolicy', 'CNOIIIChainPolicy', 'CNOIVChainPolicy', 'ConstructionResults', 'HotCNOChainPolicy', 'HotCNOIChainPolicy', 'HotCNOIIChainPolicy', 'HotCNOIIIChainPolicy', 'INITIALIZED_UNVERIFIED', 'INITIALIZED_VERIFIED', 'MISSING_KEY_REACTION', 'MISSING_KEY_SPECIES', 'MainSequencePolicy', 'MainSequenceReactionChainPolicy', 'MultiReactionChainPolicy', 'NetworkPolicy', 'NetworkPolicyStatus', 'ProtonProtonChainPolicy', 'ProtonProtonIChainPolicy', 'ProtonProtonIIChainPolicy', 'ProtonProtonIIIChainPolicy', 'ReactionChainPolicy', 'TemperatureDependentChainPolicy', 'TripleAlphaChainPolicy', 'UNINITIALIZED', 'network_policy_status_to_string'] class CNOChainPolicy(MultiReactionChainPolicy): def __eq__(self, other: ReactionChainPolicy) -> bool: """ @@ -224,6 +226,13 @@ class CNOIVChainPolicy(TemperatureDependentChainPolicy): """ Get the name of the reaction chain policy. """ +class ConstructionResults: + @property + def engine(self) -> gridfire._gridfire.engine.DynamicEngine: + ... + @property + def scratch_blob(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... class HotCNOChainPolicy(MultiReactionChainPolicy): def __eq__(self, other: ReactionChainPolicy) -> bool: """ @@ -407,14 +416,18 @@ class MainSequencePolicy(NetworkPolicy): """ Construct MainSequencePolicy from seed species and mass fractions. """ - def construct(self) -> gridfire._gridfire.engine.DynamicEngine: + def construct(self) -> ConstructionResults: """ Construct the network according to the policy. """ + def get_engine_stack(self) -> list[gridfire._gridfire.engine.DynamicEngine]: + ... def get_engine_types_stack(self) -> list[gridfire._gridfire.engine.EngineTypes]: """ Get the types of engines in the stack constructed by the network policy. """ + def get_partition_function(self) -> gridfire._gridfire.partition.PartitionFunction: + ... def get_seed_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: """ Get the set of seed reactions required by the network policy. @@ -423,6 +436,8 @@ class MainSequencePolicy(NetworkPolicy): """ Get the set of seed species required by the network policy. """ + def get_stack_scratch_blob(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... def get_status(self) -> NetworkPolicyStatus: """ Get the current status of the network policy. @@ -743,6 +758,10 @@ class TripleAlphaChainPolicy(TemperatureDependentChainPolicy): """ Get the name of the reaction chain policy. """ +def network_policy_status_to_string(status: NetworkPolicyStatus) -> str: + """ + Convert a NetworkPolicyStatus enum value to its string representation. + """ INITIALIZED_UNVERIFIED: NetworkPolicyStatus # value = INITIALIZED_VERIFIED: NetworkPolicyStatus # value = MISSING_KEY_REACTION: NetworkPolicyStatus # value = diff --git a/stubs/gridfire/_gridfire/solver.pyi b/stubs/gridfire/_gridfire/solver.pyi index ee9938ef..44ae0beb 100644 --- a/stubs/gridfire/_gridfire/solver.pyi +++ b/stubs/gridfire/_gridfire/solver.pyi @@ -5,47 +5,113 @@ from __future__ import annotations import collections.abc import fourdst._phys.atomic import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads import gridfire._gridfire.type +import types import typing -__all__: list[str] = ['CVODESolverStrategy', 'CVODETimestepContext', 'DynamicNetworkSolverStrategy', 'SolverContextBase'] -class CVODESolverStrategy(DynamicNetworkSolverStrategy): - def __init__(self, engine: gridfire._gridfire.engine.DynamicEngine) -> None: +__all__: list[str] = ['GridSolver', 'GridSolverContext', 'MultiZoneDynamicNetworkSolver', 'PointSolver', 'PointSolverContext', 'PointSolverTimestepContext', 'SingleZoneDynamicNetworkSolver', 'SolverContextBase'] +class GridSolver(MultiZoneDynamicNetworkSolver): + def __init__(self, engine: gridfire._gridfire.engine.DynamicEngine, solver: SingleZoneDynamicNetworkSolver) -> None: """ - Initialize the CVODESolverStrategy object. + Initialize the GridSolver object. """ - def evaluate(self, netIn: gridfire._gridfire.type.NetIn, display_trigger: bool = False) -> gridfire._gridfire.type.NetOut: + def evaluate(self, solver_ctx: SolverContextBase, netIns: collections.abc.Sequence[gridfire._gridfire.type.NetIn]) -> list[gridfire._gridfire.type.NetOut]: """ evaluate the dynamic engine using the dynamic engine class """ - def get_absTol(self) -> float: +class GridSolverContext(SolverContextBase): + detailed_logging: bool + stdout_logging: bool + zone_completion_logging: bool + def __init__(self, ctx_template: gridfire._gridfire.engine.scratchpads.StateBlob) -> None: + ... + @typing.overload + def clear_callback(self) -> None: + ... + @typing.overload + def clear_callback(self, zone_idx: typing.SupportsInt) -> None: + ... + def init(self) -> None: + ... + def reset(self) -> None: + ... + @typing.overload + def set_callback(self, callback: collections.abc.Callable[[...], None]) -> None: + ... + @typing.overload + def set_callback(self, callback: collections.abc.Callable[[...], None], zone_idx: typing.SupportsInt) -> None: + ... +class MultiZoneDynamicNetworkSolver: + def evaluate(self, solver_ctx: SolverContextBase, netIns: collections.abc.Sequence[gridfire._gridfire.type.NetIn]) -> list[gridfire._gridfire.type.NetOut]: """ - Get the absolute tolerance for the CVODE solver. + evaluate the dynamic engine using the dynamic engine class for multiple zones (using openmp if available) """ - def get_relTol(self) -> float: +class PointSolver(SingleZoneDynamicNetworkSolver): + def __init__(self, engine: gridfire._gridfire.engine.DynamicEngine) -> None: """ - Get the relative tolerance for the CVODE solver. + Initialize the PointSolver object. """ - def get_stdout_logging_enabled(self) -> bool: + def evaluate(self, solver_ctx: SolverContextBase, netIn: gridfire._gridfire.type.NetIn, display_trigger: bool = False, force_reinitialization: bool = False) -> gridfire._gridfire.type.NetOut: """ - Check if solver logging to standard output is enabled. + evaluate the dynamic engine using the dynamic engine class """ - def set_absTol(self, absTol: typing.SupportsFloat) -> None: - """ - Set the absolute tolerance for the CVODE solver. - """ - def set_callback(self, cb: collections.abc.Callable[[CVODETimestepContext], None]) -> None: - """ - Set a callback function which will run at the end of every successful timestep - """ - def set_relTol(self, relTol: typing.SupportsFloat) -> None: - """ - Set the relative tolerance for the CVODE solver. - """ - def set_stdout_logging_enabled(self, logging_enabled: bool) -> None: - """ - Enable logging to standard output. - """ -class CVODETimestepContext(SolverContextBase): +class PointSolverContext: + callback: collections.abc.Callable[[PointSolverTimestepContext], None] | None + detailed_logging: bool + stdout_logging: bool + def __init__(self, engine_ctx: gridfire._gridfire.engine.scratchpads.StateBlob) -> None: + ... + def clear_context(self) -> None: + ... + def has_context(self) -> bool: + ... + def init(self) -> None: + ... + def init_context(self) -> None: + ... + def reset_all(self) -> None: + ... + def reset_cvode(self) -> None: + ... + def reset_user(self) -> None: + ... + @property + def J(self) -> _generic_SUNMatrix: + ... + @property + def LS(self) -> _generic_SUNLinearSolver: + ... + @property + def Y(self) -> _generic_N_Vector: + ... + @property + def YErr(self) -> _generic_N_Vector: + ... + @property + def abs_tol(self) -> float: + ... + @abs_tol.setter + def abs_tol(self, arg1: typing.SupportsFloat) -> None: + ... + @property + def cvode_mem(self) -> types.CapsuleType: + ... + @property + def engine_ctx(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... + @property + def num_steps(self) -> int: + ... + @property + def rel_tol(self) -> float: + ... + @rel_tol.setter + def rel_tol(self, arg1: typing.SupportsFloat) -> None: + ... + @property + def sun_ctx(self) -> SUNContext_: + ... +class PointSolverTimestepContext: @property def T9(self) -> float: ... @@ -77,16 +143,15 @@ class CVODETimestepContext(SolverContextBase): def state(self) -> list[float]: ... @property + def state_ctx(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... + @property def t(self) -> float: ... -class DynamicNetworkSolverStrategy: - def describe_callback_context(self) -> list[tuple[str, str]]: +class SingleZoneDynamicNetworkSolver: + def evaluate(self, solver_ctx: SolverContextBase, netIn: gridfire._gridfire.type.NetIn) -> gridfire._gridfire.type.NetOut: """ - Get a structure representing what data is in the callback context in a human readable format - """ - def evaluate(self, netIn: gridfire._gridfire.type.NetIn) -> gridfire._gridfire.type.NetOut: - """ - evaluate the dynamic engine using the dynamic engine class + evaluate the dynamic engine using the dynamic engine class for a single zone """ class SolverContextBase: pass diff --git a/stubs/gridfire/_gridfire/type.pyi b/stubs/gridfire/_gridfire/type.pyi index 45332f62..739086da 100644 --- a/stubs/gridfire/_gridfire/type.pyi +++ b/stubs/gridfire/_gridfire/type.pyi @@ -59,3 +59,9 @@ class NetOut: @property def num_steps(self) -> int: ... + @property + def specific_neutrino_energy_loss(self) -> float: + ... + @property + def specific_neutrino_flux(self) -> float: + ... diff --git a/stubs/gridfire/_gridfire/utils/__init__.pyi b/stubs/gridfire/_gridfire/utils/__init__.pyi index d8738d61..0a86e92c 100644 --- a/stubs/gridfire/_gridfire/utils/__init__.pyi +++ b/stubs/gridfire/_gridfire/utils/__init__.pyi @@ -4,10 +4,11 @@ GridFire utility method bindings from __future__ import annotations import fourdst._phys.composition import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads import typing from . import hashing __all__: list[str] = ['formatNuclearTimescaleLogString', 'hash_atomic', 'hash_reaction', 'hashing'] -def formatNuclearTimescaleLogString(engine: gridfire._gridfire.engine.DynamicEngine, Y: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> str: +def formatNuclearTimescaleLogString(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, Y: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> str: """ Format a string for logging nuclear timescales based on temperature, density, and energy generation rate. """ diff --git a/stubs/gridfiregridfire/__init__.pyi b/stubs/gridfiregridfire/__init__.pyi new file mode 100644 index 00000000..a5db9463 --- /dev/null +++ b/stubs/gridfiregridfire/__init__.pyi @@ -0,0 +1,42 @@ +from __future__ import annotations +from gridfire._gridfire import config +from gridfire._gridfire import engine +from gridfire._gridfire import exceptions +from gridfire._gridfire import io +from gridfire._gridfire import partition +from gridfire._gridfire import policy +from gridfire._gridfire import reaction +from gridfire._gridfire import screening +from gridfire._gridfire import solver +from gridfire._gridfire import type +from gridfire._gridfire import utils +import importlib as importlib +import sys as sys +from . import _gridfire +__all__: list = ['type', 'utils', 'engine', 'solver', 'exceptions', 'partition', 'reaction', 'screening', 'io', 'policy', 'config'] +def gf_author(): + ... +def gf_collaboration(): + ... +def gf_credits(): + ... +def gf_description(): + ... +def gf_email(): + ... +def gf_license(): + ... +def gf_metadata(): + ... +def gf_url(): + ... +def gf_version(): + ... +__author__ = None +__description__: str = 'Python interface to the GridFire nuclear network code' +__email__: str = '"Emily M. Boudreaux" , Aaron Dotter ' +__license__: str = 'GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. \n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n Preamble\n\n The GNU General Public License is a free, copyleft license for\n software and other kinds of works.\n\n The licenses for most software and other practical works are designed\n to take away your freedom to share and change the works. By contrast,\n the GNU General Public License is intended to guarantee your freedom to\n share and change all versions of a program--to make sure it remains free\n software for all its users. We, the Free Software Foundation, use the\n GNU General Public License for most of our software; it applies also to\n any other work released this way by its authors. You can apply it to\n your programs, too.\n\n When we speak of free software, we are referring to freedom, not\n price. Our General Public Licenses are designed to make sure that you\n have the freedom to distribute copies of free software (and charge for\n them if you wish), that you receive source code or can get it if you\n want it, that you can change the software or use pieces of it in new\n free programs, and that you know you can do these things.\n\n To protect your rights, we need to prevent others from denying you\n these rights or asking you to surrender the rights. Therefore, you have\n certain responsibilities if you distribute copies of the software, or if\n you modify it: responsibilities to respect the freedom of others.\n\n For example, if you distribute copies of such a program, whether\n gratis or for a fee, you must pass on to the recipients the same\n freedoms that you received. You must make sure that they, too, receive\n or can get the source code. And you must show them these terms so they\n know their rights.\n\n Developers that use the GNU GPL protect your rights with two steps:\n (1) assert copyright on the software, and (2) offer you this License\n giving you legal permission to copy, distribute and/or modify it.\n\n For the developers\' and authors\' protection, the GPL clearly explains\n that there is no warranty for this free software. For both users\' and\n authors\' sake, the GPL requires that modified versions be marked as\n changed, so that their problems will not be attributed erroneously to\n authors of previous versions.\n\n Some devices are designed to deny users access to install or run\n modified versions of the software inside them, although the manufacturer\n can do so. This is fundamentally incompatible with the aim of\n protecting users\' freedom to change the software. The systematic\n pattern of such abuse occurs in the area of products for individuals to\n use, which is precisely where it is most unacceptable. Therefore, we\n have designed this version of the GPL to prohibit the practice for those\n products. If such problems arise substantially in other domains, we\n stand ready to extend this provision to those domains in future versions\n of the GPL, as needed to protect the freedom of users.\n\n Finally, every program is threatened constantly by software patents.\n States should not allow patents to restrict development and use of\n software on general-purpose computers, but in those that do, we wish to\n avoid the special danger that patents applied to a free program could\n make it effectively proprietary. To prevent this, the GPL assures that\n patents cannot be used to render the program non-free.\n\n The precise terms and conditions for copying, distribution and\n modification follow.\n\n TERMS AND CONDITIONS\n\n 0. Definitions.\n\n "This License" refers to version 3 of the GNU General Public License.\n\n "Copyright" also means copyright-like laws that apply to other kinds of\n works, such as semiconductor masks.\n\n "The Program" refers to any copyrightable work licensed under this\n License. Each licensee is addressed as "you". "Licensees" and\n "recipients" may be individuals or organizations.\n\n To "modify" a work means to copy from or adapt all or part of the work\n in a fashion requiring copyright permission, other than the making of an\n exact copy. The resulting work is called a "modified version" of the\n earlier work or a work "based on" the earlier work.\n\n A "covered work" means either the unmodified Program or a work based\n on the Program.\n\n To "propagate" a work means to do anything with it that, without\n permission, would make you directly or secondarily liable for\n infringement under applicable copyright law, except executing it on a\n computer or modifying a private copy. Propagation includes copying,\n distribution (with or without modification), making available to the\n public, and in some countries other activities as well.\n\n To "convey" a work means any kind of propagation that enables other\n parties to make or receive copies. Mere interaction with a user through\n a computer network, with no transfer of a copy, is not conveying.\n\n An interactive user interface displays "Appropriate Legal Notices"\n to the extent that it includes a convenient and prominently visible\n feature that (1) displays an appropriate copyright notice, and (2)\n tells the user that there is no warranty for the work (except to the\n extent that warranties are provided), that licensees may convey the\n work under this License, and how to view a copy of this License. If\n the interface presents a list of user commands or options, such as a\n menu, a prominent item in the list meets this criterion.\n\n 1. Source Code.\n\n The "source code" for a work means the preferred form of the work\n for making modifications to it. "Object code" means any non-source\n form of a work.\n\n A "Standard Interface" means an interface that either is an official\n standard defined by a recognized standards body, or, in the case of\n interfaces specified for a particular programming language, one that\n is widely used among developers working in that language.\n\n The "System Libraries" of an executable work include anything, other\n than the work as a whole, that (a) is included in the normal form of\n packaging a Major Component, but which is not part of that Major\n Component, and (b) serves only to enable use of the work with that\n Major Component, or to implement a Standard Interface for which an\n implementation is available to the public in source code form. A\n "Major Component", in this context, means a major essential component\n (kernel, window system, and so on) of the specific operating system\n (if any) on which the executable work runs, or a compiler used to\n produce the work, or an object code interpreter used to run it.\n\n The "Corresponding Source" for a work in object code form means all\n the source code needed to generate, install, and (for an executable\n work) run the object code and to modify the work, including scripts to\n control those activities. However, it does not include the work\'s\n System Libraries, or general-purpose tools or generally available free\n programs which are used unmodified in performing those activities but\n which are not part of the work. For example, Corresponding Source\n includes interface definition files associated with source files for\n the work, and the source code for shared libraries and dynamically\n linked subprograms that the work is specifically designed to require,\n such as by intimate data communication or control flow between those\n subprograms and other parts of the work.\n\n The Corresponding Source need not include anything that users\n can regenerate automatically from other parts of the Corresponding\n Source.\n\n The Corresponding Source for a work in source code form is that\n same work.\n\n 2. Basic Permissions.\n\n All rights granted under this License are granted for the term of\n copyright on the Program, and are irrevocable provided the stated\n conditions are met. This License explicitly affirms your unlimited\n permission to run the unmodified Program. The output from running a\n covered work is covered by this License only if the output, given its\n content, constitutes a covered work. This License acknowledges your\n rights of fair use or other equivalent, as provided by copyright law.\n\n You may make, run and propagate covered works that you do not\n convey, without conditions so long as your license otherwise remains\n in force. You may convey covered works to others for the sole purpose\n of having them make modifications exclusively for you, or provide you\n with facilities for running those works, provided that you comply with\n the terms of this License in conveying all material for which you do\n not control copyright. Those thus making or running the covered works\n for you must do so exclusively on your behalf, under your direction\n and control, on terms that prohibit them from making any copies of\n your copyrighted material outside their relationship with you.\n\n Conveying under any other circumstances is permitted solely under\n the conditions stated below. Sublicensing is not allowed; section 10\n makes it unnecessary.\n\n 3. Protecting Users\' Legal Rights From Anti-Circumvention Law.\n\n No covered work shall be deemed part of an effective technological\n measure under any applicable law fulfilling obligations under article\n 11 of the WIPO copyright treaty adopted on 20 December 1996, or\n similar laws prohibiting or restricting circumvention of such\n measures.\n\n When you convey a covered work, you waive any legal power to forbid\n circumvention of technological measures to the extent such circumvention\n is effected by exercising rights under this License with respect to\n the covered work, and you disclaim any intention to limit operation or\n modification of the work as a means of enforcing, against the work\'s\n users, your or third parties\' legal rights to forbid circumvention of\n technological measures.\n\n 4. Conveying Verbatim Copies.\n\n You may convey verbatim copies of the Program\'s source code as you\n receive it, in any medium, provided that you conspicuously and\n appropriately publish on each copy an appropriate copyright notice;\n keep intact all notices stating that this License and any\n non-permissive terms added in accord with section 7 apply to the code;\n keep intact all notices of the absence of any warranty; and give all\n recipients a copy of this License along with the Program.\n\n You may charge any price or no price for each copy that you convey,\n and you may offer support or warranty protection for a fee.\n\n 5. Conveying Modified Source Versions.\n\n You may convey a work based on the Program, or the modifications to\n produce it from the Program, in the form of source code under the\n terms of section 4, provided that you also meet all of these conditions:\n\n a) The work must carry prominent notices stating that you modified\n it, and giving a relevant date.\n\n b) The work must carry prominent notices stating that it is\n released under this License and any conditions added under section\n 7. This requirement modifies the requirement in section 4 to\n "keep intact all notices".\n\n c) You must license the entire work, as a whole, under this\n License to anyone who comes into possession of a copy. This\n License will therefore apply, along with any applicable section 7\n additional terms, to the whole of the work, and all its parts,\n regardless of how they are packaged. This License gives no\n permission to license the work in any other way, but it does not\n invalidate such permission if you have separately received it.\n\n d) If the work has interactive user interfaces, each must display\n Appropriate Legal Notices; however, if the Program has interactive\n interfaces that do not display Appropriate Legal Notices, your\n work need not make them do so.\n\n A compilation of a covered work with other separate and independent\n works, which are not by their nature extensions of the covered work,\n and which are not combined with it such as to form a larger program,\n in or on a volume of a storage or distribution medium, is called an\n "aggregate" if the compilation and its resulting copyright are not\n used to limit the access or legal rights of the compilation\'s users\n beyond what the individual works permit. Inclusion of a covered work\n in an aggregate does not cause this License to apply to the other\n parts of the aggregate.\n\n 6. Conveying Non-Source Forms.\n\n You may convey a covered work in object code form under the terms\n of sections 4 and 5, provided that you also convey the\n machine-readable Corresponding Source under the terms of this License,\n in one of these ways:\n\n a) Convey the object code in, or embodied in, a physical product\n (including a physical distribution medium), accompanied by the\n Corresponding Source fixed on a durable physical medium\n customarily used for software interchange.\n\n b) Convey the object code in, or embodied in, a physical product\n (including a physical distribution medium), accompanied by a\n written offer, valid for at least three years and valid for as\n long as you offer spare parts or customer support for that product\n model, to give anyone who possesses the object code either (1) a\n copy of the Corresponding Source for all the software in the\n product that is covered by this License, on a durable physical\n medium customarily used for software interchange, for a price no\n more than your reasonable cost of physically performing this\n conveying of source, or (2) access to copy the\n Corresponding Source from a network server at no charge.\n\n c) Convey individual copies of the object code with a copy of the\n written offer to provide the Corresponding Source. This\n alternative is allowed only occasionally and noncommercially, and\n only if you received the object code with such an offer, in accord\n with subsection 6b.\n\n d) Convey the object code by offering access from a designated\n place (gratis or for a charge), and offer equivalent access to the\n Corresponding Source in the same way through the same place at no\n further charge. You need not require recipients to copy the\n Corresponding Source along with the object code. If the place to\n copy the object code is a network server, the Corresponding Source\n may be on a different server (operated by you or a third party)\n that supports equivalent copying facilities, provided you maintain\n clear directions next to the object code saying where to find the\n Corresponding Source. Regardless of what server hosts the\n Corresponding Source, you remain obligated to ensure that it is\n available for as long as needed to satisfy these requirements.\n\n e) Convey the object code using peer-to-peer transmission, provided\n you inform other peers where the object code and Corresponding\n Source of the work are being offered to the general public at no\n charge under subsection 6d.\n\n A separable portion of the object code, whose source code is excluded\n from the Corresponding Source as a System Library, need not be\n included in conveying the object code work.\n\n A "User Product" is either (1) a "consumer product", which means any\n tangible personal property which is normally used for personal, family,\n or household purposes, or (2) anything designed or sold for incorporation\n into a dwelling. In determining whether a product is a consumer product,\n doubtful cases shall be resolved in favor of coverage. For a particular\n product received by a particular user, "normally used" refers to a\n typical or common use of that class of product, regardless of the status\n of the particular user or of the way in which the particular user\n actually uses, or expects or is expected to use, the product. A product\n is a consumer product regardless of whether the product has substantial\n commercial, industrial or non-consumer uses, unless such uses represent\n the only significant mode of use of the product.\n\n "Installation Information" for a User Product means any methods,\n procedures, authorization keys, or other information required to install\n and execute modified versions of a covered work in that User Product from\n a modified version of its Corresponding Source. The information must\n suffice to ensure that the continued functioning of the modified object\n code is in no case prevented or interfered with solely because\n modification has been made.\n\n If you convey an object code work under this section in, or with, or\n specifically for use in, a User Product, and the conveying occurs as\n part of a transaction in which the right of possession and use of the\n User Product is transferred to the recipient in perpetuity or for a\n fixed term (regardless of how the transaction is characterized), the\n Corresponding Source conveyed under this section must be accompanied\n by the Installation Information. But this requirement does not apply\n if neither you nor any third party retains the ability to install\n modified object code on the User Product (for example, the work has\n been installed in ROM).\n\n The requirement to provide Installation Information does not include a\n requirement to continue to provide support service, warranty, or updates\n for a work that has been modified or installed by the recipient, or for\n the User Product in which it has been modified or installed. Access to a\n network may be denied when the modification itself materially and\n adversely affects the operation of the network or violates the rules and\n protocols for communication across the network.\n\n Corresponding Source conveyed, and Installation Information provided,\n in accord with this section must be in a format that is publicly\n documented (and with an implementation available to the public in\n source code form), and must require no special password or key for\n unpacking, reading or copying.\n\n 7. Additional Terms.\n\n "Additional permissions" are terms that supplement the terms of this\n License by making exceptions from one or more of its conditions.\n Additional permissions that are applicable to the entire Program shall\n be treated as though they were included in this License, to the extent\n that they are valid under applicable law. If additional permissions\n apply only to part of the Program, that part may be used separately\n under those permissions, but the entire Program remains governed by\n this License without regard to the additional permissions.\n\n When you convey a copy of a covered work, you may at your option\n remove any additional permissions from that copy, or from any part of\n it. (Additional permissions may be written to require their own\n removal in certain cases when you modify the work.) You may place\n additional permissions on material, added by you to a covered work,\n for which you have or can give appropriate copyright permission.\n\n Notwithstanding any other provision of this License, for material you\n add to a covered work, you may (if authorized by the copyright holders of\n that material) supplement the terms of this License with terms:\n\n a) Disclaiming warranty or limiting liability differently from the\n terms of sections 15 and 16 of this License; or\n\n b) Requiring preservation of specified reasonable legal notices or\n author attributions in that material or in the Appropriate Legal\n Notices displayed by works containing it; or\n\n c) Prohibiting misrepresentation of the origin of that material, or\n requiring that modified versions of such material be marked in\n reasonable ways as different from the original version; or\n\n d) Limiting the use for publicity purposes of names of licensors or\n authors of the material; or\n\n e) Declining to grant rights under trademark law for use of some\n trade names, trademarks, or service marks; or\n\n f) Requiring indemnification of licensors and authors of that\n material by anyone who conveys the material (or modified versions of\n it) with contractual assumptions of liability to the recipient, for\n any liability that these contractual assumptions directly impose on\n those licensors and authors.\n\n All other non-permissive additional terms are considered "further\n restrictions" within the meaning of section 10. If the Program as you\n received it, or any part of it, contains a notice stating that it is\n governed by this License along with a term that is a further\n restriction, you may remove that term. If a license document contains\n a further restriction but permits relicensing or conveying under this\n License, you may add to a covered work material governed by the terms\n of that license document, provided that the further restriction does\n not survive such relicensing or conveying.\n\n If you add terms to a covered work in accord with this section, you\n must place, in the relevant source files, a statement of the\n additional terms that apply to those files, or a notice indicating\n where to find the applicable terms.\n\n Additional terms, permissive or non-permissive, may be stated in the\n form of a separately written license, or stated as exceptions;\n the above requirements apply either way.\n\n 8. Termination.\n\n You may not propagate or modify a covered work except as expressly\n provided under this License. Any attempt otherwise to propagate or\n modify it is void, and will automatically terminate your rights under\n this License (including any patent licenses granted under the third\n paragraph of section 11).\n\n However, if you cease all violation of this License, then your\n license from a particular copyright holder is reinstated (a)\n provisionally, unless and until the copyright holder explicitly and\n finally terminates your license, and (b) permanently, if the copyright\n holder fails to notify you of the violation by some reasonable means\n prior to 60 days after the cessation.\n\n Moreover, your license from a particular copyright holder is\n reinstated permanently if the copyright holder notifies you of the\n violation by some reasonable means, this is the first time you have\n received notice of violation of this License (for any work) from that\n copyright holder, and you cure the violation prior to 30 days after\n your receipt of the notice.\n\n Termination of your rights under this section does not terminate the\n licenses of parties who have received copies or rights from you under\n this License. If your rights have been terminated and not permanently\n reinstated, you do not qualify to receive new licenses for the same\n material under section 10.\n\n 9. Acceptance Not Required for Having Copies.\n\n You are not required to accept this License in order to receive or\n run a copy of the Program. Ancillary propagation of a covered work\n occurring solely as a consequence of using peer-to-peer transmission\n to receive a copy likewise does not require acceptance. However,\n nothing other than this License grants you permission to propagate or\n modify any covered work. These actions infringe copyright if you do\n not accept this License. Therefore, by modifying or propagating a\n covered work, you indicate your acceptance of this License to do so.\n\n 10. Automatic Licensing of Downstream Recipients.\n\n Each time you convey a covered work, the recipient automatically\n receives a license from the original licensors, to run, modify and\n propagate that work, subject to this License. You are not responsible\n for enforcing compliance by third parties with this License.\n\n An "entity transaction" is a transaction transferring control of an\n organization, or substantially all assets of one, or subdividing an\n organization, or merging organizations. If propagation of a covered\n work results from an entity transaction, each party to that\n transaction who receives a copy of the work also receives whatever\n licenses to the work the party\'s predecessor in interest had or could\n give under the previous paragraph, plus a right to possession of the\n Corresponding Source of the work from the predecessor in interest, if\n the predecessor has it or can get it with reasonable efforts.\n\n You may not impose any further restrictions on the exercise of the\n rights granted or affirmed under this License. For example, you may\n not impose a license fee, royalty, or other charge for exercise of\n rights granted under this License, and you may not initiate litigation\n (including a cross-claim or counterclaim in a lawsuit) alleging that\n any patent claim is infringed by making, using, selling, offering for\n sale, or importing the Program or any portion of it.\n\n 11. Patents.\n\n A "contributor" is a copyright holder who authorizes use under this\n License of the Program or a work on which the Program is based. The\n work thus licensed is called the contributor\'s "contributor version".\n\n A contributor\'s "essential patent claims" are all patent claims\n owned or controlled by the contributor, whether already acquired or\n hereafter acquired, that would be infringed by some manner, permitted\n by this License, of making, using, or selling its contributor version,\n but do not include claims that would be infringed only as a\n consequence of further modification of the contributor version. For\n purposes of this definition, "control" includes the right to grant\n patent sublicenses in a manner consistent with the requirements of\n this License.\n\n Each contributor grants you a non-exclusive, worldwide, royalty-free\n patent license under the contributor\'s essential patent claims, to\n make, use, sell, offer for sale, import and otherwise run, modify and\n propagate the contents of its contributor version.\n\n In the following three paragraphs, a "patent license" is any express\n agreement or commitment, however denominated, not to enforce a patent\n (such as an express permission to practice a patent or covenant not to\n sue for patent infringement). To "grant" such a patent license to a\n party means to make such an agreement or commitment not to enforce a\n patent against the party.\n\n If you convey a covered work, knowingly relying on a patent license,\n and the Corresponding Source of the work is not available for anyone\n to copy, free of charge and under the terms of this License, through a\n publicly available network server or other readily accessible means,\n then you must either (1) cause the Corresponding Source to be so\n available, or (2) arrange to deprive yourself of the benefit of the\n patent license for this particular work, or (3) arrange, in a manner\n consistent with the requirements of this License, to extend the patent\n license to downstream recipients. "Knowingly relying" means you have\n actual knowledge that, but for the patent license, your conveying the\n covered work in a country, or your recipient\'s use of the covered work\n in a country, would infringe one or more identifiable patents in that\n country that you have reason to believe are valid.\n\n If, pursuant to or in connection with a single transaction or\n arrangement, you convey, or propagate by procuring conveyance of, a\n covered work, and grant a patent license to some of the parties\n receiving the covered work authorizing them to use, propagate, modify\n or convey a specific copy of the covered work, then the patent license\n you grant is automatically extended to all recipients of the covered\n work and works based on it.\n\n A patent license is "discriminatory" if it does not include within\n the scope of its coverage, prohibits the exercise of, or is\n conditioned on the non-exercise of one or more of the rights that are\n specifically granted under this License. You may not convey a covered\n work if you are a party to an arrangement with a third party that is\n in the business of distributing software, under which you make payment\n to the third party based on the extent of your activity of conveying\n the work, and under which the third party grants, to any of the\n parties who would receive the covered work from you, a discriminatory\n patent license (a) in connection with copies of the covered work\n conveyed by you (or copies made from those copies), or (b) primarily\n for and in connection with specific products or compilations that\n contain the covered work, unless you entered into that arrangement,\n or that patent license was granted, prior to 28 March 2007.\n\n Nothing in this License shall be construed as excluding or limiting\n any implied license or other defenses to infringement that may\n otherwise be available to you under applicable patent law.\n\n 12. No Surrender of Others\' Freedom.\n\n If conditions are imposed on you (whether by court order, agreement or\n otherwise) that contradict the conditions of this License, they do not\n excuse you from the conditions of this License. If you cannot convey a\n covered work so as to satisfy simultaneously your obligations under this\n License and any other pertinent obligations, then as a consequence you may\n not convey it at all. For example, if you agree to terms that obligate you\n to collect a royalty for further conveying from those to whom you convey\n the Program, the only way you could satisfy both those terms and this\n License would be to refrain entirely from conveying the Program.\n\n 13. Use with the GNU Affero General Public License.\n\n Notwithstanding any other provision of this License, you have\n permission to link or combine any covered work with a work licensed\n under version 3 of the GNU Affero General Public License into a single\n combined work, and to convey the resulting work. The terms of this\n License will continue to apply to the part which is the covered work,\n but the special requirements of the GNU Affero General Public License,\n section 13, concerning interaction through a network will apply to the\n combination as such.\n\n 14. Revised Versions of this License.\n\n The Free Software Foundation may publish revised and/or new versions of\n the GNU General Public License from time to time. Such new versions will\n be similar in spirit to the present version, but may differ in detail to\n address new problems or concerns.\n\n Each version is given a distinguishing version number. If the\n Program specifies that a certain numbered version of the GNU General\n Public License "or any later version" applies to it, you have the\n option of following the terms and conditions either of that numbered\n version or of any later version published by the Free Software\n Foundation. If the Program does not specify a version number of the\n GNU General Public License, you may choose any version ever published\n by the Free Software Foundation.\n\n If the Program specifies that a proxy can decide which future\n versions of the GNU General Public License can be used, that proxy\'s\n public statement of acceptance of a version permanently authorizes you\n to choose that version for the Program.\n\n Later license versions may give you additional or different\n permissions. However, no additional obligations are imposed on any\n author or copyright holder as a result of your choosing to follow a\n later version.\n\n 15. Disclaimer of Warranty.\n\n THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\n APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\n HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY\n OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\n THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\n IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\n ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n 16. Limitation of Liability.\n\n IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\n THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\n GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\n USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\n DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\n PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\n EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\n SUCH DAMAGES.\n\n 17. Interpretation of Sections 15 and 16.\n\n If the disclaimer of warranty and limitation of liability provided\n above cannot be given local legal effect according to their terms,\n reviewing courts shall apply local law that most closely approximates\n an absolute waiver of all civil liability in connection with the\n Program, unless a warranty or assumption of liability accompanies a\n copy of the Program in return for a fee.\n\n END OF TERMS AND CONDITIONS\n\n How to Apply These Terms to Your New Programs\n\n If you develop a new program, and you want it to be of the greatest\n possible use to the public, the best way to achieve this is to make it\n free software which everyone can redistribute and change under these terms.\n\n To do so, attach the following notices to the program. It is safest\n to attach them to the start of each source file to most effectively\n state the exclusion of warranty; and each file should have at least\n the "copyright" line and a pointer to where the full notice is found.\n\n \n Copyright (C) \n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see .\n\n Also add information on how to contact you by electronic and paper mail.\n\n If the program does terminal interaction, make it output a short\n notice like this when it starts in an interactive mode:\n\n Copyright (C) \n This program comes with ABSOLUTELY NO WARRANTY; for details type `show w\'.\n This is free software, and you are welcome to redistribute it\n under certain conditions; type `show c\' for details.\n\n The hypothetical commands `show w\' and `show c\' should show the appropriate\n parts of the General Public License. Of course, your program\'s commands\n might be different; for a GUI interface, you would use an "about box".\n\n You should also get your employer (if you work as a programmer) or school,\n if any, to sign a "copyright disclaimer" for the program, if necessary.\n For more information on this, and how to apply and follow the GNU GPL, see\n .\n\n The GNU General Public License does not permit incorporating your program\n into proprietary programs. If your program is a subroutine library, you\n may consider it more useful to permit linking proprietary applications with\n the library. If this is what you want to do, use the GNU Lesser General\n Public License instead of this License. But first, please read\n .' +__url__: str = '' +__version__: str = '0.7.4rc3' +__warningregistry__: dict = {'version': 0} +_meta: importlib.metadata._adapters.Message # value = diff --git a/stubs/gridfiregridfire/_gridfire/__init__.pyi b/stubs/gridfiregridfire/_gridfire/__init__.pyi new file mode 100644 index 00000000..58a175d8 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/__init__.pyi @@ -0,0 +1,16 @@ +""" +Python bindings for the fourdst utility modules which are a part of the 4D-STAR project. +""" +from __future__ import annotations +from . import config +from . import engine +from . import exceptions +from . import io +from . import partition +from . import policy +from . import reaction +from . import screening +from . import solver +from . import type +from . import utils +__all__: list[str] = ['config', 'engine', 'exceptions', 'io', 'partition', 'policy', 'reaction', 'screening', 'solver', 'type', 'utils'] diff --git a/stubs/gridfiregridfire/_gridfire/config.pyi b/stubs/gridfiregridfire/_gridfire/config.pyi new file mode 100644 index 00000000..57eb9940 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/config.pyi @@ -0,0 +1,47 @@ +""" +GridFire configuration bindings +""" +from __future__ import annotations +import typing +__all__: list[str] = ['AdaptiveEngineViewConfig', 'CVODESolverConfig', 'EngineConfig', 'EngineViewConfig', 'GridFireConfig', 'SolverConfig'] +class AdaptiveEngineViewConfig: + def __init__(self) -> None: + ... + @property + def relativeCullingThreshold(self) -> float: + ... + @relativeCullingThreshold.setter + def relativeCullingThreshold(self, arg0: typing.SupportsFloat) -> None: + ... +class CVODESolverConfig: + def __init__(self) -> None: + ... + @property + def absTol(self) -> float: + ... + @absTol.setter + def absTol(self, arg0: typing.SupportsFloat) -> None: + ... + @property + def relTol(self) -> float: + ... + @relTol.setter + def relTol(self, arg0: typing.SupportsFloat) -> None: + ... +class EngineConfig: + views: EngineViewConfig + def __init__(self) -> None: + ... +class EngineViewConfig: + adaptiveEngineView: AdaptiveEngineViewConfig + def __init__(self) -> None: + ... +class GridFireConfig: + engine: EngineConfig + solver: SolverConfig + def __init__(self) -> None: + ... +class SolverConfig: + cvode: CVODESolverConfig + def __init__(self) -> None: + ... diff --git a/stubs/gridfiregridfire/_gridfire/engine/__init__.pyi b/stubs/gridfiregridfire/_gridfire/engine/__init__.pyi new file mode 100644 index 00000000..bda6579c --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/engine/__init__.pyi @@ -0,0 +1,972 @@ +""" +Engine and Engine View bindings +""" +from __future__ import annotations +import collections.abc +import fourdst._phys.atomic +import fourdst._phys.composition +import gridfire._gridfire.io +import gridfire._gridfire.partition +import gridfire._gridfire.reaction +import gridfire._gridfire.screening +import gridfire._gridfire.type +import numpy +import numpy.typing +import typing +from . import diagnostics +from . import scratchpads +__all__: list[str] = ['ACTIVE', 'ADAPTIVE_ENGINE_VIEW', 'AdaptiveEngineView', 'BuildDepthType', 'DEFAULT', 'DEFINED_ENGINE_VIEW', 'DefinedEngineView', 'DynamicEngine', 'EQUILIBRIUM', 'Engine', 'EngineTypes', 'FILE_DEFINED_ENGINE_VIEW', 'FULL_SUCCESS', 'FifthOrder', 'FileDefinedEngineView', 'FourthOrder', 'Full', 'GRAPH_ENGINE', 'GraphEngine', 'INACTIVE_FLOW', 'MAX_ITERATIONS_REACHED', 'MULTISCALE_PARTITIONING_ENGINE_VIEW', 'MultiscalePartitioningEngineView', 'NONE', 'NOT_PRESENT', 'NO_SPECIES_TO_PRIME', 'NetworkBuildDepth', 'NetworkConstructionFlags', 'NetworkJacobian', 'NetworkPrimingEngineView', 'PRIMING_ENGINE_VIEW', 'PrimingReport', 'PrimingReportStatus', 'REACLIB', 'REACLIB_STRONG', 'REACLIB_WEAK', 'SecondOrder', 'Shallow', 'SparsityPattern', 'SpeciesStatus', 'StepDerivatives', 'ThirdOrder', 'WRL_BETA_MINUS', 'WRL_BETA_PLUS', 'WRL_ELECTRON_CAPTURE', 'WRL_POSITRON_CAPTURE', 'WRL_WEAK', 'build_nuclear_network', 'diagnostics', 'primeNetwork', 'regularize_jacobian', 'scratchpads'] +class AdaptiveEngineView(DynamicEngine): + def __init__(self, baseEngine: DynamicEngine) -> None: + """ + Construct an adaptive engine view with a base engine. + """ + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + """ + Calculate deps/dT and deps/drho + """ + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + """ + Calculate the molar reaction flow for a given reaction. + """ + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + """ + Calculate the right-hand side (dY/dt) and energy generation rate. + """ + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + """ + Recursively collect composition from current engine and any sub engines if they exist. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + """ + Generate the Jacobian matrix for the current state. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + """ + Generate the jacobian matrix only for the subset of the matrix representing the active species. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + """ + Generate the jacobian matrix for the given sparsity pattern + """ + def getBaseEngine(self) -> DynamicEngine: + """ + Get the base engine associated with this adaptive engine view. + """ + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the set of logical reactions in the network. + """ + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of species in the network. + """ + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: + """ + Get the current screening model of the engine. + """ + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the destruction timescales for each species in the network. + """ + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: + """ + Get the index of a species in the network. + """ + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + """ + Get the status of a species in the network. + """ + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the timescales for each species in the network. + """ + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + """ + Prime the engine with a NetIn object to prepare for calculations. + """ + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + """ + Update the engine state based on the provided NetIn object. + """ +class BuildDepthType: + pass +class DefinedEngineView(DynamicEngine): + def __init__(self, peNames: collections.abc.Sequence[str], baseEngine: GraphEngine) -> None: + """ + Construct a defined engine view with a list of tracked reactions and a base engine. + """ + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + """ + Calculate deps/dT and deps/drho + """ + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + """ + Calculate the molar reaction flow for a given reaction. + """ + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + """ + Calculate the right-hand side (dY/dt) and energy generation rate. + """ + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + """ + Recursively collect composition from current engine and any sub engines if they exist. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + """ + Generate the Jacobian matrix for the current state. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + """ + Generate the jacobian matrix only for the subset of the matrix representing the active species. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + """ + Generate the jacobian matrix for the given sparsity pattern + """ + def getBaseEngine(self) -> DynamicEngine: + """ + Get the base engine associated with this defined engine view. + """ + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the set of logical reactions in the network. + """ + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of species in the network. + """ + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: + """ + Get the current screening model of the engine. + """ + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the destruction timescales for each species in the network. + """ + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: + """ + Get the index of a species in the network. + """ + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + """ + Get the status of a species in the network. + """ + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the timescales for each species in the network. + """ + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + """ + Prime the engine with a NetIn object to prepare for calculations. + """ + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + """ + Update the engine state based on the provided NetIn object. + """ +class DynamicEngine: + pass +class Engine: + pass +class EngineTypes: + """ + Members: + + GRAPH_ENGINE : The standard graph-based engine. + + ADAPTIVE_ENGINE_VIEW : An engine that adapts based on certain criteria. + + MULTISCALE_PARTITIONING_ENGINE_VIEW : An engine that partitions the system at multiple scales. + + PRIMING_ENGINE_VIEW : An engine that uses a priming strategy for simulations. + + DEFINED_ENGINE_VIEW : An engine defined by user specifications. + + FILE_DEFINED_ENGINE_VIEW : An engine defined through external files. + """ + ADAPTIVE_ENGINE_VIEW: typing.ClassVar[EngineTypes] # value = + DEFINED_ENGINE_VIEW: typing.ClassVar[EngineTypes] # value = + FILE_DEFINED_ENGINE_VIEW: typing.ClassVar[EngineTypes] # value = + GRAPH_ENGINE: typing.ClassVar[EngineTypes] # value = + MULTISCALE_PARTITIONING_ENGINE_VIEW: typing.ClassVar[EngineTypes] # value = + PRIMING_ENGINE_VIEW: typing.ClassVar[EngineTypes] # value = + __members__: typing.ClassVar[dict[str, EngineTypes]] # value = {'GRAPH_ENGINE': , 'ADAPTIVE_ENGINE_VIEW': , 'MULTISCALE_PARTITIONING_ENGINE_VIEW': , 'PRIMING_ENGINE_VIEW': , 'DEFINED_ENGINE_VIEW': , 'FILE_DEFINED_ENGINE_VIEW': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + @typing.overload + def __repr__(self) -> str: + ... + @typing.overload + def __repr__(self) -> str: + """ + String representation of the EngineTypes. + """ + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class FileDefinedEngineView(DefinedEngineView): + def __init__(self, baseEngine: GraphEngine, fileName: str, parser: gridfire._gridfire.io.NetworkFileParser) -> None: + """ + Construct a defined engine view from a file and a base engine. + """ + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + """ + Calculate deps/dT and deps/drho + """ + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + """ + Calculate the molar reaction flow for a given reaction. + """ + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + """ + Calculate the right-hand side (dY/dt) and energy generation rate. + """ + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + """ + Recursively collect composition from current engine and any sub engines if they exist. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + """ + Generate the Jacobian matrix for the current state. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + """ + Generate the jacobian matrix only for the subset of the matrix representing the active species. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + """ + Generate the jacobian matrix for the given sparsity pattern + """ + def getBaseEngine(self) -> DynamicEngine: + """ + Get the base engine associated with this file defined engine view. + """ + def getNetworkFile(self) -> str: + """ + Get the network file associated with this defined engine view. + """ + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the set of logical reactions in the network. + """ + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of species in the network. + """ + def getParser(self) -> gridfire._gridfire.io.NetworkFileParser: + """ + Get the parser used for this defined engine view. + """ + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: + """ + Get the current screening model of the engine. + """ + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the destruction timescales for each species in the network. + """ + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: + """ + Get the index of a species in the network. + """ + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + """ + Get the status of a species in the network. + """ + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the timescales for each species in the network. + """ + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + """ + Prime the engine with a NetIn object to prepare for calculations. + """ + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + """ + Update the engine state based on the provided NetIn object. + """ +class GraphEngine(DynamicEngine): + @typing.overload + def __init__(self, composition: fourdst._phys.composition.Composition, depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: + """ + Initialize GraphEngine with a composition and build depth. + """ + @typing.overload + def __init__(self, composition: fourdst._phys.composition.Composition, partitionFunction: gridfire._gridfire.partition.PartitionFunction, depth: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ...) -> None: + """ + Initialize GraphEngine with a composition, partition function and build depth. + """ + @typing.overload + def __init__(self, reactions: gridfire._gridfire.reaction.ReactionSet) -> None: + """ + Initialize GraphEngine with a set of reactions. + """ + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + """ + Calculate deps/dT and deps/drho + """ + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + """ + Calculate the molar reaction flow for a given reaction. + """ + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + """ + Calculate the right-hand side (dY/dt) and energy generation rate. + """ + def calculateReverseRate(self, reaction: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat, composition: ...) -> float: + """ + Calculate the reverse rate for a given reaction at a specific temperature, density, and composition. + """ + def calculateReverseRateTwoBody(self, reaction: ..., T9: typing.SupportsFloat, forwardRate: typing.SupportsFloat, expFactor: typing.SupportsFloat) -> float: + """ + Calculate the reverse rate for a two-body reaction at a specific temperature. + """ + def calculateReverseRateTwoBodyDerivative(self, reaction: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat, composition: fourdst._phys.composition.Composition, reverseRate: typing.SupportsFloat) -> float: + """ + Calculate the derivative of the reverse rate for a two-body reaction at a specific temperature. + """ + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + """ + Recursively collect composition from current engine and any sub engines if they exist. + """ + def exportToCSV(self, ctx: scratchpads.StateBlob, filename: str) -> None: + """ + Export the network to a CSV file for analysis. + """ + def exportToDot(self, ctx: scratchpads.StateBlob, filename: str) -> None: + """ + Export the network to a DOT file for visualization. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + """ + Generate the Jacobian matrix for the current state. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + """ + Generate the jacobian matrix only for the subset of the matrix representing the active species. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + """ + Generate the jacobian matrix for the given sparsity pattern + """ + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the set of logical reactions in the network. + """ + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of species in the network. + """ + def getPartitionFunction(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.partition.PartitionFunction: + """ + Get the partition function used by the engine. + """ + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: + """ + Get the current screening model of the engine. + """ + @typing.overload + def getSpeciesDestructionTimescales(self, ctx: scratchpads.StateBlob, composition: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeReactions: gridfire._gridfire.reaction.ReactionSet) -> ...: + ... + @typing.overload + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the destruction timescales for each species in the network. + """ + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: + """ + Get the index of a species in the network. + """ + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + """ + Get the status of a species in the network. + """ + @typing.overload + def getSpeciesTimescales(self, ctx: scratchpads.StateBlob, composition: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeReactions: gridfire._gridfire.reaction.ReactionSet) -> ...: + ... + @typing.overload + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the timescales for each species in the network. + """ + def involvesSpecies(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if a given species is involved in the network. + """ + def isPrecomputationEnabled(self, arg0: scratchpads.StateBlob) -> bool: + """ + Check if precomputation is enabled for the engine. + """ + def isUsingReverseReactions(self, arg0: scratchpads.StateBlob) -> bool: + """ + Check if the engine is using reverse reactions. + """ + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + """ + Prime the engine with a NetIn object to prepare for calculations. + """ + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + """ + Update the engine state based on the provided NetIn object. + """ +class MultiscalePartitioningEngineView(DynamicEngine): + def __init__(self, baseEngine: GraphEngine) -> None: + """ + Construct a multiscale partitioning engine view with a base engine. + """ + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + """ + Calculate deps/dT and deps/drho + """ + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + """ + Calculate the molar reaction flow for a given reaction. + """ + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + """ + Calculate the right-hand side (dY/dt) and energy generation rate. + """ + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + """ + Recursively collect composition from current engine and any sub engines if they exist. + """ + def exportToDot(self, ctx: scratchpads.StateBlob, filename: str, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> None: + """ + Export the network to a DOT file for visualization. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + """ + Generate the Jacobian matrix for the current state. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + """ + Generate the jacobian matrix only for the subset of the matrix representing the active species. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + """ + Generate the jacobian matrix for the given sparsity pattern + """ + def getBaseEngine(self) -> DynamicEngine: + """ + Get the base engine associated with this multiscale partitioning engine view. + """ + def getDynamicSpecies(self: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of dynamic species in the network. + """ + def getFastSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of fast species in the network. + """ + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the set of logical reactions in the network. + """ + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of species in the network. + """ + def getNormalizedEquilibratedComposition(self, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + """ + Get the normalized equilibrated composition for the algebraic species. + """ + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: + """ + Get the current screening model of the engine. + """ + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the destruction timescales for each species in the network. + """ + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: + """ + Get the index of a species in the network. + """ + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + """ + Get the status of a species in the network. + """ + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the timescales for each species in the network. + """ + def involvesSpecies(self: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if a given species is involved in the network (in either the algebraic or dynamic set). + """ + def involvesSpeciesInDynamic(self: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if a given species is involved in the network's dynamic set. + """ + def involvesSpeciesInQSE(self: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if a given species is involved in the network's algebraic set. + """ + def partitionNetwork(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + """ + Partition the network based on species timescales and connectivity. + """ + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + """ + Prime the engine with a NetIn object to prepare for calculations. + """ + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + """ + Update the engine state based on the provided NetIn object. + """ +class NetworkBuildDepth: + """ + Members: + + Full : Full network build depth + + Shallow : Shallow network build depth + + SecondOrder : Second order network build depth + + ThirdOrder : Third order network build depth + + FourthOrder : Fourth order network build depth + + FifthOrder : Fifth order network build depth + """ + FifthOrder: typing.ClassVar[NetworkBuildDepth] # value = + FourthOrder: typing.ClassVar[NetworkBuildDepth] # value = + Full: typing.ClassVar[NetworkBuildDepth] # value = + SecondOrder: typing.ClassVar[NetworkBuildDepth] # value = + Shallow: typing.ClassVar[NetworkBuildDepth] # value = + ThirdOrder: typing.ClassVar[NetworkBuildDepth] # value = + __members__: typing.ClassVar[dict[str, NetworkBuildDepth]] # value = {'Full': , 'Shallow': , 'SecondOrder': , 'ThirdOrder': , 'FourthOrder': , 'FifthOrder': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class NetworkConstructionFlags: + """ + Members: + + NONE : No special construction flags. + + REACLIB_STRONG : Include strong reactions from reaclib. + + WRL_BETA_MINUS : Include beta-minus decay reactions from weak rate library. + + WRL_BETA_PLUS : Include beta-plus decay reactions from weak rate library. + + WRL_ELECTRON_CAPTURE : Include electron capture reactions from weak rate library. + + WRL_POSITRON_CAPTURE : Include positron capture reactions from weak rate library. + + REACLIB_WEAK : Include weak reactions from reaclib. + + WRL_WEAK : Include all weak reactions from weak rate library. + + REACLIB : Include all reactions from reaclib. + + DEFAULT : Default construction flags (Reaclib strong and weak). + """ + DEFAULT: typing.ClassVar[NetworkConstructionFlags] # value = + NONE: typing.ClassVar[NetworkConstructionFlags] # value = + REACLIB: typing.ClassVar[NetworkConstructionFlags] # value = + REACLIB_STRONG: typing.ClassVar[NetworkConstructionFlags] # value = + REACLIB_WEAK: typing.ClassVar[NetworkConstructionFlags] # value = + WRL_BETA_MINUS: typing.ClassVar[NetworkConstructionFlags] # value = + WRL_BETA_PLUS: typing.ClassVar[NetworkConstructionFlags] # value = + WRL_ELECTRON_CAPTURE: typing.ClassVar[NetworkConstructionFlags] # value = + WRL_POSITRON_CAPTURE: typing.ClassVar[NetworkConstructionFlags] # value = + WRL_WEAK: typing.ClassVar[NetworkConstructionFlags] # value = + __members__: typing.ClassVar[dict[str, NetworkConstructionFlags]] # value = {'NONE': , 'REACLIB_STRONG': , 'WRL_BETA_MINUS': , 'WRL_BETA_PLUS': , 'WRL_ELECTRON_CAPTURE': , 'WRL_POSITRON_CAPTURE': , 'REACLIB_WEAK': , 'WRL_WEAK': , 'REACLIB': , 'DEFAULT': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + @typing.overload + def __repr__(self) -> str: + ... + @typing.overload + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class NetworkJacobian: + @typing.overload + def __getitem__(self, key: tuple[fourdst._phys.atomic.Species, fourdst._phys.atomic.Species]) -> float: + """ + Get an entry from the Jacobian matrix using species identifiers. + """ + @typing.overload + def __getitem__(self, key: tuple[typing.SupportsInt, typing.SupportsInt]) -> float: + """ + Get an entry from the Jacobian matrix using indices. + """ + @typing.overload + def __setitem__(self, key: tuple[fourdst._phys.atomic.Species, fourdst._phys.atomic.Species], value: typing.SupportsFloat) -> None: + """ + Set an entry in the Jacobian matrix using species identifiers. + """ + @typing.overload + def __setitem__(self, key: tuple[typing.SupportsInt, typing.SupportsInt], value: typing.SupportsFloat) -> None: + """ + Set an entry in the Jacobian matrix using indices. + """ + def data(self) -> ...: + """ + Get the underlying sparse matrix data. + """ + def infs(self) -> list[tuple[tuple[fourdst._phys.atomic.Species, fourdst._phys.atomic.Species], float]]: + """ + Get all infinite entries in the Jacobian matrix. + """ + def mapping(self) -> dict[fourdst._phys.atomic.Species, int]: + """ + Get the species-to-index mapping. + """ + def nans(self) -> list[tuple[tuple[fourdst._phys.atomic.Species, fourdst._phys.atomic.Species], float]]: + """ + Get all NaN entries in the Jacobian matrix. + """ + def nnz(self) -> int: + """ + Get the number of non-zero entries in the Jacobian matrix. + """ + def rank(self) -> int: + """ + Get the rank of the Jacobian matrix. + """ + def shape(self) -> tuple[int, int]: + """ + Get the shape of the Jacobian matrix as (rows, columns). + """ + def singular(self) -> bool: + """ + Check if the Jacobian matrix is singular. + """ + def to_csv(self, filename: str) -> None: + """ + Export the Jacobian matrix to a CSV file. + """ + def to_numpy(self) -> numpy.typing.NDArray[numpy.float64]: + """ + Convert the Jacobian matrix to a NumPy array. + """ +class NetworkPrimingEngineView(DefinedEngineView): + @typing.overload + def __init__(self, ctx: scratchpads.StateBlob, primingSymbol: str, baseEngine: GraphEngine) -> None: + """ + Construct a priming engine view with a priming symbol and a base engine. + """ + @typing.overload + def __init__(self, ctx: scratchpads.StateBlob, primingSpecies: fourdst._phys.atomic.Species, baseEngine: GraphEngine) -> None: + """ + Construct a priming engine view with a priming species and a base engine. + """ + def calculateEpsDerivatives(self, ctx: scratchpads.StateBlob, comp: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> ...: + """ + Calculate deps/dT and deps/drho + """ + def calculateMolarReactionFlow(self: DynamicEngine, ctx: scratchpads.StateBlob, reaction: ..., comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> float: + """ + Calculate the molar reaction flow for a given reaction. + """ + def calculateRHSAndEnergy(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> StepDerivatives: + """ + Calculate the right-hand side (dY/dt) and energy generation rate. + """ + def collectComposition(self, ctx: scratchpads.StateBlob, composition: ..., T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> fourdst._phys.composition.Composition: + """ + Recursively collect composition from current engine and any sub engines if they exist. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> NetworkJacobian: + """ + Generate the Jacobian matrix for the current state. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, activeSpecies: collections.abc.Sequence[fourdst._phys.atomic.Species]) -> NetworkJacobian: + """ + Generate the jacobian matrix only for the subset of the matrix representing the active species. + """ + @typing.overload + def generateJacobianMatrix(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, sparsityPattern: collections.abc.Sequence[tuple[typing.SupportsInt, typing.SupportsInt]]) -> NetworkJacobian: + """ + Generate the jacobian matrix for the given sparsity pattern + """ + def getBaseEngine(self) -> DynamicEngine: + """ + Get the base engine associated with this priming engine view. + """ + def getNetworkReactions(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the set of logical reactions in the network. + """ + def getNetworkSpecies(self, arg0: scratchpads.StateBlob) -> list[fourdst._phys.atomic.Species]: + """ + Get the list of species in the network. + """ + def getScreeningModel(self, arg0: scratchpads.StateBlob) -> gridfire._gridfire.screening.ScreeningType: + """ + Get the current screening model of the engine. + """ + def getSpeciesDestructionTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the destruction timescales for each species in the network. + """ + def getSpeciesIndex(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> int: + """ + Get the index of a species in the network. + """ + def getSpeciesStatus(self, ctx: scratchpads.StateBlob, species: fourdst._phys.atomic.Species) -> SpeciesStatus: + """ + Get the status of a species in the network. + """ + def getSpeciesTimescales(self: DynamicEngine, ctx: scratchpads.StateBlob, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> dict[fourdst._phys.atomic.Species, float]: + """ + Get the timescales for each species in the network. + """ + def primeEngine(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> PrimingReport: + """ + Prime the engine with a NetIn object to prepare for calculations. + """ + def project(self, ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn) -> fourdst._phys.composition.Composition: + """ + Update the engine state based on the provided NetIn object. + """ +class PrimingReport: + def __repr__(self) -> str: + ... + @property + def primedComposition(self) -> fourdst._phys.composition.Composition: + """ + The composition after priming. + """ + @property + def status(self) -> PrimingReportStatus: + """ + Status message from the priming process. + """ + @property + def success(self) -> bool: + """ + Indicates if the priming was successful. + """ +class PrimingReportStatus: + """ + Members: + + FULL_SUCCESS : Priming was full successful. + + NO_SPECIES_TO_PRIME : Solver Failed to converge during priming. + + MAX_ITERATIONS_REACHED : Engine has already been primed. + """ + FULL_SUCCESS: typing.ClassVar[PrimingReportStatus] # value = + MAX_ITERATIONS_REACHED: typing.ClassVar[PrimingReportStatus] # value = + NO_SPECIES_TO_PRIME: typing.ClassVar[PrimingReportStatus] # value = + __members__: typing.ClassVar[dict[str, PrimingReportStatus]] # value = {'FULL_SUCCESS': , 'NO_SPECIES_TO_PRIME': , 'MAX_ITERATIONS_REACHED': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + @typing.overload + def __repr__(self) -> str: + ... + @typing.overload + def __repr__(self) -> str: + """ + String representation of the PrimingReport. + """ + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class SparsityPattern: + pass +class SpeciesStatus: + """ + Members: + + ACTIVE : Species is active in the network. + + EQUILIBRIUM : Species is in equilibrium. + + INACTIVE_FLOW : Species is inactive due to flow. + + NOT_PRESENT : Species is not present in the network. + """ + ACTIVE: typing.ClassVar[SpeciesStatus] # value = + EQUILIBRIUM: typing.ClassVar[SpeciesStatus] # value = + INACTIVE_FLOW: typing.ClassVar[SpeciesStatus] # value = + NOT_PRESENT: typing.ClassVar[SpeciesStatus] # value = + __members__: typing.ClassVar[dict[str, SpeciesStatus]] # value = {'ACTIVE': , 'EQUILIBRIUM': , 'INACTIVE_FLOW': , 'NOT_PRESENT': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + @typing.overload + def __repr__(self) -> str: + ... + @typing.overload + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class StepDerivatives: + @property + def dYdt(self) -> dict[fourdst._phys.atomic.Species, float]: + """ + The right-hand side (dY/dt) of the ODE system. + """ + @property + def energy(self) -> float: + """ + The energy generation rate. + """ +def build_nuclear_network(composition: ..., weakInterpolator: ..., maxLayers: gridfire._gridfire.engine.NetworkBuildDepth | typing.SupportsInt = ..., ReactionTypes: NetworkConstructionFlags = ...) -> gridfire._gridfire.reaction.ReactionSet: + """ + Build a nuclear network from a composition using all archived reaction data. + """ +def primeNetwork(ctx: scratchpads.StateBlob, netIn: gridfire._gridfire.type.NetIn, engine: ..., ignoredReactionTypes: collections.abc.Sequence[...] | None = None) -> PrimingReport: + """ + Prime a network with a short timescale ignition + """ +def regularize_jacobian(jacobian: NetworkJacobian, composition: fourdst._phys.composition.Composition) -> NetworkJacobian: + """ + regularize_jacobian + """ +ACTIVE: SpeciesStatus # value = +ADAPTIVE_ENGINE_VIEW: EngineTypes # value = +DEFAULT: NetworkConstructionFlags # value = +DEFINED_ENGINE_VIEW: EngineTypes # value = +EQUILIBRIUM: SpeciesStatus # value = +FILE_DEFINED_ENGINE_VIEW: EngineTypes # value = +FULL_SUCCESS: PrimingReportStatus # value = +FifthOrder: NetworkBuildDepth # value = +FourthOrder: NetworkBuildDepth # value = +Full: NetworkBuildDepth # value = +GRAPH_ENGINE: EngineTypes # value = +INACTIVE_FLOW: SpeciesStatus # value = +MAX_ITERATIONS_REACHED: PrimingReportStatus # value = +MULTISCALE_PARTITIONING_ENGINE_VIEW: EngineTypes # value = +NONE: NetworkConstructionFlags # value = +NOT_PRESENT: SpeciesStatus # value = +NO_SPECIES_TO_PRIME: PrimingReportStatus # value = +PRIMING_ENGINE_VIEW: EngineTypes # value = +REACLIB: NetworkConstructionFlags # value = +REACLIB_STRONG: NetworkConstructionFlags # value = +REACLIB_WEAK: NetworkConstructionFlags # value = +SecondOrder: NetworkBuildDepth # value = +Shallow: NetworkBuildDepth # value = +ThirdOrder: NetworkBuildDepth # value = +WRL_BETA_MINUS: NetworkConstructionFlags # value = +WRL_BETA_PLUS: NetworkConstructionFlags # value = +WRL_ELECTRON_CAPTURE: NetworkConstructionFlags # value = +WRL_POSITRON_CAPTURE: NetworkConstructionFlags # value = +WRL_WEAK: NetworkConstructionFlags # value = diff --git a/stubs/gridfiregridfire/_gridfire/engine/diagnostics.pyi b/stubs/gridfiregridfire/_gridfire/engine/diagnostics.pyi new file mode 100644 index 00000000..e0955a9e --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/engine/diagnostics.pyi @@ -0,0 +1,16 @@ +""" +A submodule for engine diagnostics +""" +from __future__ import annotations +import collections.abc +import fourdst._phys.composition +import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads +import typing +__all__: list[str] = ['inspect_jacobian_stiffness', 'inspect_species_balance', 'report_limiting_species'] +def inspect_jacobian_stiffness(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, json: bool) -> ... | None: + ... +def inspect_species_balance(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, species_name: str, comp: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat, json: bool) -> ... | None: + ... +def report_limiting_species(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, Y_full: collections.abc.Sequence[typing.SupportsFloat], E_full: collections.abc.Sequence[typing.SupportsFloat], relTol: typing.SupportsFloat, absTol: typing.SupportsFloat, top_n: typing.SupportsInt, json: bool) -> ... | None: + ... diff --git a/stubs/gridfiregridfire/_gridfire/engine/scratchpads.pyi b/stubs/gridfiregridfire/_gridfire/engine/scratchpads.pyi new file mode 100644 index 00000000..6509bc84 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/engine/scratchpads.pyi @@ -0,0 +1,267 @@ +""" +Engine ScratchPad bindings +""" +from __future__ import annotations +import fourdst._phys.atomic +import fourdst._phys.composition +import gridfire._gridfire.reaction +import typing +__all__: list[str] = ['ADAPTIVE_ENGINE_VIEW_SCRATCHPAD', 'ADFunRegistrationResult', 'ALREADY_REGISTERED', 'AdaptiveEngineViewScratchPad', 'DEFINED_ENGINE_VIEW_SCRATCHPAD', 'DefinedEngineViewScratchPad', 'GRAPH_ENGINE_SCRATCHPAD', 'GraphEngineScratchPad', 'MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD', 'MultiscalePartitioningEngineViewScratchPad', 'SCRATCHPAD_BAD_CAST', 'SCRATCHPAD_NOT_FOUND', 'SCRATCHPAD_NOT_INITIALIZED', 'SCRATCHPAD_OUT_OF_BOUNDS', 'SCRATCHPAD_TYPE_COLLISION', 'SCRATCHPAD_UNKNOWN_ERROR', 'SUCCESS', 'ScratchPadType', 'StateBlob', 'StateBlobError'] +class ADFunRegistrationResult: + """ + Members: + + SUCCESS + + ALREADY_REGISTERED + """ + ALREADY_REGISTERED: typing.ClassVar[ADFunRegistrationResult] # value = + SUCCESS: typing.ClassVar[ADFunRegistrationResult] # value = + __members__: typing.ClassVar[dict[str, ADFunRegistrationResult]] # value = {'SUCCESS': , 'ALREADY_REGISTERED': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class AdaptiveEngineViewScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def initialize(self, arg0: ...) -> None: + ... + def is_initialized(self) -> bool: + ... + @property + def active_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + ... + @property + def active_species(self) -> list[fourdst._phys.atomic.Species]: + ... + @property + def has_initialized(self) -> bool: + ... +class DefinedEngineViewScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def is_initialized(self) -> bool: + ... + @property + def active_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + ... + @property + def active_species(self) -> set[fourdst._phys.atomic.Species]: + ... + @property + def has_initialized(self) -> bool: + ... + @property + def reaction_index_map(self) -> list[int]: + ... + @property + def species_index_map(self) -> list[int]: + ... +class GraphEngineScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def initialize(self, engine: ...) -> None: + ... + def is_initialized(self) -> bool: + ... + @property + def has_initialized(self) -> bool: + ... + @property + def local_abundance_cache(self) -> list[float]: + ... + @property + def most_recent_rhs_calculation(self) -> ... | None: + ... + @property + def stepDerivativesCache(self) -> dict[int, ...]: + ... +class MultiscalePartitioningEngineViewScratchPad: + ID: typing.ClassVar[ScratchPadType] # value = + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone(self) -> ...: + ... + def initialize(self) -> None: + ... + def is_initialized(self) -> bool: + ... + @property + def algebraic_species(self) -> list[fourdst._phys.atomic.Species]: + ... + @property + def composition_cache(self) -> dict[int, fourdst._phys.composition.Composition]: + ... + @property + def dynamic_species(self) -> list[fourdst._phys.atomic.Species]: + ... + @property + def has_initialized(self) -> bool: + ... + @property + def qse_groups(self) -> list[...]: + ... +class ScratchPadType: + """ + Members: + + GRAPH_ENGINE_SCRATCHPAD + + MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD + + ADAPTIVE_ENGINE_VIEW_SCRATCHPAD + + DEFINED_ENGINE_VIEW_SCRATCHPAD + """ + ADAPTIVE_ENGINE_VIEW_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + DEFINED_ENGINE_VIEW_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + GRAPH_ENGINE_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD: typing.ClassVar[ScratchPadType] # value = + __members__: typing.ClassVar[dict[str, ScratchPadType]] # value = {'GRAPH_ENGINE_SCRATCHPAD': , 'MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD': , 'ADAPTIVE_ENGINE_VIEW_SCRATCHPAD': , 'DEFINED_ENGINE_VIEW_SCRATCHPAD': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class StateBlob: + @staticmethod + def error_to_string(arg0: StateBlobError) -> str: + ... + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def clone_structure(self) -> StateBlob: + ... + def enroll(self, arg0: ScratchPadType) -> None: + ... + def get(self, arg0: ScratchPadType) -> ...: + ... + def get_registered_scratchpads(self) -> set[ScratchPadType]: + ... + def get_status(self, arg0: ScratchPadType) -> ...: + ... + def get_status_map(self) -> dict[ScratchPadType, ...]: + ... +class StateBlobError: + """ + Members: + + SCRATCHPAD_OUT_OF_BOUNDS + + SCRATCHPAD_NOT_FOUND + + SCRATCHPAD_BAD_CAST + + SCRATCHPAD_NOT_INITIALIZED + + SCRATCHPAD_TYPE_COLLISION + + SCRATCHPAD_UNKNOWN_ERROR + """ + SCRATCHPAD_BAD_CAST: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_NOT_FOUND: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_NOT_INITIALIZED: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_OUT_OF_BOUNDS: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_TYPE_COLLISION: typing.ClassVar[StateBlobError] # value = + SCRATCHPAD_UNKNOWN_ERROR: typing.ClassVar[StateBlobError] # value = + __members__: typing.ClassVar[dict[str, StateBlobError]] # value = {'SCRATCHPAD_OUT_OF_BOUNDS': , 'SCRATCHPAD_NOT_FOUND': , 'SCRATCHPAD_BAD_CAST': , 'SCRATCHPAD_NOT_INITIALIZED': , 'SCRATCHPAD_TYPE_COLLISION': , 'SCRATCHPAD_UNKNOWN_ERROR': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +ADAPTIVE_ENGINE_VIEW_SCRATCHPAD: ScratchPadType # value = +ALREADY_REGISTERED: ADFunRegistrationResult # value = +DEFINED_ENGINE_VIEW_SCRATCHPAD: ScratchPadType # value = +GRAPH_ENGINE_SCRATCHPAD: ScratchPadType # value = +MULTISCALE_PARTITIONING_ENGINE_VIEW_SCRATCHPAD: ScratchPadType # value = +SCRATCHPAD_BAD_CAST: StateBlobError # value = +SCRATCHPAD_NOT_FOUND: StateBlobError # value = +SCRATCHPAD_NOT_INITIALIZED: StateBlobError # value = +SCRATCHPAD_OUT_OF_BOUNDS: StateBlobError # value = +SCRATCHPAD_TYPE_COLLISION: StateBlobError # value = +SCRATCHPAD_UNKNOWN_ERROR: StateBlobError # value = +SUCCESS: ADFunRegistrationResult # value = diff --git a/stubs/gridfiregridfire/_gridfire/exceptions.pyi b/stubs/gridfiregridfire/_gridfire/exceptions.pyi new file mode 100644 index 00000000..92796a95 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/exceptions.pyi @@ -0,0 +1,61 @@ +""" +GridFire exceptions bindings +""" +from __future__ import annotations +__all__: list[str] = ['BadCollectionError', 'BadRHSEngineError', 'CVODESolverFailureError', 'DebugException', 'EngineError', 'FailedToPartitionEngineError', 'GridFireError', 'HashingError', 'IllConditionedJacobianError', 'InvalidQSESolutionError', 'JacobianError', 'KINSolSolverFailureError', 'MissingBaseReactionError', 'MissingKeyReactionError', 'MissingSeedSpeciesError', 'NetworkResizedError', 'PolicyError', 'ReactionError', 'ReactionParsingError', 'SUNDIALSError', 'ScratchPadError', 'SingularJacobianError', 'SolverError', 'StaleJacobianError', 'UnableToSetNetworkReactionsError', 'UninitializedJacobianError', 'UnknownJacobianError', 'UtilityError'] +class BadCollectionError(EngineError): + pass +class BadRHSEngineError(EngineError): + pass +class CVODESolverFailureError(SUNDIALSError): + pass +class DebugException(GridFireError): + pass +class EngineError(GridFireError): + pass +class FailedToPartitionEngineError(EngineError): + pass +class GridFireError(Exception): + pass +class HashingError(UtilityError): + pass +class IllConditionedJacobianError(SolverError): + pass +class InvalidQSESolutionError(EngineError): + pass +class JacobianError(EngineError): + pass +class KINSolSolverFailureError(SUNDIALSError): + pass +class MissingBaseReactionError(PolicyError): + pass +class MissingKeyReactionError(PolicyError): + pass +class MissingSeedSpeciesError(PolicyError): + pass +class NetworkResizedError(EngineError): + pass +class PolicyError(GridFireError): + pass +class ReactionError(GridFireError): + pass +class ReactionParsingError(ReactionError): + pass +class SUNDIALSError(SolverError): + pass +class ScratchPadError(GridFireError): + pass +class SingularJacobianError(SolverError): + pass +class SolverError(GridFireError): + pass +class StaleJacobianError(JacobianError): + pass +class UnableToSetNetworkReactionsError(EngineError): + pass +class UninitializedJacobianError(JacobianError): + pass +class UnknownJacobianError(JacobianError): + pass +class UtilityError(GridFireError): + pass diff --git a/stubs/gridfiregridfire/_gridfire/io.pyi b/stubs/gridfiregridfire/_gridfire/io.pyi new file mode 100644 index 00000000..6024a26b --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/io.pyi @@ -0,0 +1,14 @@ +""" +GridFire io bindings +""" +from __future__ import annotations +__all__: list[str] = ['NetworkFileParser', 'ParsedNetworkData', 'SimpleReactionListFileParser'] +class NetworkFileParser: + pass +class ParsedNetworkData: + pass +class SimpleReactionListFileParser(NetworkFileParser): + def parse(self, filename: str) -> ParsedNetworkData: + """ + Parse a simple reaction list file and return a ParsedNetworkData object. + """ diff --git a/stubs/gridfiregridfire/_gridfire/partition.pyi b/stubs/gridfiregridfire/_gridfire/partition.pyi new file mode 100644 index 00000000..50c78f24 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/partition.pyi @@ -0,0 +1,142 @@ +""" +GridFire partition function bindings +""" +from __future__ import annotations +import collections.abc +import typing +__all__: list[str] = ['BasePartitionType', 'CompositePartitionFunction', 'GroundState', 'GroundStatePartitionFunction', 'PartitionFunction', 'RauscherThielemann', 'RauscherThielemannPartitionDataRecord', 'RauscherThielemannPartitionFunction', 'basePartitionTypeToString', 'stringToBasePartitionType'] +class BasePartitionType: + """ + Members: + + RauscherThielemann + + GroundState + """ + GroundState: typing.ClassVar[BasePartitionType] # value = + RauscherThielemann: typing.ClassVar[BasePartitionType] # value = + __members__: typing.ClassVar[dict[str, BasePartitionType]] # value = {'RauscherThielemann': , 'GroundState': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class CompositePartitionFunction: + @typing.overload + def __init__(self, partitionFunctions: collections.abc.Sequence[BasePartitionType]) -> None: + """ + Create a composite partition function from a list of base partition types. + """ + @typing.overload + def __init__(self, arg0: CompositePartitionFunction) -> None: + """ + Copy constructor for CompositePartitionFunction. + """ + def evaluate(self, z: typing.SupportsInt, a: typing.SupportsInt, T9: typing.SupportsFloat) -> float: + """ + Evaluate the composite partition function for given Z, A, and T9. + """ + def evaluateDerivative(self, z: typing.SupportsInt, a: typing.SupportsInt, T9: typing.SupportsFloat) -> float: + """ + Evaluate the derivative of the composite partition function for given Z, A, and T9. + """ + def get_type(self) -> str: + """ + Get the type of the partition function (should return 'Composite'). + """ + def supports(self, z: typing.SupportsInt, a: typing.SupportsInt) -> bool: + """ + Check if the composite partition function supports given Z and A. + """ +class GroundStatePartitionFunction(PartitionFunction): + def __init__(self) -> None: + ... + def evaluate(self, z: typing.SupportsInt, a: typing.SupportsInt, T9: typing.SupportsFloat) -> float: + """ + Evaluate the ground state partition function for given Z, A, and T9. + """ + def evaluateDerivative(self, z: typing.SupportsInt, a: typing.SupportsInt, T9: typing.SupportsFloat) -> float: + """ + Evaluate the derivative of the ground state partition function for given Z, A, and T9. + """ + def get_type(self) -> str: + """ + Get the type of the partition function (should return 'GroundState'). + """ + def supports(self, z: typing.SupportsInt, a: typing.SupportsInt) -> bool: + """ + Check if the ground state partition function supports given Z and A. + """ +class PartitionFunction: + pass +class RauscherThielemannPartitionDataRecord: + @property + def a(self) -> int: + """ + Mass number + """ + @property + def ground_state_spin(self) -> float: + """ + Ground state spin + """ + @property + def normalized_g_values(self) -> float: + """ + Normalized g-values for the first 24 energy levels + """ + @property + def z(self) -> int: + """ + Atomic number + """ +class RauscherThielemannPartitionFunction(PartitionFunction): + def __init__(self) -> None: + ... + def evaluate(self, z: typing.SupportsInt, a: typing.SupportsInt, T9: typing.SupportsFloat) -> float: + """ + Evaluate the Rauscher-Thielemann partition function for given Z, A, and T9. + """ + def evaluateDerivative(self, z: typing.SupportsInt, a: typing.SupportsInt, T9: typing.SupportsFloat) -> float: + """ + Evaluate the derivative of the Rauscher-Thielemann partition function for given Z, A, and T9. + """ + def get_type(self) -> str: + """ + Get the type of the partition function (should return 'RauscherThielemann'). + """ + def supports(self, z: typing.SupportsInt, a: typing.SupportsInt) -> bool: + """ + Check if the Rauscher-Thielemann partition function supports given Z and A. + """ +def basePartitionTypeToString(type: BasePartitionType) -> str: + """ + Convert BasePartitionType to string. + """ +def stringToBasePartitionType(typeStr: str) -> BasePartitionType: + """ + Convert string to BasePartitionType. + """ +GroundState: BasePartitionType # value = +RauscherThielemann: BasePartitionType # value = diff --git a/stubs/gridfiregridfire/_gridfire/policy.pyi b/stubs/gridfiregridfire/_gridfire/policy.pyi new file mode 100644 index 00000000..3a5c89b9 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/policy.pyi @@ -0,0 +1,769 @@ +""" +GridFire network policy bindings +""" +from __future__ import annotations +import collections.abc +import fourdst._phys.atomic +import fourdst._phys.composition +import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads +import gridfire._gridfire.partition +import gridfire._gridfire.reaction +import typing +__all__: list[str] = ['CNOChainPolicy', 'CNOIChainPolicy', 'CNOIIChainPolicy', 'CNOIIIChainPolicy', 'CNOIVChainPolicy', 'ConstructionResults', 'HotCNOChainPolicy', 'HotCNOIChainPolicy', 'HotCNOIIChainPolicy', 'HotCNOIIIChainPolicy', 'INITIALIZED_UNVERIFIED', 'INITIALIZED_VERIFIED', 'MISSING_KEY_REACTION', 'MISSING_KEY_SPECIES', 'MainSequencePolicy', 'MainSequenceReactionChainPolicy', 'MultiReactionChainPolicy', 'NetworkPolicy', 'NetworkPolicyStatus', 'ProtonProtonChainPolicy', 'ProtonProtonIChainPolicy', 'ProtonProtonIIChainPolicy', 'ProtonProtonIIIChainPolicy', 'ReactionChainPolicy', 'TemperatureDependentChainPolicy', 'TripleAlphaChainPolicy', 'UNINITIALIZED', 'network_policy_status_to_string'] +class CNOChainPolicy(MultiReactionChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class CNOIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class CNOIIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class CNOIIIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class CNOIVChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class ConstructionResults: + @property + def engine(self) -> gridfire._gridfire.engine.DynamicEngine: + ... + @property + def scratch_blob(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... +class HotCNOChainPolicy(MultiReactionChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class HotCNOIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class HotCNOIIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class HotCNOIIIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class MainSequencePolicy(NetworkPolicy): + @typing.overload + def __init__(self, composition: fourdst._phys.composition.Composition) -> None: + """ + Construct MainSequencePolicy from an existing composition. + """ + @typing.overload + def __init__(self, seed_species: collections.abc.Sequence[fourdst._phys.atomic.Species], mass_fractions: collections.abc.Sequence[typing.SupportsFloat]) -> None: + """ + Construct MainSequencePolicy from seed species and mass fractions. + """ + def construct(self) -> ConstructionResults: + """ + Construct the network according to the policy. + """ + def get_engine_stack(self) -> list[gridfire._gridfire.engine.DynamicEngine]: + ... + def get_engine_types_stack(self) -> list[gridfire._gridfire.engine.EngineTypes]: + """ + Get the types of engines in the stack constructed by the network policy. + """ + def get_partition_function(self) -> gridfire._gridfire.partition.PartitionFunction: + ... + def get_seed_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the set of seed reactions required by the network policy. + """ + def get_seed_species(self) -> set[fourdst._phys.atomic.Species]: + """ + Get the set of seed species required by the network policy. + """ + def get_stack_scratch_blob(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... + def get_status(self) -> NetworkPolicyStatus: + """ + Get the current status of the network policy. + """ + def name(self) -> str: + """ + Get the name of the network policy. + """ +class MainSequenceReactionChainPolicy(MultiReactionChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class MultiReactionChainPolicy(ReactionChainPolicy): + pass +class NetworkPolicy: + pass +class NetworkPolicyStatus: + """ + Members: + + UNINITIALIZED + + INITIALIZED_UNVERIFIED + + MISSING_KEY_REACTION + + MISSING_KEY_SPECIES + + INITIALIZED_VERIFIED + """ + INITIALIZED_UNVERIFIED: typing.ClassVar[NetworkPolicyStatus] # value = + INITIALIZED_VERIFIED: typing.ClassVar[NetworkPolicyStatus] # value = + MISSING_KEY_REACTION: typing.ClassVar[NetworkPolicyStatus] # value = + MISSING_KEY_SPECIES: typing.ClassVar[NetworkPolicyStatus] # value = + UNINITIALIZED: typing.ClassVar[NetworkPolicyStatus] # value = + __members__: typing.ClassVar[dict[str, NetworkPolicyStatus]] # value = {'UNINITIALIZED': , 'INITIALIZED_UNVERIFIED': , 'MISSING_KEY_REACTION': , 'MISSING_KEY_SPECIES': , 'INITIALIZED_VERIFIED': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class ProtonProtonChainPolicy(MultiReactionChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class ProtonProtonIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class ProtonProtonIIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class ProtonProtonIIIChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +class ReactionChainPolicy: + pass +class TemperatureDependentChainPolicy(ReactionChainPolicy): + pass +class TripleAlphaChainPolicy(TemperatureDependentChainPolicy): + def __eq__(self, other: ReactionChainPolicy) -> bool: + """ + Check equality with another ReactionChainPolicy. + """ + def __hash__(self) -> int: + ... + def __init__(self) -> None: + ... + def __ne__(self, other: ReactionChainPolicy) -> bool: + """ + Check inequality with another ReactionChainPolicy. + """ + def __repr__(self) -> str: + ... + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the reaction chain contains a reaction with the given ID. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the reaction chain contains the given reaction. + """ + def get_reactions(self) -> gridfire._gridfire.reaction.ReactionSet: + """ + Get the ReactionSet representing this reaction chain. + """ + def hash(self, seed: typing.SupportsInt) -> int: + """ + Compute a hash value for the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ + @typing.overload + def name(self) -> str: + """ + Get the name of the reaction chain policy. + """ +def network_policy_status_to_string(status: NetworkPolicyStatus) -> str: + """ + Convert a NetworkPolicyStatus enum value to its string representation. + """ +INITIALIZED_UNVERIFIED: NetworkPolicyStatus # value = +INITIALIZED_VERIFIED: NetworkPolicyStatus # value = +MISSING_KEY_REACTION: NetworkPolicyStatus # value = +MISSING_KEY_SPECIES: NetworkPolicyStatus # value = +UNINITIALIZED: NetworkPolicyStatus # value = diff --git a/stubs/gridfiregridfire/_gridfire/reaction.pyi b/stubs/gridfiregridfire/_gridfire/reaction.pyi new file mode 100644 index 00000000..d2659168 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/reaction.pyi @@ -0,0 +1,249 @@ +""" +GridFire reaction bindings +""" +from __future__ import annotations +import collections.abc +import fourdst._phys.atomic +import fourdst._phys.composition +import typing +__all__: list[str] = ['LogicalReaclibReaction', 'RateCoefficientSet', 'ReaclibReaction', 'ReactionSet', 'get_all_reactions', 'packReactionSet'] +class LogicalReaclibReaction(ReaclibReaction): + @typing.overload + def __init__(self, reactions: collections.abc.Sequence[ReaclibReaction]) -> None: + """ + Construct a LogicalReaclibReaction from a vector of ReaclibReaction objects. + """ + @typing.overload + def __init__(self, reactions: collections.abc.Sequence[ReaclibReaction], is_reverse: bool) -> None: + """ + Construct a LogicalReaclibReaction from a vector of ReaclibReaction objects. + """ + def __len__(self) -> int: + """ + Overload len() to return the number of source rates. + """ + def add_reaction(self, reaction: ReaclibReaction) -> None: + """ + Add another Reaction source to this logical reaction. + """ + def calculate_forward_rate_log_derivative(self, T9: typing.SupportsFloat, rho: typing.SupportsFloat, Ye: typing.SupportsFloat, mue: typing.SupportsFloat, Composition: fourdst._phys.composition.Composition) -> float: + """ + Calculate the forward rate log derivative at a given temperature T9 (in units of 10^9 K). + """ + def calculate_rate(self, T9: typing.SupportsFloat, rho: typing.SupportsFloat, Ye: typing.SupportsFloat, mue: typing.SupportsFloat, Y: collections.abc.Sequence[typing.SupportsFloat], index_to_species_map: collections.abc.Mapping[typing.SupportsInt, fourdst._phys.atomic.Species]) -> float: + """ + Calculate the reaction rate at a given temperature T9 (in units of 10^9 K). Note that for a reaclib reaction only T9 is actually used, all other parameters are there for interface compatibility. + """ + def size(self) -> int: + """ + Get the number of source rates contributing to this logical reaction. + """ + def sources(self) -> list[str]: + """ + Get the list of source labels for the aggregated rates. + """ +class RateCoefficientSet: + def __init__(self, a0: typing.SupportsFloat, a1: typing.SupportsFloat, a2: typing.SupportsFloat, a3: typing.SupportsFloat, a4: typing.SupportsFloat, a5: typing.SupportsFloat, a6: typing.SupportsFloat) -> None: + """ + Construct a RateCoefficientSet with the given parameters. + """ +class ReaclibReaction: + __hash__: typing.ClassVar[None] = None + def __eq__(self, arg0: ReaclibReaction) -> bool: + """ + Equality operator for reactions based on their IDs. + """ + def __init__(self, id: str, peName: str, chapter: typing.SupportsInt, reactants: collections.abc.Sequence[fourdst._phys.atomic.Species], products: collections.abc.Sequence[fourdst._phys.atomic.Species], qValue: typing.SupportsFloat, label: str, sets: RateCoefficientSet, reverse: bool = False) -> None: + """ + Construct a Reaction with the given parameters. + """ + def __neq__(self, arg0: ReaclibReaction) -> bool: + """ + Inequality operator for reactions based on their IDs. + """ + def __repr__(self) -> str: + ... + def all_species(self) -> set[fourdst._phys.atomic.Species]: + """ + Get all species involved in the reaction (both reactants and products) as a set. + """ + def calculate_rate(self, T9: typing.SupportsFloat, rho: typing.SupportsFloat, Y: collections.abc.Sequence[typing.SupportsFloat]) -> float: + """ + Calculate the reaction rate at a given temperature T9 (in units of 10^9 K). + """ + def chapter(self) -> int: + """ + Get the REACLIB chapter number defining the reaction structure. + """ + def contains(self, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if the reaction contains a specific species. + """ + def contains_product(self, arg0: fourdst._phys.atomic.Species) -> bool: + """ + Check if the reaction contains a specific product species. + """ + def contains_reactant(self, arg0: fourdst._phys.atomic.Species) -> bool: + """ + Check if the reaction contains a specific reactant species. + """ + def excess_energy(self) -> float: + """ + Calculate the excess energy from the mass difference of reactants and products. + """ + def hash(self, seed: typing.SupportsInt = 0) -> int: + """ + Compute a hash for the reaction based on its ID. + """ + def id(self) -> str: + """ + Get the unique identifier of the reaction. + """ + def is_reverse(self) -> bool: + """ + Check if this is a reverse reaction rate. + """ + def num_species(self) -> int: + """ + Count the number of species in the reaction. + """ + def peName(self) -> str: + """ + Get the reaction name in (projectile, ejectile) notation (e.g., 'p(p,g)d'). + """ + def product_species(self) -> set[fourdst._phys.atomic.Species]: + """ + Get the product species of the reaction as a set. + """ + def products(self) -> list[fourdst._phys.atomic.Species]: + """ + Get a list of product species in the reaction. + """ + def qValue(self) -> float: + """ + Get the Q-value of the reaction in MeV. + """ + def rateCoefficients(self) -> RateCoefficientSet: + """ + get the set of rate coefficients. + """ + def reactant_species(self) -> set[fourdst._phys.atomic.Species]: + """ + Get the reactant species of the reaction as a set. + """ + def reactants(self) -> list[fourdst._phys.atomic.Species]: + """ + Get a list of reactant species in the reaction. + """ + def sourceLabel(self) -> str: + """ + Get the source label for the rate data (e.g., 'wc12w', 'st08'). + """ + @typing.overload + def stoichiometry(self, species: fourdst._phys.atomic.Species) -> int: + """ + Get the stoichiometry of the reaction as a map from species to their coefficients. + """ + @typing.overload + def stoichiometry(self) -> dict[fourdst._phys.atomic.Species, int]: + """ + Get the stoichiometry of the reaction as a map from species to their coefficients. + """ +class ReactionSet: + __hash__: typing.ClassVar[None] = None + @staticmethod + def from_clones(reactions: collections.abc.Sequence[...]) -> ReactionSet: + """ + Create a ReactionSet that takes ownership of the reactions by cloning the input reactions. + """ + def __eq__(self, LogicalReactionSet: ReactionSet) -> bool: + """ + Equality operator for LogicalReactionSets based on their contents. + """ + def __getitem__(self, index: typing.SupportsInt) -> ...: + """ + Get a LogicalReaclibReaction by index. + """ + def __getitem___(self, id: str) -> ...: + """ + Get a LogicalReaclibReaction by its ID. + """ + @typing.overload + def __init__(self, reactions: collections.abc.Sequence[...]) -> None: + """ + Construct a LogicalReactionSet from a vector of LogicalReaclibReaction objects. + """ + @typing.overload + def __init__(self) -> None: + """ + Default constructor for an empty LogicalReactionSet. + """ + @typing.overload + def __init__(self, other: ReactionSet) -> None: + """ + Copy constructor for LogicalReactionSet. + """ + def __len__(self) -> int: + """ + Overload len() to return the number of LogicalReactions. + """ + def __ne__(self, LogicalReactionSet: ReactionSet) -> bool: + """ + Inequality operator for LogicalReactionSets based on their contents. + """ + def __repr__(self) -> str: + ... + def add_reaction(self, reaction: ...) -> None: + """ + Add a LogicalReaclibReaction to the set. + """ + def clear(self) -> None: + """ + Remove all LogicalReactions from the set. + """ + @typing.overload + def contains(self, id: str) -> bool: + """ + Check if the set contains a specific LogicalReaclibReaction. + """ + @typing.overload + def contains(self, reaction: ...) -> bool: + """ + Check if the set contains a specific Reaction. + """ + def contains_product(self, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if any reaction in the set has the species as a product. + """ + def contains_reactant(self, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if any reaction in the set has the species as a reactant. + """ + def contains_species(self, species: fourdst._phys.atomic.Species) -> bool: + """ + Check if any reaction in the set involves the given species. + """ + def getReactionSetSpecies(self) -> set[fourdst._phys.atomic.Species]: + """ + Get all species involved in the reactions of the set as a set of Species objects. + """ + def hash(self, seed: typing.SupportsInt = 0) -> int: + """ + Compute a hash for the LogicalReactionSet based on its contents. + """ + def remove_reaction(self, reaction: ...) -> None: + """ + Remove a LogicalReaclibReaction from the set. + """ + def size(self) -> int: + """ + Get the number of LogicalReactions in the set. + """ +def get_all_reactions() -> ReactionSet: + """ + Get all reactions from the REACLIB database. + """ +def packReactionSet(reactionSet: ReactionSet) -> ReactionSet: + """ + Convert a ReactionSet to a LogicalReactionSet by aggregating reactions with the same peName. + """ diff --git a/stubs/gridfiregridfire/_gridfire/screening.pyi b/stubs/gridfiregridfire/_gridfire/screening.pyi new file mode 100644 index 00000000..e2b9c181 --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/screening.pyi @@ -0,0 +1,68 @@ +""" +GridFire plasma screening bindings +""" +from __future__ import annotations +import collections.abc +import fourdst._phys.atomic +import gridfire._gridfire.reaction +import typing +__all__: list[str] = ['BARE', 'BareScreeningModel', 'ScreeningModel', 'ScreeningType', 'WEAK', 'WeakScreeningModel', 'selectScreeningModel'] +class BareScreeningModel: + def __init__(self) -> None: + ... + def calculateScreeningFactors(self, reactions: gridfire._gridfire.reaction.ReactionSet, species: collections.abc.Sequence[fourdst._phys.atomic.Species], Y: collections.abc.Sequence[typing.SupportsFloat], T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> list[float]: + """ + Calculate the bare plasma screening factors. This always returns 1.0 (bare) + """ +class ScreeningModel: + pass +class ScreeningType: + """ + Members: + + BARE + + WEAK + """ + BARE: typing.ClassVar[ScreeningType] # value = + WEAK: typing.ClassVar[ScreeningType] # value = + __members__: typing.ClassVar[dict[str, ScreeningType]] # value = {'BARE': , 'WEAK': } + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: typing.SupportsInt) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: typing.SupportsInt) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class WeakScreeningModel: + def __init__(self) -> None: + ... + def calculateScreeningFactors(self, reactions: gridfire._gridfire.reaction.ReactionSet, species: collections.abc.Sequence[fourdst._phys.atomic.Species], Y: collections.abc.Sequence[typing.SupportsFloat], T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> list[float]: + """ + Calculate the weak plasma screening factors using the Salpeter (1954) model. + """ +def selectScreeningModel(type: ScreeningType) -> ScreeningModel: + """ + Select a screening model based on the specified type. Returns a pointer to the selected model. + """ +BARE: ScreeningType # value = +WEAK: ScreeningType # value = diff --git a/stubs/gridfiregridfire/_gridfire/solver.pyi b/stubs/gridfiregridfire/_gridfire/solver.pyi new file mode 100644 index 00000000..44ae0beb --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/solver.pyi @@ -0,0 +1,157 @@ +""" +GridFire numerical solver bindings +""" +from __future__ import annotations +import collections.abc +import fourdst._phys.atomic +import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads +import gridfire._gridfire.type +import types +import typing +__all__: list[str] = ['GridSolver', 'GridSolverContext', 'MultiZoneDynamicNetworkSolver', 'PointSolver', 'PointSolverContext', 'PointSolverTimestepContext', 'SingleZoneDynamicNetworkSolver', 'SolverContextBase'] +class GridSolver(MultiZoneDynamicNetworkSolver): + def __init__(self, engine: gridfire._gridfire.engine.DynamicEngine, solver: SingleZoneDynamicNetworkSolver) -> None: + """ + Initialize the GridSolver object. + """ + def evaluate(self, solver_ctx: SolverContextBase, netIns: collections.abc.Sequence[gridfire._gridfire.type.NetIn]) -> list[gridfire._gridfire.type.NetOut]: + """ + evaluate the dynamic engine using the dynamic engine class + """ +class GridSolverContext(SolverContextBase): + detailed_logging: bool + stdout_logging: bool + zone_completion_logging: bool + def __init__(self, ctx_template: gridfire._gridfire.engine.scratchpads.StateBlob) -> None: + ... + @typing.overload + def clear_callback(self) -> None: + ... + @typing.overload + def clear_callback(self, zone_idx: typing.SupportsInt) -> None: + ... + def init(self) -> None: + ... + def reset(self) -> None: + ... + @typing.overload + def set_callback(self, callback: collections.abc.Callable[[...], None]) -> None: + ... + @typing.overload + def set_callback(self, callback: collections.abc.Callable[[...], None], zone_idx: typing.SupportsInt) -> None: + ... +class MultiZoneDynamicNetworkSolver: + def evaluate(self, solver_ctx: SolverContextBase, netIns: collections.abc.Sequence[gridfire._gridfire.type.NetIn]) -> list[gridfire._gridfire.type.NetOut]: + """ + evaluate the dynamic engine using the dynamic engine class for multiple zones (using openmp if available) + """ +class PointSolver(SingleZoneDynamicNetworkSolver): + def __init__(self, engine: gridfire._gridfire.engine.DynamicEngine) -> None: + """ + Initialize the PointSolver object. + """ + def evaluate(self, solver_ctx: SolverContextBase, netIn: gridfire._gridfire.type.NetIn, display_trigger: bool = False, force_reinitialization: bool = False) -> gridfire._gridfire.type.NetOut: + """ + evaluate the dynamic engine using the dynamic engine class + """ +class PointSolverContext: + callback: collections.abc.Callable[[PointSolverTimestepContext], None] | None + detailed_logging: bool + stdout_logging: bool + def __init__(self, engine_ctx: gridfire._gridfire.engine.scratchpads.StateBlob) -> None: + ... + def clear_context(self) -> None: + ... + def has_context(self) -> bool: + ... + def init(self) -> None: + ... + def init_context(self) -> None: + ... + def reset_all(self) -> None: + ... + def reset_cvode(self) -> None: + ... + def reset_user(self) -> None: + ... + @property + def J(self) -> _generic_SUNMatrix: + ... + @property + def LS(self) -> _generic_SUNLinearSolver: + ... + @property + def Y(self) -> _generic_N_Vector: + ... + @property + def YErr(self) -> _generic_N_Vector: + ... + @property + def abs_tol(self) -> float: + ... + @abs_tol.setter + def abs_tol(self, arg1: typing.SupportsFloat) -> None: + ... + @property + def cvode_mem(self) -> types.CapsuleType: + ... + @property + def engine_ctx(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... + @property + def num_steps(self) -> int: + ... + @property + def rel_tol(self) -> float: + ... + @rel_tol.setter + def rel_tol(self, arg1: typing.SupportsFloat) -> None: + ... + @property + def sun_ctx(self) -> SUNContext_: + ... +class PointSolverTimestepContext: + @property + def T9(self) -> float: + ... + @property + def currentConvergenceFailures(self) -> int: + ... + @property + def currentNonlinearIterations(self) -> int: + ... + @property + def dt(self) -> float: + ... + @property + def engine(self) -> gridfire._gridfire.engine.DynamicEngine: + ... + @property + def last_step_time(self) -> float: + ... + @property + def networkSpecies(self) -> list[fourdst._phys.atomic.Species]: + ... + @property + def num_steps(self) -> int: + ... + @property + def rho(self) -> float: + ... + @property + def state(self) -> list[float]: + ... + @property + def state_ctx(self) -> gridfire._gridfire.engine.scratchpads.StateBlob: + ... + @property + def t(self) -> float: + ... +class SingleZoneDynamicNetworkSolver: + def evaluate(self, solver_ctx: SolverContextBase, netIn: gridfire._gridfire.type.NetIn) -> gridfire._gridfire.type.NetOut: + """ + evaluate the dynamic engine using the dynamic engine class for a single zone + """ +class SolverContextBase: + pass diff --git a/stubs/gridfiregridfire/_gridfire/type.pyi b/stubs/gridfiregridfire/_gridfire/type.pyi new file mode 100644 index 00000000..739086da --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/type.pyi @@ -0,0 +1,67 @@ +""" +GridFire type bindings +""" +from __future__ import annotations +import fourdst._phys.composition +import typing +__all__: list[str] = ['NetIn', 'NetOut'] +class NetIn: + composition: fourdst._phys.composition.Composition + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + @property + def density(self) -> float: + ... + @density.setter + def density(self, arg0: typing.SupportsFloat) -> None: + ... + @property + def dt0(self) -> float: + ... + @dt0.setter + def dt0(self, arg0: typing.SupportsFloat) -> None: + ... + @property + def energy(self) -> float: + ... + @energy.setter + def energy(self, arg0: typing.SupportsFloat) -> None: + ... + @property + def tMax(self) -> float: + ... + @tMax.setter + def tMax(self, arg0: typing.SupportsFloat) -> None: + ... + @property + def temperature(self) -> float: + ... + @temperature.setter + def temperature(self, arg0: typing.SupportsFloat) -> None: + ... +class NetOut: + def __repr__(self) -> str: + ... + @property + def composition(self) -> fourdst._phys.composition.Composition: + ... + @property + def dEps_dRho(self) -> float: + ... + @property + def dEps_dT(self) -> float: + ... + @property + def energy(self) -> float: + ... + @property + def num_steps(self) -> int: + ... + @property + def specific_neutrino_energy_loss(self) -> float: + ... + @property + def specific_neutrino_flux(self) -> float: + ... diff --git a/stubs/gridfiregridfire/_gridfire/utils/__init__.pyi b/stubs/gridfiregridfire/_gridfire/utils/__init__.pyi new file mode 100644 index 00000000..0a86e92c --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/utils/__init__.pyi @@ -0,0 +1,18 @@ +""" +GridFire utility method bindings +""" +from __future__ import annotations +import fourdst._phys.composition +import gridfire._gridfire.engine +import gridfire._gridfire.engine.scratchpads +import typing +from . import hashing +__all__: list[str] = ['formatNuclearTimescaleLogString', 'hash_atomic', 'hash_reaction', 'hashing'] +def formatNuclearTimescaleLogString(ctx: gridfire._gridfire.engine.scratchpads.StateBlob, engine: gridfire._gridfire.engine.DynamicEngine, Y: fourdst._phys.composition.Composition, T9: typing.SupportsFloat, rho: typing.SupportsFloat) -> str: + """ + Format a string for logging nuclear timescales based on temperature, density, and energy generation rate. + """ +def hash_atomic(a: typing.SupportsInt, z: typing.SupportsInt) -> int: + ... +def hash_reaction(reaction: ...) -> int: + ... diff --git a/stubs/gridfiregridfire/_gridfire/utils/hashing/__init__.pyi b/stubs/gridfiregridfire/_gridfire/utils/hashing/__init__.pyi new file mode 100644 index 00000000..b85a400a --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/utils/hashing/__init__.pyi @@ -0,0 +1,6 @@ +""" +module for gridfire hashing functions +""" +from __future__ import annotations +from . import reaction +__all__: list[str] = ['reaction'] diff --git a/stubs/gridfiregridfire/_gridfire/utils/hashing/reaction.pyi b/stubs/gridfiregridfire/_gridfire/utils/hashing/reaction.pyi new file mode 100644 index 00000000..131f482d --- /dev/null +++ b/stubs/gridfiregridfire/_gridfire/utils/hashing/reaction.pyi @@ -0,0 +1,12 @@ +""" +utility module for hashing gridfire reaction functions +""" +from __future__ import annotations +import typing +__all__: list[str] = ['mix_species', 'multiset_combine', 'splitmix64'] +def mix_species(a: typing.SupportsInt, z: typing.SupportsInt) -> int: + ... +def multiset_combine(acc: typing.SupportsInt, x: typing.SupportsInt) -> int: + ... +def splitmix64(x: typing.SupportsInt) -> int: + ... diff --git a/subprojects/cppad.wrap b/subprojects/cppad.wrap new file mode 100644 index 00000000..56ab5b18 --- /dev/null +++ b/subprojects/cppad.wrap @@ -0,0 +1,7 @@ +[wrap-file] +directory = CppAD-20250000.2 +source_url = https://github.com/coin-or/CppAD/archive/refs/tags/20250000.2.tar.gz +source_filename = CppAD-20250000.2.tar.gz +source_hash = d6688c7530913dfd286f7db71b007fd96df10a9e8b43ad74539e4450c9917ebf + +[cmake] \ No newline at end of file diff --git a/subprojects/fourdst.wrap b/subprojects/fourdst.wrap index a805e371..5ab46be9 100644 --- a/subprojects/fourdst.wrap +++ b/subprojects/fourdst.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://github.com/4D-STAR/fourdst -revision = v0.9.14 +revision = v0.9.18 depth = 1 diff --git a/subprojects/mimalloc.wrap b/subprojects/mimalloc.wrap new file mode 100644 index 00000000..555cdc7e --- /dev/null +++ b/subprojects/mimalloc.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = mimalloc-3.1.5 +source_url = https://github.com/microsoft/mimalloc/archive/refs/tags/v3.1.5.tar.gz +source_filename = mimalloc-3.1.5.tar.gz +source_hash = 1c6949032069d5ebea438ec5cedd602d06f40a92ddf0f0d9dcff0993e5f6635c +patch_filename = mimalloc_3.1.5-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/mimalloc_3.1.5-1/get_patch +patch_hash = 321b4507c1adda5b7aa9954a5f1748e17bf30a11142b4f6c3d52929523565e80 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/mimalloc_3.1.5-1/mimalloc-3.1.5.tar.gz +wrapdb_version = 3.1.5-1 + +[provide] +mimalloc = mi_dep diff --git a/subprojects/unordered_dense.wrap b/subprojects/unordered_dense.wrap new file mode 100644 index 00000000..fbfb60cb --- /dev/null +++ b/subprojects/unordered_dense.wrap @@ -0,0 +1,6 @@ +[wrap-git] +url = https://github.com/martinus/unordered_dense.git +revision = v4.8.1 +depth = 1 + +[cmake] \ No newline at end of file diff --git a/tests/extern/C/gridfire_evolve_multi.c b/tests/extern/C/gridfire_evolve_multi.c new file mode 100644 index 00000000..bc6609c9 --- /dev/null +++ b/tests/extern/C/gridfire_evolve_multi.c @@ -0,0 +1,125 @@ +#include "gridfire/extern/gridfire_extern.h" +#include + +#define NUM_SPECIES 8 +#define ZONES 100 +#define ZONE_POLICY MULTI_ZONE + +// Define a macro to check return codes +#define CHECK_RET_CODE(ret, ctx, msg) \ + if ((ret) != 0 && (ret) != 1) { \ + printf("Error %s: %s (No. %d) [%s]\n", msg, gf_error_code_to_string(ret), ret, gf_get_last_error_message(ctx)); \ + gf_free(ZONE_POLICY, ctx); \ + return 1; \ + } + +int main() { + printf("Testing GridFireEvolve Multi\n"); + printf(" Number of zones: %d\n", ZONES); + printf(" Number of species: %d\n", NUM_SPECIES); + printf(" Initializing.."); + void* ctx = gf_init(ZONE_POLICY); + printf(" Done.\n"); + printf(" Setting number of zones to %d..", ZONES); + gf_set_num_zones(ZONE_POLICY, ctx, ZONES); + printf(" Done.\n"); + + const char* species_names[NUM_SPECIES]; + species_names[0] = "H-1"; + species_names[1] = "He-3"; + species_names[2] = "He-4"; + species_names[3] = "C-12"; + species_names[4] = "N-14"; + species_names[5] = "O-16"; + species_names[6] = "Ne-20"; + species_names[7] = "Mg-24"; + const double abundance_root[NUM_SPECIES] = { + 0.702616602672027, + 9.74791583949078e-06, + 0.06895512307276903, + 0.00025, + 7.855418029399437e-05, + 0.0006014411598306529, + 8.103062886768109e-05, + 2.151340851063217e-05 + }; + + double abundances[ZONES][NUM_SPECIES]; + for (size_t zone = 0; zone < ZONES; zone++) { + for (size_t i = 0; i < NUM_SPECIES; i++) { + abundances[zone][i] = abundance_root[i]; + } + } + + double Temps[ZONES]; + double Rhos[ZONES]; + + for (size_t zone = 0; zone < ZONES; zone++) { + Temps[zone] = 1.0e7 + (double)zone * 1.0e5; // From 10 million K to 20 million K + Rhos[zone] = 1.5e2; + printf("Zone %zu - Temp: %e K, Rho: %e g/cm^3\n", zone, Temps[zone], Rhos[zone]); + } + return 0; + + printf(" Registering species..."); + int ret = gf_register_species(ctx, NUM_SPECIES, species_names); + CHECK_RET_CODE(ret, ctx, "SPECIES"); + printf(" Done.\n"); + + printf(" Constructing engine from policy..."); + ret = gf_construct_engine_from_policy(ctx, "MAIN_SEQUENCE_POLICY", abundance_root, NUM_SPECIES); + CHECK_RET_CODE(ret, ctx, "MAIN_SEQUENCE_POLICY"); + printf(" Done.\n"); + + printf(" Constructing solver from engine..."); + ret = gf_construct_solver_from_engine(ctx); + CHECK_RET_CODE(ret, ctx, "CVODE"); + printf(" Done.\n"); + + double Y_out[ZONES][NUM_SPECIES]; + double energy_out[ZONES]; + double dEps_dT[ZONES]; + double dEps_dRho[ZONES]; + double specific_neutrino_energy_loss[ZONES]; + double specific_neutrino_flux[ZONES]; + double mass_lost[ZONES]; + + printf(" Evolving...\n"); + ret = gf_evolve( + ZONE_POLICY, + ctx, + abundances, + NUM_SPECIES, + Temps, // Temperature in K + Rhos, // Density in g/cm^3 + 3e17, // Time step in seconds + 1e-12, + Y_out, + energy_out, + dEps_dT, + dEps_dRho, + specific_neutrino_energy_loss, + specific_neutrino_flux, &mass_lost + ); + CHECK_RET_CODE(ret, ctx, "EVOLUTION"); + printf(" Done.\n"); + + + printf("Evolved abundances:\n"); + for (size_t zone = 0; zone < ZONES; zone++) { + printf("=== Zone %zu ===\n", zone); + for (size_t i = 0; i < NUM_SPECIES; i++) { + printf(" Species %s: %e\n", species_names[i], Y_out[zone][i]); + } + printf(" Energy output: %e\n", energy_out[zone]); + printf(" dEps/dT: %e\n", dEps_dT[zone]); + printf(" dEps/dRho: %e\n", dEps_dRho[zone]); + printf(" Specific neutrino energy loss: %e\n", specific_neutrino_energy_loss[zone]); + printf(" Specific neutrino flux: %e\n", specific_neutrino_flux[zone]); + printf(" Mass lost: %e\n", mass_lost[zone]); + } + + gf_free(ZONE_POLICY, ctx); + + return 0; +} \ No newline at end of file diff --git a/tests/extern/C/gridfire_evolve.c b/tests/extern/C/gridfire_evolve_single.c similarity index 78% rename from tests/extern/C/gridfire_evolve.c rename to tests/extern/C/gridfire_evolve_single.c index 7834dabf..8ee076e3 100644 --- a/tests/extern/C/gridfire_evolve.c +++ b/tests/extern/C/gridfire_evolve_single.c @@ -4,14 +4,14 @@ // Define a macro to check return codes #define CHECK_RET_CODE(ret, ctx, msg) \ - if (ret != 0 && ret != 1) { \ - printf("Error %s: %s\n", msg, gf_get_last_error_message(ctx)); \ - gf_free(ctx); \ + if ((ret) != 0 && (ret) != 1) { \ + printf("Error %s: %s [%s]\n", msg, gf_get_last_error_message(ctx), gf_error_code_to_string(ret)); \ + gf_free(SINGLE_ZONE, ctx); \ return 1; \ } int main() { - void* ctx = gf_init(); + void* ctx = gf_init(SINGLE_ZONE); const char* species_names[NUM_SPECIES]; species_names[0] = "H-1"; @@ -39,7 +39,7 @@ int main() { ret = gf_construct_engine_from_policy(ctx, "MAIN_SEQUENCE_POLICY", abundances, NUM_SPECIES); CHECK_RET_CODE(ret, ctx, "MAIN_SEQUENCE_POLICY"); - ret = gf_construct_solver_from_engine(ctx, "CVODE"); + ret = gf_construct_solver_from_engine(ctx); CHECK_RET_CODE(ret, ctx, "CVODE"); double Y_out[NUM_SPECIES]; @@ -50,21 +50,24 @@ int main() { double specific_neutrino_flux; double mass_lost; + const double T_in = 1e7; // Temperature in K + const double rho_in = 1.5e2; // Density in g/cm^3 + ret = gf_evolve( + SINGLE_ZONE, ctx, abundances, NUM_SPECIES, - 1.5e7, // Temperature in K - 1.5e2, // Density in g/cm^3 + &T_in, // Temperature in K + &rho_in, // Density in g/cm^3 3e17, // Time step in seconds - 1e-12, // Initial time step in seconds + 1e-12, Y_out, &energy_out, &dEps_dT, &dEps_dRho, &specific_neutrino_energy_loss, - &specific_neutrino_flux, - &mass_lost + &specific_neutrino_flux, &mass_lost ); CHECK_RET_CODE(ret, ctx, "EVOLUTION"); @@ -81,7 +84,7 @@ int main() { printf("Specific neutrino flux: %e\n", specific_neutrino_flux); printf("Mass lost: %e\n", mass_lost); - gf_free(ctx); + gf_free(SINGLE_ZONE, ctx); return 0; } \ No newline at end of file diff --git a/tests/extern/C/meson.build b/tests/extern/C/meson.build index 80db9f58..98f44f5e 100644 --- a/tests/extern/C/meson.build +++ b/tests/extern/C/meson.build @@ -1,5 +1,11 @@ -executable('test_c_extern', 'gridfire_evolve.c', +executable('gf_extern_c_single', 'gridfire_evolve_single.c', install: false, c_args: ['-Wall', '-Wextra'], dependencies: [gridfire_extern_dep] -) \ No newline at end of file +) + +executable('gf_extern_c_multi', 'gridfire_evolve_multi.c', + install: false, + c_args: ['-Wall', '-Wextra'], + dependencies: [gridfire_extern_dep] +) diff --git a/tests/extern/fortran/gridfire_evolve_multi.f90 b/tests/extern/fortran/gridfire_evolve_multi.f90 new file mode 100644 index 00000000..341e2d48 --- /dev/null +++ b/tests/extern/fortran/gridfire_evolve_multi.f90 @@ -0,0 +1,131 @@ +program main_multi + use iso_c_binding + use gridfire_mod + implicit none + + ! --- Constants --- + integer, parameter :: NUM_SPECIES = 8 + integer, parameter :: ZONES = 100 + + type(GridFire) :: net + integer(c_int) :: ierr + integer :: i, z + + ! --- 1. Define Species --- + character(len=5), dimension(NUM_SPECIES) :: species_names = [ & + "H-1 ", & + "He-3 ", & + "He-4 ", & + "C-12 ", & + "N-14 ", & + "O-16 ", & + "Ne-20", & + "Mg-24" & + ] + + ! Initial Mass Fractions + ! Standard solar-ish composition template + real(c_double), dimension(NUM_SPECIES) :: abundance_root = [ & + 0.702616602672027d0, & + 9.74791583949078d-06, & + 0.06895512307276903d0, & + 0.00025d0, & + 7.855418029399437d-05, & + 0.0006014411598306529d0, & + 8.103062886768109d-05, & + 2.151340851063217d-05 & + ] + + ! --- Multi-Zone Arrays --- + ! Fortran is Column-Major. To match C's Row-Major [ZONES][SPECIES], + ! we dimension as (SPECIES, ZONES) so that Species are contiguous for each Zone. + real(c_double), dimension(NUM_SPECIES, ZONES) :: Y_in, Y_out + + ! Thermodynamic Conditions Arrays + real(c_double), dimension(ZONES) :: T_arr + real(c_double), dimension(ZONES) :: rho_arr + + ! Output Arrays + real(c_double), dimension(ZONES) :: energy_out + real(c_double), dimension(ZONES) :: dedt + real(c_double), dimension(ZONES) :: dedrho + real(c_double), dimension(ZONES) :: snu_e_loss + real(c_double), dimension(ZONES) :: snu_flux + real(c_double), dimension(ZONES) :: dmass + + ! Time settings + real(c_double) :: tMax = 3.0e17 ! 10 Gyr total time + real(c_double) :: dt0 = 1e-12 ! Starting Timestep + + ! --- 2. Setup Data --- + print *, "Testing GridFireEvolve Multi (Fortran)" + print *, " Number of zones: ", ZONES + print *, " Number of species: ", NUM_SPECIES + + do z = 1, ZONES + ! Initialize Abundances (Copy root to every zone) + Y_in(:, z) = abundance_root + + ! Initialize T and Rho gradient + ! T: 1.0e7 -> 2.0e7 in steps of 1.0e5 + T_arr(z) = 1.0d7 + dble(z-1) * 1.0d5 + rho_arr(z) = 1.5d2 + + if (z <= 3) then + print '(A, I0, A, ES12.5, A, ES12.5, A)', & + " Zone ", z-1, " - Temp: ", T_arr(z), " K, Rho: ", rho_arr(z), " g/cm^3" + end if + end do + + ! --- 3. Initialize GridFire Multi-Zone --- + print *, "Initializing GridFire..." + ! Note: Pass integer(c_size_t) for zone count + call net%gff_init(MULTI_ZONE, int(ZONES, c_size_t)) + + ! --- 4. Register Species --- + print *, "Registering species..." + call net%gff_register_species(species_names) + + ! --- 5. Configure Engine & Solver --- + print *, "Setting up Main Sequence Policy..." + call net%gff_setup_policy("MAIN_SEQUENCE_POLICY", abundance_root) + + print *, "Setting up CVODE Solver..." + call net%gff_setup_solver("CVODE") + + ! --- 6. Evolve --- + print *, "Evolving system..." + + ! Note: We pass the arrays T_arr and rho_arr. + call net%gff_evolve(Y_in, T_arr, rho_arr, tMax, dt0, & + Y_out, energy_out, dedt, dedrho, & + snu_e_loss, snu_flux, dmass, ierr) + + if (ierr /= 0) then + print *, "Evolution Failed with error code: ", ierr + print *, "Error Message: ", net%gff_get_last_error() + call net%gff_free() + stop + end if + + ! --- 7. Report Results --- + print *, "" + print *, "--- Results (First 3 Zones) ---" + + do z = 1, 3 + print *, "=== Zone ", z-1, " ===" + print '(A, ES12.5, A)', " Energy Gen: ", energy_out(z), " erg/g/s" + print '(A, ES12.5)', " Mass Lost: ", dmass(z) + print '(A, ES12.5)', " T: ", T_arr(z) + + print *, " Key Abundances (H-1, He-4, C-12):" + print '(3(ES12.5, 1X))', Y_out(1, z), Y_out(3, z), Y_out(4, z) + print *, "" + end do + + print *, "... (Zones 4-", ZONES, " omitted) ..." + + ! --- 8. Cleanup --- + call net%gff_free() + +end program main_multi \ No newline at end of file diff --git a/tests/extern/fortran/gridfire_evolve.f90 b/tests/extern/fortran/gridfire_evolve_single.f90 similarity index 82% rename from tests/extern/fortran/gridfire_evolve.f90 rename to tests/extern/fortran/gridfire_evolve_single.f90 index ac0b9c4d..0f38326a 100644 --- a/tests/extern/fortran/gridfire_evolve.f90 +++ b/tests/extern/fortran/gridfire_evolve_single.f90 @@ -41,30 +41,31 @@ program main ! Thermodynamic Conditions (Solar Core-ish) real(c_double) :: T = 1.5e7 ! 15 Million K real(c_double) :: rho = 150.0e0 ! 150 g/cm^3 - real(c_double) :: dt = 3.0e17 ! 1 second timestep + real(c_double) :: tMax = 3.0e17 ! 10 Gyr total time + real(c_double) :: dt0 = 1e-12 ! Starting Timestep ! --- 2. Initialize GridFire --- print *, "Initializing GridFire..." - call net%gff_init() + call net%gff_init(SINGLE_ZONE) ! --- 3. Register Species --- print *, "Registering species..." - call net%register_species(species_names) + call net%gff_register_species(species_names) ! --- 4. Configure Engine & Solver --- print *, "Setting up Main Sequence Policy..." - call net%setup_policy("MAIN_SEQUENCE_POLICY", Y_in) + call net%gff_setup_policy("MAIN_SEQUENCE_POLICY", Y_in) print *, "Setting up CVODE Solver..." - call net%setup_solver("CVODE") + call net%gff_setup_solver("CVODE") ! --- 5. Evolve --- - print *, "Evolving system (dt =", dt, "s)..." - call net%evolve(Y_in, T, rho, dt, Y_out, energy_out, dedt, dedrho, snu_e_loss, snu_flux, dmass, ierr) + print *, "Evolving system (t = ", tMax, "s dt =", dt0, "s)..." + call net%gff_evolve(Y_in, T, rho, tMax, dt0, Y_out, energy_out, dedt, dedrho, snu_e_loss, snu_flux, dmass, ierr) if (ierr /= 0) then print *, "Evolution Failed with error code: ", ierr - print *, "Error Message: ", net%get_last_error() + print *, "Error Message: ", net%gff_get_last_error() call net%gff_free() ! Always cleanup stop end if diff --git a/tests/extern/fortran/meson.build b/tests/extern/fortran/meson.build index 60601a00..6e7738c3 100644 --- a/tests/extern/fortran/meson.build +++ b/tests/extern/fortran/meson.build @@ -1,5 +1,11 @@ -executable('test_fortran_extern', 'gridfire_evolve.f90', +executable('gf_fortran_single_zone_test', 'gridfire_evolve_single.f90', install: false, fortran_args: ['-Wall', '-Wextra'], dependencies: [gridfire_fortran_dep] -) \ No newline at end of file +) + +executable('gf_fortran_multi_zone_test', 'gridfire_evolve_multi.f90', + install: false, + fortran_args: ['-Wall', '-Wextra'], + dependencies: [gridfire_fortran_dep] +) diff --git a/tests/graphnet_sandbox/main.cpp b/tests/graphnet_sandbox/main.cpp index f42ffa67..f53eee32 100644 --- a/tests/graphnet_sandbox/main.cpp +++ b/tests/graphnet_sandbox/main.cpp @@ -1,7 +1,12 @@ +// ReSharper disable CppUnusedIncludeDirective #include #include +#include +#include +#include #include "gridfire/gridfire.h" +#include // Required for parallel_setup #include "fourdst/composition/composition.h" #include "fourdst/logging/logging.h" @@ -14,7 +19,7 @@ #include -#include "gridfire/reaction/reaclib.h" +#include "gridfire/utils/gf_omp.h" static std::terminate_handler g_previousHandler = nullptr; @@ -26,7 +31,7 @@ gridfire::NetIn init(const double temp, const double rho, const double tMax) { std::setlocale(LC_ALL, ""); g_previousHandler = std::set_terminate(quill_terminate_handler); quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); - logger->set_log_level(quill::LogLevel::TraceL2); + logger->set_log_level(quill::LogLevel::Info); using namespace gridfire; const std::vector X = {0.7081145999999999, 2.94e-5, 0.276, 0.003, 0.0011, 9.62e-3, 1.62e-3, 5.16e-4}; @@ -108,14 +113,14 @@ void log_results(const gridfire::NetOut& netOut, const gridfire::NetIn& netIn) { std::vector rowLabels = [&]() -> std::vector { std::vector labels; for (const auto& species : logSpecies) { - labels.push_back(std::string(species.name())); + labels.emplace_back(species.name()); } - labels.push_back("ε"); - labels.push_back("dε/dT"); - labels.push_back("dε/dρ"); - labels.push_back("Eν"); - labels.push_back("Fν"); - labels.push_back("<μ>"); + labels.emplace_back("ε"); + labels.emplace_back("dε/dT"); + labels.emplace_back("dε/dρ"); + labels.emplace_back("Eν"); + labels.emplace_back("Fν"); + labels.emplace_back("<μ>"); return labels; }(); @@ -138,18 +143,18 @@ void log_results(const gridfire::NetOut& netOut, const gridfire::NetIn& netIn) { } -void record_abundance_history_callback(const gridfire::solver::CVODESolverStrategy::TimestepContext& ctx) { +void record_abundance_history_callback(const gridfire::solver::PointSolverTimestepContext& ctx) { s_wrote_abundance_history = true; const auto& engine = ctx.engine; // std::unordered_map> abundances; std::vector Y; - for (const auto& species : engine.getNetworkSpecies()) { - const size_t sid = engine.getSpeciesIndex(species); + for (const auto& species : engine.getNetworkSpecies(ctx.state_ctx)) { + const size_t sid = engine.getSpeciesIndex(ctx.state_ctx, species); double y = N_VGetArrayPointer(ctx.state)[sid]; Y.push_back(y > 0.0 ? y : 0.0); // Regularize tiny negative abundances to zero } - fourdst::composition::Composition comp(engine.getNetworkSpecies(), Y); + fourdst::composition::Composition comp(engine.getNetworkSpecies(ctx.state_ctx), Y); std::unordered_map> abundances; @@ -219,36 +224,36 @@ void quill_terminate_handler() std::abort(); } -void callback_main(const gridfire::solver::CVODESolverStrategy::TimestepContext& ctx) { +void callback_main(const gridfire::solver::PointSolverTimestepContext& ctx) { record_abundance_history_callback(ctx); } -int main(int argc, char** argv) { +int main() { + GF_PAR_INIT(); using namespace gridfire; - CLI::App app{"GridFire Sandbox Application."}; - + constexpr size_t breaks = 1; double temp = 1.5e7; double rho = 1.5e2; - double tMax = 3.1536e+17; - - app.add_option("-t,--temp", temp, "Temperature in K (Default 1.5e7K)"); - app.add_option("-r,--rho", rho, "Density in g/cm^3 (Default 1.5e2g/cm^3)"); - app.add_option("--tmax", tMax, "Maximum simulation time in s (Default 3.1536e17s)"); - - CLI11_PARSE(app, argc, argv); + double tMax = 3.1536e+16/breaks; const NetIn netIn = init(temp, rho, tMax); policy::MainSequencePolicy stellarPolicy(netIn.composition); - stellarPolicy.construct(); - engine::DynamicEngine& engine = stellarPolicy.construct(); + auto [engine, ctx_template] = stellarPolicy.construct(); + std::println("Sandbox Engine Stack: {}", stellarPolicy); + std::println("Scratch Blob State: {}", *ctx_template); - solver::CVODESolverStrategy solver(engine); - solver.set_callback(solver::CVODESolverStrategy::TimestepCallback(callback_main)); + constexpr size_t nZones = 100; + std::array netIns; + for (size_t zone = 0; zone < nZones; ++zone) { + netIns[zone] = netIn; + netIns[zone].temperature = 1.0e7; + } - const NetOut netOut = solver.evaluate(netIn, false); + const solver::PointSolver localSolver(engine); + solver::GridSolverContext solverCtx(*ctx_template); + const solver::GridSolver gridSolver(engine, localSolver); - log_results(netOut, netIn); - log_callback_data(temp); -} + std::vector netOuts = gridSolver.evaluate(solverCtx, netIns | std::ranges::to()); +} \ No newline at end of file diff --git a/tests/graphnet_sandbox/meson.build b/tests/graphnet_sandbox/meson.build index ef538396..0a1c5dc5 100644 --- a/tests/graphnet_sandbox/meson.build +++ b/tests/graphnet_sandbox/meson.build @@ -3,3 +3,9 @@ executable( 'main.cpp', dependencies: [gridfire_dep, cli11_dep], ) + +#executable( +# 'spectral_sandbox', +# 'spectral_main.cpp', +# dependencies: [gridfire_dep, cli11_dep] +#) diff --git a/tests/python/py_test_multi.py b/tests/python/py_test_multi.py new file mode 100644 index 00000000..8b8188db --- /dev/null +++ b/tests/python/py_test_multi.py @@ -0,0 +1,79 @@ +from gridfire.solver import GridSolver, PointSolver, GridSolverContext +from gridfire.policy import MainSequencePolicy +from fourdst.composition import Composition + +from fourdst.composition import CanonicalComposition +from fourdst.atomic import Species +from gridfire.type import NetIn + +import numpy as np + +def rescale_composition(comp_ref : Composition, ZZs : float, Y_primordial : float = 0.248) -> Composition: + CC : CanonicalComposition = comp_ref.getCanonicalComposition() + + dY_dZ = (CC.Y - Y_primordial) / CC.Z + + Z_new = CC.Z * (10**ZZs) + Y_bulk_new = Y_primordial + (dY_dZ * Z_new) + X_new = 1.0 - Z_new - Y_bulk_new + + if X_new < 0: raise ValueError(f"ZZs={ZZs} yields unphysical composition (X < 0)") + + ratio_H = X_new / CC.X if CC.X > 0 else 0 + ratio_He = Y_bulk_new / CC.Y if CC.Y > 0 else 0 + ratio_Z = Z_new / CC.Z if CC.Z > 0 else 0 + + Y_new_list = [] + newComp : Composition = Composition() + s: Species + for s in comp_ref.getRegisteredSpecies(): + Xi_ref = comp_ref.getMassFraction(s) + + if s.el() == "H": + Xi_new = Xi_ref * ratio_H + elif s.el() == "He": + Xi_new = Xi_ref * ratio_He + else: + Xi_new = Xi_ref * ratio_Z + + Y = Xi_new / s.mass() + newComp.registerSpecies(s) + newComp.setMolarAbundance(s, Y) + + return newComp + +def init_composition(ZZs : float = 0) -> Composition: + Y_solar = [7.0262E-01, 9.7479E-06, 6.8955E-02, 2.5000E-04, 7.8554E-05, 6.0144E-04, 8.1031E-05, 2.1513E-05] + S = ["H-1", "He-3", "He-4", "C-12", "N-14", "O-16", "Ne-20", "Mg-24"] + return rescale_composition(Composition(S, Y_solar), ZZs) + + +def init_netIn(temp: float, rho: float, time: float, comp: Composition) -> NetIn: + n : NetIn = NetIn() + n.temperature = temp + n.density = rho + n.tMax = time + n.dt0 = 1e-12 + n.composition = comp + return n + +def years_to_seconds(years: float) -> float: + return years * 3.1536e7 + + +def main(): + C = init_composition() + temps = np.linspace(1.5e7, 2e7, 100) + rhos = np.linspace(1.5e2, 1.5e2, 100) + netIns = [] + for T, R in zip(temps, rhos): + netIns.append(init_netIn(T, R, years_to_seconds(100e6), C)) + policy = MainSequencePolicy(C) + construct = policy.construct() + local_solver = PointSolver(construct.engine) + grid_solver = GridSolver(construct.engine, local_solver) + solver_ctx = GridSolverContext(construct.scratch_blob) + results = grid_solver.evaluate(solver_ctx, netIns) + +if __name__ == "__main__": + main() diff --git a/tests/python/py_test_single.py b/tests/python/py_test_single.py new file mode 100644 index 00000000..7e5f4276 --- /dev/null +++ b/tests/python/py_test_single.py @@ -0,0 +1,73 @@ +from gridfire.solver import PointSolver, PointSolverContext +from gridfire.policy import MainSequencePolicy +from fourdst.composition import Composition + +from fourdst.composition import CanonicalComposition +from fourdst.atomic import Species +from gridfire.type import NetIn + +def rescale_composition(comp_ref : Composition, ZZs : float, Y_primordial : float = 0.248) -> Composition: + CC : CanonicalComposition = comp_ref.getCanonicalComposition() + + dY_dZ = (CC.Y - Y_primordial) / CC.Z + + Z_new = CC.Z * (10**ZZs) + Y_bulk_new = Y_primordial + (dY_dZ * Z_new) + X_new = 1.0 - Z_new - Y_bulk_new + + if X_new < 0: raise ValueError(f"ZZs={ZZs} yields unphysical composition (X < 0)") + + ratio_H = X_new / CC.X if CC.X > 0 else 0 + ratio_He = Y_bulk_new / CC.Y if CC.Y > 0 else 0 + ratio_Z = Z_new / CC.Z if CC.Z > 0 else 0 + + Y_new_list = [] + newComp : Composition = Composition() + s: Species + for s in comp_ref.getRegisteredSpecies(): + Xi_ref = comp_ref.getMassFraction(s) + + if s.el() == "H": + Xi_new = Xi_ref * ratio_H + elif s.el() == "He": + Xi_new = Xi_ref * ratio_He + else: + Xi_new = Xi_ref * ratio_Z + + Y = Xi_new / s.mass() + newComp.registerSpecies(s) + newComp.setMolarAbundance(s, Y) + + return newComp + +def init_composition(ZZs : float = 0) -> Composition: + Y_solar = [7.0262E-01, 9.7479E-06, 6.8955E-02, 2.5000E-04, 7.8554E-05, 6.0144E-04, 8.1031E-05, 2.1513E-05] + S = ["H-1", "He-3", "He-4", "C-12", "N-14", "O-16", "Ne-20", "Mg-24"] + return rescale_composition(Composition(S, Y_solar), ZZs) + + +def init_netIn(temp: float, rho: float, time: float, comp: Composition) -> NetIn: + n : NetIn = NetIn() + n.temperature = temp + n.density = rho + n.tMax = time + n.dt0 = 1e-12 + n.composition = comp + return n + +def years_to_seconds(years: float) -> float: + return years * 3.1536e7 + + +def main(): + C = init_composition() + netIn = init_netIn(2.75e6, 1.5e1, years_to_seconds(10e9), C) + policy = MainSequencePolicy(C) + construct = policy.construct() + solver = PointSolver(construct.engine) + solver_ctx = PointSolverContext(construct.scratch_blob) + results = solver.evaluate(solver_ctx, netIn, False, False) + print(results) + +if __name__ == "__main__": + main() diff --git a/tests/python/test.py b/tests/python/test.py deleted file mode 100644 index 74b512ba..00000000 --- a/tests/python/test.py +++ /dev/null @@ -1,51 +0,0 @@ -from gridfire.engine import GraphEngine, MultiscalePartitioningEngineView, AdaptiveEngineView -from gridfire.solver import DirectNetworkSolver -from gridfire.type import NetIn - -from fourdst.composition import Composition -from fourdst.atomic import species - -symbols : list[str] = ["H-1", "He-3", "He-4", "C-12", "N-14", "O-16", "Ne-20", "Mg-24"] -X : list[float] = [0.708, 2.94e-5, 0.276, 0.003, 0.0011, 9.62e-3, 1.62e-3, 5.16e-4] - - -comp = Composition() -comp.registerSymbol(symbols) -comp.setMassFraction(symbols, X) -comp.finalize(True) - -print(f"Initial H-1 mass fraction {comp.getMassFraction("H-1")}") - -netIn = NetIn() -netIn.composition = comp -netIn.temperature = 1.5e7 -netIn.density = 1.6e2 -netIn.tMax = 4e17 -netIn.dt0 = 1e-12 - -baseEngine = GraphEngine(netIn.composition, 2) -baseEngine.setUseReverseReactions(False) - -qseEngine = MultiscalePartitioningEngineView(baseEngine) - -adaptiveEngine = AdaptiveEngineView(qseEngine) - -solver = DirectNetworkSolver(adaptiveEngine) - - -def callback(context): - H1Index = context.engine.getSpeciesIndex(species["H-1"]) - He4Index = context.engine.getSpeciesIndex(species["He-4"]) - C12ndex = context.engine.getSpeciesIndex(species["C-12"]) - Mgh24ndex = context.engine.getSpeciesIndex(species["Mg-24"]) - print(f"Time: {context.t}, H-1: {context.state[H1Index]}, He-4: {context.state[He4Index]}, C-12: {context.state[C12ndex]}, Mg-24: {context.state[Mgh24ndex]}") - -# solver.set_callback(callback) -results = solver.evaluate(netIn) - -print(f"Final H-1 mass fraction {results.composition.getMassFraction("H-1")}") - - - - - diff --git a/tools/config/generate_config_files.cpp b/tools/gf_config/generate_config_files.cpp similarity index 100% rename from tools/config/generate_config_files.cpp rename to tools/gf_config/generate_config_files.cpp diff --git a/tools/config/meson.build b/tools/gf_config/meson.build similarity index 100% rename from tools/config/meson.build rename to tools/gf_config/meson.build diff --git a/tools/gf_multi/main.cpp b/tools/gf_multi/main.cpp new file mode 100644 index 00000000..41aa2e51 --- /dev/null +++ b/tools/gf_multi/main.cpp @@ -0,0 +1,393 @@ +// ReSharper disable CppUnusedIncludeDirective +#include +#include +#include +#include +#include + +#include "gridfire/gridfire.h" +#include // Required for parallel_setup + +#include "fourdst/composition/composition.h" +#include "fourdst/logging/logging.h" +#include "fourdst/atomic/species.h" +#include "fourdst/composition/utils.h" + +#include "quill/Logger.h" +#include "quill/Backend.h" +#include "CLI/CLI.hpp" + +#include + +#include "gridfire/utils/gf_omp.h" + +static std::terminate_handler g_previousHandler = nullptr; +static std::vector>>> g_callbackHistory; +static bool s_wrote_abundance_history = false; +void quill_terminate_handler(); + +enum class ScalingTypes { + LINEAR, + LOG, + GEOM +}; + +std::map scaling_type_map = { + {"linear", ScalingTypes::LINEAR}, + {"log", ScalingTypes::LOG}, + {"geom", ScalingTypes::GEOM} +}; + +template +concept IsOrderableLinear = std::floating_point; + +template +concept IsOrderableLog = std::floating_point; + +template +constexpr std::vector linspace(T start, T end, size_t N) { + if (N == 0) { + return {}; + } + if (N == 1) { + return {start}; + } + + std::vector result{}; + result.resize(N); + + for (std::size_t i = 0; i < N; ++i) { + const T t = static_cast(i) / static_cast(N - 1); + result[i] = std::lerp(start, end, t); + } + + return result; +} + +template +std::vector logspace(T start, T end, size_t N) { + if (N == 0) { + return {}; + } + if (N == 1) { + return {start}; + } + + std::vector result{}; + result.resize(N); + + const T log_start = start; + const T log_end = end; + + for (std::size_t i = 0; i < N; ++i) { + const T t = static_cast(i) / static_cast(N - 1); + const T exponent = std::lerp(log_start, log_end, t); + result[i] = std::pow(static_cast(10), exponent); + } + + return result; +} + +template +std::vector geomspace(T start, T end, size_t N) { + if (start <= 0 || end <= 0) { + throw std::domain_error("geomspace requires positive start/end values"); + } + + const T log_start = std::log10(start); + const T log_end = std::log10(end); + + std::vector result = logspace(log_start, log_end, N); + + result[0] = start; + result[N - 1] = end; + + return result; +} + + + +gridfire::NetIn init(const double temp, const double rho, const double tMax) { + std::setlocale(LC_ALL, ""); + g_previousHandler = std::set_terminate(quill_terminate_handler); + quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); + logger->set_log_level(quill::LogLevel::Info); + + using namespace gridfire; + const std::vector X = {0.7081145999999999, 2.94e-5, 0.276, 0.003, 0.0011, 9.62e-3, 1.62e-3, 5.16e-4}; + const std::vector symbols = {"H-1", "He-3", "He-4", "C-12", "N-14", "O-16", "Ne-20", "Mg-24"}; + + + const fourdst::composition::Composition composition = fourdst::composition::buildCompositionFromMassFractions(symbols, X); + + NetIn netIn; + netIn.composition = composition; + netIn.temperature = temp; + netIn.density = rho; + netIn.energy = 0; + + netIn.tMax = tMax; + netIn.dt0 = 1e-12; + + return netIn; +} + +void log_results(const gridfire::NetOut& netOut, const gridfire::NetIn& netIn) { + std::vector logSpecies = { + fourdst::atomic::H_1, + fourdst::atomic::He_3, + fourdst::atomic::He_4, + fourdst::atomic::C_12, + fourdst::atomic::N_14, + fourdst::atomic::O_16, + fourdst::atomic::Ne_20, + fourdst::atomic::Mg_24 + }; + + std::vector initial; + std::vector final; + std::vector delta; + std::vector fractional; + for (const auto& species : logSpecies) { + double initial_X = netIn.composition.getMassFraction(species); + double final_X = netOut.composition.getMassFraction(species); + double delta_X = final_X - initial_X; + double fractionalChange = (delta_X) / initial_X * 100.0; + + initial.push_back(initial_X); + final.push_back(final_X); + delta.push_back(delta_X); + fractional.push_back(fractionalChange); + } + + initial.push_back(0.0); // Placeholder for energy + final.push_back(netOut.energy); + delta.push_back(netOut.energy); + fractional.push_back(0.0); // Placeholder for energy + + initial.push_back(0.0); + final.push_back(netOut.dEps_dT); + delta.push_back(netOut.dEps_dT); + fractional.push_back(0.0); + + initial.push_back(0.0); + final.push_back(netOut.dEps_dRho); + delta.push_back(netOut.dEps_dRho); + fractional.push_back(0.0); + + initial.push_back(0.0); + final.push_back(netOut.specific_neutrino_energy_loss); + delta.push_back(netOut.specific_neutrino_energy_loss); + fractional.push_back(0.0); + + initial.push_back(0.0); + final.push_back(netOut.specific_neutrino_flux); + delta.push_back(netOut.specific_neutrino_flux); + fractional.push_back(0.0); + + initial.push_back(netIn.composition.getMeanParticleMass()); + final.push_back(netOut.composition.getMeanParticleMass()); + delta.push_back(final.back() - initial.back()); + fractional.push_back((final.back() - initial.back()) / initial.back() * 100.0); + + std::vector rowLabels = [&]() -> std::vector { + std::vector labels; + for (const auto& species : logSpecies) { + labels.emplace_back(species.name()); + } + labels.emplace_back("ε"); + labels.emplace_back("dε/dT"); + labels.emplace_back("dε/dρ"); + labels.emplace_back("Eν"); + labels.emplace_back("Fν"); + labels.emplace_back("<μ>"); + return labels; + }(); + + + gridfire::utils::Column paramCol("Parameter", rowLabels); + gridfire::utils::Column initialCol("Initial", initial); + gridfire::utils::Column finalCol ("Final", final); + gridfire::utils::Column deltaCol ("δ", delta); + gridfire::utils::Column percentCol("% Change", fractional); + + std::vector> columns; + columns.push_back(std::make_unique>(paramCol)); + columns.push_back(std::make_unique>(initialCol)); + columns.push_back(std::make_unique>(finalCol)); + columns.push_back(std::make_unique>(deltaCol)); + columns.push_back(std::make_unique>(percentCol)); + + + gridfire::utils::print_table("Simulation Results", columns); +} + + +void record_abundance_history_callback(const gridfire::solver::PointSolverTimestepContext& ctx) { + s_wrote_abundance_history = true; + const auto& engine = ctx.engine; + // std::unordered_map> abundances; + std::vector Y; + for (const auto& species : engine.getNetworkSpecies(ctx.state_ctx)) { + const size_t sid = engine.getSpeciesIndex(ctx.state_ctx, species); + double y = N_VGetArrayPointer(ctx.state)[sid]; + Y.push_back(y > 0.0 ? y : 0.0); // Regularize tiny negative abundances to zero + } + + fourdst::composition::Composition comp(engine.getNetworkSpecies(ctx.state_ctx), Y); + + + std::unordered_map> abundances; + for (const auto& sp : comp | std::views::keys) { + abundances.emplace(std::string(sp.name()), std::make_pair(sp.mass(), comp.getMolarAbundance(sp))); + } + g_callbackHistory.emplace_back(ctx.t, abundances); +} + + +void save_callback_data(const std::string_view filename) { + std::set unique_species; + for (const auto &abundances: g_callbackHistory | std::views::values) { + for (const auto &species_name: abundances | std::views::keys) { + unique_species.insert(species_name); + } + } + std::ofstream csvFile(filename.data(), std::ios::out); + csvFile << "t,"; + + size_t i = 0; + for (const auto& species_name : unique_species) { + csvFile << species_name; + if (i < unique_species.size() - 1) { + csvFile << ","; + } + i++; + } + + csvFile << "\n"; + + for (const auto& [time, data] : g_callbackHistory) { + csvFile << time << ","; + size_t j = 0; + for (const auto& species_name : unique_species) { + if (!data.contains(species_name)) { + csvFile << "0.0"; + } else { + csvFile << data.at(species_name).second; + } + if (j < unique_species.size() - 1) { + csvFile << ","; + } + ++j; + } + csvFile << "\n"; + } + + csvFile.close(); +} + +void log_callback_data(const double temp) { + if (s_wrote_abundance_history) { + std::cout << "Saving abundance history to abundance_history.csv" << std::endl; + save_callback_data("abundance_history_" + std::to_string(temp) + ".csv"); + } + +} + +void quill_terminate_handler() +{ + log_callback_data(1.5e7); + quill::Backend::stop(); + if (g_previousHandler) + g_previousHandler(); + else + std::abort(); +} + +void callback_main(const gridfire::solver::PointSolverTimestepContext& ctx) { + record_abundance_history_callback(ctx); +} + +int main(int argc, char** argv) { + GF_PAR_INIT(); + using namespace gridfire; + + double tMin = 1e7; + double tMax = 3e7; + ScalingTypes tempScaling = ScalingTypes::LINEAR; + + double rhoMin = 1e2; + double rhoMax = 1e3; + ScalingTypes rhoScaling = ScalingTypes::LOG; + + double evolveTime = 1e13; + size_t shells = 10; + + + CLI::App app("GridFire Quick CLI Test"); + // Add temp, rho, and tMax as options if desired + app.add_option("--tMin", tMin, "Initial Temperature")->default_val(std::format("{:5.2E}", tMin)); + app.add_option("--tMax", tMax, "Maximum Temperature")->default_val(std::format("{:5.2E}", tMax)); + app.add_option("--tempScaling", tempScaling, "Temperature Scaling Type (linear, log, geom)")->default_val(ScalingTypes::LINEAR)->transform(CLI::CheckedTransformer(scaling_type_map, CLI::ignore_case)); + + app.add_option("--rhoMin", rhoMin, "Initial Density")->default_val(std::format("{:5.2E}", rhoMin)); + app.add_option("--rhoMax", rhoMax, "Maximum Density")->default_val(std::format("{:5.2E}", rhoMax)); + app.add_option("--rhoScaling", rhoScaling, "Density Scaling Type (linear, log, geom)")->default_val(ScalingTypes::LOG)->transform(CLI::CheckedTransformer(scaling_type_map, CLI::ignore_case)); + + app.add_option("--shell", shells, "Number of Shells")->default_val(shells); + + app.add_option("--evolveTime", evolveTime, "Evolution Time")->default_val(std::format("{:5.2E}", evolveTime)); + + + CLI11_PARSE(app, argc, argv); + NetIn rootNetIn = init(tMin, tMax, evolveTime); + + std::vector temps; + std::vector densities; + + switch (tempScaling) { + case ScalingTypes::LINEAR: + temps = linspace(tMin, tMax, static_cast(shells)); + break; + case ScalingTypes::LOG: + temps = logspace(std::log10(tMin), std::log10(tMax), static_cast(shells)); + break; + case ScalingTypes::GEOM: + temps = geomspace(tMin, tMax, static_cast(shells)); + break; + } + switch (rhoScaling) { + case ScalingTypes::LINEAR: + densities = linspace(rhoMin, rhoMax, static_cast(shells)); + break; + case ScalingTypes::LOG: + densities = logspace(std::log10(rhoMin), std::log10(rhoMax), static_cast(shells)); + break; + case ScalingTypes::GEOM: + densities = geomspace(rhoMin, rhoMax, static_cast(shells)); + break; + } + + std::vector netIns; + netIns.reserve(shells); + for (size_t i = 0; i < static_cast(shells); ++i) { + NetIn netIn = rootNetIn; + netIn.temperature = temps[i]; + netIn.density = densities[i]; + netIns.emplace_back(netIn); + } + + policy::MainSequencePolicy stellarPolicy(rootNetIn.composition); + auto [engine, ctx_template] = stellarPolicy.construct(); + + solver::PointSolver point_solver(engine); + solver::GridSolver grid_solver(engine, point_solver); + solver::GridSolverContext solver_ctx(*ctx_template); + + + std::vector results = grid_solver.evaluate(solver_ctx, netIns); + for (size_t i = 0; i < results.size(); ++i) { + std::cout << "=== Shell " << i << " ===" << std::endl; + log_results(results[i], netIns[i]); + } +} \ No newline at end of file diff --git a/tools/gf_multi/meson.build b/tools/gf_multi/meson.build new file mode 100644 index 00000000..66b00b49 --- /dev/null +++ b/tools/gf_multi/meson.build @@ -0,0 +1 @@ +executable('gf_multi', 'main.cpp', dependencies: [gridfire_dep, cli11_dep]) \ No newline at end of file diff --git a/tools/gf_quick/main.cpp b/tools/gf_quick/main.cpp new file mode 100644 index 00000000..88a59fb2 --- /dev/null +++ b/tools/gf_quick/main.cpp @@ -0,0 +1,377 @@ +// ReSharper disable CppUnusedIncludeDirective +#include +#include +#include +#include +#include + +#include "gridfire/gridfire.h" +#include // Required for parallel_setup + +#include "fourdst/composition/composition.h" +#include "fourdst/logging/logging.h" +#include "fourdst/atomic/species.h" +#include "fourdst/composition/utils.h" + +#include "quill/Logger.h" +#include "quill/Backend.h" +#include "CLI/CLI.hpp" + +#include + +#include "gridfire/utils/gf_omp.h" + + +static std::terminate_handler g_previousHandler = nullptr; +static std::vector>>> g_callbackHistory; +static bool s_wrote_abundance_history = false; +void quill_terminate_handler(); + +using namespace fourdst::composition; +Composition rescale(const Composition& comp, double target_X, double target_Z) { + // 1. Validate inputs + if (target_X < 0.0 || target_Z < 0.0 || (target_X + target_Z) > 1.0 + 1e-14) { + throw std::invalid_argument("Target mass fractions X and Z must be non-negative and sum to <= 1.0"); + } + + // Force high precision for the target Y to ensure X+Y+Z = 1.0 exactly in our logic + long double ld_target_X = static_cast(target_X); + long double ld_target_Z = static_cast(target_Z); + long double ld_target_Y = 1.0L - ld_target_X - ld_target_Z; + + // Clamp Y to 0 if it dipped slightly below due to precision (e.g. X+Z=1.0000000001) + if (ld_target_Y < 0.0L) ld_target_Y = 0.0L; + + // 2. Manually calculate current Mass Totals (bypass getCanonicalComposition to avoid crashes) + long double total_mass_H = 0.0L; + long double total_mass_He = 0.0L; + long double total_mass_Z = 0.0L; + + // We need to iterate and identify species types manually + // Standard definition: H (z=1), He (z=2), Metals (z>2) + // Note: We use long double accumulators to prevent summation drift + for (const auto& [spec, molar_abundance] : comp) { + // Retrieve atomic properties. + // Note: usage assumes fourdst::atomic::Species has .z() and .mass() + // consistent with the provided composition.cpp + int z = spec.z(); + double a = spec.mass(); + + long double mass_contribution = static_cast(molar_abundance) * static_cast(a); + + if (z == 1) { + total_mass_H += mass_contribution; + } else if (z == 2) { + total_mass_He += mass_contribution; + } else { + total_mass_Z += mass_contribution; + } + } + + long double total_mass_current = total_mass_H + total_mass_He + total_mass_Z; + + // Edge case: Empty composition + if (total_mass_current <= 0.0L) { + // Return empty or throw? If input was empty, return empty. + if (comp.size() == 0) return comp; + throw std::runtime_error("Input composition has zero total mass."); + } + + // 3. Calculate Scaling Factors + // Factor = (Target_Mass_Fraction / Old_Mass_Fraction) + // = (Target_Mass_Fraction) / (Old_Group_Mass / Total_Mass) + // = (Target_Mass_Fraction * Total_Mass) / Old_Group_Mass + + long double scale_H = 0.0L; + long double scale_He = 0.0L; + long double scale_Z = 0.0L; + + if (ld_target_X > 1e-16L) { + if (total_mass_H <= 1e-19L) { + throw std::runtime_error("Cannot rescale Hydrogen to " + std::to_string(target_X) + + " because input has no Hydrogen."); + } + scale_H = (ld_target_X * total_mass_current) / total_mass_H; + } + + if (ld_target_Y > 1e-16L) { + if (total_mass_He <= 1e-19L) { + throw std::runtime_error("Cannot rescale Helium to " + std::to_string((double)ld_target_Y) + + " because input has no Helium."); + } + scale_He = (ld_target_Y * total_mass_current) / total_mass_He; + } + + if (ld_target_Z > 1e-16L) { + if (total_mass_Z <= 1e-19L) { + throw std::runtime_error("Cannot rescale Metals to " + std::to_string(target_Z) + + " because input has no Metals."); + } + scale_Z = (ld_target_Z * total_mass_current) / total_mass_Z; + } + + // 4. Apply Scaling and Construct New Vectors + std::vector new_species; + std::vector new_abundances; + new_species.reserve(comp.size()); + new_abundances.reserve(comp.size()); + + for (const auto& [spec, abundance] : comp) { + new_species.push_back(spec); + + long double factor = 0.0L; + int z = spec.z(); + + if (z == 1) { + factor = scale_H; + } else if (z == 2) { + factor = scale_He; + } else { + factor = scale_Z; + } + + // Calculate new abundance in long double then cast back + long double new_val_ld = static_cast(abundance) * factor; + new_abundances.push_back(static_cast(new_val_ld)); + } + + return Composition(new_species, new_abundances); +} + +gridfire::NetIn init(const double temp, const double rho, const double tMax) { + std::setlocale(LC_ALL, ""); + g_previousHandler = std::set_terminate(quill_terminate_handler); + quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); + logger->set_log_level(quill::LogLevel::Info); + + using namespace gridfire; + const std::vector X = {0.7081145999999999, 2.94e-5, 0.276, 0.003, 0.0011, 9.62e-3, 1.62e-3, 5.16e-4}; + const std::vector symbols = {"H-1", "He-3", "He-4", "C-12", "N-14", "O-16", "Ne-20", "Mg-24"}; + + + const fourdst::composition::Composition composition = fourdst::composition::buildCompositionFromMassFractions(symbols, X); + + NetIn netIn; + netIn.composition = composition; + netIn.temperature = temp; + netIn.density = rho; + netIn.energy = 0; + + netIn.tMax = tMax; + netIn.dt0 = 1e-12; + + return netIn; +} + +void log_results(const gridfire::NetOut& netOut, const gridfire::NetIn& netIn) { + std::vector logSpecies = { + fourdst::atomic::H_1, + fourdst::atomic::He_3, + fourdst::atomic::He_4, + fourdst::atomic::C_12, + fourdst::atomic::N_14, + fourdst::atomic::O_16, + fourdst::atomic::Ne_20, + fourdst::atomic::Mg_24 + }; + + std::vector initial; + std::vector final; + std::vector delta; + std::vector fractional; + for (const auto& species : logSpecies) { + double initial_X = netIn.composition.getMassFraction(species); + double final_X = netOut.composition.getMassFraction(species); + double delta_X = final_X - initial_X; + double fractionalChange = (delta_X) / initial_X * 100.0; + + initial.push_back(initial_X); + final.push_back(final_X); + delta.push_back(delta_X); + fractional.push_back(fractionalChange); + } + + initial.push_back(0.0); // Placeholder for energy + final.push_back(netOut.energy); + delta.push_back(netOut.energy); + fractional.push_back(0.0); // Placeholder for energy + + initial.push_back(0.0); + final.push_back(netOut.dEps_dT); + delta.push_back(netOut.dEps_dT); + fractional.push_back(0.0); + + initial.push_back(0.0); + final.push_back(netOut.dEps_dRho); + delta.push_back(netOut.dEps_dRho); + fractional.push_back(0.0); + + initial.push_back(0.0); + final.push_back(netOut.specific_neutrino_energy_loss); + delta.push_back(netOut.specific_neutrino_energy_loss); + fractional.push_back(0.0); + + initial.push_back(0.0); + final.push_back(netOut.specific_neutrino_flux); + delta.push_back(netOut.specific_neutrino_flux); + fractional.push_back(0.0); + + initial.push_back(netIn.composition.getMeanParticleMass()); + final.push_back(netOut.composition.getMeanParticleMass()); + delta.push_back(final.back() - initial.back()); + fractional.push_back((final.back() - initial.back()) / initial.back() * 100.0); + + std::vector rowLabels = [&]() -> std::vector { + std::vector labels; + for (const auto& species : logSpecies) { + labels.emplace_back(species.name()); + } + labels.emplace_back("ε"); + labels.emplace_back("dε/dT"); + labels.emplace_back("dε/dρ"); + labels.emplace_back("Eν"); + labels.emplace_back("Fν"); + labels.emplace_back("<μ>"); + return labels; + }(); + + + gridfire::utils::Column paramCol("Parameter", rowLabels); + gridfire::utils::Column initialCol("Initial", initial); + gridfire::utils::Column finalCol ("Final", final); + gridfire::utils::Column deltaCol ("δ", delta); + gridfire::utils::Column percentCol("% Change", fractional); + + std::vector> columns; + columns.push_back(std::make_unique>(paramCol)); + columns.push_back(std::make_unique>(initialCol)); + columns.push_back(std::make_unique>(finalCol)); + columns.push_back(std::make_unique>(deltaCol)); + columns.push_back(std::make_unique>(percentCol)); + + + gridfire::utils::print_table("Simulation Results", columns); +} + + +void record_abundance_history_callback(const gridfire::solver::PointSolverTimestepContext& ctx) { + s_wrote_abundance_history = true; + const auto& engine = ctx.engine; + // std::unordered_map> abundances; + std::vector Y; + for (const auto& species : engine.getNetworkSpecies(ctx.state_ctx)) { + const size_t sid = engine.getSpeciesIndex(ctx.state_ctx, species); + double y = N_VGetArrayPointer(ctx.state)[sid]; + Y.push_back(y > 0.0 ? y : 0.0); // Regularize tiny negative abundances to zero + } + + fourdst::composition::Composition comp(engine.getNetworkSpecies(ctx.state_ctx), Y); + + + std::unordered_map> abundances; + for (const auto& sp : comp | std::views::keys) { + abundances.emplace(std::string(sp.name()), std::make_pair(sp.mass(), comp.getMolarAbundance(sp))); + } + g_callbackHistory.emplace_back(ctx.t, abundances); +} + + +void save_callback_data(const std::string_view filename) { + std::set unique_species; + for (const auto &abundances: g_callbackHistory | std::views::values) { + for (const auto &species_name: abundances | std::views::keys) { + unique_species.insert(species_name); + } + } + std::ofstream csvFile(filename.data(), std::ios::out); + csvFile << "t,"; + + size_t i = 0; + for (const auto& species_name : unique_species) { + csvFile << species_name; + if (i < unique_species.size() - 1) { + csvFile << ","; + } + i++; + } + + csvFile << "\n"; + + for (const auto& [time, data] : g_callbackHistory) { + csvFile << time << ","; + size_t j = 0; + for (const auto& species_name : unique_species) { + if (!data.contains(species_name)) { + csvFile << "0.0"; + } else { + csvFile << data.at(species_name).second; + } + if (j < unique_species.size() - 1) { + csvFile << ","; + } + ++j; + } + csvFile << "\n"; + } + + csvFile.close(); +} + +void log_callback_data(const double temp) { + if (s_wrote_abundance_history) { + std::cout << "Saving abundance history to abundance_history.csv" << std::endl; + save_callback_data("abundance_history_" + std::to_string(temp) + ".csv"); + } + +} + +void quill_terminate_handler() +{ + log_callback_data(1.5e7); + quill::Backend::stop(); + if (g_previousHandler) + g_previousHandler(); + else + std::abort(); +} + +void callback_main(const gridfire::solver::PointSolverTimestepContext& ctx) { + record_abundance_history_callback(ctx); +} + +int main(int argc, char** argv) { + GF_PAR_INIT(); + using namespace gridfire; + + double temp = 1.5e7; + double rho = 1.5e2; + double tMax = 3.1536e+16; + double X = 0.7; + double Z = 0.02; + + + CLI::App app("GridFire Quick CLI Test"); + // Add temp, rho, and tMax as options if desired + app.add_option("--temp", temp, "Initial Temperature")->default_val(std::format("{:5.2E}", temp)); + app.add_option("--rho", rho, "Initial Density")->default_val(std::format("{:5.2E}", rho)); + app.add_option("--tmax", tMax, "Maximum Time")->default_val(std::format("{:5.2E}", tMax)); + // app.add_option("--X", X, "Target Hydrogen Mass Fraction")->default_val(std::format("{:5.2f}", X)); + // app.add_option("--Z", Z, "Target Metal Mass Fraction")->default_val(std::format("{:5.2f}", Z)); + + CLI11_PARSE(app, argc, argv); + NetIn netIn = init(temp, rho, tMax); + for (const auto& [sp, y] : netIn.composition) { + std::println("Species: {}, Abundance: {}", sp.name(), y); + } + return 0; + // netIn.composition = rescale(netIn.composition, X, Z); + + policy::MainSequencePolicy stellarPolicy(netIn.composition); + auto [engine, ctx_template] = stellarPolicy.construct(); + + solver::PointSolverContext solver_context(*ctx_template); + solver::PointSolver solver(engine); + + NetOut result = solver.evaluate(solver_context, netIn); + log_results(result, netIn); +} \ No newline at end of file diff --git a/tools/gf_quick/meson.build b/tools/gf_quick/meson.build new file mode 100644 index 00000000..6e520a11 --- /dev/null +++ b/tools/gf_quick/meson.build @@ -0,0 +1 @@ +executable('gf_quick', 'main.cpp', dependencies: [gridfire_dep, cli11_dep]) \ No newline at end of file diff --git a/tools/meson.build b/tools/meson.build index 75f2745b..d4fae098 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -1,3 +1,5 @@ if get_option('build_tools') - subdir('config') + subdir('gf_config') + subdir('gf_quick') + subdir('gf_multi') endif \ No newline at end of file diff --git a/utils/cloc/ignore.txt b/utils/cloc/ignore.txt new file mode 100644 index 00000000..3d1c1e62 --- /dev/null +++ b/utils/cloc/ignore.txt @@ -0,0 +1,3 @@ +include/gridfire/partition/rauscher_thielemann_partition_data.h +include/gridfire/reaction/reactions_data.h +include/gridfire/reaction/weak/weak_rate_library.h diff --git a/validation/vv/GridFireValidationSuite.py b/validation/vv/GridFireValidationSuite.py index 7c31d986..eff9081c 100644 --- a/validation/vv/GridFireValidationSuite.py +++ b/validation/vv/GridFireValidationSuite.py @@ -1,7 +1,8 @@ from gridfire.policy import MainSequencePolicy, NetworkPolicy -from gridfire.engine import DynamicEngine, GraphEngine +from gridfire.engine import DynamicEngine, GraphEngine, EngineTypes from gridfire.type import NetIn +from typing import Dict from fourdst.composition import Composition from testsuite import TestSuite @@ -9,6 +10,12 @@ from utils import init_netIn, init_composition, years_to_seconds from enum import Enum +EngineNameToType: Dict[str, EngineTypes] = { + "graphengine": EngineTypes.GRAPH_ENGINE, + "multiscalepartitioningengineview": EngineTypes.MULTISCALE_PARTITIONING_ENGINE_VIEW, + "adaptiveengineview": EngineTypes.ADAPTIVE_ENGINE_VIEW +} + class SolarLikeStar_QSE_Suite(TestSuite): def __init__(self): initialComposition : Composition = init_composition() @@ -22,11 +29,11 @@ class SolarLikeStar_QSE_Suite(TestSuite): notes="Thermodynamically Static, MultiscalePartitioning Engine View" ) - def __call__(self): + def __call__(self, pynucastro_compare: bool = False, pync_engine: str = "AdaptiveEngineView"): policy : MainSequencePolicy = MainSequencePolicy(self.composition) engine : DynamicEngine = policy.construct() netIn : NetIn = init_netIn(self.temperature, self.density, self.tMax, self.composition) - self.evolve(engine, netIn) + self.evolve(engine, netIn, pynucastro_compare = pynucastro_compare, engine_type=EngineNameToType[pync_engine.lower()]) class MetalEnhancedSolarLikeStar_QSE_Suite(TestSuite): def __init__(self): @@ -41,7 +48,7 @@ class MetalEnhancedSolarLikeStar_QSE_Suite(TestSuite): notes="Thermodynamically Static, MultiscalePartitioning Engine View, Z enhanced by 1 dex, temperature reduced to 80% of solar core" ) - def __call__(self): + def __call__(self, pynucastro_compare: bool = False, pync_engine: str = "AdaptiveEngineView"): policy : MainSequencePolicy = MainSequencePolicy(self.composition) engine : GraphEngine = policy.construct() netIn : NetIn = init_netIn(self.temperature, self.density, self.tMax, self.composition) @@ -59,7 +66,7 @@ class MetalDepletedSolarLikeStar_QSE_Suite(TestSuite): notes="Thermodynamically Static, MultiscalePartitioning Engine View, Z depleted by 1 dex, temperature increased to 120% of solar core" ) - def __call__(self): + def __call__(self, pynucastro_compare: bool = False, pync_engine: str = "AdaptiveEngineView"): policy : MainSequencePolicy = MainSequencePolicy(self.composition) engine : GraphEngine = policy.construct() netIn : NetIn = init_netIn(self.temperature, self.density, self.tMax, self.composition) @@ -78,7 +85,7 @@ class SolarLikeStar_No_QSE_Suite(TestSuite): notes="Thermodynamically Static, No MultiscalePartitioning Engine View" ) - def __call__(self): + def __call__(self, pynucastro_compare: bool = False, pync_engine: str = "AdaptiveEngineView"): engine : GraphEngine = GraphEngine(self.composition, 3) netIn : NetIn = init_netIn(self.temperature, self.density, self.tMax, self.composition) self.evolve(engine, netIn) @@ -94,9 +101,19 @@ if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Run some subset of the GridFire validation suite.") parser.add_argument('--suite', type=str, choices=[suite.name for suite in ValidationSuites], nargs="+", help="The validation suite to run.") + parser.add_argument("--all", action="store_true", help="Run all validation suites.") + parser.add_argument("--pynucastro-compare", action="store_true", help="Generate pynucastro comparison data.") + parser.add_argument("--pync-engine", type=str, choices=["GraphEngine", "MultiscalePartitioningEngineView", "AdaptiveEngineView"], default="AdaptiveEngineView", help="The GridFire engine to use to select the reactions for pynucastro comparison.") args = parser.parse_args() - for suite_name in args.suite: - suite = ValidationSuites[suite_name] - instance : TestSuite = suite.value() - instance() + if args.all: + for suite in ValidationSuites: + instance : TestSuite = suite.value() + instance(args.pynucastro_compare, args.pync_engine) + + else: + for suite_name in args.suite: + suite = ValidationSuites[suite_name] + instance : TestSuite = suite.value() + instance(args.pynucastro_compare, args.pync_engine) + diff --git a/validation/vv/testsuite.py b/validation/vv/testsuite.py index a4f0ed79..d698ca9c 100644 --- a/validation/vv/testsuite.py +++ b/validation/vv/testsuite.py @@ -2,11 +2,14 @@ from abc import ABC, abstractmethod import fourdst.atomic import scipy.integrate +import gridfire from fourdst.composition import Composition -from gridfire.engine import DynamicEngine, GraphEngine +from gridfire.engine import DynamicEngine, GraphEngine, AdaptiveEngineView, MultiscalePartitioningEngineView +from gridfire.engine import EngineTypes +from gridfire.policy import MainSequencePolicy from gridfire.type import NetIn, NetOut from gridfire.exceptions import GridFireError -from gridfire.solver import CVODESolverStrategy +from gridfire.solver import PointSolver, PointSolverContext from logger import StepLogger from typing import List import re @@ -21,6 +24,12 @@ import numpy as np import json import time +EngineTypeLookup : Dict[EngineTypes, Any] = { + EngineTypes.ADAPTIVE_ENGINE_VIEW: AdaptiveEngineView, + EngineTypes.MULTISCALE_PARTITIONING_ENGINE_VIEW: MultiscalePartitioningEngineView, + EngineTypes.GRAPH_ENGINE: GraphEngine +} + def load_network_module(filepath): module_name = os.path.basename(filepath).replace(".py", "") if module_name in sys.modules: # clear any existing module with the same name @@ -103,12 +112,16 @@ class TestSuite(ABC): self.composition : Composition = composition self.notes : str = notes - def evolve_pynucastro(self, engine: GraphEngine): + def evolve_pynucastro(self, engine: DynamicEngine): print("Evolution complete. Now building equivalent pynucastro network...") # Build equivalent pynucastro network for comparison reaclib_library : pyna.ReacLibLibrary = pyna.ReacLibLibrary() rate_names = [r.id().replace("e+","").replace("e-","").replace(", ", ",") for r in engine.getNetworkReactions()] + with open(f"{self.name}_rate_names_pynuc.txt", "w") as f: + for r_name in rate_names: + f.write(f"{r_name}\n") + goodRates : List[pyna.rates.reaclib_rate.ReacLibRate] = [] missingRates = [] @@ -156,7 +169,23 @@ class TestSuite(ABC): atol=1e-8 ) endTime = time.time() + initial_duration = endTime - startTime print("Pynucastro integration complete. Writing results to JSON...") + print("Running pynucastro a second time to account for any JIT compilation overhead...") + startTime = time.time() + sol = scipy.integrate.solve_ivp( + net.rhs, + [0, self.tMax], + Y0, + args=(self.density, self.temperature), + method="BDF", + jac=net.jacobian, + rtol=1e-5, + atol=1e-8 + ) + endTime = time.time() + final_duration = endTime - startTime + print(f"Pynucastro second integration complete. Initial run time: {initial_duration: .4f} s, Second run time: {final_duration: .4f} s") data: List[Dict[str, Union[float, Dict[str, float]]]] = [] @@ -182,7 +211,8 @@ class TestSuite(ABC): "Temperature": self.temperature, "Density": self.density, "tMax": self.tMax, - "ElapsedTime": endTime - startTime, + "RunTime0": initial_duration, + "RunTime1": final_duration, "DateCreated": datetime.now().isoformat() }, "Steps": data @@ -191,16 +221,16 @@ class TestSuite(ABC): with open(f"GridFireValidationSuite_{self.name}_pynucastro.json", "w") as f: json.dump(pynucastro_json, f, indent=4) - def evolve(self, engine: GraphEngine, netIn: NetIn, pynucastro_compare: bool = True): - solver : CVODESolverStrategy = CVODESolverStrategy(engine) + def evolve(self, engine: DynamicEngine, solver_ctx: PointSolverContext, netIn: NetIn, pynucastro_compare: bool = True, engine_type: EngineTypes | None = None): + solver : PointSolver = PointSolver(engine) stepLogger : StepLogger = StepLogger() - solver.set_callback(lambda ctx: stepLogger.log_step(ctx)) + solver_ctx.callback(lambda ctx: stepLogger.log_step(ctx)) startTime = time.time() try: startTime = time.time() - netOut : NetOut = solver.evaluate(netIn) + netOut : NetOut = solver.evaluate(solver_ctx, netIn) endTime = time.time() stepLogger.to_json( f"GridFireValidationSuite_{self.name}_OKAY.json", @@ -232,10 +262,23 @@ class TestSuite(ABC): ) if pynucastro_compare: - self.evolve_pynucastro(engine) - + if engine_type is not None: + if engine_type == EngineTypes.ADAPTIVE_ENGINE_VIEW: + print("Pynucastro comparison using AdaptiveEngineView...") + self.evolve_pynucastro(engine) + elif engine_type == EngineTypes.MULTISCALE_PARTITIONING_ENGINE_VIEW: + print("Pynucastro comparison using MultiscalePartitioningEngineView...") + graphEngine : GraphEngine = GraphEngine(self.composition, depth=3) + multiScaleEngine : MultiscalePartitioningEngineView = MultiscalePartitioningEngineView(graphEngine) + self.evolve_pynucastro(multiScaleEngine) + elif engine_type == EngineTypes.GRAPH_ENGINE: + print("Pynucastro comparison using GraphEngine...") + graphEngine : GraphEngine = GraphEngine(self.composition, depth=3) + self.evolve_pynucastro(graphEngine) + else: + print(f"Pynucastro comparison not implemented for engine type: {engine_type}") @abstractmethod - def __call__(self): + def __call__(self, pynucastro_compare: bool = False, pync_engine: str = "AdaptiveEngineView"): pass