Sunteți pe pagina 1din 17

Tema 2

Aritmética del computador y


análisis de errores

Siempre que queremos trabajar con problemas reales, en ciencia, ingenierı́a, economı́a, etc, encon-
tramos que

• Tenemos que partir de datos que son resultados de medidas, y por tanto están sometidos a
errores, debido a las limitaciones de los aparatos de medida y a los posibles fallos cometidos
por el observador.

• Tenemos que hacer uso de ordenadores para realizar los cálculos, y los ordenadores tienen una
capacidad de almacenar números limitada. Tanto los datos de partida, como los resultados
de cada operación elemental, si no son números con los que pueda trabajar el ordenador, éste
va a aproximarlos por otro número que pueda utilizar.

Esto hace que constantemente se estén cometiendo errores. En muchos casos estos errores, que
inicialmente se pueden suponer muy pequeños, se van a mantener pequeños a lo largo del cálculo
hasta llegar al resultado final. Sin embargo, en otras situaciones se encuentra que aunque los
errores de los datos sean pequeños, y los cometidos en cada operación elemental también lo sean,
el error en el resultado final puede ser tan grande que el resultado no sea admisible. Vamos a
dedicar este tema a estudiar estos aspectos relativos al error, y a ver en qué casos el uso de un
método u otro para la resolución de un problema puede llevarnos a resultados afectados por los
errores en formas muy diferentes.

2.1 Almacenamiento de números en computadores


En el análisis que vamos a hacer en este capı́tulo vamos a utilizar para la representación de números
la notación cientı́fica o de punto flotante. De acuerdo con esta notación representamos los números
como
± 0.d1 d2 · · · dq × 10e , (2.1)
donde por ± entendemos el signo del número, dj , j = 1, . . . , q son cifras entre 0 y 9 de modo que
d1 ≥ 1 y e es un número entero. Al número decimal 0.d1 d2 · · · dq con su signo lo denominamos
mantisa, nos referimos al número entero e como exponente y decimos que un número de la forma
(2.1) tiene q cifras significativas. Damos a continuación, a modo de ejemplo la notación cientı́fica
de algunos números:

15
Elena Medina Reus 16

1326.789 en notación cientı́fica 0.1326789 × 104 , tiene 7 cifras significativas,


0.0003702 en notación cientı́fica 0.3702 × 10−3 , tiene 4 cifras significativas,
-5.27 en notación cientı́fica −0.527 × 101 , tiene 3 cifras significativas,
3.14159265 en notación cientı́fica 0.314159265 × 101 tiene 9 cifras significativas.

Para almacenar números, los ordenadores generalmente utilizan el sistema binario, o la repre-
sentación en base 2. Al igual que en el sistema decimal el número 1207 lo entendemos como

1207 = 7 × 100 + 0 × 101 + 2 × 102 + 1 × 103 ,

en el sistema binario el número 100101 lo tenemos que interpretar en la forma

100101 : 1 × 20 + 0 × 21 + 1 × 22 + 0 × 23 + 0 × 24 + 1 × 25 ,

y por lo tanto corresponde en base 10 a 37. La gran ventaja del sistema binario para el ordenador,
es que sólo se manejan dos cifras: 0 y 1, que pueden ser fácilmente almacenadas como paso (0) o
interrupción (1) de la corriente eléctrica. Cada una de estas cantidades recibe el nombre de bit.
Para entender cómo el ordenador almacena números mediante este sistema vamos a concentrarnos
en un ejemplo sencillo (en general la técnica es más complicada y se pueden introducir algunas
variantes a lo que se expone a continiación). Consideremos un ordenador que almacena números
mediante 32 bits (en base 2). Seguimos representando el número en la forma mantisa (m)-exponente
(e), que en base 2 viene dada como
m × 2e ,
y tomamos los 32 bits repartidos del siguiente modo:
• 8 bits representan el exponente. Estos bits están repartidos de la siguiente forma:
– 1 bit lo utilizamos para representar el signo: si el número es positivo le asignamos un 0
mientras que si es negativo, el bit que representa el signo tiene el valor 1.
– Los 7 bits restantes nos dan, en base 2, el valor absoluto del exponente. Esto quiere
decir que el exponente mayor que admitimos es 1111111 en base 2, es decir

1 × 20 + 1 × 21 + 1 × 22 + 1 × 23 + 1 × 24 + 1 × 25 + 1 × 26 = 127,

y análogamente el menor exponente admitido es -127.


• 24 bits representan la mantisa. En este caso la representación viene dada como
– 1 bit corresponde al signo: 0 para positivo y 1 para negativo.
– 23 bits corresponden a la mantisa: ahora leemos ésta cómo

0.r1 r2 r3 · · · = r1 × 2−1 + r2 × 2−2 + r3 × 2−3 + . . . . (2.2)

Además, si al igual que hicimos con la notación cientı́fica en base 10, exigimos que el
primer bit de la mantisa sea diferente de 0, tenemos que en base 2 sólo puede ser 1,
luego no tenemos necesidad de emplear un bit en almacenarlo. Tenemos entonces que
lo que el ordenador va a guardar de (2.2) es

r2 r3 r4 · · · r24

Ejemplo 2.1. El número almacenado por el ordenador como

0 0010110 1 00000110000001010100000
Elena Medina Reus 17

tiene un exponente positivo cuyo valor es

