Math errors

J

jzakiya

(-3)**3 => -27

(-27)**(1/3.0) give NaN instead of -3

All odd roots (1/3,1/5,1/7 etc) of negative numbers should give
negative root values, as above, but ruby (in irb) gives NaN (not a
number), even when I require 'complex' .

Is this considered an error in Ruby?
 
B

Benoit Daloze

[Note: parts of this message were removed to make it a legal post.]

IN 1.9.2 I got:

~ $> ruby -ve 'p v=Math.cbrt(-27); p v**3'
ruby 1.9.2dev (2009-12-11 trunk 26067) [x86_64-darwin10.2.0]
-3.0
-27.0

~ $> ruby -ve 'p v=(-27)**(1/3.0); p v**3'
(1.5000000000000004+2.598076211353316i)
(-27.000000000000007+1.2434497875801753e-14i)

~ $> ruby -ve 'p v=(-27)**(Rational(1,3)); p v**3'
(1.5+2.5980762113533156i)
(-26.99999999999999+3.552713678800501e-15i)

Got easy results, but with all different values ...
So, the first is right, of course.
The second is a good approximation, for floats ...
And the last is almost good, while I would expect to be exact (I think it
should use Math.cbrt in this case)

I would probably interested to use BigDecimal, but it's impossible I think
to use it for Complex. (And actually it accept only Fixnum exponent)

Another error in the exception:
TypeError: wrong argument type BigDecimal (expected Fixnum)

But it accept Float, really ;)
 
W

W. James

jzakiya said:
(-3)**3 => -27

(-27)**(1/3.0) give NaN instead of -3

All odd roots (1/3,1/5,1/7 etc) of negative numbers should give
negative root values, as above, but ruby (in irb) gives NaN (not a
number), even when I require 'complex' .

Is this considered an error in Ruby?

irb(main):001:0> 1/3.0
=> 0.333333333333333

--
 
W

W. James

jzakiya said:
(-3)**3 => -27

(-27)**(1/3.0) give NaN instead of -3

All odd roots (1/3,1/5,1/7 etc) of negative numbers should give
negative root values, as above, but ruby (in irb) gives NaN (not a
number), even when I require 'complex' .

Is this considered an error in Ruby?

irb(main):006:0> (-27)**(1/3.0)
=> NaN
irb(main):007:0> -27 ** (1/3.0)
=> -3.0

irb(main):012:0> RUBY_VERSION
=> "1.8.7"

--
 
D

Dasson, Raghav

Removing the brackets across -27.0 does the trick, though would need to fin=
d the logic behind the same
(-27)**(1/3.0) gives NaN

-27**(1/3.0) gives -3

Regards,
Raghav

-----Original Message-----
From: jzakiya [mailto:[email protected]]=20
Sent: Friday, December 18, 2009 12:15 PM
To: ruby-talk ML
Subject: Math errors

(-3)**3 =3D> -27

(-27)**(1/3.0) give NaN instead of -3

All odd roots (1/3,1/5,1/7 etc) of negative numbers should give
negative root values, as above, but ruby (in irb) gives NaN (not a
number), even when I require 'complex' .

Is this considered an error in Ruby?
 
D

Dasson, Raghav

jzakiya said:
(-3)**3 =3D> -27
=20
(-27)**(1/3.0) give NaN instead of -3
=20
All odd roots (1/3,1/5,1/7 etc) of negative numbers should give
negative root values, as above, but ruby (in irb) gives NaN (not a
number), even when I require 'complex' .
=20
Is this considered an error in Ruby?


I guess, you are right. THIS IS A 'MATH ERROR' in Ruby.

The ** method is not able to handle negative numbers raised to Floating poi=
nts (that are not Integers) =20
 
J

jzakiya

I guess, you are right. THIS IS A 'MATH ERROR' in Ruby.

The ** method is not able to handle negative numbers raised to Floating points (that are not Integers)  

