Apprendre Haskell en venant de Python : Partie 3 : les Fonctions

Les fonctions, objets de première classe

Sans surprise dans un langage de programmation fonctionnel, les fonctions sont des objets de premières classes : elles se manipulent donc comme toutes les autres variables : une fonction peut prendre en entrée une fonction ou retourner une fonction. Cela permet d’ailleurs de résoudre un problème que l’on va voir sur ce billet.

Notre première fonction

Nous allons commencer par une fonction simple pour illustrer comment on déclare une fonction. Le but est de calculer une fonction f(x) = 3 \cdot \left( x - 1 \right)^2 + 4.

f :: (Num a) => a -> a
f x = 3*(x-1)^2 + 4

On prendra toujours la peine de préciser le type de la fonction avant, comme ici. C’est le plus souvent quelque-chose qui n’est pas indispensable, mais cela est une première forme de commentaire dans son code, et, si l’on choisit bien le nom de ses variables et de ses fonctions, les commentaires peuvent très souvent être réduits.

La déclaration du type de la fonction nous dit qu’elle prend en entrée une variable d’un type numérique et renvoie en sortie une variable de ce même type. La séparation entre le type de la variable d’entrée et celle de sortie se fait par les symboles (->). La classe du type entre parenthèse et l’ensemble de symboles (=>) possède la même signification que précédemment.

La déclaration a ici la forme suivante :

  • on commence par mettre le nom de la fonction,
  • puis on met celle de la valeur d’entrée,
  • après on place un signe égal,
  • et enfin ce que doit renseigner la fonction.

On se retrouve dans un style de programmation beaucoup plus déclarative qu’en Python ou en C. On est également assez proche des notations mathématiques, les parenthèses en moins.

Une fois le script interprété, vous pouvez voir ce que la fonction vous renvoie pour 0, 1 ou -1 en écrivant dans la console :

  • f 0
  • f 1
  • f (-1)

Vous remarquez la grande différence avec le Python : aucun besoin de parenthèse ! Seul le dernier appel a besoin de parenthèse : ceci est dû à la double signification du symbole (-) : il permet à la fois de prendre l’opposé d’un nombre ou de faire une soustraction. L’interpréteur choisit plutôt de considérer toujours la soustraction, donc pour forcer le fait de considérer le nombre -1 comme un seul bloc, on utilise des parenthèses pour supprimer l’ambiguïté.

Qu’une sortie et qu’une entrée !

Tout comme en Python, une fonction ne peut renvoyer qu’une sortie. L’utilisation des n-uplets (ou tuples) permet néanmoins de faire des choses relativement transparentes à ce niveau-là, en Python comme en Haskell, mais on verra cela après.

Par contre, le fait qu’une fonction ne puisse prendre qu’une entrée parait très limitant… Mais c’est plutôt l’inverse. Dans la plupart des cas, ce n’est pas très contraignant, et seule la déclaration de la fonction sera un peu étrange, on va voir cela après. Dans les autres cas, on va même pouvoir profiter de cette particularité pour mettre en place des astuces pas piquées des hannetons. Mais ne brûlons pas les étapes.

D’abord un exemple simple d’une fonction a priori à 2 variables d’entrées : le calcul de l’Indice de Masse Corporel (ou IMC), qui est le ratio entre la masse et le carré de la taille. Pour quelques informations intéressantes sur le sujet, je vous conseille cette vidéo de Risque Alpha.

imc :: (Fractional a) => a -> a -> a
imc m h = m/h^2

[Note : Il n’est pas possible de commencer le nom d’une variable ou d’une fonction par une majuscule en Haskell, d’où le choix effectué ici.]

Vous pouvez grâce à cette fonction calculer l’IMC d’un homme de 90 kg qui mesure 1m90 :

imc 90 1.90

Mais quelle est la signification de tout cela ? Il est impossible de faire une fonction de plusieurs variables ! Comment est possible ce miracle ?

Si dans la plupart des cas, on se contentera de dire que l’on vient de déclarer une fonction qui prend 2 entrées, c’est un abus de langage que la déclaration de la fonction nous permet de préciser : ce que l’on a fait, c’est créer une fonction qui prend en entrée m et renvoie une fonction dépendante de h.

On pourrait réécrire la déclaration de la fonction ainsi :

imc :: (Fractional a) => a -> (a -> a)
(imc m) h = m/h^2

Je laisse cette idée faire un tour dans un coin de votre cerveau et faire un noeud dedans, ce noeud est appelé curryfication. Vous verrez que ce n’est pas le premier que vous aurez grâce (ou à cause) de Haskell. Il est tout à fait possible de curryfier des fonctions en Python, mais l’écriture ce ce type de fonction serait plus lourde qu’en Haskell et ferait intervenir des lambdas.

D’ailleurs, en parlant de lambda !

Lambda et fonction anonyme

Comme en Python, il y a la possibilité de créer des fonctions anonymes grâce à la lettre λ. Mais en Python, on sait qu’on est obligé de mettre en toute lettre lambda pour mettre en place cela (sûrement de part la difficulté de taper des lettres grecs directement grâce au clavier ?). En Haskell, on utile seulement le caractère \ qui ressemble à un λ qui aurait perdu une jambe.

Reprenons notre exemple de l’IMC, et voyons comment expliciter l’opération de curryfication :

imc :: (Fractional a) => a -> (a -> a)
imc m = \h -> m/h^2

On voit bien comment on crée pour chaque valeur de m une fonction dans ces conditions. La création d’une fonction anonyme avec \ est très proche de ce qui ce fait en Python. En plus de pouvoir créer des fonctions à la volée, on verra bien des cas où les fonctions anonymes nous serrons bien utiles.

Opérateurs et fonctions

En fait, l’utilisation d’opérateur est équivalent à l’utilisation de fonction. D’ailleurs, cela peut être explicité en utilisant des parenthèses, on passe d’une utilisation classique infixe à une notation préfixe.

(/) 5 2

Cette écriture est tout à fait équivalente à

5/2

