Mathematica: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Recupero di 0 fonte/i e segnalazione di 1 link interrotto/i. #IABot (v1.6.2)
m Errori di Lint: Tag annidati male
Riga 42:
A titolo esemplificativo, quella che segue è la rappresentazione interna di un notebook contenente una sezione, una sottosezione, due celle di testo e una formula:
 
 
<code>
'''Notebook['''{
Cell[CellGroupData[{
Riga 63:
}, Open]
]
}''']''' </code>
 
Questa scrittura, che è contenuta nel file di testo ASCII con suffisso .nb che costituisce il notebook, viene interpretata dal front-end di Mathematica o di Mathreader per produrre una visualizzazione di tipo WYSIWYG il cui contenuto può essere ulteriormente modificato dall'utente ed eventualmente inviato al kernel per la valutazione.
Riga 69:
Tutte le versioni per UNIX/Linux sono dotate anche di un front-end a riga di comando; all'utente viene presentata un'interfaccia in formato puramente testuale, di cui viene dato un esempio qui di seguito:
 
<code>
% math
Mathematica 5.2 for Sun Solaris (UltraSPARC)
Line 77 ⟶ 76:
In[1]:= Solve[x^2 + 2 x - 9 == 0, x]
Out[1]= {{x -> -1 - Sqrt[10]}, {x -> -1 + Sqrt[10]}} </code>
 
Le prime versioni di Mathematica per MS-DOS erano dotate del solo front-end a riga di comando.
Line 94 ⟶ 93:
mentre l'assegnamento alla variabile x (che non richiede di essere dichiarata prima di essere utilizzata) della succitata somma, ossia la scrittura x=1+1, viene rappresentata internamente con
 
<code> Set[x, Plus[1,1]] </code>
 
Il vantaggio di questa rappresentazione è che tutto il contenuto di notebook e package (che a loro volta non sono altro che espressioni) può essere rappresentato con semplici file di testo in formato ASCII, condivisibili tra le diverse piattaforme su cui Mathematica è implementato.
La rappresentazione interna di un'espressione può essere visualizzata per mezzo dei comandi '''Fullform''' e '''TreeForm'''.
 
<code>
<small>In[5]:=</small> '''FullForm[1 + Sin[2 Pi (w t + a)]];
<small>Out[5]:=</small> Plus[1, Sin[Times[2, Pi, Plus[a, Times[t, w]]]]] </code>
 
L'intestazione di un'espressione può essere visualizzata per mezzo del comando '''Head[]''':
 
<code>
<small>In[1]:=</small> '''Head[1 + 1]'''
<small>Out[1]=</small> Plus
 
<small>In[2]:=</small> '''Head[{1,2,3}]'''
<small>Out[2]=</small> List </code>
 
Le sue parti interne sono invece accessibili utilizzando la procedura Part[n1,n2,...] la cui forma breve è rappresentata da <nowiki>[[n1,n2,...]]</nowiki>. Nell'esempio che segue vengono estratte, rispettivamente: l'intestazione, il secondo argomento di Plus, il primo (e unico) argomento della funzione Sin, il secondo addendo del terzo fattore nell'argomento di Sin.
 
