Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.ruby > #4288 > unrolled thread

Re: Math cube root

Started bySergey Avseyev <sergey.avseyev@gmail.com>
First post2011-05-11 14:45 -0500
Last post2011-05-14 13:12 -0500
Articles 11 — 9 participants

Back to article view | Back to comp.lang.ruby

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Math cube root Sergey Avseyev <sergey.avseyev@gmail.com> - 2011-05-11 14:45 -0500
    Re: Math cube root Jeremy Bopp <jeremy@bopp.net> - 2011-05-11 15:06 -0500
    Re: Math cube root Josef 'Jupp' Schugt <jupp@gmx.de> - 2011-05-12 07:25 -0500
      Re: Math cube root serialhex <serialhex@gmail.com> - 2011-05-12 08:54 -0500
        Re: Math cube root Colin Bartlett <colinb2r@googlemail.com> - 2011-05-12 10:26 -0500
          Re: Math cube root Josh Cheek <josh.cheek@gmail.com> - 2011-05-12 13:30 -0500
            Re: Math cube root serialhex <serialhex@gmail.com> - 2011-05-12 13:46 -0500
            Re: Math cube root Rob Biedenharn <Rob@AgileConsultingLLC.com> - 2011-05-12 13:53 -0500
              Re: Math cube root jzakiya <jzakiya@gmail.com> - 2011-05-12 13:20 -0700
                Re: Math cube root serialhex <serialhex@gmail.com> - 2011-05-12 15:36 -0500
            Re: Math cube root Martin DeMello <martindemello@gmail.com> - 2011-05-14 13:12 -0500

#4288 — Re: Math cube root

FromSergey Avseyev <sergey.avseyev@gmail.com>
Date2011-05-11 14:45 -0500
SubjectRe: Math cube root
Message-ID<dbc7278d5a23fce616550d07283c1da1@ruby-forum.com>
How can you explain this:

    $ irb
    1.9.2p180 (main):001:0> 1000 ** (1.0/3)
    9.999999999999998
    1.9.2p180 (main):002:0> Math.sqrt(100)
    10.0

-- 
Posted via http://www.ruby-forum.com/.

[toc] | [next] | [standalone]


#4290

FromJeremy Bopp <jeremy@bopp.net>
Date2011-05-11 15:06 -0500
Message-ID<4DCAEC4C.6080900@bopp.net>
In reply to#4288
On 5/11/2011 14:45, Sergey Avseyev wrote:
> How can you explain this:
> 
>     $ irb
>     1.9.2p180 (main):001:0> 1000 ** (1.0/3)
>     9.999999999999998
>     1.9.2p180 (main):002:0> Math.sqrt(100)
>     10.0

You're using floating point arithmetic which is always inexact.  The
1.0/3 part cannot be represented with infinite precision, so it's
basically rounded at a certain point.  The result is then used for the
rest of the operation, which may compound the inaccuracy introduced by
the initial rounding.

If you must use floating point operations, be prepared to accept results
that are only *close* to what you expect, where close is largely
dependent on the operations being performed.

http://en.wikipedia.org/wiki/Floating_point

-Jeremy

[toc] | [prev] | [next] | [standalone]


#4349

FromJosef 'Jupp' Schugt <jupp@gmx.de>
Date2011-05-12 07:25 -0500
Message-ID<op.vvdbgayy6p3xzb@pen2>
In reply to#4288
On Wed, 11 May 2011 21:45:42 +0200, Sergey Avseyev  
<sergey.avseyev@gmail.com> wrote:

> How can you explain this:
>
>     $ irb
>     1.9.2p180 (main):001:0> 1000 ** (1.0/3)
>     9.999999999999998
>     1.9.2p180 (main):002:0> Math.sqrt(100)
>     10.0

Floating-point numbers have a finite precision. As a result, the outcome  
of a numerical (computer) calculation usually differs from the outcome of  
the mathematical calculation. Assume you only can operate with integers  
and want to compute the square root of 133. You may then end up with  
either 11 (11² = 121) or 12 (12² = 144) while the actual result is  
approximately 11.5 (11.5² = 121 + 11 + 0.25 = 132.25; more precisely  
11.5325625947).