Inversement, une fonction de 2 variables peut-être plus lisible en notation infixe, c’est notamment le cas avec compare, div ou mod. Pour cela, on utilise le signe ` (alt gr 7é) autour de la fonction concernée.

5 `mod` 2

est équivalent à

mod 5 2

Filtrage par motif (pattern matching)

On souhaite définir une fonction qui renvoie le nom du chiffre donné en entrée. On peut alors simplement utiliser les gardes pour mettre en place cette fonction :

ditMonChiffre :: (Integral a) => a -> String
ditMonChiffre n
    | n == 0    = "zero"
    | n == 1    = "un"
    | n == 2    = "deux"
    | n == 3    = "trois"
    | n == 4    = "quatre"
    | n == 5    = "cinq"
    | n == 6    = "six"
    | n == 7    = "sept"
    | n == 8    = "huit"
    | n == 9    = "neuf"
    | otherwise = "Ce n'est pas un chiffre"

Mais Haskell peut reconnaître un motif (en anglais, on parle de pattern) dans l’entrée, et on peut ainsi définir directement un comportement pour certaines entrées :

ditMonChiffre :: (Integral a) => a -> String
ditMonChiffre 0 = "zero"
ditMonChiffre 1 = "un"
ditMonChiffre 2 = "deux"
ditMonChiffre 3 = "trois"
ditMonChiffre 4 = "quatre"
ditMonChiffre 5 = "cinq"
ditMonChiffre 6 = "six"
ditMonChiffre 7 = "sept"
ditMonChiffre 8 = "huit"
ditMonChiffre 9 = "neuf"
ditMonChiffre n = "Ce n'est pas un chiffre"

On voit les possibilités très déclaratives de ce langage comparées à des langages impératifs : on ne fait que déclarer un comportement pour différentes entrées. Attention néanmoins à l’ordre des motifs : on doit toujours aller du particulier au général, car, lors de l’exécution, lorsque le motif a été reconnu, la ligne correspondante est utilisée, et c’est fini. Par exemple, placer la dernière ligne plus tôt changerait complètement le comportement de la fonction.

Pour aller plus loin, on va définir le ou et le et logique en utilisant le filtrage par motif :

et :: Bool -> Bool -> Bool
et True y = y
et False _ = False

ou :: Bool -> Bool -> Bool
ou True _ = True
ou False y = y

Lorsqu’on n’a pas besoin d’une ou de plusieurs variables d’entrée pour le calcul, on utilise le tiret du bas (underscore : _).

Cela permet aussi de définir facilement des fonctions par récurrence. Par exemple la fonction factorielle :

factorielle :: (Integral a) => a -> a
factorielle 0 = 1
factorielle n = n * factorielle (n - 1)

La définition par récurrence des fonctions est centrale en programmation fonctionnelle, mais les bonnes pratiques disent souvent de les éviter. C’est un soucis central : la récursivité est très dangereuse pour la lisibilité de votre code, et la plupart des fonctionnalités souhaitées sont accessibles sans avoir besoin d’expliciter la récursivité.

La récursivité en Haskell doit être comme une bonne charpente : présente, centrale, solide, mais invisible.

La suite…

Il y aura sûrement un billet qui prendra la suite, Haskell étant parmi le langage archétypal de la programmation fonctionnel, la maitrise des fonctions est incontournable à la maitrise du langage.

Apprendre Haskell en venant de Python : Partie 2 : les Types Basiques

Typage statique avec inférence de type vs. typage dynamique : quelle différence pour l’utilisateur ?

Python est un langage à typage dynamique : l’interpréteur déduit à la volée le type des différentes variables sur lesquelles il travaille. Haskell est, lui, un langage à typage statique. Si vous avez fait autre chose que du Python, vous avez sûrement déjà vu ces déclarations de type obligatoire dans de nombreux langages à typage statique.

Ici, nous pourrions déclarer chacune de nos variables, par exemple ainsi :

a = 5 :: Int

Int correspond aux entiers bornés : contrairement à Python, le type Int ne correspond pas à une précision arbitraire. On peut alors tester avec l’interpréteur GHCi le résultat de cette ligne.

Pour connaitre le type d’une variable, vous pouvez écrire dans la console :

:t a

Et il devrait vous répondre :

a :: Int

Le (::) peut se lire : « est de type ».

Mais les concepteurs de Haskell ont fait quelque-chose de différent : le langage est à typage statique, effectivement, mais il utilise un système d’inférence de type. Cela fait que la gestion des types des différentes variables se fait de manière transparente pour le codeur, très proche de ce qui peut se passer en Python.

Mais, allez vous me dire, comment fait-il pour savoir si ma variable est un entier ou un flottant quand je met simplement :

a = 5

Vous pouvez modifier votre script, l’enregistrer et relancer l’interprétation en appuyant de nouveau sur F6. Pour relancer le script, il suffit de taper comme « commande de sortie » :r. Cela permettra de relancer votre script au lieu de fermer la console.

Si vous retentez de lui demander le type de a, alors vous aurez la réponse suivante :

a :: Integer

Integer correspond au nombre entier à précision arbitraire. Donc, n’étant pas sur du type de la variable a, il en a fait un nombre entier le plus général possible.

Et si je rajoute une virgule pour en faire un flottant ?

a = 5.0

Là, quand on teste le type, on obtient :

a :: Double

a est alors un nombre flottant double précision Double (à ne pas confondre avec les nombres flottants à simple précision Float).

Donc, vu qu’il est impossible d’additionner des entiers avec des flottants, ce petit code devrait nous renvoyer une erreur :

a = 5
b = 5.0
c = a + b

Mais ce n’est pas le cas. Pire, quand on regarde le type de a, on a alors un Double !

Quel est ce mystère ?

L’inférence de type, c’est magique !

En fait, il faut se souvenir avec l’interpréteur (ou le compilateur) Haskell, c’est qu’il est extrêmement paresseux. Il ne fera ses calculs que quand on lui demande. Donc a n’est pas un entier à la premier ligne, c’est juste 5, et on verra bien ce qu’on en fait après. De même pour b. Quand enfin on lui demande un calcul à la troisième ligne, alors il est bien obligé de choisir, et pour permettre de faire un calcul correctement, il est obligé de faire de a un flottant (ici un Double).

On peut même lui dire de faire quelque-chose comme cela explicitement :

a = 5 :: (Num x) => x
b = 5.0
c = a + b

Ce que j’ai écrit sur la première ligne, c’est que a doit être d’un type x quelconque, mais que ce type x doit être un nombre (c’est le Num). La flèche => permet de définir un contexte pour le type x. On pourrait lire cette ligne ainsi : a vaut 5 en étant du type x, x étant un nombre.

Il est ainsi préférable de réfléchir ainsi à la création de nos fonctions : non pas quel type elles vont prendre en entrées, mais quelles contraintes devront avoir les types en entrées ?

Les classes de types numériques

On a déjà vu que la classes Num, qui correspond à la classe des nombres : elle permet d’utiliser les opération mathématiques de base : l’addition (+), la multiplication (*), la soustraction (-).

Lorsqu’on peut définir la division classique, on parle alors de Fractional (/). Pour la division euclidienne (`div` pour le ratio, `mod` pour le reste), il faut des entiers Integral (nativement, cela correspond aux types Int et Integer, définis plus tôt).

Note : pour taper `, il faut utiliser la combinaison de touche alt gr + è puis espace sur un clavier azerty classique.

L’ensemble des rationnels peut être codé comme étant un ratio d’entier, et donc faire parties des Fractionnal sans être codé par des nombres à virgule. Les autres Fractionnal sont donc a priori des nombres à virgule flottants Floating (nativement Float et Double). Cela permet également de définir les quelques fonctions mathématiques de bases que l’on verra plus tard.

L’opération de mise à la puissance dépend des cas :

  • L’opérateur (^) correspond à la mise à la puissance par un entier positif d’un nombre quelconque, avec le résultat qui correspondra au type de la base.
  • l’opérateur (**) correspond à la mise à la puissance d’un flottant par un autre nombre flottant.

Suivant les cas, vous pourrez devrez utiliser l’un ou l’autre… C’est là que l’on commence à voir la petite différence entre Python et Haskell concernant le typage : on peut très difficilement utiliser un unique opérateur de puissance pour répondre à tous les cas avec un typage statique.

Pour permettre encore plus de choix dans la création des types, il y a également la notion d’ordre qui permet de distinguer parmi les différents nombres : les nombres que l’on peut ordonner sont des Real, les inversibles (Fractional) que l’on peut ordonner sont des RealFrac et les flottants que l’on peut ordonner sont des RealFloat.

Quelques autres types basiques

Les booléens (Bool)

Comme dans Python, on a une classe qui représente les booléens, et qui correspondent donc à la valeur vrai (True) ou faux (False). En particulier, c’est le résultat de tests d’égalité (==), d’inégalité (/=) [Attention, en Python, c’est (!=)], de tests d’infériorité ou de supériorité stricts (< ou >) ou large (<= ou >=).

Pour faire des opérations booléennes avec ce type, on a : (not) pour le non [comme en Python], (&&) pour le et [à la place de and en Python] et (||) pour le ou [à la place de or en Python]. Pour ceux qui ont déjà fait du C ou du Java, cela ne devrait pas les dépayser.

Les ordres (Ordering)

Les créateurs de Haskell se sont rendus compte que le résultat d’une comparaison pouvait mener à trois résultat :

  • a < b : a est plus petit que b (Less Than en anglais)
  • a = b : a est égal à b (EQual en anglais)
  • a > b : a est plus grand que b (Greater Than en anglais)

Il existe donc un type possédant trois valeurs qui correspond à ce résultat : ces 3 valeurs sont LT, EQ et GT.

Pour comparer une variable a et une variable b, vous pouvez utiliser la fonction compare :

a `compare` b

Les caractères (Char)

Les caractères sont représentés entre simple guillemet (‘) tandis que les chaînes de caractères sont entre double guillemets (« ). Contrairement à Python, les chaînes de caractères ne sont pas un type à part, mais c’est une liste de caractères. Nous verrons bientôt comment gérer les listes. Le codage des caractère est l’Unicode, comme en Python 3.

Note : tous vos fichiers doivent être encodé en UTF8. Pour plus d’explication sur pourquoi, je vous conseille : Sam et Max : L’encoding en Python, une bonne fois pour toute

Quelques autres classes

De nouvelles propriétés apparaissent naturellement, qui vont permettre de préciser les types que l’on pourra utiliser :

  • Eq x, si l’on peut définir l’égalité et la non-égalité sur le type x
  • Ord x, si l’on peut définir un ordre sur le type x
  • Show x, si l’on peut transformer la variable d’un type x en chaîne de caractère
  • Read x, si l’on peut transformer une chaîne de caractère en variable d’une chaîne x

D’autres classes un peu moins importantes :

  • Enum x, si l’on peut énumérer des valeurs du type x
  • Bounded x, si l’on peut définir des plus petites et des plus grandes valeurs du type x

Pour résumer les classes

Je vous propose un petit résumé des classes que l’on a vu sous forme graphique pour bien voir les parentés. A l’intérieur se trouve les opérateurs ou les fonctions emblématiques de la classe. Nous ne les avons pas tous vu, mais vous pouvez déjà en tester certaines sur la console GHCi.

Prelude_class

Cette image a été inspirée de Standard Haskell Classes.

Apprendre Haskell en venant de Python : Partie 1 : l’Installation et la Configuration (exemple avec Notepad++ sur Windows)

Les Téléchargements

On va directement aller dans le vif du sujet : il vous faut un éditeur de bonne qualité (j’utilise Notepad++ sur Windows) et une distribution Haskell. La plus populaire semble être Haskell Platform (qui comprend entre autre le Glasgow Haskell Compiler, GHC, et le système Cabal pour gérer les bibliothèques).

Si vous venez de Python, cela est équivalent à avoir installé un environnement du type Anaconda ou Miniconda.

Si vous avez déjà un éditeur préféré, c’est que Haskell n’est certainement pas votre deuxième langage de programmation, et que vous devriez savoir adapter les conseils suivants à votre éditeur préféré.

Configurer Notepad++

D’abord, il faut s’assurer de pouvoir lancer GHCi (l’interpréteur GHC) avec Notepad++ (Npp). Un gestionnaire d’extension est maintenant présent en natif sur Npp. Donc, grâce à lui, installez NppExec :

  • Une fois Notepad++ installé, lancez-le
  • Allez dans le menu Modules d’extension, puis cliquez sur Gestionnaire des modules d’extension…
  • Recherchez NppExec, cochez la case correspondante, puis cliquez sur installer. [Note : je vous conseille aussi les modules Compare et NppExport].

Cette extension vous permet de lancer une console Windows dans la fenêtre en appuyant sur F6 directement, et cela directement en se plaçant dans le dossier où est placé votre script.

Nous allons commencer par enregistrer le script NppExec qui va nous servir à interpréter un script Haskell. En tapant sur F6, copiez-collez ce texte :

ghci "$(FULL_CURRENT_PATH)"