1 × 21 + 1 × 22 + 1 × 24 = 22,

y tiene una mantisa negativa de valor absoluto

1 × 2−1 + 1 × 2−7 + 1 × 2−8 + 1 × 2−15 + 1 × 2−17 + 1 × 2−19 = 0.5117588043212890625.

De esta forma, en sistema decimal se trata del número

−0.5117588043212890625 × 222 = −2.146472 × 106 .

Como hemos comentado anteriormente, de acuerdo con este esquema tenemos que el ordenador
puede almacenar números en los que el exponente −127 ≤ e ≤ 127, mientras que la mantisa tomará
valores en el intervalo [1/2, 1). Entonces:

• El número más pequeño, en valor absoluto, que podrá almacenar el ordenador es 12 × 2−127 =
2−128 ≈ 3 × 10−39 . Cualquier número inferior en valor absoluto que se genere en los cálculos,
el ordenador lo tomará como 0. Este fenómeno se conoce como “underflow” o desbordamiento
por defecto.

• El ordenador no puede almacenar números superiores a 2127 ≈ 1.7 × 1038 . El fenómeno que
tiene lugar cuando como resultado de un cálculo se genera un número superior, es conocido
como “overflow” o desbordamiento por exceso. En este caso la máquina no puede continuar
realizando cálculos. Envı́a un mensaje de error y se detiene.

En máquinas reales, la capacidad de almacenamiento suele ser muy superior. Ası́ por ejemplo
en Maxima se pueden manejar números con valores absolutos comprendidos entre 10 −308 y 10308 .

2.2 Aritmética de redondeo. Errores


Hemos visto ya cómo la capacidad de almacenar números de una máquina es finita, mientras que
los números que necesitamos manejar son infinitos. Este problema no se reduce tan sólo a los dos
casos de desbordamiento que hemos comentado en la sección anterior. Se tiene de hecho que los
números comprendidos en cualquier intervalo son infinitos, y la máquina es por tanto incapaz de
representarlos. Vamos a estudiar a continuación cómo se aborda este problema. Consideramos por
simplicidad una máquina decimal (expresamos los números en base 10) que trabaja con q cifras
significativas. Es claro que un número real puede tener más de q cifras significativas, y de hecho lo
genérico serı́a necesitar infinitas cifras para representarlo en forma decimal. Escribimos el número
en notación de punto flotante como

x = 0.d1 d2 d3 · · · dq dq+1 dq+2 · · · × 10e ,

donde los números di son tales que 0 ≤ di ≤ 9 para i ≥ 2 y 1 ≤ d1 ≤ 9. Dado que la máquina de
cálculo no dispone de capacidad para representarlo lo aproximamos por el número máquina más
próximo. Este número recibe el nombre de redondeo de x, lo denotamos como x ∗ y lo definimos
como: 
 dq si dq+1 < 5,
x∗ = 0.d1 d2 · · · dq−1 δq × 10e , donde δq :=
dq + 1 si dq+1 ≥ 5.

Elena Medina Reus 18

Ejemplo 2.2. Una máquina de cálculo que trabaja con 5 cifras significativas representarı́a los
números

x1 = 0.4378912814, x2 = 13 = 0.333333 · · · , x3 = 2 = 1.4142135 · · · ,

x4 = π = 3.141592654 · · · , x5 = e = 2.718281828 · · · ,
como

x∗1 = 0.43789, x∗2 = 0.33333, x∗3 = 0.14142 × 101 , x∗4 = 0.31416 × 101 , x∗5 = 0.27183 × 101 .

Observación 2.1. En el caso de que estemos trabajando con q cifras significativas y tengamos
que dq+1 ≥ 5 y dq = 9, tendrı́amos el redondeo dado como

x∗ = 0.d1 d2 · · · dq−2 δq−1 δq , siendo δq = 0, δq−1 = dq + 1.

Procedemos de la misma forma si alguna más de las cifras anteriores es igual a 9. Ası́, por ejemplo,
el redondeo a 5 cifras significativas de los números

x1 = 0.345697325, x2 = 0.1299976,

es
x∗1 = 0.34570, x2 = 0.13000.

Errores de redondeo
Ya hemos visto que en general los resultados de los cálculos no pueden ser representados en la
máquina de forma exacta. La máquina tiene por tanto que realizar una aproximación. Esto
supone que estamos cometiendo errores. Para cuantizar estos errores se introducen los siguientes
conceptos
Definición 2.1. Sea x un número que no puede ser representado por la máquina y denotamos x ∗
su redondeo a un número máquina. Se define entonces
error absoluto: |x − x∗ |,

|x − x∗ |
error relativo: .
|x|

En general, preferimos trabajar con el error relativo ya que la información que nos proporciona
nos da mejor una idea de si nuestro resultado es bueno o no. Por ejemplo un error absoluto del
orden de 500, podrı́a parecer muy grande, sin embargo si el número que está afectado por este
error es del orden de 106 , el error no es tan importante. Resulta de más interés decir que el error
relativo es del orden de 2 × 10−3 .
Ejemplo 2.3. Consideremos una máquina que trabaja con la representación decimal, y con 5
cifras significativas, y sean

x = 0.31426 × 103 , y = 0.92577 × 105 ,

tenemos entonces que


x
x+y = 0.9289126×105 , x−y = −0.9226274×105 , x∗y = 0.2909324802×108 , = 0.3394579647 · · ·×10−2 ,
y
Elena Medina Reus 19

