In questo capitolo si illustreranno le modalità di utilizzo dei sorgenti allegati; verranno descritte le routine principali in Fortran e C, e verranno mostrati alcuni esempi di compilazione dei programmi.
Nella scelta dei nomi da dare alle routine sviluppate, si è scelto di seguire lo schema già usato da Fortran e LAPACK:
- s:
- numeri reali in singola precisione;
- d:
- numeri reali in doppia precisione;
- c:
- numeri complessi in singola precisione;
- z:
- numeri complessi in doppia precisione.
Si può quindi generalizzare lo schema dei nomi in questo modo:
Come accennato in precedenza, il metodo di Wassing non richiede la memorizzazione esplicita della matrice. Risulta dunque necessario stabilire un formato standard per le funzioni che restituiscono gli elementi della matrice dei coefficienti del sistema lineare in esame.
Si tenga presente che la matrice è intesa essere AT. Le funzioni, perciò, dovranno essere tali che f(i,j) ≡ aji, cioè richiedendo l’elemento (i,j) all’interno delle librerie per il metodo di Wassing, questo deve essere l’elemento (j,i) della matrice dei coefficienti del sistema lineare Ax=b. In seguito, si farà sempre riferimento ad AT: l’elemento aij è l’elemento (i,j) di AT, e dunque l’elemento (j,i) di A.
Il formato che deve essere rispettato da queste funzioni, è il seguente:
<tipo> <nome>(int i, int j, int n)
dove
<tipo> | è il tipo di dato opportuno |
<nome> | è il nome scelto per la funzione |
i | è la riga dell’elemento |
j | è la colonna dell’elemento |
n | è la dimensione della matrice |
Le routine di risoluzione dispongono di un parametro, attraverso il quale viene indicato il <nome> della funzione da utilizzare per ottenere gli elementi della matrice dei coefficienti: in questo modo le routine sono più flessibili in quanto consentono di utilizzare un nome arbitrario per queste funzioni.
Le routine Fortran restituiscono, in un parametro, il risultato dell’applicazione del metodo, come avviene nelle routine LAPACK; poi, a seconda che si utilizzi la versione con pivoting o meno, il numero ed il tipo dei parametri da passare cambia, come descritto di seguito:
@percentf_wasv_tab.tex
@percentf_wapvtsv_tab.tex
Nell’implementazione in C, le routine sono delle funzioni, il cui valore di ritorno indica se la risoluzione ha avuto successo o meno, in maniera simile a valid o ip(n+1) visto in precedenza per le routine Fortran.
@percentc_wasv_tab.tex
@percentc_wapvtsv_tab.tex
Di seguito, verrà mostrato come utilizzare i codici implementati, facendo uso di semplici esempi di compilazione.
Per poter compilare il sorgente Fortran è necessario dichiarare, all’interno del programma principale, tutti i vettori di cui farà uso la routine di risoluzione. Definite, dunque, le strutture dati opportune, si devono anche dichiarare le funzioni per gli elementi della matrice dei coefficienti A e della matrice dei termini noti B; dopo aver costruito il vettore b, è infine possibile richiamare la routine di risoluzione.
Si consideri un codice di esempio:
Program sxolve Implicit None Integer n, nz, nb, i, j, k, valid Parameter (n=10) Parameter (nz=(n*n)/4) Parameter (nb=1) Real z(nz), c(n), b(n*nb) Real sgetb, sgetk External sgetb, sgetk do i=1,n k=nb*(i-1) do j=1,nb b(k+j)=-sgetb(i,n) enddo enddo call swasv(n,b,nb,z,nz,c,sgetk,valid) if (valid.ne.0) then print *, 'Minore principale di ordine ',valid,' nullo' endif end
Se il programma precedente viene chiamato sxolve.f, allora per compilarlo si utilizza la seguente linea di comando:
g77 -O3 -o <output> sxolve.f swasv.f sgetk.f sgetb.f
dove con <output> si è indicato il nome del file eseguibile risultato della compilazione. Sono state attivate anche le opzioni di ottimizzazione -O3 che, come detto, consentono di ottenere eseguibili più performanti.
Nel caso il programma principale e le altre routine non si trovino tutti nella stessa directory, si dovrà precisare, oltre al nome del file, anche il percorso per raggiungerlo.
Per la compilazione del codice C le cose sono leggermente differenti da quanto visto in precedenza: per poter chiamare una funzione, è necessario dichiararne l’intestazione, che è composta dal tipo di ritorno, dal nome della funzione e dalla lista dei parametri con il rispettivo tipo. Per facilitare la fase di dichiarazione delle funzioni, è stato utilizzato il file wassing.h che contiene tutte le intestazioni delle funzioni utilizzate: esso deve essere incluso tramite la direttiva del preprocessore #include wassing.h all’interno del proprio codice sorgente. Dopo aver costruito il vettore dei termini noti b, è possibile richiamare la routine di risoluzione.
Si consideri il file sorgente che segue:
#include <stdio.h> #include <stdlib.h> #include "wassing.h" #define dim 10 #define nbb 1 int main() { float *b; int res, i, j; b=(float *) calloc(dim*nbb, sizeof(float)); if (b==NULL) { fprintf(stderr, "%s: Impossibile allocare la memoria necessaria\n", __FILE__); exit(1); } for (i=0; i<dim; i++) { for(j=0; j<nbb; j++) { b[nbb*i+j]=-sgetb(i+1,dim); } } res=swasv(dim, b, nbb, sgetk); if(res!=0) { printf("Minore principale di ordine %d nullo\n", res); } free(b); return 0; }
che si suppone chiamato sxolve.c. Per compilarlo, si deve eseguire questa riga di compilazione:
gcc -O3 -o <output> sxolve.c swasv.c sgetk.c sgetb.c -lm
Come detto, il C non dispone dell’aritmetica dei numeri complessi: a questo proposito sono state definite delle macro del preprocessore, riunite nel file ccomplex.h, che deve essere incluso in maniera simile a wassing.h all’interno del codice che fa uso delle routine per i numeri complessi. Inoltre, deve anche essere indicato, sulla riga di compilazione, il file ccomplex.c: dunque, la riga di compilazione da eseguire sarà simile alla seguente (i nomi dei file iniziano con c, ad indicare l’utilizzo di numeri complessi in singola precisione, ed il programma principale è chiamato cxolve.c):
gcc -O3 -o <output> cxolve.c cwasv.c cgetk.c cgetb.c → → ccomplex.c -lm
È inoltre presente un file di intestazioni per le routine LAPACK, chiamato lapack.h, da usare come descritto in precedenza.
È necessario anche utilizzare il parametro di linking -lm, che include nel programma le funzioni matematiche della libreria C math.h, in quanto sia wassing.h che ccomplex.h le richiedono.
Anche in questo caso, è consigliabile attivare le ottimizzazioni.