Search

J’utilise MATLAB depuis plus de 25 ans. (Et avant cela, j’ai même utilisé MATRIXx, une tentative tardive et non regrettée de spinoff, ou peut-être d’arnaque). Ce n’est pas le premier langage dans lequel j’ai appris à programmer, mais c’est celui avec lequel j’ai grandi sur le plan mathématique. Connaître MATLAB a été très bénéfique pour ma carrière.

Cependant, il est impossible d’ignorer la montée en puissance de Python dans le calcul scientifique. MathWorks doit penser la même chose : non seulement ils ont ajouté la possibilité d’appeler Python directement à partir de MATLAB, mais ils ont adopté emprunté certaines de ses caractéristiques de langage, telles que la diffusion plus agressive pour les opérandes des opérateurs binaires.

On en est arrivé à un point où je me suis interrogé sur mon utilisation continue de MATLAB à la fois dans la recherche et l’enseignement. Pourtant, tant de choses m’y viennent facilement, et j’ai tellement investi dans des matériaux pour cela, qu’il était difficile de rallier la motivation pour vraiment apprendre quelque chose de nouveau.

Entrez dans le manuel basé sur MATLAB que j’ai coécrit pour l’introduction aux mathématiques computationnelles. Le livre a plus de 40 fonctions et 160 exemples de calcul, et il couvre ce que je pense être une base complète dans l’utilisation de MATLAB pour le calcul scientifique numérique. Donc, en partie pour m’améliorer et en partie pour accroître l’utilité du livre, j’ai entrepris cette année de traduire les codes en Julia et en Python. Cette expérience m’a conduit à une perspective particulière sur les trois langages en relation avec le calcul scientifique, que j’essaie de saisir ci-dessous.

Je vais surtout mettre de côté les questions de coût et d’ouverture. MATLAB, contrairement à Python et Julia, n’est ni sans bière ni sans parole. Il s’agit en effet d’une distinction énorme – pour certains, une distinction dispositive – mais je veux considérer les mérites techniques. Pendant de nombreuses années, MATLAB a été bien supérieur à n’importe quel produit gratuit dans un certain nombre de domaines très utiles, et si vous vouliez être productif, alors le coût ne comptait pas. C’est une considération distincte de l’attrait platonique d’un langage et d’un écosystème.

Lorsque vous mettez le coût de côté, un cadre utile pour beaucoup de différences entre ces langages réside dans leurs origines. MATLAB, le plus ancien des efforts, a donné la priorité aux mathématiques, en particulier aux mathématiques orientées numériquement. Python, qui a été lancé pour de bon à la fin des années 1980, a mis l’accent sur l’informatique. Julia, qui a commencé en 2009, a entrepris de trouver un meilleur équilibre entre ces côtés.

MATLAB

À l’origine, chaque valeur dans MATLAB était un tableau de nombres à virgule flottante en double précision. Les deux aspects de ce choix, tableaux et virgule flottante, étaient des décisions de conception inspirées.

La norme IEEE 754 pour la virgule flottante n’a même pas été adoptée avant 1985, et la mémoire était mesurée en K, et non en G. Les doubles en virgule flottante n’étaient pas la manière la plus efficace de représenter les caractères ou les entiers, mais c’était ce que les scientifiques, les ingénieurs et, de plus en plus, les mathématiciens voulaient utiliser la plupart du temps. En outre, il n’était pas nécessaire de déclarer des variables ni d’allouer explicitement de la mémoire. Laisser l’ordinateur s’occuper de ces tâches, et se débarrasser des types de données, libérait votre cerveau pour penser aux algorithmes qui allaient opérer sur les données.

Les tableaux étaient importants parce que les algorithmes numériques en algèbre linéaire commençaient à s’imposer, sous la forme de LINPACK et EISPACK. Mais y accéder avec le porte-étendard du calcul scientifique, FORTRAN 77, était un processus en plusieurs étapes qui impliquait de déclarer des variables, d’appeler des routines au nom cryptique, de compiler le code, puis d’examiner les fichiers de données et de sortie. Écrire une multiplication matricielle sous la forme A*B et obtenir la réponse imprimée immédiatement a changé la donne.