mientras que la máquina de cálculo nos proporcionarı́a las aproximaciones


 ∗
∗ ∗ ∗ x
(x+y) = 0.92891×10 , 5
(x−y) = −0.92263×10 , 5
(x∗y) = 0.29093×10 , 8
= 0.33946×10−2 ,
y
lo que supone unos errores relativos
|(x + y)∗ − (x + y)| |(x − y)∗ − (x − y)|
< 3 × 10−6 , < 3 × 10−6 ,
|x + y| |x − y|
 ∗  
x

|(x ∗ y) − (x ∗ y)| | y − xy |
< 10−5 ,   < 3 × 10−6 .
|x ∗ y| x
| y |

En el ejemplo anterior hemos visto que haciendo los cálculos con 5 cifras significativas, los errores
que obtenemos son pequeños. Sin embargo esto depende también de los números con los que hemos
estado trabajando. Algunas operaciones pueden llevar a una pérdida de cifras significativas lo que
supone un claro incremento del error. Veamos a continuación un ejemplo que ilustra este hecho
Ejemplo 2.4. Partimos de los números

x = 0.3721478693, y = 0.3720230572,

cuya diferencia es
x − y = 0.0001248121.
Si volvemos a considerar una máquina que trabaje con 5 cifras significativas tenemos que

x∗ = 0.37215, y ∗ = 0.37202 ⇒ x∗ − y ∗ = 0.00013,

que ya es un número máquina y no necesita ser redondeado. Tenemos entonces que mientras que x ∗
e y ∗ tienen 5 cifras significativas, la representación de la diferencia tiene sólo 2 cifras significativas.
Esta pérdida de cifras significativas tiene como consecuencia un error relativo de
|(x∗ − y ∗ ) − (x − y)|
= 0.0416,
|(x − y)|
es decir, el error relativo es superior al 4%, lo que ya es un error mucho más importante que los
que veı́amos en el ejemplo anterior.
Es claro que lo que ha supuesto tener un error relativo importante en el último ejemplo es el
hecho de que hemos restado dos números muy parecidos. Este hecho se conoce como sustracción
de números casi-iguales, y es siempre fuente de errores importantes. Tendremos que volver más
adelante a considerar este tipo de problema.

Una consecuencia de los errores que cometemos en los cálculos debido a la necesidad de re-
dondear, es que algunas propiedades matemáticas dejan de ser ciertas al aplicar la aritmética de
redondeo. Veamos un ejemplo
Ejemplo 2.5. Sabemos que la suma de números reales satisface la propiedad asociativa: dados
tres números reales a, b y c, se tiene que

a + (b + c) = (a + b) + c.

Sin embargo, cuando estamos aplicando aritmética de redondeo no calculamos a + (b + c) sino


[a∗ + (b∗ + c∗ )∗ ]∗ , es decir
Elena Medina Reus 20

• En primer lugar realizamos la suma de los números obtenidos al redondear b y c: b ∗ + c∗ .

• Redondeamos este primer resultado: (b∗ + c∗ )∗ .

• Al resultado anterior le sumamos el redondeo de a: a∗ + (b∗ + c∗ )∗

• Finalmente redondeamos este resultado: [a∗ + (b∗ + c∗ )∗ ]∗

De la misma forma no calculamos (a + b) + c sino [(a∗ + b∗ )∗ + c∗ ]∗ , y en general

[a∗ + (b∗ + c∗ )∗ ]∗ 6= [(a∗ + b∗ )∗ + c∗ ]∗ .

Comprobamos este hecho con un ejemplo concreto: consideramos los números a, b y c que re-
dondeados a 8 cifras significativas son

a∗ = 0.23371258 × 10−4 , b∗ = 0.33678429 × 102 , c∗ = −0.33677811 × 102 .

Tenemos entonces para [a∗ + (b∗ + c∗ )∗ ]∗ :

• (b∗ + c∗ )∗ = b∗ + c∗ = 0.61800000 × 10−3 ,

• a∗ + (b∗ + c∗ )∗ = 0.641371258 × 10−3 .

• [a∗ + (b∗ + c∗ )∗ ]∗ = 0.64137126 × 10−3 .

Mientras que para [(a∗ + b∗ )∗ + c∗ ]∗ se obtiene:

• a∗ + b∗ = 0.33678452371 × 102 ,

• (a∗ + b∗ )∗ = 0.33678452 × 102 ,

• [(a∗ + b∗ )∗ + c∗ ]∗ = (a∗ + b∗ )∗ + c∗ = 0.641 × 10−3 .

Encontramos que la segunda forma de hacer los cálculos ha supuesto una mayor pérdida de cifras
significativas, y en consecuencia ambas formas no son equivalentes.

2.3 Estabilidad
Hemos visto que en aritmética de redondeo se pierden las propiedades matemáticas que se satis-
facen cuando se asume que los cálculos se realizan de forma exacta. Esto hace que procedimientos
matemáticamente equivalentes para resolver un problema, cuando se asume que los cálculos se
realizan de forma exacta, dejan de ser equivalentes cuando estamos aplicando aritmética de re-
dondeo. En consecuencia, para resolver un problema, de los diferentes procedimientos de los que
disponemos, tenemos que elegir áquel que evite que pequeños errores tanto en los datos iniciales
como en los pasos intermedios se propaguen de forma importante al resultado final. En este sentido
introducimos las siguientes definiciones.

