openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1313 lines
31 KiB

// $Id: cond_op.hpp 3845 2016-11-19 01:50:47Z bradbell $
# ifndef CPPAD_LOCAL_COND_OP_HPP
# define CPPAD_LOCAL_COND_OP_HPP
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell
CppAD is distributed under multiple licenses. This distribution is under
the terms of the
Eclipse Public License Version 1.0.
A copy of this license is included in the COPYING file of this distribution.
Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
-------------------------------------------------------------------------- */
namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
/*!
\file cond_op.hpp
Forward, reverse, and sparse operations for conditional expressions.
*/
/*!
Shared documentation for conditional expressions (not called).
<!-- define conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Base
base type for the operator; i.e., this operation was recorded
using AD< \a Base > and computations by this routine are done using type
\a Base.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\param parameter
For j = 0, 1, 2, 3,
if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
\param cap_order
number of columns in the matrix containing the Taylor coefficients.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end conditional_exp_op -->
*/
template <class Base>
inline void conditional_exp_op(
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
const Base* parameter ,
size_t cap_order )
{ // This routine is only for documentation, it should never be used
CPPAD_ASSERT_UNKNOWN( false );
}
/*!
Shared documentation for conditional expression sparse operations (not called).
<!-- define sparse_conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Vector_set
is the type used for vectors of sets. It can be either
sparse_pack or sparse_list.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end sparse_conditional_exp_op -->
*/
template <class Vector_set>
inline void sparse_conditional_exp_op(
size_t i_z ,
const addr_t* arg ,
size_t num_par )
{ // This routine is only for documentation, it should never be used
CPPAD_ASSERT_UNKNOWN( false );
}
/*!
Compute forward mode Taylor coefficients for op = CExpOp.
<!-- replace conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Base
base type for the operator; i.e., this operation was recorded
using AD< \a Base > and computations by this routine are done using type
\a Base.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\param parameter
For j = 0, 1, 2, 3,
if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
\param cap_order
number of columns in the matrix containing the Taylor coefficients.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end conditional_exp_op -->
\param p
is the lowest order of the Taylor coefficient of z that we are computing.
\param q
is the highest order of the Taylor coefficient of z that we are computing.
\param taylor
\b Input:
For j = 0, 1, 2, 3 and k = 0 , ... , q,
if y_j is a variable then
<code>taylor [ arg[2+j] * cap_order + k ]</code>
is the k-th order Taylor coefficient corresponding to y_j.
\n
\b Input: <code>taylor [ i_z * cap_order + k ]</code>
for k = 0 , ... , p-1,
is the k-th order Taylor coefficient corresponding to z.
\n
\b Output: <code>taylor [ i_z * cap_order + k ]</code>
for k = p , ... , q,
is the k-th order Taylor coefficient corresponding to z.
*/
template <class Base>
inline void forward_cond_op(
size_t p ,
size_t q ,
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
const Base* parameter ,
size_t cap_order ,
Base* taylor )
{ Base y_0, y_1, y_2, y_3;
Base zero(0);
Base* z = taylor + i_z * cap_order;
CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
if( arg[1] & 1 )
{
y_0 = taylor[ arg[2] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
y_0 = parameter[ arg[2] ];
}
if( arg[1] & 2 )
{
y_1 = taylor[ arg[3] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
y_1 = parameter[ arg[3] ];
}
if( p == 0 )
{ if( arg[1] & 4 )
{
y_2 = taylor[ arg[4] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
y_2 = parameter[ arg[4] ];
}
if( arg[1] & 8 )
{
y_3 = taylor[ arg[5] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
y_3 = parameter[ arg[5] ];
}
z[0] = CondExpOp(
CompareOp( arg[0] ),
y_0,
y_1,
y_2,
y_3
);
p++;
}
for(size_t d = p; d <= q; d++)
{ if( arg[1] & 4 )
{
y_2 = taylor[ arg[4] * cap_order + d];
}
else y_2 = zero;
if( arg[1] & 8 )
{
y_3 = taylor[ arg[5] * cap_order + d];
}
else y_3 = zero;
z[d] = CondExpOp(
CompareOp( arg[0] ),
y_0,
y_1,
y_2,
y_3
);
}
return;
}
/*!
Multiple directions forward mode Taylor coefficients for op = CExpOp.
<!-- replace conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Base
base type for the operator; i.e., this operation was recorded
using AD< \a Base > and computations by this routine are done using type
\a Base.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\param parameter
For j = 0, 1, 2, 3,
if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
\param cap_order
number of columns in the matrix containing the Taylor coefficients.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end conditional_exp_op -->
\param q
is order of the Taylor coefficient of z that we are computing.
\param r
is the number of Taylor coefficient directions that we are computing.
\par tpv
We use the notation
<code>tpv = (cap_order-1) * r + 1</code>
which is the number of Taylor coefficients per variable
\param taylor
\b Input:
For j = 0, 1, 2, 3, k = 1, ..., q,
if y_j is a variable then
<code>taylor [ arg[2+j] * tpv + 0 ]</code>
is the zero order Taylor coefficient corresponding to y_j and
<code>taylor [ arg[2+j] * tpv + (k-1)*r+1+ell</code> is its
k-th order Taylor coefficient in the ell-th direction.
\n
\b Input:
For j = 0, 1, 2, 3, k = 1, ..., q-1,
<code>taylor [ i_z * tpv + 0 ]</code>
is the zero order Taylor coefficient corresponding to z and
<code>taylor [ i_z * tpv + (k-1)*r+1+ell</code> is its
k-th order Taylor coefficient in the ell-th direction.
\n
\b Output: <code>taylor [ i_z * tpv + (q-1)*r+1+ell ]</code>
is the q-th order Taylor coefficient corresponding to z
in the ell-th direction.
*/
template <class Base>
inline void forward_cond_op_dir(
size_t q ,
size_t r ,
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
const Base* parameter ,
size_t cap_order ,
Base* taylor )
{ Base y_0, y_1, y_2, y_3;
Base zero(0);
size_t num_taylor_per_var = (cap_order-1) * r + 1;
Base* z = taylor + i_z * num_taylor_per_var;
CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
CPPAD_ASSERT_UNKNOWN( 0 < q );
CPPAD_ASSERT_UNKNOWN( q < cap_order );
if( arg[1] & 1 )
{
y_0 = taylor[ arg[2] * num_taylor_per_var + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
y_0 = parameter[ arg[2] ];
}
if( arg[1] & 2 )
{
y_1 = taylor[ arg[3] * num_taylor_per_var + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
y_1 = parameter[ arg[3] ];
}
size_t m = (q-1) * r + 1;
for(size_t ell = 0; ell < r; ell++)
{ if( arg[1] & 4 )
{
y_2 = taylor[ arg[4] * num_taylor_per_var + m + ell];
}
else y_2 = zero;
if( arg[1] & 8 )
{
y_3 = taylor[ arg[5] * num_taylor_per_var + m + ell];
}
else y_3 = zero;
z[m+ell] = CondExpOp(
CompareOp( arg[0] ),
y_0,
y_1,
y_2,
y_3
);
}
return;
}
/*!
Compute zero order forward mode Taylor coefficients for op = CExpOp.
<!-- replace conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Base
base type for the operator; i.e., this operation was recorded
using AD< \a Base > and computations by this routine are done using type
\a Base.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\param parameter
For j = 0, 1, 2, 3,
if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
\param cap_order
number of columns in the matrix containing the Taylor coefficients.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end conditional_exp_op -->
\param taylor
\b Input:
For j = 0, 1, 2, 3,
if y_j is a variable then
\a taylor [ \a arg[2+j] * cap_order + 0 ]
is the zero order Taylor coefficient corresponding to y_j.
\n
\b Output: \a taylor [ \a i_z * \a cap_order + 0 ]
is the zero order Taylor coefficient corresponding to z.
*/
template <class Base>
inline void forward_cond_op_0(
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
const Base* parameter ,
size_t cap_order ,
Base* taylor )
{ Base y_0, y_1, y_2, y_3;
Base* z;
CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
if( arg[1] & 1 )
{
y_0 = taylor[ arg[2] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
y_0 = parameter[ arg[2] ];
}
if( arg[1] & 2 )
{
y_1 = taylor[ arg[3] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
y_1 = parameter[ arg[3] ];
}
if( arg[1] & 4 )
{
y_2 = taylor[ arg[4] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
y_2 = parameter[ arg[4] ];
}
if( arg[1] & 8 )
{
y_3 = taylor[ arg[5] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
y_3 = parameter[ arg[5] ];
}
z = taylor + i_z * cap_order;
z[0] = CondExpOp(
CompareOp( arg[0] ),
y_0,
y_1,
y_2,
y_3
);
return;
}
/*!
Compute reverse mode Taylor coefficients for op = CExpOp.
This routine is given the partial derivatives of a function
G( z , y , x , w , ... )
and it uses them to compute the partial derivatives of
\verbatim
H( y , x , w , u , ... ) = G[ z(y) , y , x , w , u , ... ]
\endverbatim
where y above represents y_0, y_1, y_2, y_3.
<!-- replace conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Base
base type for the operator; i.e., this operation was recorded
using AD< \a Base > and computations by this routine are done using type
\a Base.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\param parameter
For j = 0, 1, 2, 3,
if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
\param cap_order
number of columns in the matrix containing the Taylor coefficients.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end conditional_exp_op -->
\param d
is the order of the Taylor coefficient of z that we are computing.
\param taylor
\b Input:
For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
if y_j is a variable then
\a taylor [ \a arg[2+j] * cap_order + k ]
is the k-th order Taylor coefficient corresponding to y_j.
\n
\a taylor [ \a i_z * \a cap_order + k ]
for k = 0 , ... , \a d
is the k-th order Taylor coefficient corresponding to z.
\param nc_partial
number of columns in the matrix containing the Taylor coefficients.
\param partial
\b Input:
For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
if y_j is a variable then
\a partial [ \a arg[2+j] * nc_partial + k ]
is the partial derivative of G( z , y , x , w , u , ... )
with respect to the k-th order Taylor coefficient corresponding to y_j.
\n
\b Input: \a partial [ \a i_z * \a cap_order + k ]
for k = 0 , ... , \a d
is the partial derivative of G( z , y , x , w , u , ... )
with respect to the k-th order Taylor coefficient corresponding to z.
\n
\b Output:
For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
if y_j is a variable then
\a partial [ \a arg[2+j] * nc_partial + k ]
is the partial derivative of H( y , x , w , u , ... )
with respect to the k-th order Taylor coefficient corresponding to y_j.
*/
template <class Base>
inline void reverse_cond_op(
size_t d ,
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
const Base* parameter ,
size_t cap_order ,
const Base* taylor ,
size_t nc_partial ,
Base* partial )
{ Base y_0, y_1;
Base zero(0);
Base* pz;
Base* py_2;
Base* py_3;
CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
pz = partial + i_z * nc_partial + 0;
if( arg[1] & 1 )
{
y_0 = taylor[ arg[2] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
y_0 = parameter[ arg[2] ];
}
if( arg[1] & 2 )
{
y_1 = taylor[ arg[3] * cap_order + 0 ];
}
else
{ CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
y_1 = parameter[ arg[3] ];
}
if( arg[1] & 4 )
{
py_2 = partial + arg[4] * nc_partial;
size_t j = d + 1;
while(j--)
{ py_2[j] += CondExpOp(
CompareOp( arg[0] ),
y_0,
y_1,
pz[j],
zero
);
}
}
if( arg[1] & 8 )
{
py_3 = partial + arg[5] * nc_partial;
size_t j = d + 1;
while(j--)
{ py_3[j] += CondExpOp(
CompareOp( arg[0] ),
y_0,
y_1,
zero,
pz[j]
);
}
}
return;
}
/*!
Compute forward Jacobian sparsity patterns for op = CExpOp.
<!-- replace sparse_conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Vector_set
is the type used for vectors of sets. It can be either
sparse_pack or sparse_list.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end sparse_conditional_exp_op -->
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\param sparsity
\b Input:
if y_2 is a variable, the set with index t is
the sparsity pattern corresponding to y_2.
This identifies which of the independent variables the variable y_2
depends on.
\n
\b Input:
if y_3 is a variable, the set with index t is
the sparsity pattern corresponding to y_3.
This identifies which of the independent variables the variable y_3
depends on.
\n
\b Output:
The set with index T is
the sparsity pattern corresponding to z.
This identifies which of the independent variables the variable z
depends on.
*/
template <class Vector_set>
inline void forward_sparse_jacobian_cond_op(
bool dependency ,
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
Vector_set& sparsity )
{
CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
# ifndef NDEBUG
size_t k = 1;
for( size_t j = 0; j < 4; j++)
{ if( ! ( arg[1] & k ) )
CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );
k *= 2;
}
# endif
sparsity.clear(i_z);
if( dependency )
{ if( arg[1] & 1 )
sparsity.binary_union(i_z, i_z, arg[2], sparsity);
if( arg[1] & 2 )
sparsity.binary_union(i_z, i_z, arg[3], sparsity);
}
if( arg[1] & 4 )
sparsity.binary_union(i_z, i_z, arg[4], sparsity);
if( arg[1] & 8 )
sparsity.binary_union(i_z, i_z, arg[5], sparsity);
return;
}
/*!
Compute reverse Jacobian sparsity patterns for op = CExpOp.
This routine is given the sparsity patterns
for a function G(z, y, x, ... )
and it uses them to compute the sparsity patterns for
\verbatim
H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
\endverbatim
where y represents the combination of y_0, y_1, y_2, and y_3.
<!-- replace sparse_conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Vector_set
is the type used for vectors of sets. It can be either
sparse_pack or sparse_list.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end sparse_conditional_exp_op -->
\param dependency
Are the derivatives with respect to left and right of the expression below
considered to be non-zero:
\code
CondExpRel(left, right, if_true, if_false)
\endcode
This is used by the optimizer to obtain the correct dependency relations.
\param sparsity
if y_2 is a variable, the set with index t is
the sparsity pattern corresponding to y_2.
This identifies which of the dependent variables depend on the variable y_2.
On input, this pattern corresponds to the function G.
On ouput, it corresponds to the function H.
\n
\n
if y_3 is a variable, the set with index t is
the sparsity pattern corresponding to y_3.
This identifies which of the dependent variables depeond on the variable y_3.
On input, this pattern corresponds to the function G.
On ouput, it corresponds to the function H.
\n
\b Output:
The set with index T is
the sparsity pattern corresponding to z.
This identifies which of the dependent variables depend on the variable z.
On input and output, this pattern corresponds to the function G.
*/
template <class Vector_set>
inline void reverse_sparse_jacobian_cond_op(
bool dependency ,
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
Vector_set& sparsity )
{
CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
# ifndef NDEBUG
size_t k = 1;
for( size_t j = 0; j < 4; j++)
{ if( ! ( arg[1] & k ) )
CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );
k *= 2;
}
# endif
if( dependency )
{ if( arg[1] & 1 )
sparsity.binary_union(arg[2], arg[2], i_z, sparsity);
if( arg[1] & 2 )
sparsity.binary_union(arg[3], arg[3], i_z, sparsity);
}
// --------------------------------------------------------------------
if( arg[1] & 4 )
sparsity.binary_union(arg[4], arg[4], i_z, sparsity);
if( arg[1] & 8 )
sparsity.binary_union(arg[5], arg[5], i_z, sparsity);
return;
}
/*!
Compute reverse Hessian sparsity patterns for op = CExpOp.
This routine is given the sparsity patterns
for a function G(z, y, x, ... )
and it uses them to compute the sparsity patterns for
\verbatim
H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
\endverbatim
where y represents the combination of y_0, y_1, y_2, and y_3.
<!-- replace sparse_conditional_exp_op -->
The C++ source code coresponding to this operation is
\verbatim
z = CondExpRel(y_0, y_1, y_2, y_3)
\endverbatim
where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
\tparam Vector_set
is the type used for vectors of sets. It can be either
sparse_pack or sparse_list.
\param i_z
is the AD variable index corresponding to the variable z.
\param arg
\n
\a 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
\a arg[1] & 1
\n
If this is zero, y_0 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 2
\n
If this is zero, y_1 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 4
\n
If this is zero, y_2 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[1] & 8
\n
If this is zero, y_3 is a parameter. Otherwise it is a variable.
\n
\n
\a arg[2 + j ] for j = 0, 1, 2, 3
\n
is the index corresponding to y_j.
\param num_par
is the total number of values in the vector \a parameter.
\par Checked Assertions
\li NumArg(CExpOp) == 6
\li NumRes(CExpOp) == 1
\li arg[0] < static_cast<size_t> ( CompareNe )
\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
<!-- end sparse_conditional_exp_op -->
\param jac_reverse
\a jac_reverse[i_z]
is false (true) if the Jacobian of G with respect to z is always zero
(may be non-zero).
\n
\n
\a jac_reverse[ arg[4] ]
If y_2 is a variable,
\a jac_reverse[ arg[4] ]
is false (true) if the Jacobian with respect to y_2 is always zero
(may be non-zero).
On input, it corresponds to the function G,
and on output it corresponds to the function H.
\n
\n
\a jac_reverse[ arg[5] ]
If y_3 is a variable,
\a jac_reverse[ arg[5] ]
is false (true) if the Jacobian with respect to y_3 is always zero
(may be non-zero).
On input, it corresponds to the function G,
and on output it corresponds to the function H.
\param hes_sparsity
The set with index \a i_z in \a hes_sparsity
is the Hessian sparsity pattern for the function G
where one of the partials is with respect to z.
\n
\n
If y_2 is a variable,
the set with index \a arg[4] in \a hes_sparsity
is the Hessian sparsity pattern
where one of the partials is with respect to y_2.
On input, this pattern corresponds to the function G.
On output, this pattern corresponds to the function H.
\n
\n
If y_3 is a variable,
the set with index \a arg[5] in \a hes_sparsity
is the Hessian sparsity pattern
where one of the partials is with respect to y_3.
On input, this pattern corresponds to the function G.
On output, this pattern corresponds to the function H.
*/
template <class Vector_set>
inline void reverse_sparse_hessian_cond_op(
size_t i_z ,
const addr_t* arg ,
size_t num_par ,
bool* jac_reverse ,
Vector_set& hes_sparsity )
{
CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
# ifndef NDEBUG
size_t k = 1;
for( size_t j = 0; j < 4; j++)
{ if( ! ( arg[1] & k ) )
CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );
k *= 2;
}
# endif
if( arg[1] & 4 )
{
hes_sparsity.binary_union(arg[4], arg[4], i_z, hes_sparsity);
jac_reverse[ arg[4] ] |= jac_reverse[i_z];
}
if( arg[1] & 8 )
{
hes_sparsity.binary_union(arg[5], arg[5], i_z, hes_sparsity);
jac_reverse[ arg[5] ] |= jac_reverse[i_z];
}
return;
}
} } // END_CPPAD_LOCAL_NAMESPACE
# endif