Beruflich Dokumente
Kultur Dokumente
html
Computación Numérica
Profesores: José M. Alonso, Fernando Alvarruiz, Juan Garayoa, Jesús Peinado, José L. Pérez, José E.
Román, Vicente Vidal.
http://www.dsic.upv.es/asignaturas/eui/cnu/prac
Objetivos evaluables:
Funciones auxiliares
Como veremos en el próximo apartado, Matlab representa los números con unos 16 dígitos de
precisión. Sin embargo, en este apartado vamos a trabajar con menos dígitos, para que la aparición
de errores sea más evidente. Para ello, vamos a utilizar unas funciones que simulan las operaciones
aritméticas elementales, utilizando tantos dígitos como queramos (menos de 16). Las cabeceras de las
funciones son:
function x=suma_r(a,b,n)
% x=suma_r(a,b,n) devuelve la suma de a y b, realizada con n dígitos
1 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html
% decimales de precisión
function x=resta_r(a,b,n)
% x=resta_r(a,b,n) devuelve la resta a - b, realizada con n dígitos
% decimales de precisión
function x=prod_r(a,b,n)
% x=prod_r(a,b,n) devuelve el producto de a y b, realizado con n dígitos
% decimales de precisión
function x=div_r(a,b,n)
% x=div_r(a,b,n) devuelve la división a / b, realizada con n digitos
% decimales de precisión
function x=exp_r(a,b,n)
% x=exp_r(a,b,n) devuelve "a" elevado a "b", realizado con n dígitos
% decimales de precisión; atención, sólo funciona para b entero mayor
% o igual que 0
function x=redond(a,n)
% x=redond(a,n) devuelve en x el valor "a" redondeado a n dígitos
% decimales de precisión
Las raíces de la ecuación de segundo grado ax2+bx+c=0 se pueden calcular mediante las
expresiones
Una función implementada en Matlab que calcule las dos raíces utilizando estas expresiones podría
ser la siguiente:
Ejercicio 1: Completa la función anterior y utilízala para resolver una cierta ecuación (valores de a, b,
c fijos) variando los valores de n (por ejemplo, entre 1 y 16). Observa que para diferentes
precisiones (valores de n) los resultados varían. La lógica nos hace pensar que los resultados más
cercanos al valor correcto se obtienen en el caso en que más dígitos de precisión se utilizan. Sin
embargo, no conviene fiarse de la lógica: vamos a analizar el error cometido en cada caso.
2 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html
Podemos asumir que las soluciones exactas de la ecuación son las que calcula Matlab con la función
roots. Esta función calcula las raíces de un polinomio p(x)=anxn+...+a2x2+a1x+a0, el cual se
representa en Matlab mediante un vector fila [an ... a1 a0]. Por ejemplo, para la ecuación
x2+111.11x+1.2121=0
ans =
-111.0991
>> x(2)
ans =
-0.0109
>>
Ejercicio 2: Realizar un script de Matlab que mediante un bucle variando n desde 1 hasta 16 calcule
las raíces de la ecuación usando la función raices1, obtenga las soluciones exactas mediante roots y
calcule el error relativo de cada una de las soluciones, tanto x1 como x2. El script debe mostrar el
valor de n y los errores. Realiza el análisis de los errores con la siguiente ecuación: x2+62.1x+1=0.
En particular, observa:
Nota: En el ejercicio anterior, para poder calcular el error, las soluciones obtenidas con raices1 y con
roots deben estar en el mismo orden. Para ello, puede ser necesario utilizar la función sort de
Matlab.
Fórmulas alternativas
Una alternativa para calcular las raíces de la ecuación de segundo grado ax2+bx+c=0 es racionalizar
las expresiones anteriores, con lo que se obtienen estas nuevas fórmulas
Ejercicio 3: Implementa una función Matlab raices2, similar a raices1, que utilice estas expresiones.
Repite el análisis de errores con esta nueva función. A la vista de los resultados, ¿cuáles crees que
son la expresiones que menor error comenten? ¿Crees que en algún caso se está produciendo un
fenómeno de cancelación de dígitos?
3 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html
Objetivos evaluables:
La relación entre este formato y la representación de números reales viene dada por la siguiente
expresión, que pone el valor del número v en función del contenido de los tres campos s, e, f.
Matlab utiliza siempre este formato para representar los números internamente. Ahora bien, a la hora
de mostrar los números por la pantalla, Matlab lo hace con un cierto número de dígitos decimales. La
forma de mostrar los números se puede cambiar, como se muestra en el siguiente ejemplo:
>> pi
ans =
3.1416
ans =
3.14159265358979
En esta práctica, nos interesa estudiar en detalle cómo se representan los números internamente y,
por ello, queremos mostrar el formato de 64 bits completo, tal como se almacena en binario. Para
ello, podemos utilizar la función destripa (nota: esta función no forma parte de Matlab).
4 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html
>> destripa(pi)
s exponente.. mantisa............................................. n
0 10000000000 1001001000011111101101010100010001000010110100011000 <3.141592653589793>
Ejercicio 5: Utiliza la función destripa para analizar la representación de los números 1 y 2. ¿Por qué
la mantisa en binario aparece llena de ceros? ¿Por qué el exponente está a unos en un caso y a ceros
en el otro? Ahora, en base a la representación del 1 y el 2, piensa cuál sería el resultado de realizar la
suma (1+2=3). Piensa qué pasos realiza el procesador (igualar exponentes, sumar mantisas y
normalizar). Luego, utiliza destripa para comprobarlo.
Ejercicio 6: Realiza en Matlab las siguientes operaciones: 1+10-15 y 1+10-16. A primera vista, estas
operaciones son muy parecidas pero hay una diferencia importante. Utiliza destripa para ver la
representación del resultado en los dos casos. En el segundo caso, ¿qué diferencia hay con la
representación del 1? ¿Qué ha pasado?
Objetivos evaluables:
5 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html
Queremos calcular la derivada en el punto x0 = 2. El valor exacto de la derivada sería f '(2) = -0.25.
Ahora bien, vamos a calcular una aproximación de este valor como cociente de dos incrementos (de
manera similar a como se hizo en el ejemplo del paracaidista):
Nota: Para estos ejercicios puede ser útil implementar la función f como una función de Matlab, en
un fichero f.m:
function v = f(x)
v = 1/x;
Ejercicio 8: Realiza un script de Matlab que mediante un bucle vaya decrementando el valor de h
desde 0.1 hasta 10-16 y, para cada uno de estos valores, calcule la aproximación de la derivada y el
error relativo cometido (en valor absoluto).
for i=1:16
h(i) = 10^-i;
der(i) = ... COMPLETAR
err(i) = ... COMPLETAR
end
Ejercicio 9: Modifica el script anterior para que realice una gráfica del error relativo en función de h.
Para que se aprecie mejor la variación del error, haz la gráfica con el comando loglog, que es
equivalente a plot pero utilizando escalas logarítmicas tanto en vertical como en horizontal. ¿A qué
se debe el comportamiento del error? ¿Cuál es el valor óptimo de h en este caso?
6 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html
Objetivos:
Hemos visto que en el formato IEEE doble precisión, la operación 1+10-15 da un resultado distinto
de 1, mientras que 1+10-16 da como resultado 1, es decir, el número 10-16 es tan pequeño que al
realizar la operación de suma se pierden todos los dígitos que pudiera aportar al resultado.
Como se ha visto en teoría, hay un valor que llamamos épsilon, ε, que es el mínimo número que
sumado a 1 da como resultado un valor mayor que 1. En el caso de IEEE doble precisión, este
número estará entre 10-16 y 10-15, como se ha visto por el ejemplo. Pero, ¿cuál es exactamente ese
valor?
El valor de ε se puede deducir de forma teórica a partir de la descripción del formato IEEE. Sin
embargo, lo que vamos a hacer ahora es obtenerlo mediante un algoritmo. La idea es realizar un
bucle en el cual probamos la operación 1+x para valores cada vez más pequeños de x, hasta detectar
que el resultado de la suma da exactamente 1.
n = 0;
x = 1;
y = 2;
while y~=1
fprintf('n=%g, x=%g, y=%g\n',n,x,y)
n = n+1;
x = x/2;
y = 1+x;
end
x = x*2;
n = n-1;
Nota: Observar que después del bucle se deshace la última iteración para recuperar el valor anterior
al que provocó la salida del bucle.
n = 0;
x = 1;
y = 0;
7 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html
while x~=0
fprintf('n=%g, x=%g\n',n,x)
n = n+1;
y = x;
x = x/2;
end
n = n-1;
Ejercicio 11: Explica qué cálculo realiza la función. ¿Para qué sirve la asignación y = x?
Ejercicio 12: Realiza una función similar que obtenga el número máximo que puede representar
Matlab (por supuesto, sin considerar Inf). Esta función presenta una dificultad añadida que deberás
tener en cuenta (para saber a qué nos referimos, piensa cómo escribirías a mano el máximo
representable).
Ejercicio 13: Utiliza la función destripa para justificar que los valores obtenidos se ajustan al
formato de representación IEEE doble precisión.
Ejercicio 14: Compara los valores obtenidos con los que proporciona Matlab con los comandos eps,
realmin y realmax. ¿Coinciden en todos los casos? En el caso de que no sea así, justifica a qué se
debe la diferencia.
8 de 8 16/3/06 17:53