我想推断几个变量的二阶多项式的最小值/最大值。变量本身可以是不可微的函数或其他任何函数,因此,分析问题的一种好方法是找到合适的二次形式并分析关联的矩阵是否是(正)(半)定的。
我可以手动执行此操作,并通过对结果调用expand来验证我是否正确代数。以下示例:
import sympy as s
s.init_printing(use_unicode=False,use_latex=False)
x,y,a,b,c,d,e,f = s.symbols("x y a b c d e f")
p1 = a*x*x + 2*b*x*y + c*y*y + d*x + e*y + f
display(p1)
# First deal with cross terms by manual completion of squares and check for no mistakes...
p2 = a*(x+(b/a)*y)**2 - (b*y)**2/a + c*y*y + d*x + e*y + f
assert s.simplify(p1-p2) == 0
# Eliminate cross term by substitution
t = s.Symbol("t")
p3 = p2.subs(x,t-(b/a)*y).expand().collect(y)
display(p3)
# Manual completion of squares again
p4 = a*(t+(d/2/a))**2 - (d/2)**2/a + f + (c-b**2/a)* ( y + (e-b*d/a)/2/(c-b**2/a))**2 - ((e-b*d/a)/2)**2/(c-b**2/a)
assert s.simplify(p3-p4) == 0
display(p4)
上面的代码给出输出:
2 2
a*x + 2*b*x*y + c*y + d*x + e*y + f
/ 2\
2 2 | b | / b*d\
a*t + d*t + f + y *|c - --| + y*|e - ---|
\ a / \ a /
2 2
/ e b*d\ /e b*d\
2 / 2\ | - - ---| |- - ---| 2
/ d \ | b | | 2 2*a| \2 2*a/ d
a*|t + ---| + f + |c - --|*|y + -------| - ---------- - ---
\ 2*a/ \ a / | 2| 2 4*a
| b | b
| c - --| c - --
\ a / a
手动读取结果,可以看到a>0
和c-b*b/a >0
的形式最小。通过查看二次表达式,我可以看到t
和y
的哪些值最小。我可以替代找到我的x
。
现在的问题是:如何使用sympy自动执行此操作?在我的具体示例中,我还有更多的用语,并且可能会沿途弄乱一些系数...