MATLAB a également rendu les graphiques faciles et beaucoup plus accessibles. Pas de bibliothèques spécifiques à la machine avec des appels de bas niveau, juste plot(x,y) et vous voyiez à peu près ce que toute autre personne avec MATLAB verrait. Il y a eu d’autres innovations, comme les nombres complexes intégrés, les matrices éparses, les outils pour construire des interfaces graphiques multiplateformes et une suite de pointe de solveurs ODE, qui ont fait de MATLAB l’endroit où faire du calcul scientifique à la vitesse de la pensée.

Cependant, la conception qui était idéale pour les calculs interactifs, même longs, n’était pas toujours propice à l’écriture de bons logiciels performants. Le déplacement des données entre de nombreuses fonctions nécessitait de jongler avec de nombreuses variables et de consulter fréquemment la documentation sur les arguments d’entrée et de sortie. Une fonction par fichier disque dans un espace de noms plat était d’une simplicité rafraîchissante pour un petit projet, mais un casse-tête pour un grand projet. Certains schémas de programmation (vectorisation, pré-allocation de mémoire) devaient être appliqués si l’on voulait éviter les goulots d’étranglement en termes de vitesse. Le calcul scientifique s’appliquait désormais à beaucoup plus de domaines, avec de grandes quantités de différents types de données natives. Etc.

MathWorks a répondu en continuant d’innover au sein de MATLAB : fonctions en ligne, fonctions imbriquées, fermetures de variables, nombreux types de données, fonctionnalités orientées objet, frameworks de tests unitaires, et ainsi de suite. Chaque innovation était probablement la solution à un problème important. Mais l’accumulation de 40 ans de ces changements a eu pour effet secondaire d’éroder la simplicité et l’unité du concept. En 2009, j’ai écrit un livre qui couvrait assez bien ce que je considérais comme l’essentiel de MATLAB en moins de 100 pages. Pour autant que je sache, tous ces éléments sont toujours disponibles. Mais vous devez en savoir beaucoup plus maintenant pour vous dire compétent.

Python

Dans un sens, l’histoire de Python semble être presque une image miroir de celle de MATLAB. Tous deux présentaient une ligne de commande interactive (aujourd’hui largement appelée REPL, pour « read-eval-print loop ») et l’absence de déclarations de variables et de compilation. Mais MATLAB a été créé comme un terrain de jeu pour les analystes numériques, tandis que Python a été créé en pensant aux hackers. Chacun a ensuite évolué vers l’autre public par le biais de révisions et d’extensions.

À mon sens, Python manque encore d’attrait mathématique. Vous avez de la laideur et des petits désagréments tels que ** au lieu de ^, @ pour la multiplication matricielle (une innovation récente !), un shape plutôt que la taille d’une matrice, un stockage orienté ligne, etc. Si vous pensez que V.conj().T@D**3@V est une manière élégante d’écrire $V^*D^3V$, alors vous avez peut-être besoin de voir un médecin. Et il y a l’indexation zéro (par opposition aux index qui commencent à 1). J’ai lu les arguments, et je ne les trouve pas décisifs. Il s’agit clairement d’une question de préférence – l’objet de guerres saintes en ligne – parce que vous pouvez citer des exemples disgracieux pour chaque convention. Ce que je trouve décisif est que nous avons des décennies de pratique mathématique indexant les vecteurs et les matrices à partir d’un, et la plupart des pseudocodes font cette hypothèse.