Definición 2.2. Un algoritmo es un procedimiento que describe de forma inequı́voca una serie
finita de pasos a seguir en un orden determinado para resolver un problema o aproximar su solución.

Si volvemos al ejemplo 2.5, se proponen dos algoritmos diferentes para obtener el resultado de
la suma a + b + c:

• En el primer algoritmo empezamos por realizar la suma b∗ + c∗ con su correspondiente


redondeo, y posteriormente al resultado le sumamos a∗ y volvemos a redondear.
Elena Medina Reus 21

• En el segundo algoritmo realizamos en primer lugar la suma a∗ + b∗ redondeamos, y a


continuación sumamos c∗ y volvemos a redondear.

Es claro que el primer algoritmo nos lleva a mejores resultados que el segundo, ya que éste tiene
como resultado la pérdida de cifras significativas. Esto motiva la siguiente definición:

Definición 2.3. Decimos que un algoritmo es estable cuando los pequeños errores cometidos en
cada operación elemental tienen como resultado pequeños errores en el resultado final. En caso
contrario decimos que el algoritmo es inestable.

Ası́, cuando tenemos que resolver un problema nos interesa en primer lugar encontrar un algo-
ritmo estable para obtener el resultado, y además de que el algoritmo sea estable, queremos que
el error final sea lo menor posible. Presentamos algunos ejemplos y comentamos algunas ideas
básicas en este sentido.

Ejemplo 2.6. Supongamos que queremos evaluar integrales definidas de la forma


Z 1
In = xn ex dx, n = 0, 1, . . . , N, (2.3)
0

para algún número natural N . Realizando integración por partes, tomando u = x n y dv = ex dx


es claro que Z Z
xn ex dx = xn ex − n xn−1 ex dx,

y sustituyendo los lı́mites de integración encontramos

In = e − nIn−1 . (2.4)

Por otra parte se tiene que Z 1


1
I0 = ex dx = ex |0 = e − 1,
0

lo que junto con la ecuación (2.4) cambiando n por n + 1 nos proporciona un algoritmos para
calcular las integrales (2.3) consistente en

I0 = e − 1,
(2.5)
In+1 = e − (n + 1)In , n = 0, 1, . . . , N − 1.

Vamos a aplicar este algoritmo con Maxima para N = 15, usando aritmética con 7 cifras significa-
tivas. Para ello empezamos haciendo

fpprec:7;

Una vez fijada la precisión, realizamos un programa que haga uso de un bucle de la forma while...
do... (ver tema 1). En este programa hemos hecho uso de la instrucción append, que une dos
listas de valores. La lista que hemos denotado como integrales incluye todos los pares (n, I n )
que tenemos calculados. Cada vez que calculamos uno nuevo la incluimos en la lista mediante la
instrucción

integrales:append(integrales,[[n,I]])

Con todo esto el programa nos queda:


Elena Medina Reus 22

n:0$
I:bfloat(%e-1)$
integrales:[[n,I]]$
while n<15 do (I:bfloat(%e-(n+1)*I),n:n+1,integrales:append(integrales,[[n,I]]))$
integrales;

que da como resultado


h
[0, 1.718282b0] , [1, 1.0b0] , [2, 7.182818b − 1] , [3, 5.634364b − 1] , [4, 4.645362b − 1] , [5, 3.956006b − 1] ,
[6, 3.446785b − 1] , [7, 3.055326b − 1] , [8, 2.740212b − 1] , [9, 2.520909b − 1] , [10, 1.973725bi− 1] ,
[11, 5.471844b − 1] , [12, −3.84793b0] , [13, 5.274138b1] , [14, −7.35661b2] , [15, 1.103763b4]

Pero aunque los primeros resultados son correctos es evidente que los últimos no pueden serlo. En
efecto, en el intervalo [0, 1] en el que estamos realizando la integración se tiene que e x ≤ e luego
0 ≤ xn ex ≤ xn e, y por tanto debemos tener
Z 1
e
0 ≤ In ≤ xn e dx = .
0 n+1
Es imposible entonces que obtengamos resultados negativos o de magnitudes tan grandes como
algunos de los que encontramos en la lista anterior. Dado que el algoritmo (2.5) es exacto, el
motivo de que los resultados obtenidos sean incorrectos es que este algoritmo es inestable. Un
pequeño error en un cálculo, al cabo de unas cuantas aplicaciones de la segunda ecuación de (2.5)
(iteraciones) tiene como consecuencia un error muy grande en los resultados.
Vamos a comentar a continuación, mediante dos ejemplos cómo en algunos casos si conocemos
cuál es la posible fuente de error podemos elegir adecuadamente el algoritmo que evite que la
propagación de los errores sea importante:

Sustracción de números casi-iguales: Resolución de ecuaciones de se-


gundo grado
Hemos visto en el ejemplo 2.4 cómo el tener que restar dos números muy parecidos nos conduce
a la pérdida de cifras significativas y en consecuencia a que el error relativo de redondeo pueda
hacerse muy grande. Cuando en la evaluación de una función encontramos que tenemos que llevar
a cabo una sustracción de este tipo, es conveniente estudiar previamente si tenemos alguna forma
equivalente de evaluar la función que evite tener que realizar esta sustracción.
Supongamos por ejemplo, que tenemos que evaluar la función
p
f (x) = 1 + x2 − 1,

