Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

root function

by Anonymous Monk
on Jun 21, 2008 at 18:25 UTC ( [id://693294]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi i wanted to know if there is a function to calculate the root of a number with my own exponent . i could not find them in the manual and searched on other sites but i could not find anything .

Replies are listed 'Best First'.
Re: root function
by FunkyMonk (Chancellor) on Jun 21, 2008 at 18:33 UTC
    It's just basic maths. The cube root of 27 is 27**(1/3). If you really want a function, try
    print wop( 8, 3 ); #2 print wop( 27, 3 ); #3 sub wop { my ( $base, $root ) = @_; return $base ** (1/$root) }

    update: s/If/If you/


    Unless I state otherwise, all my code runs with strict and warnings
      You're going to have to rename that function "whop" for a US audience. :)
Re: root function
by swampyankee (Parson) on Jun 21, 2008 at 21:18 UTC

    FunkyMonk has one way; another is

    x(1/y) = eln(x)/y. Just beware that 00 should be undefined, and Perl's ** operator is essentially a wrapper around C's "pow" function, so it will almost certainly puke on (-3)(1/3), even though it shouldn't.


    Information about American English usage here and here. Floating point issues? Please read this before posting. — emc

      Yes it does. (-3)**(1/3) results in nan; But so does the log approach, too.

      The odd roots of negative numbers must be treated separately as they are limit cases.

      I'd try something like:

      if ($base>0) { return $base**(1/$root); } elsif ($base==0) { return 0; ## or do manage the special case 0**0; } elsif ($root)==int($root) && $root%2==1) { return -((-$base)**($root)); } else { return 'nan'; }

      Not tested, so probably broken :)

      Careful with that hash Eugene.

        The logarithms of negative numbers are defined; it's just that they require complex numbers to represent. It's not my fault that Perl (and C) can't cope with them ;-).

        All will become clear when one remembers that eπi = -1


        Information about American English usage here and here. Floating point issues? Please read this before posting. — emc

      linux:
      $ perl -le'print -3 ** (1/3)' -1.44224957030741
      ActivePerl:
      >perl -le"print -3 ** (1/3)" -1.44224957030741

      Update: Oops, precedence problem

      $ perl -le'print( (-3) ** (1/3) )' nan
      >perl -e"print( (-3) ** (1/3) )" -1.#IND
        sini@ordinalfabetix:~$ perl -le"print ((-3)**(1/3));" nan sini@ordinalfabetix:~$

        Exponent operator ** has higher priority than unary minus so you are doing -(3**(1/3)) instead of ((-3)**(1/3)).

        This gives you accidentally the right result but it would tell you that square root of -2 == -1.414265...

        Careful with that hash Eugene.

Re: root function
by Sixtease (Friar) on Jun 21, 2008 at 18:37 UTC

    I have also found the Math::NumberCruncher module, which seems to have a function for that.

    use strict; use warnings; print "Just Another Perl Hacker\n";
Re: root function
by casiano (Pilgrim) on Jun 22, 2008 at 10:35 UTC
    Perl with the help of PDL::Complex can cope with Complex Numbers. See below:

    pp2@nereida:~/.ssh$ perl -wde 0 main::(-e:1): 0 DB<1> use PDL DB<2> use PDL::Complex DB<3> $x = r2C(-27) # From real to complex DB<4> $r = Croots $x, 3 # There are three complex roots DB<5> print $r # It is sad that there is a bug # with "" overload Use of uninitialized value in numeric ... [ 1.5 +2.59807621135332i -3 +3.67381906146713e-16i 1.5 -2.59807621135332i ] DB<6> x $ra # The answer is a PDL object 0 PDL::Complex=SCALAR(0x8a6a0a8) -> 144899352 DB<7> p re $r # Get the "real" components [1.5 -3 1.5] DB<8> p im $r # And the imaginary ones: [ 2.5980762 3.6738191e-16 -2.5980762] DB<9> $y = $r ** 3 # Check the solution: DB<10> p re $y [-27 -27 -27] DB<11> p im $y # Almost 0, as expected [3.3064372e-15 9.9193115e-15 6.8636015e-14]
    Hope it helps

    Casiano

      And PDL 2.040 or so introduced "native" complex numbers, without the visible real/imaginary dimension. It doesn't yet have an analogue of the Croots (multiple complex roots), evidently due to a lack of demand.

      It would not be hard to implement, since the n roots of a complex number can be calculated very easily using https://en.wikipedia.org/wiki/De_Moivre%27s_formula: root_n = r(cos(theta + 2pi/n) + i sin(theta + 2pi/n)). Pull requests welcome!

Re: root function
by igelkott (Priest) on Jun 22, 2008 at 00:55 UTC
    calculate the root

    Besides the suggested home-made functions, you could also try pow in the POSIX module.

      Either you're calling ** a home-made function, or they're just as needed for pow as for **.
        calling ** a home-made function

        I wouldn't call the ** operator a "function" at all. ;-)

        I didn't mean anything wrong by home-made but just tried to answer the op literally with an alternative solution. Nothing too serious.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://693294]
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-20 04:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found