// assume that F2CAD_USE_CppAD is defined
# include <f2cad/f2cad.hpp>
namespace {
static CppADvector< CppAD::AD<double> > X;
static CppAD::ADFun<double> *F = 0;
}
namespace f2cad {
void Independent(integer n, doublereal *x)
{
// check not two Independents in a row
assert( X.size() == 0 );
// make sure the set of independent variables not empty
assert( n > 0 );
// check for a previously defined function (nonzero pointer)
if( F != 0 )
{ delete F;
F = 0;
}
// move data into structure expected by CppAD
X.resize(n);
integer j;
for(j = 0; j < n; j++)
X[j] = x[j];
// declare independent variables
CppAD::Independent(X);
// make x equivalent to X
for(j = 0; j < n; j++)
x[j] = X[j];
return;
}
void Dependent(integer m, doublereal *y)
{
// check that directly follows call to Independent
assert( X.size() > 0 );
assert( F == 0 );
// make sure the set of dependent variables not empty
assert( m > 0 );
// move data into structure expected by CppAD
CppADvector< CppAD::AD<double> > Y(m);
integer i;
for(i = 0; i < m; i++)
Y[i] = y[i];
// construct the AD function object
F = new CppAD::ADFun<double>(X, Y);
// no longer need independent variable information
X.resize(0);
}
// linked here from Partial<doublereal>(integer i, integer j)
double Partial(const doublereal &zero, integer i, integer j)
{
// check that directly follows call to Dependent
assert( X.size() == 0 );
assert( F != 0 );
// check dimension of arguments
integer m = F->Range();
integer n = F->Domain();
assert( 0 <= i );
assert( 0 <= j );
assert( i < m );
assert( j < n );
assert( zero == doublereal(0) );
// move data into structure expected by CppAD
CppADvector<double> dx(n);
integer k;
for(k = 0; k < n; k++)
dx[k] = 0.;
dx[j] = 1.;
// Forward mode calculation
CppADvector<double> dy(m);
dy = F->Forward(1, dx);
// return the result
return dy[i];
}
double Value(const doublereal &z)
{ // convert in a way that works even if we are recording
return CppAD::Value( Var2Par(z) );
}
doublereal Sign(const doublereal* x, const doublereal* y)
{ if( *y >= 0. )
return abs(*x);
return -abs(*x);
}
} // end f2cad namespace