You may like to use formatted output of numbers that suppresses digits  
beyond the actual precision:

jupp@pen2:~ $ irb
irb(main):001:0> "%.15f" % 1000 ** (1.0/3)
=> "9.999999999999998"
irb(main):002:0> "%.14f" % 1000 ** (1.0/3)
=> "10.00000000000000"

The above example turns the numerical value into a string displaying a  
fractional part with 15 and 14 digits, respectively. Assuming that IEEE  
754 double precision floating point numbers (i.e. those used by Ruby) have  
a precision of a little less than 16 (decimal) digits it is safe to assume  
that the complexity of operation you perform results in a value that is  
precise to a little less than 15 digits - which means that you can assume  
14 digits to be correct. By chance it MAY be precise to more digits as it  
is the case for Math.sqrt(100) - but that is nothing you can rely on  
unless you learn some gory details of numerical mathematics.

HTH

[toc] | [prev] | [next] | [standalone]


#4362

Fromserialhex <serialhex@gmail.com>
Date2011-05-12 08:54 -0500
Message-ID<BANLkTinHrposaNZY0WqEitvAGEYOL-o=SQ@mail.gmail.com>
In reply to#4349
[Note:  parts of this message were removed to make it a legal post.]

On Thu, May 12, 2011 at 8:25 AM, Josef 'Jupp' Schugt <jupp@gmx.de> wrote:

> On Wed, 11 May 2011 21:45:42 +0200, Sergey Avseyev <
> sergey.avseyev@gmail.com> wrote:
>
>  How can you explain this:
>>
>>    $ irb
>>    1.9.2p180 (main):001:0> 1000 ** (1.0/3)
>>    9.999999999999998
>>    1.9.2p180 (main):002:0> Math.sqrt(100)
>>    10.0
>
>
instead of using floats you can try to use rational numbers in ruby:

ruby-1.9.2-p180 :001 > require 'mathn'
 => true
ruby-1.9.2-p180 :002 > 1000 ** (1.0/3)
 => 9.999999999999998
ruby-1.9.2-p180 :003 > 1000 ** (1/3)
 => 10
ruby-1.9.2-p180 :004 > 1.0/3
 => 0.3333333333333333
ruby-1.9.2-p180 :005 > 1/3
 => (1/3)

you need to require 'mathn' which will change integer division (and make all
the numbers play nicely together) but other than that things will work
better. the only down side to this whole thing is that rationals are slower
than floats (probably significantly so) because it is a pair of integers.
 and some values when you look at them wont seem to make sense as a
rational, like PI:

ruby-1.9.2-p180 :011 > Math::PI
 => 3.141592653589793
ruby-1.9.2-p180 :012 > Math::PI.to_r
 => (884279719003555/281474976710656)

you can always num.to_f back but that also takes time.  one last thing: if
your inputs are floats i'm not sure there is a nice way to convert them to
rationals:

ruby-1.9.2-p180 :016 > (1.0/3).to_r
 => (6004799503160661/18014398509481984)
ruby-1.9.2-p180 :017 > 1/3
 => (1/3)

so this entire e-mail may be moot :P
hex

[toc] | [prev] | [next] | [standalone]


#4380

FromColin Bartlett <colinb2r@googlemail.com>
Date2011-05-12 10:26 -0500
Message-ID<BANLkTim3+BkN3HHp0T8-8aX6feRCjyAOUg@mail.gmail.com>
In reply to#4362
On Thu, May 12, 2011 at 2:54 PM, serialhex <serialhex@gmail.com> wrote:
> ...
> instead of using floats you can try to use rational numbers in ruby:
> ruby-1.9.2-p180 :001 > require 'mathn'
which also changes this:
  (-1) ** (1.0 / 3) #=> NaN
to:
  (-1) ** (1.0 / 3) #=> (0.5+0.866025403784439i)
so we can also get complex roots if we want them!

