Пример #1
0
inline void forward_zmulvv_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(ZmulvvOp) == 2 );
	CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 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 + arg[0] * num_taylor_per_var;
	Base* y = taylor + 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] = azmul(x[0], y[m]) + azmul(x[m],  y[0]);
		for(k = 1; k < q; k++)
			z[m] += azmul(x[(q-k-1)*r + ell + 1], y[(k-1)*r + ell + 1]);
	}
}
Пример #2
0
inline 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) / 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);

		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(j);

		for(k = 1; k < j; k++)
		{	pb[j-k] -= Base(k) * azmul(pz[j], z[k]);
			pz[k]   -= Base(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) * azmul(pb[0], x[0]);
}
Пример #3
0
inline void reverse_zmulvp_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(ZmulvpOp) == 2 );
	CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( d < cap_order );
	CPPAD_ASSERT_UNKNOWN( d < nc_partial );

	// Arguments
	Base y  = parameter[ arg[1] ];

	// Partial derivatives corresponding to arguments and result
	Base* px = partial + arg[0] * nc_partial;
	Base* pz = partial + i_z    * nc_partial;

	// number of indices to access
	size_t j = d + 1;
	while(j)
	{	--j;
		px[j] += azmul(pz[j], y);
	}
}
Пример #4
0
inline void forward_zmulvp_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(ZmulvpOp) == 2 );
	CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 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 + arg[0] * num_taylor_per_var + m;
	Base* z = taylor + i_z    * num_taylor_per_var + m;

	// Paraemter value
	Base y = parameter[ arg[1] ];

	for(size_t ell = 0; ell < r; ell++)
		z[ell] = azmul(x[ell], y);
}
Пример #5
0
inline void forward_zmulvp_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(ZmulvpOp) == 2 );
	CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( q < cap_order );
	CPPAD_ASSERT_UNKNOWN( p <= q );

	// Taylor coefficients corresponding to arguments and result
	Base* x = taylor + arg[0] * cap_order;
	Base* z = taylor + i_z    * cap_order;

	// Paraemter value
	Base y = parameter[ arg[1] ];

	for(size_t d = p; d <= q; d++)
		z[d] = azmul(x[d], y);
}
Пример #6
0
inline void forward_zmulvv_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(ZmulvvOp) == 2 );
	CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( q < cap_order );
	CPPAD_ASSERT_UNKNOWN( p <= q );

	// Taylor coefficients corresponding to arguments and result
	Base* x = taylor + arg[0] * cap_order;
	Base* y = taylor + 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);
		for(k = 0; k <= d; k++)
			z[d] += azmul(x[d-k], y[k]);
	}
}
Пример #7
0
inline 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(j);

		for(k = 1; k <= j; k++)
		{	px[k]   += Base(k) * azmul(pz[j], z[j-k]);
			pz[j-k] += Base(k) * azmul(pz[j], x[k]);
		}
		--j;
	}
	px[0] += azmul(pz[0], z[0]);
}
Пример #8
0
inline 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);
}
Пример #9
0
inline 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) / 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);
		for(k = 1; k < j; k++)
			pz[k]   -= azmul(pz[j], z[j-k]);
		--j;
	}
	px[0] += azmul(pz[0], inv_z0) / Base(2);
}
Пример #10
0
inline void reverse_zmulvv_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(ZmulvvOp) == 2 );
	CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( d < cap_order );
	CPPAD_ASSERT_UNKNOWN( d < nc_partial );

	// Arguments
	const Base* x  = taylor + arg[0] * cap_order;
	const Base* y  = taylor + arg[1] * cap_order;

	// Partial derivatives corresponding to arguments and result
	Base* px = partial + arg[0] * nc_partial;
	Base* py = partial + 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]);
		}
	}
}
Пример #11
0
inline void forward_zmulvv_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(ZmulvvOp) == 2 );
	CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );

	// Taylor coefficients corresponding to arguments and result
	Base* x = taylor + arg[0] * cap_order;
	Base* y = taylor + arg[1] * cap_order;
	Base* z = taylor + i_z    * cap_order;

	z[0] = azmul(x[0], y[0]);
}
Пример #12
0
inline 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]);
}
Пример #13
0
// case where x and y are AD<Base> -------------------------------------------
template <class Base> AD<Base>
azmul(const AD<Base>& x, const AD<Base>& y)
{
	// compute the Base part
	AD<Base> result;
	result.value_ = azmul(x.value_, y.value_);

	// check if there is a recording in progress
	ADTape<Base>* tape = AD<Base>::tape_ptr();
	if( tape == CPPAD_NULL )
		return result;
	tape_id_t tape_id = tape->id_;

	// tape_id cannot match the default value for tape_id_; i.e., 0
	CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
	bool var_x = x.tape_id_ == tape_id;
	bool var_y = y.tape_id_ == tape_id;

	if( var_x )
	{	if( var_y )
		{	// result = azmul(variable, variable)
			CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );
			CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );

			// put operand addresses in tape
			tape->Rec_.PutArg(x.taddr_, y.taddr_);

			// put operator in the tape
			result.taddr_ = tape->Rec_.PutOp(ZmulvvOp);

			// make result a variable
			result.tape_id_ = tape_id;
		}
		else if( IdenticalZero( y.value_ ) )
		{	// result = variable * 0
		}
		else if( IdenticalOne( y.value_ ) )
		{	// result = variable * 1
			result.make_variable(x.tape_id_, x.taddr_);
		}
		else
		{	// result = zmul(variable, parameter)
			CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );
			CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );

			// put operand addresses in tape
			addr_t p = tape->Rec_.PutPar(y.value_);
			tape->Rec_.PutArg(x.taddr_, p);

			// put operator in the tape
			result.taddr_ = tape->Rec_.PutOp(ZmulvpOp);

			// make result a variable
			result.tape_id_ = tape_id;
		}
	}
	else if( var_y )
	{	if( IdenticalZero(x.value_) )
		{	// result = 0 * variable
		}
		else if( IdenticalOne( x.value_ ) )
		{	// result = 1 * variable
			result.make_variable(y.tape_id_, y.taddr_);
		}
		else
		{	// result = zmul(parameter, variable)
			CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );
			CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );

			// put operand addresses in tape
			addr_t p = tape->Rec_.PutPar(x.value_);
			tape->Rec_.PutArg(p, y.taddr_);

			// put operator in the tape
			result.taddr_ = tape->Rec_.PutOp(ZmulpvOp);

			// make result a variable
			result.tape_id_ = tape_id;
		}
	}
	return result;
}
Пример #14
0
template <class Base> AD<Base>
azmul(const VecAD_reference<Base>& x, const Base& y)
{	return azmul(x.ADBase(), AD<Base>(y)); }
Пример #15
0
template <class Base> AD<Base>
azmul(const AD<Base>& x, const Base& y)
{	return azmul(x, AD<Base>(y)); }
Пример #16
0
template <class Base> AD<Base>
azmul(const Base& x, const AD<Base>& y)
{	return azmul(AD<Base>(x), y); }
Пример #17
0
inline 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) / 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(j);

		for(k = 1; k < j; k++)
		{	// update partials w.r.t b^(j-k)
			pb[j-k] -= Base(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(k) * azmul(pz[j], b[j-k]);
		}
		--j;
	}

	// j == 0 case
	px[0] -= azmul( pz[0] + azmul(pb[0], x[0]), inv_b0);
}
Пример #18
0
template <class Base> AD<Base>
azmul(const Base& x, const VecAD_reference<Base>& y)
{	return azmul(AD<Base>(x), y.ADBase()); }