Vai al contenuto

12/03/2025 - Esercitazione su bash e gnuplot

Bash

I seguenti esercizi presuppongono la lettura del manuale ‘man‘ per la loro risoluzione.

Creare una struttura di cartelle

Supponiamo di voler creare in un solo colpo tre sottocartelle una dentro l’altra. Quale delle seguenti opzioni dovrei utilizzare?




Lettura file di testo

Voglio leggere le prime 10 righe di un file di testo chiamato "necronomicon.txt"




Cercare all’interno di un file

Il file di testo piazza_del_mercato.txt contiene uno script con 10000 righe del tipo "Personaggio: frase che viene detta". Voglio elencare tutte le battute dette da Waldo. Quale dei seguenti comandi posso usare?




Trovare la posizione di un eseguibile di sistema

Vorrei sapere dove si trova l’eseguibile gcc sul mio computer. Come posso trovarlo?




Spostare files

Voglio spostare il file les_miserables.txt nella cartella fr. Quale dei seguenti comandi posso usare?





Gnuplot

Installazione

Gnuplot è un programma molto versatile per creare grafici di funzioni o di dati. É di solito già disponibile sulle distribuzioni Linux e può essere installato facilmente sia su Mac, lanciando il comando

brew install gnuplot

che su Windows andando sulla pagina ufficiale e scaricando l'eseguibile dell'ultima versione. Linux dovrebbe aver gnuplot già installato ma in caso contrario potete utilizzare il comando:

sudo apt-get install gnuplot

Per far partire gnuplot dal terminale basta eseguire

gnuplot

Funzionamento

Ora possiamo fare il grafico di una funzione come ad esempio f(x) = sin (x) oppure f(x) = cos (x)2 facendo

gnuplot> plot sin(x)

oppure

gnuplot> plot cos(x)**2

Dove il simbolo  ** denota l’elevamento a potenza.

I comandi precedenti creano un singolo grafico a schermo con una sola funzione. Se vogliamo averle entrambe possiamo fare invece

gnuplot> plot sin(x)
gnuplot> replot cos(x)**2

Il comando plot genera un grafico da zero, mentre replot aggiunge un grafico a uno precedentemente fatto tramite plot.

Avrete notato che x non è mai stata definita: gnuplot assume che sia la variabile implicita su cui fare il grafico.

La libreria di funzioni matematiche a disposizione è molto estesa (vedi Fig. 1).

Image title

Fig 1. Funzioni matematiche integrate in gnuplot [fonte].

Possiamo usare i comandi set e unset per controllare gli aspetti essenziali di un grafico, ad esempio:

Imposta il range sull’asse X tra 0 e 2π (per asse Y usa yrange):

gnuplot> set xrange [0:2*pi]

Imposta il nome dell’asse Y (per asse X usa xlabel)

gnuplot> set ylabel "f(x)"

Imposta il titolo del grafico

gnuplot> set title "My Plot"

Imposta scala logaritmica su Y

gnuplot> set logscale y

Disabilita scala logaritmica su X

gnuplot> unset logscale x

Posiziona la legenda in basso a sinistra

gnuplot> set key bottom left

Oltre a fare grafici di funzioni possiamo anche utilizzare gnuplot per ottenere un grafico direttamente da dei dati. Ad esempio, prendiamo un file organizzato in colonne come il seguente

0.0   0.00000    1.00000    0.00000   1.00000   0.200
0.5   0.47942    0.87758    0.54630   1.64872   0.450
1.0   0.84147    0.54030    1.55741   2.71828   0.473
1.5   1.55741    0.07074   14.10142   4.48169   0.604

Crea un file nella stessa cartella dove hai eseguito gnuplot da terminale, inserisci i dati che trovi qui sopra e salvalo come file.dat. Puoi usare l’editor di testo che preferisci per fare questa cosa, ad esempio gedit. A questo punto possiamo fare un grafico dei dati specificando quali colonne usare, ad esempio:

Fa un grafico usando la colonna 1 come ascisse e la colonna 2 come ordinate

