3.2 Pivoteo parcial por filas

Referencia: Chapra 9.4.2 p268, pdf 292.

Para minimizar errores en la solución de matrices, se prefiere tener el valor mayor de cada fila en la diagonal, denominado «pivote».

Para los algoritmos, el pivoteo se realiza sobre la matriz aumentada, para así ordenar también los valores del vector B.

A = np.array([[4,2,5],
              [2,5,8],
              [5,4,3]])


B = np.array([[60.70],
              [92.90],
              [56.30]])

Matriz Aumentada, se realiza al concatenar la matriz A con el vector B por medio de columnas. Observe que el vector B se utilza en forma de columna.

AB = np.concatenate((A,B),axis=1)

el resultado de AB corresponde a:

>>> AB
array([[ 4. ,  2. ,  5. , 60.7],
       [ 2. ,  5. ,  8. , 92.9],
       [ 5. ,  4. ,  3. , 56.3]])

El pivoteo parcial corresponde al procedimiento realizado por filas en la matriz AB, por ejemplo:

Para el pivoteo por fila, para la primera fila se inicia revisando la primera columna, desde la diagonal en adelante y se observa dónde se encuentra la mayor magnitud escalar (usando valor absoluto).

columna = [|4|,
           |2|,
           |5|]
dondemax = 2

El mayor debe encontrarse en la primera posición de la columna, que corresponde a la diagonal de la matriz.  de no se así, debe intercambiar las filas de la matriz.

AB = [[ 5. , 4. , 3. , 56.3],
      [ 2. , 5. , 8. , 92.9],
      [ 4. , 2. , 5. , 60.7]]

Para la segunda fila , se toma la segunda columna desde la diagonal en adelante y se repite el proceso.

columna = [|5|,
           |2|]
dondemax = 0

que repetido para todas las filas de la matriz, tiene como resultado:

matriz pivoteada por fila:
AB = [[ 5. ,  4. ,  3. , 56.3],
      [ 2. ,  5. ,  8. , 92.9],
      [ 4. ,  2. ,  5. , 60.7]]

En el algoritmo propuesto, se usa una copia de la matriz, de tal manera que se conserve la matriz original para comparar con el resultado.

Si no se requiere la matriz original, no se realiza la copia y se ahorra el espacio de memoria; detalle importante para matrices de «gran» tamaño.

# Pivotea por filas, Pivoteo parcial
# Recibe la matriz A, copia en C para no modificar A
# Si hay ceros en diagonal, la matriz es singular,
# Tarea: Revisar si diagonal tiene ceros
import numpy as np

def pivoteafila(M):
    tamano = np.shape(M)
    n = tamano[0]
    m = tamano[1]
    C = np.copy(M)
    for i in range(0,n-1,1):
        # columna desde diagonal i en adelante
        columna = np.abs(C[i:,i])
        dondemax = np.argmax(columna)
        # revisa dondemax no está en la diagonal
        if (dondemax != 0):
            # intercambia fila
            temporal = np.copy(C[i,:])
            C[i,:] = C[dondemax+i,:]
            C[dondemax+i,:] = temporal
    return(C)

# INGRESO
A = np.array([[4,2,5],
              [2,5,8],
              [5,4,3]])

B = np.array([[60.70],
              [92.90],
              [56.30]])

# PROCEDIMIENTO
AB = np.concatenate((A,B),axis=1)
respuesta = pivoteafila(AB)
# SALIDA
print('matriz pivoteada por fila:')
print(respuesta)