Problema con funzione Matlab
Nel programma che sto' scrivendo per il calcolo delle radici di un equazione utilizzando la "regula falsi" pongo:
f=inline(funz);dove funz è una stringa.Più avanti nel programma pongo
f(a(i+1))=f(c(i));.Eseguendo il codice mi da come risultato
The following error occurred converting from double to inline,Input must be a string.Allora ho provato a modicare la funzione così
f(a(i+1))=num2str(f(c(i)));in modo che $f(c(i))$sia trasformata in stringa.Purtoppo continua a darmi errore.

Risposte
"One":
f(a(i+1))=f(c(i));
Questo penso abbia poco senso. a e c penso siano due vettori (di interi? o reali?). Supponiamo che a(i+1)=N e c(i)=M.
Con questa istruzione stai assegnando(?) a f(N) il valore f(M).
Prova a scrivere e spiegare quello che vorresti fare; probabilmente riuscirai da solo a capire quello che non va.
Con questa istruzione stai assegnando(?) a f(N) il valore f(M).
Si...$a$ e $b$ sono reali e rappresentano gli estremi di un intervallo (che inizia da $a$ e finisce in $b$), $c$ viene calcolato con la formula $c(i) = ((f(b(i))*a(i))-(f(a(i))*b(i)))/(f(b(i))-f(a(i)))$.Se risulta $f(b(i))*f(a(i)) <0$ devo porre $f(a(i+1))=f(a(i))$ e $f(b(i+1))=f(c(i))$.L'algoritmo è quello del metodo "regula falsi".
Io questo metodo non l'ho mai usato. Ho letto ora su internet come funziona e da quanto ho capito è un misto tra il metodo di bisezione e il metodo delle secanti. Continuo, comunque, a rimanere perplesso quando dici che devi porre $f(a(i+1)) = f(a(i))$ e $f(b(i+1))=f(c(i))$. Probabilmente sbaglio io dato che non conosco il metodo, ma da un punto di vista matematico mi sembra strana come cosa. Per ora ti consiglio di dare un'occhiata alla sezione Numerical Analysis di
http://en.wikipedia.org/wiki/False_position_method
e al codice che è scritto più avanti.
Su wikipedia in spagnolo c'è anche un codice in Java che ad occhio mi sembra più chiaro di quello in C.
http://en.wikipedia.org/wiki/False_position_method
e al codice che è scritto più avanti.
Su wikipedia in spagnolo c'è anche un codice in Java che ad occhio mi sembra più chiaro di quello in C.
Continuo, comunque, a rimanere perplesso quando dici che devi porre f(a(i+1))=f(a(i)) e f(b(i+1))=f(c(i)).Hai ragione!Ho letto male io l'algoritmo che avevo sul mio libro...e ci ho perso quasi una giornata