Au delà des petits désagréments, je trouve l’écosystème Python+NumPy+SciPy kludgy et incohérent. La pièce à conviction A est le fait qu’en dépit du fait que le langage est plutôt consacré à l’orientation objet, il existe une classe de matrice, et pourtant son utilisation est découragée et sera dépréciée. Peut-être que MATLAB m’a simplement corrompu, mais je trouve que les matrices sont un type d’objet suffisamment important pour être conservé et promu. L’un des principaux arguments de vente de la POO n’est-il pas que vous pouvez demander à * de faire des choses différentes pour les tableaux et les matrices ? Il existe de nombreuses autres infélicités à cet égard. (Pourquoi ai-je besoin d’une commande appelée spsolve ? Ne puis-je pas simplement appeler solve sur une matrice éparse ? Et ainsi de suite.)

Il y a aussi des endroits où l’écosystème numérique me semble un peu mince. Par exemple, les solveurs de quadrature et d’ODE ressemblent à un ensemble minimal en 2019. AFAICT il n’y a pas de méthodes pour les DAE, les DDE, les solveurs symplectiques ou les solveurs implicites qui permettent des itérations internes de Krylov. Jetez un coup d’œil aux références de ces fonctions ; elles ont pour la plupart 30 ans ou plus – elles sont encore bonnes, mais très loin d’être complètes. Le paquet Matplotlib est un travail incroyable, et pendant un certain temps, il semblait meilleur que MATLAB, mais je trouve qu’il manque encore beaucoup de 3D.

Certains experts soutiennent qu’il y a des raisons profondes pour lesquelles le code Python a du mal à suivre en vitesse d’exécution avec les langages compilés. Je suis amusé par les résultats de la recherche de « python est trop lent ». Les défenseurs de Python avancent les mêmes arguments et s’excusent comme on le faisait pour MATLAB à l’époque. Cela ne veut pas dire qu’ils ont tort, mais il y a plus qu’un simple problème de perception.

Je pense comprendre pourquoi Python a été si excitant pour de nombreuses personnes dans le calcul scientifique. Il a une certaine syntaxe et une puissance proche de MATLAB, disponible à partir d’un REPL. Il a de grands outils autour de lui et joue bien avec d’autres langages et domaines de l’informatique. Il offre tout cela gratuitement et avec une bien meilleure reproductibilité à long terme. Clairement, il fonctionne bien pour beaucoup de gens qui voient probablement peu de raisons de changer.

Mais pour les choses que je sais faire en informatique scientifique, Python ressemble beaucoup plus à une corvée à apprendre et à utiliser que ce à quoi je suis habitué. Nous ne saurons pas avant un certain temps s’il va continuer à balayer la communauté ou s’il a déjà approché son apogée. Je n’ai pas de pouvoirs spéciaux de prédiction, mais je suis baissier.

Julia

Julia a les avantages et les inconvénients d’être un retardataire. J’applaudis les créateurs de Julia pour avoir pensé qu’ils pouvaient faire mieux :

Nous voulons un langage qui soit open source, avec une licence libérale. Nous voulons la vitesse de C avec le dynamisme de Ruby. Nous voulons un langage homoiconique, avec de vraies macros comme Lisp, mais avec une notation mathématique évidente et familière comme Matlab. Nous voulons quelque chose d’aussi utilisable pour la programmation générale que Python, d’aussi facile pour les statistiques que R, d’aussi naturel pour le traitement des chaînes de caractères que Perl, d’aussi puissant pour l’algèbre linéaire que Matlab, d’aussi bon pour coller des programmes ensemble que le shell. Quelque chose d’extrêmement simple à apprendre, mais qui satisfasse les hackers les plus sérieux. Nous le voulons interactif et nous le voulons compilé.

Dans une large mesure, je crois qu’ils ont réussi. Tard sur la route de la version 1.0, ils ont semblé minimiser un peu le REPL, et il y avait quelques églises presque gratuites loin de MATLAB. (Comment exactement LinRange est mieux que linspace ?) Ce sont des quolibets, cependant.

C’est le premier langage que j’ai utilisé qui va au-delà de l’ASCII. J’éprouve toujours une satisfaction déraisonnable à utiliser des variables comme ϕ et des opérateurs comme . C’est plus que cosmétique ; être capable de ressembler davantage aux expressions mathématiques que nous écrivons est un vrai plus, bien que cela complique un peu l’enseignement et la documentation.

