Aggiornato per Mathematica versione 11

Equazioni

Gianluca Gorni
Università di Udine, Dipartimento di Matematica e Informatica

Ultima modifica: 11 gennaio 2018

Questo file è concepito principalmente per essere letto interattivamente su schermo. Per questo, e anche per risparmiare spazio, gli output di solito sono omessi. L'utente che legge da schermo li deve rigenerare mandando in esecuzione le celle di input una alla volta.
Qualcuno vorrà stampare per leggere su carta: in tal caso apra i gruppi di celle ed esegua tutte le celle prima di stampare. Le celle si possono eseguire tutte in un sol colpo col menu Evaluation > Evaluate Notebook.

Inizializzazione

Inizializzazione consigliata:

SetOptions[$FrontEnd,CommonDefaultFormatTypes->{"Output"->StandardForm}];

Distinguere fra assegnazione (=) ed equazione (==)

Chiedo a Mathematica se 3=3:

3=3

Cosa vuol dire questo messaggio? Vuol dire che noi scrivendo 3=3 chiediamo a Mathematica di assegnare il valore 3 al secondo membro all'oggetto 3 che sta al primo membro. Tuttavia Mathematica permette di assegnare valori solo a variabili. L'oggetto 3 al primo membro non è una variabile, ma un "raw object" , una costante.
Un esempio in cui i due membri sono diversi:

3=4

Per chiedere a Mathematica se 3=3 la sintassi giusta è col doppio uguale (Equal):

3==3

3==4

Quando Mathematica incontra un doppio uguale, salvo avviso contrario non esegue sui due membri se non le trasformazioni che farebbe se incontrasse i due membri da soli, cioè in genere niente o quasi:

x+x+y==z

(x^2)==2

a==a

Se i due membri non vengono identici carattere per carattere, Mathematica restituisce l'uguaglianza senza pronunciarsi se sia vera o falsa:

(((x+y))^2)==(x^2)+2x y+(y^2)

(a^2)-(b^2)==(a-b)(a+b)

Per capire se un'uguaglianza è un'indentità si può provare con Simplify:

Simplify[(((x+y))^2)==(x^2)+2x y+(y^2)]

Simplify[(a^2)-(b^2)==(a-b)(a+b)]

Comunque l'uso più comune del doppio uguale è per le equazioni, all'interno di comandi come Reduce e Solve.

Equazioni risolte passo-passo

Conti come questi si possono anche fare "manualmente" manipolando equazioni. Prima di tutto carichiamo le seguenti definizioni ausiliarie:

Unprotect[Plus,Power,Times,Factor,Or,Equal];

((a_==b_)+c_):=(a+c==b+c);
((a_==b_)*c_):=(a*c==b*c);
(a_==b_)^n_:=(a^n==b^n);
Factor[a_==b_]:=Factor[a]==Factor[b];
ExpandAll[Or[a_,b__]]^:=Or@@ExpandAll[{a,b}];
ExpandAll[Equal[a_,b_]]^:=Equal@@ExpandAll[{a,b}];

Protect[Plus,Power,Times,Factor,Or,Equal];