para x = c siendo c un número muy pequeño, 0 < c << 1. Tenemos entonces, √ que si no disponemos
de suficiente precisión para hacer los cálculos, el ordenado va a tomar 1 + c2 ≈ 1 y el resultado de
f (c) va a perder muchas cifras significativas, pudiendo incluso dar como resultado 0. Sin embargo
si escribimos f (x) en la forma equivalente
√ √
( 1 + x2 − 1)( 1 + x2 + 1) x2
f (x) = √ =√ ,
1 + x2 + 1 1 + x2 + 1
hemos evitado la sustracción de números casi-iguales. Tenemos en consecuencia que evaluar f (c)
como
Elena Medina Reus 23


• f (c) = 1 + c2 − 1 es un algoritmo inestable,
c2
• f (c) = √ es un algoritmo estable.
1 + c2 + 1
Observación 2.2. Encontramos el mismo problema, y podemos abordarlo del mismo modo cuando
tenemos que evaluar una función de la forma
p
g(x) = 1 + x2 − x,
para x = c siendo c un número positivo y muy grande, c >> 1.
Estos problemas nos aparecen con frecuencia en la resolución de ecuaciones de segundo grado.
Presentamos a continuación un ejemplo:
Ejemplo 2.7. Consideramos la ecuación de segundo grado
x2 + 62.10x + 1 = 0,
que denotando a = 1, b = 62.10 y c = 1 tiene por soluciones
√ √
−b + b2 − 4ac −b − b2 − 4ac
x1 = = −0.01610724, x2 = = −62.083893.
2a 2a
Si sustituimos los datos en las expresiones anteriores y utilizamos aritmética de redondeo con 4
cifras significativas tenemos que:
p
b2 ≈ 3856, b2 − 4ac ≈ 3852, b2 − 4ac ≈ 62.06,
y en consecuencia

• −b + b2 − 4ac ≈ −0.04 lo que proporciona para x∗1 = −0.02.

• −b − b2 − 4ac ≈ −124.2 lo que proporciona para x∗2 = −62.10.
Vemos ası́ que el algoritmo proporcionado para calcular las raı́ces ha provocado una pérdida de
cifras significativas en el caso de la raı́z x1 . Si calculamos los errores relativos encontramos que
|x∗1 − x1 | |x∗2 − x2 |
≈ 0.25, ≈ 3.2 × 10−4 .
|x1 | |x2 |
Ası́, mientras que el resultado para x2 √ es muy bueno, no podemos decir lo mismo del resultado
para x1 . Comparando los valores de b y b2 − 4ac es claro que la pérdida de cifras significativas en
x1 , y por consiguiente el error en esta raı́z, se debe a una sustracción de números casi-iguales. Pro-
cedemos a evitar esta sustracción como hemos explicado anteriormente: modificamos el algoritmo
para calcular x1 como
√ √ √
−b + b2 − 4ac (−b + b2 − 4ac)(b + b2 − 4ac) 2c
x1 = = √ =− √ ,
2a 2
2a(b + b − 4ac) b + b2 − 4ac
que teniendo en cuenta los cálculos anteriores, con 4 cifras significativas nos queda como
2
x∗∗
1 =− = −0.01610,
124.2
mucho mejor aproximación al valor de x1 . En particular el error relativo viene dado por:
|x∗1 − x1 |
≈ 6 × 10−4 .
|x1 |
Elena Medina Reus 24

Método de Horner para la evaluación de polinomios


Un problema que encontramos con frecuencia es el de evaluar un polinomio en cierto valor de la
variable. Para realizar dicha evaluación hacemos uso de un algoritmo. Por ejemplo, tomamos, para
hacer la explicación más sencilla, un polinomio de grado 3 de la forma

p(x) = a3 x3 + a2 x2 + a1 x + a0 , (2.6)

y asumimos que el algoritmo que usamos para evaluarlo en x = c es:

• Calculamos c2 = c c y lo redondeamos en caso necesario.


• Calculamos c3 como el valor anteriormente calculado para c2 multiplicado por c, y un nuevo
redondeo si es preciso.

• Multiplicamos el valor calculado de c3 por a3 y redondeamos.

• Multiplicamos el valor calculado de c2 por a2 y redondeamos.

• Multiplicamos a1 por c y redondeamos.

• Sumamos los valores obtenidos para a3 c3 y a2 c2 , aplicando el correspondiente redondeo.


• Sumamos el resultado anterior a a1 c, con un nuevo redondeo si es preciso.

• Sumamos finalmente el último resultado a a0 y en caso necesario volvemos a redondear.

Es claro que de esta forma hemos realizado 5 multiplicaciones y 3 sumas. Sin embargo si escribimos
el polinomio en la forma
p(x) = a0 + x(a1 + x(a2 + xa3 )), (2.7)
la evaluación en x = c consistirá en
• Multiplicamos a3 por c y redondeamos si es preciso.

• Sumamos el resultado anterior a a2 , volviendo a aplicar redondeo.

• Multiplicamos el último resultado por c, y redondeamos.

• Sumamos a1 al número obtenido en el paso anterior y volvemos a redondear.

• Multiplicamos el último resultado por c con el correspondiente redondeo.

• Finalmente sumamos a0 al resultado anterior y redondeamos en caso necesario.