Approfitto per chiedere delucidazioni su un errore che mi da ora il programma di cui parlavo prima:
function [x0]=regulafalsi(funz,a,b,max1,toll) f=inline(funz); fprintf('Inizio REGULA FALSI') cont=1; . . . . for (i=1:max1) c(i) = ((f(b(i))*a(i))-(f(a(i))*b(i)))/(f(b(i))-f(a(i))); if (f(c(i))==0) x0=c(i); fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',x0,cont) elseif (f(c(i))*f(a(i))<0) a(i+1)=a(i); b(i+1)=c(i); cont=cont+1; else a(i+1)=c(i); b(i+1)=b(i); cont=cont+1; end if (i>1) if (abs(f(c(i))-f(c(i-1))) < toll) x0=c(i); fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',x0,cont) end end end
Come errore mi da Function definitions are not permitted in this context..Qualcuno sa dirmi perchè?
Io non ottengo quell'errore. Non capisco, inoltre, quei 4 punti dopo cont=1.
Ti consiglio comunque di inserire dopo gli fprintf il comando break in modo che quando trova la soluzione esce dal ciclo e non continui a fare itereazioni.
Ti consiglio comunque di inserire dopo gli fprintf il comando break in modo che quando trova la soluzione esce dal ciclo e non continui a fare itereazioni.
Non capisco, inoltre, quei 4 punti dopo cont=1.
I quattro punti,gli ho messi per saltare una piccola parte di codice secondo me ininfluente.
Io non ottengo quell'errore.
A te funziona?A me continua a darmi il solito errore.
Ti consiglio comunque di inserire dopo gli fprintf il comando break
Ho messo $return$ invece che $break$,perchè mi pare che $break$ lo accettasse solo se dentro un ciclo....
Posto il programma per intero:
function [x0]=regulafalsi(funz,a,b,max1,toll) f=inline(funz); fprintf('Inizio REGULA FALSI') cont=1; if a >= b ('ATTENZIONE: a>=b'), return,end if f(a)*f(b)>0 ('ATTENZIONE: f(a)*f(b) >0'), return,end if (f(a)==0) x0=a; fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',x0,cont) end if (f(b)==0) x0=b; fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',x0,cont) end for (i=1:max1) c(i) = ((f(b(i))*a(i))-(f(a(i))*b(i)))/(f(b(i))-f(a(i))); cont=cont+1; if (f(c(i))==0) x0=c(i); fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',x0,cont) return elseif (f(c(i))*f(a(i))<0) a(i+1)=a(i); b(i+1)=c(i); else a(i+1)=c(i); b(i+1)=b(i); end if (i>1) if (abs(f(c(i))-f(c(i-1))) < toll) x0=c(i); fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',x0,cont) return end end end
A me non dà nessun errore, ma penso che questo possa dipendere dall'esempio su cui stiamo testando.
Prova a postare la tua chiamata della funzione così posso vedere che funzione e valori stai utilizzando.
Comunque, a parte nei tre if iniziali, break funziona perchè sei dentro un ciclo.
Prova a postare la tua chiamata della funzione così posso vedere che funzione e valori stai utilizzando.
Comunque, a parte nei tre if iniziali, break funziona perchè sei dentro un ciclo.
Dati:
Chiamata:
Errore:
Infine ho cambiato il test d'arresto così:
Questo è il programma aggiornato:
funz = '-x^2+5*x+2'; max1=100; toll = 1e-6; a=0; b=6;
Chiamata:
function [x0]=regulafalsi(funz,a,b,max1,toll)
Errore:
function [x0]=regulafalsi(funz,a,b,max1,toll) | Error: Function definitions are not permitted in this context.
Infine ho cambiato il test d'arresto così:
if ((abs(c(i)-c(i-1)) < tollx) || (abs(f(c(i))) < tollf))
Questo è il programma aggiornato:
function [x0]=regulafalsi(funz,a,b,max1,tollx,tollf) f=inline(funz); fprintf('Inizio REGULA FALSI') cont=1; if a >= b ('ATTENZIONE: a>=b'), return,end if f(a)*f(b)>0 ('ATTENZIONE: f(a)*f(b) >0'), return,end if (f(a)==0) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',a,cont) end if (f(b)==0) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',b,cont) end for (i=1:max1) c(i) = ((f(b(i))*a(i))-(f(a(i))*b(i)))/(f(b(i))-f(a(i))); cont=cont+1; if (f(c(i))==0) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',c(i),cont) return elseif (f(c(i))*f(a(i))<0) a(i+1)=a(i); b(i+1)=c(i); else a(i+1)=c(i); b(i+1)=b(i); end if (i>1) if ((abs(c(i)-c(i-1)) < tollx) || (abs(f(c(i))) < tollf)) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0g \ passi',c(i),cont) return elseif x0=c(i); end end end
Allora, il motivo dell'errore è che chiami la funzione in modo sbagliato. Quando chiami la dunzione non devi riscrivere la parola chiave function prima della variabile x0.
La chiamata giusta è:
Poi attento alle modifiche che hai fatto. Se hai definito delle nuove varibili tollx e tollf ricordati che o vanno dichiarate da qualche parte o devi metterle come input.
La chiamata giusta è:
[x0]=regulafalsi(funz,a,b,max1,toll)
Poi attento alle modifiche che hai fatto. Se hai definito delle nuove varibili tollx e tollf ricordati che o vanno dichiarate da qualche parte o devi metterle come input.
Allora, il motivo dell'errore è che chiami la funzione in modo sbagliato.

