Anda di halaman 1dari 11

Laboratorio de Computacin Cientfica

PRCTICA 4: Races de funciones

Curso 2012-13

Como en los mdulos anteriores, construye tu informe de prcticas incorporando tus programas, resultados, figuras o/y comentarios o conclusiones.
Introduccin al clculo de races con MATLAB MATLAB proporciona la funcin x=fzero(nombre_funcion,x0,tol,it) para obtener la raz de una funcin. Si la funcin est definida en un fichero .m (en cuyo caso debe tener la estructura y=nombre_funcion(x)) el primer argumento de fzero es una cadena con el nombre de la funcin (por ejemplo, el nombre de la funcin entre comillas simples). Alternativamente, la funcin puede ser definida usando el comando inline. Los otros argumentos de entrada a fzero son la aproximacin inicial x0, el nmero de iteraciones del proceso iterativo it (si it es igual a 1, el proceso se repite hasta que la solucin est dentro de una tolerancia tol). Los dos ltimos argumentos se pueden omitir. La funcin fzero emplea el mtodo de Brent, que combina la interpolacin cuadrtica inversa con la biseccin. Para evaluar el valor de una funcin almacenada en una variable se usa la funcin interna feval. Su sintaxis es y = feval(fun, x). Teclea help feval para ms informacin. Existen tambin funciones internas de Matlab para el clculo de races de polinomios. La funcin r=roots(c) calcula las races r de un polinomio cuyos coeficientes se encuentran almacenados en el vector

c de la forma: c(1)xn+...+c(n)x+c(n+1). De forma inversa, la funcin c=poly(r) genera un polinomio que


tiene como races los valores almacenados en el vector r. Finalmente, y=polyval(c,x) evala el valor del polinomio cuyos coeficientes vienen dados en c en el punto x. .

1.

Sea el siguiente polinomio p(x)=x2-5x+6. Determina sus races mediante funciones internas de Matlab. Determina los valores que toma el polinomio p(x) en x= [1.5 3.5].

p=[1 -5 6]; raices=roots(p) raices = 3.0000 2.0000 x=[1.5 3.5]; polyval(p,x) ans = 0.7500 0.7500

Luego observamos que p(1.5)=p(3.5)=0.75

Laboratorio de Computacin Cientfica


2.

Curso 2012-13

Con las funciones internas conv y deconv se puede multiplicar y dividir polinomios. Sean p(x) = 2x + 1 y q(x) = 3x + 4, determina el polinomio resultante de su multiplicacin y asigna el resultado a un polinomio r(x). Divide este polinomio r(x) por el polinomio p(x). Con los operadores + y se calcula la suma y resta de polinomios. Resta y suma los polinomios r y p.

p=[2 1]; q=[3 4]; r=conv(p,q) %multiplicacin de polinomios r = 6 11 4 %luego el resultado es ( )

[coc,res]=deconv(r,p) %divisin de polinomios coc = 3 res = 0 0 0 4 %luego el resultado es y de resto 0.

Para sumar y restar los polinomios deben coincidir las dimensiones de sus vectores de coeficientes, luego hemos de completar con ceros a la izquierda el de menor longitud.
>> p=[0,p] p = 0 >> r+p ans = 6 >> r-p ans = 6 9 3 13 5 2 1

Laboratorio de Computacin Cientfica


3.

Curso 2012-13

El siguiente ejemplo nos permite analizar el condicionamiento de una funcin, en este caso de un polinomio de grado 10. Una funcin est mal condicionada cuando sus races son muy sensibles a pequeos cambios en los coeficientes. Es importante conocer si una funcin est mal o bien condicionada ya que en caso de que est mal condicionada, como en este ejemplo, los resultados obtenidos seran poco fiables. En este ejemplo estudiaremos cmo cambian las races de un polinomio cuando se altera levemente uno de sus coeficientes. >>X=[1:10]; % X son las races del polinomio P >>P=poly(X); P(2)=P(2)+0.001; nuevas_raices=roots(P) Compara las races originales y las nuevas races tras la modificacin del polinomio. Este polinomio est bien o mal condicionado?