gnuplot> plot "file.dat" using 1:2

Aggiunge un grafico che usa la colonna 1 come ascisse e la 4 come ordinate

gnuplot> replot "file.dat" using 1:4

Fa un grafico usando le colonne 1 e 3 aggiungendo una linea che collega i dati

gnuplot> plot "file.dat" using 1:3 with lines

Fa un grafico usando la colonna 1 come ascisse, la colonna 5 come ordinate e la colonna 6 come errore sulle ordinate

gnuplot> plot "file.dat" using 1:5:6 with yerr

Con i comandi che abbiamo visto finora dovreste essere in grado di utilizzare a pieno gnuplot in modalità interattiva. Spesso invece possiamo voler salvare un grafico su un file esterno.

Ad esempio, per salvarlo in formato PDF potete usare

gnuplot> set terminal pdfcairo size 10,4.5 lw 1.5 enhanced
gnuplot> set output "plot.pdf"
gnuplot> plot sin(x)**2
gnuplot> unset output

L’azione dei comandi è la seguente

  • il primo comando imposta l’output di gnuplot su pdfcairo (il pacchetto che gestisce la generazione di file pdf) aggiungendo in più alcune opzioni utili
  • Il secondo comando dichiara che vogliamo usare un file chiamato "plot.pdf" per salvare il nostro grafico
  • Il terzo comando fa un semplice grafico (notate che ora non viene stampato a schermo come succedeva prima)
  • Il quarto comando chiude il file salvandolo su disco

Se vogliamo continuare ad utilizzare gnuplot in modalità interattiva, senza chiuderlo e riaprirlo, possiamo resettare l’output con il comando

gnuplot> set terminal x11

Per approfondire ulteriormente l’argomento potete consultare ad esempio le seguenti risorse

Nel resto di questa esercitazione esploreremo invece l’utilizzo di gnuplot come calcolatore. Abbiamo già visto che gnuplot mette a disposizione una vasta libreria di funzioni matematiche, in aggiunta possiamo

  • Definire una nostra funzione

    gnuplot> f1(x) = sin(sqrt(1.0+cos(x)))
    gnuplot> set xrange [-2*pi:2*pi]
    gnuplot> plot f1(x)
    

    Questo codice definisce la funzione \(f1(x)=\sin\left(\sqrt{1.0+\cos(x)}\right)\) e ne fa il grafico sull’intervallo \([−2\pi,2\pi]\).

    Possiamo anche definire funzioni che dipendono da uno o più parametri

    gnuplot> f2(x,a,b) = sin(a*sqrt(1.0+cos(b*x)))
    gnuplot> plot f2(x,1.0,1.0)
    gnuplot> replot f2(x,2.0,0.5)
    

    dove ora la funzione che abbiamo definito è invece \(f2(x,a,b)=\sin\left(a\sqrt{1.0+\cos(bx)}\right)\)

  • stampare il valore di un’espressione matematica

    gnuplot> print tan(4)*(0.5**(sqrt(3*cos(0.1))))
    

    questo comando stampa il valore di \(\tan(4) 0.5^{\sqrt{3\cos(0.1)}}\)

  • definire delle variabili e assegnarne valori

    gnuplot> a=4
    gnuplot> b=3*cos(0.1)
    gnuplot> c=tan(a)*(0.5**sqrt(b))
    gnuplot> print c
    

    In questo codice definiamo tre variabili

    • la variabile a a cui assegniamo il valore 4

    • la variabile b a cui assegniamo il valore 3cos (0.1)

    • la variabile c a cui assegniamo un valore che dipende dal valore contenuto nelle prime due variabili

    Una volta assegnato il valore alla variabile c, se poi cambiamo a o b questo non cambierà. Ad esempio provate ad eseguire il codice

    gnuplot> a=4
    gnuplot> b=3
    gnuplot> c=a*b
    gnuplot> print c
    gnuplot> a=2
    gnuplot> print c
    gnuplot> c=2*a*b
    gnuplot> print c
    

    nella penultima riga abbiamo sovrascritto il valore contenuto in c usando i valori correnti delle variabili a e b.