Travailler dans Julia m’a exposé que j’ai pris certaines habitudes de programmation à cause des choix de MATLAB, pas d’une supériorité inhérente. La vectorisation n’est pas naturelle pour beaucoup de choses. C’est révélateur de découvrir dans Julia que vous pouvez vectoriser n’importe quelle fonction juste en ajoutant un point à son nom. La construction d’une matrice par le biais d’une compréhension fait que les boucles imbriquées (ou les astuces meshgrid) ressemblent à des fouets à bogues en comparaison, et éviter une matrice via un générateur pour une simple sommation donne l’impression d’obtenir quelque chose pour rien. (Je suis conscient que Python a des caractéristiques de langage similaires.)

La grande caractéristique de la répartition multiple rend certaines choses beaucoup plus faciles et plus claires que l’orientation objet. Par exemple, supposons que vous ayez des classes Mur et Balle dans un langage traditionnel orienté objet. Quelle classe doit détecter la collision d’une balle avec un mur ? Ou bien avez-vous besoin d’une classe Room pour jouer les arbitres ? Ce genre de questions peut me faire perdre la tête. Avec le dispatching multiple, les données sont emballées dans des types d’objets, mais les méthodes qui opèrent sur les données ne sont pas liées à une classe. Donc

function detect_collision(B::Ball,W::Wall)

connaît les types mais est défini indépendamment d’eux. Il m’a fallu pas mal de programmation pour apprécier à quel point la notion de dispatch multiple est intéressante et potentiellement importante pour étendre le langage.

L’écosystème numérique a évolué rapidement. Mon exemple numéro un est DifferentialEquations.jl, écrit par l’incroyable Chris Rackauckas. Si ce logiciel ne remporte pas bientôt le prix Wilkinson, le système est cassé. Il suffit d’aller sur le site et de se préparer à être converti.

Je n’ai pas encore vu les gros gains de vitesse par rapport à MATLAB que promet Julia. C’est en partie dû à mon inexpérience relative et aux types de tâches que je fais, mais c’est aussi en partie parce que MathWorks a fait un travail incroyable d’optimisation automatique du code. Ce n’est pas un aspect du codage sur lequel je me concentre la plupart du temps, de toute façon.

Programmer dans Julia m’a pris un certain temps pour me sentir à l’aise avec (peut-être que je deviens juste vieux et cristallisé). Il me fait penser aux types de données plus que je ne le voudrais, et il y a toujours le soupçon sournois que j’ai manqué la bonne façon de faire quelque chose. Mais pour une utilisation quotidienne, je suis à peu près aussi susceptible de me tourner vers Julia que vers MATLAB maintenant.

La ligne de fond

MATLAB est la solution d’entreprise, en particulier pour l’ingénierie. C’est probablement encore le plus facile à apprendre pour les tâches numériques de base. Une documentation méticuleuse et des décennies d’outils d’apprentissage contribués comptent définitivement.

MATLAB est la berline BMW du monde du calcul scientifique. C’est cher, et c’est avant de commencer à parler des accessoires (boîtes à outils). Vous payez pour des performances et un service solides comme le roc et sans accroc. Il attire également une quantité disproportionnée de haine.

Python est une camionnette Ford. Il est omniprésent et aimé par beaucoup (aux États-Unis). Il peut faire tout ce que vous voulez, et il est construit pour faire certaines choses que les autres véhicules ne peuvent pas faire. Il y a de fortes chances pour que vous souhaitiez en emprunter un de temps en temps. Mais elle n’offre pas une grande expérience de conduite pure.

Julia est une Tesla. Elle est construite avec l’objectif audacieux de changer l’avenir, et elle le pourrait. Elle peut aussi devenir une simple note de bas de page. Mais en attendant, vous vous rendrez là où vous allez avec style, et avec de la puissance à revendre.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.