pythonfunctionoptimizationscipyminima

Optimizing a function within a given range in scipy


I have been trying to get the minimum for a function of a single variable. The function is:

sym.sqrt((x+6)**2 + 25) + sym.sqrt((x-6)**2 - 121)

The function's derivative (which is (x - 6)/sym.sqrt((x - 6)**2 - 121) + (x + 6)/sym.sqrt((x + 6)**2 + 25)) blows up for x equal to -5 ad becomes complex for x greater than that (for example, -4) but less than 18 (which we can ignore for simplicity here), due to the first term. Therefore, I wrote the code to only evaluate the function for x between -6 and -10 (by inspection, I could see that the minimum was around -8.6, so I chose -10):

def h(x):

    for x in np.arange(-10,-5):

        sym.sqrt((x+6)**2 + 25) + sym.sqrt((x-6)**2 - 121)

    result = optimize.minimize_scalar(h,bounds=(-10,-5))

    x_min = result.x

    print(x_min)

Unfortunately, I got this error:

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Can someone help me with this issue?

Regards,

Prasannaa


Solution

  • I don't think numpy and sympy play well together unless you lambdify your sympy equation. And I'm not sure with NaN values either, which appear to be in your equation.

    You could try it numerically. When plotting your functions I found no minimum in the range, but there was a maximum in the derivative:

    import numpy as np
    from matplotlib import pyplot as plt
    from scipy.signal import argrelmax
    
    x = np.linspace(-10, -6, 256) # generate x range of interest
    y = np.sqrt((x+6)**2 + 25) + np.sqrt((x-6)**2 - 121)
    
    dydx = (x - 6)/np.sqrt((x - 6)**2 - 121) + (x + 6)/np.sqrt((x + 6)**2 + 25)
    
    maximum, = argrelmax(dydx) # returns index of maximum
    
    x[maximum]
    >>> -8.50980392
    
    # plot it
    plt.plot(x, y)
    ax = plt.gca().twinx() # make twin axes so can see both y and dydx
    ax.plot(x, dydx, 'tab:orange')
    ax.plot(x[maximum], dydx[maximum], 'r.')
    

    plot of code above with maximum identified