예제 #1
0
static int xconvert(const char* x, pod_vector<T>& out, const char** errPos, int sep) {
	if (sep == 0) { sep = Potassco::def_sep; }
	typename pod_vector<T>::size_type sz = out.size();
	std::size_t t = Potassco::convert_seq<T>(x, out.max_size() - sz, std::back_inserter(out), static_cast<char>(sep), errPos);
	if (!t) { out.resize(sz); }
	return static_cast<int>(t);
}
예제 #2
0
	void reverse_cskip(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;
		CPPAD_ASSERT_UNKNOWN( op_       == op );
		CPPAD_ASSERT_UNKNOWN( op_arg    == op_arg_ );
		CPPAD_ASSERT_UNKNOWN( op_index  == op_index_ );
		CPPAD_ASSERT_UNKNOWN( var_index == var_index_ );

		CPPAD_ASSERT_UNKNOWN( op == CSkipOp );
		CPPAD_ASSERT_UNKNOWN( NumArg(CSkipOp) == 0 );
		/*
		The variables that need fixing are op_arg_ and op_arg. Currently, 
		op_arg points first arugment for the previous operator.
		*/
		--op_arg;
		op_arg      = op_arg_    -= (op_arg[0] + 4);

		CPPAD_ASSERT_UNKNOWN(
		op_arg[1] + op_arg[2] == op_arg[ 3 + op_arg[1] + op_arg[2] ]
		);
		CPPAD_ASSERT_UNKNOWN( op_index_  < op_rec_.size() );
		CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ );
		CPPAD_ASSERT_UNKNOWN( var_index_  < num_var_rec_ );
	}
예제 #3
0
	/// Approximate amount of memory used by the recording 
	size_t Memory(void) const
	{	return op_rec_.capacity()        * sizeof(CPPAD_OP_CODE_TYPE) 
		     + vecad_ind_rec_.capacity() * sizeof(size_t)
		     + op_arg_rec_.capacity()    * sizeof(addr_t)
		     + par_rec_.capacity()       * sizeof(Base)
		     + text_rec_.capacity()      * sizeof(char);
	}
예제 #4
0
	void reverse_csum(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;
		CPPAD_ASSERT_UNKNOWN( op_       == op );
		CPPAD_ASSERT_UNKNOWN( op_arg    == op_arg_ );
		CPPAD_ASSERT_UNKNOWN( op_index  == op_index_ );
		CPPAD_ASSERT_UNKNOWN( var_index == var_index_ );

		CPPAD_ASSERT_UNKNOWN( op == CSumOp );
		CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 );
		/*
		The variables that need fixing are op_arg_ and op_arg. Currently, 
		op_arg points to the last argument for the previous operator.
		*/
		// last argument for this csum operation
		--op_arg;
		// first argument for this csum operation
		op_arg      = op_arg_    -= (op_arg[0] + 4);
		// now op_arg points to the first argument for this csum operator

		CPPAD_ASSERT_UNKNOWN(
		op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ]
		);

		CPPAD_ASSERT_UNKNOWN( op_index_  < op_rec_.size() );
		CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ );
		CPPAD_ASSERT_UNKNOWN( var_index_  < num_var_rec_ );
	}
