Introduzione all`uso di Mathematica

Transcript

Introduzione all`uso di Mathematica
Introduzione all’uso di Mathematica c
Antonio Leaci
24 marzo 2012
Dipartimento di Matematica e Fisica “Ennio De Giorgi”
In questo file è inclusa una vecchia e breve introduzione a Mathematica 5 che non è stata modificata.
Nel frattempo, oltre ad essere cambiata la denominazione del Dipartimento di cui faccio parte, è stata
rilasciata la versione Mathematica 8.
Oltre a questa pagina iniziale, ho aggiunto una brevissima appendice su alcune funzionalità introdotte
con Mathematica 8
Università del Salento
Introduzione a Mathematica
Antonio Leaci
Dipartimento di Matematica “Ennio De Giorgi”
N.B. Questo file è stato generato “quasi” automaticamente da Mathematica a partire da un notebook (estensione
.nb, in parte presente su questa pagina) ed elaborato con LATEX. Per leggere e modificare un notebook bisogna
utilizzare Mathematica oppure il Wolfram CDF Player scaricabile gratuitamente dal sito Wolfram.com . Invece
questo file .pdf si legge facilmente con Acrobat Reader. Potrebbero esserci delle incongruenze dovute a questi
passaggi intermedi.
Questa introduzione è suddivisa in capitoli. Per aprire (o chiudere) ciascun capitolo (nel notebook) fare doppioclick sulla parentesi quadra azzurra all’estrema destra con freccetta. Le parentesi azzurre individuano le celle che
contengono testo oppure comandi oppure output.
1. Osservazioni preliminari.
Queste brevi note rappresentano una introduzione molto sintetica all’uso del programma Mathematica. Lo scopo
principale è di utilizzarlo come supporto allo studio di argomenti di matematica (analisi matematica, geometria,
algebra lineare, probabilità e statistica, cenni di calcolo numerico, ecc.). Naturalmente questo non può sostituire lo
studio teorico degli argomenti di matematica. Per fare un esempio concreto, il problema della ricerca del massimo
o del minimo di una funzione di una o più variabili, non può prescindere dalla conoscenza e comprensione del
Teorema di Weierstrass e delle sue estensioni, che sotto opportune ipotesi garantisce l’esistenza del massimo e del
minimo di una funzione. Il programma Mathematica ci può solo aiutare ad individuare i candidati ad essere punti
di massimo o di minimo.
Naturalmente sono disponibili molte risorse per imparare ad utilizzare il programma. Oltre a numerosi libri e articoli disponibili su Internet (in particolare sul sito della Casa produttrice www.wolfram.com), la principale risorsa,
che consiglio vivamente di utilizzare, è l’ottimo help in linea, che si può consultare premendo il tasto F1 o dal
menù a tendina Help.
1
In esso è interamente contenuto il libro The Mathematica Book di S.Wolfram, all’interno del quale si può efficacemente navigare in base all’argomento a cui si è interessati. La sua lettura non è comunque particolarmente agevole,
almeno per i principianti. Meglio all’inizio limitarsi a consultare la parte A Practical Introduction to Mathematica.
Molto più utili sono il Tour e le Demos da cui si possono apprendere interattivamente molti esempi di uso di Mathematica. Inoltre è estremamente efficace l’elenco delle funzioni disponibili (Built-in) e dei Package di estensione
(Adds-on), che sono organizzate per argomenti, e forniscono il nome e la descrizione dei comandi, con numerosi
esempi di utilizzo, che possono essere “riciclati” per affrontare il problema in esame.
Il programma Mathematica è sostanzialmente un linguaggio di programmazione finalizzato alla manipolazione di
espressioni, ma non entrerò nella discussione approfondita delle procedure di programmazione. Mi limiterò a segnalare il minimo indispensabile di concetti di programmazione e mi soffermerò sull’uso dei comandi tipicamente
matematici.
Concludendo questo primo paragrafo, faccio notare che Mathematica “parla” in inglese, dunque i comandi e l’help
sono in inglese. In particolare i comandi Built-in sono costituiti generalmente da intere parole (eventualmente
composte) in inglese in cui ogni parola inizia con la lettera maiuscola e con gli argomenti delimitati da parentesi
quadre. Fanno eccezione, ad esempio, il determinante (che si ottiene con Det[]) oppure la derivata (che si ottiene
con D[]) oppure i nomi delle funzioni matematiche (Sin[], Cos[], Tan[], ArcTan[], Exp[], ecc.). Il programma
distingue tra lettere maiuscole e minuscole, quindi ad esempio una funzione sin[] non è definita (potrebbe essere definita dall’utente, ma creerebbe una discreta confusione). Si consiglia di definire funzioni e variabili usando
lettere minuscole, per evitare conflitti con eventuali funzioni o costanti predefinite, ad esempio con i numeri E,Pi,I)
2. Struttura del programma.
Il programma Mathematica nella versione per Windows si divide in due sottoprogrammi: il FrontEnd e il Kernel.
2
Con doppio-click sull’icona di Mathematica, appare una schermata come quella precedente, la finestra bianca è il
foglio in cui scrivere, mentre le due finestre sulla destra si chiamano palette e verranno illustrate in seguito.
Il FrontEnd è sostanzialmente un programma di elaborazione testi (ad esempio questa introduzione è scritta usando il FrontEnd, con l’opzione ottenuta dal menù a tendina Format/Style Sheet/Classroom) e serve a gestire l’Input/Output verso il Kernel (che è la parte del programma che effettivamente esegue i comandi). Per inserire le
parti di testo si sceglie il menù a tendina Format/Style/Text, mentre per immettere i comandi si sceglie il menù
Format/Style/Input.
Il FrontEnd permette di salvare i risultati ottenuti durante una sessione di lavoro in file detti Notebook, che hanno
estensione .nb. Si usa il menù File/Save As e si assegna un nome. Ad esempio il file che contiene queste note si
chiama Introduzione.nb.
Il Kernel è un manipolatore di espressioni ed esegue i comandi provenienti dal FrontEnd, producendo espressioni,
numeri, grafici, suoni, animazioni.
Prima osservazione importante: per inviare un comando al Kernel bisogna premere contemporaneamente Maiuscola+Invio.
Il solo tasto Invio serve solo per andare a capo nella scrittura del testo in un Notebook.
Schema di
Utente
funzionamento del programma
FrontEnd
Notebook.nb
Kernel
La figura precedente è stata ottenuta con i comandi che seguono, per il momento piuttosto misteriosi, che potete
tranquillamente ignorare. Notate solo che i grafici vengono creati uno per volta e assegnati ad una variabile. Poi
sono messi insieme con il comando Show[].
3
In[1]:= << Graphics‘Arrow‘
g1 = Graphics[{Circle[{0, 0.5}, 0.4], Text[¢¢ Utente¢¢ , {0, 0.5}],
Arrow[{0.6, 0.5}, {0.9, 0.5}, HeadScaling ® Relative]},
AspectRatio ® Automatic]
-Graphicsg2 = Graphics[{RGBColor[0.8, 0.8, 0.8], Rectangle[{1, 0.3}, {2, 1}],
RGBColor[0.8, 0.8, 0.8], Rectangle[{2.5, 0.3}, {3.7, 1}],
RGBColor[0.8, 0.8, 0.8], Rectangle[{1, -1}, {2, -0.3}], RGBColor[0, 0, 0],
Text[¢¢ FrontEnd¢¢ , {1.5, 0.6}], Text[¢¢ Notebook.nb¢¢ , {3.1, 0.6}],
Text[¢¢ Kernel¢¢ , {1.5, -0.6}],
Arrow[{2.1, 0.5}, {2.4, 0.5}, HeadScaling ® Relative],
Arrow[{1.3, 0.2}, {1.3, -0.2}, HeadScaling ® Relative],
Arrow[{1.6, -0.2}, {1.6, 0.2}, HeadScaling ® Relative]},
AspectRatio ® Automatic]
-GraphicsShow[g1, g2, PlotLabel ®¢¢ Schema di funzionamento del programma¢¢ ]
-Graphics-
3. Calcolo numerico e calcolo simbolico.
Il programma Mathematica (analogamente ad altri programmi simili come Derive o Maxima, quest’ultimo liberamente scaricabile da Internet) è un sistema integrato di calcolo simbolico, di grafica bidimensionale e tridimensionale, di manipolazione di espressioni e di dati.
Qual è la differenza con un tradizionale sistema di calcolo?
Un qualunque linguaggio di programmazione (C, C++, Java, Pascal, Fortran, ecc.) o programmi come il foglio
di calcolo Excel e il potente programma di calcolo numerico Matlab, forniscono come risultato del calcolo, ad
esempio, di 1/3 o di radice quadrata di 2 i numeri 0.33333333333333 oppure 1.41421356237310, o ancora come
valore di 280 il numero 1.208925819614629e+024, dunque un numero costituito al massimo da 16 cifre decimali
(la mantissa) e una potenza 10 p (la caratteristica) con un esponente p che varia generalmente tra -308 e 308. Numeri più grandi generano l’errore di Overflow. Inoltre i linguaggi di programmazione o i programmi di calcolo
numerico non consentono di effettuare calcoli letterali, ottenendo ad esempio come derivata dell’espressione xn
l’espressione n xn-1 .
Il programma Mathematica è pensato per lavorare con espressioni e non con numeri. Ecco alcuni esempi di calcoli
dal risultato molto differente da quelli ottenuti in precedenza. (Le celle con sfondo beige sono celle di input e da
esse, premendo Maiuscola+Invio, si invia un comando al Kernel. Le celle con sfondo rosa contengono l’output).
In[2]:= 1/3
1
Out[2]=
3
In[3]:= Sqrt[2]
0
Out[3]= 2
In[4]:= 2ˆ80
Out[4]= 1208925819614629174706176
In[5]:= 100!
Out[5]= 93326215443944152681699238856266700490715968264381621468592963895217599993229
91560894146397615651828625369792082722375825118521091686400000000000000000000
4
Osserviamo che il simbolo % si riferisce all’ultimo Output ottenuto e la funzione N[] fornisce un’approssimazione
numerica con un numero di cifre da scegliere. Ad esempio l’approssimazione di 100! con 20 cifre è
In[6]:= N[%, 20]
Out[6]= 9.332621544394415268 ´ 10157
4. Una premessa fondamentale: le parentesi.
In Mathematica esistono 4 tipi di parentesi, e ciascuna di esse svolge un ruolo ben preciso:
tonde ( ), graffe { }, doppie quadre [[ ]]. Non si può fare confusione sul loro uso.
parentesi quadre [ ],
1) Parentesi quadre.
Le abbiamo già usate in precedenza. Si ottengono premendo contemporaneamente AltGr+[ oppure AltGr+].
Servono esclusivamente per indicare l’argomento delle funzioni (già predefinite o definite da noi). Ad esempio
In[7]:= Exp[1 + Log[2]]
Out[7]= ã1+Log[2]
(notate che l’espressione non è stata semplificata)
In[8]:= Simplify[%]
Out[8]= 2ã
2) Parentesi tonde.
Le parentesi tonde servono per stabilire le precedenze nell’esecuzione di calcoli, e si possono annidare a piacere.
Ad esempio:
In[9]:= (1 + 3)ˆ2/3 + 1
19
Out[9]=
3
In[10]:= (1 + 3)ˆ(2/3) + 1
Out[10]= 1 + 2 21/3
In[11]:= (2 + Sqrt[2])/2 * 3
0
3
J2 + 2N
Out[11]=
2
In[12]:= (2 + Sqrt[2])/(2 3)
0
1
J2 + 2N
Out[12]=
6
Osserviamo che le usuali operazioni di addizione, moltiplicazione, divisione ed elevamento a potenza si ottengono
con + , * oppure uno spazio, / e ˆ . Come si è visto in precedenza, bisogna fare attenzione all’uso delle parentesi
tonde. Per esempio:
In[13]:= ((1 + x) * (1 - x) + 1)/(xˆ2 + 3) * (x + 7)
(7 + x) (1 + (1 - x) (1 + x))
Out[13]=
3 + x2
Naturalmente è utile assegnare un nome ad un’espressione calcolata. Per esempio assegniamo alla lettera f
l’espressione precedente:
In[14]:= f = %
(7 + x) (1 + (1 - x) (1 + x))
Out[14]=
3 + x2
5
Da ora in poi la lettera f contiene tale espressione.
In[15]:= f
(7 + x) (1 + (1 - x) (1 + x))
Out[15]=
3 + x2
Se ne può calcolare facilmente la derivata:
In[16]:= D[f, x]
2 x (7 + x) 2 x (7 + x) (1 + (1 - x) (1 + x)) 1 + (1 - x) (1 + x)
+
Out[16]= 2
3 + x2
3 + x2
(3 + x2 )
Per semplificare un’espressione basta dare il comando
In[17]:= Simplify[%]
-6 + 70 x + 11 x2 + x4
Out[17]= 2
(3 + x2 )
Per liberare la lettera f basta porre
In[18]:= f = .
Ora la lettera f indica solo se stessa
In[19]:= f
Out[19]= f
3) Parentesi graffe.
Le parentesi graffe servono per creare liste ordinate. Si ottengono premendo contemporaneamente Maiusc+AltGr+[
oppure Maiusc+AltGr+]. Assegniamo un nome ad una lista:
In[20]:= lista = {2, 5, 2, a, xˆ2}
Out[20]= {2, 5, 2, a, x2 }
In particolare i vettori sono liste e le matrici sono liste di liste.
Creiamo due vettori e una matrice:
In[21]:= v1 = {1, -1, -2, 3}
Out[21]= {1, -1, -2, 3}
In[22]:= v2 = {2, -1, 4, 3}
Out[22]= {2, -1, 4, 3}
In[23]:= m = {{1, 2, -3, 4}, {2, 1, 1, 5}}
Out[23]= {{1, 2, -3, 4}, {2, 1, 1, 5}}
Per visualizzare una matrice nella forma tradizionale basta dare il comando:
In[24]:= MatrixForm[m]
1 2 -3 4
Out[24]= K
O
2 1
1
5
oppure
In[25]:= m//MatrixForm
1 2 -3 4
Out[25]= K
O
2 1
1
5
Quest’ultima si chiama forma infissa del comando.
Si può calcolare il prodotto scalare tra vettori o il prodotto matrice per vettore usando l’operatore punto . .
6
In[26]:= v1.v2
Out[26]= 4
In[27]:= m.v1//MatrixForm
17
Out[27]= K
O
14
In[28]:= v1.m
Dot :: dotsh : Tensors {1, -1, -2, 3} and
{{1, 2, -3, 4}, {2, 1, 1, 5}} have incompatible shapes. More¼
Out[28]= {1, -1, -2, 3}.{{1, 2, -3, 4}, {2, 1, 1, 5}}
Notiamo che il programma,contrariamente alle usuali regole, ha moltiplicato tra loro due vettori riga, e una matrice
2x4 per un vettore riga 1x4, mentre la moltiplicazione a sinistra ha prodotto un messaggio di errore. All’occorrenza
dispone comunque del comando Transpose[].
In[29]:= v1.Transpose[m]
Out[29]= {17, 14}
In seguito torneremo brevemente sull’algebra lineare.
4) Doppie parentesi quadre.
Servono per estrarre gli elementi dalle liste. Ad esempio:
In[30]:= lista[[4]]
Out[30]= a
In[31]:= m[[1]][[3]]
Out[31]= -3
Abbiamo ottenuto l’elemento nella prima riga e terza colonna della matrice m . Estraiamo una sottomatrice 2 ´ 2:
In[32]:= m//MatrixForm
1 2 -3 4
O
2 1
1
5
Out[32]= K
In[33]:= {m[[1]][[{1, 2}]], m[[2]][[{1, 2}]]}
Out[33]= {{1, 2}, {2, 1}}
In[34]:= Det[%]
Out[34]= -3
Diamo un nome alla sottomatrice 2 ´ 2 (notate l’uso del doppio % per fare riferimento al penultimo Output)
In[35]:= mm = %%
Out[35]= {{1, 2}, {2, 1}}
In[36]:= b = {2, 3}
Out[36]= {2, 3}
Possiamo risolvere il sistema lineare con matrice dei coefficienti mm e termine noto b :
In[37]:= x = LinearSolve[mm, b]
4 1
Out[37]= : , >
3 3
Facciamo la verifica:
In[38]:= mm.x
Out[38]= {2, 3}
7
5. Altra premessa fondamentale: l’uguaglianza.
In Mathematica esistono 3 tipi di uguaglianza: la definizione, la definizione differita, l’uguaglianza in una equazione. Anche qui non si può fare confusione sul loro uso.
1) Definizione.
L’ abbiamo già usata in precedenza e si ottiene con = . L’espressione a sinistra diventa immediatamente uguale a
ciò che compare a destra:
In[39]:= f = (xˆ2 - 1)ˆ2
2
Out[39]= (-1 + x2 )
Se assegniamo il valore 2 alla variabile x
In[40]:= x = 2
Out[40]= 2
l’espressione f diventa
In[41]:= f
Out[41]= 9
Se liberiamo la variabile x
In[42]:= x = .
In[43]:= f
2
Out[43]= (-1 + x2 )
2) Definizione differita.
Si ottiene con il simbolo := . L’espressione a sinistra non diventa immediatamente uguale a ciò che compare
a destra ma viene valutata di volta in volta quando viene richiamata. Notate che h è definita immediatamente
mentre g è definita in maniera differita e osservate la differenza di funzionamento.
In[44]:= h = D[f, x]
Out[44]= 4 x (-1 + x2 )
In[45]:= g := D[f, x]
Come vedete manca l’output. Adesso richiamiamo g
In[46]:= g
Out[46]= 4 x (-1 + x2 )
Modifichiamo f
In[47]:= f = fˆ2
4
Out[47]= (-1 + x2 )
In[48]:= h
Out[48]= 4 x (-1 + x2 )
è la derivata della vecchia f
In[49]:= g
8
Out[49]= 8 x (-1 + x2 )
3
è la derivata della nuova f
La definizione differita è molto utile, come vedremo su esempi più significativi
comando che calcola la lunghezza di una curva o l’area di una superficie).
(per esempio per scrivere un
3) Uguaglianza in un’equazione.
Si ottiene con il simbolo == (due segni = consecutivi). Questo simbolo è un operatore logico, infatti si ottiene
In[50]:= 2 == 3
Out[50]= False
In[51]:= 3 == 3
Out[51]= True
Serve per formulare (e risolvere) un’equazione o un sistema usando per esempio il comando Solve[,] . Per
risolvere un’equazione, assicuriamoci prima che il simbolo x sia libero
In[52]:= x = .
In[53]:= Solve[2xˆ2 + 3x - 2 == 0, x]
1
Out[53]= :{x ® -2}, :x ® >>
2
Le soluzioni sono date sotto forma di “regola di sostituzione” per la variabile x, che rimane non assegnata. Per
assegnare le soluzioni a due variabili si può usare la regola di sostituzione ottenuta, che è fatta da due parti e si
attiva mediante il comando /.
In[54]:= x/.%
Out[54]= : - 2,
1
>
2
In[55]:= {a, b} = %
1
>
2
Out[55]= : - 2,
adesso a e b sono le due soluzioni.
Facciamo la verifica (il simbolo “freccia” si ottiene scrivendo ->):
In[56]:= 2xˆ2 + 3x - 2/.x ® a
Out[56]= 0
In[57]:= 2xˆ2 + 3x - 2/.x ® b
Out[57]= 0
Naturalmente dal Teorema di Ruffini segue, usando il comando Expand[] per sviluppare il prodotto:
In[58]:= Expand[2(x - a)(x - b)]
Out[58]= -2 + 3 x + 2 x2
Per risolvere un sistema dobbiamo dare le liste delle equazioni e delle incognite.
In[59]:= Solve[{xˆ2 + yˆ2 == 4, 2x - 3y == 1}, {x, y}]
0
0
1
1
J2 - 3 51N, y ®
J - 3 - 2 51N>,
Out[59]= ::x ®
13
13
0
0
1
1
:x ®
J2 + 3 51N, y ®
J - 3 + 2 51N>>
13
13
Sono state trovate due soluzioni (naturalmente!). Facciamo la verifica per la prima soluzione:
In[60]:= {xˆ2 + yˆ2/.%[[1]], 2x - 3y/.%[[1]]}
9
Out[60]= :
0
0
0
0
2
2
3
1
1
2
J2 - 3 51N +
J - 3 - 2 51N ,
J2 - 3 51N J - 3 - 2 51N>
169
169
13
13
In[61]:= Simplify[%]
Out[61]= {4, 1}
Lo stesso controllo si può fare con la seconda soluzione.
6. Terza premessa: espressioni e funzioni.
Fino ad ora abbiamo sempre definito delle espressioni. Ad esempio in memoria abbiamo ancora l’espressione di
f modificata
In[62]:= f
4
Out[62]= (-1 + x2 )
Se vogliamo valutarla nel punto x=2 dobbiamo usare una regola di sostituzione, come sempre mediante il comando
/. ; si ottiene
In[63]:= f/.x ® 2
Out[63]= 81
Invece possiamo definire una funzione, data dalla stessa legge di f ma con una dipendenza esplicita dalla variabile
x. Questo si ottiene indicandola a sinistra nella definizione con x_ (x seguito dal simbolo “sottolineato” _ ). Prima
liberiamo il simbolo g
In[64]:= g = .
In[65]:= g[x_] = f
4
Out[65]= (-1 + x2 )
Adesso possiamo calcolare il valore di g[x] molto facilmente
In[66]:= {g[1], g[2], g[3]}
Out[66]= {0, 81, 4096}
e anche delle sue derivate (con le funzioni basta usare l’apice per avere la derivata prima)
In[67]:= {g¢ [1], g¢ [2], g¢ [3], g¢ [x]}
Out[67]= :0, 432, 12288, 8 x (-1 + x2 ) >
3
Il comando apice però può dare risultati sbagliati nel caso in cui venga utilizzato per una funzione composta. In tal
caso meglio utilizzare D[].
L’uso delle funzioni serve anche per scrivere “programmi” nel linguaggio di Mathematica, ma questo è un argomento più avanzato.
7. Un po’ di Analisi Matematica.
Possiamo facilmente ottenere un’idea del grafico di |f’|
In[68]:= Plot[Abs[D[f, x]]//Evaluate, {x, -2, 2}]
10
4
3
2
1
-1
-2
1
2
Out[68]= -Graphics-
Notate la necessità del comando //Evaluate usato con la notazione infissa (cioè preceduto da //).
Se si evidenzia il grafico precedente e si scorre su di esso con il mouse, tenendo premuto il tasto Ctrl, nell’angolo
in basso a sinistra si ottengono le coordinate del punto su cui il mouse passa.
Calcolare la derivata di una espressione contenente il valore assoluto, fornisce invece un risultato poco maneggevole:
In[69]:= D[Abs[f], x]
3
Out[69]= 8 x Abs[-1 + x2 ] Abs¢ [-1 + x2 ]
In[70]:= %/.x ® 1/2
3
27
Abs¢ B - F
Out[70]=
16
4
In questo caso è più opportune definire due diverse espressioni di f, tenendo conto della definizione del valore
assoluto, e studiare le derivate di queste due espressioni separatamente.
Cambiamo ora l’espressione in f
In[71]:= f = x/(1 + xˆ2)
x
1 + x2
Out[71]=
e diamo un nome alla derivata di f
In[72]:= fx = D[f, x]
2 x2
1
Out[72]= 2 +
1 + x2
(1 + x2 )
In[73]:= fx = Simplify[%]
1 - x2
Out[73]=
2
(1 + x2 )
Troviamo i punti in cui la derivata si annulla
In[74]:= pcrit = Solve[fx == 0, x]
Out[74]= {{x ® -1}, {x ® 1}}
e calcoliamo il valore di f in questi punti
In[75]:= f/.%
1 1
Out[75]= : - , >
2 2
Studiamo il segno della derivata prima. Per risolvere le disequazioni si usa il comando Reduce[]
In[76]:= Reduce[fx > 0, x]
11
Out[76]= -1 < x < 1
Calcoliamo la derivata seconda di f nei due punti critici. Notate la sintassi per derivare f rispetto a x due volte
In[77]:= D[f, {x, 2}]
Out[77]= -
2
ö
æ
2
÷
ç 8x
÷
+xç
÷
ç
ç
2 3
2 2÷
(1 + x )
(1 + x ) ø
è (1 + x )
4x
2 2
In[78]:= %/.pcrit
1
1
Out[78]= : , - >
2
2
Dunque x=-1 è un punto di minimo relativo per f, mentre x=1 è un punto di massimo relativo per f .
Possiamo cercare i punti di flesso e gli intervalli di convessità:
In[79]:= fxx = Simplify[D[fx, x]]
2 x (-3 + x2 )
Out[79]=
3
(1 + x2 )
In[80]:= Solve[fxx == 0, x]
0
0
Out[80]= :{x ® 0}, :x ® - 3>, :x ® 3>>
In[81]:= Reduce[fxx > 0, x]
0
0
Out[81]= - 3 < x < 0||x > 3
Le doppie linee verticali significano “oppure” mentre il simbolo && significa “e”. Disegniamo contemporaneamente il grafico di f (in blu) e della sua derivata (in rosso)
In[82]:= Plot[{f, fx}, {x, -5, 5}, PlotStyle ® {Hue[0.7], Hue[0.9]}]
1
0.8
0.6
0.4
0.2
-4
-2
2
-0.2
-0.4
Out[82]= -Graphics-
Attenzione all’uso del comando Plot[], potrebbe dare risultati inaspettati:
In[83]:= g = Abs[2 - ãˆSqrt[Log[x]]] - 1
0
Log[x]
Out[83]= -1 + AbsB2 - ã
F
In[84]:= Plot[g, {x, -3, 3}]
12
4
2
1
-3
-2
-1
1
2
3
-1
Out[84]= -Graphics-
Naturalmente il dominio di g è x³1 ma il comando Abs[] ci ha consentito di passare dal campo complesso e
ritornare in campo reale.
8. Uso delle palette.
Nel margine destro della finestra figurano le palette (se non ci sono, la più utile si ottiene dal menù File/Palettes/BasicInput).
Tramite esse si possono scrivere i comandi e le formule in maniera tradizionale. Basta premere sul simbolo che si
vuole utilizzare. Per esempio un integrale definito:
In[85]:= à
ƒ
ƒâƒ
ƒ
A questo punto, posizionando il mouse sulle caselle vuote, si immettono le espressioni volute:
In[86]:= à
3
fâx
0
Log[10]
Out[86]=
2
Naturalmente lo stesso risultato si ottiene immettendo il comando nel solito formato di input
In[87]:= Integrate[f, {x, 0, 3}]
Log[10]
Out[87]=
2
Ancora usando la palette otteniamo l’integrale indefinito di f:
In[88]:= à fâx
Out[88]=
1
Log[1 + x2 ]
2
9. Altri problemi di Analisi Matematica.
Possiamo calcolare il limite di f per x->+Infinity
In[89]:= Limit[f, x ® +¥]
Out[89]= 0
Possiamo ottenere la formula di Taylor di una funzione nel punto x=0 di grado 10
13
In[90]:= Series[Tan[xˆ2], {x, 0, 10}]
x6 2 x10
Out[90]= x2 +
+
+ O[x]11
3
15
Per avere solo il polinomio di Taylor si usa il seguente comando:
In[91]:= t = Normal[%]
x6 2 x10
+
Out[91]= x2 +
3
15
Mostriamo il grafico della funzione e del polinomio di Taylor precedente.
In[92]:= Plot[{Tan[xˆ2], t}, {x, -3, 3}, PlotStyle ® {Hue[0.3], Hue[0.7]}]
30
20
10
-3
-2
-1
1
2
3
-10
-20
Out[92]= -Graphics-
Possiamo calcolare la somma di alcune serie (oppure di somme finite). Usiamo il pulsante corrispondente nella
palette (il simbolo ¥, si trova nella palette File/Palettes/BasicTypesetting).
ƒ
In[93]:= ⠃
ƒ=ƒ
Riempiamo le caselle vuote e premiamo come sempre Maiusc+Invio
¥
In[94]:= â
k=1
k
2ˆk
Out[94]= 2
(chi ha studiato la serie geometrica e il teorema di derivazione per serie può controllare il risultato ottenuto)
¥
In[95]:= â
Out[95]=
k=1
Π2
1
k2
6
Oppure si può usare il comando
In[96]:= Sum[1/kˆ2, {k, 1, ¥}]
Definiamo una funzione che dipende da due argomenti. Prima liberiamo il simbolo f e il simbolo a
In[97]:= f = .; a = .
In[98]:= f[a_, x_] = Sin[a x]
Out[98]= Sin[a x]
14
Diamo tre valori al parametro a e coloriamo i grafici usando questa volta il comando RGBColor[„] che stabilisce
le componenti di Rosso, Verde (Green) e Blu.
In[99]:= Plot[{f[1, x], f[2, x], f[3, x]}, {x, 0, 2Π},
PlotStyle ® {RGBColor[1, 0, 0], RGBColor[0, 1, 0], RGBColor[0, 0, 1]},
Background ® RGBColor[1, 1, 0]]
1
0.5
1
2
3
4
5
6
-0.5
-1
Out[99]= -Graphics-
Proviamo a calcolare l’integrale del prodotto di due funzioni con parametri diversi
In[100]:= Integrate[f[k, x] * f[h, x], {x, 0, 2Π}]
Sin[2 (h - k) Π] Sin[2 (h + k) Π]
Out[100]=
2 (h - k)
2 (h + k)
Semplifichiamo, aggiungendo l’informazione che h e k sono numeri interi (usare la palette per l’appartenenza)
In[101]:= Simplify[%, {h Î Integers, k Î Integers, h ¹ k}]
Out[101]= 0
In[102]:= Integrate[f[k, x] * f[k, x], {x, 0, 2Π}]
Sin[4 k Π]
Out[102]= Π 4k
In[103]:= Simplify[%, {k Î Integers}]
Out[103]= Π
Liberiamo il simbolo della funzione f:
In[104]:= f = .
10. Un compito di Analisi Matematica (I anno).
Compito di Analisi Matematica
Lecce, 24 maggio 2010
15
1) Studiare la funzione
f (x) = x +
1
|x - 1|
2) Calcolare l’integrale
à
3
0
ãx ãx - 1âx
0
3) Studiare la serie
¥
â
n=1
n
2n
4) Calcolare il seguente limite
lim
x®0
sin x - tan x
x3
5) Determinare il polinomio di Taylor centrato in x = 0 di grado 5 della funzione
f (x) =
ãx log(1 + x)
cos x
Soluzione
1) Il dominio è R ” {1}. Studiamo gli asintoti.
In[105]:= f[x_] = x + 1/Abs[x - 1]
1
Out[105]= x +
Abs[-1 + x]
In[106]:= Limit[f[x], x ® +¥]
Out[106]= ¥
Cerchiamo l’asintoto obliquo.
In[107]:= Limit[f[x]/x, x ® +¥]
Out[107]= 1
In[108]:= Limit[f[x] - x, x ® +¥]
Out[108]= 0
La retta y = x è asintoto obliquo a destra.
In[109]:= Limit[f[x], x ® -¥]
Out[109]= -¥
In[110]:= Limit[f[x]/x, x ® -¥]
Out[110]= 1
In[111]:= Limit[f[x] - x, x ® -¥]
Out[111]= 0
La retta y = x è anche asintoto obliquo a sinistra. Calcoliamo ora i limiti destro e sinistro in x=1.
16
In[112]:= Limit[f[x], x ® 1, Direction ® -1]
Out[112]= ¥
In[113]:= Limit[f[x], x ® 1, Direction ® 1]
Out[113]= ¥
La retta x = 1 è asintoto verticale.
Distinguiamo ora tra x > 1 e x < 1. Definiamo due funzioni.
In[114]:= f1[x_] = x + 1/(x - 1)
1
+x
-1 + x
Out[114]=
In[115]:= f1x = D[f1[x], x]
1
(-1 + x)2
Out[115]= 1 -
In[116]:= Together[%]
-2 x + x2
Out[116]=
(-1 + x)2
In[117]:= Solve[f1x == 0, x]
Out[117]= {{x ® 0}, {x ® 2}}
Solo x = 2 è accettabile.
In[118]:= f1[x]/.%
Out[118]= {-1, 3}
In[119]:= f1xx = D[f1[x], {x, 2}]
General :: spell1 : Possible spelling error : new symbol name ”¢¢
f1xx”¢¢ is similar to existing symbol ”¢¢ f1x”¢¢ .
2
Out[119]=
(-1 + x)3
La derivata seconda è positiva, dunque x = 2 è punto di minimo relativo e la funzione è convessa per x > 1 .
In[120]:= f2[x_] = x + 1/(1 - x)
1
+x
1-x
Out[120]=
In[121]:= f2x = D[f2[x], x]
1
(1 - x)2
Out[121]= 1 +
In[122]:= Together[%]
2 - 2 x + x2
Out[122]=
(-1 + x)2
In[123]:= Solve[f2x == 0, x]
Out[123]= {{x ® 1 - ä}, {x ® 1 + ä}}
La derivata prima è positiva, dunque la funzione è crescente in (-¥,1)
In[124]:= f2xx = D[f2[x], x, x]
General :: spell1 : Possible spelling error : new symbol name ”¢¢
f2xx”¢¢ is similar to existing symbol ”¢¢ f2x”¢¢ .
2
Out[124]=
(1 - x)3
La derivata seconda è positiva, dunque la funzione è convessa per x < 1 . Possiamo disegnare il grafico di f .
In[125]:= Plot[{f[x], x}, {x, -10, 10},
PlotStyle ® {{Thickness[0.01], RGBColor[1, 0, 0]},
{Thickness[0.01], RGBColor[0, 0, 1]}},
PlotRange ® {{-10, 10}, {-10, 10}}, AspectRatio ® 1]
17
10
7.5
5
2.5
-10
-7.5
-5
-2.5
2.5
5
7.5
10
-2.5
-5
-7.5
-10
Out[125]= -Graphics-
(Per salvare un grafico, fare click su di esso e scegliere dal menù Edit/Save Selection As il formato grafico che si
preferisce: PostScript, Bitmap, ecc.)
2) Calcoliamo l’integrale
In[126]:= Integrate[Exp[x] * Sqrt[Exp[x] - 1], {x, 0, 3}]
2
3/2
(-1 + ã3 )
Out[126]=
3
3) La serie è a termini positivi. Usiamo il criterio del rapporto:
In[127]:= Limit[((n + 1)/2ˆ(n + 1))/(n/2ˆn), n ® +¥]
1
2
Out[127]=
Poiché il risultato è minore di 1, la serie converge. Calcoliamo la somma:
In[128]:= Sum[n/2ˆn, {n, 1, +¥}]
Out[128]= 2
4) Calcoliamo il limite
In[129]:= Limit[(Sin[x] - Tan[x])/xˆ3, x ® 0]
1
Out[129]= 2
5) Determiniamo il polinomio di Taylor
In[130]:= f[x_] = Exp[x] * Log[1 + x]/ Cos[x]
Out[130]= ãx Log[1 + x] Sec[x]
In[131]:= Series[f[x], {x, 0, 5}]
x2 5 x3 x4 9 x5
Out[131]= x +
+
+
+
+ O[x]6
2
6
4
20
Consideriamo solo il polinomio
In[132]:= p = Normal[%]
x2 5 x3 x4 9 x5
+
+
+
Out[132]= x +
2
6
4
20
Confrontiamo la funzione (in rosso) con il polinomio (in blu).
In[133]:= Plot[{f[x], p}, {x, -0.95, 0.95},
PlotStyle ® {RGBColor[1, 0, 0], RGBColor[0, 0, 1]}]
18
3
2
1
-0.75 -0.5 -0.25
0.25
0.5
0.75
-1
-2
Out[133]= -Graphics-
11. Un compito di Analisi Matematica (II anno).
Compito di Analisi Matematica
Lecce, 24 maggio 2010
1) Sviluppare in serie di Fourier la funzione 2 - periodica definita in (0,2) da
f(x) = x2
2) Determinare massimo e minimo della funzione
f (x) = x2 - 2y2 - 5xy
nell¢ insieme {x2 + y2 £ 1}.
3) Risolvere il Problema di Cauchy
y”[x] = 2 y’[x] - y[x],
y[0] = 1,
y’[0] = 2
4) Calcolare l’integrale triplo
Ù E zâxâyâz
dove E = {x2 +y2 +z2 £ 1, x2 +y2 £ z2 , z ³ 0}
5) Calcolare la lunghezza della curva (elica)
j(t)=(3cos t, 3sen t, t),
t Î [0,6Π].
6) Calcolare l’area della superficie
j(u,v) = (u + v, u - v, u v) su {u2 +v2 £ 1}.
Soluzione
1) Determiniamo la serie di Fourier.
In[134]:= T = 2
Out[134]= 2
In[135]:= Ω = 2Π/T
Out[135]= Π
In[136]:= f[x_] = xˆ2
Out[136]= x2
In[137]:= a[0] =
Out[137]=
2 T
à f[x]âx
T 0
8
3
19
In[138]:= a[h_] = SimplifyB
2 T
à f[x] Cos[h Ω x]âx, h Î IntegersF
T 0
(nel comando Sim pli fy[] abbiamo aggiunto l’informazione fondamentale che h è un numero intero).
Out[138]=
4
h2 Π2
In[139]:= b[h_] = SimplifyB
Out[139]= -
2 T
à f[x] Sin[h Ω x]âx, h Î IntegersF
T 0
4
hΠ
Formiamo una somma parziale della serie di Fourier (il punto e virgola alla fine del comando serve per evitare la
visualizzazione di un lungo output)
In[140]:= s[x_] = a[0]/2 + Sum[a[h] * Cos[h Ω x] + b[h] * Sin[h Ω x], {h, 1, 100}];
In[141]:= Plot[s[x]//Evaluate, {x, -4.2, 4.2}]
4
3
2
1
-4
-2
2
4
Out[141]= -Graphics-
2) Studiamo la funzione, cominciando a cercare i punti critici.
In[142]:= f[x_, y_] = xˆ2 - 2yˆ2 - 5 x y
Out[142]= x2 - 5 x y - 2 y2
Possiamo calcolare il gradiente di f[x, y] e trovare i punti critici di f
In[143]:= gr = {D[f[x, y], x], D[f[x, y], y]}
Out[143]= {2 x - 5 y, -5 x - 4 y}
In[144]:= pcrit = Solve[gr == 0, {x, y}]
Out[144]= {{x ® 0, y ® 0}}
Calcoliamo il valore di f nel punto trovato
In[145]:= f[x, y]/.pcrit
Out[145]= {0}
Calcoliamo la matrice hessiana di f:
In[146]:= H = {{D[f[x, y], x, x], D[f[x, y], x, y]},
{D[f[x, y], y, x], D[f[x, y], y, y]}}
Out[146]= {{2, -5}, {-5, -4}}
Calcoliamo il determinante di H nei punti critici
In[147]:= Det[H]/.pcrit
Out[147]= {-33}
Dunque il punto (0, 0) è di sella.
Per trovare i punti di massimo e di minimo assoluto nel cerchio di centro l’origine e raggio 1 (che esistono
per il Teorema di Weierstrass) usiamo il metodo dei moltiplicatori di Lagrange per esaminare la circonferenza.
Definiamo
20
In[148]:= L[x_, y_, Λ_] = f[x, y] - Λ(xˆ2 + yˆ2 - 1);
e risolviamo il sistema
In[149]:= pvinc =
FullSimplify[
Solve[{D[L[x, y, Λ], x] == 0, D[L[x, y, Λ], y] == 0,
D[L[x, y, Λ], Λ] == 0}, {x, y, Λ}]]
2
2
0
1
3
3
1
1
Out[149]= ::Λ ® J - 1 - 34N, x ® - 0 ,y ® + 0 >,
2
2 2 34
2 2 34
2
2
0
1
1
3
3
1
:Λ ® J - 1 - 34N, x ®
0
+ 0 >,
,y ®
2
2 2 34
2 2 34
2
2
0
1
1
1
3
3
:Λ ® J - 1 + 34N, x ® + 0 ,y ®
- 0 >,
2
2 2 34
2 2 34
2
2
0
1
1
1
3
3
:Λ ® J - 1 + 34N, x ®
+ 0 ,y ® - 0 >>
2
2 2 34
2 2 34
Abbiamo ottenuto quattro punti critici vincolati. Diamogli un nome.
In[150]:= {{a1 = x/.pvinc[[1]], b1 = y/.pvinc[[1]]},
{a2 = x/.pvinc[[2]], b2 = y/.pvinc[[2]]},
{a3 = x/.pvinc[[3]], b3 = y/.pvinc[[3]]},
{a4 = x/.pvinc[[4]], b4 = y/.pvinc[[4]]}}
2
2
2
2
1
1
1
1
3
3
3
3
Out[150]= :: - 0 ,+ 0 >, :
- 0 ,
+ 0 >,
2 2 34
2 2 34
2 2 34
2 2 34
2
2
2
2
3
3
3
3
1
1
1
1
:+ 0 ,
- 0 >, :
+ 0 ,- 0 >>
2 2 34
2 2 34
2 2 34
2 2 34
Calcoliamo il valore di f nei punti trovati
3
æ1
æ
1
3 ö
3 ö
÷
÷
ç
ç + 0
֍
÷,
ç
ç
ç 2 2 34 ÷
֍
÷
ç 2 - 2 034 ÷
øè
ø
è
3
æ
æ1
æ1
1
3
3 ö
3 ö
3 ö
ç1
÷
÷
÷
÷-5 ç
ç
֍
÷,
ç + 0
-2ç
- 0
ç
ç
ç 2 + 2 034 ÷
÷
ç 2 - 2 034 ÷
֍
÷
ç 2 2 34 ÷
2 2 34
è
ø
è
øè
ø
3
æ
ö
æ1
öç
æ1
1
3
3 ÷
3 ÷
3 ö
ç1
÷
÷+5 ç
ç
֍
÷,
-2ç
+ 0
ç
ç
ç 2 - 2 034 ÷
÷
ç 2 - 2 034 ÷
֍
÷
ç 2 + 2 034 ÷
2 2 34
è
ø
è
øè
ø
3
æ
æ
3
3 ö
3 ö
3 ö
1
÷
־
÷>
ç1
ç1
ç1
÷
÷
÷
ç
ç
+ 0
-2ç
ç
÷+5 ç
֍
÷
ç 2 + 2 034 ÷
ç 2 - 2 034 ÷
ç 2 - 2 034 ÷
2 2 34
ø
øè
ø
è
è
In[151]:= f[x, y]/.pvinc
æ
3
3 ö
1
÷
ç1
÷-5
-2ç
Out[151]= : - 0
ç
÷
ç 2 + 2 034 ÷
2 2 34
ø
è
Calcoliamo il valore approssimato di f
In[152]:= N[%]
Out[152]= {-3.41548, -3.41548, 2.41548, 2.41548}
In conclusione i punti di minimo e di massimo assoluto si trovano sulla frontiera e sono rispettivamente
In[153]:= {{a1, b1}, {a2, b2}}
2
2
2
2
1
1
1
1
3
3
3
3
- 0 ,+ 0 >, :
- 0 ,
+ 0 >>
Out[153]= :: 2 2 34
2 2 34
2 2 34
2 2 34
21
In[154]:= {{a3, b3}, {a4, b4}}
2
2
2
2
1
1
1
1
3
3
3
3
Out[154]= :: + 0 ,
- 0 >, :
+ 0 ,- 0 >>
2 2 34
2 2 34
2 2 34
2 2 34
In[155]:= Plot3D[f[x, y], {x, -3, 3}, {y, -3, 3},
PlotLabel- >¢¢ Grafico di f(x, y)¢¢ ]
Grafico di f( x,y )
20
0
-20
-40
2
0
-2
0
-2
2
Out[155]= -SurfaceGraphics-
Questo grafico è nel quadrato di lato 6. Per avere il grafico nel cerchio di raggio 1 dobbiamo descriverlo come una
superficie utilizzando le coordinate polari
In[156]:= ParametricPlot3D[{r * Cos[Θ], r * Sin[Θ], f[r * Cos[Θ], r * Sin[Θ]]},
{r, 0, 1}, {Θ, 0, 2Π}, PlotPoints ® {20, 30}]
-1
-0.5
1
0.5
0
0
0.5
1
-0.5
-1
2
0
-2
Out[156]= -Graphics3D-
(naturalmente è cambiata la scala del grafico)
3) Risolviamo il Problema di Cauchy con il comando DSolve[]
In[157]:= DSolve[{y¢¢ [x] == 2y¢ [x] - y[x], y[0] == 1, y¢ [0] == 2}, y[x], x]
Out[157]= {{y[x] ® ãx (1 + x)}}
Anche questa volta la soluzione è una regola di sostituzione. Per ottenere la funzione che risolve il P.d.C. usiamo
un altro simbolo
In[158]:= h[x_] = y[x]/.%
Out[158]= {ãx (1 + x)}
In[159]:= Plot[h[x], {x, -2, 2}]
22
10
8
6
4
2
-2
-1
1
2
Out[159]= -Graphics-
Questo problema sarebbe stato più difficile, anche se dalla teoria conosciamo il metodo per trovare la soluzione
(basta cambiare opportunamente la variabile indipendente e quella dipendente):
In[160]:= DSolve[{y¢ [x] == (x + y[x] + 1)/(x + 2y[x] + 2), y[1] == 1}, y[x],
x]
Solve :: tdep : The equations appear to involve the variables
to be solved for in an essentially non - algebraic way.
0
ArcTanhB 2 (1+y[x])
F 1
x
0
Out[160]= SolveB Log[2 - x2 + 4 y[x] + 2 y[x]2 ] ==
+
2
2
0
ArcTanhB2 2F Log[7]
0
, {y[x]}F
+
2
2
Il programma non è riuscito a trovare la soluzione.
4) Usiamo le coordinate cilindriche. Dobbiamo risolvere l’uguaglianza
x2 +y2 =1- (x2 +y2 ) quindi Ρ2 = 12 .
Allora, inserendo il determinante dello jacobiano, e usando la formula di riduzione (la prima variabile viene
integrata per ultima)
In[161]:= Integrate[z * Ρ, {J, 0, 2 Π}, {Ρ, 0, 1/Sqrt[2]}, {z, Ρ, Sqrt[1 - Ρˆ2]}]
Π
Out[161]=
8
5) Definiamo una funzione che calcola la lunghezza di una arbitraria curva (notate l’uso della definizione differita,
altrimenti il comando non funzionerebbe!).
In[162]:= lung[curv_, a_, b_] :=
Integrate[Simplify[Sqrt[D[curv, t].D[curv, t]]], {t, a, b}]
Utilizziamo la funzione sulla curva assegnata:
In[163]:= j[t_] = {3 Cos[t], 3 Sin[t], t}
Out[163]= {3 Cos[t], 3 Sin[t], t}
In[164]:= lung[j[t], 0, 6Π]
0
10 Π
Out[164]= 6
Disegniamo il sostegno della curva
In[165]:= ParametricPlot3D[j[t]//Evaluate, {t, 0, 6Π}]
23
-2
2
0
2
0
-2
15
10
5
0
Out[165]= -Graphics3D-
Notate che la funzione permette anche di calcolare la lunghezza di una curva piana.
In[166]:= j[t_] = {2 Cos[t] , 2 Sin[t]}
Out[166]= {2 Cos[t], 2 Sin[t]}
In[167]:= lung[j[t], 0, 2Π]
Out[167]= 4 Π
6) Per calcolare integrali superficiali importiamo un Package che permette di calcolare il prodotto vettoriale
In[168]:= << Calculus‘VectorAnalysis‘
Definiamo (la superficie dovrà sempre essere espressa mediante le variabili (u,v) in un dominio rettangolare)
In[169]:= area[superf_, a_, b_, c_, d_] :=
Integrate[
FullSimplify[
Sqrt[CrossProduct[D[superf, u], D[superf, v]].
CrossProduct[D[superf, u], D[superf, v]]]], {u, a, b}, {v, c, d}]
Poiché il dominio è un cerchio dobbiamo usare le coordinate polari (ma le variabili debbono sempre chiamarsi
(u,v) )
In[170]:= j[u_, v_] = {u * Cos[v] + u * Sin[v], u * Cos[v] - u * Sin[v],
uˆ2 * Cos[v] * Sin[v]}
Out[170]= {u Cos[v] + u Sin[v], u Cos[v] - u Sin[v], u2 Cos[v] Sin[v]}
In[171]:= area[j[u, v], 0, 1, 0, 2Π]
0
0 æ
0 ö
ç
ç - 2 2 + 3÷
÷Π
Out[171]= 2 2 ç
÷
ç
÷
3
è
ø
In[172]:= ParametricPlot3D[j[u, v]//Evaluate, {u, 0, 1}, {v, 0, 2Π}]
0.5
0.25
0
-0.25
-0.5
1
0
-1
0
-1
1
24
Out[172]= -Graphics3D-
Usiamo lo stesso comando per calcolare l’area della superficie sferica di raggio R
In[173]:= j[u_, v_] = {R * Cos[u] * Sin[v], R * Sin[u] * Sin[v], R * Cos[v]}
Out[173]= {R Cos[u] Sin[v], R Sin[u] Sin[v], R Cos[v]}
In[174]:= area[j[u,
v], 0, 2Π, 0, Π]
1
4
Out[174]= 4 Π R
Calcoliamo l’area del toro di raggi R > r e disegniamo il nastro di Moebius.
In[175]:= j[u_, v_] = {(R + r Cos[u]) Cos[v], (R + r Cos[u]) Sin[v], r Sin[u]}
Out[175]= {(R + r Cos[u]) Cos[v], (R + r Cos[u]) Sin[v], r Sin[u]}
In[176]:= Simplify[area[j[u, v], 0, 2Π, 0, 2Π], R > r > 0]
Out[176]= 4 Π2 r R
In[177]:= R = 3; r = 1;
In[178]:= ParametricPlot3D[j[u, v], {u, 0, 2Π}, {v, 0, 2Π}, Axes ® False]
Out[178]= -Graphics3DIn[179]:= j[u_, v_] = {2 Cos[u] + v * Cos[u] * Cos[u/2],
2 Sin[u] + v * Sin[u] * Cos[u/2], v * Sin[u/2]}
u
u
u
Out[179]= :2 Cos[u] + v Cos B F Cos[u], 2 Sin[u] + v Cos B F Sin[u], v Sin B F>
2
2
2
In[180]:= ParametricPlot3D[j[u, v], {u, 0, 2Π}, {v, -1, 1}, Axes ® False]
Out[180]= -Graphics3D-
25
12. Grafici, animazioni, suoni.
Abbiamo già visto come produrre vari grafici. Nell’help potete trovare molti altri esempi.
anche sovrapporre. Mostriamo una sfera e un piano.
In[181]:= g1 = ParametricPlot3D[{Sin[Φ] Cos[J], Sin[Φ] Sin[J], Cos[Φ]},
{Φ, 0, Π}, {J, 0, 2Π}, Axes ® False]
Out[181]= -Graphics3DIn[182]:= g2 = Plot3D[x - y, {x, -1, 1}, {y, -1, 1}, Axes ® False]
Out[182]= -SurfaceGraphicsIn[183]:= Show[g1, g2]
26
I grafici si possono
Out[183]= -Graphics3D-
Si possono ottenere anche superfici in forma implicita. Per questo bisogna importare un apposito Package usando
il seguente comando:
In[184]:= << Graphics‘ContourPlot3D‘
In[185]:= g1 = ContourPlot3D[xˆ2 + yˆ2 + zˆ2 - 4, {x, -2, 2}, {y, -2, 2},
{z, -2, 2}]
Out[185]= -Graphics3DIn[186]:= g2 = ContourPlot3D[(x - 1)ˆ2 + yˆ2 - 1, {x, 0, 2}, {y, -1, 1}, {z, -2, 2}]
27
Out[186]= -Graphics3DIn[187]:= Show[g1, g2]
Out[187]= -Graphics3D-
Vediamo come ottenere delle animazioni. Facciamo scorrere una circonferenza su una retta. Un punto della
circonferenza percorre una curva detta cicloide, che ha molte proprietà interessanti (scrivo solo i comandi da dare,
non possiamo vedere il risultato!).
In[188]:= Do[
grafico = ParametricPlot[{t - Sin[t], 1 - Cos[t]}, {t, 0, x},
PlotStyle ® {{GrayLevel[0.7], Thickness[0.005]},
RGBColor[0, 0, 1]}, AspectRatio ® Automatic,
ImageSize ® {500, 200}, PlotRange ® {{-1, 10}, {-1, 2.5}},
DisplayFunction ® Identity];
grafico1 = ParametricPlot[{x + Cos[t], 1 + Sin[t]}, {t, 0, 2Π},
PlotStyle ® {{GrayLevel[0.7], Thickness[0.005]},
RGBColor[0, 0, 1]}, AspectRatio ® Automatic,
ImageSize ® {500, 200}, PlotRange ® {{-1, 10}, {-1, 2.5}},
DisplayFunction ® Identity];
punto1 = Graphics[{RGBColor[1, 0, 0], PointSize[0.015],
Point[{x - Sin[x], 1 - Cos[x]}]}];
linea1 = Graphics[{RGBColor[1, 0, 0], Thickness[0.005],
Line[{{x - Sin[x], 1 - Cos[x]}, {x, 1}}]}];
mov[x] = Show[{grafico, grafico1, punto1, linea1},
DisplayFunction ® $DisplayFunction], {x, 0.01, 9, 0.1}]
Per vedere l’animazione, fare doppio click sull’immagine. Per fermarla fare un altro click.
Un’altra animazione che simula le oscillazioni di una membrana elastica.
In[189]:= f[x_, y_, a_, t_] := Cos[t] * Sin[a * x] * Sin[a * y]
In[190]:= Do[
grafico = Plot3D[f[x, y, 2, t], {x, 0, Π}, {y, 0, Π},
Axes ® False, DisplayFunction ® Identity];
l[t] = Show[{grafico}, DisplayFunction ® $DisplayFunction],
{t, 0, 2Π, 2Π/10}]
28
Infine ascoltiamo una nota (anche per questo ci vuole proprio il Notebook!):
In[191]:= Play[Sin[2000t], {t, 1, 3}]
Out[191]= -Sound-
e una sovrapposizione di note di varie frequenze
In[192]:= f[t_] = Sum[Sin[3000 * k * t] * kˆ3, {k, 1, 4}];
In[193]:= Play[f[t], {t, 1, 3}]
Out[193]= -Sound-
13. Un ultimo argomento: le definizioni per ricorrenza.
Molto spesso si incontrano successioni definite per ricorrenza. Consideriamo, per esempio,
I Numeri di Fibonacci
La succeccione di Fibonacci si ottiene assegnando i primi due termini, e poi calcolando gli altri come somma dei
due precedenti. Un primo modo è il seguente:
In[194]:= fib1[n_] := fib1[n - 1] + fib1[n - 2]
In[195]:= fib1[1] = 1
Out[195]= 1
In[196]:= fib1[2] = 1
Out[196]= 1
In[197]:= fib1[15]
Out[197]= 610
Vediamo quanto tempo serve per calcolare il termine 35-esimo
In[198]:= fib1[35]//Timing
Out[198]= {23.86 Second, 9227465}
29
Troppo tempo e la crescita è esponenziale! Il problema è che ogni volta deve ricominciare tutto.
Si può dare una definizione in modo che il programma tenga in memoria i numeri già calcolati.
In[199]:= fib2[n_] := fib2[n] = fib2[n - 1] + fib2[n - 2]
In[200]:= fib2[1] = 1
Out[200]= 1
In[201]:= fib2[2] = 1
Out[201]= 1
In[202]:= fib2[200]//Timing
Out[202]= {0. Second, 280571172992510140037611932413038677189525}
Mica male come guadagno! Ma c’è ancora un problema.
In[203]:= fib1[350]//Timing
$RecursionLimit :: reclim : Recursion depth of 256 exceeded. More¼
$RecursionLimit :: reclim : Recursion depth of 256 exceeded. More¼
$RecursionLimit :: reclim : Recursion depth of 256 exceeded. More¼
General :: stop : Further output of $RecursionLimit :: reclim
will be suppressed during this calculation. More¼
Out[203]= $Aborted
(per interrompere un calcolo troppo lungo si usa il menù Kernel/Abort Evaluation).
Il programma ha raggiunto il numero massimo di ricorsione. Ci serve un’altra soluzione, questa volta senza usare
la ricorsione. Dobbiamo scrivere un piccolo programma con un ciclo for che si ottiene mediante il comando Do[]
In[204]:= fibo[q_] := {a = 1; b = 1; Do[{c = a + b; a = b; b = c}, {i, 3, q}]; c}
In[205]:= fibo[5000]//Timing;
In[206]:= N[%, 30]
Out[206]= {0.015 Second, {3.8789684543883256337019163083 ´ 101044 }}
Comunque Mathematica ha un comando built-in per questa successione:
In[207]:= Fibonacci[5000]//Timing;
In[208]:= N[%, 30]
Out[208]= {0. Second, {3.8789684543883256337019163083 ´ 101044 }}
che è leggermente più veloce.
30
Appendice. Un brevissimo cenno su Mathematica 8.
Nella versione 8 sono state introdotte molte novità, ed alcuni comandi descritti in precedenza sono
diventati obsoleti. Non userò in questa appendice lo stesso stile usato nelle sezioni precedenti ma mi
limiterò a segnalare poche novità.
Innanzitutto sono cambiati il FrontEnd e l’help (quest’ultimo, a mio parere, è diventato più difficile
da utilizzare). Comunque l’help rimane sempre la principale risorsa a cui attingere per avere degli esempi
significativi e per controllare la sintassi dei comandi. Inutile tentare di ricordare esattamente come immettere i comandi: basta evidenziarli e premere il tasto F1 per avere subito un promemoria e gli esempi
principali.
Risulta molto utile il nuovo uso dei colori: ciò che viene scritto rimane in blu finché non coincide esattamente con il nome di una funzione o di una costante già definita.
Anche le parentesi rimangono colorate in viola se non c’è corrispondenza tra parentesi aperte e parentesi
chiuse.
Se si commette un errore di sintassi e si preme Shift+Invio tutta la cella è colorata in rosso e si riesce
a capire abbastanza facilmente dove è l’errore.
Molti dei Package sono inclusi direttamente nel Kernel e dunque non c’è più bisogno di richiamarli. Ad
esempio nel caso dei grafici in forma implicita considerati a pagina 27, basta individuare un parallelepipedo
contenente il grafico da visualizzare e dare direttamente il comando
ContourPlot3D[x2 +y2 == z2 +1, {x, −3.5, 3.5}, {y, −3.5, 3.5}, {z, −3, 3}] per ottenere l’iperboloide:
Il meccanismo illustrato a pagina 28 per ottenere animazioni non funziona più: al suo posto è stata
introdotta la funzione Manipulate[]. Un’altra nuova funzione per gestire definizioni “dinamiche” è
Dynamic[].
Ad esempio, il comando Manipulate[Plot[Sin[2k π x], {x, 0, 1}], {k, 1, 10}] produce la visualizzazione
di sinusoidi con frequenza compresa tra 1 e 10.
Per ottenere l’animazione della cicloide si può usare il seguente comando
Manipulate[
grafico =
ParametricPlot[{t - Sin[t], 1 - Cos[t]}, {t, 0, x},
PlotStyle -> {{GrayLevel[0.7], Thickness[0.005]},
31
RGBColor[0, 0, 1]}, AspectRatio -> Automatic,
ImageSize -> {500, 200}, PlotRange -> {{-1, 10}, {-1, 2.5}}];
grafico1 =
ParametricPlot[{x + Cos[t], 1 + Sin[t]}, {t, 0, 2 Pi},
PlotStyle -> {{GrayLevel[0.7], Thickness[0.005]},
RGBColor[0, 0, 1]}, AspectRatio -> Automatic,
ImageSize -> {500, 200}, PlotRange -> {{-1, 10}, {-1, 2.5}}];
punto1 =
Graphics[{RGBColor[1, 0, 0], PointSize[0.015],
Point[{x - Sin[x], 1 - Cos[x]}]}];
punto2 =
Graphics[{RGBColor[0, 0, 1], PointSize[0.015], Point[{x, 1}]}];
linea1 =
Graphics[{RGBColor[1, 0, 0], Thickness[0.005],
Line[{{x - Sin[x], 1 - Cos[x]}, {x, 1}}]}];
Show[{grafico, grafico1, punto1, punto2, linea1}], {x, 0.1, 9, 0.2}]
Un frame dell’animazione è mostrato in figura:
x
4.7
2.5
2.0
1.5
1.0
0.5
2
4
6
8
10
-0.5
-1.0
Risulta molto utile la nuova funzione Boole[] che non è altro che la funzione caratteristica di un
insieme: per esempio adesso per calcolare l’integrale 4) proposto a pagina 19 basta, anche in questo caso,
individuare un parallelepipedo contenente l’insieme di integrazione e immettere il comando
Integrate[z Boole[x2 + y2 + z2 < 1 && x2 + y2 < z2 && z > 0], {x, -1, 1},{y, -1, 1},{z, 0, 1}],
ottenendo il risultato senza usare esplicitamente la formula di riduzione per gli integrali multipli. La
funzione Boole[] è molto utile anche per disegnare grafici.
Per risolvere l’esercizio 2) di pagina 18 sulla ricerca del massimo e del minimo di una funzione, basta
inserire la funzione, la condizione (o le condizioni tra parentesi graffe) che individua l’insieme, in due
variabili un rettangolo abbastanza grande contenente l’insieme, e immettere i nuovi comandi:
Maximize[x2 − 2y2 − 5xy, x2 + y2 ≤ 1,{x, -1, 1},{y, -1, 1}],
Minimize[x2 − 2y2 − 5xy, x2 + y2 ≤ 1,{x, -1, 1},{y, -1, 1}].
Concludo queste brevi note con un’incursione nel campo del Calcolo Numerico. Ci sono equazioni
differenziali per cui non riusciamo a trovare una soluzione esplicita. Ad esempio proviamo a risolvere il
Problema di Cauchy:

x2 + y 2 − 1
 ′
y = 2
x + y2 + 1

y(0) = 0
Usiamo il comando DSolve[]
DSolve[{y’[x] == (x^2 + y[x]^2 - 1)/(x^2 + y[x]^2 + 1), y[0] == 0}, y[x], x]
e la risposta è
32
DSolve[{Derivative[1][y][x] == (-1 + x^2 + y[x]^2)/(1 + x^2 + y[x]^2),
y[0] == 0}, y[x], x]
quindi Mathematica 8 non riesce a risolvere il problema (non ci riuscirebbe neanche Mathematica ∞).
Ricorriamo al comando NDSolve[], che non fornisce una soluzione esatta ma solo una “funzione interpolante”. Attenzione alla sintassi del comando, molto diversa da quella di DSolve[]
s = NDSolve[{y’[x] == (x^2 + y[x]^2 - 1)/(x^2 + y[x]^2 + 1),
y[0] == 0}, y, {x, -3, 3}]
la risposta è
{{y ->
InterpolatingFunction[{{-3.,3.}},<>]}}
e tracciamo il grafico della soluzione con il comando
Plot[Evaluate[y[x] /. s], {x, -3, 3}, PlotRange -> All]
0.6
0.4
0.2
-3
-2
1
-1
-0.2
-0.4
-0.6
33
2
3