Aproximaciones y errores de redondeo

Definiciones de error

La relación entre valor exacto o verdadero y el valor aproximado es la siguiente:

\begin{equation*} \text{valor verdadero} = \text{valor aproximado} + \text{error} \end{equation*}

Despejando el error de la anterior ecuación:

\begin{equation*} E_{t} = \text{valor verdadero} - \text{valor aproximado} \end{equation*}

donde $E_{t}$ representa el valor exacto del error o error "verdadero"

Una desventaja de la anterior fórmula es que no toma en cuenta el orden de la magnitud del valor aproximado, una manera de tomar en cuenta la magnitud de la aproximación consiste en normalizar el error verdadero respecto al valor verdadero:

\begin{equation} \text{Error relativo verdadero} = \frac{\text{error verdadero}}{\text{valor verdadero}} \end{equation}

si multiplicamos por 100%:

\begin{equation} \epsilon_{t} = \frac{\text{error verdadero}}{\text{valor verdadero}} \cdot 100 \% \end{equation}

donde $\epsilon_{t}$ representa error relativo porcentual verdadero.

En muchas aplicaciones reales no se conoce el valor verdadero, una alternativa es normalizar la mejor estimación posible del error verdadero:

\begin{equation*} \epsilon_{a} = \frac{\text{error aproximado}}{\text{valor aproximado}} \cdot 100 \% \end{equation*}

donde $\epsilon_{a}$ representa error relativo porcentual aproximado, ciertos métodos numéricos usan un método iterativo para calcular en forma sucesiva aproximaciones para tal caso la anterior forma expresada en forma iterativa es:

\begin{equation*} \epsilon_{a} = \frac{\text{error aproximado actual - error aproximado anterior}}{\text{valor aproximado actual}} \cdot 100 \% \end{equation*}

A menudo cuando se realizan cálculos no importa mucho el signo de $\epsilon_{a}$, sino que el valor absoluto relativo porcentual sea menor que una tolerancia porcentual prefijada.

\begin{equation*} | \epsilon_{a} | < \epsilon_{s} \end{equation*}

Es conveniente relacionar estos errores con el número de $n$ cifras significativas:

\begin{equation*} \epsilon_{s} = \frac{10^{2 - n}}{2} \cdot 100\% \end{equation*}

Estimación del error con métodos iterativos

Calcular $e^{x}$ usando series de Maclaurin para $x = 0.5$ usando tres cifras significativas:

\begin{equation*} e^{x} = \frac{x^{0}}{0!} + \frac{x^{1}}{1!} + \frac{x^{2}}{2!} + \frac{x^{3}}{3!} + \cdots \end{equation*}

El error prefijado $\epsilon_{s}$ será:

\begin{equation*} \epsilon_{s} = \frac{10^{2 - 3}}{2} \cdot 100\% = 0.05\% \end{equation*}

Primera aproximación

\begin{equation*} e^{0.5} = 1 \end{equation*}

Calculando $\epsilon_{t}$

\begin{equation*} \epsilon_{t} = \frac{1.648721 - 1}{1.648721} \cdot 100\% = 39.35\% \end{equation*}

Calculando $\epsilon_{a}$

\begin{equation*} \epsilon_{a} = \frac{1 - 0}{1} \cdot 100\% = 100\% \end{equation*}

Segunda aproximación

\begin{equation*} e^{0.5} = 1 + 0.5 = 1.5 \end{equation*}

Calculamos $\epsilon_{t}$

\begin{equation*} \epsilon_{t} = \frac{1.648721 - 1.5}{1.648721} \cdot 100\% = 9.02\% \end{equation*}

Calculamos $\epsilon_{a}$

\begin{equation*} \epsilon_{a} = \frac{1.5 - 1}{1.5} \cdot 100\% = 33.33\% \end{equation*}

Implementación

Mediante el siguiente programa se calculará los errores de aproximación:


In [1]:
x = 0.5
valor_actual = 0.0