This behavior was shown in ruby ree 1.8.6, 1.8.6, 1.8.7, 1.9.1

-27**1/3.0 => -9.0
-27 ** 1/3.0 => -9.0
-27 ** (1/3.0) => -3.0
-27**(1/3.0) => -3.0
(-27)**(1/3.0) => NaN
(-27) ** (1/3.0) => NaN

OK, the first two expression are evaluated as (-27**1)/3 => -9
The second two are correct (what I expected).
But the last two, WHY??
 
J

jzakiya

This behavior was shown in ruby ree 1.8.6, 1.8.6, 1.8.7, 1.9.1

-27**1/3.0       => -9.0
-27 ** 1/3.0     => -9.0
-27 ** (1/3.0)   => -3.0
-27**(1/3.0)     => -3.0
(-27)**(1/3.0)   => NaN
(-27) ** (1/3.0) => NaN

OK, the first two expression are evaluated as (-27**1)/3 => -9
The second two are correct (what I expected).
But the last two, WHY??

And just to verify:

(27)**(1/3.0) => 3.0

So Ruby is messing up parsing (-27)**(1/3.0)
 
F

Fleck Jean-Julien

Hello,
This behavior was shown in ruby ree 1.8.6, 1.8.6, 1.8.7, 1.9.1

-27**1/3.0 =A0 =A0 =A0 =3D> -9.0
-27 ** 1/3.0 =A0 =A0 =3D> -9.0
-27 ** (1/3.0) =A0 =3D> -3.0
-27**(1/3.0) =A0 =A0 =3D> -3.0
(-27)**(1/3.0) =A0 =3D> NaN
(-27) ** (1/3.0) =3D> NaN

OK, the first two expression are evaluated as (-27**1)/3 =3D> -9
The second two are correct (what I expected).
But the last two, WHY??

As Matz said, the second two are evaluated as - (27**(1/3.0)), that is
you take the cubic root of +27 which is 3 and then distribute the
minus.
That way, you take the cubic root of a positive number which does not
raise any problem.

Cheers,

--=20
JJ Fleck
PCSI1 Lyc=E9e Kl=E9ber
 
J

jzakiya

Hello,




As Matz said, the second two are evaluated as - (27**(1/3.0)), that is
you take the cubic root of +27 which is 3 and then distribute the
minus.
That way, you take the cubic root of a positive number which does not
raise any problem.

Cheers,

That is WRONG, you cannot do that.
That only works for odd roots of negative numbers.
The even root of negative numbers are imaginary.

-27**3**-1 => -3 **correct
-27**2**-1 => -5.19615242270663 **WRONG, its 5.196152i
 
F

Fleck Jean-Julien

That is WRONG, you cannot do that.

Well, I never said that you should do that, I just explained how Ruby
interpreted it...
That only works for odd roots of negative numbers.
The even root of negative numbers are imaginary.

-27**3**-1 =3D> -3 **correct
-27**2**-1 =3D> -5.19615242270663 **WRONG, its 5.196152i

Sure. That's quite a hint why ** does not accept a negative number
with a non integer exponent. To take into account all the special
cases, you should first see if your exponent is a rational and in that
case, see if the denominator is odd (after all due simplifications of
course). In this case (and only this case), you could try to decipher
a root for this negative number.

Cheers,

--=20
JJ Fleck
PCSI1 Lyc=E9e Kl=E9ber
 
W

William James

Fleck said:
Well, I never said that you should do that, I just explained how Ruby
interpreted it...


Sure. That's quite a hint why ** does not accept a negative number
with a non integer exponent. To take into account all the special
cases, you should first see if your exponent is a rational and in that
case, see if the denominator is odd (after all due simplifications of
course). In this case (and only this case), you could try to decipher
a root for this negative number.

Cheers,


def root base, n
exp = 1.0/n
return base ** exp if base >= 0 or n.even?
-( base.abs ** exp )
end

