ProgrammazioneAvanzataInR

66
Politecnico di Milano Dip ar timento di Ma tema tica Dispensa di Elementi di Programmazione Avanzata in R a cura di Laura Azzimonti Stef ano Baraldo I diritti d’autore sono riservati. Ogni sfruttamento commerciale sarà perseguito. Autori: Laura Azzimonti e Stefano Baraldo, Dipartimento di Matematica “F. Brioschi”, Politecnico di Milano, piazza Leonardo da Vinci 32, 20133 Milano; email: laura.azzimonti@g mail.com, [email protected].

Transcript of ProgrammazioneAvanzataInR

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 1/66

Politecnico di Milano

Dipartimento di Matematica

Dispensa di

Elementi di Programmazione Avanzata in R

a cura di

Laura Azzimonti

Stefano Baraldo

I diritti d’autore sono riservati. Ogni sfruttamento commerciale sarà perseguito. Autori: Laura Azzimonti

e Stefano Baraldo, Dipartimento di Matematica “F. Brioschi”, Politecnico di Milano, piazza Leonardo da Vinci

32, 20133 Milano; email: [email protected], [email protected].

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 2/66

Indice

Introduzione 1

1 Come funziona R 3

1.1 La struttura dati  SEXPREC . . . . . . . . . . . . . . . . . . . . . 31.2 La gestione della memoria . . . . . . . . . . . . . . . . . . . . 41.3 Il loop   read-parse-evaluate    . . . . . . . . . . . . . . . . . . . . 51.4 Funzioni ordinarie e primitive . . . . . . . . . . . . . . . . . . 7

2 Programmazione ad oggetti 10

2.1 Classi S3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.2 Classi S4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.2.1 Ereditarietà . . . . . . . . . . . . . . . . . . . . . . . . 13

2.3 Metodi S4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.3.1 Funzioni generiche . . . . . . . . . . . . . . . . . . . . 15

2.4 Un trucco: programmazione ad oggetti con le closures . . . . . 17

3 Interazioni con altri linguaggi 20

3.1 Richiamare funzioni in C/Fortran . . . . . . . . . . . . . . . . 203.1.1 .C e .Fortran . . . . . . . . . . . . . . . . . . . . . . . 213.1.2 .Call e .External . . . . . . . . . . . . . . . . . . . . . 24

3.2 Eseguire R da un programma C . . . . . . . . . . . . . . . . . 25

4 Calcolo parallelo in R 29

4.1   Rmpi   . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.1.1 Principali funzioni di  Rmpi   . . . . . . . . . . . . . . . . 294.1.2 Invio dati . . . . . . . . . . . . . . . . . . . . . . . . . 304.1.3 Esecuzione funzioni . . . . . . . . . . . . . . . . . . . . 314.1.4 Ricezione dati . . . . . . . . . . . . . . . . . . . . . . . 334.1.5 Struttura del codice . . . . . . . . . . . . . . . . . . . . 344.1.6 Esempi codice . . . . . . . . . . . . . . . . . . . . . . . 364.1.7 Simulazioni e confronto . . . . . . . . . . . . . . . . . . 44

2

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 3/66

4.2   snow   . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

4.2.1 Principali funzioni di  snow   . . . . . . . . . . . . . . . . 504.2.2 Invio/ricezione di dati ed esecuzione di funzioni . . . . 504.2.3 Struttura del codice . . . . . . . . . . . . . . . . . . . . 51

A Codici Calcolo Parallelo 53

A.1 Brute-force . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53A.2 Task-push . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55A.3 Task-pull . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Bibliografia 63

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 4/66

Introduzione

R [1] è un linguaggio di programmazione, nonché un programma per inter-pretare tale linguaggio, orientato ad applicazioni in ambito statistico, ideato

nel 1993 da Ross Ihaka e Robert Gentleman. Nacque come interprete perun linguaggio di programmazione funzionale simile a Scheme, ma in brevetempo gli ideatori cominciarono ad adottare le strutture sintattiche del soft-ware commerciale S, ideato da Rick Becker, John Chambers e Allan Wilksa metà anni ’70. Ad oggi, pur essendo un software open source autonomo eampiamente supportato da una nutritissima comunità, R mantiene una com-patibilità quasi piena con S e S-PLUS, differenziandosene, a livello utente,solo per alcuni dettagli come le regole di scoping .

Il codice sorgente di   R   è scritto in linguaggio C, ed è compilabile pertutte le principali piattaforme. Supporta in modo naturale l’implementazione

di pacchetti aggiuntivi ed estensioni scritte in C, C++ e Fortran (nonchénaturalmente nel linguaggio R stesso), ma varie estensioni sono disponibiliper l’interazione con programmi scritti in altri linguaggi, tra cui ad esempioPython, Perl e SQL.

La comunità di R  è ad oggi molto estesa, e continua a migliorare ed esten-dere il programma rendendo disponibili vari pacchetti sul Comprehensive RArchive Network (CRAN ). Tali estensioni rispondono da un lato alla neces-sità rendere disponibili a tutti metodi statistici (e non) anche molto avanzati,dall’altro a quella di sopperire alle limitazioni del programma base in fatto diefficienza. In questo lavoro daremo alcuni cenni riguardanti questo secondoaspetto: innanzitutto vengono descritti alcuni aspetti chiave del funziona-mento del programma, dopodiché vengono esposti alcuni elementi di tecnicheavanzate come la programmazione a oggetti, la chiamata di funzioni scrit-te in altri linguaggi di programmazione e il calcolo parallelo, quest’ultimoargomento corredato anche di alcuni casi test.

All’interno dell’elaborato non verranno esposti i fondamenti della sintassidel linguaggio   R   , poiché sarebbe fuori dallo scopo del lavoro. In ogni casola trattazione è pensata per essere accessibile, con poco sforzo, anche a chiancora non conosce questo linguaggio. Chi fosse interessato ad approfondirne

1

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 5/66

Introduzione    2

le basi è invitato a consultare i manuali [2] e [3].

Questo elaborato è stato redatto facendo riferimento a  R versione 2.11.0.

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 6/66

Capitolo 1

Come funziona R

L’obiettivo di questo capitolo non è quello di fornire una descrizione com-pleta ed esaustiva del funzionamento di   R   e della struttura del suo codicesorgente, ma di dare un’idea generale delle principali meccaniche sottostantial linguaggio  R  e all’interfaccia di uso abituale.

