Exemple #1
0
vec sem::update_d(double tol, int max_iter)
{
    int i;
    double conv_crit = 1.0;
    int counter = 0;
    double old_obj, new_obj;
    new_obj = get_objective();

    //pre-allocate memory for gradient, hessian and update
    vec grad(v_ + gamma_indices_.n_elem);
    mat hessian(v_ + gamma_indices_.n_elem, v_ + gamma_indices_.n_elem);
    vec update(v_ + gamma_indices_.n_elem);

    while(conv_crit > tol && counter < max_iter) {
        old_obj = new_obj;

        // build in backtracking if necessary
        set_gradient_hessian(grad, hessian);
        update =  join_cols(lambda_, gamma_) - solve(hessian, grad);

        lambda_ = update(0, v_ - 1);
        gamma_ = update(v_, v_ + gamma_indices_.n_elem);

        new_obj = get_objective();
        conv_crit = fabs((new_obj - old_obj)/old_obj);
        counter++;
    }
}
Exemple #2
0
 void hessian(const F& functional,
              const Eigen::VectorXd& x,
              Eigen::MatrixXd& H) {
   double f;
   Eigen::VectorXd g(x.size());
   hessian(functional, x, f, g, H);
 }
 double BLSSS::find_posterior_mode() {
   BinomialLogitUnNormalizedLogPosterior logpost(m_, pri_.get());
   const Selector &inc(m_->coef().inc());
   Vector beta(m_->included_coefficients());
   int dim = beta.size();
   if (dim == 0) {
     return negative_infinity();
     // TODO: This logic prohibits an empty model.  Better to return
     // the actual value of the un-normalized posterior, which in
     // this case would just be the likelihood portion.
   } else {
     Vector gradient(dim);
     Matrix hessian(dim, dim);
     double logf;
     std::string error_message;
     bool ok = max_nd2_careful(beta,
                               gradient,
                               hessian,
                               logf,
                               Target(logpost),
                               dTarget(logpost),
                               d2Target(logpost),
                               1e-5,
                               error_message);
     if (ok) {
       m_->set_included_coefficients(beta, inc);
       return logf;
     } else {
       return negative_infinity();
     }
   }
 }
Exemple #4
0
bool Snake::shift_frame(bool direction) {

  if (!direction) {
    int position = vid.get(CV_CAP_PROP_POS_FRAMES);
    if (position < 1) {
      return true;
    }
    vid.set(CV_CAP_PROP_POS_FRAMES, position - 1);
  }

  if (!vid.read(img)) {
    return false;
  }
  update_raw_img();

  grad = gradient(img, 1);
  hess = hessian(img, 1);

#ifdef PRINT_META
  save_double_heat_map(grad.first, "/Users/ivan/.supp/code/snakes/hgx.jpg");
  save_double_heat_map(grad.second, "/Users/ivan/.supp/code/snakes/hgy.jpg");
  save_double_heat_map(hess, "/Users/ivan/.supp/code/snakes/hh.jpg");
#endif
  abs_threshold(grad.first, threshold);
  abs_threshold(grad.second, threshold);
  abs_threshold(hess, threshold);

#ifdef PRINT_META
  save_double_heat_map(grad.first, "/Users/ivan/.supp/code/snakes/thgx.jpg");
  save_double_heat_map(grad.second, "/Users/ivan/.supp/code/snakes/thgy.jpg");
  save_double_heat_map(hess, "/Users/ivan/.supp/code/snakes/thh.jpg");
#endif
  return true;
}
Exemple #5
0
bool erf(void)
{	bool ok = true;
	ok     &= old_example();
# if CPPAD_USE_CPLUSPLUS_2011
	ok     &= hessian();
# endif
	return ok;
}
Exemple #6
0
 void test_hessian_dot_vector(const F& functional,
                              const Eigen::VectorXd& x,
                              const Eigen::VectorXd& v) {
   
   Eigen::MatrixXd H_auto(x.size(), x.size());
   try {
     hessian(functional, x, H_auto);
   } catch (nomad_error& e) {
     std::cout << "Cannot compute Hessian Doc Vector Test" << std::endl;
     throw e;
   }
   
   Eigen::VectorXd H_dot_v_auto(x.size());
   try {
     hessian_dot_vector(functional, x, v, H_dot_v_auto);
   } catch (nomad_error& e) {
     std::cout << "Cannot compute Hessian Doc Vector Test" << std::endl;
     throw e;
   }
   
   std::cout.precision(6);
   int width = 12;
   int n_column = 3;
   
   std::cout << "Hessian Dot Vector Test:" << std::endl;
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   std::cout << "    "
             << std::setw(width) << std::left << "Component"
             << std::setw(width) << std::left << "Automatic"
             << std::setw(width) << std::left << "Exact"
             << std::endl;
   std::cout << "    "
             << std::setw(width) << std::left << "(i)"
             << std::setw(width) << std::left << "Derivative"
             << std::setw(width) << std::left << ""
             << std::endl;
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   
   Eigen::VectorXd H_dot_v = H_auto * v;
   
   for (eigen_idx_t i = 0; i < x.size(); ++i) {
     
     std::cout << "    "
               << std::setw(width) << std::left << i
               << std::setw(width) << std::left << H_dot_v_auto(i)
               << std::setw(width) << std::left << H_dot_v(i)
               << std::endl;
     
   }
   
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   std::cout << std::endl;
   
 }
  //---------------------------------------------------------------
  // This function is called by Tao to evaluate the Hessian at x
  PetscErrorCode
  __libmesh_tao_hessian(Tao /*tao*/, Vec x, Mat h, Mat pc, void * ctx)
  {
    START_LOG("hessian()", "TaoOptimizationSolver");

    PetscErrorCode ierr = 0;

    libmesh_assert(x);
    libmesh_assert(h);
    libmesh_assert(pc);
    libmesh_assert(ctx);

    // ctx should be a pointer to the solver (it was passed in as void *)
    TaoOptimizationSolver<Number> * solver =
      static_cast<TaoOptimizationSolver<Number> *> (ctx);

    OptimizationSystem & sys = solver->system();

    // We'll use current_local_solution below, so let's ensure that it's consistent
    // with the vector x that was passed in.
    PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(sys.solution.get());
    PetscVector<Number> X(x, sys.comm());

    // Perform a swap so that sys.solution points to X
    X.swap(X_sys);
    // Impose constraints on X
    sys.get_dof_map().enforce_constraints_exactly(sys);
    // Update sys.current_local_solution based on X
    sys.update();
    // Swap back
    X.swap(X_sys);

    // Let's also wrap pc and h in PetscMatrix objects for convenience
    PetscMatrix<Number> PC(pc, sys.comm());
    PetscMatrix<Number> hessian(h, sys.comm());
    PC.attach_dof_map(sys.get_dof_map());
    hessian.attach_dof_map(sys.get_dof_map());

    if (solver->hessian_object != libmesh_nullptr)
      {
        // Following PetscNonlinearSolver by passing in PC. It's not clear
        // why we pass in PC and not hessian though?
        solver->hessian_object->hessian(*(sys.current_local_solution), PC, sys);
      }
    else
      libmesh_error_msg("Hessian function not defined in __libmesh_tao_hessian");

    PC.close();
    hessian.close();

    STOP_LOG("hessian()", "TaoOptimizationSolver");

    return ierr;
  }
Exemple #8
0
double el_sem_naive::update_dual(double tol, int max_iter)
{

    //pre-allocate memory for gradient, hessian and update
    vec grad(v_ + (v_ *(v_ + 1) )/ 2 );
    mat hessian(v_ + (v_ *(v_ + 1) )/ 2 ,v_ + (v_ *(v_ + 1) )/ 2 );
    vec update(v_ + (v_ *(v_ + 1) )/ 2 );
    grad.zeros();
    hessian.zeros();
    update.zeros();

    // backtracking parameters
    double backtracking_scaling_const = .4;
    int back_tracking_counter;
    int max_back_track = 20; // steps required to scale update by 1e-8

    while(conv_crit_ > tol && counter_ < max_iter) {


        // build in backtracking if necessary
        set_gradient_hessian(grad, hessian);

        // back tracking line search

        update = solve(hessian, grad);

        //back track to ensure everything is greater than 1/n
        back_tracking_counter = 0;
        while(!backtracking(update) && back_tracking_counter < max_back_track) {
            update *= backtracking_scaling_const;
            back_tracking_counter++;
        }
        //if back tracking does not terminate because of max iterations update
        //else terminate
        if(back_tracking_counter < max_back_track) {
            dual_ -= update;
        } else {
            return -99999;
        }


        conv_crit_ = norm(grad ,2);
        counter_++;
    }

    d_ = (constraints_.t() * dual_) + 1.0;
    if(conv_crit_ < tol) {
        return -sum(log(n_ * d_));
    } else {
        return -999999999;
    }

}
Exemple #9
0
 void test_trace_matrix_times_hessian(const F& functional,
                                      const Eigen::VectorXd& x,
                                      const Eigen::MatrixXd& M) {
   
   Eigen::MatrixXd H_auto(x.size(), x.size());
   try {
     hessian(functional, x, H_auto);
   } catch (nomad_error& e) {
     std::cout << "Cannot compute Trace Matrix Times Hessian Test" << std::endl;
     throw e;
   }
   
   double trace_m_times_h = (M * H_auto).trace();
   
   double trace_m_times_h_auto;
   try {
     trace_matrix_times_hessian(functional, x, M, trace_m_times_h_auto);
   } catch (nomad_error& e) {
     std::cout << "Cannot compute Trace Matrix Times Hessian Test" << std::endl;
     throw e;
   }
   
   std::cout.precision(6);
   int width = 12;
   int n_column = 2;
   
   std::cout << "Trace Matrix Times Hessian Test:" << std::endl;
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   std::cout << "    "
             << std::setw(width) << std::left << "Automatic"
             << std::setw(width) << std::left << "Exact"
             << std::endl;
   std::cout << "    "
             << std::setw(width) << std::left << "Derivative"
             << std::setw(width) << std::left << ""
             << std::endl;
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   
   std::cout << "    "
             << std::setw(width) << std::left << trace_m_times_h_auto
             << std::setw(width) << std::left << trace_m_times_h
             << std::endl;
   
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   std::cout << std::endl;
   
 }
Matrix<double> SixHumpCamelBackFunction::calculate_Hessian(void) const
{
   const unsigned int variables_number = 2;

   const Vector<double> argument = neural_network_pointer->get_independent_parameters_pointer()->get_parameters();

   Matrix<double> hessian(variables_number, variables_number);

   hessian[0][0] = 10* pow(argument[0],4) - 25.2 * pow(argument[0],2) + 8;
   hessian[0][1] = 1.0;
   hessian[1][0] = 1.0;
   hessian[1][1] = 48*pow(argument[1],2)-8;

   return(hessian);
}
Exemple #11
0
/* hessian(tag, n, x[n], lower triangle of H[n][n])                         */
fint hessian_(fint* ftag,
              fint* fn,
              fdouble* fx,
              fdouble* fh) /* length of h should be n*n but the
                            upper half of this matrix remains unchanged */
{
    int rc= -1;
    int tag=*ftag, n=*fn;
    double** H = myalloc2(n,n);
    double* x = myalloc1(n);
    spread1(n,fx,x);
    rc= hessian(tag,n,x,H);
    pack2(n,n,H,fh);
    free((char*)*H);
    free((char*)H);
    free((char*)x);
    return rc;
}
/**
 * Generating the gradient and the hessian from my_matrixfun
 */
