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++; } }
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(); } } }
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; }
bool erf(void) { bool ok = true; ok &= old_example(); # if CPPAD_USE_CPLUSPLUS_2011 ok &= hessian(); # endif return ok; }
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; }
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; } }
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); }
/* 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); }
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; }
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(); } }
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); } }
/***********************************************************************//** * @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; }
/* 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",°ree); 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; }
/***********************************************************************//** * @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; }
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; } }
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; }
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) }
//---------------------------------------------------------------------------- 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); }
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; }
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; }