De esta forma hemos realizado 3 multiplicaciones y 3 sumas. Al ser menor el número de opera-
ciones, y por tanto las aproximaciones por redondeo que debemos llevar a cabo, esperamos mejores
resultados de la evaluación del polinomio en la forma (2.7). Esta forma de escribir el polinomio, que
realmente supone un algoritmos diferente para evaluarlo, es conocida como Método de Horner
y puede implementarse en Maxima mediante la instrucción horner(pol), siendo pol un polinomio.
Presentamos un ejemplo a continuación:

Ejemplo 2.8. Sea el polinomio

p(x) = x3 − 6.1x2 + 3.2x + 1.5,


Elena Medina Reus 25

que queremos evaluar en c = 4.71 con una máquina de cálculo que trabaja con 4 cifras significativas.
Los resultados obtenidos de cálculo directo son:
(c2 )∗ = 22.18, (c3 )∗ := ((c2 )∗ c)∗ = 104.5,

(6.1(c2 )∗ )∗ = 135.3, (3.2c)∗ = 15.07,

(c3 )∗ − (6.1(c2 )∗ )∗ = −30.8, ((c3 )∗ − (6.1(c2 )∗ )∗ ) + (3.2c)∗ = −15.73,

(((c3 )∗ − (6.1(c2 )∗ )∗ ) + (3.2c)∗ ) + 1.5 = −14.23.

Mientras que si escribimos el polinomio en su forma de Horner

p(x) = 1.5 + x(3.2 + x(−6.1 + x)),

tenemos los cálculos


−6.1 + c = −1.39, (c(−6.1 + c))∗ = −6.547,

3.2 + (c(−6.1 + c))∗ = −3.347, (c(3.2 + (c(−6.1 + c))∗ ))∗ = −15.76,

1.5 + (c(3.2 + (c(−6.1 + c))∗ ))∗ = −14.26.

El resultado ha sido diferente según el algoritmo empleado, mientras que si realizamos los cálculos
con Maxima, con la precisión de 16 cifras significativas, obtenemos p(c) = −14.263899. Tenemos
entonces que hemos obtenido mejor resultado mediante la aplicación del método de Horner.

Esta diferencia en el resultado según el algoritmo empleado es mucho más clara cuando el
polinomio es de grado elevado. Si el grado del polinomio es n. El número de operaciones viene
dado por:

• Aplicando el algoritmo (2.6) 2n − 1 multiplicaciones y n sumas.


• Aplicando el algoritmo (2.7) n multiplicaciones y n sumas.

Las multiplicaciones suponen un esfuerzo, y por tanto un tiempo, de cálculo superior al de las
sumas, y generalmente un mayor incremento del error de redondeo.

2.4 Condicionamiento
Hemos visto que, en general, cometemos errores tanto al almacenar los números como al realizar
operaciones elementales. Sin embargo esto no es la única fuente de error. En efecto, si estamos
pensando en un ejemplo surgido en fı́sica, quı́mica, ingenierı́a o cualquier otra ciencia experimental,
los datos del problema habrán sido obtenidos como resultados de medidas y las medidas están
siempre afectadas por errores que dependen tanto de la precisión del aparato de medida, que
siempre es limitada, como de posibles fallos que puedan ser cometidos por el observador que está
realizando la medida.
Surge entonces la siguiente cuestión: Tenemos un conjunto de datos que tienen pequeños errores,
ya sean debidos al redondeo o a que son resultados de medidas, y estos datos los vamos a utilizar
en la resolución de un problema. Queremos saber cómo será el error en el resultado del problema
como consecuencia de los errores de los datos iniciales, con independencia del método con el que
realicemos los cálculos. Introducimos en este sentido la siguiente definición:
Elena Medina Reus 26

Definición 2.4. Decimos que un problema está bien condicionado, si pequeños errores en los
datos dan lugar también a pequeños errores en los resultados. Si por el contrario, pequeños errores
en los datos dan lugar a errores importantes en los resultados, decimos que el problema está mal
condicionado.
Vamos a considerar tres tipos de problemas básicos en los que podemos ilustrar este concepto:

Evaluación de funciones
Empezamos por plantearnos un problema elemental: tenemos que evaluar una función f (x) en
x = a pero el valor de a lo hemos obtenido como resultado de una medida y en consecuencia está
afectado por un error: no tenemos realmente a sino b = a + h siendo |h| el error absoluto, y por
tanto |h|
|a| el error relativo. Queremos ver cómo afecta este error al error que vamos a cometer al
tomar f (b) en lugar de f (a). Es importante notar, que a diferencia de lo estudiado en la sección
anterior, aquı́ no estamos considerando los errores de redondeo que se comenten en las operaciones
elementales que nos conducen a la evaluación de f sino tan sólo el hecho de que partimos de un dato
con un error y esto va a darnos un resultado con un error. Queremos saber si un error relativo
pequeño en el dato supondrá también un error relativo pequeño en el resultado, problema bien
condicionado, o por el contrario, aunque el error relativo del dato sea pequeño, el error relativo en
el resultado puede ser importante, problema mal condicionado.
Si suponemos que h es pequeño, podemos esperar que se verifique

f (b) = f (a + h) ≈ f (a) + f 0 (a)h,

ası́, el error relativo de f (a) será


|f 0 (a)h|
.
|f (a)|
Definimos el número de condición, como el cociente entre el error relativo del resultado y el
error relativo del dato. Esto es
|f 0 (a)h|
|f (a)| |a f 0 (a)|
κ(f (a)) = = , (2.8)
|h| |f (a)|
|a|

