예제 #1
20
void put_check_for_nan(const CppAD::vector<Base>& vec, std::string& file_name)
{
	size_t char_size       = sizeof(Base) * vec.size();
	const char* char_ptr   = reinterpret_cast<const char*>( vec.data() );
# if CPPAD_HAS_MKSTEMP
	char pattern[] = "/tmp/fileXXXXXX";
	int fd = mkstemp(pattern);
	file_name = pattern;
	write(fd, char_ptr, char_size);
	close(fd);
# else
# if CPPAD_HAS_TMPNAM_S
		std::vector<char> name(L_tmpnam_s);
		if( tmpnam_s( name.data(), L_tmpnam_s ) != 0 )
		{	CPPAD_ASSERT_KNOWN(
				false,
				"Cannot create a temporary file name"
			);
		}
		file_name = name.data();
# else
		file_name = tmpnam( CPPAD_NULL );
# endif
	std::fstream file_out(file_name.c_str(), std::ios::out|std::ios::binary );
	file_out.write(char_ptr, char_size);
	file_out.close();
# endif
	return;
}
예제 #2
1
void ode_evaluate(
	CppAD::vector<Float> &x  , 
	size_t m                 , 
	CppAD::vector<Float> &fm )
{
	typedef CppAD::vector<Float> Vector;

	size_t n = x.size();
	size_t ell;
	CPPAD_ASSERT_KNOWN( m == 0 || m == 1,
		"ode_evaluate: m is not zero or one"
	);
	CPPAD_ASSERT_KNOWN( 
		((m==0) & (fm.size()==n)) || ((m==1) & (fm.size()==n*n)),
		"ode_evaluate: the size of fm is not correct"
	);
	if( m == 0 )
		ell = n;
	else	ell = n + n * n;

	// set up the case we are integrating
	Float  ti   = 0.;
	Float  tf   = 1.;
	Float  smin = 1e-5;
	Float smax  = 1.;
	Float scur  = 1.;
	Float erel  = 0.;
	vector<Float> yi(ell), eabs(ell);
	size_t i, j;
	for(i = 0; i < ell; i++)
	{	eabs[i] = 1e-10;
		if( i < n )
			yi[i] = 1.;
		else	yi[i]  = 0.;
	}

	// return values
	Vector yf(ell), ef(ell), maxabs(ell);
	size_t nstep;

	// construct ode method for taking one step
	ode_evaluate_method<Float> method(m, x);

	// solve differential equation
	yf = OdeErrControl(method, 
		ti, tf, yi, smin, smax, scur, eabs, erel, ef, maxabs, nstep);

	if( m == 0 )
	{	for(i = 0; i < n; i++)
			fm[i] = yf[i];
	}
	else
	{	for(i = 0; i < n; i++)
			for(j = 0; j < n; j++)
				fm[i * n + j] = yf[n + i * n + j];
	}
	return;
}
	void sparse_jac_fun(
		size_t                       m    ,
		size_t                       n    ,
		const FloatVector&           x    ,
		const CppAD::vector<size_t>& row  , 
		const CppAD::vector<size_t>& col  , 
		size_t                       p    ,
		FloatVector&                 fp   )
	{
		// check numeric type specifications
		CheckNumericType<Float>();
		// check value of p
		CPPAD_ASSERT_KNOWN(
			p == 0 || p == 1,
			"sparse_jac_fun: p != 0 and p != 1"
		);
		size_t K = row.size();
		CPPAD_ASSERT_KNOWN(
			K >= m,
			"sparse_jac_fun: row.size() < m"
		);
		size_t i, j, k;

		if( p == 0 )
			for(i = 0; i < m; i++)
				fp[i] = Float(0);

		Float t;
		for(k = 0; k < K; k++)
		{	i    = row[k];
			j    = col[k];
			t    = exp( x[j] * x[j] / 2.0 );	
			switch(p)
			{
				case 0:
				fp[i] += t;
				break;

				case 1:
				fp[k] = t * x[j];
				break;
			}
		}
	}
