Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.2.0 introduces `too many indices for array` error in `optimize.newton()` #9608

Closed
NicolasHug opened this issue Dec 18, 2018 · 3 comments · Fixed by #9612
Closed

Version 1.2.0 introduces `too many indices for array` error in `optimize.newton()` #9608

NicolasHug opened this issue Dec 18, 2018 · 3 comments · Fixed by #9612

Comments

@NicolasHug
Copy link
Contributor

@NicolasHug NicolasHug commented Dec 18, 2018

Since version 1.2.0, optimize.newton fails when passing an array with a single entry and when passing fprime2

Reproducing code example:

from scipy.optimize import newton
import numpy as np

def f(x):
    return x**2

def fprime(x):
    return 2 * x

def fprime2(x):
    return 2

def test():
    x0 = np.array([-2], dtype=np.float32)

    optimum = newton(f, x0=x0)  # OK
    print(optimum)
    optimum = newton(f, x0=x0, fprime=fprime)  # OK
    print(optimum)
    optimum = newton(f, x0=x0, fprime=fprime, fprime2=fprime2)  # Error
    print(optimum)

test()

Error message:

[-1.95439407e-08]
[-7.4505806e-09]
Traceback (most recent call last):
  File "lolx.py", line 23, in <module>
    test()
  File "lolx.py", line 20, in test
    optimum = newton(f, x0=x0, fprime=fprime, fprime2=fprime2)  # Error
  File "/home/nico/.virtualenvs/pygbm/lib/python3.7/site-packages/scipy/optimize/zeros.py", line 263, in newton
    full_output)
  File "/home/nico/.virtualenvs/pygbm/lib/python3.7/site-packages/scipy/optimize/zeros.py", line 380, in _array_newton
    dp = dp / (1.0 - 0.5 * dp * fder2[nz_der] / fder[nz_der])
IndexError: too many indices for array

Scipy/Numpy/Python version information:

Works in 1.1.0

1.1.0 1.15.4 sys.version_info(major=3, minor=7, micro=1, releaselevel='final', serial=0)

Fails in 1.2.0

1.2.0 1.15.4 sys.version_info(major=3, minor=7, micro=1, releaselevel='final', serial=0)
@rgommers

This comment has been minimized.

Copy link
Member

@rgommers rgommers commented Dec 19, 2018

@NicolasHug thanks for the report.

@mikofski would you mind having a look at this one?

@mikofski

This comment has been minimized.

Copy link
Contributor

@mikofski mikofski commented Dec 19, 2018

Thanks @NicolasHug for reporting this! It's an interesting case, b/c the 2nd derivative returns a Python scalar

def fprime2(x):
    return 2

which is different than the function and 1st derivative, which both return NumPy arrays

def f(x):
    return x**2

def fprime(x):
    return 2 * x

because the initial guess, x, is a NumPy array

def test():
    x0 = np.array([-2], dtype=np.float32)

So the same error would have occurred if fprime returned an scalar.

When evaluating fprime2, the return is converted to a NumPy array on L380

fder2 = np.asarray(fprime2(p, *args))

but the size is not preserved, and so that's the bug. I think I have a fix. I'll submit a PR shortly.

@mikofski

This comment has been minimized.

Copy link
Contributor

@mikofski mikofski commented Dec 19, 2018

I propose to only use _array_newton if the size of the initial guess is greater than one.

I also propose that the functions be required to return the same size as the argument. So if in the example above, x0 = np.array([-2, -3], dtype=np.float32) then fprime2(x) would be required to return an array of the same size as x, or np.tile(2, x.shape). The docstring already required this for func, but did not explicitly require it for fprime or fprime2 so I've updated the docs:

If x0 is a sequence, then newton returns an array, and func must be vectorized and return a sequence or array of the same shape as its first argument.

Finally, I reran the airspeed benchmarks and there are no differences with the proposed changes.

ogrisel added a commit to NicolasHug/scikit-learn that referenced this issue Apr 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.