http://qs321.pair.com?node_id=652386

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

I'm a new user for this website and i'm still beginner in programming Perl language............i only know the very basics....... i need your help in programming the exponential function (e^x) e to the power of x http://upload.wikimedia.org/math/0/b/c/0bc08045195dc823c22d1fa283cb0759.png i need to program the function it self as it appears in the picture above and then compare it to the biult-in function in Perl........ exp (); your help is too appreciated Thanks

Replies are listed 'Best First'.
Re: Exponential Function Programming
by okram (Monk) on Nov 22, 2007 at 15:44 UTC
```# exp.

\$n = 2;

\$e_n = exp(\$n);
print "e^\$n = \$e_n\n";

sub my_factorial {
my \$n = shift;
my \$s=1;
my \$r=1;
while (\$s <= \$n) {
\$r *= \$s;
\$s++;
}
if(\$n == 0) {
\$r=0;
}
return \$r;
}

sub my_exp_x {
my \$x = shift;
my \$max_iterations = shift;

my \$result = 1 + \$x;
my \$i = 2;

while (\$i < \$max_iterations) {

\$result += (\$x ** (\$i)) / (my_factorial(\$i));

\$i++;

}

return \$result;
}

print "test: ", my_exp_x(\$n,1000);
```sub my_factorial {
...
if(\$n == 0) {
\$r=0;
}
return \$r;
}
Your function says that 0 factorial is 0. But it's not; it's 1.

Perl 6 is very generous in this:

```pugs> sub postfix:<!> (Int \$n) { [*] 1..\$n }
undef
pugs> say \$_! for ^10
1
1
2
6
24
120
720
5040
40320
362880
undef

(I personally believe that I've posted this before here and in different media, but that's jut because it's quite about the only thing I can actually do in pugs ATM.)

i got your program but what im looking for is how to do the basic function as it is for example i need to do X to the power of N, then divide it by N factorial and at the end add them all from (1 until the N number i entered) Thanks alot
x to the power of n is done via: \$x ** \$n or
```sub x_power_n {
my \$x = shift;
my \$n = shift;
my \$result = \$x;
my \$i = 1;
while (\$i < \$n) {
\$result *= \$x;
\$i++;
}
return \$result;
}
You need to do this, though, "infinite" times, reason why I provided a parameter to "stop" after a certain time.
A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Exponential Function Programming
by fenLisesi (Priest) on Nov 22, 2007 at 17:21 UTC
```#!/usr/bin/perl -wTl

use strict;
use warnings;

use bignum 'bexp';  ## get the latest from CPAN
use Memoize;

use constant MAX_POWER  => 30;
use constant MAX_DIGITS => 50;

my \$X = shift || 1;
memoize('my_factorial');

my \$best = bexp( \$X, MAX_DIGITS );

my \$estimate = 1;
for my \$i (1 .. MAX_POWER) {
\$estimate += (\$X ** \$i) / my_factorial( \$i );

print join "\n", (\$i, \$best, \$estimate,
abs( \$best - \$estimate ), q());
}

exit( 0 );

##--------------------------------------------------+
sub my_factorial {
my (\$n) = @_;
return 1 if \$n == 1;
\$n * my_factorial( \$n - 1 );
}
Re: Exponential Function Programming
by swampyankee (Parson) on Nov 23, 2007 at 01:10 UTC

Perl has an exponentiation operator (**, just like Fortran's ;-)), so x**n is easy. I believe, however, that Perl uses the C math library's pow routine (and 0**0 is undefined, and should return NaN, regardless of Perl's behavior, but I digress). In any case, writing a sub to calculate small integer powers, with little concern for efficiency, is quite easy. The factorials require a routine. Don't make the mistake of writing a recursive routine to calculate factorials; they are easily, and much more efficiently, calculated by a for loop.

Neither piece is particularly difficult. Beware, though, that numerical programming can be quite tricky when values get large or small. There is a wealth of information to be had, for example at na net and the Dictionary of Algorithms and Data Structures.

emc

Information about American English usage here and here.

Any Northeastern US area jobs? I'm currently unemployed.

Re: Exponential Function Programming
by pajout (Curate) on Nov 22, 2007 at 19:33 UTC
I think that this is more noble and incomprehensible :>)
```#!/usr/bin/perl
use strict;
use warnings;
sub exp_ {
my \$x = shift;
my (\$d, \$ret, \$i) = (1.0, 1);
while (\$ret - \$d != \$ret) {
\$d *= \$x/++\$i;
\$ret += \$d;
}
return \$ret;
}
for (1..100) {
print "exp(\$_) = ".exp_(\$_)."\n";
}
\$ret - \$d != \$ret is interesting. One would think it's the same as \$d (in boolean context), but it isn't. By testing the effect of \$d (\$ret - \$d != \$ret) instead of \$d itself, the loop can be ended sooner.
```my \$ret = 1;

for my \$d (1e-15, 1e-20) {
printf("%g %d %d\n",
\$d,
( \$d              )?1:0,
( \$ret-\$d != \$ret )?1:0,
);
}
```1e-015 1 1   # Often equivalent.