nuevas_raices = 10.1553 10.1553 7.2317 7.2317 5.1377 5.1377 3.9476 3.0020 2.0000 1.0000 + + + 1.1489i 1.1489i 1.5828i 1.5828i 0.5930i 0.5930i

Observamos que con haber modificado ligeramente el segundo coeficiente del polinomio, las nuevas races han cambiado enormemente (tan solo las tres o cuatro ltimas son muy parecidas), luego era un polinomio mal condicionado.

Laboratorio de Computacin Cientfica

Curso 2012-13

4.

Programa una funcin en el fichero mifuncion.m que evale la siguiente expresin matemtica y=esin(x) - 2*cos(x). Dibuja dicha funcin en el intervalo [0,10]. Cuntas races tiene esta funcin? Calcular todas las races de la funcin en el intervalo [0, 10] llamando a la funcin fzero cuantas veces sean necesarias, usando distintos valores de x0 cada vez. Detalla todas las instrucciones y las races que has obtenido.

function r=mifuncion(f,a,b) % %r=mifuncion(f,a,b) dibuja y calcula las races de la funcin "f" en el %intervalo [a,b]. f debe ser dependiente de "x" y se introduce entre %comillas % f=inline(f,'x'); %definimos la funcin f=f(x) inline % %DIBUJAR LA FUNCION EN EL INTERVALO DADO X=linspace(a,b,1e3); %vector con el dominio de la variable independiente F=feval(f,X); %vector con el dominio de la variable dependiente f=f(X) plot(X,F) grid on %activa la rejilla %CALCULAR RACES x0=input('Introducir valores para x0: '); n=length(x0); %Medir longitud del vector con los x0 introducidos r=zeros(1,n); %Prefijamos el tamao que va a tener la solucin for i=1:n r(i)=fzero(f,x0(i)); %aplica la instruccin fzero para cada x0 end

Ahora ejecutamos el programa para la funcin que nos piden


>> mifuncion('exp(sin(x))-2*cos(x)',0,10) Introducir valores para x0: [0,4.5,7] %elegimos valores cercanos a los ceros

ans = 0.5574 4.9007 6.8406

Laboratorio de Computacin Cientfica


5.

Curso 2012-13

Programa una funcin df=resta(fun1, fun2, x) que evale la diferencia entre dos funciones arbitrarias fun1 y fun2 en el punto x. Usa tu funcin para dibujar la diferencia entre las funciones y1=x2, y2=sin(x) en el intervalo [0, 2].

function df=resta(fun1,fun2,x) % %Evala la diferencia entre dos funciones arbitrarias 'fun1' y 'fun2' en el %punto x rf1=inline(fun1); rf2=inline(fun2); df=rf1(x)-rf2(x); >> >> >> >> X=linspace(0,2); %al definir as X se evaluar en el intervalo entero df=resta('x.^2','sin(x)',X); plot(X,df) grid on

Laboratorio de Computacin Cientfica


6.

Curso 2012-13

Escribe una funcin que calcule una raz de una funcin cualquiera usando el mtodo de biseccin. Para ello escribe una funcin, [x,it]=bisecc(funcion,a,b), que admita como parmetros de entrada cualquier funcin tipo fun.m y el intervalo (a,b) donde se ha de buscar la raz, y devuelva la raz x y el nmero de iteraciones it del mtodo de biseccin. La tolerancia, tol, para el clculo de la raz se introducir por teclado usando input. Utiliza el comando fprintf('\n %i %f %f %f %f',it, x, y,a,b) para sacar por pantalla durante la ejecucin los resultados parciales en cada iteracin. Usa tu funcin bisecc para calcular las races de la funcin f(x)= x-sen(x)-1 y comprueba el resultado obtenido comparando tu raz con la obtenida usando fzero.