1.1 La struttura dati   SEXPREC

Lavorando normalmente in  R  è possibile utilizzare oggetti di natura molto

varia, tra cui naturalmente variabili numeriche, stringhe, vettori e matrici,oppure strutture più complesse come liste, dataframes (tabelle di dati com-positi), factors (vettori di etichette con un numero prestabilito di livelli) ealtri. Tutti questi oggetti sono in realtà memorizzati da   R come puntatori aoggetti di un unico tipo, una  struct  denominata nel sorgente C  SEXPREC, lacui definizione è la seguente:

1   t y pe de f s tr uc t S E XP RE C {

2   S E X P R E C _ H E A D E R ;

3   u ni on {

4   s t ru c t p r i m sx p _ st r u c t p r im s x p ;

5

  s t ru c t s y m s xp _ s t ru c t s y ms x p ;6   s t ru c t l i s t sx p _ st r u c t l i st s x p ;

7   s t ru c t e n v s xp _ s t ru c t e n vs x p ;

8   s t ru c t c l o s xp _ s t ru c t c l os x p ;

9   s t ru c t p r o m sx p _ st r u c t p r om s x p ;

10   } u ;

11   } S E XP R EC , * S E XP ;

La macro alla riga 2 fa riferimento a  struct  che includono informazioniriguardanti il tipo dell’oggetto memorizzato (nonché dei puntatori usati dal

3

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 7/66

CAPITOLO 1. COME FUNZIONA R    4

garbage collector), mentre la   union u  contiene varie triplette di puntatori a

SEXPREC (tranne  primsxp, che è un intero per motivi che saranno chiariti nelparagrafo 1.4), utilizzate in modo diverso a seconda del tipo di dato per ilquale è istanziato il singolo oggetto  SEXPREC. Il dato effettivo, ad esempio l’int

che contiene il valore numerico di un oggetto  R  di tipo  integer, viene allocatonello spazio in memoria immediatamente successivo al relativo   SEXPREC, inuna posizione e per una lunghezza che sono quindi univocamente determinatedalla posizione del relativo oggetto  SEXPREC  (di dimensione nota a priori) edal tipo di dato.

All’interno dei sorgenti, o all’interno di codici aggiuntivi che intendonofarne uso, i  SEXPREC sono gestiti attraverso puntatori, denominati SEXP, e ge-

