/* * 竹内・安藤に載っている計算法を明確化して実装した。 */ #include <iostream> #include <iomanip> #include <cmath> using namespace std; #include "easy_elliptic.hpp" int main(void) { int n, m; double k, kn, kp, a, an, bn, phi, newphi, newa, M, phin, pi, exact, estimate; pi = 4.0 * atan(1.0); cout << setprecision(16); k=0.99; phi=1; exact = F(k, phi); kn=k; kp=sqrt(1-kn*kn); phin=phi; a=1; an=a; bn=kp; for (n = 1; n < 100; n++) { cout << endl << "n=" << n << endl; newa = (an+bn)/2; bn = sqrt(an*bn); an = newa; newphi = phin + atan(kp*tan(phin)); cout << "とりあえずnewphi=" << newphi << ", 2*phi" << (n-1) << "=" << 2*phin << endl; if (abs(newphi - 2 * phin) <= pi / 2) cout << "|newphi-2*phi|=" << abs(newphi - 2 * phin) << "<=pi/2 なのでOK" << endl; else { cout << "少し修正" << endl; m = rint((2 * phin - newphi) / pi); newphi += m * pi; } // 多分不要 while (abs(newphi - 2 * phin) > pi/2) { cout << "小さすぎるので足す" << endl; newphi += pi; cout << "修正newphi=" << newphi << ", 2*phi=" << 2*phi << endl; } kn = (1-kp)/(1+kp); kp = sqrt(1-kn*kn); phin = newphi; estimate = a / an * phin / (1 << n); cout << n << " ステップの近似値=" << estimate << ", 誤差=" << abs(exact-estimate) << endl; if (abs(an-bn) < 1e-15) { cout << "n=" << n << endl; break; } } if (n == 100) cout << "n==" << n << endl; M = an; estimate = a / M * phin / (1 << n); cout << "k=" << k << ", phi=" << phi << endl; cout << "M=" << M << ", phi" << n << "=" << phin << endl; cout << "評価=" << estimate << endl; cout << "boost によると F(k,phi)=" << exact << endl; return 0; }