--
 
J

jzakiya

def root base, n
  exp = 1.0/n
  return base ** exp if base >= 0 or n.even?
  -( base.abs ** exp )
end

--

Remember

i = (-1)^(1/2)

i^1 = i
i^2 = -1
i^3 = -i
i^4 = 1
Then it repeats, for example: i^5 = i*(i^4) = i

For negative real value roots:

x = (-a)^(1/n) where n is odd integer => x = -[a^(1/n)]

But for negative real value roots where n is even:

x = (-a)^(1/n) where n is even gives

x = |a^(1/n)|*(-1)^(1/n)
x = |a^(1/n)|*(i^2)^(1/n)
x = |a^(1/n)|*(i)^(2/n)
from e^(i*x) = cos(x) + i*sin(x) where x = PI/2
x = |a^{1/n)|*e^(PI*i/2)^(2/n)
x = |a^(1/n)|*e^(PI*i/n)
x = |a^(1/n)|*(cos(PI/n) + i*sin(PI/n)) for n even

(-256)^(1/2) = |256^(1/2)|*(cos(PI/2) + i*sin(PI/2))
= (16)(0 + i) = 16i

(-256)^(/4) = |256^(1/4)|*(cos(PI/4) + i*sin(PI/4))
= (4)*(0.707 + 0.707*i)
= 2.828 + i*2.828
= 2.828*(1+i)

Check in irb
require 'complex'
include Math

x = Complex(-256,0)

x**(1/2.0)
=> (9.79685083057902e-16+16.0i)

X**(1/4.0)
=> (2.82842712474619+2.82842712474619i)
 
J

jzakiya

def root base, n
  exp = 1.0/n
  return base ** exp if base >= 0 or n.even?
  -( base.abs ** exp )
end

Remember

i = (-1)^(1/2)

i^1 =  i
i^2 = -1
i^3 = -i
i^4 =  1
Then it repeats, for example: i^5 = i*(i^4) = i

For negative real value roots:

x = (-a)^(1/n) where n is odd integer => x = -[a^(1/n)]

But for negative real value roots where n is even:

x = (-a)^(1/n) where n is even gives

x = |a^(1/n)|*(-1)^(1/n)
x = |a^(1/n)|*(i^2)^(1/n)
x = |a^(1/n)|*(i)^(2/n)
from e^(i*x) = cos(x) + i*sin(x) where x = PI/2
x = |a^{1/n)|*e^(PI*i/2)^(2/n)
x = |a^(1/n)|*e^(PI*i/n)
x = |a^(1/n)|*(cos(PI/n) + i*sin(PI/n)) for n even

(-256)^(1/2) = |256^(1/2)|*(cos(PI/2) + i*sin(PI/2))
             = (16)(0 + i) = 16i

(-256)^(/4) = |256^(1/4)|*(cos(PI/4) + i*sin(PI/4))
            = (4)*(0.707 + 0.707*i)
            = 2.828 + i*2.828
            = 2.828*(1+i)

Check in irb
require 'complex'
include Math

x = Complex(-256,0)

x**(1/2.0)
=> (9.79685083057902e-16+16.0i)

X**(1/4.0)
=> (2.82842712474619+2.82842712474619i)

BTW there is an error (sort of) in 'complex' too
require 'complex'
include Math
x = Complex(-27,0)
=> (-27+0i)
y = x**(1/3.0) # or x**3**-1
=> (1.5+2.59807621135332i) # should be (-3+0i)
=> (-27.0+1.24344978758018e-14i)
Complex(-3,0)**3
=> -27

Whenever you take the root n of a number you actually
get n values. If the value is positive you get n copies
of the same positive real value.

When you take the root of a negative real value you
get n roots too, for n even and odd.

For even odd, you get one real root and n/2 Complex Conjugate Pairs
(CCP).

Thus, for n=3 for (-27)^(1/3) the real root is x1=-3
and x2 is y above and x3 is the CCP of y.

