三角関数と逆三角関数

当サイトではアフィリエイトプログラムを利用して商品を紹介しています。

【Python】三角関数

math モジュールの math.sin(x), math.cos(x), math.tan(x) は、それぞれ引数 x の正弦(サイン)余弦 (コサイン)正接(タンジェント) を返します。引数には整数と浮動小数点数を渡せますが、複素数を指定することはできません。
 
math.sin(x), math.cos(x), math.tan(x) は受け取った角度 x をラジアンとして処理します。

# PYTHON_MATH_TRIGONOMETRIC_01

# In[1]

import math

# 円周率を定義
pi = math.pi

val_sin = math.sin(pi/6)
val_cos = math.cos(pi/6)
val_tan = math.tan(pi/6)

print("sin(pi/6) : {}".format(val_sin))
print("cos(pi/6) : {}".format(val_cos))
print("tan(pi/6) : {}".format(val_tan))

# sin(pi/6) : 0.49999999999999994
# cos(pi/6) : 0.8660254037844387
# tan(pi/6) : 0.5773502691896257

math.tan(x) の扱いには注意が必要です。
本来ならば、$\tan(\pi/2)$ は値をもたないはずです:
 \[\lim_{x\rightarrow \pm\pi/2}\tan x=\mp\infty\]
しかし、math.tan(x) に pi/2 を渡すと非常に大きな値を返してきます。

# In[2]

# 円周率を定義
pi = math.pi

val = math.tan(pi/2)

print("tan(pi/2) : {}".format(val))
# tan(pi/2) : 1.633123935319537e+16

引数が pi/2 の整数倍でも同じことが起こります。数値計算では無理数 $\pi$ を有限桁数の近似値で表すので、このように三角関数の計算で若干の誤差を伴います。プログラムの内容によっては、引数に pi/2 の整数倍が渡されたときは浮動小数点数型の inf (無限大) や -inf (負の無限大) を返すような関数を作るなどの工夫が必要になる場合があります。
 
度数法 (degree) で表された角度の三角関数を計算するときには、math.radians() を使って角度をラジアンに変換してから、math.sin(), math.cos(), math.tan() に渡します。

# PYTHON_MATH_TRIGONOMETRIC

# In[1]

import math

# sin60°,cos60°,tan60°を計算
val_sin = math.sin(math.radians(60))
val_cos = math.cos(math.radians(60))
val_tan = math.tan(math.radians(60))

print("sin60°: {}".format(val_sin))
print("cos60°: {}".format(val_cos))
print("tan60°: {}".format(val_tan))

# sin60°: 0.8660254037844386
# cos60°: 0.5000000000000001
# tan60°: 1.7320508075688767

これだと引数の指定の仕方が面倒なので、度数法の角度をそのまま渡せるような関数を作っておくのも1つの方法です。

# In[2]

# degreeで引数を指定する三角関数の定義
def dsin(x):
    return math.sin(math.radians(x))

def dcos(x):
    return math.cos(math.radians(x))

def dtan(x):
    return math.tan(math.radians(x))

print("sin60°: {}".format(dsin(60)))
print("cos60°: {}".format(dcos(60)))
print("tan60°: {}".format(dtan(60)))

# sin60°: 0.8660254037844386
# cos60°: 0.5000000000000001
# tan60°: 1.7320508075688767

【NumPy】三角関数

NumPyを活用した三角関数の計算についても簡単に解説しておきます。numpy.sin(x), numpy.cos(x), numpy.tan(x) は、それぞれ引数 x の正弦(サイン)、余弦(コサイン)、正接(タンジェント)を返します。引数には整数・浮動小数点数の他に、複素数や配列 (ndarray) を渡すことができます。

# NUMPY_TRIGONOMETRIC

# In[1]

import numpy as np
np.set_printoptions(precision=3)

# 円周率を定義
pi = np.pi

x = np.array([pi/4, pi/2, pi])

sin_x = np.sin(x)
cos_x = np.cos(x)
tan_x = np.tan(x)

print("sinx:\n{}".format(sin_x))
print("cosx:\n{}".format(cos_x))
print("tanx:\n{}".format(tan_x))

# sinx:
# [7.071e-01 1.000e+00 1.225e-16]
# cosx:
# [7.071e-01  6.123e-17 -1.000e+00]
# tanx:
# [1.000e+00  1.633e+16 -1.225e-16]

複素数の三角関数の計算例も載せておきます。
複素変数 $z$ の三角関数は次のように定義されています:
 \[\sin z=\frac{e^{iz}-e^{-iz}}{2i},\quad \ \cos z=\frac{e^{iz}+e^{-iz}}{2},\quad \tan z=\frac{\sin z}{\cos z}\] 

# In[2]

# 複素数を要素にもつ配列を用意
z = np.array([1j, 1+1j, 1+2J])

# 配列の各要素の三角関数を計算
sin_z = np.sin(z)
cos_z = np.cos(z)
tan_z = np.tan(z)