prodottiNotevoli[espr_]:=espr/.{((a_)^2)-((b_)^2):>(a-b) (a+b),((a_)^2)+b_?Negative:>(a-(Sqrt[-b])) (a+(Sqrt[-b]))};
annullamentoDelProdotto[espr_]:=espr/.(a_Times==0):>Or@@Map[#==0&,List@@a];
estraiDaOr=#1/.HoldPattern[Or[a__]]:>{a}[[First[#2]]]&;
distribuisci[espr_]:=espr/.{(p:{(_Or+_.)..}):>Or@@MapIndexed[estraiDaOr,p],(p:{(_Or*_.)..}):>Or@@MapIndexed[estraiDaOr,p]};

Esempio 1 (equazione lineare)

Poi poniamoci il problema di risolvere l'equazione 3x+4==0:

Clear[x];
3x+4==0

Togliamo 4 da ambo i membri: usiamo il simbolo %, che sta per l'ouput immediatamente precedente:

Clear[x];
3x+4==0;
%-4

Dividiamo ambo i membri per 3:

Clear[x];
3x+4==0;
%-4;
%/3

L'equazione è risolta! Questa è una soluzione ed è l'unica perché i passaggi che abbiamo fatto sono tutti reversibili:

Clear[x];
x==-(4/3);
%*3;
%+4

Esempio 2 (equazione quadratica)

Prendiamo l'equazione (x^2)+2x-3==0:

(x^2)+2x-3==0

Con l'intenzione di mettere in evidenza un quadrato perfetto, aggiungiamo 4 ad ambo i membri:

(x^2)+2x-3==0;
%+4

Fattorizziamo:

(x^2)+2x-3==0;
%+4;
%//Factor

Portiamo 4 al primo membro:

(x^2)+2x-3==0;
%+4;
%//Factor;
%-4

Scomponiamo col prodotto notevole:

(x^2)+2x-3==0;
%+4;
%//Factor;
%-4;
%//prodottiNotevoli

Applichiamo la regola dell'annullamento del prodotto:

(x^2)+2x-3==0;
%+4;
%//Factor;
%-4;
%//prodottiNotevoli;
%//annullamentoDelProdotto

Isoliamo x nelle due equazioni aggiungendo rispettivamente 1 e -3 da ambo i membri:

(x^2)+2x-3==0;
%+4;
%//Factor;
%-4;
%//prodottiNotevoli;
%//annullamentoDelProdotto;
%+{1,-3}//distribuisci

Ecco risolta l'equazione! Queste sono tutte e sole le soluzioni perché i passaggi che abbiamo fatto sono tutti reversibili.

Equazioni con soluzioni in forma logica: Reduce

Un comando che risolve le equazioni (e altro ancora) è Reduce, che presenta le soluzioni in forma di espressione logica:

Reduce[(x^2)==2,x]

Reduce[(x^2)==2,x]//StandardForm

Nella tavolozza, Reduce è nascosto alla fine di "More":

Possiamo anche non indicare la variabile rispetto a cui risolvere, e lasciarla decidere a Mathematica:

Reduce[(x^2)==2]

In StandardForm, la doppia sbarra verticale in x==-(Sqrt[2])||x==(Sqrt[2]) è la disgiunzione logica "oppure", Or.
Il simbolo ∨ per la disgiunzione si può inserire con Esc||Esc oppure EscorEsc.
Il simbolo ∧ per la congiunzione si può inserire con Esc&&Esc oppure EscandEsc.
Nella tavolozza i simboli logici sono sotto Typesetting, sezione ×, penultima riga al centro:

Riassumendo:

({{significato, Or, And}, {simbolo, ∨, ∧}, {stile 1, Esc||Esc, Esc&&Esc}, {stile 2, EscorEsc, EscandEsc}})

Chi ha familiarità col LATEX stia attento che le relazioni binarie ⋁ e ⋀ che si ottengono coi nomi LATEX: Esc\veeEsc, Esc\wedgeEsc non sono sinonimi di Or e And. L’utente è libero di usarle per altri significati.

Un sistema di equazioni:

Reduce[{(x^2)-y==2,x+y==0},{x,y}]

Reduce[{(x^2)-y==2,x+y==0},{x,y},Backsubstitution->True]

Nella StandardForm i doppi ampersand in (x==-2&&y==2)||(x==1&&y==-1) sono la congiunzione logica "e". La congiunzione "e" ha la precedenza nella notazione rispetto alla disgiunzione "oppure". Quindi il risultato va interpretato come (x==-2&&y==2)||(x==1&&y==-1).

Dando una lista di equazioni fra graffe, si intende il sistema di equazioni, cioè si cercano i valori delle incognite che rendono vere tutte le equazioni contemporaneamente. Invece che mettere le equazioni in una lista, si può anche collegarle con la congiunzione logica, il significato è lo stesso:

Reduce[(x^2)-y==2&&x+y==0,{x,y}]

Nel caso di equazioni contenenti parametri, Reduce elenca tutti i casi speciali:

Reduce[a*x==b,x]

L'output si può interpretare così:
1) quando a=0 e b=0 tutti gli x sono soluzione (b==0∧a==0 non impone nessuna restrizione su x);
2) quando a≠0 la soluzione è unica e vale x=b/a.
3) il caso a=0 e b≠0 non viene riportato perché non ha soluzioni; in una disgiunzione, una componente falsa si può cancellare.

Reduce risolve l'equazione di secondo grado a (x^2)+b x+c==0 in tutti i casi, e non soltanto nel caso "generico" a≠0:

Reduce[a*(x^2)+b*x+c==0,x]

Reduce[d*(x^3)+a*(x^2)+b*x+c==0,x]

Reduce accetta anche disuguaglianze:

Reduce[{a*(x^2)+b*x+c==0,a≠0},x]

Reduce[a*(x^2)+b*x+c==0∧a≠0,x]

Si può ottenere il simbolo di disuguaglianza (Unequal) scrivendo in successione !=
In generale il punto esclamativo prima di un'espressione logica equivale alla negazione:

1≠0

!(a==0)

(Non fare confusione col fattoriale).

Cosa può succedere se non si specifica la variabile rispetto a cui risolvere?

Reduce[a*(x^2)+b*x+c==0]

Reduce è un comando molto potente, e risolve per esempio anche disequazioni:

Reduce[(x^2)+3x-2<0,x]

Nel caso di disuguaglianze, Reduce assume che le variabili siano reali. Nelle equazioni invece le variabili sono complesse, a meno che non si dichiari esplicitamente che si sta lavorando su ℝ:

Reduce[(x^3)+2x+1==0,x]

Reduce[(x^3)+2x+1==0,x,Reals]

Si può anche chiedere di risolvere sugli interi:

Reduce[2x-5y==1,{x,y},Integers]

Reduce[(x^2)+(y^2)==(z^2),{x,y,z},Integers]

Equazioni risolte con regole di sostituzione: Solve

Per risolvere le equazioni algebriche il comando principale è Solve, che prende come primo argomento l'equazione (o la lista delle equazioni) da risolvere e come secondo argomento l'incognita (o la lista delle incognite):

Solve[x-1==2-x,x]

Reduce[x-1==2-x,x]

Si trova Solve facilmente nella tavolozza:

