optimagic-dev / optimagic

optimagic is a Python package for numerical optimization. It is a unified interface to optimizers from SciPy, NlOpt and other packages. optimagic's minimize function works just like SciPy's, so you don't have to adjust your code. You simply get more optimizers for free. On top you get diagnostic tools, parallel numerical derivatives and more.
https://optimagic.readthedocs.io/
MIT License
270 stars 30 forks source link

Improve error message for probability constraint #545

Open ChristianZimpelmann opened 1 month ago

ChristianZimpelmann commented 1 month ago

What would you like to enhance and why? Is it related to an issue/problem?

The following code fails with the message TypeError: only integer scalar arrays can be converted to a scalar index.

import numpy as np
import optimagic as om

def fun(params):
    offset = np.linspace(1, 0, params.shape[0])
    x = params["value"] - offset
    return x @ x

params = pd.DataFrame(
    {
        "value": [0.3, 0.2, 0.5],
        "lower_bound": [0, 0, 0],
        "upper_bound": [1, 1, 1],
    },
    index=["pi_1", "pi_2", "pi_3"],
)
res = om.minimize(
    fun=fun,
    params=params,
    algorithm="scipy_lbfgsb",
    constraints=om.ProbabilityConstraint(selector=lambda params: params[:3]),
)

The problem seems to be that the bounds in the params DataFrame are not allowed (although they are also implemented by ProbabilityConstraint).

Building params as follows works fine:

params = pd.DataFrame(
    {
        "value": [0.3, 0.2, 0.5],
        "lower_bound": [np.nan, np.nan, np.nan],
        "upper_bound": [np.nan, np.nan, np.nan],
    },
    index=["pi_1", "pi_2", "pi_3"],
)

Describe the solution you'd like

Catch exception and improve error message.

Alternative: allow for specifying the bounds. This would require some thought on how to handle cases in which other bounds than 0, 1 are specified in the DataFrame.