void test_matrix_twice(){
   std::cout << "== test_matrix_twice() ==" << std::endl;
   // use with normal floats
   Eigen::VectorXd a(3),b(3);
   a.setLinSpaced(0.,1.);
   b.setLinSpaced(1.,2.);
   double c = my_matrixfun(a,b);
   std::cout << "Result: " << c << std::endl;

   // use with AutoDiffScalar
   typedef Eigen::Matrix<double,Eigen::Dynamic,1> inner_derivative_type;
   typedef Eigen::AutoDiffScalar<inner_derivative_type> inner_active_scalar;
   typedef Eigen::Matrix<inner_active_scalar,Eigen::Dynamic,1> outer_derivative_type;
   typedef Eigen::AutoDiffScalar<outer_derivative_type> outer_active_scalar;
   typedef Eigen::Matrix<outer_active_scalar,Eigen::Dynamic,1> AVector;
   AVector Aa(a.size()),Ab(b.size());
   // copy value from non-active example
   for(int i=0;i<a.size();i++)Aa(i).value().value() = a(i);
   for(int i=0;i<b.size();i++)Ab(i).value().value() = b(i);
   // initialize derivative vectors
   const int derivative_num = a.size() + b.size();
   int derivative_idx = 0;
   for(int i=0;i<Aa.size();i++){
       init_twice_active_var(Aa(i),derivative_num,derivative_idx);
       derivative_idx++;
   }
   for(int i=0;i<Ab.size();i++){
       init_twice_active_var(Ab(i),derivative_num,derivative_idx);
       derivative_idx++;
   }

   outer_active_scalar Ac = my_matrixfun(Aa,Ab);
   std::cout << "Result: " << Ac.value().value() << std::endl;
   std::cout << "Gradient: " << 
       Ac.value().derivatives().transpose() << std::endl;

   std::cout << "Hessian" << std::endl;
   Eigen::MatrixXd hessian(Ac.derivatives().size(),Ac.derivatives().size());
   for(int idx=0;idx<Ac.derivatives().size();idx++){
       hessian.middleRows(idx,1) = 
           Ac.derivatives()(idx).derivatives().transpose();
   }
   std::cout << hessian << std::endl;
}
Matrix<double> DeJongFunction::getHessian(Vector<double> argument)
{
   Matrix<double> hessian(numberOfVariables, numberOfVariables, 0.0);

   for(int i = 0; i < numberOfVariables; i++)
   {
      for(int j = 0; j < numberOfVariables; j++)
      {
         if(i == j)
         {
            hessian[i][j] = 2.0;
         }
         else
         {
            hessian[i][j] = 0.0;
         }
      }
   }

   return(hessian);
}
  typename element_type_trait<Tp>::element_type estimate_error_hessian(fitter<Ty,Tx,Tp,Ts>& fit,const Tstr& pname,const Ts& dchi)
  {
    size_t porder=fit.get_param_order(pname);
    holder<param_modifier<Ty,Tx,Tp,Tstr> > h;
    try
      {
	h.reset(fit.get_param_modifier().clone());
      }
    catch(const param_modifier_not_defined&)
      {
	h.reset(0);
      }
    fit.clear_param_modifier();
    Tp p=fit.get_all_params();
    Ts a=hessian(fit.get_statistic(),p,porder,porder)/2;
    if(h.get())
      {
	fit.set_param_modifier(*(h.get()));
      }
    fit.fit();
    return std::sqrt(dchi/a);
  }
Exemple #15
0
Warp MT::Lucas_Kanade(Warp warp)
{	
	//See "Lucas-Kanade 20 years on A unifying framework"
	float last_E = 1.0f;
	for (int iter = 0; iter < max_iteration; ++iter) {
		++number_iteration;
		Matrix<float, 6, 1> G = Matrix<float, 6, 1>::Constant(0.0f);
		Matrix<float, 6, 6> H = Matrix<float, 6, 6>::Constant(0.0f);
		float E = 0.0f;
		for (int i = 0; i < fine_samples.size(); ++i) {
			Matrix<float, 2, 6> dW;
			Vector2f p = warp.gradient(fine_samples[i], dW);
			Vector32f F;
			Matrix<float, 32, 2> dF;
			feature.gradient4(p.x(), p.y(), F.data(), dF.col(0).data(), dF.col(1).data());
			F -= fine_model.col(i);
			float e = sigmoid(F.squaredNorm());
			float w = sigmoid_factor * e * (1.0f - e);
			G += w * (dW.transpose() * (dF.transpose() * -F));
			//H.triangularView<Upper> += w * (dW.transpose() * (dF.transpose() * dF) * dW);
			hessian(H, w, dW, dF);
			E += e;
		}
		E = E / fine_samples.size();
		H.triangularView<Lower>() = H.transpose();
		Matrix<float, 6, 1> D = H.fullPivHouseholderQr().solve(G);
		warp.steepest(D);
		if (log != NULL)
			(*log) << E << " ";
		if (iter > 1 && D.segment<3>(3).squaredNorm() < translate_eps && last_E - E < error_eps)
			break;
		last_E = E;
	}
	if (log != NULL)
		(*log) << endl;
	return warp;
}
Exemple #16
0
double SaLSA::get_Adiel_and_grad_internal(ScalarFieldTilde& Adiel_rhoExplicitTilde, ScalarFieldTilde& Adiel_nCavityTilde, IonicGradient* extraForces, bool electricOnly) const
{
	EnergyComponents& Adiel = ((SaLSA*)this)->Adiel;
	const ScalarFieldTilde& phi = state; // that's what we solved for in minimize

	//First-order correct estimate of electrostatic energy:
	ScalarFieldTilde phiExt = coulomb(rhoExplicitTilde);
	Adiel["Electrostatic"] = -0.5*dot(phi, O(hessian(phi))) + dot(phi - 0.5*phiExt, O(rhoExplicitTilde));
	
	//Gradient w.r.t rhoExplicitTilde:
	Adiel_rhoExplicitTilde = phi - phiExt;

	//The "cavity" gradient is computed by chain rule via the gradient w.r.t to the shape function:
	const auto& solvent = fsp.solvents[0];
	ScalarField Adiel_shape; ScalarFieldArray Adiel_siteShape(solvent->molecule.sites.size());
	for(int r=rStart; r<rStop; r++)
	{	const MultipoleResponse& resp = *response[r];
		ScalarField& Adiel_s = resp.iSite<0 ? Adiel_shape : Adiel_siteShape[resp.iSite];
		if(resp.l>6) die("Angular momenta l > 6 not supported.\n");
		double prefac = 0.5 * 4*M_PI/(2*resp.l+1);
		ScalarFieldArray IlGradVphi = I(lGradient(resp.V * phi, resp.l));
		for(int lpm=0; lpm<(2*resp.l+1); lpm++)
			Adiel_s -= prefac * (IlGradVphi[lpm]*IlGradVphi[lpm]);
	}
	for(unsigned iSite=0; iSite<solvent->molecule.sites.size(); iSite++)
		if(Adiel_siteShape[iSite])
			Adiel_shape += I(Sf[iSite] * J(Adiel_siteShape[iSite]));
	nullToZero(Adiel_shape, gInfo); Adiel_shape->allReduce(MPIUtil::ReduceSum);
	
	//Propagate shape gradients to A_nCavity:
	ScalarField Adiel_nCavity;
	propagateCavityGradients(Adiel_shape, Adiel_nCavity, Adiel_rhoExplicitTilde, electricOnly);
	Adiel_nCavityTilde = nFluid * J(Adiel_nCavity);
	
	setExtraForces(extraForces, Adiel_nCavityTilde);
	return Adiel;
}
  double PRSS::find_posterior_mode() {
    const Selector &included(model_->inc());
    d2TargetFunPointerAdapter logpost(
        boost::bind(&PoissonRegressionModel::log_likelihood, model_,
                    _1, _2, _3, _4),
        boost::bind(&MvnBase::logp_given_inclusion, slab_prior_.get(),
                    _1, _2, _3, included, _4));
    Vector beta = model_->included_coefficients();
    int dim = beta.size();
    if (dim == 0) {
      return negative_infinity();
      // TODO: This logic prohibits an empty model.  Better to return
      // the actual value of the un-normalized log posterior, which in
      // this case would just be the likelihood portion.
    }

    Vector gradient(dim);
    Spd hessian(dim);
    double logf;
    std::string error_message;
    bool ok = max_nd2_careful(beta,
                              gradient,
                              hessian,
                              logf,
                              Target(logpost),
                              dTarget(logpost),
                              d2Target(logpost),
                              1e-5,
                              error_message);
    if (ok) {
      model_->set_included_coefficients(beta, included);
      return logf;
    } else {
      return negative_infinity();
    }
  }
Exemple #18
0
vector<vector<double> > qFinderDMM::getHessian(){
    try {
        vector<double> alpha(numOTUs, 0.0000);
        double alphaSum = 0.0000;
        
        vector<double> pi = zMatrix[currentPartition];
        vector<double> psi_ajk(numOTUs, 0.0000);
        vector<double> psi_cjk(numOTUs, 0.0000);
        vector<double> psi1_ajk(numOTUs, 0.0000);
        vector<double> psi1_cjk(numOTUs, 0.0000);
        
        for(int j=0;j<numOTUs;j++){
            
            if (m->control_pressed) {  break; }
            
            alpha[j] = exp(lambdaMatrix[currentPartition][j]);
            alphaSum += alpha[j];
            
            for(int i=0;i<numSamples;i++){
                double X = (double) countMatrix[i][j];
                
                psi_ajk[j] += pi[i] * psi(alpha[j]);
                psi1_ajk[j] += pi[i] * psi1(alpha[j]);
                
                psi_cjk[j] += pi[i] * psi(alpha[j] + X);
                psi1_cjk[j] += pi[i] * psi1(alpha[j] + X);
            }
        }
        
        
        double psi_Ck = 0.0000;
        double psi1_Ck = 0.0000;
        
        double weight = 0.0000;
        
        for(int i=0;i<numSamples;i++){
            if (m->control_pressed) {  break; }
            weight += pi[i];
            double sum = 0.0000;
            for(int j=0;j<numOTUs;j++){     sum += alpha[j] + countMatrix[i][j];    }
            
            psi_Ck += pi[i] * psi(sum);
            psi1_Ck += pi[i] * psi1(sum);
        }
        
        double psi_Ak = weight * psi(alphaSum);
        double psi1_Ak = weight * psi1(alphaSum);
        
        vector<vector<double> > hessian(numOTUs);
        for(int i=0;i<numOTUs;i++){ hessian[i].assign(numOTUs, 0.0000); }
        
        for(int i=0;i<numOTUs;i++){
            if (m->control_pressed) {  break; }
            double term1 = -alpha[i] * (- psi_ajk[i] + psi_Ak + psi_cjk[i] - psi_Ck);
            double term2 = -alpha[i] * alpha[i] * (-psi1_ajk[i] + psi1_Ak + psi1_cjk[i] - psi1_Ck);
            double term3 = 0.1 * alpha[i];
            
            hessian[i][i] = term1 + term2 + term3;
            
            for(int j=0;j<i;j++){   
                hessian[i][j] = - alpha[i] * alpha[j] * (psi1_Ak - psi1_Ck);
                hessian[j][i] = hessian[i][j];
            }
        }
        
        return hessian;
    }
    catch(exception& e){
        m->errorOut(e, "qFinderDMM", "getHessian");
        exit(1);
    }
}
Exemple #19
0
/***********************************************************************//**
 * @brief Evaluate log-likelihood function
 *
 * @param[in] pars Optimizer parameters.
 *
 * @exception GException::invalid_statistics
 *            Invalid optimization statistics encountered.
 *
 * This method evaluates the -(log-likelihood) function for parameter
 * optimization. It handles both binned and unbinned data and supportes
 * Poisson and Gaussian statistics. 
 * Note that different statistics and different analysis methods
 * (binned/unbinned) may be combined.
 ***************************************************************************/
