libprima / prima

PRIMA is a package for solving general nonlinear optimization problems without using derivatives. It provides the reference implementation for Powell's derivative-free optimization methods, i.e., COBYLA, UOBYQA, NEWUOA, BOBYQA, and LINCOA. PRIMA means Reference Implementation for Powell's methods with Modernization and Amelioration, P for Powell.
http://libprima.net
BSD 3-Clause "New" or "Revised" License
292 stars 36 forks source link

Add recursive C test #85

Closed jschueller closed 9 months ago

zaikunzhang commented 10 months ago

@jschueller You are so fast! Very impressive. Thank you.

jschueller commented 10 months ago

the fortran/c implementation seems to be ok

zaikunzhang commented 10 months ago

Hi @jschueller Julien,

Thank you for the impressively quick response.

I will implement the Fortran test, but it will not be soon since I am quite busy now.

I tried to understand the C test. It seems that you are defining

f_outer(x) = prima(f_inner, x)

which means that f_outer(x) is the minimal value of f_inner obtained by minimizing f_inner using a prima solver starting from x.

For the purpose of the recursive test, this is sufficient. However, I note that f_outer is in fact a constant function: f_outer(x) = min f_inner = 0 in this case.

What I did in MATLAB is

f_outer(x) = prima(f_inner(x, y), y0)

which means that f_outer(x) is the minimal value of f_inner(x, y) obtained by minimizing f_inner with respect to y using a prima solver starting from y0 (set to a random number in my implementation). Or, more mathematically,

$$f1(x) = \min{y} f_0(x, y).$$

I am not sure whether this is doable in C.

zaikunzhang commented 10 months ago

I am not sure whether this is doable in C.

This seems doable using the data pointer. https://github.com/libprima/prima/pull/86

zaikunzhang commented 9 months ago

Many interesting things have been observed during the recursive tests on the Fortran and MATLAB sides. So I am interested in seeing what would happen on the C side. It would be surprising if nothing surprising happen at all.

In particular, I found that the recursion-safety of the Fortran code depends on the compiler options, unless the compiler conforms to Fortran 2018 by default. Before Fortran 2018, the Fortran standard does not guarantee that Fortran subroutines can be called recursively unless they are declared with the recursive attribute.

Consequently, the recursion-safety of the c interface depends on the compiler options used for building the Fortran library.

See I have updated prima/CMakelist.txt to require the Fortran compilers to ensure recursion-safety:https://github.com/libprima/prima/commit/9633ef5b31c383ec9a2f3a67e9a641eb9b052c70 .

In the future, when compilers all conform to Fortran 2018 by default, these options may be removed. But we may just retain them for safety and backward compatibility.

Thanks.