24086


このコードから三角関数表がどうして作られるのかわかりません。  
実行すると確かに三角関数表なのですが、奇っ怪な方法の理由はわかります。  
sinを一度しか呼ばないという制限のためです。  
けれど、その後どうしてこんな方法でと思ったので質問します。

[code]

    static void make_sintbl(int n, float sintbl[])
    {
        int i, n2, n4, n8;
        double c, s, dc, ds, t;
        n2 = n / 2;  n4 = n / 4;  n8 = n / 8;
        t = sin(PI / n);
        dc = 2 * t * t;  ds = sqrt(dc * (2 - dc));
        t = 2 * dc;  c = sintbl[n4] = 1;  s = sintbl[0] = 0;
        for (i = 1; i < n8; i++) {
            c -= dc;  dc += t * c;
            s += ds;  ds -= t * s;
            sintbl[i] = (float)s;
            sintbl[n4 - i] = (float)c;
        }
        if (n8 != 0) sintbl[n8] = (float)sqrt(0.5);
        for (i = 0; i < n4; i++)
            sintbl[n2 - i] = sintbl[i];
        for (i = 0; i < n2 + n4; i++)
            sintbl[i + n2] = - sintbl[i];
    }
    
[/code]

C言語による最新アルゴリズム辞典:奥村晴彦著:技術評論社より  
※ 同書の該当部分に「標本点の数 n は2の整数乗に限る」との記載あり


CC BY-SA 3.0
2016-04-17T03:16:50.680
24079
2016-04-17T12:19:49.887
2016-04-17T09:36:17.960
10455
question
アルゴリズム
このコードから三角関数表がどうして作られるのかわかりません


[ピタゴラスの定理](https://ja.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E9%96%A2%E6%95%B0%E3%81%AE%E5%85%AC%E5%BC%8F%E3%81%AE%E4%B8%80%E8%A6%A7#.E3.83.94.E3.82.BF.E3.82.B4.E3.83.A9.E3.82.B9.E3.81.AE.E5.AE.9A.E7.90.86)や[倍角公式](https://ja.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E9%96%A2%E6%95%B0%E3%81%AE%E5%85%AC%E5%BC%8F%E3%81%AE%E4%B8%80%E8%A6%A7#.E5.80.8D.E8.A7.92.E3.83.BB.E4.B8.89.E5.80.8D.E8.A7.92.E3.83.BB.E5.8D.8A.E8.A7.92.E3.81.AE.E5.85.AC.E5.BC.8F)などを使っているのでは？

例えば`sin2Θ`は`sinΘ`を使って  
[![sin2Θ = 2 sinΘ cosΘ = 2 sinΘ * sqrt\(1 -
\(sinΘ\)^2\)](https://i.stack.imgur.com/b8SjU.png)](https://i.stack.imgur.com/b8SjU.png)  
とできるっぽいです。


CC BY-SA 3.0
2016-04-17T07:40:50.870
24086
2016-04-17T07:40:50.870
4236
24079
answer


ほぼ、sayuri さんの回答に書いてある通りですが、  
`for (i = 1; i < n8; i++) {...}`内部の式は、

[code]

    c == cos(x)
    s == sin(x)
    dc == cos(x)*(1-cos(Δx))+sin(x)*sin(Δx)
    ds == sin(x)*(cos(Δx)-1)+cos(x)*sin(Δx)
    
[/code]

である場合に、計算後は

[code]

    c == cos(x+Δx)
    s == sin(x+Δx)
    //`dc`, `ds`は省略します
    
[/code]

となることが、加法定理などから証明できます。(証明も省略しときます。)  
(もちろん初期値を`x=0`とした時に上記の前提を満たすことも証明できます。ちなみにご質問のコードだと`Δx = 2π/n`にあたります。)

加法定理をもろに使って、`cos(x)*cos(Δx)-sin(x)*sin(Δx)`,
`cos(x)*sin(Δx)+sin(x)*cos(Δx)`などの形の計算をした方がわかりやすいと思うのですが、なぜご質問に記載のような式としているのかまではわかりません。もしかしたら図形的な説明のつく古い公式なのかもしれないと思ったんですが、短時間検索しただけでは由来はわかりませんでした。

なお、最後の`for (i = 0; i < n2 + n4; i++)`の部分は`for (i = 0; i < n2;
i++)`の間違いではないかと思います。(`sin(π+x)==-sin(x)`を使っています。)また、上記の説明が成り立つためには`n8 =
n/8`が整数でありさえすれば良いので、「標本点の数 n
は2の整数乗に限る」条件は厳しすぎで、「nは8の倍数であること」と言う条件さえ成立すれば良いように思われます。(n =
360とすれば、0°〜359°の度数法での三角関数表も作れます。)


CC BY-SA 3.0
2016-04-17T12:07:53.033
24092
2016-04-17T12:19:49.887
2016-04-17T12:19:49.887
13972
13972
24079
answer