Search

Jeg har brugt MATLAB i over 25 år. (Og før det brugte jeg endda MATRIXx, et sent, ubeklageligt forsøg på en spinoff, eller måske en ripoff). Det er ikke det første sprog, jeg lærte at programmere i, men det er det sprog, som jeg blev voksen med matematisk set. Det har været meget godt for min karriere at kende MATLAB.

Det er imidlertid umuligt at ignorere Pythons fremgang inden for videnskabelig databehandling. MathWorks må føle det på samme måde: Ikke alene har de tilføjet muligheden for at kalde Python direkte fra MATLAB, men de har også lånt nogle af dets sprogfunktioner, f.eks. mere aggressiv udsendelse for operander i binære operatorer.

Det er nået et punkt, hvor jeg har sat spørgsmålstegn ved min fortsatte brug af MATLAB i både forskning og undervisning. Der er dog så meget, der falder mig let der, og jeg har investeret så meget i materialer til det, at det var svært at samle motivation til virkelig at lære noget nyt.

Enter den MATLAB-baserede lærebog, som jeg har været med til at skrive til introduktion til computational math. Bogen har over 40 funktioner og 160 beregningseksempler, og den dækker det, som jeg synes er en grundig grundig basis i brugen af MATLAB til numerisk videnskabelig beregning. Så dels som selvforbedring, dels for at øge bogens anvendelighed, har jeg i år sat mig for at oversætte koderne til Julia og Python. Denne erfaring har ført mig til et særligt perspektiv på de tre sprog i forhold til videnskabelig databehandling, som jeg forsøger at beskrive nedenfor.

Jeg vil for det meste se bort fra spørgsmålene om omkostninger og åbenhed. MATLAB er i modsætning til Python og Julia hverken ølfri eller talefri. Dette er ganske vist en stor forskel – for nogle er det en afgørende forskel – men jeg vil se på de tekniske fordele. I mange år var MATLAB langt bedre end noget gratis produkt på en række meget nyttige måder, og hvis man ønskede at være produktiv, så var det lige meget med prisen. Det er en anden overvejelse end den platoniske appel af et sprog og et økosystem.

Når man ser bort fra omkostningerne, ligger en nyttig ramme for en masse af forskellene mellem disse sprog i deres oprindelse. MATLAB, det ældste af disse bestræbelser, prioriterede matematik, især numerisk orienteret matematik. Python, som begyndte for alvor i slutningen af 1980’erne, gjorde datalogi til sit centrale fokus. Julia, som begyndte i 2009, satte sig for at finde en bedre balance mellem disse sider.

MATLAB

Originalt var hver værdi i MATLAB et array af dobbeltpræcisionsfrivillige tal med flydende komma. Begge aspekter af dette valg, arrays og floating point, var inspirerede designbeslutninger.

IEEE 754-standarden for floating point blev ikke engang vedtaget før 1985, og hukommelsen blev målt i K, ikke G. Floating point-dobbelte tal var ikke den mest effektive måde at repræsentere tegn eller hele tal på, men det var det, som videnskabsmænd, ingeniører og i stigende grad matematikere ønskede at bruge det meste af tiden. Desuden behøvede variabler ikke at blive deklareret, og hukommelse behøvede ikke at blive eksplicit allokeret. Når man lod computeren håndtere disse opgaver og fjernede datatyperne, blev hjernen frigjort til at tænke på de algoritmer, der skulle operere med dataene.

Arrays var vigtige, fordi numeriske algoritmer inden for lineær algebra var ved at komme til deres ret, i form af LINPACK og EISPACK. Men at få adgang til dem med standardbæreren inden for videnskabelig databehandling, FORTRAN 77, var en proces i flere trin, der involverede deklaration af variabler, kald af kryptisk navngivne rutiner, kompilering af kode og derefter undersøgelse af data- og outputfiler. At skrive en matrixmultiplikation som A*B og få svaret udskrevet med det samme var en ny mulighed.

MATLAB gjorde også grafikken let og langt mere tilgængelig. Ingen besværlige maskinspecifikke biblioteker med opkald på lavt niveau, bare plot(x,y) og du så stort set det samme, som alle andre med MATLAB ville se. Der var flere innovationer, som f.eks. indbagte komplekse tal, sparsomme matricer, værktøjer til at bygge grafiske brugergrænseflader på tværs af platforme og en førende suite af ODE-løsere, der gjorde MATLAB til stedet, hvor man kunne lave videnskabelige beregninger med tankens hastighed.

Det design, der var ideelt til interaktive beregninger, selv langvarige beregninger, var imidlertid ikke altid befordrende for at skrive godt og performant software. At flytte data rundt mellem mange funktioner krævede jonglering med masser af variabler og hyppig konsultation af dokumentation om input- og output-argumenter. Én funktion pr. diskfil i et fladt navnerum var forfriskende enkelt for et lille projekt, men en hovedpine for et stort projekt. Visse programmeringsmønstre (vektorisering, forhåndsallokering af hukommelse) måtte anvendes, hvis man ønskede at undgå hastighedsflaskehalse. Videnskabelig databehandling blev nu anvendt på langt flere områder med store mængder af forskellige native datatyper. Etc.

