Search code examples
pythonscipyleast-squarestrilateration

Why is my python lmfit leastsq fitting function being passed too many arguments?


I've tried to search for someone making the same mistake as me, but have had no joy! It's also my 1st post, so I apologise if it's badly explained or directed. Advice welcome.

The problem I am solving is: Finding the position of a receiver of some kind by measuring the distances to a number of known reference points. It's basic trilateration, and I am using least squares to do this.

I have successfully used the scipy.optimize lesatsq function already to do this, so I'm pretty sure my fitting function works. However, I want to be able to use some of the extra features that the lmfit Python package offers, and I'm struggling to translate it accross. Full attempt code is here: http://pastebin.com/4xbfkaCm

The lmfit minimize function sets up calls to my fitting function, (which is called residualfunct) as follows, with stationarray being a numpy array containing station locations and ranges and params being a dictionary of parameters to be used in the fitting function

position = minimize(residualfunct, params, args=(stationarray))

and my fitting function is defined as

def residualfunct(params, stationarray):

    X = params['solutionX'].value
    Y = params['solutionY'].value
    Z = params['solutionZ'].value
    result = numpy.array([s[3] - linalg.norm(array((X,Y,Z))-array((s[0],s[1],s[2]))) for s in stationarray])
    print result
    return result

When I run this code I get the TypeError:

residualfunct() takes exactly 2 arguments (5 given).

as this call is made by the minimize function, I don't see what control I have over this. I can only imagine that this is being raised because I am passing an np.array as an argument, but this seems unavoidable. Can anyone see what I am doing wrong?

Thanks


Solution

  • In the call to minimize, change

    args=(stationarray)
    

    to

    args=(stationarray,)
    

    args must be a sequence (typically a tuple) whose elements are the arguments passed to the function. To create a tuple of length 1, you need the extra comma. When you write args=(stationarray) (without the extra comma), the parentheses have no effect, and it is the same as writing args=stationarray. minimize then calls the function as residualfunct(params, stationarray[0], stationarray[1], ...), which results in the error that you reported.