function [x,it]=bisecc(fun,a,b) fprintf('Resultados del mtodo de la biseccin\n') fprintf('\n') it=0; %Inicializar contabilizador de iteraciones fun=inline(fun,'x'); %definir funcin inline u=feval(fun,a); v=feval(fun,b); c=a+(b-a)*0.5; w=feval(fun,c); %u=fun(a); v=fun(b); c=(a+b)/2; w=fun(c); if sign(u)==sign(v) %si fun(a)=fun(b) no se puede aplicar el mtodo error('ERROR: La funcin debe cambiar de signo en (a,b)') end tol=input('Introducir valor de tolerancia: '); %se supone un valor pequeo para mayor precisin while abs(w)>tol %el bucle se repite hasta que fun(c)<=tolerancia it=it+1; %sumar una iteracin c=a+(b-a)*0.5; %punto medio del intervalo, los extremos irn cambiando y por tanto tambin l w=feval(fun,c); %imagen del punto medio del intervalo, cuando est cercana a cero finaliza el bucle fprintf('\nit= %i c= %f f(c)= %f a= %f b= %f \n',it,c,w,a,b) if sign(u)==sign(w) %si se cumple esto la raz est en el lado derecho a=c; u=w; else b=c; end end x=c;

Ahora introducimos:
>> [x,it]=bisecc('x-sin(x)-1',-1,3) Introducir valor de tolerancia: 1e-5 it= 1 c= 1.000000 f(c)= -0.841471 a= -1.000000 b= 3.000000 it= 2 c= 2.000000 f(c)= 0.090703 a= 1.000000 b= 3.000000 it= 3 c= 1.500000 f(c)= -0.497495 a= 1.000000 b= 2.000000 it= 4 c= 1.750000 f(c)= -0.233986 a= 1.500000 b= 2.000000 it= 5 c= 1.875000 f(c)= -0.079086 a= 1.750000 b= 2.000000 it= 6 c= 1.937500 f(c)= 0.003986 a= 1.875000 b= 2.000000 it= 7 c= 1.906250 f(c)= -0.038011 a= 1.875000 b= 1.937500 it= 8 c= 1.921875 f(c)= -0.017127 a= 1.906250 b= 1.937500 it= 9 c= 1.929688 f(c)= -0.006599 a= 1.921875 b= 1.937500 it= 10 c= 1.933594 f(c)= -0.001314 a= 1.929688 b= 1.937500 it= 11 c= 1.935547 f(c)= 0.001334 a= 1.933594 b= 1.937500 it= 12 c= 1.934570 f(c)= 0.000010 a= 1.933594 b= 1.935547 x = 1.9346

Laboratorio de Computacin Cientfica


it = 12

Curso 2012-13

Comparamos con la funcin fzero:


>> x=fzero(inline('x-sin(x)-1'),[-1,3]) x = 1.9346

Con la tolerancia que hemos puesto (de 4 decimales de precisin) los dos mtodos coinciden 7. Aplica tu funcin bisecc.m para determinar las dos races del ejercicio 1.

>> x1=bisecc('x^2-5*x+6',1.5,2.5) Introducir valor de tolerancia: 1e-5 x1 = 2 >> x2=bisecc('x^2-5*x+6',2.5,3.5) Introducir valor de tolerancia: 1e-5 x2 = 3

Lo resuelve en la primera iteracin porque el punto medio de los intervalos ya coincide con la raz

Laboratorio de Computacin Cientfica


8.

Curso 2012-13

Programa una funcin [x,it] = interpol(g,tol,x0,x1) que obtenga numricamente una raz de la funcin matemtica g(x) usando el mtodo iterativo de interpolacin lineal con una tolerancia tol, siendo x0 y x1 los valores iniciales (prximos a la raz exacta x) con los que comienza el mtodo. La ejecucin de la funcin debe incluir la aparicin en pantalla de los pasos o iteraciones sucesivas, mostrando los valores de: n de iteracin, solucin parcial aproximada x y el valor de fun(x). En este caso, se definir la funcin de entrada g usando el comando inline en vez de mediante un fichero .m. Usa tu programa para calcular las races de la funcin f(x) del ejercicio 6.

