以下に、diagonalize2d.py のソースコードを解析し、Sphinx(MyST)でビルド可能なMarkdownドキュメントを作成します。

# diagonalize2d.py

## 概要

``diagonalize2d.py`` は、2x2の実数行列の対角化を可視化するPythonスクリプトです。

## 詳細説明

このスクリプトは以下の機能を提供します。

1.  元の基底ベクトル (``a1``, ``a2``) と、それらの行列 ``S`` による像 (``S a1``, ``S a2``) を描画します。
2.  2x2の実数行列 ``S`` の固有値と固有ベクトルを計算します。
3.  行列が実数上で対角化可能でない場合、メッセージを表示して終了します。
4.  行列が実数上で対角化可能である場合、実固有ベクトル (``v1``, ``v2``) と、それらの像 (``S v1``, ``S v2``) を描画します。
5.  対角化前後の基底ベクトル間の角度を出力します。

**解釈:**

*   ``S`` が対称行列の場合、対角化基底は直交するので、角度は90度を保ちます。
*   ``S`` が非対称であるが実数上で対角化可能な場合、対角化基底は一般に直交しません。
*   複素固有値が現れる場合、実数の主軸基底は存在しません。

## 前提条件

*   Python 3がインストールされていること。
*   以下の非標準ライブラリがインストールされていること。

## 必要な非標準ライブラリ

*   ``numpy`` (数値計算ライブラリ)
*   ``matplotlib`` (グラフ描画ライブラリ)

## インストール方法

必要なライブラリは ``pip`` を使用してインストールできます。