@printf("%s \t %s \t %s \t %12s\n", "iteración", "exp(0.5)", "ϵₜ %", "ϵₐ %")

for i = 0:5
    valor_anterior = valor_actual
    valor_actual = valor_actual + (x^i)/factorial(i)
    et = ((exp(x) - valor_actual)/exp(x))*100
    ea = ((valor_actual - valor_anterior) / valor_actual)*100
    @printf("%d \t %16f \t %f \t %f\n", i+1, valor_actual, et, ea)
end


iteración 	 exp(0.5) 	 ϵₜ % 	         ϵₐ %
1 	         1.000000 	 39.346934 	 100.000000
2 	         1.500000 	 9.020401 	 33.333333
3 	         1.625000 	 1.438768 	 7.692308
4 	         1.645833 	 0.175162 	 1.265823
5 	         1.648438 	 0.017212 	 0.157978
6 	         1.648698 	 0.001416 	 0.015795

Seudocódigo para cálculos iterativos

función MetodoIterativo(valor, es, iteración_máxima)
    iteración = 1
    solución_actual = valor
    ea = 100
    hacer
        iteración = iteración + 1
        solución_anterior = solución_actual
        solución_actual = ...
        si solución_actual != 0
            ea = abs((solución_actual - solución_anterior) / solución_actual) * 100
        fin si
    hasta (ea <= es) o (iteración >= iteración_máxima)
    fin hacer
    MetodoIterativo = solución_actual
fin MetodoIterativo

Implementación para calcular $e^{x}$


In [2]:
function exponencial(x, es, i_max)
    i = 0
    valor_actual = 0
    while true
        valor_anterior = valor_actual
        valor_actual = valor_actual + (x^i)/factorial(i)
        i = i + 1
        if valor_actual != 0
            ea = ((valor_actual - valor_anterior) / valor_actual)*100
        end
        if (ea <= es) || (i >= i_max)
            println("iteración = ", i) # solo para comprobar
            println("ea = ", ea) # solo para comprobar
            println("et = ", ((exp(x) - valor_actual)/exp(x))*100) # solo para comprobar
            break
        end
    end
    return valor_actual
end


Out[2]:
exponencial (generic function with 1 method)

In [3]:
exponencial(1, 1e-6, 100)


iteración = 12
ea = 9.216155641522974e-7
et = 8.316106763523326e-8
Out[3]:
2.718281826198493

Errores de redondeo

Representación de números en la computadora

Los números se asemejan a una recta con dominio discreto y espaciados a $\Delta x$

gráfico

El siguiente número que existe después de $0$ es


In [4]:
nextfloat(0.0)


Out[4]:
5.0e-324

El siguiente número que existe después de $1$ es:


In [5]:
nextfloat(1.0)


Out[5]:
1.0000000000000002

In [6]:
Δx = nextfloat(1.0) - 1.0
println("Δx = ", Δx)


Δx = 2.220446049250313e-16

Épsilon de máquina

El épsilon de máquina es la "distancia" entre dos números de punto flotante, se calcula como:

\begin{equation*} \epsilon = b^{1 - t} \end{equation*}

donde $b$ es el número base y $t$ es el número de cifras significativas en la mantisa, por ejemplo si $t = 16$:

\begin{equation*} \epsilon = 10^{1 - 16} = 0.000000000000001 \end{equation*}

Puede ser calculado mediante el siguiente seudocódigo:

epsilon = 1
hacer
    epsilon = epsilon / 2
hasta epsilon + 1 <= 1
fin hacer
epsilon = 2 * epsilon

Programa para calcular el épsilon de máquina


In [7]:
ϵ = 1
while true
    ϵ = ϵ/2
    if ϵ + 1 <= 1
        break
    end
end
ϵ = 2ϵ


Out[7]:
2.220446049250313e-16

Comparamos con el comando eps()


In [8]:
eps(Float64)


Out[8]:
2.220446049250313e-16

