int main(int argc, char ** argv){ int option = -1; if( argc <= 1 || ( (option = atoi(argv[1])) < 0 ) ){ print_usage(); } int count = 0; if(argc >= 3) count = atoi(argv[2]); printf("Welcome to effectTest, option %d, count %d\n", option, count); switch(option){ case 0: functional(count); break; case 1: left(); break; case 2: right(); break; case 3: duplicate(); break; case 4: invalid(); break; case 5: special(); break; case 9: other(); break; } return 0; }
typename std::enable_if<is_var<typename F::var_type>::value && F::var_type::order() >= 1, void >::type trace_matrix_times_hessian(const F& functional, const Eigen::VectorXd& x, const Eigen::MatrixXd& M, double& f, Eigen::VectorXd& g, double& trace_m_times_h) { reset(); eigen_idx_t d = x.size(); try { auto f_var = functional(x); f = f_var.first_val(); // First-order first_order_reverse_adj(f_var); for (eigen_idx_t i = 0; i < d; ++i) g(i) = var_nodes_[i + 1].first_grad(); // Second-order trace_m_times_h = 0; for (eigen_idx_t i = 0; i < d; ++i) { for (eigen_idx_t j = 0; j < d; ++j) var_nodes_[j + 1].second_val() = M(j, i); second_order_forward_val(f_var); second_order_reverse_adj(f_var); trace_m_times_h += var_nodes_[i + 1].second_grad(); } reset(); } catch (nomad_error& e) { reset(); throw e; } }
typename std::enable_if<is_var<typename F::var_type>::value && F::var_type::order() >= 2, void >::type hessian(const F& functional, const Eigen::VectorXd& x, double& f, Eigen::VectorXd& g, Eigen::MatrixXd& H) { reset(); eigen_idx_t d = x.size(); try { auto f_var = functional(x); f = f_var.first_val(); // First-order first_order_reverse_adj(f_var); for (eigen_idx_t i = 0; i < d; ++i) g(i) = var_nodes_[i + 1].first_grad(); // Second-order for (eigen_idx_t i = 0; i < d; ++i) { for (eigen_idx_t j = 0; j < d; ++j) var_nodes_[j + 1].second_val() = static_cast<double>(i == j); second_order_forward_val(f_var); second_order_reverse_adj(f_var); for (eigen_idx_t j = 0; j < d; ++j) H(i, j) = var_nodes_[j + 1].second_grad(); } reset(); } catch (nomad_error& e) { reset(); throw e; } }
typename std::enable_if<is_var<typename F::var_type>::value && F::var_type::order() >= 2, void >::type hessian_dot_vector(const F& functional, const Eigen::VectorXd& x, const Eigen::VectorXd& v, double& f, Eigen::VectorXd& g, Eigen::VectorXd& hessian_dot_v) { reset(); eigen_idx_t d = x.size(); try { auto f_var = functional(x); f = f_var.first_val(); // First-order first_order_reverse_adj(f_var); for (eigen_idx_t i = 0; i < d; ++i) g(i) = var_nodes_[i + 1].first_grad(); // Second-order for (eigen_idx_t i = 0; i < d; ++i) var_nodes_[i + 1].second_val() = v(i); second_order_forward_val(f_var); second_order_reverse_adj(f_var); for (eigen_idx_t i = 0; i < d; ++i) hessian_dot_v(i) = var_nodes_[i + 1].second_grad(); reset(); } catch (nomad_error& e) { reset(); throw e; } }