Enregistrez le sous un nom explicite comme « Haskell interprété ».

Hello World

Pour notre premier script, on va faire simple. Ouvrez grâce à Npp un nouveau fichier texte et enregistrez le avec une extension .hs, comme par exemple mon_premier_programme_Haskell.hs.

main = putStrLn "Hello, World!"

Puis tapez sur F6 : choisissez le script défini précédemment, et lancez-le. Dans la console, tapez main. Et voilà !

Compiler du Haskell

Alors, si vous n’avez vraiment fait que du Python avant, il se peut que vous n’ayez jamais créer d’exécutable, et que vous n’ayez donc fait que de l’interprétation de scripts, et jamais de compilation. Cela va donc être la création de votre premier exécutable dans ce cas-là.

Fermez la console (F6 puis Kill). Et appuyez de nouveau sur F6. Copiez-collez alors ce texte :

ghc --make "$(FULL_CURRENT_PATH)"

Enregistrez le sous un nom explicite comme « Haskell compilé », puis continuez avec OK. Normalement, cela devrait mettre un peu plus de temps. Quelques fichiers ont été créés dans votre dossier normalement, dont une fichier exécutable d’extension .exe. Si vous tentez de double-cliquer dessus, vous risquez de ne pas voir grand chose. En effet, dès le programme terminé, la fenêtre de la console se ferme. Et ce programme ce termine vite…

Refermez la console et appuyez de nouveau sur F6. Copiez-collez alors ce texte :

$(CURRENT_DIRECTORY)\$(NAME_PART).exe

Enregistrez le sous un nom explicite comme « Exécuter exécutable », puis continuez avec OK. Normalement, vous avez votre résultat. Et voilà !

Conclusion

Vous savez déjà :

  • Créer un script Haskell avec l’extension qui va bien (.hs).
  • Lancer l’interpréteur Haskell via un éditeur.
  • Lancer le compilateur Haskell via un éditeur.
  • Exécuter un exécutable via un éditeur.

Vous n’avez peut-être encore aucune idée de ce qu’est Haskell, mais vous avez maintenant tous les outils de base pour vous amuser avec.

Avant de finir

On se retrouve souvent avec des problèmes d’indentation lorsqu’on programme, en particulier lier à la présence de tabulation gênante.

On peut soit supprimer totalement l’indentation automatique de Notepad++ (ce que je trouve exagéré, c’est quand même pratique), soit la configurer correctement. Il ne faut surtout aucune tabulation dans votre script. Pour cela :

  • Dans le menu Paramètres…/Préférences…
  • Allez dans la partie Langage du menu de gauche.
  • Dans la partie droite de la fenêtre, cochez la case Insérer des espaces.
  • Si vous voulez vraiment supprimer l’indentation automatique : allez dans la partie Divers du menu de gauche et cochez la case correspondante.

 

 

 

Fonction de transfert d’un système linéaire continu et invariant : pourquoi ?

Dans ce billet, nous allons nous pencher sur le problème de la définition de ce qu’est une fonction de transfert, comment elle apparait naturellement lorsqu’on parle de systèmes linéaires continus invariants et comment elle est accompagnée par le produit de convolution.

Nous n’irons pas dans tous les arcanes mathématiques, mais je vais essayer de ne pas tricher sur le vocabulaire et vous faire sentir les principaux points qui peuvent être problématiques pour un mathématicien.

Comme dans une grande part de la physique, il est toujours bon d’organiser l’espace sur lequel on va travailler.

Espace des fonctions de carré intégrable

Comme on parle de systèmes continus, on va naturellement s’intéresser à des fonctions du temps e(t) et s(t) : l’entrée et la sortie. Ce sont des fonctions de \mathbb{R} dans \mathbb{R}.

Il ne reste plus qu’à trouver un produit scalaire à cet espace ou à un espace y ressemblant.

Le produit scalaire classique somme le produit de toutes les composantes entre elles. Si on s’inspire de cela, on peut considérer qu’une composante est la valeur à un instant donné. On obtient alors relativement facilement cette idée de produit scalaire :

(f,g) = \int_{\mathbb{R}} f(\tau) \, g(\tau) d\tau = \int_{-\infty}^{+\infty} f(\tau) \, g(\tau) d\tau

Premier problème, il faut limiter un peu l’espace pour que le produit scalaire ait un sens : on doit donc se contenter des fonctions de carré intégrable (l’intégrale sur \mathbb{R} converge).

Avec cela de donné, vous devriez facilement prouver qu’il s’agit bien d’une forme bilinéaire symétrique positive. Le problème arrive dès qu’il s’agit de conclure sur le fait que c’est une forme définie. L’ensemble des formes isotropes est en effet l’ensemble des fonctions f_0 tel que :

0 = (f_0,f_0) = \int_{\mathbb{R}} f_0(\tau)^2 d\tau

Et, tout ce qu’on peut conclure alors, c’est que f_0 est nul presque partout sur \mathbb{R} et non pas que f_0 est la fonction nulle (fonction qui a tout antécédent renvoie la valeur 0).

Pour que notre produit scalaire soit défini, il va donc falloir changer un petit peu notre espace : le zéro devra correspondre à l’ensemble des fonction f dont la mesure est nulle (mesure définie avec notre produit scalaire), que l’on appellera classe d’égalité, car elles ont même mesure. Ce choix de vocabulaire est intéressant pour un physicien : les fonctions d’une classe d’égalité ne peuvent pas être distinguées, car la mesure de la différence entre elles est nulle.

C’est ainsi que nous allons pouvoir (presque) travailler dans l’espace des fonctions de carré sommable L^2(\mathbb{R}) défini comme étant l’ensemble des classes d’égalité de fonctions mesurables définies presque partout sur \mathbb{R} et à valeur dans \mathbb{R} telles que leur carré soit Lebesgue-intégrable sur \mathbb{R}.

Cette histoire de Lebesgue-intégrabilité est juste une précision de mathématicien afin de garantir un certain nombre de propriétés sympathiques sur lesquelles nous ne nous pencherons pas ici.

À la recherche d’une base

Le mieux maintenant pour continuer de travailler est de trouver une base : et le problème est important : si on repense à comment a été créé le produit scalaire que l’on utilise, on a utilisé la notion implicite que la valeur en un instant de notre fonction est comme une composante.

Il nous faudrait donc une fonction :

  • nulle presque partout, sauf en un instant t_0,
  • mais de mesure non nulle.

En fait, l’idéal serait une fonction \delta_{t_0} tel que :

