|
Prev
| Next
|
|
|
|
|
|
json_atom4_op.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
.
Json Atomic Function Operator: Example and Test
Source Code
# include <cppad/cppad.hpp>
namespace {
class atomic_avg : public CppAD::atomic_four<double> {
public:
atomic_avg(void) : CppAD::atomic_four<double>("avg")
{ }
private:
// for_type
bool for_type(
size_t call_id ,
const CppAD::vector<CppAD::ad_type_enum>& type_x ,
CppAD::vector<CppAD::ad_type_enum>& type_y ) override
{ type_y[0] = type_x[0];
return true;
}
// forward
bool forward(
size_t call_id ,
const CppAD::vector<bool>& select_y ,
size_t order_low ,
size_t order_up ,
const CppAD::vector<double>& taylor_x ,
CppAD::vector<double>& taylor_y ) override
{
// order_up
if( order_up != 0 )
return false;
//
// n
size_t n = taylor_x.size();
if( n == 0 )
return false;
//
// taylor_y
double sum = 0.0;
for(size_t j = 0; j < n; ++j)
sum += taylor_x[j];
taylor_y[0] = sum / double(n);
//
return true;
}
};
}
bool atom4_op(void)
{ bool ok = true;
using CppAD::vector;
using CppAD::AD;
//
// avg
atomic_avg avg;
//
// -----------------------------------------------------------------------
// g (p; x) = avg( [ p_0 * x_0, p_0 * x_1 ] )
// = p_0 * (x_0 + x_1) / 2
//
// This function has an atomic function operator with name avg
// node_1 : p[0]
// node_2 : x[0]
// node_3 : x[1]
// node_4 : p[0] * x[0]
// node_5 : p[0] * x[1]
// node_6 : avg( p[0] * x[0], p[0] * x[1] )
// y[0] = p[0] * ( x[0] + x[1] ) / 2
std::string json =
"{\n"
" 'function_name' : 'g(p; x)',\n"
" 'op_define_vec' : [ 2, [\n"
" { 'op_code':1, 'name':'atom4' } ,\n"
" { 'op_code':2, 'name':'mul', 'n_arg':2 } ]\n"
" ],\n"
" 'n_dynamic_ind' : 1,\n" // p[0]
" 'n_variable_ind' : 2,\n" // x[0], x[1]
" 'constant_vec' : [ 0, [ ] ],\n"
" 'op_usage_vec' : [ 3, [\n"
" [ 2, 1, 2 ] ,\n" // p[0] * x[0]
" [ 2, 1, 3 ] ,\n" // p[0] * x[1]
// avg( p[0] * x[0], p[0] * x[1] )
" [ 1, 'avg', 0, 1, 2, [ 4, 5 ] ] ]\n"
" ],\n"
" 'dependent_vec' : [ 1, [6] ] \n"
"}\n";
// Convert the single quote to double quote
for(size_t i = 0; i < json.size(); ++i)
if( json[i] == '\'' ) json[i] = '"';
// ------------------------------------------------------------------------
CppAD::ADFun<double> g;
g.from_json(json);
// ------------------------------------------------------------------------
ok &= g.Domain() == 2;
ok &= g.Range() == 1;
ok &= g.size_dyn_ind() == 1;
//
// set p in g(p; x)
vector<double> p(1);
p[0] = 2.0;
g.new_dynamic(p);
//
// evalute g(p; x)
vector<double> x(2), y(1);
x[0] = 3.0;
x[1] = 4.0;
y = g.Forward(0, x);
//
// check value
ok &= y[0] == p[0] * (x[0] + x[1]) / 2.0;
// ------------------------------------------------------------------------
json = g.to_json();
g.from_json(json);
// ------------------------------------------------------------------------
ok &= g.Domain() == 2;
ok &= g.Range() == 1;
ok &= g.size_dyn_ind() == 1;
//
// set p in g(p; x)
p[0] = 5.0;
g.new_dynamic(p);
//
// evalute g(p; x)
x[0] = 6.0;
x[1] = 7.0;
y = g.Forward(0, x);
//
// check value
ok &= y[0] == p[0] * (x[0] + x[1]) / 2.0;
// ------------------------------------------------------------------------
return ok;
}
Input File: example/json/atom4_op.cpp