Cerca

Ho usato MATLAB per oltre 25 anni. (E prima di allora, ho anche usato MATRIXx, un tardivo e deplorevole tentativo di spinoff, o forse un ripoff). Non è il primo linguaggio in cui ho imparato a programmare, ma è quello con cui sono cresciuto matematicamente. Conoscere MATLAB è stato molto positivo per la mia carriera.

Tuttavia, è impossibile ignorare l’ascesa di Python nel calcolo scientifico. MathWorks deve sentirsi allo stesso modo: non solo hanno aggiunto la possibilità di chiamare Python direttamente dall’interno di MATLAB, ma hanno adottato alcune delle sue caratteristiche del linguaggio, come la trasmissione più aggressiva per gli operandi degli operatori binari.

Ha raggiunto un punto in cui ho messo in discussione il mio continuo utilizzo di MATLAB sia nella ricerca che nell’insegnamento. Eppure mi viene così facile lì, e ho così tanto investito in materiali per esso, che è stato difficile raccogliere la motivazione per imparare davvero qualcosa di nuovo.

Entra nel libro di testo basato su MATLAB che ho co-scritto per la matematica computazionale introduttiva. Il libro ha più di 40 funzioni e 160 esempi di calcolo, e copre ciò che penso sia una base completa nell’uso di MATLAB per il calcolo scientifico numerico. Quindi, in parte come auto-miglioramento, e in parte per aumentare l’utilità del libro, quest’anno ho deciso di tradurre i codici in Julia e Python. Questa esperienza mi ha portato ad una particolare prospettiva sui tre linguaggi in relazione al calcolo scientifico, che cerco di catturare qui di seguito.

Metterò da parte soprattutto le questioni del costo e dell’apertura. MATLAB, a differenza di Python e Julia, non è né senza birra né senza parole. Questa è davvero un’enorme distinzione – per alcuni, una distinzione dispositiva – ma voglio considerare i meriti tecnici. Per molti anni, MATLAB è stato ben al di là di qualsiasi prodotto gratuito in un certo numero di modi altamente utili, e se si voleva essere produttivi, allora il costo era dannato. È una considerazione separata dal fascino platonico di un linguaggio e di un ecosistema.

Quando si mettono da parte i costi, una cornice utile per molte delle differenze tra questi linguaggi sta nelle loro origini. MATLAB, il più vecchio degli sforzi, ha dato priorità alla matematica, in particolare alla matematica orientata ai numeri. Python, che ha iniziato seriamente alla fine degli anni ’80, ha fatto dell’informatica il suo obiettivo centrale. Julia, che ha iniziato nel 2009, ha cercato di trovare un maggiore equilibrio tra queste parti.

MATLAB

In origine, ogni valore in MATLAB era un array di numeri in virgola mobile a doppia precisione. Entrambi gli aspetti di questa scelta, gli array e la virgola mobile, erano decisioni progettuali ispirate.

Lo standard IEEE 754 per la virgola mobile non fu nemmeno adottato fino al 1985, e la memoria era misurata in K, non in G. I doppi in virgola mobile non erano il modo più efficiente per rappresentare caratteri o interi, ma erano ciò che scienziati, ingegneri e, sempre più spesso, matematici volevano usare la maggior parte del tempo. Inoltre, le variabili non dovevano essere dichiarate e la memoria non doveva essere esplicitamente allocata. Lasciando che il computer gestisse questi compiti e togliendo di mezzo i tipi di dati, si liberava il cervello per pensare agli algoritmi che avrebbero operato sui dati.

Le matrici erano importanti perché gli algoritmi numerici nell’algebra lineare stavano diventando propri, nella forma di LINPACK e EISPACK. Ma accedervi con il portatore standard del calcolo scientifico, FORTRAN 77, era un processo a più fasi che implicava la dichiarazione di variabili, la chiamata di routine dal nome criptico, la compilazione del codice e poi l’esame dei dati e dei file di output. Scrivere una moltiplicazione di matrice come A*B e ottenere subito la risposta stampata era un cambio di gioco.

MATLAB ha anche reso la grafica facile e molto più accessibile. Nessuna libreria specifica per la macchina con chiamate di basso livello, solo plot(x,y) e si vedeva più o meno quello che chiunque altro con MATLAB avrebbe visto. C’erano altre innovazioni, come i numeri complessi integrati, matrici sparse, strumenti per costruire interfacce grafiche multipiattaforma e una suite all’avanguardia di risolutori di ODE, che rendevano MATLAB il luogo dove fare calcoli scientifici alla velocità del pensiero.

Tuttavia, il design ideale per calcoli interattivi, anche lunghi, non era sempre favorevole alla scrittura di software buono e performante. Spostare i dati tra molte funzioni richiedeva di destreggiarsi tra molte variabili e di consultare frequentemente la documentazione sugli argomenti di input e di output. Una funzione per file di disco in un namespace piatto era rinfrescante e semplice per un piccolo progetto, ma un mal di testa per uno grande. Certi modelli di programmazione (vettorizzazione, preallocazione della memoria) dovevano essere applicati se si voleva evitare i colli di bottiglia della velocità. Il calcolo scientifico veniva ora applicato a molti più domini, con grandi quantità di diversi tipi di dati nativi. Etc.

