diff --git a/AppFortran.tex b/AppFortran.tex new file mode 100644 index 0000000..b7222ab --- /dev/null +++ b/AppFortran.tex @@ -0,0 +1,87 @@ +\chapter{Il fortran 95} +Il linguaggio di programmazione usato per implementare gli algoritmi è stato il FORTRAN, una +``minor revision''\footnote{non ho mai capito come si traduca veramente in italiano la parola +revision -- ogni suggerimento è bene accetto} del FORTRAN 90. \\ +Rispetto all versioni precedenti ci sono delle interessanti novità, per cui se state pensando +``Oddio, il FORTRAN nel 2009, non ci posso credere'' prima leggete il seguito\footnote{Ebbene sì, +è quello che ho pensato io, ma poi mi sono resoconto che il linguaggio aveva fatto dei progressi +dagli anni sessanta a questa parte}; è l'elenco delle cose che non mi aspettavo +\begin{enumerate}[(a)] + \item Allocazione dinamica della memoria; + \item Creazione di tipi astratti e overloading degli operatori; + \item Programmazione ad oggetti e polimorfismo (solo Fortran 2003/2008); +\end{enumerate} + +In ogni caso, in queste note includerò alcune righe su come si scrivono le prime righe di codice +in fortran. In codice Fortran saranno infatti riportati tutti gli esempi nella parte di esercitazione. + +\section{La sintassi} +\subsection{Hello World!} +Per una convenzione che di cui non so l'origine non è posibbile cominciare da qualcosa di diverso del +programma Hello World! Noi non saremo da meno. Cominceremo a guardare il codice e a commentarlo +passo passo.. + +\begin{lstlisting}[frame=tb,caption=Hello World,label=lst:helloworld] + PROGRAM helloworld + IMPLICIT NONE + WRITE(*,*) 'Hello World' + END PROGRAM +\end{lstlisting} + +Tutte le righe precedute da \lstinline-!- sono dei commenti e quindi vengono scartate +dal compilatore. Ad esempio '\lstinline-a = 1 ! Inizializzazione-' è equivalente a +'\lstinline-a = 1-'. + +L'istruzione \lstinline-PROGRAM helloworld- spiega al compilatore che questo è l'inizio del +nostro programma e che si chiamerà helloworld. Si aspetta di trovare alla fine un +\lstinline-END PROGRAM- che noi abbiamo prontamente inserito. + +L'istruzione \lstinline-IMPLICIT NONE- serve invece a disattivare delle convenzione che si +usavano nelle prime versione del fortran (e che esistono ancora per retrocompatibilità) +che stabiliscono che le variabili \lstinline-i,j,k- sono di tipo intero, mentre ad esempio +\lstinline-x,y,z- sono reali. Questo non è desiderabile in un linguaggio di programmazione +moderno in cui ci si aspetta di scrivere del codice comprensibile. + +Infine l'istruzione \lstinline-WRITE(*,*)- scrive sull stdout\footnote{che, nelle maggior parte +dei casi, coincide con il monitor} tutti gli argomenti che gli si passano dopo. \`E possibile +controllare la formattazione di quello che viene stampato ma, come è simboleggiato dagli asterischi, +per ora non ce ne stiamo preoccupando. + +\subsection{La struttura} +Un programma in FORTRAN ha una struttura prefissata: +\begin{lstlisting}[label=lst:fotranstruct,frame=tb] + PROGRAM nomeprogramma + IMPLICIT NONE + ! Specificazioni: in questa parte si trova la dichiarazione + ! delle variabili e dei nuovi tipi + + ! Parte di esecuzione: qui troviamo il codice vero e proprio che + ! viene eseguito + + ! Subroutine: qui troviamo la definizione dei sottoprogrammi che + ! possono venire chiamati dalla parte di esecuzione + END PROGRAM +\end{lstlisting} +\subsection{I tipi} +Come il C e tutti i linguaggi che vantano una certa storia il FORTRAN è un linguaggio tipato, +ovvero ogni variabile ha un tipo (ad esempio intero) e non gli si possono assegnare valori +di tipi differenti. \\ +Si possono aggiungere delle parole chiave alle dichiarazioni di tipi, più precisamente +\begin{itemize} + \item \lstinline-PARAMETER-: questa indica che la variabile non verrà modificata, è semplicemente + un parametro per il programma. +\end{itemize} +I tipi principali presenti in Fortran sono +\begin{itemize} + \item \textbf{Interi}: Sono denotati dalla parola chiave \lstinline-INTEGER- e sono appunto numeri + interi. Generalemente occupano $4$ byte. + \item \textbf{Reali}: Numeri reali, che vengono memorizzati come floating point. La parola chiave + è \lstinline-REAL- e occupano generalmente $4$ byte. Per i nostri scopi questi sono pochi, e quindi + useremo in generale il seguente trucchetto: + \begin{lstlisting}[frame=tb] + INTEGER, PARAMETER :: db = KIND(0.D0) + REAL(dp) :: real_var + \end{lstlisting} + +\end{itemize} + \ No newline at end of file diff --git a/CalcoloScientifico.tex b/CalcoloScientifico.tex index 5b13d6d..28cc913 100644 --- a/CalcoloScientifico.tex +++ b/CalcoloScientifico.tex @@ -122,6 +122,9 @@ %% \newcommand{\PhC}{\makebox[0.45\width]{P}\raisebox{-0.35ex}{H}\makebox[0.58\width]{C}\makebox[0.5\width]{ }} +%% Fotran +\newcommand{\fort}[1]{\textt{FORTRAN #1}} + %% Codice fortran \definecolor{listinggray}{gray}{0.95} \lstset{language=fortran} @@ -244,4 +247,10 @@ %% Page rank \include{AppPageRank} +\part{Appendice} + +\appendix + +\include{AppFortran} + \end{document} diff --git a/capitolo2.tex b/capitolo2.tex index db11130..1f5c5d6 100644 --- a/capitolo2.tex +++ b/capitolo2.tex @@ -306,9 +306,9 @@ date le considerazioni sulla complessità fatte in precedenza. Il caso di una matrice complessa viene gestito esattamente con lo shifting di $-\alpha_{nn}^{(k)}I$ come descritto sopra, e si verifica che le cose funzionano bene. Più complesso, invece, è il caso di una matrice reale. -In quel caso infatti gli autovalori possono essere complessi coniugati e non si desidera passare da aritmetica -reale ad aritmetica complessa. Questo porterebbe a problemi di complessità, ma principalmente farebbe -perdere la simmetria\footnote{Per simmetria si intende la certezza di ottenere autovalori complessi coniugati, +In quella situazione infatti gli autovalori possono essere complessi coniugati e non si desidera passare da aritmetica +reale ad aritmetica complessa. Questo porterebbe a problemi di complessità, ma il danno più grave sarebbe +perdere la simmetria\footnote{Per simmetria intendiamo la certezza di ottenere autovalori complessi coniugati, cosa di cui non si potrebbe essere certi con una matrice complessa qualsiasi. } della matrice, e quindi in definitiva parecchia informazione sul problema. \begin{os} @@ -326,25 +326,25 @@ Per determinare come eseguire lo shifting nel caso reale conviene cambiare punto ad ora. Possiamo osservare che se poniamo $p_k(z) = z - \alpha_k$ di fatto lo shifting è equivalente a considerare la matrice $\hat A_k = p(A_k)$. Dato che riteniamo che $\alpha_k$ sia una buona approssimazione dell'autovalore cercato della matrice per analogia nel caso reale possiamo utilizzare $p_k(x) = (x - \lambda)(x - \con{\lambda})$ -che è un polinomio reale. Si verifica (e, ancora una volta, noi non lo faremo) che le cose continuano a funzionare +che è un polinomio reale. Si verifica (e, ancora una volta, noi non lo faremo) che tutto continua a funzionare bene ma sorgono dei problemi di complessità. \\ Il polinomio $p_k$ è infatti adesso di II grado e non è per nulla banale, in generale, calcolare $A_k^2$. Inoltre $p_k(A_k)$ non è neppure una matrice in forma di Hessenberg, il che sembrerebbe farci perdere tutti i vantaggi computazionali che avevamo fino a questo momento. Per fortuna esiste una tecnica che, modificando l'iterazione, riesce a riolvere questo problema. -\subsection{La tecnica del Bulge Chasing\protect\footnote{bulge chasing in inglese significa inseguimento -del bernoccolo, e s riesce ad apprezzare il senso del nome osservando come questa tecnica si traduce graficamente sugli elementi -non zero della matrice. Questi si comportano infatti come un bernoccolo che scende sempre di più sulla -sottodiagonale per poi sparire lasciando una matrice in forma di Hessenberg superiore.}} +\subsection{La tecnica del Bulge Chasing} Nell'applicazione della tecnica dello shifting vista nel paragrafo precedente, abbiamo supposto di calcolare $p_k(A_k)$ e dopo calcolare la fattorizzazione QR. Ci siamo però accorto che se $p_k$ è -un polinomio di secondo grado vengono persi tutti i vantaggi computazionali dati dalla forma di Hessengerg. -Vogliamo quindi ora calcolare la fattorizzazione QR \textbf{mentre} calcoliamo $p_k(A_k)$ in modo da -rendere la risultante matrice in forma di Hessenberg e dimnuire la complessità del calcolo del polinomio. +un polinomio di secondo grado vengono persi tutti i vantaggi computazionali dati dalla forma di Hessenberg. +Vogliamo quindi ora modificare la fattorizzazione QR \textbf{mentre} calcoliamo $p_k(A_k)$ in modo da +rendere la risultante matrice in forma di Hessenberg e diminuire la complessità del calcolo del polinomio. La fattorizzazione QR ottenuta sarà ``essenzialmente uguale''\footnote{ovvero sarà uguale a meno di una matrice di fase reale} a quella che avremmo ottenuto seguendo -il procedimento precedente. +il procedimento precedente; questo modo di operare è detto \emph{Bulge Chasing}\footnote{bulge chasing in inglese significa inseguimento +del bernoccolo, e s riesce ad apprezzare il senso del nome osservando come questa tecnica si traduce graficamente sugli elementi +non zero della matrice. Questi si comportano infatti come un bernoccolo che scende sempre di più sulla +sottodiagonale per poi sparire lasciando una matrice in forma di Hessenberg superiore.}. Possiamo cominciare a calcolare solo la prima colonna della matrice $p_k(A_k)$, ovvero $p_k(A_k)e_1$. Una volta calcolata questa possiamo calcolare anche una matrice di Householder $P_0$ tale che