Matlab errore codice su calcolo di un punto critico con metodo di Newton
Allora il problema dice questo:

Il mio codice è questo:


Il problema è che mi da questo errore (e inoltre le iterate le calcola male dato che viene Nan):

Ma non capisco effettivamente dove sia l'errore, mi sono messo a rileggerlo e tutto ma non riesco a risolvere, qualcuno mi sa dire? Grazie.

Il mio codice è questo:


Il problema è che mi da questo errore (e inoltre le iterate le calcola male dato che viene Nan):

Ma non capisco effettivamente dove sia l'errore, mi sono messo a rileggerlo e tutto ma non riesco a risolvere, qualcuno mi sa dire? Grazie.
Risposte
Il messaggio di errore ti sta dicendo che stai cercando di accedere alla seconda posizione, ma ciò non è consentito perché la size dell'array è 1.
Se vuoi avere una speranza che il tuo codice venga debuggato, copia e incollato qui usando gli appositi tag [code][/code] e inserendo il codice in mezzo, invece di copiare e incollare immagini (che sarebbe anche sconsigliato
)
Se vuoi avere una speranza che il tuo codice venga debuggato, copia e incollato qui usando gli appositi tag [code][/code] e inserendo il codice in mezzo, invece di copiare e incollare immagini (che sarebbe anche sconsigliato

Nel secondo punto devi usare il teorema fondamentale del calcolo integrale
"feddy":
Nel secondo punto devi usare il teorema fondamentale del calcolo integrale
si infatti l ho usato, ora ti mando il codice, grazie
[quote="feddy"]Il messaggio di errore ti sta dicendo che stai cercando di accedere alla seconda posizione, ma ciò non è consentito perché la size dell'array è 1.
Se vuoi avere una speranza che il tuo codice venga debuggato, copia e incollato qui usando gli appositi tag
Mentre questa è la funzione:
Se vuoi avere una speranza che il tuo codice venga debuggato, copia e incollato qui usando gli appositi tag
[/code] e inserendo il codice in mezzo, invece di copiare e incollare immagini (che sarebbe anche sconsigliato <!-- s:) --><img src="/datas/uploads/forum/emoji/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) --> )[/quote]<br /> <br /> Questo è lo script:<br /> <br /> [code]g=@(t)(exp(-t).*(t-1)); m=15; a=0; b=5; f=@(x)( (x(:,end)-0)/6/m.*( g(x(:,1))+2*sum(g(x(:,3:2:2*m)),2)+4*sum(g(x(:,2:2:2*m)),2)+g(x(:,2*m+1))) ); f1= @(x)(exp(-x).*(x-1)); k=0; t=linspace(a,b,100); for tt=t k=k+1; x(k,:)=linspace(0,tt,2*m+1); end figure(1) hold on plot(t,f(x),'k','LineWidth',4) tolf=1e-10; tola=1e-10; tolr=1e-10; maxit=100; x0=2; [valmax]=minf(f1,x0,tolr,tola,tolf,maxit); plot(valmax,f(valmax),'r')
Mentre questa è la funzione:
function [valmax]=minf(f1,x_0,tollr,tolla,tollf,maxit) valmax=x_0; h=1e-4; y=f1(valmax); d=2*h*y/(f1(valmax+h)-f1(valmax-h)); flag=2; for k=1:maxit valmax=valmax-d; y=f1(valmax); res(k)=abs(y); if abs(y)<tollf, flag=0; return, end if abs(d)<tollr*abs(valmax)+tolla, flag=1; return, end d=2*h*y/(f1(valmax+h)-f1(valmax-h)); display(valmax) end
Cosa succede se selezioni $x_0=1.5$ come guess iniziale?
Qualche appunto "stilistico" che però risultano molto importanti quando si lavora:
-) Se condividi un codice, per quanto piccolo sia, assicurati che chi lo riceve possa essere in grado di farlo girare. In questo caso, mancava un end alla fine della function. Ovviamente non è stato un problema in questo caso, tuttavia in contesti più generali/complicati che ti troverai ad affrontare è fondamentale che quanto condiviso sia immediatamente in grado di girare, in modo da facilitare chi collabora con te.
-) Cercare di non riscrivere tutto da capo. Il metodo di Newton è qualcosa di generico, non andrebbe specializzato a casi particolari. In questo caso, chiunque sia un minimo del settore capisce che stai stimando la derivata prima con un rapporto incrementale. Tuttavia, una buona definizione di quella funzione dovrebbe prevedere il caso in cui l'utente voglia che la derivata prima sia stimata o no. Ovviamente la traccia dice altro ed è giusto che tu la segua. Inoltre, almeno dal punto di vista didattico può essere utilissimo riscrivere molte volte le stesse cose per imparare. Come dicevo prima, però, nella pratica è utile cercare di evitare di riscrivere funzioni identiche in modo da minimizzare la possibilità di errori.
-) Commenta. Non bisogna commentare compulsivamente ogni linea, però le parti più cruciali di un codice andrebbero descritte con parole chiave così che è chiaro a chi legge il tuo codice (MA soprattutto al te futuro) cosa stai facendo. Di nuovo, in questo caso non serve a chi legge visto che è qualcosa di "standard". Ma è bene tenerlo a mente.
Qualche appunto "stilistico" che però risultano molto importanti quando si lavora:
-) Se condividi un codice, per quanto piccolo sia, assicurati che chi lo riceve possa essere in grado di farlo girare. In questo caso, mancava un end alla fine della function. Ovviamente non è stato un problema in questo caso, tuttavia in contesti più generali/complicati che ti troverai ad affrontare è fondamentale che quanto condiviso sia immediatamente in grado di girare, in modo da facilitare chi collabora con te.
-) Cercare di non riscrivere tutto da capo. Il metodo di Newton è qualcosa di generico, non andrebbe specializzato a casi particolari. In questo caso, chiunque sia un minimo del settore capisce che stai stimando la derivata prima con un rapporto incrementale. Tuttavia, una buona definizione di quella funzione dovrebbe prevedere il caso in cui l'utente voglia che la derivata prima sia stimata o no. Ovviamente la traccia dice altro ed è giusto che tu la segua. Inoltre, almeno dal punto di vista didattico può essere utilissimo riscrivere molte volte le stesse cose per imparare. Come dicevo prima, però, nella pratica è utile cercare di evitare di riscrivere funzioni identiche in modo da minimizzare la possibilità di errori.
-) Commenta. Non bisogna commentare compulsivamente ogni linea, però le parti più cruciali di un codice andrebbero descritte con parole chiave così che è chiaro a chi legge il tuo codice (MA soprattutto al te futuro) cosa stai facendo. Di nuovo, in questo caso non serve a chi legge visto che è qualcosa di "standard". Ma è bene tenerlo a mente.
Ho visto che mi da errore quando va a calcolare [code]f(valmax)[\code] alla fine, poichè dice index in position 2 exceeds array bounds. Index must not exceed 1.
Certo, l'errore è quello di prima. Ma controlla il valore di "valmax" ora. Non sarà più NaN
"feddy":
Certo, l'errore è quello di prima. Ma controlla il valore di "valmax" ora. Non sarà più NaN
si è vero, ora mi ha dato $0,5$ poi $0,8$ poi $0,9$ e infine $1$ che è il punto critico, ma come faccio a emttere il punto sul grafico $(valmax,f(valmax))$ se non me lo fa mettere?
Tu stai calcolando lo zero di $f1$, non di $f$... dunque credo dovresti mostrare la storia di convergence per $f1$. Ad ogni modo, il problema è che valmax è un double, mentre f prende una matrice come input (infatti scrivi x(:,etc)).
Oltretutto, quello che ti viene chiesto è un grafico dove in ascissa hai il numero di iterazione e in ordinata il residuo. Dunque dovresti salvarti la storia dei residui dentro il metodo di Newton. Ti torna?
Oltretutto, quello che ti viene chiesto è un grafico dove in ascissa hai il numero di iterazione e in ordinata il residuo. Dunque dovresti salvarti la storia dei residui dentro il metodo di Newton. Ti torna?
"feddy":
Tu stai calcolando lo zero di $f1$, non di $f$... dunque credo dovresti mostrare la storia di convergence per $f1$. Ad ogni modo, il problema è che valmax è un double, mentre f prende una matrice come input (infatti scrivi x(:,etc)).
Oltretutto, quello che ti viene chiesto è un grafico dove in ascissa hai il numero di iterazione e in ordinata il residuo. Dunque dovresti salvarti la storia dei residui dentro il metodo di Newton. Ti torna?
Intendi il terzo punto che mi dice di mettere il punto $(x_k,f_k)$ nella figura 1? (che poi la storia dei residui l ho salvata infatti oh scritto
res(k)=abs(y)però tu credo che stai parlando della parte 2, che effettivamente mi sono scordato di scrivere ma non era quello il problema.
No parlo del secondo punto, dove ti viene chiesta la Figura 2.
Il problema è che la tua $f$ è definita avendo in mente una quadratura composita. Per semplificarti la vita nel plot puoi definirla come
newfe1 = @(x) integral(g,0,x);
Questa chiaramente puoi valutarla per valmax. Ora sto viaggiando quindi non ho il tempo di scriverti una soluzione più elegante
newfe1 = @(x) integral(g,0,x);
Questa chiaramente puoi valutarla per valmax. Ora sto viaggiando quindi non ho il tempo di scriverti una soluzione più elegante

Vabe in caso lo approssimo quel valore con una formula di quadratura, direi che può andar bene, sennò no saprei
il problema è che posso usare solo formule di quadratura (parlo per il corso) e non funzioni prestabilite, quindi devo per forza fare cosi...
D'accordo. In tal caso puoi definire f così:
function I = f(x) %metodo di simpson per integrare g tra 0 e x end
quindi per ogni valore scalare ritorna uno scalare, e in particolare puoi valutare f(valmax). Ad ogni modo è la parte più semplice dell'esercizio... a questo punto è più una questione di gusti che altro

"feddy":
D'accordo. In tal caso puoi definire f così:
function I = f(x) %metodo di simpson per integrare g tra 0 e x end
Quindi tu dici di definire una funzione che mi approssima il valore di dell'integrale in un punto, ma poi dovrei crearci un vettore per fare il grafico? C'è come faccio a fare il grafico di $F$ con delle approssimazioni puntuali, faccio il plot per ogni coppia $(x,y)$? ma così non mi viene una funzione continua..., mentre se intendi di approssimare solo il valore $(x_k,f(x_k))$ allora sono d accordo perchè anche io ho detto cosi prima, ma basare l'intera funzione su approssimazioni puntuali invece che su handle di approssimazioni, non so se possa venire bene....
Se $x$ è il vettore di punti per i quali vuoi conoscere il valore di $F$, non vedo dove sia il problema. E' come quando vuoi plottare il grafico di $f(x)=\sin(x)$. Quello che scrviersti
Ho fatto quanto intendevo nel seguente codice. Non sono abituato a scrivere codice MatLab e ho scritto in fretta dunque lo stile non è il migliore, ma l'output dovrebbe convincerti (In rosso il minimo)
plot(x,sin(x))
Ho fatto quanto intendevo nel seguente codice. Non sono abituato a scrivere codice MatLab e ho scritto in fretta dunque lo stile non è il migliore, ma l'output dovrebbe convincerti (In rosso il minimo)
clear all close all global g; global m; g=@(t)(exp(-t).*(t-1)); m=15; a=0; b=5; x = linspace(0,5,100); v = []; for i=1:length(x) v = [v,f(x(i))]; end plot(x,v,'*') f1= @(x)(exp(-x).*(x-1)); tolf=1e-10; tola=1e-10; tolr=1e-10; maxit=100; x0=1.5; [valmax]=minf(f1,x0,tolr,tola,tolf,maxit); f(valmax) hold on plot(valmax,f(valmax),'*') function [valmax]=minf(f1,x_0,tollr,tolla,tollf,maxit) valmax=x_0; h=1e-4; y=f1(valmax); d=2*h*y/(f1(valmax+h)-f1(valmax-h)); flag=2; for k=1:maxit valmax=valmax-d; y=f1(valmax); res(k)=abs(y); if abs(y)<tollf, flag=0; return, end if abs(d)<tollr*abs(valmax)+tolla, flag=1; return, end d=2*h*y/(f1(valmax+h)-f1(valmax-h)); display(valmax) end end function I=f(x) % Integra da 0 a x la funzione g global g; global m h = ((x)/2)/m; xx = linspace(0,x,m); I = 0; for i = 1:m-1 I = I + h/3*(g(xx(i)) + 4*g((xx(i)+xx(i+1))/2) + g(xx(i+1))); end end
Ah ok, va bene.