void GObservations::likelihood::eval(const GOptimizerPars& pars) 
{
    // Timing measurement
    #if defined(G_EVAL_TIMING)
    #ifdef _OPENMP
    double t_start = omp_get_wtime();
    #else
    clock_t t_start = clock();
    #endif
    #endif

    // Single loop for common exit point
    do {

        // Get number of parameters
        int npars = pars.size();

        // Fall through if we have no free parameters
        if (npars < 1) {
            continue;
        }

        // Free old memory
        if (m_gradient  != NULL) delete m_gradient;
        if (m_curvature != NULL) delete m_curvature;

        // Initialise value, gradient vector and curvature matrix
        m_value     = 0.0;
        m_npred     = 0.0;
        m_gradient  = new GVector(npars);
        m_curvature = new GMatrixSparse(npars,npars);

        // Set stack size and number of entries
        int stack_size  = (2*npars > 100000) ? 2*npars : 100000;
        int max_entries =  2*npars;
        m_curvature->stack_init(stack_size, max_entries);

        // Allocate vectors to save working variables of each thread
        std::vector<GVector*>       vect_cpy_grad;
        std::vector<GMatrixSparse*> vect_cpy_curvature;
        std::vector<double*>        vect_cpy_value;
        std::vector<double*>        vect_cpy_npred;

        // Here OpenMP will paralellize the execution. The following code will
        // be executed by the differents threads. In order to avoid protecting
        // attributes ( m_value,m_npred, m_gradient and m_curvature), each thread
        // works with its own working variables (cpy_*). When a thread starts,
        // we add working variables in a vector (vect_cpy_*). When computation
        // is finished we just add all elements contain in the vector to the
        // attributes value.
        #pragma omp parallel
        {
            // Allocate and initialize variable copies for multi-threading
            GModels        cpy_model(m_this->models());
            GVector*       cpy_gradient  = new GVector(npars);
            GMatrixSparse* cpy_curvature = new GMatrixSparse(npars,npars);
            double*        cpy_npred     = new double(0.0);
            double*        cpy_value     = new double(0.0);

            // Set stack size and number of entries
            cpy_curvature->stack_init(stack_size, max_entries);

            // Push variable copies into vector. This is a critical zone to
            // avoid multiple thread pushing simultaneously.
            #pragma omp critical
            {
                vect_cpy_grad.push_back(cpy_gradient);
                vect_cpy_curvature.push_back(cpy_curvature); 
                vect_cpy_value.push_back(cpy_value);
                vect_cpy_npred.push_back(cpy_npred);
            }

            // Loop over all observations. The omp for directive will deal
            // with the iterations on the differents threads.
            #pragma omp for
            for (int i = 0; i < m_this->size(); ++i) {

                // Compute likelihood
                *cpy_value += m_this->m_obs[i]->likelihood(cpy_model,
                                                           cpy_gradient,
                                                           cpy_curvature,
                                                           cpy_npred);

            } // endfor: looped over observations

            // Release stack
            cpy_curvature->stack_destroy();

        } // end pragma omp parallel

        // Now the computation is finished, update attributes.
        // For each omp section, a thread will be created.
        #pragma omp sections
        {
            #pragma omp section
            {
                for (int i = 0; i < vect_cpy_curvature.size() ; ++i) {
                    *m_curvature += *(vect_cpy_curvature.at(i));
                    delete vect_cpy_curvature.at(i);
                }
            }

            #pragma omp section
            {
                for (int i = 0; i < vect_cpy_grad.size(); ++i){
                    *m_gradient += *(vect_cpy_grad.at(i));
                    delete vect_cpy_grad.at(i);
                }
            }

            #pragma omp section
            {
                for(int i = 0; i < vect_cpy_npred.size(); ++i){
                    m_npred += *(vect_cpy_npred.at(i));
                    delete vect_cpy_npred.at(i);
                }
            }

            #pragma omp section
            {
                for (int i = 0; i < vect_cpy_value.size(); ++i){
                    m_value += *(vect_cpy_value.at(i));
                    delete vect_cpy_value.at(i);
                }
            }
        } // end of pragma omp sections

        // Release stack
        m_curvature->stack_destroy();

    } while(0); // endwhile: main loop

    // Copy over the parameter gradients for all parameters that are
    // free (so that we can access the gradients from outside)
    for (int ipar = 0; ipar < pars.size(); ++ipar) {
        if (pars[ipar]->is_free()) {
            GOptimizerPar* par = const_cast<GOptimizerPar*>(pars[ipar]);
            par->factor_gradient((*m_gradient)[ipar]);
        }
    }

    // Optionally use Hessian instead of curvature matrix
    #if defined(G_USE_HESSIAN)
    *m_curvature = hessian(pars);
    #endif

    // Optionally dump gradient and curvature matrix
    #if defined(G_EVAL_DEBUG)
    std::cout << *m_gradient << std::endl;
    for (int i = 0; i < pars.size(); ++i) {
        for (int j = 0; j < pars.size(); ++j) {
            std::cout << (*m_curvature)(i,j) << " ";
        }
        std::cout << std::endl;
    }
    #endif

    // Timing measurement
    #if defined(G_EVAL_TIMING)
    #ifdef _OPENMP
    double t_elapse = omp_get_wtime()-t_start;
    #else
    double t_elapse = (double)(clock() - t_start) / (double)CLOCKS_PER_SEC;
    #endif
    std::cout << "GObservations::optimizer::eval: CPU usage = "
              << t_elapse << " sec" << std::endl;
    #endif

    // Return
    return;
}
Exemple #20
0
/*                                                             MAIN PROGRAM */
int main() {
    int i, j, k;
    int tag = 1;                  /* tape tag */
    int taskCount = 0;

    int pFW, pRV, pTR, degree, keep;   /* forward/reverse parameters */
    int evalCount;                     /* # of evaluations */


    /****************************************************************************/
    /*                                        READ CONTROL PARAMETERS FROM FILE */
    int controlParameters[cpCount];
    FILE* controlFile;

    /*------------------------------------------------------------------------*/
    /*                                                      open file to read */
    if ((controlFile = fopen(controlFileName,"r")) == NULL) {
        fprintf(stdout,"ERROR: Could not open control file %s\n",
                controlFileName);
        exit(-1);
    }

    /*------------------------------------------------------------------------*/
    /*                                                        read all values */
    for (i=0; i<cpCount; i++)
        fscanf(controlFile,"%d%*[^\n]",&controlParameters[i]);

    indepDim  = controlParameters[cpDimension];
    pFW       = controlParameters[cpVecCountFW];
    pRV       = controlParameters[cpVecCountRV];
    pTR       = controlParameters[cpVecCountTR];
    degree    = controlParameters[cpDegree];
    evalCount = controlParameters[cpAverageCount];

    /*------------------------------------------------------------------------*/
    /*                                                     close control file */
    fclose(controlFile);


    /****************************************************************************/
    /*                                               VARIABLES & INITIALIZATION */

    /*------------------------------------------------------------------------*/
    /* Initialize all problem parameters (including  dimension) */
    initProblemParameters();

    /*------------------------------------------------------------------------*/
    /* Initialize the independent variables */
    double* indeps = new double[indepDim];
    initIndependents(indeps);

    /*------------------------------------------------------------------------*/
    /* Check main parameters */
    if (evalCount <= 0) {
        fprintf(stdout,"    # of evaluations to average over = ? ");
        fscanf(stdin,"%d",&evalCount);
        fprintf(stdout,"\n");
    }

    if ((degree <= 1) &&
            (controlParameters[cpHosFW] || controlParameters[cpHovFW] ||
             controlParameters[cpHosRV] || controlParameters[cpHovRV] ||
             controlParameters[cpTensor])) {
        fprintf(stdout,"    degree = ? ");
        fscanf(stdin,"%d",&degree);
        fprintf(stdout,"\n");
    }
    keep = degree + 1;

    if ((pFW < 1) &&
            (controlParameters[cpFovFW] || controlParameters[cpHovFW])) {
        fprintf(stdout,"    # of vectors in vector forward mode = ? ");
        fscanf(stdin,"%d",&pFW);
        fprintf(stdout,"\n");
    }

    if ((pRV < 1) &&
            (controlParameters[cpFovRV] || controlParameters[cpHovRV])) {
        fprintf(stdout,"    # of vectors in vector reverse mode = ? ");
        fscanf(stdin,"%d",&pRV);
        fprintf(stdout,"\n");
    }

    if ((pTR < 1) &&
            (controlParameters[cpTensor])) {
        fprintf(stdout,"    # of vectors in tensor mode = ? ");
        fscanf(stdin,"%d",&pTR);
        fprintf(stdout,"\n");
    }

    /*------------------------------------------------------------------------*/
    /* Necessary variable */
    double depOrig=0.0, depTape;    /* function value */
    double ***XPPP, **XPP;
    double ***YPPP, **YPP, *YP;
    double ***ZPPP, **ZPP, *ZP;
    double          *UP, u;
    double                 *VP;
    double                 *WP;
    double          *JP;
    short           **nzPP;
    int retVal=0;                 /* return value */
    double t00, t01, t02, t03;  /* time values */
    double          **TPP;
    double          **SPP;
    double          **HPP;
    int dim;


    /****************************************************************************/
    /*                                                          NORMALIZE TIMER */



    /****************************************************************************/
    /*                                          0. ORIGINAL FUNCTION EVALUATION */
    /*                                             ---> always                  */
    fprintf(stdout,"\nTASK %d: Original function evaluation\n",
            taskCount++);

    t00 = myclock();
    for (i=0; i<evalCount; i++)
        depOrig = originalScalarFunction(indeps);
    t01 = myclock();

    double timeUnit;
    if (t01-t00) {
        timeUnit = 1.0/(t01-t00);
        fprintf(stdout,"          ");
        fprintf(stdout,TIMEFORMAT,1.0,
                (t01-t00)/evalCount);
    } else {
        fprintf(stdout,"    !!! zero timing !!!\n");
        fprintf(stdout,"    set time unit to 1.0\n");
        timeUnit = 1;
    }


    /****************************************************************************/
    /*                                                   1. TAPING THE FUNCTION */
    /*                                                      ---> always         */
    fprintf(stdout,"--------------------------------------------------------");
    fprintf(stdout,"\nTASK %d: Taping the function\n",
            taskCount++);

    t00 = myclock();
    /* NOTE: taping will be performed ONCE only */
    depTape = tapingScalarFunction(tag,indeps);
    t01 = myclock();

    size_t tape_stats[STAT_SIZE];
    tapestats(tag,tape_stats);

    fprintf(stdout,"\n    independents            %zu\n",tape_stats[NUM_INDEPENDENTS]);
    fprintf(stdout,"    dependents              %zu\n",tape_stats[NUM_DEPENDENTS]);
    fprintf(stdout,"    operations              %zu\n",tape_stats[NUM_OPERATIONS]);
    fprintf(stdout,"    operations buffer size  %zu\n",tape_stats[OP_BUFFER_SIZE]);
    fprintf(stdout,"    locations buffer size   %zu\n",tape_stats[LOC_BUFFER_SIZE]);
    fprintf(stdout,"    constants buffer size   %zu\n",tape_stats[VAL_BUFFER_SIZE]);
    fprintf(stdout,"    maxlive                 %zu\n",tape_stats[NUM_MAX_LIVES]);
    fprintf(stdout,"    valstack size           %zu\n\n",tape_stats[TAY_STACK_SIZE]);

    fprintf(stdout,"           ");
    fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit*evalCount,
            (t01-t00));

    /****************************************************************************/
    /*                                                           2. ZOS_FORWARD */
    if (controlParameters[cpZosFW]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: forward(tag, m=1, n=%d, keep, X[n], Y[m])\n",
                taskCount++,indepDim);
        fprintf(stdout,"         ---> zos_forward\n");

        /*----------------------------------------------------------------------*/
        /* NO KEEP */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,0,indeps,&depTape);
        t01 = myclock();

        fprintf(stdout,"    NO KEEP");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* KEEP */
        t02 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,1,indeps,&depTape);
        t03 = myclock();

        fprintf(stdout,"    KEEP   ");
        fprintf(stdout,TIMEFORMAT,(t03-t02)*timeUnit,
                (t03-t02)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpZosFW] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
            fprintf(stdout,"    Should be the same values:\n");
            fprintf(stdout,"    (original) %12.8E =? %12.8E (forward from tape)\n",
                    depOrig,depTape);
        }
    }


    /****************************************************************************/
    /*                                                           3. FOS_FORWARD */
    if (controlParameters[cpFosFW]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: forward(tag, m=1, n=%d, d=1, keep, X[n][d+1], Y[d+1])\n",
                taskCount++,indepDim);
        fprintf(stdout,"         ---> fos_forward\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        XPP = new double*[indepDim];
        for (i=0; i<indepDim; i++) {
            XPP[i] = new double[2];
            XPP[i][0] = indeps[i];
            XPP[i][1] = (double)rand();
        }
        YP = new double[2];

        /*----------------------------------------------------------------------*/
        /* NO KEEP */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,1,0,XPP,YP);
        t01 = myclock();

        fprintf(stdout,"    NO KEEP");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* KEEP */
        t02 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,1,2,XPP,YP);
        t03 = myclock();

        fprintf(stdout,"    KEEP   ");
        fprintf(stdout,TIMEFORMAT,(t03-t02)*timeUnit,
                (t03-t02)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpFosFW] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
            fprintf(stdout,"    Should be the same values:\n");
            fprintf(stdout,"    (original) %12.8E =? %12.8E (forward from tape)\n",
                    depOrig,YP[0]);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<indepDim; i++)
            delete[] XPP[i];
        delete[] XPP;
        delete[] YP;
    }


    /****************************************************************************/
    /*                                                           4. HOS_FORWARD */
    if (controlParameters[cpHosFW]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: forward(tag, m=1, n=%d, d=%d, keep, X[n][d+1], Y[d+1])\n",
                taskCount++,indepDim,degree);
        fprintf(stdout,"         ---> hos_forward\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        XPP = new double*[indepDim];
        for (i=0; i<indepDim; i++) {
            XPP[i] = new double[1+degree];
            XPP[i][0] = indeps[i];
            for (j=1; j<=degree; j++)
                XPP[i][j] = (double)rand();
        }
        YP = new double[1+degree];

        /*----------------------------------------------------------------------*/
        /* NO KEEP */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,degree,0,XPP,YP);
        t01 = myclock();

        fprintf(stdout,"    NO KEEP");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* KEEP */
        t02 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,degree,keep,XPP,YP);
        t03 = myclock();

        fprintf(stdout,"    KEEP   ");
        fprintf(stdout,TIMEFORMAT,(t03-t02)*timeUnit,
                (t03-t02)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpHosFW] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
            fprintf(stdout,"    Should be the same values:\n");
            fprintf(stdout,"    (original) %12.8E =? %12.8E (forward from tape)\n",
                    depOrig,YP[0]);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<indepDim; i++)
            delete[] XPP[i];
        delete[] XPP;
        delete[] YP;
    }


    /****************************************************************************/
    /*                                                           5. FOV_FORWARD */
    if (controlParameters[cpFovFW]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: forward(tag, m=1, n=%d, p=%d, x[n], X[n][p], y[m], Y[m][p])\n",
                taskCount++,indepDim,pFW);
        fprintf(stdout,"         ---> fov_forward\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        XPP = new double*[indepDim];
        for (i=0; i<indepDim; i++) {
            XPP[i] = new double[pFW];
            for (j=0; j<pFW; j++)
                XPP[i][j] = (double)rand();
        }
        YP  = new double[1];
        YPP = new double*[1];
        YPP[0] = new double[pFW];

        /*----------------------------------------------------------------------*/
        /* always NO KEEP */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,pFW,indeps,XPP,YP,YPP);
        t01 = myclock();

        fprintf(stdout,"  (NO KEEP)");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpFovFW] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<indepDim; i++)
            delete[] XPP[i];
        delete[] XPP;
        delete[] YP;
        delete[] YPP[0];
        delete[] YPP;
    }


    /****************************************************************************/
    /*                                                           6. HOV_FORWARD */
    if (controlParameters[cpHovFW]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: forward(tag, m=1, n=%d, d=%d, p=%d, x[n], X[n][p][d], y[m], Y[m][p][d])\n",
                taskCount++,indepDim,degree,pFW);
        fprintf(stdout,"         ---> hov_forward\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        XPPP = new double**[indepDim];
        for (i=0; i<indepDim; i++) {
            XPPP[i] = new double*[pFW];
            for (j=0; j<pFW; j++) {
                XPPP[i][j] = new double[degree];
                for (k=0; k<degree; k++)
                    XPPP[i][j][k] = (double)rand();
            }
        }
        YP  = new double[1];
        YPPP = new double**[1];
        YPPP[0] = new double*[pFW];
        for (j=0; j<pFW; j++)
            YPPP[0][j] = new double[degree];

        /*----------------------------------------------------------------------*/
        /* always NO KEEP */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = forward(tag,1,indepDim,degree,pFW,indeps,XPPP,YP,YPPP);
        t01 = myclock();

        fprintf(stdout,"  (NO KEEP)");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpHovFW] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<indepDim; i++) {
            for (j=0; j<pFW; j++)
                delete[] XPPP[i][j];
            delete[] XPPP[i];
        }
        delete[] XPPP;
        delete[] YP;
        for (j=0; j<pFW; j++)
            delete[] YPPP[0][j];
        delete[] YPPP[0];
        delete[] YPPP;
    }


    /****************************************************************************/
    /*                                                           7. FOS_REVERSE */
    if (controlParameters[cpFosRV]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: reverse(tag, m=1, n=%d, d=0, u, Z[n])\n",
                taskCount++,indepDim);
        fprintf(stdout,"         ---> fos_reverse\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        ZP = new double[indepDim];
        u  = (double)rand();

        /*----------------------------------------------------------------------*/
        /* Forward with keep*/
        forward(tag,1,indepDim,1,indeps,&depTape);

        /*----------------------------------------------------------------------*/
        /* Reverse */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = reverse(tag,1,indepDim,0,u,ZP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpFosRV] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] ZP;
    }


    /****************************************************************************/
    /*                                                           8. HOS_REVERSE */
    if (controlParameters[cpHosRV]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: reverse(tag, m=1, n=%d, d=%d, u, Z[n][d+1])\n",
                taskCount++,indepDim,degree);
        fprintf(stdout,"         ---> hos_reverse\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        ZPP = new double*[indepDim];
        for (i=0; i<indepDim; i++)
            ZPP[i] = new double[degree+1];
        u  = (double)rand();
        XPP = new double*[indepDim];
        for (i=0; i<indepDim; i++) {
            XPP[i] = new double[1+degree];
            XPP[i][0] = indeps[i];
            for (j=1; j<=degree; j++)
                XPP[i][j] = (double)rand();
        }
        YP = new double[1+degree];

        /*----------------------------------------------------------------------*/
        /* Forward with keep*/
        forward(tag,1,indepDim,degree,keep,XPP,YP);

        /*----------------------------------------------------------------------*/
        /* Reverse */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = reverse(tag,1,indepDim,degree,u,ZPP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpHosRV] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<indepDim; i++)
            delete[] ZPP[i];
        delete[] ZPP;
        for (i=0; i<indepDim; i++)
            delete[] XPP[i];
        delete[] XPP;
        delete[] YP;
    }


    /****************************************************************************/
    /*                                                           9. FOV_REVERSE */
    if (controlParameters[cpFovRV]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: reverse(tag, m=1, n=%d, d=0, p=%d, U[p], Z[p][n])\n",
                taskCount++,indepDim,pRV);
        fprintf(stdout,"         ---> fov_reverse\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        ZPP = new double*[pRV];
        for (i=0; i<pRV; i++)
            ZPP[i] = new double[indepDim];
        UP = new double[pRV];
        for (i=0; i<pRV; i++)
            UP[i] = (double)rand();

        /*----------------------------------------------------------------------*/
        /* Forward with keep*/
        forward(tag,1,indepDim,1,indeps,&depTape);

        /*----------------------------------------------------------------------*/
        /* Reverse */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = reverse(tag,1,indepDim,0,pRV,UP,ZPP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpFovRV] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<pRV; i++)
            delete[] ZPP[i];
        delete[] ZPP;
        delete[] UP;
    }


    /****************************************************************************/
    /*                                                          10. HOV_REVERSE */
    if (controlParameters[cpHovRV]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: reverse(tag, m=1, n=%d, d=%d, p=%d, U[p], Z[p][n][d+1], nz[p][n])\n",
                taskCount++,indepDim,degree,pRV);
        fprintf(stdout,"         ---> hov_reverse\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        ZPPP = new double**[pRV];
        for (i=0; i<pRV; i++) {
            ZPPP[i] = new double*[indepDim];
            for (j=0; j<indepDim; j++)
                ZPPP[i][j] = new double[degree+1];
        }
        UP = new double[pRV];
        for (i=0; i<pRV; i++)
            UP[i] = (double)rand();
        XPP = new double*[indepDim];
        for (i=0; i<indepDim; i++) {
            XPP[i] = new double[1+degree];
            XPP[i][0] = indeps[i];
            for (j=1; j<=degree; j++)
                XPP[i][j] = (double)rand();
        }
        YP = new double[1+degree];
        nzPP = new short*[pRV];
        for (i=0; i<pRV; i++)
            nzPP[i] = new short[indepDim];

        /*----------------------------------------------------------------------*/
        /* Forward with keep*/
        forward(tag,1,indepDim,degree,keep,XPP,YP);

        /*----------------------------------------------------------------------*/
        /* Reverse  without nonzero pattern*/
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = reverse(tag,1,indepDim,degree,pRV,UP,ZPPP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Reverse  with nonzero pattern*/
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = reverse(tag,1,indepDim,degree,pRV,UP,ZPPP,nzPP);
        t01 = myclock();

        fprintf(stdout,"       (NZ)");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpHovRV] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<pRV; i++) {
            for (j=0; j<indepDim; j++)
                delete[] ZPPP[i][j];
            delete[] ZPPP[i];
            delete[] nzPP[i];
        }
        delete[] ZPPP;
        delete[] nzPP;
        delete[] UP;
        for (i=0; i<indepDim; i++)
            delete[] XPP[i];
        delete[] XPP;
        delete[] YP;
    }


    /****************************************************************************/
    /*                                                             11. FUNCTION */
    if (controlParameters[cpFunction]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: function(tag, m=1, n=%d, X[n], Y[m])\n",
                taskCount++,indepDim);

        /*----------------------------------------------------------------------*/
        /* Function evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = function(tag,1,indepDim,indeps,&depTape);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpFunction] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
            fprintf(stdout,"    Should be the same values:\n");
            fprintf(stdout,"    (original) %12.8E =? %12.8E (forward from tape)\n",
                    depOrig,depTape);
        }
    }


    /****************************************************************************/
    /*                                                             12. JACOBIAN */
    if (controlParameters[cpJacobian]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: gradient(tag, n=%d, X[n], G[n])\n",
                taskCount++,indepDim);

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        JP = new double[indepDim];

        /*----------------------------------------------------------------------*/
        /* Gradient evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = gradient(tag,indepDim,indeps,JP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpJacobian] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] JP;
    }


    /****************************************************************************/
    /*                                                               13. VECJAC */
    if (controlParameters[cpVecJac]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: vec_jac(tag, m=1, n=%d, repeat, X[n], U[m], V[n])\n",
                taskCount++,indepDim);

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        UP = new double[1];
        UP[0] = (double)rand();
        VP = new double[indepDim];

        /*----------------------------------------------------------------------*/
        /* Evaluation without repeat */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = vec_jac(tag,1,indepDim,0,indeps,UP,VP);
        t01 = myclock();

        fprintf(stdout,"(no repeat)");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Evaluation with repeat */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = vec_jac(tag,1,indepDim,1,indeps,UP,VP);
        t01 = myclock();

        fprintf(stdout,"   (repeat)");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpVecJac] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] UP;
        delete[] VP;
    }


    /****************************************************************************/
    /*                                                               14. JACVEC */
    if (controlParameters[cpJacVec]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: jac_vec(tag, m=1, n=%d, X[n], V[n], U[m])\n",
                taskCount++,indepDim);

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        UP = new double[1];
        VP = new double[indepDim];
        for (i=0; i<indepDim; i++)
            VP[i] = (double)rand();

        /*----------------------------------------------------------------------*/
        /* Evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = jac_vec(tag,1,indepDim,indeps,VP,UP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpJacVec] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] UP;
        delete[] VP;
    }


    /****************************************************************************/
    /*                                                              15. HESSIAN */
    if (controlParameters[cpHessian]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: hessian(tag, n=%d, X[n], lower triangle of H[n][n])\n",
                taskCount++,indepDim);

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        HPP = new double*[indepDim];
        for (i=0; i<indepDim; i++)
            HPP[i] = new double[indepDim];

        /*----------------------------------------------------------------------*/
        /* Evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = hessian(tag,indepDim,indeps,HPP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpHessian] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        for (i=0; i<indepDim; i++)
            delete[] HPP[i];
        delete[] HPP;
    }


    /****************************************************************************/
    /*                                                              16. HESSVEC */
    if (controlParameters[cpHessVec]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: hess_vec(tag, n=%d, X[n], V[n], W[n])\n",
                taskCount++,indepDim);

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        VP = new double[indepDim];
        for (i=0; i<indepDim; i++)
            VP[i] = (double)rand();
        WP = new double[indepDim];

        /*----------------------------------------------------------------------*/
        /* Evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = hess_vec(tag,indepDim,indeps,VP,WP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpHessVec] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] VP;
        delete[] WP;
    }


    /****************************************************************************/
    /*                                                           17. LAGHESSVEC */
    if (controlParameters[cpLagHessVec]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: lagra_hess_vec(tag, m=1, n=%d, X[n], U[m], V[n], W[n])\n",
                taskCount++,indepDim);

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        UP = new double[1];
        UP[0] = (double)rand();
        VP = new double[indepDim];
        for (i=0; i<indepDim; i++)
            VP[i] = (double)rand();
        WP = new double[indepDim];

        /*----------------------------------------------------------------------*/
        /* Evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            retVal = lagra_hess_vec(tag,1,indepDim,indeps,UP,VP,WP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
        if (controlParameters[cpLagHessVec] > 1) {
            fprintf(stdout,"\n    Return value: %d\n",retVal);
        }

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] VP;
        delete[] WP;
        delete[] UP;
    }


    /****************************************************************************/
    /*                                                               18. TENSOR */
    if (controlParameters[cpTensor]) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: tensor_eval(tag, m =1, n=%d, d=%d, p=%d, X[n], tensor[m][dim], S[n][p])\n",
                taskCount++,indepDim,degree, pTR);
        fprintf(stdout,"\n         dim = ((p+d) over d)\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        dim = binomi(pTR+degree,degree);
        TPP = new double*[1];
        TPP[0] = new double[dim];
        SPP = new double*[indepDim];
        for (i=0; i<indepDim; i++) {
            SPP[i] = new double[pTR];
            for (j=0; j<pTR; j++)
                SPP[i][j]=(i==j)?1.0:0.0;
        }

        /*----------------------------------------------------------------------*/
        /* tensor evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            tensor_eval(tag,1,indepDim,degree,pTR,indeps,TPP,SPP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
    if (controlParameters[cpTensor] > 1) {}

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] TPP[0];
        delete[] TPP;
        for (i=0; i<indepDim; i++)
            delete[] SPP[i];
        delete[] SPP;
    }


    /****************************************************************************/
    /*                                                       19. INVERSE TENSOR */
    if (controlParameters[cpInvTensor] && (1==indepDim)) {
        fprintf(stdout,"--------------------------------------------------------");
        fprintf(stdout,"\nTASK %d: inverse_tensor_eval(tag, m=n=1, d=%d, p=%d, X[n], tensor[m][dim], S[n][p])\n",
                taskCount++,degree, pTR);
        fprintf(stdout,"\n         dim = ((p+d) over d)\n");

        /*----------------------------------------------------------------------*/
        /* Allocation & initialisation of tensors */
        dim = binomi(pTR+degree,degree);
        TPP = new double*[1];
        TPP[0] = new double[dim];
        SPP = new double*[1];
        SPP[0] = new double[pTR];
        for (j=0; j<pTR; j++)
            SPP[0][j]=(0==j)?1.0:0.0;

        /*----------------------------------------------------------------------*/
        /* tensor evaluation */
        t00 = myclock();
        for (i=0; i<evalCount; i++)
            inverse_tensor_eval(tag,1,degree,pTR,indeps,TPP,SPP);
        t01 = myclock();

        fprintf(stdout,"           ");
        fprintf(stdout,TIMEFORMAT,(t01-t00)*timeUnit,
                (t01-t00)/evalCount);

        /*----------------------------------------------------------------------*/
        /* Debug infos */
    if (controlParameters[cpInvTensor] > 1) {}

        /*----------------------------------------------------------------------*/
        /* Free tensors */
        delete[] TPP[0];
        delete[] TPP;
        delete[] SPP[0];
        delete[] SPP;
    }

    return 1;
}
Exemple #21
0
/***********************************************************************//**
 * @brief Compute Hessian matrix
 *
 * @param[in] pars Optimizer parameters.
 *
 * @return Hessian matrix.
 ***************************************************************************/