\int_{\mathcal{I}} \delta_{t_0}(\tau)^2 d\tau = \left \{ \begin{matrix} 0 \quad \text{si} \quad t_0 \notin \mathcal{I} \\ 1 \quad \text{si} \quad t_0 \in \mathcal{I} \end{matrix} \right.

Vous aurez beau vous creuser la tête : il est complètement impossible de fabriquer cette fonction… donc on va la créer et ne pas l’appeler fonction, mais distribution. Je vous présente donc la distribution de Dirac \delta tel que :

\int_{\mathcal{I}} \delta(\tau-t_0) d\tau = \left  \{ \begin{matrix} 0 \quad \text{si} \quad t_0 \notin \mathcal{I} \\ 1 \quad \text{si} \quad t_0 \in \mathcal{I} \end{matrix} \right.

Il s’agit d’une abstraction très proche de ce qui peut être utilisé en mécanique (masse ponctuelle), en électromagnétisme (charge ponctuelle) ou en probabilité (probabilité d’une valeur donnée contrairement à une densité de probabilité sur un intervalle).

Ici, on parlera assez naturellement d’une impulsion : un signal infiniment court, mais contenant une certaine énergie.

Je pourrais essayer de vous donner toutes les images possibles, mais le fait est qu’il s’agit juste de la base la plus naturelle du monde pour notre espace vectoriel. On aura en effet :

f(t) = (f,\delta_{t}) = \int_{\mathbb{R}} f(\tau) \, \delta(t-\tau) d\tau

Pour chaque instant t, on a donc un vecteur de la base qui permet la projection d’une fonction afin d’obtenir la valeur en ce point.

Vous pouvez relativement facilement vous convaincre qu’il s’agit d’une famille orthonormée, donc libre.

Pour le côté génératrice, il suffit de décomposer une fonction f suivant cette base, et on obtient donc :

f(t) = \int_{\mathbb{R}} (f,\delta_{\tau}) \delta_{\tau}(t) d\tau

Que l’on peut réécrire bien sûr comme étant :

f(t) = \int_{\mathbb{R}} f(t) \delta(t-\tau) d\tau

Cette expression est donc à la fois la représentation du produit scalaire par un vecteur unitaire de la base (lorsqu’on considère f(t) comme un scalaire), mais aussi la représentation d’un vecteur dans sa base (lorsqu’on considère f(t) comme un vecteur).

Linéarité et invariance : apparition du produit de convolution et de la fonction de transfert

Soit un processus linéaire et invariant noté u qui, à une entrée e(t) associe une sortie s(t).

Si on décompose e(t) dans la base décrite plus haut, on obtient :

e(t) =  \int_{\mathbb{R}} (e,\delta_{\tau}) \delta(t-\tau) d\tau

On a, par définition de e(t), s(t) et u(t) :

s(t) = u(e(t)) =  u \left ( \int_{\mathbb{R}} (e,\delta_{\tau}) \delta(t-\tau) d\tau \right )

Par linéarité, on a donc :

s(t) = \int_{\mathbb{R}} (e,\delta_{\tau}) u \left (\delta(t-\tau) \right ) d\tau 

On a l’invariance aussi à utiliser : elle nous dit que le processus ne varie pas de comportement par décalage temporel, ce qu’on peut écrire :

\text{si} \quad s(t) = u(e(t)) \quad \text{alors} \quad \forall d \in \mathbb{R} \quad s(t+d) = u(e(t+d))

En particulier, si on note h(t) = u(\delta(t)) la réponse du processus à une impulsion, alors on a :

\forall \tau \in \mathbb{R} \quad s(t-\tau) = u(\delta(t-\tau))

Donc, par invariance, on obtient donc :

s(t) = \int_{\mathbb{R}} (e,\delta_{\tau}) h(t-\tau) d\tau 

Si on remplace le produit scalaire par sa valeur, on obtient donc :

s(t) = \int_{\mathbb{R}} e(\tau) h(t-\tau) d\tau 

Cette opération est appelée produit de convolution, noté comme suite :

s(t) = (e*h) = \int_{\mathbb{R}} e(\tau) h(t-\tau) d\tau 

Et h(t), en plus d’être la réponse à une impulsion unitaire du système, cette fonction est également appelée fonction de transfert du processus.

Nous venons de prouver que toute sortie d’un système continu et invariant pouvait donc s’écrire comme le produit de convolution de son entrée et de sa fonction de transfert.

Pour des raisons que je ne détaillerais pas ici, cette relation est aussi valable si e et h n’appartiennent pas à L^2(\mathbb{R}) (ou plutôt la généralisation de L^2(\mathbb{R}) contenant également les distributions).

Transformée de Laplace

La transformée de Laplace permet de passer à l’espace temporel de variable t à l’espace de Laplace L de variable p par la transformation suivante :

F(p) = \mathcal{L} \lbrace f(t) \rbrace = \int_{\mathbb{R}} e^{-pt} f(t) dt

Et malgré tout ce qu’on peut penser, la transformation la plus importante est sans doute celle du produit de convolution :

\mathcal{L} \lbrace e*h \rbrace = \int_{\mathbb{R}} e^{-pt} \int_{\mathbb{R}} e(\tau) \, h(t-\tau) d\tau dt

Par le théorème de Fubini, on passe alors à :

\mathcal{L} \lbrace e*h \rbrace = \int_{\mathbb{R}}  \int_{\mathbb{R}} e^{-pt} e(\tau) h(t-\tau)  dt d\tau

On remplace alors :

e^{-pt} = e^{-pt + p\tau - p\tau} = e^{-p(t - \tau) - p\tau} = e^{-p(t - \tau)} e^{- p\tau}

Cela nous donne donc en réorganisant les termes :

\mathcal{L} \lbrace e*h \rbrace = \int_{\mathbb{R}}  \int_{\mathbb{R}} e^{- p\tau} e(\tau) e^{-p(t - \tau)} h(t-\tau)  dt d\tau

On fait le changement de variable t' = t - \tau et on fait sortir les termes constants (ne dépendant pas de t’) :

\mathcal{L} \{ e*h \} = \int_{\mathbb{R}}  e^{- p\tau} e(\tau) \int_{\mathbb{R}} e^{-pt'} h(t')  dt' d\tau

On reconnait alors une première transformée de Laplace :

\mathcal{L}  \{ e*h \} = \int_{\mathbb{R}}  e^{- p\tau} e(\tau) \mathcal{L} \lbrace h \rbrace d\tau

Or, la transformée de Laplace est une fonction de p indépendant de \tau, on obtient donc :

\mathcal{L}  \{ e*h \} = \mathcal{L} \lbrace h \rbrace \int_{\mathbb{R}} e^{- p\tau} e(\tau)  d\tau

On reconnait alors une seconde transformée de Laplace :

\mathcal{L} \lbrace e*h \rbrace = \mathcal{L} \lbrace h \rbrace \times \mathcal{L} \lbrace e \rbrace

Ou dans la présentation classique que l’on peut donner aux étudiants. Lorsque l’on a un processus linéaire invariant d’entrée e(t) (de transformation de Laplace E(p)) et de sortie s(t) (de transformation de Laplace S(p)), alors il existe une fonction de transfert H(p) tel que :

S(p) =H(p) E(p)

On est passé de produit de convolution à des produits plus conventionnels ce qui apparait plus pratique sans nul doute.

Mais dans le travail demandé, on ne passe presque jamais par les produits de convolution, mais très souvent par des équations différentielles. Ce sera l’occasion de voir d’où viennent un certain nombre de propriétés de la transformée de Laplace et leur utilisation en rapport notamment avec la causalité.

Triomphe de Babar (2) : Preuve de Varignon sans algèbre

Si, dans le billet précédent, la preuve de l’équivalence entre champ vectoriel équiprojectif et relation de Varignon vous a été donnée, cette dernière fait intervenir une bonne part d’algèbre.

Je vais essayer de vous proposer ici une preuve ne faisant intervenir que des concepts de géométrie vectorielle et on pourra en profiter pour voir une méthode pour prouver des relations vectorielles.

Si vous souhaitez une visualisation pour mieux comprendre ce qui se passe, je vous propose cette vidéo.

Tourne le produit mixte

Le produit mixte est invariant par permutation circulaire, on peut réécrire cette propriété comme suis :

\forall \vec{a},\vec{b},\vec{c} \quad \left ( \vec{a} \wedge \vec{b}  \right ) . \vec{c} = \left ( \vec{c} \wedge \vec{a}  \right ).\vec{b} = \left (\vec{b} \wedge \vec{c}  \right ).\vec{a}

Remarquons qu’il suffit de prouver la première égalité pour prouver immédiatement la seconde.

Remarquons que si l’on décompose chaque vecteur dans une base orthonormée, il suffit que la relation soit vraie pour tous les triplet de la base pour qu’elle soit vraie pour tous les vecteurs de l’espace.

Alors, si, à priori, la preuve pourrait sembler complexe, ce n’est plus le cas : elle est, au pire, un petit peu fastidieuse : trois triplets avec trois choix pour chacun représentent 3^3 = 27 cas à traiter. Dans l’idéal, une représentation en cube aurait été parfaite, mais cette dernière est difficilement possible sur le papier.

Nous allons donc nous contenter de trois tableaux 3×3. Voici d’abord ceux de \left ( \vec{a} \wedge \vec{b} \right ) . \vec{c}

\vec{c} = \vec{x}\\ \begin{array}{|c|c|c|c|} \hline \vec{a} \backslash \vec{b} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & \vec{0}.\vec{x}=0 &  \vec{z}.\vec{x}=0 &  -\vec{y}.\vec{x}=0\\ \hline \vec{y} & -\vec{z}.\vec{x}=0 &  \vec{0}.\vec{x}=0 &  \vec{x}.\vec{x}=1\\ \hline \vec{z} & \vec{y}.\vec{x}=0 &  -\vec{x}.\vec{x}=-1 &  \vec{0}.\vec{x}=0\\ \hline \end{array}

\vec{c} = \vec{y}\\ \begin{array}{|c|c|c|c|} \hline \vec{a} \backslash \vec{b} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & \vec{0}.\vec{y}=0 &  \vec{z}.\vec{y}=0 &  -\vec{y}.\vec{y}=-1\\ \hline \vec{y} & -\vec{z}.\vec{y}=0 &  \vec{0}.\vec{y}=0 &  \vec{x}.\vec{y}=0\\ \hline \vec{z} & \vec{y}.\vec{y}=1 &  -\vec{x}.\vec{y}=0 &  \vec{0}.\vec{y}=0\\ \hline \end{array}

\vec{c} = \vec{z}\\ \begin{array}{|c|c|c|c|} \hline \vec{a} \backslash \vec{b} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & \vec{0}.\vec{z}=0 &  \vec{z}.\vec{z}=1 &  -\vec{y}.\vec{z}=0\\ \hline \vec{y} & -\vec{z}.\vec{z}=-1 &  \vec{0}.\vec{z}=0 &  \vec{x}.\vec{z}=0\\ \hline \vec{z} & \vec{y}.\vec{z}=0 &  -\vec{x}.\vec{z}=0 &  \vec{0}.\vec{z}=0\\ \hline \end{array}

Nous allons donc pouvoir les comparer aux tableaux obtenus avec \left ( \vec{c} \wedge \vec{a}  \right ).\vec{b} :

\vec{c} = \vec{x}\\ \begin{array}{|c|c|c|c|} \hline \vec{a} \backslash \vec{b} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & \vec{0}.\vec{x}=0 &  \vec{0}.\vec{y}=0 &  -\vec{0}.\vec{z}=0\\ \hline \vec{y} & \vec{z}.\vec{x}=0 &  \vec{z}.\vec{y}=0 &  \vec{z}.\vec{z}=1\\ \hline \vec{z} & -\vec{y}.\vec{x}=0 &  -\vec{y}.\vec{y}=-1 &  -\vec{y}.\vec{z}=0\\ \hline \end{array}

\vec{c} = \vec{y}\\ \begin{array}{|c|c|c|c|} \hline \vec{a} \backslash \vec{b} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & -\vec{z}.\vec{x}=0 &  -\vec{z}.\vec{y}=0 &  -\vec{z}.\vec{z}=-1\\ \hline \vec{y} & \vec{0}.\vec{x}=0 &  \vec{0}.\vec{y}=0 &  \vec{0}.\vec{z}=0\\ \hline \vec{z} & \vec{x}.\vec{x}=1 &  \vec{x}.\vec{y}=0 &  \vec{x}.\vec{z}=0\\ \hline \end{array}

\vec{c} = \vec{z}\\ \begin{array}{|c|c|c|c|} \hline \vec{a} \backslash \vec{b} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & \vec{y}.\vec{x}=0 &  \vec{y}.\vec{y}=1 &  \vec{y}.\vec{z}=0\\ \hline \vec{y} & -\vec{x}.\vec{x}=-1 &  -\vec{x}.\vec{y}=0 &  -\vec{x}.\vec{z}=0\\ \hline \vec{z} & \vec{0}.\vec{x}=0 &  \vec{0}.\vec{y}=0 &  \vec{0}.\vec{z}=0\\ \hline \end{array}

Le résultat est identique dans les 27 cas, donc la formule est vraie dans le cas général.

On peut noter plusieurs remarques :

  • on aurait pu aisément faire seulement 3 tableaux pour ne représenter que la différence entre le terme de gauche par le terme de droite et constater qu’il est nul pour tous les triplets ;
  • dans ce cas particulier, on peut constater que beaucoup de cas sont nuls trivialement (le produit vectoriel d’un vecteur par lui-même est nul, et le produit vectoriel est orthogonal a ses deux antécédents) : seuls les cas où \vec{a}, \vec{b} et \vec{c} sont différents présentent un résultat non trivial : cela représente seulement 3! = 6 cas ;
  • on peut construire une base ad hoc pour se simplifier les choses et limiter le nombre de cas à étudier : si \vec{a}/\left \Vert \vec{a} \right \Vert est considérée comme le premier élément de la base orthonormée considérée. On peut de la même façon considérer que la deuxième vecteur peut être représenté uniquement grâce aux deux premiers vecteurs de la base grâce au choix du deuxième vecteur de la base (voir la suite).

Preuve du double produit

Prouvons maintenant la formule du double produit vectoriel ainsi :

\left ( \vec{a} \wedge \vec{b} \right ) \wedge \vec{c} = \left (\vec{a}.\vec{c} \right ) \vec{b}- \left (\vec{b}.\vec{c} \right )\vec{a}

La définition de la base se fera ainsi :

  • Dans le cas où \vec{a} et \vec{b} ne sont pas colinéaire, on travaillera dans la base suivante :
    \mathcal{B} = \left ( \vec{x} = \dfrac{\vec{a}}{\left \Vert \vec{a} \right \Vert}, \vec{y} = \dfrac{\vec{b}-(\vec{b}.\vec{x})\vec{x}}{\left \Vert \vec{b}-(\vec{b}.\vec{x})\vec{x} \right \Vert}, \vec{z}=\vec{x}\wedge \vec{y} \right )
  • Si \vec{a} et \vec{b} sont colinéaires et \vec{a} \neq \vec{0}, on travaillera dans n’importe quelle base commençant par le vecteur \vec{x} défini de la même façon.
  • Dans le cas où \vec{a} = \vec{0} et \vec{b} \neq \vec{0}, on définit \vec{y}=\vec{b}/\left \Vert \vec{b} \right \Vert et les deux autres vecteurs de façon quelconque.
  • Si \vec{a} et \vec{b} sont nuls, alors n’importe quelle base convient.

Le but de cette construction est de faire en sorte que, dans tous les cas, le vecteur \vec{a} est porté par \vec{x}, et le vecteur \vec{b} est porté par \vec{x} et \vec{y} et \vec{c} est quelconque. La construction est unpetit peu fastidieuse, mais c’est parce qu’elle demande de prendre en compte les cas particuliers.

Mais, grâce à elle, on se retrouve donc avec seulement 6 cas à étudier au lieu de 27.

Voici d’abord le résultat pour le membre de gauche \left ( \vec{a} \wedge \vec{b} \right ) \wedge \vec{c} :

\vec{a} = \vec{x}\\ \begin{array}{|c|c|c|c|} \hline \vec{b} \backslash \vec{c} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & \vec{0}\wedge\vec{x}=\vec{0} &  \vec{0}\wedge\vec{y}=\vec{0} &  \vec{0}\wedge\vec{z}=\vec{0} \\ \hline \vec{y} & \vec{z}\wedge\vec{x}=\vec{y} &  \vec{z}\wedge\vec{y}=-\vec{x} &  \vec{z}\wedge\vec{z}=\vec{0} \\ \hline \end{array}

Et voici le résultat pour le membre de droite \left (\vec{a}.\vec{c} \right ) \vec{b}- \left (\vec{b}.\vec{c} \right )\vec{a} :

\vec{a} = \vec{x}\\ \begin{array}{|c|c|c|c|} \hline \vec{b} \backslash \vec{c} & \vec{x} &  \vec{y} &  \vec{z}\\ \hline \vec{x} & 1\vec{x}-1\vec{x}=\vec{0} & 0\vec{x}-0\vec{x}=\vec{0} &  0\vec{x}-0\vec{x}=\vec{0} \\ \hline \vec{y} & 1\vec{y}-0\vec{x}=\vec{y} &  0\vec{y}-1\vec{x}=-\vec{x} &  0\vec{y}-0\vec{x}=\vec{0} \\ \hline \end{array}

Les résultats des deux tableaux correspondent, donc on a prouvé notre relation dans une base particulière, donc dans toutes les bases.

Ce n’est surement pas la preuve la plus élégante, mais elle possède un atout que je trouve redoutable : elle permet de vérifier une formule vectorielle floue en moins d’une minute sur un brouillon.

L’orthogonalité vue comme conséquence d’un produit vectoriel

On se pose une équation d’orthogonalité de vecteur tel que :

\vec{a}.\vec{b} = 0

On veut prouver alors que cela implique qu’il existe une famille de vecteur \vec{c} + \lambda \vec{b} tel que :

\vec{c}.\vec{b} = 0 \\ \vec{a} = \left ( \vec{c} + \lambda \vec{b} \right ) \wedge \vec{b}

Le fait que l’ajout du vecteur \lambda \vec{b} ne change rien au résultat est assez évident. L’une des manières de construire cette démonstration est de trouver un vecteur \vec{c} qui convienne.

On propose par exemple, tant que \vec{b} \neq \vec{0}  :

\vec{c} = \dfrac{\vec{b} \wedge \vec{a}}{\vec{b}.\vec{b}}

Vérifions que l’on retrouve bien le bon résultat en utilisant la formule du double produit vectoriel :

\vec{c} \wedge \vec{b} = \dfrac{\vec{b} \wedge \vec{a}}{\vec{b}.\vec{b}} \wedge \vec{b} = \dfrac{(\vec{b}.\vec{b})\vec{a}-(\vec{b}.\vec{a})\vec{b}}{\vec{b}.\vec{b}} = \vec{a}

Dans le cas où \vec{b} = \vec{0}, il suffit de prendre : \vec{c} = \vec{0} par exemple, bien que dans ce cas-là, toutes les résultantes soient possibles.

Il est donc toujours possible de construire une relation de produit vectoriel à partir d’une orthogonalité.

Propriété fondamentale de la fonction différence des moments

Soit une base orthonormée \left ( \vec{i},\vec{j},\vec{k} \right ), une origine O et un champ équiprojectif de moment \mathcal{M}(M).

On pose la fonction \vec{u_O}(M) =\mathcal{M}(M)-\mathcal{M}(0) qui, à tout point de l’espace, associe la différence du moment en ce point par le moment à l’origine O.

Par la relation d’équiprojectivité, on obtient rapidement que :

\vec{u_O}(M).\vec{OM} = 0

Il existe donc une famille de vecteur \vec{R}_O(M) + \lambda \vec{OM} tel que :

\vec{u_O}(M)= (\vec{R}_O(M) + \lambda \vec{OM}) \wedge \vec{OM}

De même pour le point N quelconque aussi : il existe une famille de vecteur \vec{R}_O(N) + \mu \vec{ON} tel que :

\vec{u_O}(N)= (\vec{R}_O(N) + \mu \vec{ON}) \wedge \vec{ON}

Si on soustrait les deux relations précédentes, on obtient donc :

\vec{u_O}(M) - \vec{u_O}(N) = (\vec{R}_O(M) + \lambda \vec{OM}) \wedge \vec{OM} - (\vec{R}_O(N) + \mu \vec{ON}) \wedge \vec{ON}

En repassant par la définition de la fonction \vec{u_O}(M) et en utilisant la propriété d’équiprojectivité du champ des moments, lorsqu’on projette cette équation sur \vec{MN}, on obtient :

0 = \left ( (\vec{R}_O(M) + \lambda \vec{OM}) \wedge \vec{OM} \right ). \vec{MN}- \left ( (\vec{R}_O(N) + \mu \vec{ON}) \wedge \vec{ON}\right ). \vec{MN}

En utilisant l’invariance du produit mixte par permutation circulaire, on obtient :

0 = \left ( \vec{OM} \wedge \vec{MN} \right ) . \left ( \vec{R}_O(M) + \lambda \vec{OM} \right ) - \left ( \vec{ON} \wedge \vec{MN} \right ) . \left (\vec{R}_O(N) + \mu \vec{ON} \right )

Or, on peut réécrire le premier produit vectoriel :

\vec{OM} \wedge \vec{MN} =\vec{OM} \wedge \vec{MN}+\vec{OM} \wedge \vec{OM} = \vec{OM} \wedge \left( \vec{OM}  +\vec{MN} \right) = \vec{OM} \wedge \vec{ON}

De même pour le deuxième produit vectoriel :

\vec{ON} \wedge \vec{MN} = \vec{ON} \wedge \left( \vec{MN}  +\vec{NO} \right) = \vec{ON} \wedge \vec{MO}= \vec{OM} \wedge \vec{ON}

On obtient pour tout point M et N la relation suivante :

\left ( \vec{OM} \wedge \vec{ON} \right ) . \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(N) - \mu \vec{ON} \right ) = 0

C’est cette relation qui sera surtout utilisée par la suite.

Preuve sur 3 points particuliers du repère

Soient les trois points I, J et K définis par :

\vec{OI} = \vec{i}, \quad \vec{OJ} = \vec{j}, \quad \vec{OK} = \vec{k}

Si on remplace le couple M et N par I et J, puis par J et K et enfin par K et I, on obtient les trois relations suivantes, avec les variables \lambda, \mu et \nu qui correspondent respectivement à \vec{OI}, \vec{OJ} et \vec{OK} :

\left ( \vec{OI} \wedge \vec{OJ} \right ) . \left ( \vec{R}_O(I) + \lambda \vec{OI} - \vec{R}_O(J) - \mu \vec{OJ} \right ) = 0 \\ \left ( \vec{OJ} \wedge \vec{OK} \right ) . \left ( \vec{R}_O(J) + \mu \vec{OJ} - \vec{R}_O(K) - \nu \vec{OK} \right ) = 0 \\ \left ( \vec{OK} \wedge \vec{OI} \right ) . \left ( \vec{R}_O(K) + \nu \vec{OK} - \vec{R}_O(I) - \lambda \vec{OI} \right ) = 0

Que l’on peut simplement réécrire :

\left ( \vec{R}_O(I) + \lambda \vec{i} \right ). \vec{k} = \left ( \vec{R}_O(J) + \mu \vec{j} \right ). \vec{k} \\ \left ( \vec{R}_O(J) + \mu \vec{j} \right ). \vec{i} = \left ( \vec{R}_O(K) + \nu \vec{k} \right ). \vec{i} \\ \left ( \vec{R}_O(K) + \nu \vec{k} \right ). \vec{j} = \left ( \vec{R}_O(I) + \lambda \vec{i} \right ). \vec{j}

On se rend déjà compte des égalités suivantes :

\vec{R}_O(I) . \vec{k} = \vec{R}_O(J) . \vec{k} \\ \vec{R}_O(J) . \vec{i} = \vec{R}_O(K) . \vec{i} \\ \vec{R}_O(K) . \vec{j} = \vec{R}_O(I) . \vec{j}

Si on choisit correctement les valeurs de \lambda, \mu, \nu, on obtient un vecteur qui appartient aux trois familles de vecteurs en même temps :

\lambda= \vec{R}_O(J). \vec{i} = \vec{R}_O(K). \vec{i} \\ \mu = \vec{R}_O(K). \vec{j} = \vec{R}_O(I). \vec{j} \\ \nu = \vec{R}_O(I). \vec{k} = \vec{R}_O(J). \vec{k}

Et on a donc un vecteur unique \vec{R}_O(\mathcal{B}) tel que :

\vec{u_O}(I)= \vec{R}_O(\mathcal{B}) \wedge \vec{OI} \\ \vec{u_O}(J)= \vec{R}_O(\mathcal{B}) \wedge \vec{OJ} \\ \vec{u_O}(K)= \vec{R}_O(\mathcal{B}) \wedge \vec{OK}

Il ne reste donc plus qu’à prouver que ceci est vrai pour n’importe quel point M.

Généralisation pour tous les points

Pour un point M  d’abscisse x, d’ordonnée y et de cote z, on obtient en remplaçant le couple M et N par M et I, puis par M et J et enfin par M et K :

\left ( \vec{OM} \wedge \vec{OI} \right ) . \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) = 0 \\ \left ( \vec{OM} \wedge \vec{OJ} \right ) . \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) = 0 \\ \left ( \vec{OM} \wedge \vec{OK} \right ) . \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) = 0