For n=5, you get one real root and 2 pairs of CCPs, etc.

For n even, you get n/2 CCPs only.
So, for n=2 there is one pair of CCP roots.
For n=4 you get 2 different CCP roots, etc,
Thus for n even there are no real roots.

So, I think it's more intuitive (for most people)
to expect Complex(-27,0)**(1/n-odd) to return the real
root x1 only (i.e. (-3)*(-3)*(-3) = -27), so have it
act as Complex(-27,0).real (for n odd) be the default.

I guess complex variables aren't called complex for nothing. :)
 
J

jzakiya

On Dec 18, 2:13 pm, "William James" <> wrote:

i = (-1)^(1/2)
i^1 =  i
i^2 = -1
i^3 = -i
i^4 =  1
Then it repeats, for example: i^5 = i*(i^4) = i
For negative real value roots:
x = (-a)^(1/n) where n is odd integer => x = -[a^(1/n)]
But for negative real value roots where n is even:
x = (-a)^(1/n) where n is even gives
x = |a^(1/n)|*(-1)^(1/n)
x = |a^(1/n)|*(i^2)^(1/n)
x = |a^(1/n)|*(i)^(2/n)
from e^(i*x) = cos(x) + i*sin(x) where x = PI/2
x = |a^{1/n)|*e^(PI*i/2)^(2/n)
x = |a^(1/n)|*e^(PI*i/n)
x = |a^(1/n)|*(cos(PI/n) + i*sin(PI/n)) for n even
(-256)^(1/2) = |256^(1/2)|*(cos(PI/2) + i*sin(PI/2))
             = (16)(0 + i) = 16i
(-256)^(/4) = |256^(1/4)|*(cos(PI/4) + i*sin(PI/4))
            = (4)*(0.707 + 0.707*i)
            = 2.828 + i*2.828
            = 2.828*(1+i)
Check in irb
x = Complex(-256,0)
x**(1/2.0)
=> (9.79685083057902e-16+16.0i)
X**(1/4.0)
=> (2.82842712474619+2.82842712474619i)

BTW there is an error (sort of) in 'complex' too
require 'complex'
include Math
x = Complex(-27,0)

=> (-27+0i)
y = x**(1/3.0) # or x**3**-1

=> (1.5+2.59807621135332i)  # should be (-3+0i)

=> (-27.0+1.24344978758018e-14i)
Complex(-3,0)**3

=> -27

Whenever you take the root n of a number you actually
get n values. If the value is positive you get n copies
of the same positive real value.

When you take the root of a negative real value you
get n roots too, for n even and odd.

For even odd, you get one real root and n/2 Complex Conjugate Pairs
(CCP).

Thus, for n=3 for (-27)^(1/3) the real root is x1=-3
and x2 is y above and x3 is the CCP of y.

For n=5, you get one real root and 2 pairs of CCPs, etc.

For n even, you get n/2 CCPs only.
So, for n=2 there is one pair of CCP roots.
For n=4 you get 2 different CCP roots, etc,
Thus for n even there are no real roots.

So, I think it's more intuitive (for most people)
to expect Complex(-27,0)**(1/n-odd) to return the real
root x1 only (i.e. (-3)*(-3)*(-3) = -27), so have it
act as Complex(-27,0).real (for n odd) be the default.

I guess complex variables aren't called complex for nothing. :)

Oooh, I just noticed:
Complex(-27**(1/3.0),0) => (-3.0+0i).

So that acts I expected/want.

So maybe it would be nice to be able to do:

Complex(-a**(1/n),0).roots or
Complex(a**(1/n)).roots where a is already complex
and have this return all the roots in an array so you
can see/pick which one(s) you want.
 
J

jzakiya

