Last active
September 11, 2021 03:23
-
-
Save ohno/49c05a68c665b3bd15807f1ae5574483 to your computer and use it in GitHub Desktop.
LinearAlgebra.jl Tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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