What is an interface / wrapper? #79
Replies: 2 comments 4 replies
-
|
I think that, as dicussed in #62 (comment), the Julia interface to the algorithms of the PRIMA library implemented in PRIMA.jl is quite similar to the basic interface that you propose here perhaps with different default settings. Thanks to the expressiveness of Julia, I do not see the needs (for now) of a higher level interface. Except maybe the single optimizer which automatically choose the best method considering the contraints (as what you have done for Python). The only difficulty I can see is to check the signature of the user-defined function (which is different for COBYLA)/ |
Beta Was this translation helpful? Give feedback.
-
|
Something else that the high level interface can handle is the scaling of variables. I have open an issue here for the Julia interface to PRIMA algorithms with a proposition to cope with scaling. The proposition is not specific to the Julia case. The only remaining issue not handled by this proposition is the printing of the variables when |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Consider a package that is implemented in C or Fortran. Take PRIMA as an example. As of September 2023, it is only implemented in modern Fortran. To make PRIMA available in other languages, we need to provide interfaces (or wrappers; I will not distinguish the two words in the sequel).
What is an interface?
In my opinion, there are two different types of interfaces, namely the basic interface and the advanced one, which will be detailed below.
Let us still take PRIMA as an example. It provides the following Fortran subroutines for solving nonlinear optimization problems without using derivatives.
Here,
calfunis a callback function that evaluates the objective function (calcfcevaluates the objective function and nonlinear constraints);x0is the starting point;Aineqandbineqdefine the linear inequality constraints;Aeqandbeqdefine the linear equality constraints;xlandxudefine that bound constraints;rhobeg,rhoend,ftarget, andmaxfunare some parameters needed by the solvers.Note that I have deliberately removed some arguments in the signature to make things simpler.
Suppose that we want to make these solvers available in MATLAB. So a MATLAB interface is needed.
Basic interface
The basic interface makes the above-mentioned solvers callable in MATLAB, providing the following MATLAB functions.
This is done by compiling the Fortran code using MEX provided by MathWorks.
Advanced interface
The basic interface is already nice. Users need to do the following when they want to use PRIMA to solve their problems.
calfunorcalcfc,x0,xl,xu,Aineq,bineq,Aeq,beq, which ever applicable.rhobeg,rhoend,ftarget, andmaxfun.This seems not too difficult. However, in practice, things may not be so simple. Here are some examples.
newuoaanduobyqacan solve such a problem; indeed, the other three solvers can do it as well.rhobeg,rhoend,ftarget, andmaxfunrepresent and how to set them. Note that I have already simplified the problem here. In reality, the solvers have many more parameters ---cobylahas more than 20. It will be challenging and tedious to set all the parameters properly.The advanced interface is another layer between the basic interface and the users, handling all these problems in a user-friendly way.
Take the MATLAB interface of PRIMA as an example. The interface wraps everything under a single MATLAB function
prima. This function has the following features.primahas the same signature as the MATLAB functionfminconfrom MathWorks, so users do not need to learn how to use prima. Basically, they just need to changefminconto prima in their existing MATLAB code. That's all.primaselects the solver according to the problem unless the user specifies the solver by setting theAlgorithmoption. If the solver specified by the user is invalid or cannot solve the problem, a warning will be raised and a solver will be selected.primadefaults the parameters to values that work well in general except for those set by the user. If the user sets a parameter improperly, then a warning will be raised and the default value will be taken.primapreprocesses the inputs from the user before sending them to the solver. For example,lincoaexpectsx0to be feasible. If the user provides an infeasible starting point, thenprimawill projectx0to the feasible region before passing it tolincoa. Otherwise,lincoawill not behave properly. Indeed, points 2 and 3 above can also be regarded as part of the preprocessing.primapostprocesses the outputs from the solver before returning them to the user. An important aspect of the postprocessing is to validate that the outputs are reasonable --- for example, the number of function evaluations is not more thanmaxfun(the maximum number of function evaluations allowed). This is done only in the debugging mode, which is off by default and can be turned on by setting thedebugoption totrue. If ever some outputs are invalid, an error will be raised in the debug mode, so that the user will be informed and may inform the developer.In the MATLAB interface of PRIMA, points 2, 3, and 4 are handled by
preprima, while point 5 is done bypostprima.primacallspreprimabefore solving the problem, and callspostprimaafterward.With an advanced interface like
prima, users only need to focus on the definition of the optimization problem, at which they should be experts. The setup of the solver needs minimum care.What should we do in other languages (Python, Julia, R, ...)?
Ideally, we should provide the advanced interface elaborated above.
However, this may take a bit of time, since many details need to be handled. Instead of doing things in one shot, we should first produce the basic interface, and then work out the advanced one gradually. In some languages (Julia, for example), the basic interface can be generated automatically. The advanced one, however, does need a human being to handcraft with some care and patience.
The basic interface can also be used to integrate our solvers into existing libraries, e.g., SciPy in Python and Optimization.jl in Julia. In this scenario, these libraries will likely handle the inputs and outputs in a systematic and mature way. So we only need to code a thin wrapper between the basic interface and the library to make them understand each other. This is much easier to produce than a user-friendly interface for humans.
Beta Was this translation helpful? Give feedback.
All reactions