SciPy, una libreria Python per la matematica, la scienza e l’ingegneria

SciPy è una libreria in Python, o più precisamente una collezione di algoritmi matematici ed altre funzioni particolarmente utilizzate in ambito scientifico. SciPy è costruita su NumPy, una libreria che estende il linguaggio Python per meglio gestire i calcoli matematici.

Grazie a SciPy, una sessione di Python non ha niente da invidiare ad altri ambienti come Matlab, IDL, Octave e SciLab. SciPy si dimostrerà uno strumento insostituibile per chiunque abbia a che fare con il mondo dei calcoli scientifici.

SciPy una libreria Python per la matematica, la scienza e l'ingegneria

Come e’ organizzata la libreria SciPy

SciPy è organizzata in diverse sezioni, ognuna delle quali ricopre diversi argomenti del calcolo scientifico. La struttura della libreria è quindi composta da diversi moduli (sub-packages), ognuno inerente ad un determinato argomento di applicazione

  • cluster – Algoritmi di clustering
  • constants – Costanti matematiche e fisiche
  • fftpack – Funzioni della Trasformata di Fourier
  • integrate – Integrazione e equazioni differenziali ordinarie
  • interpolate – Interpolazione e smoothing spline
  • io – Input e Output
  • linalg – Algebra lineare
  • ndimage – Image processing N-dimensionale
  • odr – Regressione delle distanze ortogonali
  • optimize – Funzioni di Ottimizzazione e di root-finding
  • signal – Elaborazione di Segnale
  • sparse – Matrici sparse e funzioni associate
  • spatial – Strutture dati spaziali e algoritmi
  • special – Altre funzioni speciali
  • stats – Distribuzioni statistiche e funzioni correlate

Generalmente, quando si lavora con SciPy, si importano singolarmente solo i moduli necessari. Per esempio:

>>> from scipy import some_module
>>> some_module.some_function() 

Prima di cominciare

SciPy è una libreria costruita su NumPy, e quindi ogni volta che abbiamo bisogno di lavorare con array sarà necessario dapprima importarla.

>>> import numpy as np

Inoltre, quando si lavora con dati scientifici è spesso necessario utilizzare delle rappresentazioni grafiche. Quindi un’altra importantissima (e utile) libreria è matplotlib.

>>> import matplotlib as mpl
>>> import matplotlib.pyplot as plt

Documentazione in rete

Sia SciPy che NumPy e Matplotlib hanno moltissima documentazione in rete. Per quanto riguarda la documentazione ufficiale, molti file HTML e PDF sono disponibili su docs.scipy.org.

Se invece volete scendere più in dettaglio nell’argomento e avere a disposizione molti esempi e tutorial su SciPy, vi consiglio questo libro. Non è proprio recentissimo, ma è molto esaustivo sull’argomento.

Elegant SciPy book - O'Reilly

Elegant SciPy: The Art of Scientific Python

J.Nunez-Iglesias et al. – O’ Reilly 2017

Per quanto riguarda NumPy, vi consiglio questo libro. Vi è un capitolo introduttivo a questa libreria molto semplice ed intuitivo, ricco di esempi. In poche ore, prenderete familiarità con questa libreria comprendendone tutte le funzionalità base. Inoltre vi sono altri capitoli sull’utilizzo di Matplotlib applicati a librerie scientifiche e ad applicazioni pratiche.

Python Data Analytics (2nd Edition)

Python Data Analytics: With Pandas, NumPy, and Matplotlib (2nd Edition)

Fabio Nelli – Apress 2018

Esempio – il Diagramma di Voronoi

E’ impossibile in un singolo articolo parlare interamente di tutte le funzionalità della libreria SciPy, come anche entrare in dettaglio per ogni singolo modulo.

Una buona introduzione a SciPy può essere quella di scegliere un’applicazione di esempio, come i diagrammi di Voronoi. Con poche righe di codice si potranno intuire le similitudini con Matlab, SciLab e Octave, e come sia possibile lavorare interattivamente ad un problema matematico o scientifico. Grande pregio però è che SciPy è completamente integrato a Python, con la possibilità di integrarlo a qualsiasi altra libreria o applicazione.

Prima di cominciare con il codice vediamo però una breve introduzione ai diagrammi di Voronoi, nota anche tassellatura di Dirichlet. L’operazione consiste nel suddividere un’area in n poligoni convessi, determinati da n punti definiti in tale area. I poligoni devono essere generati in modo tale che ogni punto all’interno di tale poligono sia più vicino al suo punto di generazione (uno degli n punti) che a qualsiasi altro.

