# asApproximateFraction[AtOrder:]

9 messages
Open this post in threaded view
|

## asApproximateFraction[AtOrder:]

 Hi All,    asApproximateFraction isn't that useful.  It is based on asApproximateFractionAtOrder:, which gives you the best fraction it can find up to order.  e.g.testContinuedFractions self assert: (Float pi asApproximateFractionAtOrder: 1) = (22/7). self assert: (Float pi asApproximateFractionAtOrder: 3) = (355/113) Here's 32-bit Float 1/3:((FloatArray new: 1) at: 1 put: 1/3; at: 1) 0.3333333432674408((FloatArray new: 1) at: 1 put: 1/3; at: 1) asApproximateFraction (11184811/33554432)That's not what I expected :-).  The problem is that asApproximateFractionAtOrder: is great if you know the number you're dealing with, but if you don't then it'll give you too much information.[This value comes up in the vm parameters system report page, where 1/3 is the ratio of growth to heap size above which a full GC is performed, i.e. by default every time a scavenge causes the heap grows by 1/3 from the last time a full GC was performed, the system will do a full GC.  It would be great to report this as 1/3, not 0.33333298563957214, which is what's emerging from the C code in the VM].Let's get a feeling for orders; they're effectively negative powers of 10:(1 to: 20) collect: [:order| | f |{ order. (f := Float pi asApproximateFractionAtOrder: order). f asFloat. (f asFloat - Float pi) abs}]{{1 . (22/7) . 3.142857142857143 . 0.0012644892673496777}. {2 . (333/106) . 3.141509433962264 . 8.32196275291075e-5}. {3 . (355/113) . 3.1415929203539825 . 2.667641894049666e-7}. {4 . (103993/33102) . 3.1415926530119025 . 5.778906242426274e-10}. {5 . (104348/33215) . 3.141592653921421 . 3.3162805834763276e-10}. {6 . (208341/66317) . 3.1415926534674368 . 1.2235634727630895e-10}. {7 . (312689/99532) . 3.1415926536189365 . 2.914335439641036e-11}. {8 . (833719/265381) . 3.141592653581078 . 8.715250743307479e-12}. {9 . (1146408/364913) . 3.141592653591404 . 1.6107115641261771e-12}. {10 . (4272943/1360120) . 3.141592653589389 . 4.04121180963557e-13}. {11 . (5419351/1725033) . 3.1415926535898153 . 2.220446049250313e-14}. {12 . (80143857/25510582) . 3.1415926535897927 . 4.440892098500626e-16}. {13 . (245850922/78256779) . 3.141592653589793 . 0.0}. {14 . (817696623/260280919) . 3.141592653589793 . 0.0}. {15 . (19052873251/6064717916) . 3.141592653589793 . 0.0}. {16 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. {17 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. {18 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. {19 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. {20 . (19870569874/6324998835) . 3.141592653589793 . 0.0}}More useful would be something like:asApproximateFractionToEpsilon: epsilon "Answer a Fraction approximating the receiver. This conversion uses the  continued fraction method to approximate a floating point number." 1 to: 12 do: [:order| | fraction | fraction := self asApproximateFractionAtOrder: order. (fraction - self) abs <= epsilon ifTrue: [^fraction]]. ^ self asApproximateFractionAtOrder: 0and then instead ofasApproximateFraction "Answer a Fraction approximating the receiver. This conversion uses the  continued fraction method to approximate a floating point number." ^ self asApproximateFractionAtOrder: 0one could haveasApproximateFraction "Answer a Fraction approximating the receiver. This conversion uses the  continued fraction method to approximate a floating point number." ^self asApproximateFractionToEpsilon: 1e-6And hence{ 0.0. 0.333. 0.5. 1.0. Float pi . ((FloatArray new: 1) at: 1 put: 1/3; at: 1) } collect:    [:n| n asApproximateFractionToEpsilon: 1e-6]{0 . (333/1000) . (1/2) . 1 . (355/113) . (1/3)}Votes for or against changing asApproximateFraction to use asApproximateFractionToEpsilon:? (asApproximateFraction has no senders into base image)Suggestions for a selector that would use self asApproximateFractionToEpsilon: 1e-6 (less clumsy than e.g. asUsefulApproximateFraction)._,,,^..^,,,_best, Eliot
Open this post in threaded view
|

## Re: asApproximateFraction[AtOrder:]

 Do you normally want your fraction precise to an actual epsilon or to a fraction of the real value? Actually I guess that you could make a % value by working out the integer part, approximating the epsilon from that and using your method, so go for it. Not that I'm a numerics geek by any stretch. > On 23-04-2018, at 1:23 PM, Eliot Miranda <[hidden email]> wrote: > > Hi All, > >     asApproximateFraction isn't that useful.  It is based on asApproximateFractionAtOrder:, which gives you the best fraction it can find up to order.  e.g. > > testContinuedFractions > self assert: (Float pi asApproximateFractionAtOrder: 1) = (22/7). > self assert: (Float pi asApproximateFractionAtOrder: 3) = (355/113) > > Here's 32-bit Float 1/3: > > ((FloatArray new: 1) at: 1 put: 1/3; at: 1) 0.3333333432674408 > > ((FloatArray new: 1) at: 1 put: 1/3; at: 1) asApproximateFraction (11184811/33554432) > > That's not what I expected :-).  The problem is that asApproximateFractionAtOrder: is great if you know the number you're dealing with, but if you don't then it'll give you too much information. > > [This value comes up in the vm parameters system report page, where 1/3 is the ratio of growth to heap size above which a full GC is performed, i.e. by default every time a scavenge causes the heap grows by 1/3 from the last time a full GC was performed, the system will do a full GC.  It would be great to report this as 1/3, not 0.33333298563957214, which is what's emerging from the C code in the VM]. > > Let's get a feeling for orders; they're effectively negative powers of 10: > > (1 to: 20) collect: [:order| | f | > { order. (f := Float pi asApproximateFractionAtOrder: order). f asFloat. (f asFloat - Float pi) abs}] > {{1 . (22/7) . 3.142857142857143 . 0.0012644892673496777}. >  {2 . (333/106) . 3.141509433962264 . 8.32196275291075e-5}. >  {3 . (355/113) . 3.1415929203539825 . 2.667641894049666e-7}. >  {4 . (103993/33102) . 3.1415926530119025 . 5.778906242426274e-10}. >  {5 . (104348/33215) . 3.141592653921421 . 3.3162805834763276e-10}. >  {6 . (208341/66317) . 3.1415926534674368 . 1.2235634727630895e-10}. >  {7 . (312689/99532) . 3.1415926536189365 . 2.914335439641036e-11}. >  {8 . (833719/265381) . 3.141592653581078 . 8.715250743307479e-12}. >  {9 . (1146408/364913) . 3.141592653591404 . 1.6107115641261771e-12}. >  {10 . (4272943/1360120) . 3.141592653589389 . 4.04121180963557e-13}. >  {11 . (5419351/1725033) . 3.1415926535898153 . 2.220446049250313e-14}. >  {12 . (80143857/25510582) . 3.1415926535897927 . 4.440892098500626e-16}. >  {13 . (245850922/78256779) . 3.141592653589793 . 0.0}. >  {14 . (817696623/260280919) . 3.141592653589793 . 0.0}. >  {15 . (19052873251/6064717916) . 3.141592653589793 . 0.0}. >  {16 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. >  {17 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. >  {18 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. >  {19 . (19870569874/6324998835) . 3.141592653589793 . 0.0}. >  {20 . (19870569874/6324998835) . 3.141592653589793 . 0.0}} > > > More useful would be something like: > > asApproximateFractionToEpsilon: epsilon > "Answer a Fraction approximating the receiver. This conversion uses the > continued fraction method to approximate a floating point number." > > 1 to: 12 do: > [:order| | fraction | > fraction := self asApproximateFractionAtOrder: order. > (fraction - self) abs <= epsilon ifTrue: > [^fraction]]. > ^ self asApproximateFractionAtOrder: 0 > > and then instead of > > asApproximateFraction > "Answer a Fraction approximating the receiver. This conversion uses the > continued fraction method to approximate a floating point number." > > ^ self asApproximateFractionAtOrder: 0 > > one could have > > asApproximateFraction > "Answer a Fraction approximating the receiver. This conversion uses the > continued fraction method to approximate a floating point number." > > ^self asApproximateFractionToEpsilon: 1e-6 > > And hence > > { 0.0. 0.333. 0.5. 1.0. Float pi . ((FloatArray new: 1) at: 1 put: 1/3; at: 1) } collect: >     [:n| n asApproximateFractionToEpsilon: 1e-6] > {0 . (333/1000) . (1/2) . 1 . (355/113) . (1/3)} > > Votes for or against changing asApproximateFraction to use asApproximateFractionToEpsilon:? (asApproximateFraction has no senders into base image) > > Suggestions for a selector that would use self asApproximateFractionToEpsilon: 1e-6 (less clumsy than e.g. asUsefulApproximateFraction). > > _,,,^..^,,,_ > best, Eliot > tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/timSpell checkers at maximum!  Fire!
Open this post in threaded view
|

## Re: asApproximateFraction[AtOrder:]

Open this post in threaded view
|

## Re: asApproximateFraction[AtOrder:]

 > On 23-04-2018, at 1:59 PM, Eliot Miranda <[hidden email]> wrote: > > Hi Tim, > > On Mon, Apr 23, 2018 at 1:34 PM, tim Rowledge <[hidden email]> wrote: > Do you normally want your fraction precise to an actual epsilon or to a fraction of the real value? > > Actually I guess that you could make a % value by working out the integer part, approximating the epsilon from that and using your method, so go for it. Not that I'm a numerics geek by any stretch. > >  So you'd rather see > > asApproximateFraction > "Answer a Fraction approximating the receiver. This conversion uses the > continued fraction method to approximate a floating point number." > > ^self asApproximateFractionToEpsilon: self abs / 1.0e6 > > ?   Seems good to me. It's like the difference between wanting to print numbers to X decimal places vs Y significant digits. I think... tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/timMaintenance free: It's impossible to fix.
Open this post in threaded view
|

## Re: asApproximateFraction[AtOrder:]

Open this post in threaded view
|

## Re: asApproximateFraction[AtOrder:]

Open this post in threaded view
|

## Re: asApproximateFraction[AtOrder:]

Open this post in threaded view
|

## Re: asApproximateFraction[AtOrder:]

Open this post in threaded view
|