```bash
pip install numpy matplotlib

使い方

コマンドライン引数

diagonalize2d.py は以下のコマンドライン引数を取ります。

  • S11 (必須, float): 2x2行列 S の1行1列目の成分。

  • S12 (必須, float): 2x2行列 S の1行2列目の成分。

  • S21 (必須, float): 2x2行列 S の2行1列目の成分。

  • S22 (必須, float): 2x2行列 S の2行2列目の成分。

  • --save FILENAME (オプション, str): 出力する図のファイル名。デフォルトは diagonalize2d.png です。

実行例

行列 S = [[1, 2], [3, 4]] の対角化を可視化し、結果を output.png という名前で保存する場合:

python diagonalize2d.py 1 2 3 4 --save output.png

入力

入力は、コマンドライン引数として与えられる4つの浮動小数点数です。これらが S11, S12, S21, S22 として、以下の2x2行列 S を構成します。

S = \begin{pmatrix} S_{11} & S_{12} \\ S_{21} & S_{22} \end{pmatrix}

出力

標準出力:

スクリプトは以下の情報を標準出力に出力します。

  • 入力された行列 S

  • 元の基底ベクトル (a1, a2) の情報とそれらのなす角度。

  • 元の基底ベクトルに行列 S を作用させた像 (S a1, S a2) と、それぞれが元のベクトルと平行であるかどうかの判定結果。

  • 行列 S が実数上で対角化可能であるかの判定結果とメッセージ。

  • 行列 S が対称行列であるかの判定結果。

  • 実数上で対角化可能な場合:

    • 固有値 (lambda1, lambda2) と対応する正規化された固有ベクトル (v1, v2) およびその角度。

    • 元の基底と対角化基底のなす角度の比較と、対称性に関するコメント。

    • 対角化された行列 P^{-1} S P の結果。

  • 実数上で対角化不可能な場合:

    • 計算された固有値(複素数を含む場合がある)。

  • 図の保存先ファイル名。

画像ファイル:

Matplotlibによって生成された図が、--save オプションで指定されたファイル名(デフォルトは diagonalize2d.png)で保存されます。

  • 実数上で対角化可能な場合、図は2つのサブプロットで構成されます。

    • 左側: 元の基底ベクトル (a1, a2) とそれらの像 (S a1, S a2)。

    • 右側: 実固有ベクトル (v1, v2) とそれらの像 (S v1, S v2)。

  • 実数上で対角化不可能な場合、図は1つのサブプロットで構成され、元の基底ベクトル (a1, a2) とそれらの像 (S a1, S a2) を表示します。

関数リファレンス

unit(v: numpy.ndarray) -> numpy.ndarray

  • 概要: 与えられたベクトルを単位ベクトルに正規化します。

  • 詳細説明: ベクトルのL2ノルムが非常に小さい(EPS 以下)場合、ゼロベクトルとみなし ValueError を発生させます。 EPS の値はコード内で 1e-10 と定義されています。

  • 引数:

    • v (numpy.ndarray): 正規化する2Dベクトル。

  • 戻り値:

    • (numpy.ndarray): 正規化された単位ベクトル。

  • 発生しうるエラー:

    • ValueError: ゼロベクトルを正規化しようとした場合。

angle_deg(v: numpy.ndarray) -> float

  • 概要: 2Dベクトルが+X軸となす角度を度数で計算します。

  • 詳細説明: 角度の範囲は (-180, 180] 度となります。math.atan2 を使用して計算されます。

  • 引数:

    • v (numpy.ndarray): 角度を計算する2Dベクトル。

  • 戻り値:

    • (float): +X軸となす角度(度数)。

angle_between_deg(v1: numpy.ndarray, v2: numpy.ndarray) -> float

  • 概要: 2つの2Dベクトル間の最小角度を度数で計算します。

  • 詳細説明: 計算される角度の範囲は [0, 180] 度となります。内積とアークコサインを用いて計算されます。 入力ベクトルは最初に unit() 関数で正規化されます。

  • 引数:

    • v1 (numpy.ndarray): 1つ目の2Dベクトル。

    • v2 (numpy.ndarray): 2つ目の2Dベクトル。

  • 戻り値:

    • (float): 2つのベクトル間の最小角度(度数)。

is_parallel(v1: numpy.ndarray, v2: numpy.ndarray, tol: float = 1e-9) -> bool

  • 概要: 2つの2Dベクトルが平行であるかをチェックします。

  • 詳細説明: 2Dベクトル (x1, y1)(x2, y2) が平行である場合、x1*y2 - y1*x2 (2D外積のZ成分) は0になります。 この値が指定された許容誤差 tol よりも小さい絶対値であれば、平行とみなします。

  • 引数:

    • v1 (numpy.ndarray): 1つ目の2Dベクトル。

    • v2 (numpy.ndarray): 2つ目の2Dベクトル。

    • tol (float, オプション): 平行とみなすための許容誤差。デフォルトは 1e-9 です。

  • 戻り値:

    • (bool): 2つのベクトルが平行であれば True、そうでなければ False

classify_real_diagonalizable(S: numpy.ndarray)

  • 概要: 2x2行列が実数上で対角化可能であるかを判定します。

  • 詳細説明: 行列 S の固有値と固有ベクトルを計算し、以下の条件で対角化可能性を判定します。

    1. 固有値が複素数を含む場合、実数上で対角化不可能。

    2. 実数固有値のみの場合でも、固有ベクトルが線形独立でない場合、実数上で対角化不可能。 それ以外の場合は、実数上で対角化可能と判定します。

  • 引数:

    • S (numpy.ndarray): 判定対象の2x2実数行列。

  • 戻り値:

    • (tuple): 以下の要素を持つタプルを返します。

      • diagonalizable_over_R (bool): 実数上で対角化可能であれば True、そうでなければ False

      • message (str): 対角化可能性に関する説明メッセージ。

      • eigenvalues (numpy.ndarray): 計算された固有値。複素数を含む場合があります。

      • eigenvectors (numpy.ndarray): 計算された固有ベクトル。複素数を含む場合があります。

sort_eigensystem(vals: numpy.ndarray, vecs: numpy.ndarray)

  • 概要: 固有値と固有ベクトルをソートし、表示用に正規化します。

  • 詳細説明: 固有値を昇順にソートし、それに対応するように固有ベクトルの順序も変更します。 さらに、各固有ベクトルの最初の非ゼロ成分が正になるように符号を調整し、表示を統一します。 この符号調整は、ベクトルの v[0]EPS より大きい絶対値を持つ場合は v[0] の符号を、そうでない場合は v[1] の符号を確認して行われます。

  • 引数:

    • vals (numpy.ndarray): ソート対象の固有値。

    • vecs (numpy.ndarray): ソート対象の固有ベクトル(各列が1つの固有ベクトル)。

  • 戻り値:

    • (tuple): 以下の要素を持つタプルを返します。

      • vals (numpy.ndarray): ソートされ、符号調整後の固有値。

      • vecs (numpy.ndarray): ソートされ、符号調整後の固有ベクトル。

plot_vectors(ax, basis_vectors, image_vectors, basis_labels, image_labels, title)

  • 概要: 指定された軸上に基底ベクトルとそれらの像を描画します。

  • 詳細説明: プロットの軸範囲は自動的に調整され、全てのベクトルが見えるように設定されます。 基底ベクトルは黒い実線矢印、像ベクトルは赤い実線矢印で表示されます。 軸の目盛り、ラベル、タイトルは非表示になり、グリッドと枠線も描画されません。 title パラメータはコード内ではコメントアウトされており、使用されていません。

  • 引数:

    • ax (Matplotlib Axes オブジェクト): 描画対象のMatplotlib Axesオブジェクト。

    • basis_vectors (list of numpy.ndarray): 基底ベクトルのリスト。

    • image_vectors (list of numpy.ndarray): 基底ベクトルの像のリスト。

    • basis_labels (list of str): 基底ベクトルのラベルのリスト。

    • image_labels (list of str): 像ベクトルのラベルのリスト。

    • title (str): プロットのタイトル(コード内では使用されていません)。

  • 戻り値: なし。

main()

  • 概要: 2x2実数行列の対角化を可視化し、結果を出力するメイン関数です。

  • 詳細説明: コマンドライン引数から行列の要素を受け取り、以下の処理を実行します。

    1. 元の基底ベクトルとその像を計算し、角度情報と共に表示します。

    2. 行列が実数上で対角化可能かを判定し、その結果と理由を表示します。

    3. 行列が対称であるかを判定します。

    4. 実数上で対角化可能であれば、固有値と正規化された固有ベクトルを計算・表示し、 元の基底と固有ベクトルによる対角化基底の角度を比較します。 さらに、対角化された行列 P^{-1} S P を表示します。

    5. 結果を2つのサブプロット(元の基底と対角化基底)または1つのサブプロット(対角化不可能時)に描画し、 指定されたファイル名で保存して表示します。

  • 引数: なし。

  • 戻り値: なし。

変更履歴

コードからは確認できません。

ライセンス

コードからは確認できません。