Skip to content
Snippets Groups Projects
02-exponentielle4.md 8.56 KiB
Newer Older
Nicolas M. Thiéry's avatar
Nicolas M. Thiéry committed
---
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": "428f797fd97eab35723ed43789ccd075", "grade": false, "grade_id": "cell-9aacd071eecda33d", "locked": true, "schema_version": 3, "solution": false}}

# TP : implanter la fonction exponentielle (4/5)

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

## Partie 4 : calcul de l'exponentielle avec une précision fixée ♣

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "9edfd845868254b0b7250f0324d9bd8e", "grade": false, "grade_id": "cell-0749edc234488c4e", "locked": true, "schema_version": 3, "solution": false}}

Dans la partie 2, vous avez défini une fonction `expRang` qui
calcule une approximation de l'exponentielle en tronquant la somme à
un certain rang décidé à l'avance. Cependant le rang nécessaire pour
obtenir une bonne précision dépend du nombre réel $x$ pour lequel on
veut calculer $e^x$. On cherche maintenant à calculer une
approximation de l'exponentielle en fixant la *précision* et non plus
le rang. Pour cela on va écrire une nouvelle fonction d'approximation
de l'exponentielle, dans laquelle le rang auquel on arrête la somme ne
sera pas décidé à l'avance, mais dépendra de l'évolution du calcul
qu'on est en train de faire.

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

:::{admonition} Exercice 1

1. copiez-collez dans les quatre cellules suivantes vos fonctions
   `puissance` et `factorielle` de la [partie 1](02-exponentielle1.md)
   ainsi que `abs` et `egal` de la [partie 3](02-exponentielle3.md);
   si vous avez déjà défini la fonction `egal_relatif`, mettez là ici
   sous le nom `egal` :

```{code-cell}
---
deletable: false
nbgrader:
  cell_type: code
  checksum: 9dbad1fb6194a4cf651984e8ed33df9d
  grade: false
  grade_id: cell-26c2f80b0554f206
  locked: false
  schema_version: 3
  solution: true
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
```

```{code-cell}
---
deletable: false
nbgrader:
  cell_type: code
  checksum: d03351564853b0dbd4044aeb4f8357ab
  grade: false
  grade_id: cell-7e5ba48349f32c00
  locked: false
  schema_version: 3
  solution: true
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
```

```{code-cell}
---
deletable: false
nbgrader:
  cell_type: code
  checksum: ae1bdf35f3db90c901bd4098f57d4868
  grade: false
  grade_id: cell-40ce2ba5515a4b3f
  locked: false
  schema_version: 3
  solution: true
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
```

```{code-cell}
---
deletable: false
nbgrader:
  cell_type: code
  checksum: d9eb60aa93ee354b899aad226435b27f
  grade: false
  grade_id: cell-5658ebbda24de111
  locked: false
  schema_version: 3
  solution: true
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
```

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

:::{admonition} Exercice 1 (suite)
2.  Définissez une nouvelle fonction d'approximation de l'exponentielle
    qui somme les termes $\frac{x^i}{i!}$ jusqu'à ce que le prochain
    terme à ajouter ne modifie pas la valeur de la somme, selon la
    précision donnée :
:::

```{code-cell}
---
deletable: false
nbgrader:
  cell_type: code
  checksum: e87fc3252164787c69ae8a445ff14b08
  grade: false
  grade_id: cell-5b6857150b2f0d95
  locked: false
  schema_version: 3
  solution: true
---
/** Calcul de la fonction exponentielle à precision fixée
 * @param x un nombre de type double
 * @param epsilon un nombre de type double
 * @return e^x avec précision epsilon
**/
double expPrecision(double x, double epsilon) {
    // REMPLACEZ CETTE LIGNE ET LA SUIVANTE PAR VOTRE RÉPONSE
    throw std::runtime_error("À faire");
}
```

```{code-cell}
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: c181420de39a3d84a7aa9da1c4024f6a
  grade: false
  grade_id: cell-acdedc110ac3a389
  locked: true
  schema_version: 3
  solution: false
  task: false
---
double epsilon = 0.000000001
```