Par invariance du produit mixte par permutation circulaire, on obtient donc :

\left ( \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) \wedge \vec{OM} \right ) . \vec{OI} = 0 \\ \left ( \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) \wedge \vec{OM} \right ) . \vec{OJ} = 0 \\ \left ( \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) \wedge \vec{OM} \ \right ) . \vec{OK} = 0

On retrouve une relation vectorielle projetée sur tous les vecteurs de la base, ce qui prouve donc que :

\left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) \wedge \vec{OM}= \vec{0}

Donc \left ( \vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) \right ) et \vec{OM} sont colinéaires. Que l’on peut réécrire par le fait qu’il existe un réel k tel que :

\vec{R}_O(M) + \lambda \vec{OM} - \vec{R}_O(\mathcal{B}) = k \vec{OM}

Pour \lambda =k, on obtient bien que \vec{R}_O(\mathcal{B}) fait partie de la famille qui permet le calcul de la fonction \vec{u_O}(M).

Indépendance de l’origine

On a donc bien obtenu que pour n’importe quel point M, il existe un unique vecteur \vec{R}_O tel que :

\vec{u_O}(M) =\mathcal{M}(M)-\mathcal{M}(0) = \vec{R}_O \wedge \vec{OM}

Donc cela est aussi vrai pour le point N quelconque aussi :