stiti nel codice attraverso una vasta gamma di macro (ne vedremo un esempiodi utilizzo nel paragrafo 3.1.   R  crea uno di questi oggetti per  ogni   strutturada esso utilizzata, incluse non solo le variabili classiche, ma anche le funzio-ni e gli environments che contengono le variabili. Questa uniformità nellastruttura di dati e operatori, se da un lato diminuisce molto le prestazionicomputazionali, rende il linguaggio estremamente accessibile.

1.2 La gestione della memoria

A differenza di quanto avviene nel C e C++, in R l’utente non de-

ve preoccuparsi dell’allocazione (dinamica) o cancellazione della memoriaesplicitamente.

Per quando riguarda l’allocazione, l’allocator di   R   la effettua automati-camente all’assegnazione di una variabile o alla chiamata di una funzione.Per evitare copie inutili,  SEXPREC_HEADER  contiene al suo interno la variabileunsigned int named, che assume valore 0, 1 o 2 a seconda che l’oggetto inquestione sia referenziato da nessuna, una o più variabili in  R   . In situazio-ni come un assegnamento   b <- a, finché   a  o   b  non vengono modificati nonè necessario allocare un’ulteriore copia del dato a cui le due variabili fannoriferimento; questa nuova allocazione in effetti non viene effettuata, e un’e-

ventuale funzione (primitiva, si veda il paragrafo 1.4) che debba agire su  a ob eseguirà prima il controllo

1   if ( N AM ED ( x ) = = 2)

2   x = d u pl ic a te ( x ) ;

duplicando il dato solo al momento opportuno.Analogamente ad altri linguaggi interpretati, il compito di liberare la

memoria inutilizzata è affidato a un garbage collector. Il garbage collectordi   R   è di tipo generazionale, ovvero classifica gli oggetti in memoria in 3

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 8/66

CAPITOLO 1. COME FUNZIONA R    5

 “generazioni” ed effettua continuamente cicli di “raccolta della spazzatura”,

all’interno dei quali cerca quali oggetti non sono più referenziati da  R  e rendela memoria da essi occupata disponibile per un nuovo utilizzo. Ogni 20 ciclidi raccolta tra gli oggetti più giovani viene effettuato un ciclo sugli oggettidelle due generazioni più giovani, e ogni 5 cicli di quest’ultimo tipo ne vieneeffettuato uno su tutti gli oggetti.

Avere presente questo meccanismo si rivelerà importante al paragrafo 3.1,quando vedremo come maneggiare oggetti  SEXP  all’interno di codici C creatidall’utente.

1.3 Il loop   read-parse-evaluateCome in ogni linguaggio interpretato, ogni operazione richiesta a  R  dall’u-

tente deve passare attraverso 2 fasi fondamentali: il  parsing   delle istruzioni,ovvero l’individuazione, nel testo delle istruzioni, delle strutture sintatticheproprie del linguaggio e dei simboli definiti, e l’evaluation , ovvero la valutazio-ne dei valori effettivi dei simboli individuati e lo svolgimento delle operazionisu tali valori.

Il parser di   R   è stato creato attraverso GNU Bison 2.3, un generatoredi parser in base a una grammatica fornita. Nel caso di   R   la grammaticaè sostanzialmente quella di S, con differenze minime. Le strutture sintatti-

che riconosciute sono riassunte dalla Tabella 1.1 (tratta da [4]), dove   expr rappresenta a sua volta un’espressione,  op   e  unaryOp   sono rispettivamenteun operatore binario e unario,  nameString   e  constNameString   rappresenta-no stringhe/nomi sintattici e costanti numeriche/logiche,  Name  è il nome diuna variabile mentre sublist  e formlist  sono liste di espressioni o combinazioniName =expr  separati da virgole.

Il parser individua le espressioni valide, ma non è detto che tali espres-sioni abbiano senso al momento dell’evaluation. Ad esempio, utilizzando lafunzione di R parse, con la quale possiamo ottenere la  unevaluated expression da una stringa di codice, si può lanciare

1   > a <- " ciao "2   > u ne va l < - p ar se ( t e xt = " a +1 " )

3   > u ne va l

4   e x p r e s s i o n ( a + 1 )

5   a t t r ( , " s r c f i l e " )

6   < t e x t >

senza ottenere errori. Tuttavia, essendo il  +  un operatore non definito perstringhe, l’evaluator si accorgerà dell’inconsistenza.

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 9/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 10/66

CAPITOLO 1. COME FUNZIONA R    7

1   ‘ i f ‘ ( ‘ > ‘ ( a , b ) , ‘ - ‘ ( a , b ) , ‘ - ‘ ( b , a ) )

Le istruzioni legate a parole chiave od operatori, come   if,   while,   +,   [<-

e altri, sono effettivamente codificate in   R   come funzioni, utilizzabili nellaforma consueta se richiamate tra backticks. In questo modo, essendo notol’ordine con cui effettuare le varie chiamate grazie al parser, qualsiasi codicepuò venire eseguito come una complessa chiamata di funzioni in sequenza oannidate.

Fino ad ora siamo stati vaghi sul concetto di funzione, facendo riferimentoin particolare a ciò che l’utente utilizza come tali all’interno del linguaggioR   . In realtà si possono individuare due tipi principali di funzioni: quelleordinarie, definite tramite linguaggio  R  , e quelle primitive, il cui corpo è in

realtà scritto nel sorgente del programma. Queste ultime hanno un’impor-tanza fondamentale, in quanto  la valutazione di un’espressione atomica viene effettuata solamente se richiesta da una funzione primitiva .

1.4 Funzioni ordinarie e primitive

Una   funzione ordinaria , o meglio un oggetto di tipo  closure , è costituitoda un SEXPREC che usa i puntatori definiti in  struct closxp_struct closxp (siveda 1.1), ovvero  *formals,  *body e  *env. Questi tre campi sono i componen-ti fondamentali dell’oggetto closure, e possono essere visualizzati attraversoapposite funzioni:

1   > s pr od < - f u nc t io n ( x1 = 1 , x 2 =1 ) {

2   + r et ur n ( x1 % *% x2 )

3   + }

4   > f o rm a l s ( s p ro d )

5   $ x1

6   $ x2

7   > b o dy ( s p r o d )

8   {

9   r et ur n ( x1 % * % x 2 )

10   }11   > e n v ir o n m en t ( f u n )

12   < e n v i r o n m e n t : R _ G l o b a l En v >

Il campo   formals   contiene gli argomenti formali, ovvero i nomi degli argo-menti da passare contenuti nella definizione della funzione; il campo   body contiene il vero e proprio codice da eseguire quando la funzione viene lan-ciata; infine,  environment  fa riferimento all’ambiente in cui vanno cercate levariabili non locali alla funzione.

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 11/66

CAPITOLO 1. COME FUNZIONA R    8

Nel caso dell’esempio precedente, l’enclosing environment   della funzio-

ne  sprod, al momento della definizione, viene impostato per default, ovveroquello globale della sessione di  R   . Una funzione ha tipicamente un environ-ment differente da  R_GlobalEnv   solamente se esse proviene da un pacchettoin cui è stato specificato un  namespace , oppure quando la funzione è statachiamata a sua volta da un’altra funzione; in tal caso l’enclosing environmentè costituito dalle variabili locali della funzione chiamante. La ricerca dellevariabili viene effettuata secondo un criterio gerarchico: se un nome non vie-ne trovato nello scope locale, viene cercato nell’enclosing environment, poinell’enclosing environment di quest’ultimo, e così via, fino a quello globale.

L’evaluation di una funzione ordinaria procede in 3 passi:

•   Matching   degli argomenti passati con gli argomenti formali. Poichéle funzioni utilizzate in   R  hanno spesso molti argomenti, per comodi-tà d’uso non è obbligatorio che essi vengano passati seguendo l’ordinespecificato dalla definizione, ma questo rende necessaria l’identificazio-ne degli argomenti. Esistono più criteri di matching, che vengono ap-plicati secondo una priorità prestabilita. Innanzitutto viene effettuatoun matching esatto, ovvero una variabile passata con nome identico aquello di uno degli argomenti formali viene associata a tale argomento.Dopodiché viene effettuato un matching parziale, in base alle porzioniiniziali dei nomi. Infine, le variabili rimanenti vengono associate in base

all’ordine con cui si presentano. Se nella definizione della funzione èpresente tra gli argomenti formali  ..., gli argomenti passati non asso-ciabili a nessun argomento formale vengono trasferiti al posto dei   ...

presenti nella chiamata a una funzione inclusa nel  body.

•   Creazione di un environment , quello locale, che contiene gli argomentipassati ed è incluso nell’enclosing environment  della funzione.

•   Evaluation  del corpo della funzione e return. In  R esiste un meccanismodetto  lazy evaluation , che ha lo scopo di evitare valutazioni non neces-sarie di variabili. Per ogni argomento formale viene creato un oggetto

di tipo   promise , che contiene un’espressione, il riferimento a un envi-ronment e una flag   seen; l’espressione contenuta nella promise vienevalutata solo una volta (viene controllata preventivamente la flag seenper sapere se è necessaria la valutazione) nell’environment specificato,e solo in 2 casi: se la variabile diventa argomento di una funzione pri-mitiva o se l’evaluation è necessaria per la selezione di un metodo (siveda il capitolo 2).

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 12/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 13/66

Capitolo 2

Programmazione ad oggetti

La programmazione ad oggetti in R   è resa possibile in modo molto diversoda come lo si intende tipicamente nei linguaggi di programmazione objectoriented; le classi sono ad esempio più simili a delle semplici  struct C che nonalle classi C++. Le   classi S3 , che fungono tutt’ora da struttura per buonaparte degli output delle funzioni più usate di   R   , consistono semplicementein liste di oggetti diversi alle quali viene associata un’etichetta; le  classi S4invece, che mimano le classi introdotte nelle ultime versioni di S, dispongonodi una struttura ben definita. Quelli che vengono chiamati  metodi   in  R sonoinvece a tutti gli effetti degli overloading di funzioni, che permettono a una

stessa funzione di avere comportamenti diversi a seconda della classe dei suoiargomenti.

2.1 Classi S3

Una classe in stile S3 si definisce molto semplicemente come una lista,dopodiché le si applica l’etichetta corrispondente alla classe a cui la si vuoleassociare con il comando  class.

1   > P 1 = NU LL

2   > P 1 $x = 13   > P 1 $y = 1

4   > P 2 = NU LL

5   > P 2 $ r = s qr t ( 2 )

6   > P 2 $ t h et a = 3 * p i / 4

7   > c l as s ( P 1 ) = " x y po i n t "

8   > c l as s ( P 2 ) = " r t h et a p oi n t "

Possiamo notare che non è stata dichiarata da nessuna parte la strutturadelle due classi create a partire dalle liste  P1 e  P2: il controllo della presenza

10

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 14/66

CAPITOLO 2. PROGRAMMAZIONE AD OGGETTI    11

di determinati campi e della validità del loro contenuto è lasciato completa-

mente al programmatore e all’utente. Nell’esempio in alto abbiamo creatodue punti in coordinate cartesiane e polari, e vogliamo scrivere una funzione,denominata  xpos, che restituisca la coordinate cartesiana  x del punto a pre-scindere dal sistema di riferimento con cui l’abbiamo salvato. Innanzituttocreiamo la funzione che effettuerà la scelta del metodo S3 adatto, chiamandoal suo interno  UseMethod:

1   x p os = f u n c t i on ( x , . . .)

2   U s e M e t h o d ( " x p o s " )

A questo punto i metodi possono essere definiti semplicemente scrivendonuove funzioni nella forma  funzione.classe, specificando un corpo diverso aseconda dei casi:

1   > x p os . x y p o i nt = f u n c t i on ( x ) x $ x

2   > x p os . r t h e t a po i n t = f u n c ti o n ( x ) x $ r * c os ( x $ t h e ta )

3   > x po s ( P1 )

4   [ 1] 1

5   > x po s ( P2 )

6   [ 1 ] -1

Possiamo notare che   xpos   esamina la classe dell’argomento passato divolta in volta, e su questa base ha scelto quale metodo utilizzare.

Come semplice meccanismo di polimorfismo è inoltre possibile specificareper un oggetto S3 più classi di appartenenza simultanee:

1   s 3 cl as s < - N UL L

2   s 3 c l a ss $ n a m e < - " n o m e "

3   s 3 cl as s $ n um be r < - 0

4   c l as s ( s 3 c l as s ) < - c ( " N o me " , " M a t r i co l a " , " N o me _ M a t r i co l a " )

2.2 Classi S4

Una classe S4 è una struttura dati contenente diversi attributi (denomi-nati   slot ) di tipo predeterminato. Per definire una classe di questo tipo siricorre al comando

1   s e t Cl a s s ( " c la s s _ n a me " , r e p r es e n t at i o n ( x = " t yp e 1 " , y = " t y pe 2

" ) , p r o to t y pe = l i s t ( x = va lx , y = v a ly )

dove   class_name   è una stringa che definisce il nome della classe, mentrerepresentation è una funzione che definisce gli attributi e ne associa un tipo(nel caso dell’esempio sopra, gli attributi sono  x  e  y); l’argomento opzionale

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 15/66

CAPITOLO 2. PROGRAMMAZIONE AD OGGETTI    12

prototype permette invece di stabilire dei valori di default per gli attributi,

inserendoli all’interno di una lista.Per creare un’istanza di una classe definita in precedenza si utilizza la

funzione  new, eventualmente specificando tra i suoi argomenti i valori di ini-zializzazione per gli attributi. L’accesso agli attributi (tutti pubblici) vieneeffettuato attraverso l’operatore @ o con la funzione  slot:

1   > s e t C l as s ( " p u n t o 2 D " , r e p r e s e n t a t i o n ( x = " n u m e r i c " , y = "

n u m e r i c " ) , p r o t o t y p e = l i s t ( x = 0 , y = 0 ) )

2   [ 1 ] " p u n t o2 D "

3   > P < - n ew ( " p u nt o2 D " , x =4 )

4   > P @x

5   [ 1] 46   > s l ot ( P , " x " )

7   [ 1] 4

8   > P @y

9   [ 1] 0

10   > P@y < - " c ia o"

11   E rr or e i n c h ec k Sl o tA s si g nm e nt ( o b je ct , n am e , v al ue ) : . ..

A differenza delle classi S3, le classi S4 permettono l’assegnamento divalori agli attributi solo per il tipo indicato nella definizione, il quale puòconsistere in un tipo standard di   R  o in una classe già definita. Nonostantequesto controllo, è possibile che siano richieste ulteriori proprietà agli attri-buti non verificabili col solo controllo del tipo (per esempio, che un vettore ditipo  numeric   abbia una lunghezza predeterminata). Esistono 2 meccanismiper controllare la coerenza degli oggetti creati: l’overloading del costruttoree il controllo di validità.

Anticipando per un attimo l’argomento della Sezione 2.3, vediamo la de-finizione del metodo  initialize, ovvero un overloading della funzione omo-nima, per la classe  punto2D. Nel corpo del metodo possiamo notare che sonoindicate le istruzioni da eseguire prima di effettuare l’inizializzazione stan-dard: in questo caso, se l’utente crea un oggetto  punto2D  senza specificare ivalori iniziali di x e  y, (la funzione missing(par) restituisce TRUE se la funzione

in cui è contenuta ha ricevuto come parametro  par,  FALSE altrimenti), vienechiamata una versione meno specifica di  initialize, ovvero quella standard,con parametri inizializzati a 0.

1   s e t M e t h o d ( " i n i t i a l i z e " , " p u n t o 2 D " , f u n c t i o n ( . O b j e c t , x , y

, . . . ) {

2   i f ( m i s si n g ( x ) & m i s si n g ( y ) ) {

3   c a l l N e x t M e t h o d ( . O b j e c t , x = 0 , y = 0 , . . . )

4   }

5   }

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 16/66

CAPITOLO 2. PROGRAMMAZIONE AD OGGETTI    13

Inoltre può essere definita una funzione di controllo della validità di un

oggetto, che oltre ad essere richiamata esplicitamente può essere imposta-ta per controllare la validità prima delle inizializzazioni e delle copie. Adesempio, volendo creare una classe   curva   contenente due vettori   x   e   y   chedefiniscano le coordinate della discretizzazione di una curva in   R2, saremointeressati ad assicurarci che i due vettori abbiamo la stessa lunghezza. Lafunzione  validObject  si può quindi definire come:

1   v a l id O b je c t < - f u n ct i on ( o b j e c t ) {

2   i f ( l e ng t h ( o b j ec t @ x ) = = l e ng t h ( o b j ec t @ y ) ) T R UE

3   e l se p a st e ( " U n e qu a l x , y l e n gt h s ? )

4   }

Tale funzione può essere impostata come funzione di validazione alla defi-nizione della classe, passando il parametro  validity=validObject nella chia-mata a  setClass, oppure può essere eseguita in un momento successivo perverificare la validità dei parametri, con la chiamata  setValidity("curva",

validObject).

2.2.1 Ereditarietà

La programmazione ad oggetti in  R  prevede anche un meccanismo di ere-ditarietà da altre classi S4 o da tipi standard, mentre non è possibile ereditare

da classi S3, le quali non hanno una struttura ben definita e conforme a quelladel più recente paradigma di programmazione ad oggetti di S ed  R  .

Una classe può essere definita come “figlia” con due meccanismi. Il piùimmediato è l’uso dell’argomento opzionale  contains  di  setClass:

1   s e t C l a s s ( " p u n t o 3 D " , r e p r e s e n t a t i o n ( z = " n u m e r i c " ) , c o n t a i n s = "

p u n t o 2 D " )

Un oggetto  punto3D avrà ora 3 attributi, di cui due,  x e  y, ereditati dallaclasse  punto2D; inoltre a un attributo definito come di classe  punto2D  potràessere assegnato anche un oggetto di classe  punto3D. L’argomento contains

può anche essere una lista, in modo tale che la nuova classe erediti da più “genitori” . Il secondo meccanismo è definire una  class union :

1   s e t C l a s s U n i o n ( " u n i o n e " , c ( " c l a s s e 1 " , " c l a s s e 2 " ) )

In questo modo viene creata la classe   unione, la quale non ha attributima risulta essere madre di  classe1 e  classe2. La classe  unione potrà quindiessere specificata come tipo di un attributo, in modo da permettere che sianoconformi a quell’attributo oggetti di una qualsiasi sua classe figlia; notiamoche il meccanismo di ereditarietà in questo caso è invertito: si specifica quali

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 17/66

CAPITOLO 2. PROGRAMMAZIONE AD OGGETTI    14

classi possono ereditare dalla class union, anziché dire di ogni classe figlia che

la class union è loro madre.Si possono infine definire classi   virtuali , che esattamente come in C++

non possono venire istanziate pur essendo possibile ereditare da esse; il loroscopo è quello di fornire uno scheletro comune valido per molte classi cheperò non hanno alcuna funzione se non vengono specializzate.

1   s e t C l a s s ( " v i r t u a l e " , r e p r e s e n t a t i o n ( x = " n u m e r i c " ) ,

2   c o n t a i n s = " V I R T U A L " )

Come nel caso della class union, una classe virtuale può essere specificatacome tipo di un attributo.

2.3 Metodi S4

Un metodo in stile S4 viene creato attraverso la seguente definizione:

1   s e t M e t h o d ( " f u n c t i o n _ n a m e " , s i g n a t u r e ( x = " t y p e 1 " , y = " t y p e 2 " ) ,

d e f i n i t i o n )

dove  function_name  è il nome della funzione che si vuole creare o di cuisi vuole effettuare l’overloading,  signature definisce le classi degli argomentiche provocano la chiamata di questa versione della funzione, mentre al postodi  definition va inserito il corpo della funzione da eseguire se gli argomenti

passati corrispondono alle classi indicate nella signature. Quando viene chia-mata,   setMethod   inserisce il metodo in una tabella di funzioni, pronto peressere selezionato nel caso in cui i tipi degli argomenti passati coincidano coni tipi previsti dalla definizione del metodo.

Vediamo un esempio in cui si vuole creare nuovi metodi  plot  e  [[ per laclasse  cerchio, costituita da una struttura di due attributi numerici rappre-sentanti centro e raggio.

1   s e t C l a s s ( " c e r c h i o " , r e p r e s e n t a t i o n ( R = " n u m e r i c " , C = " n u m e r i c "

) )

2   s e t M e t h o d ( " p l o t " , s i g n a t u r e ( x = " c e r c h i o " , y = ’ m i s s i n g ’ ) ,

3   f u n c t i o n ( x , y , . . . ) {4   r < - s lo t ( x , " R " )

5   c en t < - s lo t ( x, " C ")

6   t < - s eq ( 0 , 2 * pi , b y = 0 . 0 1 )

7   p l o t ( c e n t [ 1 ] + r * c o s ( t ) , c e n t [ 2 ] + r * s i n ( t ) )

8   }

9   )

10

11   s e t Me t h od ( " [ [ " , s i g n at u r e ( x = " c e r c hi o " , i = " c h a ra c t er " , j = "

 m issin g " ) ,

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 18/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 19/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 20/66

CAPITOLO 2. PROGRAMMAZIONE AD OGGETTI    17

Poiché la funzione Arith prevede i due argomenti e1  ed  e2, che rappresen-

tano gli argomenti di un qualsiasi operatore binario del suo gruppo, l’overloa-ding di questa funzione accoppiata a un uso ragionevole di  callGeneric  (inquesto caso sui singoli attributi dei due oggetti  cerchio  ricevuti in ingresso)permette di generalizzare in una sola volta tutte le operazioni binarie allaclasse  cerchio.

I gruppi possono anche essere creati annidati fra loro, ma occorre fareattenzione alla gerarchia di selezione. Il method dispatch effettuato dallafunzione generica sceglie, con il seguente ordine di priorità:

1. un metodo con firma compatibile

2. un metodo compatibile per la group generic, se presente

3. un metodo compatibile per la group generic della group generic e cosìvia, se presenti

4. una metodo compatibile ereditato da una superclasse degli argomenti.La distanza da tali metodi e’ data dalla somma su tutti gli argomentidella lontananza della superclasse (distanza 1 per la madre, 2 per la “nonna”, ecc.)

2.4 Un trucco: programmazione ad oggetti conle closures

Come abbiamo visto, la programmazione ad oggetti in  R  comporta note-voli differenze rispetto a quella che si può effettuare ad esempio nel C++;in particolare, non esistono attributi privati, cosa che rende le classi pocopiù che semplici  struct, inoltre i metodi sono sostanzialmente degli overloa-ding, quindi anch’essi possono essere solo pubblici. In [5] è stata propostauna tecnica che è in grado di ovviare in parte a questi problemi e che si puòapplicare senza l’uso di pacchetti aggiuntivi; essa consiste in un uso intel-

ligente delle proprietà delle   closures , ovvero semplicemente le funzioni di   R, e dell’operatore di assegnamento non locale   <<-. Tale operatore cerca lavariabile da assegnare nell’environment in cui viene valutato l’assegnamento,e solo successivamente negli environment esterni; se non trova la variabile,la crea nell’environment globale. Vediamo un esempio in cui viene creatala “classe”   vector, la quale contiene gli attributi   V, un vettore, ed   M, la suamedia campionaria.

1   v e c t o r < - f u n c t i o n ( v ) {

2   m e an _ v e c t or < - f u n ct i o n ( ) {

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 21/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 22/66

CAPITOLO 2. PROGRAMMAZIONE AD OGGETTI    19

In particolare si può osservare che l’utilizzo delle funzioni interne permette di

modificare gli attributi della classe, cosa che non può avvenire utilizzando imetodi classici in quanto è contro la filosofia di  R  permettere che una funzionepossa modificare al suo interno un oggetto definito all’esterno di essa.

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 23/66

Capitolo 3

Interazioni con altri linguaggi

Con l’eventuale ausilio di alcune sue estensioni,  R  offre la possibilità di in-teragire con vari altri programmi e linguaggi di programmazione. Un esempiomolto semplice, per interagire con la shell UNIX, è la funzione  system:

1   > s ys te m ( " a= ’ u so l a s he ll ! ’ ; e ch o $ a " )

2   u s o l a s he ll !

Al di là delle possibilità offerte dai pacchetti aggiuntivi,   R   offre in mo-do naturale delle interfacce a funzioni scritte in C o Fortran, attraverso lefunzioni   .C,   .Fortran,   .Call   e   .External. L’uso di tali funzioni è esposto

nel paragrafo 3.1, mentre il paragrafo 3.2 fornisce alcuni cenni all’uso di Rall’interno di programmi C.

3.1 Richiamare funzioni in C/Fortran

Le 4 funzioni primitive che permettono di interagire con codici C e For-tran (e C++) offrono un’interfaccia superficialmente piuttosto simile, ma sidistinguono per alcuni aspetti fondamentali. In generale, ricevono come pri-mo argomento una stringa che denota il nome di una funzione C o Fortran, ecome argomenti opzionali (denotati da ...) tutti gli argomenti che si vogliono

passare a tale funzione. La funzione individuata dal primo argomento deveessere stata preventivamente caricata da uno shared object, che si può crearein modo molto semplice da terminale/prompt dei comandi con il comando

$ > R C MD S HL IB m yl ib . c

che crea la libreria dinamica mylib.so. Se tale libreria fa parte di un pacchet-to, essa viene caricata automaticamente al caricamento dello stesso, men-tre nel caso in cui la si voglia caricare manualmente si ricorre alla funzionedyn.load.

20

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 24/66

CAPITOLO 3. INTERAZIONI CON ALTRI LINGUAGGI    21

1   > d yn . l o a d ( " m y li b . s o " )

2   > m y f u n ( a r g1 , a r g2 , . . . ) {3   ...

4   .C(" myfunc" ,arg1, arg2 ,...)

5   ...

6   }

7   > d yn . u n l o ad ( " m y l i b . so " )

3.1.1 .C e .Fortran

Le funzioni primitive  .C e  .Fortran  forniscono interfacce a codici C/For-

tran in modo tale che all’interno di tali codici non sia necessario manipo-lare oggetti   SEXPREC. Questo viene fatto convertendo gli argomenti di   .C

o   .Fortran   dal secondo in avanti in variabili di tipi C/Fortran, secondo lecorrispondenze indicate in Tabella 3.1.

Tipo R Tipo C Tipo Fortran

logical int * INTEGER

integer int * INTEGER

double double * DOUBLE PRECISION

complex Rcomplex * DOUBLE COMPLEX

character char ** CHARACTER*255

raw char *   nessuno

Tabella 3.1: Conversioni effettuate da .C e  .Fortran

Gli argomenti che si possono passare a  .C  e  .Fortran sono quindi limitatiai soli tipi previsti nella prima colonna della Tabella 3.1.

Vediamo più nel dettaglio il funzionamento di queste funzioni attraversoun esempio, che presenta tre implementazioni per  R del crivello di Eratostene:la prima scritta interamente in codice  R, la seconda implementata attraverso

una funzione C incapsulata da un wrapper  R  e la terza implementata in modoanalogo ma con una funzione Fortran. La versione  R dell’algoritmo cui faremoriferimento è la seguente.

1   # C r iv el l o d i E r at o st e ne . R ic ev e u n i nt er o n c om e  

a rg om en to e t ro va t ut ti i n um er i p ri mi f in o a n .

2   s i e v e < - f u n ct i o n ( n ) {

3   s < - s eq (2 , n)

4   i f ( n < 4 ) {

5   } else {

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 25/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 26/66

CAPITOLO 3. INTERAZIONI CON ALTRI LINGUAGGI    23

1   #include <Rmath .h>

2   // s è la lista dei numeri da 2 a n  3   v oi d s ie ve _ c ( in t * n , i nt * s ) {

4   i nt t i me s ;

5   i f (* n < 4) { } e ls e {

6   f or ( i n t i = 2 ; i < = f l o or ( s q r t ( * n ) ) ; + + i ) {

7   i f ( s [ i - 2 ] ! = 0 ) {

8   t i m e s = 2 ;

9   w h il e ( i * t i me s < = * n ) {

10   s [ ( i * t i m e s ) - 2 ] = 0 ;

11   t i m e s + + ;

12   }

13   }14   }

15   }

16   }

1   C S è la lista dei numeri da 2 a N  

2   S U B RO U T IN E S I EV E _ F ( N , S )

3   I NT EG ER N , S (N ) , T IM ES , I

4   I F ( N . LT . 4) T HE N

5   G OT O 2 0

6   ELSE

7   D O 2 0 , I = 2 , F L OO R ( S Q RT ( F L O A T ( N ) ) )8   I F ( S ( I - 1) . N E . 0 ) T H EN

9   T I M E S = 2

10   10 IF ( I * TIMES . LE . N ) THEN

11   S(I* TIMES -1)=0

12   T I M E S = T I M E S + 1

13   G OT O 1 0

14   ELSE

15   ENDIF

16   ELSE

17   ENDIF

18   20 C ONT INUE19   ENDIF

20   END

Come possiamo notare, le due funzioni sono state scritte senza tener contodel fatto che sarebbero state successivamente utilizzate da  R. Nella versione Cè stato importato l’header file  Rmath.h per sfruttare le funzioni matematichedefinite nel sorgente di   R  (nello specifico la radice quadrata), ma ciò non èobbligatorio dato che tutte le variabili in gioco sono di tipi standard C.

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 27/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 28/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 29/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 30/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 31/66

CAPITOLO 3. INTERAZIONI CON ALTRI LINGUAGGI    28

6   p r i n t f ( " % s " , " \ n " ) ;

7   r e tu r n 0 ;8   }

All’interno del  main  troviamo il   SEXP res che ospita il risultato ottenutodall’esecuzione dello script   esempi_locpoly.r. Le righe che seguono l’as-segnamento di   res   sono semplicemente strumentali alla visualizzazione delrisultato, che richiede l’estrazione del valore numerico ottenuto attraverso lamacro  REAL.

Per compilare ed eseguire questo programma è opportuno definire preli-minarmente, da prompt dei comandi o shell (come nell’esempio), la variabiled’ambiente

$ > R _ H O M E _ D I R = " / L i b r a r y / F r a m e w o r k s / R . f r a m e w o r k / R e s o u r c e s "

$ > e x po r t R _ H OM E _ DI R

Il file main.c va naturalmente compilato linkando le opportune librerie di R,nel modo seguente:

$ > c c - I $ R _ H OM E _ D IR / i n c l u d e / - L $ R _ HO M E _ DI R / l i b / - l R m a in .

c - o m y Cp r og r am . o u t

Al momento dell’esecuzione la variabile   R_HOME_DIR   diventa essenziale, inquanto l’attuale processo deve conoscere la home directory di R per poterlolanciare quando richiesto.

$ > . / m y C p ro g r am . o u t

K e r nS m o ot h 2 . 23 l o ad e d

C op y ri gh t M . P . W an d 1 99 7 - 20 09

-5.312348

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 32/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 33/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 34/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 35/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 36/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 37/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 38/66

CAPITOLO 4. CALCOLO PARALLELO IN R    35

1   # i n cl u d e < m pi . h >

2   # i n c l u de < R . h >

La funzione  mpi_send  contenuta nel file  Rmpi.c è la seguente:

1   S E XP m p i _s e n d ( S EX P s e xp _ da t a , S E XP s e xp _ ty p e , S E XP

s e xp _ de s t , S E XP s e xp _ ta g , S E XP s e x p_ c o mm ) {

2   i nt s le n , le n = L E N GT H ( s e x p _ da t a ) , t y pe = I N T E G ER (

s e x p _ t y p e ) [ 0 ] , d e st = I N T E G E R ( s e x p _ d e s t ) [ 0 ] ;

3   i nt c o mm n = I N T E GE R ( s e x p _ co m m ) [ 0] , t a g = I N TE G E R ( s e x p_ t a g )

[0];

4   s w it c h ( t y pe ) {

5   c a se 1 : m p i _ er r h a nd l e r ( M P I _ Se n d ( I N T E GE R ( s e x p _ da t a ) ,

l en , M PI _ IN T , d es t , t ag , c o mm [ c o m m n ] ) ) ;6   b r e a k ;

7   c a se 2 : m p i _ er r h a nd l e r ( M P I _ Se n d ( R E AL ( s e x p _ d at a ) ,

l en , M P I_ D OU B LE , d es t , t ag , c o mm [ c o m m n ] ) ) ;

8   b r e a k ;

9   c a s e 3 : s l e n = L E N G T H ( S T R I N G _ E L T ( s e x p _d a t a , 0 ) ) ;

10   M P I _ S e n d ( C H A R 2 ( S T R I N G _ E L T ( s e x p _d a t a , 0 ) ) , s l en ,

M P I_ C HA R , d es t , t ag , c o mm [ c o m m n ] ) ;

11   b r e a k ;

12   c a se 4 : M P I _S e n d ( R AW ( s e x p _ d at a ) , l en , MP I _B Y TE ,

d es t , t ag , c o mm [ c o m m n ] ) ;

13   b r e a k ;14   d e f a u l t : P R O T E C T ( s e x p _ d a t a = A S _ N U M E R I C ( s e x p _ d a t a ) ) ;

15   m p i _ er r h an d l e r ( M P I _S e n d ( R EA L ( s e x p _d a t a ) , 1 ,

d a t at y p e [ 0] , d es t , t ag , c o mm [ c o m m n ] ) ) ;

16   U N P R O T E C T ( 1 ) ;

17   b r e a k ;

18   }

19   r e tu r n R _ N il V a lu e ;

20   }

All’interno di questa funzione viene effettuato uno   switch   sui diversi tipi

di dati che possono essere passati come argomento alla funzione. Nel casoper esempio in cui il dato inviato sia un intero, alla riga 5, viene effettuatoun  cast  a intero del dato di tipo   SEXP; il dato così convertito viene passatocome argomento delle funzione C   MPI_Send, contenuta nella libreria   mpi. Idati di tipi diversi vengono trattati in modo analogo. Anche la funzione

 mpi.send.Robj richiama la funzione C  mpi.send:

1   m p i . s e n d . R o b j < - f u n c t i o n ( o b j , d e s t , t a g , c o m m = 1 ) { m p i . s e n d ( x

= . m pi . s e r i a l iz e ( o b j ) , t y pe = 4 , d e st = d e st , t ag = t ag , c o mm

= c o m m ) }

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 39/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 40/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 41/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 42/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 43/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 44/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 45/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 46/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 47/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 48/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 49/66

CAPITOLO 4. CALCOLO PARALLELO IN R    46

a discostarsi leggermente dall’andamento teorico. L’andamento reale con 16

sottoprocessi risulta invece essere molto distante dall’andamento teorico inquanto non migliora le prestazioni ottenute con 8 sottoprocessi.

Task-Push

I risultati ottenuti utilizzando il metodo   Task-Push , con un numero ditask   pari a   2N   e  N  pari al numero di sottoprocessi, sono rappresentati inFigura 4.3 e 4.4. Si può notare già in Figura 4.3a che nel caso si usinosolo 2 sottoprocessi   slave   l’algoritmo parallelo non risulta essere efficienterispetto all’algoritmo sequenziale classico. Anche osservando l’andamento inscala logaritmica in Figura 4.3b, si nota che l’utilizzo di 2 sottoprocessi nonporta ad un miglioramento rispetto all’utilizzo dell’algoritmo sequenziale. LaFigura 4.4 mostra il confronto tra il tempo effettivo impiegato ad eseguirel’algoritmo delle k-medie in parallelo con un numero diverso di sottoprocessie il tempo impiegato ad eseguire l’algoritmo delle k-medie classico, a paritàdi dimensione dei dati. Si può notare che in nessun caso l’andamento realerisulta essere confrontabile con l’andamento teorico. Questo algoritmo, cherappresenta un passo intermedio tra gli algoritmi   Brute-Force   e  Task-pull , èutile per capire lo scambio di informazioni tra sottoprocessi ma risulta esserepoco efficiente.

(a) Tempi di esecuzione (b) Tempi di esecuzione in scalalogaritmica

Figura 4.3: Tempi di esecuzione del metodo Task-Push per l’algoritmodelle k-medie con 2, 4, 8 e 16 sottoprocessi   slave 

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 50/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 51/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 52/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 53/66

CAPITOLO 4. CALCOLO PARALLELO IN R    50

4.2   snow

Un altro pacchetto R che permette di implementare algoritmi paralleli in R

è  snow [8]. Questo pacchetto è basato su diversi protocolli di comunicazione,tra cui MPI, PVM, SOCK e NWS. Anche in questo caso viene creata unacomunicazione di tipo master-slave  tra sottoprocessi all’interno di un sistemaa memoria distribuita.

4.2.1 Principali funzioni di   snow

La libreria  snow viene caricata per mezzo del comando

1   l i b r a r y ( " s n o w " )

Una volta caricata la libreria è possibile creare un cluster   di  N  sottoprocessiper mezzo dell’istruzione

1   c l < - m a ke C l u st e r ( N , t y pe = g e t C l u s t er O p t io n ( " t y p e " ) , . . .)

La funzione   makeCluster  ha un argomento   type   che permette di specifica-re quale tipo di protocollo di comunicazione usare. Esistono inoltre dellevarianti di   makeCluster  specifiche per i diversi protocolli:   makeMPIcluster,

 makePVMcluster,  makeSOCKcluster e  makeNWScluster.Per chiudere i sottoprocessi creati precedentemente e appartenenti al

cluster   cl si utilizza il comando:1   s t o p C l u s t e r ( c l )

4.2.2 Invio/ricezione di dati ed esecuzione di funzioni

Le funzioni definite nel pacchetto  snow non permettono di scrivere codiciflessibili come quelli basati sul pacchetto  Rmpi. Sono implementate nel pac-chetto solo poche funzioni e tali funzioni risultano essere molto efficienti [6].La prima di queste funzioni è  clusterSplit:

1   c l u st e r S pl i t ( cl , s eq )

Tale funzione permette di dividere (in parti uguali) una sequenza   seq  tra isottoprocessi appartenenti al  cluster   cl. Il risultato di tale funzione vienesalvato all’interno di una lista di dimensione pari al numero di sottoprocessiappartenenti al cluster   cl.

Le funzioni implementate nel pacchetto al fine di eseguire una funzioneall’interno dei sottoprocessi sono 2:   clusterCall  e  clusterApply. La primadi queste funzioni ha i seguenti argomenti:

1   clusterCall (cl, fun ,...)

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 54/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 55/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 56/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 57/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 58/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 59/66

APPENDICE A. CODICI CALCOLO PARALLELO    56

23   # F in ch é n on s i r ic ev e u na t ag = 2 ( ch e i nd ic a c he t ut ti

i o t as k s on o s ta ti e ff et tu at i ) s i e se gu e il t as k  24   w hi le (tag != 2) {

25   # E se gu o i l t as k  

26   f o l dN u m be r < - t a sk $ f o l d N u mb e r

27   n i = s u m ( f o l d = = f o l d N u m b e r )

28   p = d i m ( M k ) [ 2 ]

29   K = d i m ( M k ) [ 1 ]

30   c l u s t e r = d o u b l e ( n i )

31   d i s t a n z a = d o u b l e ( K )

32   # c al co lo d el la d is ta nz a t ra i d at i e i me do id i

33   f or ( i i n 1 : ni ) {

34   f or ( k i n 1 : K) {35   d i s t a n z a [ k ] = d i s t a n z a E ( d a t i [ f o l d = = f o l d N u m b e r

, ] [ i ,] , M k [ k , ])

36   }

37   # a s s e g na z i on e d el c l u st e r  

38   c l u s t e r [ i ] = w h i c h . m i n ( d i s t a n z a )

39   }

40   # c a lc ol o d el le m ed ie p er i d at i r e la t iv i a l

s o t t o p r o c e s s o

41   f or ( k i n 1 : K) {

42   M k [ k , ] = m e a n ( d a t i [ f o l d = = f o l d Nu m b e r , ] [ c l u s t e r = = k

,])43   }

44   # C o st r ui s co e i nv io i r i su l ta t i

45   r e s u l t < - l i s t ( r e s u l t = M k , C = c l u s t er , f o l d N u m b e r =

f o l d N u m b e r )

46   mpi.send .Robj (result ,0,1)

47   # R ic ev o u n n uo vo t as k  

48   t a sk < - m pi . r e c v . R o bj ( m p i . a n y . s ou r c e ( ) , mp i . a ny . t a g

() )

49   t a sk _ i n f o < - m pi . g e t . s o u r ce t a g ( )

50   t ag < - t as k _ i nf o [ 2]

51   }52   # C o nc l us i t ut ti i t as k  

53   # I n vi o il m e ss a gg i o : c on c lu s i t ut ti i t as k  

54   ju nk <- 0

55   mpi. send. Robj(junk ,0,2)

56   }

57

58   # a s s eg n az i on e d ei d at i a i d iv e rs i t as k  

59   N T A S K S = 4

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 60/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 61/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 62/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 63/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 64/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 65/66

7/26/2019 ProgrammazioneAvanzataInR

http://slidepdf.com/reader/full/programmazioneavanzatainr 66/66