TP: Implementing the Exponential Function (1/5)

TP: Implementing the Exponential Function (1/5)#

**Imagine you are developing the new mathematical function library for

Python.** Initially, the only operations you are allowed to use are the

usual arithmetic operations such as + * / %. Our goal today is

to write the function that calculates \(e^x\).

To do this, we use the definition of \(e^x\) as a series (infinite sum):

e^x = \sum_{n=0}^{+\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} +\cdots+\frac{x^n}{n!}+\cdots^^^math_block

It is noted that it is particularly necessary to calculate \(x^n\) as well as \(n!\). This will be

the subject of the first part. In the second part, we will calculate an approximation of

the exponential function by truncating it to a fixed number of terms; for example:

\(e^x \simeq 1+\frac{x^2}{2!}+\frac{x^3}{3!}\)

The accuracy of such an approximation depends greatly on the value of \(x\). In the

part 4 we will use an adaptive method: this time we will fix the desired

relative precision and calculate as many terms as necessary to achieve this

precision. To do this, we will have previously defined – and implemented! – in part 3 what

we mean by relative precision.

Part 1: Power and factorial functions#

The goal of this part is to write the factorielle and puissance functions and to

verify that the expected results are obtained. Complete the

factorielle function below, then check the results of the following cells:

Todo

  • Choisir et homogénéiser la syntaxe pour les docstrings.

Warning

Warning about the result type We want the functions to return floating-point numbers

(float). Indeed, the divisions in the exponential series

require decimal numbers to avoid rounding errors. Furthermore, the

factorials quickly become enormous \((10! = 3 628 800)\), and a float allows for better

handling of these large numbers. We can ensure that the result is a float from its

initialization: resultat = 1.0.

def factorielle(n):
    """ Factorielle
      @param n un entier positif ou nul
      @return la valeur n! en tant que nombre à virgule flottante (float)
    """
    ### BEGIN SOLUTION
    r = 1.0
    for i in range(1, n+1):
        r *= i    # Rappel: c'est équivalent à r = r * i
    return r
    ### END SOLUTION
factorielle(5)
120.0
assert( factorielle(0) == 1   )   # Par convention mathématique
assert( factorielle(3) == 6   )
assert( factorielle(4) == 24  )
assert( factorielle(5) == 120 )
assert( type(factorielle(0)) == float )
### BEGIN HIDDEN TESTS
assert( factorielle(8) == 40320)
### END HIDDEN TESTS

Check the order of magnitude of the following calculation. If the value is aberrant, check the use of the double type at all stages of the calculation.

factorielle(100)
9.33262154439441e+157

Complete the puissance function below, then check the results of the following cells:

Note

In Python, we can directly use

the opérateur puissance ** operator, but here we want to

reimplement the function as a pedagogical exercise.

def puissance( x, n):
    """ Puissance
      @param x un nombre de type float
      @param n un entier positif ou nul
      @return le nombre x^n de type float
    """
    ### BEGIN SOLUTION
    r = 1
    for i in range(n):
        r *= x
    return r
    ### END SOLUTION
puissance(2, 4)
16
assert( puissance(1,  10) == 1     )
assert( puissance(2,   5) == 32    )
assert( puissance(1.5, 3) == 3.375 )

Add tests (always with assert) to verify the limit cases: verify (for

a value of \(x\) of your choice) that \(x^0\) equals \(1\), that \(0^r\) equals \(0\) for \(r\) non-

zero, and that \(0^0\) equals \(1\):

### BEGIN SOLUTION
assert( puissance(3, 0) == 1 )
assert( puissance(0, 3) == 0 )
assert( puissance(0, 0) == 1 )
### END SOLUTION

Part 1 Summary#

You now have the prerequisites to implement the exponential function. You can

now move on to part 2.