\vec{u_O}(N) =\mathcal{M}(N)-\mathcal{M}(0) = \vec{R}_O \wedge \vec{ON}

Si l’on soustrait ces deux relations, on obtient alors :

\mathcal{M}(M)-\mathcal{M}(N) = \vec{R}_O \wedge \vec{MN}

On voit que le point origine n’intervient plus : la résultante est indépendante de ce point arbitraire, et on peut la renomer simplement \vec{R} tel que, quels que soient deux points M et N :

\mathcal{M}(M)-\mathcal{M}(N) = \vec{R} \wedge \vec{MN}

Le triomphe de Babar ou la preuve de Varignon

Toutes les personnes ayant subi un cours classique de mécanique en France connaissent cet outil qu’est le torseur… Mais le connait-on si bien que cela ?

Ce petit billet est juste là pour rappeler quelques propriétés et mettre en place quelques preuves qui sont souvent très vite passées sous silence, soit par manque d’intérêt pratique, soit par manque de fondement mathématique chez les étudiants.

Si vous souhaitez une visualisation pour mieux comprendre ce qui se passe, je vous propose cette vidéo.

Définition d’un torseur

Un torseur est un champ vectoriel équiprojectif. Je sais, cela commence fort… mais qu’est-ce que cela signifie ? Un champ vectoriel est juste une fonction qui associe un vecteur à chaque point d’un espace. Ainsi, l’accélération de la pesanteur est un champ vectoriel : en chaque point de l’espace, on peut y associer une norme et une direction. Dans le cas d’un torseur, on parlera de moment en un point.

La propriété d’équiprojectivité oblige à se tourner vers la notion d’espace vectoriel euclidien, c’est-à-dire un espace muni d’un produit scalaire, c’est-à-dire une forme bilinéaire (linéaire suivant chacune de ses deux entrées), symétrique (\vec{u}.\vec{v} = \vec{v}.\vec{u} ), définie (\vec{u}.\vec{u} = 0 ssi  \vec{u} = \vec{0}) et positive (\vec{u}.\vec{u} \geq 0).

Parmi les propriétés fondamentales du produit scalaire, l’une des plus importantes est la projection, qui permet de passer d’une équation vectorielle à une version scalaire ne représentant que ce qui se passe  suivant une direction particulière.

L’équiprojectivité : le latin pour les nuls

Du latin aequus (égal), et projicio (jeter en avant, projacio). Il s’agit donc d’une projection identique de notre champ vectoriel.

La propriété d’équiprojectivité consiste en effet à avoir, pour deux points différents A et B, les moments correspondants (\vec{\mathcal{M}}(A) et \vec{\mathcal{M}}(B)) qui ont la même projection. Mais la question subsiste, suivant quelle direction ? La réponse est la plus simple possible : suivant la direction créée par les deux points pris au hasard.

On peut donc réécrire la propriété fondamentale d’un champ équiprojectif comme étant :
\forall (A,B) \quad\vec{\mathcal{M}}(B).\vec{AB} = \vec{\mathcal{M}}(A).\vec{AB}

Mais on sait tous que cette relation est presque anecdotique devant une relation bien plus importante, connue sous le nom civil de relation de Varignon, ou par son nom de scène : formule BABAR :
\forall (A,B) \exists! \vec{R} \quad | \quad \vec{\mathcal{M}}(B) = \vec{\mathcal{M}}(A) + \vec{BA} \wedge \vec{R}

Ce vecteur \vec{R} est appelé résultante. Et, croyez-le ou non, ces deux formulations sont exactement équivalentes (dans un espace de dimension 3). Le fait de prouver qu’un champ vectoriel répondant à la formule de Varignon est bien équiprojectif est presque trivial : si on projette Varignon sur \vec{AB}, on obtient :
\forall (A,B) \quad \vec{\mathcal{M}}(B).\vec{AB} = \vec{\mathcal{M}}(A).\vec{AB} + \vec{BA} \wedge \vec{R}.\vec{AB} = \vec{\mathcal{M}}(A).\vec{AB}

Deux façons possibles, par exemple, pour se convaincre que la deuxième moitié du terme de droite est nulle :

  • le produit scalaire de deux termes orthogonaux est toujours nul et le résultat d’un produit vectoriel est orthogonal à ses deux termes ;
  • le produit mixte résultant a ses trois termes trivialement coplanaires (le volume du parallélépipède engendré par ces trois vecteurs est donc nul).

