build(CppAD): brought in CppAD for autodiff
we need an autodiff library at some point (or we need to roll our own but I do not think that makes sense). CppAD is well tested and header only and easy to include. It is also Liscene compatible with GPL v3.0. Here we bring it in as a dependency
This commit is contained in:
160
build-config/cppad/include/cppad/local/abs_op.hpp
Normal file
160
build-config/cppad/include/cppad/local/abs_op.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
263
build-config/cppad/include/cppad/local/acos_op.hpp
Normal file
263
build-config/cppad/include/cppad/local/acos_op.hpp
Normal file
@@ -0,0 +1,263 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
264
build-config/cppad/include/cppad/local/acosh_op.hpp
Normal file
264
build-config/cppad/include/cppad/local/acosh_op.hpp
Normal file
@@ -0,0 +1,264 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
186
build-config/cppad/include/cppad/local/ad_tape.hpp
Normal file
186
build-config/cppad/include/cppad/local/ad_tape.hpp
Normal file
@@ -0,0 +1,186 @@
|
||||
# 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 <cppad/local/define.hpp>
|
||||
|
||||
namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL__NAMESPACE
|
||||
|
||||
/*!
|
||||
Class used to hold tape that records AD<Base> operations.
|
||||
|
||||
\tparam Base
|
||||
An <tt>AD<Base></tt> object is used to recording <tt>AD<Base></tt> operations.
|
||||
*/
|
||||
|
||||
template <class Base>
|
||||
class ADTape {
|
||||
// Friends =============================================================
|
||||
|
||||
// classes -------------------------------------------------------------
|
||||
friend class AD<Base>;
|
||||
friend class ADFun<Base>;
|
||||
friend class atomic_base<Base>;
|
||||
friend class atomic_three<Base>;
|
||||
friend class discrete<Base>;
|
||||
friend class VecAD<Base>;
|
||||
friend class VecAD_reference<Base>;
|
||||
|
||||
// functions -----------------------------------------------------------
|
||||
// PrintFor
|
||||
friend void CppAD::PrintFor <Base> (
|
||||
const AD<Base>& flag ,
|
||||
const char* before ,
|
||||
const AD<Base>& var ,
|
||||
const char* after
|
||||
);
|
||||
// CondExpOp
|
||||
friend AD<Base> CppAD::CondExpOp <Base> (
|
||||
enum CompareOp cop ,
|
||||
const AD<Base> &left ,
|
||||
const AD<Base> &right ,
|
||||
const AD<Base> &trueCase ,
|
||||
const AD<Base> &falseCase
|
||||
);
|
||||
// pow
|
||||
friend AD<Base> CppAD::pow <Base>
|
||||
(const AD<Base> &x, const AD<Base> &y);
|
||||
// azmul
|
||||
friend AD<Base> CppAD::azmul <Base>
|
||||
(const AD<Base> &x, const AD<Base> &y);
|
||||
// Parameter
|
||||
friend bool CppAD::Parameter <Base>
|
||||
(const AD<Base> &u);
|
||||
// Variable
|
||||
friend bool CppAD::Variable <Base>
|
||||
(const AD<Base> &u);
|
||||
// operators -----------------------------------------------------------
|
||||
// arithematic binary operators
|
||||
# if _MSC_VER
|
||||
// see https://stackoverflow.com/questions/63288453
|
||||
template <class Type> friend AD<Type> CppAD::operator * <Type>
|
||||
(const AD<Type> &left, const AD<Type> &right);
|
||||
# else
|
||||
friend AD<Base> CppAD::operator * <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
# endif
|
||||
friend AD<Base> CppAD::operator + <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
friend AD<Base> CppAD::operator - <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
friend AD<Base> CppAD::operator / <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
|
||||
// comparison operators
|
||||
# if _MSC_VER
|
||||
template <class Type> friend bool CppAD::operator == <Type>
|
||||
(const AD<Type> &left, const AD<Type> &right);
|
||||
template <class Type> friend bool CppAD::operator != <Type>
|
||||
(const AD<Type> &left, const AD<Type> &right);
|
||||
# else
|
||||
friend bool CppAD::operator == <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
friend bool CppAD::operator != <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
# endif
|
||||
friend bool CppAD::operator < <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
friend bool CppAD::operator <= <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
friend bool CppAD::operator > <Base>
|
||||
(const AD<Base> &left, const AD<Base> &right);
|
||||
friend bool CppAD::operator >= <Base>
|
||||
(const AD<Base> &left, const AD<Base> &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<Base> Rec_;
|
||||
// ----------------------------------------------------------------------
|
||||
// private functions
|
||||
//
|
||||
// add a parameter to the tape
|
||||
addr_t RecordParOp(const AD<Base>& y);
|
||||
|
||||
// see CondExp.h
|
||||
void RecordCondExp(
|
||||
enum CompareOp cop ,
|
||||
AD<Base> &returnValue ,
|
||||
const AD<Base> &left ,
|
||||
const AD<Base> &right ,
|
||||
const AD<Base> &trueCase ,
|
||||
const AD<Base> &falseCase
|
||||
);
|
||||
|
||||
public:
|
||||
// public function only used by CppAD::Independent
|
||||
template <class ADBaseVector>
|
||||
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 <tt>ADTape<Base></tt> to <tt>recorder<Base></tt>.
|
||||
*/
|
||||
template <class Base>
|
||||
addr_t ADTape<Base>::RecordParOp(const AD<Base>& 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
|
||||
338
build-config/cppad/include/cppad/local/add_op.hpp
Normal file
338
build-config/cppad/include/cppad/local/add_op.hpp
Normal file
@@ -0,0 +1,338 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
263
build-config/cppad/include/cppad/local/asin_op.hpp
Normal file
263
build-config/cppad/include/cppad/local/asin_op.hpp
Normal file
@@ -0,0 +1,263 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
264
build-config/cppad/include/cppad/local/asinh_op.hpp
Normal file
264
build-config/cppad/include/cppad/local/asinh_op.hpp
Normal file
@@ -0,0 +1,264 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
235
build-config/cppad/include/cppad/local/atan_op.hpp
Normal file
235
build-config/cppad/include/cppad/local/atan_op.hpp
Normal file
@@ -0,0 +1,235 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
236
build-config/cppad/include/cppad/local/atanh_op.hpp
Normal file
236
build-config/cppad/include/cppad/local/atanh_op.hpp
Normal file
@@ -0,0 +1,236 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
32
build-config/cppad/include/cppad/local/atom_state.hpp
Normal file
32
build-config/cppad/include/cppad/local/atom_state.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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
|
||||
161
build-config/cppad/include/cppad/local/atomic_index.hpp
Normal file
161
build-config/cppad/include/cppad/local/atomic_index.hpp
Normal file
@@ -0,0 +1,161 @@
|
||||
# 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 <vector>
|
||||
# include <cppad/utility/thread_alloc.hpp>
|
||||
|
||||
namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
|
||||
|
||||
struct atomic_index_info {
|
||||
size_t type;
|
||||
std::string name;
|
||||
void* ptr;
|
||||
};
|
||||
|
||||
// BEGIN_ATOMIC_INDEX
|
||||
template <class Base>
|
||||
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<atomic_index_info> 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
|
||||
275
build-config/cppad/include/cppad/local/color_general.hpp
Normal file
275
build-config/cppad/include/cppad/local/color_general.hpp
Normal file
@@ -0,0 +1,275 @@
|
||||
# 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 <cppad/configure.hpp>
|
||||
# include <cppad/local/cppad_colpack.hpp>
|
||||
|
||||
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
|
||||
<code>(row[k], col[k])</code> 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
|
||||
<code>(row[k], col[k])</code> 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, <code>color[i] == m</code>, then
|
||||
the i-th row does not appear in the vector row.
|
||||
Otherwise, <code>color[i] < m</code>.
|
||||
\n
|
||||
\n
|
||||
Suppose two differen rows, <code>i != r</code> have the same color and
|
||||
column index j is such that both of the pairs
|
||||
<code>(i, j)</code> and <code>(r, j)</code> appear in the sparsity pattern.
|
||||
It follows that neither of these pairs appear in the set of
|
||||
<code>(row[k], col[k])</code> entries.
|
||||
\n
|
||||
\n
|
||||
This routine tries to minimize, with respect to the choice of colors,
|
||||
the maximum, with respct to k, of <code>color[ row[k] ]</code>
|
||||
(not counting the indices k for which row[k] == m).
|
||||
*/
|
||||
template <class SetVector, class SizeVector>
|
||||
void color_general_cppad(
|
||||
const SetVector& pattern ,
|
||||
const SizeVector& row ,
|
||||
const SizeVector& col ,
|
||||
CppAD::vector<size_t>& 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<bool> 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<bool> 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 <class SetVector, class SizeVector>
|
||||
void color_general_colpack(
|
||||
const SetVector& pattern ,
|
||||
const SizeVector& row ,
|
||||
const SizeVector& col ,
|
||||
CppAD::vector<size_t>& color )
|
||||
{
|
||||
size_t m = pattern.n_set();
|
||||
size_t n = pattern.end();
|
||||
|
||||
// Determine number of non-zero entries in each row
|
||||
CppAD::vector<size_t> 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<unsigned int*> adolc_pattern(m);
|
||||
CppAD::vector<unsigned int> 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<unsigned int>::max() >= n_nonzero[i],
|
||||
"Matrix is too large for colpack"
|
||||
);
|
||||
adolc_pattern[i][0] = static_cast<unsigned int>( 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<unsigned int>::max() >= j,
|
||||
"Matrix is too large for colpack"
|
||||
);
|
||||
adolc_pattern[i][k++] = static_cast<unsigned int>( 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
|
||||
309
build-config/cppad/include/cppad/local/color_symmetric.hpp
Normal file
309
build-config/cppad/include/cppad/local/color_symmetric.hpp
Normal file
@@ -0,0 +1,309 @@
|
||||
# ifndef CPPAD_LOCAL_COLOR_SYMMETRIC_HPP
|
||||
# define CPPAD_LOCAL_COLOR_SYMMETRIC_HPP
|
||||
# include <cppad/configure.hpp>
|
||||
# include <cppad/local/cppad_colpack.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 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
|
||||
<code>(row[k], col[k])</code> 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
|
||||
<code>(row[k], col[k])</code> 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 <code>color[ row[k] ]</code>.
|
||||
*/
|
||||
template <class SetVector>
|
||||
void color_symmetric_cppad(
|
||||
const SetVector& pattern ,
|
||||
CppAD::vector<size_t>& row ,
|
||||
CppAD::vector<size_t>& col ,
|
||||
CppAD::vector<size_t>& 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<size_t> > pair_needed(m);
|
||||
std::set<size_t>::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<size_t> 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<size_t> 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<bool> 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 <class SetVector>
|
||||
void color_symmetric_colpack(
|
||||
const SetVector& pattern ,
|
||||
CppAD::vector<size_t>& row ,
|
||||
CppAD::vector<size_t>& col ,
|
||||
CppAD::vector<size_t>& 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<size_t> 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<unsigned int*> adolc_pattern(m);
|
||||
CppAD::vector<unsigned int> 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<unsigned int>::max() >= n_nonzero[i],
|
||||
"Matrix is too large for colpack"
|
||||
);
|
||||
adolc_pattern[i][0] = static_cast<unsigned int>( 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<unsigned int>::max() >= j,
|
||||
"Matrix is too large for colpack"
|
||||
);
|
||||
adolc_pattern[i][k++] = static_cast<unsigned int>( 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
|
||||
420
build-config/cppad/include/cppad/local/comp_op.hpp
Normal file
420
build-config/cppad/include/cppad/local/comp_op.hpp
Normal file
@@ -0,0 +1,420 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
1317
build-config/cppad/include/cppad/local/cond_op.hpp
Normal file
1317
build-config/cppad/include/cppad/local/cond_op.hpp
Normal file
File diff suppressed because it is too large
Load Diff
238
build-config/cppad/include/cppad/local/cos_op.hpp
Normal file
238
build-config/cppad/include/cppad/local/cos_op.hpp
Normal file
@@ -0,0 +1,238 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
238
build-config/cppad/include/cppad/local/cosh_op.hpp
Normal file
238
build-config/cppad/include/cppad/local/cosh_op.hpp
Normal file
@@ -0,0 +1,238 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
104
build-config/cppad/include/cppad/local/cppad_colpack.hpp
Normal file
104
build-config/cppad/include/cppad/local/cppad_colpack.hpp
Normal file
@@ -0,0 +1,104 @@
|
||||
# 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
|
||||
<code>ColPack/ColPackHeaders.h</code> has a
|
||||
<code>using namespace std</code> 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,
|
||||
<code>adolc_pattern[i][0]</code> is the number of non-zeros in row i.
|
||||
For <code>j = 1 , ... , adolc_sparsity[i]<code>,
|
||||
<code>adolc_pattern[i][j]</code> 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, <code>color[i] == m</code>, then
|
||||
<code>adolc_pattern[i][0] == 0</code>.
|
||||
Otherwise, <code>color[i] < m</code>.
|
||||
\n
|
||||
\n
|
||||
Suppose two differen rows, <code>i != r</code> have the same color.
|
||||
It follows that for all column indices j;
|
||||
it is not the case that both
|
||||
<code>(i, j)</code> and <code>(r, j)</code> 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<size_t>& color ,
|
||||
size_t m ,
|
||||
size_t n ,
|
||||
const CppAD::vector<unsigned int*>& adolc_pattern
|
||||
);
|
||||
|
||||
/*!
|
||||
Link from CppAD to ColPack used for symmetric sparse matrices
|
||||
(not yet used or tested).
|
||||
|
||||
This CppAD library routine is necessary because
|
||||
<code>ColPack/ColPackHeaders.h</code> has a
|
||||
<code>using namespace std</code> 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,
|
||||
<code>adolc_pattern[i][0]</code> is the number of non-zeros in row i.
|
||||
For <code>j = 1 , ... , adolc_sparsity[i]<code>,
|
||||
<code>adolc_pattern[i][j]</code> 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<size_t>& color ,
|
||||
size_t n ,
|
||||
const CppAD::vector<unsigned int*>& adolc_pattern
|
||||
);
|
||||
|
||||
} } // END_CPPAD_LOCAL_NAMESPACE
|
||||
|
||||
# endif
|
||||
# endif
|
||||
|
||||
199
build-config/cppad/include/cppad/local/cskip_op.hpp
Normal file
199
build-config/cppad/include/cppad/local/cskip_op.hpp
Normal file
@@ -0,0 +1,199 @@
|
||||
# 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<Base> or Base value.
|
||||
We use Base parameter and Base variable to refer to the
|
||||
correspond Base value.
|
||||
We use AD<Base> parameter and AD<Base> variable to refer to the
|
||||
correspond AD<Base> value.
|
||||
|
||||
\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 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<Base> parameter.
|
||||
Otherwise it is an AD<Base> variable.
|
||||
\n
|
||||
\n
|
||||
arg[1] & 2
|
||||
\n
|
||||
If this is zero, right is an AD<Base> parameter.
|
||||
Otherwise it is an AD<Base> 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
|
||||
<tt>arg[5+i]</tt>
|
||||
for <tt>i = 1 , ... , arg[4]</tt> are the operations to skip if the
|
||||
comparison result is true and both left and right are
|
||||
identically Base parameters.
|
||||
\n
|
||||
<tt>arg[5+arg[4]+i]</tt>
|
||||
for <tt>i = 1 , ... , arg[5]</tt> 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<Base> parameter,
|
||||
<code>parameter [ arg[2] ]</code> is its value.
|
||||
If right is an AD<Base> parameter,
|
||||
<code>parameter [ arg[3] ]</code> 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<Base> variable,
|
||||
<code>taylor [ size_t(arg[2]) * cap_order + 0 ]</code>
|
||||
is the zeroth order Taylor coefficient corresponding to left.
|
||||
If right is an AD<Base> variable,
|
||||
<code>taylor [ size_t(arg[3]) * cap_order + 0 ]</code>
|
||||
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 <class Base>
|
||||
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
|
||||
612
build-config/cppad/include/cppad/local/csum_op.hpp
Normal file
612
build-config/cppad/include/cppad/local/csum_op.hpp
Normal file
@@ -0,0 +1,612 @@
|
||||
# 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 <class Base>
|
||||
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<Base> 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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
|
||||
183
build-config/cppad/include/cppad/local/declare_ad.hpp
Normal file
183
build-config/cppad/include/cppad/local/declare_ad.hpp
Normal file
@@ -0,0 +1,183 @@
|
||||
# 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 <cppad/configure.hpp>
|
||||
# include <cstdint>
|
||||
|
||||
/*!
|
||||
\file declare_ad.hpp CppAD forward declarations; i.e., before definition
|
||||
*/
|
||||
|
||||
namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
|
||||
|
||||
template <class Base> class ADTape;
|
||||
template <class Base> class player;
|
||||
template <class Base> 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 Base> class AD;
|
||||
template <class Base, class RecBase=Base> class ADFun;
|
||||
template <class Base> class atomic_base;
|
||||
template <class Base> class atomic_three;
|
||||
template <class Base> class discrete;
|
||||
template <class Base> class VecAD;
|
||||
template <class Base> class VecAD_reference;
|
||||
|
||||
// functions with one VecAD<Base> argument
|
||||
template <class Base> bool Constant (const VecAD<Base> &u);
|
||||
template <class Base> bool Dynamic (const VecAD<Base> &u);
|
||||
template <class Base> bool Parameter (const VecAD<Base> &u);
|
||||
template <class Base> bool Variable (const VecAD<Base> &u);
|
||||
|
||||
// functions with one AD<Base> argument
|
||||
template <class Base> bool Constant (const AD<Base> &u);
|
||||
template <class Base> bool Dynamic (const AD<Base> &u);
|
||||
template <class Base> bool Parameter (const AD<Base> &u);
|
||||
template <class Base> bool Variable (const AD<Base> &u);
|
||||
//
|
||||
template <class Base> int Integer (const AD<Base> &u);
|
||||
template <class Base> bool IdenticalZero (const AD<Base> &u);
|
||||
template <class Base> bool IdenticalOne (const AD<Base> &u);
|
||||
template <class Base> bool IdenticalCon (const AD<Base> &u);
|
||||
template <class Base> bool LessThanZero (const AD<Base> &u);
|
||||
template <class Base> bool LessThanOrZero (const AD<Base> &u);
|
||||
template <class Base> bool GreaterThanZero (const AD<Base> &u);
|
||||
template <class Base> bool GreaterThanOrZero (const AD<Base> &u);
|
||||
template <class Base> AD<Base> Var2Par (const AD<Base> &u);
|
||||
template <class Base> AD<Base> abs (const AD<Base> &u);
|
||||
template <class Base> AD<Base> acos (const AD<Base> &u);
|
||||
template <class Base> AD<Base> asin (const AD<Base> &u);
|
||||
template <class Base> AD<Base> atan (const AD<Base> &u);
|
||||
template <class Base> AD<Base> cos (const AD<Base> &u);
|
||||
template <class Base> AD<Base> cosh (const AD<Base> &u);
|
||||
template <class Base> AD<Base> exp (const AD<Base> &u);
|
||||
template <class Base> AD<Base> log (const AD<Base> &u);
|
||||
template <class Base> AD<Base> log10 (const AD<Base> &u);
|
||||
template <class Base> AD<Base> sin (const AD<Base> &u);
|
||||
template <class Base> AD<Base> sinh (const AD<Base> &u);
|
||||
template <class Base> AD<Base> sqrt (const AD<Base> &u);
|
||||
template <class Base> AD<Base> tan (const AD<Base> &u);
|
||||
//
|
||||
template <class Base> unsigned short hash_code(const AD<Base>& u);
|
||||
|
||||
// arithematic operators
|
||||
template <class Base> AD<Base> operator + (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> AD<Base> operator - (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> AD<Base> operator * (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> AD<Base> operator / (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
|
||||
// comparison operators
|
||||
template <class Base> bool operator < (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> bool operator <= (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> bool operator > (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> bool operator >= (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> bool operator == (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
template <class Base> bool operator != (
|
||||
const AD<Base> &left, const AD<Base> &right);
|
||||
|
||||
// pow
|
||||
template <class Base> AD<Base> pow (
|
||||
const AD<Base> &x, const AD<Base> &y);
|
||||
|
||||
// azmul
|
||||
template <class Base> AD<Base> azmul (
|
||||
const AD<Base> &x, const AD<Base> &y);
|
||||
|
||||
// NearEqual
|
||||
template <class Base> bool NearEqual(
|
||||
const AD<Base> &x, const AD<Base> &y, const Base &r, const Base &a);
|
||||
|
||||
template <class Base> bool NearEqual(
|
||||
const Base &x, const AD<Base> &y, const Base &r, const Base &a);
|
||||
|
||||
template <class Base> bool NearEqual(
|
||||
const AD<Base> &x, const Base &y, const Base &r, const Base &a);
|
||||
|
||||
// CondExpOp
|
||||
template <class Base> AD<Base> CondExpOp (
|
||||
enum CompareOp cop ,
|
||||
const AD<Base> &left ,
|
||||
const AD<Base> &right ,
|
||||
const AD<Base> &trueCase ,
|
||||
const AD<Base> &falseCase
|
||||
);
|
||||
|
||||
// IdenticalEqualCon
|
||||
template <class Base>
|
||||
bool IdenticalEqualCon (const AD<Base> &u, const AD<Base> &v);
|
||||
|
||||
// EqualOpSeq
|
||||
template <class Base>
|
||||
bool EqualOpSeq (const AD<Base> &u, const AD<Base> &v);
|
||||
|
||||
// PrintFor
|
||||
template <class Base>
|
||||
void PrintFor(
|
||||
const AD<Base>& flag ,
|
||||
const char* before ,
|
||||
const AD<Base>& var ,
|
||||
const char* after
|
||||
);
|
||||
|
||||
// Value
|
||||
template <class Base> Base Value(const AD<Base> &x);
|
||||
|
||||
// Pow function
|
||||
template <class Base> AD<Base> pow
|
||||
(const AD<Base> &x, const AD<Base> &y);
|
||||
|
||||
// input operator
|
||||
template <class Base> std::istream&
|
||||
operator >> (std::istream &is, AD<Base> &x);
|
||||
|
||||
// output operator
|
||||
template <class Base> std::ostream&
|
||||
operator << (std::ostream &os, const AD<Base> &x);
|
||||
template <class Base> std::ostream&
|
||||
operator << (std::ostream &os, const VecAD_reference<Base> &e);
|
||||
template <class Base> std::ostream&
|
||||
operator << (std::ostream &os, const VecAD<Base> &vec);
|
||||
}
|
||||
|
||||
# endif
|
||||
321
build-config/cppad/include/cppad/local/define.hpp
Normal file
321
build-config/cppad/include/cppad/local/define.hpp
Normal file
@@ -0,0 +1,321 @@
|
||||
# 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:
|
||||
<code>
|
||||
size_t(enum_value) <= std::numeric_limits<CPPAD_VEC_ENUM_TYPE>::max()
|
||||
&& is_pod<CPPAD_VEC_ENUM_TYPE>
|
||||
</code>
|
||||
*/
|
||||
# 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<Base>.
|
||||
It uses this case to define the cases where
|
||||
left has type AD<Base> and right has type
|
||||
VecAD_reference<Base>,
|
||||
Base, or
|
||||
double.
|
||||
The argument right is const and call by reference.
|
||||
This macro converts the operands to AD<Base> and then
|
||||
uses the definition of the same operation for that case.
|
||||
*/
|
||||
|
||||
# define CPPAD_FOLD_ASSIGNMENT_OPERATOR(Op) \
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
template <class Base> \
|
||||
AD<Base>& operator Op \
|
||||
(AD<Base> &left, double right) \
|
||||
{ return left Op AD<Base>(right); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base>& operator Op \
|
||||
(AD<Base> &left, const Base &right) \
|
||||
{ return left Op AD<Base>(right); } \
|
||||
\
|
||||
inline AD<double>& operator Op \
|
||||
(AD<double> &left, const double &right) \
|
||||
{ return left Op AD<double>(right); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base>& operator Op \
|
||||
(AD<Base> &left, const VecAD_reference<Base> &right) \
|
||||
{ return left Op right.ADBase(); }
|
||||
|
||||
// =====================================================================
|
||||
/*!
|
||||
\def CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op)
|
||||
Declares automatic coercion for certain binary operations with AD result.
|
||||
|
||||
This macro assumes that the operator
|
||||
\verbatim
|
||||
left Op right
|
||||
\endverbatim
|
||||
is defined for the case where left and right
|
||||
and the result of the operation all
|
||||
have type AD<Base>.
|
||||
It uses this case to define the cases either left
|
||||
or right has type VecAD_reference<Base> or AD<Base>
|
||||
and the type of the other operand is one of the following:
|
||||
VecAD_reference<Base>, AD<Base>, Base, double.
|
||||
All of the arguments are const and call by reference.
|
||||
This macro converts the operands to AD<Base> and then
|
||||
uses the definition of the same operation for that case.
|
||||
*/
|
||||
# define CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op) \
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Operations with VecAD_reference<Base> and AD<Base> only*/ \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const AD<Base> &left, const VecAD_reference<Base> &right) \
|
||||
{ return left Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const VecAD_reference<Base> &left, const VecAD_reference<Base> &right)\
|
||||
{ return left.ADBase() Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const VecAD_reference<Base> &left, const AD<Base> &right) \
|
||||
{ return left.ADBase() Op right; } \
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Operations Base */ \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const Base &left, const AD<Base> &right) \
|
||||
{ return AD<Base>(left) Op right; } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const Base &left, const VecAD_reference<Base> &right) \
|
||||
{ return AD<Base>(left) Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const AD<Base> &left, const Base &right) \
|
||||
{ return left Op AD<Base>(right); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const VecAD_reference<Base> &left, const Base &right) \
|
||||
{ return left.ADBase() Op AD<Base>(right); } \
|
||||
\
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Operations double */ \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const double &left, const AD<Base> &right) \
|
||||
{ return AD<Base>(left) Op right; } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const double &left, const VecAD_reference<Base> &right) \
|
||||
{ return AD<Base>(left) Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const AD<Base> &left, const double &right) \
|
||||
{ return left Op AD<Base>(right); } \
|
||||
\
|
||||
template <class Base> \
|
||||
AD<Base> operator Op \
|
||||
(const VecAD_reference<Base> &left, const double &right) \
|
||||
{ return left.ADBase() Op AD<Base>(right); } \
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Special case to avoid ambuigity when Base is double */ \
|
||||
\
|
||||
inline AD<double> operator Op \
|
||||
(const double &left, const AD<double> &right) \
|
||||
{ return AD<double>(left) Op right; } \
|
||||
\
|
||||
inline AD<double> operator Op \
|
||||
(const double &left, const VecAD_reference<double> &right) \
|
||||
{ return AD<double>(left) Op right.ADBase(); } \
|
||||
\
|
||||
inline AD<double> operator Op \
|
||||
(const AD<double> &left, const double &right) \
|
||||
{ return left Op AD<double>(right); } \
|
||||
\
|
||||
inline AD<double> operator Op \
|
||||
(const VecAD_reference<double> &left, const double &right) \
|
||||
{ return left.ADBase() Op AD<double>(right); }
|
||||
|
||||
// =======================================================================
|
||||
|
||||
/*!
|
||||
\def CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op)
|
||||
Declares automatic coercion for certain binary operations with bool result.
|
||||
|
||||
This macro assumes that the operator
|
||||
\verbatim
|
||||
left Op right
|
||||
\endverbatim
|
||||
is defined for the case where left and right
|
||||
have type AD<Base> and the result has type bool.
|
||||
It uses this case to define the cases either left
|
||||
or right has type
|
||||
VecAD_reference<Base> or AD<Base>
|
||||
and the type of the other operand is one of the following:
|
||||
VecAD_reference<Base>, AD<Base>, Base, double.
|
||||
All of the arguments are const and call by reference.
|
||||
This macro converts the operands to AD<Base> and then
|
||||
uses the definition of the same operation for that case.
|
||||
*/
|
||||
# define CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op) \
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Operations with VecAD_reference<Base> and AD<Base> only*/ \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const AD<Base> &left, const VecAD_reference<Base> &right) \
|
||||
{ return left Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const VecAD_reference<Base> &left, const VecAD_reference<Base> &right)\
|
||||
{ return left.ADBase() Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const VecAD_reference<Base> &left, const AD<Base> &right) \
|
||||
{ return left.ADBase() Op right; } \
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Operations Base */ \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const Base &left, const AD<Base> &right) \
|
||||
{ return AD<Base>(left) Op right; } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const Base &left, const VecAD_reference<Base> &right) \
|
||||
{ return AD<Base>(left) Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const AD<Base> &left, const Base &right) \
|
||||
{ return left Op AD<Base>(right); } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const VecAD_reference<Base> &left, const Base &right) \
|
||||
{ return left.ADBase() Op AD<Base>(right); } \
|
||||
\
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Operations double */ \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const double &left, const AD<Base> &right) \
|
||||
{ return AD<Base>(left) Op right; } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const double &left, const VecAD_reference<Base> &right) \
|
||||
{ return AD<Base>(left) Op right.ADBase(); } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const AD<Base> &left, const double &right) \
|
||||
{ return left Op AD<Base>(right); } \
|
||||
\
|
||||
template <class Base> \
|
||||
bool operator Op \
|
||||
(const VecAD_reference<Base> &left, const double &right) \
|
||||
{ return left.ADBase() Op AD<Base>(right); } \
|
||||
/* ----------------------------------------------------------------*/ \
|
||||
/* Special case to avoid ambuigity when Base is double */ \
|
||||
\
|
||||
inline bool operator Op \
|
||||
(const double &left, const AD<double> &right) \
|
||||
{ return AD<double>(left) Op right; } \
|
||||
\
|
||||
inline bool operator Op \
|
||||
(const double &left, const VecAD_reference<double> &right) \
|
||||
{ return AD<double>(left) Op right.ADBase(); } \
|
||||
\
|
||||
inline bool operator Op \
|
||||
(const AD<double> &left, const double &right) \
|
||||
{ return left Op AD<double>(right); } \
|
||||
\
|
||||
inline bool operator Op \
|
||||
(const VecAD_reference<double> &left, const double &right) \
|
||||
{ return left.ADBase() Op AD<double>(right); }
|
||||
|
||||
# endif
|
||||
121
build-config/cppad/include/cppad/local/discrete_op.hpp
Normal file
121
build-config/cppad/include/cppad/local/discrete_op.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
# 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
|
||||
<code>tpv = (cap_order-1) * r + 1</code>
|
||||
which is the number of Taylor coefficients per variable
|
||||
|
||||
\param taylor
|
||||
\b Input: <code>taylor [ arg[1] * tpv + 0 ]</code>
|
||||
is the zero order Taylor coefficient corresponding to x.
|
||||
\n
|
||||
\b Output: if <code>p == 0</code>
|
||||
<code>taylor [ i_z * tpv + 0 ]</code>
|
||||
is the zero order Taylor coefficient corresponding to z.
|
||||
For k = max(p, 1), ... , q,
|
||||
<code>taylor [ i_z * tpv + (k-1)*r + 1 + ell ]</code>
|
||||
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 <class Base>
|
||||
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<Base>::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
|
||||
574
build-config/cppad/include/cppad/local/div_op.hpp
Normal file
574
build-config/cppad/include/cppad/local/div_op.hpp
Normal file
@@ -0,0 +1,574 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
598
build-config/cppad/include/cppad/local/erf_op.hpp
Normal file
598
build-config/cppad/include/cppad/local/erf_op.hpp
Normal file
@@ -0,0 +1,598 @@
|
||||
# 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 <cppad/local/mul_op.hpp>
|
||||
# include <cppad/local/sub_op.hpp>
|
||||
# include <cppad/local/exp_op.hpp>
|
||||
|
||||
|
||||
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 <class Base>
|
||||
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<addr_t>::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<Base>(double(j));
|
||||
z_4[j] = static_cast<Base>(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 <class Base>
|
||||
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<addr_t>::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
|
||||
<code>tpv = (cap_order-1) * r + 1</code>
|
||||
which is the number of Taylor coefficients per variable
|
||||
|
||||
\param taylor
|
||||
\b Input: If x is a variable,
|
||||
<code>taylor [ arg[0] * tpv + 0 ]</code>,
|
||||
is the zero order Taylor coefficient for all directions and
|
||||
<code>taylor [ arg[0] * tpv + (k-1)*r + ell + 1 ]</code>,
|
||||
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,
|
||||
<code>
|
||||
taylor[ (i_z - j) * tpv + (k-1)*r + ell + 1]
|
||||
</code>
|
||||
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 <class Base>
|
||||
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<addr_t>::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<Base>(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 <class Base>
|
||||
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<addr_t>::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
|
||||
194
build-config/cppad/include/cppad/local/exp_op.hpp
Normal file
194
build-config/cppad/include/cppad/local/exp_op.hpp
Normal file
@@ -0,0 +1,194 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
199
build-config/cppad/include/cppad/local/expm1_op.hpp
Normal file
199
build-config/cppad/include/cppad/local/expm1_op.hpp
Normal file
@@ -0,0 +1,199 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
386
build-config/cppad/include/cppad/local/graph/cpp_graph_itr.hpp
Normal file
386
build-config/cppad/include/cppad/local/graph/cpp_graph_itr.hpp
Normal file
@@ -0,0 +1,386 @@
|
||||
# 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 <cppad/utility/vector.hpp>
|
||||
# include <cppad/local/graph/cpp_graph_op.hpp>
|
||||
|
||||
// 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<graph_op_enum>* operator_vec_;
|
||||
const vector<size_t>* 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<size_t> str_index_;
|
||||
size_t n_result_;
|
||||
vector<size_t> 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<size_t>::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<size_t>* str_index_ptr;
|
||||
size_t n_result;
|
||||
const vector<size_t>* 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<graph_op_enum>& operator_vec ,
|
||||
const vector<size_t>& 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
|
||||
@@ -0,0 +1,23 @@
|
||||
/* --------------------------------------------------------------------------
|
||||
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
|
||||
@@ -0,0 +1,94 @@
|
||||
# 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 <cstddef>
|
||||
# include <string>
|
||||
# include <map>
|
||||
|
||||
# include <cppad/utility/vector.hpp>
|
||||
# include <cppad/configure.hpp>
|
||||
# include <cppad/core/graph/graph_op_enum.hpp>
|
||||
|
||||
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
|
||||
28
build-config/cppad/include/cppad/local/graph/dev_graph.omh
Normal file
28
build-config/cppad/include/cppad/local/graph/dev_graph.omh
Normal file
@@ -0,0 +1,28 @@
|
||||
-----------------------------------------------------------------------------
|
||||
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
|
||||
389
build-config/cppad/include/cppad/local/graph/json_lexer.hpp
Normal file
389
build-config/cppad/include/cppad/local/graph/json_lexer.hpp
Normal file
@@ -0,0 +1,389 @@
|
||||
# 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 <string>
|
||||
# include <cppad/core/cppad_assert.hpp>
|
||||
|
||||
// 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
|
||||
24
build-config/cppad/include/cppad/local/graph/json_lexer.omh
Normal file
24
build-config/cppad/include/cppad/local/graph/json_lexer.omh
Normal file
@@ -0,0 +1,24 @@
|
||||
-----------------------------------------------------------------------------
|
||||
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
|
||||
55
build-config/cppad/include/cppad/local/graph/json_parser.hpp
Normal file
55
build-config/cppad/include/cppad/local/graph/json_parser.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
# 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 <string>
|
||||
# include <cppad/utility/vector.hpp>
|
||||
# include <cppad/local/graph/cpp_graph_op.hpp>
|
||||
# include <cppad/core/graph/cpp_graph.hpp>
|
||||
|
||||
/*
|
||||
$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
|
||||
54
build-config/cppad/include/cppad/local/graph/json_writer.hpp
Normal file
54
build-config/cppad/include/cppad/local/graph/json_writer.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
# 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 <string>
|
||||
# include <cppad/utility/vector.hpp>
|
||||
# include <cppad/local/graph/cpp_graph_op.hpp>
|
||||
# include <cppad/utility/to_string.hpp>
|
||||
|
||||
/*
|
||||
$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
|
||||
244
build-config/cppad/include/cppad/local/hash_code.hpp
Normal file
244
build-config/cppad/include/cppad/local/hash_code.hpp
Normal file
@@ -0,0 +1,244 @@
|
||||
# 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 <cppad/core/base_hash.hpp>
|
||||
/*!
|
||||
\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<unsigned short>::max() >= CPPAD_HASH_TABLE_SIZE
|
||||
\li sizeof(value) is even
|
||||
\li sizeof(unsigned short) == 2
|
||||
*/
|
||||
template <class Value>
|
||||
unsigned short local_hash_code(const Value& value)
|
||||
{ CPPAD_ASSERT_UNKNOWN(
|
||||
std::numeric_limits<unsigned short>::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<const unsigned short*>(& value);
|
||||
//
|
||||
size_t i = sizeof(value) / 2 - 1;
|
||||
//
|
||||
size_t sum = v[i];
|
||||
//
|
||||
while(i--)
|
||||
sum += v[i];
|
||||
//
|
||||
unsigned short code = static_cast<unsigned short>(
|
||||
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<unsigned short>::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 <class Base>
|
||||
unsigned short local_hash_code(
|
||||
OpCode op ,
|
||||
const addr_t* arg ,
|
||||
size_t npar ,
|
||||
const Base* par )
|
||||
{ CPPAD_ASSERT_UNKNOWN(
|
||||
std::numeric_limits<unsigned short>::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<unsigned short> (
|
||||
CPPAD_HASH_TABLE_SIZE / static_cast<unsigned short>(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<unsigned short>(
|
||||
static_cast<unsigned short>(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<const unsigned short*>(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<const unsigned short*>(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<const unsigned short*>(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<const unsigned short*>(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
|
||||
119
build-config/cppad/include/cppad/local/independent.hpp
Normal file
119
build-config/cppad/include/cppad/local/independent.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
# 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<Base> operations.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Start recording AD<Base> operations: Implementation in local namespace.
|
||||
|
||||
\tparam ADVector
|
||||
This is simple vector type with elements of type AD<Base>.
|
||||
|
||||
\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 <class Base>
|
||||
template <class ADVector>
|
||||
void ADTape<Base>::Independent(
|
||||
ADVector& x ,
|
||||
size_t abort_op_index ,
|
||||
bool record_compare ,
|
||||
ADVector& dynamic
|
||||
) {
|
||||
// check ADVector is Simple Vector class with AD<Base> elements
|
||||
CheckSimpleVector< AD<Base>, 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<Base>::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<addr_t>(j+1);
|
||||
dynamic[j].tape_id_ = id_;
|
||||
dynamic[j].ad_type_ = dynamic_enum;
|
||||
CPPAD_ASSERT_UNKNOWN( Dynamic( dynamic[j] ) );
|
||||
}
|
||||
}
|
||||
} } // END_CPPAD_LOCAL_NAMESPACE
|
||||
|
||||
# endif
|
||||
79
build-config/cppad/include/cppad/local/is_pod.hpp
Normal file
79
build-config/cppad/include/cppad/local/is_pod.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
# 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 <class T> inline bool is_pod(void) { return false; }
|
||||
// bool
|
||||
template <> inline bool is_pod<bool>(void) {return true;}
|
||||
// short
|
||||
template <> inline bool is_pod<short int>(void) {return true;}
|
||||
template <> inline bool is_pod<unsigned short int>(void) {return true;}
|
||||
// int
|
||||
template <> inline bool is_pod<int>(void) {return true;}
|
||||
template <> inline bool is_pod<unsigned int>(void) {return true;}
|
||||
// long
|
||||
template <> inline bool is_pod<long int>(void) {return true;}
|
||||
template <> inline bool is_pod<unsigned long int>(void) {return true;}
|
||||
// long long
|
||||
template <> inline bool is_pod<long long int>(void) {return true;}
|
||||
template <> inline bool is_pod<unsigned long long int>(void) {return true;}
|
||||
// Character types
|
||||
template <> inline bool is_pod<char>(void) {return true;}
|
||||
template <> inline bool is_pod<signed char>(void) {return true;}
|
||||
template <> inline bool is_pod<unsigned char>(void) {return true;}
|
||||
template <> inline bool is_pod<wchar_t>(void) {return true;}
|
||||
template <> inline bool is_pod<char16_t>(void) {return true;}
|
||||
template <> inline bool is_pod<char32_t>(void) {return true;}
|
||||
// floating point types
|
||||
template <> inline bool is_pod<float>(void) {return true;}
|
||||
template <> inline bool is_pod<double>(void) {return true;}
|
||||
template <> inline bool is_pod<long double>(void) {return true;}
|
||||
|
||||
} } // END_CPPAD_LOCAL_NAMESPACE
|
||||
|
||||
# endif
|
||||
41
build-config/cppad/include/cppad/local/is_pod.hpp.in
Normal file
41
build-config/cppad/include/cppad/local/is_pod.hpp.in
Normal file
@@ -0,0 +1,41 @@
|
||||
# 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 <cstddef>
|
||||
|
||||
/*!
|
||||
\file is_pod.hpp
|
||||
File that defines is_pod<Type>(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 <class T> 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
|
||||
697
build-config/cppad/include/cppad/local/load_op.hpp
Normal file
697
build-config/cppad/include/cppad/local/load_op.hpp
Normal file
@@ -0,0 +1,697 @@
|
||||
# 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<Base> 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 <class Addr, class Base>
|
||||
void forward_load_p_op_0(
|
||||
const local::player<Base>* 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<addr_t>::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 <class Addr, class Base>
|
||||
void forward_load_v_op_0(
|
||||
const local::player<Base>* 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<addr_t>::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).
|
||||
|
||||
<!-- replace preamble -->
|
||||
The C++ source code corresponding to this operation is
|
||||
\verbatim
|
||||
v[x] = y
|
||||
\endverbatim
|
||||
where v is a VecAD<Base> vector, x is an AD<Base> object,
|
||||
and y is AD<Base> 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:
|
||||
<!-- end preamble -->
|
||||
|
||||
\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 <class Vector_set, class Addr>
|
||||
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
|
||||
|
||||
|
||||
<!-- replace preamble -->
|
||||
The C++ source code corresponding to this operation is
|
||||
\verbatim
|
||||
v[x] = y
|
||||
\endverbatim
|
||||
where v is a VecAD<Base> vector, x is an AD<Base> object,
|
||||
and y is AD<Base> 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:
|
||||
<!-- end preamble -->
|
||||
|
||||
\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
|
||||
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
|
||||
<code>tpv = (cap_order-1) * r + 1</code>
|
||||
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 <code>i_var > 0</code>, v[x] is a variable and
|
||||
for k = 1 , ... , q
|
||||
<code>taylor[ i_var * tpv + (k-1)*r+1+ell ]</code>
|
||||
is the k-th order coefficient for v[x] in the ell-th direction,
|
||||
\n
|
||||
\n
|
||||
Output
|
||||
\n
|
||||
for k = p , ... , q,
|
||||
<code>taylor[ i_z * tpv + (k-1)*r+1+ell ]</code>
|
||||
is set to the k-order Taylor coefficient for z in the ell-th direction.
|
||||
*/
|
||||
template <class Addr, class Base>
|
||||
void forward_load_op(
|
||||
const local::player<Base>* 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.
|
||||
|
||||
<!-- replace preamble -->
|
||||
The C++ source code corresponding to this operation is
|
||||
\verbatim
|
||||
v[x] = y
|
||||
\endverbatim
|
||||
where v is a VecAD<Base> vector, x is an AD<Base> object,
|
||||
and y is AD<Base> 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:
|
||||
<!-- end preamble -->
|
||||
|
||||
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 <class Addr, class Base>
|
||||
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 <class Vector_set, class Addr>
|
||||
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 <class Vector_set, class Addr>
|
||||
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 <class Vector_set, class Addr>
|
||||
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
|
||||
203
build-config/cppad/include/cppad/local/log1p_op.hpp
Normal file
203
build-config/cppad/include/cppad/local/log1p_op.hpp
Normal file
@@ -0,0 +1,203 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
202
build-config/cppad/include/cppad/local/log_op.hpp
Normal file
202
build-config/cppad/include/cppad/local/log_op.hpp
Normal file
@@ -0,0 +1,202 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
359
build-config/cppad/include/cppad/local/mul_op.hpp
Normal file
359
build-config/cppad/include/cppad/local/mul_op.hpp
Normal file
@@ -0,0 +1,359 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
59
build-config/cppad/include/cppad/local/op.hpp
Normal file
59
build-config/cppad/include/cppad/local/op.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
# 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 <cppad/local/sparse/internal.hpp>
|
||||
|
||||
// operations
|
||||
# include <cppad/core/std_math_11.hpp>
|
||||
# include <cppad/local/abs_op.hpp>
|
||||
# include <cppad/local/add_op.hpp>
|
||||
# include <cppad/local/acos_op.hpp>
|
||||
# include <cppad/local/acosh_op.hpp>
|
||||
# include <cppad/local/asin_op.hpp>
|
||||
# include <cppad/local/asinh_op.hpp>
|
||||
# include <cppad/local/atan_op.hpp>
|
||||
# include <cppad/local/atanh_op.hpp>
|
||||
# include <cppad/local/comp_op.hpp>
|
||||
# include <cppad/local/cond_op.hpp>
|
||||
# include <cppad/local/cos_op.hpp>
|
||||
# include <cppad/local/cosh_op.hpp>
|
||||
# include <cppad/local/cskip_op.hpp>
|
||||
# include <cppad/local/csum_op.hpp>
|
||||
# include <cppad/local/discrete_op.hpp>
|
||||
# include <cppad/local/div_op.hpp>
|
||||
# include <cppad/local/erf_op.hpp>
|
||||
# include <cppad/local/exp_op.hpp>
|
||||
# include <cppad/local/expm1_op.hpp>
|
||||
# include <cppad/local/load_op.hpp>
|
||||
# include <cppad/local/log_op.hpp>
|
||||
# include <cppad/local/log1p_op.hpp>
|
||||
# include <cppad/local/mul_op.hpp>
|
||||
# include <cppad/local/parameter_op.hpp>
|
||||
# include <cppad/local/pow_op.hpp>
|
||||
# include <cppad/local/print_op.hpp>
|
||||
# include <cppad/local/sign_op.hpp>
|
||||
# include <cppad/local/sin_op.hpp>
|
||||
# include <cppad/local/sinh_op.hpp>
|
||||
# include <cppad/local/sqrt_op.hpp>
|
||||
# include <cppad/local/sub_op.hpp>
|
||||
# include <cppad/local/sparse/binary_op.hpp>
|
||||
# include <cppad/local/sparse/unary_op.hpp>
|
||||
# include <cppad/local/store_op.hpp>
|
||||
# include <cppad/local/tan_op.hpp>
|
||||
# include <cppad/local/tanh_op.hpp>
|
||||
# include <cppad/local/zmul_op.hpp>
|
||||
|
||||
|
||||
# endif
|
||||
439
build-config/cppad/include/cppad/local/op_code_dyn.hpp
Normal file
439
build-config/cppad/include/cppad/local/op_code_dyn.hpp
Normal file
@@ -0,0 +1,439 @@
|
||||
# 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
|
||||
1512
build-config/cppad/include/cppad/local/op_code_var.hpp
Normal file
1512
build-config/cppad/include/cppad/local/op_code_var.hpp
Normal file
File diff suppressed because it is too large
Load Diff
123
build-config/cppad/include/cppad/local/optimize/cexp_info.hpp
Normal file
123
build-config/cppad/include/cppad/local/optimize/cexp_info.hpp
Normal file
@@ -0,0 +1,123 @@
|
||||
# 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 <cppad/local/declare_ad.hpp> // defines CompareOp
|
||||
# include <cppad/utility/vector.hpp>
|
||||
|
||||
/*!
|
||||
$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<optimize::struct_cskip_new>(void)
|
||||
{ return true; }
|
||||
} }
|
||||
|
||||
# endif
|
||||
@@ -0,0 +1,42 @@
|
||||
# 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 <cppad/local/op_code_var.hpp>
|
||||
# include <cppad/local/declare_ad.hpp> // 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
|
||||
@@ -0,0 +1,47 @@
|
||||
# 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 <stack>
|
||||
# include <cppad/local/optimize/csum_op_info.hpp>
|
||||
|
||||
/*!
|
||||
\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<struct struct_csum_op_info> op_info;
|
||||
|
||||
/// old variable indices to be added
|
||||
std::stack<addr_t> add_var;
|
||||
|
||||
/// old variable indices to be subtracted
|
||||
std::stack<addr_t> sub_var;
|
||||
|
||||
/// dynamic parameter indices to be added
|
||||
std::stack<addr_t> add_dyn;
|
||||
|
||||
/// dynamic parameter indices to be subtracted
|
||||
std::stack<addr_t> sub_dyn;
|
||||
};
|
||||
|
||||
} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE
|
||||
|
||||
# endif
|
||||
@@ -0,0 +1,260 @@
|
||||
# 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 <cppad/local/optimize/match_op.hpp>
|
||||
# include <cppad/local/optimize/cexp_info.hpp>
|
||||
# include <cppad/local/optimize/usage.hpp>
|
||||
|
||||
// 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<Base> 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 <class Addr, class Base>
|
||||
void get_cexp_info(
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<addr_t>& op_previous ,
|
||||
const pod_vector<usage_t>& op_usage ,
|
||||
const pod_vector<addr_t>& cexp2op ,
|
||||
const sparse::list_setvec& cexp_set ,
|
||||
vector<struct_cexp_info>& 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<addr_t>::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<unsigned char>(arg[1]);
|
||||
info.left = arg[2];
|
||||
info.right = arg[3];
|
||||
//
|
||||
// max_left_right
|
||||
addr_t index = 0;
|
||||
if( arg[1] & 1 )
|
||||
index = std::max<addr_t>(index, info.left);
|
||||
if( arg[1] & 2 )
|
||||
index = std::max<addr_t>(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
|
||||
@@ -0,0 +1,447 @@
|
||||
# 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 <cppad/local/optimize/match_op.hpp>
|
||||
# include <cppad/local/optimize/usage.hpp>
|
||||
# include <cppad/local/optimize/hash_code.hpp>
|
||||
|
||||
// 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<addr_t>& dyn_ind2par_ind ,
|
||||
const pod_vector<bool> & dyn_par_is ,
|
||||
const pod_vector<addr_t>& dyn_arg_offset ,
|
||||
const pod_vector<addr_t>& dyn_par_arg ,
|
||||
const pod_vector<addr_t>& par_ind2dyn_ind ,
|
||||
const pod_vector<addr_t>& dyn_previous ,
|
||||
pod_vector<addr_t>& 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 <class Addr, class Base>
|
||||
void get_dyn_previous(
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
pod_vector<bool>& par_usage ,
|
||||
pod_vector<addr_t>& 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<addr_t>& dyn_ind2par_ind( play->dyn_ind2par_ind() );
|
||||
const pod_vector<bool>& dyn_par_is( play->dyn_par_is() );
|
||||
const pod_vector<opcode_t>& dyn_par_op( play->dyn_par_op() );
|
||||
const pod_vector<addr_t>& 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<addr_t> par_ind2dyn_ind(num_par);
|
||||
|
||||
// mapping from dynamic parameter index to first argument index
|
||||
pod_vector<addr_t> 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<addr_t> 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
|
||||
@@ -0,0 +1,269 @@
|
||||
# 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 <cppad/local/optimize/match_op.hpp>
|
||||
# include <cppad/local/optimize/usage.hpp>
|
||||
|
||||
// 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<Base> 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 <class Addr, class Base>
|
||||
bool get_op_previous(
|
||||
size_t collision_limit ,
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
sparse::list_setvec& cexp_set ,
|
||||
pod_vector<addr_t>& op_previous ,
|
||||
pod_vector<usage_t>& 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<addr_t>::max)() ) >= num_op
|
||||
);
|
||||
// ----------------------------------------------------------------------
|
||||
// compute op_previous
|
||||
// ----------------------------------------------------------------------
|
||||
sparse::list_setvec hash_table_op;
|
||||
hash_table_op.resize(CPPAD_HASH_TABLE_SIZE, num_op);
|
||||
//
|
||||
pod_vector<bool> work_bool;
|
||||
pod_vector<addr_t> 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<size_t> 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
|
||||
853
build-config/cppad/include/cppad/local/optimize/get_op_usage.hpp
Normal file
853
build-config/cppad/include/cppad/local/optimize/get_op_usage.hpp
Normal file
@@ -0,0 +1,853 @@
|
||||
# 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 <cppad/local/optimize/cexp_info.hpp>
|
||||
# include <cppad/local/optimize/usage.hpp>
|
||||
# include <cppad/local/sweep/call_atomic.hpp>
|
||||
|
||||
// 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 <class Base>
|
||||
void op_inc_arg_usage(
|
||||
const player<Base>* play ,
|
||||
bool check_csum ,
|
||||
size_t i_result ,
|
||||
size_t i_arg ,
|
||||
pod_vector<usage_t>& 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 <class Addr, class Base>
|
||||
void get_op_usage(
|
||||
bool conditional_skip ,
|
||||
bool compare_op ,
|
||||
bool print_for_op ,
|
||||
bool cumulative_sum_op ,
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<size_t>& dep_taddr ,
|
||||
pod_vector<addr_t>& cexp2op ,
|
||||
sparse::list_setvec& cexp_set ,
|
||||
pod_vector<bool>& vecad_used ,
|
||||
pod_vector<usage_t>& 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<addr_t>::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<Base> atom_x; // value of parameters in x
|
||||
vector<ad_type_enum> type_x; // type for each argument
|
||||
vector<size_t> atom_ix; // variables indices for argument vector
|
||||
vector<bool> depend_y; // results that are used
|
||||
vector<bool> 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<size_t> 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<Base, Base>(
|
||||
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<Base>::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
|
||||
@@ -0,0 +1,506 @@
|
||||
# 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 <cppad/local/optimize/get_op_usage.hpp>
|
||||
|
||||
// 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 <class Addr, class Base>
|
||||
void get_par_usage(
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<usage_t>& op_usage ,
|
||||
pod_vector<bool>& vecad_used ,
|
||||
pod_vector<bool>& 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<bool>& dyn_par_is( play->dyn_par_is() );
|
||||
const pod_vector<opcode_t>& dyn_par_op( play->dyn_par_op() );
|
||||
const pod_vector<addr_t>& dyn_par_arg( play->dyn_par_arg() );
|
||||
const pod_vector<addr_t>& dyn_ind2par_ind( play->dyn_ind2par_ind() );
|
||||
const pod_vector_maybe<Base>& 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<Base> parameter_x; // value of parameters in x
|
||||
vector<ad_type_enum> type_x; // type for each component of z
|
||||
vector<size_t> atom_ix; // variables indices for argument vector
|
||||
vector<bool> depend_y; // results that are used
|
||||
vector<bool> 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<Base, Base>(
|
||||
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<Base, Base>(
|
||||
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
|
||||
@@ -0,0 +1,57 @@
|
||||
# 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
|
||||
292
build-config/cppad/include/cppad/local/optimize/match_op.hpp
Normal file
292
build-config/cppad/include/cppad/local/optimize/match_op.hpp
Normal file
@@ -0,0 +1,292 @@
|
||||
# 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 <cppad/local/optimize/hash_code.hpp>
|
||||
// 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 <class Addr>
|
||||
bool match_op(
|
||||
size_t collision_limit ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
pod_vector<addr_t>& op_previous ,
|
||||
size_t current ,
|
||||
sparse::list_setvec& hash_table_op ,
|
||||
pod_vector<bool>& work_bool ,
|
||||
pod_vector<addr_t>& 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<bool>& variable(work_bool);
|
||||
//
|
||||
// var2previous_var is a reference to, and better name for, work_addr_t
|
||||
pod_vector<addr_t>& 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<addr_t>::max(),
|
||||
std::numeric_limits<addr_t>::max(),
|
||||
std::numeric_limits<addr_t>::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<addr_t>( 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
|
||||
1351
build-config/cppad/include/cppad/local/optimize/optimize_run.hpp
Normal file
1351
build-config/cppad/include/cppad/local/optimize/optimize_run.hpp
Normal file
File diff suppressed because it is too large
Load Diff
386
build-config/cppad/include/cppad/local/optimize/record_csum.hpp
Normal file
386
build-config/cppad/include/cppad/local/optimize/record_csum.hpp
Normal file
@@ -0,0 +1,386 @@
|
||||
# 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 <class Addr, class Base>
|
||||
struct_size_pair record_csum(
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<usage_t>& op_usage ,
|
||||
const pod_vector<addr_t>& new_par ,
|
||||
const pod_vector<addr_t>& new_var ,
|
||||
size_t current ,
|
||||
recorder<Base>* 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<bool>& 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
|
||||
102
build-config/cppad/include/cppad/local/optimize/record_pv.hpp
Normal file
102
build-config/cppad/include/cppad/local/optimize/record_pv.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
# 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 <class Addr, class Base>
|
||||
struct_size_pair record_pv(
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<addr_t>& new_par ,
|
||||
const pod_vector<addr_t>& new_var ,
|
||||
size_t i_op ,
|
||||
recorder<Base>* 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
|
||||
101
build-config/cppad/include/cppad/local/optimize/record_vp.hpp
Normal file
101
build-config/cppad/include/cppad/local/optimize/record_vp.hpp
Normal file
@@ -0,0 +1,101 @@
|
||||
# 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 <class Addr, class Base>
|
||||
struct_size_pair record_vp(
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<addr_t>& new_par ,
|
||||
const pod_vector<addr_t>& new_var ,
|
||||
size_t i_op ,
|
||||
recorder<Base>* 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
|
||||
@@ -0,0 +1,91 @@
|
||||
# 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 <class Addr, class Base>
|
||||
struct_size_pair record_vv(
|
||||
const player<Base>* play ,
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<addr_t>& new_var ,
|
||||
size_t i_op ,
|
||||
recorder<Base>* 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
|
||||
@@ -0,0 +1,32 @@
|
||||
# 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
|
||||
39
build-config/cppad/include/cppad/local/optimize/usage.hpp
Normal file
39
build-config/cppad/include/cppad/local/optimize/usage.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
# 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 <cppad/local/define.hpp>
|
||||
|
||||
// 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
|
||||
89
build-config/cppad/include/cppad/local/parameter_op.hpp
Normal file
89
build-config/cppad/include/cppad/local/parameter_op.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
# 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<Base> 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 <class Base>
|
||||
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
|
||||
30
build-config/cppad/include/cppad/local/play/addr_enum.hpp
Normal file
30
build-config/cppad/include/cppad/local/play/addr_enum.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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
|
||||
89
build-config/cppad/include/cppad/local/play/atom_op_info.hpp
Normal file
89
build-config/cppad/include/cppad/local/play/atom_op_info.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
# 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 <class Base>
|
||||
atomic_base<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<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<Base>(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<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<Base>* >( v_ptr );
|
||||
return atom_fun;
|
||||
}
|
||||
|
||||
} } } // END_CPPAD_LOCAL_PLAY_NAMESPACE
|
||||
|
||||
# endif
|
||||
853
build-config/cppad/include/cppad/local/play/player.hpp
Normal file
853
build-config/cppad/include/cppad/local/play/player.hpp
Normal file
@@ -0,0 +1,853 @@
|
||||
# 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 <cppad/local/play/addr_enum.hpp>
|
||||
# include <cppad/local/play/sequential_iterator.hpp>
|
||||
# include <cppad/local/play/subgraph_iterator.hpp>
|
||||
# include <cppad/local/play/random_setup.hpp>
|
||||
# include <cppad/local/atom_state.hpp>
|
||||
# include <cppad/local/is_pod.hpp>
|
||||
|
||||
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 Base>
|
||||
class player {
|
||||
// player<Base> must be a friend of player< AD<Base> > for base2ad to work
|
||||
template <class AnotherBase> 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<opcode_t> op_vec_;
|
||||
|
||||
/// The operation argument indices in the recording
|
||||
pod_vector<addr_t> arg_vec_;
|
||||
|
||||
/// Character strings ('\\0' terminated) in the recording.
|
||||
pod_vector<char> text_vec_;
|
||||
|
||||
/// The VecAD indices in the recording.
|
||||
pod_vector<addr_t> 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<Base> all_par_vec_;
|
||||
|
||||
/// Which elements of all_par_vec_ are dynamic parameters
|
||||
/// (size equal number of parametrers)
|
||||
pod_vector<bool> 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<addr_t> dyn_ind2par_ind_;
|
||||
|
||||
/// operators for just the dynamic parameters
|
||||
/// (size equal number of dynamic parameters)
|
||||
pod_vector<opcode_t> dyn_par_op_;
|
||||
|
||||
/// arguments for the dynamic parameter operators
|
||||
pod_vector<addr_t> 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<unsigned char> 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<unsigned char> 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<unsigned char> 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<unsigned short>::max() )
|
||||
return play::unsigned_short_enum;
|
||||
//
|
||||
// unsigned int
|
||||
if( required <= std::numeric_limits<unsigned int>::max() )
|
||||
return play::unsigned_int_enum;
|
||||
//
|
||||
// unsigned size_t
|
||||
CPPAD_ASSERT_UNKNOWN(
|
||||
required <= std::numeric_limits<size_t>::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<Base>& rec, size_t n_ind)
|
||||
{
|
||||
# ifndef NDEBUG
|
||||
size_t addr_t_max = size_t( std::numeric_limits<addr_t>::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<Base> to another player<Base>
|
||||
|
||||
\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<Base> > from this player<Base>
|
||||
player< AD<Base> > base2ad(void) const
|
||||
{ player< AD<Base> > 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<Base> > = pod_maybe_vector<Base>
|
||||
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 <class Addr>
|
||||
void setup_random(void)
|
||||
{ play::random_setup(
|
||||
num_var_rec_ ,
|
||||
op_vec_ ,
|
||||
arg_vec_ ,
|
||||
op2arg_vec_.pod_vector_ptr<Addr>() ,
|
||||
op2var_vec_.pod_vector_ptr<Addr>() ,
|
||||
var2op_vec_.pod_vector_ptr<Addr>()
|
||||
);
|
||||
}
|
||||
/// 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<Base>& all_par_vec(void)
|
||||
{ return all_par_vec_; }
|
||||
/// get non-const version of all_par_vec
|
||||
const pod_vector_maybe<Base>& 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<bool>& dyn_par_is(void) const
|
||||
{ return dyn_par_is_; }
|
||||
/// const version of dynamic parameter index to parameter index
|
||||
const pod_vector<addr_t>& dyn_ind2par_ind(void) const
|
||||
{ return dyn_ind2par_ind_; }
|
||||
/// const version of dynamic parameter operator
|
||||
const pod_vector<opcode_t>& dyn_par_op(void) const
|
||||
{ return dyn_par_op_; }
|
||||
/// const version of dynamic parameter arguments
|
||||
const pod_vector<addr_t>& 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<Base>::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<addr_t> begin_subgraph(
|
||||
const play::const_random_iterator<addr_t>& random_itr ,
|
||||
const pod_vector<addr_t>* subgraph ) const
|
||||
{ size_t subgraph_index = 0;
|
||||
return play::const_subgraph_iterator<addr_t>(
|
||||
random_itr,
|
||||
subgraph,
|
||||
subgraph_index
|
||||
);
|
||||
}
|
||||
/// const subgraph iterator end
|
||||
template <class Addr>
|
||||
play::const_subgraph_iterator<Addr> end_subgraph(
|
||||
const play::const_random_iterator<Addr>& random_itr ,
|
||||
const pod_vector<addr_t>* subgraph ) const
|
||||
{ size_t subgraph_index = subgraph->size() - 1;
|
||||
return play::const_subgraph_iterator<Addr>(
|
||||
random_itr,
|
||||
subgraph,
|
||||
subgraph_index
|
||||
);
|
||||
}
|
||||
// -----------------------------------------------------------------------
|
||||
/// const random iterator
|
||||
template <class Addr>
|
||||
play::const_random_iterator<Addr> get_random(void) const
|
||||
{ return play::const_random_iterator<Addr>(
|
||||
op_vec_,
|
||||
arg_vec_,
|
||||
op2arg_vec_.pod_vector_ptr<Addr>(),
|
||||
op2var_vec_.pod_vector_ptr<Addr>(),
|
||||
var2op_vec_.pod_vector_ptr<Addr>()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
} } // END_CPPAD_lOCAL_NAMESPACE
|
||||
# endif
|
||||
152
build-config/cppad/include/cppad/local/play/random_iterator.hpp
Normal file
152
build-config/cppad/include/cppad/local/play/random_iterator.hpp
Normal file
@@ -0,0 +1,152 @@
|
||||
# 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 Addr>
|
||||
class const_random_iterator {
|
||||
private:
|
||||
/// vector of operators on the tape
|
||||
const pod_vector<opcode_t>* 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<addr_t>* arg_vec_;
|
||||
|
||||
/// mapping from operator index to index of first argument in arg_vec_
|
||||
const pod_vector<Addr>* op2arg_vec_;
|
||||
|
||||
/// mapping from operator index to index of primary (last) result
|
||||
const pod_vector<Addr>* op2var_vec_;
|
||||
|
||||
/// mapping from primary variable index to operator index
|
||||
/// (only specified for primary variables)
|
||||
const pod_vector<Addr>* 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<opcode_t>& op_vec , ///< op_vec_
|
||||
const pod_vector<addr_t>& arg_vec , ///< arg_vec_
|
||||
const pod_vector<Addr>* op2arg_vec , ///< op2ar_vec_
|
||||
const pod_vector<Addr>* op2var_vec , ///< op2var_vec_
|
||||
const pod_vector<Addr>* 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
|
||||
144
build-config/cppad/include/cppad/local/play/random_setup.hpp
Normal file
144
build-config/cppad/include/cppad/local/play/random_setup.hpp
Normal file
@@ -0,0 +1,144 @@
|
||||
# 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
|
||||
<code>op = OpCode[ op_vec[op_index] ]</code>
|
||||
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 <class Addr>
|
||||
void random_setup(
|
||||
size_t num_var ,
|
||||
const pod_vector<opcode_t>& op_vec ,
|
||||
const pod_vector<addr_t>& arg_vec ,
|
||||
pod_vector<Addr>* op2arg_vec ,
|
||||
pod_vector<Addr>* op2var_vec ,
|
||||
pod_vector<Addr>* 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
|
||||
@@ -0,0 +1,290 @@
|
||||
# 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<opcode_t>* op_vec ,
|
||||
const pod_vector<addr_t>* 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
|
||||
@@ -0,0 +1,132 @@
|
||||
# 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 <cppad/local/play/random_iterator.hpp>
|
||||
|
||||
// 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 Addr>
|
||||
class const_subgraph_iterator {
|
||||
private:
|
||||
/// a random iterator used to access player information
|
||||
const const_random_iterator<Addr>* random_itr_;
|
||||
|
||||
/// sorted subset of operator indices that we will include
|
||||
const pod_vector<addr_t>* 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<Addr>& random_itr , ///< random_itr_
|
||||
const pod_vector<addr_t>* 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<Addr>& 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<Addr>& 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
|
||||
565
build-config/cppad/include/cppad/local/pod_vector.hpp
Normal file
565
build-config/cppad/include/cppad/local/pod_vector.hpp
Normal file
@@ -0,0 +1,565 @@
|
||||
# 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 <cstdint>
|
||||
# endif
|
||||
# include <cstring>
|
||||
# include <algorithm>
|
||||
# include <cppad/utility/thread_alloc.hpp>
|
||||
# include <cppad/core/cppad_assert.hpp>
|
||||
# include <cppad/local/is_pod.hpp>
|
||||
|
||||
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<Type> must be true).
|
||||
|
||||
*/
|
||||
template <class Type>
|
||||
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<Type>() );
|
||||
}
|
||||
|
||||
/// 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<Type>() );
|
||||
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<void*>( 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 <class Other>
|
||||
pod_vector<Other>* pod_vector_ptr(void)
|
||||
{ return reinterpret_cast< pod_vector<Other>* >(this);
|
||||
}
|
||||
template <class Other>
|
||||
const pod_vector<Other>* pod_vector_ptr(void) const
|
||||
{ return reinterpret_cast< const pod_vector<Other>* >(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 <class Index>
|
||||
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 <class Index>
|
||||
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<void*>(data_);
|
||||
|
||||
// get new memory and set capacity
|
||||
void* v_ptr = thread_alloc::get_memory(byte_length_, byte_capacity_);
|
||||
data_ = reinterpret_cast<Type*>(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<void*>( 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<Type*>(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<void*>( 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<void*>( data_ );
|
||||
void* v_ptr_x = reinterpret_cast<void*>( 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<Type> is true.
|
||||
*/
|
||||
template <class Type>
|
||||
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<size_t>() );
|
||||
}
|
||||
|
||||
/// 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<Type>() )
|
||||
{ // call destructor for each element
|
||||
for(size_t i = 0; i < capacity_; i++)
|
||||
(data_ + i)->~Type();
|
||||
}
|
||||
void* v_ptr = reinterpret_cast<void*>( 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 <class Index>
|
||||
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 <class Index>
|
||||
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<Type*>(v_ptr);
|
||||
|
||||
if( ! is_pod<Type>() )
|
||||
{ // 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<Type>() )
|
||||
{ for(size_t i = 0; i < old_capacity; i++)
|
||||
(old_data + i)->~Type();
|
||||
}
|
||||
v_ptr = reinterpret_cast<void*>( 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<Type>() )
|
||||
{ // call destructor for each old element
|
||||
for(size_t i = 0; i < capacity_; i++)
|
||||
(data_ + i)->~Type();
|
||||
}
|
||||
v_ptr = reinterpret_cast<void*>( 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<Type*>(v_ptr);
|
||||
//
|
||||
CPPAD_ASSERT_UNKNOWN( length_ <= capacity_ );
|
||||
//
|
||||
if( ! is_pod<Type>() )
|
||||
{ // 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<Type>() )
|
||||
{ // call destructor for each element
|
||||
for(size_t i = 0; i < capacity_; i++)
|
||||
(data_ + i)->~Type();
|
||||
}
|
||||
void* v_ptr = reinterpret_cast<void*>( 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
|
||||
672
build-config/cppad/include/cppad/local/pow_op.hpp
Normal file
672
build-config/cppad/include/cppad/local/pow_op.hpp
Normal file
@@ -0,0 +1,672 @@
|
||||
# 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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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<addr_t>::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 <class Base>
|
||||
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 <class Base>
|
||||
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<addr_t>::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
|
||||
147
build-config/cppad/include/cppad/local/print_op.hpp
Normal file
147
build-config/cppad/include/cppad/local/print_op.hpp
Normal file
@@ -0,0 +1,147 @@
|
||||
# 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, <code>parameter[arg[1]]</code> is its value.
|
||||
Othwise <code>taylor[ size_t(arg[1]) * cap_order + 0 ]</code> 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, <code>parameter[arg[3]]</code> is its value.
|
||||
Othwise <code>taylor[ size_t(arg[3]) * cap_order + 0 ]</code> 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: <code>text[arg[1]]</code> 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 <class Base>
|
||||
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
|
||||
1458
build-config/cppad/include/cppad/local/prototype_op.hpp
Normal file
1458
build-config/cppad/include/cppad/local/prototype_op.hpp
Normal file
File diff suppressed because it is too large
Load Diff
287
build-config/cppad/include/cppad/local/record/comp_op.hpp
Normal file
287
build-config/cppad/include/cppad/local/record/comp_op.hpp
Normal file
@@ -0,0 +1,287 @@
|
||||
# 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 <cppad/local/record/recorder.hpp>
|
||||
|
||||
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 <class Base>
|
||||
void recorder<Base>::comp_eq(
|
||||
bool var_left ,
|
||||
bool var_right ,
|
||||
bool dyn_left ,
|
||||
bool dyn_right ,
|
||||
const AD<Base>& aleft ,
|
||||
const AD<Base>& 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 <class Base>
|
||||
void recorder<Base>::comp_le(
|
||||
bool var_left ,
|
||||
bool var_right ,
|
||||
bool dyn_left ,
|
||||
bool dyn_right ,
|
||||
const AD<Base>& aleft ,
|
||||
const AD<Base>& 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 <class Base>
|
||||
void recorder<Base>::comp_lt(
|
||||
bool var_left ,
|
||||
bool var_right ,
|
||||
bool dyn_left ,
|
||||
bool dyn_right ,
|
||||
const AD<Base>& aleft ,
|
||||
const AD<Base>& 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
|
||||
176
build-config/cppad/include/cppad/local/record/cond_exp.hpp
Normal file
176
build-config/cppad/include/cppad/local/record/cond_exp.hpp
Normal file
@@ -0,0 +1,176 @@
|
||||
# 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 <cppad/local/record/recorder.hpp>
|
||||
|
||||
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 <class Base>
|
||||
void recorder<Base>::cond_exp(
|
||||
tape_id_t tape_id ,
|
||||
enum CompareOp cop ,
|
||||
AD<Base> &result ,
|
||||
const AD<Base> &left ,
|
||||
const AD<Base> &right ,
|
||||
const AD<Base> &if_true ,
|
||||
const AD<Base> &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
|
||||
169
build-config/cppad/include/cppad/local/record/put_dyn_atomic.hpp
Normal file
169
build-config/cppad/include/cppad/local/record/put_dyn_atomic.hpp
Normal file
@@ -0,0 +1,169 @@
|
||||
# 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 <cppad/local/record/recorder.hpp>
|
||||
|
||||
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 <class Base> template <class VectorAD>
|
||||
void recorder<Base>::put_dyn_atomic(
|
||||
tape_id_t tape_id ,
|
||||
size_t atomic_index ,
|
||||
const vector<ad_type_enum>& type_x ,
|
||||
const vector<ad_type_enum>& type_y ,
|
||||
const VectorAD& ax ,
|
||||
VectorAD& ay )
|
||||
// END_PROTOTYPE
|
||||
{ CPPAD_ASSERT_UNKNOWN(
|
||||
(tape_id == 0) == (AD<Base>::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
|
||||
150
build-config/cppad/include/cppad/local/record/put_var_atomic.hpp
Normal file
150
build-config/cppad/include/cppad/local/record/put_var_atomic.hpp
Normal file
@@ -0,0 +1,150 @@
|
||||
# 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 <cppad/local/record/recorder.hpp>
|
||||
|
||||
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 <class Base> template <class VectorAD>
|
||||
void recorder<Base>::put_var_atomic(
|
||||
tape_id_t tape_id ,
|
||||
size_t atomic_index ,
|
||||
const vector<ad_type_enum>& type_x ,
|
||||
const vector<ad_type_enum>& type_y ,
|
||||
const VectorAD& ax ,
|
||||
VectorAD& ay )
|
||||
// END_PROTOTYPE
|
||||
{ CPPAD_ASSERT_KNOWN(
|
||||
size_t( std::numeric_limits<addr_t>::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<Base>::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
|
||||
130
build-config/cppad/include/cppad/local/record/put_var_vecad.hpp
Normal file
130
build-config/cppad/include/cppad/local/record/put_var_vecad.hpp
Normal file
@@ -0,0 +1,130 @@
|
||||
# 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 <cppad/local/record/recorder.hpp>
|
||||
|
||||
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 <class Base>
|
||||
addr_t recorder<Base>::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<addr_t>( 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 <class Base>
|
||||
addr_t recorder<Base>::put_var_vecad(
|
||||
size_t length ,
|
||||
const pod_vector<addr_t>& 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<addr_t>::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
|
||||
848
build-config/cppad/include/cppad/local/record/recorder.hpp
Normal file
848
build-config/cppad/include/cppad/local/record/recorder.hpp
Normal file
@@ -0,0 +1,848 @@
|
||||
# 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 <cppad/core/hash_code.hpp>
|
||||
# include <cppad/local/pod_vector.hpp>
|
||||
# include <cppad/core/ad_type.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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 Base>
|
||||
class recorder {
|
||||
friend class player<Base>;
|
||||
|
||||
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<opcode_t> op_vec_;
|
||||
|
||||
/// The VecAD indices in the recording.
|
||||
pod_vector<addr_t> all_dyn_vecad_ind_;
|
||||
pod_vector<addr_t> all_var_vecad_ind_;
|
||||
|
||||
/// The argument indices in the recording
|
||||
pod_vector<addr_t> arg_vec_;
|
||||
|
||||
/// Character strings ('\\0' terminated) in the recording.
|
||||
pod_vector<char> text_vec_;
|
||||
|
||||
/// Hash table to reduced number of duplicate parameters in all_par_vec_
|
||||
pod_vector<addr_t> 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<Base> all_par_vec_;
|
||||
|
||||
/// Which elements of all_par_vec_ are dynamic parameters
|
||||
/// (same size are all_par_vec_)
|
||||
pod_vector<bool> dyn_par_is_;
|
||||
|
||||
/// operators for just the dynamic parameters in all_par_vec_
|
||||
pod_vector<opcode_t> dyn_par_op_;
|
||||
|
||||
/// arguments for the dynamic parameter operators
|
||||
pod_vector<addr_t> 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<void*>( 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<addr_t>& 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<addr_t>& 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 <class VectorAD>
|
||||
void put_dyn_atomic(
|
||||
tape_id_t tape_id ,
|
||||
size_t atom_index ,
|
||||
const vector<ad_type_enum>& type_x ,
|
||||
const vector<ad_type_enum>& type_y ,
|
||||
const VectorAD& ax ,
|
||||
VectorAD& ay
|
||||
);
|
||||
//
|
||||
// put_var_atomic
|
||||
template <class VectorAD>
|
||||
void put_var_atomic(
|
||||
tape_id_t tape_id ,
|
||||
size_t atom_index ,
|
||||
const vector<ad_type_enum>& type_x ,
|
||||
const vector<ad_type_enum>& 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<Base> &result ,
|
||||
const AD<Base> &left ,
|
||||
const AD<Base> &right ,
|
||||
const AD<Base> &if_true ,
|
||||
const AD<Base> &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<Base>& aleft ,
|
||||
const AD<Base>& aright ,
|
||||
bool result
|
||||
);
|
||||
void comp_le(
|
||||
bool var_left ,
|
||||
bool var_right ,
|
||||
bool dyn_left ,
|
||||
bool dyn_right ,
|
||||
const AD<Base>& aleft ,
|
||||
const AD<Base>& aright ,
|
||||
bool result
|
||||
);
|
||||
void comp_lt(
|
||||
bool var_left ,
|
||||
bool var_right ,
|
||||
bool dyn_left ,
|
||||
bool dyn_right ,
|
||||
const AD<Base>& aleft ,
|
||||
const AD<Base>& 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<Base>& 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 <class Base>
|
||||
addr_t recorder<Base>::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<opcode_t>(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<addr_t>::max() >= num_var_rec_ - 1,
|
||||
"cppad_tape_addr_type maximum value has been exceeded"
|
||||
)
|
||||
|
||||
return static_cast<addr_t>( 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 <code>num_var_load_rec()</code>
|
||||
increases by one after each call to this function.
|
||||
*/
|
||||
template <class Base>
|
||||
addr_t recorder<Base>::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<addr_t>::max() >= num_var_rec_ - 1,
|
||||
"cppad_tape_addr_type maximum value has been exceeded"
|
||||
)
|
||||
return static_cast<addr_t>( 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 <class Base>
|
||||
addr_t recorder<Base>::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<addr_t>( 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 <class Base>
|
||||
addr_t recorder<Base>::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<addr_t>( 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 <class Base>
|
||||
addr_t recorder<Base>::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<addr_t>( 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 <class Base>
|
||||
addr_t recorder<Base>::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 <class Base>
|
||||
void recorder<Base>::put_dyn_arg_vec(const pod_vector<addr_t>& 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 <class Base>
|
||||
addr_t recorder<Base>::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<size_t>( hash_code(par) );
|
||||
|
||||
// current index in all_par_vec_ corresponding to this hash code
|
||||
size_t index = static_cast<size_t>( 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<addr_t>( 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<addr_t>( index );
|
||||
//
|
||||
// return the parameter index
|
||||
CPPAD_ASSERT_KNOWN(
|
||||
static_cast<size_t>( std::numeric_limits<addr_t>::max() ) >= index,
|
||||
"cppad_tape_addr_type maximum value has been exceeded"
|
||||
)
|
||||
return static_cast<addr_t>( 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 <class Base>
|
||||
void recorder<Base>::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 <class Base>
|
||||
void recorder<Base>::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 <class Base>
|
||||
void recorder<Base>::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 <class Base>
|
||||
void recorder<Base>::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 <class Base>
|
||||
void recorder<Base>::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 <class Base>
|
||||
void recorder<Base>::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 <class Base>
|
||||
size_t recorder<Base>::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 <class Base>
|
||||
void recorder<Base>::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 <class Base>
|
||||
addr_t recorder<Base>::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<addr_t>::max() ) >= i,
|
||||
"cppad_tape_addr_type maximum value has been exceeded"
|
||||
);
|
||||
//
|
||||
return static_cast<addr_t>( i );
|
||||
}
|
||||
|
||||
} } // END_CPPAD_LOCAL_NAMESPACE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// member function implementations
|
||||
# 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>
|
||||
|
||||
# endif
|
||||
25
build-config/cppad/include/cppad/local/record/recorder.omh
Normal file
25
build-config/cppad/include/cppad/local/record/recorder.omh
Normal file
@@ -0,0 +1,25 @@
|
||||
-----------------------------------------------------------------------------
|
||||
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
|
||||
@@ -0,0 +1,66 @@
|
||||
# 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 <cassert>
|
||||
# include <cppad/configure.hpp>
|
||||
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
|
||||
153
build-config/cppad/include/cppad/local/sign_op.hpp
Normal file
153
build-config/cppad/include/cppad/local/sign_op.hpp
Normal file
@@ -0,0 +1,153 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
240
build-config/cppad/include/cppad/local/sin_op.hpp
Normal file
240
build-config/cppad/include/cppad/local/sin_op.hpp
Normal file
@@ -0,0 +1,240 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
239
build-config/cppad/include/cppad/local/sinh_op.hpp
Normal file
239
build-config/cppad/include/cppad/local/sinh_op.hpp
Normal file
@@ -0,0 +1,239 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
617
build-config/cppad/include/cppad/local/sparse/binary_op.hpp
Normal file
617
build-config/cppad/include/cppad/local/sparse/binary_op.hpp
Normal file
@@ -0,0 +1,617 @@
|
||||
# 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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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
|
||||
23
build-config/cppad/include/cppad/local/sparse/dev_sparse.omh
Normal file
23
build-config/cppad/include/cppad/local/sparse/dev_sparse.omh
Normal file
@@ -0,0 +1,23 @@
|
||||
-----------------------------------------------------------------------------
|
||||
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
|
||||
455
build-config/cppad/include/cppad/local/sparse/internal.hpp
Normal file
455
build-config/cppad/include/cppad/local/sparse/internal.hpp
Normal file
@@ -0,0 +1,455 @@
|
||||
# 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 <cppad/local/define.hpp>
|
||||
# include <cppad/local/sparse/pack_setvec.hpp>
|
||||
# include <cppad/local/sparse/list_setvec.hpp>
|
||||
# include <cppad/local/sparse/svec_setvec.hpp>
|
||||
|
||||
// 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 <code>internal_pattern<Element_type>::pattern_type</code>
|
||||
is the type of the corresponding internal sparsity pattern.
|
||||
*/
|
||||
template <class Element_type> struct internal_pattern;
|
||||
/// Specilization for bool elements.
|
||||
template <>
|
||||
struct internal_pattern<bool>
|
||||
{
|
||||
typedef sparse::pack_setvec pattern_type;
|
||||
};
|
||||
/// Specilization for <code>std::set<size_t></code> elements.
|
||||
template <>
|
||||
struct internal_pattern< std::set<size_t> >
|
||||
{
|
||||
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 <class SizeVector, class InternalSparsity>
|
||||
void set_internal_pattern(
|
||||
bool zero_empty ,
|
||||
bool input_empty ,
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& internal_index ,
|
||||
InternalSparsity& internal_pattern ,
|
||||
const sparse_rc<SizeVector>& 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 <class InternalSparsity>
|
||||
void set_internal_pattern(
|
||||
bool zero_empty ,
|
||||
bool input_empty ,
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& 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 <class InternalSparsity>
|
||||
void set_internal_pattern(
|
||||
bool zero_empty ,
|
||||
bool input_empty ,
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& internal_index ,
|
||||
InternalSparsity& internal_pattern ,
|
||||
const vector<bool>& 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 <class InternalSparsity>
|
||||
void set_internal_pattern(
|
||||
bool zero_empty ,
|
||||
bool input_empty ,
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& internal_index ,
|
||||
InternalSparsity& internal_pattern ,
|
||||
const vector< std::set<size_t> >& 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<size_t>::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<size_t>::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 <class SizeVector, class InternalSparsity>
|
||||
void get_internal_pattern(
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& internal_index ,
|
||||
const InternalSparsity& internal_pattern ,
|
||||
sparse_rc<SizeVector>& 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 <class InternalSparsity>
|
||||
void get_internal_pattern(
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& 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 <class InternalSparsity>
|
||||
void get_internal_pattern(
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& internal_index ,
|
||||
const InternalSparsity& internal_pattern ,
|
||||
vector<bool>& 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 <class InternalSparsity>
|
||||
void get_internal_pattern(
|
||||
bool transpose ,
|
||||
const pod_vector<size_t>& internal_index ,
|
||||
const InternalSparsity& internal_pattern ,
|
||||
vector< std::set<size_t> >& 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
|
||||
1721
build-config/cppad/include/cppad/local/sparse/list_setvec.hpp
Normal file
1721
build-config/cppad/include/cppad/local/sparse/list_setvec.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
-----------------------------------------------------------------------------
|
||||
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
|
||||
910
build-config/cppad/include/cppad/local/sparse/pack_setvec.hpp
Normal file
910
build-config/cppad/include/cppad/local/sparse/pack_setvec.hpp
Normal file
@@ -0,0 +1,910 @@
|
||||
# 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 <cppad/core/cppad_assert.hpp>
|
||||
# include <cppad/local/pod_vector.hpp>
|
||||
|
||||
// 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<Pack> 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<Pack>::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<Pack>::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<Pack>& 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<class SetVector>
|
||||
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
|
||||
@@ -0,0 +1,32 @@
|
||||
-----------------------------------------------------------------------------
|
||||
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
|
||||
254
build-config/cppad/include/cppad/local/sparse/setvector.omh
Normal file
254
build-config/cppad/include/cppad/local/sparse/setvector.omh
Normal file
@@ -0,0 +1,254 @@
|
||||
/* --------------------------------------------------------------------------
|
||||
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
|
||||
1506
build-config/cppad/include/cppad/local/sparse/svec_setvec.hpp
Normal file
1506
build-config/cppad/include/cppad/local/sparse/svec_setvec.hpp
Normal file
File diff suppressed because it is too large
Load Diff
317
build-config/cppad/include/cppad/local/sparse/unary_op.hpp
Normal file
317
build-config/cppad/include/cppad/local/sparse/unary_op.hpp
Normal file
@@ -0,0 +1,317 @@
|
||||
# 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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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 <class Vector_set>
|
||||
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
|
||||
193
build-config/cppad/include/cppad/local/sqrt_op.hpp
Normal file
193
build-config/cppad/include/cppad/local/sqrt_op.hpp
Normal file
@@ -0,0 +1,193 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
52
build-config/cppad/include/cppad/local/std_set.hpp
Normal file
52
build-config/cppad/include/cppad/local/std_set.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
# 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 <cppad/local/define.hpp>
|
||||
|
||||
// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
|
||||
# include <cppad/utility/thread_alloc.hpp>
|
||||
|
||||
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 <class Scalar>
|
||||
const std::set<Scalar>& one_element_std_set(void)
|
||||
{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
|
||||
static std::set<Scalar> one;
|
||||
if( one.empty() )
|
||||
one.insert(1);
|
||||
return one;
|
||||
}
|
||||
/*!
|
||||
A standard set with a two elements.
|
||||
*/
|
||||
template <class Scalar>
|
||||
const std::set<Scalar>& two_element_std_set(void)
|
||||
{ CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
|
||||
static std::set<Scalar> two;
|
||||
if( two.empty() )
|
||||
{ two.insert(1);
|
||||
two.insert(2);
|
||||
}
|
||||
return two;
|
||||
}
|
||||
|
||||
} } // END_CPPAD_LOCAL_NAMESPACE
|
||||
# endif
|
||||
489
build-config/cppad/include/cppad/local/store_op.hpp
Normal file
489
build-config/cppad/include/cppad/local/store_op.hpp
Normal file
@@ -0,0 +1,489 @@
|
||||
# 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<Base> 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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]);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
/*
|
||||
==============================================================================
|
||||
<!-- define preamble -->
|
||||
The C++ source code corresponding to this operation is
|
||||
\verbatim
|
||||
v[x] = y
|
||||
\endverbatim
|
||||
where v is a VecAD<Base> vector, x is an AD<Base> object,
|
||||
and y is AD<Base> 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:
|
||||
<!-- end preamble -->
|
||||
==============================================================================
|
||||
*/
|
||||
/*!
|
||||
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 <class Vector_set>
|
||||
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
|
||||
|
||||
<!-- replace preamble -->
|
||||
The C++ source code corresponding to this operation is
|
||||
\verbatim
|
||||
v[x] = y
|
||||
\endverbatim
|
||||
where v is a VecAD<Base> vector, x is an AD<Base> object,
|
||||
and y is AD<Base> 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:
|
||||
<!-- end preamble -->
|
||||
|
||||
\param dependency
|
||||
is this a dependency (or sparsity) calculation.
|
||||
|
||||
\copydetails CppAD::local::sparse_store_op
|
||||
*/
|
||||
template <class Vector_set>
|
||||
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
|
||||
|
||||
<!-- replace preamble -->
|
||||
The C++ source code corresponding to this operation is
|
||||
\verbatim
|
||||
v[x] = y
|
||||
\endverbatim
|
||||
where v is a VecAD<Base> vector, x is an AD<Base> object,
|
||||
and y is AD<Base> 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:
|
||||
<!-- end preamble -->
|
||||
|
||||
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 <class Vector_set>
|
||||
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
|
||||
|
||||
<!-- replace preamble -->
|
||||
The C++ source code corresponding to this operation is
|
||||
\verbatim
|
||||
v[x] = y
|
||||
\endverbatim
|
||||
where v is a VecAD<Base> vector, x is an AD<Base> object,
|
||||
and y is AD<Base> 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:
|
||||
<!-- end preamble -->
|
||||
|
||||
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 <class Vector_set>
|
||||
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
|
||||
500
build-config/cppad/include/cppad/local/sub_op.hpp
Normal file
500
build-config/cppad/include/cppad/local/sub_op.hpp
Normal file
@@ -0,0 +1,500 @@
|
||||
# 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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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 <class Base>
|
||||
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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user