예제 #5
0
	/*!
	Fetch the next operator during a reverse sweep.

	Use reverse_start to initialize to reverse play back.
	The first call to reverse_next (after reverse_start) will give the 
	last operator in the recording.
	We use the notation reverse_routine to denote the set
	reverse_start, reverse_next, reverse_csum, reverse_cskip.

	\param op [in,out]
	The input value of \c op must be its output value from the 
	previous call to a reverse_routine.
	Its output value is the next operator in the recording (in reverse order).
	The last operator sets op equal to EndOp.

	\param op_arg [in,out]
	The input value of \c op_arg must be its output value from the 
	previous call to a reverse_routine.
	Its output value is the
	beginning of the vector of argument indices for this operation.
	The last operator sets op_arg equal to the beginning of the 
	argument indices for the entire recording.
	For speed, \c reverse_next does not check for the special cases
	<tt>op == CSumOp</tt> or <tt>op == CSkipOp</tt>. In these cases, the other
	return values from \c reverse_next must be corrected by a call to 
	\c reverse_csum or \c reverse_cskip respectively.


	\param op_index [in,out]
	The input value of \c op_index must be its output value from the 
	previous call to a reverse_routine.
	Its output value
	is the index of this operator in the recording. Thus the output
	value following the previous call to reverse_start is equal to 
	the number of variables in the recording minus one.
	In addition, the output value decreases by one with each call to
	reverse_next.
	The last operator sets op_index equal to 0.

	\param var_index [in,out]
	The input value of \c var_index must be its output value from the 
	previous call to a reverse_routine.
	Its output value is the
	index of the primary (last) result corresponding to the operator op.
	The last operator sets var_index equal to 0 (corresponding to BeginOp
	at beginning of operation sequence).
	*/
	void reverse_next(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;
		CPPAD_ASSERT_UNKNOWN( op_       == op );
		CPPAD_ASSERT_UNKNOWN( op_arg    == op_arg_ );
		CPPAD_ASSERT_UNKNOWN( op_index  == op_index_ );
		CPPAD_ASSERT_UNKNOWN( var_index == var_index_ );

		// index of the last result for the next operator
		CPPAD_ASSERT_UNKNOWN( var_index_ >= NumRes(op_) );
		var_index   = var_index_ -= NumRes(op_);

		// next operator
		CPPAD_ASSERT_UNKNOWN( op_index_  > 0 );
		op_index    = --op_index_;                                  // index
		op          = op_         = OpCode( op_rec_[ op_index_ ] ); // value

		// first argument for next operator
		op_arg      = op_arg_    -= NumArg(op);
		CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ );
		CPPAD_ASSERT_UNKNOWN( 
			op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() 
		);
	}
예제 #6
0
	/*!
	Correct \c forward_next return values when <tt>op == CSkipOp</tt>.

	\param op [in]
	The input value of op must be the return value from the previous
	call to \c forward_next and must be \c CSkipOp. It is not modified.

	\param op_arg [in,out]
	The input value of \c op_arg must be the return value from the 
	previous call to \c forward_next. Its output value is the
	beginning of the vector of argument indices for the next operation.

	\param op_index [in]
	The input value of \c op_index does must be the return value from the
	previous call to \c forward_next. Its is not modified.

	\param var_index [in,out]
	The input value of \c var_index must be the return value from the
	previous call to \c forward_next. It is not modified.
	*/
	void forward_cskip(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;
		CPPAD_ASSERT_UNKNOWN( op_       == op );
		CPPAD_ASSERT_UNKNOWN( op_arg    == op_arg_ );
		CPPAD_ASSERT_UNKNOWN( op_index  == op_index_ );
		CPPAD_ASSERT_UNKNOWN( var_index == var_index_ );

		CPPAD_ASSERT_UNKNOWN( op == CSkipOp );
		CPPAD_ASSERT_UNKNOWN( NumArg(CSkipOp) == 0 );
		CPPAD_ASSERT_UNKNOWN(
		op_arg[4] + op_arg[5] == op_arg[ 6 + op_arg[4] + op_arg[5] ]
		);
		/*
		The only thing that really needs fixing is op_arg_.
		Actual number of arugments for this operator is
			7 + op_arg[4] + op_arg[5]
 		We must change op_arg_ so that when you add NumArg(CSkipOp)
		you get first argument for next operator in sequence.
		*/
		op_arg  = op_arg_  += 7 + op_arg[4] + op_arg[5];

		CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ );
		CPPAD_ASSERT_UNKNOWN( 
			op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size()
		);
		CPPAD_ASSERT_UNKNOWN( var_index_  < num_var_rec_ );
	}
예제 #7
0
	/// Approximate amount of memory used by the recording 
	size_t Memory(void) const
	{	return rec_op_.capacity()        * sizeof(CPPAD_OP_CODE_TYPE) 
		     + rec_vecad_ind_.capacity() * sizeof(size_t)
		     + rec_op_arg_.capacity()    * sizeof(addr_t)
		     + rec_par_.capacity()       * sizeof(Base)
		     + rec_text_.capacity()      * sizeof(char);
	}
