Ejemplo n.º 1
0
VectorBase ADFun<Base>::Forward(
	size_t              q         , 
	const VectorBase&   xq        , 
	      std::ostream& s         )
{	// temporary indices
	size_t i, j, k;

	// number of independent variables
	size_t n = ind_taddr_.size();

	// number of dependent variables
	size_t m = dep_taddr_.size();

	// check Vector is Simple Vector class with Base type elements
	CheckSimpleVector<Base, VectorBase>();


	CPPAD_ASSERT_KNOWN(
		size_t(xq.size()) == n || size_t(xq.size()) == n*(q+1),
		"Forward(q, xq): xq.size() is not equal n or n*(q+1)"
	);

	// lowest order we are computing
	size_t p = q + 1 - size_t(xq.size()) / n;
	CPPAD_ASSERT_UNKNOWN( p == 0 || p == q );
	CPPAD_ASSERT_KNOWN(
		q <= num_order_taylor_ || p == 0,
		"Forward(q, xq): Number of Taylor coefficient orders stored in this"
		" ADFun\nis less than q and xq.size() != n*(q+1)."
	);  
	CPPAD_ASSERT_KNOWN(
		p <= 1 || num_direction_taylor_ == 1,
		"Forward(q, xq): computing order q >= 2"
		" and number of directions is not one."
		"\nMust use Forward(q, r, xq) for this case"
	);
	// does taylor_ need more orders or fewer directions
	if( (cap_order_taylor_ <= q) | (num_direction_taylor_ != 1) )
	{	if( p == 0 )
		{	// no need to copy old values during capacity_order
			num_order_taylor_ = 0;
		}
		else	num_order_taylor_ = q;
		size_t c = std::max(q + 1, cap_order_taylor_);
		size_t r = 1;
		capacity_order(c, r);
	}
	CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ > q );
	CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 1 );

	// short hand notation for order capacity
	size_t C = cap_order_taylor_;

	// set Taylor coefficients for independent variables
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_  );

		// ind_taddr_[j] is operator taddr for j-th independent variable
		CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == InvOp );

		if( p ==  q )
			taylor_[ C * ind_taddr_[j] + q] = xq[j];
		else
		{	for(k = 0; k <= q; k++)
				taylor_[ C * ind_taddr_[j] + k] = xq[ (q+1)*j + k];
		}
	}

	// evaluate the derivatives
	CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
	CPPAD_ASSERT_UNKNOWN( load_op_.size()  == play_.num_load_op_rec() );
	if( q == 0 )
	{	forward0sweep(s, true,
			n, num_var_tape_, &play_, C, 
			taylor_.data(), cskip_op_.data(), load_op_,
			compare_change_count_,
			compare_change_number_,
			compare_change_op_index_
		);
	}
	else
	{	forward1sweep(s, true, p, q, 
			n, num_var_tape_, &play_, C, 
			taylor_.data(), cskip_op_.data(), load_op_,
			compare_change_count_,
			compare_change_number_,
			compare_change_op_index_
		);
	}

	// return Taylor coefficients for dependent variables
	VectorBase yq;
	if( p == q )
	{	yq.resize(m);
		for(i = 0; i < m; i++)
		{	CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_  );
			yq[i] = taylor_[ C * dep_taddr_[i] + q];
		}
	}
	else
	{	yq.resize(m * (q+1) );
		for(i = 0; i < m; i++)	
		{	for(k = 0; k <= q; k++)
				yq[ (q+1) * i + k] = 
					taylor_[ C * dep_taddr_[i] + k ]; 
		}
	}
# ifndef NDEBUG
	if( check_for_nan_ )
	{	bool ok = true;
		if( p == 0 )
		{	for(i = 0; i < m; i++)
			{	// Visual Studio 2012, CppAD required in front of isnan ?
				ok &= ! CppAD::isnan( yq[ (q+1) * i + 0 ] );
			}
		} 
		CPPAD_ASSERT_KNOWN(ok,
			"yq = f.Forward(q, xq): has a zero order Taylor coefficient "
			"with the value nan."
		);  
		if( 0 < q )
		{	for(i = 0; i < m; i++)
			{	for(k = p; k <= q; k++)
				{	// Studio 2012, CppAD required in front of isnan ?
					ok &= ! CppAD::isnan( yq[ (q+1-p)*i + k-p ] );
				}
			}
		}
		CPPAD_ASSERT_KNOWN(ok,
		"yq = f.Forward(q, xq): has a non-zero order Taylor coefficient\n"
		"with the value nan (but zero order coefficients are not nan)."
		);
	}
# endif

	// now we have q + 1  taylor_ coefficient orders per variable
	num_order_taylor_ = q + 1;

	return yq;
}
Ejemplo n.º 2
0
Vector ADFun<Base>::Forward(
	size_t p                    , 
	const Vector& x_p           , 
	std::ostream& s             )
{	// temporary indices
	size_t i, j;

	// number of independent variables
	size_t n = ind_taddr_.size();

	// number of dependent variables
	size_t m = dep_taddr_.size();

	// check Vector is Simple Vector class with Base type elements
	CheckSimpleVector<Base, Vector>();

	CPPAD_ASSERT_KNOWN(
		size_t(x_p.size()) == n,
		"Second argument to Forward does not have length equal to\n"
		"the dimension of the domain for the corresponding ADFun."
	);
	CPPAD_ASSERT_KNOWN(
		p <= taylor_per_var_,
		"The number of taylor_ coefficient currently stored\n"
		"in this ADFun object is less than p."
	);  

	// check if the taylor_ matrix needs more columns
	if( taylor_col_dim_ <= p )
		capacity_taylor(p + 1);
	CPPAD_ASSERT_UNKNOWN( taylor_col_dim_ > p );

	// set the p-th order taylor_ coefficients for independent variables
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < total_num_var_ );

		// ind_taddr_[j] is operator taddr for j-th independent variable
		CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == InvOp );

		// It is also variable taddr for j-th independent variable
		taylor_[ind_taddr_[j] * taylor_col_dim_ + p] = x_p[j];
	}

	// evaluate the derivatives
	if( p == 0 )
	{
# if CPPAD_USE_FORWARD0SWEEP
		compare_change_ = forward0sweep(s, true,
			n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
		);
# else
		compare_change_ = forward_sweep(s, true,
			p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
		);
# endif
	}
	else forward_sweep(s, false,
		p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
	);

	// return the p-th order taylor_ coefficients for dependent variables
	Vector y_p(m);
	for(i = 0; i < m; i++)
	{	CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < total_num_var_ );
		y_p[i] = taylor_[dep_taddr_[i] * taylor_col_dim_ + p];
	}
# ifndef NDEBUG
	if( hasnan(y_p) )
	{	if( p == 0 )
		{	CPPAD_ASSERT_KNOWN(false,
				"y = f.Forward(0, x): has a nan in y."
			);  
		}
		else
		{	CPPAD_ASSERT_KNOWN(false,
				"y_p = f.Forward(p, x_p): has a nan in y_p for p > 0, "
				"but not for p = 0."
			);
		}
	}
# endif


	// now we have p + 1  taylor_ coefficients per variable
	taylor_per_var_ = p + 1;

	return y_p;
}