function [x,it]=interpol(g,tol,x0,x1) fprintf('Resultados del mtodo de la biseccin\n') fprintf('\n') it=0; %Inicializar contabilizador de iteraciones g=inline(g,'x'); %definir funcin inline u=feval(g,x0); v=feval(g,x1); c=x1-v/(v-u)*(x1-x0); w=feval(g,c); %u=g(x0); v=g(x1); c=x1-f(x1)/(f(x1)-f(x0))*(x1-x0); w=g(c); if sign(u)==sign(v) %si fun(a)=fun(b) no se puede aplicar el mtodo error('ERROR: La funcin debe cambiar de signo en (a,b)') end while abs(w)>tol %el bucle se repite hasta que fun(c)<=tolerancia it=it+1; %sumar una iteracin c=x1-v/(v-u)*(x1-x0); w=feval(g,c); fprintf('\nit= %i c= %f f(c)= %f a= %f b= %f \n',it,c,w,x0,x1) if sign(u)==sign(w) %si se cumple esto la raz est en el lado derecho x0=c; u=w; else x1=c; v=w; end end x=c; >> [x,it]=interpol('x-sin(x)-1',1e-5,-1,3) Resultados del mtodo de la biseccin it= 1 c= 0.535793 f(c)= -0.974730 a= -1.000000 b= 3.000000 it= 2 c= 1.383453 f(c)= -0.599050 a= 0.535793 b= 3.000000 it= 3 c= 1.777440 f(c)= -0.201286 a= 1.383453 b= 3.000000 it= 4 c= 1.896888 f(c)= -0.050413 a= 1.777440 b= 3.000000 it= 5 c= 1.926015 f(c)= -0.011556 a= 1.896888 b= 3.000000 it= 6 c= 1.932650 f(c)= -0.002592 a= 1.926015 b= 3.000000 it= 7 c= 1.934136 f(c)= -0.000579 a= 1.932650 b= 3.000000 it= 8 c= 1.934468 f(c)= -0.000129 a= 1.934136 b= 3.000000 it= 9 c= 1.934542 f(c)= -0.000029 a= 1.934468 b= 3.000000 it= 10 c= 1.934558 f(c)= -0.000006 a= 1.934542 b= 3.000000 x = 1.9346

it = 10

Obtenemos el mismo resultado que con el mtodo de la biseccin, pero en menos iteraciones.

Laboratorio de Computacin Cientfica


9.

Curso 2012-13

El clculo de la raz cuadrada de 3 se puede determinar calculando la raz positiva de la ecuacin x2=3; si la reescribimos tenemos la expresin x=(3+x)/(1+x). Programa una funcin que determine la raz cuadrada de 3 por el mtodo del punto fijo con la expresin que se indica, considerando como valor inicial 1. Cuntas iteraciones se han realizado para llegar a tener trece decimales exactos de precisin?

function x=punto_fijo(fx,gx,x0,tol) % %x=punto_fijo(fx,gx,x0,tol) Obtiene la raz de fx por el mtodo de punto %fijo % %Valores de entrada % fx: funcin f(x) de la que se pretende calcular la raz % gx: lo que se obtiene al despejar de f(x)--> x=g(x) % x0: valor inicial del que se parte % tol: tolerancia admitida % fx=inline(fx,'x'); gx=inline(gx,'x'); %definir funciones inline fprintf('Mtodo de punto fijo\n') fprintf('\n') x=x0;%inicializamos la variable de salida en el punto inicial n=0; %contabilizador de iteraciones F=feval(fx,x); %evaluamos la funcin en el valor inicial while abs(F)>tol n=n+1; x=feval(gx,x); %proceso iterativo principal x(s+1)=g(x(s)) F=feval(fx,x); %Este valor debe ir reducindose hasta ser admitido en la tolerancia fprintf('n= %i x= %f \n',n,x) end

