Uno de los problemas que más se presenta en matemáticas es el de calcular la solución de una ecuación. En algunas (pocas) ocasiones, esto puede hacerse por métodos analíticos, es decir, se puede “despejar” la incógnita para encontrar el o los valores que resuelven la ecuación. En la gran mayoría de las ocasiones con algún interés práctico esto no es posible y es necesario recurrir a un método numérico que, con la ayuda de un ordenador, nos permita calcular un valor aproximado de la solución.
Método de Bisección
Antes de comenzar a desarrollar los fundamentos de este método, repasemos un resultado matemático que nos sirve de apoyo para fundamentar la validez de nuestra solución numérica.
Teorema de Bolzano: Sea \(f\) una función real continua en un intervalo cerrado \([a,b]\) con \(f(a)\) y \(f(b)\) de signos contrarios. Entonces existe al menos un punto c del intervalo abierto \((a,b)\) con \(f(c)=0\).
El método de Bisección se apoya en el teorema anterior que asegura que (bajo las condiciones expuestas en el teorema) el método es siempre convergente aunque la velocidad de convergencia es lineal (es decir que es un método “lento”). Su simplicidad lo hace ideal para aprender a programar en R y computar numéricamente las raíces de cualquier función continua en un intervalo cerrado.
El método consiste en lo siguiente:
Debe existir seguridad sobre la continuidad de la función \(f(x)\) en el intervalo \([a,b]\)
A continuación se verifica que \(f(a)\cdot f(b)<0\).
Se calcula el punto medio m del intervalo \([a,b]\) y se evalúa \(f(m)\):
Si ese valor es igual a cero, ya hemos encontrado la raíz buscada.
En caso de que no lo sea, verificamos se redefine el intervalo \([a,b]\) como: \([m,b]\) si \(\text{sign}\{f(a)\}=\text{sign}\{f(m)\}\) ó \([a,m]\) si \(\text{sign}\{f(b)\}=\text{sign}\{f(m)\}\).
Con este nuevo intervalo se continúa sucesivamente encerrando la solución en un intervalo cada vez más pequeño, hasta alcanzar la precisión deseada.
Programando el método en R:
Vamos a implementar en R el método propuesto a través de una función que se llamará bisección y tendrá 3 argumentos: \(f\), \(a\) y \(b\):
# Halla la raíz de f (una función definida en R) en el intervalo [a,b]
biseccion <- function(f,a,b) {
plot(f,from=a,to=b) # Grafico la función y
abline(h=0,col="blue") # pinto el eje-X de color azul.
# Definimos los valores iniciales de m, n y un 'error'
# que mide la amplitud del intervalo sobre el que trabajamos.
m = (a+b)/2 ; n = 0; error<-abs(a-b)/2
while (error > 1.e-5 & n < 100) { # "Doble-tolerancia" del método
n<-n+1
if (f(m) == 0) break # Si el cero esta en el medio de [a,b] paro.
if (f(m)*f(a) < 0) {b = m} else {a = m} # La regla antes planteada.
m = (a+b)/2 # Redefino el intervalo con los valores actualizados.
# Genero output gráfico y en pantalla del método:
text(m,0,n,cex=0.8,col="red")
error = abs(a-b)/2
cat("X=",m,"\tE=",error,"\n")
} # Fin del while()
}# Fin de la función biseccion().
p <- function(x){return(x-2^{-x}) }
biseccion(p,0,1)
X= 0.75 E= 0.25
X= 0.625 E= 0.125
X= 0.6875 E= 0.0625
X= 0.65625 E= 0.03125
X= 0.640625 E= 0.015625
X= 0.6484375 E= 0.0078125
X= 0.6445312 E= 0.00390625
X= 0.6425781 E= 0.001953125
X= 0.6416016 E= 0.0009765625
X= 0.6411133 E= 0.0004882812
X= 0.6413574 E= 0.0002441406
X= 0.6412354 E= 0.0001220703
X= 0.6411743 E= 6.103516e-05
X= 0.6412048 E= 3.051758e-05
X= 0.6411896 E= 1.525879e-05
X= 0.6411819 E= 7.629395e-06

