[erlang-questions] How to calculate series expansion e^x

Alex Alvarez eajam@REDACTED
Thu Feb 26 01:38:54 CET 2015


Or just simply...


-module(e_fun).

-export ([start/2]).

start (N, X) ->
   1 + step (N - 1, 1, X, 1.0, 0).

step (0, _, _, _, S) -> S;
step (N, NN, X, Z, S) ->
     ZZ = Z * X/NN,
   step (N - 1, NN + 1, X, ZZ, S + ZZ).


Here I'm just reusing the each previous term (ZZ) of the Taylor series 
to compute the next term and then add it up to the sum (S).

Cheers,
Alex


On 02/24/2015 10:27 PM, Richard A. O'Keefe wrote:
> On 25/02/2015, at 11:00 am, Harit Himanshu <harit.subscriptions@REDACTED> wrote:
>
>> I am trying to learn Functional Programming and Erlang by practicing problems available online.
>>
>> One question where I don't know about solving it is
>>
>> The series expansion of ex is given by:
>>
>> 1 + x + x2/2! + x3/3! + x4/4! + .......
>>
>> Evaluate e^x for given values of x, by using the above expansion for the first 10 terms.
>>
>>
>> The problem statement could be found here
>>
>> Can someone guide me how this could be achieved in Erlang?
> The first 10 terms of exp(X) are
>       X    X^2   X^3         X^9
> 1 + --- + --- + --- + ... + ---
>       1     2     6           9!
> This is a polynomial.  We can evaluate it cheaply using
> Horner's Rule.  Any time you have a polynomial to
> evaluate, you should think about using Horner's Rule.
>
>       X     /     X    /      X        /      X  \   \ \
> 1 + --- * | 1 + --- * | 1 + --- * ... | 1 + --- | ...| |
>       1     \     2    \      3        \       9 /   / /
>
> We can see a building block here: 1 + (X/n)*Rest.
>
> So let's make a function for the building block:
>
> step(X, N, Rest)
>    when is_float(X), is_float(N), is_float(Rest) ->
>      1.0 + (X/N)*Rest.
>
> There are 9 steps, which is small enough to do by hand:
> (NINE steps to get TEN terms.  I hope that's clear.)
>
> exp(X)
>    when is_float(X) ->
>      step(X, 1.0, step(X, 2.0, step(X, 3.0,
>      step(X, 4.0, step(X, 5.0, step(X, 6.0,
>      step(X, 7.0, step(X, 8.0, step(X, 9.0, 1.0))))))))).
>
>
> I should point out that this is a lousy way to compute
> exp(X) for abs(X) "large".  Waving hands vaguely, you
> want X^10/10! "small".  The relative error for X = 1.0
> is -1.1e-7, for X = 2.0 is -4.6e-5, and for X = 4.0 is
> a scary -0.0081.
>
> One technique that's used in cases like this is
> RANGE REDUCTION.  e^x = 2^(1.442695... * x).
> To begin, scale x by log of e to the base 2,
> and separate that into an integer part N and a fraction
> part F.  e^x is then 2^(N+F) = 2^N*2^F.  Since F is
> "small", we can use something like this polynomial.
> And then we can use the equivalent of C's ldexp() to
> handle the 2^N* part.  Or we could if Erlang _had_ an
> equivalent of ldexp().
>
> You don't really need the is_float/1 tests; I put them in
> so that the compiler could generate better native code.
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150225/c509df7f/attachment.htm>


More information about the erlang-questions mailing list