leer
. Sus argumentos serán, por este orden, el tamaño de la matriz (un solo valor, puesto que es cuadrada) y luego la propia matriz, a la que vamos a suponer que hemos predimensionado a tamaño 100. Vamos a echar un vistazo a cómo son las cabeceras de las funciones que tienen algún argumento tabla o matriz.
Plantilla a poner | |
void nombrefuncion ( ...tipo nombrematriz[filas][columnas]...)
|
Lo primero el tipo de los elementos de la matriz (float, Metros, Punto, ...)
Luego el nombre. En ningún caso lleva * Las tablas o matrices son siempre, automáticamente, de entrada y salida.
Luego un par de corchetes y entre ellos el número de filas de la matriz. Reglamentariamente no es obligatorio y se podría dejar el par de corchetes vacío. Para evitar confusiones con otras situaciones en las que no se pueden dejar vacíos, suele ser recomendable acostumbrarse a ponerlo siempre.
Luego otro par de corchetes y entre ellos el número de columnas de la matriz. Es obligatorio: no se puede en ningún caso dejar el par de corchetes vacío.
|
void escribir(int filas, int colums, float matriz[filas][colums])
Está perfecta. También podríamos haber omitido filas en el primer par de corchetes.
void generar(float matriz[][colums], int *filas, int *colums)
Tiene un fallo: la cantidad de columnas que se pone en los corchetes es la de dimensión, no la que realmente uses.
void trasponer(float matriz[][], filas, colums, *traspuesta[][])
Tiene varios fallos: una matriz nunca lleva * la cantidad de columnas es obligatorio ponerla y faltan tipos.
void leer(int *tamreal, float matrizgrande[100][100])
void leer(int *tamreal, float *matrizgrande[][100])
void leer(int *tamreal, float matrizgrande[100][])
Vamos a resolver el determinante por el método de los adjuntos. Cada adjunto lo resolveremos por el mismo método, así que necesitamos homogeneizar el tratamiento. Vamos a optar porque las sucesivas matrices sean de tamaño ajustado. Entonces la original hay que copiarla a otra ajustada, lo cual podemos hacer en main
o en una función. Otra opción es leer primero el tamaño y esperar ahí para dimensionar la matriz. Toma la decisión que quieras y prepáralo. Pienso que para eso no necesites pistas.
Sigamos. Puesto que vamos a usar el método de los adjuntos, vamos a preparar una función para sacar la matriz adjunta de un elemento.
void adjunta(int tam, float mator[tam][tam], int fel, int cel, float matad[tam-1][tam-1])
void adjunta(int tam, float mator[][tam], int fel, int cel, tam--, float *matad[][tam])
void leer(int *tamreal, float matrizgrande[100][])
Preparemos esa función. Rellenaremos la matriz adjunta copiando desde la matriz original. Para recorrerla tendremos el típico doble ciclo de filas y columnas. Vamos con el de filas.
Realmente tenemos que recorrer ambas matrices, pero no son iguales (la adjunta es más pequeña), así que inicializaremos también su índice de filas, pero el incremento, como no va a ser siempre (la fila del elemento cuya adjunta estamos creando no cuenta), lo llevaremos dentro del ciclo.
for(filor=0,filad=0;filor<tam; filor++)
for(filor=filad=0;filor<tam-1; filor+1)
for(filor=0,filad=0;filad<tam; filor=filor+1)
for(filor=filad=0;filor<tam; filor+=1)
Dentro de este ciclo de filas, lo primero que vamos a mirar es si esta fila hay que copiarla. La del elemento cuya adjunta estamos sacando, no hay que copiarla; el resto sí.
if(filor==fel)
if(fel=filor)
if(filor==fel-1)
Si se cumple el if hay que pasar a la siguiente: puedes usar la instrucción continue
. Si no, pasamos al ciclo de columnas, que es análogo al de filas, también con un if
al principio para ver si hay que saltarse esa columna. Si no, copiamos el elemento de la original a la adjunta.
¿Recuerdas cómo se maneja un elemento de una matriz o tabla?
Plantilla a poner | |
...,nombrematriz[fila][columna]...
|
Se pone el nombre de la matriz
Luego un par de corchetes y entre ellos el número de la fila del elemento que interesa de la matriz. Recuerda que están numeradas desde 0
Luego otro par de corchetes y entre ellos el número de columna.
|
matad[filad][colad]=mator[filor][color];
matad[filor][color]=mator[filor][color];
mator[filor][color]=matad[filad][colad];
Después de copiar el elemento sube la columna de la adjunta (recuerda que lo habíamos dejado para incrementarlo dentro del ciclo) Después del ciclo de columnas pon el incremento de la fila de la adjunta. Termina la función adjunta comprobando las llaves.
En el programa principal habrá una llamada a la función determinante
. Esa función irá calculando los adjuntos, llamando a la propia función determinante
¿Qué argumentos tendrá la función? El tamaño y la propia matriz cuyo determinante interesa como entrada, y el determinante como salida. De esa forma podemos construir la cabecera.
¿Cómo será la llamada? ¿Cómo son las llamadas a funciones cuando algún argumento es una matriz?
Plantilla a poner | |
nombrefunción(...nombrematriz...);
|
Se pone el nombre de la matriz, sólo, sin corchetes,, siempre que queramos pasar la matriz completa (si pones corchetes pasaría sólo un elemento)
|
determinante(tamreal, matriz, &det);
determinante(tamreal, matriz[tamreal][tamreal], &det);
determinante(tamreal, matriz[][], &det);
Vamos a construir la función determinante.
Esta función va a necesitar llamarse a sí misma, para calcular los adjuntos. Toda función que haga eso tiene que tener separado un caso simple que se resuelve directamente.
Vamos a elegir el tamaño 2 para resolución directa, así que pon un if que compruebe si el tamaño es 2
*det=matriz[0][0]*matriz[1][1]-matriz[0][1]*matriz[1][0];
*det=matriz[1][1]*matriz[2][2]-matriz[1][2]*matriz[2][1];
det=matriz[1][1]*matriz[0][0]-matriz[1][0]*matriz[0][1];
En otro caso (else) vamos a usar los adjuntos de la primera fila. Antes pon el determinante a 0, porque lo iremos sumando.
En el ciclo de la primera fila vamos a mover dos variables: la columna y el signo, que va cambiando.
for(col=0,signo=1; col<tam; col++,signo=-signo)
for(col=0,signo=+; col<=tam; ++col,-signo)
Dentro del ciclo lo primero sacar la matriz adjunta del elemento correspondiente, para lo cual usaremos la función que hicimos antes.
adjunta(tam, matriz, 0, col, matadj);
adjunta(tam,matriz,fil,col,adjunta);
fil
no la tenemos, y una variable no puede llamarse igual que una función.
adjunta(tam-1,matriz,fil,col,&matadjunta);
tam
, fil
no la tenemos, y las matrices nunca pasan con &
Ahora calcularemos el determinante de la matriz adjunta usando la propia función determinante.
determinante(tam-1, matadj, &detadj);
determinante(tam, matriz, &*det);;
tam
es el tamaño de la matriz completa, el de la adjunta será uno menos, la matriz que hay que pasar es la adjunta, y no podemos usar det
para el determinante de la adjunta porque ése es el que usamos para la completa, y nos lo machacaría; necesitamos otra variable
determinante(tam, matadj, det);
tam
es el tamaño de la matriz completa, el de la adjunta será uno menos, y no podemos usar det
para el determinante de la adjunta porque ése es el que usamos para la completa, y nos lo machacaría; necesitamos otra variable
Una vez calculado el determinante de la matriz adjunta, le multiplicamos por el elemento correspondiente y, con su signo, le acumulamos al determinante total.
*det+=matriz[0][col]*signo*detadj;
*det = *det+matriz[fil][col]*(signo)detadj;
(signo)detadj
no tiene sentido; signo
es una variable que vale 1 ó -1 y lo vamos multiplicando
*det = *det (signo)matadj[0][col]*det;
(signo)matadj
no tiene sentido; signo
es una variable que vale 1 ó -1 y lo vamos multiplicando. El elemento le cogemos de la matriz completa. Y el determinante adjunto lo habíamos puesto en otra variable.
Cierra los ciclos,cierra el else y declara todas las variables. Comprueba que en todas las funciones estén declaradas todas las variables.
Pruébalo con una matriz cuyo determinante conozcas. Si te atascas con algo, consulta al profesor.