El método de Gauss-Seidel no será muy sencillo de resolver debido a la cantidad de operaciones e iteraciones que se realizan, pero para una computadora ésto no es problema alguno.
Trataré de explicarles la lógica que se ha de seguir para hacer un programa que resuelva un sistema de ecuaciones de 3X3 con este método; para ello yo usaré el lenguaje PHP pero el método, como todo buen algoritmo, es mudable a cualquier lenguaje.
Primero que nada es bueno el encasillar todos nuestros programas, o sea dividir lo más posible el problema en funciones pequeñas que se mandan a llamar de manera pertinente. Así que para empezar sería bueno tener funciones que calculen lo que será X1, X2 y X3.
Para ello podemos hacer ésto:
function getX1($b1,$a12,$x2,$a13,$x3,$a11)
{
return ($b1-($a12*$x2)-($a13*$x3))/$a11;
}
function getX2($b2,$a21,$x1,$a23,$x3,$a22)
{
return ($b2 - ($a21*$x1) - ($a23 * $x3)) / $a22;
}
function getX3($b3,$a31,$x1,$a32,$x2,$a33)
{
return ($b3 - ($a31 * $x1) - ($a32 * $x2)) / $a33;
}
Los parámetros que reciben las funciones son los mismo con los cuales se calculan matemáticamente X1, X2 y X3, por ello los nombré de la misma manera que en las funciones tradicionales.
function getEa($x1,$x2)
{
return abs((($x2-$x1)/$x2)*100);
}
{
return abs((($x2-$x1)/$x2)*100);
}
Siendo x1 el valor anterior y x2 el valor actual.
¿Cómo hacemos eso? Sencillo, primero necesitamos tener todos los valores necesarios para la función, o sea los que será Es; además de tener los valores iniciales para X1, X2 y X3 y un arreglo de 2 espacios para cada una de éstas variables (o sea 3 arreglos de 2 espacios); ¿para qué? pues por que allí se almacenarán los valores de Ea actual y anterior. Estos arreglos quedarían así (Por motivos propios los nombré como X11, X21 y X31 a cada arreglo):
$x11[0]=$x1;
$x11[1]=0;
$x21[0]=$x2;
$x21[1]=0;
$x31[0]=$x3;
$x31[1]=0;
$x11[1]=0;
$x21[0]=$x2;
$x21[1]=0;
$x31[0]=$x3;
$x31[1]=0;
La posición inicial de los arreglos será la que guarde el valor calculado de las X's anteriores, en ella se guardará en valor inicial de cada X's; en la segunda posición se guardará el nuevo valor de las X's, inicialmente es 0.
Luego, recordando que todos las operaciones se repiten indefinidamente, es obvio que necesitamos un bucle; el "while" es en este caso el más apto. Yo por practico le puse una condición True para que se repita infinitas veces:
while (true)
{
}
Claro, dentro del bucle le pondré un "break" cuando la condición adecuada deba romper el bucle, pero por ahora lo dejamos así.
Inmediatamente, al inicial el bucle, es necesario re-calcular los valores de las X's y depositarlos en la segunda posición de su respectivo arreglo; y bueno, para el cálculo ya tenemos las funciones, nuestro bucle queda, por ahora, así:
while (true)
{
$x11[1]=getX1($b1,$a12,$x21[0],$a13,$x31[0],$a11);
$x21[1]=getX2($b2,$a21,$x11[1],$a23,$x31[0],$a22);
$x31[1]=getX3($b3,$a31,$x11[1],$a32,$x21[1],$a33);
}
{
$x11[1]=getX1($b1,$a12,$x21[0],$a13,$x31[0],$a11);
$x21[1]=getX2($b2,$a21,$x11[1],$a23,$x31[0],$a22);
$x31[1]=getX3($b3,$a31,$x11[1],$a32,$x21[1],$a33);
}
Como ven, en algunas ocasiones envío la posición 0 de unos arreglos y luego envío la posición 1; ésto por que recuerden que en el calculo de X1 se usan los antiguos valores de las X's, en X2 se usa el nuevo valor de X1 pero el antiguo valor de X3 (por que aún no se ha calculado el nuevo) y en X3 ya se usan los nuevos valores de X1 y X2.
Después, y solo por que en ocasiones suele ocurrir en la primera interacción, se comprueba si ninguno de los nuevos valores de X's no es igual a 0.
Después se calcula, mediante la función getEa que programamos anteriormente, los Ea para cada uno de los nuevos valores de las X's con los anteriores; y si los 3 son menores o iguales a Es rompemos el ciclo. Entonces nuestro "while" queda así:
while(true)
{
$x11[1]=getX1($b1,$a12,$x21[0],$a13,$x31[0],$a11);
$x21[1]=getX2($b2,$a21,$x11[1],$a23,$x31[0],$a22);
$x31[1]=getX3($b3,$a31,$x11[1],$a32,$x21[1],$a33);
if($x11[1]!=0 || $x21[1]!=0 || $x31[1]!=0)
{
if(getEa($x11[0],$x11[1])<=$es)
{
if(getEa($x21[0],$x21[1])<=$es)
{
if(getEa($x31[0],$x31[1])<=$es)
{
break;
}
}
}
}
}
{
$x11[1]=getX1($b1,$a12,$x21[0],$a13,$x31[0],$a11);
$x21[1]=getX2($b2,$a21,$x11[1],$a23,$x31[0],$a22);
$x31[1]=getX3($b3,$a31,$x11[1],$a32,$x21[1],$a33);
if($x11[1]!=0 || $x21[1]!=0 || $x31[1]!=0)
{
if(getEa($x11[0],$x11[1])<=$es)
{
if(getEa($x21[0],$x21[1])<=$es)
{
if(getEa($x31[0],$x31[1])<=$es)
{
break;
}
}
}
}
}
Y para finalizar nuestro bucle, re-posicionamos los nuevos valores de las X's en la posición 0 de sus arreglos y dejamos la posición 1 en 0:
$x11[0]=$x11[1];
$x21[0]=$x21[1];
$x31[0]=$x31[1];
$x21[0]=$x21[1];
$x31[0]=$x31[1];
Entonces el programa final queda:
$x11[0]=$x1;
$x11[1]=0;
$x21[0]=$x2;
$x21[1]=0;
$x31[0]=$x3;
$x31[1]=0;
while(true)
{
$x11[1]=getX1($b1,$a12,$x21[0],$a13,$x31[0],$a11);
$x21[1]=getX2($b2,$a21,$x11[1],$a23,$x31[0],$a22);
$x31[1]=getX3($b3,$a31,$x11[1],$a32,$x21[1],$a33);
if($x11[1]!=0 || $x21[1]!=0 || $x31[1]!=0)
{
if(getEa($x11[0],$x11[1])<=$es)
{
if(getEa($x21[0],$x21[1])<=$es)
{
if(getEa($x31[0],$x31[1])<=$es)
{
break;
}
}
}
}
$x11[0]=$x11[1];
$x21[0]=$x21[1];
$x31[0]=$x31[1];
}
$resultados[0]= $x11[1];
$resultados[1]= $x21[1];
$resultados[2]= $x31[1];
He aquí como me quedó el programa al subirlo al internet (y ponerle una interfaz con html :P ):
Programa gauss-seidel
Sigan programando.
Edición: Como el código de arriba puede confundir por lo largo y las inexistentes alineaciones en Blogger dejo un enlace de descarga:
Gauss-seidel en PHP
Edición: Como el código de arriba puede confundir por lo largo y las inexistentes alineaciones en Blogger dejo un enlace de descarga:
Gauss-seidel en PHP
como coloco eso en php
ResponderEliminarPues mira, ya teniendo instalado tu servidor php (Yo uso XAMPP para windows, windows) en la carpeta para el localhost (en mi caso es htdocs, C/XAMPP/htdocs) creo un archivo con extensión .php
ResponderEliminarPara incrustar código php debes ponerlo entre las etiquetas < ?php y ?>
por ejemplo:
< ?php
function getX1($b1,$a12,$x2,$a13,$x3,$a11)
{
return ($b1-($a12*$x2)-($a13*$x3))/$a11;
}
function getX2($b2,$a21,$x1,$a23,$x3,$a22)
{
return ($b2 - ($a21*$x1) - ($a23 * $x3)) / $a22;
}
function getX3($b3,$a31,$x1,$a32,$x2,$a33)
{
return ($b3 - ($a31 * $x1) - ($a32 * $x2)) / $a33;
}
function getEa($x1,$x2)
{
return abs((($x2-$x1)/$x2)*100);
}
?>
y pues para que funciones pones el código final que hace que todo funcione (y declarando el valor de $es:
< ?php
$x11[0]=$x1;
$x11[1]=0;
$x21[0]=$x2;
$x21[1]=0;
$x31[0]=$x3;
$x31[1]=0;
while(true)
{
$x11[1]=getX1($b1,$a12,$x21[0],$a13,$x31[0],$a11);
$x21[1]=getX2($b2,$a21,$x11[1],$a23,$x31[0],$a22);
$x31[1]=getX3($b3,$a31,$x11[1],$a32,$x21[1],$a33);
if($x11[1]!=0 || $x21[1]!=0 || $x31[1]!=0)
{
if(getEa($x11[0],$x11[1])<=$es)
{
if(getEa($x21[0],$x21[1])<=$es)
{
if(getEa($x31[0],$x31[1])<=$es)
{
break;
}
}
}
}
$x11[0]=$x11[1];
$x21[0]=$x21[1];
$x31[0]=$x31[1];
}
$resultados[0]= $x11[1];
$resultados[1]= $x21[1];
$resultados[2]= $x31[1];
?>
Yo metí ese código en una función y que me regrese el arreglo $resultados:
< ?php
gauss($a11,$a12,$a13,$a21,$a22,$a23,$a31,$a32,$a33,$b1,$b2,$b3,$x1,$x2,$x3,$es)
{
$x11[0]=$x1;
$x11[1]=0;
$x21[0]=$x2;
...
return $resultados;
}
?>
La interfaz que yo puse en el enlace fue hecho en HTML, la tabla es un formulario que funciona por método POST, al recibir los valores POST mandé a llamar la función gauss con los parámetros que se metieron en el formulario.
Aclaro que $b1,$b2 y $b3 son los valores de las ecuaciones, $X1, $X2 y $X3 son los valores que se le da arbitrariamente a las x's...
ResponderEliminar< ?php
ResponderEliminargauss($a11,$a12,$a13,$a21,$a22,$a23,$a31,$a32,$a33,$b1,$b2,$b3,$x1,$x2,$x3,$es)
{
$x11[0]=$x1;
$x11[1]=0;
$x21[0]=$x2;
...
return $resultados;
}
?> esta parte no te entendi
lo copio como esta y me sale error en el return
ResponderEliminarfunction getX1($b1,$a12,$x2,$a13,$x3,$a11)
{
return ($b1-($a12*$x2)-($a13*$x3))/$a11;
}
function getX2($b2,$a21,$x1,$a23,$x3,$a22)
{
return ($b2 - ($a21*$x1) - ($a23 * $x3)) / $a22;
}
function getX3($b3,$a31,$x1,$a32,$x2,$a33)
{
return ($b3 - ($a31 * $x1) - ($a32 * $x2)) / $a33;
Bueno, yo escribí < ?php separando el < y el ? ya que Blogger ignora esa sintaxis, tú ponlo junto (no sé si esto te mandó también error).
ResponderEliminarOtra cosa, ¿Qué error te manda en el return? A lo que veo te falta cerrar la llave del final
function getX3($b3,$a31,$x1,$a32,$x2,$a33)
{
return ($b3 - ($a31 * $x1) - ($a32 * $x2)) / $a33;
}
Sobre la función gauss(....) pues es nada más que introduces el ultimo código que puse en una función, quedaría realmente así:
gauss($a11,$a12,$a13,$a21,$a22,$a23,$a31,$a32,$a33,$b1,$b2,$b3,$x1,$x2,$x3,$es)
{
$x11[0]=$x1;
$x11[1]=0;
$x21[0]=$x2;
$x21[1]=0;
$x31[0]=$x3;
$x31[1]=0;
while(true)
{
$x11[1]=getX1($b1,$a12,$x21[0],$a13,$x31[0],$a11);
$x21[1]=getX2($b2,$a21,$x11[1],$a23,$x31[0],$a22);
$x31[1]=getX3($b3,$a31,$x11[1],$a32,$x21[1],$a33);
if($x11[1]!=0 || $x21[1]!=0 || $x31[1]!=0)
{
if(getEa($x11[0],$x11[1])<=$es)
{
if(getEa($x21[0],$x21[1])<=$es)
{
if(getEa($x31[0],$x31[1])<=$es)
{
break;
}
}
}
}
$x11[0]=$x11[1];
$x21[0]=$x21[1];
$x31[0]=$x31[1];
}
$resultados[0]= $x11[1];
$resultados[1]= $x21[1];
$resultados[2]= $x31[1];
return $resultados;
}
y te arrojaría el arreglo $resultados que contiene en los valores finales de X1, X2 y X3...
agregame al face http://www.facebook.com/michael.cotes
ResponderEliminarme podrias dar el archivo del programa completo es que no he podido armarlo y me sirve para la clase que tengo
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarVale, te paso mi programa; son dos archivos: el index.php (y el que se tiene que abrir desde el navegador) que más que nada da la interfaz y el de funciones.php que contiene, precisamente, las funciones que expuse :P
ResponderEliminarhttps://dl.dropboxusercontent.com/u/46960544/gauss_seidel.rar
muchas gracias me ha servido de mucho no lo habia podido hacer por que me faltava hacer estos $tabla[0][0]=$a11; cada una XD
ResponderEliminarinicializar la tabla :P
ResponderEliminarDe nada, camarada; gracias por visitar mi blog;