> ...
> one last thing: if your inputs are floats i'm not sure there is a nice way
> to convert them to rationals:
>   (1.0/3).to_r  #=> (6004799503160661/18014398509481984)
I think that is a nice way! It's telling us (I think) what is the
exact rational represented by the float. After all, a float is just a
special type of rational, or rather floats are a subset of the subset
of the rationals defined by them have powers of two as denominators in
their representation using the smallest positive denominator. (I hope
that's correct.)

Whether it's a *good* idea to be able to convert floats to "ordinary"
rationals is another question, and I'm sceptical about that: I think
one should probably only want to do it if one fully understands
floating point representation, and if one fully understands floating
point representation, I suspect one wouldn't want to do it!

[toc] | [prev] | [next] | [standalone]


#4404

FromJosh Cheek <josh.cheek@gmail.com>
Date2011-05-12 13:30 -0500
Message-ID<BANLkTimbw9FHpdtPmmxpMgxJ5foU7jFVcQ@mail.gmail.com>
In reply to#4380
[Note:  parts of this message were removed to make it a legal post.]

On Thu, May 12, 2011 at 10:26 AM, Colin Bartlett <colinb2r@googlemail.com>wrote:

> On Thu, May 12, 2011 at 2:54 PM, serialhex <serialhex@gmail.com> wrote:
> > ...
> > instead of using floats you can try to use rational numbers in ruby:
> > ruby-1.9.2-p180 :001 > require 'mathn'
> which also changes this:
>  (-1) ** (1.0 / 3) #=> NaN
> to:
>  (-1) ** (1.0 / 3) #=> (0.5+0.866025403784439i)
> so we can also get complex roots if we want them!
>
>
Which we don't here, given that the cube root of -1 isn't imaginary :/

[toc] | [prev] | [next] | [standalone]


#4410

Fromserialhex <serialhex@gmail.com>
Date2011-05-12 13:46 -0500
Message-ID<BANLkTi=qy8sqSS+As3R7eLfimbpnfyJfZQ@mail.gmail.com>
In reply to#4404
[Note:  parts of this message were removed to make it a legal post.]

On Thu, May 12, 2011 at 2:30 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

> Which we don't here, given that the cube root of -1 isn't imaginary :/


there are actually 3 cube roots of -1 (and 4 quad roots of -1, and 5 penta
roots of -1 and...)
behold the code:

ruby-1.9.2-p180 :004 > a = (-1)**(1/3)
 => (0.5000000000000001+0.8660254037844386i)
ruby-1.9.2-p180 :005 > a.conj
 => (0.5000000000000001-0.8660254037844386i)
ruby-1.9.2-p180 :006 > a.conj**3
 => (-1.0-3.885780586188048e-16i)
ruby-1.9.2-p180 :007 > a**3
 => (-1.0+3.885780586188048e-16i)
ruby-1.9.2-p180 :008 > (-1)**3
 => -1

(conjugation simply flips the sign of the imaginary number, which is helpful
for a bunch of things)  so while there may be 1 _real_ root for a given
number, there are n roots for any number taken to the (1/n)th power.  and
while most people will want the (simple) (-1)**(1/3) == (-1) answer, they
are all right (minus the floating-point rounding errors... which is kind of
odd cause i would think that i would be getting the rational representation
of the complex numbers instead of floats... idfk... whatev!)
hex

[toc] | [prev] | [next] | [standalone]


#4411

FromRob Biedenharn <Rob@AgileConsultingLLC.com>
Date2011-05-12 13:53 -0500
Message-ID<8814B308-5CA5-47C8-8EC8-1635C2932921@AgileConsultingLLC.com>
In reply to#4404
On May 12, 2011, at 2:30 PM, Josh Cheek wrote:

> On Thu, May 12, 2011 at 10:26 AM, Colin Bartlett <colinb2r@googlemail.com 
> >wrote:
>
>> On Thu, May 12, 2011 at 2:54 PM, serialhex <serialhex@gmail.com>  
>> wrote:
>>> ...
>>> instead of using floats you can try to use rational numbers in ruby:
>>> ruby-1.9.2-p180 :001 > require 'mathn'
>> which also changes this:
>> (-1) ** (1.0 / 3) #=> NaN
>> to:
>> (-1) ** (1.0 / 3) #=> (0.5+0.866025403784439i)
>> so we can also get complex roots if we want them!
>>
>>
> Which we don't here, given that the cube root of -1 isn't imaginary :/


ONE of the cube roots of -1 isn't imaginary, but the other two are.   
Since (1.0/3) isn't exactly one-third, raising -1 to (1.0/3) isn't  
exactly the same as taking the cube root either.

-Rob

Rob Biedenharn		
Rob@AgileConsultingLLC.com	http://AgileConsultingLLC.com/
rab@GaslightSoftware.com		http://GaslightSoftware.com/

[toc] | [prev] | [next] | [standalone]


#4426

Fromjzakiya <jzakiya@gmail.com>
Date2011-05-12 13:20 -0700
Message-ID<20200593-602f-486f-b273-a68423b0cc3b@34g2000pru.googlegroups.com>
In reply to#4411
On May 12, 2:53 pm, Rob Biedenharn <R...@AgileConsultingLLC.com>
wrote:
> On May 12, 2011, at 2:30 PM, Josh Cheek wrote:
>
>
>
>
>
>
>
>
>
> > On Thu, May 12, 2011 at 10:26 AM, Colin Bartlett <colin...@googlemail.com
> > >wrote:
>
> >> On Thu, May 12, 2011 at 2:54 PM, serialhex <serial...@gmail.com>  
> >> wrote:
> >>> ...
> >>> instead of using floats you can try to use rational numbers in ruby:
> >>> ruby-1.9.2-p180 :001 > require 'mathn'
> >> which also changes this:
> >> (-1) ** (1.0 / 3) #=> NaN
> >> to:
> >> (-1) ** (1.0 / 3) #=> (0.5+0.866025403784439i)
> >> so we can also get complex roots if we want them!
>
> > Which we don't here, given that the cube root of -1 isn't imaginary :/
>
> ONE of the cube roots of -1 isn't imaginary, but the other two are.  
> Since (1.0/3) isn't exactly one-third, raising -1 to (1.0/3) isn't  
> exactly the same as taking the cube root either.
>
> -Rob
>
> Rob Biedenharn          
> R...@AgileConsultingLLC.com  http://AgileConsultingLLC.com/
> r...@GaslightSoftware.com            http://GaslightSoftware.com/

See my Roots Module.
https://gist.github.com/422636

It allows you to easily (and accurately) get all n values for a root
n,
for all number classes.

Instead of:  1000**3**-1  of 1000**(1.0/3) to get only default root
Instead do:  1000.root(3) or 1000.roots(3), for all 3 cube roots

Jabari Zakiya

[toc] | [prev] | [next] | [standalone]


#4430

Fromserialhex <serialhex@gmail.com>
Date2011-05-12 15:36 -0500
Message-ID<BANLkTimuFG2Yi-UdnWw9wYjS_VaVRfgdPw@mail.gmail.com>
In reply to#4426
[Note:  parts of this message were removed to make it a legal post.]

On Thu, May 12, 2011 at 4:25 PM, jzakiya <jzakiya@gmail.com> wrote:

> See my Roots Module.
> https://gist.github.com/422636
>

spiffy!!!
hex

[toc] | [prev] | [next] | [standalone]


#4544

FromMartin DeMello <martindemello@gmail.com>
Date2011-05-14 13:12 -0500
Message-ID<BANLkTim4Ot+Dp5r-ucagY7WV=P+7iGh5wg@mail.gmail.com>
In reply to#4404
On Fri, May 13, 2011 at 12:00 AM, Josh Cheek <josh.cheek@gmail.com> wrote:
> On Thu, May 12, 2011 at 10:26 AM, Colin Bartlett <colinb2r@googlemail.com>wrote:
>> which also changes this:
>>  (-1) ** (1.0 / 3) #=> NaN
>> to:
>>  (-1) ** (1.0 / 3) #=> (0.5+0.866025403784439i)
>> so we can also get complex roots if we want them!
>>
>>
> Which we don't here, given that the cube root of -1 isn't imaginary :/

Think of -1 in polar form (r exp(i theta)) as 1.exp(i pi), then note
that the cube roots are (1 exp (i pi/3)), (1 exp (i 2pi/3)) and (1
exp(i pi)). The principal cube root is the one with the smallest value
of theta.

martin

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.ruby


csiph-web