At least in the case of fmin_slsqp (and probably most of the other
optimizers) the attributes returned when full_output=True are things
that are being calculated anyway. There really shouldn't be much
penalty in terms of speed. I agree that keeping the old call
signatures in a deprecated mode would be a good idea, though I admit I
don't really like the idea of changing the function names away from
fmin_xxxx. Perhaps we keep the current function definitions and only
the full_output argument becomes deprecated?
On Wed, Mar 10, 2010 at 12:32 AM, <josef.pktd@gmail.com> wrote:
> On Tue, Mar 9, 2010 at 11:54 PM, <josef.pktd@gmail.com> wrote:
>> On Tue, Mar 9, 2010 at 10:37 PM, Rob Falck <robfalck@gmail.com> wrote:
>>> Returning an object would be my preference as well, it seems more
>>> pythonic. Most optimizers should be able to return at a minimum
>>>>>> result.x
>>> result.objfun
>>> result.iterations
>>> result.exit_status
>>>>>> Some optimizers have other useful data to return, such as the Lagrange
>>> multiplers from slsqp. Going down that path means probably breaking
>>> current implementations of the optimizers, but doing it right would be
>>> worth it, in my opinion. We should also agree upon names for the
>>> common attributes.
>>>> If we create new functions, as David argued, then the old signature
>> could still be kept.
>>>> I was curious what the increase in call overhead is, and for an
>> essentially empty function it would be up to 60%. However, since this
>> is mainly for functions that do heavier work, this will not be really
>> relevant. (It might add a little bit to my Monte Carlos or bootstrap,
>> but this should be negligible), and we will gain if we don't have to
>> redo some calculations.
>>>> The main reason I liked the full output option instead of always
>> returning a result instance, is that, if full_output is true, then
>> additional results can be calculated, that I don't want when I just
>> need a fast minimal result.
>> something like this might work, without any undesired calculations and
> any break in current API, and return type is independent of
> "full_output" flag. (short of going to a class with lazy evaluation)
>> def function2a():
> '''current function'''
> return np.arange(5)
>> new:
>> def function5a(full_output=True):
> '''current function rewritten to return Store'''
> result = Store()
> result.a = np.arange(5)
> if full_output:
> #results that require additional memory or additional calculations
> result.b = function0()
> return result
>> def function5():
> '''replacement for current function'''
> result = function5a(full_output=False)
> return result.a
>>> The extra calculations might not apply for many functions, but I have
> some in statsmodels for which I could also switch to this kind of
> pattern instead of making the return type conditional on a keyword.
>> Josef
--
- Rob Falck