y este número nos indica cómo afecta el error relativo del dato al error relativo del resultado. En
consecuencia si κ(f (a)) es grande un error relativo pequeño en el dato afecta de forma importante
al resultado y el problema está mal condicionado, mientras que si el número de condición es
pequeño, un error relativo pequeño en el dato tiene como consecuencia un error relativo pequeño
en el resultado, y el problema está bien condicionado. Veamos algunos ejemplos
2
Ejemplo 2.9. Consideramos la función f (x) = ex . Sustituyendo en (2.8) tenemos que el número
de condición para la evaluación de f (a) viene dado por κ(f (a)) = 2a2 , por lo tanto
• El número de condición es grande si a es grande, tenemos que el problema está mál condi-
cionado. Lo ponemos de manifiesto a continuación tomando a = 25 y b = 25.01, el error
relativo entonces es 4 × 10−4 . A partir de las siguientes instrucciones de Maxima

f(x):=exp(x^2)$
a:25$
b:25.01$
Elena Medina Reus 27

fa:float(f(a))$
fb:float(f(b))$
errorrelativo:abs(fb-fa)/abs(fa)$
print(fa,fb,errorrelativo);

obtenemos los resultados

2.7167594696637367 ∗ 10+271 , 4.4796270653201427 ∗ 10+271 , 0.64888615107123,

en los que vemos que el error relativo es ahora tan importante, que hace que el resultado no
podamos considerarlo válido.

• Por el contrario si a es pequeño, el número de condición es también pequeño. Lo comprobamos


tomando a = 0.5, b = 0.51, ası́ el error relativo es 0.02 y el resultado

f(x):=exp(x^2)$
a:0.5$
b:0.51$
fa:float(f(a))$
fb:float(f(b))$
errorrelativo:abs(fb-fa)/abs(fa)$
print(fa,fb,errorrelativo);

1.284025416687741, 1.297059786159305, 0.010151177151296,

tiene un error relativo de aproximadamente 0.01.

Con el ejemplo anterior hemos visto que el condicionamiento depende tanto de la función, como
del punto en el que queramos evaluarla. Ilustramos este hecho con un nuevo ejemplo

Ejemplo 2.10. Consideramos la función f (x) = cos(x), que teniendo en cuenta (2.8) tiene número
de condición
κ(f (x)) = x tan(x).
Es claro que este número será muy pequeño si x es pequeño, sin embargo si x está próximo a
π
2 ≈ 1.570796327, el número de condición se hará muy grande. Veamos cómo cerca de este valor
partiendo de un error relativo inferior a 10−5 encontramos un resultado con un error superior al
100%

f(x):=cos(x)$
a:1.57079$
b:1.57078$
fa:float(f(a))$
fb:float(f(b))$
errorrelativo:abs(fb-fa)/abs(fa)$
print(fa,fb,errorrelativo);

6.3267948966684677 ∗ 10−6 , 1.6326794895828789 ∗ 10−5 , 1.580579134061399.


Elena Medina Reus 28

Resolución de sistemas lineales


Otra situación en la que resulta de gran interés el condicionamiento es la resolución de sistemas
lineales. Vamos a limitarnos aquı́ a exponer un ejemplo. Supongamos que en el estudio de un
problema, nos encontramos que tenemos que resolver el sistema lineal
10x1 + 7x2 + 8x3 + 7x4 = 32,
7x1 + 5x2 + 6x3 + 5x4 = 23,
8x1 + 6x2 + 10x3 + 9x4 = 33,
7x1 + 5x2 + 9x3 + 10x4 = 31.
Podemos proceder con Maxima, para ello empezamos por introducir la matriz del sistema a la que
denominamos A como
A:matrix([10,7,8,7],[7,5,6,5],[8,6,10,9],[7,5,9,10])$
Invertimos dicha matriz mediante la instrucción invert en la forma
B:invert(A);
lo que nos da el resultado
 
25 −41 10 −6
 −41 68 −17 10 
 .
 10 −17 5 −3 
−6 10 −3 2
Tenemos entonces que si denominamos b al vector de los términos independientes, y lo introducimos
en Maxima como
b:[32,23,33,31];
la solución del sistema viene dada por el vector A−1 b = Bb, o en Maxima
B . b;
que da como resultado
 
1
1
 
1
1.
Es decir, nuestro sistema tiene como solución
x1 = x2 = x3 = x4 = 1,
Supongamos ahora que los términos independientes del sistema son resultados de medidas, en las
que hemos cometidos pequeños errores, y el sistema nos ha quedado de la forma
10y1 + 7y2 + 8y3 + 7y4 = 32.1,
7y1 + 5y2 + 6y3 + 5y4 = 22.9,
8y1 + 6y2 + 10y3 + 9y4 = 33.1,
7y1 + 5y2 + 9y3 + 10y4 = 30.9.
Tenemos de nuevo la misma matriz del sistema que en el caso anterior, pero el vector de términos
independientes debemos modificarlo, introduciendo ahora
Elena Medina Reus 29

c:[32.1,22.9,33.1,30.9]$

y en consecuencia, la nueva solución

B . c;

viene dada como


 
9.2
−12.6
 4.5  .
 

