void ForSparseJacSet(
	bool                        transpose        , 
	size_t                      q                , 
	const VectorSet&            r                ,
	VectorSet&                  s                ,
	size_t                      total_num_var    ,
	CppAD::vector<size_t>&      dep_taddr        ,
	CppAD::vector<size_t>&      ind_taddr        ,
	CppAD::player<Base>&        play             ,
	CPPAD_INTERNAL_SPARSE_SET&  for_jac_sparsity )
{
	// temporary indices
	size_t i, j;
	std::set<size_t>::const_iterator itr;

	// range and domain dimensions for F
	size_t m = dep_taddr.size();
	size_t n = ind_taddr.size();

	CPPAD_ASSERT_KNOWN(
		q > 0,
		"RevSparseJac: q is not greater than zero"
	);
	CPPAD_ASSERT_KNOWN(
		size_t(r.size()) == n || transpose,
		"RevSparseJac: size of r is not equal to n and transpose is false."
	);
	CPPAD_ASSERT_KNOWN(
		size_t(r.size()) == q || ! transpose,
		"RevSparseJac: size of r is not equal to q and transpose is true."
	);

	// allocate memory for the requested sparsity calculation
	for_jac_sparsity.resize(total_num_var, q);

	// set values corresponding to independent variables
	if( transpose )
	{	for(i = 0; i < q; i++)
		{	// add the elements that are present
			itr = r[i].begin();
			while( itr != r[i].end() )
			{	j = *itr++;
				CPPAD_ASSERT_KNOWN(
				j < n,
				"ForSparseJac: transpose is true and element of the set\n"
				"r[j] has value greater than or equal n."
				);
				CPPAD_ASSERT_UNKNOWN( ind_taddr[j] < total_num_var );
				// operator for j-th independent variable
				CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp );
				for_jac_sparsity.add_element( ind_taddr[j], i);
			}
		}
	}
	else
	{	for(i = 0; i < n; i++)
		{	CPPAD_ASSERT_UNKNOWN( ind_taddr[i] < total_num_var );
			// ind_taddr[i] is operator taddr for i-th independent variable
			CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[i] ) == InvOp );

			// add the elements that are present
			itr = r[i].begin();
			while( itr != r[i].end() )
			{	j = *itr++;
				CPPAD_ASSERT_KNOWN(
					j < q,
					"ForSparseJac: an element of the set r[i] "
					"has value greater than or equal q."
				);
				for_jac_sparsity.add_element( ind_taddr[i], j);
			}
		}
	}
	// evaluate the sparsity patterns
	ForJacSweep(
		n,
		total_num_var,
		&play,
		for_jac_sparsity
	);

	// return values corresponding to dependent variables
	CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m || transpose );
	CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || ! transpose );
	for(i = 0; i < m; i++)
	{	CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var );

		// extract results from for_jac_sparsity
		// and add corresponding elements to sets in s
		CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end() == q );
		for_jac_sparsity.begin( dep_taddr[i] );
		j = for_jac_sparsity.next_element();
		while( j < q )
		{	if( transpose )
				s[j].insert(i);
			else	s[i].insert(j);
			j = for_jac_sparsity.next_element();
		}
	}
}
void ForSparseJacBool(
	bool                   transpose        ,
	size_t                 q                , 
	const VectorSet&       r                ,
	VectorSet&             s                ,
	size_t                 total_num_var    ,
	CppAD::vector<size_t>& dep_taddr        ,
	CppAD::vector<size_t>& ind_taddr        ,
	CppAD::player<Base>&   play             ,
	sparse_pack&           for_jac_sparsity )
{
	// temporary indices
	size_t i, j;

	// range and domain dimensions for F
	size_t m = dep_taddr.size();
	size_t n = ind_taddr.size();

	CPPAD_ASSERT_KNOWN(
		q > 0,
		"ForSparseJac: q is not greater than zero"
	);
	CPPAD_ASSERT_KNOWN( 
		size_t(r.size()) == n * q,
		"ForSparseJac: size of r is not equal to\n"
		"q times domain dimension for ADFun object."
	);

	// allocate memory for the requested sparsity calculation result
	for_jac_sparsity.resize(total_num_var, q);

	// set values corresponding to independent variables
	for(i = 0; i < n; i++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr[i] < total_num_var );
		// ind_taddr[i] is operator taddr for i-th independent variable
		CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[i] ) == InvOp );

		// set bits that are true
		if( transpose )
		{	for(j = 0; j < q; j++) if( r[ j * n + i ] )
				for_jac_sparsity.add_element( ind_taddr[i], j);
		}
		else
		{	for(j = 0; j < q; j++) if( r[ i * q + j ] )
				for_jac_sparsity.add_element( ind_taddr[i], j);
		}
	}

	// evaluate the sparsity patterns
	ForJacSweep(
		n,
		total_num_var,
		&play,
		for_jac_sparsity
	);

	// return values corresponding to dependent variables
	CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m * q );
	for(i = 0; i < m; i++)
	{	CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var );

		// extract the result from for_jac_sparsity
		if( transpose )
		{	for(j = 0; j < q; j++)
				s[ j * m + i ] = false;
		}
		else
		{	for(j = 0; j < q; j++)
				s[ i * q + j ] = false;
		}
		CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end() == q );
		for_jac_sparsity.begin( dep_taddr[i] );
		j = for_jac_sparsity.next_element();
		while( j < q )
		{	if( transpose )
				s[j * m + i] = true;
			else	s[i * q + j] = true;
			j = for_jac_sparsity.next_element();
		}
	}
}
예제 #3
0
			/**
			 * Accessor to vertices.
			 * @return	pointer to vertices collection.
			 */
			VectorSet* getVertices()
			{
				VectorSet* newVertices = new VectorSet();

				for(unsigned i = 0; i < vertices.size(); i++)
					newVertices->push_back(vertices[i]);
				return newVertices;
			}
