From 5a1528e973f48b7f7223159d430b6fe94abec0ac Mon Sep 17 00:00:00 2001 From: Eric Phipps Date: Thu, 25 Jul 2024 09:40:05 -0600 Subject: [PATCH] Update cp-opt implementation to be consistent with latest TTB --- data/aminoacid-cpopt-lbfgsb.json | 10 +++--- data/aminoacid-cpopt-rol-hess.json | 2 +- data/aminoacid-cpopt-rol.json | 10 +++--- data/aminoacid-gcpopt-rol.json | 10 +++--- data/rol_truncated_cg.xml | 4 +-- python/src/Genten_Pybind11_classes.cpp | 6 ++-- src/Genten_AlgParams.cpp | 30 +++++++++--------- src/Genten_AlgParams.hpp | 6 ++-- src/Genten_CP_Model.hpp | 42 +++++++++++++++----------- src/Genten_JSON_Schema.hpp | 34 ++++++++++----------- src/lbfgsb/Genten_CP_Opt_Lbfgsb.cpp | 10 +++--- src/lbfgsb/Genten_GCP_Opt_Lbfgsb.cpp | 6 ++-- src/rol/Genten_CP_Opt_Rol.cpp | 2 +- src/rol/Genten_CP_Opt_Rol.hpp | 4 +-- src/rol/Genten_CP_RolObjective.hpp | 2 +- src/rol/Genten_GCP_Opt_Rol.hpp | 4 +-- 16 files changed, 94 insertions(+), 88 deletions(-) diff --git a/data/aminoacid-cpopt-lbfgsb.json b/data/aminoacid-cpopt-lbfgsb.json index 4b3a89d59f..8d0aec3a77 100644 --- a/data/aminoacid-cpopt-lbfgsb.json +++ b/data/aminoacid-cpopt-lbfgsb.json @@ -18,19 +18,19 @@ "cp-opt": { "method": "lbfgsb", - "maxiters": 20, - "tol": 1e-4 + "maxiters": 200, + "gtol": 1e-4 }, "testing": { "final-fit": { - "value": 0.98, - "absolute-tolerance": 0.1 + "value": 0.99, + "absolute-tolerance": 0.05 }, "iterations": { - "value": 19, + "value": 39, "absolute-tolerance": 2 } } diff --git a/data/aminoacid-cpopt-rol-hess.json b/data/aminoacid-cpopt-rol-hess.json index bc97690a70..26eb9da357 100644 --- a/data/aminoacid-cpopt-rol-hess.json +++ b/data/aminoacid-cpopt-rol-hess.json @@ -30,7 +30,7 @@ }, "iterations": { - "value": 17, + "value": 19, "absolute-tolerance": 3 } } diff --git a/data/aminoacid-cpopt-rol.json b/data/aminoacid-cpopt-rol.json index 44660ceb15..cb21daf372 100644 --- a/data/aminoacid-cpopt-rol.json +++ b/data/aminoacid-cpopt-rol.json @@ -18,19 +18,19 @@ "cp-opt": { "method": "rol", - "maxiters": 20, - "tol": 1e-4 + "maxiters": 200, + "gtol": 1e-4 }, "testing": { "final-fit": { - "value": 0.98, - "absolute-tolerance": 0.1 + "value": 0.99, + "absolute-tolerance": 0.05 }, "iterations": { - "value": 20, + "value": 63, "absolute-tolerance": 2 } } diff --git a/data/aminoacid-gcpopt-rol.json b/data/aminoacid-gcpopt-rol.json index 232e3e5768..6acda4f9f2 100644 --- a/data/aminoacid-gcpopt-rol.json +++ b/data/aminoacid-gcpopt-rol.json @@ -18,8 +18,8 @@ "gcp-opt": { "method": "rol", - "maxiters": 20, - "tol": 1e-4, + "maxiters": 200, + "gtol": 1e-4, "type": "gaussian", "fit": true }, @@ -27,12 +27,12 @@ { "final-fit": { - "value": 0.98, - "absolute-tolerance": 0.1 + "value": 0.99, + "absolute-tolerance": 0.05 }, "iterations": { - "value": 20, + "value": 80, "absolute-tolerance": 2 } } diff --git a/data/rol_truncated_cg.xml b/data/rol_truncated_cg.xml index 71cdf9653d..1a4a648672 100644 --- a/data/rol_truncated_cg.xml +++ b/data/rol_truncated_cg.xml @@ -5,9 +5,9 @@ - + - + diff --git a/python/src/Genten_Pybind11_classes.cpp b/python/src/Genten_Pybind11_classes.cpp index d4197bb5e6..0e1248e73a 100644 --- a/python/src/Genten_Pybind11_classes.cpp +++ b/python/src/Genten_Pybind11_classes.cpp @@ -254,10 +254,10 @@ void pygenten_algparams(py::module &m){ cl.def_readwrite("lower", &Genten::AlgParams::lower); cl.def_readwrite("upper", &Genten::AlgParams::upper); cl.def_readwrite("rolfilename", &Genten::AlgParams::rolfilename); - cl.def_readwrite("factr", &Genten::AlgParams::factr); - cl.def_readwrite("pgtol", &Genten::AlgParams::pgtol); + cl.def_readwrite("ftol", &Genten::AlgParams::ftol); + cl.def_readwrite("gtol", &Genten::AlgParams::gtol); cl.def_readwrite("memory", &Genten::AlgParams::memory); - cl.def_readwrite("max_total_iters", &Genten::AlgParams::max_total_iters); + cl.def_readwrite("sub_iters", &Genten::AlgParams::sub_iters); cl.def_readwrite("hess_vec_method", &Genten::AlgParams::hess_vec_method); cl.def_readwrite("hess_vec_tensor_method", &Genten::AlgParams::hess_vec_tensor_method); cl.def_readwrite("hess_vec_prec_method", &Genten::AlgParams::hess_vec_prec_method); diff --git a/src/Genten_AlgParams.cpp b/src/Genten_AlgParams.cpp index aa2cfeb435..dd679ebdef 100644 --- a/src/Genten_AlgParams.cpp +++ b/src/Genten_AlgParams.cpp @@ -78,10 +78,10 @@ Genten::AlgParams::AlgParams() : lower(-DOUBLE_MAX), upper(DOUBLE_MAX), rolfilename(""), - factr(1e7), - pgtol(1e-5), + ftol(1e-10), + gtol(1e-5), memory(5), - max_total_iters(5000), + sub_iters(10), hess_vec_method(Hess_Vec_Method::default_type), hess_vec_tensor_method(Hess_Vec_Tensor_Method::default_type), hess_vec_prec_method(Hess_Vec_Prec_Method::default_type), @@ -211,10 +211,10 @@ void Genten::AlgParams::parse(std::vector& args) lower = parse_ttb_real(args, "--lower", lower, -DOUBLE_MAX, DOUBLE_MAX); upper = parse_ttb_real(args, "--upper", upper, -DOUBLE_MAX, DOUBLE_MAX); rolfilename = parse_string(args, "--rol", rolfilename.c_str()); - factr = parse_ttb_real(args, "--factr", factr, 0.0, DOUBLE_MAX); - pgtol = parse_ttb_real(args, "--pgtol", pgtol, 0.0, DOUBLE_MAX); + ftol = parse_ttb_real(args, "--ftol", ftol, 0.0, DOUBLE_MAX); + gtol = parse_ttb_real(args, "--gtol", gtol, 0.0, DOUBLE_MAX); memory = parse_ttb_indx(args, "--memory", memory, 0, INT_MAX); - max_total_iters = parse_ttb_indx(args, "--total-iters", max_total_iters, 0, INT_MAX); + sub_iters = parse_ttb_indx(args, "-sub-iters", sub_iters, 1, INT_MAX); hess_vec_method = parse_ttb_enum(args, "--hess-vec", hess_vec_method, Genten::Hess_Vec_Method::num_types, Genten::Hess_Vec_Method::types, @@ -397,10 +397,10 @@ void Genten::AlgParams::parse(const ptree& input) parse_ptree_enum(cpopt_input, "method", opt_method); parse_generic_solver_params(cpopt_input); parse_ptree_value(cpopt_input, "rol-file", rolfilename); - parse_ptree_value(cpopt_input, "factr", factr, 0.0, DOUBLE_MAX); - parse_ptree_value(cpopt_input, "pgtol", pgtol, 0.0, DOUBLE_MAX); + parse_ptree_value(cpopt_input, "ftol", ftol, 0.0, DOUBLE_MAX); + parse_ptree_value(cpopt_input, "gtol", gtol, 0.0, DOUBLE_MAX); parse_ptree_value(cpopt_input, "memory", memory, 0, INT_MAX); - parse_ptree_value(cpopt_input, "total-iters", max_total_iters, 0, INT_MAX); + parse_ptree_value(cpopt_input, "sub-iters", sub_iters, 1, INT_MAX); parse_mttkrp(cpopt_input); }; @@ -640,10 +640,10 @@ void Genten::AlgParams::print_help(std::ostream& out) out << " --lower lower bound of factorization" << std::endl; out << " --upper upper bound of factorization" << std::endl; out << " --rol path to ROL optimization settings file for CP-Opt method" << std::endl; - out << " --factr factr parameter for L-BFGS-B" << std::endl; - out << " --pgtol pgtol parameter for L-BFGS-B" << std::endl; + out << " --ftol relative residual reduction tolerance for L-BFGS-B" << std::endl; + out << " --gtol gradient tolerance for L-BFGS-B" << std::endl; out << " --memory memory parameter for L-BFGS-B" << std::endl; - out << " --total-iters max total iterations for L-BFGS-B" << std::endl; + out << " --sub-iters max inner iterations for L-BFGS-B" << std::endl; out << " --hess-vec Hessian-vector product method: "; for (unsigned i=0; i iwa(3*n); std::vector wa(2*m*n + 5*n + 11*m*m + 8*m); integer task = START; @@ -283,7 +283,7 @@ namespace Genten { history.resize(iters+1); history[iters].iteration = iters; history[iters].residual = f; - history[iters].fit = ttb_real(1.0) - f / (ttb_real(0.5)*nrm_X_sq); + history[iters].fit = ttb_real(1.0) - f; history[iters].grad_norm = nrmg; history[iters].cum_time = time; @@ -346,7 +346,7 @@ namespace Genten { std::cout << "Reached maximum number of total iterations." << std::endl; else std::cout << Impl::findTaskString(task) << std::endl; - const ttb_real fit = ttb_real(1.0) - f / (ttb_real(0.5)*nrm_X_sq); + const ttb_real fit = ttb_real(1.0) - f; std::cout << "Final fit = " << std::setprecision(3) << std::scientific << fit << std::endl; std::cout << "Total time = " << std::setprecision(2) << std::scientific diff --git a/src/lbfgsb/Genten_GCP_Opt_Lbfgsb.cpp b/src/lbfgsb/Genten_GCP_Opt_Lbfgsb.cpp index db7602f861..cf6e8c904b 100644 --- a/src/lbfgsb/Genten_GCP_Opt_Lbfgsb.cpp +++ b/src/lbfgsb/Genten_GCP_Opt_Lbfgsb.cpp @@ -134,10 +134,10 @@ void gcp_opt_lbfgsb_impl(const TensorT& X, // L-BFGS-B data integer m = algParams.memory; - double factr = algParams.factr; - double pgtol = algParams.pgtol; + double factr = algParams.ftol/MACHINE_EPSILON; + double pgtol = algParams.gtol; ttb_indx iterMax = algParams.maxiters; - ttb_indx total_iterMax = algParams.max_total_iters; + ttb_indx total_iterMax = iterMax * algParams.sub_iters; std::vector iwa(3*n); std::vector wa(2*m*n + 5*n + 11*m*m + 8*m); integer task = START; diff --git a/src/rol/Genten_CP_Opt_Rol.cpp b/src/rol/Genten_CP_Opt_Rol.cpp index eee3b7cae5..558daa80b8 100644 --- a/src/rol/Genten_CP_Opt_Rol.cpp +++ b/src/rol/Genten_CP_Opt_Rol.cpp @@ -181,7 +181,7 @@ namespace Genten { ttb_real tol; const ttb_real res = objective->value(*z, tol); const ttb_real nrm = x.global_norm(); - const ttb_real fit = ttb_real(1.0) - res / (ttb_real(0.5)*nrm*nrm) ; + const ttb_real fit = ttb_real(1.0) - res ; if (algParams.printitn > 0) { stream << "Final fit = " << fit << std::endl; stream << "Total time = " << timer.getTotalTime(0) << std::endl diff --git a/src/rol/Genten_CP_Opt_Rol.hpp b/src/rol/Genten_CP_Opt_Rol.hpp index 361fb32aa9..47295c11ee 100644 --- a/src/rol/Genten_CP_Opt_Rol.hpp +++ b/src/rol/Genten_CP_Opt_Rol.hpp @@ -113,8 +113,8 @@ namespace Genten { // Set stopping criteria Teuchos::ParameterList& status_params = rol_params.sublist("Status Test"); - status_params.set("Gradient Tolerance", algParams.tol); - status_params.set("Step Tolerance", algParams.tol); + status_params.set("Gradient Tolerance", algParams.gtol); + status_params.set("Step Tolerance", algParams.ftol); status_params.set("Iteration Limit", algParams.maxiters); // Print iterations diff --git a/src/rol/Genten_CP_RolObjective.hpp b/src/rol/Genten_CP_RolObjective.hpp index 75015ed209..b261ffa5a4 100644 --- a/src/rol/Genten_CP_RolObjective.hpp +++ b/src/rol/Genten_CP_RolObjective.hpp @@ -208,7 +208,7 @@ namespace Genten { ttb_real res = cp_model.value(M); history.lastEntry().residual = res; - history.lastEntry().fit = ttb_real(1.0) - res / (ttb_real(0.5)*nrm_X_sq); + history.lastEntry().fit = ttb_real(1.0) - res; return res; } diff --git a/src/rol/Genten_GCP_Opt_Rol.hpp b/src/rol/Genten_GCP_Opt_Rol.hpp index 80125f0be6..faae7086f4 100644 --- a/src/rol/Genten_GCP_Opt_Rol.hpp +++ b/src/rol/Genten_GCP_Opt_Rol.hpp @@ -120,8 +120,8 @@ namespace Genten { // Set stopping criteria Teuchos::ParameterList& status_params = rol_params.sublist("Status Test"); - status_params.set("Gradient Tolerance", algParams.tol); - status_params.set("Step Tolerance", algParams.tol); + status_params.set("Gradient Tolerance", algParams.gtol); + status_params.set("Step Tolerance", algParams.ftol); status_params.set("Iteration Limit", algParams.maxiters); // Print iterations