Invalid indexing or function definition. Indexing must follow MATLAB indexing. Function arguments must be symbolic variables, and function body must be sym expression.

9 Ansichten (letzte 30 Tage)
Hi all,
I am about to cut my veins because i have been for three days with this code and I can't fix the error. I have taken a look to the same error for other codes, but I can't see it in my code. Could someone tell me what is wrong? Below I paste the code. Thanks in advance!!
function c= regulafalsi (f, tol, ite, a, b)
% f= equation, tol=maximum error, ite = number of maximum iterations, a= right extreme of interval, b= left extreme of interval
syms x
syms f
syms a
syms b
syms c
f= @(x) exp(-x)-log(x);
f(a)= exp(-a)-log(a); %I have written these to see if I fixed the error, but not succeed
f(b)= exp(-b)-log(b);
f(c)= exp(-c)-log(c);
c = (a*f(b)-b*f(a))/(f(b)-f(a));
prod_ab=f(a) * f(b);
prod_ac=f(a) * f(c);
prod_bc=f(b) * f(c);
if prod_ab > 0
fprintf('El intervalo elegido no garantiza que contenga una solución.\n');
end
contador = 0;
while abs(b-a)>tol || contador<ite
if prod_ac<0
b = c;
elseif prod_bc<0
a = c;
elseif abs(f(c))<tol || contador<ite
fprintf('\La raíz es %f\n\n y el número de iteraciones es %f\n', c, contador)
contador = contador + 1;
end
%error messages received are:
%Error using sym/subsindex (line 953)
%Invalid indexing or function definition. Indexing must follow MATLAB indexing. Function arguments must be symbolic
%variables, and function body must be sym expression.
%Error in regulafalsi (line 9)
%f(a)= exp(-a)-log(a);

Akzeptierte Antwort

Voss
Voss am 30 Dez. 2021
f is a function (handle). If you want the value of f at a, you don't have to evaluate and store it like that. In fact, you cannot store something as f(a); this is the reason for the error. If you want to use the value of f at a, just say f(a) - no need to store it (but you can store it as some other variable, say, f_a = f(a), if you want to).
(Also, notice the Symbolic Math Toolbox is not used in the code below.)
f= @(x) exp(-x)-log(x);
a = 2;
b = 3;
c = (a*f(b)-b*f(a))/(f(b)-f(a));
prod_ab=f(a) * f(b);
prod_ac=f(a) * f(c);
prod_bc=f(b) * f(c);
disp(c)
0.8640
disp(prod_ab)
0.5850
disp(prod_ac)
-0.3167
disp(prod_bc)
-0.5954
  8 Kommentare
Voss
Voss am 31 Dez. 2021
Notice the difference in how f was defined initially:
f= @(x) exp(-x)-log(x);
and how it is now:
exp(-x)-log(x)
You have to put the @(x) so that MATLAB knows it's a function, essentially. So you would call your function like this:
regulafalsi2(@(x) exp(-x)-log(x), 1, 1.5, 10, 0.00001)
But there is a second problem, which Walter mentioned at the start and which has not been corrected:
"In your code, where do you update prod_ab, prod_ac, prod_bc inside the while loop ?"
When you change the values of a and/or b you need to update all relevant variables that depend on those values, so not only c, which you have done, but also prod_ac and prod_bc, because if you don't update those, the code inside the while loop uses the old values which were based on the old a, b and c. (Also, notice that prod_ab is not used inside the while loop, but maybe it should be?)
Salceda  Fernández Barredo del Amo
Good morning Benjamin and Walter and happy 2022, thank you very much for the support in these days..
I have used the function feval() to calculate my f in each argument, also I have changed the code to update f(a), f(b) and f(c) into the while loop. I thought at first that, changing a, b and c was enough to change the associated function.
As it is a method that, in each loop selects a new interval, depending on which of the subintervals the product of the f(x) is < 0, it gets updated one or other, but substituting a or b by c. That is the reason why prod_ab does not change, because is the initial interval and is only evaluated once.
The updated (and at last) working code is:
function regulafalsi(f,a,b,nit,t)
%Inputs: f=función, a=valor inferior, b=valor superior, nit=número máximo
%de iteraciones, t=tolerancia
%Outputs: c=raíz, k=número de iteraciones realizadas
fa=feval(f,a); % utilizo la función feval para evaluar la función f en a
fb=feval(f,b);
disp('----------------------------------------------------------------------------------')
disp('iter a b c f(c) t ')
disp('----------------------------------------------------------------------------------')
fprintf('\n') %para que muestre cómo va realizando los bucles y el resultado en cada uno
if fa*fb>0 % si no cumple teorema de Bolzano
fprintf('No existe solución en el intervalo [%f,%f]',a,b);
c=[];
k=0;
l=0;
else
l=abs(b-a); %l es el tamaño del intervalo inicial
k=0; % k el número de iteraciones necesarias hasta que se cumpla la condición del while, iniciamos en cero
c = (a*fb-b*fa)/(fb-fa);% la fórmula de regula-falsi para calcular el punto de corte inicial
fc=feval(f,c); % utilizo la función feval para evaluar la función f en c
while t<=abs(f(c)) %mientras que el valor de la función en c en valor absoluto siga siendo mayor que la tolerancia (error que fijamos)
c = (a*fb-b*fa)/(fb-fa); %calculamos el punto de corte inicial; lo dejamos dentro del while para que e vaya actualizando en cada bucle
fc=feval(f,c); %calculamos cuánto vale c en la función que hemos introducido como f
if (fa*fc<0) %si el producto es menor de cero, la raiz está en el intervalo [a-c]
b=c; %se asigna c como el nuevo límite superior en vez de b
fb=fc; % se actualiza fb
k=k+1;%se añade una iteración al contador antes de comenzar el siguiente bucle
elseif (fb*fc<0) %si es menor de cero, la raiz está en el intervalo [c-b], y el resto como arriba pero sustituyendo c por a
a=c;
fa=fc;
k=k+1;
elseif fc==0 %si obtenemos directamente la raiz porque f(c) es cero
fprintf('\La raíz es %f\n\n', c)
end
Thank you again for all your help, I will remember these Xmas as "Regula-Falsi" ones...
Best regards,
Salceda

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte


Version

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by