加法定理を使って sin、cos を再帰的に求める 5 / Python で再現する

参考: Interface(インターフェース) 2017年10月号, pp.158-159

import matplotlib.pyplot as plt
import numpy as np

def SinCos(initθ, Δθ):
    # 最初の sin、cos と sinΔθ、cosΔθ だけは組み込み函数を使って普通に計算するが、
    # それ以降は掛け算、足し算、引き算だけで再帰的に sin、cos を順次計算する。
    Δθ = Δθ
    sin0 = np.sin(initθ)
    cos0 = np.cos(initθ)
    sinΔθ = np.sin(Δθ)
    cosΔθ = np.cos(Δθ)
    
    sincos = np.array([0.0, 0.0, sin0, cos0])
    
    def sin_cos():
        adj = 1.5 - 0.5 * (sincos[2]**2.0 + sincos[3]**2.0) # 簡易補正
        #adj = 1.0/np.sqrt(sincos[2]**2.0 + sincos[3]**2.0) # 厳密補正
        sincos[0:2] = sincos[2:4]
        sincos[2:4] = sincos[2] * cosΔθ + sincos[3] * sinΔθ, sincos[3] * cosΔθ - sincos[2] * sinΔθ
        return sincos[0:2] * adj

    return sin_cos



initθ, Δθ = 0, np.pi/(2**3) # 初期値と Δθ はあらかじめ計算しておく。
sincos = SinCos(initθ, Δθ) # 初期値をセットしてクロージャを開いて、
θList = []
sinList = []
cosList = []
for i in range(50):
    sin, cos = sincos() # ディスクローズされた函数を実行し続けて、実行するたびに sin、cos の値を更新する。

    θList.append(i * Δθ)
    sinList.append(sin)
    cosList.append(cos)
    #print("θ: %.2f, sin: %.6f, cos: %.6f, mag: %.16f" % (i*Δθ, sin, cos, np.sqrt(sin**2 + cos**2)))
    #print(i*Δθ, sin, cos, sin**2 + cos**2, sep="\t")

    
plt.plot(θList,sinList,
         θList,cosList)
plt.xlabel("θ")
plt.grid()
plt.show()

実行結果:
f:id:ti-nspire:20180406130611p:plain:w400