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:
Hint
Use a for
loop with a counter and an
[accumulator../boucles/03-compteurs-accumulateurs.md): initialize the accumulator to
\(1.0\), then count from \(1\) to \(10\) by multiplying the accumulator by the value of the
counter each time.
Reminder: if you wish, you can use the shortcut r *= i
for
r = r * i
.
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.