On Dec 20, 9:51 am, Colin Bartlett <colin... / googlemail.com> wrote: > If this can be made to work, it might be useful. > Two thoughts that occur to me are: > > 1. The code you show would probably need to use Rational(?), > otherwise 1/n (or 1.0/n) may not be what one thinks it is. From a mathematical/engineering perspective it is understood that a root n is a positive integer > 1. In other words, what number 'r' multiplied by itself n times equals 'x'. A coding implementation can do the requisite checks on all the inputs and raise needed exceptions/warnings. Of course from an arithmetic perspective (a)^(1/n) can take any value of n (integer, float, complex) but if n not a positive integer (or interizable) number > 1 then the discussion here may not apply to those cases. I think the syntax of (a)^(n^-1) vs (a)^(1/n) makes the point more mathematical clearer that what you are doing is finding the nth root of 'a' vs raising 'a' to a fractional power. > 2. What would one do with a number (Float or Rational) > which is arbitrarily close to 1/n but which is not 1/n? If a number can be expressed as rational n = b/c then 'c' would be the root, and 'b' would be the power and (a)^b^(c^-1), otherwise see comment above. > I'd also like to take the opportunity of this thread > to suggest removing (!) something from Complex, > unless anyone can make a good case for retaining it: > > require "complex" > n = -2 #=> -2 > p = 1 #=> 1 > cn = Complex( n, 0 ) #=> Complex(-2, 0) > cp = Complex( p, 0 ) #=> Complex(1, 0) > n > p #=> false > cn > p #=> true > cn > cp #=> true > > The Complex numbers are not an "ordered field", > at least not in any normally useful sense. > > At the moment if either x or y is Complex > then x <=> y is calculated as x.abs <=> y.abs; > > # File complex.rb, line 312 > def <=> (other) > self.abs <=> other.abs > end > > I think that can be misleading (see the examples above), > and I would prefer it if "<=>" and "<", etc, > were *not* defined for Complex, > and if one wants to compare absolute values > then one should do so explicitly. I would agree that <, >, are ambiguous. It's not just a matter of magnitude size but also angular 'size', Remember, complex variables are really vectors with magnitude and direction (angle). Take the example of a ferris wheel ride. Where you get on it is angular distance zero from your start. Once the ride starts, it will eventually be rotating at some constant speed, with changing angular direction. However, the max angular distance from the start with be when you are at the top of the ferris wheel, which is an angular distance of PI (180) degrees from your start. All other locations have CCP angular distance from the start. Thus, any complex number is defined with polar rep of |mag(a)| /_ angle(a) Therefore, to find all the n roots of real values, I can change my original code to make it more efficient and flexible by making it just find the magnitude and angles of the root locations. def Complex.root(a,n,k) angle = (2*k+1)*PI/n # for 'a' real negative angle += PI/n if a > 0 # for 'a' real positive mag = a.abs**n**-1 # The kth root of (a)**n**-1 mag*Complex(cos(angle),sin(angle)) end The key is to find the appropriate angle rotation for 'a' positive or negative. Now by finding that angle and mag values, all the numeric classes can be written to find all the roots of real values with easy syntax. In Integer/Float you could now do: a.root(n) # default to +/- real root or first CCP a.root(n,k) # kth ccw root a.roots(n) # array of all (ccw) roots To make it intuitive (and follow Matz's POLS) let k roots go from 1st to kth, k = 1..n, which means that the routine that uses k just needs to subtract 1 from it before computing the angle. These features can be integrated within all the other numeric classes/modules as appropriate.