Aproximaciones cuando se realiza un gran número de cálculos


In [9]:
sum1 = float32(0.0)
sum2 = float32(0.0)
sum3 = float64(0.0)

x1 = float32(1.0)
x2 = float32(1.0e-5)
x3 = float64(1.0e-5)

for i = 1:100000
    sum1 = sum1 + x1
    sum2 = sum2 + x2
    sum3 = sum3 + x3
end

println("Cálculos son Float32")
println("Valor exacto = ", 100000)
println("Valor aproximado = ", sum1)
println("Cálculos son Float32")
println("Valor exacto = ", 1)
println("Valor aproximado = ", sum2)
println("Cálculos son Float64")
println("Valor exacto = ", 1)
println("Valor aproximado = ", sum3)


Cálculos son Float32
Valor exacto = 100000
Valor aproximado = 100000.0
Cálculos son Float32
Valor exacto = 1
Valor aproximado = 1.0009902
Cálculos son Float64
Valor exacto = 1
Valor aproximado = 0.9999999999980838

Cancelación por resta

Calcular las raices de

\begin{equation*} x^{2} + 3000.001 x + 3 \end{equation*}

Usando la fórmula

\begin{align*} x_{1} &= \frac{-3000.001 + \sqrt{3000.001^{2} - 4 (1) (3)}}{2 (1)} = -0.001 \\ x_{2} &= \frac{-3000.001 - \sqrt{3000.001^{2} - 4 (1) (3)}}{2 (1)} = -3000 \end{align*}

In [10]:
a = float32(1.0)
b = float32(3000.001)
c = float32(3.0)

d = sqrt(b^2 - 4*a*c)
x1 = (-b + d) / 2*a
x2 = (-b - d) / 2*a

println("Cálculos con Float32")
println("x1 = ", x1)
println("x2 = ", x2)

a = 1.0
b = 3000.001
c = 3.0

d = sqrt(b^2 - 4*a*c)
x1 = (-b + d) / 2*a
x2 = (-b - d) / 2*a

println("Cálculos con Float64")
println("x1 = ", x1)
println("x2 = ", x2)


Cálculos con Float32
x1 = -0.0009765625
x2 = -3000.0
Cálculos con Float64
x1 = -0.0009999999999763531
x2 = -3000.0

Cuando $b^{2} \gg 4ac$ se racionaliza la fórmula

\begin{align} x_{1} &= \frac{-b + \sqrt{b^{2} - 4 a c}}{2 a} \left( \frac{-b - \sqrt{b^{2} - 4 a c}}{-b - \sqrt{b^{2} - 4 a c}} \right) = \frac{-2 c}{b + \sqrt{b^{2} - 4 a c}} \\ x_{2} &= \frac{-b - \sqrt{b^{2} - 4 a c}}{2 a} \left( \frac{-b + \sqrt{b^{2} - 4 a c}}{-b + \sqrt{b^{2} - 4 a c}} \right) = \frac{-2 c}{b - \sqrt{b^{2} - 4 a c}} \end{align}

In [11]:
a = float32(1.0)
b = float32(3000.001)
c = float32(3.0)

d = sqrt(b^2 - 4*a*c)
x1 = -2*c / (b + d)
x2 = -2*c / (b - d)

println("Cálculos con Float32")
println("x1 = ", x1)
println("x2 = ", x2)

a = 1.0
b = 3000.001
c = 3.0

d = sqrt(b^2 - 4*a*c)
x1 = -2*c / (b + d)
x2 = -2*c / (b - d)

println("Cálculos con Float64")
println("x1 = ", x1)
println("x2 = ", x2)


Cálculos con Float32
x1 = -0.001
x2 = -3072.0
Cálculos con Float64
x1 = -0.001
x2 = -3000.0000000709406

Convergencia

Calcular $e^{x}$ usando series de Maclaurin para $x = 10$ y $x = -10$:

\begin{equation*} e^{x} = \frac{x^{0}}{0!} + \frac{x^{1}}{1!} + \frac{x^{2}}{2!} + \frac{x^{3}}{3!} + \cdots \end{equation*}

Esta vez no usaremos la función factorial() en la función que calculará $e^{x}$, se usará el siguiente método:

\begin{equation*} e^{x} = 1 + (1) \frac{x}{1} + (1) ( \frac{x}{1} ) \frac{x}{2} + (1) ( \frac{x}{1} ) ( \frac{x}{2} ) \frac{x}{3} + (1) ( \frac{x}{1} ) ( \frac{x}{2} ) ( \frac{x}{3} ) \frac{x}{4} + \cdots \end{equation*}

In [12]:
function seriee(x)
    i = 0
    valor_anterior = float32(0.0)
    sumando = float32(1.0)
    valor_actual = float32(1.0)
    @printf("%s \t %s \t %s \t %20s\n", "i", "valor_anterior", "sumando", "valor_actual")
    
    while true
        i += 1
        valor_anterior = valor_actual
        sumando = sumando * float32(x)/i 
        valor_actual = valor_actual + sumando
        @printf("%d \t %0.12f \t %0.12f \t %0.12f\n", i, valor_anterior, sumando, valor_actual)
        if valor_actual == valor_anterior
            break
        end
    end
    println("exp($(x)) = ", exp(x))
end


Out[12]:
seriee (generic function with 1 method)

In [13]:
seriee(10)


i 	 valor_anterior 	 sumando 	         valor_actual
1 	 1.000000000000 	 10.000000000000 	 11.000000000000
2 	 11.000000000000 	 50.000000000000 	 61.000000000000
3 	 61.000000000000 	 166.666671752930 	 227.666671752930
4 	 227.666671752930 	 416.666687011719 	 644.333374023438
5 	 644.333374023438 	 833.333374023438 	 1477.666748046875
6 	 1477.666748046875 	 1388.889038085938 	 2866.555664062500
7 	 2866.555664062500 	 1984.127197265625 	 4850.682617187500
8 	 4850.682617187500 	 2480.158935546875 	 7330.841796875000
9 	 7330.841796875000 	 2755.732177734375 	 10086.574218750000
10 	 10086.574218750000 	 2755.732177734375 	 12842.306640625000
11 	 12842.306640625000 	 2505.211181640625 	 15347.517578125000
12 	 15347.517578125000 	 2087.676025390625 	 17435.193359375000
13 	 17435.193359375000 	 1605.904541015625 	 19041.097656250000
14 	 19041.097656250000 	 1147.074584960938 	 20188.171875000000
15 	 20188.171875000000 	 764.716430664063 	 20952.888671875000
16 	 20952.888671875000 	 477.947753906250 	 21430.835937500000
17 	 21430.835937500000 	 281.145751953125 	 21711.982421875000
18 	 21711.982421875000 	 156.192077636719 	 21868.173828125000
19 	 21868.173828125000 	 82.206359863281 	 21950.380859375000
20 	 21950.380859375000 	 41.103179931641 	 21991.484375000000
21 	 21991.484375000000 	 19.572942733765 	 22011.056640625000
22 	 22011.056640625000 	 8.896792411804 	 22019.953125000000
23 	 22019.953125000000 	 3.868170738220 	 22023.822265625000
24 	 22023.822265625000 	 1.611737847328 	 22025.433593750000
25 	 22025.433593750000 	 0.644695103168 	 22026.078125000000
26 	 22026.078125000000 	 0.247959643602 	 22026.326171875000
27 	 22026.326171875000 	 0.091836899519 	 22026.417968750000
28 	 22026.417968750000 	 0.032798893750 	 22026.451171875000
29 	 22026.451171875000 	 0.011309962720 	 22026.462890625000
30 	 22026.462890625000 	 0.003769987496 	 22026.466796875000
31 	 22026.466796875000 	 0.001216124976 	 22026.468750000000
32 	 22026.468750000000 	 0.000380039040 	 22026.468750000000
exp(10) = 22026.465794806718