Poi attento alle modifiche che hai fatto. Se hai definito delle nuove varibili tollx e tollf ricordati che o vanno dichiarate da qualche parte o devi metterle come input.
OK.
Grazie
Vorrei evitare ti aprire un'altro post,quindi scrivo qui il mio attuale problema:
Sto facendo un metodo per calcolare le radici di un equazione tramite la "Regula falsi",qui sotto metto il mio prpogramma:
Dove funz è la funzione,a e b sono gli estremi dell'intervallo,tollx e tollf le tolleranze e max1 il numero massimo di passi da fare.
Quando eseguo il programma mi appare il seguente errore:
Quindi pare che non legga funz come funzione,anche se io ho messo in input
Mi potete dare qualche consiglio?
Sto facendo un metodo per calcolare le radici di un equazione tramite la "Regula falsi",qui sotto metto il mio prpogramma:
function [x0]=regulafalsi(funz,a,b,max1,tollx,tollf) f=inline(funz); fprintf('Inizio calcolo radice con metodo REGULA FALSI \n') cont=0; if a >= b ('ATTENZIONE: a>=b'); return,end if f(a)*f(b)>0 ('ATTENZIONE: f(a)*f(b) >0'); return,end if (f(a)==0) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0d \t passi',a,cont-1) return end if (f(b)==0) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0d \t passi',b,cont-1) return end for (i=1:max1) c(i) = ((f(b(i))*a(i))-(f(a(i))*b(i)))/(f(b(i))-f(a(i))); cont=cont+1; if (f(c(i))==0) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0d \t passi',c(i),cont-1) return elseif (f(c(i))*f(a(i))<0) a(i+1)=a(i); b(i+1)=c(i); else a(i+1)=c(i); b(i+1)=b(i); end if (i>1) if ((abs(c(i)-c(i-1)) < tollx) || (abs(f(c(i))) < tollf)) fprintf('Il valore della radice è %6.10g \t calcolato in %6.0d \t passi \n',c(i),cont-1) x0=c(i); return else x0=c(i); end end end end
Dove funz è la funzione,a e b sono gli estremi dell'intervallo,tollx e tollf le tolleranze e max1 il numero massimo di passi da fare.
Quando eseguo il programma mi appare il seguente errore:
Error in regulafalsi (line 2) f=inline(funz);
Quindi pare che non legga funz come funzione,anche se io ho messo in input
funz='-x^2+5*x+2'.
Mi potete dare qualche consiglio?
Penso di aver capito dov'è l'errore. Nei due IF iniziali fai stampare una stringa e poi fai return. Il problema è che la variabile che dovresti restituire, cioè x0, non ha alcun valore. Questo va fatto anche se il programma non entra in quei due IF, perchp se ci entrasse non saprebbe cosa fare. Infatti l'errore per intero che matlab ti dovrebbe dare non è solo quallo riportato da te ma
Adesso, onestamente non so perchè identifichi l'errore con la linea 3 del codice, però la seconda parte dell'errore è utile.
Io ho provato a mettere in quei due IF, x0=NaN in modo da assegnare un valore a x che non si confonda con l'eventuale soluzione trovata e quell'errore mi è scomparso.
Ho notato un'altra cosa. Come ti ho detto non conosco questo algoritmo, quindi potrei sbagliarmi.
Potresti spiegarmi questa parte?
Il mio dubbio è che sia nell'IF sia nell'ELSE assegni un valore ad x0 e questo valore sarà lo stesso indipendentemente dal fatto che tu sia nell'IF o nell'ELSE. L'unica differenza è che nel secondo caso continui a fare iterazioni dato che non c'è alcun return, nell'altro ti fermi perché la soluzione l'hai trovata. Quindi a mio avviso quell'else è inutile.
Error in ==> regulafalsi at 3 f=inline(funz); ??? Output argument "x0" (and maybe others) not assigned during call to PathName file
Adesso, onestamente non so perchè identifichi l'errore con la linea 3 del codice, però la seconda parte dell'errore è utile.
Io ho provato a mettere in quei due IF, x0=NaN in modo da assegnare un valore a x che non si confonda con l'eventuale soluzione trovata e quell'errore mi è scomparso.
Ho notato un'altra cosa. Come ti ho detto non conosco questo algoritmo, quindi potrei sbagliarmi.
Potresti spiegarmi questa parte?
if ((abs(c(i)-c(i-1)) < tollx) || (abs(f(c(i))) < tollf)) fprintf('2 Il valore della radice è %6.10g \t calcolato in %6.0d \t passi \n',c(i),cont-1) x0=c(i); return else x0=c(i); end
Il mio dubbio è che sia nell'IF sia nell'ELSE assegni un valore ad x0 e questo valore sarà lo stesso indipendentemente dal fatto che tu sia nell'IF o nell'ELSE. L'unica differenza è che nel secondo caso continui a fare iterazioni dato che non c'è alcun return, nell'altro ti fermi perché la soluzione l'hai trovata. Quindi a mio avviso quell'else è inutile.