scipy.optimize.minimize
had a very subtle spec or bug.
I thought it was close to a bug, but when I fixed it, people who were already using it seemed to be in trouble, so I set up an issue and asked, "If you want to fix it, I'll give you a pull request?"
I was supposed to put out a pull request, so I put it out.
Just recently, it was finally merged.
scipy.optimize.minimize
?If you give it a function, it will nicely optimize the parameters and minimize the value returned by the function. For example, let's say you have the expression $ z = 2x ^ 2 + (3y --2) ^ 2 + xy $. It solves what is $ x, y $ that makes $ z $ the smallest? At first glance, you can see that when $ x = 0, y = 2/3 $, it will be zero, and it will be smaller than that.
def f(x, y):
return 2 * x**2 + (3*y - 2)**2 + x*y
print(scipy.optimize.minimize(f, [0., 0.]))
And, if you give a function and an appropriate initial value ([0., 0.]
), it will ask for a nice value.
When it is array ([-0.16901447, 0.67605677]), it seems to be -0.05633802816721355.
scipy.optimize.minimize
has multiple algorithms for minimization, which can be selected by giving an argument ofmethod = "..."
.
By the way, only when there is only one argument and when you use the "Powell" method, a little nasty thing happens.
import numpy as np
import scipy.optimize
def fun(x):
return x*x
res = scipy.optimize.minimize(fun, [0.1], method="Nelder-Mead")
print("Nelder-Mead:")
print("Optimized:", res.x, "Shape:", res.x.shape)
res = scipy.optimize.minimize(fun, [0.1], method="COBYLA")
print("COBYLA:")
print("Optimized:", res.x, "Shape:", res.x.shape)
res = scipy.optimize.minimize(fun, [0.1], method="Powell")
print("Powell:")
print("Optimized:", res.x, "Shape:", res.x.shape)
Nelder-Mead:
Optimized: [1.94289029e-16] Shape: (1,)
COBYLA:
Optimized: [0.00010234] Shape: (1,)
Powell:
Optimized: 4.163336342344337e-17 Shape: ()
Did you understand?
The return value shape
is different.
Actually, in addition to this, I tried all 14 types, including those that must specify Jacobian and those that must specify Hessian, but only the "Powell" method was like this.
Well, it's a bug. This is a historic project. It may be difficult to decide whether or not to fix it now. Already, Powell may affect those who believe this and use it. But, well, I decided to ask because it was a big deal.
(January 2019) So I forked it for the time being and tried to fix it in my repository. I knew that I could fix it, so I set up an issue, put up the fixed link, and said, "If this is all right, I'll put out a PR." https://github.com/scipy/scipy/issues/9715
(August 2019) Then, he said, "It's a bug, so it's better to fix it, but due to compatibility issues, I want you to change the function to put the fix in." So I issued a PR in that way. https://github.com/scipy/scipy/pull/10640
(September 2019) The changes are good, but the added test is a bit redundant, so I got a comment saying that I should fix it, so I fixed it, etc. It was left unanswered for a while.
(December 2019) It has been merged into master.
It took about a year. I think that the developers were also busy and the content was not so big, so the priority was low.
--Since it was necessary to set up an issue, write a commit message, and issue a PR in a format suitable for Scipy, check "what is it supposed to be in the first place" and match it to that format It was quite difficult to do ――It may be that you didn't write the commit message properly. ――It took a long time, but the developers were kind enough to respond properly. ――Even if it's a small thing, I'm glad I did it because I was able to contribute to the improvement of the famous library called scipy that I and everyone are using. ――I thought again that it is important not to be afraid and to do your best to listen to people.
Open source isn't just free to use, it's also full of opportunities. Even if it's very boring, it may be a chance to contribute if you think "that?" I would like to continue contributing to open source if there is something I can do.
Recommended Posts