GMatrixSparse GObservations::likelihood::hessian(const GOptimizerPars& pars)
{
    // Set strategy constants (low)
    //const int    ncyles             = 3;
    //const double step_tolerance     = 0.5;
    //const double gradient_tolerance = 0.1;

    // Set strategy constants (medium)
    const int    ncyles             = 5;
    const double step_tolerance     = 0.3;
    const double gradient_tolerance = 0.05;

    // Set strategy constants (high)
    //const int    ncyles             = 7;
    //const double step_tolerance     = 0.1;
    //const double gradient_tolerance = 0.02;


    // Create working copy of parameters
    GOptimizerPars wrk_pars = pars;

    // Get number of parameters
    int npars = wrk_pars.size();

    // Allocate Hessian matrix
    GMatrixSparse hessian(npars, npars);

    // Find out machine precision
    double eps = 0.1;
    while (1.0+eps != 1.0) {
        eps *= 0.5;
    }
    double eps2 = 2.0 * std::sqrt(eps);

    // Function value
    eval(wrk_pars);
    double f = value();

    // Compute aimsag
    double aimsag = std::sqrt(eps2) * std::abs(f);

    // Diagonal elements
    std::vector<double> g2(npars, 0.0);
    std::vector<double> grd(npars, 0.0);
    std::vector<double> dir(npars, 0.0);
    std::vector<double> yy(npars, 0.0);

    // Loop over parameters
    for (int i = 0; i < npars; ++i) {
    
        // Get parameter
        GOptimizerPar* par = wrk_pars[i];

        // Interrupt if parameter is fixed
        if (par->is_fixed()) {
            hessian(i,i) = 0.0;
            continue;
        }

        // Setup step size
        double xtf  = par->factor_value();
        double dmin = 8.0 * eps2 * std::abs(xtf);
        double d    = 0.000001;
        if (d < dmin) {
            d = dmin;
        }

        // Loop over cycles
        for (int icyc = 0; icyc < ncyles; ++icyc) {
        //for (int icyc = 0; icyc < 1; ++icyc) {

            // Initialise
            double sag = 0.0;
            double fs1 = 0.0; // right-hand side
            double fs2 = 0.0; // left-hand side

            // Compute gradient
            for (int multpy = 0; multpy < 5; ++multpy) {
            //for (int multpy = 0; multpy < 1; ++multpy) {

                // Compute right-hand side
                par->factor_value(xtf + d);
                eval(wrk_pars);
                fs1  = value();
                
                // Compute left-hand side
                par->factor_value(xtf - d);
                eval(wrk_pars);
                fs2  = value();
                
                // Recover current value
                par->factor_value(xtf);
                
                // Compute sag
                sag = 0.5 * (fs1 + fs2 - 2.0*f);

                // Break if sag is okay
                if (std::abs(sag) > eps2 || sag == 0.0) {
                    break;
                }

                // ... otherwise increase step size
                d *= 10.0;
                
            } // endfor

            // Save old step size and second derivative
            double dlast  = d;
            double g2bfor = g2[i];

            // Compute parameter derivatives and store step size and
            // function value
            g2[i]  = 2.0 * sag/(d*d);
            grd[i] = (fs1-fs2)/(2.*d);
            dir[i] = d;
            yy[i]  = fs1;

            // Compute a new step size based on the aimed sag
            if (sag != 0.0) {
                d = std::sqrt(2.0*aimsag/std::abs(g2[i]));
            }
            if (d < dmin) {
                d = dmin;
            }
            /*
            else if (par->factor_value()+d > par->factor_max()) {
                d = dmin;
            }
            else if (par->factor_value()-d > par->factor_min()) {
                d = dmin;
            }
            */
            
            // Check if converged
            if (std::abs((d-dlast)/d) < step_tolerance) {
                break;
            }
            if (std::abs((g2[i]-g2bfor)/g2[i]) < gradient_tolerance) {
                break;
            }
            d = std::min(d, 10.*dlast);
            d = std::max(d, 0.1*dlast);

        } // endfor: cycles

        // Set diagonal element
        hessian(i,i) = g2[i];

    } // endfor: looped over all parameters

    // Debug dump
    #if defined(G_HESSIAN)
    std::cout << "GObservations::likelihood::hessian: ";
    std::cout << "deltas and gradients:" << std::endl;
    for (int i = 0; i < npars; ++i) {
        std::cout << dir[i] << " ";
        std::cout << grd[i] << std::endl;
    }
    #endif

    // Compute off-diagonal elements
    for (int i = 0; i < npars; ++i) {
    
        // Get parameter 1
        GOptimizerPar* par1 = wrk_pars[i];
        double         x1   = par1->factor_value();
        
        // Increment parameter 1
        par1->factor_value(x1 + dir[i]);

        // Loop over columns
        for (int j = i+1; j < npars; ++j) {

            // Get parameter 2
            GOptimizerPar* par2 = wrk_pars[j];
            double         x2   = par2->factor_value();

            // Interrupt if parameter is fixed
            if (par1->is_fixed() || par2->is_fixed()) {
                hessian(i,j) = 0.0;
                hessian(j,i) = 0.0;
                continue;
            }

            // Increment parameter 2
            par2->factor_value(x2 + dir[j]);

            // Evaluate Hessian element
            eval(wrk_pars);
            double fs1     = value();
            double element = (fs1 + f - yy[i] - yy[j])/(dir[i]*dir[j]);
            
            // Store Hessian element
            hessian(i,j) = element;
            hessian(j,i) = element;

            // Restore parameter 2
            par2->factor_value(x2);
            
        } // endfor: looped over columns
        
        // Restore parameter 1
        par1->factor_value(x1);

    } // endfor: looped over parameters

    // Debug dump
    #if defined(G_HESSIAN)
    std::cout << "GObservations::likelihood::hessian: " << std::endl;
    std::cout << hessian << std::endl;
    #endif

    // Return Hessian
    return hessian;
}
Exemple #22
0
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
	double *v, *x, sigma, *lambda, *pr; mwIndex *ir, *jc;
	char *mode; int imode;

    //Check Inputs
    if(nrhs < 1) {
        printInfo();        
        return;
    }   
    if(nrhs < 2) {
        mexErrMsgTxt("You must supply the callback mode and input vector.");
        return;
    }
    if(mxIsEmpty(prhs[0]) || !mxIsChar(prhs[0])) {
        mexErrMsgTxt("The mode must be a string!");
        return;
    }
    if(!mxIsEmpty(prhs[1])) {
        if(mxIsClass(prhs[1],"scipvar") || mxIsClass(prhs[1],"barvec")) {
            mexErrMsgTxt("SCIP and BARON cannot be used with this callback function - please specify 'mcode' via symbset as the cbmode.");
            return;
        }           
        if(!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1])) {
            mexErrMsgTxt("The input vector must be a dense real double vector!");
            return;
        }
    }
    else {
        mexErrMsgTxt("The input vector must be a dense real double vector!");
        return;
    }
	//Check x input size
	if(mxGetNumberOfElements(prhs[1]) != getNoVar()) {
		mexErrMsgTxt("The input vector is not the right size!");
	}
	//Get x
	x = mxGetPr(prhs[1]);
	
	//Determine input mode and setup return variable
	mode = mxArrayToString(prhs[0]);
	lower(mode);
	if(!strcmp(mode,"obj")) {
		imode = 0;
		plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
		v = mxGetPr(plhs[0]);
	}
	else if(!strcmp(mode,"grad")) {
		imode = 1;
		plhs[0] = mxCreateDoubleMatrix(1,getNoVar(), mxREAL);
		v = mxGetPr(plhs[0]);
	}
	else if(!strcmp(mode,"con")) {
		imode = 2;
		plhs[0] = mxCreateDoubleMatrix(getNoCon(),1, mxREAL);
		v = mxGetPr(plhs[0]);
	}
	else if(!strcmp(mode,"jac")) {
		imode = 3;
		plhs[0] = mxCreateSparse(getNoCon(),getNoVar(),getNNZJac(),mxREAL);   
		pr = mxGetPr(plhs[0]);
		ir = mxGetIr(plhs[0]);
		jc = mxGetJc(plhs[0]);
	}
	else if(!strcmp(mode,"hess")) {
		if(nrhs < 4) {
			mexErrMsgTxt("You must supply the callback mode, input vector, sigma and lambda for Hessian Evaluations.");
			return;
		}
		//Check length of Sigma
		if(mxIsEmpty(prhs[2]) || !mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]) || mxGetNumberOfElements(prhs[2]) != 1)
			mexErrMsgTxt("Sigma must be a real, double scalar.");
		//Check length of Lambda
		if(!mxIsDouble(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || mxGetNumberOfElements(prhs[3]) != getNoCon())
			mexErrMsgTxt("Lambda must be a real, double, dense vector with ncon elements.");
		//Get Sigma, Lambda
		sigma = *mxGetPr(prhs[2]);
		lambda = mxGetPr(prhs[3]);
		imode = 4;
		plhs[0] = mxCreateSparse(getNoVar(),getNoVar(),getNNZHess(),mxREAL);   
		pr = mxGetPr(plhs[0]);
		ir = mxGetIr(plhs[0]);
		jc = mxGetJc(plhs[0]);
	}
	else
		mexErrMsgTxt("Unknown mode - options are 'obj', 'grad', 'con', 'jac', or 'hess'");
	mxFree(mode);
	
	
	//Call Req Callback
	switch(imode)
	{
		case 0: //objective
			*v = objective(x);
			break;
		case 1: //gradient
			gradient(x,v);
			break;
		case 2: //constraints
			constraints(x,v);
			break;
		case 3: //jacobian
			jacobian(x,pr,ir,jc);
			break;
		case 4: //hessian
			hessian(x,sigma,lambda,pr,ir,jc);
			break;
	}
}
Exemple #23
0
SolutionInfo
Alignment::align(bool n)
{
	// create initial solution
	SolutionInfo si;
	si.volume = -1000.0;
	si.iterations = 0;
	si.center1 = _refCenter;
	si.center2 = _dbCenter;
	si.rotation1 = _refRotMat;
	si.rotation2 = _dbRotMat;
	
	// scaling of the exclusion spheres
	double scale(1.0);
	if (_nbrExcl != 0)
	{
		scale /= _nbrExcl;
	}

	// try 4 different start orientations
	for (unsigned int _call(0); _call < 4; ++_call )
	{
		// create initial rotation quaternion
		SiMath::Vector rotor(4,0.0);
		rotor[_call] = 1.0;
		
		double volume(0.0), oldVolume(-999.99), v(0.0);
		SiMath::Vector dG(4,0.0);  // gradient update
		SiMath::Matrix hessian(4,4,0.0), dH(4,4,0.0); // hessian and hessian update
		unsigned int ii(0);
		for ( ; ii < 100; ++ii)
		{			
			// compute gradient of volume
			_grad = 0.0;
			volume = 0.0;
			hessian = 0.0;
			for (unsigned int i(0); i < _refMap.size(); ++i)
			{
				// compute the volume overlap of the two pharmacophore points
				SiMath::Vector Aq(4,0.0);
				SiMath::Matrix * AkA = _AkA[i];
				Aq[0] = (*AkA)[0][0] * rotor[0] + (*AkA)[0][1] * rotor[1] + (*AkA)[0][2] * rotor[2] + (*AkA)[0][3] * rotor[3];
				Aq[1] = (*AkA)[1][0] * rotor[0] + (*AkA)[1][1] * rotor[1] + (*AkA)[1][2] * rotor[2] + (*AkA)[1][3] * rotor[3];
				Aq[2] = (*AkA)[2][0] * rotor[0] + (*AkA)[2][1] * rotor[1] + (*AkA)[2][2] * rotor[2] + (*AkA)[2][3] * rotor[3];
				Aq[3] = (*AkA)[3][0] * rotor[0] + (*AkA)[3][1] * rotor[1] + (*AkA)[3][2] * rotor[2] + (*AkA)[3][3] * rotor[3];
				
				double qAq = Aq[0] * rotor[0] + Aq[1] * rotor[1] + Aq[2] * rotor[2] +Aq[3] * rotor[3];
				
				v = GCI2 * pow(PI/(_refMap[i].alpha+_dbMap[i].alpha),1.5) * exp(-qAq);

				double c(1.0);
				
				// add normal if AROM-AROM
				// in this case the absolute value of the angle is needed
				if (n 
					&&  (_refMap[i].func == AROM) && (_dbMap[i].func == AROM)
					&&  (_refMap[i].hasNormal) && (_dbMap[i].hasNormal))
				{
					// for aromatic rings only the planar directions count
					// therefore the absolute value of the cosine is taken
					c = _normalContribution(_refMap[i].normal, _dbMap[i].normal, rotor);
				
					// update based on the sign of the cosine
					if (c < 0)
					{
						c *= -1.0;
						_dCdq *= -1.0;
						_d2Cdq2 *= -1.0;
					} 
					
					for (unsigned int hi(0); hi < 4; hi++)
					{
						_grad[hi] += v * ( _dCdq[hi] - 2.0 * c * Aq[hi] );
						for (unsigned int hj(0); hj < 4; hj++)
						{
							hessian[hi][hj] += v * (_d2Cdq2[hi][hj] - 2.0 * _dCdq[hi]*Aq[hj] + 2.0 * c * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj])); 
						}
					}
					v *= c;
				}
				else if (n 
					&& ((_refMap[i].func == HACC) || (_refMap[i].func == HDON) || (_refMap[i].func == HYBH)) 
					&& ((_dbMap[i].func == HYBH) || (_dbMap[i].func == HACC)  || (_dbMap[i].func == HDON))
					&& (_refMap[i].hasNormal)
					&& (_dbMap[i].hasNormal))
				{
					// hydrogen donors and acceptor also have a direction
					// in this case opposite directions have negative impact 

					c = _normalContribution(_refMap[i].normal, _dbMap[i].normal, rotor);
						
					for (unsigned int hi(0); hi < 4; hi++)
					{
						_grad[hi] += v * ( _dCdq[hi] - 2.0 * c * Aq[hi] );
						for (unsigned int hj(0); hj < 4; hj++)
						{
							hessian[hi][hj] += v * (_d2Cdq2[hi][hj] - 2.0 * _dCdq[hi]*Aq[hj] + 2.0 * c * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj])); 
						}
					}
					
					v *= c;
				}
				else if (_refMap[i].func == EXCL)
				{
					// scale volume overlap of exclusion sphere with a negative scaling factor
					// => exclusion spheres have a negative impact
					v *= -scale;
					// update gradient and hessian directions
					for (unsigned int hi=0; hi < 4; hi++)
					{
						_grad[hi] -= 2.0 * v * Aq[hi];
						for (unsigned int hj(0); hj < 4; hj++)
						{
							hessian[hi][hj] += 2.0 * v * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj]); 
						}
					}
				}
				else
				{
					// update gradient and hessian directions
					for (unsigned int hi(0); hi < 4; hi++)
					{
						_grad[hi] -= 2.0 * v * Aq[hi];
						for (unsigned int hj(0); hj < 4; hj++)
						{
							hessian[hi][hj] += 2.0 * v * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj]); 
						}
					}
				}
				
				volume += v;
			}

			// stop iterations if the increase in volume overlap is too small (gradient ascent)
			// or if the volume is not defined
			if (std::isnan(volume) || (volume - oldVolume < 1e-5))
			{
				break; 
			}
			
			// reset old volume	
			oldVolume = volume;
					
			inverseHessian(hessian);
			// update gradient based on inverse hessian
			_grad = rowProduct(hessian,_grad);
			// small scaling of the gradient
			_grad *= 0.9;

			// update rotor based on gradient information
			rotor += _grad;

			// normalise rotor such that it has unit norm
			normalise(rotor);
		}

		// save result in info structure
		if (oldVolume > si.volume)
		{
			si.rotor = rotor;
			si.volume = oldVolume;
			si.iterations = ii;
		}	
	}

	return si;
}
Exemple #24
0
void GaussianProcess::optimize()
{
	const double dp = 0.1;
	const double dp_squared = dp*dp;
	const double step_size = 0.1;
	double err = 1000000000000000.0;

// 	const double beta = 0.8;

	unsigned int iter = 0;
// 	VectorXd params(params_orig.size());
	VectorXd params = kernel->params;
	VectorXd params_orig = kernel->params;
	double base = objective(params_orig);

	VectorXd gradient(params.size());
	MatrixXd hessian(params.size(),params.size());
	double alpha = 10000;
	while (err > 0.0001 && iter < 5000){
// 	while (iter < 100){
		params_orig = params;	
		for (unsigned int i = 0; i < params.size(); ++i){
			params(i) = params_orig(i) + dp;
			std::cout << params.transpose() << std::endl;
			const double v1 = objective(params);
			params(i) = params_orig(i) - dp;
			const double v2 = objective(params);
			std::cout << v1 <<","<< v2<<std::endl;

			gradient(i) = (v1 - v2)/(2.*dp);
// 			hessian(i,i) = alpha + (v1 - 2.*base - v2)/dp_squared;
// 			alpha = 0.95*alpha;
			params(i) = params_orig(i);
/*
			for (unsigned j = i+1; j < params.size(); ++j){
				params(i) = params_orig(i) + dp;
				params(j) = params_orig(j) + dp;
				const double h1 = objective(params);

				params(i) = params_orig(i) + dp;
				params(j) = params_orig(j) - dp;
				const double h2 = objective(params);

				params(i) = params_orig(i) - dp;
				params(j) = params_orig(j) + dp;
				const double h3 = objective(params);
				
				params(i) = params_orig(i) - dp;
				params(j) = params_orig(j) - dp;
				const double h4 = objective(params);
	
				const double h_val = (h1 - h2 - h3 + h4)/(4.*dp_squared);
				hessian(i,j) = h_val;
				hessian(j,i) = h_val;
			}
*/
		}

// 		const VectorXd d_param = hessian.inverse()*gradient;
 		std::cout << "Before: " << params.transpose() << std::endl;
		const VectorXd d_param = step_size*gradient;
 		std::cout << d_param.transpose() << std::endl;
		params -= d_param; 
 		std::cout <<  "After: " << params.transpose() << std::endl;
		const double val = objective(params);
		std::cout << val <<std::endl;
		kernel->params = params;
		err = fabs(val - base);///fabs(base);
// 		std::cout << gradient.transpose() << std::endl;
// 		std::cout << err << ", " << val << std::endl;
		base = val;
		/*
		if (iter % 10){
			std::cout << val << " " << kernel->params.transpose() << std::endl;
		}
		*/
		iter += 1;
	} // end while (err > 0.0001)


	
}
Exemple #25
0
//----------------------------------------------------------------------------
int ExtractRidges::Main (int, char**)
{
    std::string imageName = Environment::GetPathR("Head.im");
    ImageDouble2D image(imageName.c_str());

    // Normalize the image values to be in [0,1].
    int quantity = image.GetQuantity();
    double minValue = image[0], maxValue = minValue;
    int i;
    for (i = 1; i < quantity; ++i)
    {
        if (image[i] < minValue)
        {
            minValue = image[i];
        }
        else if (image[i] > maxValue)
        {
            maxValue = image[i];
        }
    }
    double invRange = 1.0/(maxValue - minValue);
    for (i = 0; i < quantity; ++i)
    {
        image[i] = (image[i] - minValue)*invRange;
    }

    // Use first-order centered finite differences to estimate the image
    // derivatives.  The gradient is DF = (df/dx, df/dy) and the Hessian
    // is D^2F = {{d^2f/dx^2, d^2f/dxdy}, {d^2f/dydx, d^2f/dy^2}}.
    int xBound = image.GetBound(0);
    int yBound = image.GetBound(1);
    int xBoundM1 = xBound - 1;
    int yBoundM1 = yBound - 1;
    ImageDouble2D dx(xBound, yBound);
    ImageDouble2D dy(xBound, yBound);
    ImageDouble2D dxx(xBound, yBound);
    ImageDouble2D dxy(xBound, yBound);
    ImageDouble2D dyy(xBound, yBound);
    int x, y;
    for (y = 1; y < yBoundM1; ++y)
    {
        for (x = 1; x < xBoundM1; ++x)
        {
            dx(x, y) = 0.5*(image(x+1, y) - image(x-1, y));
            dy(x, y) = 0.5*(image(x, y+1) - image(x, y-1));
            dxx(x, y) = image(x+1, y) - 2.0*image(x, y) + image(x-1, y);
            dxy(x, y) = 0.25*(image(x+1, y+1) + image(x-1, y-1)
                - image(x+1, y-1) - image(x-1, y+1));
            dyy(x, y) = image(x, y+1) - 2.0*image(x, y) + image(x, y+1);
        }
    }
    dx.Save("dx.im");
    dy.Save("dy.im");
    dxx.Save("dxx.im");
    dxy.Save("dxy.im");
    dyy.Save("dyy.im");

    // The eigensolver produces eigenvalues a and b and corresponding
    // eigenvectors U and V:  D^2F*U = a*U, D^2F*V = b*V.  Define
    // P = Dot(U,DF) and Q = Dot(V,DF).  The classification is as follows.
    //   ridge:   P = 0 with a < 0
    //   valley:  Q = 0 with b > 0
    ImageDouble2D aImage(xBound, yBound);
    ImageDouble2D bImage(xBound, yBound);
    ImageDouble2D pImage(xBound, yBound);
    ImageDouble2D qImage(xBound, yBound);
    for (y = 1; y < yBoundM1; ++y)
    {
        for (x = 1; x < xBoundM1; ++x)
        {
            Vector2d gradient(dx(x, y), dy(x, y));
            Matrix2d hessian(dxx(x, y), dxy(x, y), dxy(x, y), dyy(x, y));
            EigenDecompositiond decomposer(hessian);
            decomposer.Solve(true);
            aImage(x,y) = decomposer.GetEigenvalue(0);
            bImage(x,y) = decomposer.GetEigenvalue(1);
            Vector2d u = decomposer.GetEigenvector2(0);
            Vector2d v = decomposer.GetEigenvector2(1);
            pImage(x,y) = u.Dot(gradient);
            qImage(x,y) = v.Dot(gradient);
        }
    }
    aImage.Save("a.im");
    bImage.Save("b.im");
    pImage.Save("p.im");
    qImage.Save("q.im");

    // Use a cheap classification of the pixels by testing for sign changes
    // between neighboring pixels.
    ImageRGB82D result(xBound, yBound);
    for (y = 1; y < yBoundM1; ++y)
    {
        for (x = 1; x < xBoundM1; ++x)
        {
            unsigned char gray = (unsigned char)(255.0f*image(x, y));

            double pValue = pImage(x, y);
            bool isRidge = false;
            if (pValue*pImage(x-1 ,y) < 0.0
            ||  pValue*pImage(x+1, y) < 0.0
            ||  pValue*pImage(x, y-1) < 0.0
            ||  pValue*pImage(x, y+1) < 0.0)
            {
                if (aImage(x, y) < 0.0)
                {
                    isRidge = true;
                }
            }

            double qValue = qImage(x,y);
            bool isValley = false;
            if (qValue*qImage(x-1, y) < 0.0
            ||  qValue*qImage(x+1, y) < 0.0
            ||  qValue*qImage(x, y-1) < 0.0
            ||  qValue*qImage(x, y+1) < 0.0)
            {
                if (bImage(x,y) > 0.0)
                {
                    isValley = true;
                }
            }

            if (isRidge)
            {
                if (isValley)
                {
                    result(x, y) = GetColor24(gray, 0, gray);
                }
                else
                {
                    result(x, y) = GetColor24(gray, 0, 0);
                }
            }
            else if (isValley)
            {
                result(x, y) = GetColor24(0, 0, gray);
            }
            else
            {
                result(x, y) = GetColor24(gray, gray, gray);
            }
        }
    }
    result.Save("result.im");

    return 0;
}
double evaluate_derivatives(int n, int m, double* x, int* options) {
  int order = options[0];
  int nnz;
  double t1 = k_getTime();
  if (options[1] == 0) { // Teed = new double*[n];
    assert(m == 1);
    double** seed = new double*[n];
    for (int i = 0; i < n; i++) {
      seed[i] = new double[n];
      for (int j = 0; j < n; j++) {
        seed[i][j] = ((i==j)?1.0:0.0);
      }
    }
    int dim = binomi(n+order, order);
    double** tensorhelp = myalloc2(1, dim);
    tensor_eval(TAG, 1, n, order, n, x, tensorhelp, seed);
    for (int i = 0; i < n; i++) {
      delete[] seed[i];
    }
    delete[] seed; 
    myfree2(tensorhelp);
  } else {
    if (order == 2)  { // Hessian
      assert(m == 1);
      if (options[1] == 1 || options[1] == 2) { // Direct or Indirect
        int opt[2] = {0, 0}; // default is indirect;
        if (options[1] == 1) {opt[0] = 1;} // set direct;
        unsigned int * rind = NULL;
        unsigned int * cind = NULL;
        double * values = NULL;
        sparse_hess(TAG, n, 0, x, &nnz, &rind, &cind, &values, opt);
#ifdef PRINT_RESULT
        for (int i = 0; i < nnz; i++) {
          printf("H[%d, %d] = %.6f\n", rind[i], cind[i], values[i]);
        }
#endif
        free(rind);
        free(cind);
        free(values);
      } else if (options[1] == 3) { // FullHess
        double** H = new double*[n];
        for (int i = 0; i < n; i++) {
          H[i] = new double[n];
        }
        hessian(TAG, n, x, H);
        nnz = n*n;
#ifdef PRINT_RESULT
        for (int i = 0; i < n; i++) {
          for (int j = 0; j <= i; j++) {
            printf("H[%d, %d] = %.6f\n", i, j, H[i][j]);
          }
        }
#endif
        for (int i = 0; i < n; i++) {
          delete[] H[i];
        }
        delete[] H;
      } else if (options[1] == 4) { // Single Hv
        double v[n];
        double Hv[n];
        for (int i = 0; i < n; i++) {
          v[i] = 1.0;
          Hv[i] = 0.0;
        }
        hess_vec(TAG, n, x, v, Hv);
        nnz = n;
      } else if (options[1] == 5) { // dense second order reverse
        double** H = new double*[n];
        for (int i = 0; i < n; i++) {
          H[i] = new double[n];
        }
        hessian_dense(TAG, n, x, H);
        nnz = n*n;
#ifdef PRINT_RESULT
        for (int i = 0; i < n; i++) {
          for (int j = 0; j <= i; j++) {
            printf("H[%d, %d] = %.6f\n", i, j, H[i][j]);
          }
        }
#endif
        for (int i = 0; i < n; i++) {
          delete[] H[i];
        }
        delete[] H;
      } else if (options[1] == 6){ // sparse second order reverse
        unsigned int * rind = NULL;
        unsigned int * cind = NULL;
        double * values = NULL;
        hessian_sparse(TAG, n, x, &nnz, &rind, &cind, &values);
#ifdef PRINT_RESULT
        for (int i = 0; i < nnz; i++) {
          printf("H[%d, %d] = %.6f\n", rind[i], cind[i], values[i]);
        }
#endif
        free(rind);
        free(cind);
        free(values);
      } else if (options[1] == 7) { // Hess-matrix options
        double** H  = myalloc2(n, n);
        double y;
        double*** Xppp = myalloc3(n, n, 1);
        double*** Yppp = myalloc3(1, n, 1);
        for (int i = 0; i < n; i++) {
          for (int j = 0; j < n; j++) {
             Xppp[i][j][0] = 0;
          }
          Xppp[i][i][0] = 1.0;
        }
        double** Upp = myalloc2(1,2);
        Upp[0][0] = 1; Upp[0][1] = 0;
        double*** Zppp = myalloc3(n, n, 2);
        int ret_val = hov_wk_forward(TAG,1,n,1,2,n,x,Xppp,&y,Yppp);
        ret_val = hos_ov_reverse(TAG,1,n,1,n,Upp,Zppp);
        for (int i = 0; i < n; ++i) {
          for (int l = 0; l < n; ++l) {
            H[l][i] = Zppp[i][l][1];
          }
        }
#ifdef PRINT_RESULT
        for (int i = 0; i < n; i++) {
          for (int j = 0; j <= i; j++) {
            printf("H[%d, %d] = %.6f\n", i, j, H[i][j]);
          }
        }
#endif
        myfree2(H);
        myfree3(Xppp);
        myfree3(Yppp);
        myfree2(Upp);
        myfree3(Zppp);
      }
    } else if (order == 1) { // Gradient or Jacobian
      if (m == 1) { // gradient
        double g[n];
        gradient(TAG, n, x, g);
#ifdef PRINT_RESULT
        for (int i = 0; i < n; i++) {
          printf("g[%d] = %.6f\n", i, g[i]);
        }
#endif
      } else { // jacobian
        double** J = new double*[m];
        for (int i = 0; i < m; i++) {
          J[i] = new double[n];
        }
        jacobian(TAG, m, n, x, J);
#ifdef PRINT_RESULT
        for (int i = 0; i < m; i++) {
          for (int j = 0; j < n; j++) {
            printf("J[%d][%d] = %.6f\n", i, j, J[i][j]);
          }
        }
#endif
        for (int i = 0; i < m; i++) {
          delete[] J[i];
        }
        delete[] J;
      }
      nnz = n*m;
    }
  }


  double time_elapsed = k_getTime() - t1;
  size_t size;
  size_t** tind;
  double* values;
  printf("ADOLC nnz[%d] method[%d] order[%d] timing = %.6f\n", nnz, options[1], options[0], time_elapsed);
  return time_elapsed;
}
void dirichlet_fit_main(struct data_t *data, int rseed)
{
    const int N = data->N, S = data->S, K = data->K;
    int i, j, k;

    gsl_rng *ptGSLRNG;
    gsl_rng_env_setup();
    gsl_set_error_handler_off();
    ptGSLRNG = gsl_rng_alloc(gsl_rng_default);
    gsl_set_error_handler_off();
    gsl_rng_set(ptGSLRNG, rseed);

    /* allocate matrices */
    double **aadZ, **aadLambda, **aadErr, *adW;
    adW = (double *) calloc(K, sizeof(double));

    aadZ = (double **) calloc(K, sizeof(double *));
    aadLambda = (double **) calloc(K, sizeof(double *));
    aadErr = (double **) calloc(K, sizeof(double*));

    aadZ[0] = (double *) calloc(K * N, sizeof(double));
    aadLambda[0] = (double *) calloc(K * S, sizeof(double));
    aadErr[0] = (double *) calloc(K * S, sizeof(double));

    for (k = 1; k < K; k++) {
        aadZ[k] = aadZ[0] + k * N;
        aadLambda[k] = aadLambda[0] + k * S;
        aadErr[k] = aadErr[0] + k * S;
    }

    /* soft k means initialiser */
    kmeans(data, ptGSLRNG, adW, aadZ, aadLambda);
    for (k = 0; k < K; k++) {
        adW[k] = 0.0;
        for (i = 0; i < N; i++)
            adW[k] += aadZ[k][i];
    }

    if (data->verbose)
        Rprintf("  Expectation Maximization setup\n");
    for (k = 0; k < K; k++) {
        for (j = 0; j < S; j++) {
            const double x = aadLambda[k][j];
            aadLambda[k][j] = (x > 0.0) ? log(x) : -10;
        }
        optimise_lambda_k(aadLambda[k], data, aadZ[k]);
    }

    /* simple EM algorithm */
    int iter = 0;
    double dNLL = 0.0, dNew, dChange = BIG_DBL;

    if (data->verbose)
        Rprintf("  Expectation Maximization\n");
    while (dChange > 1.0e-6 && iter < 100) {
        calc_z(aadZ, data, adW, aadLambda); /* latent var expectation */
        for (k = 0; k < K; k++) /* mixture components, given pi */
            optimise_lambda_k(aadLambda[k], data, aadZ[k]);
        for (k = 0; k < K; k++) { /* current likelihood & weights */
            adW[k] = 0.0;
            for(i = 0; i < N; i++)
                adW[k] += aadZ[k][i];
        }

        dNew = neg_log_likelihood(adW, aadLambda, data);
        dChange = fabs(dNLL - dNew);
        dNLL = dNew;
        iter++;
        R_CheckUserInterrupt();
        if (data->verbose && (iter % 10) == 0)
            Rprintf("    iteration %d change %f\n", iter, dChange);
    }

    /* hessian */
    if (data->verbose)
        Rprintf("  Hessian\n");
    gsl_matrix *ptHessian = gsl_matrix_alloc(S, S),
        *ptInverseHessian = gsl_matrix_alloc(S, S);
    gsl_permutation *p = gsl_permutation_alloc(S);
    double dLogDet = 0., dTemp;
    int signum, status;

    for (k = 0; k < K; k++) {
        data->adPi = aadZ[k];
        if (k > 0)
            dLogDet += 2.0 * log(N) - log(adW[k]);
        hessian(ptHessian, aadLambda[k], data);

        status = gsl_linalg_LU_decomp(ptHessian, p, &signum);
        gsl_linalg_LU_invert(ptHessian, p, ptInverseHessian);
        for (j = 0; j < S; j++) {
            aadErr[k][j] = gsl_matrix_get(ptInverseHessian, j, j);
            dTemp = gsl_matrix_get(ptHessian, j, j);
            dLogDet += log(fabs(dTemp));
        }
    }

    gsl_matrix_free(ptHessian);
    gsl_matrix_free(ptInverseHessian);
    gsl_permutation_free(p);

    /* results */
    double dP = K * S + K - 1;
    data->NLE = dNLL; data->LogDet = dLogDet;
    data->fit_laplace = dNLL + 0.5 * dLogDet - 0.5 * dP * log(2. * M_PI);
    data->fit_bic = dNLL + 0.5 * log(N) * dP;
    data->fit_aic = dNLL + dP;

    group_output(data, aadZ);
    mixture_output(data, adW, aadLambda, aadErr);

    free(aadErr[0]); free(aadErr);
    free(aadLambda[0]); free(aadLambda);
    free(aadZ[0]); free(aadZ);
    free(adW);
}
Matrix<double> ObjectiveFunction::getHessian(Vector<double> argument)
{
   Matrix<double> hessian(numberOfVariables, numberOfVariables, 0.0);

   double evaluation11 = 0.0, evaluation12 = 0.0;
   double evaluation21 = 0.0, evaluation22 = 0.0;

   // Obtain the upper part of the Hessian matrix

   for(int i = 0; i < numberOfVariables; i++)
   {
      for(int j = i; j < numberOfVariables; j++)
      {
         // Perturb argument components i and j

         argument[i] += epsilon;
         argument[j] += epsilon;

         // Calculate evaluation

         evaluation22 = getEvaluation(argument);

         // Restart argument components i and j

         argument[i] -= epsilon;
         argument[j] -= epsilon;


         // Perturb argument components i and j

         argument[i] += epsilon;
         argument[j] -= epsilon;

         // Calculate evaluation

         evaluation21 = getEvaluation(argument);

         // Restart argument components i and j

         argument[i] -= epsilon;
         argument[j] += epsilon;


         // Perturb argument components i and j

         argument[i] -= epsilon;
         argument[j] += epsilon;

         // Calculate evaluation

         evaluation12 = getEvaluation(argument);

         // Restart potential free parameters i and j

         argument[i] += epsilon;
         argument[j] -= epsilon;


         // Perturb potential free parameters i and j

         argument[i] -= epsilon;
         argument[j] -= epsilon;

         // Calculate evaluation

         evaluation11 = getEvaluation(argument);

         // Restart potential free parameters i and j

         argument[i] += epsilon;
         argument[j] += epsilon;

         // Calculate second derivative

         hessian[i][j]
         = (evaluation22 - evaluation21 - evaluation12 + evaluation11)/(4.0*pow(epsilon,2));
      }
   }

   // Obtain the rest of elements by symmetry

   for(int i = 0; i < numberOfVariables; i++)
   {
      for(int j = 0; j < i; j++)
      {
         hessian[i][j] = hessian[j][i];
      }
   }

   return(hessian);
}
Exemple #29
0
 void test_hessian(const F& functional,
                   const Eigen::VectorXd& x,
                   const double epsilon = 1e-6) {
   
   eigen_idx_t d = x.size();
   
   Eigen::MatrixXd auto_H(x.size(), x.size());
   try {
     hessian(functional, x, auto_H);
   } catch (nomad_error& e) {
     std::cout << "Cannot compute Hessian Test" << std::endl;
     throw e;
   }
   
   Eigen::MatrixXd diff_H(x.size(), x.size());
   try {
     finite_diff_hessian(functional, x, diff_H, epsilon);
   } catch (nomad_error& e) {
     std::cout << "Cannot compute Hessian Test" << std::endl;
     throw e;
   }
   
   std::cout.precision(6);
   int width = 12;
   int n_column = 5;
   
   std::cout << "Hessian Test:" << std::endl;
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   std::cout << "    "
             << std::setw(width) << std::left << "Row"
             << std::setw(width) << std::left << "Column"
             << std::setw(width) << std::left << "Automatic"
             << std::setw(width) << std::left << "Finite"
             << std::setw(width) << std::left << "Delta / "
             << std::endl;
   std::cout << "    "
             << std::setw(width) << std::left << "(i)"
             << std::setw(width) << std::left << "(j)"
             << std::setw(width) << std::left << "Derivative"
             << std::setw(width) << std::left << "Difference"
             << std::setw(width) << std::left << "Stepsize^{2}"
             << std::endl;
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   
   for (eigen_idx_t i = 0; i < d; ++i) {
     for (eigen_idx_t j = 0; j < d; ++j) {
       std::cout << "    "
                 << std::setw(width) << std::left << i
                 << std::setw(width) << std::left << j
                 << std::setw(width) << std::left << auto_H(i, j)
                 << std::setw(width) << std::left << diff_H(i, j)
                 << std::setw(width) << std::left
                 << (auto_H(i, j) - diff_H(i, j)) / (epsilon * epsilon)
                 << std::endl;
     }
   }
   
   std::cout << "    " << std::setw(n_column * width) << std::setfill('-')
             << "" << std::setfill(' ') << std::endl;
   std::cout << std::endl;
   
 }
