# Ejercicios Pérdida de Significancia


```python
import numpy as np
import matplotlib.pyplot as plt
```

## Comentario de la clase...

Del ejercicio realizado en clases teníamos problemas con $p=53$ para representación en *doble precisión*. Se puede representar hasta $2^{53}$ sin problemas y luego solo podemos sumar múltiplos de $2$ (combinaciones de los bits asociados a $2^{1}$, $2^{2}$, $2^{3}$, $\dots$), ya que se pierde el $2^0$. Ver el ejemplo en el video de la clase.


```python
2.**53, 2.**53+1, 2.**53+2, 2.**53+3, 2.**53+4, 2.**53+5, 2.**53+6, 2.**53+7, 2.**53+8, 2.**53+9
```

## Ejercicio 1

Obtener $a+\sqrt{a^2 + b^4}$, $a=-12345678987654321$, $b=123$.

Resultado aproximado: $9.2699089790398179 \times 10^{-9}$


```python
a = -12345678987654321.
b = 123.
```


```python
print("a: %f, b: %f" % (a, b))
```

Perdemos un dígito...

### Cálculo directo


```python
a + np.sqrt(a ** 2 + b ** 4)
```

### Manejo algebraico

\begin{equation}
    \begin{split}
        a+\sqrt{a^2 + b^4} & = a+\sqrt{a^2 + b^4} \cdot \frac{a-\sqrt{a^2 + b^4}}{a- \sqrt{a^2 + b^4}} \\
            & = \frac{a^2-a^2 - b^4}{a- \sqrt{a^2 + b^4}} \\
            & = \frac{-b^4}{a - \sqrt{a^2 + b^4}} \\
            & = \frac{b^4}{\sqrt{a^2 + b^4} - a}
    \end{split}
\end{equation}


```python
b ** 4 / (np.sqrt(a ** 2 + b ** 4) - a)
```

## Ejercicio 2

Obtener

\begin{equation}
    x^2 = 1.2222222^2 + 3344556600^2
\end{equation}

Esto sería:
\begin{equation}
    x = \sqrt{1.2222222^2 + 3344556600^2}
\end{equation}

El resultado es aproximadamente $3.34455660000000000022332214\times 10^9$


```python
c1 = 1.2222222
c2 = 3344556600.
```


```python
print(c1, c2)
```


```python
x1 = np.sqrt(c1 ** 2 + c2 ** 2)
```


```python
print(x1)
```

Utilizando

\begin{equation}
    x^2 = (c_1 + c_2)^2 - 2c_1c_2
\end{equation}


```python
x2 = np.sqrt((c1 + c2) ** 2 - 2 * c1 * c2)
```


```python
print(x2)
```

Utilizando un uno conveniente

\begin{equation}
    \begin{split}
        x^2 & = \sqrt{c_1^2 + c_2^2} \, \frac{\sqrt{c_1^2 + c_2^2}}{\sqrt{c_1^2 + c_2^2}} \\
            & = \frac{c_1^2 + c_2^2}{\sqrt{c_1^2 + c_2^2}} 
    \end{split}
\end{equation}


```python
x3 = (c1 ** 2 + c2 ** 2) / np.sqrt(c1 ** 2 + c2 ** 2)
```


```python
print(x3)
```


```python
print(abs(3.34455660000000000022332214e9 - x1))
print(abs(3.34455660000000000022332214e9 - x2))
print(abs(3.34455660000000000022332214e9 - x3))
```

No todos los manejos algebraicos nos ayudarán a resolver problemas mal planteados.

## Ejercicio 3

Calcular las raíces de

\begin{equation}
    x^2 + 9^{12} x - 3 = 0
\end{equation}

\begin{equation}
    x = \frac{-9^{12} \pm \sqrt{9^{24} + 12}}{2}
\end{equation}

Una raíz sería:

$x_1=\frac{-9^{12} - \sqrt{9^{24} + 12}}{2}= −2.824\times 10^{11}$

En el caso de la segunda raíz esto es muy cercano a $0$

$x_2=\frac{-9^{12} + \sqrt{9^{24} + 12}}{2}$

$-9^{12} + \sqrt{9^{24}} \approx 0$ pero según cómo lo calculemos vamos a poder recuperar algunos decimales.

### Cálculo directo


```python
def root(a, b, c):
    r1 = (-b - np.sqrt(b ** 2 - 4 * a * c)) / (2 * a)
    r2 = (-b + np.sqrt(b ** 2 - 4 * a * c)) / (2 * a)
    return r1, r2
```


```python
a = 1.
b = 9. ** 12
c = -3.
```


```python
x1, x2 = root(a, b, c)
```


```python
print(x1, x2)
```

### Manejo algebraico

\begin{equation}
    \begin{split}
        x_2 & = \frac{-b + \sqrt{b^2 - 4ac}}{2a} \\
            & = \frac{-b + \sqrt{b^2 - 4ac}}{2a} \, \frac{b + \sqrt{b^2 - 4ac}}{b + \sqrt{b^2 - 4ac}} \\
            & = \frac{-4ac}{2a(b + \sqrt{b^2 - 4ac})} \\
            & = \frac{-2c}{(b + \sqrt{b^2 - 4ac})}
    \end{split}
\end{equation}


```python
def root_improved(a, b, c):
    r1 = (-b - np.sqrt(b ** 2 - 4 * a * c)) / (2 * a)
    r2 = -2 * c / (b + np.sqrt(b ** 2 - 4 * a * c))
    return r1, r2
```


