Я хочу рассуждать о минимуме / максимуме многочленов второй степени от нескольких переменных. Сами переменные могут быть недифференцируемыми функциями или чем-то еще, поэтому хороший способ проанализировать проблему - найти подходящую квадратичную форму и проанализировать, является ли ассоциированная матрица (положительной) (полу) -определенной.
Я могу сделать это вручную и убедиться, что правильно выполнил алгебру, вызвав расширение для моего результата. Пример этого ниже:
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? В моем конкретном примере у меня есть еще много терминов, и, вероятно, я буду путать некоторые коэффициенты по пути ...