|
Prev
| Next
|
|
|
|
|
|
jit_get_started.cpp |
|
@(@\newcommand{\W}[1]{ \; #1 \; }
\newcommand{\R}[1]{ {\rm #1} }
\newcommand{\B}[1]{ {\bf #1} }
\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }
\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }
\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} }
\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }@)@This is cppad-20221105 documentation. Here is a link to its
current documentation
.
JIT Computation of Derivatives: Example and Test
Purpose
This is a simple example using CppAD for Just In Time (JIT)
compilation, linking, and running of C source code that computes derivatives.
Source
# include <cstddef>
# include <iostream>
# include <fstream>
# include <map>
# include <cppad/configure.hpp>
# if CPPAD_USE_CPLUSPLUS_2017
# include <filesystem>
# endif
// DLL_EXT
# ifdef _WIN32
# define DLL_EXT ".dll"
# else
# define DLL_EXT ".so"
# endif
# include <cppad/cppad.hpp>
bool get_started(void)
{ bool ok = true;
//
// p
# if CPPAD_USE_CPLUSPLUS_2017
std::filesystem::path p;
# endif
//
using CppAD::AD;
using CppAD::ADFun;
using CppAD::Independent;
using CppAD::NearEqual;
//
// f
// f(r, a) = (x_0 * cos(x_1) , x_0 * sin(x_1))^T
size_t n = 2;
size_t m = 2;
CPPAD_TESTVECTOR( AD<double> ) ax(n), ay(m);
for(size_t j = 0; j < n; ++j)
ax[j] = AD<double>( j + 1);
Independent(ax);
ay[0] = ax[0] * cos( ax[1] );
ay[1] = ax[0] * sin( ax[1] );
ADFun<double> f(ax, ay);
ADFun< AD<double> , double > af = f.base2ad();
//
// g(x) = f'(x)
// g(x) = [ cos(x_1) , - x_0 * sin(x_1) ]
// [ sin(x_1) , x_0 * cos(x_1) ]
Independent(ax);
CPPAD_TESTVECTOR( AD<double> ) az(m * n);
az = af.Jacobian(ax);
ADFun<double> g(ax, az);
g.function_name_set("g");
//
// csrc_file
// created in std::filesystem::current_path()
std::string c_type = "double";
std::string csrc_file = "jit_get_started.c";
std::ofstream ofs;
ofs.open(csrc_file , std::ofstream::out);
g.to_csrc(ofs, c_type);
ofs.close();
//
// p, ok
# if CPPAD_USE_CPLUSPLUS_2017
p = std::filesystem::current_path();
p /= csrc_file;
ok &= std::filesystem::exists(p);
# endif
//
// dll_file
// created in std::filesystem::current_path()
std::string dll_file = "jit_get_started" DLL_EXT;
CPPAD_TESTVECTOR( std::string) csrc_files(1);
csrc_files[0] = csrc_file;
std::map< std::string, std::string > options;
std::string err_msg = CppAD::create_dll_lib(dll_file, csrc_files, options);
if( err_msg != "" )
{ std::cerr << "jit_get_started: err_msg = " << err_msg << "\n";
return false;
}
//
// p, ok
# if CPPAD_USE_CPLUSPLUS_2017
p = std::filesystem::current_path();
p /= dll_file;
ok &= std::filesystem::exists(p);
# endif
//
// dll_linker
CppAD::link_dll_lib dll_linker(dll_file, err_msg);
if( err_msg != "" )
{ std::cerr << "jit_get_started: err_msg = " << err_msg << "\n";
return false;
}
//
// g_ptr
std::string function_name = "cppad_jit_g";
void* void_ptr = dll_linker(function_name, err_msg);
if( err_msg != "" )
{ std::cerr << "jit_get_started: err_msg = " << err_msg << "\n";
return false;
}
//
// jit_double
using CppAD::jit_double;
//
// g_ptr
jit_double g_ptr =
reinterpret_cast<jit_double>(void_ptr);
//
// x, z, compare_change
// z = g(x)
size_t nx = n, nz = m * n, compare_change = 0;
std::vector<double> x(nx), z(nz);
x[0] = 0.3;
x[1] = 0.5;
g_ptr(nx, x.data(), nz, z.data(), &compare_change);
//
// ok
ok &= compare_change == 0;
//
// eps99
double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
//
// ok
// df_0 / dx_0 is stored in z[0 * n + 0]
double value = z[ 0 * n + 0];
double check = std::cos(x[1]);
ok &= NearEqual(value, check, eps99, eps99);
//
// ok
// df_0 / dx_1 is stored in z[0 * n + 1]
value = z[ 0 * n + 1];
check = - x[0] * std::sin(x[1]);
ok &= NearEqual(value, check, eps99, eps99);
//
// ok
// df_1 / dx_0 is stored in z[1 * n + 0]
value = z[ 1 * n + 0];
check = std::sin(x[1]);
ok &= NearEqual(value, check, eps99, eps99);
//
// ok
// df_1 / dx_1 is stored in z[1 * n + 1]
value = z[ 1 * n + 1];
check = x[0] * std::cos(x[1]);
ok &= NearEqual(value, check, eps99, eps99);
//
return ok;
}
Input File: example/jit/get_started.cpp