Annotation of ADD_ver_10/Source Code/Source Files/CalculosMatrices.c, revision 1.1

1.1     ! rico        1: /******************************************************************************/
        !             2: /* MÓDULO: CalculosMatrices.c                                                 */
        !             3: /*                                                                            */
        !             4: /* Este módulo contiene las funciones que realizan cálculos sobre             */
        !             5: /* las matrices.                                                              */
        !             6: /******************************************************************************/
        !             7: /* Fecha: 26 de septiembre de 2005                                            */
        !             8: /******************************************************************************/
        !             9: 
        !            10: #include <stdio.h>
        !            11: #include <stdlib.h>
        !            12: #include <string.h>
        !            13: 
        !            14: #include "defines.h"
        !            15: #include "tipos.h"
        !            16: #include "calculosmatrices.h"
        !            17: 
        !            18: /* configuración */
        !            19: extern struct argumentos configuracion;
        !            20: 
        !            21: /* análisis de dependencias de datos */
        !            22: extern struct punterosD matriz;
        !            23: extern unsigned char **matrizC;
        !            24: extern char **OrdenParcial;
        !            25: 
        !            26: /* parámetros asociados a las matrices */
        !            27: extern parametromatriz *pasos;
        !            28: extern parametromatriz *mediapasos;
        !            29: extern parametromatriz *grado;
        !            30: extern parametromatriz *mediagrado;
        !            31: extern parametromatriz *acoplo;
        !            32: extern parametromatriz *mediaacoplo;
        !            33: 
        !            34: /* otros resultados */
        !            35: extern unsigned long *distribucionpasos;
        !            36: 
        !            37: 
        !            38: /* esta función calcula la matriz de caminos de dependencias C */
        !            39: /* a partir de una matriz de dependencias D */
        !            40: /* devuelve el número de pasos de computación requeridos para */
        !            41: /* finalizar la computación de la secuencia expresada por D */
        !            42: /* (la matriz de caminos devuelta no ha sido reducida a 0s y 1s) */
        !            43: 
        !            44: /* esta función es muy consumidora de tiempo ya que calcula potencias de D */
        !            45: 
        !            46: unsigned int CalcularMatrizCaminos(unsigned char **D, unsigned char **C)
        !            47: {
        !            48:     char mensaje[MAX_LINE];
        !            49:     unsigned char *v;        /* vector temporal */
        !            50:     unsigned char **tmp;    /* matriz temporal */
        !            51: 
        !            52:     unsigned int i, j, k, potencia;
        !            53:     unsigned int suma;
        !            54:     unsigned char matriz_nula;
        !            55: 
        !            56: 
        !            57:     if(D == NULL)
        !            58:     {
        !            59:         sprintf(mensaje, "[CalcularMatrizCaminos] La matriz D indicada no existe");
        !            60:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !            61:     }
        !            62: 
        !            63:     /* necesito un vector y una matriz temporal de 'unsigned char' */
        !            64:     /* para calcular las sucesivas potencias de la matriz D */
        !            65: 
        !            66:     /* hago la reserva de memoria para el vector */
        !            67:     v = calloc(configuracion.ventana , sizeof(unsigned char *));
        !            68:     if (v == NULL)
        !            69:     {
        !            70:         sprintf(mensaje, "[CalcularMatrizCaminos] Memoria insuficiente");
        !            71:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !            72:         /* el programa finaliza si no hay memoria suficiente */
        !            73:     }
        !            74: 
        !            75:     /* hago la reserva de memoria para la matriz */
        !            76:     /* 1º un puntero por cada fila */
        !            77:     tmp = calloc(configuracion.ventana , sizeof(unsigned char *));
        !            78:     if (tmp == NULL)
        !            79:     {
        !            80:         sprintf(mensaje, "[CalcularMatrizCaminos] Memoria insuficiente");
        !            81:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !            82:         /* el programa finaliza si no hay memoria suficiente */
        !            83:     }
        !            84:     /* 2º un 'char' por cada columna */
        !            85:     for(i=0; i<configuracion.ventana; i++)
        !            86:     {
        !            87:         tmp[i] = calloc(configuracion.ventana, sizeof(unsigned char));
        !            88:         if (tmp[i] == NULL)
        !            89:         {
        !            90:             sprintf(mensaje, "[CalcularMatrizCaminos] Memoria insuficiente");
        !            91:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !            92:             /* el programa finaliza si no hay memoria suficiente */
        !            93:         }
        !            94:     }
        !            95: 
        !            96: 
        !            97:     /* inicio la matriz temporal con la matriz 'identidad' (1s en la diagonal) */
        !            98:     /* al reservar con 'calloc' se rellena con 0s */
        !            99: 
        !           100:     for(i=0; i<configuracion.ventana; i++) tmp[i][i] = 1;
        !           101: 
        !           102: 
        !           103:     /* calculo sucesivas potencias de la matriz 'D' hasta que se anule */
        !           104:     /* utilizo la expresión TMP * D = TMP */
        !           105:     /* el uso del vector me permite escribir el resultado sobre 'TMP' */
        !           106:     for(potencia=0; potencia<configuracion.ventana; potencia++)
        !           107:     {
        !           108:         for(i=0; i<configuracion.ventana; i++)
        !           109:         {
        !           110:               for(k=0; k<configuracion.ventana; k++) v[k]=tmp[i][k];
        !           111:             for(j=0; j<configuracion.ventana; j++)
        !           112:             {
        !           113:                 suma = 0;
        !           114:                 for(k=0; k<configuracion.ventana; k++)
        !           115:                 {
        !           116:                     suma += v[k] * D[k][j];
        !           117:                 }
        !           118:                 tmp[i][j] = suma;
        !           119:             }
        !           120:         }
        !           121: 
        !           122:         /* la matriz 'TMP' contiene la n-ésima+1 potencia de 'D' */
        !           123: 
        !           124:         /* ahora evalúo si el resultado es la matriz nula */
        !           125:         /* si es así no tengo que continuar ya que no hay */
        !           126:         /* caminos de dependencias de longitud mayor */
        !           127: 
        !           128:         matriz_nula = SI;
        !           129:         for(i=0; i<configuracion.ventana; i++)
        !           130:         {
        !           131:             for(j=0; j<configuracion.ventana; j++)
        !           132:             {
        !           133:                 if(tmp[i][j] != 0) {matriz_nula = NO; break;}
        !           134:             }
        !           135:             if(matriz_nula == NO) break;
        !           136:         }
        !           137:         if(matriz_nula == SI) break;
        !           138: 
        !           139:         /* sumo la nueva potencia de la matriz de dependencias D^^p */
        !           140:         /* a la matriz de caminos parcial 'C' si me han pasado un puntero no nulo */
        !           141:         if(*C != NULL)
        !           142:         {
        !           143:             for(i=0; i<configuracion.ventana; i++)
        !           144:             {
        !           145:                 for(j=0; j<configuracion.ventana; j++) C[i][j] += tmp[i][j];
        !           146:             }
        !           147:         }
        !           148:     }
        !           149: 
        !           150:     /* libero la memoria reservada anteriormente */
        !           151:     /* libero el vector */
        !           152:     free(v);
        !           153:     /* libero la matriz */
        !           154:     for(i=0; i<configuracion.ventana; i++) free(tmp[i]); free(tmp);
        !           155: 
        !           156:     return potencia+1;    /* devuelve el rango de la primera potencia nula de 'D' */
        !           157: }
        !           158: 
        !           159: 
        !           160: /* esta función establece la lista del orden parcial contenido en D */
        !           161: /* y devuelve el número de pasos de computación del camino crítico */
        !           162: /* si le pasamos un puntero NULO en el parámetro lista sólo realiza el */
        !           163: /* calculo de pasos de computación (método más rápido que el anterior) */
        !           164: /* se asume que la matriz D no ha sido reducida a 0s y 1s */
        !           165: 
        !           166: unsigned int ListaOrdenParcial(unsigned char **D, char **lista)
        !           167: {
        !           168:     char mensaje[MAX_LINE];
        !           169:     unsigned char *lanzadas;    /* vector de instrucciones lanzadas */
        !           170:     unsigned char **tmp;        /* matriz temporal */
        !           171: 
        !           172:     unsigned int pasos, procesadas;
        !           173:     unsigned int i, j;
        !           174:     char cadena[6];        /* cadena para pasar enteros a strings */
        !           175: 
        !           176: 
        !           177:     if(D == NULL)
        !           178:     {
        !           179:         sprintf(mensaje, "[ListaOrdenParcial] La matriz D indicada no existe");
        !           180:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           181:     }
        !           182: 
        !           183:     /* necesito un vector y una matriz temporal de 'unsigned char' */
        !           184:     /* para calcular las sucesivas potencias de la matriz D */
        !           185: 
        !           186:     /* hago la reserva de memoria para el vector */
        !           187:     lanzadas = calloc(configuracion.ventana , sizeof(unsigned char *));
        !           188:     if (lanzadas == NULL)
        !           189:     {
        !           190:         sprintf(mensaje, "[ListaOrdenParcial] Memoria insuficiente");
        !           191:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           192:         /* el programa finaliza si no hay memoria suficiente */
        !           193:     }
        !           194: 
        !           195:     /* hago la reserva de memoria para la matriz */
        !           196:     /* 1º un puntero por cada fila */
        !           197:     tmp = calloc(configuracion.ventana , sizeof(unsigned char *));
        !           198:     if (tmp == NULL)
        !           199:     {
        !           200:         sprintf(mensaje, "[ListaOrdenParcial] Memoria insuficiente");
        !           201:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           202:         /* el programa finaliza si no hay memoria suficiente */
        !           203:     }
        !           204:     /* 2º un 'char' por cada columna */
        !           205:     for(i=0; i<configuracion.ventana; i++)
        !           206:     {
        !           207:         tmp[i] = calloc(configuracion.ventana, sizeof(unsigned char));
        !           208:         if (tmp[i] == NULL)
        !           209:         {
        !           210:             sprintf(mensaje, "[ListaOrdenParcial] Memoria insuficiente");
        !           211:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           212:             /* el programa finaliza si no hay memoria suficiente */
        !           213:         }
        !           214:     }
        !           215: 
        !           216:     /* copio la matriz de dependencias D sobre la temporal */
        !           217:     for(i=0; i<configuracion.ventana; i++)
        !           218:     {
        !           219:         for(j=0; j<configuracion.ventana; j++) tmp[i][j] = D[i][j];
        !           220:     }
        !           221:     
        !           222:     /* pongo a cero el vector de lanzadas */
        !           223:     for(i=0; i<configuracion.ventana; i++) lanzadas[i] = 0;
        !           224: 
        !           225:     /* inicio el contador de pasos de computaci¢n */
        !           226:     pasos = 0;
        !           227: 
        !           228:     /* inicio el contador de instrucciones procesadas */
        !           229:     procesadas = 0;
        !           230: 
        !           231: 
        !           232:     while(configuracion.ventana - procesadas)
        !           233:     {
        !           234:         pasos++;
        !           235: 
        !           236:         /* busco tareas independientes entre las NO lanzadas */
        !           237:         for(i=0; i<configuracion.ventana; i++)
        !           238:         {
        !           239:             if(lanzadas[i]==0)    /* si es 0 significa que no se ha lanzado */
        !           240:             {
        !           241:                    /* miro si el vector de dependencias es nulo */
        !           242:                 for(j=0; j<i; j++)
        !           243:                 {
        !           244:                     if(tmp[i][j]!=0) break;
        !           245:                 }
        !           246:                 if(j==i)
        !           247:                 {
        !           248:                     lanzadas[i]=1; /* la instrucci¢n es independiente */
        !           249: 
        !           250:                     /* anoto la instrucción en la lista del orden parcial */
        !           251:                     /* en el paso de computación en curso */
        !           252:                     if(lista != NULL)
        !           253:                     {
        !           254:                         sprintf(cadena, "%u", i);
        !           255:                         AgregarElementoLista(lista[pasos-1], cadena);
        !           256:                     }
        !           257:                 }
        !           258:             }
        !           259:         }
        !           260: 
        !           261:         /* ahora actualizo la matriz de dependencias con la lista de */
        !           262:         /* instrucciones independientes que han sido lanzadas */
        !           263: 
        !           264:         for(i=0; i<configuracion.ventana; i++)
        !           265:         {
        !           266:             if(lanzadas[i]==1)    /* si es 1 significa que es independiente */
        !           267:             {
        !           268:                 for(j=i+1; j<configuracion.ventana; j++)
        !           269:                 {
        !           270:                     if(tmp[j][i]!=0) tmp[j][i]=0;
        !           271:                 }
        !           272:             }
        !           273:         }
        !           274: 
        !           275:         /* ahora actualizo el vector de lanzadas */
        !           276:         for(i=0; i<configuracion.ventana; i++)
        !           277:         {
        !           278:             if(lanzadas[i]==1)
        !           279:             {
        !           280:                 lanzadas[i]=2; /* significa que ha sido procesada */
        !           281:                    procesadas++;
        !           282:             }
        !           283:         }
        !           284:     }
        !           285: 
        !           286:     /* libero la memoria reservada anteriormente */
        !           287:     /* libero el vector */
        !           288:     free(lanzadas);
        !           289:     /* libero la matriz */
        !           290:     for(i=0; i<configuracion.ventana; i++) free(tmp[i]); free(tmp);
        !           291: 
        !           292:     return pasos;
        !           293: }
        !           294: 
        !           295: 
        !           296: /* esta función determina el 'acoplamiento' de una matriz de dependencias de datos */
        !           297: 
        !           298: unsigned int Acoplamiento(unsigned char **D)
        !           299: {
        !           300:     char mensaje[MAX_LINE];
        !           301:     unsigned int i, j;
        !           302:     unsigned int acoplo = 0;
        !           303: 
        !           304:     if(D == NULL)
        !           305:     {
        !           306:         sprintf(mensaje, "[Acoplamiento] La matriz D indicada no existe");
        !           307:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           308:     }
        !           309: 
        !           310:     /* puesto que las matrices se obtienen de la secuencia de código */
        !           311:     /* estamos seguros de que son canónicas y, por tanto, no es necesario */
        !           312:     /* hacer el recorrido completo de todas sus componentes */
        !           313:     /* basta con empezar en la instrucción 1 y recorres columnas hasta la diagonal */
        !           314:     for(i=1; i<configuracion.ventana; i++)
        !           315:     {
        !           316:         for(j=0; j<i; j++) if(D[i][j] != 0) acoplo++;
        !           317:     }
        !           318: 
        !           319:     return acoplo;
        !           320: }
        !           321: 
        !           322: 
        !           323: 
        !           324: /* esta función reserva memoria para un array de 'num_cadenas' de punteros /*
        !           325: /* a cadenas de caracteres de tamaño fijo 'tamano' y devuelve el puntero */
        !           326: 
        !           327: /* con esta estructura implantaremos la lista de orden parcial */
        !           328: /* trabajando con punteros a char y cadenas de tamaño variable puede */
        !           329: /* ser más eficaz pero es necesario ser más cuidadoso */
        !           330: 
        !           331: char ** CrearArrayStrings(unsigned int num_cadenas, unsigned int tamano)
        !           332: {
        !           333:     char mensaje[MAX_LINE];
        !           334:     unsigned int i;
        !           335:     char **listado;
        !           336: 
        !           337:     /* 1º un puntero por cada fila */
        !           338:     listado = calloc(num_cadenas, sizeof(char *));
        !           339:     if (listado == NULL)
        !           340:     {
        !           341:         sprintf(mensaje, "[CrearArrayStrings] Memoria insuficiente");
        !           342:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           343:         /* el programa finaliza si no hay memoria suficiente */
        !           344:     }
        !           345:     /* 2º cuatro 'char' por cada columna (3 caracteres de número y un separador ':') */
        !           346:     for(i=0; i<configuracion.ventana; i++)
        !           347:     {
        !           348:         listado[i] = calloc(tamano, sizeof(char));
        !           349:         if (listado[i] == NULL)
        !           350:         {
        !           351:             sprintf(mensaje, "[CrearArrayStrings] Memoria insuficiente");
        !           352:             Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           353:             /* el programa finaliza si no hay memoria suficiente */
        !           354:         }
        !           355:     }
        !           356:     return listado;
        !           357: }
        !           358: 
        !           359: 
        !           360: /* reserva memoria para construir un listado de orden parcial: */
        !           361: /* cada línea del listado corresponde a un paso de computación */
        !           362: /* y cada paso de computación contiene una cadena con la lista */
        !           363: /* de instrucciones sin dependencias de datos en ese momento */
        !           364: 
        !           365: void CrearListaOrdenParcial()
        !           366: {
        !           367:     unsigned int dim;
        !           368: 
        !           369:     dim = configuracion.ventana;
        !           370: 
        !           371:     OrdenParcial = CrearArrayStrings(dim, 4*dim);
        !           372: }
        !           373: 
        !           374: 
        !           375: /* inicia el listado de orden parcial rellenando con la cadena vacía '\0' */
        !           376: 
        !           377: void IniciarListaOrdenParcial()
        !           378: {
        !           379:     unsigned int i, dim;
        !           380: 
        !           381:     dim = configuracion.ventana;
        !           382:     
        !           383:     if(OrdenParcial != NULL) for(i=0; i<dim; i++) *OrdenParcial[i] = '\0'; 
        !           384: }
        !           385: 
        !           386: 
        !           387: /* libera la memoria reservada para el listado de orden parcial */
        !           388: 
        !           389: void LiberarMemoriaListaOrdenParcial()
        !           390: {
        !           391:     unsigned int i,dim;
        !           392: 
        !           393:     dim = configuracion.ventana;
        !           394: 
        !           395:     if(OrdenParcial != NULL)
        !           396:     {
        !           397:         for(i=0; i<dim; i++)
        !           398:         {
        !           399:             free(OrdenParcial[i]); 
        !           400:         }
        !           401:         free(OrdenParcial);
        !           402:     }
        !           403: }
        !           404: 
        !           405: 
        !           406: /* crea la matriz de caminos de dependencias */
        !           407: 
        !           408: void CrearMatrizCaminos()
        !           409: {
        !           410:     matrizC = CrearMatriz();
        !           411: }
        !           412: 
        !           413: 
        !           414: /* inicia la matriz de caminos de dependencias */
        !           415: 
        !           416: void IniciarMatrizCaminos()
        !           417: {
        !           418:     IniciarMatriz(matrizC);
        !           419: }
        !           420: 
        !           421: 
        !           422: /* libera la memoria de la matriz de caminos */
        !           423: 
        !           424: void LiberarMemoriaMatrizCaminos()
        !           425: {
        !           426:     LiberarMemoriaMatriz(matrizC);
        !           427: }
        !           428: 
        !           429: 
        !           430: /* reserva espacio en memoria para una variable agregada */
        !           431: 
        !           432: parametromatriz * CrearVariableAgregada()
        !           433: {
        !           434:     char mensaje[MAX_LINE];
        !           435:     parametromatriz *variable;
        !           436:     
        !           437:     variable = calloc(1, sizeof(parametromatriz));
        !           438:     if (variable == NULL)
        !           439:     {
        !           440:         sprintf(mensaje, "[CrearVariableAgragada] Memoria insuficiente");
        !           441:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           442:         /* el programa finaliza si no hay memoria suficiente */
        !           443:     }
        !           444: 
        !           445:     return variable;
        !           446: }
        !           447: 
        !           448: 
        !           449: /* inicia a 0 una variable agregada */
        !           450: 
        !           451: void IniciarVariableAgregada(parametromatriz *variable)
        !           452: {
        !           453:     variable->Ddatoexp = 0.0;
        !           454:     variable->Ddir_exp = 0.0;
        !           455:     variable->Dpilaexp = 0.0; 
        !           456:     variable->Destadoexp = 0.0; 
        !           457:         
        !           458:     variable->Ddatoimp = 0.0; 
        !           459:     variable->Ddir_imp = 0.0; 
        !           460:     variable->Dpilaimp = 0.0; 
        !           461:     variable->Destadoimp = 0.0; 
        !           462: 
        !           463:     variable->ADdatoexp = 0.0; 
        !           464:     variable->ADdir_exp = 0.0; 
        !           465:     variable->ADpilaexp = 0.0; 
        !           466:     variable->ADestadoexp = 0.0; 
        !           467:         
        !           468:     variable->ADdatoimp = 0.0; 
        !           469:     variable->ADdir_imp = 0.0; 
        !           470:     variable->ADpilaimp = 0.0; 
        !           471:     variable->ADestadoimp = 0.0; 
        !           472: 
        !           473:     variable->Sdatoexp = 0.0; 
        !           474:     variable->Sdir_exp = 0.0; 
        !           475:     variable->Spilaexp = 0.0; 
        !           476:     variable->Sestadoexp = 0.0; 
        !           477:         
        !           478:     variable->Sdatoimp = 0.0; 
        !           479:     variable->Sdir_imp = 0.0; 
        !           480:     variable->Spilaimp = 0.0; 
        !           481:     variable->Sestadoimp = 0.0; 
        !           482: 
        !           483:     variable->D = 0.0; 
        !           484: }
        !           485: 
        !           486: 
        !           487: 
        !           488: /* esta función calcula el nuevo promedio de una variable agregada (media) a partir del */
        !           489: /* índice (n) y del valor actual o en curso de esa variable (actual) */
        !           490: 
        !           491: /*
        !           492: void CalcularPromedioVariableAgregada(parametromatriz *media, parametromatriz *actual, unsigned long n)
        !           493: {
        !           494:     if(matriz.Ddatoexp != NULL) media->Ddatoexp = ((n - 1) * media->Ddatoexp + actual->Ddatoexp) / n;
        !           495:     if(matriz.Ddir_exp != NULL) media->Ddir_exp = ((n - 1) * media->Ddir_exp + actual->Ddir_exp) / n;
        !           496:     if(matriz.Dpilaexp != NULL) media->Dpilaexp = ((n - 1) * media->Dpilaexp + actual->Dpilaexp) / n; 
        !           497:     if(matriz.Destadoexp != NULL) media->Destadoexp = ((n - 1) * media->Destadoexp + actual->Destadoexp) / n; 
        !           498:         
        !           499:     if(matriz.Ddatoimp != NULL) media->Ddatoimp = ((n - 1) * media->Ddatoimp + actual->Ddatoimp) / n; 
        !           500:     if(matriz.Ddir_imp != NULL) media->Ddir_imp = ((n - 1) * media->Ddir_imp + actual->Ddir_imp) / n; 
        !           501:     if(matriz.Dpilaimp != NULL) media->Dpilaimp = ((n - 1) * media->Dpilaimp + actual->Dpilaimp) / n; 
        !           502:     if(matriz.Destadoimp != NULL) media->Destadoimp = ((n - 1) * media->Destadoimp + actual->Destadoimp) / n; 
        !           503: 
        !           504:     if(matriz.ADdatoexp != NULL) media->ADdatoexp = ((n - 1) * media->ADdatoexp + actual->ADdatoexp) / n; 
        !           505:     if(matriz.ADdir_exp != NULL) media->ADdir_exp = ((n - 1) * media->ADdir_exp + actual->ADdir_exp) / n; 
        !           506:     if(matriz.ADpilaexp != NULL) media->ADpilaexp = ((n - 1) * media->ADpilaexp + actual->ADpilaexp) / n; 
        !           507:     if(matriz.ADestadoexp != NULL) media->ADestadoexp = ((n - 1) * media->ADestadoexp + actual->ADestadoexp) / n; 
        !           508:         
        !           509:     if(matriz.ADdatoimp != NULL) media->ADdatoimp = ((n - 1) * media->ADdatoimp + actual->ADdatoimp) / n; 
        !           510:     if(matriz.ADdir_imp != NULL) media->ADdir_imp = ((n - 1) * media->ADdir_imp + actual->ADdir_imp) / n; 
        !           511:     if(matriz.ADpilaimp != NULL) media->ADpilaimp = ((n - 1) * media->ADpilaimp + actual->ADpilaimp) / n; 
        !           512:     if(matriz.ADestadoimp != NULL) media->ADestadoimp = ((n - 1) * media->ADestadoimp + actual->ADestadoimp) / n; 
        !           513: 
        !           514:     if(matriz.Sdatoexp != NULL) media->Sdatoexp = ((n - 1) * media->Sdatoexp + actual->Sdatoexp) / n; 
        !           515:     if(matriz.Sdir_exp != NULL) media->Sdir_exp = ((n - 1) * media->Sdir_exp + actual->Sdir_exp) / n; 
        !           516:     if(matriz.Spilaexp != NULL) media->Spilaexp = ((n - 1) * media->Spilaexp + actual->Spilaexp) / n; 
        !           517:     if(matriz.Sestadoexp != NULL) media->Sestadoexp = ((n - 1) * media->Sestadoexp + actual->Sestadoexp) / n; 
        !           518:         
        !           519:     if(matriz.Sdatoimp != NULL) media->Sdatoimp = ((n - 1) * media->Sdatoimp + actual->Sdatoimp) / n; 
        !           520:     if(matriz.Sdir_imp != NULL) media->Sdir_imp = ((n - 1) * media->Sdir_imp + actual->Sdir_imp) / n; 
        !           521:     if(matriz.Spilaimp != NULL) media->Spilaimp = ((n - 1) * media->Spilaimp + actual->Spilaimp) / n; 
        !           522:     if(matriz.Sestadoimp != NULL) media->Sestadoimp = ((n - 1) * media->Sestadoimp + actual->Sestadoimp) / n; 
        !           523: 
        !           524:     if(matriz.D != NULL) media->D = ((n - 1) * media->D + actual->D) / n; 
        !           525: }
        !           526: */
        !           527: 
        !           528: 
        !           529: /* utilizando la función: */
        !           530: /* double CalcularNuevoPromedio (double promedioanterior, double valoractual, unsigned long n)
        !           531: /* es más compacto aunque quizá algo más lento */
        !           532: 
        !           533: void CalcularPromedioVariableAgregada(parametromatriz *media, parametromatriz *actual, unsigned long n)
        !           534: {
        !           535:     if(matriz.Ddatoexp != NULL) media->Ddatoexp = CalcularNuevoPromedio(media->Ddatoexp, actual->Ddatoexp, n);
        !           536:     if(matriz.Ddir_exp != NULL) media->Ddir_exp = CalcularNuevoPromedio(media->Ddir_exp, actual->Ddir_exp, n);
        !           537:     if(matriz.Dpilaexp != NULL) media->Dpilaexp = CalcularNuevoPromedio(media->Dpilaexp, actual->Dpilaexp, n); 
        !           538:     if(matriz.Destadoexp != NULL) media->Destadoexp = CalcularNuevoPromedio(media->Destadoexp, actual->Destadoexp, n); 
        !           539:         
        !           540:     if(matriz.Ddatoimp != NULL) media->Ddatoimp = CalcularNuevoPromedio(media->Ddatoimp, actual->Ddatoimp, n); 
        !           541:     if(matriz.Ddir_imp != NULL) media->Ddir_imp = CalcularNuevoPromedio(media->Ddir_imp, actual->Ddir_imp, n); 
        !           542:     if(matriz.Dpilaimp != NULL) media->Dpilaimp = CalcularNuevoPromedio(media->Dpilaimp, actual->Dpilaimp, n); 
        !           543:     if(matriz.Destadoimp != NULL) media->Destadoimp = CalcularNuevoPromedio(media->Destadoimp, actual->Destadoimp, n); 
        !           544: 
        !           545:     if(matriz.ADdatoexp != NULL) media->ADdatoexp = CalcularNuevoPromedio(media->ADdatoexp, actual->ADdatoexp, n); 
        !           546:     if(matriz.ADdir_exp != NULL) media->ADdir_exp = CalcularNuevoPromedio(media->ADdir_exp, actual->ADdir_exp, n); 
        !           547:     if(matriz.ADpilaexp != NULL) media->ADpilaexp = CalcularNuevoPromedio(media->ADpilaexp, actual->ADpilaexp, n); 
        !           548:     if(matriz.ADestadoexp != NULL) media->ADestadoexp = CalcularNuevoPromedio(media->ADestadoexp, actual->ADestadoexp, n); 
        !           549:         
        !           550:     if(matriz.ADdatoimp != NULL) media->ADdatoimp = CalcularNuevoPromedio(media->ADdatoimp, actual->ADdatoimp, n); 
        !           551:     if(matriz.ADdir_imp != NULL) media->ADdir_imp = CalcularNuevoPromedio(media->ADdir_imp, actual->ADdir_imp, n); 
        !           552:     if(matriz.ADpilaimp != NULL) media->ADpilaimp = CalcularNuevoPromedio(media->ADpilaimp, actual->ADpilaimp, n); 
        !           553:     if(matriz.ADestadoimp != NULL) media->ADestadoimp = CalcularNuevoPromedio(media->ADestadoimp, actual->ADestadoimp, n); 
        !           554: 
        !           555:     if(matriz.Sdatoexp != NULL) media->Sdatoexp = CalcularNuevoPromedio(media->Sdatoexp, actual->Sdatoexp, n); 
        !           556:     if(matriz.Sdir_exp != NULL) media->Sdir_exp = CalcularNuevoPromedio(media->Sdir_exp, actual->Sdir_exp, n); 
        !           557:     if(matriz.Spilaexp != NULL) media->Spilaexp = CalcularNuevoPromedio(media->Spilaexp, actual->Spilaexp, n); 
        !           558:     if(matriz.Sestadoexp != NULL) media->Sestadoexp = CalcularNuevoPromedio(media->Sestadoexp, actual->Sestadoexp, n); 
        !           559:         
        !           560:     if(matriz.Sdatoimp != NULL) media->Sdatoimp = CalcularNuevoPromedio(media->Sdatoimp, actual->Sdatoimp, n); 
        !           561:     if(matriz.Sdir_imp != NULL) media->Sdir_imp = CalcularNuevoPromedio(media->Sdir_imp, actual->Sdir_imp, n); 
        !           562:     if(matriz.Spilaimp != NULL) media->Spilaimp = CalcularNuevoPromedio(media->Spilaimp, actual->Spilaimp, n); 
        !           563:     if(matriz.Sestadoimp != NULL) media->Sestadoimp = CalcularNuevoPromedio(media->Sestadoimp, actual->Sestadoimp, n); 
        !           564: 
        !           565:     if(matriz.D != NULL) media->D = CalcularNuevoPromedio(media->D, actual->D, n); 
        !           566: }
        !           567: 
        !           568: 
        !           569: /* esta función calcula los pasos de computación de cada matriz de dependencias */
        !           570: 
        !           571: /* para calcular los pasos de computación se usa el método más rápido, es decir, */
        !           572: /* construir la lista de orden parcial... aunque no se anote ya que pasamos un puntero nulo */
        !           573: 
        !           574: void CalcularPasosComputacion(parametromatriz *pasos)
        !           575: {
        !           576:     if(matriz.Ddatoexp != NULL) pasos->Ddatoexp = ListaOrdenParcial(matriz.Ddatoexp, NULL);
        !           577:     if(matriz.Ddir_exp != NULL) pasos->Ddir_exp = ListaOrdenParcial(matriz.Ddir_exp, NULL);
        !           578:     if(matriz.Dpilaexp != NULL) pasos->Dpilaexp = ListaOrdenParcial(matriz.Dpilaexp, NULL); 
        !           579:     if(matriz.Destadoexp != NULL) pasos->Destadoexp = ListaOrdenParcial(matriz.Destadoexp, NULL); 
        !           580:         
        !           581:     if(matriz.Ddatoimp != NULL) pasos->Ddatoimp = ListaOrdenParcial(matriz.Ddatoimp, NULL); 
        !           582:     if(matriz.Ddir_imp != NULL) pasos->Ddir_imp = ListaOrdenParcial(matriz.Ddir_imp, NULL); 
        !           583:     if(matriz.Dpilaimp != NULL) pasos->Dpilaimp = ListaOrdenParcial(matriz.Dpilaimp, NULL); 
        !           584:     if(matriz.Destadoimp != NULL) pasos->Destadoimp = ListaOrdenParcial(matriz.Destadoimp, NULL); 
        !           585: 
        !           586:     if(matriz.ADdatoexp != NULL) pasos->ADdatoexp = ListaOrdenParcial(matriz.ADdatoexp, NULL); 
        !           587:     if(matriz.ADdir_exp != NULL) pasos->ADdir_exp = ListaOrdenParcial(matriz.ADdir_exp, NULL); 
        !           588:     if(matriz.ADpilaexp != NULL) pasos->ADpilaexp = ListaOrdenParcial(matriz.ADpilaexp, NULL); 
        !           589:     if(matriz.ADestadoexp != NULL) pasos->ADestadoexp = ListaOrdenParcial(matriz.ADestadoexp, NULL); 
        !           590:         
        !           591:     if(matriz.ADdatoimp != NULL) pasos->ADdatoimp = ListaOrdenParcial(matriz.ADdatoimp, NULL); 
        !           592:     if(matriz.ADdir_imp != NULL) pasos->ADdir_imp = ListaOrdenParcial(matriz.ADdir_imp, NULL); 
        !           593:     if(matriz.ADpilaimp != NULL) pasos->ADpilaimp = ListaOrdenParcial(matriz.ADpilaimp, NULL); 
        !           594:     if(matriz.ADestadoimp != NULL) pasos->ADestadoimp = ListaOrdenParcial(matriz.ADestadoimp, NULL); 
        !           595: 
        !           596:     if(matriz.Sdatoexp != NULL) pasos->Sdatoexp = ListaOrdenParcial(matriz.Sdatoexp, NULL); 
        !           597:     if(matriz.Sdir_exp != NULL) pasos->Sdir_exp = ListaOrdenParcial(matriz.Sdir_exp, NULL); 
        !           598:     if(matriz.Spilaexp != NULL) pasos->Spilaexp = ListaOrdenParcial(matriz.Spilaexp, NULL); 
        !           599:     if(matriz.Sestadoexp != NULL) pasos->Sestadoexp = ListaOrdenParcial(matriz.Sestadoexp, NULL); 
        !           600:         
        !           601:     if(matriz.Sdatoimp != NULL) pasos->Sdatoimp = ListaOrdenParcial(matriz.Sdatoimp, NULL); 
        !           602:     if(matriz.Sdir_imp != NULL) pasos->Sdir_imp = ListaOrdenParcial(matriz.Sdir_imp, NULL); 
        !           603:     if(matriz.Spilaimp != NULL) pasos->Spilaimp = ListaOrdenParcial(matriz.Spilaimp, NULL); 
        !           604:     if(matriz.Sestadoimp != NULL) pasos->Sestadoimp = ListaOrdenParcial(matriz.Sestadoimp, NULL); 
        !           605: 
        !           606:     if(matriz.D != NULL) pasos->D = ListaOrdenParcial(matriz.D, NULL); 
        !           607: }
        !           608: 
        !           609: 
        !           610: 
        !           611: /* esta función calcula el grado de paralelismo a partir de los pasos de computación */
        !           612: /* ver si es necesario prevenir la división por 0 */
        !           613: 
        !           614: /*
        !           615: void CalcularGradoParalelismo(parametromatriz *pasos, parametromatriz *grado)
        !           616: {
        !           617:     if(matriz.Ddatoexp != NULL) grado->Ddatoexp = 1 / pasos->Ddatoexp;
        !           618:     if(matriz.Ddir_exp != NULL) grado->Ddir_exp = 1 / pasos->Ddir_exp;
        !           619:     if(matriz.Dpilaexp != NULL) grado->Dpilaexp = 1 / pasos->Dpilaexp; 
        !           620:     if(matriz.Destadoexp != NULL) grado->Destadoexp = 1 / pasos->Destadoexp; 
        !           621:         
        !           622:     if(matriz.Ddatoimp != NULL) grado->Ddatoimp = 1 / pasos->Ddatoimp; 
        !           623:     if(matriz.Ddir_imp != NULL) grado->Ddir_imp = 1 / pasos->Ddir_imp; 
        !           624:     if(matriz.Dpilaimp != NULL) grado->Dpilaimp = 1 / pasos->Dpilaimp; 
        !           625:     if(matriz.Destadoimp != NULL) grado->Destadoimp = 1 / pasos->Destadoimp; 
        !           626: 
        !           627:     if(matriz.ADdatoexp != NULL) grado->ADdatoexp = 1 / pasos->ADdatoexp; 
        !           628:     if(matriz.ADdir_exp != NULL) grado->ADdir_exp = 1 / pasos->ADdir_exp; 
        !           629:     if(matriz.ADpilaexp != NULL) grado->ADpilaexp = 1 / pasos->ADpilaexp; 
        !           630:     if(matriz.ADestadoexp != NULL) grado->ADestadoexp = 1 / pasos->ADestadoexp; 
        !           631:         
        !           632:     if(matriz.ADdatoimp != NULL) grado->ADdatoimp = 1 / pasos->ADdatoimp; 
        !           633:     if(matriz.ADdir_imp != NULL) grado->ADdir_imp = 1 / pasos->ADdir_imp; 
        !           634:     if(matriz.ADpilaimp != NULL) grado->ADpilaimp = 1 / pasos->ADpilaimp; 
        !           635:     if(matriz.ADestadoimp != NULL) grado->ADestadoimp = 1 / pasos->ADestadoimp; 
        !           636: 
        !           637:     if(matriz.Sdatoexp != NULL) grado->Sdatoexp = 1 / pasos->Sdatoexp; 
        !           638:     if(matriz.Sdir_exp != NULL) grado->Sdir_exp = 1 / pasos->Sdir_exp; 
        !           639:     if(matriz.Spilaexp != NULL) grado->Spilaexp = 1 / pasos->Spilaexp; 
        !           640:     if(matriz.Sestadoexp != NULL) grado->Sestadoexp = 1 / pasos->Sestadoexp; 
        !           641:         
        !           642:     if(matriz.Sdatoimp != NULL) grado->Sdatoimp = 1 / pasos->Sdatoimp; 
        !           643:     if(matriz.Sdir_imp != NULL) grado->Sdir_imp = 1 / pasos->Sdir_imp; 
        !           644:     if(matriz.Spilaimp != NULL) grado->Spilaimp = 1 / pasos->Spilaimp; 
        !           645:     if(matriz.Sestadoimp != NULL) grado->Sestadoimp = 1 / pasos->Sestadoimp; 
        !           646: 
        !           647:     if(matriz.D != NULL) grado->D = 1 / pasos->D; 
        !           648: }
        !           649: 
        !           650: */
        !           651: 
        !           652: 
        !           653: 
        !           654: /* esta función calcula el grado de paralelismo NORMALIZADO a partir de */
        !           655: /* la dimensión de la ventana de instrucciones y de los pasos de computación */
        !           656: 
        !           657: void CalcularGradoParalelismoNormalizado(parametromatriz *pasos, parametromatriz *grado)
        !           658: {
        !           659:     unsigned int dim;
        !           660: 
        !           661:     dim = configuracion.ventana;
        !           662:     
        !           663:     if(matriz.Ddatoexp != NULL) grado->Ddatoexp = InversoNormalizado(dim, pasos->Ddatoexp);
        !           664:     if(matriz.Ddir_exp != NULL) grado->Ddir_exp = InversoNormalizado(dim, pasos->Ddir_exp);
        !           665:     if(matriz.Dpilaexp != NULL) grado->Dpilaexp = InversoNormalizado(dim, pasos->Dpilaexp); 
        !           666:     if(matriz.Destadoexp != NULL) grado->Destadoexp = InversoNormalizado(dim, pasos->Destadoexp); 
        !           667:         
        !           668:     if(matriz.Ddatoimp != NULL) grado->Ddatoimp = InversoNormalizado(dim, pasos->Ddatoimp); 
        !           669:     if(matriz.Ddir_imp != NULL) grado->Ddir_imp = InversoNormalizado(dim, pasos->Ddir_imp); 
        !           670:     if(matriz.Dpilaimp != NULL) grado->Dpilaimp = InversoNormalizado(dim, pasos->Dpilaimp); 
        !           671:     if(matriz.Destadoimp != NULL) grado->Destadoimp = InversoNormalizado(dim, pasos->Destadoimp); 
        !           672: 
        !           673:     if(matriz.ADdatoexp != NULL) grado->ADdatoexp = InversoNormalizado(dim, pasos->ADdatoexp); 
        !           674:     if(matriz.ADdir_exp != NULL) grado->ADdir_exp = InversoNormalizado(dim, pasos->ADdir_exp); 
        !           675:     if(matriz.ADpilaexp != NULL) grado->ADpilaexp = InversoNormalizado(dim, pasos->ADpilaexp); 
        !           676:     if(matriz.ADestadoexp != NULL) grado->ADestadoexp = InversoNormalizado(dim, pasos->ADestadoexp); 
        !           677:         
        !           678:     if(matriz.ADdatoimp != NULL) grado->ADdatoimp = InversoNormalizado(dim, pasos->ADdatoimp); 
        !           679:     if(matriz.ADdir_imp != NULL) grado->ADdir_imp = InversoNormalizado(dim, pasos->ADdir_imp); 
        !           680:     if(matriz.ADpilaimp != NULL) grado->ADpilaimp = InversoNormalizado(dim, pasos->ADpilaimp); 
        !           681:     if(matriz.ADestadoimp != NULL) grado->ADestadoimp = InversoNormalizado(dim, pasos->ADestadoimp); 
        !           682: 
        !           683:     if(matriz.Sdatoexp != NULL) grado->Sdatoexp = InversoNormalizado(dim, pasos->Sdatoexp); 
        !           684:     if(matriz.Sdir_exp != NULL) grado->Sdir_exp = InversoNormalizado(dim, pasos->Sdir_exp); 
        !           685:     if(matriz.Spilaexp != NULL) grado->Spilaexp = InversoNormalizado(dim, pasos->Spilaexp); 
        !           686:     if(matriz.Sestadoexp != NULL) grado->Sestadoexp = InversoNormalizado(dim, pasos->Sestadoexp); 
        !           687:         
        !           688:     if(matriz.Sdatoimp != NULL) grado->Sdatoimp = InversoNormalizado(dim, pasos->Sdatoimp); 
        !           689:     if(matriz.Sdir_imp != NULL) grado->Sdir_imp = InversoNormalizado(dim, pasos->Sdir_imp); 
        !           690:     if(matriz.Spilaimp != NULL) grado->Spilaimp = InversoNormalizado(dim, pasos->Spilaimp); 
        !           691:     if(matriz.Sestadoimp != NULL) grado->Sestadoimp = InversoNormalizado(dim, pasos->Sestadoimp); 
        !           692: 
        !           693:     if(matriz.D != NULL) grado->D = InversoNormalizado(dim, pasos->D); 
        !           694: }
        !           695: 
        !           696: 
        !           697: /* esta función calcula el acoplamiento de cada matriz de dependencias */
        !           698: 
        !           699: void CalcularAcoplamiento(parametromatriz *acoplamiento)
        !           700: {
        !           701:     if(matriz.Ddatoexp != NULL) acoplamiento->Ddatoexp = Acoplamiento(matriz.Ddatoexp);
        !           702:     if(matriz.Ddir_exp != NULL) acoplamiento->Ddir_exp = Acoplamiento(matriz.Ddir_exp);
        !           703:     if(matriz.Dpilaexp != NULL) acoplamiento->Dpilaexp = Acoplamiento(matriz.Dpilaexp); 
        !           704:     if(matriz.Destadoexp != NULL) acoplamiento->Destadoexp = Acoplamiento(matriz.Destadoexp); 
        !           705:         
        !           706:     if(matriz.Ddatoimp != NULL) acoplamiento->Ddatoimp = Acoplamiento(matriz.Ddatoimp); 
        !           707:     if(matriz.Ddir_imp != NULL) acoplamiento->Ddir_imp = Acoplamiento(matriz.Ddir_imp); 
        !           708:     if(matriz.Dpilaimp != NULL) acoplamiento->Dpilaimp = Acoplamiento(matriz.Dpilaimp); 
        !           709:     if(matriz.Destadoimp != NULL) acoplamiento->Destadoimp = Acoplamiento(matriz.Destadoimp); 
        !           710: 
        !           711:     if(matriz.ADdatoexp != NULL) acoplamiento->ADdatoexp = Acoplamiento(matriz.ADdatoexp); 
        !           712:     if(matriz.ADdir_exp != NULL) acoplamiento->ADdir_exp = Acoplamiento(matriz.ADdir_exp); 
        !           713:     if(matriz.ADpilaexp != NULL) acoplamiento->ADpilaexp = Acoplamiento(matriz.ADpilaexp); 
        !           714:     if(matriz.ADestadoexp != NULL) acoplamiento->ADestadoexp = Acoplamiento(matriz.ADestadoexp); 
        !           715:         
        !           716:     if(matriz.ADdatoimp != NULL) acoplamiento->ADdatoimp = Acoplamiento(matriz.ADdatoimp); 
        !           717:     if(matriz.ADdir_imp != NULL) acoplamiento->ADdir_imp = Acoplamiento(matriz.ADdir_imp); 
        !           718:     if(matriz.ADpilaimp != NULL) acoplamiento->ADpilaimp = Acoplamiento(matriz.ADpilaimp); 
        !           719:     if(matriz.ADestadoimp != NULL) acoplamiento->ADestadoimp = Acoplamiento(matriz.ADestadoimp); 
        !           720: 
        !           721:     if(matriz.Sdatoexp != NULL) acoplamiento->Sdatoexp = Acoplamiento(matriz.Sdatoexp); 
        !           722:     if(matriz.Sdir_exp != NULL) acoplamiento->Sdir_exp = Acoplamiento(matriz.Sdir_exp); 
        !           723:     if(matriz.Spilaexp != NULL) acoplamiento->Spilaexp = Acoplamiento(matriz.Spilaexp); 
        !           724:     if(matriz.Sestadoexp != NULL) acoplamiento->Sestadoexp = Acoplamiento(matriz.Sestadoexp); 
        !           725:         
        !           726:     if(matriz.Sdatoimp != NULL) acoplamiento->Sdatoimp = Acoplamiento(matriz.Sdatoimp); 
        !           727:     if(matriz.Sdir_imp != NULL) acoplamiento->Sdir_imp = Acoplamiento(matriz.Sdir_imp); 
        !           728:     if(matriz.Spilaimp != NULL) acoplamiento->Spilaimp = Acoplamiento(matriz.Spilaimp); 
        !           729:     if(matriz.Sestadoimp != NULL) acoplamiento->Sestadoimp = Acoplamiento(matriz.Sestadoimp); 
        !           730: 
        !           731:     if(matriz.D != NULL) acoplamiento->D = (double) Acoplamiento(matriz.D); 
        !           732: }
        !           733: 
        !           734: 
        !           735: 
        !           736: /* esta función reserva memoria para salvar el histograma de pasos de computación */
        !           737: /* asociado a la matriz de dependencias de datos D (no el resto) */
        !           738: 
        !           739: void CrearHistogramaPasos()
        !           740: {
        !           741:     char mensaje[MAX_LINE];
        !           742: 
        !           743:     distribucionpasos = calloc(configuracion.ventana+1, sizeof(unsigned long));
        !           744:     if (distribucionpasos == NULL)
        !           745:     {
        !           746:         sprintf(mensaje, "[CrearHistogramaPasos] Memoria insuficiente");
        !           747:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
        !           748:         /* el programa finaliza si no hay memoria suficiente */
        !           749:     }
        !           750: }
        !           751: 
        !           752: 
        !           753: /* inicia el histograma a 0 (con la reserva de calloc no es necesario) */
        !           754: 
        !           755: void IniciarHistogramaPasos()
        !           756: {
        !           757:     unsigned int i;
        !           758: 
        !           759:     for(i=0; i<configuracion.ventana; i++) distribucionpasos[i] = 0;
        !           760: }
        !           761: 
        !           762: 
        !           763: /* libera la memoria reservada para el histograma */
        !           764: 
        !           765: void LiberarMemoriaHistogramaPasos()
        !           766: {
        !           767:     free(distribucionpasos);
        !           768: }
        !           769: 
        !           770: 
        !           771: /* actualiza los datos del histograma */
        !           772: 
        !           773: void ActualizarHistogramaPasos()
        !           774: {
        !           775:     distribucionpasos[(unsigned int)pasos->D]++;
        !           776: }
        !           777: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>