예제 #8
0
파일: sparse_pack.hpp 프로젝트: ZiiCee/OPTI
	/*! Change number of sets, set end, and initialize all sets as empty

	If \c n_set_in is zero, any memory currently allocated for this object 
	is freed. Otherwise, new memory may be allocated for the sets (if needed).

	\param n_set_in
	is the number of sets in this vector of sets.

	\param end_in
	is the maximum element plus one (the minimum element is 0).
	*/
	void resize(size_t n_set_in, size_t end_in) 
	{
		n_set_          = n_set_in;
		end_            = end_in;
		if( n_set_ == 0 )
		{	data_.free();
			return;
		}
		// now start a new vector with empty sets
		Pack zero(0);
		data_.erase();

		n_pack_         = ( 1 + (end_ - 1) / n_bit_ );
		size_t i        = n_set_ * n_pack_;

		if( i > 0 )
		{	data_.extend(i);
			while(i--)
				data_[i] = zero;
		}

		// values that signify past end of list
		next_index_   = n_set_;
		next_element_ = end_;
	}
예제 #9
0
	/*!
	Fetch the next operator during a forward sweep.

	Use forward_start to initialize to the first operator; i.e.,
	the BeginOp at the beginning of the recording. 
	We use the notation forward_routine to denote the set
	forward_start, forward_next, forward_csum, forward_cskip.

	\param op [in,out]
	The input value of \c op must be its output value from the 
	previous call to a forward_routine.
	Its output value is the next operator in the recording.
	For speed, \c forward_next does not check for the special cases
	where  <tt>op == CSumOp</tt> or <tt>op == CSkipOp</tt>. In these cases, 
	the other return values from \c forward_next must be corrected by a call 
	to \c forward_csum or \c forward_cskip respectively.

	\param op_arg [in,out]
	The input value of \c op_arg must be its output value form the
	previous call to a forward routine. 
	Its output value is the
	beginning of the vector of argument indices for this operation.

	\param op_index [in,out]
	The input value of \c op_index must be its output value form the
	previous call to a forward routine. 
	Its output value is the index of the next operator in the recording. 
	Thus the ouput value following the previous call to forward_start is one.
	In addition,
	the output value increases by one with each call to forward_next. 

	\param var_index [in,out]
	The input value of \c var_index must be its output value form the
	previous call to a forward routine. 
	Its output value is the
	index of the primary (last) result corresponding to the operator op.
	*/
	void forward_next(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;
		CPPAD_ASSERT_UNKNOWN( op_       == op );
		CPPAD_ASSERT_UNKNOWN( op_arg    == op_arg_ );
		CPPAD_ASSERT_UNKNOWN( op_index  == op_index_ );
		CPPAD_ASSERT_UNKNOWN( var_index == var_index_ );

		// index for the next operator 
		op_index    = ++op_index_;

		// first argument for next operator 
		op_arg      = op_arg_    += NumArg(op_);

		// next operator
		op          = op_         = OpCode( op_rec_[ op_index_ ] );

		// index for last result for next operator
		var_index   = var_index_ += NumRes(op);
		

		CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ );
		CPPAD_ASSERT_UNKNOWN( 
			op_arg_ + NumArg(op) <= op_arg_rec_.data() + op_arg_rec_.size() 
		);
		CPPAD_ASSERT_UNKNOWN( var_index_  < num_var_rec_ );
	}
예제 #10
0
	/// Fetch a rough measure of amount of memory used to store recording
	/// (just lengths, not capacities). 
	size_t Memory(void) const
	{	return rec_op_.size()        * sizeof(OpCode) 
		     + rec_op_arg_.size()    * sizeof(addr_t)
		     + rec_par_.size()       * sizeof(Base)
		     + rec_text_.size()      * sizeof(char)
		     + rec_vecad_ind_.size() * sizeof(addr_t)
		;
	}
예제 #11
0
	/// Fetch a rough measure of amount of memory used to store recording
	/// (just lengths, not capacities). 
	size_t Memory(void) const
	{	return op_rec_.size()        * sizeof(OpCode) 
		     + op_arg_rec_.size()    * sizeof(addr_t)
		     + par_rec_.size()       * sizeof(Base)
		     + text_rec_.size()      * sizeof(char)
		     + vecad_ind_rec_.size() * sizeof(addr_t)
		;
	}
예제 #12
0
	/*!
	Frees all information in recording.

	Frees the operation sequence store in this recording 
	(the operation sequence is empty after this operation).
	The buffers used to store the current recording are returned
	to the system (so as to conserve on memory).
	*/
	void free(void)
	{	num_rec_var_  = 0;
		rec_op_.free();
		rec_vecad_ind_.free();
		rec_op_arg_.free();
		rec_par_.free();
		rec_text_.free();
	}
