Forum >> Programmazione Python >> Calcolo scientifico >> libreria di calcolo

Pagina: 1

Salve a tutti,

tra non molto mi accingerò nello sviluppo di una libreria di calcolo in python mirata a risolvere determinati problemi numerici operanti su array monodimensiali.


La domanda che volevo porre alla comunity è un consiglio su come cominciare ad affrontare il problema, in particolare sono indeciso tra due differenti approcci che vi espongo in seguito:

1_scrivere la libreria di calcolo totalmente in python, creare degli script-test utilizzanti questa libreria, determinare senzioni di script tempo-critiche tramite profiling ed in fine procedere ad ottimizzazione attraverso interfacce a basso livello (Python/C API, ctypes, Cython... ulteriore problematica sarà poi capire quale in questo contesto sarà meglio utilizzare);

2_scrivere la libreria di calcolo in c++ ed interfacciare in seguito al python.

La prima metodologia mi convince di più in quanto ottimizzerebbe i tempi di sviluppo, tuttavia non vorrei rimetterci in prestazioni.


grazie a tutti :)

E' un po' strana come domanda. Ovviamente esistono già librerie di calcolo basate su array (a partire da Numpy) che sono molto performanti, testate, sviluppate, conosciute. Se hai un problema pratico da risolvere, dovresti prima di tutto verificare se davvero non è risolvibile da Numpy, Pandas, o una delle centinaia di librerie scientifiche che popolano l'ecosistema esistente.

Se invece davvero "vuoi" scrivere una tua libreria di calcolo, allora i casi sono due: il primo caso è se "fai sul serio", cioè se davvero hai in mente di scrivere una cosa che poi deve essere usata in produzione. Allora dovresti prima verificare/dimostrare che in effetti esiste un'area applicativa che non è coperta da nessuna libreria esistente, oppure dove tu potresti fare di meglio, magari con algoritmi migliori o interfacce migliori. In questo secondo caso forse è preferibile che tu ti dedichi a migliorare le librerie esistenti (sottoponendo patch, o al limite anche forkandole) invece di ripartire daccapo. Se invece proprio hai individuato un'area non coperta da nessuno, allora sì, in effetti dovresti scrivere una libreria tua. Sul fatto che dovresti scriverla in python o in c++, boh la verità è che anche qui, dipende se vuoi proprio davvero reinventare la ruota. Voglio dire, nel 99% dei casi la scriverai in... Numpy, ovvero in python ma appoggiandoti a una libreria già esistente come Numpy (i cui algoritmi sono già ottimizzati in c). Se invece davvero pensi che la tua necessità richieda addirittura la scrittura di una libreria che parte completamente da zero... ehm, ok. Ti consiglio di dare un'occhiata al codice sorgente di Numpy, Pandas o altre cose esistenti per capire come si regolano loro.


Il secondo caso è "se non fai sul serio", ovvero se lo stai facendo come esercizio per te. In questo caso, mi sembra ovvio che dovresti scriverla in python puro e non preoccuparti della performance (perché tanto, se poi ti serve davvero calcolare in fretta, c'è Numpy).

l'obiettivo del progetto in cui sono coinvolto è proprio rendere utilizzabile in python una serie di algoritmi che non sono presenti in librerie già esistenti. Per quanto riguarda la struttura dati di questi array... conosco numpy (che utilizzo al momento insieme a scipy e matplotlib principalmente per analisi dati) tuttavia per avvantaggiare la portabilità del codice preferivo farne a meno.

Per capirci meglio non vorrei rendere necessario avere numpy per accedere alle funzionalità della libreria (tuttavia la cosa è valutabile).

Personalmente nel caso di scrittura in python ero più indirizzato a liste o array del modulo array, in modo da non rendere necessario l'utilizzo di librerie esterne. Inoltre nel mio caso avrò a che fare con array solo 1D.

Diciamo che l'essenza della domanda che ho posto sta nel valutare se possa essere utile definire una nuova struttura dati a basso livello con tutta l'algoritmica associata, oppure se sia più opportuno utilizzare ad alto livello strutture dati gia implementate e definirne solo l'algoritmica a basso livello (e solo quella che realmente porta vantaggi pratici nell'essere ottimizzata).

spero di essermi spiegato meglio nel caso sono qui :)







Allego uno script buttato giù al volo che in realtà non centra nulla con quanto devo fare ma il concetto è il medesimo e semplifica molto la discussione. Immaginate che all'interno dell'override dell'operatore somma ci sia un algoritmo particolarmente gravoso in termini computazionali. In sostanza le istanze di Miaclasse devono poter essere combinate in vario modo creando a loro volta un oggetto Miaclasse. Ovviamente le operazioni con cui sarà possibile combinare gli oggetti Miaclasse saranno delle più svariate.