print("sinz:\n{}".format(sin_z))
print("cosz:\n{}".format(cos_z))
print("tanz:\n{}".format(tan_z))

# sinz:
# [0.   +1.175j 1.298+0.635j 3.166+1.96j ]
# cosz:
# [1.543-0.j    0.834-0.989j 2.033-3.052j]
# tanz:
# [0.   +0.762j 0.272+1.084j 0.034+1.015j]

三角関数のグラフ

Matplotlib.pyplot を読み込んで三角関数のグラフを描画させるサンプルコードを載せておきます。

# NUMPY_TRIGONOMETRIC_PLOT

# In[1]

import numpy as np
import matplotlib.pyplot as plt

# フィギュアを設定
fig = plt.figure()

# グリッド線を表示
plt.style.use("ggplot")

# グラフ描画領域を追加
ax = fig.add_subplot(111)

# x軸, y軸のラベルを設定
ax.set_xlabel("x", fontsize = 16)
ax.set_ylabel("y", fontsize = 16)

# -2*pi~2*piまでpi/36刻みのデータを用意
x = np.arange(-2*np.pi, 2*np.pi, np.pi/36)

# yのデータを用意
y1 = np.sin(x)
y2 = np.cos(x)

# 三角関数のグラフをプロット
ax.plot(x, y1, label = "y = sinx")
ax.plot(x, y2, label = "y = cosx")

# 凡例は左下に表示
ax.legend(loc = "lower left")

Python 三角関数のグラフ

【SymPy】三角関数

sympy.cos(x), sympy.sin(x), sympy.tan(x) はそれぞれ x の余弦(コサイン)、正弦(サイン)、正接(タンジェント)を返します。

# SYMPY_TRIGONOMETRIC

# In[1]

import sympy

# 記号xを定義
sympy.var('x')

# 円周率
pi = sympy.pi

# f(x) = cosx
func = sympy.cos(x)

print(func.subs(x, pi))
# -1

$\cos x,\ \sin x,\ \tan x$ の逆数をそれぞれ $x$ の正割 (secant)、余割 (cosecant)、余接 (cotangent) とよび、それぞれ $\sec x,\ \csc x,\ \cot x$ という記号で表します:
 \[\sec x=\frac{1}{\cos x},\quad \csc x=\frac{1}{\sin x},\quad \cot x=\frac{1}{\tan x}\]
sympy.sec(x), sympy.csc(x), sympy.cot(x) は、それぞれ x の正割、余割、余接を返します。

# In[2]

# 記号xを定義
x = sympy.Symbol('x')

# 円周率を定義
pi = sympy.pi

f = sympy.sec(x + pi)
g = sympy.csc(x + pi)
h = sympy.cot(x + pi)

print(f)
print(g)
print(h)

# -sec(x)
# -csc(x)
# cot(x)

trigsimp()

sympy.trigsimp() は三角関数の公式を適用して数式を簡略化します。

# SYMPY_TRIGSIMP

# In[1]

from sympy import *
var ("x y")

f = cos(x)**2 + sin(x)**2 + a*sin(x)*cos(x)

# 数式を簡略化
g = trigsimp(f)

print(g)
# a*sin(2*x)/2 + 1

expand_trig()

sympy.expand_trig() は加法定理や倍角公式などを使って三角関数を展開します。

# PYTHON_SYMPY_EXPAND_TRIG

# In[1]

f = sin(x + y) + cos(2*x)

# 加法定理と倍角公式で展開
g = expand_trig(f)

print(g)
# sin(x)*cos(y) + sin(y)*cos(x) + 2*cos(x)**2 - 1

【Python】逆三角関数

math モジュールには逆三角関数を求める関数がいくつか用意されています。
math.asin(x) は引数 x の 逆正弦 $\mathrm{Arcsin}(x)$ をラジアン単位で返します。

# PYTHON_MATH_INVERSE_TRIGONOMETRIC

# In[1]

# Arcsin(0.5)
a = math.asin(0.5)

print(a)
# 0.5235987755982989

math.acos(x) は引数 x の 逆余弦 $\mathrm{Arccos}(x)$ をラジアン単位で返します。

# In[2]

# Arccos(0.5)
b = math.acos(0.5)

print(b)
# 1.0471975511965979

math.atan(x) は引数 x の 逆正接 $\mathrm{Arctan}(x)$ をラジアン単位で返します。

# In[3]

# Arctan(0.5)
c = math.atan(0.5)

print(c)
# 0.4636476090008061

math.atan2(y/x) は原点 O と座標 $(x,y)$ を結ぶ直線が $x$ 軸となす角度を $-\pi$ から $\pi$ の範囲で返します。

# In[4]

# 原点Oと(1,1)を結ぶ直線がx軸となす角度
d = math.atan2(1, 1)

# dを度数法に変換
d_deg = math.degrees(d)

print(d)
print(d_deg)
# 0.7853981633974483
# 45.0

【NumPy】逆三角関数

