Skip Menu |

This queue is for tickets about the Math-BigInt CPAN distribution.

Report information
The Basics
Id: 61139
Status: resolved
Priority: 0/
Queue: Math-BigInt

People
Owner: Nobody in particular
Requestors: calvin.schwenzfeier [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.997
Fixed in: 1.999714



Subject: Bug in Math::BigFloat ->batan() method.
Date: Tue, 7 Sep 2010 11:41:19 -0600
To: bug-Math-BigInt [...] rt.cpan.org
From: Calvin Schwenzfeier <calvin.schwenzfeier [...] gmail.com>
Greetings, Attached is a test file which tickles a bug in the Math::BigFloat ->batan() method. Specifically, the bug manifests when the value (*n*) you are trying to find the arc-tangent of is outside the range -1 ≤ *n* ≤ 1 , but only if the value (*n*) is not an integer (that is, finding the arc-tangent of 2 works; but 2.1 and 1.9 both go off in infinite loops). Looking at the source, it appears there is code to map numbers into the above range and then map them back after the arc-tangent series computation. My guess is one or both of the mapping operations are wrong (haven't taken the time to figure out which). ~Cal P.S.: The values used in the test file came from Wolfram|Alpha (i.e., http://www.wolframalpha.com/input/?i=atan%282.5%29), then rounded to approximately the correct precision. So if values are not exactly matching up, check the last few digits.

Message body is not shown because sender requested not to inline it.

The test seems to stall at #157 on my Win32 laptop, so this might still be a problem.

Message body is not shown because it is too large.

This bug needs to be retitled --- it doesn't let me do so. If it can't be retitled, it needs to be refiled under a more descriptive name. Need title: "Infinite loop in atan function (Math::BigFloat->batan() method)" current title is too vague to describe what is going on or to get attention of a maintainer... Could be worse, might say 'bad thing happens'? ;-)
Sorta kills my ability to use my calc prog for this to get any result. Only workaround is to set do bigfloat in a separate process or maybe thread -- and set a timer. If it doesn't come back in 2-3 seconds, kill it and tell user CPAN module for Math is to buggy to come up with a reply in a reasonable amount of time, so calculation was terminated. Makes it a real pain to even try to do calculations with this lib...
On Thu Jul 19 12:34:34 2012, LAWALSH wrote: Show quoted text
> > current title is too vague to describe what is going on or to get > attention of a maintainer...
I don't know about the other maintaners, but all bugs in this distribution have my attention. The main problem, as I see it, are all the fundamental design flaws in the distributions Math-BigInt, Math-BigRat, Math-BigFloat, and bignum. All basic OO design rules have been thrown overboard for the sake of speed. The distributions are woven together in a terrible mess. Fix one thing, and something else breaks somewhere unexpected. This mess makes it very difficult to fix things properly. Before I start fixing the bugs in this distribution, I want to redesign the internals of the four mentioned distributions to ordinary OO-style programming, so that bugs can be fixed more easily. This is a work in progress that I have not finished yet.
Subject: Math::BigFloat ->batan() infinite loop and accuracy
See a fix for the infinite loop issue in: https://rt.cpan.org/Ticket/Display.html?id=88293#txn-1278395 though it does not fix the accuracy issues here or in 84953. Also, a simple idea from Brent 2006 gives a big speedup (about 30x with Calc, about 100x with GMP). right after the 1/x loop and before the 'no strict 'refs'': my $fmul = 8; $x->bdiv($x->copy->bmul($x)->binc->bsqrt($scale+4)->binc, $scale+4); $x->bdiv($x->copy->bmul($x)->binc->bsqrt($scale+4)->binc, $scale+4); $x->bdiv($x->copy->bmul($x)->binc->bsqrt($scale+4)->binc, $scale+4); then immediately after the 'while (3 < 5)' loop: $x->bmul($fmul); For a more dynamic solution, replace the first part with: my $fmul = 1; foreach my $k (0 .. int($scale/20)) { $fmul *= 2; $x->bdiv($x->copy->bmul($x)->binc->bsqrt($scale+4)->binc,$scale+4); } which gives even more speedup on the example test (with the GMP backend it completes in under 2.5s, with Calc in about 10s, vs. 10 minutes+ without the speedup). I've found the exp reduction works quite well also ( exp(x) = (exp(x/2)^2 ), where we can just accumulate the final exponent as a bigint.
The bigflt_atan.t file included in the original report now works for me with these changes. (1) The values -2.5 to -1.6 and 1.6 to 2.5 have an extra digit so need to be rounded to match the desired accuracy. The value for -1.9 and 1.9 should end with "...1942" rather than ...1943. Use PARI/GP, set \p to 200 or so, call atan and check results when in doubt. (2) In the PI/2 calculation, use "$scale - 2" instead of "$scale - 3". This will fix the incorrect last digit in -1.1 and 1.1, while still passing the full test suite. (3) This part is entirely optional and is really another issue. To finish in a reasonable time, I used this performance change right after the PI/2 and before no strict refs: my $fmul = 1; my $escale = int($scale/20); foreach my $k (1 .. $escale) { $fmul *= 2; $x->bdiv($x->copy->bmul($x)->binc->bsqrt($scale+$escale+2)->binc,$scale+$escale+2); } then after the while (3 < 5) loop: $x->bmul($fmul) if $fmul > 1; This makes the whole test suite (including bigflt_atan.t) reduce from 690s to 17s for me.
Fixed in Math-BigInt v1.999714. Thanks to DANAJ (Dana Jacobsen) for the fix and for the suggestions for speeding up the code. The batan2() method was almost completely rewritten. If it returned a result, the result was often incorrect.