Bug #860
Check impl of RingTwinFloatImpl::myIsRational
Description
Since the old impl of RingTwinFloat::myIsInteger
simply called myIsRational
and then checked that the denominator was 1, and since it seemed to behave strangely sometimes (perhaps needless InsuffPrec
error?), do an optical check of the code to see if it is right.
Perhaps write some documentation about myIsRational
since the code is non-trivial?
Related issues
History
#1 Updated by John Abbott over 8 years ago
- Related to Bug #858: floor for TwinFloat can produce ERR::SERIOUS added
#2 Updated by John Abbott about 8 years ago
- Status changed from New to In Progress
- Assignee set to John Abbott
- % Done changed from 0 to 20
I have just read through the code for RingTwinFloatImpl::myIsRational
and it looks OK to me.
The only dodgy aspect is that floating point rounding errors are not handled rigorously, but since the width of the outer interval is only heuristic, a small numerical error due to rounding is acceptable (and it really does not seem worth complicating the code to make it absolutely correct).
The code could be altered to convert the mpf_t
values into exact (binary) rationals, and then SimplestRatBetween
can be called. Currently I'm undecided whether this would be a good idea; perhaps I'll do some speed tests to see whether there would be any significant difference in speed.
#3 Updated by John Abbott about 8 years ago
I have implemented a variant of myIsRational
which uses SimplestBigRatBetween
. The implementation is certainly much shorter than the current impl.
However a speed test indicates that explicitly reimplementing the algorithm is about 3 times faster when all rationals to be recovered are quite simple (all rationals of the form N/D
with N
and D
coprime and less than some bound -- I used 400 as the bound).
Frankly, I'm astonished. I had expected calling SimplestBigRatBetween
to be just a little slower for such simple fractions (because of the overhead of converting floats to exact rationals). I also expect SimplestBigRatBetween
to be faster when the rationals to be recovered are more complicated (so the internal loop makes more iterations).
Now I'm puzzled.
#4 Updated by John Abbott about 8 years ago
I have just tried a speed test with more complicated rationals (all of the form p1/p2
where p1
and p2
are distinct 10-digit primes). Strangely this was even more favourable for the float approach over calling SimplestBigRatBetween
. I'd better look at the code of SimplestBigRatBetween
, sigh!
NOTE: the times were 2.7s for "float", and 11.2s for SimplestBigRatBetween
-- makes no sense! :-(
#5 Updated by John Abbott about 8 years ago
I have just tried another timing test with a list of about 90000 copies of fibonacci(400)/fibonacci(401)
mapped into RingTwinFloat(280)
.
I measured about 54s using "floats", against 360s using SimplestBigRatBetween
. That's almost a factor of 7 in favour of "floats"... I'm amazed (actually disbelieving).
The source code for SimplestBigRatBetween
looks to be fine: it uses ContFracIter
so ought to avoid any wasteful computation. Time for some tedious profiling... sigh!
#6 Updated by John Abbott about 8 years ago
One possible explanation for ContFracIter
being so slow is that its implementation is "very clean" (e.g. it uses BigRat
values internally). Perhaps once we impl "move operators" the situation will improve (but I'd be amazed to see a factor of 7 improvement).
#7 Updated by John Abbott about 8 years ago
- Description updated (diff)
- Status changed from In Progress to Feedback
- % Done changed from 20 to 90
This has largely been completed; there remains only the mystery as to why SimplestBigRatBetween
is too slow -- this I have put into a new issue: #897.
In RingTwinFloat::myIsRational
uses the faster, direct route; the slower but neater method via SimplestBigRatBetween
is present but excluded via a #if 0 ... #endif
#8 Updated by John Abbott about 8 years ago
- Related to Slug #897: SimplestBigRatBetween: why is it so slow? added
#9 Updated by John Abbott almost 8 years ago
- Status changed from Feedback to Closed
- % Done changed from 90 to 100
#10 Updated by Anna Maria Bigatti about 7 years ago
- Estimated time set to 3.01 h