Con queste basi possiamo eseguire dei semplici algoritmi che non richiedono troppa automazione.

Algoritmo di Bisezione

Immaginate di avere una funzione \(f(x)\) e di voler trovare la posizione di un suo zero, ovvero un valore \(x^*\) per cui \(f(x^*) = 0\). L’algoritmo di bisezione permette di stimare \(x^*\) con una procedura iterativa.

Per partire ci servono due punti \(a_0\) e \(b_0\), con \(b_0 > a_0\), per cui \(f(a_0)f(b_0) < 0\). Questa condizione implica che la funzione \(f(x)\) cambia segno mentre andiamo da \(a_0\) a \(b_0\) e quindi lo zero \(x^*\) deve trovarsi fra i due. A questo punto possiamo dare una stima \(c_0 = (a_0+b_0)/2\) per la posizione dello zero della funzione.

Se ora vogliamo trovare un’approssimazione migliore possiamo calcolare il valore \(f(c_0)\) della funzione in \(c_0\), avremo quindi

  • se \(f(a_0)f(c_0) < 0\) allora siamo sicuri che \(x^* \in[a_0,c_0]\). Procediamo quindi settando \(a_1 = a_0\) e \(b_1 = c_0\)
  • altrimenti avremo che \(f(c_0)f(b_0) < 0\) e quindi \(x^* \in [a_0,c_0]\). Procediamo quindi settando \(a_1 = c_0\) e \(b_1 = b_0\).

una volta ottenuti i punti \(a_1\) e \(b_1\) che definiscono il nuovo intervallo per cui \(x^* \in [a_1,b_1]\), la nuova stima per lo zero sará quindi \(c_1 = (a_1+b_1)/2\). Questa procedura puó essere fatta piú volte per ottenere stime piú precise di \(x^*\).

Per eseguire questo algoritmo in modo semplice con gnuplot possiamo usare due accorgimenti

  • possiamo eseguire piú comandi in una sola riga usando ;

    gnuplot> a=1; b=3; print "test iniziale:",f(a)*f(b)
    gnuplot> c=(a+b)/2.0; print "c=",c; print "test:",f(a)*f(c)
    

    La prima riga imposta i valori iniziali di a e b e stampa il risultato di f(a)f(b) per controllare sia negativo come vogliamo. Nella seconda riga calcoliamo c, ne stampiamo il valore e stampiamo anche f(a)f(c) per poter fare il passo successivo: se il valore stampato é positivo facciamo a = c, se é negativo facciamo b = c.

  • usando la freccia in sú possiamo recuperare i comandi dati in precedenza senza riscriverli interamente

Esercizio

Prendiamo una variabile aleatoria $r4 con una distribuzione Gaussiana di media \(μ = 0\) e varianza \(σ = 1\). La probabilitá di osservare la variabile in un intervallo \(\[−L,L\]\) centrato in zero é data da

\(Pr[-L\leq r\leq L] = \frac{1}{\sqrt{2\pi}}\int\_{-x}^x dr e^{-\frac{1}{2}r^2}=\text{erf}\left(\frac{L}{\sqrt{2}}\right)\)

La funzione erf (error function) é giá implementata su gnuplot. Cerca quindi di usare l’algoritmo di bisezione per risolvere l’equazione \(\label{eq:eqzero} \text{erf}\left(\frac{x}{\sqrt{2}}\right)=0.8\)

  • implementa la corretta funzione di cui trovare lo zero
  • fai un grafico della funzione e verifica che uno zero esista effettivamente
  • usa il grafico per trovare due punti iniziali a e b che vadano bene
  • approssima la soluzione di Eq. [eq:eqzero eseguendo almeno 10 iterazioni di bisezione
  • [BONUS] come faresti a stimare l’errore nella stima della soluzione?
  • [BONUS] fai un grafico della soluzione approssimata in funzione del numero di iterazioni