예제 #13
0
	/*!
	Frees all information in recording.

	Frees the operation sequence store in this recording 
	(the operation sequence is empty after this operation).
	The buffers used to store the current recording are returned
	to the system (so as to conserve on memory).
	*/
	void free(void)
	{	num_var_rec_     = 0;
		num_load_op_rec_ = 0;
		op_rec_.free();
		vecad_ind_rec_.free();
		op_arg_rec_.free();
		par_rec_.free();
		text_rec_.free();
	}
예제 #14
0
	void reverse_start(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{
		op_arg      = op_arg_     = op_arg_rec_.data() + op_arg_rec_.size();
		op_index    = op_index_   = op_rec_.size() - 1; 
		var_index   = var_index_  = num_var_rec_ - 1;
		op          = op_         = OpCode( op_rec_[ op_index_ ] );
		CPPAD_ASSERT_UNKNOWN( op_ == EndOp );
		CPPAD_ASSERT_NARG_NRES(op, 0, 0);
		return;
	}
예제 #15
0
	/// Erase all information in an operation sequence player.
	void Erase(void)
	{	
		num_rec_var_       = 0;
		num_rec_vecad_vec_ = 0;

		rec_op_.erase();
		rec_vecad_ind_.erase();
		rec_op_arg_.erase();
		rec_par_.erase();
		rec_text_.erase();
	}
예제 #16
0
	/// Erase all information in an operation sequence player.
	void Erase(void)
	{	
		num_var_rec_       = 0;
		num_load_op_rec_   = 0;
		num_vecad_vec_rec_ = 0;

		op_rec_.erase();
		vecad_ind_rec_.erase();
		op_arg_rec_.erase();
		par_rec_.erase();
		text_rec_.erase();
	}
예제 #17
0
	void start_reverse(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{
		op_arg_     = rec_op_arg_.size();                // index
		op_arg      = op_arg_ + rec_op_arg_.data();      // pointer

		op_index    = op_index_   = rec_op_.size() - 1; 
		var_index   = var_index_  = num_rec_var_ - 1;

		op          = op_         = OpCode( rec_op_[ op_index_ ] );
		CPPAD_ASSERT_UNKNOWN( op_ == EndOp );
		CPPAD_ASSERT_NARG_NRES(op, 0, 0);
		return;
	}
예제 #18
0
void get_internal_sparsity(
    bool                          transpose         ,
    const pod_vector<size_t>&     internal_index    ,
    const InternalSparsity&       internal_pattern  ,
    vector<bool>&                 pattern_out       )
{   typedef typename InternalSparsity::const_iterator iterator;
    // number variables
    size_t nr = internal_index.size();
    //
    // column size of interanl sparstiy pattern
    size_t nc = internal_pattern.end();
    //
    pattern_out.resize(nr * nc);
    for(size_t ij = 0; ij < nr * nc; ij++)
        pattern_out[ij] = false;
    //
    for(size_t i = 0; i < nr; i++)
    {   CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() );
        iterator itr(internal_pattern, internal_index[i]);
        size_t j = *itr;
        while( j < nc )
        {   if( transpose )
                pattern_out[j * nr + i] = true;
            else
                pattern_out[i * nc + j] = true;
            j = *(++itr);
        }
    }
    return;
}
예제 #19
0
void get_internal_sparsity(
    bool                          transpose         ,
    const pod_vector<size_t>&     internal_index    ,
    const InternalSparsity&       internal_pattern  ,
    vector< std::set<size_t> >&   pattern_out       )
{   typedef typename InternalSparsity::const_iterator iterator;
    // number variables
    size_t nr = internal_index.size();
    //
    // column size of interanl sparstiy pattern
    size_t nc = internal_pattern.end();
    //
    if( transpose )
        pattern_out.resize(nc);
    else
        pattern_out.resize(nr);
    for(size_t k = 0; k < pattern_out.size(); k++)
        pattern_out[k].clear();
    //
    for(size_t i = 0; i < nr; i++)
    {   CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() );
        iterator itr(internal_pattern, internal_index[i]);
        size_t j = *itr;
        while( j < nc )
        {   if( transpose )
                pattern_out[j].insert(i);
            else
                pattern_out[i].insert(j);
            j = *(++itr);
        }
    }
    return;
}
예제 #20
0
	/*!  
 	Moving an operation sequence from a recorder to a player
 
	\param rec
	the object that was used to record the operation sequence.  After this 
	operation, the state of the recording is no longer defined. For example,
	the \c pod_vector member variables in \c this have been swapped with
	\c rec .
 	*/
	void get(recorder<Base>& rec)
	{	size_t i;

		// just set size_t values
		num_var_rec_        = rec.num_var_rec_;
		num_load_op_rec_    = rec.num_load_op_rec_; 

		// op_rec_
		op_rec_.swap(rec.op_rec_);

		// vec_ind_rec_
		vecad_ind_rec_.swap(rec.vecad_ind_rec_);

		// op_arg_rec_
		op_arg_rec_.swap(rec.op_arg_rec_);

		// par_rec_
		par_rec_.swap(rec.par_rec_);

		// text_rec_
		text_rec_.swap(rec.text_rec_);

		// set the number of VecAD vectors
		num_vecad_vec_rec_ = 0;
		for(i = 0; i < vecad_ind_rec_.size(); i += vecad_ind_rec_[i] + 1)
			num_vecad_vec_rec_++;

		// vecad_ind_rec_ contains size of each VecAD followed by
		// the parameter indices used to iniialize it.
		CPPAD_ASSERT_UNKNOWN( i == vecad_ind_rec_.size() );
	}
