Eulerフォント / 三角関数の離散系バージョン

結城浩

2005年5月8日

離散系バージョンの関数探し

「ミルカさんの隣で」を書いてから、 LaTeXでEulerフォントで数式を出すのが楽しくなり、 その勢いで今度は 「離散系バージョンの関数探し」という文章を書きました。

Eulerフォント( AMS Euler) というのは、Hermann Zapf(ザフ)がデザインした数式用のフォントです。 『コンピュータの数学』で使われており、同書の著者前書きには、 「ザフの設計の基本方針は, 字の上手な数学者が手書きした場合の数学の薫りをもたせることである.」(p.viii) と書かれています。

確かにEulerフォントは、 全体的に手書きの風合いがあります(たとえば数字のゼロの上がとんがっている)。 このフォントで数式を出力すると、自分が書いたものでも、 まるで偉大な数学者の手によるもののような気分になれます(^_^)

Eulerフォントを使うときのLaTeXの書き方は、たとえばこんな感じです。 途中に \usepackage{euler} と書いてあるのがわかると思います。

\documentclass{jsarticle}
\title{ミルカさんの隣で\footnote{http://www.hyuki.com/story/diffsum.html}}
\author{結城浩\footnote{http://www.hyuki.com/\ Hiroshi Yuki \copyright\ 2005, All rights reserved.}}
\date{2005年5月}
\usepackage{amsmath}
\usepackage{euler}
\begin{document}
\maketitle
    ...
\end{document}

さて、 「ミルカさんの隣で」は連続と離散の話(微分と差分の話)でした。 あの文章にはx^nしか出てきませんでしたが、 ほかの関数についても少し調べてPDFに書いてみました。 ご興味のある方はお読みください。 また、誤りのご指摘、ご意見やご感想もぜひお送りください。

追記

「Hermann Zapfはヘルマン・ツァップと読むはず」というご指摘をいただきましたが、 『コンピュータの数学』では「Hermann Zapf(ザフ)」と表記されていましたので、 それに倣っています。

三角関数の離散系バージョン

以下の文章は、LaTeXのソースになっています。

\documentclass[fleqn]{jsarticle}
\title{三角関数の離散系バージョン}
\author{結城浩\footnote{http://www.hyuki.com/\ Hiroshi Yuki \copyright\ 2005, All rights reserved.}}
\date{2005年5月}
\usepackage{amsmath}
\usepackage{euler}
\begin{document}
% \thispagestyle{empty}
\maketitle
% \tableofcontents

\par
この文章は、
「離散系バージョンの関数探し」\footnote{http://www.hyuki.com/story/diffsum2.html}の続きです。
「離散系バージョンの関数探し」では、
三角関数の離散系バージョンはあまり納得が行かない結果で終わりました。
そこで、級数展開を使って求められないかどうかを調べてみます。

\par
まず、
$\cos x$と$\sin x$の級数展開は次の通りです。

\begin{eqnarray*}
\cos x = + \frac{x^0}{0!} - \frac{x^2}{2!}
         + \frac{x^4}{4!} - \frac{x^8}{8!} + \cdots
    = \sum_{k=0}^{\infty} (-1)^k \frac{x^{2k+0}}{(2k + 0)!}\\
\sin x = + \frac{x^1}{1!} - \frac{x^3}{3!}
         + \frac{x^5}{5!} - \frac{x^7}{7!} + \cdots
    = \sum_{k=0}^{\infty} (-1)^k \frac{x^{2k+1}}{(2k + 1)!}\\
\end{eqnarray*}

\par
$x^n$の部分を機械的に下方階乗冪$x^{\underline{n}}$に書き換えると、次のようになります。

\begin{eqnarray*}
c(x) = + \frac{x^{\underline{0}}}{0!} - \frac{x^{\underline{2}}}{2!}
       + \frac{x^{\underline{4}}}{4!} - \frac{x^{\underline{8}}}{8!} + \cdots
    = \sum_{k=0}^{\infty} (-1)^k \frac{x^{\underline{2k+0}}}{(2k + 0)!}\\
s(x) = + \frac{x^{\underline{1}}}{1!} - \frac{x^{\underline{3}}}{3!}
       + \frac{x^{\underline{5}}}{5!} - \frac{x^{\underline{7}}}{7!} + \cdots
    = \sum_{k=0}^{\infty} (-1)^k \frac{x^{\underline{2k+1}}}{(2k + 1)!}\\
\end{eqnarray*}

\par
項別に差分を取って確かめると、
$c(x)$と$s(x)$は以下の差分方程式を満たします(収束するかどうかの吟味は無視しています)。

\begin{eqnarray*}
\Delta c(x) & = & - s(x) \\
\Delta s(x) & = & c(x) \\
\end{eqnarray*}

うん、これなら三角関数の離散系バージョンがきちんと出るかもしれませんね。
どんな関数なんでしょう。わくわく。
振る舞いを把握するために、具体的な値を計算してみましょう。
はじめの20項までを計算して、$x = 0, 1, 2, ..., 15$のときの$c(x)$と$s(x)$を求めるPerlのプログラムを書きました。

\begin{verbatim}
use strict;
use bignum;

my $maxn = 20;

for my $n (0..15) {
    my $c = &c($n);
    my $s = &s($n);
    printf("%3d %8g %8g\n", $n, $c, $s);
}

sub c {
    my $x = shift;
    my $result = 0;
    for my $k (0..$maxn-1) {
        $result += (-1)**$k * &p($x, 2 * $k + 0) / &factorial(2 * $k + 0);
    }
    return $result;
}

sub s {
    my $x = shift;
    my $result = 0;
    for my $k (0..$maxn-1) {
        $result += (-1)**$k * &p($x, 2 * $k + 1) / &factorial(2 * $k + 1);
    }
    return $result;
}

# ($x - 0)($x - 1)(...)($x - ($n-1))
sub p {
    my ($x, $n) = @_;
    my $result = 1;
    for my $k (0..$n-1) {
        $result *= $x - $k;
    }
    return $result;
}

sub factorial {
    my $n = shift;
    my $result = 1;
    while ($n > 0) {
        $result *= $n;
        $n--;
    }
    return $result;
}
\end{verbatim}

動かしてみたところ、次のようになりました。

\begin{verbatim}
  0        1        0
  1        1        1
  2        0        2
  3       -2        2
  4       -4        0
  5       -4       -4
  6        0       -8
  7        8       -8
  8       16        0
  9       16       16
 10        0       32
 11      -32       32
 12      -64        0
 13      -64      -64
 14        0     -128
 15      128     -128
\end{verbatim}

何と。
「離散系バージョンの関数探し」
の$f(x)$および$g(x)$と同じ結果ではありませんか。
\par
同じ差分方程式でおなじ初期値なのだから、当然なのか…。
くすん。

\newpage
\begin{thebibliography}{9}
\bibitem{diffsum}
    結城浩,
    「ミルカさんの隣で」,
    \verb|http://www.hyuki.com/story/diffsum.html|,
    2005.

\bibitem{diffsum2}
    結城浩,
    「離散系バージョンの関数探し」,
    \verb|http://www.hyuki.com/story/diffsum2.html|,
    2005.

\bibitem{present}
    吉田武,
    『オイラーの贈り物』(p.~216),
    ちくま学芸文庫,
    ISBN4-480-08675-7,
    2001.
\end{thebibliography}
\end{document}

追記

(み)さんから

「三角関数の離散系バージョン」の話ですが,

s0(x) = 0, 1, 1, 0,-1,-1, 0, ... (x=0,1,2,3,4,5,6,...)
s1(x) = 1, 0,-1,-1, 0, 1, 1, ...
s2(x) =-1,-1, 0, 1, 1, 0,-1, ...

というのをたまたま思いつきました. D sin(x) = sin (x + pi/2) に対し,この s0(x) は Delta s0(x) = s0(x + 1) という性質があるので,s0(x) は sin x の離散系バージョンの一つといってよいかと思います.

結城から

なるほど。cos, sinのデュオではなく、 s0, s1, s2のトリオなのですね。 面白いです!

ぴろさんから

三角関数の離散バージョン:

f(0) = 1
g(0) = 0
f(x+1) = (f(x) + g(x)) / sqrt(2)
g(x+1) = (g(x) - f(x)) / sqrt(2)

でどうでしょう?

結城から

なるほど。 確かにこれだと、周期性をもった関数になりますね。 ありがとうございます。 ただ…、これだと「三角関数の微分方程式に対応する差分方程式から導いたよ」 という感覚が薄れてしまうのでちょっと残念です。

ぴろさんから、さらに

    f(x+2) = f(x+1) + g(x+1) = 2g(x)
    g(x+2) = g(x+1) - f(x+1) = -2f(x)
から三角関数の加法定理を使って
    f(x+1)g(1)+g(x+1)f(1) = 2g(x)
    f(x+1)f(1)-g(x+1)g(1) = 2f(x)
ここでf(1)=g(1)とするとf(1)^2+g(1)^2=1からf(1)=g(1)=sqrt(2)で
    f(x+1)=(f(x)+g(x))/sqrt(2)
    g(x+1)=(g(x)-f(x))/sqrt(2)
ということで差分方程式から導いたっぽくないでしょうか?

結城から

うんうん、導いたっぽいですね! (^_^)V

以下、そのほかの方々からのリンクです。

さらにリンクを追記(2005-05-14)