Repository navigation
Add thread-safe Steihaug, BOBYQA and NEWUOA trust-region optimizers - #1
Merged
Merged
Conversation
- steihaug(): Steihaug truncated-CG trust-region Newton minimizer ported from the Rust crate basin (exact-Hessian and matrix-free modes), with a thread-safe C entry point steihaug_solve_c(). Matches basin bit for bit. - bobyqa()/newuoa(): line-by-line C++ ports of Powell's BOBYQA/NEWUOA from minqa 1.2.8, drop-in replacements for the minqa R functions, with thread-safe C entry points. Bitwise identical to minqa; BOBYQA's RESCUE step evaluates the intended point instead of minqa's uninitialized one. - Append new slots to .RcppTrustPtr()/RcppTrust.h for nlmixr2est. - OpenMP thread-safety tests, fidelity tests against minqa and basin reference counts, new vignette "trust-region-methods". - NAMESPACE is now roxygen-managed. - License changed to GPL-2 (minqa-derived code); trust and basin notices retained in inst/COPYRIGHTS. Version 0.2.0.
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
- On non-x86_64, don't compare end points of the ill-conditioned tight-bounds BOBYQA case (FMA-contracted Fortran stops elsewhere). - Skip the iprint text comparison on Windows, where Rprintf and C++ snprintf format %#g differently. - Cover NEWUOA's BIGDEN and BOBYQA's RESCUE paths, every Steihaug stopping rule, R wrapper argument handling, and the C entry points' invalid-input and callback-failure codes (coverage 75.9% -> 92.0%).
- Ill-conditioned tight-bounds BOBYQA case: on non-x86_64 compare only the result class (minqa's FMA-contracted Fortran exits with ierr 3 there). - Trigger the non-finite-x abort with a NaN start instead of an unbounded run; check the unbounded ierr = 3 exit only on x86_64. - Loosen the RESCUE test's accuracy threshold; assert RelativeCostTolerance and MaxIter explicitly.
- Add M. J. D. Powell as author (Michael J. D. Powell) and cite his original BOBYQA/NEWUOA Fortran 77 sources (PRIMA archive) and papers in DESCRIPTION, man pages, README, vignette and inst/COPYRIGHTS. - License stays GPL-2: the C++ ports are translated from minqa's modified Fortran and R/minqa.R and the print glue follow minqa's R/C++ code, so the minqa authors remain listed as contributors/copyright holders.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds three trust-region optimizers. Like
trust(), each has an R function and a thread-safe C entry point with no R API calls and no global state, so it can be used as an inner or outer optimizer inside nlmixr2est's parallel C++ code.steihaug()steihaug_solve_c()bobyqa()bobyqa_solve_c()newuoa()newuoa_solve_c()UOBYQA is not included: it needs O(n²) points, and NEWUOA covers the same case.
How closely the ports match
R/minqa.Rsemantics.rescue.fcallsCALFUN(N,X,IPRINT)withXundefined insideRESCUE, so it evaluates the objective at uninitialized memory and results aren't repeatable. The port uses Powell's intendedW(1..N). Runs that enterRESCUEmatch a copy of minqa with only that line fixed.maxit = 100and an absolute gradient tolerance of1e-8.Downstream interface
.RcppTrustPtr()andinst/include/RcppTrust.hgain appended slots:bobyqa_solve_c,newuoa_solve_c,minqa_result_free,steihaug_solve_c,steihaug_result_free. Existing slots are unchanged.NULL.Other changes
inst/COPYRIGHTS.NEWS.mdadded.NAMESPACEis now roxygen-managed.vignette("trust-region-methods"); README and the main vignette updated.Testing
tests/testthat/test-minqa.R: exact comparison with minqa when it is installed (approximate on non-x86_64), error codes, R error propagation.tests/testthat/test-steihaug.R: basin reference counts, matrix-free vs exact, termination reasons, input validation.n) were run under AddressSanitizer and UBSan.R CMD check --as-cran: 1 NOTE, a non-portable compiler flag from this machine's R configuration.