Karim Belabas on Sun, 08 Oct 2017 10:39:34 +0200


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: a(n+1) = log(1+a(n))


* Karim Belabas [2017-10-08 10:35]:
> * Elim Qiu [2017-10-08 05:44]:
> > I'm study the behavior of   n(n a(n) -2) / log(n)
> > where a(1) > 0, a(n+1) = log(1+a(n))
> > 
> > Using Pari:
> > 
> > f(n) =
> > { my(v = 2);
> >   for(k=1,n, v = log(1+v));
> >   return(n*(n*v -2) / (log(n)));
> > }
> > 
> > It turns out the program runs very slowly. The same logic in python runs
> > 100 time faster but not have the accuracy I need.
> > 
> > Any ideas?
> 
> You are hit by PARI's "poor man's interval arithmetic" (always compute
> as correctly as the input allows). This works :
> 
>   g(n) =
>   { my(v = 2, one = 1.0);
>     for(k=1,n, v = log(1+v) * one);
>     return(n*(n*v -2) / (log(n)));
>   }
> 
>   (10:25) gp > g(10^6)
>   time = 2,376 ms.
>   %1 = 0.51488946924922388659082316377748262728
> 
> The reason why your original function is very slow is that, since v << 1,
> 1 + v has more bits of accuracy than v . So that the internal accuracy
> increases quickly during your loop, slowing down the computation
> immensely. Multiplying by 1.0 (at the original accuracy), I restore the
> accuracy we expected.
[...]
> P.S. It is true that log(1+v) should *lose* some accuracy since 1+v is
> close to 1, but we are more conservative when reducing accuracy than
> when increasing it. The net "gain" is 1 more word of accuracy per loop
> iteration...

N.B. the "simpler" v = log(one + v) is a little faster but less
accurate, due to loss of accuracy in the log [ cf. P.S. above ].
The proposed solution is stabler.

Cheers,

    K.B.
--
Karim Belabas, IMB (UMR 5251)  Tel: (+33) (0)5 40 00 26 17
Universite de Bordeaux         Fax: (+33) (0)5 40 00 21 23
351, cours de la Liberation    http://www.math.u-bordeaux.fr/~kbelabas/
F-33405 Talence (France)       http://pari.math.u-bordeaux.fr/  [PARI/GP]
`