예제 #4
1
	void sparse_hes_fun(
		size_t                       n    ,
		const FloatVector&           x    ,
		const CppAD::vector<size_t>& row  , 
		const CppAD::vector<size_t>& col  , 
		size_t                       p    ,
		FloatVector&                fp    )
	{
		// check numeric type specifications
		CheckNumericType<Float>();

		// check value of p
		CPPAD_ASSERT_KNOWN(
			p < 3,
			"sparse_hes_fun: p > 2"
		);

		size_t i, j, k;
		size_t size = 1;
		for(k = 0; k < p; k++)
			size *= n;
		for(k = 0; k < size; k++)
			fp[k] = Float(0);

		size_t K = row.size();
		Float t;
		Float dt_i;
		Float dt_j;
		for(k = 0; k < K; k++)
		{	i    = row[k];
			j    = col[k];
			t    = exp( x[i] * x[j] );	
			dt_i = t * x[j];
			dt_j = t * x[i];
			switch(p)
			{
				case 0:
				fp[0] += t;
				break;

				case 1:
				fp[i] += dt_i;
				fp[j] += dt_j;
				break;

				case 2:
				fp[i * n + i] += dt_i * x[j];
				fp[i * n + j] += t + dt_j * x[j];
				//
				fp[j * n + i] += t + dt_i * x[i];
				fp[j * n + j] += dt_j * x[i];
				break;
			}
		}
			
	}