MathWorks reagerede ved at fortsætte med at innovere inden for MATLAB: inline-funktioner, nested functions, variable closures, talrige datatyper, objektorienterede funktioner, rammer for unit testing og så videre og så videre. Hver innovation var sandsynligvis løsningen på et vigtigt problem. Men ophobningen af 40 år med disse ændringer har haft den bivirkning, at enkelheden og konceptets enhed eroderes. I 2009 skrev jeg en bog, der på mindre end 100 sider temmelig godt dækkede det, jeg betragtede som det væsentlige i MATLAB. Så vidt jeg ved, er alle disse ting stadig tilgængelige. Men man skal vide meget mere nu for at kunne kalde sig selv dygtig.

Python

Pythons historie synes på en måde næsten at være et spejlbillede af MATLAB’s historie. Begge havde en interaktiv kommandolinje (som nu almindeligvis kaldes REPL, for “read-eval-print loop”) og var fri for variabeldeklarationer og kompilering. Men MATLAB blev skabt som en legeplads for numeriske analytikere, mens Python blev skabt med hackere i tankerne. Hver af dem voksede derefter i retning af det andet publikum gennem revisioner og udvidelser.

For mig at se mangler Python stadig matematisk appel. Du har grimheder og små irritationsmomenter som ** i stedet for ^, @ til matrixmultiplikation (en nyere nyskabelse!), et shape i stedet for størrelsen af en matrix, rækkeorienteret lagring osv. Hvis du tror, at V.conj().T@D**3@V er en elegant måde at skrive $V^*D^3V$ på, så skal du måske til lægen. Og så er der nul-indeksering (i modsætning til indekser, der starter ved 1). Jeg har læst argumenterne, og jeg finder dem ikke afgørende. Det er tydeligvis et spørgsmål om præferencer – det er stof til hellige krige på nettet – for man kan anføre ubehøvlede eksempler for begge konventioner. Det, jeg finder afgørende, er, at vi har årtiers matematisk praksis med at indeksere vektorer og matricer ud fra en, og at de fleste pseudokoder tager udgangspunkt i denne antagelse.

Bortset fra de små irritationsmomenter synes jeg, at økosystemet Python+NumPy+SciPy er klodset og inkonsekvent. Eksempel A er det faktum, at på trods af at sproget er temmelig dedikeret til objektorientering, findes der en matrixklasse, og alligevel frarådes brugen af den og vil blive forældet. Måske har MATLAB simpelthen korrumperet mig, men jeg synes, at matricer er en vigtig nok type objekt til at blive bevaret og fremmes. Er det ikke et vigtigt salgsargument for OOP, at man kan få * til at gøre forskellige ting for arrays og matricer? Der er mange andre uhensigtsmæssigheder i denne henseende. (Hvorfor har jeg brug for en kommando, der hedder spsolve? Kan jeg ikke bare kalde solve på en sparsom matrix? Og så videre og så videre.)

Der er også steder, hvor det numeriske økosystem ser lidt tyndt ud for mig. F.eks. ligner kvadratur- og ODE-løsere et minimumsæt i 2019. AFAICT er der ingen metoder til DAE’er, DDE’er, symplektiske solvers eller implicitte solvers, der tillader indre Krylov-iterationer. Tag et kig på referencerne for disse funktioner; de er for det meste 30 eller flere år gamle – stadig gode, men meget langt fra komplette. Matplotlib-pakken er et fantastisk stykke arbejde, og i et stykke tid så den bedre ud end MATLAB, men jeg finder den stadig ret mangelfuld i 3D.

Som nogle eksperter hævder, at der er dybe årsager til, at Python-kode kæmper for at holde trit med kompilerede sprog i udførelseshastighed. Jeg morer mig over resultaterne af en søgning på “python is too slow”. Pythons forkæmpere kommer med mange af de samme argumenter/undskyldninger, som folk gjorde for MATLAB tilbage i tiden. Det betyder ikke, at de tager fejl, men der er mere end blot et opfattelsesproblem.

Jeg tror, at jeg forstår, hvorfor Python har været så spændende for mange mennesker inden for videnskabelig databehandling. Det har en vis MATLAB-agtig syntaks og kraft, tilgængelig fra en REPL. Det har gode værktøjer omkring sig og spiller godt sammen med andre sprog og områder inden for databehandling. Det tilbød det uden omkostninger og med langt bedre reproducerbarhed på lang sigt. Det er klart, at det fungerer godt for mange mennesker, som sandsynligvis ikke ser nogen grund til at skifte.

Men til de ting, jeg ved, hvordan man laver inden for videnskabelig databehandling, føles Python meget mere som en pligt at lære og bruge, end jeg er vant til. Vi vil først vide om et stykke tid, om det vil fortsætte med at feje gennem samfundet, eller om det allerede har nærmet sig sit højdepunkt. Jeg har ingen særlige forudsigelseskræfter, men jeg er bearish.

Julia

Julia har fordelene og ulemperne ved at være en efternøler. Jeg roser Julia-skaberne for at tro, at de kunne gøre det bedre:

