Example #1
0
void CompositeOFTest::test_composite_clone( ObjectiveFunction& OF )
{
    // save current count of instances of underlying OFs for later
    const int init_count = FauxObjectiveFunction::get_instance_count();

    // clone the objective function
    ObjectiveFunction* clone = OF.clone();

    // check that the underlying OFs were also cloned
    CPPUNIT_ASSERT( init_count < FauxObjectiveFunction::get_instance_count() );

    // check that the value is the same
    MsqPrintError err(cout);
    double orig_val, clone_val;
    bool rval;
    rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), orig_val, false, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT(rval);
    rval = clone->evaluate( ObjectiveFunction::CALCULATE, patch(), clone_val, false, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT(rval);
    CPPUNIT_ASSERT_DOUBLES_EQUAL( orig_val, clone_val, 1e-6 );

    // check that cloned instances of underlying OFs are deleted
    delete clone;
    CPPUNIT_ASSERT_EQUAL( init_count, FauxObjectiveFunction::get_instance_count() );
}
void generateSimplexTab(const std::vector<Constraint<ArgType>>& constraints,
		const ObjectiveFunction<ArgType, RetType, CoeffType>& function,
		Matrix<CoeffType>& simplexTab)
{
	unsigned long cols = simplexTab.getColumnsNumber(), rows =
			simplexTab.getRowsNumber(), constrNum = constraints.size(), argsNum =
			function.size();
	if(constrNum + 1 != rows || argsNum + constrNum + 2 != cols)
		throw "simplexTab has not proper size";
	for (unsigned long i = 0; i < constrNum; i++) //generuje część odpowiedzialna za ograniczenia pod argumentami
		for (unsigned long j = 0; j < argsNum; j++)
			simplexTab(i, j) = constraints[i].getCoeff(j);
	for (unsigned long j = 0; j < argsNum; j++) // generuje dolną część tablicy pod argumentami
		simplexTab(rows - 1, j) = -function.getCoeff(j);
	for (unsigned long j = 0; j < constrNum; j++) // generuje część związaną ze zmiennymi dodatkowymi
		simplexTab(j, j + argsNum) = 1;
	for (unsigned long j = 0; j < constrNum; j++) // część pod p - same zera
		simplexTab(j, argsNum + constrNum) = 0;
	for (unsigned long j = 0; j < constrNum; j++) // ostatnia kolumna, kolumna B
		simplexTab(j, argsNum + constrNum + 1) = constraints[j].getB();
	for (unsigned long j = argsNum; j < argsNum + constrNum - 1; j++) //ostatni wiersz pod zmienn. dodatk. - same zera
		simplexTab(rows - 1, j) = 0;
	simplexTab(rows - 1, cols - 2) = 1;
	simplexTab(rows - 1, cols - 1) = 0;
}
Example #3
0
void UnOptimizer::optimize_vertex_positions( PatchData &pd, MsqError &err) {
  assert( pd.num_free_vertices() == 1 && pd.vertex_by_index(0).is_free_vertex() );
  std::vector<Vector3D> grad(1);
  double val, junk, coeff;
  bool state;
  
  state = objectiveFunction->evaluate_with_gradient( ObjectiveFunction::CALCULATE,
                                                     pd, val, grad, err );
  MSQ_ERRRTN(err);
  if (!state) {
    MSQ_SETERR(err)(MsqError::INVALID_MESH);
    return;
  }
  grad[0] /= grad[0].length();
  
  PatchDataVerticesMemento* memento = pd.create_vertices_memento( err ); MSQ_ERRRTN(err);
  std::auto_ptr<PatchDataVerticesMemento> deleter( memento );
  pd.get_minmax_edge_length( junk, coeff );
  
  for (int i = 0; i < 100; ++i) {
    pd.set_free_vertices_constrained( memento, &grad[0], 1, coeff, err ); MSQ_ERRRTN(err);
    state = objectiveFunction->evaluate( ObjectiveFunction::CALCULATE, pd, val, true, err );
    MSQ_ERRRTN(err);
    if (state)
      break;
    coeff *= 0.5;
  }
  if (!state) {
    pd.set_to_vertices_memento( memento, err );
  }
}
std::vector<double> OptimizerNaive::generateRandomPoint(const ObjectiveFunction & objective_function) const
{
    static RandomNumberGenerator random_generator(0., 1.);

    std::vector<double> dmin = objective_function.getDomainMin();
    std::vector<double> dmax = objective_function.getDomainMax();
    int x_dim = objective_function.getDimension();

    std::vector<double> x;
    for(int i=0 ; i<x_dim ; i++) {
        x.push_back(random_generator.generateNumber() * (dmax[i] - dmin[i]) + dmin[i]); // TODO denormalize in dmin dmax
    }
    
    return x;
}
Example #5
0
// Gradient computations
double DenseCRF::gradient( int n_iterations, const ObjectiveFunction & objective, VectorXf * unary_grad, VectorXf * lbl_cmp_grad, VectorXf * kernel_grad) const {
	// Run inference
	std::vector< MatrixXf > Q(n_iterations+1);
	MatrixXf tmp1, unary( M_, N_ ), tmp2;
	unary.fill(0);
	if( unary_ )
		unary = unary_->get();
	expAndNormalize( Q[0], -unary );
	for( int it=0; it<n_iterations; it++ ) {
		tmp1 = -unary;
		for( unsigned int k=0; k<pairwise_.size(); k++ ) {
			pairwise_[k]->apply( tmp2, Q[it] );
			tmp1 -= tmp2;
		}
		expAndNormalize( Q[it+1], tmp1 );
	}
	
	// Compute the objective value
	MatrixXf b( M_, N_ );
	double r = objective.evaluate( b, Q[n_iterations] );
	sumAndNormalize( b, b, Q[n_iterations] );

	// Compute the gradient
	if(unary_grad && unary_)
		*unary_grad = unary_->gradient( b );
	if( lbl_cmp_grad )
		*lbl_cmp_grad = 0*labelCompatibilityParameters();
	if( kernel_grad )
		*kernel_grad = 0*kernelParameters();
	
	for( int it=n_iterations-1; it>=0; it-- ) {
		// Do the inverse message passing
		tmp1.fill(0);
		int ip = 0, ik = 0;
		// Add up all pairwise potentials
		for( unsigned int k=0; k<pairwise_.size(); k++ ) {
			// Compute the pairwise gradient expression
			if( lbl_cmp_grad ) {
				VectorXf pg = pairwise_[k]->gradient( b, Q[it] );
				lbl_cmp_grad->segment( ip, pg.rows() ) += pg;
				ip += pg.rows();
			}
			// Compute the kernel gradient expression
			if( kernel_grad ) {
				VectorXf pg = pairwise_[k]->kernelGradient( b, Q[it] );
				kernel_grad->segment( ik, pg.rows() ) += pg;
				ik += pg.rows();
			}
			// Compute the new b
			pairwise_[k]->applyTranspose( tmp2, b );
			tmp1 += tmp2;
		}
		sumAndNormalize( b, tmp1.array()*Q[it].array(), Q[it] );
		
		// Add the gradient
		if(unary_grad && unary_)
			*unary_grad += unary_->gradient( b );
	}
	return r;
}
Example #6
0
void CompositeOFTest::test_eval_fails( ObjectiveFunction& OF )
{
    MsqError err;
    double value;
    OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err );
    CPPUNIT_ASSERT_EQUAL(MsqError::INTERNAL_ERROR, err.error_code());
}
Example #7
0
void CompositeOFTest::test_invalid_eval( ObjectiveFunction& OF )
{
    MsqPrintError err(cout);
    bool rval;
    double value;
    rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT(rval == false);
}
Example #8
0
void CompositeOFTest::test_evaluate( double expected, ObjectiveFunction& OF )
{
    MsqPrintError err(cout);
    double value;
    bool rval = OF.evaluate( ObjectiveFunction::CALCULATE, patch(), value, false, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT(rval);
    CPPUNIT_ASSERT_DOUBLES_EQUAL( expected, value, 1e-6 );
}
/*! 
  Numerically Calculates the gradient of the ObjectiveFunction for the
  free vertices in the patch.  Returns 'false' if the patch is outside
  of a required feasible region, returns 'ture' otherwise.
  The behavior of the function depends on the value of the boolean
  useLocalGradient.  If useLocalGradient is set to
  'true', compute_numerical_gradient creates a sub-patch around a free
  vertex, and then perturbs that vertex in one of the coordinate directions.
  Only the ObjectiveFunction value on the local sub-patch is used in the
  computation of the gradient.  Therefore, useLocalGradient should only
  be set to 'true' for ObjectiveFunctions which can use this method.  Unless
  the concrete ObjectiveFunction sets useLocalGradient to 'true' in its
  constructor, the value will be 'false'.  In this case, the objective
  function value for the entire patch is used in the calculation of the
  gradient.  This is computationally expensive, but it is numerically
  correct for all (C_1) functions.
  \param pd  PatchData on which the gradient is taken.
  \param grad  Array of Vector3D of length the number of vertices used to store gradient.
  \param OF_val will be set to the objective function value.
 */
bool ObjectiveFunction::evaluate_with_gradient( EvalType eval_type,
                                                PatchData &pd,
                                                double& OF_val,
                                                std::vector<Vector3D>& grad,
                                                MsqError &err )
{
  bool b;
  grad.resize( pd.num_free_vertices() );
  
    // Fast path for single-free-vertex patch
  if (pd.num_free_vertices() == 1) {
    const EvalType sub_type = (eval_type == CALCULATE) ? CALCULATE : TEMPORARY;
    b = compute_subpatch_numerical_gradient( eval_type, sub_type, pd, OF_val, grad[0], err );
    return !MSQ_CHKERR(err) && b;
  }
  
  ObjectiveFunction* of = this;
  std::auto_ptr<ObjectiveFunction> deleter;
  if (eval_type == CALCULATE) {
    of->clear();
    b = of->evaluate( ACCUMULATE, pd, OF_val, OF_FREE_EVALS_ONLY, err );
    if (err) { // OF doesn't support BCD type evals, try slow method
      err.clear();
      of->clear();
      b = compute_patch_numerical_gradient( CALCULATE, CALCULATE, pd, OF_val, grad, err );
      return !MSQ_CHKERR(err) && b;
    }
    else if (!b)
      return b;
  } 
  else {
    b = this->evaluate( eval_type, pd, OF_val, OF_FREE_EVALS_ONLY, err );
    if (MSQ_CHKERR(err) || !b)
      return false;
    of = this->clone();
    deleter = std::auto_ptr<ObjectiveFunction>(of);
  }

    // Determine number of layers of adjacent elements based on metric type.
  unsigned layers = min_patch_layers();
  
    // Create a subpatch for each free vertex and use it to evaluate the
    // gradient for that vertex.
  double flocal;
  PatchData subpatch;
  for (size_t i = 0; i < pd.num_free_vertices(); ++i)
  {
    pd.get_subpatch( i, layers, subpatch, err ); MSQ_ERRZERO(err);
    b = of->compute_subpatch_numerical_gradient( SAVE, TEMPORARY, subpatch, flocal, grad[i], err );
    if (MSQ_CHKERR(err) || !b) {
      of->clear();
      return false;
    }
  }
  
  of->clear();
  return true;
}
FunctionArguments<ArgType> simplex(
		const std::vector<Constraint<ArgType>>& constraints,
		const ObjectiveFunction<ArgType, RetType, CoeffType>& function)
{
	if(constraints.size() == 0)
		throw "No constraints";
	if(constraints[0].size() != function.size())
		throw "Size of constraints not equal to function size";
	Matrix<CoeffType> simplexTab(constraints.size() + 1,
			function.size() + constraints.size() + 2);
	unsigned long cols = simplexTab.getColumnsNumber(), rows =
			simplexTab.getRowsNumber(), constrNum = constraints.size(), argsNum =
			function.size();
	generateSimplexTab(constraints, function, simplexTab);
	std::map<unsigned long,unsigned long> slackSwaped;
	while (simplexTab.countIfInRange(rows - 1, 0, rows - 1, cols - 1,
			[](const CoeffType& x)
			{	return x<0;}))
	{
		unsigned long pivotColumn, row;
		simplexTab.findMinimumInRange(rows - 1, 0, rows - 1, cols - 3, row,
				pivotColumn);
		row = findMinInColumnBDiv(simplexTab, pivotColumn);
		slackSwaped[row]=pivotColumn;
		simplexTab.multiplyRow(1/simplexTab(row,pivotColumn),row);
		for(unsigned long j=0;j<rows;j++)
			if(j!=row)
				simplexTab.addRow(-simplexTab(j,pivotColumn),row,j);
	}
	std::cout<<simplexTab;
	FunctionArguments<ArgType> bestSolution;
	bestSolution.size(argsNum);
	for(unsigned long j=0;j<constrNum;j++)
		bestSolution.setArg(slackSwaped[j],simplexTab(j,cols-1));
	return bestSolution;
}
Example #11
0
void ProgNmaAlignment::processImage(const FileName &fnImg,
		const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut) {
	static size_t imageCounter = 0;
	++imageCounter;

	double rhoStart=trustradius_scale*250.;
        double rhoEnd=trustradius_scale*50.;

	int niter=10000;

	ObjectiveFunction *of;

	int dim = numberOfModes;

	parameters.initZeros(dim + 5);
	currentImgName = fnImg;
	sprintf(nameTemplate, "_node%d_img%lu_XXXXXX", rangen, (long unsigned int)imageCounter);

	trial.initZeros(dim + 5);
	trial_best.initZeros(dim + 5);

	fitness_min.initZeros(1);
	fitness_min(0) = 1000000.0;

	currentStage = 1;
#ifdef DEBUG
	std::cerr << std::endl << "DEBUG: ===== Node: " << rangen
	<<" processing image " << fnImg <<"(" << objId << ")"
	<< " at stage: " << currentStage << std::endl;
#endif
	of = new ObjFunc_nma_alignment(1, dim);

	of->xStart.setSize(dim);
	for (int i = 0; i < dim; i++)
		of->xStart[i] = 0.;

#ifdef DEBUG
	strcpy(of->name,("OF1_"+integerToString(rangen)).c_str());
	of->setSaveFile();
#endif

	CONDOR(rhoStart, rhoEnd, niter, of);
#ifdef DEBUG
	of->printStats();
	FILE *ff = fopen(("res1_"+integerToString(rangen)+".xmd").c_str(),"w");
	fprintf(ff,"%s & %i & %i & (%i) & %e \\\\\n", of->name, of->dim(), of->getNFE(), of->getNFE2(), of->valueBest);
	fclose(ff);
#endif

	bestStage1 = trial = parameters = trial_best;

	delete of;

	currentStage = 2;
#ifdef DEBUG
	std::cerr << std::endl << "DEBUG: ===== Node: " << rangen
	<<" processing image " << fnImg <<"(" << objId << ")"
	<< " at stage: " << currentStage << std::endl;
#endif

	fitness_min(0) = 1000000.0;

	of = new ObjFunc_nma_alignment(1, dim);

	of->xStart.setSize(dim);
	for (int i = 0; i < dim; i++)
		of->xStart[i] = parameters(i);
#ifdef DEBUG
	strcpy(of->name,("OF2_"+integerToString(rangen)).c_str());
	of->setSaveFile();
#endif

	rhoStart=trustradius_scale*50.-1., rhoEnd=0.5;
	CONDOR(rhoStart, rhoEnd, niter, of);
#ifdef DEBUG
	of->printStats();
	ff=fopen(("res2_"+integerToString(rangen)+".xmd").c_str(),"w");
	fprintf(ff,"%s & %i & %i & (%i) & %e \\\\\n", of->name, of->dim(), of->getNFE(), of->getNFE2(), of->valueBest);
	fclose(ff);
#endif

#ifdef DEBUG
	std::cout << "Best fitness = " << fitness << std::endl;
	for (int i=0; i<dim; i++)
	{
		std::cout << "Best deformations = " << dd[i] << std::endl;
	}
#endif

	trial = trial_best;

	for (int i = dim; i < dim + 5; i++) {
		parameters(i - dim) = trial_best(i);
	}

	for (int i = 0; i < dim; i++) {
		parameters(5 + i) = trial_best(i);
	}

	parameters.resize(VEC_XSIZE(parameters) + 1);
	parameters(VEC_XSIZE(parameters) - 1) = fitness_min(0);

	writeImageParameters(fnImg);
	delete of;
}