Álgebra lineal: ¿Cómo se escribe un programa en C para reducir una matriz a una forma escalonada o una forma escalonada reducida?

Prueba este algoritmo,

La función ToReducedRowEchelonForm (Matrix M) es
plomo : = 0
rowCount : = el número de filas en M
columnCount : = el número de columnas en M

para 0 ≤ r < rowCount do
if columnCountlead entonces
detener
terminara si
i = r
mientras que M [ i , lead ] = 0 do
i = i + 1
si rowCount = i entonces
i = r
plomo = plomo + 1
if columnCount = lead entonces
detener
terminara si
terminara si
terminar mientras
Intercambiar filas iy r
Si M [ r , plomo ] no es 0, divida la fila r por M [ r , plomo ]
para 0 ≤ i < rowCount do
si lo hago
Resta M [i, plomo] multiplicado por la fila r de la fila i
terminara si
fin para
plomo = plomo + 1
fin para
función final

El código también se proporciona aquí (forma escalonada de fila reducida) pero intente escribirlo una vez usando el algoritmo anterior.

Los detalles exactos pueden depender un poco del tamaño y el formato de almacenamiento de su matriz de entrada, pero aquí hay una sugerencia en C99, se espera un valor n seguido de una densa matriz n-por-n en orden principal de fila, dada como texto en la entrada estándar.

Escribí esto en base al pseudocódigo en “Matemática numérica y computación” de Cheney y Kincaid (4ª ed., Págs. 260); no hay verificación de cordura, no ha sido sometido a pruebas exhaustivas y no es increíblemente hermoso, pero podría funcionar para que su computadora reduzca algunas matrices.

En 136 líneas, abarrotaría la página de preguntas, por lo que probablemente sea mejor colocarla en un comentario (plegable), a continuación.

Realmente estoy luchando con esto como principiante, pero he programado en otros idiomas antes. Siempre quise programar RREF, así que comencé asumiendo que no hay filas con ceros y que es solucionable … todas esas comprobaciones que haría más tarde; pero este código no funciona … ¿por qué?

while (plomo {
for (int i = 0; i {
si (i! = plomo)
{
cout << A [plomo] [plomo] << "" << A [i] [plomo];
para (int j = 0; j {
A [i] [j] = A [plomo] [plomo] * A [i] [j];
A [i] [plomo] = A [i] [plomo] * A [plomo] [j];
A [i] [j] = A [i] [j] -A [i] [plomo];
}
cout << endl;
}
}
plomo ++;
cout << endl;

}

Probablemente hay otras formas más fáciles de hacerlo, pero lo codificaría de la misma manera que hago estos problemas (estrategia general). Primero, configuro el coeficiente del elemento en la fila 1, columna 1 a 1 (divida la fila por ese elemento).

Luego tome el primer elemento de la siguiente fila y ajústelo a cero (reste r2 – elemento * r1). Repita para el primer elemento de la tercera fila y así sucesivamente para todas las filas. Luego vaya a la fila 2, columna 2 y configúrelo en 1 (divida por ese elemento) y configure los elementos en el resto de la columna 2 a cero. Luego fila 3, columna 3 y así sucesivamente …

Podría ahorrar tiempo y división por cero errores al verificar si el elemento no era cero, por ejemplo. Pero esa sería la estrategia general que utilizo: ir en diagonal desde el elemento anterior distinto de cero, establecerlo en 1, establecer todos los elementos debajo de cero, enjuagar y repetir. Creo que eso debería darle a la fila forma escalonada.

¡Te dejaré una fila reducida y casos imposibles de resolver!

Si sabe cómo hacerlo a mano, simplemente programe las mismas reglas. Si no sabe cómo hacerlo a mano, nunca lo conseguirá. Pero puede comprar un paquete que lo haga por usted.