Exemple #30
0
int main(int argc, char *argv[]) {
  int n=get_num_ind();
  int i,j;
  struct timeval tv1,tv2;
  adouble *xad;
  adouble fad;
  double f;
  double *x;
  x=new double[n];
  xad=new adouble[n];
get_initial_value(x);

  printf("evaluating the function...");
trace_on(tag);
  for(i=0;i<n;i++)
  {
    xad[i] <<= x[i];  
  }
  fad=func_eval(xad); 
  fad >>= f;
trace_off();
  printf("done!\n");
//  printf("function value  =<%10.20f>\n",f);
//  function(tag,1,n,x,&f);
//  printf("adolc func value=<%10.20f>\n",f);
//tape_doc(tag,1,n,x,&f);
#ifdef _compare_with_full
  double **H;
  H = myalloc2(n,n);
  printf("computing full hessain....");
  gettimeofday(&tv1,NULL);
  hessian(tag,n,x,H);
  printf("done\n");
  gettimeofday(&tv2,NULL);
  printf("Computing the full hessian cost %10.6f seconds\n",(tv2.tv_sec-tv1.tv_sec)+(double)(tv2.tv_usec-tv1.tv_usec)/1000000);
#ifdef _PRINTOUT
    for(i=0;i<n;i++){
      for(j=0;j<n;j++){
        printf("H[%d][%d]=<%10.10f>",i,j,H[i][j]);
      }
      printf("\n");
    }
    printf("\n");
#endif
#endif

#ifdef edge_pushing
  unsigned int    *rind  = NULL;
  unsigned int    *cind  = NULL;
  double *values = NULL;
  int nnz;
  int options[2];
  options[0]=PRE_ACC;
  options[1]=COMPUT_GRAPH;
  gettimeofday(&tv1,NULL);
//  edge_hess(tag, 1, n, x, &nnz, &rind, &cind, &values, options);
  sparse_hess(tag,n,0,x, &nnz, &rind, &cind, &values, options);
  gettimeofday(&tv2,NULL);
  printf("Sparse Hessian: edge pushing cost %10.6f seconds\n",(tv2.tv_sec-tv1.tv_sec)+(double)(tv2.tv_usec-tv1.tv_usec)/1000000);

#ifdef _PRINTOUT
  for(i=0;i<nnz;i++){
    printf("<%d,%d>:<%10.10f>\n",cind[i],rind[i],values[i]);
//    printf("%d %d \n", rind[i], cind[i]);
  }
#endif
#endif

#ifdef _compare_with_full
#ifdef edge_pushing
  compare_matrix(n,H,nnz,cind,rind,values);
#endif
  myfree2(H);
#endif

#ifdef edge_pushing
  printf("nnz=%d\n", nnz);
  free(rind); rind=NULL;
  free(cind); cind=NULL;
  free(values); values=NULL;
#endif
  delete[] x;
  delete[] xad;
  return 0;
}