−1.1,
es decir
y1 = 9.2, y2 = −12.6, y3 = 4.5, y4 = −1.1.
Encontramos de esta forma, que cometiendo errores relativos inferiores a 0.005 en los términos inde-
pendientes, la solución del sistema tiene errores absolutamente inadmisibles. Estamos claramente
ante un problema mal condicionado.
Igual que para el caso de la evaluación de funciones, dado un sistema lineal podemos definir
un número de condición cuya magnitud nos dice cómo afectan pequeños errores en los datos, a
los errores en la solución, y en consecuencia si el sistema está bien condicionado o no. Dado un
sistema lineal tal que la matriz del sistema es A, se define el número de condición como
|λmax |
κ(A) = , (2.9)
|λmin |
siendo λmax y λmin los autovalores de A cuyo módulo es máximo o mı́nimo. De (2.9) podemos ver
que κ(A) ≥ 1 para toda matriz A, y se tiene que:
• Si κ(A) & 1 el sistema está bien condicionado.
• Si κ(A)  1 el sistema está mal condicionado.
Volvamos al ejemplo anterior, y vamos a calcular el número de condición. Para ello empezamos por
determinar el polinomio caracterı́stico, lo que podemos hacer con Maxima utilizando la instrucción
charpoly(matriz,variable) como

pol:charpoly(A,x)$
pol:expand(pol);

lo que nos da

x4 − 35 x3 + 146 x2 − 100 x + 1.
La instrucción que nos permite calcular las raı́ces, y por tanto los autovalores de A es allroots:

raices:allroots(pol);

de donde obtenemos los autovalores

[x = 0.010150048397892, x = 0.84310714985503, x = 3.858057455944953, x = 30.28868534580213] .

Se trata en este caso de 4 autovalores reales y positivos, teniendo en cuenta sus valores tomamos
el máximo y el mı́nimo, y calculamos el número de condición de acuerdo con la definición
Elena Medina Reus 30

xmin:ev(x,raices[1]);

0.010150048397892

xmax:ev(x,raices[4]);

30.28868534580213

ncon:xmax/xmin;

2984.092701675491
El número de condición obtenido muy grande, lo que nos dice que el sistema está mal condicionado,
de acuerdo con los resultados que habı́amos obtenido anteriormente. Hemos usado la instrucción
ev para evaluar una expressión (en nuestro ejemplo x) en el valor dado en el segundo argumento.
Para indicar este segundo argumento hemos tenido en cuenta que raices es un vector, entonces
para tomar la componente i tenemos que hacer raices[i].

Determinación de las raı́ces de un polinomio


También pueden presentarse problemas de condicionamiento que es importante conocer cuando
necesitamos calcular las raı́ces de un polinomio en el que los coeficientes pueden ser resultados de
observaciones experimentales y por tanto estar sometidos a errores, o bien pueden ser números
que no admitan una representación decimal exacta, y en consecuencia deben ser aproximados para
poder trabajar con ellos en el ordenador. Puede ocurrir que pequeños errores en los coeficientes den
lugar a grandes errores en las raı́ces, como ocurre en el ejemplo que presentamos a continuación:

Ejemplo 2.11. Consideramos el polinomio de Wilkinson definido como


20
Y
w(x) = (x − i) = (x − 1)(x − 2) · · · (x − 19)(x − 20),
i=1

cuyas raı́ces son x = 1, 2, . . . , 19, 20, y veamos cómo varı́an estas raı́ces cuando:

• El coeficiente de x20 se modifica de a20 = 1 para el polinomio de Wilkinson a ã20 = 1 + 10−3 .

• El resto de los coeficientes mantienen su valor.

Es decir, queremos comparar las raı́ces del polinomio de Wilkinson w(x) con las raı́ces del polinomio
w0 (x) definido como
w0 (x) = w(x) + 10−3 x20 .
Para calcular las raı́ces de w0 (x) introducimos las siguientes instrucciones en Maxima

w:product(x-i,i,1,20)$
w0:expand(10^(-3)*x^20+w)$
allroots(w0);
Elena Medina Reus 31

y obtenemos como resultado que las raı́ces de w0 (x) son

h
x = 0.99999999999999, x = 1.999999999997564, x = 3.00000000518208,
x = 3.999991230769558, x = 5.00308848799142, x = 5.827362348742914,
x = 0.8672871116705 i + 6.402868135771345, x = 6.402868135771345 − 0.8672871116705 i,
x = 2.148957540723057 i + 7.189012901267484, x = 7.189012901267484 − 2.148957540723057 i,
x = 3.813981765310256 i + 8.173138002196376, x = 8.173138002196376 − 3.813981765310256 i,
x = 6.067661487603411 i + 9.596748564883294, x = 9.596748564883294 − 6.067661487603411 i,
x = 9.229632463293228 i + 12.14820997620488, x = 12.14820997620488 − 9.229632463293228 i,
x = 13.25906363692948 i + 18.1227720970347, x = 18.1227720970347 − 13.25906363692948 i, i
x = 11.03342426977722 i + 32.84713418140508, x = 32.84713418140508 − 11.03342426977722 i .

Esto supone que un error relativo de 10−3 en uno de los coeficientes, aunque ha introducido
errores también muy pequeños en las primeras raı́ces, se ha ido incrementando para raı́ces superiores
de w hasta dar errores relativos muy grandes. Se tiene, en consecuencia, que el polinomio de
Wilkinson está mal condicionado.

S-ar putea să vă placă și