From: jzakiya Date: 2009-12-19T10:40:21+09:00 Subject: Re: Math errors On Dec 18, 8:26 pm, jzakiya wrote: > On Dec 18, 8:02 pm, jzakiya wrote: > > > > > On Dec 18, 5:24 pm, jzakiya wrote: > > > > 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 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 > > > > > -- > > > > 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) > > > >y**3 > > > => (-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. 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.