예제 #5
0
Vector ADFun<Base>::ForOne(const Vector &x, size_t j)
{	size_t j1;

	size_t n = Domain();
	size_t m = Range();

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

	CPPAD_ASSERT_KNOWN(
		x.size() == n,
		"ForOne: Length of x not equal domain dimension for f"
	);
	CPPAD_ASSERT_KNOWN(
		j < n,
		"ForOne: the index j is not less than domain dimension for f"
	);

	// point at which we are evaluating the second partials
	Forward(0, x);

	// direction in which are are taking the derivative
	Vector dx(n);
	for(j1 = 0; j1 < n; j1++)
		dx[j1] = Base(0);
	dx[j] = Base(1);

	// dimension the return value
	Vector dy(m);

	// compute the return value
	dy = Forward(1, dx);

	return dy;
}
예제 #6
0
파일: parallel_ad.hpp 프로젝트: barak/cppad
void parallel_ad(void)
{   CPPAD_ASSERT_KNOWN(
        ! thread_alloc::in_parallel() ,
        "parallel_ad must be called before entering parallel execution mode."
    );
    CPPAD_ASSERT_KNOWN(
        AD<Base>::tape_ptr() == CPPAD_NULL ,
        "parallel_ad cannot be called while a tape recording is in progress"
    );

    // ensure statics in following functions are initialized
    elapsed_seconds();
    ErrorHandler::Current();
    local::NumArg(local::BeginOp);
    local::NumRes(local::BeginOp);
    local::one_element_std_set<size_t>();
    local::two_element_std_set<size_t>();

    // the sparse_pack class has member functions with static data
    local::sparse_pack sp;
    sp.resize(1, 1);       // so can call add_element
    sp.add_element(0, 0);  // has static data
    sp.clear(0);           // has static data
    sp.is_element(0, 0);   // has static data
    local::sparse_pack::const_iterator itr(sp, 0); // has static data
    ++itr;                                  // has static data

    // statics that depend on the value of Base
    AD<Base>::tape_id_ptr(0);
    AD<Base>::tape_handle(0);
    discrete<Base>::List();
    CheckSimpleVector< Base, CppAD::vector<Base> >();
    CheckSimpleVector< AD<Base>, CppAD::vector< AD<Base> > >();

}
예제 #7
0
void  AD<Base>::tape_delete(size_t id_old)
{
	size_t thread = id_old % CPPAD_MAX_NUM_THREADS;
	CPPAD_ASSERT_KNOWN(
		thread == thread_alloc::thread_num(),
		"AD tape recording must stop in same thread as it started in."
	);
	size_t        *id   = id_handle(thread);
	ADTape<Base> **tape = tape_handle(thread);

	CPPAD_ASSERT_UNKNOWN( *id   == id_old     );
	CPPAD_ASSERT_UNKNOWN( *tape != CPPAD_NULL );

	// increase the id for this thread in a way such that 
	// thread = id % CPPAD_MAX_NUM_THREADS
	CPPAD_ASSERT_KNOWN(
	size_t(*id) + CPPAD_MAX_NUM_THREADS <= 
		std::numeric_limits<CPPAD_TAPE_ID_TYPE>::max(),
	"To many different tapes given the type used for CPPAD_TAPE_ID_TYPE"
	);
	*id  += CPPAD_MAX_NUM_THREADS;

	// delete the old tape for this thread
	delete ( *tape );
	*tape = CPPAD_NULL;

	return;
}
예제 #8
0
파일: rev_one.hpp 프로젝트: fduffy/CppAD
Vector ADFun<Base>::RevOne(const Vector  &x, size_t i)
{	size_t i1;

	size_t n = Domain();
	size_t m = Range();

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

	CPPAD_ASSERT_KNOWN(
		x.size() == n,
		"RevOne: Length of x not equal domain dimension for f"
	);
	CPPAD_ASSERT_KNOWN(
		i < m,
		"RevOne: the index i is not less than range dimension for f"
	);

	// point at which we are evaluating the derivative
	Forward(0, x);

	// component which are are taking the derivative of
	Vector w(m);
	for(i1 = 0; i1 < m; i1++)
		w[i1] = 0.;
	w[i] = Base(1);

	// dimension the return value
	Vector dw(n);

	// compute the return value
	dw = Reverse(1, w);

	return dw;
}
예제 #9
0
void color_general_colpack(
	const VectorSet&        pattern ,
	const VectorSize&       row     ,
	const VectorSize&       col     ,
	CppAD::vector<size_t>&  color   )
{	size_t i, j, k;
	size_t m = pattern.n_set();
	size_t n = pattern.end();

	// Determine number of non-zero entries in each row
	CppAD::vector<size_t> n_nonzero(m);
	size_t n_nonzero_total = 0;
	for(i = 0; i < m; i++)
	{	n_nonzero[i] = 0;
		typename VectorSet::const_iterator pattern_itr(pattern, i);
		j = *pattern_itr;
		while( j != pattern.end() )
		{	n_nonzero[i]++;
			j = *(++pattern_itr);
		}
		n_nonzero_total += n_nonzero[i];
	}

	// Allocate memory and fill in Adolc sparsity pattern
	CppAD::vector<unsigned int*> adolc_pattern(m);
	CppAD::vector<unsigned int>  adolc_memory(m + n_nonzero_total);
	size_t i_memory = 0;
	for(i = 0; i < m; i++)
	{	adolc_pattern[i]    = adolc_memory.data() + i_memory;
		CPPAD_ASSERT_KNOWN(
			std::numeric_limits<unsigned int>::max() >= n_nonzero[i],
			"Matrix is too large for colpack"
		);
		adolc_pattern[i][0] = static_cast<unsigned int>( n_nonzero[i] );
		typename VectorSet::const_iterator pattern_itr(pattern, i);
		j = *pattern_itr;
		k = 1;
		while(j != pattern.end() )
		{
			CPPAD_ASSERT_KNOWN(
				std::numeric_limits<unsigned int>::max() >= j,
				"Matrix is too large for colpack"
			);
			adolc_pattern[i][k++] = static_cast<unsigned int>( j );
			j = *(++pattern_itr);
		}
		CPPAD_ASSERT_UNKNOWN( k == 1 + n_nonzero[i] );
		i_memory += k;
	}
	CPPAD_ASSERT_UNKNOWN( i_memory == m + n_nonzero_total );

	// Must use an external routine for this part of the calculation because
	// ColPack/ColPackHeaders.h has as 'using namespace std' at global level.
	cppad_colpack_general(color, m, n, adolc_pattern);

	return;
}
예제 #10
0
파일: hessian.hpp 프로젝트: barak/CppAD-1
Vector ADFun<Base>::Hessian(const Vector &x, const Vector &w)
{	size_t j;
	size_t k;

	size_t n = Domain();

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

	CPPAD_ASSERT_KNOWN(
		size_t(x.size()) == n,
		"Hessian: length of x not equal domain dimension for f"
	);
	CPPAD_ASSERT_KNOWN(
		size_t(w.size()) == Range(),
		"Hessian: length of w not equal range dimension for f"
	);

	// point at which we are evaluating the Hessian
	Forward(0, x);

	// define the return value
	Vector hes(n * n);

	// direction vector for calls to forward
	Vector u(n);
	for(j = 0; j < n; j++)
		u[j] = Base(0);


	// location for return values from Reverse
	Vector ddw(n * 2);

	// loop over forward directions
	for(j = 0; j < n; j++)
	{	// evaluate partials of entire function w.r.t. j-th coordinate
		u[j] = Base(1);
		Forward(1, u);
		u[j] = Base(0);

		// evaluate derivative of partial corresponding to F_i
		ddw = Reverse(2, w);

		// return desired components
		for(k = 0; k < n; k++)
			hes[k * n + j] = ddw[k * 2 + 1];
	}

	return hes;
}
예제 #11
0
void ADFun<Base>::RevSparseHesCase(
	bool              set_type         ,
	bool              transpose        ,  
	size_t            q                ,  
	const VectorSet&  s                ,
	VectorSet&        h                )
{	size_t n = Domain(); 	
	h.resize(q * n );

	CPPAD_ASSERT_KNOWN( 
		for_jac_sparse_pack_.n_set() > 0,
		"RevSparseHes: previous stored call to ForSparseJac did not "
		"use bool for the elements of r."
	);
	CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == 0 );
	CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == total_num_var_ );
	
	// use sparse_pack for the calculation
	CppAD::RevSparseHesBool( 
		transpose                ,
		q                        ,
		s                        ,
		h                        ,
		total_num_var_           ,
		dep_taddr_               ,
		ind_taddr_               ,
		play_                    ,
		for_jac_sparse_pack_ 
	);
}
예제 #12
0
파일: fun_record.hpp 프로젝트: fduffy/CppAD
void fun_record(
	cppad_ipopt_fg_info*                              fg_info ,
	size_t                                            k       ,
	const SizeVector&                                 p       ,
	const SizeVector&                                 q       ,
	size_t                                            n       ,
	const NumVector&                                  x       ,
	const SizeVector&                                 J       ,
	CppAD::vector< CppAD::ADFun<Ipopt::Number> >&     r_fun   )
{	size_t j;

	// extract u from x
	ADVector u(q[k]);
	for(j = 0; j < q[k]; j++)
	{	// when NDEBUG is not defined, this error should be caught
		// during the cppad_ipopt_nlp constructor.
		CPPAD_ASSERT_UNKNOWN( J[j] < n );
		u[j] = x[ J[j] ];
	}

	// start the recording
	CppAD::Independent(u);

	// record the evaulation of r_k (u)
	ADVector r_k = fg_info->eval_r(k, u);
	CPPAD_ASSERT_KNOWN( r_k.size() == p[k] ,
	"cppad_ipopt_nlp: eval_r return value size not equal to p[k]."
	);

	// stop the recording and store operation sequence in
	r_fun[k].Dependent(u, r_k);
}
예제 #13
0
 /// not a number
 static Float quiet_NaN(void)
 {   CPPAD_ASSERT_KNOWN(
         false,
         "numeric_limits<Float>::quiet_NaN() is not specialized for this Float"
     );
     return Float(0);
 }
