Пример #1
0
inline 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( std::numeric_limits<addr_t>::max() >= i_z );

	// z_0 = log(x)
	forward_log_op_dir(q, r, i_z, 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);
}
Пример #2
0
inline 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(
		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 + 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);
}
Пример #3
0
/* Helper function for markArgs */
void markOpField(
		 //std::ostream      &os ,
		 void* os,
		 const char *leader,
		 //const Type     &value, 
		 const addr_t*   op_arg,
		 size_t          width ){
  addr_t index=addr_t(op_arg-play_.op_arg_rec_.data());
  arg_mark_[index]=true;
}
Пример #4
0
inline 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(
		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);
}
Пример #5
0
inline 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(
		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
}
Пример #6
0
inline 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( std::numeric_limits<addr_t>::max() >= i_z );

	// z_0 = log(x)
	forward_log_op(p, q, i_z, 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 + arg[0]  * cap_order;
		Base* y   = taylor + 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);
}
Пример #7
0
inline 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( std::numeric_limits<addr_t>::max() >= i_z );

	// z_0 = log(x)
	forward_log_op(p, q, i_z, 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 + 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);
}
Пример #8
0
inline 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( 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, arg[0], cap_order, taylor, nc_partial, partial
	);
}
Пример #9
0
void ADTape<Base>::RecordCondExp(
	enum CompareOp  cop         ,
	AD<Base>       &returnValue ,
	const AD<Base> &left        ,
	const AD<Base> &right       ,
	const AD<Base> &if_true     ,
	const AD<Base> &if_false    )
{	size_t   ind0, ind1, ind2, ind3, ind4, ind5;
	size_t   returnValue_taddr;

	// taddr_ of this variable
	CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );
	returnValue_taddr = Rec_.PutOp(CExpOp);

	// ind[0] = cop
	ind0 = addr_t( cop );

	// ind[1] = base 2 representaion of the value
	// [Var(left), Var(right), Var(if_true), Var(if_false)]
	ind1 = 0;

	// Make sure returnValue is in the list of variables and set its taddr
	if( Parameter(returnValue) )
		returnValue.make_variable(id_, returnValue_taddr );
	else	returnValue.taddr_ = returnValue_taddr;

	// ind[2] = left address
	if( Parameter(left) )
		ind2 = Rec_.PutPar(left.value_);
	else
	{	ind1 += 1;
		ind2 = left.taddr_;
	}

	// ind[3] = right address
	if( Parameter(right) )
		ind3 = Rec_.PutPar(right.value_);
	else
	{	ind1 += 2;
		ind3 = right.taddr_;
	}

	// ind[4] = if_true address
	if( Parameter(if_true) )
		ind4 = Rec_.PutPar(if_true.value_);
	else
	{	ind1 += 4;
		ind4 = if_true.taddr_;
	}

	// ind[5] =  if_false address
	if( Parameter(if_false) )
		ind5 = Rec_.PutPar(if_false.value_);
	else
	{	ind1 += 8;
		ind5 = if_false.taddr_;
	}

	CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );
	CPPAD_ASSERT_UNKNOWN( ind1 > 0 );
	Rec_.PutArg(ind0, ind1, ind2, ind3, ind4, ind5);

	// check that returnValue is a dependent variable
	CPPAD_ASSERT_UNKNOWN( Variable(returnValue) );
}
Пример #10
0
void subgraph_info::get_rev(
    const play::const_random_iterator<Addr>&   random_itr  ,
    const pod_vector<size_t>&                  dep_taddr   ,
    addr_t                                     i_dep       ,
    pod_vector<addr_t>&                        subgraph    )
{   // check sizes
    CPPAD_ASSERT_UNKNOWN( map_user_op_.size()   == n_op_ );

    // process_range_
    CPPAD_ASSERT_UNKNOWN( process_range_[i_dep] == false );
    process_range_[i_dep] = true;

    // special value; see init_rev_in_subgraph
    addr_t depend_yes = addr_t( n_dep_ );

    // assumption on i_dep
    CPPAD_ASSERT_UNKNOWN( i_dep < depend_yes );

    // start with an empty subgraph for this dependent variable
    subgraph.resize(0);

    // tape index corresponding to this dependent variable
    size_t i_var = dep_taddr[i_dep];

    // operator corresponding to this dependent variable
    size_t i_op = random_itr.var2op(i_var);
    i_op        = size_t( map_user_op_[i_op] );

    // if this variable depends on the selected indepent variables
    // process its subgraph
    CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] != i_dep )
    if( in_subgraph_[i_op] <= depend_yes )
    {   subgraph.push_back( addr_t(i_op) );
        in_subgraph_[i_op] = i_dep;
    }

    // space used to return set of arguments that are variables
    pod_vector<size_t> argument_variable;

    // temporary space used by get_argument_variable
    pod_vector<bool> work;

    // scan all the operators in this subgraph
    size_t sub_index = 0;
    while(sub_index < subgraph.size() )
    {   // this operator connected to this dependent and selected independent
        i_op = size_t( subgraph[sub_index] );
        CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] == i_dep );
        //
        // There must be a result for this operator
# ifndef NDEBUG
        OpCode op = random_itr.get_op(i_op);
        CPPAD_ASSERT_UNKNOWN(op == AFunOp || NumRes(op) > 0 );
# endif
        //
        // which variables are connected to this operator
        get_argument_variable(random_itr, i_op, argument_variable, work);
        for(size_t j = 0; j < argument_variable.size(); ++j)
        {   // add the corresponding operators to the subgraph
            size_t j_var = argument_variable[j];
            size_t j_op  = random_itr.var2op(j_var);
            j_op         = size_t( map_user_op_[j_op] );
            bool add = in_subgraph_[j_op] <= depend_yes;
            add     &= in_subgraph_[j_op] != i_dep;
            if( random_itr.get_op(j_op) == InvOp )
            {   CPPAD_ASSERT_UNKNOWN( j_op == j_var );
                add &= select_domain_[j_var - 1];
            }
            if( add )
            {   subgraph.push_back( addr_t(j_op) );
                in_subgraph_[j_op] = i_dep;
            }
        }
        // we are done scaning this subgraph operator
        ++sub_index;
    }
}
Пример #11
0
bool isDepArg(const addr_t*   op_arg){
  addr_t index=addr_t(op_arg-play_.op_arg_rec_.data());
  return   arg_mark_[index];
}