#gauss
# resuelve un sistema de ecuaciones, mediante el metodo de Gauss
import os

os.system("clear")

a=[[214.0,2.0,-4.0,8.5,-7.0],
    [1.0,15.0,-2.0,2.0,18.0],
    [-10.0,-2.0,5.0,-1.0,-23.0],
    [82.0,13.0,-17.0,1.0,12.0]]         # matriz de coeficiente mas termino independiente
d=[0.0,0.0,0.0,0.0]                     # vector solucion
n=len(a)-1
z=[[214.0,2.0,-4.0,8.5,-7.0],           # se copia la matriz original parapoder hacer la verificacion
    [1.0,15.0,-2.0,2.0,18.0],
    [-10.0,-2.0,5.0,-1.0,-23.0],
    [82.0,13.0,-17.0,1.0,12.0]]

def imprimematriz(x):
    # tener en cuenta que en realidad es una lista anidada o un vector de vectores
    n=len(x)-1
    i=0
    while i<=n:
        j=0
        while j<=n+1:   # agrego uno para tomar la columna ampliada
        
            print '{0:8.4f}'.format(x[i][j]),  # el 0, indica el orden del argumento dentro de los parentesis del format
            #print x[i][j],                     # 8.4f indica un numero de 8 cifras con 4 decimales y la f que es float
            j=j+1
        print 
        i=i+1
    dum=raw_input("Toque una tecla")
        
def imprimevector(x):
    n=len(x)-1
    i=0
    while i<=n:
        print '{0:8.4f} '.format(x[i])
        i=i+1

# verifico que no haya un 0 en la diagonal principal
i=0
while i<=n:
    if a[i][i]==0:
        print "0 en la diagonal",i
        exit()
    i=i+1


print "matriz ampliada"
imprimematriz(a)
print "-------------------"
k=0
while k<=n:
    i=k
    while i<=n:
        j=n+1                           # se hubica en la columna ampliada
        while j>=k:                     # empieza por atras porque si divide pivite por si mismo queda 1
            a[i][j]=a[i][j]/a[i][k]     # divide por el pivote toda la linea
            j=j-1                       # recorre la fila de atras para adelante, paso a la columna anterior
        i=i+1                           # termino la fila, paso a la fila inferior
    i2=k+1
    print "dividi todos por la columan del pivote",k
    imprimematriz(a)
    while i2<=n:
        j2=n+1                           # se hubica en la columna ampliada
        while j2>=k:                     # empieza por atras porque si resto pivite por si mismo queda 0
            a[i2][j2]=a[k][j2]-a[i2][j2] #resta las lineas hacia abajo
            j2=j2-1                      # paso a la columna anterio
        i2=i2+1                          # termino la fila y paso a la fila inferior
    k=k+1
    print  "resto los elementos de todas las filas a la fila del pivote",k-1
    imprimematriz(a)

print "matriz diagonalizada"
imprimematriz(a)
print "-------------------"
# calculo d
# haciendo una retrosustitucion
i=n                                     # empiezo en la ultima fila
while i>=0:                             #recorro de abajo hacia arriba
    print
    imprimematriz(a)
    b=0.0                               #borro un acumulador
    j=n                                 #me paro en la ultima columna
    while j>i:                          #recorro toda la fila
        print " acumulo a[",i,j,"] * d[",j,"]",
        b=b+a[i][j]*d[j]                #calculo lo que debo restar a la columna de la matriz ampliada 
        j=j-1
    d[i]=a[i][n+1]-b                    # resto a a[i][n+1] que es el vctor adosado de la matriz ampliada el b que calcule y lo guardo en el vector d que es la solucion 
    print "se lo resto a a[",i,n+1
    i=i-1
print
print "Solucion"
imprimevector(d)

#verificacion
print
print "verificacion"
i=0
while i<=n:
    dummy=0.0
    j=0
    while j<=n:
        dummy=dummy+z[i][j]*d[j]
        j=j+1
    print '{0:8.4f} '.format(dummy)
    i=i+1