>hessian
>...対称行列A と 2次形式F は1対1に対応します。
???
(本日の)ChatGPT先生へ
2次形式Fの行列は、何ですか。
(表示を省略)
上記をQiitaにそのまま貼り付けるmathjaxのソースコードに変換して下さい。一つの全体版でお願いします。math から
(以下、回答を貼り付け)
$$
F(x_1,x_2,\ldots,x_n)
$$
を
$$
F(\mathbf{x})=\mathbf{x}^T A \mathbf{x}
$$
の形に表したときの係数行列 \(A\) のことを、2次形式 \(F\) の行列といいます。
ここで
```math
\mathbf{x}
=
\begin{pmatrix}
x_1\\
x_2\\
\vdots\\
x_n
\end{pmatrix}
です。
例1
2次形式
F(x,y)=3x^2+4xy+5y^2
を考えます。
行列を
A=
\begin{pmatrix}
a & b\\
b & c
\end{pmatrix}
とすると
\begin{aligned}
\mathbf{x}^T A \mathbf{x}
&=
\begin{pmatrix}
x & y
\end{pmatrix}
\begin{pmatrix}
a & b\\
b & c
\end{pmatrix}
\begin{pmatrix}
x\\
y
\end{pmatrix}\\
&=
ax^2+2bxy+cy^2
\end{aligned}
です。
したがって
a=3,\qquad 2b=4,\qquad c=5
より
A=
\begin{pmatrix}
3 & 2\\
2 & 5
\end{pmatrix}
となります。
つまり
F(x,y)
=
\begin{pmatrix}
x&y
\end{pmatrix}
\begin{pmatrix}
3&2\\
2&5
\end{pmatrix}
\begin{pmatrix}
x\\
y
\end{pmatrix}
です。
なぜ交差項を半分にするのか
例えば
A=
\begin{pmatrix}
3&4\\
4&5
\end{pmatrix}
とすると
\mathbf{x}^TA\mathbf{x}
=
3x^2+8xy+5y^2
となります。
なぜなら
4xy+4yx=8xy
だからです。
したがって
xy
の係数が (c) のとき、
行列の対応する成分には
\frac{c}{2}
を入れます。
一般の場合
F(x_1,\ldots,x_n)
=
\sum_{i,j=1}^{n} a_{ij}x_i x_j
は
F(\mathbf{x})
=
\mathbf{x}^T A \mathbf{x}
と書けます。
2次形式の行列は通常
A=A^T
を満たす対称行列として取ります。
3変数の例
F(x,y,z)
=
x^2+4xy+6xz+2y^2+8yz+3z^2
なら
A=
\begin{pmatrix}
1 & 2 & 3\\
2 & 2 & 4\\
3 & 4 & 3
\end{pmatrix}
です。
なぜなら
4xy=2xy+2yx,
6xz=3xz+3zx,
8yz=4yz+4zy
だからです。
まとめ
線形代数では
F(\mathbf{x})=\mathbf{x}^TA\mathbf{x}
の行列 (A) を 2次形式の行列 (matrix of the quadratic form) と呼びます。
対称行列 (A) と2次形式 (F) は1対1に対応します。
上記をsympyで教えて下さい。
from sympy import *
init_printing()
#--------------------------------------------------
# 例1
# F(x,y)=3x^2+4xy+5y^2
#--------------------------------------------------
x, y = symbols('x y')
F = 3*x**2 + 4*x*y + 5*y**2
print("F =")
pprint(F)
# 2次形式の行列
A = Matrix([
[3, 2],
[2, 5]
])
print("\nA =")
pprint(A)
X = Matrix([x, y])
# x^T A x
F2 = (X.T * A * X)[0]
print("\nx^T A x =")
pprint(expand(F2))
print("\nF - x^T A x =")
pprint(simplify(F - F2))
#--------------------------------------------------
# 行列から2次形式を生成
#--------------------------------------------------
print("\n------------------------------")
print("行列 → 2次形式")
print("------------------------------")
a11, a12, a22 = symbols('a11 a12 a22')
Agen = Matrix([
[a11, a12],
[a12, a22]
])
Fgen = expand((X.T*Agen*X)[0])
print("\n一般形:")
pprint(Fgen)
# 結果
# a11*x^2 + 2*a12*x*y + a22*y^2
#--------------------------------------------------
# 3変数の例
#--------------------------------------------------
print("\n------------------------------")
print("3変数")
print("------------------------------")
x, y, z = symbols('x y z')
A3 = Matrix([
[1, 2, 3],
[2, 2, 4],
[3, 4, 3]
])
X3 = Matrix([x, y, z])
F3 = expand((X3.T*A3*X3)[0])
print("\nA3 =")
pprint(A3)
print("\nF3 =")
pprint(F3)
# 得られる結果
# x^2 + 4xy + 6xz + 2y^2 + 8yz + 3z^2
#--------------------------------------------------
# 2次形式から行列を求める
#--------------------------------------------------
print("\n------------------------------")
print("2次形式 → 行列")
print("------------------------------")
F = x**2 + 4*x*y + 6*x*z + 2*y**2 + 8*y*z + 3*z**2
A_from_F = Matrix([
[1, 4/2, 6/2],
[4/2, 2, 8/2],
[6/2, 8/2, 3]
])
print("\nA_from_F =")
pprint(A_from_F)
print("\n確認")
Fcheck = expand((X3.T*A_from_F*X3)[0])
pprint(Fcheck)
print("\nF - Fcheck =")
pprint(simplify(F - Fcheck))
#--------------------------------------------------
# Hessianを利用して自動的に求める
#--------------------------------------------------
print("\n------------------------------")
print("Hessianから求める")
print("------------------------------")
F = x**2 + 4*x*y + 6*x*z + 2*y**2 + 8*y*z + 3*z**2
H = hessian(F, (x, y, z))
print("\nHessian =")
pprint(H)
A = H/2
print("\nA = Hessian / 2")
pprint(A)
print("\n確認")
Fh = expand((X3.T*A*X3)[0])
pprint(Fh)
print("\nF - Fh =")
pprint(simplify(F - Fh))
結果
F =
2 2
3⋅x + 4⋅x⋅y + 5⋅y
A =
⎡3 2⎤
⎢ ⎥
⎣2 5⎦
x^T A x =
2 2
3⋅x + 4⋅x⋅y + 5⋅y
F - x^T A x =
0
------------------------------
行列 → 2次形式
------------------------------
一般形:
2 2
a₁₁⋅x + 2⋅a₁₂⋅x⋅y + a₂₂⋅y
------------------------------
3変数
------------------------------
A3 =
⎡1 2 3⎤
⎢ ⎥
⎢2 2 4⎥
⎢ ⎥
⎣3 4 3⎦
F3 =
2 2 2
x + 4⋅x⋅y + 6⋅x⋅z + 2⋅y + 8⋅y⋅z + 3⋅z
------------------------------
2次形式 → 行列
------------------------------
A_from_F =
⎡ 1 2.0 3.0⎤
⎢ ⎥
⎢2.0 2 4.0⎥
⎢ ⎥
⎣3.0 4.0 3 ⎦
確認
2 2 2
x + 4.0⋅x⋅y + 6.0⋅x⋅z + 2⋅y + 8.0⋅y⋅z + 3⋅z
F - Fcheck =
0
------------------------------
Hessianから求める
------------------------------
Hessian =
⎡2 4 6⎤
⎢ ⎥
⎢4 4 8⎥
⎢ ⎥
⎣6 8 6⎦
A = Hessian / 2
⎡1 2 3⎤
⎢ ⎥
⎢2 2 4⎥
⎢ ⎥
⎣3 4 3⎦
確認
2 2 2
x + 4⋅x⋅y + 6⋅x⋅z + 2⋅y + 8⋅y⋅z + 3⋅z
F - Fh =
0
いつもと違うおすすめです。
wikipedia内
Qiita内
sympy doc
sympy.matrices.dense.hessian (f, varlist, constraints=())