[Tutor] constructing semi-arbitrary functions
Peter Otten
__peter__ at web.de
Tue Feb 18 18:59:53 CET 2014
Oscar Benjamin wrote:
> On 17 February 2014 20:13, Peter Otten <__peter__ at web.de> wrote:
>> André Walker-Loud <walksloud at gmail.com> wrote:
>>>
>>> The 3rd party minimizer utilizes the .func_code.co_varnames and
>>> .func_code.co_argcount to determine the name and number of variables to
>>> minimize. eg.
>>>
>>> =========
>>> METHOD 2: use strings, exec and globals to construct function
>>> def minimize(pars,x,y,dy):
>>> global g_x, g_y, g_dy
>>> g_x = x; g_y = y; g_dy = dy
>>> argnames = ['c_%i'%(i) for i in range(len(pars))]
>>> funcargs = ", ".join(argnames)
>>> funcdef = 'def chisq_mn(' + funcargs + '):\n'
>>> funcdef += ' global g_x, g_y, g_dy\n'
>>> funcdef += ' return chisq(['+funcargs+'],g_x,g_y,g_dy)\n' #chisq
>>> is defined in same file
>>> # evaluate string and build function
>>> print "funcdef=", funcdef
>>> exec funcdef in globals()
>>
>> I think you are looking for closures:
>
> Closures would be a good fit for this if the third-party minimisation
> routine didn't assume that it always receives a function whose formal
> parameters are the variables to be minimised and have the names that
> are intended for display.
Thank you for reading the OP more thoroughly and for taking the time to
explain to those who don't ;)
> This one would work (assuming that we want to minimise over x):
>
>> def make_poly(coeff):
>> def poly(x):
>> return sum(c * x ** n for n, c in enumerate(coeff))
>> return poly
>
> This one won't work:
>
>> def minimize(x, y, dy):
>> def chisq_mn(*args):
>> return chisq(args, x, y, dy)
>> return chisq_mn
>
>>>> def minimize(x, y, dy):
> ... def chisq_mn(*args):
> ... return chisq(args, x, y, dy)
> ... return chisq_mn
> ...
>>>> f = minimize(2, 4, 0.1)
>>>> f.func_code.co_varnames
> ('args',)
>>>> f.func_code.co_argcount
> 0
>
> The OP wants to pass this function to a routine that looks like:
>
> def minimise(func):
> num = func.func_code.co_argcount
> names = func.func_code.co_varnames
> # Actual minimisation code
> return _minimise(func, num, names)
I don't know if the OP may use it, but there seems to be a version of minuit
that allows to override the function signature:
"""
class iminuit.Minuit
Minuit(fcn, throw_nan=False, pedantic=True, frontend=None,
forced_parameters=None, print_level=1, errordef=None, **kwds)
Construct minuit object from given fcn
Arguments:
[...]
forced_parameters: tell Minuit not to do function signature detection and
use this argument instead. (Default None (automagically detect signature)
"""
http://iminuit.github.io/iminuit/api.html
More information about the Tutor
mailing list