<code>
<small>In[3]:=</small> '''expr = 1 + Sin[2 Pi (w t + a)];
<small>In[4]:=</small> '''{Part[expr, 0], expr<nowiki>[[</nowiki>2<nowiki>]]</nowiki>, expr<nowiki>[[2, 1]]</nowiki>, expr<nowiki>[[2, 1, 3, 2]]</nowiki>}'''
<small>Out[4]=</small> {Plus, Sin[2 Pi (a + t w)], 2 Pi (a + t w), t w} </code>
 
==== Atomi ====
Mathematica offre anche dei tipi atomici che identificano le diverse tipologie di numero (intero, razionale, reale, complesso) e di simbolo (simbolo del linguaggio, stringa di caratteri). I tipi atomici in Mathematica sono: '''Integer''', '''Rational''', '''Real''', '''Complex''', '''Symbol''' e '''String'''.
La rappresentazione di un atomo differisce in un certo senso da quella delle espressioni tradizionali (i cui dati sono riportati tra le parentesi quadre dell'espressione) in quanto l'intestazione non viene in genere visualizzata, pur essendo restituita dal comando Head. I seguenti comandi applicano la procedura Head a ciascun elemento della lista che segue '''/@''' (la notazione infissa di Map[]):
 
<code>
<small>In[1]:=</small> '''Head /@ {7, 2/3, 2.71, 5 - 3 I, I, E, Pi}'''
<small>Out[1]=</small> {Integer, Rational, Real, Complex, Complex, Symbol, Symbol}
 
<small>In[2]:=</small> '''Head /@ {Integer, Plus, Map, Solve, "Integer", "Pluto"}'''
<small>Out[2]=</small> {Symbol, Symbol, Symbol, Symbol, String, String} </code>
 
=== Valutazione delle espressioni ===
Quando si invia un'espressione al kernel, questi la elabora (o, mutuando il termine anglofono ''Evaluate'', la ''valuta'') immediatamente applicando (nell'ordine) all'intestazione, agli argomenti e all'espressione nel suo complesso una serie di regole di trasformazione specificate dall'utente o predefinite nel linguaggio.
 
<code>
<small>In[1]:=</small> '''1 + 1'''
<small>Out[1]=</small> 2 </code>
 
A differenza di altri prodotti analoghi, quali [[Maxima (software)|Maxima]] e [[Maple]], Mathematica applica ricorsivamente le regole di trasformazione memorizzate fino a quando l'espressione elaborata non subisce ulteriori variazioni (si dice che è stato raggiunto un [[punto fisso]]), o viene raggiunto un limite di ricorsione predefinito. Perché ciò abbia senso è opportuna - anche se non imposta - l'assenza di effetti collaterali (''side effect''); da questo elemento deriva la somiglianza con la programmazione funzionale.
Line 141 ⟶ 137:
Il processo di valutazione da parte del kernel è in parte trasparente all'utente e questo può essere fonte di frustrazione per il programmatore novizio. Dato che l'intestazione e gli argomenti vengono valutati per primi, quando l'espressione viene valutata nel suo complesso ha già subìto una parziale trasformazione della sua sintassi. Siccome le regole di riscrittura si basano su sostituzioni sintattiche, e non semantiche, può capitare che certe regole di sostituzione non trovino più applicazione sulla forma modificata e pertanto non sortiscano l'effetto desiderato.
Ad esempio, è possibile sostituire il simbolo 1 con il simbolo 3 per mezzo della seguente regola di sostituzione
 
<code>
<small>In[1]:=</small> '''1 /. (1->3)'''
<small>Out[1]=</small> 3 </code>
 
internamente rappresentata come:
 
<code> ReplaceAll[1,Rule[1,3]] </code>
 
Tuttavia, se si cerca di effettuare una sostituzione dello stesso simbolo nella scrittura 1+1 si ottiene un risultato diverso dal valore 6 atteso:
 
<code>
<small>In[2]:=</small> '''1 + 1 /. (1->3)'''
<small>Out[2]=</small> 2 </code>
 
Questo succede perché ha avuto luogo una valutazione trasparente dell'espressione <code>ReplaceAll[Plus[1,1],Rule[1,3]]</code> prima che la regola di sostituzione invocata da ReplaceAll potesse essere applicata. Il kernel ha infatti valutato gli argomenti di ReplaceAll prima di chiamare tale funzione. Il risultato è stato che ReplaceAll ha avuto la seguente sintassi di chiamata:
 
<code> ReplaceAll[2, Rule[1,3]] </code>
 
e, non potendo trovare il simbolo 1, non ha sortito alcun effetto.
Line 163 ⟶ 159:
====== Esempio pratico ======
Un esempio non banale di come la valutazione trasparente dell'intestazione possa portare a risultati in apparente contraddizione con quelli attesi è il seguente: uno dei modi per calcolare la derivata simbolica di una funzione in Mathematica è tramite la forma postfissa dell'operatore Derivative; se f[x] è la funzione della variabile x, allora la derivata è data da f'[x]. Questa operazione è equivalente alla forma in notazione prefissa Derivative[1][f][x], che consiste di una funzione della variabile x con intestazione Derivative[1][f]. Quando si valuta l'espressione, Mathematica procede a elaborare l'intestazione, calcolando la derivata prima della funzione pura f e poi la valuta in corrispondenza dell'argomento (in questo caso x). Ad esempio, se f è la funzione speciale seno integrale si ha
 
<code>
<small>In[3]:=</small> '''SinIntegral'[x]'''
<small>Out[3]=</small> Sin[x]/x </code>
 
Se però si vuole calcolare la derivata della funzione SinIntegral[x^2], la seguente valutazione
 
<code>
<small>In[4]:=</small> '''SinIntegral'[x^2]'''
<small>Out[4]=</small> Sin[x^2]/x^2 </code>
 
fornisce un risultato che non concorda con le regole di derivazione composta di una funzione. Questo perché l'intestazione è stata valutata senza tener conto degli argomenti della funzione. Il risultato dell'operazione è infatti la derivata funzionale del seno integrale valutata in corrispondenza del valore x^2.
Per ottenere un risultato in accordo con la regola di derivazione delle funzioni composte è necessario utilizzare il comando D[expr,var] in cui si specifica la variabile rispetto alla quale si deriva:
 
<code>
<small>In[5]:=</small> '''D[SinIntegral[x^2],x]'''
<small>Out[5]=</small> 2 Sin[x^2]/x </code>
 
==== La riduzione a forma normale ====
Line 199 ⟶ 195:
=== Manipolazione delle espressioni ===
Uno dei principi guida di Mathematica è la struttura unificata presente dietro quasi tutti gli oggetti rappresentabili in Mathematica. Ad esempio se inseriamo l'espressione <math>x^4+1</math>, essa verrà rappresentata come se fosse stato scritto:
 