```python
x1, x2 = root_improved(a, b, c)
```


```python
print(x1, x2)
```

Mirando con mayor detalle, si $4|ac| \ll b^2$, $b$ y $\sqrt{b^2-4ac}$ son similares en magnitud por lo tanto una de las raíces va a sufrir pérdida de significancia. Revisar el libro guía para más detalles de cómo solucionar el problema.

## Ejercicio 4

Sean
\begin{equation}
    E_1(x)=\frac{1-\cos(x)}{\sin^2(x)}, \quad E_2(x)=\frac{1}{1+\cos(x)}
\end{equation}

¿Son $E_1(x)$ y $E_2(x)$ iguales? ¿Qué ocurre al evaluarlas cerca de $0$?

Primero, ¿$E_1(x)=E_2(x)$?

\begin{equation}
    \begin{split}
        E_1(x) & =E_2(x) \\
        \frac{1-\cos(x)}{\sin^2(x)} & = \frac{1}{1+\cos(x)} \\
        (1-\cos(x))(1+\cos(x)) &= \sin^2(x) \\
        1-\cos^2(x) &= \sin^2(x) \\
        1 &= \sin^2(x) + \cos^2(x)
    \end{split}
\end{equation}

Efectivamente son iguales. Ahora veamos numéricamente qué ocurre al evaluarla cerca de $0$.


```python
E1 = lambda x: (1 - np.cos(x)) / np.sin(x) ** 2
E2 = lambda x: 1 / (1 + np.cos(x))
```


```python
xa, xb = -.5, .5
N = 101
x = np.linspace(xa, xb, N)
```


```python
x
```


```python
plt.figure(figsize=(13, 4))
plt.subplot(1, 2, 1)
plt.plot(x, E1(x), 'b.')
plt.xlabel(r"$x$")
plt.ylabel(r"$E_1(x)$")
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(x, E2(x), 'r.')
plt.xlabel(r"$x$")
plt.ylabel(r"$E_2(x)$")
plt.grid(True)
plt.tight_layout()
plt.show()
```

Tenemos problemas al evaluar $0$ en el denominador de $E_1(x)$ puesto que se indetermina.


```python
x = np.logspace(-19,0,20)[-1:0:-1]
o1 = E1(x)
o2 = E2(x)

print("x,                 E1(x),             E2(x)")
for i in np.arange(len(x)):
    print("%1.15f, %1.15f, %1.15f" % (x[i], o1[i], o2[i]))
```

## Ejercicio 5

¿Cuándo habría problemas al evaluar $f(x)$ y $g(x)$?

\begin{equation}
    f(x) = \frac{1-(1-x)^3}{x}, \quad g(x)= \frac{1}{1+x}-\frac{1}{1-x}
\end{equation}


```python
f = lambda x: (1 - (1 - x) ** 3) / x
g = lambda x: 1 / (1 + x) - 1 / (1 - x)
```


```python
xa, xb = -2, 2
N = 101
x = np.linspace(xa, xb, N)
```


```python
plt.figure(figsize=(13, 4))
plt.subplot(1, 2, 1)
plt.plot(x, f(x), 'b.')
plt.xlabel(r"$x$")
plt.ylabel(r"$f(x)$")
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(x, g(x), 'r.')
plt.xlabel(r"$x$")
plt.ylabel(r"$g(x)$")
plt.grid(True)
plt.tight_layout()
plt.show()
```

Es claro que para $f(x)$ el problema se encuentra cercano a $0$ mientras que para $g(x)$ el problema está en $-1$ y $1$. En el caso de $f(x)$ basta expandirla para obtener $f(x)=x^2-3x+3$. Si operamos sobre $g(x)$ se obtiene $g(x)=\frac{2x}{x^2-1}$, el cual contiene los mismos problemas.


```python
ff = lambda x: x ** 2 - 3 * x + 3
gg = lambda x: 2 * x / (x ** 2 - 1)
```


```python
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(x, ff(x), 'b.', label=r"$f(x)$")
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(x, gg(x), 'r.', label=r"$g(x)$")
plt.grid(True)
plt.tight_layout()
plt.show()
```

¿Existirá alguna forma de solucionar los problemas de $g(x)$?

# Referencias

* Sauer, T. (2006). Numerical Analysis Pearson Addison Wesley.
* https://github.com/tclaudioe/Scientific-Computing/blob/master/SC1/03_floating_point_arithmetic.ipynb <- Revisar este enlace que tiene ejemplos y comentarios interesantes!

9a25b132f58e3dac3e58d299cb33523e2d107ef1
ipynb
Jupyter Notebook
material/02_punto_flotante/ejercicios.ipynb
etra0/INF-285
189f8d66cf6997fc87b545378b2c5f1c7b908dbc
BSD-3-Clause
2020-04-24T01:25:24.000Z
2021-05-10T01:08:37.000Z
material/02_punto_flotante/ejercicios.ipynb
etra0/INF-285
189f8d66cf6997fc87b545378b2c5f1c7b908dbc
BSD-3-Clause
2020-04-22T00:57:29.000Z
2020-04-23T23:59:28.000Z
material/02_punto_flotante/ejercicios.ipynb
etra0/INF-285
189f8d66cf6997fc87b545378b2c5f1c7b908dbc
BSD-3-Clause
2020-04-20T01:15:09.000Z
2020-07-27T22:53:59.000Z
Qwen/Qwen-72B
1. YES
2. YES