0
度から
度まで
度刻みの振幅に対して、
振り子の周期を計算する。
完全楕円積分であるから、
算術幾何平均(AGM)アルゴリズムを使って計算した
(本当は GSL を呼び出せばよいわけで、半分道楽…いや、
GSL を使わず標準的な関数だけですむのは多少意味があるか?
冪級数展開 (10) を使って計算する方が良いかな?)。
/*
* toujisei.c --- 単振り子の等時性
* T=4√l/g K(k), k=sin θ0/2
* Th=2π√l/g
* http://www.math.meiji.ac.jp/~mk/labo/text/prog/toujisei.c
*/
#include <stdio.h>
#include <math.h>
double pi;
/*
* 算術幾何平均アルゴリズムで完全楕円積分 K(k), E(k) を求める
*/
int kanzen(double k, double *K, double *E)
{
int i;
double a,b,an,bn,cn,anp1,bnp1,cnp1;
double power2, s, AGM;
if (k < 0 || k >= 1) {
fprintf(stderr, "k must be in [0,1)\n");
*K = *E = 0.0;
return 1;
}
a = 1.0; b = sqrt(1.0 - k * k);
an = a; bn = b; cn = sqrt(an * an - bn * bn);
/* s = 2^(n-1) * cn * cn の和 (n=0,1,2,...) */
power2 = 0.5;
s = power2 * cn * cn;
for (i = 0; i <= 10; i++) {
anp1 = (an + bn) / 2; bnp1 = sqrt(an * bn); cnp1 = (an - bn) / 2;
an = anp1; bn = bnp1; cn = cnp1;
/* printf("%20.15f, %20.15f, %20.15f\n", an, bn, cn); */
power2 *= 2;
s += power2 * cn * cn;
if (fabs(an-bn) < 2e-16)
break;
}
if (fabs(an-bn)>1e-15) {
fprintf(stderr,"k=%f: does not converge. i=%d, an=%f, bn=%f, |an-bn|=%e\n",
k, i, an, bn, fabs(an-bn));
return 1;
}
AGM = an;
*K = pi / 2 / AGM;
*E = (a - s) * (*K);
return 0;
}
int main()
{
double theta,k,K,E;
int deg;
pi = 4 * atan(1.0);
for (deg = 0; deg < 180; deg++) {
theta = deg * pi / 180.0;
k = sin(theta / 2);
kanzen(k, &K, &E);
printf("%2d %20.15f\n", deg, 2 * K / pi);
}
return 0;
}
| Mathematica ではこんな感じ |
Plot[2 EllipticK[Sin[t Degree/2]^2] / Pi, {t,0,179}, PlotRange->{0,4}]
|
桂田 祐史