I was looking for a way to maximize a function subject to constraints
but didn't find any, so I wrote it myself (based on an example on
http://www.sagenb.org/home/pub/353/):
def lagrange_multipliers(f, g, varx):
n = len(g)
lmb = [var("lambda_%d" % i) for i in range(n)]
L = f
for i in range(n):
L += lmb[i]*g[i]
sol = solve(L.gradient(varx+lmb), varx+lmb)
return sol
This function takes an expression 'f', a list of expressions
'g' (constraints) and a list of variables 'varx'. Example (solves
http://en.wikipedia.org/wiki/Lagrange_multipliers#Simple_example):
sage: var("x,y")
sage: lagrange_multipliers(x^2*y, [x^2+y^2-3], [x,y])
[[x == 0, y == sqrt(3), lambda_0 == 0], [x == 0, y == -sqrt(3),
lambda_0 == 0], [x == sqrt(2), y == 1, lambda_0 == -1], [x == sqrt(2),
y == -1, lambda_0 == 1], [x == -sqrt(2), y == 1, lambda_0 == -1], [x
== -sqrt(2), y == -1, lambda_0 == 1]]
or, in the notebook, using show() (sorry if there's any encoding
problem):
[[x=0,y=√3,λ₀=0],[x=0,y=−√3,λ₀=0],[x=√2,y=1,λ₀=(−1)],[x=√2,y=
(−1),λ₀=1],[x=−√2,y=1,λ₀=(−1)],[x=−√2,y=(−1),λ₀=1]]
displaying nice lambdas with subscripts.
It should also work for several constraints:
sage: lagrange_multipliers(x^2+y^2+z^2, [x+y-2, x-z-3], [x,y,z])
[[x == 0, y == 0, z == 0, lambda_0 == 0, lambda_1 == 0]]
TO DO (maybe):
* Remove the lambdas from the result, or add an option to remove them
(they're not part of the solution).
* Show the values of f at the solutions, and find the solution with
greater/less value.
* Rename the function.