はじめに
『スタンフォード ベクトル・行列からはじめる最適化数学』の学習ノートです。
「数式の行間埋め」や「Pythonを使っての再現」によって理解を目指します。本と一緒に読んでください。
この記事は3.4節「角度」の内容です。
なす角の定義を確認します。
【前の内容】
【他の内容】
【今回の内容】
なす角の定義
まずは、2つのベクトルのなす角の定義を数式で確認します。
内積については「1.4:内積の性質と計算例【『スタンフォード線形代数入門』のノート】 - からっぽのしょこ」、ユークリッドノルムについては「3.1-2:ユークリッドノルム・ユークリッド距離の性質と計算例【『スタンフォード線形代数入門』のノート】 - からっぽのしょこ」を参照してください。
同じサイズ(次元数)のベクトルのなす角は、次の式で定義されます。
ただし、またはが0ベクトルだと0除算になるため定義できません。
は逆コサイン関数(コサイン関数の逆関数)、はユークリッドノルムです。
は、弧度法における角度であり、ラジアンと呼びます。度数法における角度をで表すと、とは、で変換できます。よって、のときであり、のときです。
逆関数の性質よりなので、定義式を次の式に変形できます。
さらに、両辺にノルムの積を掛けると、「内積」と「ノルムの積」の関係が得られます。
例えば、のときなのでになります。
余弦関数と逆余弦関数
次は、余弦関数(コサイン関数・cosine function)と、余弦関数の逆関数である逆余弦関数(逆コサイン関数・inverse cosine function)をグラフで確認します。
利用するライブラリを読み込みます。
# 利用ライブラリ import numpy as np import matplotlib.pyplot as plt
コサイン関数を計算します。
# 余弦関数の変数(ラジアン)を作成 t_vals = np.linspace(start=-2.0*np.pi, stop=2.0*np.pi, num=500) print(t_vals[:10].round(2)) # 余弦関数を計算 cos_vals = np.cos(t_vals) print(cos_vals[:10].round(2))
[-6.28 -6.26 -6.23 -6.21 -6.18 -6.16 -6.13 -6.11 -6.08 -6.06]
[1. 1. 1. 1. 0.99 0.99 0.99 0.98 0.98 0.97]
コサイン関数の入力変数(ラジアン)を作成して、コサイン関数を計算します。コサイン関数はnp.cos()
で計算できます。
円周率はnp.pi
で扱えます。
コサイン関数のグラフを作成します。
# 軸目盛ラベル用の値を設定 denom = 3.0 n_ticks = np.arange( start=np.floor(t_vals.min() / np.pi * denom), stop=np.ceil(t_vals.max() / np.pi * denom) + 1, step=1) #t_labels = ['$\\frac{' + str(int(n)) + '}{' + str(int(denom)) + '} \pi$' for n in n_ticks] t_labels = ['$' + ('-' if n < 0.0 else '') + '\\frac{' + str(int(abs(n))) + '}{' + str(int(denom)) + '} \pi$' for n in n_ticks] # 余弦関数を作図 fig, ax = plt.subplots(figsize=(8, 6), facecolor='white') ax.plot(t_vals, cos_vals, label='cos t') ax.set_xticks(ticks=n_ticks*np.pi/denom, labels=t_labels) ax.set_xlim(left=t_vals.min(), right=t_vals.max()) ax.grid() ax.set_xlabel('t') ax.set_ylabel('cos t') fig.suptitle('cosine function', fontsize=20) ax.legend() plt.show()
コサイン関数はの値をとります。また、ラジアンが(角度だと)のサイズで周期的に推移します。
続いて、逆コサイン関数を計算します。
# 逆余弦関数の変数(余弦関数の出力)を作成 #u_vals = np.linspace(start=-1.5, stop=1.5, num=500) u_vals = np.sort(np.unique(cos_vals)) print(u_vals[:10].round(2)) # 逆余弦関数を計算 arccos_vals = np.arccos(u_vals) print(arccos_vals[:10].round(2))
[-1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]
[3.14 3.12 3.11 3.1 3.08 3.08 3.07 3.06 3.06 3.05]
逆コサイン関数の入力変数を作成して、逆コサイン関数を計算します。逆コサイン関数はnp.arccos()
で計算できます。
逆コサイン関数のグラフを作成します。
# 軸目盛ラベル用の値を設定 denom = 3.0 n_ticks = np.arange( start=0.0, stop=np.ceil(1.0 * denom) + 1, step=1) t_labels = ['$\\frac{'+str(int(n)) + '}{' + str(int(denom)) + '} \pi$' for n in n_ticks] # 逆余弦関数を作図 fig, ax = plt.subplots(figsize=(8, 6), facecolor='white') ax.plot(u_vals, arccos_vals, label='arccos u') ax.set_yticks(ticks=n_ticks*np.pi/denom, labels=t_labels) ax.grid() ax.set_xlabel('u') ax.set_ylabel('arccos u') fig.suptitle('inverse cosine function', fontsize=20) ax.legend() plt.show()
「逆コサイン関数の入力」は「コサイン関数の出力」、「逆コサイン関数の出力」は「コサイン関数の入力」つまり「ラジアン」に対応します。
よって、入力はの範囲に限られ、出力は(角度だと)の範囲の値をとります。入力が範囲外の場合はnan
になります。
この記事では、なす角の定義式を確認しました。次の記事では、なす角を可視化します。
参考書籍
- Stephen Boyd・Lieven Vandenberghe(著),玉木 徹(訳)『スタンフォード ベクトル・行列からはじめる最適化数学』講談社サイエンティク,2021年.
おわりに
やっぱり内容的に少し薄いんですけど、ラジアンの話とかコサイン関数と逆コサイン関数がとる範囲の話とかを書いておく必要があったので、引用用に記事にしておきます。
【次の内容】