简体   繁体   中英

Returning a function with dynamic variable names for use in e.g. lmfit

How to best return a function with dynamic variable names? Usually one should avoid it. But due to external package constraints this might not always be possible. Eg LMFit uses explicit variable names to adress parameters of the model.

If the function is

def (x, y):
    return y*x

then one needs to adress the parameter by its explcit name y .

For complex, generic fitting models one might need to dynamically generate a model with different parameters eg:

def make_model(x, myDict):
    
    ...
    def myModel(x, V1, V2):
        ...
        ...
        return result

    return myModel

In this example I want to change the names of the variables V1 and V2 to eg the keys of myDict . Is this possible? Should one do this at all and if not, how else do I create a function with exchangable variable names for use in such packages? I do not want to keep them to be called V1 and V2 because when adressing them later (and when having > 5 parameters) it might be clumsy to keep track of the names for the user.

Is this possible?

The short answer is "No". The lmfit.Model class inspects the model function to determine parameter names. This is an important feature that is an advantage to the user: Parameters should be named and not put in some syntactically-important but semanitically meaningless order.

You could use something like scipy.optimize.curve_fit . For that, variables are are reduced from parameter objects with attributes to floating point values that must be in a consistent but ultimately meaningless order. There are other reasons to avoid curve_fit , but this poor abstraction of "fitting parameter" is really unfortunate - it's like the authors forgot they were using Python and thought they were writing Fortran77.

Or you could use lmfit.minimize and write your own objective function (for curve-fitting, just returning "(data-mode)/uncertainty"). With that interface, you pass a lmfit.Parameters object - essentially a (ordered) dictionary of Parameter objects that you then unpack in your objective function.

Should one do this at all and if not,

I would say "probably not" and than you should not name Parameters V1 , V2 , etc unless that is meaningful to you and the person working with the results. If you told me that V1 is 100.2 and V2 is 0.75, I would say "oh, ok...". OTOH, if you told me Volume1 is 100.2 and Velocity2 is 0.75, now I'm starting to understand. Names matter.

how else do I create a function with exchangable variable names for use in such packages?

Build functions with named Parameters and then keep track of them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM