opensim-org / opensim-moco

Solve optimal control problems for musculoskeletal models using OpenSim and direct collocation.
https://opensim.stanford.edu/moco
Apache License 2.0
57 stars 16 forks source link

MocoControlGoal: user-chosen exponent #410

Closed chrisdembia closed 5 years ago

chrisdembia commented 5 years ago

The branch MocoControlGoal_divide_by_displacement allows users to set the exponent on the controls, and also allows users to divide by the model's displacement over the phase.

These changes are causing the first problem in exampleMocoTrack to increase its runtime from 89 seconds to 120 seconds. This is too large of an increase!

I suspect the issue is using pow() and allowing the exponent to be set at runtime.

We should find a way to have a generic exponent without the worse performance.

@carmichaelong , are you interested?

carmichaelong commented 5 years ago

Hm, an interesting problem. Unsure how exactly to get that trade-off. Any thoughts on making a few special cases not depend on the slow pow() method? For instance, allow l1 or l2 penalties to not use pow()? Otherwise use pow()?

chrisdembia commented 5 years ago

Yes I'd be fine with that. I guess mostly I just don't want a performance penalty for l2.

carmichaelong commented 5 years ago

@chrisdembia Should I just work directly with the branch in progress?

chrisdembia commented 5 years ago

Yes, that'd be great.

carmichaelong commented 5 years ago

Tested some cases to try to narrow down where the time lost might have gone. Used the same test as you did (commenting out second test in exampleMocoTrack).

Using MocoControlGoal_divide_by_displacement branch:

Using master branch: 270.8 +/- 9.73

Seems to indicate that a separate case for multiplying controls for an exact power of 2 calculation might speed things up, but I definitely didn't see quite the performance change that you did (<10% in my case, whereas yours was closer to 25%)

chrisdembia commented 5 years ago

That's quite thorough. Hmm, weird. Maybe I was doing something wrong.

carmichaelong commented 5 years ago

Did some testing on a more recent processor (but still Windows 10, using Visual Studio 2017). Seems to show even smaller differences in branches:

master branch: 165.4 +/- 1.52 sec

MocoControlGoal_divide_by_displacement branch: 168.2 +/- 4.76 sec

MocoControlGoal_divide_by_displacement branch with explicit multiply (instead of pow): 167.4 +/- 2.70 sec

On a separate note, one reason for different testing times between computers (aside from CPU resources) could be due to small differences in solving the problem. For instance, the first computer above converged on iteration 259, while the second computer converged after 389 iterations.

chrisdembia commented 5 years ago

Darn. Well, I guess this is a good thing?

Interesting. More iterations but shorter runtime.

chrisdembia commented 5 years ago

I found the issue. On my Mac, pow(x, 2) gives a different result than x * x, causing the optimizer to take more iterations for some problems, and less in others. This is likely a platform-dependent issue.

carmichaelong commented 5 years ago

Wow that's annoying. Sounds like x * x should be a separate branched case then, given how often it's used?

chrisdembia commented 5 years ago

Yes, it is. Yes, I made that change on the branch.