equazioni lineari e matrici: la matematica in rete - Cineca

Transcript

equazioni lineari e matrici: la matematica in rete - Cineca
Piano Nazionale Lauree Scientifiche - a.a. 2010/11
Laboratorio PLS
EQUAZIONI LINEARI E MATRICI:
LA MATEMATICA IN RETE
con
I.T.C. “ZANON” (Udine)
L.S. “LE FILANDIERE” (San Vito al Tagliamento)
Dimitri Breda1 , Alessandra Maniglio2 , Paola Pignoni3 , Stefania Pividori3
1 Dipartimento
di Matematica e Informatica
Università degli Studi di Udine
[email protected]
http://users.dimi.uniud.it/˜dimitri.breda/
2 Liceo
Scientifico “Le Filandiere”
San Vito al Tagliamento
[email protected]
2 Istituto
Tecnico Commerciale “Zanon”
Udine
[email protected]
[email protected]
1
Indice
1
Introduzione
2
Vettori, matrici e sistemi lineari
2.1 Piano cartesiano e vettori . . . . .
2.2 Trasformazioni lineari e matrici .
2.3 Sistemi lineari . . . . . . . . . . .
2.4 Un po’ di trigonometria non nuoce
2.5 Ma quanto costa? . . . . . . . . .
3
3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
9
17
23
27
Google
3.1 Matrici di connettività e navigatori casuali . . . . . . . .
3.2 La fortuna di Google: il metodo delle potenze e tanti zeri
3.3 Pagine penzolanti e ricerche personalizzate . . . . . . .
3.4 Pagerank finalmente?! . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
29
30
36
40
50
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
A Appendice: cifre significative, accuratezza e precisione
56
B Codici Pagerank realizzati
57
2
1
Introduzione
Queste pagine vogliono rappresentare una breve guida alle attività svolte all’interno del Piano Nazionale Lauree Scientifiche (PLS) per il Laboratorio “Equazioni lineari e matrici: la matematica in rete”.
Esse sono rivolte a selezioni di alunni di classi quarte provenienti dall’Istituto Tecnico Commerciale “Zanon” di Udine e dal Liceo Scientifico “Le Filandiere” di San Vito al Tagliamento, nonchè progettate
congiuntamente tra i docenti universitari e gli insegnanti di cui nel frontespizio.
Si premette che, seguendo le direttive del PLS, gli argomenti sviluppati non vengono presentati in modo meramente nozionistico, piuttosto con l’intento di stimolare la curiosità e l’interesse dei partecipanti
verso tematiche a forte contenuto matematico - anche avanzato rispetto agli standard dei programmi ministeriali previsti per l’istruzione secondaria - ma che, tutto sommato, si possono spesso incontrare nella
vita quotidiana, soprattutto in una realtà permeata dall’intensivo utilizzo della teconologia e dell’informatica come quella attuale. È bene avvisare il lettore più preparato che le esigenze di semplificazione
emerse nella scrittura di queste note hanno spesso invaso lo spazio normalmente destinato al rigore e alla
completezza caratteristici di una trattazione matematica.
A tale scopo, e vista la disponibilità dei laboratori della Facoltà di Scienze MFN dell’Università di Udine, dove si svolge parte dell’attività, ci si avvale del software MATLAB© come veicolo di apprendimento.
Rimandiamo una volta per tutte a [1, 2] gli eventuali lettori dall’interesse “insaziabile”, sottolineando che
parte del materiale presentato è preso da tali riferimenti, frutto del creatore stesso di Matlab, Cleve Moler.
I protagonisti di queste note sono in primo luogo i vettori, le matrici ed i sistemi lineari. Tralasciandone le più profonde connotazioni algebriche e geometriche per le ragioni premesse, vettori e matrici sono
introdotti in Sezione 2 nel caso bidimensionale, ovvero il più semplice possibile. Aldilà delle esigenze
di semplificazione, questo caso si presta ottimamante all’interpretazione geometrica della matrice come
trasformazione lineare nel piano cartesiano. Dopo aver introdotto - e “digerito” - operazioni quali il
prodotto scalare di vettori e il prodotto righe-colonne di matrici, rivisiteremo sotto un’altra prospettiva i
sistemi di equazioni lineari che già ben conosciamo. La parte finale di tale sezione sarà dedicata all’analisi
dei costi computazionali che comportano le operazioni base dell’algebra matriciale. L’intera Sezione è
poi accompagnata da esempi ed esercizi con lo scopo di avvicinare gradualmente gli alunni all’utlizzo di
Matlab.
Apprese e consolidate le nuove nozioni di cui sopra, le sfrutteremo in Sezione 3 per addentrarci nel
mondo della rete e del World Wide Web (WWW) in particolare. L’obiettivo che ci poniamo consiste nel
comprendere gli aspetti fondamentali che ci permettono di ordinare le informazioni che ci interessano
in un mondo tanto vasto come il WWW, di capirne la modellizzazione matematica che è ivi nascosta,
per arrivare infine a realizzare delle implementazioni Matlab dell’algoritmo PAGERANK© utilizzato da
GOOGLE© .
Riguardo alla struttura delle attività, è bene osservare che il laboratorio inizia con la conferenza “Dal
mattone a Google: equazioni ovunque” tenuta dal docente universitario presso gli Istituti aderenti, allo
scopo di introdurre gli alunni alle tematiche trattate. Esso continua poi con una fase di “azzeramento” dei
requisiti (coprente a grandi linee i contenuti della Sezione 2), condotta dagli insegnanti coinvolti presso i
relativi Istituti. Si giunge quindi allo “stage” degli alunni presso i laboratori della Facoltà, dove vengono
impartite le nozioni base di Matlab e si procede all’implementazione dei codici. Seguono poi opportune
fasi di approfondimento e verifica.
Con un po’ di pazienza, e guidati dal motore principe della ricerca e delle innovazioni scientifiche e,
in genere, culturali - la curiosità - alla fine di quest’esperienza guarderemo alle matrici e ai sistemi con
un riguardo maggiore di quello che potremmo abitualmente concedere ad una semplice tabella di numeri
3
o a delle noiose equazioni da risolvere. Certo non pretenderemo di coglierne a pieno tutte le notevoli
potenzialità che celano al loro interno, ma per questo...c’è sempre l’opportunità di iscriversi ai Corsi di
Laurea della Facoltà di Scienze!
4
2
2.1
Vettori, matrici e sistemi lineari
Piano cartesiano e vettori
Tutti noi conosciamo bene il piano cartesiano (da René Descartes [1596-1650], filosofo e matematico
francese) e sappiamo che ogni suo punto può essere univocamente associato ad una coppia di numeri, le
sue coordinate. Indichiamo tali numeri in un modo forse un po’ diverso da quello abituale, ovvero con un
vettore colonna:
x1
x=
.
x2
Ad esempio, il punto associato al vettore x di Figura 1 ha coordinate
2
x=
.
4
Sono definite in modo naturale operazioni quali la somma algebrica di vettori
x1
y1
x1 + y 1
x+y =
+
=
x2
y2
x2 + y 2
e la moltiplicazione per uno scalare
sx = s
x1
x2
=
sx1
sx2
Il loro significato geometrico è fornito, nel primo caso, dalla cosiddetta regola del parallelogramma e,
nel secondo, dall’allungamento se |s| > 1 o accorciamento se |s| < 1, eventualmente accompagnati dal
cambio di verso se s < 0. La loro “combinazione” prende il nome, appunto, di combinazione lineare di
vettori:
ax1 + by1
by1
ax1
y1
x1
.
=
+
=
+b
ax + by = a
ax2 + by2
by2
ax2
y2
x2
Esempio 1 In Figura 1 è rappresentato il vettore
x=
2
4
relativo al punto di coordinate x1 = 2 ed x2 = 4. Inoltre abbiamo il vettore
−1
y=
,
2
la loro somma
x+y =
2−1
4+2
=
1
6
ed, infine, il prodotto di x con lo scalare s = −0.5:
−0.5 · 2
−1
s · x = −0.5 · x =
=
.
−0.5 · 4
−2
Da notare che, come anticipato, uno scalare negativo ha l’effetto di cambiare il verso del vettore che
moltiplica.
5
Esercizio 1 Secondo la regola del parallelogramma, il vettore somma di due vettori corrisponde geometricamente alla diagonale principale del parallelogramma che ha per lati i due vettori addendi, vedi
Esempio 1. A cosa corrisponde invece il vettore differenza? (Sugg.: non servono regole nuove, basta
usare sapientemente la somma e la moltiplicazione per uno scalare)
Matlab 1 In Matlab potremmo eseguire il contenuto dell’Esempio 1 con le seguenti istruzioni (premete
invio alla fine di ogni istruzione):
>> x=[2;4]
x =
2
4
>> y=[-1;2]
y =
-1
2
>> x+y
ans =
1
6
>> s=-0.5
s =
-0.5000
>> s*x
ans =
-1
-2
Cogliamo l’occasione per dire che il simbolo “+” indica la somma algebrica, mentre “*” la moltiplicazione in genere. Osserviamo poi che i vettori colonna si inseriscono separando gli elementi con “;”
all’interno di parentesi quadre.
Meno naturale può risultare l’operazione di prodotto scalare di due vettori, definito come
x1
y1
x·y =
·
= x1 y1 + x2 y2 ,
x2
y2
ovvero la somma dei prodotti delle componenti corrispondenti.
Esempio 2 Per
2
3
3
1
x=
e
y=
risulta
x · y = 2 · 3 + 3 · 1 = 9,
6
7
m
6
5
x
4
3
2
y
1
0
−1
−2
−3
−2
−0.5! x
−1
0
1
2
3
Figura 1: somma algebrica e moltiplicazione per uno scalare.
mentre con
z=
−3
2
risulta
x · z = 2 · (−3) + 3 · 2 = 0.
I vettori sono rappresentati in Figura 2.
Matlab 2 In Matlab:
>> x=[2;3]
x =
2
3
>> y=[3;1]
y =
3
1
>> x’*y
ans =
9
>> z=[-3;2]
z =
-3
7
2
>> x’*z
ans =
0
Per eseguire il prodotto scalare usiamo “’ *”. Ma per ora non occupiamoci del significato del simbolo
“’”, lo apprenderemo strada facendo.
4
x
3
z
2
y
1
0
−1
−4
−3
−2
−1
0
1
2
3
4
Figura 2: prodotto scalare e vettori perpendicolari.
Dal precedente esempio potremmo indurre che due vettori sono perpendicolari (od ortogonali) se il
loro prodotto scalare risulta nullo. Questo fatto costituisce in realtà un fondamentale Teorema dell’algebra
lineare e della geometria piana:
x ⊥ y ⇔ x · y = 0 ⇔ x1 y1 + x2 y2 = 0.
(1)
Di seguito proponiamo un esempio interessante di uso del prodotto scalare. Ad ogni modo, il significato geometrico di tale operazione verrà approfondito più avanti.
Esempio 3 Per apprezzare alcune implicazioni “reali” del prodotto scalare, prendiamo in prestito dalla Fisica il concetto di lavoro. Il lavoro L (scalare) che una forza F (vettore) compie a seguito dello
spostamento s (vettore) del suo punto di applicazione è il prodotto scalare
L = F · s.
8
2.2
Trasformazioni lineari e matrici
Ora ci chiediamo, dato un punto del piano individuato dal vettore x, quale sia il modo più generale
possibile per ottenere un nuovo punto individuato da un vettore y attraverso combinazione lineare delle
coordinate di x. Più in dettaglio, vogliamo che ciascuna coordinata del nuovo punto y sia combinazione
lineare delle coordinate di x. Traducendo in linguaggio matematico:
y1
ax1 + bx2
y=
=
(2)
y2
cx1 + dx2
con a, b, c e d scalari assegnati.
Esempio 4 In Figura 3 possiamo vedere il caso concreto relativo a
2
x=
4
ed a = 4, b = −3, c = −2 e d = 1. Si ottiene dunque
y1
ax1 + bx2
4·2−3·4
−4
y=
=
=
=
.
y2
cx1 + dx2
−2 · 2 + 1 · 4
0
x
4
3
2
1
0
−1
−5
y=Ax
−4
−3
−2
−1
0
1
2
3
Figura 3: prodotto matrice-vettore.
Possiamo scrivere in modo più “compatto” il passaggio da x ad y? Il trucco è nel raccogliere in modo
opportuno tutti i dati che ci servono, ovvero le coordinate di x (e questo lo sappiamo già fare con la
9
notazione di vettore colonna) e i quattro scalari a, b, c e d. Un modo semplice è quello di utilizzare una
sorta di tabella con due righe e due colonne:
a b
,
c d
che ricalca fedelmente la posizione degli scalari nella (2).
Ma come faccio a sapere che posizione occupa lo scalare c nella mia tabella se ne conosco solamente
il “nome”? Per superare questa lieve difficoltà cambiamo notazione e diamo un nome (ragionevole) alla
tabella:
a11 a12
A=
.
a21 a22
Allora aij indicherà l’elemento della tabella A che occupa l’i-esima riga e la j-esima colonna. Ad esempio
a21 indicherà l’elemento di A in seconda riga e prima colonna. Da questo momento in poi possiamo usare
a pieno diritto il termine matrice per indicare l’oggetto matematico A.
Tornando alla nostra trasformazione x → y, scriveremo dunque in modo compatto:
x1
a11 a12
a11 x1 + a12 x2
y1
= Ax,
=
=
y=
x2
a21 a22
a21 x1 + a22 x2
y2
definendo cosı̀ il prodotto matrice-vettore.
Riassumendo: tutte le trasformazioni che, preso un vettore ne producono un altro attraverso combinazioni lineari delle coordinate del primo sono esprimibili in modo compatto con l’applicazione di una
matrice al vettore stesso. Si parla allora di trasformazioni lineari nel piano e le matrici vengono anche
dette applicazioni lineari.
Ora, come facciamo a memorizzare le regole usate per esprimere il prodotto matrice-vettore appena
introdotto? Denotiamo con a1,: il vettore riga costituito dagli elementi della prima riga di A (la ragione
di tale notazione sarà chiara in Matlab 3):
a1,: = a11 a12 .
Finora abbiamo utilizzato però vettori colonna. Allora introduciamo quella che si chiama trasposizione
(da cui il simbolo T come apice):
a11
T
a1,: =
.
a12
In seguito approfondiremo la vera natura di tale operazione. Adesso che abbiamo la prima riga di A come
colonna, possiamo usare l’abituale prodotto scalare con il vettore x per accorgerci che, se y = Ax, allora
y1 = a11 x1 + a12 x2 = a1,: T · x.
Analagomente:
y2 = a21 x1 + a22 x2 = a2,: T · x
per
a2,: =
ovvero
T
a21 a22
a2,: =
a21
a22
.
Deduciamo che ogni coordinata risultante da un prodotto matrice-vettore Ax è data dal prodotto scalare
della relativa “riga” con il vettore x stesso.
10
Esempio 5 L’esempio 4 può essere rivisto nel seguente modo compatto:
4 −3
2
4·2−3·4
−4
y = Ax =
=
=
.
−2 1
4
−2 · 2 + 1 · 4
0
Esercizio 2 Non dovrebbe sorprendere che per qualunque vettore risulta sempre
(vT )T = v.
Matlab 3 Per usare Matlab dobbiamo prima imparare ad inserire una matrice, la qualcosa è abbastanza
semplice ed intuitiva. Infatti, la matrice
a11 a12
A=
a21 a22
viene creata con il comando:
A=[a11,a12;a21,a22]
ovvero:
• inserendo gli elementi tra parentesi quadre
• separando le righe con “;”
• separando gli elementi all’interno di una stessa riga con “,” (o spazi “ ”).
Allora il nostro prodotto matrice-vettore si esegue nel seguente modo:
>> A=[4,-3;-2,1]
A =
4
-3
-2
1
>> x=[2;4]
x =
2
4
>> y=A*x
y =
-4
0
L’esito si è già visto in Figura 3. Osserviamo anche l’uso del simbolo “:” per indicare righe e colonne
di A:
11
>> A(1,:)
ans =
4
-3
>> A(2,:)
ans =
-2
1
>> A(:,1)
ans =
4
-2
>> A(:,2)
ans =
-3
1
Verifichiamo quindi che le componenti di y sono i prodotti scalari delle corrispondenti righe di A per il
vettore x. Innanzitutto dobbiamo “trasporre” le righe di A per farle diventare vettori colonna. Per questo
usiamo l’apice “’”:
>> b1=A(1,:)’
b1 =
4
-3
>> b2=A(2,:)’
b2 =
-2
1
ed effettuiamo il prodotto scalare come abbiamo imparato:
>> b1’*x
ans =
-4
>> b2’*x
ans =
0
Ora, avrete notato che abbiamo usato l’apice di traposizione due volte, il che non cambia le cose
(Esercizio 2):
>> b1
b1 =
4
-3
>> b1’’
ans =
4
-3
12
Ma su questo apparente corto circuito torneremo in seguito.
Esercizio 3 Date due matrici A e B, la loro somma è definita estendendo in maniera naturale la somma
componente per componente vista per i vettori, quindi:
a11 a12
b11 b12
a11 + b11 a12 + b12
A+B =
+
=
.
a21 a22
b21 b22
a21 + b21 a22 + b22
Dimostrate ora che per il prodotto matrice-vettore vale la proprietà distributiva sia rispetto alla matrice,
ovvero:
(A + B)x = Ax + Bx,
sia rispetto al vettore, ovvero:
A(x + y) = Ax + Ay.
Bene, adesso che abbiamo imparato il prodotto matrice-vettore, non sarà assolutamente difficile imparare il prodotto righe-colonne di due matrici. Consideriamo infatti le matrici
a11 a12
A=
a21 a22
e
B=
b11 b12
b21 b22
.
Che cosa significa il prodotto
C = AB =
a11 a12
a21 a22
b11 b12
?
b21 b22
Se non l’avete già intuito, basta considerare la matrice B come una “collezione” di colonne, che indicheremo come (ricordando la notazione “:”)
B = [b:,1 , b:,2 ]
dove indichiamo con
b11
b21
b12
b22
b:,1 =
e
b:,2 =
i vettori corrispondenti, rispettivamente, alla prima e alla seconda colonna della matrice B, usando una
notazione analoga a quanto già visto per le righe. Allora il prodotto C = AB può essere visto come la
matrice
C = [c:,1 , c:,2 ]
dove ciascuna colonna è il prodotto della matrice A per la relativa colonna di B:
a11 b11 + a12 b21
c:,1 = Ab:,1 =
a21 b11 + a22 b21
13
e
a11 b12 + a12 b22
a21 b12 + a22 b22
c:,2 = Ab:,2 =
.
Quindi il prodotto viene distribuito ad ogni colonna:
AB = A[b:,1 , b:,2 ] = [Ab:,1 , Ab:,2 ] = [c:,1 , c:,2 ] = C
ovvero
a11 a12
a21 a22
b11 b12
b21 b22
=
(3)
a11 b11 + a12 b21 a11 b12 + a12 b22
a21 b11 + a22 b21 a21 b12 + a22 b22
.
Esempio 6 Per
A=
e
4 −3
−2 1
B=
1 0
5 2
si ottiene
AB =
4 −3
−2 1
1 0
5 2
=
4·1−3·5
4·0−3·2
−2 · 1 + 1 · 5 −2 · 0 + 1 · 2
=
−11 −6
3
2
.
Matlab 4 In Matlab (ricordando che A esiste già!):
>> B=[1,0;5,2]
B =
1
0
5
2
>> A*B
ans =
-11
-6
3
2
Esercizio 4 Provate a costruire una matrice I che, moltiplicando qualunque vettore x, lo lascia invariato,
ovvero:
Ix = x.
Esercizio 5 Date tre matrici qualunque A, B e C di 2 righe e 2 colonne, dimostrate ora che per il prodotto
righe-colonne valgono sia la proprietà distributiva
A(B + C) = AB + AC
sia la proprietà associativa
A(BC) = (AB)C.
14
Senza ulteriori spiegazioni, non dovrebbe essere difficile accertarsi della validità delle seguente generalizzazione derivante dalla (3):
A[b:,1 , b:,2 , . . . , b:,n ] = [c:,1 , c:,2 , . . . , c:,n ].
Come si suol dire, “fatto 30 facciamo 31”. Visto che abbiamo appena usato una matrice che ha più
colonne (ovvero n) che righe (ovvero 2), allora diciamo che se una matrice M ha r righe e c colonne ed i
suoi elementi sono numeri reali, cioè


