Project

General

Profile

Bug #860

Check impl of RingTwinFloatImpl::myIsRational

Added by John Abbott over 8 years ago. Updated about 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Safety
Start date:
30 Mar 2016
Due date:
% Done:

100%

Estimated time:
3.01 h
Spent time:

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

Related to CoCoALib - Bug #858: floor for TwinFloat can produce ERR::SERIOUSClosed2016-03-26

Related to CoCoALib - Slug #897: SimplestBigRatBetween: why is it so slow?Closed2016-06-25

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

Also available in: Atom PDF