三角関数#
三角比#
直角三角形は、内角\(\theta\)の値を固定するとすべて相似な形となるため、\(x/r\)や\(y/r\)などの辺の長さ同士の比は一定になる。
Show code cell source
import numpy as np
import matplotlib.pyplot as plt
base = [0, 0]
x = [2, 0]
r = [2, 1]
fig, ax = plt.subplots(figsize=[4,3])
ax.plot([base[0], x[0]], [base[1], x[1]], label=r"$x$", color="steelblue")
ax.text(x=(x[0] - x[1])/2, y=x[1]+0.01, s=r"$x$", color="steelblue")
ax.plot([base[0], r[0]], [base[1], r[1]], label=r"$r$", color="green")
ax.text(x=1, y=0.5, s=r"$r$", color="green", ha="right")
ax.plot([x[0], r[0]], [x[1], r[1]], label=r"$y$", color="orange")
ax.text(x=x[0]-0.02, y=(r[1]-x[1])/2, s=r"$y$", color="orange", ha="right")
ax.legend()
fig.show()
この値を三角比と呼び、角度\(\theta\)の値によって決まるものとなる。
三角関数#
三角比の定義では、直角三角形の内角となりうる\(0^\circ\)から\(90^\circ\)の間の値しかとれないが、それ以外の値もとれるように定義を拡張したものが三角関数である。
\(r=1\)の場合、\(\sin \theta = \frac{y}{1} = y, \cos \theta = \frac{x}{1} = x\)となり扱いやすい。これを利用して、半径1、中心が原点の円(単位円)の円周上の点、\(x\)軸の正の向きからの角度が\(\theta\)の点の\(y\)座標を\(\sin \theta\)、\(x\)座標を\(\cos \theta\)と定義する。
Show code cell source
theta = (np.arange(0, 360) * np.pi / 180)
y = np.sin(theta)
x = np.cos(theta)
# base
fig, ax = plt.subplots(figsize=[4, 4])
ax.plot(x, y)
ax.axhline(0, color="gray")
ax.axvline(0, color="gray")
# line
theta = (120 * np.pi / 180)
y = np.sin(theta)
x = np.cos(theta)
ax.plot([0, x], [0, y], color="darkorange")
ax.text(x - 0.1, y + 0.1, r"($\cos \theta, \sin \theta$)", color="darkorange", ha="center")
fig.show()
Show code cell source
fig, ax = plt.subplots(figsize=[6,2])
width = 2 * np.pi
x = np.linspace(-width, width, 100)
ax.plot(x, np.sin(x), label=r"$\sin x$")
ax.plot(x, np.cos(x), label=r"$\cos x$")
ax.axhline(0, color="gray", alpha=0.5)
step_size = np.pi / 2
ticks = np.arange(-width, width + step_size, step_size) # 0から2πまでπ/2刻み
tick_labels = [r"-2$\pi$", r"-$\frac{3\pi}{2}$", r"-$\pi$", r"-$\frac{\pi}{2}$", r"$0$", r"$\frac{\pi}{2}$", r"$\pi$", r"$\frac{3\pi}{2}$", r"$2\pi$"]
ax.set_xticks(ticks)
ax.set_xticklabels(tick_labels)
ax.grid(True)
ax.legend()
fig.show()
Show code cell source
fig, ax = plt.subplots(figsize=[6,2])
r = np.array([0, 0.5, 1, 1.5, 2])
r = (-r).tolist() + r.tolist()
ticks = [c * np.pi for c in r]
x = np.linspace(-6.5, 6.5, 100)
ax.plot(x, np.tan(x), label=r"$\tan x$")
ax.set(xticks=ticks)
ax.grid(True)
ax.legend()
fig.show()
逆三角関数#
三角関数の逆関数のことを逆三角関数という。
Show code cell source
fig, ax = plt.subplots(figsize=[2,3])
x = np.linspace(-np.pi, np.pi, 100)
ax.plot(np.sin(x), x, label=r"$x = \sin y$")
ax.plot(np.cos(x), x, label=r"$x = \cos y$")
ax.legend()
fig.show()
例:内積から角度を取り出す#
で、ここで\(\theta\)はラジアンであり、コサイン類似度\(\cos \theta = 0\)のときは\(\theta = \arccos \theta= \frac{\pi}{2} \approx 1.571\)
ラジアンを度(degree)に戻すには\(degree = \theta \times (180 / \pi)\)
Show code cell source
a = np.array([0, 1])
b = np.array([1, 0])
fig, ax = plt.subplots()
ax.plot([0, a[0]], [0, a[1]], color="steelblue")
ax.plot([0, b[0]], [0, b[1]], color="steelblue")
ax.text(a[0] * 1.01, a[1] * 1.01, f"a={a}", color="steelblue")
ax.text(b[0] * 1.01, b[1] * 1.01, f"b={b}", color="steelblue")
cos_theta = (a @ b) / (np.linalg.norm(a) * np.linalg.norm(b)) # cos θ
theta = np.arccos(cos_theta)
degree = theta * (180 / np.pi)
ax.set(xlabel="x", ylabel="y", title=fr"$\cos \theta$ = {cos_theta:.1f}, $\theta= arccos \theta = ${theta:.3f}, degree={degree:.0f}")
fig.show()
Note
内積やコサイン類似度との関係 三角比の定義式
の両辺に\(r\)を掛けると、
となる。
2つのベクトル\(a, b\)のなす角度を\(\theta\)とすると、内積\(\boldsymbol{a} \cdot \boldsymbol{b}\)は
と定義される。
Show code cell source
a = np.array([4, 2])
b = np.array([1, 2])
fig, ax = plt.subplots()
ax.plot([0, a[0]], [0, a[1]], color="steelblue")
ax.plot([0, b[0]], [0, b[1]], color="steelblue")
ax.text(a[0] * 1.01, a[1] * 1.01, f"a={a}", color="steelblue")
ax.text(b[0] * 1.01, b[1] * 1.01, f"b={b}", color="steelblue")
b_ = ((np.linalg.norm(b) / np.linalg.norm(a)) * a).astype(int)
ax.plot([0, b_[0]], [0, b_[1]], color="darkorange")
ax.plot([b[0], b_[0]], [b[1], b_[1]], color="darkorange", linestyle=":")
ax.text(1.5, 1.5, "|b| sin θ", color="dimgray")
ax.text(b_[0] * 1.07, b_[1] * 0.95, f"b'={b_}", color="darkorange")
ax.text(*(b_ * 0.5), "|b| cos θ ?", color="dimgray")
fig.show()
bからaへ垂線をたらして射影したものの長さは\(||b|| \sin \theta\)となる。これは単位円における\(y = r \sin \theta\)に相当する(ノルム\(||b||\)はベクトルの長さのため)
同様に\(x = r \cos \theta\)から\(y = ||b|| \cos \theta\)となる
はずだが…?
cos_theta = (a @ b) / (np.linalg.norm(a) * np.linalg.norm(b)) # cos θ
b_length = np.linalg.norm(b) * cos_theta # |b| cos θ
print(b_length, np.linalg.norm(b_)) ## 一致しない
1.7888543819998315 2.23606797749979
cos_theta = (a @ b) / (np.linalg.norm(a) * np.linalg.norm(b)) # cos θ
theta = np.arccos(cos_theta)
b_length = np.linalg.norm(b) * np.sin(theta) # |b| sin θ
print(b_length, np.linalg.norm(b - b_)) ## 一致しない
1.3416407864998743 1.4142135623730951
三角関数の基本的性質#
性質1
一般に \(f(-x)=-f(x)\) となる関数を 奇関数、 \(f(-x)=f(x)\) となる関数を 偶関数 という。
\(\sin x, \tan x\) は奇関数, \(\cos x\) は偶関数である
性質2(相互関係)
三平方の定理より\(x^2 + y^2 = r^2\)なので
性質3 (加法定理)
性質4(2倍角の公式)