class Miaclasse():
    def __init__(self, val1, val2, array):
        self._val1 = val1
        self._val2 = val2
        self._array = array
     
    @property
    def array(self):
        return self._array
    
    def __add__(self, other):
        if isinstance(other, Miaclasse):
            new_val1 = min(self._val1, other._val1)
            new_val2 = max(self._val2, other._val2)
            new_array = self._array + other._array
            return Miaclasse(new_val1, new_val2, new_array)

a1 = Miaclasse(0, 2, [1,2,3])
a2 = Miaclasse(3, 5, [4,5,6]) 

a3 = a1 + a2

print(a3.array)


> non vorrei rendere necessario avere numpy

Questa mi sembra davvero una preoccupazione inutile, se sono vere le premesse. Se davvero stai facendo "algoritmi che non sono presenti in altre librerie", probabilmente stai in un ambito scientifico molto raffinato (mi chiedo francamente di quali algoritmi stai parlando... cioè, non è che python copra tutto lo scibile umano, ci mancherebbe... ma insomma, di roba ce n'è davvero). E se sei in quell'ambito, allora poco ma sicuro *tutti* i tuoi potenziali utenti già usano numpy per il loro lavoro. Davvero, non c'è niente di più comune di una libreria scientifica che abbia numpy come prerequisito. In particolare, si usano gli array di numpy perché sono potenti, veloci, testati. Onestamente, la mia impressione è che se basi una libreria nuova su un array "fatto in casa" da te, è più probabile che gli utenti siano portati a diffidarne piuttosto che ad adottarla.


> possa essere utile definire una nuova struttura dati a basso livello

Mah, guarda: questa è una di quelle domande che se le fai, vuol già dire che la risposta probabilmente è no. Cioè, la risposta sarebbe: è utile farlo solo se hai già visto che gli array di numpy non vanno bene per quello che vuoi fare, per un motivo specifico. Ma se tu avessi già trovato il motivo specifico per cui gli array di numpy non vanno bene, allora non avresti bisogno di fare la domanda...


Senza contare che è una perdita del tuo tempo: tutto il tempo che impieghi a scrivere (e riscrivere, e ottimizzare, e testare, etc etc) una struttura di basso livello come un array, è tempo che sottrai agli algoritmi veri e propri che vuoi scrivere e che dovrebbero essere il centro del tuo lavoro.


E infatti, prendi l'esempio che hai scritto: hai un bel dire che è super-semplificato, ma il problema è che sembra proprio inutile alla radice. Se il tuo lavoro vero e proprio contiene questa idea in qualsiasi forma, boh magari c'è qualcosa che mi sfugge ma ti suggerirei di ripensarci a fondo. Quello che hai scritto è un wrapper intorno a un tipo python già esistente, un lista. Ora, lasciamo perdere il fatto che una lista non è un array, ed è notevolmente meno performante di qualsiasi array che trovi in giro (perchè è pensata per altri scopi). Ma devi chiederti se le manipolazioni che intendi fare su questo tuo "array" non sono in realtà già implementate in un qualche tipo già esistente: una lista python, un array.array, un array di numpy, va a sapere. O una combinazione di questi.


Comunque, alla fine... la programmazione a oggetti è sempre la strada maestra. Il mio consiglio è di concentrarti sui tuoi algoritmi, e cominciare a usare gli array di numpy. Se poi a un certo punto dovessi vedere che gli array di numpy non ce la fanno, o devi fare troppi giri strani per usarli, o va a sapere, allora potrai sempre rimpiazzarli con un tuo array "custom". Se il codice che hai scritto segue una buona tecnica a oggetti, dovresti poter rimpiazzare gli array di numpy con pochissimi cambiamenti al codice.





Oh, e un'altra cosa che mi viene in mente: tu dici che vuoi scrivere degli algoritmi che adesso non ci sono in python. Ma hai controllato che qualcuno non li abbia già implementati in qualche altro linguaggio? Magari fortran, o java, o va a sapere? Perché in quel caso potresti anche considerare di scrivere un bridge per quelle librerie "straniere" in python, invece che metterti a re-implementare l'algoritmo. Potrebbe essere una buona soluzione...

riguardo agli array numpy ammetto che mi fai riflettere... al max potrei scrivere il codice compatibile sia con array numpy sia con array del modulo array e se l'applicativo trova numpy utilizza tali array se no nel caso ripiega sugli array del modulo array... cioè solo come concept del tipo:


try:
    import numpy
except:
    import array
può essere una buona idea?


Tuttavia se mi confermi che è di uso comune appoggiarsi a numpy... il fatto è che non mi sembra elegante appoggiarmi a una libreria cosi completa per utilizzare l'array numpy come mero contenitore nel caso scriva successivamente le sezioni algoritmiche in c++.. o dici di scrivere direttamente tutto in python scrivendo gli algoritmi utilizzando le operazioni degli array numpy senza cercare possibili ottimizzazioni?

Tali algoritmi (o meglio parte di essi) non sono presenti in python in quanto sviluppati da un mio professore per risolvere alcune problematiche in un particolare contesto, e per ora è possibile utilizzare quella matematica solo istallando un compilatore di un linguaggio dedicato (a base c). Mi pare (non ne sono propriamente sicuro) sia utilizzato solo in ambito accademico. L'idea era dunque quella di un porting di tale matematica in un ambiente più moderno con i vantaggi che ne derivano.







Nel mentre mi è venuta un' idea e mi piacerebbe sapere cosa ne pensate.




Se utilizzassi gli array numpy sarebbe comunque possibile ottimizzare regioni tempo-critiche tramite Cython che se non sbaglio (purtroppo ho solo letto qualcosa su Cython ma mai utilizzato) risulta ben compatibile con gli array numpy. Se si raggiungessero prestazioni accettabili mi eviterebbero di scrivere codice direttamente in c/c++. Può essere un buon approccio?

> potrei scrivere il codice compatibile sia con array numpy sia con array del modulo array

puoi farlo senz'altro, basta che tutte le operazioni che fai sull'array siano le stesse in un caso o nell'altro... cosa che dopo un po' potrebbe essere difficile da controllare ogni volta. Davvero, non capisco perché stai cercando ogni possibile scusa per complicarti la vita e *non* scrivere il codice che devi scrivere. Sembra che tu debba progettare la prima astronave per Marte, e però prima di tutto ti blocchi a pensare se piacerà di più alla gente se la dipingi di blu o di verde. Mah.


> non mi sembra elegante appoggiarmi a una libreria cosi completa per utilizzare l'array numpy come mero contenitore

Boh, devo averlo visto fare decine di volte. Ma poi cos'è, devi partecipare a un concorso di eleganza per programmatori?


> dici di scrivere direttamente tutto in python scrivendo gli algoritmi
utilizzando le operazioni degli array numpy senza cercare possibili
ottimizzazioni?

Ecco, questo è *esattamente* ciò che sto dicendo. Lascia perdere le ottimizzazioni (di cui tra l'altro per il momento nessuno ha ancora dimostrato il bisogno... che succede se alla fine della giornata si dimostra che un po' di codice python/numpy basta e avanza per il tipo di calcoli che devi fare davvero? Tutta questa ansia precoce non la capisco). Scrivi un prototipo in "puro python", ovviamente con numpy e/o con tutte (ma proprio tutte) le librerie esterne che ti servono, e solo dopo che hai visto che funziona, lo hai testato, eccetera, allora potrai cominciare a esplorare come ottimizzarlo.


Tra l'altro non so se cogli l'ironia della cosa. Dici che il tuo prof ha sviluppato questa matematica in un linguaggio dedicato (caspita... ma lo ha fatto negli anni '70? comunque...), e che vuoi "modernizzarlo"... Dopo di che, ti metti a pensare a come riscrivere un array da zero. Ma se davvero questa matematica è così complessa da aver bisogno di una "customizzazione" così specifica addirittura già a partire dai tipi fondamentali come gli array, allora forse è meglio lasciare tutto nel linguaggio dedicato del tuo professore, no?

> Nel mentre mi è venuta un' idea e mi piacerebbe sapere cosa ne pensate.(...)

Ne penso più o meno ciò che penso di tutto il resto. Dal colore della vernice dell'astronave sei passato a bloccarti pensando al tipo di carattere per le scritte sulla fiancata. Certo, come no: è possibile anche questa strada che dici. Ma se non cominci a buttare giù un po' di codice brutto sporco e cattivo per questi algoritmi, ho paura che la tua astronave per Marte sarà ottimizzatissima, ma non parte più.

Non approvo eccessivamente i toni però mi hai convinto sull utilizzo degli array numpy.
Il discorso principale tuttavia non era su che struttura dati utilizzare ma come approcciare al problema, cioè se convenisse partire subito dal basso livello o se prototipare ad alto livello e se e dove necessario ottimizzare.

Già pendevo per la soluzione di partire dall alto livello e da quanto ho capito me ne dai conferma.

Non sono bloccato perché devo ancora partire.. Volevo solo un consiglio dalla community su come impostare una libreria di calcolo numerico.


Grazie dei consigli :)
Se c'è un linguaggio adatto a fare un rapido prototipo e vedere come va, questo è python. Buttati, poi mi saprai dire.


Senza contare che non abbiamo neppure preso in considerazione finora la soluzione dell'hardware. Voglio dire, se il mio problema è la performance, prima di spaccarmi la testa a sviluppare un array home-made più performante di quello di numpy, proverei a verificare se i calcoli pesanti non possono essere fatti in modo concorrente e distribuiti su più processori (e alla fine, visto che poi è quello che fanno tutti, su una bella istanza di AWS lambda). Certo, a questo punto qualcuno potrebbe dirti che vale la pena di farlo in Golang, ma insomma...



Pagina: 1



Esegui il login per scrivere una risposta.