Re: root function
by FunkyMonk (Canon) 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/
 [reply] [d/l] 

You're going to have to rename that function "whop" for a US audience. :)
 [reply] 
Re: root function
by swampyankee (Parson) on Jun 21, 2008 at 21:18 UTC

FunkyMonk has one way; another is
x^{(1/y)} = e^{ln(x)/y}. Just beware that 0^{0} 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
 [reply] 

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.
 [reply] [d/l] 

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
 [reply] 





$ 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
 [reply] [d/l] [select] 

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.
 [reply] [d/l] 



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";
 [reply] 

 [reply] 
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.67381906146713e16i
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.6738191e16 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.3064372e15 9.9193115e15 6.8636015e14]
Hope it helps
Casiano  [reply] [d/l] 
Re: root function
by igelkott (Priest) on Jun 22, 2008 at 00:55 UTC

calculate the root
Besides the suggested homemade functions, you could also try pow in the POSIX module.
 [reply] 

Either you're calling ** a homemade function, or they're just as needed for pow as for **.
 [reply] [d/l] [select] 

 [reply] [d/l] 