Nous allons garder le reste du billet pour montrer que la réciproque est vraie : pour cela, nous allons montrer que la fonction \vec{u} : \vec{AB} \rightarrow \vec{u}(\vec{AB}) = \left ( \vec{\mathcal{M}}(B) - \vec{\mathcal{M}}(A) \right ) est un endomorphisme antisymétrique, que tout endomorphisme antisymétrique est forcément linéaire, qu’il se représente donc comme une multiplication par une matrice antisymétrique qui peut donc se résumer par un produit vectoriel.

Si le résultat est connu, et que la preuve n’est pas si difficile que cela, au moins a-t-elle le mérite de brasser de l’algèbre linéaire et de la géométrie vectorielle, dont la maitrise peut permettre de faciliter la résolution de quelques exercices ou problèmes.

L’endomorphisme antisymétrique : parce que le grec, les mathématiciens, ils aiment bien ça aussi !

Pour endomorphisme : du grec ancien : éndon (dedans) et morphè (forme).
Pour antisymétrie : Du grec ancien anti (au lieu de, en comparaison de, contre) et du grec ancien par le latin : symmetria, composé de sýn (avec) et métron (mesure).

Un endomorphisme est juste le nom d’une application dans elle-même : on va ainsi créée l’application qui dépend d’un point d’origine arbitraire O et définie par \vec{u_O} : \vec{OA} \rightarrow \vec{u_O}(\vec{OA}) = \left ( \vec{\mathcal{M}}(A) - \vec{\mathcal{M}}(O) \right ). Elle va bien de l’espace vectoriel (des positions de point) à l’espace vectoriel (des différences de moment).

Un endomorphisme \vec{u_O} est dit antisymétrique s’il possède la propriété suivante :

\forall (\vec{x},\vec{y}) \quad \vec{u_O}(\vec{x}).\vec{y} = - \vec{x}.\vec{u_O}(\vec{y})

Pour ceux qui se souviennent de ce qu’est un endomorphisme adjoint, un endomorphisme antisymétrique a son adjoint qui est également son opposé. Mais cela revient juste à la propriété montrée plus haut.

Pour prouver cette simple propriété, on va créer deux points A et B à partir de deux vecteurs quelconques \vec{x} et \vec{y} tel que : \vec{OA} = \vec{x} et \vec{OB} = \vec{y}. Voyons ce que cela nous donne :

\vec{u_O}(\vec{x}).\vec{y} = \vec{u}(\vec{OA}).\vec{OB}\\ \vec{u_O}(\vec{x}).\vec{y} = \left( \vec{M}(A)-\vec{M}(O) \right).\vec{OB}\\ \vec{u_O}(\vec{x}).\vec{y} = \vec{M}(A).\vec{OB} -\vec{M}(O).\vec{OB}

Par bilinéarité du produit scalaire (distributivité de l’addition).

\vec{u_O}(\vec{x}).\vec{y} = \vec{M}(A).\left(\vec{OA} + \vec{AB}\right) -\vec{M}(O).\vec{OB}\\ \vec{u_O}(\vec{x}).\vec{y} = \vec{M}(A).\vec{OA} + \vec{M}(A).\vec{AB} -\vec{M}(O).\vec{OB}

Par la relation de Chasles, puis l’utilisation de la bilinéarité du produit scalaire (distributivité de l’addition).

\vec{u_O}(\vec{x}).\vec{y} = \vec{M}(O).\vec{OA} + \vec{M}(B)\vec{AB} -\vec{M}(B).\vec{OB}

Par l’équiprojectivité du champ des moments.

\vec{u_O}(\vec{x}).\vec{y} = \vec{M}(O).\vec{OA} + \vec{M}(B).\left(\vec{AB}-\vec{OB}\right)\\ \vec{u_O}(\vec{x}).\vec{y} = \vec{M}(O).\vec{OA} - \vec{M}(B).\left(\vec{OB}+\vec{BA}\right)\\ \vec{u_O}(\vec{x}).\vec{y} = \vec{M}(O).\vec{OA} - \vec{M}(B).\vec{OA}

Par bilinéarité du produit scalaire (factorisation), puis utilisation de la relation de Chasles.

\vec{u_O}(\vec{x}).\vec{y} = \left( \vec{M}(O)-\vec{M}(B) \right).\vec{OA}\\ \vec{u_O}(\vec{x}).\vec{y} = -\left( \vec{M}(B)-\vec{M}(O) \right).\vec{OA}\\ \vec{u_O}(\vec{x}).\vec{y} = -\vec{u_O}(\vec{OB}).\vec{OA}\\ \vec{u_O}(\vec{x}).\vec{y} = -\vec{u_O}(\vec{y}).\vec{x}

Par bilinéarité du produit scalaire (factorisation), puis utilisation de la définition de l’endomorphisme \vec{u}(\vec{OB}) et enfin par définition des positions des points A et B.

Notre endomorphisme est donc antisymétrique… Et cela tombe très bien, parce qu’il est alors linéaire, ce qui va nous apporter beaucoup pour la suite.

Linéarité et Chasles : bye-bye l’arbitraire de l’origine

Tout endomorphisme antisymétrique est linéaire. Ceci se prouve assez facilement une fois que l’on se souvient d’une certaine propriété, qui peut sembler évidente mais que l’on va néanmoins prouver ici par souci d’exhaustivité : lorsqu’une relation vectorielle est vraie suivant toutes les projections possibles, alors elle est vraie.

En langage mathématique, on obtient donc le théorème suivant :

\forall \vec{x} \quad \vec{a}.\vec{x} = \vec{b}.\vec{x} \Leftrightarrow \vec{a} = \vec{b} \\

La réciproque est bien sûr trivialement vraie. L’implication peut sembler évidente à beaucoup de monde également, mais en faire une preuve complète en fait un bon exercice pour citer clairement les propriétés du produit scalaire utilisé et permettre de généraliser ce résultat même à des espaces vectoriels infinis. En effet, toutes les preuves précédentes et les deux qui vont suivre sont également valable dans un espace infini.

\forall \vec{x}\quad \vec{a}.\vec{x} = \vec{b}.\vec{x}

On met en facteur en faisant apparaître un zéro en terme de gauche :

(\vec{a}-\vec{b}).\vec{x} =0

En particulier, la propriété est vrai pour \vec{x} = \vec{a}-\vec{b} :
(\vec{a}-\vec{b}).(\vec{a}-\vec{b}) =0

Or le produit scalaire est une forme définie (\vec{u}.\vec{u} = 0 ssi  \vec{u} = \vec{0}), d’où l’on déduit:
\vec{a}-\vec{b} = \vec{0}

Et donc on peut conclure :

\vec{a} = \vec{b}

Autrement dit, si une chose est vraie suivant tous les points de vue, cette chose est vraie. Les philosophes pourraient encore débattre, les mathématiciens non…

Revenons-en au cœur du problème : tout endomorphisme antisymétrique est linéaire. On sait, par l’antisymétrie de l’endomorphisme \vec{u_O} :

\forall (\vec{x},\vec{y},\vec{z}) \\ \vec{u_O}(\lambda\vec{x}+\vec{y}).\vec{z} = -\left (\lambda\vec{x}+\vec{y} \right ).\vec{u_O}(\vec{z})

On utilise ensuite la bilinéarité du produit scalaire :

\vec{u_O}(\lambda\vec{x}+\vec{y}).\vec{z} = -\lambda\, \vec{x}.\vec{u_O}(\vec{z}) -\vec{y}.\vec{u_O}(\vec{z})

Et de nouveau par l’antisymétrie de l’endomorphisme \vec{u_O} :

\vec{u_O}(\lambda\vec{x}+\vec{y}).\vec{z} = \lambda\, \vec{u_O}(\vec{x}).\vec{z} +\vec{u_O}(\vec{y}).\vec{z} \\ \vec{u_O}(\lambda\vec{x}+\vec{y}).\vec{z} = \left ( \lambda\, \vec{u_O}(\vec{x})+\vec{u_O}(\vec{y}) \right ).\vec{z}

Et cette dernière équation étant vraie quelque-soit \vec{z}, on en conclue par le théorème rapidement présenté en début de paragraphe que :

\vec{u_O}(\lambda\vec{x}+\vec{y}) = \lambda\, \vec{u_O}(\vec{x})+\vec{u_O}(\vec{y})

Autrement dit, l’endomorphisme \vec{u_O} est linéaire.

Et de là tombe ce qui a pu vous sembler comme la pire escroquerie que l’on ne vous ait jamais vendue : l’endomorphisme \vec{u_O} est dépendant du point O, choix complètement arbitraire. Et l’on n’a jamais vu en mécanique la résultante d’un torseur dépendre de l’origine.

Pour l’instant, la définition de l’endomorphisme n’était claire que pour des vecteurs positionnés par rapport à l’origine. Essayons de résoudre maintenant un cas différent avec deux points A et B quelconques :

\vec{u_O}(\vec{AB}) = \vec{u_O}(\vec{OB}-\vec{OA})

Par la relation de Chasles.

\vec{u_O}(\vec{AB}) = \vec{u_O}(\vec{OB})-\vec{u_O}(\vec{AO})

Par la linéarité de l’endomorphisme.

\vec{u_O}(\vec{AB}) = \left ( \vec{\mathcal{M}}(B) - \vec{\mathcal{M}}(O) \right )-\left ( \vec{\mathcal{M}}(A) - \vec{\mathcal{M}}(O) \right )

Par l’endomorphisme défini grâce au moment du point obtenu vecteur position.

Et on a donc la propriété suivante, vraie quelque soit le couple de point A, B :