numpy.arcsin(x), numpy.arccos(x), numpy.arctan(x) は、それぞれ x の逆正弦、逆余弦、逆正接を返すユニバーサル関数です。たとえば、$-1$ から $1$ を一定の幅で刻んだ連続データを渡して、逆三角関数のグラフを描くためのデータを作成できます。

# NUMPY_INVERSE_TRIGONOMETRIC

# In[1]

import numpy as np
import matplotlib.pyplot as plt

# FigureとAxesを設定
fig = plt.figure(figsize = (5, 5))
ax = fig.add_subplot(111)
ax.grid()
ax.set_xlim([-1, 1])
ax.set_ylim([-3, 3])
ax.set_xlabel("x", fontsize = 15)
ax.set_ylabel("y", fontsize = 15)

# xのデータを用意
x = np.linspace(-1, 1, 513)

# yのデータを用意
y1 = np.arcsin(x)
y2 = np.arccos(x)

# データをプロット
ax.plot(x, y1, color = "red", label = "y = Arcsinx")
ax.plot(x, y2, color = "blue", label = "y = Arccosx")

# 凡例は左下に表示
ax.legend(loc = "lower right")

[numpy] arcsin, arccos
numpy.arctan2(x, y) は原点 O と座標 $(x,y)$ を結ぶ直線が $x$ 軸となす角度を $-\pi$ から $\pi$ の範囲で返します。

# In[2]

# 原点Oと(1,1)を結ぶ直線がx軸となす角度
ang = np.arctan2(-1, 1)

# dを度数法に変換
ang_deg = np.rad2deg(ang)

print(ang)
print(ang_deg)
# -0.7853981633974483
# -45.0

コメント

  1. HNaito より:

    下記は誤植と思われますので、ご確認ください。
    # 【math】三角関数の下の文で、浮動小数点を渡せますが → 浮動小数点数を渡せますが

  2. あとりえこばと より:

    【AI連載小説】科学とコードの交差点(27)「三角関数の授業」
     
    夕方、六郷開誠はアルバイト先の家庭教師として、高校生の沙織さんの家に向かっていました。沙織さんは三角関数についての基本を理解したいとのことで、開誠は教材やノートを用意し、しっかりと準備を整えていました。
     
    沙織さんの家に到着すると、開誠は元気な挨拶と笑顔で迎えられました。

    六郷開誠: こんにちは、沙織さん!今日は三角関数の基本についてお話ししましょうね。
     
    沙織: こんにちは、開誠さん!ありがとうございます。三角関数って、ちょっと難しいイメージがあるんですよね。
     
    六郷開誠: そんなことありませんよ。三角関数は実際に使われることが多く、理解すると数学の様々な問題が解けるようになります。まずは基本から見ていきましょう。
     
    開誠はホワイトボードに三角関数の基本的な定義や性質を書きながら、分かりやすく説明していきました。沙織さんも熱心にメモをとりながら、質問があればすぐに質問してくる姿勢が伺えました。

    六郷開誠: 三角関数には主に、sin(サイン)、cos(コサイン)、tan(タンジェント)があります。これらは直角三角形の辺の比率として定義されています。
     
    沙織: なるほど、三角形の辺の比率で表すんですね。じゃあ、それぞれの具体的な定義はどうなんですか?
     
    六郷開誠: よく考えましたね。sinθは対象の角θの対辺と斜辺の比、cosθは隣接の角θの隣接辺と斜辺の比、tanθは対象の角θの対辺と隣接辺の比です。
     
    開誠は具体的な三角関数の定義や三角形の図を描きながら、分かりやすく説明しました。その後、基本的な三角関数の性質や公式についても解説し、例題を解いていく中で理解を深めていくことを目指しました。

    授業が終わり、開誠と沙織はリビングで軽く雑談をしていました。沙織は少し疲れた様子でしたが、開誠は明るい表情で話しかけました。

    六郷開誠: 今日の授業、理解できましたか?三角関数は最初は少し抽象的で難しいかもしれませんが。
     
    沙織: はい、なんとかついていけたと思います。先生の説明、とてもわかりやすかったです。ありがとう。
     
    六郷開誠: それならよかったです。もし質問があれば、何でも聞いてくださいね。

    沙織: そう言ってもらえて安心しました。三角関数、高校のテストでもよく出るんですよね?
     
    六郷開誠: そうですね。三角関数は三角形だけでなく、波や周期的な現象のモデリングなどでも使われます。高校の範囲だけでなく、大学や専門学校でもさらに深く学ぶことができますよ。
     
    沙織: なるほど、いろんなところで使われるんですね。それにしても、先生ってプログラミングも得意なんですか?
     
    六郷開誠: はい、プログラミングも得意です。物理学の研究で数値計算やシミュレーションにもよく使いますし、プログラミングの授業も受け持っています。
     
    沙織: すごいですね。私もプログラミングに興味があるんです。何かオススメの言語はありますか?
     
    六郷開誠: それは素晴らしいですね。プログラミング言語は用途によって違いますが、初心者にはPythonがおすすめです。シンプルで読みやすく、様々な分野で使えますよ。