예제 #1
1
bool link_sparse_hessian(
	size_t                           size     , 
	size_t                           repeat   , 
	CppAD::vector<double>&           x        ,
	const CppAD::vector<size_t>&     row      ,
	const CppAD::vector<size_t>&     col      ,
	CppAD::vector<double>&           hessian  )
{
	// -----------------------------------------------------
	// setup
	typedef vector<double>              DblVector;
	typedef vector< std::set<size_t> >  SetVector;
	typedef CppAD::AD<double>           ADScalar;
	typedef vector<ADScalar>            ADVector;

	size_t i, j, k;
	size_t order = 0;         // derivative order corresponding to function
	size_t m = 1;             // number of dependent variables
	size_t n = size;          // number of independent variables
	size_t K = row.size();    // number of non-zeros in lower triangle
	ADVector   a_x(n);        // AD domain space vector
	ADVector   a_y(m);        // AD range space vector
	DblVector  w(m);          // double range space vector
	DblVector hes(K);         // non-zeros in lower triangle
	CppAD::ADFun<double> f;   // AD function object

	// weights for hessian calculation (only one component of f)
	w[0] = 1.;

	// use the unspecified fact that size is non-decreasing between calls
	static size_t previous_size = 0;
	bool print    = (repeat > 1) & (previous_size != size);
	previous_size = size;

	// declare sparsity pattern
# if USE_SET_SPARSITY
	SetVector sparsity(n);
# else
	typedef vector<bool>                BoolVector;
	BoolVector sparsity(n * n);
# endif
	// initialize all entries as zero
	for(i = 0; i < n; i++)
	{	for(j = 0; j < n; j++)
			hessian[ i * n + j] = 0.;
	}
	// ------------------------------------------------------
	extern bool global_retape;
	if( global_retape) while(repeat--)
	{	// choose a value for x 
		CppAD::uniform_01(n, x);
		for(j = 0; j < n; j++)
			a_x[j] = x[j];

		// declare independent variables
		Independent(a_x);	

		// AD computation of f(x)
		CppAD::sparse_hes_fun<ADScalar>(n, a_x, row, col, order, a_y);

		// create function object f : X -> Y
		f.Dependent(a_x, a_y);

		extern bool global_optimize;
		if( global_optimize )
		{	print_optimize(f, print, "cppad_sparse_hessian_optimize", size);
			print = false;
		}

		// calculate the Hessian sparsity pattern for this function
		calc_sparsity(sparsity, f);

		// structure that holds some of work done by SparseHessian
		CppAD::sparse_hessian_work work;

		// calculate this Hessian at this x
		f.SparseHessian(x, w, sparsity, row, col, hes, work);
		for(k = 0; k < K; k++)
		{	hessian[ row[k] * n + col[k] ] = hes[k];
			hessian[ col[k] * n + row[k] ] = hes[k];
		}
	}
	else
	{	// choose a value for x 
		CppAD::uniform_01(n, x);
		for(j = 0; j < n; j++)
			a_x[j] = x[j];

		// declare independent variables
		Independent(a_x);	

		// AD computation of f(x)
		CppAD::sparse_hes_fun<ADScalar>(n, a_x, row, col, order, a_y);

		// create function object f : X -> Y
		f.Dependent(a_x, a_y);

		extern bool global_optimize;
		if( global_optimize )
		{	print_optimize(f, print, "cppad_sparse_hessian_optimize", size);
			print = false;
		}

		// calculate the Hessian sparsity pattern for this function
		calc_sparsity(sparsity, f);

		// declare structure that holds some of work done by SparseHessian
		CppAD::sparse_hessian_work work;

		while(repeat--)
		{	// choose a value for x
			CppAD::uniform_01(n, x);

			// calculate sparsity at this x
			f.SparseHessian(x, w, sparsity, row, col, hes, work);

			for(k = 0; k < K; k++)
			{	hessian[ row[k] * n + col[k] ] = hes[k];
				hessian[ col[k] * n + row[k] ] = hes[k];
			}
		}
	}
	return true;
}
예제 #2
0
파일: mat_utils.c 프로젝트: kazu1977/prml
int
mat_rank(int dim, double **mat)
{
	int i, j;
	int count = 0;
	double *dr = NULL, *di = NULL;
	double **tmp;
	
	dr = new_double_vector(dim);
	di = new_double_vector(dim);
	tmp = new_double_matrix(dim, dim);
	
	/* 計算途中で値が上書きされるから元の行列のコピーを使う */
	for(i = 0; i < dim; i++)
		for(j = 0; j < dim; j++)
			tmp[i][j] = mat[i][j];
	
	/* 固有値の計算 */
	hes(tmp, dim);
	hqr(tmp, dr, di, dim);

	/* 固有値を調べる */
	/* drが実数成分、diが虚数成分 */
	for(i = 0; i < dim; i++)
		if(dr[i] > 0.0 && (!(di[i] > 0.0 || di[i] < 0.0)))
			count++;
	
	/* 配列を解放 */
	free_double_vector(dr);
	free_double_vector(di);
	free_double_matrix(tmp);

	return count;
}
예제 #3
0
파일: hessian.hpp 프로젝트: cran/RMC
Vector ADFun<Base>::Hessian(const Vector &x, size_t i)
{	size_t j;
	size_t k;
	size_t l;

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

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

	CppADUsageError(
		x.size() == n,
		"Hessian: length of x not equal domain dimension for f"
	); 
	CppADUsageError(
		i < m,
		"Hessian: index i is not less than 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);

	// direction vector for calls to reverse
	Vector w(m);
	for(l = 0; l < m; l++)
		w[l] = Base(0);
	w[i] = Base(1);

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

	// loop over forward direstions
	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;
}
예제 #4
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;
}