Ci vuole del tempo per abituarsi al modo in cui Solve formatta le soluzioni delle equazioni. Nella matematica tradizionale la soluzione di x-1==2-x si scrive come x=3/2, con l'uguaglianza. Invece Mathematica la presenta come una regola di sostituzione x->3/2. Come se non bastasse, ci mette attorno due livelli di parentesi graffe: {{x->3/2}}. Perché tutto ciò?
Lo scopo è di mettere la soluzione in un formato sostituibile immediatamente in altre formule. Supponiamo che mi interessi il valore di (x^2)-2 piuttosto che la x in sé e per sé. Allora basta che scriva

(x^2)-2/.Solve[x-1==2-x,x]

Oppure, se devo riusare più volte la soluzione, le do un nome:

sol=Solve[x-1==2-x,x];
(x^2)-2/.sol

x-5/.sol

Reduce[x-1==2-x,x]

x/.sol

Prendiamo l'equazione di secondo grado con parametri e confrontiamo i risultati di Reduce e di Solve:

Reduce[a (x^2)+b x+c==0,x]

Solve[a (x^2)+b x+c==0,x]

Allora, quando usare Reduce e quando Solve?

Style[Grid[{{"",Reduce,Solve},{"vantaggi","soluzione completa di tutti i casi, logicamente ineccepibile",
"risultato logicamente semplice, più digeribile, di struttura prevedibile, che si può usare immediatamente"},
{"svantaggi","la soluzione è spesso un'espressione logica complicatissima di struttura imprevedibile, da cui è non banale estrarre informazioni","la soluzione può essere falsa per certi valori dei parametri"}}],FontFamily->"Times"]

With[{eq=(a (x^2)+b x+c==0)},TabView[{equazione->eq,Reduce->Reduce[eq,x],Solve->Solve[eq,x]},Alignment->Center]]

Equazioni con più incognite o con più soluzioni: liste di liste

E le parentesi graffe a cosa servono? Beh, ricordiamoci che oltre alle equazioni singole ci sono anche i sistemi in più incognite, e non sempre la soluzione è unica. La situazione generale è di avere più di una soluzione, ognuna delle quali dà il valore di più incognite. Mathematica struttura il risultato come una lista di liste di regole di sostituzione: ogni lista al primo livello è una soluzione, espressa come lista di regole di sostituzione per le singole incognite.
Un esempio di un'equazione in un'incognita con due soluzioni:

Reduce[(x^2)==4]

Solve[(x^2)==4]

Solve[(x^2)==4]//TreeForm