On Dec 18, 2:13 pm, "William James" <> wrote:
Fleck Jean-Julien wrote:
That is WRONG, you cannot do that.
Well, I never said that you should do that, I just explained how Ruby
interpreted it...
That only works for odd roots of negative numbers.
The even root of negative numbers are imaginary.
-27**3**-1 => -3 **correct
-27**2**-1 => -5.19615242270663 **WRONG, its 5.196152i
Sure. That's quite a hint why ** does not accept a negative number
with a non integer exponent. To take into account all the special
cases, you should first see if your exponent is a rational and inthat
case, see if the denominator is odd (after all due simplifications of
course). In this case (and only this case), you could try to decipher
a root for this negative number.
Cheers,
def root base, n
  exp = 1.0/n
  return base ** exp if base >= 0 or n.even?
  -( base.abs ** exp )
end
--
Remember
i = (-1)^(1/2)
i^1 =  i
i^2 = -1
i^3 = -i
i^4 =  1
Then it repeats, for example: i^5 = i*(i^4) = i
For negative real value roots:
x = (-a)^(1/n) where n is odd integer => x = -[a^(1/n)]
But for negative real value roots where n is even:
x = (-a)^(1/n) where n is even gives
x = |a^(1/n)|*(-1)^(1/n)
x = |a^(1/n)|*(i^2)^(1/n)
x = |a^(1/n)|*(i)^(2/n)
from e^(i*x) = cos(x) + i*sin(x) where x = PI/2
x = |a^{1/n)|*e^(PI*i/2)^(2/n)
x = |a^(1/n)|*e^(PI*i/n)
x = |a^(1/n)|*(cos(PI/n) + i*sin(PI/n)) for n even
(-256)^(1/2) = |256^(1/2)|*(cos(PI/2) + i*sin(PI/2))
             = (16)(0 + i) = 16i
(-256)^(/4) = |256^(1/4)|*(cos(PI/4) + i*sin(PI/4))
            = (4)*(0.707 + 0.707*i)
            = 2.828 + i*2.828
            = 2.828*(1+i)
Check in irb
require 'complex'
include Math
x = Complex(-256,0)
x**(1/2.0)
=> (9.79685083057902e-16+16.0i)
X**(1/4.0)
=> (2.82842712474619+2.82842712474619i)
BTW there is an error (sort of) in 'complex' too
=> (-27+0i)
=> (1.5+2.59807621135332i)  # should be (-3+0i)

=> (-27.0+1.24344978758018e-14i)

=> -27
Whenever you take the root n of a number you actually
get n values. If the value is positive you get n copies
of the same positive real value.
When you take the root of a negative real value you
get n roots too, for n even and odd.
For even odd, you get one real root and n/2 Complex Conjugate Pairs
(CCP).
Thus, for n=3 for (-27)^(1/3) the real root is x1=-3
and x2 is y above and x3 is the CCP of y.
For n=5, you get one real root and 2 pairs of CCPs, etc.
For n even, you get n/2 CCPs only.
So, for n=2 there is one pair of CCP roots.
For n=4 you get 2 different CCP roots, etc,
Thus for n even there are no real roots.
So, I think it's more intuitive (for most people)
to expect Complex(-27,0)**(1/n-odd) to return the real
root x1 only (i.e. (-3)*(-3)*(-3) = -27), so have it
act as Complex(-27,0).real (for n odd) be the default.
I guess complex variables aren't called complex for nothing. :)

Oooh, I just noticed:
Complex(-27**(1/3.0),0) => (-3.0+0i).

So that acts I expected/want.

So maybe it would be nice to be able to do:

Complex(-a**(1/n),0).roots or
Complex(a**(1/n)).roots where a is already complex
and have this return all the roots in an array so you
can see/pick which one(s) you want.

So if you have these methods:

Complex(a).root(n).roots # all the roots of a
Complex(a).root(n).real # the real root(s) if exists

Then for any value a (real or complex) you will get
what you want under the different conditions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,162
Messages
2,570,896
Members
47,434
Latest member
TobiasLoan

Latest Threads

Top