예제 #14
0
	/*!
 	Link from forward mode sweep to users routine.

	\param index
	index for this function in the list of all user_atomic objects

	\param id
	extra information vector that is just passed through by CppAD,
	and possibly used by user's routines.

	\param k
	order for this forward mode calculation.

	\param n
	domain space size for this calcualtion.

	\param m
	range space size for this calculation.

	\param tx
	Taylor coefficients corresponding to \c x for this calculation.

	\param ty
	Taylor coefficient corresponding to \c y for this calculation

	See the forward mode in user's documentation for user_atomic 
 	*/
	static void forward(
		size_t                index , 
		size_t                   id ,
		size_t                    k ,
		size_t                    n , 
		size_t                    m , 
		const vector<Base>&      tx ,
		vector<Base>&            ty )
	{	
# ifdef _OPENMP
		vector<bool> empty(0);
# else
		static vector<bool> empty(0);
# endif
		
		CPPAD_ASSERT_UNKNOWN( tx.size() >= n * k );
		CPPAD_ASSERT_UNKNOWN( ty.size() >= m * k );

		CPPAD_ASSERT_UNKNOWN(index < List().size() );
		user_atomic* op = List()[index];

		bool ok = op->f_(id, k, n, m, empty, empty, tx, ty);
		if( ! ok )
		{	std::stringstream ss;
			ss << k;
			std::string msg = "user_atomic: ";
			msg = msg + op->name_ + ": ok returned false from " + ss.str()
			    + " order forward mode calculation";
			CPPAD_ASSERT_KNOWN(false, msg.c_str());
		}
	}