<code>
<small>In[1]:=</small> '''x^4 + 1'''
<small>Out[1]=</small> 1+x<sup>4</sup> </code>
 
Comunque se il comando <kbd>FullForm</kbd> è utilizzato in questa espressione:
 
<code>
<small>In[2]:=</small> '''FullForm[x^4 + 1]'''
<small>Out[2]=</small> Plus[1, Power[x, 4]] </code>
 
Quasi tutti gli oggetti in Mathematica hanno la forma base ''head''[''e''<sub>1</sub>, ''e''<sub>2</sub>, ''...''] (che può anche essere visualizzata o inserita in qualche altro stile). Per esempio, la ''head'' dell'esempio precedente è <kbd>Plus</kbd>, a simboli come ''x'' hanno la forma <kbd>Symbol["x"]</kbd>. Anche le liste hanno questa struttura, dove la ''Head'' è <kbd>List</kbd>.
 
Questo principio permette alle ordinarie espressioni che non hanno nulla a che fare con le liste, di contenere operatori relativi alle liste:
 
<code>
<small>In[3]:=</small> '''Expand[(Cos[x] + 2 Log[x^11])/13]<nowiki>[[2, 1]]</nowiki>'''
<small>Out[3]=</small> 2/13 </code>
Può anche avvenire il contrario—Le liste possono essere modificate con gli operatori normali:
 
<code>
<small>In[4]:=</small> '''Map[Apply[Log, #] &, {{2, x}, {3, x}, {4, x}}]'''
<small>Out[4]=</small> {Log[x]/Log[2], Log[x]/Log[3], Log[x]/Log[4]} </code>
 
Dove la funzione <kbd>Apply</kbd> cambia la ''Head'' del suo secondo argomento in quella del primo.
Line 223 ⟶ 219:
==== Esempi ====
Il seguente esempio di codice Mathematica trova il [[determinante]] di una [[matrice]] 6&times;6 i cui elementi ''i'', ''j''-esimi contengono ''ij'' e gli elementi nulli sono sostituiti con 1.
 
<code>
<small>In[1]:=</small> '''Det[Array[Times, {6, 6}, 0] /. 0 -> 1]'''
<small>Out[1]=</small> 0 </code>
 
Quindi il determinante di questa matrice è 0.
 
Il seguente calcolo numerico trova la radice dell'equazione ''e''<sup>''x''</sup> = ''x''<sup>2</sup> + 2, partendo dal punto ''x'' = -1.
 
<code>
<small>In[2]:=</small> '''FindRoot[Exp[x] == x^2 + 2, {x, -1}]'''
<small>Out[2]=</small> {x -> 1.3190736768573652} </code>
 
== La programmazione in Mathematica ==
Line 239 ⟶ 235:
 
L'approccio più sintetico è quello di utilizzare una delle varie funzioni specializzate:
 
<code>
<small>In[3]:=</small> '''Array[GCD, {5, 5}]'''
<small>Out[3]=</small> {{1, 1, 1, 1, 1}, {1, 2, 1, 2, 1}, {1, 1, 3, 1, 1}, {1, 2, 1, 4, 1}, {1, 1, 1, 1, 5}} </code>
 
Ci sono almeno altri tre modi di fare la stessa cosa:
 
<code>
<small>In[4]:=</small> '''Table[GCD[x, y], {x, 1, 5}, {y, 1, 5}]'''
<small>Out[4]=</small> {{1, 1, 1, 1, 1}, {1, 2, 1, 2, 1}, {1, 1, 3, 1, 1}, {1, 2, 1, 4, 1}, {1, 1, 1, 1, 5}} </code>
 
Un approccio in stile APL:
 
<code>
<small>In[5]:=</small> '''Outer[GCD, Range[5], Range<nowiki>[[5]]</nowiki>'''
<small>Out[5]=</small> {{1, 1, 1, 1, 1}, {1, 2, 1, 2, 1}, {1, 1, 3, 1, 1}, {1, 2, 1, 4, 1}, {1, 1, 1, 1, 5}} </code>
 
<kbd>Outer</kbd> corrisponde all'operatore prodotto esterno, <kbd>Range</kbd> corrisponde all'[[operatore iota]].
 
Un approccio iterativo:
 
<code>
<small>In[6]:=</small>''' l1 = {}; (* inizializza come lista vuota,'''
'''dato che in conclusione vogliamo una lista *)'''
Line 266 ⟶ 263:
'''(* appende la sottolista, cioè la riga *)'''
''']; l1'''
<small>Out[6]=</small> {{1, 1, 1, 1, 1}, {1, 2, 1, 2, 1}, {1, 1, 3, 1, 1}, {1, 2, 1, 4, 1}, {1, 1, 1, 1, 5}} </code>
 
Notare come questa soluzione sia considerevolmente più lunga delle altre.