예제 #4
0
			/**
			 * Method is used to rotate solid by vectors and angle.
			 * @param	a is rotate vector.
			 * @param	b is rotate vector.
			 * @param	angle is rotate angle value.
			 */
			void Rotate(const Vector& a, const Vector& b, float angle)
			{
				for(unsigned i = 0; i < vertices.size(); i++)
				{
					Vector v = vertices[i];
					v = VectorRotate(v, a, b, angle);
					vertices[i] = v;
				}
			}
예제 #5
0
			/**
			 * Method is used to translate solid by vector.
			 * @param	t is translate vector.
			 */
			void Translate(const Vector& t)
			{
				for(unsigned i = 0; i < vertices.size(); i++)
				{
					Vector v = vertices[i];
					v = v + t;
					vertices[i] = v;
				}
			}
예제 #6
0
			/**
			 * Method is used to scale solid by vector.
			 * @param	s id scale vector.
			 */
			void Scale(const Vector& s)
			{
				for(unsigned i = 0; i < vertices.size(); i++)
				{
					Vector v = vertices[i];
					v = VectorScale(v, s);
					vertices[i] = v;
				}
			}
예제 #7
0
void sparsity_user2internal(
	sparse_set&             internal  , 
	const VectorSet&        user      ,
	size_t                  n_row     ,
	size_t                  n_col     ,
	bool                    transpose )
{	CPPAD_ASSERT_UNKNOWN( n_row == size_t(user.size()) );

	CPPAD_ASSERT_KNOWN(
		size_t( user.size() ) == n_row,
		"Size of this vector of sets sparsity pattern is not equal "
		"the range dimension for the corresponding function."
	);

	size_t i, j;
	std::set<size_t>::const_iterator itr;

	// transposed pattern case
	if( transpose )
	{	internal.resize(n_col, n_row);
		for(i = 0; i < n_row; i++)
		{	itr = user[i].begin();
			while(itr != user[i].end())
			{	j = *itr++;
				CPPAD_ASSERT_UNKNOWN( j < n_col );
				internal.add_element(j, i);
			}
		}
		return;
	}

	// same pattern case
	internal.resize(n_row, n_col);
	for(i = 0; i < n_row; i++)
	{	itr = user[i].begin();
		while(itr != user[i].end())
		{	j = *itr++;
			CPPAD_ASSERT_UNKNOWN( j < n_col );
			internal.add_element(i, j);
		}
	}
	return;
}
예제 #8
0
void solve()
{
	borderSquares[xFace]->clear();
	borderSquares[yFace]->clear();
	borderSquares[zFace]->clear();

	for (vector<Face*>::iterator iter = faces.begin(); iter != faces.end(); iter++)
	{
		// derive all Squares of this face
		Face* f = *iter;
//		unsigned int startTime = getMicroSecs();
//		cout << "deriveSquares: ";
		f->deriveSquares();
//		cout << (getMicroSecs() - startTime) << endl;

		// put all squares of faces with the same orientation together
		VectorSet* squares = borderSquares[f->orientation];
		for(VectorSet::iterator iter = f->squares.begin(); iter != f->squares.end(); iter++)
		{
			Vertex v = *iter;
			squares->insert(v);
		}
	}

	VectorSet::iterator iter = borderSquares[zFace]->begin();
	Vertex min = *iter;
	while(iter != borderSquares[zFace]->end())
	{
		if(*iter < min)
			min = *iter;
		iter++;
	}

	blocks.clear();
	blocks.insert(min);
//	unsigned int startTime = getMicroSecs();
//		cout << "collectBlocks: ";
		collectBlocks(min);
//		cout << (getMicroSecs() - startTime) << endl;

	
	cout << "The bulk is composed of " << blocks.size() << " units.\n";
}
예제 #9
0
void RevSparseHesSet(
	bool                       transpose         ,
	size_t                     q                 ,
	const  VectorSet&          s                 ,
	VectorSet&                 h                 ,
	size_t                     num_var           ,
	CppAD::vector<size_t>&     dep_taddr         ,
	CppAD::vector<size_t>&     ind_taddr         ,
	CppAD::player<Base>&       play              ,
	CPPAD_INTERNAL_SPARSE_SET& for_jac_sparsity  )
{
	// temporary indices
	size_t i, j;
	std::set<size_t>::const_iterator itr;

	// check VectorSet is Simple Vector class with sets for elements
	CheckSimpleVector<std::set<size_t>, VectorSet>(
		one_element_std_set<size_t>(), two_element_std_set<size_t>()
	);

	// range and domain dimensions for F
# ifndef NDEBUG
	size_t m = dep_taddr.size();
# endif
	size_t n = ind_taddr.size();

	CPPAD_ASSERT_KNOWN(
		q == for_jac_sparsity.end(),
		"RevSparseHes: q is not equal to its value\n"
		"in the previous call to ForSparseJac with this ADFun object."
	);
	CPPAD_ASSERT_KNOWN(
		s.size() == 1,
		"RevSparseHes: size of s is not equal to one."
	);

	// Array that will hold reverse Jacobian dependency flag.
	// Initialize as true for the dependent variables.
	pod_vector<bool> RevJac;
	RevJac.extend(num_var);	
	for(i = 0; i < num_var; i++)
		RevJac[i] = false;
	itr = s[0].begin();
	while( itr != s[0].end() )
	{	i = *itr++;
		CPPAD_ASSERT_KNOWN(
			i < m,
			"RevSparseHes: an element of the set s[0] has value "
			"greater than or equal m"
		);
		CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < num_var );
		RevJac[ dep_taddr[i] ] = true;
	}


	// vector of sets that will hold reverse Hessain values
	CPPAD_INTERNAL_SPARSE_SET rev_hes_sparsity;
	rev_hes_sparsity.resize(num_var, q);

	// compute the Hessian sparsity patterns
	RevHesSweep(
		n,
		num_var,
		&play,
		for_jac_sparsity, 
		RevJac.data(),
		rev_hes_sparsity
	);

	// return values corresponding to independent variables
	// j is index corresponding to reverse mode partial
	CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == q || transpose );
	CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n || ! transpose );
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr[j] < num_var );
		CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == j + 1 );
		CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp );

		// extract the result from rev_hes_sparsity
		// and add corresponding elements to result sets in h
		CPPAD_ASSERT_UNKNOWN( rev_hes_sparsity.end() == q );
		rev_hes_sparsity.begin(j+1);
		i = rev_hes_sparsity.next_element();
		while( i < q )
		{	if( transpose )
				h[j].insert(i);
			else	h[i].insert(j);
			i = rev_hes_sparsity.next_element();
		}
	}

	return;
}
예제 #10
0
void RevSparseHesBool(
	bool                      transpose         ,
	size_t                    q                 ,
	const VectorSet&          s                 ,
	VectorSet&                h                 ,
	size_t                    num_var           ,
	CppAD::vector<size_t>&    dep_taddr         ,
	CppAD::vector<size_t>&    ind_taddr         ,
	CppAD::player<Base>&      play              ,
	sparse_pack&              for_jac_sparsity  )
{
	// temporary indices
	size_t i, j;

	// check Vector is Simple VectorSet class with bool elements
	CheckSimpleVector<bool, VectorSet>();

	// range and domain dimensions for F
	size_t m = dep_taddr.size();
	size_t n = ind_taddr.size();

	CPPAD_ASSERT_KNOWN(
		q == for_jac_sparsity.end(),
		"RevSparseHes: q is not equal to its value\n"
		"in the previous call to ForSparseJac with this ADFun object."
	);
	CPPAD_ASSERT_KNOWN(
		size_t(s.size()) == m,
		"RevSparseHes: size of s is not equal to\n"
		"range dimension for ADFun object."
	);

	// Array that will hold reverse Jacobian dependency flag.
	// Initialize as true for the dependent variables.
	pod_vector<bool> RevJac;
	RevJac.extend(num_var);	
	for(i = 0; i < num_var; i++)
		RevJac[i] = false;
	for(i = 0; i < m; i++)
	{	CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < num_var );
		RevJac[ dep_taddr[i] ] = s[i];
	}

	// vector of sets that will hold reverse Hessain values
	sparse_pack rev_hes_sparsity;
	rev_hes_sparsity.resize(num_var, q);

	// compute the Hessian sparsity patterns
	RevHesSweep(
		n,
		num_var,
		&play,
		for_jac_sparsity, 
		RevJac.data(),
		rev_hes_sparsity
	);

	// return values corresponding to independent variables
	CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n * q );
	for(j = 0; j < n; j++)
	{	for(i = 0; i < q; i++) 
		{	if( transpose )
				h[ j * q + i ] = false;
			else	h[ i * n + j ] = false;
		}
	}

	// j is index corresponding to reverse mode partial
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr[j] < num_var );

		// ind_taddr[j] is operator taddr for j-th independent variable
		CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == j + 1 );
		CPPAD_ASSERT_UNKNOWN( play.GetOp( ind_taddr[j] ) == InvOp );

		// extract the result from rev_hes_sparsity
		CPPAD_ASSERT_UNKNOWN( rev_hes_sparsity.end() == q );
		rev_hes_sparsity.begin(j + 1);
		i = rev_hes_sparsity.next_element();
		while( i < q )
		{	if( transpose )
				h[ j * q + i ] = true;
			else	h[ i * n + j ] = true;
			i = rev_hes_sparsity.next_element();
		}
	}

	return;
}
void ADFun<Base>::SparseJacobianCase(
	const std::set<size_t>&  set_type        ,
	const VectorBase&        x               , 
	const VectorSet&         p               ,
	VectorBase&              jac             )
{
	typedef CppAD::vector<size_t> SizeVector;
	typedef CppAD::vectorBool     VectorBool;
	size_t i, j, k;

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

	// some values
	const Base zero(0);
	const Base one(1);

	// check VectorSet is Simple Vector class with sets for elements
	CheckSimpleVector<std::set<size_t>, VectorSet>(
		one_element_std_set<size_t>(), two_element_std_set<size_t>()
	);

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

	CPPAD_ASSERT_KNOWN(
		x.size() == n,
		"SparseJacobian: size of x not equal domain dimension for f"
	); 
	CPPAD_ASSERT_KNOWN(
		p.size() == m,
		"SparseJacobian: using sets and size of p "
		"not equal range dimension for f"
	); 
	CPPAD_ASSERT_UNKNOWN(jac.size() == m * n); 

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

	// initialize the return value
	for(i = 0; i < m; i++)
		for(j = 0; j < n; j++)
			jac[i * n + j] = zero;

	// create a copy of the transpose sparsity pattern
	VectorSet q(n);
	std::set<size_t>::const_iterator itr_i, itr_j;
	for(i = 0; i < m; i++)
	{	itr_j = p[i].begin();
		while( itr_j != p[i].end() )
		{	j = *itr_j++;
			q[j].insert(i);
		}
	}	

	if( n <= m )
	{	// use forward mode ----------------------------------------
	
		// initial coloring
		SizeVector color(n);
		for(j = 0; j < n; j++)
			color[j] = j;

		// See GreedyPartialD2Coloring Algorithm Section 3.6.2 of
		// Graph Coloring in Optimization Revisited by
		// Assefaw Gebremedhin, Fredrik Maane, Alex Pothen
		VectorBool forbidden(n);
		for(j = 0; j < n; j++)
		{	// initial all colors as ok for this column
			for(k = 0; k < n; k++)
				forbidden[k] = false;

			// for each row connected to column j
			itr_i = q[j].begin();
			while( itr_i != q[j].end() )
			{	i = *itr_i++;
				// for each column connected to row i
				itr_j = p[i].begin();
				while( itr_j != p[i].end() )
				{	// if this is not j, forbid it
					k = *itr_j++;
					forbidden[ color[k] ] = (k != j);
				}
			}
			k = 0;
			while( forbidden[k] && k < n )
			{	k++;
				CPPAD_ASSERT_UNKNOWN( k < n );
			}
			color[j] = k;
		}
		size_t n_color = 1;
		for(k = 0; k < n; k++) 
			n_color = std::max(n_color, color[k] + 1);

		// direction vector for calls to forward
		VectorBase dx(n);

		// location for return values from Reverse
		VectorBase dy(m);

		// loop over colors
		size_t c;
		for(c = 0; c < n_color; c++)
		{	// determine all the colums with this color
			for(j = 0; j < n; j++)
			{	if( color[j] == c )
					dx[j] = one;
				else	dx[j] = zero;
			}
			// call forward mode for all these columns at once
			dy = Forward(1, dx);

			// set the corresponding components of the result
			for(j = 0; j < n; j++) if( color[j] == c )
			{	itr_i = q[j].begin();
				while( itr_i != q[j].end() )
				{	i = *itr_i++;
					jac[i * n + j] = dy[i];
				}
			}
		}
	}
	else
	{	// use reverse mode ----------------------------------------
	
		// initial coloring
		SizeVector color(m);
		for(i = 0; i < m; i++)
			color[i] = i;

		// See GreedyPartialD2Coloring Algorithm Section 3.6.2 of
		// Graph Coloring in Optimization Revisited by
		// Assefaw Gebremedhin, Fredrik Maane, Alex Pothen
		VectorBool forbidden(m);
		for(i = 0; i < m; i++)
		{	// initial all colors as ok for this row
			for(k = 0; k < m; k++)
				forbidden[k] = false;

			// for each column connected to row i
			itr_j = p[i].begin();
			while( itr_j != p[i].end() )
			{	j = *itr_j++;	
				// for each row connected to column j
				itr_i = q[j].begin();
				while( itr_i != q[j].end() )
				{	// if this is not i, forbid it
					k = *itr_i++;
					forbidden[ color[k] ] = (k != i);
				}
			}
			k = 0;
			while( forbidden[k] && k < m )
			{	k++;
				CPPAD_ASSERT_UNKNOWN( k < n );
			}
			color[i] = k;
		}
		size_t n_color = 1;
		for(k = 0; k < m; k++) 
			n_color = std::max(n_color, color[k] + 1);

		// weight vector for calls to reverse
		VectorBase w(m);

		// location for return values from Reverse
		VectorBase dw(n);

		// loop over colors
		size_t c;
		for(c = 0; c < n_color; c++)
		{	// determine all the rows with this color
			for(i = 0; i < m; i++)
			{	if( color[i] == c )
					w[i] = one;
				else	w[i] = zero;
			}
			// call reverse mode for all these rows at once
			dw = Reverse(1, w);

			// set the corresponding components of the result
			for(i = 0; i < m; i++) if( color[i] == c )
			{	itr_j = p[i].begin();
				while( itr_j != p[i].end() )
				{	j = *itr_j++;
					jac[i * n + j] = dw[j];
				}
			}
		}
	}
}
예제 #12
0
void RevSparseJacBool(
	size_t                 p                , 
	const VectorSet&       s                ,
	VectorSet&             r                ,
	size_t                 total_num_var    ,
	CppAD::vector<size_t>& dep_taddr        ,
	CppAD::vector<size_t>& ind_taddr        ,
	CppAD::player<Base>&   play             )
{
	// temporary indices
	size_t i, j;

	// check VectorSet is Simple Vector class with bool elements
	CheckSimpleVector<bool, VectorSet>();

	// range and domain dimensions for F
	size_t m = dep_taddr.size();
	size_t n = ind_taddr.size();

	CPPAD_ASSERT_KNOWN(
		p > 0,
		"RevSparseJac: p (first argument) is not greater than zero"
	);

	CPPAD_ASSERT_KNOWN(
		s.size() == p * m,
		"RevSparseJac: s (second argument) length is not equal to\n"
		"p (first argument) times range dimension for ADFun object."
	);

	// vector of sets that will hold the results
	sparse_pack    var_sparsity;
	var_sparsity.resize(total_num_var, p);

	// The sparsity pattern corresponding to the dependent variables
	for(i = 0; i < m; i++)
	{	CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var );

		for(j = 0; j < p; j++) if( s[ i * m + j ] )
			var_sparsity.add_element( dep_taddr[i], j );
	}

	// evaluate the sparsity patterns
	RevJacSweep(
		n,
		total_num_var,
		&play,
		var_sparsity
	);

	// return values corresponding to dependent variables
	CPPAD_ASSERT_UNKNOWN( r.size() == p * n );
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) );

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

		// extract the result from var_sparsity
		for(i = 0; i < p; i++) 
			r[ i * n + j ] = false;
		CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == p );
		var_sparsity.begin(j+1);
		i = var_sparsity.next_element();
		while( i < p )
		{	r[ i * n + j ] = true;
			i              = var_sparsity.next_element();
		}
	}
}
예제 #13
0
void RevSparseJacSet(
	bool                   transpose        ,
	bool                   dependency       ,
	size_t                 q                ,
	const VectorSet&       r                ,
	VectorSet&             s                ,
	size_t                 total_num_var    ,
	CppAD::vector<size_t>& dep_taddr        ,
	CppAD::vector<size_t>& ind_taddr        ,
	CppAD::player<Base>&   play             )
{
	// temporary indices
	size_t i, j;
	std::set<size_t>::const_iterator itr;

	// check VectorSet is Simple Vector class with sets for elements
	CheckSimpleVector<std::set<size_t>, VectorSet>(
		one_element_std_set<size_t>(), two_element_std_set<size_t>()
	);

	// domain dimensions for F
	size_t n = ind_taddr.size();
	size_t m = dep_taddr.size();

	CPPAD_ASSERT_KNOWN(
		q > 0,
		"RevSparseJac: q is not greater than zero"
	);
	CPPAD_ASSERT_KNOWN(
		size_t(r.size()) == q || transpose,
		"RevSparseJac: size of r is not equal to q and transpose is false."
	);
	CPPAD_ASSERT_KNOWN(
		size_t(r.size()) == m || ! transpose,
		"RevSparseJac: size of r is not equal to m and transpose is true."
	);

	// vector of lists that will hold the results
	CPPAD_INTERNAL_SPARSE_SET    var_sparsity;
	var_sparsity.resize(total_num_var, q);

	// The sparsity pattern corresponding to the dependent variables
	if( transpose )
	{	for(i = 0; i < m; i++)
		{	itr = r[i].begin();
			while(itr != r[i].end())
			{	j = *itr++;
				CPPAD_ASSERT_KNOWN(
				j < q,
				"RevSparseJac: transpose is true and element of the set\n"
				"r[i] has value greater than or equal q."
				);
				CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var );
				var_sparsity.add_element( dep_taddr[i], j );
			}
		}
	}
	else
	{	for(i = 0; i < q; i++)
		{	itr = r[i].begin();
			while(itr != r[i].end())
			{	j = *itr++;
				CPPAD_ASSERT_KNOWN(
				j < m,
				"RevSparseJac: transpose is false and element of the set\n"
				"r[i] has value greater than or equal range dimension."
				);
				CPPAD_ASSERT_UNKNOWN( dep_taddr[j] < total_num_var );
				var_sparsity.add_element( dep_taddr[j], i );
			}
		}
	}
	// evaluate the sparsity patterns
	RevJacSweep(
		dependency,
		n,
		total_num_var,
		&play,
		var_sparsity
	);

	// return values corresponding to dependent variables
	CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || transpose );
	CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == n || ! transpose );
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) );

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

		CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );
		var_sparsity.begin(j+1);
		i = var_sparsity.next_element();
		while( i < q )
		{	if( transpose )
				s[j].insert(i);
			else	s[i].insert(j);
			i = var_sparsity.next_element();
		}
	}
}
예제 #14
0
void RevSparseJacBool(
	bool                   transpose        ,
	bool                   dependency       ,
	size_t                 q                ,
	const VectorSet&       r                ,
	VectorSet&             s                ,
	size_t                 total_num_var    ,
	CppAD::vector<size_t>& dep_taddr        ,
	CppAD::vector<size_t>& ind_taddr        ,
	CppAD::player<Base>&   play             )
{
	// temporary indices
	size_t i, j;

	// check VectorSet is Simple Vector class with bool elements
	CheckSimpleVector<bool, VectorSet>();

	// range and domain dimensions for F
	size_t m = dep_taddr.size();
	size_t n = ind_taddr.size();

	CPPAD_ASSERT_KNOWN(
		q > 0,
		"RevSparseJac: q is not greater than zero"
	);
	CPPAD_ASSERT_KNOWN(
		size_t(r.size()) == q * m,
		"RevSparseJac: size of r is not equal to\n"
		"q times range dimension for ADFun object."
	);

	// vector of sets that will hold the results
	sparse_pack    var_sparsity;
	var_sparsity.resize(total_num_var, q);

	// The sparsity pattern corresponding to the dependent variables
	for(i = 0; i < m; i++)
	{	CPPAD_ASSERT_UNKNOWN( dep_taddr[i] < total_num_var );
		if( transpose )
		{	for(j = 0; j < q; j++) if( r[ j * m + i ] )
				var_sparsity.add_element( dep_taddr[i], j );
		}
		else
		{	for(j = 0; j < q; j++) if( r[ i * q + j ] )
				var_sparsity.add_element( dep_taddr[i], j );
		}
	}

	// evaluate the sparsity patterns
	RevJacSweep(
		dependency,
		n,
		total_num_var,
		&play,
		var_sparsity
	);

	// return values corresponding to dependent variables
	CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q * n );
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) );

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

		// extract the result from var_sparsity
		if( transpose )
		{	for(i = 0; i < q; i++)
				s[ j * q + i ] = false;
		}
		else
		{	for(i = 0; i < q; i++)
				s[ i * n + j ] = false;
		}
		CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );
		var_sparsity.begin(j+1);
		i = var_sparsity.next_element();
		while( i < q )
		{	if( transpose )
				s[ j * q + i ] = true;
			else	s[ i * n + j ] = true;
			i  = var_sparsity.next_element();
		}
	}
}
예제 #15
0
void ADFun<Base>::ForSparseHesCase(
	const std::set<size_t>&   set_type         ,
	const VectorSet&          r                ,
	const VectorSet&          s                ,
	VectorSet&                h                )
{	size_t n = Domain();
# ifndef NDEBUG
	size_t m = Range();
# endif
	std::set<size_t>::const_iterator itr_1;
	//
	// check VectorSet is Simple Vector class with sets for elements
	CheckSimpleVector<std::set<size_t>, VectorSet>(
		local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()
	);
	CPPAD_ASSERT_KNOWN(
		r.size() == 1,
		"ForSparseHes: size of s is not equal to one."
	);
	CPPAD_ASSERT_KNOWN(
		s.size() == 1,
		"ForSparseHes: size of s is not equal to one."
	);
	//
	// sparsity pattern corresponding to r
	local::sparse_list for_jac_pattern;
	for_jac_pattern.resize(num_var_tape_, n + 1);
	itr_1 = r[0].begin();
	while( itr_1 != r[0].end() )
	{	size_t i = *itr_1++;
		CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 );
		// ind_taddr_[i] is operator taddr for i-th independent variable
		CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
		//
		for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] );
	}
	// compute forward Jacobiain sparsity pattern
	bool dependency = false;
	local::ForJacSweep(
		dependency,
		n,
		num_var_tape_,
		&play_,
		for_jac_pattern
	);
	// sparsity pattern correspnding to s
	local::sparse_list rev_jac_pattern;
	rev_jac_pattern.resize(num_var_tape_, 1);
	itr_1 = s[0].begin();
	while( itr_1 != s[0].end() )
	{	size_t i = *itr_1++;
		CPPAD_ASSERT_KNOWN(
			i < m,
			"ForSparseHes: an element of the set s[0] has value "
			"greater than or equal m"
		);
		CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
		rev_jac_pattern.add_element( dep_taddr_[i], 0);
	}
	//
	// compute reverse sparsity pattern for dependency analysis
	// (note that we are only want non-zero derivatives not true dependency)
	local::RevJacSweep(
		dependency,
		n,
		num_var_tape_,
		&play_,
		rev_jac_pattern
	);
	//
	// vector of sets that will hold reverse Hessain values
	local::sparse_list for_hes_pattern;
	for_hes_pattern.resize(n+1, n+1);
	//
	// compute the Hessian sparsity patterns
	local::ForHesSweep(
		n,
		num_var_tape_,
		&play_,
		for_jac_pattern,
		rev_jac_pattern,
		for_hes_pattern
	);
	// return values corresponding to independent variables
	// j is index corresponding to reverse mode partial
	h.resize(n);
	CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );
	for(size_t i = 0; i < n; i++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );
		CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );

		// extract the result from for_hes_pattern
		local::sparse_list::const_iterator itr_2(for_hes_pattern, ind_taddr_[i] );
		size_t j = *itr_2;
		while( j < for_hes_pattern.end() )
		{	CPPAD_ASSERT_UNKNOWN( 0 < j )
				h[i].insert(j-1);
			j = *(++itr_2);
		}
	}
}
예제 #16
0
void ADFun<Base>::ForSparseHesCase(
	bool              set_type         ,
	const VectorSet&  r                ,
	const VectorSet&  s                ,
	VectorSet&        h                )
{	size_t n = Domain();
	size_t m = Range();
	//
	// check Vector is Simple VectorSet class with bool elements
	CheckSimpleVector<bool, VectorSet>();
	//
	CPPAD_ASSERT_KNOWN(
		size_t(r.size()) == n,
		"ForSparseHes: size of r is not equal to\n"
		"domain dimension for ADFun object."
	);
	CPPAD_ASSERT_KNOWN(
		size_t(s.size()) == m,
		"ForSparseHes: size of s is not equal to\n"
		"range dimension for ADFun object."
	);
	//
	// sparsity pattern corresponding to r
	local::sparse_pack for_jac_pattern;
	for_jac_pattern.resize(num_var_tape_, n + 1);
	for(size_t i = 0; i < n; i++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < n + 1 );
		// ind_taddr_[i] is operator taddr for i-th independent variable
		CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );
		//
		if( r[i] )
			for_jac_pattern.add_element( ind_taddr_[i], ind_taddr_[i] );
	}
	// compute forward Jacobiain sparsity pattern
	bool dependency = false;
	local::ForJacSweep(
		dependency,
		n,
		num_var_tape_,
		&play_,
		for_jac_pattern
	);
	// sparsity pattern correspnding to s
	local::sparse_pack rev_jac_pattern;
	rev_jac_pattern.resize(num_var_tape_, 1);
	for(size_t i = 0; i < m; i++)
	{	CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
		if( s[i] )
			rev_jac_pattern.add_element( dep_taddr_[i], 0);
	}
	// compute reverse sparsity pattern for dependency analysis
	// (note that we are only want non-zero derivatives not true dependency)
	local::RevJacSweep(
		dependency,
		n,
		num_var_tape_,
		&play_,
		rev_jac_pattern
	);
	// vector of sets that will hold the forward Hessain values
	local::sparse_pack for_hes_pattern;
	for_hes_pattern.resize(n+1, n+1);
	//
	// compute the Hessian sparsity patterns
	local::ForHesSweep(
		n,
		num_var_tape_,
		&play_,
		for_jac_pattern,
		rev_jac_pattern,
		for_hes_pattern
	);
	// initialize return values corresponding to independent variables
	h.resize(n * n);
	for(size_t i = 0; i < n; i++)
	{	for(size_t j = 0; j < n; j++)
			h[ i * n + j ] = false;
	}
	// copy to result pattern
	CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );
	for(size_t i = 0; i < n; i++)
	{	// ind_taddr_[i] is operator taddr for i-th independent variable
		CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );
		CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );

		// extract the result from for_hes_pattern
		local::sparse_pack::const_iterator itr(for_hes_pattern, ind_taddr_[i] );
		size_t j = *itr;
		while( j < for_hes_pattern.end() )
		{	CPPAD_ASSERT_UNKNOWN( 0 < j )
			h[ i * n + (j-1) ] = true;
			j = *(++itr);
		}
	}
}
예제 #17
0
void RevSparseJacSet(
	size_t                 p                , 
	const VectorSet&       s                ,
	VectorSet&             r                ,
	size_t                 total_num_var    ,
	CppAD::vector<size_t>& dep_taddr        ,
	CppAD::vector<size_t>& ind_taddr        ,
	CppAD::player<Base>&   play             )
{
	// temporary indices
	size_t i, j;
	std::set<size_t>::const_iterator itr;

	// check VectorSet is Simple Vector class with sets for elements
	static std::set<size_t> two, three;
	if( two.empty() )
	{	two.insert(2);
		three.insert(3);
	}
	CPPAD_ASSERT_UNKNOWN( two.size() == 1 );
	CPPAD_ASSERT_UNKNOWN( three.size() == 1 );
	CheckSimpleVector<std::set<size_t>, VectorSet>(two, three);

	// range and domain dimensions for F
	size_t m = dep_taddr.size();
	size_t n = ind_taddr.size();

	CPPAD_ASSERT_KNOWN(
		p > 0,
		"RevSparseJac: p (first argument) is not greater than zero"
	);

	CPPAD_ASSERT_KNOWN(
		s.size() == p,
		"RevSparseJac: s (second argument) length is not equal to "
		"p (first argument)."
	);

	// vector of sets that will hold the results
	sparse_set     var_sparsity;
	var_sparsity.resize(total_num_var, p);

	// The sparsity pattern corresponding to the dependent variables
	for(i = 0; i < p; i++)
	{	itr = s[i].begin();
		while(itr != s[i].end())
		{	j = *itr++; 
			CPPAD_ASSERT_KNOWN(
				j < m,
				"RevSparseJac: an element of the set s[i] "
				"has value greater than or equal m."
			);
			CPPAD_ASSERT_UNKNOWN( dep_taddr[j] < total_num_var );
			var_sparsity.add_element( dep_taddr[j], i );
		}
	}

	// evaluate the sparsity patterns
	RevJacSweep(
		n,
		total_num_var,
		&play,
		var_sparsity
	);

	// return values corresponding to dependent variables
	CPPAD_ASSERT_UNKNOWN( r.size() == p );
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr[j] == (j+1) );

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

		// extract result from rev_hes_sparsity
		// and add corresponding elements to sets in r
		CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == p );
		var_sparsity.begin(j+1);
		i = var_sparsity.next_element();
		while( i < p )
		{	r[i].insert(j);
			i = var_sparsity.next_element();
		}
	}
}
void ADFun<Base>::SparseJacobianCase(
	bool               set_type        ,
	const VectorBase&  x               , 
	const VectorSet&   p               ,
	VectorBase&        jac             )
{
	typedef CppAD::vector<size_t> SizeVector;
	typedef CppAD::vectorBool     VectorBool;
	size_t i, j, k;

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

	// some values
	const Base zero(0);
	const Base one(1);

	// check VectorSet is Simple Vector class with bool elements
	CheckSimpleVector<bool, VectorSet>();

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

	CPPAD_ASSERT_KNOWN(
		x.size() == n,
		"SparseJacobian: size of x not equal domain dimension for f"
	); 
	CPPAD_ASSERT_KNOWN(
		p.size() == m * n,
		"SparseJacobian: using bool values and size of p "
		" not equal range dimension times domain dimension for f"
	); 
	CPPAD_ASSERT_UNKNOWN(jac.size() == m * n); 

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

	// initialize the return value
	for(i = 0; i < m; i++)
		for(j = 0; j < n; j++)
			jac[i * n + j] = zero;

	if( n <= m )
	{	// use forward mode ----------------------------------------
	
		// initial coloring
		SizeVector color(n);
		for(j = 0; j < n; j++)
			color[j] = j;

		// See GreedyPartialD2Coloring Algorithm Section 3.6.2 of
		// Graph Coloring in Optimization Revisited by
		// Assefaw Gebremedhin, Fredrik Maane, Alex Pothen
		VectorBool forbidden(n);
		for(j = 0; j < n; j++)
		{	// initial all colors as ok for this column
			for(k = 0; k < n; k++)
				forbidden[k] = false;
			// for each row that is connected to column j
			for(i = 0; i < m; i++) if( p[i * n + j] )
			{	// for each column that is connected to row i
				for(k = 0; k < n; k++)
					if( p[i * n + k] & (j != k) )	
						forbidden[ color[k] ] = true;
			}
			k = 0;
			while( forbidden[k] && k < n )
			{	k++;
				CPPAD_ASSERT_UNKNOWN( k < n );
			}
			color[j] = k;
		}
		size_t n_color = 1;
		for(k = 0; k < n; k++) 
			n_color = std::max(n_color, color[k] + 1);

		// direction vector for calls to forward
		VectorBase dx(n);

		// location for return values from Reverse
		VectorBase dy(m);

		// loop over colors
		size_t c;
		for(c = 0; c < n_color; c++)
		{	// determine all the colums with this color
			for(j = 0; j < n; j++)
			{	if( color[j] == c )
					dx[j] = one;
				else	dx[j] = zero;
			}
			// call forward mode for all these columns at once
			dy = Forward(1, dx);

			// set the corresponding components of the result
			for(j = 0; j < n; j++) if( color[j] == c )
			{	for(i = 0; i < m; i++) 
					if( p[ i * n + j ] )
						jac[i * n + j] = dy[i];
			}
		}
	}
	else
	{	// use reverse mode ----------------------------------------
	
		// initial coloring
		SizeVector color(m);
		for(i = 0; i < m; i++)
			color[i] = i;

		// See GreedyPartialD2Coloring Algorithm Section 3.6.2 of
		// Graph Coloring in Optimization Revisited by
		// Assefaw Gebremedhin, Fredrik Maane, Alex Pothen
		VectorBool forbidden(m);
		for(i = 0; i < m; i++)
		{	// initial all colors as ok for this row
			for(k = 0; k < m; k++)
				forbidden[k] = false;
			// for each column that is connected to row i
			for(j = 0; j < n; j++) if( p[i * n + j] )
			{	// for each row that is connected to column j
				for(k = 0; k < m; k++)
					if( p[k * n + j] & (i != k) )	
						forbidden[ color[k] ] = true;
			}
			k = 0;
			while( forbidden[k] && k < m )
			{	k++;
				CPPAD_ASSERT_UNKNOWN( k < n );
			}
			color[i] = k;
		}
		size_t n_color = 1;
		for(k = 0; k < m; k++) 
			n_color = std::max(n_color, color[k] + 1);

		// weight vector for calls to reverse
		VectorBase w(m);

		// location for return values from Reverse
		VectorBase dw(n);

		// loop over colors
		size_t c;
		for(c = 0; c < n_color; c++)
		{	// determine all the rows with this color
			for(i = 0; i < m; i++)
			{	if( color[i] == c )
					w[i] = one;
				else	w[i] = zero;
			}
			// call reverse mode for all these rows at once
			dw = Reverse(1, w);

			// set the corresponding components of the result
			for(i = 0; i < m; i++) if( color[i] == c )
			{	for(j = 0; j < n; j++) 
					if( p[ i * n + j ] )
						jac[i * n + j] = dw[j];
			}
		}
	}
}