예제 #15
0
inline void forward_sqrt_op_dir(
	size_t q           ,
	size_t r           ,
	size_t i_z         ,
	size_t i_x         ,
	size_t cap_order   ,
	Base*  taylor      )
{
	// check assumptions
	CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( 0 < q );
	CPPAD_ASSERT_UNKNOWN( q < cap_order );

	// Taylor coefficients corresponding to argument and result
	size_t num_taylor_per_var = (cap_order-1) * r + 1;
	Base* z = taylor + i_z * num_taylor_per_var;
	Base* x = taylor + i_x * num_taylor_per_var;
	CPPAD_ASSERT_KNOWN(
		x[0] != Base(0),
		"Forward: attempt to take derivatve of square root of zero"
	)

	size_t m = (q-1) * r + 1;
	for(size_t ell = 0; ell < r; ell++)
	{	z[m+ell] = Base(0);
		for(size_t k = 1; k < q; k++)
			z[m+ell] -= Base(k) * z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell];
		z[m+ell] /= Base(q);
		z[m+ell] += x[m+ell] / Base(2);
		z[m+ell] /= z[0];
	}
}
예제 #16
0
파일: checkpoint.hpp 프로젝트: ZiiCee/OPTI
	void operator()(const ADVector& ax, ADVector& ay, size_t id = 0)
	{	CPPAD_ASSERT_KNOWN(
			id == 0,
			"checkpoint: id is non-zero in afun(ax, ay, id)"
		);
		this->atomic_base<Base>::operator()(ax, ay, id);
	}
예제 #17
0
	/*!
 	Link from reverse mode sweep to users routine.

	\param index
	index in the list of all user_atomic objects
	corresponding to this function.


	\param id
	extra information vector that is just passed through by CppAD,
	and possibly used by user's routines.

	\param k
	order for this forward mode calculation.

	\param n
	domain space size for this calcualtion.

	\param m
	range space size for this calculation.

	\param tx
	Taylor coefficients corresponding to \c x for this calculation.

	\param ty
	Taylor coefficient corresponding to \c y for this calculation

	\param px
	Partials w.r.t. the \c x Taylor coefficients.

	\param py
	Partials w.r.t. the \c y Taylor coefficients.

	See reverse mode documentation for user_atomic 
 	*/
	static void reverse(
		size_t               index , 
		size_t                  id ,
		size_t                   k ,
		size_t                   n , 
		size_t                   m , 
		const vector<Base>&     tx ,
		const vector<Base>&     ty ,
		vector<Base>&           px ,
		const vector<Base>&     py )
	{
		CPPAD_ASSERT_UNKNOWN(index < List().size() );
		CPPAD_ASSERT_UNKNOWN( tx.size() >= n * k );
		CPPAD_ASSERT_UNKNOWN( px.size() >= n * k );
		CPPAD_ASSERT_UNKNOWN( ty.size() >= m * k );
		CPPAD_ASSERT_UNKNOWN( py.size() >= m * k );
		user_atomic* op = List()[index];

		bool ok = op->r_(id, k, n, m, tx, ty, px, py);
		if( ! ok )
		{	std::stringstream ss;
			ss << k;
			std::string msg = "user_atomic: ";
			msg = op->name_ + ": ok returned false from " + ss.str() 
			    + " order reverse mode calculation";
			CPPAD_ASSERT_KNOWN(false, msg.c_str());
		}
	}
예제 #18
0
 /// machine epsilon
 static Float epsilon(void)
 {   CPPAD_ASSERT_KNOWN(
         false,
         "numeric_limits<Float>::epsilon() is not specialized for this Float"
     );
     return Float(0);
 }
