A co jako? Rychle konvergujících řad je spousta. Mimoto ten algoritmus používá sqrt což je iracionální funkce takže sama o sobě se musí počítat iterací. No a že ten algoritmus naprosto zbytečně alokuje 300 double hodnot, když mu ve skutečnosti stačí tři, o tom už bych vůbec pomlčel.
Zkus tuhle verzi:
double Ellip_Integral(double k)
{
double a = 1.0;
double b = sqrt(1-k*k);
while ((a-b)/2 >= ERR_SMALL) {
double tmp = a;
a = (tmp+b)/2;
b = sqrt(tmp*b);
}
return PI/(2.0*a);
}
Nebo ekvivalent v Erlangu, což je takový malý důkaz že imperativní programování způsobuje trvalé poškození mozku. To vysvětluje, že se někdo může rozplývat nad špatně implementovaným algoritmem.
-define(?ERR_SMALL, 1.0e-15).
ellip_integral(K) when K > = 0, K < 1 ->
ellip(1.0, math:sqrt(1.0-K*K)).
ellip(A, B) when (A-B)/2 < ?ERR_SMALL -> math:pi()/(A+B);
ellip(A, B) -> ellip((A+B)/2, math:sqrt(A*B)).
No a nakonec bych asi skončil u něčeho takového i v C, protože každý trochu slušný kompilátor mi z toho vygeneruje stejně efektivní kód jako kdybych tam měl ten matoucí cyklus.
double ellip(double a, b) {
if ((a-b)/2 < ERR_SMALL) {
return PI/(a+b);
} else {
return ellip((a+b)/2, sqrt(a*b));
}
}
double Ellip_Integral(double k) {
return ellip(1.0, sqrt(1-k*k));
}