# minimize_constrained works for f(x,y)=x+y but not for f(x,y)=x Anonymous

Hi, need help to understand why minimize_constrained works for f(x, y) = x + y but does not work for f(x, y) = x.

Example:

var('x, y')
f(x, y) = x + y
c(x, y) = 1 - x^2 - y^2
minimize_constrained(f(x, y), [c(x, y)], [0, 0])

edit retag close merge delete

This is a bug, indeed. Comes from using "f.variables()" in minimize_constrained.

Sort by » oldest newest most voted The code of minimize_constrained starts checking if the first argument is a symbolic expression. If this were the case, it gets the variables on which such an expression depends. Then the code generates a function whose argument is a vector, needed for any subsequent computation; each variable of the expression is replaced by a component of the vector. For example, if the expression is x^2+y, the variables are x and y. The code defines a function whose argument is a vector, say p, which yields p^2+p.

When $f(x,y)=x$, the expression f(x,y) has only one variable, which is x, and so the function defined inside minimize_constrained does not depend on a vector with two components, as required, raising errors.

To use minimize_constrained, I would advise to directly define Python functions depending on vectors, either with def or lambda. For example, for $f(x,y)=x+y$, we can write

def f(x): return x + x
def c(x): return 1 - x^2 - x^2


or also

f = lambda x: x + x
c = lambda x: 1 - x^2 - x^2


In both cases, we get:

sage: minimize_constrained(f, c, [0,0])
(-0.7071774954004159, -0.7070360740443554)


Likewise, for $f(x,y)=x$, we have:

sage: f = lambda x: x
sage: c = lambda x: 1 - x^2 - x^2
sage: minimize_constrained(f, c, [0,0])
(-1.0000000049989504, 9.999999987505248e-05)


which is the expected result.

If, for clarity, you prefer to explicitly define functions in terms of x and y, you can still do that:

sage: f = lambda x,y: x
sage: c = lambda x,y: 1 - x^2 - y^2
sage: ff = lambda p: f(*p)
sage: cc = lambda p: c(*p)
sage: minimize_constrained(ff, cc, [0,0])
(-1.0000000049989504, 9.999999987505248e-05)

more

It works. Thank you! But if c is the input of interact, it does not work. I wonder why: var('x,y') @interact def _(f=x, c=1-x^2-y^2): cc = lambda p: c(*p) a=minimize_constrained(f, [cc], [0,0]) print(a)

Because in your code f and c are again symbolic expressions. In a Jupyter notebook, try the following code:

var('x,y')
@interact.options(manual=True, manual_name="Minimize")
def _(f=input_box(default=x+y, label="$f$"),
c=input_box(default=1-x^2-y^2, label="$c$")):
f1 = lambda x,y: float(f.subs(x=x,y=y))
c1 = lambda x,y: float(c.subs(x=x,y=y))
ff = lambda p: f1(*p)
cc = lambda p: c1(*p)
a = minimize_constrained(ff, cc, [0,0])
text = fr"""
The minimum of $f(x,y)={f}$ <br>
subject to ${c}\geq0$ <br> is the point ${a}$
"""
show(html(text))


Every time that you modify $f$ or $c$, the evaluation will take place once you press the Minimize button.

I confirm this doesn't work but you can substitute by

var('x, y, λ')
f(x, y) = x
c(x, y) = 1 - x^2 - y^2
Λ(x,y,λ) = x + λ*c(x,y)
dΛx = diff(Λ(x,y,x),x)
dΛy = diff(Λ(x,y,λ),y)
dΛλ = diff(Λ(x,y,λ),λ)
solve([dΛx==0,dΛy==0,dΛλ==0],(x, y, λ))

more