예제 #19
0
	/*!
 	Link from reverse Hessian sparsity sweep to users routine.

	\param index
	index in the list of all user_atomic objects
	corresponding to this function.

	\param id
	extra information vector that is just passed through by CppAD,
	and possibly used by user's routines.

	\param n
	domain space size for this calcualtion.

	\param m
	range space size for this calculation.

	\param q
	is the column dimension for the sparsity partterns.

	\param r
	is the forward Jacobian sparsity pattern w.r.t the argument vector x

	\param s
	is the reverse Jacobian sparsity pattern w.r.t the result vector y.

	\param t
	is the reverse Jacobian sparsity pattern w.r.t the argument vector x.

	\param u
	is the Hessian sparsity pattern w.r.t the result vector y.

	\param v
	is the Hessian sparsity pattern w.r.t the argument vector x.
	*/
	static void rev_hes_sparse(
		size_t                            index ,
		size_t                               id ,
		size_t                                n , 
		size_t                                m , 
		size_t                                q ,
		vector< std::set<size_t> >&           r ,
		const vector<bool>&                   s ,
		vector<bool>&                         t ,
		const vector< std::set<size_t> >&     u ,
		vector< std::set<size_t> >&           v )
	{
		CPPAD_ASSERT_UNKNOWN(index < List().size() );
		CPPAD_ASSERT_UNKNOWN( r.size() >= n );
		CPPAD_ASSERT_UNKNOWN( s.size() >= m );
		CPPAD_ASSERT_UNKNOWN( t.size() >= n );
		CPPAD_ASSERT_UNKNOWN( u.size() >= m );
		CPPAD_ASSERT_UNKNOWN( v.size() >= n );
		user_atomic* op = List()[index];

		bool ok = op->rhs_(id, n, m, q, r, s, t, u, v);
		if( ! ok )
		{	std::string msg = "user_atomic: ";
			msg = msg + op->name_ 
			    + ": ok returned false from rev_jac_sparse calculation";
			CPPAD_ASSERT_KNOWN(false, msg.c_str());
		}
	}
예제 #20
0
void ADFun<Base>::RevSparseHesCase(
	const std::set<size_t>&   set_type         ,
	bool                      transpose        ,  
	size_t                    q                ,  
	const VectorSet&          s                ,
	VectorSet&                h                )
{	size_t n = Domain();
	if( transpose )
		h.resize(n);
	else	h.resize(q);

	CPPAD_ASSERT_KNOWN( 
		for_jac_sparse_set_.n_set() > 0,
		"RevSparseHes: previous stored call to ForSparseJac did not "
		"use std::set<size_t> for the elements of r."
	);
	CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 );
	CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == num_var_tape_  );
	
	// use sparse_pack for the calculation
	CppAD::RevSparseHesSet( 
		transpose                ,
		q                        ,
		s                        ,
		h                        ,
		num_var_tape_            ,
		dep_taddr_               ,
		ind_taddr_               ,
		play_                    ,
		for_jac_sparse_set_ 
	);
}
예제 #21
0
inline void forward_sqrt_op(
	size_t j           ,
	size_t i_z         ,
	size_t i_x         ,
	size_t nc_taylor   , 
	Base*  taylor      )
{	
	// check assumptions
	CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 );
	CPPAD_ASSERT_UNKNOWN( i_x < i_z );
	CPPAD_ASSERT_UNKNOWN( j < nc_taylor );

	// Taylor coefficients corresponding to argument and result
	Base* x = taylor + i_x * nc_taylor;
	Base* z = taylor + i_z * nc_taylor;

	size_t k;
	if( j == 0 )
		z[j] = sqrt( x[0] );
	else
	{
		CPPAD_ASSERT_KNOWN(
			x[0] != Base(0),
			"Forward: attempt to take derivatve of square root of zero"
		)
		z[j] = Base(0);
		for(k = 1; k < j; k++)
			z[j] -= Base(k) * z[k] * z[j-k];
		z[j] /= Base(j);
		z[j] += x[j] / Base(2);
		z[j] /= z[0];
	}
}
예제 #22
0
	/// vector assignment operator
	/// If the resulting length of the vector would be more than
	/// \c max_length_, and \c NDEBUG is not defined,
	/// a CPPAD_ASSERT is generated.
	void operator=(
		/// right hand size of the assingment operation
		const pod_vector& x
	)
	{	size_t i;

		if( x.length_ <= capacity_ )
		{	// use existing allocation for this vector
			length_ = x.length_;
			CPPAD_ASSERT_KNOWN(
				length_ <= max_length_ ,
				"pod_vector.hpp: attempt to create to large a vector.\n"
				"If Type is CPPAD_TYPE_ADDR_TYPE, tape long for Type."
			);
		}
		else
		{	// free old memory and get new memory of sufficient length
			if( capacity_ > 0 )
			{	void* v_ptr = reinterpret_cast<void*>( data_ );
				if( ! is_pod<Type>() )
				{	// call destructor for each element
					for(i = 0; i < capacity_; i++)
						(data_ + i)->~Type();
				}
				thread_alloc::return_memory(v_ptr);
			}
			length_ = capacity_ = 0;
			extend( x.length_ );
		}
		CPPAD_ASSERT_UNKNOWN( length_   == x.length_ );
		for(i = 0; i < length_; i++)
		{	data_[i] = x.data_[i]; }
	}