Para hallar la solucin de

con 13 decimales de precisin hacemos:

>> format long >> punto_fijo('x^2-3','(3+x)/(1+x)',1,1e-13) Mtodo de punto fijo n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= n= 1 x= 2.000000 2 x= 1.666667 3 x= 1.750000 4 x= 1.727273 5 x= 1.733333 6 x= 1.731707 7 x= 1.732143 8 x= 1.732026 9 x= 1.732057 10 x= 1.732049 11 x= 1.732051 12 x= 1.732051 13 x= 1.732051 14 x= 1.732051 15 x= 1.732051 16 x= 1.732051 17 x= 1.732051 18 x= 1.732051 19 x= 1.732051 20 x= 1.732051 21 x= 1.732051 22 x= 1.732051 23 x= 1.732051 24 x= 1.732051

ans = 1.732050807568860

Laboratorio de Computacin Cientfica


Hemos necesitado 24 iteraciones para obtener una aproximacin vlida de

Curso 2012-13

10. Programa una funcin [x,it]=newton(fun, der, x0, tol) para calcular la raz de una funcin cualquiera usando el mtodo de Newton, y emplea dicha funcin para calcular las races de la funcin del ejercicio 6 y la raz cuadrada del ejercicio 9. En este caso, la funcin newton recibir como argumentos de entrada tanto la funcin cuya raz se desea calcular (fun) como su funcin derivada (der), que calculars analticamente previamente a la ejecucin, x0 la aproximacin inicial y tol la tolerancia. Las funciones fun y der sern definidas en ficheros .m. Para cada una de las funciones de los ejercicios 6 y 9 construye una tabla de sntesis indicando, el valor inicial considerado, si converge o no el mtodo, si converge indicar el nmero de iteraciones realizadas y la raz. En todos los casos considerar una tolerancia de 10-10.
function [x,it]=newton(fun,der,x0,tol) % %[x,it]=newton(fun,der,x0,tol) Calcula una raz para "fun" por el mtodo de %Newton % %Valores de entrada % fun: funcin fun(x) de la que se quiere calcular una raz. % der: derivada de fun(x). Calcular analticamente % x0: aproximacin inicial % tol: tolerancia admitida fun=inline(fun,'x'); der=inline(der,'x'); %definir las funciones inline fprintf('\nResultados del mtodo de Newton\n') fprintf('\n') it=0; %inicializamos las iteraciones x=x0; %inicializamos el valor de salida a la aprox. inicial fx=feval(fun,x); dfx=feval(der,x); %inicializamos f(x0) y f'(x0) para la primera iteracin while abs(fx)>tol it=it+1; %sumar una iteracin x=x-fx/dfx; %secuencia iterativa principal fx=feval(fun,x); dfx=feval(der,x); %evaluar los f(xi) y f'(xi) de las nuevas iteraciones fprintf('it= %i x= %f f(x)= %e \n',it,x,fx) end

Se pide primero calcular las races de ( ) ( ) . La tolerancia ser de

. Necesitamos su derivada que es: .

>> [x,it]=newton('x-sin(x)-1','1-cos(x)',1,1e-10) Resultados del mtodo de Newton it= it= it= it= it= x = 1.9346 it = 5 1 2 3 4 5 x= x= x= x= x= 2.830488 2.049555 1.938656 1.934569 1.934563 f(x)= f(x)= f(x)= f(x)= f(x)= 1.524377e+000 1.619879e-001 5.556989e-003 7.797755e-006 1.545697e-011

Podemos ver que obtenemos una precisin de 10 decimales con tan solo 5 iteraciones, luego es un mtodo muy potente No obstante el mtodo diverge si, por ejemplo, partisemos del valor inicial

Laboratorio de Computacin Cientfica


>> [x,it]=newton('x-sin(x)-1','1-cos(x)',0,1e-10) Resultados del mtodo de Newton it= 1 x= Inf f(x)= NaN x = Inf it = 1

Curso 2012-13