トップ «前の日記(2006-05-11) 最新 次の日記(2006-05-14)» 月表示 編集

日々の流転


2006-05-13 [長年日記]

λ. Haskellの複素数計算

404 Blog Not Found:%w(Complex Number).reverseで「Pythonやその他のLLに関しては、他の人によるdemoきぼんぬ」とあったので、Haskellでも試してみよう。Haskellではiやeは定義されていないのでまずそれらを定義しておく。

import Complex

i :: RealFloat a => Complex a
i = 0 :+ 1

e :: Floating a => a
e = exp 1

で、ghciで試す。

Main> i
0.0 :+ 1.0
Main> pi
3.141592653589793
Main> e
2.718281828459045
Main> e**(i*pi)
(-1.0) :+ 1.2246063538223773e-16
Main> exp (i*pi)
(-1.0) :+ 1.2246063538223773e-16
Main> log (-1)
NaN
Main> log (-1) :: Complex Double
0.0 :+ (-3.141592653589793)

Haskellには暗黙の型変換は一切ないが、型クラスを用いて定数や演算を多重定義しているため、さほど不便さを感じることはない。それから、log(-1) の結果が他の言語での πi ではなく -πi になってる。これはまあどっちでも良いわけだけど、どうして違ってしまっているかは気になる。

それから、誰かML系の言語でのdemoをきぼんぬ。

……と書いたら速攻でOCaml版が! そして、SML版とGCaml版も。

Cの複素数計算

おまけ。

#include <complex.h>
#include <math.h>
#include <stdio.h>

void cprint(const char* const expr, const double complex x)
{
    printf("%-9s = %g+%gi\n", expr, creal(x), cimag(x));
}

int main(int argc, char** argv)
{
    cprint("pi", M_PI);
    cprint("e", M_E);
    cprint("e**(i*pi)", cpow(M_E, I*M_PI));
    cprint("exp(i*pi)", cexp(I*M_PI));
    cprint("log(-1)", clog(-1));
    return 0;
}

実行結果

pi        = 3.14159+0i
e         = 2.71828+0i
e**(i*pi) = -1+1.22461e-16i
exp(i*pi) = -1+1.22461e-16i
log(-1)   = 0+3.14159i
Tags: haskell

λ. オイラーの式

Matz日記より。

そういや、私もオイラーの等式は「へ〜、そうなんだ。すごいね〜」くらいに思ったことはあるが、それ以上に感動した記憶はない。というか、今でも解析系の話はよく分からないし(汗。そんなわけで、すずきひろのぶさんが「オイラーの業績は、オイラーだけを見てもあんまり意味がなくって、歴史的文脈で読まないとわからない。だから公式を一個をとりあげてすごいとかいう奴は本当の天才か、あるいはインチキがどちらかですよ。」と言っているのを見て、なんだか安心した。