m11 m12 · · · m1c
 m21 m22 · · · m2c 


M =  ..
..
..  ,
 .
.
. 
mr1 mr2 · · · mrc
con mij ∈ R per ogni i = 1, 2, . . . , r e per ogni j = 1, 2, . . . , c, indicheremo questo fatto con
M ∈ Rr×c .
Commento 1 (importante!) Il prodotto matriciale appena introdotto ha l’unico vincolo di richiedere
che il numero di colonne della prima matrice corrisponda al numero di righe della seconda matrice. Ne convenite? Se la risposta è affermativa, allora cosa rispondereste alla domanda sulla proprietà
commutativa:
AB = BA?
Provate con un esempio, poi proveremo con Matlab...
Bene, se non avete accusato il colpo allora non avrete problemi a considerare un vettore colonna di n
elementi


v1
 v2 


v =  .. 
 . 
vn
come una particolare matrice: v ∈ Rn×1 (= Rn ). Esistono poi, come visto, anche i vettori riga:
w = [w1 , w2 , . . . , wm ].
In tal caso w ∈ R1×m (indicabile anch’esso come Rm ). Ad ogni modo, la convenzione considera i vettori
sempre come colonna, se non diversamente specificato. Bene, visto che i vettori sono particolari matrici,
nulla ci vieta di applicare loro il prodotto “vettore-vettore” inteso come caso particolare del prodotto
matriciale righe-colonne appena appreso. Siccome la regola dice che il numero di colonne del primo
fattore deve coincidere col numero di righe del secondo, se entrambi i fattori sono vettori con lo stesso
numero di elementi (diciamo n) ci rimangono solo due possibilità. Una consiste nel moltiplicare il vettore
riga per il vettore colonna, ottenendo cosı̀ un numero scalare:
R1×n · Rn×1 = R1×1
(= R).
Ma questo è proprio il prodotto scalare di vettori, ecco spiegato finalmente l’uso della trasposizione se
sono entrambi colonna: il primo deve diventare riga! Per la seconda avete un po’ più di tempo per
pensarci: la incontreremo in Sezione 3.3.
15
Matlab 5 Proviamo ad eseguire diversi prodotti matriciali in Matlab, verificandone le proprietà riguardanti la dimensione dei fattori. Iniziamo con A ∈ R3×2 e B ∈ R3×4 , il cui prodotto AB non è possibile
dato che il numero di colonne di A (2, primo fattore) differisce dal numero di righe di B (3, secondo
fattore):
>> A=[1,2;3,4;5,6]
A =
1
2
3
4
5
6
>> B=[12,11,10,9;8,7,6,5;4,3,2,1]
B =
12
11
10
9
8
7
6
5
4
3
2
1
>> A*B
??? Error using ==> mtimes
Inner matrix dimensions must agree.
Modifichiamo allora con B ∈ R2×4 , ottenendo AB ∈ R3×4 :
>> B=[8,7,6,5;4,3,2,1]
B =
8
7
6
5
4
3
2
1
>> A*B
ans =
16
13
10
7
40
33
26
19
64
53
42
31
Verifichiamo che il prodotto di matrici non è, in generale, commutativo, cioè AB 6= BA. Questo succede
sempre se le dimensioni non sono compatibili con la regola del prodotto, ad esempio con le matrici A e
B inserite, AB è lecito ma BA non lo è:
>> B*A
??? Error using ==> mtimes
Inner matrix dimensions must agree.
Ad ogni modo, in generale, il prodotto non è commutativo nemmeno quando i fattori sono “quadrati”:
>> A=[1,2;3,4]
A =
1
2
3
4
>> B=[4,3;2,1]
B =
4
3
16
2
>> A*B
ans =
8
20
>> B*A
ans =
13
5
1
5
13
20
8
Vediamo ora cosa succede con i prodotti di vettori:
>> v=[1;2;3]
v =
1
2
3
>> w=[3;2;1]
w =
3
2
1
>> v*w
??? Error using ==> mtimes
Inner matrix dimensions must agree.
>> v’*w
ans =
10
>> v*w’
ans =
3
2
1
6
4
2
9
6
3
2.3
Sistemi lineari
In questa sezione osserveremo i sistemi di equazioni lineari (in breve sistemi lineari) da un’altra prospettiva.
Cominciamo dalle cose veramente essenziali. Come rappresentante delle più semplici equazioni
lineari possiamo considerare a pieno titolo la seguente:
3x = 21,
la cui soluzione (ricordando i principi di equivalenza) è banalmente
x=
21
= 7.
3
17
Questo vale ovviamente per tutte le equazioni del tipo
ax = b
(4)
con soluzione
b
a
avendo preventivamente assunto a 6= 0. Se invece fosse a = 0, allora non avremmo soluzione per b 6= 0
(dato che non esiste alcun numero che moltiplicato per 0 fornisca un numero diverso da 0) mentre ne
avremmo infinite per b = 0 (dato che qualunque numero moltiplicato per 0 fornisce 0).
Complichiamoci ora un po’ la vita, ma non troppo, e consideriamo il classico problema della spesa che
viene proposto in mille versioni a partire dalle scuole elementari (osservando tra l’altro come l’apprendimento di certe proprietà matematiche notevoli non richieda per forza di cose la trattazione di problemi
complessi e lontani dalla realtà quotidiana più spicciola).
x=
Problema 1 Anna compra dal fruttivendolo 2 kg di mele e 1 kg di pere, spendendo 7 euro. Marco compra
dallo stesso fruttivendolo 4 kg di mele e 3 kg di pere, spendendo 17 euro. Quanto costano, rispettivamente,
1 kg di mele e 1 kg di pere?
La risoluzione di questo semplice quesito consiste nel tradurlo nelle equazioni di primo grado (ovvero
lineari)
2x1 + x2 = 7
4x1 + 3x2 = 17
avendo assunto la convenzione che x1 ed x2 rappresentino, rispettivamente, il numero incognito di kg di
mele e pere. È facile verificare che la soluzione è x1 = 2 e x2 = 3. Oppure si può procedere mediante
il metodo di eliminazione di Gauss (Carl Friedrich [1777-1855], matematico tedesco) e la sostituzione
all’indietro, come visto alla conferenza iniziale.
Guardiamo con attenzione i due membri sinistri: ci ricordano qualcosa? Ciascuno di essi rappresenta
una combinazione lineare delle incognite x1 ed x2 , attraverso rispettivamente gli scalari 2 ed 1 per la
prima equazione e 4 e 3 per la seconda. Avendo imparato come esprimere le combinazioni lineari con le
matrici, allora potremmo scrivere il nostro sistema lineare in forma vettoriale:
2 1
x1
7
=
,
x2
17
4 3
infatti
2 1
4 3
x1
x2
=
Se ora indichiamo con
2x1 + 1x2
4x1 + 3x2
A=
2 1
4 3
la cosiddetta matrice dei coefficienti, con
x1
x2
7
17
x=
il vettore delle incognite e, infine, con
b=
18
=
7
17
.
il vettore dei termini noti, allora il nostro sistema diventa
Ax = b
che ricalca fedelemente la scrittura dell’equazione (4).
Ora, ricordando il caso (scalare) della singola equazione (4), saremmo tentati di risolvere per x andando a dividere entrambi i membri per la matrice A. Ma questa, ahimè, non è certamente una strada
matematicamente percorribile. La versione matematicamente corretta passa effettivamente per
b
b
ax
= ⇔x= ,
a
a
a
ma, non essendo permessa la divisione per A, corrisponde piuttosto a:
ax = b ⇔
ax = b ⇔ a−1 (ax) = a−1 b ⇔ (a−1 a)x = a−1 b ⇔ x = a−1 b
che, nel caso della (4), è basata sull’identità
1
a−1 = ,
a
sempre sotto l’ipotesi a 6= 0. Quindi la soluzione del nostro sistema lineare è rappresentata da
Ax = b ⇔ A−1 (Ax) = A−1 b ⇔ (A−1 A)x = A−1 b ⇔ x = A−1 b
dove A−1 è la cosiddetta matrice inversa di A. Ovviamente abbiamo “scommesso” che (A−1 A)x = x.
Ma vale questa proprietà? E chi è A−1 ? Per rispondere, dobbiamo capire bene chi è a−1 . Tutti sappiamo
che tale numero soddisfa a
a−1 a = 1 = aa−1
(sempre per a 6= 0, chiaramente). Allora, per analogia, definiamo A−1 come quella matrice che soddisfa
a
AA−1 = I = A−1 A
(5)
con I la matrice identità, vedi Esercizio 4. Infatti I è il corrispondente di 1 nel caso scalare. Che proprietà
ha il numero 1 nella moltiplicazione? Esso lascia invariato qualunque numero moltiplichi:
1 · a = a = a · 1.
Ma questo vale anche per I se per moltiplicazione intendiamo il prodotto righe-colonne, infatti:
IA = A = AI.
Tale proprietà può essere verificata nel caso bidimensionale, dove
1 0
I=
,
0 1
ma vale ovviamente per qualunque dimensione con