```{code-cell}
epsilon = 1e-9
```

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "b63ce0eab42b1ba7f335ab423b39b400", "grade": false, "grade_id": "cell-83bc9f0ce83996e3", "locked": true, "schema_version": 3, "solution": false, "task": false}}

:::{admonition} Exercice 1 (suite)
Le calcul suivant devrait renvoyer $2.718 281 828 459$ :
:::

```{code-cell}
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: 14805f291bc97cc06f4686c02635b0e1
  grade: false
  grade_id: cell-7c1f3a734b045e42
  locked: true
  schema_version: 3
  solution: false
---
expPrecision(1, epsilon)
```

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "8eabb2b188ddf92b5f1f4db80b370b36", "grade": false, "grade_id": "cell-76536f0d66f087bc", "locked": true, "schema_version": 3, "solution": false, "task": false}}

:::{admonition} Exercice 1 (suite)
Il n'y a pas forcément suffisament de chiffres significatifs affichés
pour le vérifier. Faisons à la place un test :
:::

```{code-cell}
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: cddbd8a05eb769065c71af2806ff8dbf
  grade: true
  grade_id: cell-f21a4cde086edd2b
  locked: true
  points: 1
  schema_version: 3
  solution: false
  task: false
---
CHECK( abs( expPrecision(1, epsilon) - 2.718281828459 ) < epsilon )
```

::::{admonition} Exercice 1 (suite)

:::{attention} 

Si vous n'avez pas encore défini `egal_relatif` dans la [partie
3](02-exponentielle3.md), revenez-y et copiez votre fonction en début
de cette feuille sous le nom de `egal` avant de passer à la suite.

:::

Notre test d'arrêt ne garantit en fait pas d'obtenir une précision
relative de epsilon : même si le terme suivant est plus petit que
epsilon, l'accumulation de tous les termes suivants pourrait largement
dépasser epsilon, comme dans les exemples suivants :

::::

```{code-cell}
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: 3458a7cb840a0ec3e18cd083d9d786cf
  grade: true
  grade_id: cell-9841d2b60ca74549
  locked: true
  points: 1
  schema_version: 3
  solution: false
  task: false
---
CHECK( abs(expPrecision(3, epsilon) - 20.085536923 ) < 5*epsilon )
```

```{code-cell}
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: 9ef2607b3820d17a5f0d2fbc0732a5e9
  grade: true
  grade_id: cell-4fb64a4278d2ce62
  locked: true
  points: 1
  schema_version: 3
  solution: false
  task: false
---
CHECK( abs( expPrecision(5, epsilon) - 148.413159102 ) < 50*epsilon )
```

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "29f3c63939a902183db7a9ef432d7305", "grade": false, "grade_id": "cell-f14c9177d33e54ce", "locked": true, "points": 1, "schema_version": 3, "solution": false, "task": true}}

:::{admonition} Exercice 1 (suite)

3.  Comparez vos résultats avec la fonction `exp` de C++ définie dans `cmath` :

:::

```{code-cell}
---
deletable: false
editable: false
nbgrader:
  cell_type: code
  checksum: 2537f1aeb98505f096c75097b9b62f85
  grade: false
  grade_id: cell-2586899de62aebf4
  locked: true
  schema_version: 3
  solution: false
---
#include <cmath>
```

```{code-cell}
exp(5)
```

```{code-cell}
exp(3)
```

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "61175eea6bcbeb9c99086d44c8fd4d0d", "grade": false, "grade_id": "cell-9b25311fb953a3d7", "locked": true, "schema_version": 3, "solution": false}}

## Bilan de la partie 4

Très bien, vous avez défini la fonction exponentielle à précision
fixée. Maintenant étudions sa performance en calculant son temps
d'exécution :

```{code-cell}
%timeit expPrecision(10, 0.00000001);
```

+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "1437a2b557f4fe31589dbcce4311a7c2", "grade": false, "grade_id": "cell-44bb7d35a9655256", "locked": true, "schema_version": 3, "solution": false}}

Dans la [partie 5](02-exponentielle5.md), vous tenterez d'optimiser
cette définition.