# Revision history [back]

Thanks @DSM. I've tried to generalize your solution with the following:

def get3(fn, constraint_nums, x0, iobj=0):
"""
Constrained mimimization of a function that is output, along with constraint equations, from function fn.

Arguments:
fn - function that returns a tuple containing objective function and constraint equations

constraint_nums - tuple or list containing index positions of constraint equations in fn output

x0 - initial guess

iobj - index position of object function in fn output.  default = 0
"""

a = minimize_constrained(lambda x,j=iobj: fn(x)[j],
[lambda x,j=i: fn(x)[j] for i in constraint_nums],
x0)
return a


running get3(func_wrap,range(1,5),[2,3]) results in the correct (45.0, 6.25). I had some trouble with the list comprehension of the lambda functions for the constraints. If I used [lambda x: fn(x)[i] for i in constraint_nums] then the [i] wasn't hardcoded in and each of my lambda equations had a parameter i in them; the list comphehension looped through the i's meaning all the lambda functions were the same with i equal to the final i such that only my last constraint equation was used. [lambda x,j=i: fn(x)[j] for i in constraint_nums] seems to work.

Two further questions: 1.Is there a way to determine the number of values returned by a function without actually evaluating the function? If there was I could further generalise get3 by giving constraint_nums a default value. 2. What actually gets cached when I use FunctionCached? Is everything in the function stored or just the output values? When should I be using fn.clear_cache()?