Search code examples
pythonpython-3.xnumpyscipydifferentiation

Minimisation of a multivariable function


import math
import numpy
import scipy

def chisq1a(a,b,NN):
return (NN/(a**2)*b**2*(1+3/(a**2))*(1+(math.tan((math.pi)/2*(a+b*math.log(b/0.45))))**2))

x0 = numpy.array([0,0,0])

from scipy.optimize import minimize
result = scipy.optimize.minimize(chisq1a, x0)

I am trying to minimise a multivariable function in Python 3 using the above code but I obtain an error that

  TypeError: chisq1a() missing 2 required positional arguments: 'b' and 'NN'

What does this mean? This error has arisen before in the context of having subsequently written a function, initially defined with n arguments, as one with e.g n-1 arguments so there is a mismatch, but this does not seem to be the problem here. Probably the solution is simple but I just started with python a few days ago so still learning :) Thanks!


Solution

  • I'm not sure why the minimize function was designed this way but it appears that you have to unpack the arguments inside the function which you want to minimise. I wasn't able to supply multiple arguments in any other way (for example, as a tuple). I took my cue from the bottom example in the docs where they use:

    fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2
    

    as an example for multiple arguments, i.e. the single argument x which they then index inside the function. The fact that they use a lambda doesn't make a difference.

    I had to update your initial guess from [0, 0, 0] to avoid a ZeroDivisionError. The following appears to work:

    import math
    import numpy as np
    import scipy
    
    def chisq1a(x):
        a, b, NN = x
        return (NN/(a**2)*b**2*(1+3/(a**2))*(1+(math.tan((math.pi)/2*(a+b*math.log(b/0.45))))**2))
    
    x0 = np.array([1, 1, 1])
    result = scipy.optimize.minimize(chisq1a, x0)
    

    As for accessing the results, the docs linked earlier state:

    res : OptimizeResult

    The optimization result represented as a OptimizeResult object. Important attributes are: x the solution array, success a Boolean flag indicating if the optimizer exited successfully and message which describes the cause of the termination. See OptimizeResult for a description of other attributes.

    So, x is your result array that you can again unpack.

    result = scipy.optimize.minimize(chisq1a, x0)
    a, b, NN = result.x