예제 #23
0
파일: index_sort.hpp 프로젝트: fduffy/CppAD
void index_sort(const VectorKey& keys, VectorSize& ind)
{	typedef typename VectorKey::value_type Compare;
	CheckSimpleVector<size_t, VectorSize>();

	typedef index_sort_element<Compare> element;

	CPPAD_ASSERT_KNOWN(
		size_t(keys.size()) == size_t(ind.size()),
		"index_sort: vector sizes do not match"
	);

	size_t size_work = size_t(keys.size());
	size_t size_out;
	element* work =
		thread_alloc::create_array<element>(size_work, size_out);

	// copy initial order into work
	size_t i;
	for(i = 0; i < size_work; i++)
	{	work[i].set_key( keys[i] );
		work[i].set_index( i );
	}

	// sort the work array
	std::sort(work, work+size_work);

	// copy the indices to the output vector
	for(i = 0; i < size_work; i++)
		ind[i] = work[i].get_index();

	// we are done with this work array
	thread_alloc::delete_array(work);

	return;
}
예제 #24
0
inline void forward_store_vp_op_0(
	size_t         i_z         ,
	const addr_t*  arg         , 
	size_t         num_par     ,
	size_t         nc_taylor   ,
	Base*          taylor      ,
	size_t         nc_combined ,
	bool*          variable    ,
	size_t*        combined    )
{	
	CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= i_z );
	size_t i_vec = Integer( taylor[ arg[1] * nc_taylor + 0 ] );
	CPPAD_ASSERT_KNOWN( 
		i_vec < combined[ arg[0] - 1 ] ,
		"VecAD: index during zero order forward sweep is out of range"
	);

	CPPAD_ASSERT_UNKNOWN( variable != CPPAD_NULL );
	CPPAD_ASSERT_UNKNOWN( combined != CPPAD_NULL );
	CPPAD_ASSERT_UNKNOWN( NumArg(StvpOp) == 3 );
	CPPAD_ASSERT_UNKNOWN( NumRes(StvpOp) == 0 );
	CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
	CPPAD_ASSERT_UNKNOWN( arg[0] + i_vec < nc_combined );
	CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );

	variable[ arg[0] + i_vec ] = false;
	combined[ arg[0] + i_vec ] = arg[2];
}
예제 #25
0
void ADTape<Base>::Independent(VectorAD &x)
{
	// check VectorAD is Simple Vector class with AD<Base> elements
	CheckSimpleVector< AD<Base>, VectorAD>();

	// dimension of the domain space
	size_t n = x.size();
	CPPAD_ASSERT_KNOWN(
		n > 0,
		"Indepdendent: the argument vector x has zero size"
	);
	CPPAD_ASSERT_UNKNOWN( Rec_.num_rec_var() == 0 );

	// mark the beginning of the tape and skip the first variable index 
	// (zero) because parameters use taddr zero
	CPPAD_ASSERT_NARG_NRES(BeginOp, 0, 1);
	Rec_.PutOp(BeginOp);

	// place each of the independent variables in the tape
	CPPAD_ASSERT_NARG_NRES(InvOp, 0, 1);
	size_t j;
	for(j = 0; j < n; j++)
	{	// tape address for this independent variable
		x[j].taddr_ = Rec_.PutOp(InvOp);
		x[j].tape_id_    = id_;
		CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == j+1 );
		CPPAD_ASSERT_UNKNOWN( Variable(x[j] ) );
	}

	// done specifying all of the independent variables
	size_independent_ = n;
}
예제 #26
0
Vector ADFun<Base>::Jacobian(const Vector &x)
{	size_t i;
	size_t n = Domain();
	size_t m = Range();

	CPPAD_ASSERT_KNOWN(
		size_t(x.size()) == n,
		"Jacobian: length of x not equal domain dimension for F"
	);

	// point at which we are evaluating the Jacobian
	Forward(0, x);

	// work factor for forward mode
	size_t workForward = n;

	// work factor for reverse mode
	size_t workReverse = 0;
	for(i = 0; i < m; i++)
	{	if( ! Parameter(i) )
			++workReverse;
	}

	// choose the method with the least work
	Vector jac( n * m );
	if( workForward <= workReverse )
		JacobianFor(*this, x, jac);
	else	JacobianRev(*this, x, jac);

	return jac;
}
예제 #27
0
Float RombergOne(
	Fun           &F , 
	const Float   &a , 
	const Float   &b , 
	size_t         n , 
	size_t         p ,
	Float         &e )
{
	size_t ipow2 = 1;
	size_t k, i;
	Float pow2, sum, x; 

	Float  zero  = Float(0);
	Float  two   = Float(2);

	// check specifications for a NumericType
	CheckNumericType<Float>();

	CPPAD_ASSERT_KNOWN(
		n >= 2,
		"RombergOne: n must be greater than or equal 2"
	);
	CppAD::vector<Float> r(n);

	//  set r[i] = trapazoidal rule with 2^i intervals in [a, b]
	r[0]  = ( F(a) + F(b) ) * (b - a) / two; 
	for(i = 1; i < n; i++)
	{	ipow2 *= 2;
		// there must be a conversion from int to any numeric type
		pow2   = Float(int(ipow2)); 
		sum    = zero;
		for(k = 1; k < ipow2; k += 2)
		{	// start = a + (b-a)/pow2, increment = 2*(b-a)/pow2
			x    = ( (pow2 - Float(int(k))) * a + k * b ) / pow2;
			sum  = sum + F(x);
		}
		// combine function evaluations in sum with those in T[i-1]
		r[i] = r[i-1] / two + sum * (b - a) / pow2;
	}

	// now compute the higher order estimates
	size_t ipow4    = 1;   // order of accuract for previous estimate
	Float pow4, pow4minus;
	for(i = 0; i < p; i++)
	{	// compute estimate accurate to O[ step^(2*(i+1)) ]
		// put resutls in r[n-1], r[n-2], ... , r[n-i+1]
		ipow4    *= 4;
		pow4      = Float(int(ipow4));
		pow4minus = Float(ipow4-1);
		for(k = n-1; k > i; k--)
			r[k] = ( pow4 * r[k] - r[k-1] ) / pow4minus;
	}

	// error estimate for r[n]
	e = r[n-1] - r[n-2];
	if( e < zero )
		e = - e;
	return r[n-1];
}
예제 #28
0
	/// set row and column for a possibly non-zero element
	void set(size_t k, size_t r, size_t c)
	{	CPPAD_ASSERT_KNOWN(
			k < nnz_,
			"The index k is not less than nnz in sparse_rc::set"
		);
		CPPAD_ASSERT_KNOWN(
			r < nr_,
			"The index r is not less than nr in sparse_rc::set"
		);
		CPPAD_ASSERT_KNOWN(
			c < nc_,
			"The index c is to not less than nc in sparse_rc::set"
		);
		row_[k] = r;
		col_[k] = c;
		//
	}
예제 #29
0
파일: pow_op.hpp 프로젝트: kaskr/CppAD
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);
}
예제 #30
0
파일: vector.hpp 프로젝트: barak/cppad
 // --------------------------------------------------------------------
 /// constant element access; i.e., we cannot change this element value
 const Type& operator[](
     /// element index, must be less than length and convertable to size_t
     size_t i
 ) const
 {   CPPAD_ASSERT_KNOWN(
         i < length_,
         "vector: index greater than or equal vector size"
     );
     return data_[i];
 }