As mentioned two weeks ago under the thread of LFortran, I have been developing a package named PRIMA for solving general nonlinear optimization problems without using derivatives. @certik suggested that I should write about PRIMA, especially its inclusion in SciPy.
What is PRIMA?
PRIMA is a package for solving general nonlinear optimization problems without using derivatives. It provides the reference implementation of Powell’s renowned derivative-free optimization methods, i.e., COBYLA, UOBYQA, NEWUOA, BOBYQA, and LINCOA. The “P” in the name stands for Powell, and “RIMA” is an acronym for “Reference Implementation with Modernization and Amelioration”.
PRIMA is a project that I have been working intensively on for the past three years. Almost all questions I posted on this forum come from PRIMA.
Who was Powell?
Michael James David Powell FRS was “a British numerical analyst who was among the pioneers
of computational mathematics”. He was the inventor/early contributor of quasi-Newton method, trust region method, augmented Lagrangian method, and SQP method. Each of them is a pillar of modern numerical optimization. He also made significant contributions to approximation theory and methods, but I hesitate to mention more details as it is not my area.
Among numerous honors, Powell was one of the first two recipients of the Dantzig Prize from the Mathematical Programming Society/Society for Industrial and Applied Mathematics (SIAM). This is considered the highest award in optimization.
Why PRIMA?
Professor Powell carefully implemented his derivative-free optimization methods into publicly available solvers. They are widely used by engineers and scientists. For instance, see Section 1 of a recent paper on Powell’s solvers as well as the Google searches of COBYLA and BOBYQA.
However, Professor Powell’s implementation was done in Fortran 77. The code is nontrivial to understand or maintain, let alone extend. For many practitioners, this has become an obstacle to exploiting these solvers in their applications. More seriously, bugs keep emerging, but few of them get really fixed — it is highly challenging and indeed frustrating (if not depressing) to debug a maze of 244 GOTOs in 7939 lines of classic-style Fortran 77 code, especially if you do not know the sophisticated algorithms behind the code, which are nontrivial to understand by themselves.
Before he passed, Professor Powell had asked me and Professor Nick Gould to maintain his solvers. This is an honorable mission. To make the solvers more accessible, I started PRIMA. It is a project somehow similar to the translation, interpretation, and annotation of Euclid’s Elements. It will make Powell’s solvers easily understandable to everyone, not only the experts. Few people remember who translated Elements, but it is a job that must be done.
Objectives
PRIMA aims to provide the reference implementation of Powell’s methods in modern languages, first in modern Fortran (F2008 or newer), and then in MATLAB, Python, C++, Julia, and R. It will be a faithful implementation, in the sense that the code will be mathematically equivalent to Powell’s, except for the bug fixes and improvements made intentionally.
The focus is to implement these methods in a structured and modularized way so that they are understandable, maintainable, extendable, fault tolerant, and future proof. The code will have no GOTO (of course) and will use matrix-vector procedures instead of loops whenever possible. In doing so, PRIMA codes the algorithms in a way that we would present them on a blackboard.
(N.B.: There are plenty of discussions on whether we should use matrix-vector procedures or loops in Fortran. Here, the former is the correct one by all means, as long as we note one fact — in derivative-free optimization, the dominating cost comes from the function evaluations implemented by the users rather than the numerical linear algebra of the solver. Each function evaluation takes minutes or months to finish.)
Current status
Modern Fortran
After almost three years of intensive coding, the modern Fortran version of PRIMA has been finished by December 2022.
MATLAB
- An interface is provided for using the modern Fortran implementation in MATLAB.
- A pure MATLAB version of NEWUOA is implemented. It was generated straightforwardly (indeed, automatically) from an earlier version of the modern Fortran code.
Python
- The inclusion of PRIMA into SciPy is under discussion. It will replace the buggy and unmaintained Fortran 77 version of COBYLA underlying
scipy.optimize.minimize
, and make the other four solvers available to all SciPy users. - My ultimate objective is to have a native Python implementation of PRIMA independent of Fortran, similar to what we have done with NEWUOA in MATLAB as mentioned above.
Other languages
- Interfaces for using the modern Fortran implementation in other languages will be available later.
- Given the modern Fortran version, native implementations in other languages become much easier, because we now have a structured and modularized implementation as a reference. My team will implement the methods in other languages in this way. I am exploring how LLMs like ChatGPT can accelerate our progress in this process.
What is needed now?
Fortran
- Make PRIMA available with FPM.
- Generating documentation using FORD or other tools.
Python
How to include PRIMA in SciPy as soon as possible? This is the question. The major Scipy maintainers are positive about the inclusion of PRIMA solvers in SciPy. See the discussions on GitHub for details. However, I do not know Python at all. So community efforts are greatly needed here.
The first step should be replacing the Fortran 77 implementation of COBYLA in SciPy with the PRIMA version, respecting the current Python signature of COBYLA. The second step will be getting BOBYQA into SciPy, as this solver has been long requested by SciPy users. The third step is to get the other three solvers included.
Previously, my former student Tom @ragonneau and I developed Python interfaces for the Fortran 77 implementation of Powell’s solvers under the PDFO project. They may provide a good starting point to begin with.
I do not think there is any modern Fortran code with modules in the SciPy code base, or even any .f90 code.
References
[1] M. J. D. Powell, A direct search optimization method that models the objective and constraint functions by linear interpolation, In Advances in Optimization and Numerical Analysis, eds. S. Gomez and J. P. Hennart, pages 51–67, Springer Verlag, Dordrecht, Netherlands, 1994
[2] M. J. D. Powell, UOBYQA: unconstrained optimization by quadratic approximation, Math. Program., 92(B):555–582, 2002
[3] M. J. D. Powell, The NEWUOA software for unconstrained optimization without derivatives, In Large-Scale Nonlinear Optimization, eds. G. Di Pillo and M. Roma, pages 255–297, Springer, New York, US, 2006
[4] M. J. D. Powell, The BOBYQA algorithm for bound constrained optimization without derivatives, Technical Report DAMTP 2009/NA06, Department of Applied Mathematics and Theoretical Physics, Cambridge University, Cambridge, UK, 2009
[5] T. M. Ragonneau and Z. Zhang, PDFO: a cross-platform package for Powell’s derivative-free optimization solvers, arXiv:2302.13246, 2023
Remarks
- LINCOA seeks the least value of a nonlinear function subject to linear inequality constraints without using derivatives of the objective function. Powell did not publish a paper to introduce the algorithm.
- The paper [5] introduces the PDFO package rather than PRIMA. Nevertheless, it provides a good introduction to Powell’s methods.
Update: PRIMA is hiring!
In addition to the community efforts, I would like to recruit full-time postdocs and/or research assistants to work on PRIMA. He / she must come to my university in Hong Kong to work. Possible tasks include the following.
- Make PRIMA available as an FPM package. Automatic documentation of PRIMA with FORD or Sphinx.
- Developing Python interfaces / wrappers for the modern Fortran implementation of PRIMA, towards the inclusion of PRIMA into SciPy.
- Developing native implementations of PRIMA with the modern Fortran version being the reference. Interesting languages including Python, MATLAB, C++, Julia, and R.
For 2, ideally, the implementation can be obtained (semi-)automatically using scripting languages and maybe LLMs.
The postdoc must have a Ph.D. degree in computational/applied math, computer science, or related domains. The research assistant must have a Master’s degree similarly.
If you, your friend, or your student are interested, please contact me.