예제 #21
0
	/*!  
 	Moving an operation sequence from a recorder to a player
 
	\param rec
	the object that was used to record the operation sequence.  After this 
	operation, the state of the recording is no longer defined. For example,
	the \c pod_vector member variables in \c this have been swapped with
	\c rec .
 	*/
	void get(recorder<Base>& rec)
	{	size_t i;

		// Var
		num_rec_var_        = rec.num_rec_var_;

		// Op
		rec_op_.swap(rec.rec_op_);

		// VecInd
		rec_vecad_ind_.swap(rec.rec_vecad_ind_);

		// Arg
		rec_op_arg_.swap(rec.rec_op_arg_);

		// Par
		rec_par_.swap(rec.rec_par_);

		// Txt
		rec_text_.swap(rec.rec_text_);

		// set the number of VecAD vectors
		num_rec_vecad_vec_ = 0;
		for(i = 0; i < rec_vecad_ind_.size(); i += rec_vecad_ind_[i] + 1)
			num_rec_vecad_vec_++;
		// rec_vecad_ind_ contains size of each VecAD followed by
		// the parameter indices used to iniialize it.
		CPPAD_ASSERT_UNKNOWN( i == rec_vecad_ind_.size() );
	}
예제 #22
0
	/*! Change number of sets, set end, and initialize all sets as empty

	Any memory currently allocated for this object is freed. If both
	\a n_set_in and \a end_in are non-zero new memory is allocated, otherwise
	no new memory is allocated for the object.

	\param n_set_in
	is the number of sets in this vector of sets.

	\param end_in
	is the maximum element plus one (the minimum element is 0).
	*/
	void resize(size_t n_set_in, size_t end_in) 
	{	Pack zero(0);
		data_.erase();

		n_set_          = n_set_in;
		end_            = end_in;
		n_pack_         = ( 1 + (end_ - 1) / n_bit_ );
		size_t i        = n_set_ * n_pack_;

		if( i > 0 )
		{	data_.extend(i);
			while(i--)
				data_[i] = zero;
		}

		// values that signify past end of list
		next_index_   = n_set_;
		next_element_ = end_;
	}
예제 #23
0
	void reverse_csum(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;
		CPPAD_ASSERT_UNKNOWN( op == CSumOp );
		CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 );
		/*
		The things needs fixing are op_arg_ and op_arg. Currently, 
		op_arg points first arugment for the previous operator.
		*/
		--op_arg;
		op_arg_    -= (op_arg[0] + 4);
		op_arg      = op_arg_ + rec_op_arg_.data();

		CPPAD_ASSERT_UNKNOWN(
		op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ]
		);
		CPPAD_ASSERT_UNKNOWN( op_index_  < rec_op_.size() );
		CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() );
		CPPAD_ASSERT_UNKNOWN( var_index_  < num_rec_var_ );
	}