\vec{u_O}(\vec{AB}) = \vec{\mathcal{M}}(B) - \vec{\mathcal{M}}(A)

On voit alors clairement que cet endomorphisme ne dépend aucunement du point d’origine et que n’importe quel autre point nous aurait donné le même endomorphisme.

Rassurés, nous changeons donc \vec{u_O} en \vec{u} pour fêter cela !

Endomorphisme linéaire et matrice : une histoire d’amour fructueuse

On se limitera pour la suite à un espace vectoriel fini de dimension n. On peut donc définir la matrice A = (a_{i,j}) de l’endomorphisme \vec{u} dans une base orthonormée \mathcal{B} = (\vec{e}_1,...\vec{e}_n).

Les coefficients de cette matrice sont, par définition :

a_{i,j} = \vec{e}_i.\vec{u}(\vec{e}_j)

Or par antisymétrie de l’endomorphisme :

\vec{e}_i.\vec{u}(\vec{e}_j) = - \vec{e}_j.\vec{u}(\vec{e}_i)

Donc, a_{i,j} = - a_{j,i}.

Autrement dit, la matrice A est antisymétrique (A^T = -A).

Dans le cas d’un espace de dimension 3, on écrira pour la suite :

A = \begin{pmatrix} 0 & -c & b \\ c & 0 & -a \\ -b & a & 0 \end{pmatrix}

Pseudovecteur et produit vectoriel…

Soit l’entrée \vec{b} de la fonction exprimée dans la base \mathcal{B} sous la forme d’une matrice colonne :

\vec{b} = \begin{pmatrix} x\\ y\\ z \end{pmatrix}

L’image de l’entrée \vec{b} dans la base \mathcal{B} est donnée par le vecteur colonne calculé comme suit :

\vec{u}(\vec{b}) = \begin{pmatrix} 0 & -c & b \\ c & 0 & -a \\ -b & a & 0 \end{pmatrix} \begin{pmatrix} x\\ y\\ z \end{pmatrix} = \begin{pmatrix} -cy+bz\\ cx-az\\ -bx+ay \end{pmatrix}

Et là, on se rend compte que l’on peut réécrire ce calcul comme un produit vectoriel :

\vec{u}(\vec{b}) = \begin{pmatrix} -cy+bz\\ cx-az\\ -bx+ay \end{pmatrix} = \begin{pmatrix} a\\ b\\ c \end{pmatrix} \wedge \begin{pmatrix} x\\ y\\ z \end{pmatrix}

Le fait que le vecteur résultant apparaissant ici est invariant par changement de base orthonormée directe est assez simple et direct.

Résumons donc ce que nous avons trouvé : soit un champ équiprojectif \vec{\mathcal{M}} dans un espace euclidien de dimension 3 : il existe alors un unique vecteur résultant \vec{R} tel que :

\forall (A,B)   \quad \vec{\mathcal{M}}(B) -\vec{\mathcal{M}}(A) = \vec{R} \wedge \vec{AB}

On a bien prouvé la relation de Varignon pour tous les torseurs définis dans un espace de dimension 3.

Mais on peut remarquer une petite « triche » : quand on passe d’une matrice à un produit vectoriel, il y a toute une notion qui apparaît très importante : celui de l’orientation de la base !

Ainsi apparaît la notion du pseudovecteur (ou vecteur axial) qui est un vecteur dont le sens dépend de l’orientation du trièdre de référence. Comme le vecteur position est toujours un vecteur « vrai » (appelé aussi vecteur polaire), dans un torseur, soit la résultante, soit le moment est un pseudovecteur.

On les reconnaît facilement, c’est ceux que les étudiants ont le plus de mal à comprendre : vecteur vitesse angulaire (résultante du torseur cinématique), moment d’une force (moment du torseur des efforts), moment cinétique et dynamique (moment des torseurs cinétiques et dynamique bien sûr). Et l’on voit par là que le problème que peuvent avoir certains étudiants est peut-être qu’intuitivement, ils ont compris que ce n’était pas tout à fait des vecteurs comme les autres (le signe dépend du sens trigonométrique, forcément choisi arbitrairement, si vous en doutez, regardez vous dans un miroir et faites des moulinets avec les bras).

À noter que ces notions de pseudovecteurs peuvent utilement être réutilisées dans d’autres branches de la physique qui utilise le rotationnel : l’électromagnétisme ou la mécanique des fluides par exemple.

Conclusion

Au départ était la curiosité de répondre à cette question qui traînait dans un coin de ma tête depuis une bonne dizaine d’année : en quoi la relation de Varignon et l’équiprojectivité sont-elles équivalentes.

Au final, j’ai eu le droit à des révisions sur les endomorphismes linéaires et la découverte de nouveaux concepts qui prennent bien plus de sens quand on comprend d’où ils viennent.

EVER 2016: Special Session on Offshore and Marine Renewable Energy: Conversion and Transmission

logo_everEleventh International Conference on Ecological Vehicles and Renewable Energies

EVER2016, April 6-8, 2016, Grimaldi Forum, Monaco

Call for Contributions to the Special Session on Offshore and Marine Renewable Energy: Conversion and Transmission

by Sara Armstrong (MaREI, University College Cork)
and Thibaut Kovaltchouk (G2Elab)

Thematic Areas: The proposed special session is an opportunity for researchers coming from academia or industry involved in the emerging field of marine energy conversion. Topics of interest of this special session include, but are not limited to:

  • Innovative concepts, component and topologies for energy conversion from offshore natural resources, such as wind, waves, tides, thermal difference and salinity gradient, with special interest for hybrid solutions.
  • Advanced control strategies ensuring increased power extraction and/or improvement in the power quality.
  • Grid code compliance.
  • Reliability, diagnostic and aging in offshore renewable energy conversion.
  • Design and sizing of system or components.
  • Farm layouts and AC or DC transmission schemes for offshore renewable energy farms.
  • Energy storage solutions for offshore energy applications.
  • Modeling to represent marine resources.
  • Real case studies and contributions on the state of advancement of on-going projects.
  • Life cycle analysis (economical and/or environmental).
  • Social acceptance and maritime governance

Submission: Prospective authors are kindly invited to submit a comprehensive extended abstract of two to three A4 pages, written in English, one-column format, including author name(s), mailing address, and e-mail address. There is no specific template. Abstracts should be submitted directly to the special session organizers: s.armstrong@ucc.ie, thibaut.kovaltchouk@g2elab.grenoble-inp.fr. Please write “EVER Submission” in the email subject line.

Important Dates: November 22, 2015 Abstract submission
December 20, 2015 Provisional Acceptance
January 17, 2016 Full paper submission
January 31, 2016 Final acceptance

Présentation de la soutenance de thèse / PhD defense presentation

beamer_slide_titrebeamer_slide_titre_en

Présentation de la soutenance (en français)
PhD defense presentation (in English)

page_gardeManuscrit de thèse (en français) / PhD thesis manuscript (in French)

Some photos were taken by Abdallah Darkawi (thanks to him!) during the presentation and the questions :

The jury :

jury_3jury_4jury_1jury_2
From left to right:
– Bernard Multon, ENS Rennes, Doctoral advisor
– Hamid Ben Ahmed, ENS Rennes, Doctoral advisor
– Delphine Riu, Ense3, Manuscript examiner
– Mohamed Benbouzid, Université de Brest, Jury president
– Jean-Michel Vinassa, Institut Polytechnique de Bordeaux, Manuscript examiner
– Muriel Primot, Université de Nantes, Doctoral advisor
– Aurélien Babarit, École Centrale de Nantes, Thesis examiner
– Judicaël Aubry, ESTACA, Doctoral advisor

The audience :

public_1public_2

The candidate :

docteur_2docteur_1

Soutenance de thèse de doctorat / PhD defense

Contributions à la co-optimisation contrôle-dimensionnement sur cycle de vie sous contrainte réseau des houlogénérateurs directs

le 9 juillet 2015, 09h30
ENS Rennes, Salle du conseil

Soutenance de thèse devant le jury composé de :

  • M. BENBOUZID Mohamed El Hachemi, Professeur des universités, LBMS, Brest, Examinateur
  • Mme RIU Delphine, Professeur des Universités, G2Elab, Grenoble, Rapporteur
  • M. VINASSA Jean-Michel, Professeur des Universités, IMS, Bordeaux, Rapporteur
  • M. BABARIT Aurélien, Ingénieur de recherche, Ecole Centrale de Nantes, Nantes, Examinateur
  • M. AUBRY Judicaël, Enseignant-chercheur, ESTACA, Laval, Co-encadrant
  • Mme PRIMOT Muriel, Maître de Conférences, Université de Nantes, Nantes, Co-encadrante
  • M. BEN AHMED Hamid, Maître de Conférences HDR, ENS Rennes, Bruz, Co-directeur de thèse
  • M. MULTON Bernard, Professeur des Universités, ENS Rennes, Bruz, Directeur de thèse

Résumé :

Les travaux de thèse traitent de la minimisation du coût du kWh par houlogénération directe à chaîne électrique directe, enjeu crucial pour la viabilité économique de cette technologie. Malgré la simplicité d’une telle chaîne, le principe de conversion, utilisant un système oscillant, induit des fluctuations importantes de la puissance produite. Sans précautions, ces fluctuations peuvent mener à une faible efficacité de la récupération globale, à un vieillissement accéléré en cyclage des composants fragiles de la chaîne électrique ainsi qu’à un non-respect des contraintes réseau.

Continuer à lire … « Soutenance de thèse de doctorat / PhD defense »