<div dir="ltr">Hi Tim,<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 23, 2018 at 1:34 PM, tim Rowledge <span dir="ltr"><<a href="mailto:tim@rowledge.org" target="_blank">tim@rowledge.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Do you normally want your fraction precise to an actual epsilon or to a fraction of the real value?<br>
<br>
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.<br></blockquote><div><br></div><div> So you'd rather see</div><div><br></div><div><div style="color:rgb(0,0,0);font-size:12.800000190734863px">asApproximateFraction</div><div style="color:rgb(0,0,0);font-size:12.800000190734863px"><span class="gmail-m_-125616276763996881gmail-Apple-tab-span" style="white-space:pre-wrap">     </span>"Answer a Fraction approximating the receiver. This conversion uses the </div><div style="color:rgb(0,0,0);font-size:12.800000190734863px"><span class="gmail-m_-125616276763996881gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>continued fraction method to approximate a floating point number."</div><div style="color:rgb(0,0,0);font-size:12.800000190734863px"><br></div><div style="color:rgb(0,0,0);font-size:12.800000190734863px"><span class="gmail-m_-125616276763996881gmail-Apple-tab-span" style="white-space:pre-wrap">   </span>^self asApproximateFractionToEpsilon<wbr>: self abs / 1.0e6</div></div><div style="color:rgb(0,0,0);font-size:12.800000190734863px"><br></div><div style="color:rgb(0,0,0);font-size:12.800000190734863px">?  Seems to work well:</div><div style="color:rgb(0,0,0);font-size:12.800000190734863px"><br></div><div style="color:rgb(0,0,0);font-size:12.800000190734863px"><div><br></div><div><div>| them |</div><div>them := (1 to: 6) collect: [:po10| (1 / ((10 raisedTo: po10) * 3)) asFloat].</div><div>them collect: [:fraction| fraction asApproximateFractionToEpsilon: fraction / 1.0e6] {(1/30) . (1/300) . (1/3000) . (1/30000) . (1/300000) . (1/3000000)}</div><div><br></div><div>| them |</div><div>them := (1 to: 6) collect: [:po10| (1 / ((10 raisedTo: po10) / 3)) asFloat].</div><div>them collect: [:fraction| fraction asApproximateFractionToEpsilon: fraction / 1.0e6]</div><div> {(3/10) . (3/100) . (3/1000) . (3/10000) . (3/100000) . (3/1000000)}</div><div><br></div><div>Float classPool associations</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>select: [:assoc| assoc value isFloat and: [assoc value isFinite and: [assoc value fractionPart ~= 0]]]</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>thenCollect: [:assoc|</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>assoc key -> (assoc value asApproximateFractionToEpsilon: assoc value / 1.0e6)] {#Ln2->(1143/1649) . #Halfpi->(355/226) . #ThreePi->(1065/113) . #RadiansPerDegree->(71/4068) . #Epsilon->(1/1000000000000) . #MaxValLn->(16325/23) . #Ln10->(624/271) . #Pi->(355/113) . #Sqrt2->(1393/985) . #Twopi->(710/113) . #E->(1264/465)}</div></div></div><div> </div><div><br></div><div>So I'm for</div><div><br></div><div>asApproximateFraction<br>       "Answer a Fraction approximating the receiver. This conversion uses the <br>       continued fraction method to approximate a floating point number."<br> <br>       ^self asApproximateFractionToEpsilon<wbr>: (self / 1e6) abs<br></div><div><br></div><div>talking in numerical analysis ignorance...</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div class="gmail-h5"><br>
> On 23-04-2018, at 1:23 PM, Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>> wrote:<br>
> <br>
> Hi All,<br>
> <br>
>     asApproximateFraction isn't that useful.  It is based on asApproximateFractionAtOrder:, which gives you the best fraction it can find up to order.  e.g.<br>
> <br>
> testContinuedFractions<br>
>       self assert: (Float pi asApproximateFractionAtOrder: 1) = (22/7).<br>
>       self assert: (Float pi asApproximateFractionAtOrder: 3) = (355/113)<br>
>       <br>
> Here's 32-bit Float 1/3:<br>
> <br>
> ((FloatArray new: 1) at: 1 put: 1/3; at: 1) 0.3333333432674408<br>
> <br>
> ((FloatArray new: 1) at: 1 put: 1/3; at: 1) asApproximateFraction (11184811/33554432)<br>
> <br>
> 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.<br>
> <br>
> [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].<br>
> <br>
> Let's get a feeling for orders; they're effectively negative powers of 10:<br>
> <br>
> (1 to: 20) collect: [:order| | f |<br>
> { order. (f := Float pi asApproximateFractionAtOrder: order). f asFloat. (f asFloat - Float pi) abs}]<br>
> {{1 . (22/7) . 3.142857142857143 . 0.0012644892673496777}.<br>
>  {2 . (333/106) . 3.141509433962264 . 8.32196275291075e-5}.<br>
>  {3 . (355/113) . 3.1415929203539825 . 2.667641894049666e-7}.<br>
>  {4 . (103993/33102) . 3.1415926530119025 . 5.778906242426274e-10}.<br>
>  {5 . (104348/33215) . 3.141592653921421 . 3.3162805834763276e-10}.<br>
>  {6 . (208341/66317) . 3.1415926534674368 . 1.2235634727630895e-10}.<br>
>  {7 . (312689/99532) . 3.1415926536189365 . 2.914335439641036e-11}.<br>
>  {8 . (833719/265381) . 3.141592653581078 . 8.715250743307479e-12}.<br>
>  {9 . (1146408/364913) . 3.141592653591404 . 1.6107115641261771e-12}.<br>
>  {10 . (4272943/1360120) . 3.141592653589389 . 4.04121180963557e-13}.<br>
>  {11 . (5419351/1725033) . 3.1415926535898153 . 2.220446049250313e-14}.<br>
>  {12 . (80143857/25510582) . 3.1415926535897927 . 4.440892098500626e-16}.<br>
>  {13 . (245850922/78256779) . 3.141592653589793 . 0.0}.<br>
>  {14 . (817696623/260280919) . 3.141592653589793 . 0.0}.<br>
>  {15 . (19052873251/6064717916) . 3.141592653589793 . 0.0}.<br>
>  {16 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.<br>
>  {17 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.<br>
>  {18 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.<br>
>  {19 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.<br>
>  {20 . (19870569874/6324998835) . 3.141592653589793 . 0.0}}<br>
> <br>
> <br>
> More useful would be something like:<br>
> <br>
> asApproximateFractionToEpsilon<wbr>: epsilon<br>
>       "Answer a Fraction approximating the receiver. This conversion uses the <br>
>       continued fraction method to approximate a floating point number."<br>
> <br>
>       1 to: 12 do:<br>
>               [:order| | fraction |<br>
>                fraction := self asApproximateFractionAtOrder: order.<br>
>                (fraction - self) abs <= epsilon ifTrue:<br>
>                       [^fraction]].<br>
>       ^ self asApproximateFractionAtOrder: 0<br>
> <br>
> and then instead of<br>
> <br>
> asApproximateFraction<br>
>       "Answer a Fraction approximating the receiver. This conversion uses the <br>
>       continued fraction method to approximate a floating point number."<br>
> <br>
>       ^ self asApproximateFractionAtOrder: 0<br>
> <br>
> one could have<br>
> <br>
> asApproximateFraction<br>
>       "Answer a Fraction approximating the receiver. This conversion uses the <br>
>       continued fraction method to approximate a floating point number."<br>
> <br>
>       ^self asApproximateFractionToEpsilon<wbr>: 1e-6<br>
> <br>
> And hence<br>
> <br>
> { 0.0. 0.333. 0.5. 1.0. Float pi . ((FloatArray new: 1) at: 1 put: 1/3; at: 1) } collect:<br>
>     [:n| n asApproximateFractionToEpsilon<wbr>: 1e-6]<br>
> {0 . (333/1000) . (1/2) . 1 . (355/113) . (1/3)}<br>
> <br>
> Votes for or against changing asApproximateFraction to use asApproximateFractionToEpsilon<wbr>:? (asApproximateFraction has no senders into base image)<br>
> <br>
> Suggestions for a selector that would use self asApproximateFractionToEpsilon<wbr>: 1e-6 (less clumsy than e.g. asUsefulApproximateFraction).<br>
> <br>
> _,,,^..^,,,_<br>
> best, Eliot<br>
> <br>
<br>
<br>
</div></div>tim<br>
--<br>
tim Rowledge; <a href="mailto:tim@rowledge.org">tim@rowledge.org</a>; <a href="http://www.rowledge.org/tim" rel="noreferrer" target="_blank">http://www.rowledge.org/tim</a><br>
Spell checkers at maximum!  Fire!<br>
<br>
<br>
<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>