Sebbene hanno preso molto il via con l’introduzione dell’informatica, i diagrammi di Voronoi furono presi in considerazione per la prima volta nel 1644 da René Descartes. Dirichlet li utilizzò nel 1850 per lo studio delle forme quadratiche positive. Infine furono definitivamente studiati e sviluppati da Voronoi nel 1907, estendendoli anche a casi con dimensioni superiori. I diagrammi di Voronoi trovano molte applicazioni in diversi settori come la computer grafica, l’epidemiologia, la geofisica e la meteorologia.

Cominciando a programmare

Per sviluppare l’esempio seguente vi consiglio di utilizzare il notebook Jupyter o aprire una sessione di IPython, in modo da lavorare interattivamente, inserendo e valutando il codice snippet per snippet.

Nota: Per visualizzare gradualmente l’evoluzione dell’esempio aggiungete alla fine il comando plt.show() e poi cancellato e proseguite oltre.

Per prima cosa importiamo le librerie ed i moduli di SciPy necessari.

import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import KDTree, Voronoi

Gli approcci al problema di Voronoi sono due. Uno risolvibile con il modulo KDTree con cui determineremo le aree del diagramma. Ad ogni area verrà assegnato un colore diverso, e l’altro con il modulo Voronoi, con cui calcoleremo i segmenti di separazione tra le varie aree.

Adesso inseriamo i 9 punti compresi tra un’area rettangolare di dimensioni 7×8

points = np.array([[0, 0], [4, 4], [5, 6.5], 
                   [4.2,5.8], [1.7, 1.4], [3.1, 7.6], 
                   [3, 6], [3.4, 5.2], [1.8, 2.2], 
                   [2.7, 0.4], [6.5, 1.8], [2.3, 2.8]])

Passiamo adesso ai due oggetti corrispondenti ai due metodi: KDTree() e Voronoi().

tree = KDTree(points)
vor = Voronoi(points)

Creiamo una griglia suddividendo l’area in questione in 40000 particelle, (200×200). Il numero è un compromesso tra qualità e velocità di calcolo. Se volete potete variare questi valori a vostro piacimento. Suddividere l’area in particelle più piccole. Estenderemo per comodità l’area di rappresentazione a (-1,-1) in modo da rappresentare per bene anche il punto di origine (0,0).

x = np.linspace(-1, 7, 200)
y = np.linspace(-1, 8, 200)
xx, yy = np.meshgrid(x, y)
xy = np.c_[xx.ravel(), yy.ravel()]

Adesso non ci resta che rappresentare il tutto mediante le funzioni di matplotlib. Tutti i valori necessari per la rappresentazione sono già stati calcolati, una volta generati gli oggetti tree, e vor, in precedenza.

Per prima cosa inseriamo nella rappresentazione i 9 punti da noi inseriti. Questi verranno rappresentati come dei cerchietti neri. Poi delimitiamo l’area di rappresentazione con l’asse X che va da -1 a 7 e l’asse Y che va da -1 a 8.

plt.plot(points[:, 0], points[:, 1], 'ko')
plt.xlim(-1, 7); plt.ylim(-1, 8)

Adesso rappresenteremo i segmenti che separano le varie aree del diagramma di Voronoi, unendo i vertici di Voronoi calcolati tramite l’oggetto vor.

for simplex in vor.ridge_vertices:
    simplex = np.asarray(simplex)
    if np.all(simplex >= 0):
       plt.plot(vor.vertices[simplex, 0], vor.vertices[simplex, 1], 'k-')

Cosa ben più difficile da rappresentare sono i segmenti che partono dai vertici di Voronoi e vanno verso l’infinito. Ecco come rappresentarli.

center = points.mean(axis=0)
for pointidx, simplex in zip(vor.ridge_points, vor.ridge_vertices):
     simplex = np.asarray(simplex)
     if np.any(simplex < 0):
         i = simplex[simplex >= 0][0] # finite end Voronoi vertex
         t = points[pointidx[1]] - points[pointidx[0]]  # tangent
         t = t / np.linalg.norm(t)
         n = np.array([-t[1], t[0]]) # normal
         midpoint = points[pointidx].mean(axis=0)
         far_point = vor.vertices[i] + np.sign(np.dot(midpoint - center, n)) * n * 100
         plt.plot([vor.vertices[i,0], far_point[0]],
              [vor.vertices[i,1], far_point[1]], 'k-')

Infine rappresentiamo le varie aree del diagramma di Vorodoi con diversi colori, usando l’oggetto tree.

plt.pcolor(x, y, tree.query(xy)[1].reshape(200, 200))

Ed infine non ci rimane che inviare il comando per rappresentare il diagramma.

plt.show()

Ecco che apparirà il diagramma di Voronoi corrispondente ai 9 punti inseriti.

1 commento su “SciPy, una libreria Python per la matematica, la scienza e l’ingegneria

  1. Pingback: Python e gli operatori di assegnazione, matematici, logici, bitwise: overview – umbriawayamplifica

Lascia un commento