Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

BUG: The COBYQA optimizer doesn't seem to respect boundaries #201

Copy link
Copy link

Description

@GijsB
Issue body actions

Hi cobyqa team!

In a recent bug-report in the scipy repo I've found that the COBYQA optimizer doesn't always seems to respect the specified boundaries. Unfortunately, it was hard to simplify the issue to demonstrate it in an isolated manner, but I've done my best.

The context is a python package that's designed to optimize marine propellers. Each propeller is modeled using a large polynomial function that has been fit on a large set of experimental data. Using these polynomials, the performance of a propeller can be predicted. I've isolated the issue into a specific unit-test:

from propy.wageningen_b import WageningenBPropeller

from scipy.optimize import minimize, Bounds, NonlinearConstraint
from numpy import inf


def test_optimization_max_diameter() -> None:
    thrust = 1393000
    speed = 8.65
    immersion = 3.51

    def f_obj(args):
        print(f'f_obj({args})')
        return WageningenBPropeller(4, *args).losses(speed, thrust)

    def f_con(args):
        print(f'f_con({args})')
        return WageningenBPropeller(4, *args).cavitation_margin(thrust, immersion)

    minimize(
        method='COBYQA',
        fun=f_obj,
        x0=(1.0, 0.5, 0.8),
        bounds=Bounds(
            lb=(0.03, 0.3, 0.5),
            ub=(7.0, 1.05, 1.4),
            keep_feasible=(True, True, True)
        ),
        constraints=[
            NonlinearConstraint(f_con, 0, inf)
        ],
        options={
            'disp': True
        }
    )

    assert True

In one of the constraint function evaluations, the second argument of the function (area_ratio) is set to 0.088, which is out of bounds. The output of the function is shown below:

Starting the optimization procedure.
Initial trust-region radius: 1.0.
Final trust-region radius: 1e-06.
Maximum number of function evaluations: 1500.
Maximum number of iterations: 3000.

f_obj([1.    0.675 0.875])
f_obj([ 1.000e+00  6.750e-01  8.750e-01]) = 0.8352655933061457
f_con([1.    0.675 0.875])
f_con([ 1.000e+00  6.750e-01  8.750e-01]) = [-2.418e+01]
f_obj([1.375 0.675 0.875])
f_obj([ 1.375e+00  6.750e-01  8.750e-01]) = 0.780413651409479
f_con([1.375 0.675 0.875])
f_con([ 1.375e+00  6.750e-01  8.750e-01]) = [-1.249e+01]
f_obj([1.    1.05  0.875])
f_obj([ 1.000e+00  1.050e+00  8.750e-01]) = 0.8354762797478886
f_con([1.    1.05  0.875])
f_con([ 1.000e+00  1.050e+00  8.750e-01]) = [-2.383e+01]
f_obj([1.    0.675 1.25 ])
f_obj([ 1.000e+00  6.750e-01  1.250e+00]) = 0.8552303249820229
f_con([1.    0.675 1.25 ])
f_con([ 1.000e+00  6.750e-01  1.250e+00]) = [-2.418e+01]
f_obj([0.625 0.675 0.875])
f_obj([ 6.250e-01  6.750e-01  8.750e-01]) = 0.8939800911425317
f_con([0.625 0.675 0.875])
f_con([ 6.250e-01  6.750e-01  8.750e-01]) = [-6.291e+01]
f_obj([1.    0.3   0.875])
f_obj([ 1.000e+00  3.000e-01  8.750e-01]) = 0.8279419747450552
f_con([1.    0.3   0.875])
f_con([ 1.000e+00  3.000e-01  8.750e-01]) = [-2.454e+01]
f_obj([1.    0.675 0.5  ])
f_obj([ 1.000e+00  6.750e-01  5.000e-01]) = 0.8344755303132483
f_con([1.    0.675 0.5  ])
f_con([ 1.000e+00  6.750e-01  5.000e-01]) = [-2.418e+01]
f_con([1.    0.675 0.875])
f_con([1.375 0.675 0.875])
f_con([1.    1.05  0.875])
f_con([1.    0.675 1.25 ])
f_con([0.625 0.675 0.875])
f_con([1.    0.3   0.875])
f_con([1.    0.675 0.5  ])
f_con([1.375 0.675 0.875])
f_con([1.    0.675 0.875])
f_con([1.    1.05  0.875])
f_con([1.    0.675 1.25 ])
f_con([0.625 0.675 0.875])
f_con([1.    0.3   0.875])
f_con([1.    0.675 0.5  ])
f_obj([1.12373237 0.95273559 0.8562245 ])
f_obj([ 1.124e+00  9.527e-01  8.562e-01]) = 0.817229804956104
f_con([1.12373237 0.95273559 0.8562245 ])
f_con([ 1.124e+00  9.527e-01  8.562e-01]) = [-1.875e+01]
f_con([1.375 0.675 0.875])
f_con([1.12373237 0.95273559 0.8562245 ])
f_obj([0.75573562 1.02487013 0.8562245 ])
f_obj([ 7.557e-01  1.025e+00  8.562e-01]) = 0.8724748922858667
f_con([0.75573562 1.02487013 0.8562245 ])
f_con([ 7.557e-01  1.025e+00  8.562e-01]) = [-4.249e+01]
f_con([1.375 0.675 0.875])
f_con([0.75573562 1.02487013 0.8562245 ])
f_con([1.375 0.675 0.875])
f_con([0.75573562 1.02487013 0.8562245 ])
f_con([1.375 0.675 0.875])
f_con([1.    0.675 0.875])
f_con([1.    1.05  0.875])
f_con([1.    0.675 1.25 ])
f_con([0.75573562 1.02487013 0.8562245 ])
f_con([1.    0.3   0.875])
f_con([1.    0.675 0.5  ])
f_con([1.375 0.675 0.875])
f_con([1.    0.675 0.875])
f_con([1.    1.05  0.875])
f_con([1.    0.675 1.25 ])
f_con([0.75573562 1.02487013 0.8562245 ])
f_con([1.    0.3   0.875])
f_con([1.    0.675 0.5  ])
f_con([1.375 0.675 0.875])

