コード例 #1
0
ファイル: LogDetEstimator.cpp プロジェクト: DrahmA/shogun
CLogDetEstimator::CLogDetEstimator(SGSparseMatrix<float64_t> sparse_mat) 
	: CSGObject()
{
	init();

	m_computation_engine=new CSerialComputationEngine();
	SG_REF(m_computation_engine);

	CSparseMatrixOperator<float64_t>* op=
		new CSparseMatrixOperator<float64_t>(sparse_mat);

	float64_t accuracy=1E-5;

	CLanczosEigenSolver* eig_solver=new CLanczosEigenSolver(op);
	CCGMShiftedFamilySolver* linear_solver=new CCGMShiftedFamilySolver();

	m_operator_log=new CLogRationalApproximationCGM(op,m_computation_engine,
		eig_solver,linear_solver,accuracy);
	SG_REF(m_operator_log);

	#ifdef HAVE_COLPACK
	m_trace_sampler=new CProbingSampler(op,1,NATURAL,DISTANCE_TWO);
	#else
	m_trace_sampler=new CNormalSampler(op->get_dimension());
	#endif

	SG_REF(m_trace_sampler);

	SG_INFO("LogDetEstimator:Using %s, %s with 1E-5 accuracy, %s as default\n",
		m_computation_engine->get_name(), m_operator_log->get_name(),
		m_trace_sampler->get_name());
}
コード例 #2
0
ファイル: DenseFeatures.cpp プロジェクト: jimloco/shogun
template<class ST> bool CDenseFeatures<ST>::apply_preprocessor(bool force_preprocessing)
{
	if (m_subset_stack->has_subsets())
		SG_ERROR("A subset is set, cannot call apply_preproc\n");

	SG_DEBUG( "force: %d\n", force_preprocessing);

	if (feature_matrix.matrix && get_num_preprocessors())
	{
		for (int32_t i = 0; i < get_num_preprocessors(); i++)
		{
			if ((!is_preprocessed(i) || force_preprocessing))
			{
				set_preprocessed(i);
				CDensePreprocessor<ST>* p =
						(CDensePreprocessor<ST>*) get_preprocessor(i);
				SG_INFO( "preprocessing using preproc %s\n", p->get_name());

				if (p->apply_to_feature_matrix(this).matrix == NULL)
				{
					SG_UNREF(p);
					return false;
				}
				SG_UNREF(p);

			}
		}

		return true;
	}
	else
	{
		if (!feature_matrix.matrix)
			SG_ERROR( "no feature matrix\n");

		if (!get_num_preprocessors())
			SG_ERROR( "no preprocessors available\n");

		return false;
	}
}
コード例 #3
0
SGVector<complex128_t> CCGMShiftedFamilySolver::solve_shifted_weighted(
	CLinearOperator<SGVector<float64_t>, SGVector<float64_t> >* A, SGVector<float64_t> b,
	SGVector<complex128_t> shifts, SGVector<complex128_t> weights)
{
	SG_DEBUG("Entering\n");

	// sanity check
	REQUIRE(A, "Operator is NULL!\n");
	REQUIRE(A->get_dimension()==b.vlen, "Dimension mismatch! [%d vs %d]\n",
		A->get_dimension(), b.vlen);
	REQUIRE(shifts.vector,"Shifts are not initialized!\n");
	REQUIRE(weights.vector,"Weights are not initialized!\n");
	REQUIRE(shifts.vlen==weights.vlen, "Number of shifts and number of "
		"weights are not equal! [%d vs %d]\n", shifts.vlen, weights.vlen);

	// the solution matrix, one column per shift, initial guess 0 for all
	MatrixXcd x_sh=MatrixXcd::Zero(b.vlen, shifts.vlen);
	MatrixXcd p_sh=MatrixXcd::Zero(b.vlen, shifts.vlen);

	// non-shifted direction
	SGVector<float64_t> p_(b.vlen);

	// the rest of the part hinges on eigen3 for computing norms
	Map<VectorXd> b_map(b.vector, b.vlen);
	Map<VectorXd> p(p_.vector, p_.vlen);

	// residual r_i=b-Ax_i, here x_0=[0], so r_0=b
	VectorXd r=b_map;

	// initial direction is same as residual
	p=r;
	p_sh=r.replicate(1, shifts.vlen).cast<complex128_t>();

	// non shifted initializers
	float64_t r_norm2=r.dot(r);
	float64_t beta_old=1.0;
	float64_t alpha=1.0;

	// shifted quantities
	SGVector<complex128_t> alpha_sh(shifts.vlen);
	SGVector<complex128_t> beta_sh(shifts.vlen);
	SGVector<complex128_t> zeta_sh_old(shifts.vlen);
	SGVector<complex128_t> zeta_sh_cur(shifts.vlen);
	SGVector<complex128_t> zeta_sh_new(shifts.vlen);

	// shifted initializers
	zeta_sh_old.set_const(1.0);
	zeta_sh_cur.set_const(1.0);

	// the iterator for this iterative solver
	IterativeSolverIterator<float64_t> it(r, m_max_iteration_limit,
		m_relative_tolerence, m_absolute_tolerence);

	// start the timer
	CTime time;
	time.start();

	// set the residuals to zero
	if (m_store_residuals)
		m_residuals.set_const(0.0);

	// CG iteration begins
	for (it.begin(r); !it.end(r); ++it)
	{

		SG_DEBUG("CG iteration %d, residual norm %f\n",
				it.get_iter_info().iteration_count,
				it.get_iter_info().residual_norm);

		if (m_store_residuals)
		{
			m_residuals[it.get_iter_info().iteration_count]
				=it.get_iter_info().residual_norm;
		}

		// apply linear operator to the direction vector
		SGVector<float64_t> Ap_=A->apply(p_);
		Map<VectorXd> Ap(Ap_.vector, Ap_.vlen);

		// compute p^{T}Ap, if zero, failure
		float64_t p_dot_Ap=p.dot(Ap);
		if (p_dot_Ap==0.0)
			break;

		// compute the beta parameter of CG_M
		float64_t beta=-r_norm2/p_dot_Ap;

		// compute the zeta-shifted parameter of CG_M
		compute_zeta_sh_new(zeta_sh_old, zeta_sh_cur, shifts, beta_old, beta,
			alpha, zeta_sh_new);

		// compute beta-shifted parameter of CG_M
		compute_beta_sh(zeta_sh_new, zeta_sh_cur, beta, beta_sh);

		// update the solution vector and residual
		for (index_t i=0; i<shifts.vlen; ++i)
			x_sh.col(i)-=beta_sh[i]*p_sh.col(i);

		// r_{i}=r_{i-1}+\beta_{i}Ap
		r+=beta*Ap;

		// compute new ||r||_{2}, if zero, converged
		float64_t r_norm2_i=r.dot(r);
		if (r_norm2_i==0.0)
			break;

		// compute the alpha parameter of CG_M
		alpha=r_norm2_i/r_norm2;

		// update ||r||_{2}
		r_norm2=r_norm2_i;

		// update direction
		p=r+alpha*p;

		compute_alpha_sh(zeta_sh_new, zeta_sh_cur, beta_sh, beta, alpha, alpha_sh);

		for (index_t i=0; i<shifts.vlen; ++i)
		{
			p_sh.col(i)*=alpha_sh[i];
			p_sh.col(i)+=zeta_sh_new[i]*r;
		}

		// update parameters
		for (index_t i=0; i<shifts.vlen; ++i)
		{
			zeta_sh_old[i]=zeta_sh_cur[i];
			zeta_sh_cur[i]=zeta_sh_new[i];
		}
		beta_old=beta;
	}

	float64_t elapsed=time.cur_time_diff();

	if (!it.succeeded(r))
		SG_WARNING("Did not converge!\n");

	SG_INFO("Iteration took %d times, residual norm=%.20lf, time elapsed=%f\n",
		it.get_iter_info().iteration_count, it.get_iter_info().residual_norm, elapsed);

	// compute the final result vector multiplied by weights
	SGVector<complex128_t> result(b.vlen);
	result.set_const(0.0);
	Map<VectorXcd> x(result.vector, result.vlen);

	for (index_t i=0; i<x_sh.cols(); ++i)
		x+=x_sh.col(i)*weights[i];

	SG_DEBUG("Leaving\n");
	return result;
}
コード例 #4
0
SGVector<float64_t> CConjugateGradientSolver::solve(
	CLinearOperator<float64_t>* A, SGVector<float64_t> b)
{
	SG_DEBUG("CConjugateGradientSolve::solve(): Entering..\n");

	// sanity check
	REQUIRE(A, "Operator is NULL!\n");
	REQUIRE(A->get_dimension()==b.vlen, "Dimension mismatch!\n");

	// the final solution vector, initial guess is 0
	SGVector<float64_t> result(b.vlen);
	result.set_const(0.0);

	// the rest of the part hinges on eigen3 for computing norms
	Map<VectorXd> x(result.vector, result.vlen);
	Map<VectorXd> b_map(b.vector, b.vlen);

	// direction vector
	SGVector<float64_t> p_(result.vlen);
	Map<VectorXd> p(p_.vector, p_.vlen);

	// residual r_i=b-Ax_i, here x_0=[0], so r_0=b
	VectorXd r=b_map;

	// initial direction is same as residual
	p=r;

	// the iterator for this iterative solver
	IterativeSolverIterator<float64_t> it(b_map, m_max_iteration_limit,
		m_relative_tolerence, m_absolute_tolerence);

	// CG iteration begins
	float64_t r_norm2=r.dot(r);

	// start the timer
	CTime time;
	time.start();

	// set the residuals to zero
	if (m_store_residuals)
		m_residuals.set_const(0.0);

	for (it.begin(r); !it.end(r); ++it)
	{
		SG_DEBUG("CG iteration %d, residual norm %f\n",
			it.get_iter_info().iteration_count,
			it.get_iter_info().residual_norm);

		if (m_store_residuals)
		{
			m_residuals[it.get_iter_info().iteration_count]
				=it.get_iter_info().residual_norm;
		}

		// apply linear operator to the direction vector
		SGVector<float64_t> Ap_=A->apply(p_);
		Map<VectorXd> Ap(Ap_.vector, Ap_.vlen);

		// compute p^{T}Ap, if zero, failure
		float64_t p_dot_Ap=p.dot(Ap);
		if (p_dot_Ap==0.0)
			break;

		// compute the alpha parameter of CG
		float64_t alpha=r_norm2/p_dot_Ap;

		// update the solution vector and residual
		// x_{i}=x_{i-1}+\alpha_{i}p
		x+=alpha*p;

		// r_{i}=r_{i-1}-\alpha_{i}p
		r-=alpha*Ap;

		// compute new ||r||_{2}, if zero, converged
		float64_t r_norm2_i=r.dot(r);
		if (r_norm2_i==0.0)
			break;

		// compute the beta parameter of CG
		float64_t beta=r_norm2_i/r_norm2;

		// update direction, and ||r||_{2}
		r_norm2=r_norm2_i;
		p=r+beta*p;
	}

	float64_t elapsed=time.cur_time_diff();

	if (!it.succeeded(r))
		SG_WARNING("Did not converge!\n");

	SG_INFO("Iteration took %ld times, residual norm=%.20lf, time elapsed=%lf\n",
		it.get_iter_info().iteration_count, it.get_iter_info().residual_norm, elapsed);

	SG_DEBUG("CConjugateGradientSolve::solve(): Leaving..\n");
	return result;
}
コード例 #5
0
SGVector<float64_t> CLogDetEstimator::sample(index_t num_estimates)
{
	SG_DEBUG("Entering\n");
	SG_INFO("Computing %d log-det estimates\n", num_estimates);

	REQUIRE(m_operator_log, "Operator function is NULL\n");
	// call the precompute of operator function to compute the prerequisites
	m_operator_log->precompute();

	REQUIRE(m_trace_sampler, "Trace sampler is NULL\n");
	// call the precompute of the sampler
	m_trace_sampler->precompute();

	REQUIRE(m_operator_log->get_operator()->get_dimension()\
		==m_trace_sampler->get_dimension(),
		"Mismatch in dimensions of the operator and trace-sampler, %d vs %d!\n",
		m_operator_log->get_operator()->get_dimension(),
		m_trace_sampler->get_dimension());

	// for storing the aggregators that submit_jobs return
	CDynamicObjectArray* aggregators=new CDynamicObjectArray();
	index_t num_trace_samples=m_trace_sampler->get_num_samples();

	for (index_t i=0; i<num_estimates; ++i)
	{
		for (index_t j=0; j<num_trace_samples; ++j)
		{
			SG_INFO("Computing log-determinant trace sample %d/%d\n", j,
					num_trace_samples);

			SG_DEBUG("Creating job for estimate %d, trace sample %d/%d\n", i, j,
					num_trace_samples);
			// get the trace sampler vector
			SGVector<float64_t> s=m_trace_sampler->sample(j);
			// create jobs with the sample vector and store the aggregator
			CJobResultAggregator* agg=m_operator_log->submit_jobs(s);
			aggregators->append_element(agg);
			SG_UNREF(agg);
		}
	}

	REQUIRE(m_computation_engine, "Computation engine is NULL\n");

	// wait for all the jobs to be completed
	SG_INFO("Waiting for jobs to finish\n");
	m_computation_engine->wait_for_all();
	SG_INFO("All jobs finished, aggregating results\n");

	// the samples vector which stores the estimates with averaging
	SGVector<float64_t> samples(num_estimates);
	samples.zero();

	// use the aggregators to find the final result
	// use the same order as job submission to combine results
	int32_t num_aggregates=aggregators->get_num_elements();
	index_t idx_row=0;
	index_t idx_col=0;
	for (int32_t i=0; i<num_aggregates; ++i)
	{
		// this cast is safe due to above way of building the array
		CJobResultAggregator* agg=dynamic_cast<CJobResultAggregator*>
			(aggregators->get_element(i));
		ASSERT(agg);

		// call finalize on all the aggregators, cast is safe again
		agg->finalize();
		CScalarResult<float64_t>* r=dynamic_cast<CScalarResult<float64_t>*>
			(agg->get_final_result());
		ASSERT(r);

		// iterate through indices, group results in the same way as jobs
		samples[idx_col]+=r->get_result();
		idx_row++;
		if (idx_row>=num_trace_samples)
		{
			idx_row=0;
			idx_col++;
		}

		SG_UNREF(agg);
	}

	// clear all aggregators
	SG_UNREF(aggregators)

	SG_INFO("Finished computing %d log-det estimates\n", num_estimates);

	SG_DEBUG("Leaving\n");
	return samples;
}