Ejercicio para la clase:
1- Encuentra los ceros del polinomio \(q(x)=−x^2+0.5x+4\).
2- Encuentra los valores de \(x\) tal que \(p(x)=q(x)\) y tome \(p(x)=x2^x-1\). (Ayuda: que función se hace cero si \(p(x)=q(x)\)?)
3- Para los siguientes polinomios, se pide factorizarlos y obtener de esta forma las raíces o ceros de manera analítica:
3.1 \(p_1(x)=x^2+x−12\) (sol: -4 y 3).
3.2 \(p_2(x)=x^3−4x^2+x+6\) (sol: -1, 2, y 3).
3.3 \(p_3(x)=x^4−5x^2+4\) (sol: -2, -1, 1 y 2).
4- Programa en R los polinomios del punto 3, grafícalos y utiliza el algorítmo de bisección para computar numéricamente sus raíces. Verifica que los valores numéricos que obtuviste se aproximan a los ceros de la función.
Método de Newton
Definición
El método de Newton (conocido también como el método de Newton-Raphson o el método de Newton-Fourier) es un algoritmo basado en la derivada que permite encontrar aproximaciones de los ceros o raíces de una función real derivable, o inclusive aproximar valores como \(\sqrt{3},\sqrt[4]{3},\sqrt[5]{247},\pi\) encontrando de manera aproximada las raíces de las ecuaciones \(x^2−3=0\), \(x^4−3=0\), \(x^5−247=0\), \(\cos(x)+1=0\) respectivamente.
Descripción del método
Sea \(f:[a,b]→\mathbb{R}\) una función derivable
Se elige \(x_0\) en el eje de las \(x\), asumiendo que está cerca de la solución de \(f(x)=0\) (raíz buscada).
Calculamos la ecuación punto pendiente de la recta tangente a la función en \((x_0,f(x_0))\), a saber $y−f(x_0)=f′(x_0)(x−x_0) $ .\((1)\)
Esta recta debe intersecar al eje de las \(x\), en un punto más cercano a la raíz buscada; en el punto \((x_1,0)\).
El punto \((x_1,0)\) satisface la ecuación \((1)\) y sustituyendo, queda: \(0−f(x_0)=f′(x_0)(x−x_0)\). \((2)\)
Si \(f′(x_0)\neq0\), entonces despejando \(x_1\) en \((2)\) se obtiene \[x_1=x_0−\frac{f(x_0)}{f′(x_0)}\]
Repetimos el procedimiento anterior para \(x_0\), pero ahora comenzando con \(x_1\), en cuyo caso se obtiene \(\displaystyle x_2=x1−\frac{f(x_1)}{f′(x_1)}\). De forma que \(x_2\) está más cerca de la raíz buscada que \(x_1\).
Iterando cada vez con el número obtenido, se construye una secuencia: \(x_0,x_1,x_2,…,x_n,…\) de números cada vez más próximos a la raíz, tales que:
\[x_{n+1}=x_n−\frac{f(x_n)}{f′(x_n)}(3)\]
En resumen y de forma menos teórica el procedimiento es el siguiente:
Observando la gráfica de la función se estima un valor adecado para la primera aproximación \(x_1\).
Sustituyendo la primera aproximación en (3), se obtiene una segunda aproximación \(x_2\). Luego se calcula \(x_3\) sustituyendo en (3) la segunda aproximación \(x_2\); y así sucesivamente hasta que se llegue a la igualdad \(x_{n+1}=x_n\)
Código en R
El código viene dado por:
expresion <- expression (exp(x)+x-2) # escribimos el polinomio
derivada <- D(expresion, "x") # Derivada del polinomio
x <- 0 # Cualquier valor diferente de aprox
aprox <- 3 # valor puntoinicial
while ( x != aprox) {
x <- aprox # Se le asigna el valor aproximado a x.
reemplazoexpresion <- eval(expresion) #Reemplaza el valor de x en "expresión"
reemplazoderiv <- eval(derivada) #Reemplaza el valor de x en "derivada"
#newton
aprox <- x - (reemplazoexpresion/reemplazoderiv) #Ecuación método de Newton
print(x)
}
[1] 3
[1] 2
[1] 1.119203
[1] 0.5821784
[1] 0.4488018
[1] 0.4428652
[1] 0.4428544
[1] 0.4428544
Ejercicio para la clase:
1- Para los siguientes polinomios, se pide factorizarlos y obtener de esta forma las raíces o ceros de manera analítica:
1.1 \(p_1(x)=x^2+x−12\) (sol: -4 y 3).
1.2 \(p_2(x)=x^3−4x^2+x+6\) (sol: -1, 2, y 3).
1.3 \(p_3(x)=x^4−5x^2+4\) (sol: -2, -1, 1 y 2).
2- Programa en R los polinomios del punto 1, grafícalos y utiliza el algorítmo de Newthon Rhapson para computar numéricamente sus raíces. Verifica que los valores numéricos que obtuviste se aproximan a los ceros de la función.
LS0tCnRpdGxlOiAnIFJlc29sdWNpw7NuIG51bcOpcmljYSBkZSBlY3VhY2lvbmVzJwpzdWJ0aXRsZTogQ3Vyc28gZGUgSW52ZXN0aWdhY2nDs24gZGUgT3BlcmFkb3JlcwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KCgpVbm8gZGUgbG9zIHByb2JsZW1hcyBxdWUgbcOhcyBzZSBwcmVzZW50YSBlbiBtYXRlbcOhdGljYXMgZXMgZWwgZGUgY2FsY3VsYXIgbGEgc29sdWNpw7NuIGRlIHVuYSBlY3VhY2nDs24uIEVuIGFsZ3VuYXMgKHBvY2FzKSBvY2FzaW9uZXMsIGVzdG8gcHVlZGUgaGFjZXJzZSBwb3IgbcOpdG9kb3MgYW5hbMOtdGljb3MsIGVzIGRlY2lyLCBzZSBwdWVkZSDigJxkZXNwZWphcuKAnSBsYSBpbmPDs2duaXRhCnBhcmEgZW5jb250cmFyIGVsIG8gbG9zIHZhbG9yZXMgcXVlIHJlc3VlbHZlbiBsYSBlY3VhY2nDs24uIEVuIGxhIGdyYW4gbWF5b3LDrWEgZGUgbGFzIG9jYXNpb25lcyBjb24gYWxnw7puIGludGVyw6lzIHByw6FjdGljbyBlc3RvIG5vIGVzIHBvc2libGUgeSBlcyBuZWNlc2FyaW8gcmVjdXJyaXIgYSB1biBtw6l0b2RvIG51bcOpcmljbyBxdWUsIGNvbiBsYSBheXVkYSBkZSB1biBvcmRlbmFkb3IsCm5vcyBwZXJtaXRhIGNhbGN1bGFyIHVuIHZhbG9yIGFwcm94aW1hZG8gZGUgbGEgc29sdWNpw7NuLgoKCiMgTcOpdG9kbyBkZSBCaXNlY2Npw7NuCgpBbnRlcyBkZSBjb21lbnphciBhIGRlc2Fycm9sbGFyIGxvcyBmdW5kYW1lbnRvcyBkZSBlc3RlIG3DqXRvZG8sIHJlcGFzZW1vcyB1biByZXN1bHRhZG8gbWF0ZW3DoXRpY28gcXVlIG5vcyBzaXJ2ZSBkZSBhcG95byBwYXJhIGZ1bmRhbWVudGFyIGxhIHZhbGlkZXogZGUgbnVlc3RyYSBzb2x1Y2nDs24gbnVtw6lyaWNhLgoKKipUZW9yZW1hIGRlIEJvbHphbm8qKjogU2VhICRmJCB1bmEgZnVuY2nDs24gcmVhbCBjb250aW51YSBlbiB1biBpbnRlcnZhbG8gY2VycmFkbyAkW2EsYl0kIGNvbiAkZihhKSQgeSAkZihiKSQgZGUgc2lnbm9zIGNvbnRyYXJpb3MuIEVudG9uY2VzIGV4aXN0ZSBhbCBtZW5vcyB1biBwdW50byBjIGRlbCBpbnRlcnZhbG8gYWJpZXJ0byAkKGEsYikkIGNvbiAkZihjKT0wJC4KCkVsIG3DqXRvZG8gZGUgQmlzZWNjacOzbiBzZSBhcG95YSBlbiBlbCB0ZW9yZW1hIGFudGVyaW9yIHF1ZSBhc2VndXJhIHF1ZSAoYmFqbyBsYXMgY29uZGljaW9uZXMgZXhwdWVzdGFzIGVuIGVsIHRlb3JlbWEpIGVsIG3DqXRvZG8gZXMgc2llbXByZSBjb252ZXJnZW50ZSBhdW5xdWUgbGEgdmVsb2NpZGFkIGRlIGNvbnZlcmdlbmNpYSBlcyBsaW5lYWwgKGVzIGRlY2lyIHF1ZSBlcyB1biBtw6l0b2RvIOKAnGxlbnRv4oCdKS4gU3Ugc2ltcGxpY2lkYWQgbG8gaGFjZSBpZGVhbCBwYXJhIGFwcmVuZGVyIGEgcHJvZ3JhbWFyIGVuIFIgeSBjb21wdXRhciBudW3DqXJpY2FtZW50ZSBsYXMgcmHDrWNlcyBkZSBjdWFscXVpZXIgZnVuY2nDs24gY29udGludWEgZW4gdW4gaW50ZXJ2YWxvIGNlcnJhZG8uCgpFbCBtw6l0b2RvIGNvbnNpc3RlIGVuIGxvIHNpZ3VpZW50ZToKCi0gRGViZSBleGlzdGlyIHNlZ3VyaWRhZCBzb2JyZSBsYSBjb250aW51aWRhZCBkZSBsYSBmdW5jacOzbiAkZih4KSQgZW4gZWwgaW50ZXJ2YWxvICRbYSxiXSQKCi0gQSBjb250aW51YWNpw7NuIHNlIHZlcmlmaWNhIHF1ZSAkZihhKVxjZG90IGYoYik8MCQuCgotIFNlIGNhbGN1bGEgZWwgcHVudG8gbWVkaW8gbSBkZWwgaW50ZXJ2YWxvICRbYSxiXSQgeSBzZSBldmFsw7phICRmKG0pJDoKCiAgLSBTaSBlc2UgdmFsb3IgZXMgaWd1YWwgYSBjZXJvLCB5YSBoZW1vcyBlbmNvbnRyYWRvIGxhIHJhw616IGJ1c2NhZGEuCgogIC0gRW4gY2FzbyBkZSBxdWUgbm8gbG8gc2VhLCB2ZXJpZmljYW1vcyBzZSByZWRlZmluZSBlbCBpbnRlcnZhbG8gJFthLGJdJCBjb21vOiAkW20sYl0kIHNpICRcdGV4dHtzaWdufVx7ZihhKVx9PVx0ZXh0e3NpZ259XHtmKG0pXH0kIMOzICRbYSxtXSQgc2kgJFx0ZXh0e3NpZ259XHtmKGIpXH09XHRleHR7c2lnbn1ce2YobSlcfSQuCgotIENvbiBlc3RlIG51ZXZvIGludGVydmFsbyBzZSBjb250aW7DumEgc3VjZXNpdmFtZW50ZSBlbmNlcnJhbmRvIGxhIHNvbHVjacOzbiBlbiB1biBpbnRlcnZhbG8gY2FkYSB2ZXogbcOhcyBwZXF1ZcOxbywgaGFzdGEgYWxjYW56YXIgbGEgcHJlY2lzacOzbiBkZXNlYWRhLgoKPGNlbnRlcj4KIVtNw6l0b2RvIGRlIEJpc2VjY2nDs25dKGJpc2VjY2lvbi5wbmcpCjwvY2VudGVyPgoKIyMgUHJvZ3JhbWFuZG8gZWwgbcOpdG9kbyBlbiBSOgoKVmFtb3MgYSBpbXBsZW1lbnRhciBlbiBSIGVsIG3DqXRvZG8gcHJvcHVlc3RvIGEgdHJhdsOpcyBkZSB1bmEgZnVuY2nDs24gcXVlIHNlIGxsYW1hcsOhIGJpc2VjY2nDs24geSB0ZW5kcsOhIDMgYXJndW1lbnRvczogJGYkLCAkYSQgeSAkYiQ6CgpgYGB7cn0KIyBIYWxsYSBsYSByYcOteiBkZSBmICh1bmEgZnVuY2nDs24gZGVmaW5pZGEgZW4gUikgZW4gZWwgaW50ZXJ2YWxvIFthLGJdCmJpc2VjY2lvbiA8LSBmdW5jdGlvbihmLGEsYikgewpwbG90KGYsZnJvbT1hLHRvPWIpICMgR3JhZmljbyBsYSBmdW5jacOzbiB5CmFibGluZShoPTAsY29sPSJibHVlIikgIyBwaW50byBlbCBlamUtWCBkZSBjb2xvciBhenVsLgoKIyBEZWZpbmltb3MgbG9zIHZhbG9yZXMgaW5pY2lhbGVzIGRlIG0sIG4geSB1biAnZXJyb3InCiMgcXVlIG1pZGUgbGEgYW1wbGl0dWQgZGVsIGludGVydmFsbyBzb2JyZSBlbCBxdWUgdHJhYmFqYW1vcy4KbSA9IChhK2IpLzIgOyBuID0gMDsgZXJyb3I8LWFicyhhLWIpLzIKCndoaWxlIChlcnJvciA+IDEuZS01ICYgbiA8IDEwMCkgeyAjICJEb2JsZS10b2xlcmFuY2lhIiBkZWwgbcOpdG9kbwpuPC1uKzEKaWYgKGYobSkgPT0gMCkgYnJlYWsgIyBTaSBlbCBjZXJvIGVzdGEgZW4gZWwgbWVkaW8gZGUgW2EsYl0gcGFyby4KaWYgKGYobSkqZihhKSA8IDApIHtiID0gbX0gZWxzZSB7YSA9IG19ICMgTGEgcmVnbGEgYW50ZXMgcGxhbnRlYWRhLgptID0gKGErYikvMiAjIFJlZGVmaW5vIGVsIGludGVydmFsbyBjb24gbG9zIHZhbG9yZXMgYWN0dWFsaXphZG9zLgoKIyBHZW5lcm8gb3V0cHV0IGdyw6FmaWNvIHkgZW4gcGFudGFsbGEgZGVsIG3DqXRvZG86CnRleHQobSwwLG4sY2V4PTAuOCxjb2w9InJlZCIpCmVycm9yID0gYWJzKGEtYikvMgpjYXQoIlg9IixtLCJcdEU9IixlcnJvciwiXG4iKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICMgRmluIGRlbCB3aGlsZSgpCn0jIEZpbiBkZSBsYSBmdW5jacOzbiBiaXNlY2Npb24oKS4KCnAgPC0gZnVuY3Rpb24oeCl7cmV0dXJuKHgtMl57LXh9KSB9CgpiaXNlY2Npb24ocCwwLDEpCmBgYAoKIyMgRWplcmNpY2lvIHBhcmEgbGEgY2xhc2U6CgoxLSBFbmN1ZW50cmEgbG9zIGNlcm9zIGRlbCBwb2xpbm9taW8gJHEoeCk94oiSeF4yKzAuNXgrNCQuCgoyLSBFbmN1ZW50cmEgbG9zIHZhbG9yZXMgZGUgJHgkIHRhbCBxdWUgJHAoeCk9cSh4KSQgeSB0b21lICRwKHgpPXgyXngtMSQuIChBeXVkYTogcXVlIGZ1bmNpw7NuIHNlIGhhY2UgY2VybyBzaSAkcCh4KT1xKHgpJD8pCgozLSBQYXJhIGxvcyBzaWd1aWVudGVzIHBvbGlub21pb3MsIHNlIHBpZGUgZmFjdG9yaXphcmxvcyB5IG9idGVuZXIgZGUgZXN0YSBmb3JtYSBsYXMgcmHDrWNlcyBvIGNlcm9zIGRlIG1hbmVyYSBhbmFsw610aWNhOgoKMy4xICRwXzEoeCk9eF4yK3jiiJIxMiQgKHNvbDogLTQgeSAzKS4KCjMuMiAkcF8yKHgpPXheM+KIkjR4XjIreCs2JCAoc29sOiAtMSwgMiwgeSAzKS4KCjMuMyAkcF8zKHgpPXheNOKIkjV4XjIrNCQgKHNvbDogLTIsIC0xLCAxIHkgMikuCgo0LSBQcm9ncmFtYSBlbiBSIGxvcyBwb2xpbm9taW9zIGRlbCBwdW50byAzLCBncmFmw61jYWxvcyB5IHV0aWxpemEgZWwgYWxnb3LDrXRtbyBkZSBiaXNlY2Npw7NuIHBhcmEgY29tcHV0YXIgbnVtw6lyaWNhbWVudGUgc3VzIHJhw61jZXMuIFZlcmlmaWNhIHF1ZSBsb3MgdmFsb3JlcyBudW3DqXJpY29zIHF1ZSBvYnR1dmlzdGUgc2UgYXByb3hpbWFuIGEgbG9zIGNlcm9zIGRlIGxhIGZ1bmNpw7NuLgoKIyBNw6l0b2RvIGRlIE5ld3RvbgoKIyMgRGVmaW5pY2nDs24KCgpFbCBtw6l0b2RvIGRlIE5ld3RvbiAoY29ub2NpZG8gdGFtYmnDqW4gY29tbyBlbCBtw6l0b2RvIGRlIE5ld3Rvbi1SYXBoc29uIG8gZWwgbcOpdG9kbyBkZSBOZXd0b24tRm91cmllcikgZXMgdW4gYWxnb3JpdG1vIGJhc2FkbyBlbiBsYSBkZXJpdmFkYSBxdWUgcGVybWl0ZSBlbmNvbnRyYXIgYXByb3hpbWFjaW9uZXMgZGUgbG9zIGNlcm9zIG8gcmHDrWNlcyBkZSB1bmEgZnVuY2nDs24gcmVhbCBkZXJpdmFibGUsIG8gaW5jbHVzaXZlIGFwcm94aW1hciB2YWxvcmVzIGNvbW8gJFxzcXJ0ezN9LFxzcXJ0WzRdezN9LFxzcXJ0WzVdezI0N30sXHBpJCBlbmNvbnRyYW5kbyBkZSBtYW5lcmEgYXByb3hpbWFkYSBsYXMgcmHDrWNlcyBkZSBsYXMgZWN1YWNpb25lcyAkeF4y4oiSMz0wJCwgJHheNOKIkjM9MCQsICR4XjXiiJIyNDc9MCQsICRcY29zKHgpKzE9MCQgcmVzcGVjdGl2YW1lbnRlLgoKIyMgRm9ybWFsbWVudGUKClNlYSAkZiQgdW5hIGZ1bmNpw7NuIGRlcml2YWJsZSBkZWZpbmlkYSBlbiB1biBpbnRlcnZhbG8gcmVhbCAkW2EsYl0kIHkgc2VhICRmKHIpPTAkLCBlcyBkZWNpciwgc2VhICRyJCB1bmEgcmFpeiByZWFsIGRlICRmJC4gU2kgJHhfbiQgZXMgdW5hIGFwcm94aW1hY2nDs24gYSAkciQsIGVudG9uY2VzIGxhIHNpZ3VpZW50ZSBhcHJveGltYWNpw7NuICR4X3tuKzF9JCBlc3RhIGRhZGEgcG9yOgoKXFt4X3tuKzF9PXhfbi1cZnJhY3tmKHhfbil9e2YnKHhfbil9LGYnKHhfbilcbmVxIDBcXQoKIyMgRGVzY3JpcGNpw7NuIGRlbCBtw6l0b2RvCgpTZWEgJGY6W2EsYl3ihpJcbWF0aGJie1J9JCB1bmEgZnVuY2nDs24gZGVyaXZhYmxlCgoxLiBTZSBlbGlnZSAkeF8wJCBlbiBlbCBlamUgZGUgbGFzICR4JCwgYXN1bWllbmRvIHF1ZSBlc3TDoSBjZXJjYSBkZSBsYSBzb2x1Y2nDs24gZGUgJGYoeCk9MCQgKHJhw616IGJ1c2NhZGEpLgoKMi4gQ2FsY3VsYW1vcyBsYSBlY3VhY2nDs24gcHVudG8gcGVuZGllbnRlIGRlIGxhIHJlY3RhIHRhbmdlbnRlIGEgbGEgZnVuY2nDs24gZW4gJCh4XzAsZih4XzApKSQsIGEgc2FiZXIgJHniiJJmKHhfMCk9ZuKAsih4XzApKHjiiJJ4XzApICQgLiQoMSkkCgozLiBFc3RhIHJlY3RhIGRlYmUgaW50ZXJzZWNhciBhbCBlamUgZGUgbGFzICR4JCwgZW4gdW4gcHVudG8gbcOhcyBjZXJjYW5vIGEgbGEgcmHDrXogYnVzY2FkYTsgZW4gZWwgcHVudG8gJCh4XzEsMCkkLgoKNC4gRWwgcHVudG8gJCh4XzEsMCkkIHNhdGlzZmFjZSBsYSBlY3VhY2nDs24gJCgxKSQgeSBzdXN0aXR1eWVuZG8sIHF1ZWRhOgokMOKIkmYoeF8wKT1m4oCyKHhfMCkoeOKIknhfMCkkLiAkKDIpJAoKNS4gU2kgJGbigLIoeF8wKVxuZXEwJCwgZW50b25jZXMgZGVzcGVqYW5kbyAkeF8xJCBlbiAkKDIpJCBzZSBvYnRpZW5lClxbeF8xPXhfMOKIklxmcmFje2YoeF8wKX17ZuKAsih4XzApfVxdCgo2LiBSZXBldGltb3MgZWwgcHJvY2VkaW1pZW50byBhbnRlcmlvciBwYXJhICR4XzAkLCBwZXJvIGFob3JhIGNvbWVuemFuZG8gY29uICR4XzEkLCBlbiBjdXlvIGNhc28gc2Ugb2J0aWVuZSAkXGRpc3BsYXlzdHlsZSB4XzI9eDHiiJJcZnJhY3tmKHhfMSl9e2bigLIoeF8xKX0kLiBEZSBmb3JtYSBxdWUgJHhfMiQgZXN0w6EgbcOhcyBjZXJjYSBkZSBsYSByYcOteiBidXNjYWRhIHF1ZSAkeF8xJC4KCjcuIEl0ZXJhbmRvIGNhZGEgdmV6IGNvbiBlbCBuw7ptZXJvIG9idGVuaWRvLCBzZSBjb25zdHJ1eWUgdW5hIHNlY3VlbmNpYTogJHhfMCx4XzEseF8yLOKApix4X24s4oCmJCBkZSBuw7ptZXJvcyBjYWRhIHZleiBtw6FzIHByw7N4aW1vcyBhIGxhIHJhw616LCB0YWxlcyBxdWU6CgpcW3hfe24rMX09eF9u4oiSXGZyYWN7Zih4X24pfXtm4oCyKHhfbil9KDMpXF0KCkVuIHJlc3VtZW4geSBkZSBmb3JtYSBtZW5vcyB0ZcOzcmljYSBlbCBwcm9jZWRpbWllbnRvIGVzIGVsIHNpZ3VpZW50ZToKCi0gT2JzZXJ2YW5kbyBsYSBncsOhZmljYSBkZSBsYSBmdW5jacOzbiBzZSBlc3RpbWEgdW4gdmFsb3IgYWRlY2FkbyBwYXJhIGxhIHByaW1lcmEgYXByb3hpbWFjacOzbiAkeF8xJC4KCi0gU3VzdGl0dXllbmRvIGxhIHByaW1lcmEgYXByb3hpbWFjacOzbiBlbiAoMyksIHNlIG9idGllbmUgdW5hIHNlZ3VuZGEgYXByb3hpbWFjacOzbiAkeF8yJC4gTHVlZ28gc2UgY2FsY3VsYSAkeF8zJCBzdXN0aXR1eWVuZG8gZW4gKDMpIGxhIHNlZ3VuZGEgYXByb3hpbWFjacOzbiAkeF8yJDsgeSBhc8OtIHN1Y2VzaXZhbWVudGUgaGFzdGEgcXVlIHNlIGxsZWd1ZSBhIGxhIGlndWFsZGFkICR4X3tuKzF9PXhfbiQKCiMjIEPDs2RpZ28gZW4gUgoKCkVsIGPDs2RpZ28gdmllbmUgZGFkbyBwb3I6CgpgYGB7cn0KZXhwcmVzaW9uIDwtIGV4cHJlc3Npb24gKGV4cCh4KSt4LTIpICMgZXNjcmliaW1vcyBlbCBwb2xpbm9taW8KZGVyaXZhZGEgPC0gRChleHByZXNpb24sICJ4IikgIyBEZXJpdmFkYSBkZWwgcG9saW5vbWlvCiAKeCA8LSAwICAjIEN1YWxxdWllciB2YWxvciBkaWZlcmVudGUgZGUgYXByb3gKYXByb3ggPC0gMyAjIHZhbG9yIHB1bnRvaW5pY2lhbAoKd2hpbGUgKCB4ICE9IGFwcm94KSB7CiAgCiAgeCA8LSBhcHJveCAjIFNlIGxlIGFzaWduYSBlbCB2YWxvciBhcHJveGltYWRvIGEgeC4KCnJlZW1wbGF6b2V4cHJlc2lvbiA8LSBldmFsKGV4cHJlc2lvbikgI1JlZW1wbGF6YSBlbCB2YWxvciBkZSB4IGVuICJleHByZXNpw7NuIgoKcmVlbXBsYXpvZGVyaXYgPC0gZXZhbChkZXJpdmFkYSkgI1JlZW1wbGF6YSBlbCB2YWxvciBkZSB4IGVuICJkZXJpdmFkYSIKCiNuZXd0b24KCmFwcm94IDwtIHggLSAocmVlbXBsYXpvZXhwcmVzaW9uL3JlZW1wbGF6b2Rlcml2KSAjRWN1YWNpw7NuIG3DqXRvZG8gZGUgTmV3dG9uCgpwcmludCh4KQp9CmBgYAojIyBFamVyY2ljaW8gcGFyYSBsYSBjbGFzZToKCgoxLSBQYXJhIGxvcyBzaWd1aWVudGVzIHBvbGlub21pb3MsIHNlIHBpZGUgZmFjdG9yaXphcmxvcyB5IG9idGVuZXIgZGUgZXN0YSBmb3JtYSBsYXMgcmHDrWNlcyBvIGNlcm9zIGRlIG1hbmVyYSBhbmFsw610aWNhOgoKMS4xICRwXzEoeCk9eF4yK3jiiJIxMiQgKHNvbDogLTQgeSAzKS4KCjEuMiAkcF8yKHgpPXheM+KIkjR4XjIreCs2JCAoc29sOiAtMSwgMiwgeSAzKS4KCjEuMyAkcF8zKHgpPXheNOKIkjV4XjIrNCQgKHNvbDogLTIsIC0xLCAxIHkgMikuCgoyLSBQcm9ncmFtYSBlbiBSIGxvcyBwb2xpbm9taW9zIGRlbCBwdW50byAxLCBncmFmw61jYWxvcyB5IHV0aWxpemEgZWwgYWxnb3LDrXRtbyBkZSBOZXd0aG9uIFJoYXBzb24gcGFyYSBjb21wdXRhciBudW3DqXJpY2FtZW50ZSBzdXMgcmHDrWNlcy4gVmVyaWZpY2EgcXVlIGxvcyB2YWxvcmVzIG51bcOpcmljb3MgcXVlIG9idHV2aXN0ZSBzZSBhcHJveGltYW4gYSBsb3MgY2Vyb3MgZGUgbGEgZnVuY2nDs24uCgoKCgoKCg==