예제 #24
0
	void next_forward(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;

		// index for the next operator 
		op_index    = ++op_index_;

		// first argument for next operator 
		op_arg_    += NumArg(op_);                   // index
		op_arg      = op_arg_ + rec_op_arg_.data();  // pointer

		// next operator
		op          = op_         = OpCode( rec_op_[ op_index_ ] );

		// index for last result for next operator
		var_index   = var_index_ += NumRes(op);

		CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() );
		CPPAD_ASSERT_UNKNOWN( var_index_  < num_rec_var_ );
	}
예제 #25
0
void set_internal_sparsity(
    bool                               zero_empty       ,
    bool                               input_empty      ,
    bool                               transpose        ,
    const pod_vector<size_t>&          internal_index   ,
    InternalSparsity&                  internal_pattern ,
    const vector< std::set<size_t> >&  pattern_in       )
{   size_t nr = internal_index.size();
    size_t nc = internal_pattern.end();
# ifndef NDEBUG
    if( input_empty ) for(size_t i = 0; i < nr; i++)
    {   size_t i_var = internal_index[i];
        CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 );
    }
# endif
    if( transpose )
    {   CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nc );
        for(size_t j = 0; j < nc; j++)
        {   std::set<size_t>::const_iterator itr( pattern_in[j].begin() );
            while( itr != pattern_in[j].end() )
            {   size_t i = *itr;
                size_t i_var = internal_index[i];
                CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );
                CPPAD_ASSERT_UNKNOWN( j < nc );
                bool ignore  = zero_empty && i_var == 0;
                if( ! ignore )
                    internal_pattern.post_element( i_var, j);
                ++itr;
            }
        }
    }
    else
    {   CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr );
        for(size_t i = 0; i < nr; i++)
        {   std::set<size_t>::const_iterator itr( pattern_in[i].begin() );
            while( itr != pattern_in[i].end() )
            {   size_t j = *itr;
                size_t i_var = internal_index[i];
                CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );
                CPPAD_ASSERT_UNKNOWN( j < nc );
                bool ignore  = zero_empty && i_var == 0;
                if( ! ignore )
                    internal_pattern.post_element( i_var, j);
                ++itr;
            }
        }
    }
    // process posts
    for(size_t i = 0; i < nr; ++i)
        internal_pattern.process_post( internal_index[i] );
    return;
}
예제 #26
0
	/*!
	Start a play back of the recording during a forward sweep.

	Use repeated calls to forward_next to play back one operator at a time.

	\param op [out]
	The input value of \c op does not matter. Its output value is the
	first operator in the recording; i.e., BeginOp.

	\param op_arg [out]
	The input value of \c op_arg does not matter. Its output value is the
	beginning of the vector of argument indices for the first operation;
	i.e., 0

	\param op_index [out]
	The input value of \c op_index does not matter. Its output value
	is the index of the next first operator in the recording; i.e., 0.

	\param var_index [out]
	The input value of \c var_index does not matter. Its output value is the
	index of the primary (last) result corresponding to the the first
	operator (which must be a BeginOp); i.e., 0.
	*/
	void forward_start(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{
		op        = op_          = OpCode( op_rec_[0] ); 
		op_arg    = op_arg_      = op_arg_rec_.data();
		op_index  = op_index_    = 0;
		var_index = var_index_   = 0;

		CPPAD_ASSERT_UNKNOWN( op_  == BeginOp );
		CPPAD_ASSERT_NARG_NRES(op_, 1, 1);

		return;
	}
예제 #27
0
void get_internal_sparsity(
    bool                          transpose         ,
    const pod_vector<size_t>&     internal_index    ,
    const InternalSparsity&       internal_pattern  ,
    sparse_rc<SizeVector>&        pattern_out        )
{   typedef typename InternalSparsity::const_iterator iterator;
    // number variables
    size_t nr = internal_index.size();
    // column size of interanl sparstiy pattern
    size_t nc = internal_pattern.end();
    // determine nnz, the number of possibly non-zero index pairs
    size_t nnz = 0;
    for(size_t i = 0; i < nr; i++)
    {   CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() );
        iterator itr(internal_pattern, internal_index[i]);
        size_t j = *itr;
        while( j < nc )
        {   ++nnz;
            j = *(++itr);
        }
    }
    // transposed
    if( transpose )
    {   pattern_out.resize(nc, nr, nnz);
        //
        size_t k = 0;
        for(size_t i = 0; i < nr; i++)
        {   iterator itr(internal_pattern, internal_index[i]);
            size_t j = *itr;
            while( j < nc )
            {   pattern_out.set(k++, j, i);
                j = *(++itr);
            }
        }
        return;
    }
    // not transposed
    pattern_out.resize(nr, nc, nnz);
    //
    size_t k = 0;
    for(size_t i = 0; i < nr; i++)
    {   iterator itr(internal_pattern, internal_index[i]);
        size_t j = *itr;
        while( j < nc )
        {   pattern_out.set(k++, i, j);
            j = *(++itr);
        }
    }
    return;
}
예제 #28
0
void set_internal_sparsity(
    bool                          zero_empty       ,
    bool                          input_empty      ,
    bool                          transpose        ,
    const pod_vector<size_t>&     internal_index   ,
    InternalSparsity&             internal_pattern ,
    const sparse_rc<SizeVector>&  pattern_in       )
{
    size_t nr = internal_index.size();
# ifndef NDEBUG
    size_t nc = internal_pattern.end();
    if( transpose )
    {   CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nc );
        CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nr );
    }
    else
    {   CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nr );
        CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nc );
    }
    if( input_empty ) for(size_t i = 0; i < nr; i++)
    {   size_t i_var = internal_index[i];
        CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 );
    }
