Skip to content

Instantly share code, notes, and snippets.

@ohno
Last active September 11, 2021 03:23
Show Gist options
  • Save ohno/49c05a68c665b3bd15807f1ae5574483 to your computer and use it in GitHub Desktop.
Save ohno/49c05a68c665b3bd15807f1ae5574483 to your computer and use it in GitHub Desktop.
LinearAlgebra.jl Tutorial
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# LinearAlgebra.jl\n",
"\n",
"Juliaでは簡単に行列の固有値を求めることができる. このノートでは 斎藤正彦『線型代数入門』(1966, 東京大学出版会) の問題を題材として, 固有値ソルバの簡単なベンチマークテストを行った.\n",
"\n",
"© 2021 Shuhei Ohno\n",
"<br>Source: https://gist.github.com/ohno\n",
"<br>License: https://opensource.org/licenses/MIT"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Julia Version 1.6.2\n",
"Commit 1b93d53fc4 (2021-07-14 15:36 UTC)\n",
"Platform Info:\n",
" OS: Windows (x86_64-w64-mingw32)\n",
" CPU: Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz\n",
" WORD_SIZE: 64\n",
" LIBM: libopenlibm\n",
" LLVM: libLLVM-11.0.1 (ORCJIT, haswell)\n"
]
}
],
"source": [
"versioninfo()\n",
"using LinearAlgebra"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ベンチマーク\n",
"\n",
"[斎藤正彦『線型代数入門』(1966, 東京大学出版会)]( http://www.utp.or.jp/book/b302039.html) より, 第5章の問題1をベンチマークとする. 対角形の各対角成分は元の行列の固有値である.\n",
"\n",
"<table>\n",
" <tr>\n",
" <th>問題1</th>\n",
" <th>行列</th>\n",
" <th>対角形</th>\n",
" </tr>\n",
" <tr>\n",
" <td>イ)</td>\n",
" <td>\n",
" \\begin{pmatrix}\n",
" -4 & 0 & 6 \\\\\n",
" -3 & 2 & 3 \\\\\n",
" -3 & 0 & 5 \\\\\n",
" \\end{pmatrix}\n",
" </td>\n",
" <td>\n",
" \\begin{pmatrix}\n",
" 2 & 0 & 0 \\\\\n",
" 0 & 2 & 0 \\\\\n",
" 0 & 0 & -1 \\\\\n",
" \\end{pmatrix}\n",
" </td>\n",
" </tr>\n",
" <tr>\n",
" <td>ロ)</td>\n",
" <td>\n",
" \\begin{pmatrix}\n",
" 1 & 0 & -2 \\\\\n",
" 2 & -1 & -2 \\\\\n",
" -2 & 2 & 0 \\\\\n",
" \\end{pmatrix}\n",
" </td>\n",
" <td>\n",
" \\begin{pmatrix}\n",
" 1 & 0 & 0 \\\\\n",
" 0 & -1 & 0 \\\\\n",
" 0 & 0 & 0 \\\\\n",
" \\end{pmatrix}\n",
" </td>\n",
" </tr>\n",
" <tr>\n",
" <td>ハ)</td>\n",
" <td>\n",
" \\begin{pmatrix}\n",
" -3 & -2 & -2 & 1 \\\\\n",
" 2 & 3 & 2 & 0 \\\\\n",
" 3 & 1 & 2 & -1 \\\\\n",
" -4 & -2 & -2 & 2 \\\\\n",
" \\end{pmatrix}\n",
" </td>\n",
" <td>\n",
" \\begin{pmatrix}\n",
" 0 & 0 & 0 & 0 \\\\\n",
" 0 & 2 & 0 & 0 \\\\\n",
" 0 & 0 & 1 & 0 \\\\\n",
" 0 & 0 & 0 & 1 \\\\\n",
" \\end{pmatrix}\n",
" </td>\n",
" </tr>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 行列の宣言\n",
"\n",
"行列は次のように宣言する."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3 Matrix{Int64}:\n",
" -4 0 6\n",
" -3 2 3\n",
" -3 0 5"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"A = [-4 0 6;\n",
" -3 2 3;\n",
" -3 0 5]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3 Matrix{Int64}:\n",
" 1 0 -2\n",
" 2 -1 -2\n",
" -2 2 0"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"B = [ 1 0 -2;\n",
" 2 -1 -2;\n",
" -2 2 0]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4×4 Matrix{Int64}:\n",
" -3 -2 -2 1\n",
" 2 3 2 0\n",
" 3 1 2 -1\n",
" -4 -2 -2 2"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"C = [-3 -2 -2 1;\n",
" 2 3 2 0;\n",
" 3 1 2 -1;\n",
" -4 -2 -2 2]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 固有値\n",
"\n",
"事前に`using LinearAlgebra`を宣言しておく必要がある. 行列を`eigvals()`に渡すことで固有を格納した配列が得られる. なお, `eigvals()`は固有値を小さいから順に求めるため, 対角形の順序とは異なる. また, Juliaに限らず, コンピュータで実数を扱うことは不可能なので, 代わりに[浮動小数点数](https://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0)が採用される. そのため`-1`が`-0.999999999999998`となったり, `0`が`-2.539596429704816e-15`となったりする. 前述のベンチマークに矛盾しない結果が得られている."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3-element Vector{Float64}:\n",
" -1.0\n",
" 2.0\n",
" 2.0"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigvals(A)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3-element Vector{Float64}:\n",
" -0.999999999999998\n",
" -2.539596429704816e-15\n",
" 1.0000000000000024"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigvals(B)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4-element Vector{Float64}:\n",
" 4.440892098500626e-15\n",
" 0.9999999999999977\n",
" 0.9999999999999997\n",
" 1.9999999999999996"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigvals(C)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 固有ベクトル\n",
"\n",
"固有値は`eigvec()`で求められる. "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3 Matrix{Float64}:\n",
" -0.816497 0.0 -0.707107\n",
" -0.408248 1.0 0.0\n",
" -0.408248 0.0 -0.707107"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigvecs(A)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3 Matrix{Float64}:\n",
" -0.666667 0.666667 -0.707107\n",
" -0.333333 0.666667 -0.707107\n",
" -0.666667 0.333333 3.66027e-16"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigvecs(B)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4×4 Matrix{Float64}:\n",
" -0.57735 0.235702 0.0116258 -0.408248\n",
" -8.46545e-16 0.471405 -0.712657 0.816497\n",
" 0.57735 -0.707107 0.701031 -1.46869e-15\n",
" -0.57735 0.471405 0.0232516 -0.408248"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigvecs(C)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 固有値と固有ベクトルを同時に求める\n",
"\n",
"`eigen()`に行列を渡すと, 固有値と固有ベクトルを同時に求める. 固有値と固有ベクトルの配列はそれぞれ`values`と`vectors`の名前が付けられており, 個別に取り出すこともできる."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}\n",
"values:\n",
"3-element Vector{Float64}:\n",
" -1.0\n",
" 2.0\n",
" 2.0\n",
"vectors:\n",
"3×3 Matrix{Float64}:\n",
" -0.816497 0.0 -0.707107\n",
" -0.408248 1.0 0.0\n",
" -0.408248 0.0 -0.707107"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigen(A)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3-element Vector{Float64}:\n",
" -1.0\n",
" 2.0\n",
" 2.0"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigen(A).values"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3×3 Matrix{Float64}:\n",
" -0.816497 0.0 -0.707107\n",
" -0.408248 1.0 0.0\n",
" -0.408248 0.0 -0.707107"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eigen(A).vectors"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 参考文献\n",
"- [斎藤 正彦『線型代数入門』(1966, 東京大学出版会)]( http://www.utp.or.jp/book/b302039.html) \n",
"- https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.2",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment