Note sull’uso di R per l’Algebra Lineare Sommario • Introduzione – Alcuni comandi elementari di R • Creazione di matrici e vettori e accesso ai loro elementi • Alcuni particolari tipi di matrice • Operazioni con le matrici • La libreria Matrix Introduzione Alcuni comandi elementari di R Note introduttive sull’uso di R Prima di iniziare con lo studio del software R (Version 1.8.1) applicato all’Algebra Lineare, introduciamo alcuni comandi elementari, che verranno costantemente utilizzati negli esempi proposti. Per una più completa descrizione del linguaggio R si rimanda al libro “Laboratorio di Statistica con R” di Iacus e Masarotto, Mc Graw Hill 2003. Note introduttive sull’uso di R: inserimento di commenti tramite il simbolo “ # “ Il simbolo “ # “ rappresenta in R un indicatore di commento. Negli esempi proposti nei seguenti lucidi, tale simbolo verrà usato per inserire dei commenti esplicativi ai comandi via via utilizzati in R > # Come costruire una matrice in R ? > # ... aspetta e vedrai!! Note introduttive sull’uso di R: l’assegnazione di un valore tramite il comando “ <- ” Il comando “<-” sta alla base della maggior parte delle operazioni che si svolgono in R. Esso permette di assegnare ad una variabile un valore o un insieme di valori. > # uso del comando "<-" > # assegnazione alla variabile “x” del valore 2 > x<-2 > # ora per vedere il contenuto di “x”, basterà scrivere x e inviare > x [1] 2 > # vediamo un'altro esempio > # attribuzione alla variabile "corso" della stringa "psicometria" > corso<-"psicometria" > corso [1] "psicometria" Note introduttive sull’uso di R: concatenare tra loro più elementi tramite la funzione “ c() ” La funzione “c()” serve a concatenare tra loro gli elementi che vengono forniti come argomento. > # creazione di un "vettore" y contenente gli elementi 25, -22, 32, 0, 12 > y<-c(25,-22,32,0,12) > y [1] 25 -22 32 0 12 > # NOTA BENE: con il termine generico "vettore“, in R non si fa riferimento > # alla nozione di vettore usuale dell'algebra lineare > # ma semplicemente ad una stringa di valori consecutivi Creazione di matrici e vettori e accesso ai loro elementi Creazione di una matrice in R: l’uso della funzione matrix() Gli argomenti da specificare nella funzione matrix() sono nell’ordine: •l’insieme degli elementi che costituiscono la matrice; •il numero di righe che dovrà avere la matrice (nrow=numero di righe); •il numero di colonne che dovrà avere la matrice (ncol=numero di colonne); •il modo in cui R dovrà riempire la matrice. Per default R riempie la matrice per colonne. Se si vuole forzare il riempimento per riga si deve specificare l’opzione byrow=T. Creazione di una matrice in R: riempimento della matrice per colonne Utilizzando la funzione matrix() costruiamo una matrice con due rige e tre colonne. Per default R riempie la matrice per colonne. > # creazione della matrice A di dimensione 2×3 (2 righe per 3 colonne) > A<-matrix(c(1,-4,5,6,0,2),nrow=2,ncol=3) > A [,1] [,2] [,3] [1,] 1 5 0 [2,] -4 6 2 Creazione di una matrice in R: riempimento della matrice per righe Costruiamo la stessa matrice dell’esempio precedente, utilizzando questa volta l’opzione byrow=T. In questo caso R riempirà la matrice per righe. > # creazione della matrice A di dimensione 2×3 (2 righe per 3 colonne) > # utilizzando l'opzione byrow=T (che permette il riempimento per righe) > A<-matrix(c(1,5,0,-4,6,2),nrow=2,ncol=3,byrow=T) > A [,1] [,2] [,3] [1,] 1 5 0 [2,] -4 6 2 Creazione di una vettore colonna Per costruire un vettore colonna, che può essere visto come una matrice con una sola colonna, si utilizza la funzione matrix(). In questo caso, il numero di righe da specificare tramite l’opzione nrow corrisponderà al numero di elementi del vettore da creare, mentre il numero di colonne da specificare tramite l’opzione ncol verrà posto uguale a 1. > # creazione del vettore colonna "a" di dimensione 3×1 (3 righe per 1 colonna) > a<-matrix(c(4,5,2),nrow=3,ncol=1) > a [,1] [1,] 4 [2,] 5 [3,] 2 Creazione di una vettore riga Per costruire un vettore riga, che può essere visto come una matrice con una sola riga, si utilizza la funzione matrix(). In questo caso, il numero di righe da specificare tramite l’opzione nrow verrà posto uguale a 1, mentre il numero di colonne da specificare tramite l’opzione ncol corrisponderà al numero di elementi del vettore da creare. > # creazione del vettore riga "a1" di dimensione 1×3 (1 riga per 3 colonne) > a1<-matrix(c(3,5,2),nrow=1,ncol=3) > a1 [,1] [,2] [,3] [1,] 3 5 2 Le dimensioni di una matrice: l’uso della funzione dim() La funzione dim() applicata ad una matrice restituisce in output le dimensioni (numero di righe e il numero di colonne) della stessa. > # dati la matrice "A" e i due vettori "a" e "a1" > A [,1] [,2] [,3] [1,] 1 5 0 [2,] -4 6 2 > a [,1] [1,] 4 [2,] 5 [3,] 2 > a1 [,1] [,2] [,3] [1,] 3 5 2 > # calcoliamo le dimensioni di ciascun oggetto tramite la funzione dim() > dim(A) [1] 2 3 > dim(a) [1] 3 1 > dim(a1) [1] 1 3 L’accesso agli elementi di una matrice > ## data la matrice A > A [,1] [,2] [,3] [1,] 1 5 0 [2,] -4 6 2 > ## accesso all'elemento di posto 2,3 (seconda riga, terza colonna) > A[2,3] [1] 2 > ## selezione della prima riga della matrice A > A[1,] [1] 1 5 0 > ## selezione della seconda colonna della matrice A > A[,2] [1] 5 6 > ## selezione della prima e della terza colonna della matrice A > A[,c(1,3)] [,1] [,2] [1,] 1 0 [2,] -4 2 L’accesso agli elementi di una vettore > # dato il vettore colonna "a" > a [,1] [1,] 4 [2,] 5 [3,] 2 > # accesso al secondo elemento del vettore > a[2,1] [1] 5 > # o più semplicemente > a[2] [1] 5 > # dato il vettore riga "a1" > a1 [,1] [,2] [,3] [1,] 3 5 2 > # accesso al terzo elemento del vettore > a1[1,3] [1] 2 > # o più semplicemente > a1[3] [1] 2 Alcuni particolari tipi di Matrice Creazione di una matrice diagonale: l’uso della funzione diag() La funzione diag() ha diversi usi a seconda dell’argomento che le viene fornito. Data l’istruzione diag(x): •se x è un vettore di elementi, R produce una matrice diagonale con sulla diagonale gli elementi di x. •se x è una matrice, R produce un vettore formato dagli elementi della diagonale di x. > > > > # creazione della matrice diagonale A # con elementi sulla diagonale pari a 1,5,-2,-8 A<-diag(c(1,5,-2,-8)) A [,1] [,2] [,3] [,4] [1,] 1 0 0 0 [2,] 0 5 0 0 [3,] 0 0 -2 0 [4,] 0 0 0 -8 > # estrazione della diagonale della matrice A > diagonale<-diag(A) > diagonale [1] 1 5 -2 -8 Creazione di una matrice identità: tramite la funzione diag() Per creare una matrice identità (matrice diagonale con tutti 1 sulla diagonale) basterà far ricorso alla funzione diag() dando come argomento un vettore di valori pari a 1. > # creazione di una matrice identità di dimensioni 2×2 > I2<-diag(c(1,1)) > I2 [,1] [,2] [1,] 1 0 [2,] 0 1 > # creazione di una matrice identità di dimensioni 4×4 > I4<-diag(c(1,1,1,1)) > I4 [,1] [,2] [,3] [,4] [1,] 1 0 0 0 [2,] 0 1 0 0 [3,] 0 0 1 0 [4,] 0 0 0 1 Operazioni con le Matrici La somma di matrici: l’uso dell’operatore “ + ” Per calcolare la somma tra due matrici si utilizza l’operatore “ + “. (Tale operatore viene utilizzato in R anche per calcolare la somma di due scalari) > # date le matrici A e B > A [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 2 3 4 5 6 [3,] 3 4 5 6 7 [4,] 4 5 6 7 8 [5,] 5 6 7 8 9 > B [,1] [,2] [,3] [,4] [,5] [1,] 2 3 4 5 6 [2,] 3 4 5 6 7 [3,] 4 5 6 7 8 [4,] 5 6 7 8 9 [5,] 6 7 8 9 10 > # calcoliamo la matrice C come somma delle matrici A e B tramite l'operatore "+" > C<-(A+B) > C [,1] [,2] [,3] [,4] [,5] [1,] 3 5 7 9 11 [2,] 5 7 9 11 13 [3,] 7 9 11 13 15 [4,] 9 11 13 15 17 [5,] 11 13 15 17 19 La sottrazione tra matrici: l’uso dell’operatore “ - ” Per calcolare la differenza tra due matrici si utilizza l’operatore “ - “. (Tale operatore viene utilizzato in R anche per calcolare la differenza tra due scalari) > # date le matrici A e B > A [,1] [,2] [,3] [,4] [,5] [1,] 10 9 8 7 6 [2,] 5 4 3 2 1 [3,] 2 3 4 5 8 [4,] 3 2 7 8 9 [5,] 6 7 8 9 10 > B [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 2 3 4 5 6 [3,] 3 4 5 6 7 [4,] 4 5 6 7 8 [5,] 5 6 7 8 9 > # calcoliamo la matrice C come differenza tra le matrici A e B tramite l'operatore "-" > C<-(A-B) > C [,1] [,2] [,3] [,4] [,5] [1,] 9 7 5 3 1 [2,] 3 1 -1 -3 -5 [3,] -1 -1 -1 -1 1 [4,] -1 -3 1 1 1 [5,] 1 1 1 1 1 Moltiplicazione di uno scalare per una matrice: l’uso dell’operatore “ * ” Per calcolare il prodotto tra uno scalare e una matrice si utilizza l’operatore “* ”. (Tale operatore viene utilizzato in R anche per calcolare il prodotto tra due scalari). > # dati la matrice A e posto lo scalare k uguale a 2 > A [,1] [,2] [,3] [,4] [,5] [1,] 10 9 8 7 6 [2,] 5 4 3 3 1 [3,] 2 3 4 5 8 [4,] 3 2 7 8 9 [5,] 6 7 8 9 10 > k<-2 > # calcoliamo la matrice C come prodotto dello scalare k per la matrice A, > # attraverso l'operatore "*" > C<-(k*A) > C [,1] [,2] [,3] [,4] [,5] [1,] 20 18 16 14 12 [2,] 10 8 6 6 2 [3,] 4 6 8 10 16 [4,] 6 4 14 16 18 [5,] 12 14 16 18 20 Moltiplicazione fra matrici: l’uso dell’operatore “ %*% ” Per calcolare il cosiddetto “prodotto vettoriale”, e cioè il prodotto tra due matrici, si utilizza in R l’operatore “ %*% “. > # date le matrice A e B > A [,1] [,2] [,3] [1,] 0 2 4 [2,] 2 4 6 > B [,1] [,2] [1,] 3 3 [2,] 1 6 [3,] 0 1 > # calcoliamo la matrice C come prodotto delle matrici A e B, > # attraverso l'operatore " %*% " > C<-(A%*%B) > C [,1] [,2] [1,] 2 16 [2,] 10 36 Moltiplicazione fra matrici: un altro esempio > # date le matrici A e B > A [,1] [,2] [1,] 1 1 [2,] 3 1 [3,] 2 0 > B [,1] [,2] [,3] [1,] 1 2 3 [2,] 2 3 4 > # calcoliamo la matrice C come prodotto delle matrici A e B, > # attraverso l'operatore " %*% " > C<-(A%*%B) > C [,1] [,2] [,3] [1,] 3 5 7 [2,] 5 9 13 [3,] 2 4 6 Moltiplicazione fra matrici: attenzione !! Dalla teoria, si sa che due matrici possono essere moltiplicate tra loro se il numero delle colonne della prima è uguale al numero delle righe della seconda. Se si richiede ad R di moltiplicare tra loro due matrici non moltiplicabili tra loro, si ottiene come risultato un messaggio di errore. Si veda in proposito il seguente esempio. > # siano date le matrici A e B > A [,1] [,2] [1,] 1 1 [2,] 3 1 [3,] 2 0 > B [,1] [,2] [,3] [1,] 1 4 3 [2,] 2 6 4 [3,] 2 7 5 [4,] 3 1 5 [5,] 3 2 4 > # proviamo a calcolare la matrice C come prodotto delle due matrici A e B > C<-(A%*%B) Error in A %*% B : non-conformable arguments > # coerentemente con la teoria dell'algebra lineare R non svolge > # la moltiplicazione e restituisce un messaggio di errore Moltiplicazione fra vettori tramite l’operatore “ %*% ” Naturalmente anche per calcolare il prodotto tra due vettori si fa ricorso all’operatore “ %*%”. > # dati i vettori "a" e "b" > a [,1] [,2] [,3] [1,] 3 4 5 > b [,1] [1,] 4 [2,] 5 [3,] 6 > # calcoliamo la matrice C come prodotto dei vettori "a" e "b" > # attraverso l'operatore " %*% " > C<-(a%*%b) > C [,1] [1,] 62 Moltiplicazione fra vettori: secondo esempio > # dati i vettori "a" e "b" > a [,1] [1,] 1 [2,] 2 [3,] 3 > b [,1] [,2] [,3] [1,] 1 3 2 > # calcoliamo la matrice C come prodotto dei vettori "a" e "b" > C<-(a%*%b) > C [,1] [,2] [,3] [1,] 1 3 2 [2,] 2 6 4 [3,] 3 9 6 Potenze di matrici: attraverso l’operatore “ %*% ” Nota: ricordiamo che le potenze sono applicabili solamente alle matrici quadrate. > # data la matrice quadrata A > A [,1] [,2] [1,] 1 5 [2,] 2 -3 > # calcoliamo la potenza seconda di A > A%*%A [,1] [,2] [1,] 11 -10 [2,] -4 19 > # calcoliamo la potenza terza di A > A%*%A%*%A [,1] [,2] [1,] -9 85 [2,] 34 -77 Calcolo dell’inversa di una matrice: attraverso la funzione solve() Per calcolare l’inversa di una matrice si utilizza la funzione solve(). Nota: La matrice da invertire deve essere quadrata, altrimenti R produrrà un messaggio di errore coerentemente con la teoria dell’algebra lineare. > # data la matrice quadrata A > A [,1] [,2] [,3] [1,] 1 1 1 [2,] 1 2 3 [3,] 1 4 9 > # calcoliamo la matrice inversa di A attraverso la funzione solve() > Ainv<-solve(A) > Ainv [,1] [,2] [,3] [1,] 3 -2.5 0.5 [2,] -3 4.0 -1.0 [3,] 1 -1.5 0.5 > # e verifichiamo che Ainv sia effettivamente l'inversa di A > A%*%Ainv [,1] [,2] [,3] [1,] 1.000000e+00 -1.998401e-15 3.330669e-16 [2,] -8.881784e-16 1.000000e+00 -2.220446e-16 [3,] 0.000000e+00 -1.776357e-15 1.000000e+00 > # (per una miglior interpretazione dei risultati utilizziamo la funzione di R > # round() per arrotondare i valori ottenuti) > round(A%*%Ainv) [,1] [,2] [,3] [1,] 1 0 0 [2,] 0 1 0 [3,] 0 0 1 > # abbiamo così ottenuto la matrice identità [cvd] Matrice trasposta: l’uso della funzione t() La funzione t() effettua la trasposizione di una matrice (o di un vettore). > # data la matrice A > A [,1] [,2] [,3] [1,] 1 5 0 [2,] -4 6 2 > # calcoliamo la trasposta di A tramite la funzione t() > t(A) [,1] [,2] [1,] 1 -4 [2,] 5 6 [3,] 0 2 > # naturalmente t(t(A))=A ! > t(t(A)) [,1] [,2] [,3] [1,] 1 5 0 [2,] -4 6 2 La trasposizione di una matrice (o di un vettore): altri esempi > # dato il vettore colonna "a" > a [,1] [1,] 4 [2,] 5 [3,] 2 > # calcoliamo il vettore trasposto di "a" (che naturalmente sarà un vettore riga) > t(a) [,1] [,2] [,3] [1,] 4 5 2 La libreria Matrix Un approfondimento: la libreria Matrix Oltre alle funzioni già presenti all’interno all’interno del software base R (Version 1.8.1) è possibile scaricare gratuitamente presso il sito ufficiale di R (www.r-project.org) la libreria Matrix che contiene alcune funzioni molto utili nell’ambito del calcolo matriciale (come la risoluzione di sistemi di equazioni lineari, il calcolo del determinante di una matrice, la decomposizione LU …). A titolo esemplificativo riportiamo, di seguito, l’indice delle funzioni contenute in tale libreria. *** Matrix/INDEX *** Hermitian.test: Test a Matrix for Conjugate Symmetry LowerTriangular.test:Test a Matrix for Triangularity Matrix: Construct a Classed Matrix Matrix.class: Determine the subclass of a Matrix Orthonormal.test: Check for Orthogonality or Orthonormality SVD: Singular Value Decomposition of a Matrix Det: Calculate the Determinant of a Matrix diagDet:Determinant of triangular matrices eigen: Spectral Decomposition of a Matrix expand: Expand a Decomposition into Factors facmul: Multiplication by Decomposition Factors hilbert: Generate a Hilbert matrix lu.Matrix: Triangular (LU) Decomposition of a Matrix lu: Triangular Decomposition of a Square Matrix norm: Norm of a Matrix rcond: Estimate the Reciprocal Condition Number schur: Schur Decomposition of a Matrix solve.Matrix: Solve a System of Equations unpack: Full Storage Representation of Packed Matrices