# endif
    const SizeVector& row( pattern_in.row() );
    const SizeVector& col( pattern_in.col() );
    size_t nnz = row.size();
    for(size_t k = 0; k < nnz; k++)
    {   size_t r = row[k];
        size_t c = col[k];
        if( transpose )
            std::swap(r, c);
        //
        size_t i_var = internal_index[r];
        CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );
        CPPAD_ASSERT_UNKNOWN( c < nc );
        bool ignore  = zero_empty && i_var == 0;
        if( ! ignore )
            internal_pattern.post_element( internal_index[r], c );
    }
    // process posts
    for(size_t i = 0; i < nr; ++i)
        internal_pattern.process_post( internal_index[i] );
}
예제 #29
0
	void next_reverse(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;

		// index of the last result for the next operator
		CPPAD_ASSERT_UNKNOWN( var_index_ >= NumRes(op_) );
		var_index   = var_index_ -= NumRes(op_);

		// next operator
		CPPAD_ASSERT_UNKNOWN( op_index_  > 0 );
		op_index    = --op_index_;                                  // index
		op          = op_         = OpCode( rec_op_[ op_index_ ] ); // value

		// first argument for next operator
		CPPAD_ASSERT_UNKNOWN( op_arg_ >= NumArg(op)  );
		op_arg_    -= NumArg(op);                            // index
		op_arg      = op_arg_ + rec_op_arg_.data();          // pointer
	}
예제 #30
0
	/*!
	Correct \c next_forward return values when <tt>op == CSumOp</tt>.

	\param op
	The input value of op must be the return value from the previous
	call to \c next_forward and must be \c CSumOp.

	\param op_arg
	The input value of *op_arg must be the return value from the 
	previous call to \c next_forward. Its output value is the
	beginning of the vector of argument indices for this operation.

	\param op_index
	The input value of op_index does must be the return value from the
	previous call to \c next_forward. Its output value
	is the index of this operator in the recording. 

	\param var_index
	The input value of var_index must be the return value from the
	previous call to \c next_forward. Its output value is the
	index of the primary (last) result corresponding to this.
	*/
	void forward_csum(
	OpCode& op, const addr_t*& op_arg, size_t& op_index, size_t& var_index)
	{	using CppAD::NumRes;
		using CppAD::NumArg;
		CPPAD_ASSERT_UNKNOWN( op == CSumOp );
		CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 );
		CPPAD_ASSERT_UNKNOWN(
		op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ]
		);
		/*
		The only thing that really needs fixing is op_arg_.
		Actual number of arugments for this operator is
			op_arg[0] + op_arg[1] + 4.
 		We must change op_arg_ so that when you add NumArg(CSumOp)
		you get first argument for next operator in sequence.
		*/
		op_arg_    += op_arg[0] + op_arg[1] + 4;

		CPPAD_ASSERT_UNKNOWN( op_arg_ + NumArg(op) <= rec_op_arg_.size() );
		CPPAD_ASSERT_UNKNOWN( var_index_  < num_rec_var_ );
	}