In [14]:
seriee(-10)


i 	 valor_anterior 	 sumando 	         valor_actual
1 	 1.000000000000 	 -10.000000000000 	 -9.000000000000
2 	 -9.000000000000 	 50.000000000000 	 41.000000000000
3 	 41.000000000000 	 -166.666671752930 	 -125.666671752930
4 	 -125.666671752930 	 416.666687011719 	 291.000000000000
5 	 291.000000000000 	 -833.333374023438 	 -542.333374023438
6 	 -542.333374023438 	 1388.889038085938 	 846.555664062500
7 	 846.555664062500 	 -1984.127197265625 	 -1137.571533203125
8 	 -1137.571533203125 	 2480.158935546875 	 1342.587402343750
9 	 1342.587402343750 	 -2755.732177734375 	 -1413.144775390625
10 	 -1413.144775390625 	 2755.732177734375 	 1342.587402343750
11 	 1342.587402343750 	 -2505.211181640625 	 -1162.623779296875
12 	 -1162.623779296875 	 2087.676025390625 	 925.052246093750
13 	 925.052246093750 	 -1605.904541015625 	 -680.852294921875
14 	 -680.852294921875 	 1147.074584960938 	 466.222290039063
15 	 466.222290039063 	 -764.716430664063 	 -298.494140625000
16 	 -298.494140625000 	 477.947753906250 	 179.453613281250
17 	 179.453613281250 	 -281.145751953125 	 -101.692138671875
18 	 -101.692138671875 	 156.192077636719 	 54.499938964844
19 	 54.499938964844 	 -82.206359863281 	 -27.706420898438
20 	 -27.706420898438 	 41.103179931641 	 13.396759033203
21 	 13.396759033203 	 -19.572942733765 	 -6.176183700562
22 	 -6.176183700562 	 8.896792411804 	 2.720608711243
23 	 2.720608711243 	 -3.868170738220 	 -1.147562026978
24 	 -1.147562026978 	 1.611737847328 	 0.464175820351
25 	 0.464175820351 	 -0.644695103168 	 -0.180519282818
26 	 -0.180519282818 	 0.247959643602 	 0.067440360785
27 	 0.067440360785 	 -0.091836899519 	 -0.024396538734
28 	 -0.024396538734 	 0.032798893750 	 0.008402355015
29 	 0.008402355015 	 -0.011309962720 	 -0.002907607704
30 	 -0.002907607704 	 0.003769987496 	 0.000862379791
31 	 0.000862379791 	 -0.001216124976 	 -0.000353745185
32 	 -0.000353745185 	 0.000380039040 	 0.000026293856
33 	 0.000026293856 	 -0.000115163341 	 -0.000088869485
34 	 -0.000088869485 	 0.000033871573 	 -0.000054997912
35 	 -0.000054997912 	 -0.000009677592 	 -0.000064675507
36 	 -0.000064675507 	 0.000002688220 	 -0.000061987288
37 	 -0.000061987288 	 -0.000000726546 	 -0.000062713836
38 	 -0.000062713836 	 0.000000191196 	 -0.000062522638
39 	 -0.000062522638 	 -0.000000049025 	 -0.000062571664
40 	 -0.000062571664 	 0.000000012256 	 -0.000062559411
41 	 -0.000062559411 	 -0.000000002989 	 -0.000062562402
42 	 -0.000062562402 	 0.000000000712 	 -0.000062561689
43 	 -0.000062561689 	 -0.000000000166 	 -0.000062561856
44 	 -0.000062561856 	 0.000000000038 	 -0.000062561820
45 	 -0.000062561820 	 -0.000000000008 	 -0.000062561827
46 	 -0.000062561827 	 0.000000000002 	 -0.000062561827
exp(-10) = 4.5399929762484854e-5