New trust-region radius: 0.037500000000000006.
Number of function evaluations: 9.
Number of iterations: 1.
Least value of f_obj: 0.780413651409479.
Maximum constraint violation: 12.488502981664915.
Corresponding point: [ 1.375e+00  6.750e-01  8.750e-01].

f_obj([1.49745472 0.51161965 0.86225777])
f_obj([ 1.497e+00  5.116e-01  8.623e-01]) = 0.7593384210840486
f_con([1.49745472 0.51161965 0.86225777])
f_con([ 1.497e+00  5.116e-01  8.623e-01]) = [-1.058e+01]
f_con([1.375 0.675 0.875])
f_con([1.49745472 0.51161965 0.86225777])
f_con([1.375 0.675 0.875])
f_con([1.49745472 0.51161965 0.86225777])
f_con([1.375 0.675 0.875])
f_con([1.49745472 0.51161965 0.86225777])
f_con([1.375 0.675 0.875])
f_con([1.    0.675 0.875])
f_con([1.    1.05  0.875])
f_con([1.    0.675 1.25 ])
f_con([1.49745472 0.51161965 0.86225777])
f_con([1.    0.3   0.875])
f_con([1.    0.675 0.5  ])
f_con([1.49745472 0.51161965 0.86225777])
f_con([1.    0.675 0.875])
f_con([1.375 0.675 0.875])
f_con([1.    1.05  0.875])
f_con([1.    0.675 1.25 ])
f_con([1.    0.3   0.875])
f_con([1.    0.675 0.5  ])
f_obj([1.44084474 0.3        0.71284246])
f_obj([ 1.441e+00  3.000e-01  7.128e-01]) = 0.7523410826103512
f_con([1.44084474 0.3        0.71284246])
f_con([ 1.441e+00  3.000e-01  7.128e-01]) = [-1.167e+01]
f_con([1.49745472 0.51161965 0.86225777])
f_con([1.44084474 0.3        0.71284246])
f_obj([1.28109002 0.3        0.71000464])
f_obj([ 1.281e+00  3.000e-01  7.100e-01]) = 0.776183522835638
f_con([1.28109002 0.3        0.71000464])
f_con([ 1.281e+00  3.000e-01  7.100e-01]) = [-1.484e+01]
f_con([1.28109002 0.08838035 0.71000464])

There's a good chance I'm misunderstanding something, or maybe this is a small bug somewhere? Either way, I hope this information is helpful to you. Please let me know if there's any other information you need. Thank you for your help!

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.