Il sistema di due equazioni in due incognite  {({{x+y==1}, {x-y==2}}) si imposta con le due equazioni fra graffe e le due incognite pure fra graffe. Questo sistema ha una sola soluzione:

Reduce[{x+y==1,x-y==2},{x,y}]

Solve[{x+y==1,x-y==2},{x,y}]

Solve[{x+y==1,x-y==2},{x,y}]//TreeForm

With[{eq={x+y==1,x-y==2}},TabView[{sistema->Column@eq,Reduce->Reduce[eq,{x,y}],
Solve->Solve[eq,{x,y}]},Alignment->Center]]

Il sistema di secondo grado {({{(x^2)-y==1}, {x+y==0}}) con due equazioni in due incognite ha due soluzioni:

Reduce[{(x^2)-y==2,x+y==0},{x,y}]

Solve[{(x^2)-y==2,x+y==0},{x,y}]

x-y/.Solve[{(x^2)-y==2,x+y==0},{x,y}]

x/.Solve[{(x^2)-y==2,x+y==0},{x,y}]

{x,y}/.Solve[{(x^2)-y==2,x+y==0},{x,y}]

Le soluzioni espresse come lista di coppie di uguaglianze:

Solve[{(x^2)-y==2,x+y==0},{x,y}]/.Rule->Equal

Solve[{(x^2)-y==2,x+y==0},{x,y}]

In questo caso  non ci dà la y esplicita, ma la esprime in funzione di x:

Reduce[{(x^2)-y==2,x+y==0},{x,y}]

Se vogliamo esplicitare la y dobbiamo usare l'opzione Backsubstitution:

Reduce[{(x^2)-y==2,x+y==0},{x,y},Backsubstitution->True]

With[{eq={(x^2)-y==2,x+y==0}},TabView[{equazioni->Column@eq,
Reduce->Reduce[eq,{x,y},Backsubstitution->True],
Solve->Solve[eq,{x,y}]},Alignment->Center]]

Un'equazione senza soluzioni:

Reduce[x-1==x+1,x]

Solve[x-1==x+1,x]

Un'equazione in cui tutti i valori di x sono soluzioni:

Reduce[x-1==x-1,x]

Solve[x-1==x-1,x]

Un'equazione con soluzioni non reali:

Reduce[(x^2)==-1,x]

Solve[(x^2)==-1,x]

In un sistema sottodeterminato, con infinite soluzioni, Mathematica esprime alcune delle variabili in termini delle altre:

Reduce[{x-y+z==0,2x+y+z==1},{x,y,z}]

Reduce[{x-y+z==0,2x+y+z==1},{y,z,x}]

Solve[{x-y+z==0,2x+y+z==1},{x,y,z}]

Le soluzioni come lista di triple, parametrizzate:

{x,y,z}/.Solve[{x-y+z==0,2x+y+z==1},{x,y,z}]

{x,y,z}/.Solve[{x-y+z==0,2x+y+z==1},{z,y,x}]

With[{sis={x-y+z==0,2x+y+z==1}},TabView[{sistema->Column[sis],"parametro x"->Quiet@Solve[sis,{x,y,z}],"parametro y"->Quiet@Solve[sis,{y,x,z}],"parametro z"->Quiet@Solve[sis,{z,y,x}]},Alignment->Center]]

Osservate che quando si usa l'output di Solve in una sostituzione (espressione/.Solve[...]), il risultato è una lista: il primo elemento è il risultato della sostituzione con la prima soluzione, il secondo elemento viene dalla seconda sostituzione, eccetera:

x+1/.Solve[(x^2)==4,x]

Il -1 viene dalla soluzione x->-2, mentre il 3 viene dall'altra soluzione x->2.

Se desideriamo i valori delle soluzioni di Solve, senza le frecce, non ci vuole molto:

x/.Solve[(x^2)==4,x]

Reduce[(x^2)==4,x]

Posso isolare la prima delle due soluzioni di Solve[x^2==4,x] scrivendo Solve[x^2==4,x][[1]], la seconda con Solve[x^2==4,x][[2]]seconda. Questo è un meccanismo generale: l'i-esimo elemento di una lista={(Subscript[x, 1]),(Subscript[x, 2]),...,(Subscript[x, n])} si estrae con lista[[i]]:

Solve[(x^2)==4,x]

Solve[(x^2)==4,x][[1]]

Solve[(x^2)==4,x][[2]]

sol=Solve[(x^2)==4,x];
sol[[1]]

Problemini risolti

Geometria

Manipulate[Graphics[{{Yellow,Rectangle[{0,0},p]},Line[{{0,0},{First@p,0},p,{0,Last@p},{0,0}}],Text[Row[{"area","=",Times@@p}],p/2],Text[Row[{"base","=",p//First}],{First@p/2,0},{0,-1.5}],
Text[Row[{"altezza","=",p//Last}],{0,Last@p/2},{0,1.5},{0,1}],
If[aiuto,{Dashed,Line[{{15,0},{0,15}}],Text[Row[{"base","+","altezza","=",15}],{15,0},{1,-1.5},{1,-1}],Line[{{0,-3},{20,20-3}}],Text[Row[{"base","-","altezza","=",3}],{20,20-3},{1,-1.5},{1,1}],Line[{{0,3},{20,20+3}}],Text[Row[{"altezza","-","base","=",3}],{20-3,20},{1,1.5},{1,1}]},Sequence@@{}]},PlotRange->{{0,20},{0,20}},PlotLabel->Column[{Row[{"base","+","altezza","=",Plus@@p,Spacer[10],"(obiettivo: 15)"}],Row[{"base","-","altezza","=",Subtract@@p,Spacer[10],"(obiettivo: ±3)"}]}],PlotRangeClipping->True],
{{p,{10,12}},Locator},{{aiuto,False,"aiuto!"},{False,True},ControlPlacement->Bottom}]

Problemino: in un rettangolo la somma dei due lati è 15 e la differenza è 3. Quant'è l'area?
Soluzione. Chiamiamo a,b le lunghezze dei due lati. Il sistema da risolvere è {({{a+b==15}, {a-b==3}}). Il comando per risolverlo è Solve[{a+b==15, a-b==3},{a,b}]. Però qui non sono tanto i valori di a e b che ci interessano, ma piuttosto l'area a b. Possiamo avere l'area direttamente con

eq={a+b==15,a-b==3};
sol=Solve[eq,{a,b}];
a*b/.sol[[1]]

Naturalmente possiamo chiedere la differenza b-a==3, invece di a-b==3:

Solve[{a+b==15,b-a==3},{a,b}]

Si possono combinare due equazioni con un Or:

Solve[{a+b==15,b-a==3||a-b==3},{a,b}]

Approfondimento

Potremmo pensare di inglobare le due equazioni b-a==3 e a-b==3 in un'unica equazione con il valore assoluto Abs:

Solve[{a+b==15,Abs[b-a]==3},{a,b}]

Se diamo l'equazione col valore assoluto a Reduce invece che a Solve, abbiamo un risultato che potrebbe essere inaspettato:

Reduce[{a+b==15,Abs[b-a]==3},{a,b}]

Che vuol dire? Beh, Reduce ha risolto l'equazione fra i complessi, dove pare che abbia infinite soluzioni, che sono le coppie di punti diametralmente opposti del cerchio di centro {15/2,0} e raggio 3/2:

With[{semicerchioX=(Sqrt[-(x^2)+15 x-54]),semicerchioC=(Sqrt[-(c^2)+15 c-54]),centro={15/2,0}},
Manipulate[ParametricPlot[{{x,-semicerchioX},{15-x,semicerchioX}},{x,6,9},AspectRatio->Automatic,Epilog->{PointSize[Large],Point[{c,-semicerchioC}],Text["a",{c,-semicerchioC},{4,0}],Point[{15-c,semicerchioC}],
Text["b",{15-c,semicerchioC},{4,0}]},Axes->False,Frame->True,PlotRangePadding->Scaled[.05]],
{{c,6,"Re(a)"},6,9}]]

Dal 2017 esiste anche la variante RealAbs, che è il valore assoluto fra numeri reali:

Reduce[{a+b==15,RealAbs[b-a]==3},{a,b}]

Un vantaggio di RealAbs è che è derivabile (sui reali):

D[RealAbs[x],x]

mentre Abs non è derivabile (in senso complesso):

D[Abs[z],z]

Geometria analitica

Clear[x,y];
Plot[Tooltip[(x^2)-3,y==(x^2)-3],{x,-3,3},Epilog->{Tooltip[{Red,Circle[{0,1/2},(Sqrt[17])/2]},(x^2)+(y^2)-y-4==0],Tooltip[Point[{x,y}],{x,y}]/.Solve[{y==(x^2)-3,(x^2)+(y^2)-y-4==0},{x,y}]},PlotRange->{{-3,3},{-3.5,3}},AspectRatio->Automatic]

Problemino: trovare le intersezioni fra la parabola y=(x^2)-3 col cerchio (x^2)+(y^2)-y-4=0.
Soluzione:

eq={y==(x^2)-3,(x^2)+(y^2)-y-4==0};
sol=Solve[eq,{x,y}]

Se si preferiscono i risultati in termini di coppie {x,y}, si può scrivere

{x,y}/.sol

Una lista di liste in forma tradizionale viene spesso formattata come matrice. Se vogliamo vedere le parentesi graffe trasformiamo l'output con il menu Cell > Convert To > StandardForm Display, oppure scriviamo

StandardForm[{x,y}/.sol]

Se avessimo usato Reduce, estrarre le coppie sarebbe più difficile, specialmente senza Backsubstitution:

eq={y==x^2-3,x^2+y^2-y-4==0};
Reduce[eq,{x,y}]

Reduce[eq,{x,y},Backsubstitution->True]

Geometria analitica

Manipulate[Graphics[{PointSize[Large],Point[{{0,0},{1,1},{-1,2}}],If[soluz,{Red,Dashed,Opacity[.5],Thick,Circle[{-1/6,7/6},5/(3(Sqrt[2]))]},Sequence@@{}],Circle[centro,raggio]},Frame->True,PlotRange->{{-2,2},{-1,3}},PlotLabel->Row[{"equazione del cerchio: ",Identity[((EuclideanDistance[{x,y},centro])^2)-(raggio^2)/.Abs->Identity]==0}]],
{{centro,{0,3/2}},Locator},
{{raggio,1},0,2},
{{soluz,False,"mostra la soluzione"},{True,False}}]

Problemino: trovare centro e raggio del cerchio passante per i punti (0,0), (1,1), (-1,2).
Soluzione: l'equazione generica del cerchio di centro (a,b) e raggio r è (((x-a))^2)+(((y-b))^2)==(r^2). La richiesta che il cerchio passi per (0,0) si scrive con

Clear[x,y,a,b,r]

equazioneCerchio=((((x-a))^2)+(((y-b))^2)==(r^2))

eq1=equazioneCerchio/.{x->0,y->0}

Analogamente il passaggio per gli altri due punti si scrive come

eq2=equazioneCerchio/.{x->1,y->1}

eq3=equazioneCerchio/.{x->-1,y->2}

Possiamo ottenere le tre condizioni con una singola regola di sostituzione:

condizioni=equazioneCerchio/.{{x->0,y->0},{x->1,y->1},{x->-1,y->2}}

{eq1,eq2,eq3}

Abbiamo ottenuto tre equazioni nelle tre incognite a,b,r. Possiamo risolverle:

Solve[condizioni,{a,b,r}]

Le due soluzioni hanno le stesse a,b ma r opposti. La prima soluzione ha r negativo, che non avrebbe senso, però nell'equazione del cerchio r viene elevato al quadrato, quindi alla fine viene la stessa cosa. La seconda soluzione invece è accettabile tranquillamente. Conclusione: esiste un solo cerchio che passa per i punti (0,0), (1,1), (-1,2): ha centro in (-(1/6),(7/6)) e raggio (5/(3 (Sqrt[2]))). L'equazione è:

equazioneCerchio/.Solve[condizioni,{a,b,r}][[2]]

equazioneCerchio/.Solve[condizioni,{a,b,r}][[2]]//N

Possiamo portare a primo membro e scriverle in forma espansa:

(((x-a)^2+(y-b)^2-r^2/.Solve[condizioni,{a,b,r}][[2]])//ExpandAll//Together//Numerator)==0

L'equazione viene senza termine noto. Cosa prevedibile, dato che il cerchio passa per (0,0).

Si possono inglobare le condizioni di positività r>0 nel comando stesso (usando per esempio Append):

Reduce[condizioni,{a,b,r}]

Reduce[Append[condizioni,r>0],{a,b,r}]

Solve[Append[condizioni,r>0],{a,b,r}]

Equazioni non algebriche

Solve è progettato principalmente per le equazioni algebriche. Equazioni che contengono funzioni non algebriche (esponenziali, logaritmi, funzioni trigonometriche...) non sempre sono risolte completamente. 
Un esempio in cui Solve dà la soluzione completa:

Solve[Log[x]==1,x]

Reduce usa il formato logico:

Reduce[Log[x]==1,x]

Un’equazione che ha infinite soluzioni complesse:

Reduce[(2^x)==2,x]

Per questa equazione Solve ci dà la famiglia infinita di soluzioni complesse parametrizzate dal parametro intero C[1], inserite in una ConditionalExpression:

Solve[(2^x)==2,x]

Possiamo fissare una soluzione assegnando il parametro:

x/.Solve[(2^x)==2,x]/.C[1]->30

x/.Solve[(2^x)==2,x]/.C[1]->1/2

Solve[(2^x)==2,x,Reals]

Plot[{(2^x),2},{x,-3,3}]

L'equazione Sin[x]==0 ha infinite soluzioni: tutti i numeri della forma x=n π al variare di n∈ℤ.

Plot[Sin[x],{x,-4Pi,4Pi}]

Reduce le parametrizza non nel modo più semplice, comunque il risultato è corretto:

Reduce[Sin[x]==0,x]

Plot[{Sin[x],1/2},{x,-4Pi,4Pi}]

Reduce[Sin[x]==1/2,x]

Solve usa una ConditionalExpression:

Solve[Sin[x]==0,x]

x/.Solve[Sin[x]==0,x]/.C[1]->-3

Il grafico del seno incontra la bisettrice del secondo e quarto quadrante soltanto nell'origine:

Plot[{Sin[x],-x},{x,-10,10}]

Solve rinuncia a risolvere l'equazione:

Solve[Sin[x]==-x,x]

Reduce pure rinuncia:

Reduce[Sin[x]==-x,x]

però se aggiungo una disuguaglianza alla x sa risolvere l'equazione:

Reduce[Sin[x]+x==0&&-10<x<10,x]

Solve[Sin[x]+x==0&&-10<Abs[x]<10,x]

Graphics[{Point[ReIm[x]]/.Solve[Sin[x]+x==0&&-10<Abs[x]<10,x],Circle[{0,0},10]},Frame->True,PlotRangePadding->Scaled[.1]]

Similmente, i grafici di y=sin x e di y=x/2 si incontrano in tre punti:

Plot[{Sin[x],x/2},{x,-10,10}]

Reduce rinuncia:

Reduce[Sin[x]==x/2,x]

però se aggiungo una disuguaglianza alla x mi risolvere l'equazione sui reali, in termini di numeri analitici:

Reduce[Sin[x]==x/2&&-10<x<10,x]

Soluzioni complesse a distanza di meno di 10 all’origine:

Reduce[Sin[x]==x/2&&-10<Abs[x]<10,x]

Graphics[{Point[ReIm[x]]/.Solve[Sin[x]==x/2&&-10<Abs[x]<10,x],Circle[{0,0},10]},Frame->True,PlotRangePadding->Scaled[.1]]

Posso calcolare la soluzione con un numero arbitrario di cifre, per esempio diecimila:

miaSol=Root[{#1-2 Sin[#1]&,-1.8954942670339809471436297457457020865234653683728538453579`20.308429486551233}]

N[miaSol,10000]

Soluzioni approssimate

Solve e Reduce sono fatti per dare soluzioni simboliche esatte di equazioni, con metodi rigorosi. A volte però non ci sono metodi esatti per una data equazione, oppure il metodo ci sarebbe, ma è troppo complicato e lento per essere di uso pratico. Si può allora passare a metodi approssimati numerici.
Mathematica ha dei comandi predefiniti che implementano degli algoritmi numerici.

NSolve

Per le equazioni o sistemi polinomiali (o, più in generale, algebriche) c'è il comando NSolve:

NSolve[(x^4)-3(x^3)+x-3==0]

NSolve[(Sqrt[1+(x^2)+3x])==3-x,x]

NSolve[(x^2)-2x+1==0]

Il risultato di NSolve è simile al risultato di N[Solve[]]:

N[Solve[(x^4)-3(x^3)+x-3==0]]

N[Solve[(x^4)-3(x^3)+x-3==0],100]

La precisione di NSolve

Per default NSolve lavora con precisione macchina. In equazioni di grado alto mal condizionate questo può provocare soluzioni poco precise. Prendiamo questo polinomio di grado 30 con radici intere distinte:

pol=Product[x-n,{n,1,30}]//Expand

Se lo risolviamo con precisione macchina abbiamo errori grossolani:

NSolve[pol==0,x]

Se diamo l’opzione WorkingPrecision calcoli sono molto più precisi:

NSolve[pol==0,x,WorkingPrecision->5]

Proviamo a modificare il coefficiente di (x^29) aggiungendogli un ϵ:

polModificato=pol/.a_* (x^29)->(a+ϵ)(x^29)

Calcoliamo le derivate delle 30 radici rispetto al parametro ϵ in ϵ=0:

Table[D[Root[polModificato,x,n],ϵ]/.ϵ->0,{n,1,30}]//N

Vediamo che la maggior parte delle radici ha derivata molto alta. Piccole variazioni di ϵ provocano forti differenze nella radice. Possiamo visualizzare la situazione per esempio con la radice numero 24, facendone il grafico in funzione di ϵ:

Plot[Evaluate[Root[polModificato,x,24]],{ϵ,-(10^(-16)),(10^(-16))},WorkingPrecision->40,PlotRange->All]

FindRoot

Per equazioni anche non algebriche, si può usare FindRoot, che usa metodi iterativi, tipo il metodo di Newton-Raphson. Bisogna assegnare il punto di partenza dell'iterazione.

Per esempio, l'equazione sin x+(e^x)==0 sembra avere una soluzione vicina a x=-0.6:

Plot[Sin[x]+(E^x),{x,-5,1}]

Facciamo partire FindRoot da x = -0.6:

FindRoot[Sin[x]+(E^x)==0,{x,-.6}]

Come vedete, FindRoot dà una lista semplice, non una lista di liste. Questo perché quando il metodo numerico converge, produce una singola soluzione.

FindRoot[Sin[x]+(E^x)==0,{x,-3}]

Confrontiamo coi valori ottenuti con metodi esatti:

Solve[Sin[x]+(E^x)==0&&-4<x<0,x]

Si può anche risolvere un sistema:

FindRoot[{Exp[x-2]==y,(y^2)==x},{{x,1},{y,1}}]

Confrontiamo con le soluzioni esatte:

Solve[{Exp[x-2]==y,(y^2)==x,Abs[x]<3,Abs[y]<3},{x,y}]

RootSearch

C'è un pacchetto aggiuntivo scritto da 	Ted Ersek, e disponibile da http://library.wolfram.com/infocenter/MathSource/4482/
col quale si possono cercare tutte le soluzioni di un'equazione in una variabile che stanno in un intervallo. Il pacchetto va installato seguendo le istruzioni allegate.

Quando lo si vuole usare, si carica il pacchetto:

Needs["Ersek`RootSearch`"]

Si individua l'intervallo in cui cercare le soluzioni:

Plot[Sin[x]+(E^x),{x,-5,1}]

Poi si risolve l'equazione:

RootSearch[Sin[x]+(E^x)==0,{x,-6,1}]

Per funzioni analitiche la funzionalità del pacchetto è replicata ora da Solve e Reduce. RootSearch però funziona bene anche con funzioni non analitiche, come per esempio le soluzioni numeriche di equazioni differenziali.

Equazioni differenziali

DSolve per soluzioni simboliche esatte

Il comando DSolve risolve equazioni differenziali per via simbolica. I dati da fornire a DSolve sono l'equazione (o lista di equazioni, eventualmente con le condizioni iniziali), la funzione incognite (o la lista delle funzioni) incognite, e la variabile indipendente:

Clear[x,t];
DSolve[x'[t]==x[t],x[t],t]

DSolve[lhs==rhs,function,var]

DSolve si trova nella tavolozza:

Aggiungiamo una condizione iniziale:

DSolve[{x'[t]==x[t],x[0]==1},x[t],t]

Un sistema del primo ordine:

DSolve[{x'[t]==-y[t],y'[t]==x[t],x[0]==1,y[0]==0},{x[t],y[t]},t]

Un’equazione del secondo ordine:

DSolve[x''[t]==-x[t],x[t],t]

Un modo di incapsulare la soluzione in una funzione per ulteriori calcoli:

sol[t_]=x[t]/.DSolve[{x'[t]==x[t],x[0]==1},x[t],t]//First

Plot[sol[t],{t,-2,2}]

Fare attenzione se si vuole usare lo stesso simbolo per l’incognita e per la soluzione: DSolve non accetta come incognita un simbolo che è già una funzione, perché non protegge né le incognite né le variabili indipendenti da definizioni esterne:

x[t_]=x[t]/.DSolve[{x'[t]==x[t],x[0]==1},x[t],t]//First
DSolve[{x'[t]==x[t],x[0]==1},x[t],t]
DSolve[{x'[t]==x[t],x[0]==1},x,t]

Quando si inserisce DSolve direttamente dentro Plot , senza dar un simbolo alla soluzione, bisogna avvolgere il primo argomento di Plot con un Evaluate, perché Plot assegna il valore del parametro t prima di calcolare DSolve, ottenendo una cosa senza senso:

Clear[x];
x[t]/.DSolve[{x'[t]==x[t],x[0]==1},x[t],t][[1]]

Plot[x[t]/.DSolve[{x'[t]==x[t],x[0]==1},x[t],t][[1]],{t,-2,2}]

Notare che la variabile indipendente t (e anche la dipendente x) in DSolve non è locale, ma prende valore dall’esterno:

Invece Plot localizza la t:

t=1;
Plot[(t^2),{t,-1,1}]

Clear[t];
Plot[Evaluate[x[t]/.DSolve[{x'[t]==x[t],x[0]==1},x[t],t][[1]]],{t,-2,2}]

Si può usare anche la sintassi in cui la funzione incognita è un simbolo senza la variabile indipendente:

DSolve[{x'[t]==x[t],x[0]==1},x[t],t]

DSolve[{x'[t]==x[t],x[0]==1},x,t]

La versione con incognita senza [t] viene particolarmente buona quando dobbiamo sostituirla in espressioni contenenti derivate. Se sostituisco x[t] con (e^t) la sostituzione non si estende alle derivate di x:

x''[t]-2x'[t]-3x[t]/.x[t]->(E^t)

x''[t]-2x'[t]-3x[t]/.DSolve[{x'[t]==x[t],x[0]==1},x[t],t]

Se invece sostituisco x con la funzione Function[t,(e^t)], la sostituzione si estende alle derivate di x:

x''[t]-2x'[t]-3x[t]/.x->Function[t,(E^t)]

x''[t]-2x'[t]-3x[t]/.DSolve[{x'[t]==x[t],x[0]==1},x,t][[1]]

Un’equazione differenziale in forma non normale può avere più soluzioni:

DSolve[{((x'[t])^2)==x[t],x[0]==1},x,t]

Con la versione 10 di Mathematica è stata aggiunta la funzione DSolveValue, che fa gli stessi calcoli di DSolve ma nell’output mette solo la funzione, senza frecce e graffe:

f=DSolveValue[{x'[t]==x[t],x[0]==1},x,t]

f''[t]

Nella sintassi con x[t] come incognita si può dare un nome alla soluzione così:

g[t_]=DSolveValue[{x'[t]==x[t],x[0]==1},x[t],t]
g''[t]

DSolveValue in caso di più soluzioni ne da una sola:

DSolveValue[{((x'[t])^2)==x[t],x[0]==1},x,t]

DSolve può anche risolvere problemi ai limiti:

DSolve[{x''[t]==-x[t],x[0]==1,x[1]==2},x[t],t]

Mathematica risolve anche alcune classi di equazioni alle derivate parziali:

DSolve[D[u[x,y],x,y]==0,u[x,y],{x,y}]

NDSolve per soluzioni approssimate

In analogia con NSolve , c’è il comando NDSolve, che risolve equazioni differenziali con metodi numerici. La sintassi è la stessa, eccetto che per la variabile indipendente, a cui va assegnato un intervallo:

NDSolve[{x'[t]==x[t],x[0]==1},x[t],{t,0,2}]
Plot[Evaluate[x[t]/.NDSolve[{x'[t]==x[t],x[0]==1},x[t],{t,0,2}]],{t,0,2}]

Le soluzioni sono date in termini di funzioni interpolatorie.

C’è pure NDSolveValue , che fa a meno di graffe e frecce:

NDSolveValue[{x'[t]==x[t],x[0]==1},x,{t,0,2}]

Si può confrontare la soluzione numerica con quella teorica esatta:

solApprossimata=NDSolveValue[{x'[t]==x[t],x[0]==1},x,{t,0,2}];Plot[(E^t)-solApprossimata[t],{t,0,2},PlotRange->All]

Si possono risolvere per via numerica equazioni alle derivatre parziali. Per esempio, ecco la loluzione numerica dell’equazione di Laplace sul disco unitario:

sol=NDSolveValue[{Laplacian[u[x,y],{x,y}]==0,DirichletCondition[u[x,y]==Sin[x y],True]},u,{x,y}∈Disk[]]
Plot3D[sol[x,y],{x,y}∈Disk[]]

Notazione bidimensionale per i sistemi di equazioni

Volete anche voi scrivere i sistemi di equazioni nella forma {({{2x+(x^2)==-1}, {x==3}})? Selezionate la cella seguente e poi andate sul menu Palettes > Generate Palette from Selection: nascerà una tavolozza cliccabile e salvabile.

Grid[{{PasteButton[DisplayForm[StyleBox[RowBox[{StyleBox["{",SpanMaxSize->∞],GridBox[{{"\[Placeholder]"},{"\[Placeholder]"}},ColumnAlignments->Left]}],ShowAutoStyles->False]]],PasteButton[DisplayForm[StyleBox[RowBox[{StyleBox["{",SpanMaxSize->∞],GridBox[{{"\[Placeholder]"},{"\[Placeholder]"},{"\[Placeholder]"}},ColumnAlignments->Left]}],ShowAutoStyles->False]]],PasteButton[DisplayForm[StyleBox[RowBox[{StyleBox["{",SpanMaxSize->∞],GridBox[{{"\[Placeholder]"},{"\[Placeholder]"},{"\[Placeholder]"},{"\[Placeholder]"}},ColumnAlignments->Left]}],ShowAutoStyles->False]]]}},Spacings->0]

PasteButton@DisplayForm@StyleBox[
 RowBox[{
    StyleBox["{",
     SpanMaxSize->Infinity], GridBox[{
      {"\[Placeholder]"},
      {"\[Placeholder]"}
     }]}]]

({{{({{\[Placeholder]}, {\[Placeholder]}}), {({{\[Placeholder]}, {\[Placeholder]}, {\[Placeholder]}}), {({{\[Placeholder]}, {\[Placeholder]}, {\[Placeholder]}, {\[Placeholder]}})}})//InputForm

({{Solve[{({{\[Placeholder]}, {\[Placeholder]}})}//Flatten,{\[Placeholder],\[Placeholder]}], {({{\[Placeholder]}, {\[Placeholder]}, {\[Placeholder]}}), {({{\[Placeholder]}, {\[Placeholder]}, {\[Placeholder]}, {\[Placeholder]}})}})

Esercizi

In un rettangolo la somma dei due lati adiacenti è 15 e la differenza è 3. Quant'è l'area?

Trovare le intersezioni fra le curve di equazione y==(x^2) e 4(x^2)-3(y^2)==1.

Trovare i coefficienti a,b in modo tale che l'ellisse ((x^2)/(a^2))+((y^2)/(b^2))==1 incontri la parabola y==(x^2)-x nei punti di ascisse 1 e (3/4).

Trovare i coefficienti a, b in modo tale che il sistema {({{x+a y==a}, {a x-y==b}}) abbia come soluzione x==1, y==-2.

Per quali valori dei parametri a,b il sistema {({{x-a y==a}, {a x-y==b}})ha una sola soluzione, nessuna soluzione, infinite soluzioni?

Che cosa viene con Solve[(((x^2)-1)/(x-1))==2,x]? Il risultato è giusto? Come si potrebbe spiegare?