Análisis Numérico Universidad Nacional de Misiones Usando los Archivos para Cálculo de Raíces En el Aula virtual de Análisis Numérico de la Facultad de ciencias Exactas, Químicas y Naturales (Fceqyn) de la Universidad Nacional de Misiones (UNaM) se incluyen cuatro algoritmos para calcular raices. En el formato de archivos m de Matlab. Las algoritmos presentados son los sigueintes: bisct Calcula raíces empleando el método de Bisección falsp Calcula raíces por el método de la regla falsa (Regula Falsi) newton Calcula raíces por el método de Newton-Raphton secant Calcula raíces por el método de la secante Comandos utilizados en esta guía syms diff inline A continuación se transcriben los algoritmos y se indica como utilizarlos. No se detalla su funcionamiento interno, pero dado que el mismo esta a la vista solamente se requiere un conocimiento de programación en Matlab para analizarlos y comprenderlos. Los algoritmos fueron copiados de: APPLIED NUMERICAL METHODS USING MATLAB, W. Y. Yang, W. Cao, T.-S. Chung, J.Morris. Wiley Interscience, 2005. USA. Se empleará a la siguiente función en los ejemplos de implementación: tan = (π − x ) − x Algoritmo bisct function [x,err,xx] = bisct(f,a,b,TolX,MaxIter) %bisct.m to solve f(x) = 0 by using the bisection method. %input : f = ftn to be given as a string ’f’ if defined in an M-file % a/b = initial left/right point of the solution interval % TolX = upperbound of error |x(k) - xo| % MaxIter = maximum # of iterations %output: x = point which the algorithm has reached % err = (b - a)/2(half the last interval width) % xx = history of x TolFun=eps; fa = feval(f,a); fb = feval(f,b); if fa*fb > 0, error('We must have f(a)f(b)<0!'); end for k = 1: MaxIter xx(k) = (a + b)/2; fx = feval(f,xx(k)); err = (b-a)/2; if abs(fx) < TolFun | abs(err)<TolX, break; elseif fx*fa > 0, a = xx(k); fa = fx; else b = xx(k); end end x = xx(k); if k == MaxIter, fprintf('The best in %d iterations\n',MaxIter), end Usando bisect Se asigna una function inline en la variable f42, así: Mario R. ROSENBERGER 1 de 6 Usando los archivos …. raíces >> f42 = inline('tan(pi - x)-x','x'); La siguiente línea llama al algoritmo bisct, y asigna los resultados en las variables [x, err, xx] Las cuales almacenan: el valor final, el error relativo y los resultados de las iteraciones intermedias, respectivamente. Los argumentos que se asignan son, en orden de aparición: f42 : la función previamente declarada 1.6: extremo inferior del intervalo 3: extremo superior del intervalo 1e-4: tolerancia para el cálculo 50: número máximo de iteraciones antes de interrumpir el cálculo. >> [x,err,xx] = bisct(f42,1.6,3,1e-4,50) x= 2.0287 err = 8.5449e-005 xx = Columns 1 through 9 2.3000 1.9500 2.1250 2.0375 Columns 10 through 14 2.0279 2.0286 2.0290 2.0288 1.9937 2.0156 2.0266 2.0320 2.0293 2.0287>> Si se introduce un intervalo donde no se verifican signos opuestos en las imágenes de se obtendrá unmnsaje de error, como por ejemplo: >>[x,err,xx] = bisct(f42,1.5,3,1e-4,50); ??? Error using ==> bisct We must have f(a)f(b)<0! Algoritmo falsp function [x,err,xx] = falsp(f,a,b,TolX,MaxIter) %bisct.m to solve f(x)=0 by using the false position method. %input : f = ftn to be given as a string ’f’ if defined in an M-file % a/b = initial left/right point of the solution interval % TolX = upperbound of error(max(|x(k)-a|,|b-x(k)|)) % MaxIter = maximum # of iterations %output: x = point which the algorithm has reached % err = max(x(last)-a|,|b-x(last)|) % xx = history of x TolFun = eps; fa = feval(f,a); fb=feval(f,b); if fa*fb > 0, error('We must have f(a)f(b)<0!'); end for k = 1: MaxIter xx(k) = (a*fb-b*fa)/(fb-fa); %Eq.(4.3.1) fx = feval(f,xx(k)); err = max(abs(xx(k) - a),abs(b - xx(k))); if abs(fx) < TolFun | err<TolX, break; elseif fx*fa > 0, a = xx(k); fa = fx; else b = xx(k); fb = fx; end end x = xx(k); Mario R. ROSENBERGER 2 de 6 Usando los archivos …. raíces if k == MaxIter, fprintf('The best in %d iterations\n',MaxIter), end Usando falsp Se asigna una function inline en la variable f42, así: >> f42 = inline('tan(pi - x)-x','x'); La siguiente línea llama al algoritmo falsp, y asigna los resultados en las variables [x, err, xx] Las cuales almacenan: el valor final, el error relativo y los resultados de las iteraciones intermedias, respectivamente. Los argumentos que se asignan son, en orden de aparición: f42 : la función previamente declarada 1.6: extremo inferior del intervalo 3: extremo superior del intervalo 1e-4: tolerancia para el cálculo 50: número máximo de iteraciones antes de interrumpir el cálculo. >> [x,err,xx] = falsp(f42,1.7,3,1e-4,50) %with initial interval [1.7,3] The best in 50 iterations x= 2.0288 err = 0.3288 xx = Columns 1 through 7 2.5805 2.3642 2.2400 2.1644 2.1170 2.0865 2.0668 Columns 8 through 14 2.0539 2.0454 2.0398 2.0361 2.0336 2.0320 2.0309 Columns 15 through 21 2.0302 2.0297 2.0294 2.0292 2.0290 2.0289 2.0289 Columns 22 through 28 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 Columns 29 through 35 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 Columns 36 through 42 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 Columns 43 through 49 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 2.0288 Column 50 2.0288 Algoritmo Newton function [x,fx,xx] = newton(f,df,x0,TolX,MaxIter) %newton.m to solve f(x) = 0 by using Newton method. %input: f = ftn to be given as a string ’f’ if defined in an M-file % df = df(x)/dx (If not given, numerical derivative is used.) % x0 = the initial guess of the solution % TolX = the upper limit of |x(k) - x(k-1)| % MaxIter = the maximum # of iteration %output: x = the point which the algorithm has reached % fx = f(x(last)), xx = the history of x h = 1e-4; h2 = 2*h; TolFun=eps; if nargin == 4 & isnumeric(df), MaxIter = TolX; TolX = x0; x0 = df; end Mario R. ROSENBERGER 3 de 6 Usando los archivos …. raíces xx(1) = x0; fx = feval(f,x0); for k = 1: MaxIter if ~isnumeric(df), dfdx = feval(df,xx(k)); %derivative function else dfdx = (feval(f,xx(k) + h)-feval(f,xx(k) - h))/h2; %numerical drv end dx = -fx/dfdx; xx(k+1) = xx(k)+dx; %Eq.(4.4.2) fx = feval(f,xx(k + 1)); if abs(fx)<TolFun | abs(dx) < TolX, break; end end x = xx(k + 1); if k == MaxIter, fprintf('The best in %d iterations\n',MaxIter), end Usando Newton Se asigna una función inline en la variable f42, así: >> f42 = inline('tan(pi - x)-x','x'); La siguiente línea llama al algoritmo Newton, y asigna los resultados en las variables [x, err, xx] Las cuales almacenan: el valor final, el error relativo y los resultados de las iteraciones intermedias, respectivamente. Los argumentos que se asignan son, en orden de aparición: f42 : la función previamente declarada x0: punto inicial 1e-5: tolerancia para el cálculo 50: número máximo de iteraciones antes de interrumpir el cálculo. >> x0 = 1.8; TolX = 1e-5; MaxIter = 50; %with initial guess 1.8,... >> [x,err,xx] = newton(f42,x0,1e-5,50) %1st order derivative x= 2.0288 err = 1.1684e-011 xx = 1.8000 1.9220 2.0075 2.0280 2.0288 2.0288 El método de Newton necesita de la derivada de la función cuya raíz de desea calcular. Este algoritmo permite hacer una estimación numérica de la derivada, la cual se verá con detalle más adelante en el curso, o bien permite que se ingrese la derivada de la función. El primer caso se empleo en el recuadro de arriba. A continuación se mostrará como emplear la segunda opción. >> df42 = inline('-(sec(pi-x)).^2-1','x'); %1st order derivative En la línea de arriba se asigna la derivada de la función a la variable df42. Esta se ingresa en el algoritmo del método de Newton de la siguiente manera: > [x,err,xx1] = newton(f42,df42,1.8,1e-5,50) x= 2.0288 err = 1.1446e-011 xx1 = Mario R. ROSENBERGER 4 de 6 Usando los archivos …. raíces 1.8000 >> 1.9220 2.0075 2.0280 2.0288 2.0288 Para calcular el valor de la derivada de la función pude utilizarse el comando diff. Con dos ejemplos se muestra como funciona este comando. >> syms x >> diff ( tan ( pi – x ) – x ) ans = -2-tan(x)^2 y también: >> f42 = inline('tan(pi - x)-x','x'); >> syms x >> diff ( f42(x) , x ) ans = -2-tan(x)^2 Algoritmo secant function [x,fx,xx] = secant(f,x0,TolX,MaxIter,varargin) % solve f(x) = 0 by using the secant method. %input : f = ftn to be given as a string ’f’ if defined in an M-file % x0 = the initial guess of the solution % TolX = the upper limit of |x(k) - x(k - 1)| % MaxIter = the maximum # of iteration %output: x = the point which the algorithm has reached % fx = f(x(last)), xx = the history of x h = 1e-4; h2 = 2*h; TolFun=eps; xx(1) = x0; fx = feval(f,x0,varargin{:}); for k = 1: MaxIter if k <= 1, dfdx = (feval(f,xx(k) + h,varargin{:})-... feval(f,xx(k) - h,varargin{:}))/h2; else dfdx = (fx - fx0)/dx; end dx = -fx/dfdx; xx(k + 1) = xx(k) + dx; %Eq.(4.5.2) fx0 = fx; fx = feval(f,xx(k+1)); if abs(fx) < TolFun | abs(dx) < TolX, break; end end x = xx(k + 1); if k == MaxIter, fprintf('The best in %d iterations\n',MaxIter), end Usando secant Se asigna una function inline en la variable f42, así: >> f42 = inline('tan(pi - x)-x','x'); La siguiente línea llama al algoritmo secant, y asigna los resultados en las variables [x, err, xx] Mario R. ROSENBERGER 5 de 6 Usando los archivos …. raíces Las cuales almacenan: el valor final, el error relativo y los resultados de las iteraciones intermedias, respectivamente. Los argumentos que se asignan son, en orden de aparición: f42 : la función previamente declarada 2.5: punto inicial 1e-5: tolerancia para el cálculo 50: número máximo de iteraciones antes de interrumpir el cálculo. >> [x,err,xx] = secant(f42,2.5,1e-5,50) %with initial guess 1.8 x= 2.0288 err = -7.4486e-011 xx = Columns 1 through 7 2.5000 1.8147 2.1964 2.0936 2.0124 2.0305 2.0288 Columns 8 through 9 2.0288 2.0288 Mario R. ROSENBERGER 6 de 6