<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Método de Jacobi
En esta ocasión exploraremos una implementación del método de Jacobi para la aproximación de solución a sistemas de ecuaciones lineales.
Empecemos declarando un sistema de ecuaciones lineales en su forma matricial
Step1:  Con lo que, trivialmente, podemos ver su solución por medio de la implementación mas simple
Step2:  Sin embargo, deseamos implementar un método diferente, por lo que empezaremos obteniendo información acerca del sistema, por ejemplo, si queremos saber la dimensión de la matriz $A$, y por consecuente la dimensión del sistema, tendremos
Step3:  Ya sabemos que esta matriz es cuadrada, por lo que podemos obtener el primer elemento solamente con
Step4:  Recordando el método de Jacobi, tenemos que empezar con una aproximación $0$ en todas las variables, por lo que definimos un arreglo de ceros, con la funcion zeros, y lo convertimos en un objeto de tipo matrix
Step5:  Lo siguiente que voy a necesitar es un arreglo con todos los elementos de la diagonal principal, para dividir cada una de las formulas de la aproximación con estos elementos
Step6:  Una vez que obtengo la diagonal, voy a sustituir todos los elementos de esta por $0$, de manera que cuando multiplique cada una de las filas de esta matriz, por el valor de la aproximación de $x$, $x_0$, obtendré la mayoría de los elementos de cada una de las formulas
Step7:  Tomando en cuenta que nuestra primera aproximación es toda $0$, este vector es completamente correcto, ahora tenemos que dividir cada uno de estos elementos por el vector diagonal
Step8:  Por ultimo tenemos que restar cada uno de estos elementos a la division del vector $b$ con la diagonal, de tal manera que tengamos
Step9:  lo cual corresponde a nuestra primer aproximación, por lo que lo hemos guardado en x1.
Si ahora obtenemos la diferencia entre las primeras dos aproximaciones, y lo guardamos en la variable dif
Step10:  podemos obtener el cuadrado de cada una de estas diferencias con dif.T*dif, es  decir
Step11:  por lo que obtenemos nuestro error inicial. Ahora tan solo tenemos que seguir haciendo iteraciones hasta obtener una buena aproximación
<ASSISTANT_TASK:>
Python Code:
from numpy import matrix
A = matrix([[72,    0,  0,  9,  0,    0],
            [ 0, 2.88,  0,  0,  0, -4.5],
            [ 0,    0, 18,  9,  0,    0],
            [ 9,    0,  9, 12,  0,    0],
            [ 0,    0,  0,  0, 33,    0],
            [ 0, -4.5,  0,  0,  0,   33]])
b = matrix([[2],
            [0.5],
            [1],
            [0],
            [1.2],
            [5]])
Explanation: Método de Jacobi
En esta ocasión exploraremos una implementación del método de Jacobi para la aproximación de solución a sistemas de ecuaciones lineales.
Empecemos declarando un sistema de ecuaciones lineales en su forma matricial:
End of explanation
A.I*b
Explanation: Con lo que, trivialmente, podemos ver su solución por medio de la implementación mas simple:
End of explanation
A.shape
Explanation: Sin embargo, deseamos implementar un método diferente, por lo que empezaremos obteniendo información acerca del sistema, por ejemplo, si queremos saber la dimensión de la matriz $A$, y por consecuente la dimensión del sistema, tendremos:
End of explanation
A.shape[0]
Explanation: Ya sabemos que esta matriz es cuadrada, por lo que podemos obtener el primer elemento solamente con:
End of explanation
from numpy import zeros, copy
x0 = matrix(zeros(A.shape[0])).T
x0
Explanation: Recordando el método de Jacobi, tenemos que empezar con una aproximación $0$ en todas las variables, por lo que definimos un arreglo de ceros, con la funcion zeros, y lo convertimos en un objeto de tipo matrix:
End of explanation
A.diagonal()
divisores = copy(A.diagonal().T)
divisores
Explanation: Lo siguiente que voy a necesitar es un arreglo con todos los elementos de la diagonal principal, para dividir cada una de las formulas de la aproximación con estos elementos:
End of explanation
from numpy import fill_diagonal
fill_diagonal(A, 0)
A
-A*x0
Explanation: Una vez que obtengo la diagonal, voy a sustituir todos los elementos de esta por $0$, de manera que cuando multiplique cada una de las filas de esta matriz, por el valor de la aproximación de $x$, $x_0$, obtendré la mayoría de los elementos de cada una de las formulas:
$$
0 x_1 + a_{12}x_2 + a_{13}x_3+\ldots+a_{1n}x_n
$$
End of explanation
from numpy import divide
divide(-A*x0, divisores)
Explanation: Tomando en cuenta que nuestra primera aproximación es toda $0$, este vector es completamente correcto, ahora tenemos que dividir cada uno de estos elementos por el vector diagonal:
$$
\frac{0 x_1 + a_{12}x_2 + a_{13}x_3+\ldots+a_{1n}x_n}{a_{11}}
$$
End of explanation
x1 = divide(b, divisores) - divide(A*x0, divisores)
x1
Explanation: Por ultimo tenemos que restar cada uno de estos elementos a la division del vector $b$ con la diagonal, de tal manera que tengamos:
$$
\frac{b}{a_{11}} -\frac{0 x_1 + a_{12}x_2 + a_{13}x_3+\ldots+a_{1n}x_n}{a_{11}}
$$
End of explanation
dif = x1 - x0
dif
Explanation: lo cual corresponde a nuestra primer aproximación, por lo que lo hemos guardado en x1.
Si ahora obtenemos la diferencia entre las primeras dos aproximaciones, y lo guardamos en la variable dif:
End of explanation
from numpy import sqrt
e1 = sqrt((dif.T*dif)[0,0])
e1
Explanation: podemos obtener el cuadrado de cada una de estas diferencias con dif.T*dif, es  decir:
$$
(\bar{x}_1 - x_1)^2 + (\bar{x}_2 - x_2)^2 + \ldots + (\bar{x}_n - x_n)^2 =
\begin{pmatrix}
\bar{x}_1 - x_1 &
\bar{x}_2 - x_2 &
\ldots &
\bar{x}_n - x_n
\end{pmatrix}
\begin{pmatrix}
\bar{x}_1 - x_1 \
\bar{x}_2 - x_2 \
\vdots \
\bar{x}_n - x_n
\end{pmatrix}
$$
y a este valor, tan solo tenemos que sacarle la raiz cuadrada:
End of explanation
x2 = divide(b, divisores) - divide(A*x1, divisores)
x2
dif = x2 - x1
e2 = sqrt((dif.T*dif)[0,0])
e2
x3 = divide(b, divisores) - divide(A*x2, divisores)
x3
dif = x3 - x2
e3 = sqrt((dif.T*dif)[0,0])
e3
Explanation: por lo que obtenemos nuestro error inicial. Ahora tan solo tenemos que seguir haciendo iteraciones hasta obtener una buena aproximación:
End of explanation
<END_TASK>