Skip to content
Snippets Groups Projects
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
kernelspec:
  display_name: C++17
  language: C++17
  name: xcpp17

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "fc78fbcc6c6f5f0b33ef0083fdca373a", "grade": false, "grade_id": "cell-a5a96caf0e3314b2", "locked": true, "schema_version": 3, "solution": false}}

TP : implanter la fonction exponentielle (5/5)

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "c9514403258c211d52d0811f03e530f6", "grade": false, "grade_id": "cell-bc097d26c9102dde", "locked": true, "schema_version": 3, "solution": false}}

Partie 5 : optimisation ♣️

Dans notre cas, il n'est pas très efficace de réutiliser les fonctions puissance et factorielle : on refait en effet certains calculs de nombreuses fois! En effet, tel que nous avons écrit notre fonction exponentielle, pour calculer x^{r+1} on reprend le calcul du début (nouvel appel à la fonction puissance) sans utiliser le fait qu'on a déjà calculé x^r et que x^{r+1} = x^r \times x (et de même pour le calcul de la factorielle qui est repris du début à chaque appel à la fonction factorielle alors que (r+1)! = r! \times (r+1)).

Pour éviter ces recalculs, nous allons maintenant définir une nouvelle version plus efficace de la fonction exponentielle qui ne fait pas appel aux fonctions puissance ou factorielle.

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "14330926881dfa9906fb9a0509a6e304", "grade": false, "grade_id": "cell-6d56e4530ad5eb9d", "locked": true, "schema_version": 3, "solution": false}}

:::{admonition} Exercice 1

  1. Copiez-collez ici les fonctions abs et egal de la partie 3 : :::
---
deletable: false
nbgrader:
  cell_type: code
  checksum: ac0b78b2f956da68c7faa5a86096939f
  grade: false
  grade_id: cell-11c71a2c606e0da6
  locked: false
  schema_version: 3
  solution: true
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
---
deletable: false
nbgrader:
  cell_type: code
  checksum: 44ec7a6d5779db1d614df76b5f8ee470
  grade: false
  grade_id: cell-f8b3f1f99b27afb6
  locked: false
  schema_version: 3
  solution: true
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

:::{admonition} Exercice 1 (suite) 2. Complétez la fonction ci-dessous qui calcule l'exponentielle à précision donnée sans utiliser de fonction annexe (sauf egal), et en procédant de façon plus efficace. Pour cela, vous aurez besoin de trois variables d'accumulation : celle de la puissance, celle de la factorielle et celle de l'exponentielle. :::

---
deletable: false
nbgrader:
  cell_type: code
  checksum: 907876225de15ea527d95b4db2f0ab72
  grade: false
  grade_id: cell-303a8716a80dcc32
  locked: false
  schema_version: 3
  solution: true
---
/** Calcul rapide de la fonction exponentielle à précision donnée
 * @param x un nombre de type double
 * @param epsilon un nombre de type double
 * @return e^x avec précision epsilon
**/
double expRapide(double x, double epsilon) {
    // REMPLACEZ CETTE LIGNE ET LA SUIVANTE PAR VOTRE RÉPONSE
    throw std::runtime_error("À faire");
}
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: 8d0201184bba0f21e1cc937519951ef5
  grade: false
  grade_id: cell-c96d4c17c02ce941
  locked: true
  schema_version: 3
  solution: false
---
expRapide(5, 0.000000001) // 148.413159
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: e544e90d711df8993da0ea869a5fbdbb
  grade: false
  grade_id: cell-733b09f1d02a12cf
  locked: true
  schema_version: 3
  solution: false
---
expRapide(3, 0.000000001) // 20.085537
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: ee6fce39ac451bf744049ea8b586429b
  grade: false
  grade_id: cell-54872c873b619fe1
  locked: true
  schema_version: 3
  solution: false
---
expRapide(1, 0.000000001) // 2.718282

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "d5946bf20f94f5987f3c8899ada6e0f1", "grade": false, "grade_id": "cell-765bea92acc94ff3", "locked": true, "schema_version": 3, "solution": false}}

:::{admonition} Exercice 1 (suite) 3. Évaluez la performance de la fonction expRapide en utilisant à nouveau timeit. Est-ce vraiment plus rapide? :::

%timeit expRapide(10, 0.00000001);

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "1a57be5a1f128cccfa27b6c566981aa1", "grade": false, "grade_id": "cell-54073acf05987882", "locked": true, "schema_version": 3, "solution": false}}

Bilan

Vous avez maintenant une implantation nettement plus rapide de la fonction exponentielle. Faut-il pour autant toujours tout réimplanter plutôt que de réutiliser ? Non, surtout pas :

«Early optimisation is the root of all evil»

-- Donald Knuth

Ici, on pourrait par exemple obtenir les mêmes performances sans duplication de code par mémoïsation (conserver les valeurs déjà calculées de n! et x^n pour éviter de les recalculer). En général, c'est à traiter au cas par cas, en tenant compte du compromis entre temps de dévelopement et performances requises, des questions de complexité (cf cours à venir), etc.

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f3313388c3a778384dc9d70cd75033d4", "grade": false, "grade_id": "cell-c367cfa1df22e874", "locked": true, "schema_version": 3, "solution": false}}

Vous pouvez maintenant passer à la suite du TP.