Esempio n. 1
0
CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION
bool IdenticalOne(const AD<Base> &x)
{	return Parameter(x) && IdenticalOne(x.value_); }
Esempio n. 2
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;
}
Esempio n. 3
0
AD<Base> operator / (const AD<Base> &left , const AD<Base> &right)
{
	// compute the Base part
	AD<Base> result;
	result.value_  = left.value_ / right.value_;
	CPPAD_ASSERT_UNKNOWN( Parameter(result) );

	// 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_left  = left.tape_id_  == tape_id;
	bool var_right = right.tape_id_ == tape_id;

	if( var_left )
	{	if( var_right )
		{	// result = variable / variable
			CPPAD_ASSERT_KNOWN(
				left.tape_id_ == right.tape_id_,
				"Dividing AD objects that are"
				" variables on different tapes."
			);
			CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );
			CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );

			// put operand addresses in tape
			tape->Rec_.PutArg(left.taddr_, right.taddr_);
			// put operator in the tape
			result.taddr_ = tape->Rec_.PutOp(DivvvOp);
			// make result a variable
			result.tape_id_ = tape_id;
		}
		else if( IdenticalOne(right.value_) )
		{	// result = variable / 1
			result.make_variable(left.tape_id_, left.taddr_);
		}
		else
		{	// result = variable / parameter
			CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );
			CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );

			// put operand addresses in tape
			addr_t p = tape->Rec_.PutPar(right.value_);
			tape->Rec_.PutArg(left.taddr_, p);
			// put operator in the tape
			result.taddr_ = tape->Rec_.PutOp(DivvpOp);
			// make result a variable
			result.tape_id_ = tape_id;
		}
	}
	else if( var_right )
	{	if( IdenticalZero(left.value_) )
		{	// result = 0 / variable
		}
		else
		{	// result = parameter / variable
			CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 );
			CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 );

			// put operand addresses in tape
			addr_t p = tape->Rec_.PutPar(left.value_);
			tape->Rec_.PutArg(p, right.taddr_);
			// put operator in the tape
			result.taddr_ = tape->Rec_.PutOp(DivpvOp);
			// make result a variable
			result.tape_id_ = tape_id;
		}
	}
	return result;
}
Esempio n. 4
0
File: div.hpp Progetto: barak/cppad
AD<Base> operator / (const AD<Base> &left , const AD<Base> &right)
{
    // compute the Base part
    AD<Base> result;
    result.value_  = left.value_ / right.value_;
    CPPAD_ASSERT_UNKNOWN( Parameter(result) );

    // check if there is a recording in progress
    local::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 );

    // check if left and right tapes match
    bool match_left  = left.tape_id_  == tape_id;
    bool match_right = right.tape_id_ == tape_id;

    // check if left and right are dynamic parameters
    bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);
    bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);

    // check if left and right are variables
    bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);
    bool var_right = match_right & (right.ad_type_ != dynamic_enum);

    CPPAD_ASSERT_KNOWN(
        left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,
        "Divide: AD variables or dynamic parameters on different threads."
    );
    if( var_left )
    {   if( var_right )
        {   // result = variable / variable
            CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvvOp) == 1 );
            CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvvOp) == 2 );

            // put operand addresses in tape
            tape->Rec_.PutArg(left.taddr_, right.taddr_);
            // put operator in the tape
            result.taddr_ = tape->Rec_.PutOp(local::DivvvOp);
            // make result a variable
            result.tape_id_ = tape_id;
            result.ad_type_ = variable_enum;
        }
        else if( (! dyn_right) & IdenticalOne(right.value_) )
        {   // result = variable / 1
            result.make_variable(left.tape_id_, left.taddr_);
        }
        else
        {   // result = variable / parameter
            CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvpOp) == 1 );
            CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvpOp) == 2 );

            // put operand addresses in tape
            addr_t p = right.taddr_;
            if( ! dyn_right )
                p = tape->Rec_.put_con_par(right.value_);
            tape->Rec_.PutArg(left.taddr_, p);
            // put operator in the tape
            result.taddr_ = tape->Rec_.PutOp(local::DivvpOp);
            // make result a variable
            result.tape_id_ = tape_id;
            result.ad_type_ = variable_enum;
        }
    }
    else if( var_right )
    {   if( (! dyn_left) & IdenticalZero(left.value_) )
        {   // result = 0 / variable
        }
        else
        {   // result = parameter / variable
            CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivpvOp) == 1 );
            CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivpvOp) == 2 );

            // put operand addresses in tape
            addr_t p = left.taddr_;
            if( ! dyn_left )
                p = tape->Rec_.put_con_par(left.value_);
            tape->Rec_.PutArg(p, right.taddr_);
            // put operator in the tape
            result.taddr_ = tape->Rec_.PutOp(local::DivpvOp);
            // make result a variable
            result.tape_id_ = tape_id;
            result.ad_type_ = variable_enum;
        }
    }
    else if( dyn_left | dyn_right )
    {   addr_t arg0 = left.taddr_;
        addr_t arg1 = right.taddr_;
        if( ! dyn_left )
            arg0 = tape->Rec_.put_con_par(left.value_);
        if( ! dyn_right )
            arg1 = tape->Rec_.put_con_par(right.value_);
        //
        // parameters with a dynamic parameter result
        result.taddr_   = tape->Rec_.put_dyn_par(
            result.value_, local::div_dyn,   arg0, arg1
        );
        result.tape_id_ = tape_id;
        result.ad_type_ = dynamic_enum;
    }
    return result;
}