1 0

 0 1
I= .
 ..
0 ···
19
···
...
0

0
.. 
. 
.
0 
1
Esempio 7 Possiamo verificare formalmente la proprietà della matrice identità:
1 0
a11 a12
1 · a11 + 0 · a21 1 · a12 + 0 · a22
a11 a12
=
=
.
0 1
a21 a22
0 · a11 + 1 · a21 0 · a12 + 1 · a22
a21 a22
Analogamente:
a11 a12
1 0
a11 · 1 + a12 · 0 a11 · 0 + a12 · 1
a11 a12
=
=
.
a21 a22
0 1
a21 · 1 + a22 · 0 a21 · 0 + a22 · 1
a21 a22
Matlab 6 La matrice inversa si ottiene con il comando Matlab
inv(A)
che per il nostro esempio fornisce
>>A=[2,1;4,3];
>> iA=inv(A)
iA =
1.5000
-0.5000
-2.0000
1.0000
cioè
A
−1
=
3/2 −1/2
−2
1
(se volete, provate a verificare che quest’ultima soddisfa la definizione appena data).
Commento 2 (il determinante) Si può sempre definire A−1 ? Fidandoci ancora dell’analogia con il caso
scalare, sappiamo che si può parlare del numero a−1 se e sole se a 6= 0. Ma cosa vorrebe dire nel caso
delle matrici? Bisogna ricorrere alla nozione di determinante. Si definisce determinante di una matrice
a11 a12
A=
a21 a22
la quantità
det (A) = a11 a22 − a12 a21 .
Allora si può parlare di A−1 se e sole se det (A) 6= 0: questo, in realtà, è un vero e proprio Teorema
dell’algebra lineare. Una matrice A tale per cui det (A) = 0 si dice anche singolare.
Matlab 7 In Matlab il determinante si ottiene facilmente con il comando
det(A)
Ad esempio:
20
>> A=[2,1;4,3];
>> det(A)
ans =
2
infatti
det (A) = 2 · 3 − 1 · 4 = 6 − 4 = 2.
Succede ad esempio che
>> A=[2,1;4,2];
>> det(A)
ans =
0
>> iA=inv(A)
Warning: Matrix is singular to working precision.
iA =
Inf
Inf
Inf
Inf
Matlab 8 In Matlab il comando per la risoluzione dei sistemi lineari ricorda proprio la divisione. Infatti,
dopo aver inserito i nostri dati (basta il vettore dei termini noti ora):
>>b=[7;17];
si ottiene agevolmente la soluzione con il comando “\” (“backslash”):
>>x=A\b
x=
2
3
Con A−1 a disposizione, risolvere un sistema di 2 equazioni o di 20 equazioni non fa molta differenza.
Inoltre, è interessante osservare come tale notazione vettoriale permetta di gestire contemporaneamente
più sistemi lineari che abbiano la stessa matrice dei coefficienti A ma diversi vettori dei termini noti,
diciamo b1 , b2 , . . . , bn :
Ax1 = b1
Ax2 = b2
..
.
Axn = bn .
Infatti, se consideriamo la matrice
B = [b1 , b2 , . . . , bn ]
ottenuta collezionando le colonne corrispondenti ai diversi termini noti e la matrice incognita
X = [x1 , x2 , . . . , xn ]
21
ottenuta collezionando le colonne corrispondenti ai diversi vettori incogniti, allora possiamo riassumere
il tutto nel “sistemone”
AX = B.
Matematicamente l’operazione corrisponde a
X = A−1 B.
Dal punto di vista computazionale però (cioè dal punto di vista di come risolviamo i problemi con l’utilizzo del calcolatore), l’operazione di inversione di una matrice, seppur rappresenti un concetto matematico
raffinato ed ineccepibile, non è una buona pratica! Quindi, invece di invertire una matrice è preferibile
risolvere il sistema lineare corrispondente (cioè con matrice dei coefficienti A e termini noti dati dalla
matrice identità I, perchè?), meglio se con metodi efficienti come quello di eliminazione di Gauss.
Infine, proviamo a cambiare leggermente il nostro problema iniziale ipotizzando che Marco acquisti 2
kg di pere, anzichè 1, spendendo cosı̀ 14 euro. Quindi:
2x1 + x2 = 7
4x1 + 2x2 = 14
la cui matrice
A=
2 1
4 2
è singolare, infatti:
det(A) = 2 · 2 − 1 · 4 = 4 − 4 = 0.
Geometricamente, ciò significa che le righe (e, analogamente, le colonne) di A rappresentano vettori
paralleli e questo si traduce nel fatto algebrico che il membro sinistro di ciascuna delle due equazioni
considerate è in realtà lo stesso (fatto deducibile dividendo per 2 la seconda), ovvero l’informazione fornita
da una qualunque delle due equazioni è già contenuta nell’altra e perciò risulta superflua ai fini della
risoluzione del problema. Inoltre (ancor peggio), se i termini noti non sono nella medesima proporzione,
allora non esiste alcuna soluzione, il che è in perfetta analogia con il caso scalare (o se preferite pensate
ai sistemi lineari di dimensione 2 come intersezioni di rette nel piano). In generale quindi, se det (A) = 0
non ha senso scrivere x = A−1 b, sarebbe come dividere per 0!
Matlab 9 Sistemi lineari con termini noti multipli sono risolvibili in Matlab con lo stesso comando “\”:
X=A\B
e quindi il risultato può essere ottenuto con l’istruzione
X=inv(A)*B,
che è equivalente dal punto di vista teorico, ma non da quello computazionale. Infatti dietro “\” in
Matlab c’è in realtà il metodo di eliminazione di Gauss.
Passando invece al problema modificato della spesa:
>>A=[2,1;4,2];
>>x=A\b
x
Inf
-Inf
22
Cos’è accaduto? Proviamo a rispondere utilizzando la matrice inversa, sempre in Matlab:
>>iA=inv(A)
Warning: Matrix is singular to working precision.
ans=
Inf
Inf
Inf
Inf
infatti
>>det(A)
ans=
0
2.4
Un po’ di trigonometria non nuoce
Dimentichiamoci ora delle matrici e torniamo ai vettori e al prodotto scalare. Prima però apriamo una
breve parentesi parlando di trigonometria.
Consideriamo il triangolo rettangolo AOB rappresentato in Figura 4. Esso ha l’ipotenusa di lunghezza
1. Per facilitare le cose quest’ultima è vista come il raggio di un cerchio (detto cerchio trigonometrico).
Chiamiamo θ l’angolo al centro, cioè quello formato dal raggio (l’ipotenusa) e l’orizzontale. Allora
definiamo il coseno dell’angolo θ come
cos (θ) =
OA
= OA
OB
e il seno dell’angolo θ come
AB
= AB.
OB
Dunque cos (θ) è il rapporto tra la lunghezza del cateto adiacente l’angolo θ e l’ipotenusa, mentre sin (θ)
è il rapporto tra la lunghezza del cateto opposto all’angolo θ e l’ipotenusa. Non dovrebbe sorprendere che
sin (θ) =
cos (0◦ ) = 1, sin (0◦ ) = 0,
mentre
cos (90◦ ) = 0, sin (90◦ ) = 1.
Esercizio 6 Sapreste dire che valori si ottengono per θ = 45◦ ? Pensate alla diagonale del quadrato e al
Teorema di Pitagora ([∼575-495 a.C.], filosofo e matematico greco)!
Torniamo finalmente al prodotto scalare di due vettori introdotto in Sezione 1 come:
x · y = x 1 y 1 + x2 y 2
per i vettori del piano
x=
x1
x2
23
(6)
Figura 4: seni e coseni.
ed
y=
y1
y2
.
Una definizione alternativa, più legata alla geometria, è
x · y = |x||y| cos (θ)
(7)
dove θ è l’angolo compreso tra i due vettori, mentre |x| ed |y| rappresentano la loro lunghezza, ovvero
q
|x| = x21 + x22
e
q
|y| = y12 + y22
come ci insegna il Teorema di Pitagora, Figura 5.
Ma siamo sicuri che (6) e (7) coincidono? La risposta è affermativa e la dimostrazione (riportata di
seguito per gli amanti...) si basa sul cosiddetto Teorema del Coseno o Teorema di Carnot (da Lazare Carnot
[1753-1823], anche se in realtà il risultato si deve a François Viète [1540-1603], entrambi matematici
francesi - errate attribuzioni non sono poi cosı̀ rare in matematica!).
Teorema 1 Per ogni coppia di vettori piani x ed y che formano tra loro un angolo θ vale
x · y = x1 y1 + x2 y2 = |x||y| cos (θ).
Dimostrazione. Consideriamo il triangolo ABC di lati AB = x e AC = y, Figura 6. Sia θ l’angolo tra
essi compreso. Allora, per il Teorema del Coseno (il quadrato costruito su un lato è pari alla somma dei
24
5
| x|2=x21+x22
x
4
3
| x|
2
x2
1
0
x1
−1
−1
0
1
2
3
Figura 5: Teorema di Pitagora.
quadrati costruiti sugli altri due lati meno il doppio del prodotto delle lunghezze di quest’ultimi volte il
coseno dell’angolo tra essi compreso) vale:
2
2
2
BC = AB + AC − 2AB · AC · cos (θ)
ovvero, ricordando la differenza di vettori per cui BC = |x − y|,
|x − y|2 = |x|2 + |y|2 − 2|x||y| cos (θ),
da cui segue:
1
|x|2 + |y|2 − |x − y|2
2
1 2
x1 + x22 + y12 + y22 − [(x1 − y1 )2 + (x2 − y2 )2 ]
=
2
1
=
(2x1 y1 + 2x2 y2 )
2
= x1 y 1 + x2 y 2
|x||y| cos (θ) =
come volevasi dimostrare.
Esercizio 7 Il Teorema di Pitagora è un caso particolare del Teorema del Coseno, quale?
Esercizio 8 Il Teorema di Pitagora vale in qualunque dimensione, ovvero la lunghezza di un vettore x di
n componenti è
q
|x| =
x21 + x22 + · · · + x2n .
Provate a dimostrarlo per n = 3 pensando alla diagonale di un parallelepipedo e usando lo stesso
Teorema ma solo nel caso n = 2.
25
5
C
4
3
|x−y|
|x|
2
!
1
B
|y|
0
−1
−1
A
2
2
2
BC =AB +AC −2AB" BCcos!
0
1
2
3
4
5
Figura 6: Teorema del Coseno.
Ora che siamo certi dell’equivalenza delle due formule, possiamo tranquillamente misurare (il coseno
del) l’angolo tra due vettori come
cos (θ) =
x1 y1 + x2 y2
x·y
=
.
|x||y|
|x||y|
Inoltre, come visto risulta
cos (90◦ ) = 0,
ne consegue quindi che il prodotto scalare di due vettori tra loro perpendicolari è nullo (confronta con (1)
e con l’esempio 2 in Sezione 1). In generale, il prodotto scalare di due vettori ci fornisce una qualche
misura del coseno dell’angolo tra essi compreso: più quest’ultimo è vicino (in valore assoluto) ad 1, più i
vettori sono tra loro paralleli, più esso è vicino a 0, più i vettori sono tra loro perpendicolari.
Esercizio 9 Provate a fare i conti con i vettori di Figura 7.
Matlab 10 Utilizzando Matlab e con un occhio a Figura 7 confermiamo quanto appena visto:
>> x=[1;4]
x=
1
4
>> y=[2;6]
y=
2
6
26
7
y
6
5
x
4
3
2
1
z
0
−1
−3
−2
−1
0
1
2
3
Figura 7: prodotto scalare e angolo tra vettori.
>> x’*y/(norm(x)*norm(y))
ans=
0.9971
>> z=[-3;1]
z=
-3
1
>> x’*z/(norm(x)*norm(z))
ans=
0.0767
Allora abbiamo incontrato anche la divisione con “/”. Devo invece dirvi a cosa serve l’istruzione norm
o vi è chiaro?
2.5
Ma quanto costa?
Ora che sappiamo il significato del prodotto scalare di vettori e di quello matrice-vettore, cerchiamo di
capire quante operazioni comportano.
Consideriamo il prodotto scalare di due vettori x, y ∈ Rn :
x · y = x1 y 1 + x2 y 2 + · · · + xn y n .
Chiaramente per ottenere il risultato dobbiamo eseguire n moltiplicazioni ed n − 1 addizioni, fatto che
indicheremo come
C(x · y) = nM + (n − 1)A.
27
Consideriamo ora il prodotto matrice-vettore di una matrice A ∈ Rm×n e di un vettore x ∈ Rn .
Abbiamo imparato che ogni componente del risultato
y = Ax
è in realtà il prodotto scalare tra il vettore riga corrispondente di A e il vettore x:
yi = ai,: T · x, i = 1, . . . , m.
Poichè ognuno di questi costa quanto visto sopra e ne dobbiamo calcolare m, segue
C(Ax) = m[nM + (n − 1)A] = mnM + (mn − m)A.
Riscrivendo come
C(Ax) = mn(M + A) − mA,
si nota che il termine che “pesa” maggiormente è il primo, mn, possiamo quindi trascurare il secondo,
m, soprattutto quando m ed n sono ragguardevoli. Diremo perciò che il costo dell’intera operazione è
all’incirca mn flop e scriveremo O(mn) flop (si dice “dell’ordine di mn flop”).
Commento 3 Il termine flop è l’abbreviazione di “floating point operation”: 1 flop è l’operazione base
che può fare il calcolatore, diciamo che corrisponde ad una moltiplicazione ed un’addizione.
Supponiamo ora (anche se capiremo il perchè di tutto ciò solo più avanti...) che la matrice A contenga
molti elementi nulli, diciamo più precisamente che la riga i-esima di A contiene solo nnzi elementi diversi
da 0 (nnz sta infatti generalmente per “Number of Non-Zero elements”), per i = 1, . . . , m. Se cosı̀ è,
allora non è difficile intuire che il costo per il calcolo della componente i-esima yi risulta
C(yi ) = nnzi M + (nnzi − 1)A = O(nnzi ),
basta infatti non contare le moltiplicazioni per (e le addizioni con) 0! Allora il costo del prodotto finale
y = Ax si ottiene sommando i costi di ciascuna componente, quindi:
!
m
m
X
X
C(Ax) =
O(nnzi ) = O
nnzi = O(nnz)
i=1
i=1
dove
nnz =
m
X
nnzi
i=1
è il numero totale di elementi non nulli contenuti nella matrice A.
Quello che servirà ricordare di tutto questo è che, in generale, un prodotto matrice-vettore di dimensione n (quindi A ∈ Rn×n ed x ∈ Rn ) costa O(n2 ), ma se la matrice A ha solo nnz elementi diversi da
0, allora il costo scende a O(nnz). Ovviamente vale sempre nnz ≤ n2 , ma a noi interesserà in particolar
modo il caso nnz n2 (leggi “molto minore”), ovvero in cui la matrice A contiene per la maggior parte
elementi nulli: si parla di matrici sparse, e rivestono un ruolo particolare nelle computazioni data la loro
peculiarità.
28
3
Google
Internet e il WWW rappresentano fonti di problemi matematici tanto interessanti quanto difficili, almeno
a livello computazionale. Tra questi potremmo annoverare:
• la gestione dei flussi di informazioni;
• la ricerca delle informazioni;
• l’ordinamento delle informazioni.
Abbiamo accennato alle prime due tipologie durante la conferenza. In riferimento alla seconda, in particolare, è bene sottolineare che il problema nel contesto del World Wide Web (di seguito WWW) differisce
abbastanza da quello relativo, ad esempio, ad una biblioteca. I motivi sono diversi:
• la dimensione del WWW (numero di pagine web) è di gran lunga maggiore di quella di normali
cataloghi di documenti: miliardi contro milioni (o migliaia);
• il WWW si evolve molto più rapidamente di quanto lo possa fare, ad esempio, il patrimonio di una
biblioteca;
• la struttura a collegamenti ipertestuali (i link) è una caratteristica peculiare del WWW che non si
trova da altre parti.
Viste tali caratteristiche, l’ordinamento delle informazioni presenti nel WWW viene a rivestire un ruolo
particolarmente cruciale. Non sorprende dunque che quest’ultimo rappresenti un argomento di ricerca
attuale e tra i più gettonati. Tra l’altro è una tematica molto recente, si pensi che i primi lavori scientifici
apparsi in letteratura risalgono appena alla fine degli anni 90. D’altronde la prima volta che si sono
connessi due computer tra loro risale al 1969, il protocollo TCP/IP (Transmission Control Protocol /
Internet Protocol) è stato introdotto negli anni 70, l’ipertesto HTTP (Hyper Text Transfer Protocol) negli
anni 80 e il WWW ha fatto il suo ingresso ufficiale nella storia il 6 agosto 1991 (esattamente 46 anni dopo
Hiroshima).
La tecnologia messa in piedi da Google non è certamente l’unica a soddisfare l’esigenza di miliardi di
utenti di trovare le informazioni desiderate in rete. Abbiamo deciso di occuparci limitatamente di questa (e
in maniera semplificata) dato il suo notevole successo attuale. Altri metodi (vecchi e nuovi) condividono
comunque con Google alcuni aspetti fondamentali:
• sfruttano la caratteristica struttura a link del WWW (teoria dei grafi);
• descrivono il problema con matrici e vettori (algebra lineare);
• lo interpretano in senso probabilistico (teoria della probabilità);
• lo risolvono con metodi efficienti (analisi numerica).
Nel loro famoso lavoro (una copia è disponibile in rete, [3]), Larry Page and Sergey Brin (fondatori
di Google) spiegano i concetti fondamentali con cui hanno gettato le regole per ordinare il contenuto del
WWW. Al tempo erano due studenti, entrambi venticinquenni, della Stanford University. Presentiamo
brevemente di seguito gli aspetti principali della loro teoria, riprendendo il percorso seguito durante la
conferenza.
29
Innanzitutto l’obiettivo da raggiungere è quello di classificare (to rank in inglese) le pagine (pages
in inglese) del WWW secondo la loro importanza relativa (e non assoluta: ci interessa sapere se una
pagina è più importante di un’altra, ma non quanto è importante in assoluto). Da qui il nome dell’algoritmo noto come PageRank (http://www.google.it/intl/it/why_use.html). Ma che cos’è
l’importanza (di seguito anche pagerank) di una pagina web? Potremmo ipotizzare che tale caratteristica
• dipenda dal contenuto della pagina;
• sia legata al numero di link che puntano alla pagina (entranti o inlink);
• sia legata al numero di link che partono dalla pagina (uscenti o outlink);
• etc..
Come si vede, vi sono diverse possibilità. I criteri proposti da Page e Brin sono i seguenti:
(G1) il pagerank di una pagina è indipendente dal suo contenuto;
(G2) il pagerank di una pagina è trasferito in parti uguali alle pagine collegate in uscita da questa
(mediante gli outlink);
(G3) il pagerank di una pagina è la somma delle frazioni di pagerank delle pagine collegate a questa in
entrata (mediante gli inlink).
I collegamenti di cui sopra si riferiscono, ovviamente, ai link ipertestuali tra le varie pagine. Il seguente
esempio sarà di aiuto.
Esempio 8 Consideriamo una piccolossima porzione del WWW, schematizzata come in Figura 8. Come
si vede, la pagina 1 ha un pagerank 100 e, avendo 2 outlink, ne trasferirà 50 alla pagina 3 e 50 alla
pagina 4 (criterio (G2)). La pagina 3 ha due inlink, riceve cosı̀ un pagerank di 50 (metà) dalla pagina 1 e
un pagerank di 10 (un terzo) dalla pagina 2, totalizzando quindi un pagerank di 60 (criterio (G3)). Infine,
osserviamo come tali calcoli siano stati fatti senza conoscere il contenuto delle pagine (criterio (G1)).
Partendo da queste tre semplici regole svilupperemo il modello matematico su cui si basa il motore
di ricerca Google. Inizieremo con un modello piuttosto primitivo e per questo richiedente alcune ipotesi
semplificative rispetto alla situazione reale (Sezione 3.1). Impareremo poi a risolvere in maniera efficiente
il problema matematico associato (Sezione 3.2). Infine rimuoveremo le ipotesi inziali per avvicinarci il
più possibile alla realtà (Sezione 3.3). Nel frattempo, lungo il percorso, forniremo un’interpretazione
alternativa a quella algebrica.
3.1
Matrici di connettività e navigatori casuali
Come prima cosa, numeriamo le pagine web da 1 ad n e indichiamo con xi il pagerank della pagina i, i =
1, 2, . . . , n. Naturalmente n è molto grande, si stima essere attualmente intorno ai 18 miliardi (http://
www.worldwidewebsize.com/). Per il momento, visto che dobbiamo introdurre i concetti generali,
ci avvaleremo di esempi con n molto basso, dell’ordine dell’unità (un WWW piccolissimo!). Supponiamo
inoltre che ogni pagina abbia almeno un link entrante ed uno uscente, ipotesi che, come vedremo in
seguito, ha un ruolo fondamentale.
30
Figura 8: pagine web e pagerank.
Costruiamo la cosiddetta matrice di connettività C ∈ Rn×n come segue: l’elemento cij di C, quello
che occupa la riga i-esima e la colonna j-esima, vale
1 se c’è un link dalla pagina j alla pagina i
cij =
0 altrimenti.
Esempio 9 Conisderiamo il WWW di n = 4 pagine rappresentato con i suoi link tramite il grafo (semplicemente un insieme di nodi e archi orientati) di Figura 9. In base alla regola precedente, la matrice di
connettività associata risulta:


0 1 0 0
 0 0 1 1 

C=
 1 1 0 0 .
0 1 1 0
Per costruirla possiamo seguire due strade:
• per righe: ciascuna riga è relativa ad una pagina e dobbiamo guardare gli inlink di quest’ultima
(entranti in);
• per colonne: ciascuna colonna è relativa ad una pagina e dobbiamo guardare gli outlink di quest’ultima (uscenti da).
Cosı̀, ad esempio, se osserviamo la pagina 3, questa riceve i link in ingresso dalle pagine 1 e 2, per cui
la riga 3 della matrice C sarà c3,: = [1, 1, 0, 0]. Invece, se osserviamo i link in uscita da questa, andando
essi alle pagine 2 e 4 daranno luogo alla colonna 3 di C, ovvero c:,3 = [0, 1, 0, 1]T .
31
Figura 9: il grafo di un WWW con n = 4 pagine.
Adesso che abbiamo costruito la matrice di connettività C, effettuiamo quella che si chiama normalizzazione. Prendiamo dunque ciascuna colonna c:,j di C e la dividiamo per il numero di outlink outj della
pagina relativa (possiamo farlo perchè abbiamo supposto che ve ne sia almeno uno, quindi outj 6= 0).
Formiamo cosı̀ la nuova matrice H di colonne:
h:,j =
c:,j
, j = 1, 2, . . . , n.
outj
Questa operazione realizza il corrispondente matematico del criterio (G2). Da notare che risulta essere
0 ≤ hij ≤ 1, i, j = 1, 2, . . . , n,
e
n
X
hij = 1, j = 1, 2, . . . , n.
i=1
Inoltre (visto che ci siamo...), il numero di outlink della pagina j non è altro che la somma degli elementi
di c:,j , quindi:
n
X
cij = outj , j = 1, 2, . . . , n,
i=1
mentre il numero di inlink della pagina i non è altro che la somma degli elementi di ci,: , quindi:
n
X
cij = ini , i = 1, 2, . . . , n.
j=1
32
Esempio 10 Tornando all’esempio di Figura 9, osserviamo che

4
P


out
=
ci1 = 1

1


i=1


4

P


ci2 = 3
 out2 =
i=1
4
P


out3 =
ci3 = 2



i=1


4

P


 out4 =
ci4 = 1.
i=1
Quindi la matrice H risulta

0 13 0 0
 0 0 1 1 
2

H=
 1 1 0 0 .
3
0 13 12 0

Come stabilito dal criterio (G2) la pagina 3, ad esempio, trasferirà due metà del suo pagerank, in particolare alle pagine 2 e 4. Analogamente, la pagina 2 trasferirà tre terzi del suo pagerank, rispettivemente
alle pagine 1, 3 e 4. Infine le pagine 1 e 4 trasferiranno tutto il loro pagerank, rispettivamente alle pagine
3 e 2.
Per completezza contiamo anche gli inlink:

4
P


in
=
c1j = 1

1


j=1



4
P



in
=
c2j = 2
 2
j=1
4
P


in
=
c3j = 2

3


j=1



4
P



c4j = 2.
 in4 =
j=1
Come osservato, avendo assunto che ogni pagina ha almeno un outlink, la somma degli elementi di
ciascuna colonna di H vale sempre 1. Si parla in questo caso di matrice stocastica (a colonne). Per
spiegare questa terminologia ricorriamo ad un modello interpretativo di tipo probabilistico. Immaginiamo
dunque di osservare un navigatore che sta visitando il WWW di Figura 9 e che sia obbligato a cambiare
pagina ad ogni istante utilizzando a caso gli outlink a disposizione. Supponiamo ad esempio che ad
un certo istante di tempo tale navigatore stia visitando la pagina 3 (che ha 2 outlink). Allora all’istante
successivo dovrà per forza di cose trovarsi a visitare la pagina 2 o la pagina 4. Siccome si muove a caso,
la probabilità di scegliere una o l’altra pagina è suddivisa in modo uguale, quindi 1/2 e 1/2 (o 50% e 50%
se preferite). Per lo stesso principio, se scegliesse la pagina 4 (che ha 1 outlink), all’istante successivo si
troverebbe obbligatoriamente sulla pagina 2, giungendovi con probabilità 1 (o 100%). Se invece avesse
scelto la pagina 2 (che ha 3 outlink), allora all’istante successivo si ritroverebbe a visitare rispettivamente
le pagine 1, 3 o 4 con uguale probabilità, ovvero 1/3, 1/3 e 1/3 (o tutte 33.333 . . . %).
La metafora probabilistica di cui sopra va sotto il nome di navigatore virtuale. Sotto questo punto di
vista, la matrice H è una matrice di transizione di probabilità: il suo generico elemento hij rappresenta
la probabilità che ad un certo istante il navigatore virtuale passi dalla pagina j alla pagina i, seguendo
33
ovviamente l’outlink j → i. Per usare una terminologia più tecnica (e di richiamo), il navigatore virtuale
è un modello di random walk lungo il grafo associato al WWW esaminato e rappresenta una catena di
Markov.
Veniamo adesso al criterio (G3). Esso esprime una legge di tipo ricorsivo: il pagerank di una pagina
è definito sulla base del pagerank di altre pagine (quelle che hanno outlink verso di essa in particolare).
Seguendo tale ricetta, possiamo ricostruire il pagerank di ciascuna pagina. Ogni pagina, come detto,
riceve solo una frazione del pagerank di ogni altra pagina che abbia un outlink diretto alla prima. Tale
frazione corrisponde al relativo elemento della matrice H, ed esprime appunto la probabilità di percorrere
effettivamente quel link (e quindi di trasferire tramite esso parte del pagerank della pagina di partenza).
Ad esempio, per la prima:
x1 = h11 x1 + h12 x2 + h13 x3 + · · · + h1n xn ,
per la seconda:
x2 = h21 x1 + h22 x2 + h23 x3 + · · · + h2n xn ,
per la terza:
x3 = h31 x1 + h32 x2 + h33 x3 + · · · + h3n xn
e via dicendo fino all’ultima:
xn = hn1 x1 + hn2 x2 + hn3 x3 + · · · + hnn xn .
Raccogliamo tutte queste informazioni come segue:


x1 = h11 x1 + h12 x2 + h13 x3 + · · · + h1n xn




x
 2 = h21 x1 + h22 x2 + h23 x3 + · · · + h2n xn
x3 = h31 x1 + h32 x2 + h33 x3 + · · · + h3n xn

..


.


 x = h x + h x + h x + ··· + h x ,
n
n1 1
n2 2
n3 3
nn n
e, vista l’esperienza acquisita con l’algebra lineare, riscriviamo il tutto come
x = Hx
dove




x=


x1
x2
x3
..
.







xn
è il cosiddetto vettore pagerank. Attenzione: x è proprio l’incognita del nostro problema!
Esempio 11 Sempre con riferimento al WWW di Figura 9, otteniamo le equazioni

1


x1 = 0 · x1 + · x2 + 0 · x3 + 0 · x4


3



 x2 = 0 · x1 + 0 · x2 + 1 · x3 + 1 · x4
2
1


x3 = 1 · x1 + · x2 + 0 · x3 + 0 · x4


3



 x4 = 0 · x1 + 1 · x2 + 1 · x3 + 0 · x4 ,
3
2
34
ovvero, togliendo gli zeri superflui,

1


x1 = x2


3



 x2 = 1 x3 + x4
2
1


x3 = x1 + x2


3



 x4 = 1 x2 + 1 x3 .
3
2
Nella notazione vettoriale scriviamo invece


 
x1
0 31 0 0
 x2   0 0 1 1  
2


 
 x3  =  1 1 0 0  
3
0 13 12 0
x4

x1
x2 
.
x3 
x4
E a che cosa corrisponde tale problema? L’espressione x = Hx non rappresenta un vero e proprio
sistema lineare: il vettore incognito compare anche al posto di quello noto. D’altro canto, non è nemmeno
un prodotto matrice-vettore. Se però ci ricordiamo della matrice identica I di dimensione n, allora essendo
x = Ix,
sostituendo al primo membro otteniamo
Ix = Hx,
ovvero (ricordate Esercizio 3)
(I − H)x = 0.
Quest’ultimo è un vero e proprio sistema lineare, con matrice dei coefficienti I − A, vettore incognito x
e vettore noto 0 (un caso veramente particolare).
Esempio 12 Sempre con riferimento al WWW di Figura 9, le equazioni

1


x1 = x2


3


1

 x2 = x3 + x4
2
1


x2
x
=
x
+
3
1


3



 x4 = 1 x2 + 1 x3
3
2
vengono riscritte nella forma (I − H)x = 0 semplicemente portando tutti i termini a sinistra dell’uguale:

1


x1 − x 2 = 0


3



 x2 − 1 x 3 − x4 = 0
2
1


−x
−
x2 + x3 = 0
1


3



 − 1 x2 − 1 x3 + x4 = 0.
3
2
35
Nella notazione vettoriale scriviamo invece


1 − 31 0
0
x1
1
 0
  x2
−1
1
−
2


 −1 − 1 1
  x3
0
3
1
1
x4
0 −3 −2 1



0
  0 
 =  .
  0 
0
Bene, visto che siamo riusciti a tradurre il tutto in un sistema lineare, sappiamo anche come risolverlo. Purtroppo però abbiamo visto al seminario che il metodo di eliminazione gaussiana (seguito dalla
sostituzione) comporta un costo di O(2/3n3 ) flop. Essendo n dell’ordine dei miliardi, ci ritroveremmo a
dover fare miliardi di miliardi di miliard di flop, troppi anche per i calcolatori più potenti (milioni di anni
con il “Tianhe-1A”! http://www.nccs.gov/jaguar/, http://www.top500.org/). Come
superiamo questo ostacolo? La risposta nella prossima sezione.
3.2
La fortuna di Google: il metodo delle potenze e tanti zeri
Visto il costo non affrontabile del metodo di Gauss, abbandoniamo questa strada in favore di un’idea
che si applica spesso in matematica: l’iterazione. In questo contesto, potremmo riassumere la strategia
dicendo che rinunciamo alla soluzione esatta x ma, partendo da un’opportuna approssimazione iniziale
x(0) , costruiamo una successione di soluzioni x(1) , x(2) , x(3) , . . . via via sempre più vicine a quella esatta
(questa almeno è la nostra speranza). Quando siamo sufficientemente “vicini”, ci fermiamo. Il vantaggio
consiste nel costruire queste soluzioni approssimate in modo più semplice e ad un costo computazionale
molto più basso.
Tornando al problema
x = Hx,
potremmo procedere iniziando da un certo x(0) e calcolare x(1) come
x(1) = Hx(0) ,
poi x(2) come
x(2) = Hx(1) ,
x(3) come
x(3) = Hx(2)
e via dicendo. Ad ogni passo calcoliamo dunque la soluzione “nuova” facendo il prodotto della matrice
H con la soluzione “vecchia”. In generale, dopo k di questi passi ci ritroviamo con
x(k) = Hx(k−1) , k = 1, 2, . . . .
Ma quando ci si ferma? Potrebbe (il condizionale è d’obbligo per ora) essere ragionevole fermarsi
quando due soluzioni successive, quindi x(k) ed x(k−1) , differiscono di poco, cioè quando la lunghezza
del vettore differenza (o errore)
e(k) = x(k) − x(k−1)
è prossima allo zero, o perlomeno molto piccola. Abbiamo già visto nell’Esercizio 8 come calcolare la
lunghezza di un vettore, ovvero il Teorema di Pitagora generalizzato. Nel nostro caso la lunghezza di e(k) ,
che indicheremo con ke(k) k, risulta (in Matlab basta usare norm)
r
ke(k) k =
(k)
(k−1)
x1 − x1
2
(k)
(k−1)
+ x2 − x2
36
2
(k)
(k−1)
+ · · · + xn − xn
2
.
Ci fermeremo quindi dopo k passi, con k tale per cui
ke(k) k < TOL
dove TOL sarà una tolleranza da noi fissata.
L’algoritmo appena presentato è noto come metodo delle potenze (perchè secondo voi?).
Matlab 11 Applichiamo il metodo delle potenze sempre con riferimento al WWW di Figura 9. Questa
volta ci affidiamo a Matlab. Inseriamo H:
>> H=[0,1/3,0,0;0,0,1/2,1;1,1/3,0,0;0,1/3,1/2,0]
H =
0
0.3333
0
0
0
0
0.5000
1.0000
1.0000
0.3333
0
0
0
0.3333
0.5000
0
Inseriamo quindi un vettore soluzione iniziale x(0) . Supponiamo ad esempio che, inizialmente, ogni
pagina abbia lo stesso pagerank, quindi 1/n = 1/4 (capiremo poi perché).
>> x=[1/4;1/4;1/4;1/4]
x =
0.2500
0.2500
0.2500
0.2500
Nella nostra implementazione Matlab chiameremo il vettore soluzione sempre x. Terremo conto del
numero di iterazioni mediante un indice k. Siccome siamo all’inizio, diciamo che siamo al passo k = 0:
>> k=0;
Finalmente possiamo procedere con il metodo, che scriviamo tutto in una riga (!). Quest’ultima la
ripeteremo finchè non saremo soddisfatti dell’errore (abbiamo già incontrato l’istruzione norm).
>> k=k+1,e=norm(H*x-x),x=H*x
k =
1
e =
0.2282
x =
0.0833
0.3750
0.3333
0.2083
>> k=k+1,e=norm(H*x-x),x=H*x
k =
2
e =
37
0.1559
x =
0.1250
0.3750
0.2083
0.2917
>> k=k+1,e=norm(H*x-x),x=H*x
k =
3
e =
0.0780
x =
0.1250
0.3958
0.2500
0.2292
Già dopo 3 passi abbiamo ridotto l’errore. La Tabella 1 riporta i dati sui calcoli successivi. La soluzione
esatta è


0.125
 0.375 

x=
 0.250  .
0.250
Osserviamo come si ottengono errori molto piccoli già con poche decine di passi. Inoltre, osservando il
vettore pagerank soluzione x, concludiamo che, supponendo 1 l’importanza di tutto il WWW, allora 1/8
è nella pagina 1, 3/8 nella 2 e 1/4 in ciascuna delle pagine 3 e 4.
Commento 4 La Tabella 1 non deve trarre in inganno: per motivi di spazio i valori di pagerank (ultime
quattro colonne) sono riportati con 4 cifre significative (vedi Appendice A) , per cui essi possono sembrare
esatti per k ≥ 16. In realtà quelli che si vedono sono valori arrotondati a 4 cifre. Matlab li calcola
effettivamente con 15 cifre significative, fatto che corrisponde alla massima precisione del sistema di
rappresentazione dei numeri di macchina. Ecco perché è inutile proseguire le iterazioni dopo che l’errore
scende sotto 10−15 : tutto quello che segue la 15a cifra non avrebbe comunque senso!
E dopo k passi, quanto sarà costata la nostra soluzione finale x(k) (che è comunque un’approssimazione)? Per saperlo basta capire quanto costa eseguire ogni singolo passo dell’algoritmo. Osserviamo che ogni passo comporta sempre la stessa operazione, cioè il prodotto della matrice di connettività
normalizzata H volte il vettore soluzione del passo precedente:
x(k) = Hx(k−1) , k = 1, 2, . . . .
Quindi un singolo passo costa in genere O(n2 ) flop, come spiegato in Sezione 2.5. In totale O(kn2 ) flop
se facciamo k passi. Se pensiamo che in generale bastano poche decine di passi (tipicamente k n), è
già un bel risparmio. Ma non è sufficiente: siamo ancora a miliardi di miliardi di operazioni.
Abbiamo visto che ogni passo del metodo delle potenze consiste in un prodotto matrice-vettore, in
particolare Hx. Abbiamo imparato che le n componenti del vettore risultante si calcolano ciascuna come
38
k
1
6
11
16
21
26
31
36
41
46
51
56
61
66
71
76
e(k)
2.2822 × 10−1
1.9018 × 10−2
1.7455 × 10−3
1.6475 × 10−4
1.5752 × 10−5
1.5148 × 10−6
1.4602 × 10−7
1.4090 × 10−8
1.3601 × 10−9
1.3131 × 10−10
1.2677 × 10−11
1.2239 × 10−12
1.1816 × 10−13
1.1429 × 10−14
1.1012 × 10−15
9.3095 × 10−17
(k)
x1
0.0833
0.1285
0.1247
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
0.1250
(k)
x2
0.3750
0.3715
0.3754
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
0.3750
(k)
x3
0.3333
0.2465
0.2502
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
(k)
x4
0.2083
0.2535
0.2497
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
0.2500
Tabella 1: dati sul metodo delle potenze per il WWW di Figura 9.
prodotto scalare della relativa riga della matrice per il vettore colonna. Ad esempio per la componente
i-esima:
(k−1)
(k−1)
(k)
+ · · · + hin x(k−1)
= hi,: · x(k−1) .
+ hi2 x2
xi = hi1 x1
n
Ma siamo sicuri che tutti gli elementi di H sono diversi da 0? È proprio qui il nocciolo della questione:
hij 6= 0 se e solo se esiste il link j → i. Ma, in generale, i link esistenti tra le pagine web sono molto meno
di tutti quelli possibili. Questo si traduce nel fatto che molti elementi di H sono 0 e che quindi H ha pochi
elementi diversi da 0, numero che abbiamo chiamato nnz in Sezione 2.5. Qui vale esattamente lo stesso
discorso fatto alla fine di quest’ultima: il costo ad ogni passo del prodotto matrice-vettore è O(nnz) e non
più O(n2 ). Questa ragione è alla base della ragguardevole riduzione del costo computazionale, dato che
per il WWW, il numero di link esistenti nnz è di gran lunga inferiore al quadrato del numero delle pagine
web. In un’altra salsa, ogni pagina ha ben pochi link rispetto al totale delle pagine.
Esempio 13 Per il WWW di Figura 9, la matrice H risulta avere n2 = 16 elementi, di cui solo nnz = 7
diversi da 0 (meno della metà). 7 è ovviamente il numero totale di link esistenti, come si può verificare
osservando il grafo associato.
Esempio 14 Come esempio reale, riportiamo in Figura 10 una rappresentazione della matrice H per il
WWW sottostante la pagina http://www.harvard.edu, punto di accesso della Harvard University.
In tale rappresentazione, ogni punto colorato è un elemento diverso da 0 della matrice, ovvero un link.
Come si evince a colpo d’occhio, i link esistenti sono davvero pochi. Infatti si contano n = 500 pagine,
con un totale di nnz = 2636 link (notare che n2 = 250000, circa 1000 volte tanto!).
Ma quanto vale nnz per il WWW reale? Per abbozzare una stima (ma come ordine di grandezza
non andremo molto distanti), ci basiamo sul fatto che, mediamente, una pagina ha pochi link entranti.
39
0
50
100
150
200
250
300
350
400
450
500
0
100
200
300
400
500
Figura 10: la matrice di connettività H del web di Harvard.
Supponiamo un centinaio. Allora se assumiamo che n = 18 miliardi, seguirà nnz = 1800 miliardi.
Quindi un passo del metodo delle potenze costa circa 1800 miliardi di flop. Mediamente potremmo
aspettarci che k = 100 passi siano più che sufficienti a raggiungere un’accuratezza soddisfacente per
la soluzione. Quindi in totale dobbiamo eseguire 180 mila miliardi di flop. A questo punto decidiamo
di eseguire il calcolo con un computer capace di 2 Gflops (niente di speciale oggigiorno; 1 flops = 1
flop al secondo). Ovviamente supponiamo che la memoria sia sufficiente a contenere la matrice H (e
questo invece è alquanto difficile, ma è un altro discorso...). Allora per fare 180 mila miliardi di flop
ad una velocità di calcolo di 2 Gflops servono 90 mila secondi, ovvero 25 ore: una giornata abbondante.
Contando che con Gauss e il “Tianhe-1A” ci volevano milioni di anni, possiamo essere più che soddisfatti!
3.3
Pagine penzolanti e ricerche personalizzate
Vista la riduzione di costo ottenuta al termine della precedente sezione, sembrerebbe che abbiamo affrontato il problema nel modo giusto. Ma non dimentichiamo niente? Vediamo il prossimo esempio.
Matlab 12 Conisderiamo un altro WWW di n = 4 pagine
viste, la matrice di connettività normalizzata risulta:

0 21 0 0
 0 0 1 0
H=
 1 0 0 1
0 21 0 0
Se ora applichiamo il metodo delle potenze otteniamo:
40
rappresentato in Figura 11. Con le regole


.

>> H=[0 1/2 0 0;0 0 1 0;1 0 0 1;0 1/2 0 0]
H =
0
0.5000
0
0
0
0
1.0000
0
1.0000
0
0
1.0000
0
0.5000
0
0
>> x=[1/4;1/4;1/4;1/4]
x =
0.2500
0.2500
0.2500
0.2500
>> k=0;
>> k=k+1,e=norm(H*x-x),x=H*x
k =
1
e =
0.3062
x =
0.1250
0.2500
0.5000
0.1250
>> k=k+1,e=norm(H*x-x),x=H*x
k =
2
e =
0.3536
x =
0.1250
0.5000
0.2500
0.1250
>> k=k+1,e=norm(H*x-x),x=H*x
k =
3
e =
0.3062
x =
0.2500
0.2500
0.2500
0.2500
>> k=k+1,e=norm(H*x-x),x=H*x
k =
41
4
e =
0.3062
x =
0.1250
0.2500
0.5000
0.1250
>> k=k+1,e=norm(H*x-x),x=H*x
k =
5
e =
0.3536
x =
0.1250
0.5000
0.2500
0.1250
>> k=k+1,e=norm(H*x-x),x=H*x
k =
6
e =
0.3062
x =
0.2500
0.2500
0.2500
0.2500
>> k=k+1,e=norm(H*x-x),x=H*x
k =
7
e =
0.3062
x =
0.1250
0.2500
0.5000
0.1250
>> k=k+1,e=norm(H*x-x),x=H*x
k =
8
e =
0.3536
x =
0.1250
42
0.5000
0.2500
0.1250
>> k=k+1,e=norm(H*x-x),x=H*x
k =
9
e =
0.3062
x =
0.2500
0.2500
0.2500
0.2500
>> k=k+1,e=norm(H*x-x),x=H*x
k =
10
e =
0.3062
x =
0.1250
0.2500
0.5000
0.1250
>> k=k+1,e=norm(H*x-x),x=H*x
k =
11
e =
0.3536
x =
0.1250
0.5000
0.2500
0.1250
Si osserva dunque che dopo ogni 3 passi ci si ritrova al punto di partenza. Lo si vede meglio in Tabella 2.
Il WWW dell’esempio precedente è rappresentato da una matrice H per la quale il metodo delle
potenze entra in un ciclo (di periodo 3). Eppure soddisfa a tutte le ipotesi che abbiamo assunto. Non
è dunque vero che tali ipotesi sono sufficienti a garantire quella che si chiama convergenza del metodo,
ovvero il fatto che aumentando il numero di iterazioni ci si avvicina sempre più alla soluzione esatta, un
concetto di limite:
lim x(k) = x.
k→∞
C’è poi un ulteriore problema: l’ipotesi che abbiamo fatto in partenza, cioè che ogni pagina abbia
almeno un link in ingresso e uno in uscita (ini 6= 0 e outj 6= 0) non è affatto veritiera. Esistono infatti
nel WWW reale molte pagine che non hanno link entranti (ini = 0) e molte pagine che non hanno link
uscenti (outj = 0). Anzi, sono la maggior parte. Questo si traduce in una matrice di connettività C con
43
Figura 11: il grafo di un altro WWW con n = 4 pagine.
k
1
2
3
4
5
6
7
8
9
10
11
12
13
14
e(k)
0.3062
0.3536
0.3062
0.3062
0.3536
0.3062
0.3062
0.3536
0.3062
0.3062
0.3536
0.3062
0.3062
0.3536
(k)
x1
0.1250
0.1250
0.2500
0.1250
0.1250
0.2500
0.1250
0.1250
0.2500
0.1250
0.1250
0.2500
0.1250
0.1250
(k)
x2
0.2500
0.5000
0.2500
0.2500
0.5000
0.2500
0.2500
0.5000
0.2500
0.2500
0.5000
0.2500
0.2500
0.5000
(k)
x3
0.5000
0.2500
0.2500
0.5000
0.2500
0.2500
0.5000
0.2500
0.2500
0.5000
0.2500
0.2500
0.5000
0.2500
(k)
x4
0.1250
0.1250
0.2500
0.1250
0.1250
0.2500
0.1250
0.1250
0.2500
0.1250
0.1250
0.2500
0.1250
0.1250
Tabella 2: dati sul metodo delle potenze per il WWW di Figura 11.
44
intere righe o intere colonne vuote (cioè di soli zeri). In particolare, le pagine che non hanno link uscenti
si chiamano anche penzolanti (in analogia con la rappresentazione del relativo grafo). Se pensiamo al
modello del navigatore virtuale, questo non funziona più: navigando solo tramite link, se si visita una
pagina penzolante vi si rimane incastrati per sempre.
Per risolvere entrambi i problemi appena menzionati, gli ideatori di Google hanno scelto una “scorciatoia” che consiste nell’assicurarsi
• da una parte di non bloccare il navigatore virtuale durante la sua random walk;
• dall’altra di soddisfare ad ipotesi matematiche che garantiscono la convergenza del metodo delle
potenze (per qualunque scelta del vettore pagerank iniziale x(0) ).
Tale duplice obiettivo viene raggiunto andando a modificare la matrice originale eliminando tutti gli zeri
presenti (NB: questo non è necessario, ma è sufficiente), quindi creando una matrice sempre stocastica (a
colonne) ma con elementi tutti strettamente positivi. L’operazione viene fatta in due passi partendo dalla
matrice H.
Il primo passo (da H ad H 0 ) serve ad eliminare le pagine penzolanti. Se la matrice originale H presenta
delle colonne vuote, allora queste vengono riempite ovunque con 1/n. Quindi, partendo dalla matrice C
costruita come al solito, si ottiene direttamente H 0 come
 c
ij

se outj 6= 0

outj
h0ij =
1


se outj = 0.
n
Cosı̀ siamo sicuri di non bloccare il navigatore virtuale: se ad un dato istante questi si trova su una pagina
con link uscenti, allora ne sceglie uno a caso (quindi probabilità 1/outj ) , altrimenti immette un nuovo
indirizzo nella barra degli strumenti, sempre a caso (quindi probabilità 1/n dato che ci sono n possibilità).
Esempio 15 Per il WWW di Figura 12 (lo stesso di Figura 9, ma con il collegamento 1 → 3 rimosso), la
matrice H originale sarebbe


0 31 0 0
 0 0 1 1 
2

H=
 0 1 0 0 .
3
0 13 12 0
La pagina 1 è penzolante, infatti la corrispondente colonna di H è vuota. Seguendo la regola appena
spiegata, si modifica H in H 0 aggiungendo 1/4 su tutta la prima colonna:
 1 1

0 0
4
3
 1 0 1 1 
4
2

H0 = 
 1 1 0 0 .
4
3
1
1
1
0
4
3
2
Il secondo passo (da H 0 ad H 00 ) serve ad assicurarci la convergenza del metodo delle potenze. Per
realizzarlo togliamo gli zeri rimanenti di H 0 nel seguente modo. Scegliamo un numero α ∈ [0, 1], che
esprime una probabilità. Imponiamo quindi al navigatore virtuale
• con probabilità α di comportarsi come prima, cioè secondo H 0 ;
45
Figura 12: il grafo di un WWW con n = 4 pagine, di cui una penzolante.
• con probabilità 1 − α di immettere invece un indirizzo a caso (probabilità 1/n), indipendentemente
dalla presenza o meno di link uscenti.
Certamente questo modello è più aderente alla navigazione sul WWW reale: infatti, le possibilità di
navigazione offerte all’utente si riducono proprio a muoversi attraverso i link o a digitare nuovi indirizzi
indipendentemente dalla presenza o meno di link uscenti. Matematicamente, la nuova matrice H 00 si
ottiene da H 0 come
1
h00ij = αh0ij + (1 − α) .
n
Osserviamo che in questo secondo passo stiamo semplicemente aggiungendo la quantità costante (1 −
α)/n in ogni posizione della matrice αH 0 . Quindi:
 1 1

1
·
·
·
n
n
n
 1 1 ··· 1 


n
n
0
H 00 = αH + (1 − α)  .. .. . . n.. 
 . .
. . 
1
1
1
n
 n n ··· 
1 1 ··· 1

1 − α  1 1 ··· 1 

0
= αH +
 .. .. . . ..  .
n  . .
. . 
1 1 ··· 1
Ma come possiamo esprimere diversamente una matrice con tutti 1? Lo possiamo fare costruendo il
46
vettore colonna



u=

1
1
..
.





1
e facendo il prodotto righe-colonne di questo (colonna: u ∈ Rn×1 ), con il suo trasposto (riga: uT ∈ R1×n ),
ottenendo appunto la matrice Rn×n di tutti 1:
 


1
1 1 ··· 1
 1 


 
 1 1 ··· 1 
uuT =  ..  1 1 · · · 1 =  .. .. . . ..  .
 . 
 . .
. . 
1
1 1 ··· 1
Osservate che per quest’ultimo passaggio non abbiamo fatto altro che applicare il prodotto righe-colonne
ad un vettore colonna per uno riga, cioè il contrario del prodotto scalare, che corrisponde al prodotto
righe-colonne di un vettore riga per uno colonna. Abbiamo cosı̀ chiuso la questione lasciata in sospeso
alla fine della Sezione 2.2.
Applichiamo quanto appena visto al passaggio da H 0 ad H 00 , ottenendo cosı̀
uuT
.
n
Riassumendo, questa formula ci dice che il navigatore virtuale esce da una certa pagina secondo H 0 con
probabilità α o immettendo un nuovo indirizzo a caso con probabilità 1 − α.
Ma quanto vale α? Google dichiara di utilizzare α = 0.85. Aldilà che questo sia vero o meno, certo è
che se α = 0, allora il navigatore si muove sempre immettendo indirizzi nuovi a caso:
H 00 = αH 0 + (1 − α)
uuT
,
H =
n
mentre se α = 1 il navigatore si muove sempre secondo H 0 :
00
H 00 = H 0 ,
cioè secondo i link esistenti, o immettendo un indirizzo nuovo a caso solo se la pagina in cui si trova è
penzolante. Potremmo dunque affermare che una scelta di α prossimo a uno è senz’altro più fedele alla
realtà. Ma la questione non finisce qui come vedremo.
Esempio 16 Riprendiamo la matrice


H0 = 

1
4
1
4
1
4
1
4
1
3

0 0
0 12 1 
.
1

0
0
3
1
1
0
3
2
associata al WWW di Figura 12 e supponiamo α = 0.85. Otteniamo allora
 1 1

 1 1 1 1  
0 0
0.25 0.32 0.04 0.04
4
3
4
4
4
4
1
1
1
1
1
1 




0 2 1 
4
 4 4 4 4   0.25 0.04 0.46 0.88
H 00 = 0.85 
 1 1 0 0  + 0.15  1 1 1 1  '  0.25 0.32 0.04 0.04
4
3
4
4
4
4
1
1
1
1
1
1
1
0
0.25 0.32 0.46 0.04
4
3
2
4
4
4
4
47


.

Osserviamo come la matrice finale H 00 rimane stocastica (a colonne). Il suo significato finale non cambia
rimanendo sempre una matrice di transizione di probabilità: ad esempio, l’elemento h23 = 0.46 in riga 2
e colonna 3 indica che il passaggio dalla pagina 3 alla pagina 2 avviene con il 46% di probabilità.
Matlab 13 Con Matlab:
>> H=[0,1/3,1/2,0;0,0,0,1;0,1/3,1/2,0;0,1/3,0,0]
H =
0
0.3333
0.5000
0
0
0
0
1.0000
0
0.3333
0.5000
0
0
0.3333
0
0
>> u=ones(n,1)
u =
1
1
1
1
>> H1=H;H1(:,1)=u/n
H1 =
0.2500
0.3333
0.5000
0
0.2500
0
0
1.0000
0.2500
0.3333
0.5000
0
0.2500
0.3333
0
0
>> alfa=0.85;
>> H2=alfa*H1+(1-alfa)*(u*u’)/n
H2 =
0.2500
0.3208
0.4625
0.0375
0.2500
0.0375
0.0375
0.8875
0.2500
0.3208
0.4625
0.0375
0.2500
0.3208
0.0375
0.0375
Abbiamo usato anche la nuova istruzione ones, il cui significato dovrebbe risultare chiaro. Cosa più
importante, osserviamo come Matlab esegue qualunque prodotto con “*”, arrangiandosi a capire se sta
moltiplicando scalari, vettori o matrici (e se questo si può fare!).
Ora, provate voi ad eseguire il metodo delle potenze sulla matrice H 00 .
Nell’esempio precedente vi è stato chiesto di applicare il metodo delle potenze alla matrice H 00 . Osserviamo però che questa non ha nemmeno uno zero. Quindi il costo che paghiamo è O(kn2 ) flop. Abbiamo
dunque perso tutto quanto avevamo guadagnato prima?
La risposta è fortunatamente negativa. Basta solo ragionare e non agire di fretta. Supponiamo allora
di aver già costruito H 0 e riconsideriamo la matrice
H 00 = αH 0 + (1 − α)
48
uuT
.
n
Il metodo delle potenze diventa, assegnato x(0) ,
x(k) = H 00 x(k−1) , k = 1, 2, . . . .
Ma abbiamo visto che, essendo H 00 priva di zeri, paghiamo il costo pieno. Se invece sostituiamo l’espressione di H 00 nel generico passo del metodo e applichiamo le proprietà distributiva ed associativa (Esercizio
5 per le matrici, ma vale anche per i vettori ovviamente!) otteniamo
uuT
0
(k)
x
=
αH + (1 − α)
x(k−1)
n
(uuT )x(k−1)
= αH 0 x(k−1) + (1 − α)
n
T (k−1)
u(u
x
)
= αH 0 x(k−1) + (1 − α)
, k = 1, 2, . . . .
n
Ma quanto vale uT x(k−1) ? Vediamo:

T
u x
(k−1)
=
1 1 ···


1 

(k−1)
x1
(k−1)
x2
..
.
(k−1)



(k−1)
(k−1)
+ x2
+ · · · + x(k−1)
,
 = x1
n

xn
quindi questo prodotto (scalare) mi restituisce semplicemente la somma del pagerank di tutto il WWW al
passo k − 1: il pagerank totale. Per capire quanto vale, ci vuole ancora un po’ di attenzione. Se x risolve
il problema originale
x = H 00 x
allora anche ax risolve lo stesso problema per qualunque numero scalare a, infatti
H 00 (ax) = aH 00 x = ax.
Questo vuol dire che se x è soluzione, allora lo sono anche tutti i vettori paralleli ad x. Dal punto di
vista del nostro problema non ha importanza: se il vettore x ha le componenti in una certa proporzione,
allora tale proporzione non cambia se prendo un vettore parallelo ad x. Quindi l’importanza relativa delle
pagine è sempre la stessa, ed è giusto quello che a noi interessa! Allora, se dobbiamo scegliere uno tra
tutti questi vettori paralleli, prendiamo per semplicità quello le cui componenti si sommano a 1, ovvero
quello per cui il pagerank totale è 1. Segue quindi
(k−1)
1 = x1
(k−1)
+ x2
+ · · · + x(k−1)
= uT x(k−1) .
n
Sostituendo nel generico passo del metodo delle potenze si ottiene infine
u(uT x(k−1) )
n
u
0 (k−1)
= αH x
+ (1 − α) , k = 1, 2, . . . .
n
La precedente formula ci dice che ciascun passo è composto da un prodotto matrice-vettore (il primo
addendo) a cui sommiamo un altro vettore (il secondo addendo). La differenza è che cosı̀ facendo il
prodotto matrice-vettore coinvolge la matrice H 0 , la quale ha (di nuovo) tanti zeri, ripristinando dunque il
notevole risparmio computazionale che avevamo raggiunto in precedenza! Ricordiamo che il costo finale
è perciò O(k · nnz), dove nnz è il numero totale di link esistenti (non proprio...perchè?) e k il numero di
passi eseguiti con il metodo delle potenze.
x(k) = αH 0 x(k−1) + (1 − α)
49
Commento 5 La scelta di avere un pagerank totale unitario si presta a completare la metafora del navigatore virtuale: ciascuna componente xi , i = 1, 2, . . . , n, del vettore soluzione x rappresenta la probabilità di trovarsi sulla pagina i dopo un tempo di navigazione infinito. La soluzione rappresenta quello che
si dice stato stazionario della catena di Markov associata e ogni sua componente, sotto questo punto di
vista, è sicuramente un fedele indicatore dell’importanza della pagina considerata.
3.4
Pagerank finalmente?!
Ora siamo pronti a raccogliere tutto quanto appreso finora in un codice Matlab. Ma questo lo dovete fare
voi!
Prima però dobbiamo imparare a scrivere un “programma” Matlab, quello che si chiama un m-file
function: questo non è altro che un file di testo. Matlab ha il suo editor, altrimenti potete usare tranquillamente un notepad qualunque a patto che salviate il file con estensione “.m”. All’interno del corpo si
scrivono le istruzioni che prevedete di eseguire, seguendo le regole di sintassi viste sinora senza alcuna
differenza. L’unica caratteristica che è necessario aggiungere riguarda la relazione Input-Output (I/O),
e tutto questo viene inserito nella prima riga di testo, detta “intestazione”, che comincia obbligatoriamente con la parola function. Supponiamo quindi di dover scrivere un m-file che implementa un
algoritmo di risoluzione di un problema che prende in Input i dati I1 , I2 , . . . , Ir e fornisce in Output i dati
O1 , O2 , . . . , Os . Allora basterà scrivere come intestazione:
function [O1,O2,...,Os]=nome(I1,I2,...Is)
dove nome è il nome che daremo al file, quindi nome.m.
Matlab 14 Si consideri il problema di trovare le radici x1 ed x2 dell’equazione di secondo grado
ax2 + bx + c = 0
assegnati i coefficienti a, b e c. Il codice Matlab radici.m riportato nel riquadro è un esempio di m-file
function che risolve il problema. Si osservino le linee di commento 2, . . . , 5 precedute dal simbolo “%”.
Risultano molto utili in quanto il testo del commento compare se al prompt di comando si usa l’istruzione
help seguita dal nome del file:
>> help radici
[x1,x2]=radici(a,b,c)
calcola le radici x1 ed x2
dell’equazione di secondo grado
axˆ2+bx+c=0
Per eseguire basterà invece richiamare ciò che segue la parola chiave function nel testo di radici.
m, specificando ovviamente gli input, ad esempio:
>> [x1,x2]=radici(1,3,2)
x1 =
-1
x2 =
-2
50
1
2
3
4
5
f u n c t i o n [ x1 , x2 ] = r a d i c i ( a , b , c )
% [ x1 , x2 ] = r a d i c i ( a , b , c )
% c a l c o l a l e r a d i c i x1 ed x2
% d e l l ' equazione di secondo grado
% ax ˆ 2 + bx+c = 0 .
6
7
8
9
D e l t a =b ˆ 2 - 4 * a * c ;
x1 = ( - b+ s q r t ( D e l t a ) ) / ( 2 * a ) ;
x2 = ( - b - s q r t ( D e l t a ) ) / ( 2 * a ) ;
Ora avete tutti gli ingredienti per costruire il vostro pagerank.m partendo da una qualunque matrice
di connettività non normalizzata: ad essere onesti non li avete proprio tutti, ma ci aspettiamo che facciate
delle domande! Nel frattempo vediamo qualche simulazione con quello già scritto.
Esercizio 10 Costruite la matrice di connettività non normalizzata associata al web rappresentato in
figura 13 e testate il vostro prank.m calcolando il pagerank con il valore di default α = 0.85. La
classifica di importanza deve risultare P1 , P6 , P2 , P4 , P3 , P5 .
P1
P4
P2
P3
P6
P5
Figura 13: il web di dimensione 6 per l’esercizio 10.
Matlab 15 Testiamo pagerank.m sulla matrice del WWW di Harvard. Questa la possiamo caricare (e
ispezionare) come
>> load harvard
>> whos
Name
Size
C
500x500
Bytes
15184
51
Class
logical
Attributes
sparse
Quindi la possiamo “dare in pasto” a pagerank.m come segue:
>> load harvard
>> whos
Name
Size
Bytes Class
C
500x500
15184 logical
>> [x,ind,e,k]=pagerank(C,0.85,1e-5,100);
Attributes
sparse
ottenendo l’intero vettore pagerank x ordinato dalla pagina più importante alla meno importante (che non
riportiamo, essendo molto lungo), il vettore ind che contiene gli indici delle pagine ordinate secondo x
ed infine l’errore e ed il numero di passi fatti k. Possiamo ad esempio vedere chi sono le prime 10 pagine
importanti, l’errore e i passi con
>> ind(1:10),e,k
ans =
7
54
53
18
9
15
1
10
222
55
e =
8.7680e-006
k =
28
Proviamo ora a ripetere l’eseprimento per diversi valori di α (sempre tra 0 e 1):
>> [x,ind,e,k]=pagerank(C,0.9,1e-5,100);
>> ind(1:10),e,k
ans =
7
54
53
18
9
15
10
1
222
76
e =
8.9850e-006
52
k =
38
>> [x,ind,e,k]=pagerank(C,0.8,1e-5,100);
>> ind(1:10),e,k
ans =
7
54
53
18
15
9
1
10
222
55
e =
8.7392e-006
k =
22
>> [x,ind,e,k]=pagerank(C,0.5,1e-5,100);
>> ind(1:10),e,k
ans =
7
54
53
15
18
9
1
10
222
3
e =
3.4844e-006
k =
10
>> [x,ind,e,k]=pagerank(C,0.1,1e-5,100);
>> ind(1:10),e,k
ans =
54
53
15
7
18
9
53
α
k
ind
0.9 0.85 0.8 0.5 0.1
38
28 22 10
5
7
7
7
7 54
54
54 54 54 53
53
53 53 53 15
18
18 18 15
7
9
9 15 18 18
15
15
9
9
9
10
1
1
1 10
1
10 10 10 222
222 222 222 222
1
76
55 55 55 19
Tabella 3: dati sul metodo delle potenze per il WWW di Harvard al variare di α.
10
222
1
19
e =
7.0210e-007
k =
5
Che cosa notate (Tabella 3)?
Dall’esempio precedente si osserva che più α è prossimo ad 1, più passi si devono compiere per
raggiungere la stessa tolleranza. Contrariamente, più α è prossimo a 0, meno passi si devono compiere
per raggiungere la stessa tolleranza. Questo fatto indica che il metodo delle potenze è tanto più veloce
quanto più α è vicino a 0. Tutto ciò può essere dimostrato rigorosamente studiando la convergenza del
metodo, ma dovremmo introdurre i concetti di autovalore e di autovettore di una matrice...ma per questi
è meglio iscriversi all’università!
D’altro canto possiamo notare che cambiando α cambia pure la classifica delle pagine. Quindi la
questione è alquanto delicata: da una parte vorremmo essere veloci (α prossimo a 0), dall’altra vorremmo
restare fedeli al WWW reale (α prossimo a 1).
Affrontiamo infine un’ultima faccenda curiosa. Ricordiamo cha abbiamo modificato la matrice da H 0
ad H 00 imponendo alla soluzione x di soddisfare a
x = αH 0 x + (1 − α)
u(uT x)
,
n
ovvero
x = αH 0 x + (1 − α)
54
u
n
(8)
dato che

T
u x=
1 1 ···


1 

x1
x2
..
.



 = x1 + x2 + · · · + xn = 1.

xn
Come abbiamo spiegato, questo equivale a scegliere tra tutti i vettori soluzione paralleli quello che fornisce
un pagerank totale pari ad 1, il che è in accordo con la metafora del navigatore virtuale: deve infatti
muoversi con probabilità 1 ad ogni istante. Come conseguenza si può osservare che stiamo aggiungendo
al comportamento secondo i link H 0 un comportamento con probabilità 1 − α che coincide con immettere
un nuovo indirizzo scelto a caso, ovvero con probabilità
1
ui
=
n
n
per ogni pagina xi , i = 1, . . . , n. Questo corrisponde ad una scelta “democratica” o imparziale. Ed è
quella che porta ai risultati principali che si vedono in una normale ricerca con Google. Ma non è l’unica:
cosa succede, infatti, se questo nuovo indirizzo non viene scelto cosı̀ casualmente, ma “forzando” la scelta
verso una pagina piuttosto che un’altra? Matematicamente dovremmo sostituire le precedenti probabilità
con nuove probabilità, diciamo
pi
n
per la pagina xi , i = 1, . . . , n, con il vincolo che
n
X
pi
i=1
ovvero
n
X
n
=1
pi = n
i=1
(come del resto accadeva per il vettore u). Ciò equivale a modificare la (8) in
p
x = αH 0 x + (1 − α) ,
n
dove il vettore
p=
p 1 p2 · · ·
pn
T
detto vettore di personalizzazione, permette appunto di forzare in qualche modo il calcolo del pagerank
in modo da dare più importanza a certe pagine piuttosto che ad altre, e questo a priori scegliendo opportunamente i vari pesi p1 , p2 , etc.. Questo è quello che succede per i cosiddetti “link sponsorizzati” che
compaiono evidenziati in cima (o a destra) della normale lista di risultati. Provate infatti a cercare la parola “automobile” su http://www.google.it/. E se proprio non siete stufi, provate pure a modificare
il codice pagerank.m per adattarlo a questa nuova versione!
Esercizio 11 Modificate il vostro prank.m adottando la versione con vettore di personalizzazione p e,
con riferimento al web rappresentato in figura 13, provate a scegliere p in modo tale da far risalire la
pagina meno importante in classifica.
55
A
Appendice: cifre significative, accuratezza e precisione
Nel Commento 4 in Sezione 3.2 abbiamo spesso nominato il concetto di cifre significative. Brevemente,
la cifra più significativa è sempre la prima da sinistra diversa da zero, quella meno significativa è l’ultima
a destra (anche se zero): le cifre significative sono tutte quelle comprese tra queste (incluse).
Esempio 17 Il numero 0.034 ha solo 2 cifre significative (si può scrivere infatti come 3.4 × 10−2 . Invece
il numero 0.0340 ne ha 3: anche l’ultimo zero è significativo.
Nella visualizzazione dei risultati Matlab abbiamo usato fino a 15 cifre dopo il punto decimale. Quindi
un totale di 16 cifre significative (ad es. per mk ). Servono tutte?
La risposta a questa apparentemente banale domanda richiede confidenza con i seguenti concetti:
• accuratezza: numero di cifre significative esatte;
• precisione: numero di cifre significative rappresentate.
In base a quanto appena definito, risulta inutile usare un’elevata precisione (tante cifre) in presenza di
una limitata accuratezza (poche esatte). In genere poi il vincolo è posto dalla precisione del dato meno
preciso. Il seguente esempio servirà a chiarire eventuali dubbi.
Esempio 18 Siano a = 1 e b = 3 e supponiamo di voler calcolare
r
r
a
1
=
.
c=
b
3
Il risultato corretto è
c = 0.577350269189626 . . .
di cui rappresentiamo 15 cifre significative esatte. Quindi diremo che c è preciso alla 15a cifra (perché
rappresento 15 cifre significative) e altrettanto accurato (perché sono tutte e 15 corrette). Ad es.
c = 0.577350269183210 . . .
sarebbe parimenti preciso ma accurato solo alla 11a cifra (le ultime 4, in grassetto, sono errate).
Supponiamo ora di calcolare prima
1
d = ' 0.33
3
rappresentando il risultato con una√precisione di sole 2 cifre (a altrettanta accuratezza essendo entrambe
esatte). Se ora calcoliamo c come d otteniamo
√
d = 0.574456264653803 . . .
con una precisione di 15 cifre. Peccato
sia limitata a sole 2 cifre, ovvero la stessa del
√ che l’accuratezza
a
dato d. Quindi le cifre significative di d dalla 3 in poi (in grassetto) non sono affatto “significative”!
L’esempio precedente ci serve da monito per evitare un utilizzo sconsiderato delle numerose cifre che
possono uscire da una calcolatrice scientifica. Ricordate: l’accuratezza di un risultato è comunque limitata
dal numero di cifre significative del dato meno preciso!
56
Matlab 16 Proviamo a vedere diversi formati di visualizzazione calcolando
√
0.005:
>> format short
>> sqrt(.005)
ans =
0.0707
>> format long
>> sqrt(.005)
ans =
0.070710678118655
>> format long e
>> sqrt(.005)
ans =
7.071067811865475e-02
Come si vede dall’ultimo risultato Matlab fornisce sempre 15 cifre decimali significative, le quali semplicemente non sono tutte visibili negli altri formati pur essendo memorizzate nel calcolatore.
B
1
2
3
4
5
6
7
8
9
Codici Pagerank realizzati
f u n c t i o n [ x , i n d , e , k ] = p r a n k ( C , a l f a , TOL , kmax )
% [ x , i n d , e , k ] = p r a n k ( C , a l f a , TOL , kmax )
% c a l c o l a i l pagerank x a s s o c i a t o a l l a matrice
% d i c o n n e t i v i t a ' C a meno d i una t o l l e r n a z a TOL
% con numero d i i t e r a z i o n i massimo kmax p e r i l
% metodo d e l l e p o t e n z e . i n d e ' i l v e t t o r e d e g l i
% i n d i c i d e l l e p a g i n e web r e l a t i v e a C o r d i n a t o
% secondo i l pagerank x . e e ' l ' e r r o r e f i n a l e
% e f f e t t i v o e k i l numero d i i t e r a z i o n i e s e g u i t e .
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
%0 v e r i f i c a d i s p a r s i t a '
i f ¬ i s s p a r s e (C)
d i s p ( ' ATTENZIONE : l a m a t r i c e d i c o n n e t t i v i t a ' ' non e ' ' s p a r s a ! ' )
return
end
%1 : i n i z i a l i z z a z i o n e
n= s i z e ( C , 1 ) ;%numero p a g i n e web
u= o n e s ( n , 1 ) ;%v e t t o r e u n i t a r i o
c=sum ( C , 1 ) ; %numero o u t l i n k
%2 : c o s t r u z i o n e m a t r i c e d i c o n n e t t i v i t a ' n o r m a l i z z a t a H1
H1= s p a r s e ( n , n ) ;
f o r j =1: n
i f c ( j ) 6= 0
H1 ( : , j ) =C ( : , j ) / c ( j ) ;
e l s e H1 ( : , j ) = u / n ;
end
end
%2 b i s : c o s t r u z i o n e ' g o o g l e m a t r i x ' H2 ( non s e r v e p e r i l c a l c o l o ! ! )
57
29
30
31
32
33
34
35
36
37
38
39
40
41
H2= a l f a * H1+ ( 1 - a l f a ) * ( u * u ' ) / n ;
%3 : metodo p o t e n z e p e r c a l c o l o p a g e r a n k x
k =0;
xnew=u / n ;
e =2 *TOL ;
w h i l e ( e ≥TOL)&( k ≤ kmax )
k=k + 1 ;
x o l d =xnew ;
xnew= a l f a * H1 * x o l d + ( 1 - a l f a ) * u / n ;
e=norm ( xnew - x o l d ) ;
end
%4 : o u t p u t o r d i n a t o s e c o n d o p a g e r a n k x
[ x , i n d ] = s o r t ( xnew , ' d e s c e n d ' ) ;
42
43
44
45
46
47
1
2
3
4
5
6
7
8
9
10
%NB: i comandi t i p o ' s p a r s e ' s e r v o n o a non t e n e r c o n t o d e g l i z e r i
%n e i c a l c o l i . Ad e s e m p i o H1= s p a r s e ( n , n ) c r e a una m a t r i c e nxn d i t u t t i z e r i
%ma l a memorizza come s p a r s a : quando v i e n e m o d i f i c a t a n e l l e s u c c e s s i v e
%i s t r u z i o n i , comunque g l i z e r i c h e r i m a n g o n o ( t a n t i ! ) non s a r a n n o
%c o n s i d e r a t i n e i c a l c o l i .
f u n c t i o n [ x , i n d , e , k ] = p r a n k p e r s ( C , p , a l f a , TOL , kmax )
% [ x , i n d , e , k ] = p r a n k ( C , p , a l f a , TOL , kmax )
% c a l c o l a i l pagerank x a s s o c i a t o a l l a matrice
% d i c o n n e t i v i t a ' C con v e t t o r e d i p e r s o n a l i z z a % z i o n e p a meno d i una t o l l e r n a z a TOL
% con numero d i i t e r a z i o n i massimo kmax p e r i l
% metodo d e l l e p o t e n z e . i n d e ' i l v e t t o r e d e g l i
% i n d i c i d e l l e p a g i n e web r e l a t i v e a C o r d i n a t o
% secondo i l pagerank x . e e ' l ' e r r o r e f i n a l e
% e f f e t t i v o e k i l numero d i i t e r a z i o n i e s e g u i t e .
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
%0 v e r i f i c a d i s p a r s i t a '
i f ¬ i s s p a r s e (C)
d i s p ( ' ATTENZIONE : l a m a t r i c e d i c o n n e t t i v i t a ' ' non e ' ' s p a r s a ! ' )
return
end
%1 : i n i z i a l i z z a z i o n e
n= s i z e ( C , 1 ) ;%numero p a g i n e web
u= o n e s ( n , 1 ) ;%v e t t o r e u n i t a r i o
c=sum ( C , 1 ) ; %numero o u t l i n k
%2 : c o s t r u z i o n e m a t r i c e d i c o n n e t t i v i t a ' n o r m a l i z z a t a H1
H1= s p a r s e ( n , n ) ;
f o r j =1: n
i f c ( j ) 6= 0
H1 ( : , j ) =C ( : , j ) / c ( j ) ;
e l s e H1 ( : , j ) = u / n ;
end
end
%2 b i s : c o s t r u z i o n e ' g o o g l e m a t r i x ' H2 ( non s e r v e p e r i l c a l c o l o ! ! )
H2= a l f a * H1+ ( 1 - a l f a ) * ( p * u ' ) / n ;
%3 : metodo p o t e n z e p e r c a l c o l o p a g e r a n k x
k =0;
xnew=u / n ;
58
34
35
36
37
38
39
40
41
42
e =2 *TOL ;
w h i l e ( e ≥TOL)&( k ≤ kmax )
k=k + 1 ;
x o l d =xnew ;
xnew= a l f a * H1 * x o l d + ( 1 - a l f a ) * p / n ;
e=norm ( xnew - x o l d ) ;
end
%4 : o u t p u t o r d i n a t o s e c o n d o p a g e r a n k x
[ x , i n d ] = s o r t ( xnew , ' d e s c e n d ' ) ;
43
44
45
46
47
48
%NB: i comandi t i p o ' s p a r s e ' s e r v o n o a non t e n e r c o n t o d e g l i z e r i
%n e i c a l c o l i . Ad e s e m p i o H1= s p a r s e ( n , n ) c r e a una m a t r i c e nxn d i t u t t i z e r i
%ma l a memorizza come s p a r s a : quando v i e n e m o d i f i c a t a n e l l e s u c c e s s i v e
%i s t r u z i o n i , comunque g l i z e r i c h e r i m a n g o n o ( t a n t i ! ) non s a r a n n o
%c o n s i d e r a t i n e i c a l c o l i .
Riferimenti bibliografici
[1] C. Moler. Numerical computing with MATLAB.
mathworks.com/moler/index_ncm.html.
2004.
Freely available at http://www.
[2] C. Moler. Experiments with MATLAB. 2008. Freely available at http://www.mathworks.
com/moler/index_exm.html.
[3] L. Page, S. Brin, R. Motwani, and T. Winograd. The pagerank citation ranking: Bringing order to the
web. Technical Report 1999-66, Stanford InfoLab, November 1999. Previous number = SIDL-WP1999-0120.
59