MathWorks rispose continuando a innovare all’interno di MATLAB: funzioni in linea, funzioni annidate, chiusure di variabili, numerosi tipi di dati, caratteristiche orientate agli oggetti, framework di test delle unità, e così via. Ogni innovazione era probabilmente la soluzione ad un problema importante. Ma l’accumulo di 40 anni di questi cambiamenti ha avuto l’effetto collaterale di erodere la semplicità e l’unità di concetto. Nel 2009 ho scritto un libro che copriva abbastanza bene quello che consideravo l’essenziale di MATLAB in meno di 100 pagine. Per quanto ne so, tutte queste cose sono ancora disponibili. Ma devi sapere molto di più ora per definirti competente.

Python

In un certo senso la storia di Python sembra essere quasi un’immagine speculare di quella di MATLAB. Entrambi presentavano una linea di comando interattiva (ora ampiamente chiamata REPL, per “read-eval-print loop”) e la libertà dalle dichiarazioni di variabili e dalla compilazione. Ma MATLAB è stato creato come un parco giochi per analisti numerici, mentre Python è stato creato con gli hacker in mente. Ognuno è poi cresciuto verso l’altro pubblico attraverso revisioni ed estensioni.

A mio avviso, Python manca ancora di fascino matematico. Avete brutture e piccole seccature come ** invece di ^, @ per la moltiplicazione delle matrici (un’innovazione recente!), un shape invece della dimensione di una matrice, lo stoccaggio orientato alle righe, ecc. Se credete che V.conj().T@D**3@V sia un modo elegante per scrivere $V^*D^3V$, allora forse avete bisogno di vedere un dottore. E c’è l’indicizzazione a zero (al contrario degli indici che iniziano a 1). Ho letto gli argomenti e non li trovo decisivi. È chiaramente una questione di preferenze – roba da guerre sante online – perché si possono citare esempi sgraziati per entrambe le convenzioni. Quello che trovo decisivo è che abbiamo decenni di pratica matematica che indicizza vettori e matrici da uno, e la maggior parte dello pseudocodice fa questa assunzione.

Al di là dei piccoli fastidi, trovo che l’ecosistema Python+NumPy+SciPy sia kludgy e inconsistente. La prova A è il fatto che, nonostante il linguaggio sia piuttosto votato all’orientamento ad oggetti, esiste una classe matrice, eppure il suo uso è scoraggiato e sarà deprecato. Forse MATLAB mi ha semplicemente corrotto, ma trovo che le matrici siano un tipo di oggetto abbastanza importante da mantenere e promuovere. Non è uno dei principali punti di forza dell’OOP che si può avere * fare cose diverse per gli array e le matrici? Ci sono molte altre infelicità a questo proposito. (Perché ho bisogno di un comando chiamato spsolve? Non posso semplicemente chiamare solve su una matrice rada? E così via.)

Ci sono anche posti dove l’ecosistema numerico mi sembra un po’ sottile. Per esempio, i solutori di quadratura e ODE sembrano un set minimo nel 2019. AFAICT non ci sono metodi per DAEs, DDEs, solutori simplettici o solutori impliciti che consentono iterazioni interne di Krylov. Dai un’occhiata ai riferimenti per queste funzioni; sono per lo più vecchi di 30 o più anni – ancora buoni, ma molto lontani dalla completezza. Il pacchetto Matplotlib è un lavoro incredibile, e per un po’ è sembrato migliore di MATLAB, ma lo trovo ancora piuttosto carente nel 3D.

Alcuni esperti sostengono che ci sono ragioni profonde per cui il codice Python fatica a tenere il passo in velocità di esecuzione con i linguaggi compilati. Sono divertito dai risultati della ricerca di “python è troppo lento”. I campioni di Python fanno molti degli stessi argomenti/scuse che la gente faceva per MATLAB ai tempi. Questo non significa che abbiano torto, ma c’è più di un problema di percezione.

Penso di capire perché Python sia stato così eccitante per molte persone nel calcolo scientifico. Ha una sintassi e una potenza simile a MATLAB, disponibile da un REPL. Ha grandi strumenti intorno a sé e gioca bene con altri linguaggi e aree di calcolo. Offre tutto questo a costo zero e con una riproducibilità a lungo termine molto migliore. Chiaramente, funziona bene per molte persone che probabilmente vedono poche ragioni per cambiare.

Ma per le cose che so fare nel calcolo scientifico, Python sembra molto più noioso da imparare e usare di quanto sia abituato. Non sapremo per un po’ se continuerà a travolgere la comunità o se è già vicino al suo picco. Non ho particolari poteri di previsione, ma sono pessimista.

Julia

Julia ha i vantaggi e gli svantaggi di essere un ritardatario. Mi congratulo con i creatori di Julia per aver pensato di poter fare meglio:

