Open tkuchida opened 8 years ago
Uh oh. Would it be easy to give a very small example that demonstrates this bug?
Did you discover this via print statements (or something similar) inside your objectiveFunc()
?
Would it be easy to give a very small example that demonstrates this bug?
Yes: run the Examples/exampleOptimization project (no modifications necessary). Here's the output I get:
Updating Model file from 30000 to latest format... Loaded model arm26_optimize from file Arm26_Optimize.osim objective evaluation #: 1 controls = ~[0.01 0.01 0.01 0.99 0.99 0.99] bestSoFar = -3.4539 ... objective evaluation #: 207 controls = ~[0.0601281 0.0212095 0.021541 0.987047 0.72514 0.30172] bestSoFar = -4.69238 Elapsed time = 72s TRIlong control value = 0.0601281 TRIlat control value = 0.0212095 TRImed control value = 0.021541 BIClong control value = 0.987047 BICshort control value = 0.709847 BRA control value = 0.30172 Maximum hand velocity = 4.67874m/s OpenSim example completed successfully. Press any key to continue . . .
The bestSoFar
value is reported from within objectiveFunc()
and reaches -4.69238, but the optimizer returns -4.67874 (a worse result). Notice that all the controls
reported for the last objective function evaluation were within the bounds of [0.01, 0.99].
Did you discover this via print statements (or something similar) inside your
objectiveFunc()
?
Yes, I'm monitoring the progress of the optimizer in a similar way as appears in OptimizationExample.cpp.
Okay; thank you for those details.
Do you know what the root cause could be? Is it possible that the Optimizer
is just returning its last function evaluation?
Is it possible that the
Optimizer
is just returning its last function evaluation?
Yes, that is one possibility of many. It may also be the case that bestSoFar
and the value returned by the optimizer are within the convergence tolerance, in which case it could be argued that returning either would be equally acceptable—but I disagree with that argument. I can investigate further if we decide this is a priority, but I don't know enough about the code to attempt a quick fix.
The last objective function value reported from within
objectiveFunc()
(:car:) is better than the final objective function value returned by theSimTK::Optimizer
(:checkered_flag:). It may be that some algorithms would evaluate the objective function for candidate solutions that violate constraints (whereupon it might be justified to get a :checkered_flag: that is worse than :car:), but there's no such excuse when solving an unconstrained problem. Not returning the best solution seems to violate a fundamental property of what an optimizer should be expected to do (similar to the expectation that it will return a solution that is no worse than the initial guess). The difference between :car: and :checkered_flag: is likely small in most practical cases, but perhaps not always.(Using
SimTK::InteriorPoint
with numerical gradient.)