Red de conocimiento informático - Conocimiento del nombre de dominio - Cómo escribir un programa sobre matrices

Cómo escribir un programa sobre matrices

Introducción al algoritmo

La inversión de matrices es muy común en programas 3D y se utiliza principalmente para encontrar la matriz Billboard. La multiplicación según el método de cálculo definido afecta seriamente el rendimiento. Cuando se requiere una gran cantidad de operaciones matriciales de Billboard, la optimización de la inversión de la matriz puede mejorar enormemente el rendimiento. El algoritmo de inversión de matrices que se presentará aquí se denomina método de Gauss-Jordan de pivote totalmente seleccionado.

Los pasos para encontrar la inversión del método Gauss-Jordan (seleccionando todos los pivotes) son los siguientes:

Primero, realice los siguientes pasos para k de 0 a n - 1:

Seleccione el elemento con el valor absoluto más grande del submatriz de la esquina inferior derecha comenzando desde la k-ésima fila y columna k, recuerde el número de fila y el número de columna del elemento secundario e intercámbielo por el elemento primario. mediante intercambio de filas y posición de columnas. Este paso se llama seleccionar todos los pivotes.

m(k, k) = 1 / m(k, k)

m(k, j) = m(k, j) * m(k, k), j = 0, 1, ..., n-1; j != k

m(i, j) = m(i, j) - m(i, k) * m(k, j), i, j = 0, 1, ..., n-1; i, j != k

m(i, k) = -m(i, k) * m(k , k), i = 0, 1, ..., n-1; i != k

Finalmente, restaure en función de la información de intercambio de filas y columnas registrada durante el proceso de selección de todos los elementos pivote. , el principio de recuperación es el siguiente: en el proceso de selección de todos los pivotes, las filas (columnas) se intercambian primero y luego se restauran el intercambio de filas (columnas) original mediante el intercambio de columnas (filas).

Implementación (matriz de 4º orden)

float Inverse(CLAYMATRIXamp; mOut, const CLAYMATRIXamp; rhs)

{

CLAYMATRIX m( rhs);

DWORD es[4];

DWORD js[4];

float fDet = 1.0f; f = 1;

for (int k = 0; k lt; 4; k )

{

// Primer paso, seleccionar todos los pivotes

float fMax = 0.0f;

para (DWORD i = k; i lt; 4; i )

{

para (DWORD j = k; j lt; 4; j)

{

const float f = Abs(m(i, j));

si (f gt; fMax)

{

fMax = f

es[k] = i;

}

}

}

si (Abs(fMax) lt; 0.0001f)

devolver 0;

if (is[k] != k)

{

f = -f;

intercambiar (m (k, 0), m(es[k], 0));

swap(m(k, 1), m(es[k], 1));

intercambiar(m(k, 2), m(es[k], 2));

intercambiar(m(k, 3), m(es[k], 3)); p>

}

if (js[k] != k)

{

f = -f

swap(m(0, k), m(0, js[k]));

swap(m(1, k), m(1, js[k]));

intercambiar(m(2, k), m(2, js[k]));

intercambiar(m(3, k), m(3, js[k] )) ;

}

// Calcular valores de fila y columna

fDet *= m(k, k

/ / Calcular matriz inversa

// Segundo paso

m(k, k) = 1.0f / m(k, k

// Tercer paso);

for (DWORD j = 0; j lt; 4; j )

{

si (j != k)

m(k, j) *= m(k, k);

}

// Paso 4

para (DWORD i = 0; i lt 4; i )

{

si (i != k)

{

para (j =

0; j lt; 4; j )

{

si (j != k)

m(i, j) = m(i, j ) - m(i, k) * m(k, j);

}

}

}

// No Cinco pasos

para (i = 0; i lt; 4; i )

{

if (i != k)

m(i, k) *= -m(k, k);

}

}

para (k = 3; k gt; = 0; k --)

{

si (js[k] != k)

{

intercambiar(m ( k, 0), m(js[k], 0));

swap(m(k, 1), m(js[k], 1));

intercambiar(m(k, 2), m(js[k], 2));

intercambiar(m(k, 3), m(js[k], 3));

}

if (es[k] != k)

{

swap(m(0, k), m(0 , es[k]));

swap(m(1, k), m(1, es[k]));

swap(m(2, k) , m(2, es[k]));

swap(m(3, k), m(3, es[k]));

}

}

mOut = m;

return fDet * f

}

Comparar

Algoritmo original Algoritmo original (altamente optimizado) Nuevo algoritmo

Número de sumas 103 61 39

Número de multiplicaciones 170 116 69

Requiere espacio adicional 16 * sizeof (flotante) 34 * tamaño de (flotante) 25 * tamaño de (flotante)