From 810142588a0cb620f34502f6f3f3ee60dcc0a4d5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:14:11 -0800 Subject: [PATCH] Upgrade ensmallen to 2.21.1 (#64) Co-authored-by: coatless --- ChangeLog | 7 ++++ DESCRIPTION | 2 +- NEWS.md | 8 +++++ .../aug_lagrangian/aug_lagrangian_impl.hpp | 5 ++- .../ensmallen_bits/callbacks/query_front.hpp | 2 +- .../cmaes/not_empty_transformation.hpp | 32 ++++++++++------- inst/include/ensmallen_bits/ens_version.hpp | 8 ++--- .../ensmallen_bits/lbfgs/lbfgs_impl.hpp | 34 +++++++++++-------- tools/HISTORYold.md | 12 +++++-- 9 files changed, 72 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index f44c765..9b71137 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-02-16 James Balamuta + + * DESCRIPTION (Version): Release 2.21.1 + * NEWS.md: Update for Ensmallen release 2.21.1 + * inst/include/ensmallen_bits: Upgraded to Ensmallen 2.21.1 + * inst/include/ensmallen.hpp: ditto + 2023-11-27 James Balamuta * DESCRIPTION (Version): Release 2.21.0 diff --git a/DESCRIPTION b/DESCRIPTION index 6eece6b..ae6694c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RcppEnsmallen Title: Header-Only C++ Mathematical Optimization Library for 'Armadillo' -Version: 0.2.21.0.1 +Version: 0.2.21.1.1 Authors@R: c( person("James Joseph", "Balamuta", email = "balamut2@illinois.edu", role = c("aut", "cre", "cph"), diff --git a/NEWS.md b/NEWS.md index 734f907..0be574d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# RcppEnsmallen 0.2.21.1.1 + +- Upgraded to ensmallen 2.21.1: "Bent Antenna" (2024-02-16) + - Fix numerical precision issues for small-gradient L-BFGS scaling factor + computations ([#392](https://github.com/mlpack/ensmallen/pull/392)). + - Ensure the tests are built with optimisation enabled + ([#394](https://github.com/mlpack/ensmallen/pull/394)). + # RcppEnsmallen 0.2.21.0.1 - Upgraded to ensmallen 2.21.0: "Stripped Bolt Head" (2023-11-27) diff --git a/inst/include/ensmallen_bits/aug_lagrangian/aug_lagrangian_impl.hpp b/inst/include/ensmallen_bits/aug_lagrangian/aug_lagrangian_impl.hpp index 3ee6775..f972eae 100644 --- a/inst/include/ensmallen_bits/aug_lagrangian/aug_lagrangian_impl.hpp +++ b/inst/include/ensmallen_bits/aug_lagrangian/aug_lagrangian_impl.hpp @@ -136,9 +136,8 @@ AugLagrangian::Optimize( << ", starting with objective " << lastObjective << "." << std::endl; if (!lbfgs.Optimize(augfunc, coordinates, callbacks...)) - Info << "L-BFGS reported an error during optimization." - << std::endl; - Info << "Done with L-BFGS: " << coordinates << "\n"; + Info << "L-BFGS reported an error during optimization." << std::endl; + Info << "Done with L-BFGS." << std::endl; const ElemType objective = function.Evaluate(coordinates); diff --git a/inst/include/ensmallen_bits/callbacks/query_front.hpp b/inst/include/ensmallen_bits/callbacks/query_front.hpp index 9d56318..4ba9a8b 100644 --- a/inst/include/ensmallen_bits/callbacks/query_front.hpp +++ b/inst/include/ensmallen_bits/callbacks/query_front.hpp @@ -48,7 +48,7 @@ class QueryFront typename MatType, typename ObjectivesVecType, typename IndicesType> - bool GenerationalStepTaken(OptimizerType& opt, + bool GenerationalStepTaken(OptimizerType& /* opt */, FunctionType& /* function */, const MatType& /* coordinates */, const ObjectivesVecType& objectives, diff --git a/inst/include/ensmallen_bits/cmaes/not_empty_transformation.hpp b/inst/include/ensmallen_bits/cmaes/not_empty_transformation.hpp index cdf18c1..5252a42 100644 --- a/inst/include/ensmallen_bits/cmaes/not_empty_transformation.hpp +++ b/inst/include/ensmallen_bits/cmaes/not_empty_transformation.hpp @@ -9,28 +9,34 @@ * the 3-clause BSD license along with ensmallen. If not, see * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ -#ifndef NOT_EMPTY_TRANSFORMATION -#define NOT_EMPTY_TRANSFORMATION +#ifndef ENSMALLEN_CMAES_NOT_EMPTY_TRANSFORMATION +#define ENSMALLEN_CMAES_NOT_EMPTY_TRANSFORMATION - /* - This partial specialization is used to throw an exception when the - TransformationPolicyType is EmptyTransformation and call a - constructor with parameters 'lowerBound' and 'upperBound' otherwise. - This shall be removed when the deprecated constructor is removed in - the next major version of ensmallen. +/** + * This partial specialization is used to throw an exception when the + * TransformationPolicyType is EmptyTransformation and call a constructor with + * parameters 'lowerBound' and 'upperBound' otherwise. This shall be removed + * when the deprecated constructor is removed in the next major version of + * ensmallen. */ template -struct NotEmptyTransformation : std::true_type { - void Assign(T1& obj, double lowerBound, double upperBound) { +struct NotEmptyTransformation : std::true_type +{ + void Assign(T1& obj, double lowerBound, double upperBound) + { obj = T1(lowerBound, upperBound); } }; template class T, typename... A, typename... B> -struct NotEmptyTransformation, T> : std::false_type { - void Assign(T& obj, double lowerBound, double upperBound) { +struct NotEmptyTransformation, T> : std::false_type +{ + void Assign(T& /* obj */, + double /* lowerBound */, + double /* upperBound */) + { throw std::logic_error("TransformationPolicyType is EmptyTransformation"); } }; -#endif \ No newline at end of file +#endif diff --git a/inst/include/ensmallen_bits/ens_version.hpp b/inst/include/ensmallen_bits/ens_version.hpp index e91a652..eb11b4d 100644 --- a/inst/include/ensmallen_bits/ens_version.hpp +++ b/inst/include/ensmallen_bits/ens_version.hpp @@ -16,16 +16,16 @@ // The minor version is two digits so regular numerical comparisons of versions // work right. The first minor version of a release is always 10. #define ENS_VERSION_MINOR 21 -#define ENS_VERSION_PATCH 0 +#define ENS_VERSION_PATCH 1 // If this is a release candidate, it will be reflected in the version name // (i.e. the version name will be "RC1", "RC2", etc.). Otherwise the version // name will typically be a seemingly arbitrary set of words that does not // contain the capitalized string "RC". #define ENS_VERSION_NAME "Bent Antenna" // Incorporate the date the version was released. -#define ENS_VERSION_YEAR "2023" -#define ENS_VERSION_MONTH "11" -#define ENS_VERSION_DAY "23" +#define ENS_VERSION_YEAR "2024" +#define ENS_VERSION_MONTH "02" +#define ENS_VERSION_DAY "15" namespace ens { diff --git a/inst/include/ensmallen_bits/lbfgs/lbfgs_impl.hpp b/inst/include/ensmallen_bits/lbfgs/lbfgs_impl.hpp index 7aaa4bf..5d15401 100644 --- a/inst/include/ensmallen_bits/lbfgs/lbfgs_impl.hpp +++ b/inst/include/ensmallen_bits/lbfgs/lbfgs_impl.hpp @@ -79,6 +79,9 @@ double L_BFGS::ChooseScalingFactor(const size_t iterationNum, { typedef typename CubeType::elem_type CubeElemType; + constexpr const CubeElemType tol = + 100 * std::numeric_limits::epsilon(); + double scalingFactor; if (iterationNum > 0) { @@ -86,17 +89,17 @@ double L_BFGS::ChooseScalingFactor(const size_t iterationNum, // Get s and y matrices once instead of multiple times. const arma::Mat& sMat = s.slice(previousPos); const arma::Mat& yMat = y.slice(previousPos); - + const CubeElemType tmp = arma::dot(yMat, yMat); - const CubeElemType denom = (tmp != CubeElemType(0)) ? tmp : CubeElemType(1); - + const CubeElemType denom = (tmp >= tol) ? tmp : CubeElemType(1); + scalingFactor = arma::dot(sMat, yMat) / denom; } else { const CubeElemType tmp = arma::norm(gradient, "fro"); - - scalingFactor = (tmp != CubeElemType(0)) ? (1.0 / tmp) : 1.0; + + scalingFactor = (tmp >= tol) ? (1.0 / tmp) : 1.0; } return scalingFactor; @@ -135,16 +138,18 @@ void L_BFGS::SearchDirection(const MatType& gradient, for (size_t i = iterationNum; i != limit; i--) { int translatedPosition = (i + (numBasis - 1)) % numBasis; - + const arma::Mat& sMat = s.slice(translatedPosition); const arma::Mat& yMat = y.slice(translatedPosition); - + const CubeElemType tmp = arma::dot(yMat, sMat); - - rho[iterationNum - i] = (tmp != CubeElemType(0)) ? (1.0 / tmp) : CubeElemType(1); - - alpha[iterationNum - i] = rho[iterationNum - i] * arma::dot(sMat, searchDirection); - + + rho[iterationNum - i] = (tmp != CubeElemType(0)) ? (1.0 / tmp) : + CubeElemType(1); + + alpha[iterationNum - i] = rho[iterationNum - i] * + arma::dot(sMat, searchDirection); + searchDirection -= alpha[iterationNum - i] * yMat; } @@ -410,7 +415,8 @@ L_BFGS::Optimize(FunctionType& function, // // But don't do this on the first iteration to ensure we always take at // least one descent step. - // TODO: to speed this up, investigate use of arma::norm2est() in Armadillo 12.4 + // TODO: to speed this up, investigate use of arma::norm2est() in Armadillo + // 12.4 if (arma::norm(gradient, 2) < minGradientNorm) { Info << "L-BFGS gradient norm too small (terminating successfully)." @@ -442,7 +448,7 @@ L_BFGS::Optimize(FunctionType& function, << std::endl; break; } - + // Build an approximation to the Hessian and choose the search // direction for the current iteration. SearchDirection(gradient, itNum, scalingFactor, s, y, searchDirection); diff --git a/tools/HISTORYold.md b/tools/HISTORYold.md index 363e170..537b6ad 100644 --- a/tools/HISTORYold.md +++ b/tools/HISTORYold.md @@ -1,5 +1,13 @@ -### ensmallen ?.??.?: "???" -###### ????-??-?? +### ensmallen 2.21.1: "Bent Antenna" +###### 2024-02-15 + * Fix numerical precision issues for small-gradient L-BFGS scaling factor + computations ([#392](https://github.com/mlpack/ensmallen/pull/392)). + + * Ensure the tests are built with optimisation enabled + ([#394](https://github.com/mlpack/ensmallen/pull/394)). + +### ensmallen 2.21.0: "Bent Antenna" +###### 2023-11-27 * Clarify return values for different callback types ([#383](https://github.com/mlpack/ensmallen/pull/383)).