Vi ønsker et sprog, der er open source, med en liberal licens. Vi vil have hastigheden fra C med dynamikken fra Ruby. Vi ønsker et sprog, der er homoikonisk, med ægte makroer som Lisp, men med indlysende, velkendt matematisk notation som Matlab. Vi ønsker noget, der er lige så anvendeligt til generel programmering som Python, lige så let til statistik som R, lige så naturligt til strengbehandling som Perl, lige så kraftfuldt til lineær algebra som Matlab, lige så godt til at klistre programmer sammen som shell’en. Noget, der er skidt enkelt at lære, men som alligevel holder de mest seriøse hackere tilfredse. Vi vil have det interaktivt, og vi vil have det kompileret.

I høj grad mener jeg, at det er lykkedes for dem. Sent på vejen til version 1.0 syntes de at nedtone REPL’en en smule, og der var nogle næsten gratis udsvingene væk fra MATLAB. (Hvordan præcis er LinRange bedre end linspace?) Det er dog småting.

Det er det første sprog, jeg har brugt, der går ud over ASCII. Jeg får stadig en urimelig stor tilfredsstillelse af at bruge variabler som ϕ og operatorer som . Det er mere end kosmetisk; det er et reelt plus at kunne ligne de matematiske udtryk, vi skriver, mere, selv om det komplicerer undervisning og dokumentation en smule.

Arbejdet i Julia afslørede for mig, at jeg har opfanget nogle programmeringsvaner på grund af MATLAB’s valg, ikke på grund af iboende overlegenhed. Vektorisering er ikke naturligt for mange ting. Det er øjenåbnende at finde ud af i Julia, at du kan vektorisere enhver funktion blot ved at tilføje et punktum til dens navn. At konstruere en matrix gennem en comprehension får indlejrede loops (eller meshgrid-tricks) til at ligne buggy whips i sammenligning, og at undgå en matrix helt og holdent via en generator til en simpel summation føles som at få noget for ingenting. (Jeg er klar over, at Python har lignende sprogfunktioner.)

Den store funktion med multiple dispatch gør nogle ting meget nemmere og mere overskuelige end objektorientering gør. Lad os for eksempel antage, at du har Wall- og Ball-klasser i et traditionelt objektorienteret sprog. Hvilken klasse skal registrere en kollision af en bold med en væg? Eller har du brug for en Room-klasse til at spille dommer? Den slags spørgsmål kan drive mig til vanvid. Med multiple dispatch pakkes data ind i objekttyper, men de metoder, der opererer på data, er ikke bundet til en klasse. Så

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

kender til typerne, men er defineret uafhængigt af dem. Det har krævet en hel del programmering for mig at forstå, hvor interessant og potentielt vigtigt begrebet multiple dispatch er for at udvide sproget.

Det numeriske økosystem har udviklet sig hurtigt. Mit bedste eksempel er DifferentialEquations.jl, der er skrevet af den fantastiske Chris Rackauckas. Hvis denne software ikke snart vinder Wilkinson-prisen, er systemet i stykker. Bare gå ind på webstedet og forbered dig på at blive omvendt.

Jeg har endnu ikke set de store hastighedsforbedringer i forhold til MATLAB, som Julia lover. Det skyldes til dels min relative uerfarenhed og de typer opgaver, jeg udfører, men det skyldes også til dels, at MathWorks har gjort et utroligt godt stykke arbejde med automatisk optimering af kode. Det er alligevel ikke et aspekt af kodning, som jeg fokuserer på det meste af tiden.

Programmering i Julia har taget mig et stykke tid at føle mig tryg ved (måske er jeg bare ved at blive gammel og krystalliseret). Det får mig til at tænke mere over datatyper, end jeg ville ønske, og der er altid en snigende mistanke om, at jeg har overset den rigtige måde at gøre noget på. Men til daglig brug er jeg omtrent lige så tilbøjelig til at vende mig til Julia som til MATLAB nu.

Bottom line

MATLAB er virksomhedens løsning, især til ingeniørarbejde. Det er nok stadig det nemmeste at lære til grundlæggende numeriske opgaver. En omhyggelig dokumentation og årtiers medvirkende læringsværktøjer betyder helt klart noget.

MATLAB er BMW sedanen i den videnskabelige databehandlingsverden. Den er dyr, og det er før man begynder at tale om tilbehør (værktøjskasser). Du betaler for en bundsolid, jævn ydelse og service. Det tiltrækker også en uforholdsmæssig stor mængde had.

Python er en Ford pickup. Den er allestedsnærværende og elsket af mange (i USA). Den kan gøre alt det, du ønsker, og den er bygget til at gøre nogle ting, som andre køretøjer ikke kan. Der er gode chancer for, at du vil låne en i ny og næ. Men den giver ikke en stor ren køreoplevelse.

Julia er en Tesla. Den er bygget med et dristigt mål om at ændre fremtiden, og det kan den måske. Den kan også blive blot en fodnote. Men i mellemtiden vil du komme derhen, hvor du skal hen, med stil og med masser af kraft.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.