Vogliamo un linguaggio che sia open source, con una licenza libera. Vogliamo la velocità di C con il dinamismo di Ruby. Vogliamo un linguaggio omoiconico, con vere macro come il Lisp, ma con una notazione matematica ovvia e familiare come Matlab. Vogliamo qualcosa di utilizzabile per la programmazione generale come Python, facile per la statistica come R, naturale per l’elaborazione delle stringhe come Perl, potente per l’algebra lineare come Matlab, buono per incollare programmi insieme come la shell. Qualcosa che sia semplice da imparare, ma che renda felici gli hacker più seri. Lo vogliamo interattivo e lo vogliamo compilato.

In larga misura, credo che ci siano riusciti. Più tardi lungo la strada verso la versione 1.0 sembravano sminuire un po’ il REPL, e c’erano alcuni slanci quasi gratuiti lontano da MATLAB. (Come esattamente LinRange è meglio di linspace?) Questi sono cavilli, però.

Questo è il primo linguaggio che ho usato che va oltre l’ASCII. Ho ancora una quantità irragionevole di soddisfazione nell’usare variabili come ϕ e operatori come . È più che un aspetto estetico; essere in grado di assomigliare di più alle espressioni matematiche che scriviamo è un vero vantaggio, anche se complica un po’ l’insegnamento e la documentazione.

Lavorare in Julia mi ha fatto capire che ho preso alcune abitudini di programmazione a causa delle scelte di MATLAB, non una superiorità intrinseca. La vettorializzazione non è naturale per molte cose. È illuminante scoprire in Julia che si può vettorializzare qualsiasi funzione semplicemente aggiungendo un punto al suo nome. Costruire una matrice attraverso una comprensione fa sembrare i loop annidati (o i trucchi meshgrid) come delle fruste in confronto, ed evitare del tutto una matrice attraverso un generatore per una semplice somma sembra come ottenere qualcosa per niente. (Sono consapevole che Python ha caratteristiche di linguaggio simili.)

La grande caratteristica del dispatch multiplo rende alcune cose molto più facili e chiare di quanto faccia l’orientamento agli oggetti. Per esempio, supponiamo di avere le classi Wall e Ball in un linguaggio tradizionale orientato agli oggetti. Quale classe dovrebbe rilevare la collisione di una palla con un muro? O avete bisogno di una classe Room per fare da arbitro? Questo tipo di domande può portare alla distrazione. Con il dispatch multiplo, i dati sono impacchettati in tipi di oggetto, ma i metodi che operano sui dati non sono legati ad una classe. Quindi

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

conosce i tipi ma è definito indipendentemente da essi. Mi ci è voluto un bel po’ di programmazione per apprezzare quanto sia interessante e potenzialmente importante la nozione di dispatch multiplo per estendere il linguaggio.

L’ecosistema numerico si è evoluto rapidamente. Il mio esempio numero uno è DifferentialEquations.jl, scritto dall’incredibile Chris Rackauckas. Se questo software non vince presto il premio Wilkinson, il sistema è rotto. Basta andare sul sito e prepararsi ad essere convertiti.

Devo ancora vedere i grandi guadagni di velocità rispetto a MATLAB che Julia promette. In parte questo è dovuto alla mia relativa inesperienza e al tipo di compiti che svolgo, ma è anche in parte perché MathWorks ha fatto un incredibile lavoro di ottimizzazione automatica del codice. Non è un aspetto della codifica su cui mi concentro la maggior parte del tempo, comunque.

Programmare in Julia mi ci è voluto un po’ per sentirmi a mio agio (forse sto solo diventando vecchio e cristallizzato). Mi fa pensare ai tipi di dati più di quanto vorrei, e c’è sempre il sospetto che mi sia sfuggito il modo giusto di fare qualcosa. Ma per l’uso quotidiano, ho la stessa probabilità di rivolgermi a Julia come a MATLAB ora.

La linea di fondo

MATLAB è la soluzione aziendale, specialmente per l’ingegneria. È probabilmente ancora il più facile da imparare per compiti numerici di base. Una documentazione meticolosa e decenni di strumenti di apprendimento hanno sicuramente importanza.

MATLAB è la berlina BMW del mondo del calcolo scientifico. È costoso, e questo prima di iniziare a parlare degli accessori (cassette degli attrezzi). Stai pagando per una prestazione e un servizio solido come una roccia e senza intoppi. Attira anche una quantità sproporzionata di odio.

Python è un pick-up Ford. È onnipresente e amato da molti (negli USA). Può fare tutto quello che vuoi, ed è costruito per fare alcune cose che altri veicoli non possono fare. È probabile che tu voglia prenderne uno in prestito ogni tanto. Ma non offre una grande esperienza di guida pura.

Julia è una Tesla. È costruita con l’obiettivo audace di cambiare il futuro, e potrebbe farlo. Potrebbe anche diventare solo una nota a piè di pagina. Ma nel frattempo arriverete dove state andando con stile, e con potenza da vendere.

La Giulia è una Tesla.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.