VIS
|
00001 00036 #include "imgInt.h" 00037 #include "fsm.h" 00038 00039 static char rcsid[] UNUSED = "$Id: imgMlp.c,v 1.31 2005/04/26 19:08:33 jinh Exp $"; 00040 00041 00042 /*---------------------------------------------------------------------------*/ 00043 /* Constant declarations */ 00044 /*---------------------------------------------------------------------------*/ 00045 00046 /*---------------------------------------------------------------------------*/ 00047 /* Type declarations */ 00048 /*---------------------------------------------------------------------------*/ 00049 00050 00051 /*---------------------------------------------------------------------------*/ 00052 /* Structure declarations */ 00053 /*---------------------------------------------------------------------------*/ 00054 00063 typedef struct RcInfo_s { 00064 int pos; /* level */ 00065 int lNum; 00066 int lMin; /* index */ 00067 int lMax; /* index */ 00068 int gNum; 00069 int gMin; /* index */ 00070 int gMax; /* index */ 00071 int prevG; /* level */ 00072 int nextG; /* level */ 00073 union { 00074 struct { 00075 bdd_t *func; 00076 array_t *nsVarBddArray; 00077 } row; 00078 struct { 00079 bdd_t *var; 00080 int type; 00081 } col; 00082 } data; 00083 } RcInfo_t; 00084 00092 typedef struct RcList_s { 00093 int index; 00094 int otherIndex; 00095 struct RcList_s *next; 00096 struct RcList_s *prev; 00097 } RcList_t; 00098 00107 typedef struct RcListInfo_s { 00108 int num; 00109 int maxNum; 00110 int curIndex; 00111 st_table *table; 00112 RcList_t *cur; 00113 RcList_t *head; 00114 RcList_t *tail; 00115 } RcListInfo_t; 00116 00124 typedef struct ClusterList_s { 00125 int flag; /* 0 : to be conjuncted 00126 1 : start element 00127 2 : last element 00128 3 : isolated 00129 */ 00130 int start; 00131 int end; 00132 char *supports; 00133 int minCol; /* index */ 00134 int maxCol; /* index */ 00135 int nSupports; 00136 float affinity; 00137 int nQuantifyVars; 00138 mdd_t *product; 00139 array_t *nsVarBddArray; 00140 struct ClusterList_s *prev; 00141 struct ClusterList_s *next; 00142 } ClusterList_t; 00143 00151 typedef struct ClusterSortedList_s { 00152 ClusterList_t *list; 00153 struct ClusterSortedList_s *next; 00154 } ClusterSortedList_t; 00155 00164 typedef struct SccList_s { 00165 int startFunc; 00166 int lastFunc; 00167 int startVar; 00168 int lastVar; 00169 int nFuncs; 00170 int nVars; 00171 struct SccList_s *next; 00172 } SccList_t; 00173 00182 typedef struct LatchList_s { 00183 int number; 00184 int bddId; 00185 mdd_t *relation; 00186 st_table *table; 00187 } LatchList_t; 00188 00189 00190 /*---------------------------------------------------------------------------*/ 00191 /* Variable declarations */ 00192 /*---------------------------------------------------------------------------*/ 00193 00194 static int nMoves; 00195 00196 00197 /*---------------------------------------------------------------------------*/ 00198 /* Macro declarations */ 00199 /*---------------------------------------------------------------------------*/ 00200 00201 00204 /*---------------------------------------------------------------------------*/ 00205 /* Static function prototypes */ 00206 /*---------------------------------------------------------------------------*/ 00207 00208 static void SetupMlp(mdd_manager *mddManager, char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *varPos, array_t *nsVarBddArray, int *nActiveRows, int *nActiveCols, array_t *nonAppearingVarBddArray, Img_DirectionType direction, ImgTrmOption_t *option); 00209 static SccList_t * MlpDecomposeScc(mdd_manager *mddManager, char **xy, int nRows, int nActiveRows, int nActiveCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, int clusteredFlag, ImgTrmOption_t *option); 00210 static int SccSortListIncreasingWithVars(const void *p1, const void *p2); 00211 static int SccSortListDecreasingWithVars(const void *p1, const void *p2); 00212 static int SccSortListIncreasingWithArea(const void *p1, const void *p2); 00213 static int SccSortListDecreasingWithArea(const void *p1, const void *p2); 00214 static int SccSortListIncreasingWithRatio(const void *p1, const void *p2); 00215 static int SccSortListDecreasingWithRatio(const void *p1, const void *p2); 00216 static int SccSortRc(const void *p1, const void *p2); 00217 static void FreeSccList(SccList_t *sccHeadList); 00218 static int NumOfSccs(SccList_t *sccHeadList); 00219 static void BlockLowerTriangle(char **xy, int nRows, int nCols, int nActiveRows, int nActiveCols, SccList_t *sccList, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, ImgTrmOption_t *option); 00220 static void MoveBestRows(char **xy, SccList_t *sccList, int nRows, int nCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, int startFunc, int lastFunc, int startVar, int lastVar, ImgTrmOption_t *option); 00221 static void MoveBestCols(char **xy, SccList_t *sccList, int nRows, int nCols, int nActiveRows, int nActiveCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, int startFunc, int lastFunc, int startVar, int lastVar, ImgTrmOption_t *option); 00222 static void MlpPostProcess(char **xy, SccList_t *sccList, int nVars, int nRows, int nCols, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, Img_DirectionType direction, ImgTrmOption_t *option); 00223 static float ComputeLambdaMlp(char **xy, int nVars, int nRows, int nCols, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, Img_DirectionType direction, int mode, int asIs, ImgTrmOption_t *option); 00224 static void FindAndMoveSingletonRows(char **xy, SccList_t *sccList, int nRows, int nCols, int *startFunc, int *lastFunc, int *startVar, int *lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, ImgTrmOption_t *option); 00225 static int MoveSingletonRow(char **xy, SccList_t *sccList, int nRows, int nCols, int x, int *startFunc, int *lastFunc, int *startVar, int *lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, RcListInfo_t *candList, ImgTrmOption_t *option); 00226 static void FindAndMoveSingletonCols(char **xy, SccList_t *sccList, int nRows, int nCols, int *startFunc, int *lastFunc, int *startVar, int *lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, ImgTrmOption_t *option); 00227 static int MoveSingletonCol(char **xy, SccList_t *sccList, int nRows, int nCols, int y, int *startFunc, int *lastFunc, int *startVar, int *lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, RcListInfo_t *candList, ImgTrmOption_t *option); 00228 static void MoveRowToTop(char **xy, int x, int startFunc, int lastFunc, int startVar, int lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, RcListInfo_t *candList, int method); 00229 static void MoveColToLeft(char **xy, int y, int startFunc, int lastFunc, int startVar, int lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, RcListInfo_t *candList, int method); 00230 static void MoveRowToBottom(char **xy, int x, int startFunc, int lastFunc, int startVar, int lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, RcListInfo_t *candList, int method); 00231 static void MoveColToRight(char **xy, int y, int startFunc, int lastFunc, int startVar, int lastVar, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, RcListInfo_t *candList, int method); 00232 static void PrintMatrix(char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, int startFunc, int lastFunc, int startVar, int lastVar); 00233 static void PrintMatrixWithCluster(char **xy, ClusterList_t *headCluster, int nCols, int *rowOrder, int *colOrder, Img_DirectionType direction); 00234 static void PrintClusterMatrix(ClusterList_t *headCluster, int nCols, int *colOrder, Img_DirectionType direction); 00235 static void CheckMatrix(char **xy, SccList_t *sccList, int nRows, int nCols, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, int startFunc, int lastFunc, int startVar, int lastVar, int local); 00236 static void CheckCluster(ClusterList_t *headCluster, int nCols, RcInfo_t *colInfo, int *colOrder); 00237 static void WriteMatrix(FILE *fout, char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo); 00238 static void PrintRow(char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, int from, int to); 00239 static void PrintCol(char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, int from, int to); 00240 static RcListInfo_t * SortedListAlloc(void); 00241 static void SortedListFree(RcListInfo_t *candList); 00242 static void SortedListInsert(RcListInfo_t *candList, int index, int otherIndex, RcInfo_t *otherInfo, int method); 00243 static void SortedListDelete(RcListInfo_t *candList, int index); 00244 static void SortedListMove(RcListInfo_t *candList, RcInfo_t *info, int index, int method); 00245 static void CheckSortedList(RcListInfo_t *candList, RcInfo_t *info, int method); 00246 static void MlpCluster(mdd_manager *mddManager, char **xy, int nRows, int nCols, int nActiveRows, int nActiveCols, int *nClusterRows, int *nClusterCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, array_t *clusterArray, array_t *arraySmoothVarBddArray, Img_DirectionType direction, int *cRowOrder, array_t *nsVarBddArray, int *sccBorder, int *varPos, ImgTrmOption_t *option); 00247 static int MlpCountSupport(ClusterList_t *list, int *colOrder, int nActiveCols); 00248 static float MlpSupportAffinity(ClusterList_t *curList, ClusterList_t *nextList, RcInfo_t *colInfo, int *colOrder, int nActiveCols, int clusterMethod); 00249 static int RecursiveCluster(mdd_manager *mddManager, ClusterList_t *headCluster, ClusterSortedList_t *clusterSortedList, char **xy, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, int nActiveRows, int nClusterCols, Img_DirectionType direction, int *varPos, int moveFlag, ImgTrmOption_t *option); 00250 static int RemoveLocalVarsInCluster(mdd_manager *mddManager, char **xy, ClusterList_t *list, int nActiveRows, int nClusterCols, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, int moveFlag, ImgTrmOption_t *option); 00251 static int MlpNumQuantifyVars(ClusterList_t *list, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *colOrder, int nClusterCols); 00252 static ClusterSortedList_t * ClusterSortedListInsert(ClusterSortedList_t *clusterSortedList, ClusterList_t *list, int useQuantifyVars); 00253 static int CountClusterList(ClusterList_t *clusterList); 00254 static int CountClusterSortedList(ClusterSortedList_t *clusterSortedList); 00255 static array_t * CreateInitialCluster(mdd_manager *mddManager, array_t *relationArray, ImgFunctionData_t *functionData, array_t *nsVarBddArray, ImgTrmOption_t *option); 00256 static void SortCol(char **xy, int nRows, int nCols, RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder); 00257 static void UpdateDisapearingPsVars(mdd_manager *mddManager, char **xy, int nActiveRows, int nActiveCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, int row, ImgTrmOption_t *option); 00258 static void UpdateDisapearingPsVarsInCluster(mdd_manager *mddManager, char **xy, int nActiveRows, int nActiveCols, int *rowOrder, int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo, ClusterList_t *list, int moveFlag, ImgTrmOption_t *option); 00259 static void UpdateNonappearingNsVars(mdd_manager *mddManager, array_t *nsVarBddArray, int nRows, RcInfo_t *rowInfo, int *rowOrder, array_t *nonAppearingVarBddArray); 00260 static void WriteOrder(FILE *fout, int nCols, int *colOrder, RcInfo_t *colInfo); 00261 00265 /*---------------------------------------------------------------------------*/ 00266 /* Definition of exported functions */ 00267 /*---------------------------------------------------------------------------*/ 00268 00269 00281 void 00282 Img_PrintMlpOptions(void) 00283 { 00284 ImgTrmOption_t *options; 00285 char dummy[80]; 00286 00287 options = ImgGetTrmOptions(); 00288 00289 switch (options->mlpCluster) { 00290 case 0 : 00291 sprintf(dummy, "linear clustering"); 00292 break; 00293 case 1 : 00294 sprintf(dummy, "affinity based tree clustering (default)"); 00295 break; 00296 default : 00297 sprintf(dummy, "invalid"); 00298 break; 00299 } 00300 fprintf(vis_stdout, "MLP: mlp_cluster = %d (%s)\n", 00301 options->mlpCluster, dummy); 00302 00303 switch (options->mlpReorder) { 00304 case 0 : 00305 sprintf(dummy, "no reordering after clustering (default)"); 00306 break; 00307 case 1 : 00308 sprintf(dummy, "reorder using MLP after clustering (inside)"); 00309 break; 00310 case 2 : 00311 sprintf(dummy, "reorder using MLP after clustering (outside)"); 00312 break; 00313 case 3 : 00314 sprintf(dummy, "reorder using IWLS95 after clustering"); 00315 break; 00316 default : 00317 sprintf(dummy, "invalid"); 00318 break; 00319 } 00320 fprintf(vis_stdout, "MLP: mlp_reorder = %d (%s)\n", 00321 options->mlpReorder, dummy); 00322 00323 switch (options->mlpPreReorder) { 00324 case 0 : 00325 sprintf(dummy, "no reordering after clustering (default)"); 00326 break; 00327 case 1 : 00328 sprintf(dummy, "reorder using MLP after clustering (inside)"); 00329 break; 00330 case 2 : 00331 sprintf(dummy, "reorder using MLP after clustering (outside)"); 00332 break; 00333 case 3 : 00334 sprintf(dummy, "reorder using IWLS95 after clustering"); 00335 break; 00336 default : 00337 sprintf(dummy, "invalid"); 00338 break; 00339 } 00340 fprintf(vis_stdout, "MLP: mlp_pre_reorder = %d (%s)\n", 00341 options->mlpPreReorder, dummy); 00342 00343 switch (options->mlpPostProcess) { 00344 case 0 : 00345 sprintf(dummy, "no postprocessing (default)"); 00346 break; 00347 case 1 : 00348 sprintf(dummy, "do postprocessing after ordering"); 00349 break; 00350 case 2 : 00351 sprintf(dummy, "do postprocessing after clustering or reordering"); 00352 break; 00353 case 3 : 00354 sprintf(dummy, "do both 1 and 2"); 00355 break; 00356 default : 00357 sprintf(dummy, "invalid"); 00358 break; 00359 } 00360 fprintf(vis_stdout, "MLP: mlp_postprocess = %d (%s)\n", 00361 options->mlpPostProcess, dummy); 00362 } 00363 00364 00365 /*---------------------------------------------------------------------------*/ 00366 /* Definition of internal functions */ 00367 /*---------------------------------------------------------------------------*/ 00368 00369 00379 bdd_t * 00380 ImgMlpMultiwayAndSmooth(mdd_manager *mddManager, 00381 ImgFunctionData_t *functionData, 00382 array_t *relationArray, 00383 array_t *domainVarBddArray, 00384 array_t *quantifyVarBddArray, 00385 array_t *rangeVarBddArray, 00386 Img_DirectionType direction, 00387 ImgTrmOption_t *option) 00388 { 00389 int i, clusterSize; 00390 array_t *clusteredRelationArray; 00391 mdd_t *result, *relation, *tmp; 00392 00393 if (direction == Img_Forward_c) { 00394 if (array_n(domainVarBddArray) == 0 && array_n(quantifyVarBddArray) == 0) { 00395 if (array_n(relationArray) == 1) { 00396 relation = array_fetch(mdd_t *, relationArray, 0); 00397 result = bdd_dup(relation); 00398 } else { 00399 result = array_fetch(mdd_t *, relationArray, 0); 00400 for (i = 1; i < array_n(relationArray); i++) { 00401 relation = array_fetch(mdd_t *, relationArray, i); 00402 tmp = result; 00403 result = bdd_and(tmp, relation, 1, 1); 00404 mdd_free(tmp); 00405 } 00406 } 00407 return(result); 00408 } 00409 } 00410 00411 clusterSize = option->clusterSize; 00412 option->clusterSize = 1000000000; 00413 ImgMlpClusterRelationArray(mddManager, functionData, relationArray, 00414 domainVarBddArray, quantifyVarBddArray, rangeVarBddArray, 00415 direction, &clusteredRelationArray, NIL(array_t *), option); 00416 option->clusterSize = clusterSize; 00417 00418 assert(array_n(clusteredRelationArray) == 1); 00419 result = array_fetch(mdd_t *, clusteredRelationArray, 0); 00420 array_free(clusteredRelationArray); 00421 00422 return(result); 00423 } 00424 00425 00438 void 00439 ImgMlpClusterRelationArray(mdd_manager *mddManager, 00440 ImgFunctionData_t *functionData, 00441 array_t *relationArray, 00442 array_t *domainVarBddArray, 00443 array_t *quantifyVarBddArray, 00444 array_t *rangeVarBddArray, 00445 Img_DirectionType direction, 00446 array_t **clusteredRelationArrayPtr, 00447 array_t **arraySmoothVarBddArrayPtr, 00448 ImgTrmOption_t *option) 00449 { 00450 int i, j, x, y, nRows, nCols, nActiveRows, nActiveCols; 00451 int *rowOrder, *colOrder, *cRowOrder; 00452 RcInfo_t *rowInfo, *colInfo; 00453 char **xy; 00454 int nClusterRows, nClusterCols; 00455 array_t *clusterArray; 00456 bdd_t *cluster, *relation, *tempCluster, *var, *nsVar; 00457 int row, col, s, t; 00458 array_t *arraySmoothVarBddArray, *smoothVarBddArray; 00459 int qVarPos; 00460 array_t *nonAppearingVarBddArray; 00461 int *varPos; 00462 array_t *psVarBddArray, *nsVarBddArray; 00463 int index, nVars, nc; 00464 long initialTime, finalTime; 00465 array_t *clusteredRelationArray; 00466 SccList_t *sccHeadList, *sccList; 00467 int *sccBorder; 00468 float lambda1, lambda2, lambda3; 00469 FILE *fout; 00470 00471 if (option->mlpVerbosity) 00472 initialTime = util_cpu_time(); 00473 else 00474 initialTime = 0; 00475 00476 psVarBddArray = domainVarBddArray; 00477 nsVarBddArray = rangeVarBddArray; 00478 00479 if (option->mlpInitialCluster && functionData) { 00480 clusteredRelationArray = CreateInitialCluster(mddManager, relationArray, 00481 functionData, nsVarBddArray, 00482 option); 00483 } else 00484 clusteredRelationArray = relationArray; 00485 00486 nRows = array_n(clusteredRelationArray); 00487 if (direction == Img_Forward_c) 00488 nCols = array_n(domainVarBddArray) + array_n(quantifyVarBddArray); 00489 else 00490 nCols = array_n(rangeVarBddArray) + array_n(quantifyVarBddArray); 00491 00492 xy = ALLOC(char *, nRows); 00493 for (i = 0; i < nRows; i++) { 00494 xy[i] = ALLOC(char, nCols); 00495 memset(xy[i], 0, sizeof(char) * nCols); 00496 } 00497 00498 rowOrder = ALLOC(int, nRows); 00499 for (i = 0; i < nRows; i++) 00500 rowOrder[i] = i; 00501 colOrder = ALLOC(int, nCols); 00502 for (i = 0; i < nCols; i++) 00503 colOrder[i] = i; 00504 00505 rowInfo = ALLOC(RcInfo_t, nRows); 00506 memset(rowInfo, 0, sizeof(RcInfo_t) * nRows); 00507 colInfo = ALLOC(RcInfo_t, nCols); 00508 memset(colInfo, 0, sizeof(RcInfo_t) * nCols); 00509 nVars = bdd_num_vars(mddManager); 00510 varPos = ALLOC(int, nVars); 00511 memset(varPos, 0, sizeof(int) * nVars); 00512 00513 for (i = 0; i < nRows; i++) { 00514 relation = array_fetch(bdd_t *, clusteredRelationArray, i); 00515 rowInfo[i].data.row.func = bdd_dup(relation); 00516 } 00517 00518 nc = 0; 00519 for (i = 0; i < array_n(psVarBddArray); i++) { 00520 var = array_fetch(bdd_t *, psVarBddArray, i); 00521 colInfo[nc].data.col.var = var; 00522 colInfo[nc].data.col.type = 1; 00523 index = (int)bdd_top_var_id(var); 00524 varPos[index] = nc; 00525 nc++; 00526 } 00527 for (i = 0; i < array_n(quantifyVarBddArray); i++) { 00528 var = array_fetch(bdd_t *, quantifyVarBddArray, i); 00529 colInfo[nc].data.col.var = var; 00530 colInfo[nc].data.col.type = 2; 00531 index = (int)bdd_top_var_id(var); 00532 varPos[index] = nc; 00533 nc++; 00534 } 00535 00536 if (arraySmoothVarBddArrayPtr) 00537 nonAppearingVarBddArray = array_alloc(bdd_t *, 0); 00538 else 00539 nonAppearingVarBddArray = NIL(array_t); 00540 00541 SetupMlp(mddManager, xy, nRows, nCols, rowOrder, colOrder, 00542 rowInfo, colInfo, varPos, nsVarBddArray, &nActiveRows, &nActiveCols, 00543 nonAppearingVarBddArray, direction, option); 00544 00545 if (nActiveRows == 0) { 00546 clusterArray = array_alloc(mdd_t *, 0); 00547 cluster = bdd_one(mddManager); 00548 for (i = nActiveRows; i < nRows; i++) { 00549 row = rowOrder[i]; 00550 relation = rowInfo[row].data.row.func; 00551 tempCluster = bdd_and(cluster, relation, 1, 1); 00552 bdd_free(cluster); 00553 cluster = tempCluster; 00554 } 00555 array_insert_last(bdd_t *, clusterArray, cluster); 00556 *clusteredRelationArrayPtr = clusterArray; 00557 00558 if (arraySmoothVarBddArrayPtr) { 00559 arraySmoothVarBddArray = array_alloc(array_t *, 0); 00560 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 00561 array_insert_last(array_t *, arraySmoothVarBddArray, 00562 nonAppearingVarBddArray); 00563 if (direction == Img_Forward_c) { 00564 smoothVarBddArray = array_alloc(array_t *, 0); 00565 array_insert_last(array_t *, arraySmoothVarBddArray, smoothVarBddArray); 00566 } else { 00567 smoothVarBddArray = array_alloc(array_t *, 0); 00568 for (i = 0; i < nRows; i++) { 00569 row = rowOrder[i]; 00570 for (j = 0; j < array_n(rowInfo[row].data.row.nsVarBddArray); j++) { 00571 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, 00572 j); 00573 array_insert_last(bdd_t *, smoothVarBddArray, bdd_dup(nsVar)); 00574 } 00575 } 00576 array_insert_last(array_t *, arraySmoothVarBddArray, 00577 smoothVarBddArray); 00578 } 00579 } 00580 00581 FREE(varPos); 00582 for (i = 0; i < nRows; i++) { 00583 if (xy[i]) 00584 FREE(xy[i]); 00585 } 00586 FREE(xy); 00587 FREE(rowOrder); 00588 FREE(colOrder); 00589 for (i = 0; i < nRows; i++) { 00590 bdd_free(rowInfo[i].data.row.func); 00591 if (rowInfo[i].data.row.nsVarBddArray) 00592 array_free(rowInfo[i].data.row.nsVarBddArray); 00593 } 00594 FREE(rowInfo); 00595 FREE(colInfo); 00596 return; 00597 } 00598 sccHeadList = MlpDecomposeScc(mddManager, xy, nRows, nActiveRows, nActiveCols, 00599 rowOrder, colOrder, rowInfo, colInfo, 00600 0, option); 00601 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 00602 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 00603 rowInfo, colInfo, 0, nActiveRows - 1, 0, nActiveCols - 1); 00604 } 00605 sccList = sccHeadList; 00606 while (sccList) { 00607 BlockLowerTriangle(xy, nRows, nCols, nActiveRows, nActiveCols, sccList, 00608 rowOrder, colOrder, rowInfo, colInfo, option); 00609 sccList = sccList->next; 00610 } 00611 if (option->mlpVerbosity >= 2) { 00612 lambda1 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 00613 rowInfo, colInfo, rowOrder, colOrder, 00614 direction, 0, 0, option); 00615 lambda2 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 00616 rowInfo, colInfo, rowOrder, colOrder, 00617 direction, 1, 0, option); 00618 lambda3 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 00619 rowInfo, colInfo, rowOrder, colOrder, 00620 direction, 2, 0, option); 00621 fprintf(vis_stdout, "Lambda after MLP = %f (%f, %f)\n", 00622 lambda1, lambda2, lambda3); 00623 } 00624 00625 if (option->mlpVerbosity) { 00626 finalTime = util_cpu_time(); 00627 fprintf(vis_stdout, "time for MLP = %10g\n", 00628 (double)(finalTime - initialTime) / 1000.0); 00629 } 00630 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 00631 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 00632 rowInfo, colInfo, 0, nActiveRows - 1, 0, nActiveCols - 1); 00633 } 00634 00635 if (option->mlpPostProcess == 1 || option->mlpPostProcess == 3) { 00636 for (x = 0; x < nActiveRows; x++) { 00637 row = rowOrder[x]; 00638 rowInfo[row].lNum = rowInfo[row].gNum; 00639 rowInfo[row].lMin = rowInfo[row].gMin; 00640 rowInfo[row].lMax = rowInfo[row].gMax; 00641 rowInfo[row].prevG = -1; 00642 rowInfo[row].nextG = nActiveCols; 00643 } 00644 for (y = 0; y < nActiveCols; y++) { 00645 col = colOrder[y]; 00646 colInfo[col].lNum = colInfo[col].gNum; 00647 colInfo[col].lMin = colInfo[col].gMin; 00648 colInfo[col].lMax = colInfo[col].gMax; 00649 colInfo[col].prevG = -1; 00650 colInfo[col].nextG = nActiveRows; 00651 } 00652 00653 sccList = sccHeadList; 00654 while (sccList) { 00655 MlpPostProcess(xy, sccList, nCols, nActiveRows, nActiveCols, 00656 rowInfo, colInfo, rowOrder, colOrder, direction, option); 00657 sccList = sccList->next; 00658 } 00659 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 00660 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 00661 rowInfo, colInfo, 0, nActiveRows - 1, 0, nActiveCols - 1); 00662 } 00663 } 00664 00665 if (option->mlpWriteOrder) { 00666 fout = fopen(option->mlpWriteOrder, "w"); 00667 if (fout) { 00668 WriteOrder(fout, nActiveCols, colOrder, colInfo); 00669 fclose(fout); 00670 } else { 00671 fprintf(vis_stderr, "** img error: can't open file [%s]\n", 00672 option->mlpWriteOrder); 00673 } 00674 } 00675 00676 clusterArray = array_alloc(bdd_t *, 0); 00677 if (arraySmoothVarBddArrayPtr) { 00678 arraySmoothVarBddArray = array_alloc(array_t *, 0); 00679 array_insert_last(array_t *, arraySmoothVarBddArray, 00680 nonAppearingVarBddArray); 00681 } else 00682 arraySmoothVarBddArray = NIL(array_t); 00683 00684 if ((direction == Img_Forward_c && option->mlpReorder) || 00685 (direction == Img_Backward_c && option->mlpPreReorder) || 00686 option->mlpPostProcess >= 2) { 00687 cRowOrder = ALLOC(int, nActiveRows); 00688 for (i = 0; i < nActiveCols; i++) { 00689 col = colOrder[i]; 00690 colInfo[col].lNum = 0; 00691 colInfo[col].lMin = nActiveRows; 00692 colInfo[col].lMax = -1; 00693 } 00694 } else 00695 cRowOrder = NIL(int); 00696 00697 if (option->mlpClusterScc) { 00698 sccBorder = ALLOC(int, nRows); 00699 memset(sccBorder, 0, sizeof(int) * nRows); 00700 sccList = sccHeadList; 00701 while (sccList) { 00702 sccBorder[sccList->startFunc] = 1; 00703 sccBorder[sccList->lastFunc] = 2; 00704 sccList = sccList->next; 00705 } 00706 } else 00707 sccBorder = NIL(int); 00708 00709 MlpCluster(mddManager, xy, nRows, nCols, nActiveRows, nActiveCols, 00710 &nClusterRows, &nClusterCols, 00711 rowOrder, colOrder, rowInfo, colInfo, 00712 clusterArray, arraySmoothVarBddArray, 00713 direction, cRowOrder, nsVarBddArray, sccBorder, varPos, option); 00714 00715 if (sccBorder) 00716 FREE(sccBorder); 00717 00718 if ((direction == Img_Forward_c && option->mlpReorder) || 00719 (direction == Img_Backward_c && option->mlpPreReorder) || 00720 option->mlpPostProcess >= 2) { 00721 if (option->mlpDecomposeScc && NumOfSccs(sccHeadList) > 1) { 00722 FreeSccList(sccHeadList); 00723 sccHeadList = MlpDecomposeScc(mddManager, xy, nRows, 00724 nClusterRows, nClusterCols, 00725 cRowOrder, colOrder, rowInfo, colInfo, 00726 1, option); 00727 } else { 00728 sccHeadList->startFunc = 0; 00729 sccHeadList->lastFunc = nClusterRows - 1; 00730 sccHeadList->startVar = 0; 00731 sccHeadList->lastVar = nClusterCols - 1; 00732 sccHeadList->nFuncs = nClusterRows; 00733 sccHeadList->nVars = nClusterCols; 00734 } 00735 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 00736 PrintMatrix(xy, nClusterRows, nClusterCols, cRowOrder, colOrder, 00737 rowInfo, colInfo, 0, nClusterRows - 1, 0, nClusterCols - 1); 00738 } 00739 00740 if ((direction == Img_Forward_c && option->mlpReorder) || 00741 (direction == Img_Backward_c && option->mlpPreReorder)) { 00742 sccList = sccHeadList; 00743 while (sccList) { 00744 BlockLowerTriangle(xy, nRows, nCols, nClusterRows, nClusterCols, 00745 sccList, cRowOrder, colOrder, rowInfo, colInfo, 00746 option); 00747 sccList = sccList->next; 00748 } 00749 if (option->mlpVerbosity >= 2) { 00750 lambda1 = ComputeLambdaMlp(xy, nCols, nClusterRows, nClusterCols, 00751 rowInfo, colInfo, rowOrder, colOrder, 00752 direction, 0, 0, option); 00753 lambda2 = ComputeLambdaMlp(xy, nCols, nClusterRows, nClusterCols, 00754 rowInfo, colInfo, rowOrder, colOrder, 00755 direction, 1, 0, option); 00756 lambda3 = ComputeLambdaMlp(xy, nCols, nClusterRows, nClusterCols, 00757 rowInfo, colInfo, rowOrder, colOrder, 00758 direction, 2, 0, option); 00759 fprintf(vis_stdout, "Lambda after MLP-cluster = %f (%f, %f)\n", 00760 lambda1, lambda2, lambda3); 00761 } 00762 00763 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 00764 PrintMatrix(xy, nClusterRows, nClusterCols, cRowOrder, colOrder, 00765 rowInfo, colInfo, 0, nClusterRows - 1, 0, nClusterCols - 1); 00766 } 00767 } 00768 00769 if (option->mlpPostProcess >= 2) { 00770 for (x = 0; x < nClusterRows; x++) { 00771 row = rowOrder[x]; 00772 rowInfo[row].lNum = rowInfo[row].gNum; 00773 rowInfo[row].lMin = rowInfo[row].gMin; 00774 rowInfo[row].lMax = rowInfo[row].gMax; 00775 rowInfo[row].prevG = -1; 00776 rowInfo[row].nextG = nClusterCols; 00777 } 00778 for (y = 0; y < nClusterCols; y++) { 00779 col = colOrder[y]; 00780 colInfo[col].lNum = colInfo[col].gNum; 00781 colInfo[col].lMin = colInfo[col].gMin; 00782 colInfo[col].lMax = colInfo[col].gMax; 00783 colInfo[col].prevG = -1; 00784 colInfo[col].nextG = nClusterRows; 00785 } 00786 00787 sccList = sccHeadList; 00788 while (sccList) { 00789 MlpPostProcess(xy, sccList, nCols, nClusterRows, nClusterCols, 00790 rowInfo, colInfo, cRowOrder, colOrder, direction, option); 00791 sccList = sccList->next; 00792 } 00793 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 00794 PrintMatrix(xy, nClusterRows, nClusterCols, cRowOrder, colOrder, 00795 rowInfo, colInfo, 0, nClusterRows - 1, 0, nClusterCols - 1); 00796 } 00797 } 00798 00799 *clusteredRelationArrayPtr = clusterArray; 00800 00801 if (direction == Img_Forward_c) { 00802 for (i = nClusterRows - 1; i >= 0; i--) { 00803 row = cRowOrder[i]; 00804 array_insert_last(bdd_t *, clusterArray, rowInfo[row].data.row.func); 00805 rowInfo[row].data.row.func = NIL(bdd_t); 00806 } 00807 00808 if (nRows > nActiveRows) { 00809 cluster = bdd_one(mddManager); 00810 for (i = nActiveRows; i < nRows; i++) { 00811 row = rowOrder[i]; 00812 relation = rowInfo[row].data.row.func; 00813 tempCluster = bdd_and(cluster, relation, 1, 1); 00814 bdd_free(cluster); 00815 cluster = tempCluster; 00816 } 00817 array_insert_last(bdd_t *, clusterArray, cluster); 00818 } 00819 } else { 00820 if (nRows > nActiveRows) { 00821 UpdateNonappearingNsVars(mddManager, nsVarBddArray, nClusterRows, 00822 rowInfo, cRowOrder, nonAppearingVarBddArray); 00823 00824 cluster = bdd_one(mddManager); 00825 for (i = nActiveRows; i < nRows; i++) { 00826 row = rowOrder[i]; 00827 relation = rowInfo[row].data.row.func; 00828 tempCluster = bdd_and(cluster, relation, 1, 1); 00829 bdd_free(cluster); 00830 cluster = tempCluster; 00831 } 00832 array_insert_last(bdd_t *, clusterArray, cluster); 00833 } 00834 00835 for (i = 0; i < nClusterRows; i++) { 00836 row = cRowOrder[i]; 00837 array_insert_last(bdd_t *, clusterArray, rowInfo[row].data.row.func); 00838 rowInfo[row].data.row.func = NIL(bdd_t); 00839 } 00840 } 00841 00842 if (arraySmoothVarBddArrayPtr) { 00843 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 00844 00845 if (direction == Img_Forward_c) { 00846 if (nCols > nClusterCols) { 00847 for (i = nClusterCols; i < nCols; i++) { 00848 col = colOrder[i]; 00849 array_insert_last(bdd_t *, nonAppearingVarBddArray, 00850 bdd_dup(colInfo[col].data.col.var)); 00851 } 00852 } 00853 qVarPos = nClusterCols - 1; 00854 if (qVarPos >= 0) { 00855 col = colOrder[qVarPos]; 00856 while (colInfo[col].gNum == 0) { 00857 array_insert_last(bdd_t *, nonAppearingVarBddArray, 00858 bdd_dup(colInfo[col].data.col.var)); 00859 if (qVarPos == 0) 00860 break; 00861 qVarPos--; 00862 col = colOrder[qVarPos]; 00863 } 00864 } 00865 for (i = nClusterRows - 1; i >= 0; i--) { 00866 row = cRowOrder[i]; 00867 smoothVarBddArray = array_alloc(array_t *, 0); 00868 col = colOrder[qVarPos]; 00869 while (rowInfo[colInfo[col].gMin].pos == i) { 00870 array_insert_last(bdd_t *, smoothVarBddArray, 00871 bdd_dup(colInfo[col].data.col.var)); 00872 if (qVarPos == 0) 00873 break; 00874 qVarPos--; 00875 col = colOrder[qVarPos]; 00876 } 00877 array_insert_last(array_t *, arraySmoothVarBddArray, 00878 smoothVarBddArray); 00879 } 00880 00881 if (nRows > nActiveRows) { 00882 smoothVarBddArray = array_alloc(array_t *, 0); 00883 array_insert_last(array_t *, arraySmoothVarBddArray, 00884 smoothVarBddArray); 00885 } 00886 } else { 00887 if (nRows == nActiveRows) { 00888 UpdateNonappearingNsVars(mddManager, nsVarBddArray, nClusterRows, 00889 rowInfo, cRowOrder, nonAppearingVarBddArray); 00890 } else { 00891 smoothVarBddArray = array_alloc(array_t *, 0); 00892 for (i = nActiveRows; i < nRows; i++) { 00893 row = rowOrder[i]; 00894 for (j = 0; j < array_n(rowInfo[row].data.row.nsVarBddArray); j++) { 00895 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, 00896 j); 00897 array_insert_last(bdd_t *, smoothVarBddArray, bdd_dup(nsVar)); 00898 } 00899 } 00900 array_insert_last(array_t *, arraySmoothVarBddArray, 00901 smoothVarBddArray); 00902 } 00903 for (i = 0; i < nClusterRows; i++) { 00904 row = cRowOrder[i]; 00905 smoothVarBddArray = array_alloc(array_t *, 0); 00906 for (j = 0; j < array_n(rowInfo[row].data.row.nsVarBddArray); j++) { 00907 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, 00908 j); 00909 array_insert_last(bdd_t *, smoothVarBddArray, bdd_dup(nsVar)); 00910 } 00911 00912 s = colInfo[rowInfo[row].gMin].pos; 00913 t = colInfo[rowInfo[row].gMax].pos; 00914 for (j = s; j <= t; j++) { 00915 col = colOrder[j]; 00916 if (colInfo[col].data.col.type == 2) { 00917 if (rowInfo[colInfo[col].gMax].pos == i) { 00918 array_insert_last(bdd_t *, smoothVarBddArray, 00919 bdd_dup(colInfo[col].data.col.var)); 00920 } 00921 } 00922 } 00923 array_insert_last(array_t *, arraySmoothVarBddArray, 00924 smoothVarBddArray); 00925 } 00926 } 00927 } 00928 00929 FREE(cRowOrder); 00930 00931 if (option->mlpVerbosity) { 00932 finalTime = util_cpu_time(); 00933 fprintf(vis_stdout, "time for MLP-clustering-reorder = %10g\n", 00934 (double)(finalTime - initialTime) / 1000.0); 00935 } 00936 } else { 00937 *clusteredRelationArrayPtr = clusterArray; 00938 if (arraySmoothVarBddArrayPtr) 00939 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 00940 00941 if (option->mlpVerbosity) { 00942 finalTime = util_cpu_time(); 00943 fprintf(vis_stdout, "time for MLP-clustering = %10g\n", 00944 (double)(finalTime - initialTime) / 1000.0); 00945 } 00946 } 00947 00948 FreeSccList(sccHeadList); 00949 00950 FREE(varPos); 00951 for (i = 0; i < nRows; i++) { 00952 if (xy[i]) 00953 FREE(xy[i]); 00954 } 00955 FREE(xy); 00956 FREE(rowOrder); 00957 FREE(colOrder); 00958 for (i = 0; i < nRows; i++) { 00959 if (rowInfo[i].data.row.func) 00960 bdd_free(rowInfo[i].data.row.func); 00961 if (rowInfo[i].data.row.nsVarBddArray) 00962 array_free(rowInfo[i].data.row.nsVarBddArray); 00963 } 00964 FREE(rowInfo); 00965 FREE(colInfo); 00966 if (option->mlpInitialCluster) 00967 mdd_array_free(clusteredRelationArray); 00968 } 00969 00970 00980 void 00981 ImgMlpOrderRelationArray(mdd_manager *mddManager, 00982 array_t *relationArray, 00983 array_t *domainVarBddArray, 00984 array_t *quantifyVarBddArray, 00985 array_t *rangeVarBddArray, 00986 Img_DirectionType direction, 00987 array_t **orderedRelationArrayPtr, 00988 array_t **arraySmoothVarBddArrayPtr, 00989 ImgTrmOption_t *option) 00990 { 00991 int i, j, x, y, nRows, nCols, nActiveRows, nActiveCols; 00992 int *rowOrder, *colOrder; 00993 RcInfo_t *rowInfo, *colInfo; 00994 char **xy; 00995 array_t *orderedArray; 00996 bdd_t *relation, *var, *nsVar; 00997 int row, col, s, t; 00998 array_t *arraySmoothVarBddArray, *smoothVarBddArray; 00999 int qVarPos; 01000 array_t *nonAppearingVarBddArray; 01001 int *varPos; 01002 array_t *psVarBddArray, *nsVarBddArray; 01003 int index, nVars, nc; 01004 long initialTime, finalTime; 01005 SccList_t *sccHeadList, *sccList; 01006 float lambda1, lambda2, lambda3; 01007 01008 arraySmoothVarBddArray = NIL(array_t); 01009 nRows = array_n(relationArray); 01010 if (direction == Img_Forward_c) 01011 nCols = array_n(domainVarBddArray) + array_n(quantifyVarBddArray); 01012 else 01013 nCols = array_n(rangeVarBddArray) + array_n(quantifyVarBddArray); 01014 01015 if (nCols == 0) { 01016 if (direction == Img_Forward_c) { 01017 orderedArray = mdd_array_duplicate(relationArray); 01018 *orderedRelationArrayPtr = orderedArray; 01019 if (arraySmoothVarBddArrayPtr) { 01020 arraySmoothVarBddArray = array_alloc(array_t *, 0); 01021 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 01022 for (i = 0; i <= nRows; i++) { 01023 smoothVarBddArray = array_alloc(array_t *, 0); 01024 array_insert_last(array_t *, arraySmoothVarBddArray, 01025 smoothVarBddArray); 01026 } 01027 } 01028 } else { 01029 orderedArray = array_alloc(mdd_t *, 0); 01030 array_insert_last(mdd_t *, orderedArray, mdd_one(mddManager)); 01031 *orderedRelationArrayPtr = orderedArray; 01032 if (arraySmoothVarBddArrayPtr) { 01033 arraySmoothVarBddArray = array_alloc(array_t *, 0); 01034 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 01035 for (i = 0; i <= 1; i++) { 01036 smoothVarBddArray = array_alloc(array_t *, 0); 01037 array_insert_last(array_t *, arraySmoothVarBddArray, 01038 smoothVarBddArray); 01039 } 01040 } 01041 } 01042 return; 01043 } 01044 01045 if (option->mlpVerbosity) 01046 initialTime = util_cpu_time(); 01047 else 01048 initialTime = 0; 01049 01050 xy = ALLOC(char *, nRows); 01051 for (i = 0; i < nRows; i++) { 01052 xy[i] = ALLOC(char, nCols); 01053 memset(xy[i], 0, sizeof(char) * nCols); 01054 } 01055 01056 rowOrder = ALLOC(int, nRows); 01057 for (i = 0; i < nRows; i++) 01058 rowOrder[i] = i; 01059 colOrder = ALLOC(int, nCols); 01060 for (i = 0; i < nCols; i++) 01061 colOrder[i] = i; 01062 01063 rowInfo = ALLOC(RcInfo_t, nRows); 01064 memset(rowInfo, 0, sizeof(RcInfo_t) * nRows); 01065 colInfo = ALLOC(RcInfo_t, nCols); 01066 memset(colInfo, 0, sizeof(RcInfo_t) * nCols); 01067 nVars = bdd_num_vars(mddManager); 01068 varPos = ALLOC(int, nVars); 01069 memset(varPos, 0, sizeof(int) * nVars); 01070 01071 for (i = 0; i < nRows; i++) { 01072 relation = array_fetch(bdd_t *, relationArray, i); 01073 rowInfo[i].data.row.func = bdd_dup(relation); 01074 } 01075 01076 psVarBddArray = domainVarBddArray; 01077 nsVarBddArray = rangeVarBddArray; 01078 nc = 0; 01079 for (i = 0; i < array_n(psVarBddArray); i++) { 01080 var = array_fetch(bdd_t *, psVarBddArray, i); 01081 colInfo[nc].data.col.var = var; 01082 colInfo[nc].data.col.type = 1; 01083 index = (int)bdd_top_var_id(var); 01084 varPos[index] = nc; 01085 nc++; 01086 } 01087 for (i = 0; i < array_n(quantifyVarBddArray); i++) { 01088 var = array_fetch(bdd_t *, quantifyVarBddArray, i); 01089 colInfo[nc].data.col.var = var; 01090 colInfo[nc].data.col.type = 2; 01091 index = (int)bdd_top_var_id(var); 01092 varPos[index] = nc; 01093 nc++; 01094 } 01095 01096 if (arraySmoothVarBddArrayPtr) 01097 nonAppearingVarBddArray = array_alloc(bdd_t *, 0); 01098 else 01099 nonAppearingVarBddArray = NIL(array_t); 01100 SetupMlp(mddManager, xy, nRows, nCols, rowOrder, colOrder, 01101 rowInfo, colInfo, varPos, nsVarBddArray, &nActiveRows, &nActiveCols, 01102 nonAppearingVarBddArray, direction, option); 01103 if (nActiveRows == 0) { 01104 orderedArray = array_alloc(bdd_t *, 0); 01105 if (arraySmoothVarBddArrayPtr) { 01106 arraySmoothVarBddArray = array_alloc(array_t *, 0); 01107 array_insert_last(array_t *, arraySmoothVarBddArray, 01108 nonAppearingVarBddArray); 01109 } 01110 for (i = 0; i < nRows; i++) { 01111 row = rowOrder[i]; 01112 relation = rowInfo[row].data.row.func; 01113 array_insert_last(bdd_t *, orderedArray, mdd_dup(relation)); 01114 if (arraySmoothVarBddArrayPtr) { 01115 if (direction == Img_Forward_c) { 01116 smoothVarBddArray = array_alloc(array_t *, 0); 01117 array_insert_last(array_t *, arraySmoothVarBddArray, 01118 smoothVarBddArray); 01119 } else { 01120 smoothVarBddArray = rowInfo[row].data.row.nsVarBddArray; 01121 rowInfo[row].data.row.nsVarBddArray = NIL(array_t); 01122 array_insert_last(array_t *, arraySmoothVarBddArray, 01123 smoothVarBddArray); 01124 } 01125 } 01126 } 01127 *orderedRelationArrayPtr = orderedArray; 01128 if (arraySmoothVarBddArrayPtr) 01129 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 01130 01131 FREE(varPos); 01132 for (i = 0; i < nRows; i++) { 01133 if (xy[i]) 01134 FREE(xy[i]); 01135 } 01136 FREE(xy); 01137 FREE(rowOrder); 01138 FREE(colOrder); 01139 for (i = 0; i < nRows; i++) { 01140 bdd_free(rowInfo[i].data.row.func); 01141 if (rowInfo[i].data.row.nsVarBddArray) 01142 array_free(rowInfo[i].data.row.nsVarBddArray); 01143 } 01144 FREE(rowInfo); 01145 FREE(colInfo); 01146 return; 01147 } 01148 sccHeadList = MlpDecomposeScc(mddManager, xy, nRows, nActiveRows, nActiveCols, 01149 rowOrder, colOrder, rowInfo, colInfo, 01150 0, option); 01151 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 01152 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 01153 rowInfo, colInfo, 0, nActiveRows - 1, 0, nActiveCols - 1); 01154 } 01155 sccList = sccHeadList; 01156 while (sccList) { 01157 BlockLowerTriangle(xy, nRows, nCols, nActiveRows, nActiveCols, sccList, 01158 rowOrder, colOrder, rowInfo, colInfo, option); 01159 sccList = sccList->next; 01160 } 01161 if (option->mlpVerbosity >= 2) { 01162 lambda1 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 01163 rowInfo, colInfo, rowOrder, colOrder, 01164 direction, 0, 0, option); 01165 lambda2 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 01166 rowInfo, colInfo, rowOrder, colOrder, 01167 direction, 1, 0, option); 01168 lambda3 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 01169 rowInfo, colInfo, rowOrder, colOrder, 01170 direction, 2, 0, option); 01171 fprintf(vis_stdout, "Lambda after MLP = %f (%f, %f)\n", 01172 lambda1, lambda2, lambda3); 01173 } 01174 01175 if (option->mlpVerbosity) { 01176 finalTime = util_cpu_time(); 01177 fprintf(vis_stdout, "time for MLP = %10g\n", 01178 (double)(finalTime - initialTime) / 1000.0); 01179 } 01180 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 01181 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 01182 rowInfo, colInfo, 0, nActiveRows - 1, 0, nActiveCols - 1); 01183 } 01184 01185 if (option->mlpPostProcess) { 01186 for (x = 0; x < nRows; x++) { 01187 row = rowOrder[x]; 01188 rowInfo[row].lNum = rowInfo[row].gNum; 01189 rowInfo[row].lMin = rowInfo[row].gMin; 01190 rowInfo[row].lMax = rowInfo[row].gMax; 01191 rowInfo[row].prevG = -1; 01192 rowInfo[row].nextG = nCols; 01193 } 01194 for (y = 0; y < nCols; y++) { 01195 col = colOrder[y]; 01196 colInfo[col].lNum = colInfo[col].gNum; 01197 colInfo[col].lMin = colInfo[col].gMin; 01198 colInfo[col].lMax = colInfo[col].gMax; 01199 colInfo[col].prevG = -1; 01200 colInfo[col].nextG = nRows; 01201 } 01202 01203 sccList = sccHeadList; 01204 while (sccList) { 01205 MlpPostProcess(xy, sccList, nCols, nActiveRows, nActiveCols, 01206 rowInfo, colInfo, rowOrder, colOrder, direction, option); 01207 sccList = sccList->next; 01208 } 01209 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 01210 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 01211 rowInfo, colInfo, 0, nActiveRows - 1, 0, nActiveCols - 1); 01212 } 01213 } 01214 01215 orderedArray = array_alloc(bdd_t *, 0); 01216 if (arraySmoothVarBddArrayPtr) { 01217 arraySmoothVarBddArray = array_alloc(array_t *, 0); 01218 array_insert_last(array_t *, arraySmoothVarBddArray, 01219 nonAppearingVarBddArray); 01220 } 01221 01222 assert(nActiveCols > 0); 01223 if (direction == Img_Forward_c) { 01224 if (arraySmoothVarBddArrayPtr) { 01225 if (nCols > nActiveCols) { 01226 for (i = nActiveCols; i < nCols; i++) { 01227 col = colOrder[i]; 01228 array_insert_last(bdd_t *, nonAppearingVarBddArray, 01229 bdd_dup(colInfo[col].data.col.var)); 01230 } 01231 } 01232 qVarPos = nActiveCols - 1; 01233 if (qVarPos >= 0) { 01234 col = colOrder[qVarPos]; 01235 while (colInfo[col].gNum == 0) { 01236 array_insert_last(bdd_t *, nonAppearingVarBddArray, 01237 bdd_dup(colInfo[col].data.col.var)); 01238 if (qVarPos == 0) 01239 break; 01240 qVarPos--; 01241 col = colOrder[qVarPos]; 01242 } 01243 } 01244 } else 01245 qVarPos = 0; /* to avoid warning */ 01246 for (i = nActiveRows - 1; i >= 0; i--) { 01247 row = rowOrder[i]; 01248 if (arraySmoothVarBddArrayPtr) { 01249 smoothVarBddArray = array_alloc(array_t *, 0); 01250 col = colOrder[qVarPos]; 01251 while (rowInfo[colInfo[col].gMin].pos == i) { 01252 index = (int)bdd_top_var_id(colInfo[col].data.col.var); 01253 array_insert_last(bdd_t *, smoothVarBddArray, 01254 bdd_dup(colInfo[col].data.col.var)); 01255 if (qVarPos == 0) 01256 break; 01257 qVarPos--; 01258 col = colOrder[qVarPos]; 01259 } 01260 array_insert_last(array_t *, arraySmoothVarBddArray, smoothVarBddArray); 01261 } 01262 relation = bdd_dup(rowInfo[row].data.row.func); 01263 array_insert_last(bdd_t *, orderedArray, relation); 01264 } 01265 01266 if (nRows > nActiveRows) { 01267 for (i = nActiveRows; i < nRows; i++) { 01268 row = rowOrder[i]; 01269 relation = rowInfo[row].data.row.func; 01270 array_insert_last(bdd_t *, orderedArray, mdd_dup(relation)); 01271 if (arraySmoothVarBddArrayPtr) { 01272 smoothVarBddArray = array_alloc(array_t *, 0); 01273 array_insert_last(array_t *, arraySmoothVarBddArray, 01274 smoothVarBddArray); 01275 } 01276 } 01277 } 01278 } else { 01279 if (arraySmoothVarBddArrayPtr) { 01280 UpdateNonappearingNsVars(mddManager, nsVarBddArray, nActiveRows, 01281 rowInfo, rowOrder, nonAppearingVarBddArray); 01282 } 01283 if (nRows > nActiveRows) { 01284 for (i = nActiveRows; i < nRows; i++) { 01285 row = rowOrder[i]; 01286 relation = rowInfo[row].data.row.func; 01287 array_insert_last(bdd_t *, orderedArray, mdd_dup(relation)); 01288 if (arraySmoothVarBddArrayPtr) { 01289 smoothVarBddArray = rowInfo[row].data.row.nsVarBddArray; 01290 rowInfo[row].data.row.nsVarBddArray = NIL(array_t); 01291 array_insert_last(array_t *, arraySmoothVarBddArray, 01292 smoothVarBddArray); 01293 } 01294 } 01295 } 01296 for (i = 0; i < nActiveRows; i++) { 01297 row = rowOrder[i]; 01298 if (arraySmoothVarBddArrayPtr) { 01299 smoothVarBddArray = array_alloc(array_t *, 0); 01300 for (j = 0; j < array_n(rowInfo[row].data.row.nsVarBddArray); j++) { 01301 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, j); 01302 array_insert_last(bdd_t *, smoothVarBddArray, bdd_dup(nsVar)); 01303 } 01304 01305 s = colInfo[rowInfo[row].gMin].pos; 01306 t = colInfo[rowInfo[row].gMax].pos; 01307 for (j = s; j <= t; j++) { 01308 col = colOrder[j]; 01309 if (colInfo[col].data.col.type == 2) { 01310 if (rowInfo[colInfo[col].gMax].pos == i) { 01311 array_insert_last(bdd_t *, smoothVarBddArray, 01312 bdd_dup(colInfo[col].data.col.var)); 01313 } 01314 } 01315 } 01316 array_insert_last(array_t *, arraySmoothVarBddArray, smoothVarBddArray); 01317 } 01318 relation = bdd_dup(rowInfo[row].data.row.func); 01319 array_insert_last(bdd_t *, orderedArray, relation); 01320 } 01321 } 01322 01323 *orderedRelationArrayPtr = orderedArray; 01324 if (arraySmoothVarBddArrayPtr) 01325 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 01326 01327 FreeSccList(sccHeadList); 01328 01329 FREE(varPos); 01330 for (i = 0; i < nRows; i++) { 01331 if (xy[i]) 01332 FREE(xy[i]); 01333 } 01334 FREE(xy); 01335 FREE(rowOrder); 01336 FREE(colOrder); 01337 for (i = 0; i < nRows; i++) { 01338 bdd_free(rowInfo[i].data.row.func); 01339 if (rowInfo[i].data.row.nsVarBddArray) 01340 array_free(rowInfo[i].data.row.nsVarBddArray); 01341 } 01342 FREE(rowInfo); 01343 FREE(colInfo); 01344 } 01345 01346 01356 float 01357 ImgMlpComputeLambda(mdd_manager *mddManager, 01358 array_t *relationArray, 01359 array_t *domainVarBddArray, 01360 array_t *quantifyVarBddArray, 01361 array_t *rangeVarBddArray, 01362 Img_DirectionType direction, 01363 int mode, 01364 int asIs, 01365 int *prevArea, 01366 float *improvedLambda, 01367 ImgTrmOption_t *option) 01368 { 01369 int i, nRows, nCols, nActiveRows, nActiveCols; 01370 int *rowOrder, *colOrder; 01371 RcInfo_t *rowInfo, *colInfo; 01372 char **xy; 01373 bdd_t *relation, *var; 01374 int *varPos; 01375 array_t *psVarBddArray, *nsVarBddArray; 01376 int index, nVars, nc; 01377 SccList_t *sccHeadList, *sccList; 01378 float lambda; 01379 int area; 01380 01381 nRows = array_n(relationArray); 01382 if (direction == Img_Forward_c) 01383 nCols = array_n(domainVarBddArray) + array_n(quantifyVarBddArray); 01384 else 01385 nCols = array_n(rangeVarBddArray) + array_n(quantifyVarBddArray); 01386 01387 if (nCols == 0) { 01388 if (improvedLambda) { 01389 *improvedLambda = 0.0; 01390 *prevArea = 0; 01391 } 01392 return(0.0); 01393 } 01394 01395 xy = ALLOC(char *, nRows); 01396 for (i = 0; i < nRows; i++) { 01397 xy[i] = ALLOC(char, nCols); 01398 memset(xy[i], 0, sizeof(char) * nCols); 01399 } 01400 01401 rowOrder = ALLOC(int, nRows); 01402 for (i = 0; i < nRows; i++) 01403 rowOrder[i] = i; 01404 colOrder = ALLOC(int, nCols); 01405 for (i = 0; i < nCols; i++) 01406 colOrder[i] = i; 01407 01408 rowInfo = ALLOC(RcInfo_t, nRows); 01409 memset(rowInfo, 0, sizeof(RcInfo_t) * nRows); 01410 colInfo = ALLOC(RcInfo_t, nCols); 01411 memset(colInfo, 0, sizeof(RcInfo_t) * nCols); 01412 nVars = bdd_num_vars(mddManager); 01413 varPos = ALLOC(int, nVars); 01414 memset(varPos, 0, sizeof(int) * nVars); 01415 01416 for (i = 0; i < nRows; i++) { 01417 relation = array_fetch(bdd_t *, relationArray, i); 01418 rowInfo[i].data.row.func = bdd_dup(relation); 01419 } 01420 01421 psVarBddArray = domainVarBddArray; 01422 nsVarBddArray = rangeVarBddArray; 01423 nc = 0; 01424 for (i = 0; i < array_n(psVarBddArray); i++) { 01425 var = array_fetch(bdd_t *, psVarBddArray, i); 01426 colInfo[nc].data.col.var = var; 01427 colInfo[nc].data.col.type = 1; 01428 index = (int)bdd_top_var_id(var); 01429 varPos[index] = nc; 01430 nc++; 01431 } 01432 for (i = 0; i < array_n(quantifyVarBddArray); i++) { 01433 var = array_fetch(bdd_t *, quantifyVarBddArray, i); 01434 colInfo[nc].data.col.var = var; 01435 colInfo[nc].data.col.type = 2; 01436 index = (int)bdd_top_var_id(var); 01437 varPos[index] = nc; 01438 nc++; 01439 } 01440 01441 SetupMlp(mddManager, xy, nRows, nCols, rowOrder, colOrder, 01442 rowInfo, colInfo, varPos, nsVarBddArray, &nActiveRows, &nActiveCols, 01443 NIL(array_t), direction, option); 01444 if (nActiveRows == 0) { 01445 FREE(varPos); 01446 for (i = 0; i < nRows; i++) { 01447 if (xy[i]) 01448 FREE(xy[i]); 01449 } 01450 FREE(xy); 01451 FREE(rowOrder); 01452 FREE(colOrder); 01453 for (i = 0; i < nRows; i++) { 01454 bdd_free(rowInfo[i].data.row.func); 01455 if (rowInfo[i].data.row.nsVarBddArray) 01456 array_free(rowInfo[i].data.row.nsVarBddArray); 01457 } 01458 FREE(rowInfo); 01459 FREE(colInfo); 01460 01461 if (improvedLambda) { 01462 *improvedLambda = 0.0; 01463 *prevArea = 0; 01464 } 01465 return(0.0); 01466 } 01467 sccHeadList = MlpDecomposeScc(mddManager, xy, nRows, nActiveRows, nActiveCols, 01468 rowOrder, colOrder, rowInfo, colInfo, 01469 0, option); 01470 sccList = sccHeadList; 01471 while (sccList) { 01472 BlockLowerTriangle(xy, nRows, nCols, nActiveRows, nActiveCols, sccList, 01473 rowOrder, colOrder, rowInfo, colInfo, option); 01474 sccList = sccList->next; 01475 } 01476 01477 lambda = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 01478 rowInfo, colInfo, rowOrder, colOrder, 01479 direction, mode, asIs, option); 01480 01481 FreeSccList(sccHeadList); 01482 01483 FREE(varPos); 01484 for (i = 0; i < nRows; i++) { 01485 if (xy[i]) 01486 FREE(xy[i]); 01487 } 01488 FREE(xy); 01489 FREE(rowOrder); 01490 FREE(colOrder); 01491 for (i = 0; i < nRows; i++) { 01492 bdd_free(rowInfo[i].data.row.func); 01493 if (rowInfo[i].data.row.nsVarBddArray) 01494 array_free(rowInfo[i].data.row.nsVarBddArray); 01495 } 01496 FREE(rowInfo); 01497 FREE(colInfo); 01498 01499 if (option->mlpLambdaMode == 0) 01500 area = nActiveRows * nActiveCols; 01501 else 01502 area = nActiveRows * nCols; 01503 if (improvedLambda) { 01504 if (*prevArea) 01505 *improvedLambda = lambda * (float)area / (*prevArea); 01506 else 01507 *improvedLambda = 0.0; 01508 *prevArea = area; 01509 } 01510 return(lambda); 01511 } 01512 01513 01523 void 01524 ImgMlpGetQuantificationSchedule(mdd_manager *mddManager, 01525 array_t *relationArray, 01526 array_t *domainVarBddArray, 01527 array_t *quantifyVarBddArray, 01528 array_t *rangeVarBddArray, 01529 array_t **clusteredRelationArrayPtr, 01530 array_t **arraySmoothVarBddArrayPtr, 01531 Img_DirectionType direction, 01532 ImgTrmOption_t *option) 01533 { 01534 int i, j, nRows, nCols, nActiveRows, nActiveCols; 01535 int *rowOrder, *colOrder; 01536 RcInfo_t *rowInfo, *colInfo; 01537 char **xy; 01538 bdd_t *relation, *var, *nsVar; 01539 int *varPos; 01540 array_t *psVarBddArray, *nsVarBddArray; 01541 int index, nVars, nc; 01542 array_t *arraySmoothVarBddArray, *smoothVarBddArray; 01543 int qVarPos, row, col, s, t; 01544 array_t *nonAppearingVarBddArray; 01545 array_t *clusteredRelationArray; 01546 01547 nRows = array_n(relationArray); 01548 if (direction == Img_Forward_c) 01549 nCols = array_n(domainVarBddArray) + array_n(quantifyVarBddArray); 01550 else 01551 nCols = array_n(rangeVarBddArray) + array_n(quantifyVarBddArray); 01552 01553 xy = ALLOC(char *, nRows); 01554 for (i = 0; i < nRows; i++) { 01555 xy[i] = ALLOC(char, nCols); 01556 memset(xy[i], 0, sizeof(char) * nCols); 01557 } 01558 01559 rowOrder = ALLOC(int, nRows); 01560 for (i = 0; i < nRows; i++) 01561 rowOrder[i] = i; 01562 colOrder = ALLOC(int, nCols); 01563 for (i = 0; i < nCols; i++) 01564 colOrder[i] = i; 01565 01566 rowInfo = ALLOC(RcInfo_t, nRows); 01567 memset(rowInfo, 0, sizeof(RcInfo_t) * nRows); 01568 colInfo = ALLOC(RcInfo_t, nCols); 01569 memset(colInfo, 0, sizeof(RcInfo_t) * nCols); 01570 nVars = bdd_num_vars(mddManager); 01571 varPos = ALLOC(int, nVars); 01572 memset(varPos, 0, sizeof(int) * nVars); 01573 01574 psVarBddArray = domainVarBddArray; 01575 nsVarBddArray = rangeVarBddArray; 01576 if (direction == Img_Forward_c) { 01577 for (i = 0; i < nRows; i++) { 01578 relation = array_fetch(bdd_t *, relationArray, nRows - 1 - i); 01579 rowInfo[i].data.row.func = bdd_dup(relation); 01580 } 01581 } else { 01582 for (i = 0; i < nRows; i++) { 01583 relation = array_fetch(bdd_t *, relationArray, i); 01584 rowInfo[i].data.row.func = bdd_dup(relation); 01585 } 01586 } 01587 nc = 0; 01588 for (i = 0; i < array_n(psVarBddArray); i++) { 01589 var = array_fetch(bdd_t *, psVarBddArray, i); 01590 colInfo[nc].data.col.var = var; 01591 colInfo[nc].data.col.type = 1; 01592 index = (int)bdd_top_var_id(var); 01593 varPos[index] = nc; 01594 nc++; 01595 } 01596 for (i = 0; i < array_n(quantifyVarBddArray); i++) { 01597 var = array_fetch(bdd_t *, quantifyVarBddArray, i); 01598 colInfo[nc].data.col.var = var; 01599 colInfo[nc].data.col.type = 2; 01600 index = (int)bdd_top_var_id(var); 01601 varPos[index] = nc; 01602 nc++; 01603 } 01604 01605 nonAppearingVarBddArray = array_alloc(bdd_t *, 0); 01606 SetupMlp(mddManager, xy, nRows, nCols, rowOrder, colOrder, 01607 rowInfo, colInfo, varPos, nsVarBddArray, &nActiveRows, &nActiveCols, 01608 nonAppearingVarBddArray, direction, option); 01609 SortCol(xy, nActiveRows, nActiveCols, rowInfo, colInfo, rowOrder, colOrder); 01610 01611 clusteredRelationArray = array_alloc(mdd_t *, 0); 01612 arraySmoothVarBddArray = array_alloc(array_t *, 0); 01613 if (direction == Img_Forward_c) { 01614 if (nCols > nActiveCols) { 01615 for (i = nActiveCols; i < nCols; i++) { 01616 col = colOrder[i]; 01617 array_insert_last(bdd_t *, nonAppearingVarBddArray, 01618 bdd_dup(colInfo[col].data.col.var)); 01619 } 01620 } 01621 qVarPos = nActiveCols - 1; 01622 if (qVarPos >= 0) { 01623 col = colOrder[qVarPos]; 01624 while (colInfo[col].gNum == 0) { 01625 array_insert_last(bdd_t *, nonAppearingVarBddArray, 01626 bdd_dup(colInfo[col].data.col.var)); 01627 if (qVarPos == 0) 01628 break; 01629 qVarPos--; 01630 col = colOrder[qVarPos]; 01631 } 01632 } 01633 array_insert_last(array_t *, arraySmoothVarBddArray, 01634 nonAppearingVarBddArray); 01635 for (i = nActiveRows - 1; i >= 0; i--) { 01636 row = rowOrder[i]; 01637 smoothVarBddArray = array_alloc(array_t *, 0); 01638 if (rowInfo[row].gNum > 0) { 01639 col = colOrder[qVarPos]; 01640 while (rowInfo[colInfo[col].gMin].pos == i) { 01641 index = (int)bdd_top_var_id(colInfo[col].data.col.var); 01642 array_insert_last(bdd_t *, smoothVarBddArray, 01643 bdd_dup(colInfo[col].data.col.var)); 01644 if (qVarPos == 0) 01645 break; 01646 qVarPos--; 01647 col = colOrder[qVarPos]; 01648 } 01649 } 01650 array_insert_last(array_t *, arraySmoothVarBddArray, smoothVarBddArray); 01651 relation = bdd_dup(rowInfo[row].data.row.func); 01652 array_insert_last(bdd_t *, clusteredRelationArray, relation); 01653 } 01654 if (nRows > nActiveRows) { 01655 for (i = nActiveRows; i < nRows; i++) { 01656 row = rowOrder[i]; 01657 smoothVarBddArray = array_alloc(array_t *, 0); 01658 array_insert_last(array_t *, arraySmoothVarBddArray, smoothVarBddArray); 01659 relation = bdd_dup(rowInfo[row].data.row.func); 01660 array_insert_last(bdd_t *, clusteredRelationArray, relation); 01661 } 01662 } 01663 } else { 01664 array_insert_last(array_t *, arraySmoothVarBddArray, 01665 nonAppearingVarBddArray); 01666 if (nRows > nActiveRows) { 01667 for (i = nActiveRows; i < nRows; i++) { 01668 row = rowOrder[i]; 01669 smoothVarBddArray = rowInfo[row].data.row.nsVarBddArray; 01670 rowInfo[row].data.row.nsVarBddArray = NIL(array_t); 01671 array_insert_last(array_t *, arraySmoothVarBddArray, smoothVarBddArray); 01672 relation = bdd_dup(rowInfo[row].data.row.func); 01673 array_insert_last(bdd_t *, clusteredRelationArray, relation); 01674 } 01675 } 01676 for (i = 0; i < nActiveRows; i++) { 01677 row = rowOrder[i]; 01678 smoothVarBddArray = array_alloc(array_t *, 0); 01679 for (j = 0; j < array_n(rowInfo[row].data.row.nsVarBddArray); j++) { 01680 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, j); 01681 array_insert_last(bdd_t *, smoothVarBddArray, bdd_dup(nsVar)); 01682 } 01683 if (rowInfo[row].gNum > 0) { 01684 s = colInfo[rowInfo[row].gMin].pos; 01685 t = colInfo[rowInfo[row].gMax].pos; 01686 for (j = s; j <= t; j++) { 01687 col = colOrder[j]; 01688 if (colInfo[col].data.col.type == 2) { 01689 if (rowInfo[colInfo[col].gMax].pos == i) { 01690 array_insert_last(bdd_t *, smoothVarBddArray, 01691 bdd_dup(colInfo[col].data.col.var)); 01692 } 01693 } 01694 } 01695 } 01696 array_insert_last(array_t *, arraySmoothVarBddArray, smoothVarBddArray); 01697 relation = bdd_dup(rowInfo[row].data.row.func); 01698 array_insert_last(bdd_t *, clusteredRelationArray, relation); 01699 } 01700 } 01701 01702 FREE(varPos); 01703 for (i = 0; i < nRows; i++) { 01704 if (xy[i]) 01705 FREE(xy[i]); 01706 } 01707 FREE(xy); 01708 FREE(rowOrder); 01709 FREE(colOrder); 01710 for (i = 0; i < nRows; i++) { 01711 bdd_free(rowInfo[i].data.row.func); 01712 if (rowInfo[i].data.row.nsVarBddArray) 01713 array_free(rowInfo[i].data.row.nsVarBddArray); 01714 } 01715 FREE(rowInfo); 01716 FREE(colInfo); 01717 01718 *clusteredRelationArrayPtr = clusteredRelationArray; 01719 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 01720 } 01721 01722 01732 void 01733 ImgMlpPrintDependenceMatrix(mdd_manager *mddManager, 01734 array_t *relationArray, 01735 array_t *domainVarBddArray, 01736 array_t *quantifyVarBddArray, 01737 array_t *rangeVarBddArray, 01738 Img_DirectionType direction, 01739 int printFlag, FILE *fout, 01740 ImgTrmOption_t *option) 01741 { 01742 int i, nRows, nCols, nActiveRows, nActiveCols; 01743 int *rowOrder, *colOrder; 01744 RcInfo_t *rowInfo, *colInfo; 01745 char **xy; 01746 bdd_t *relation, *var; 01747 int *varPos; 01748 array_t *psVarBddArray, *nsVarBddArray; 01749 int index, nVars, nc; 01750 float lambda1, lambda2, lambda3; 01751 01752 nRows = array_n(relationArray); 01753 if (direction == Img_Forward_c) 01754 nCols = array_n(domainVarBddArray) + array_n(quantifyVarBddArray); 01755 else 01756 nCols = array_n(rangeVarBddArray) + array_n(quantifyVarBddArray); 01757 01758 xy = ALLOC(char *, nRows); 01759 for (i = 0; i < nRows; i++) { 01760 xy[i] = ALLOC(char, nCols); 01761 memset(xy[i], 0, sizeof(char) * nCols); 01762 } 01763 01764 rowOrder = ALLOC(int, nRows); 01765 for (i = 0; i < nRows; i++) 01766 rowOrder[i] = i; 01767 colOrder = ALLOC(int, nCols); 01768 for (i = 0; i < nCols; i++) 01769 colOrder[i] = i; 01770 01771 rowInfo = ALLOC(RcInfo_t, nRows); 01772 memset(rowInfo, 0, sizeof(RcInfo_t) * nRows); 01773 colInfo = ALLOC(RcInfo_t, nCols); 01774 memset(colInfo, 0, sizeof(RcInfo_t) * nCols); 01775 nVars = bdd_num_vars(mddManager); 01776 varPos = ALLOC(int, nVars); 01777 memset(varPos, 0, sizeof(int) * nVars); 01778 01779 psVarBddArray = domainVarBddArray; 01780 nsVarBddArray = rangeVarBddArray; 01781 if (direction == Img_Forward_c) { 01782 for (i = 0; i < nRows; i++) { 01783 relation = array_fetch(bdd_t *, relationArray, nRows - 1 - i); 01784 rowInfo[i].data.row.func = bdd_dup(relation); 01785 } 01786 } else { 01787 for (i = 0; i < nRows; i++) { 01788 relation = array_fetch(bdd_t *, relationArray, i); 01789 rowInfo[i].data.row.func = bdd_dup(relation); 01790 } 01791 } 01792 nc = 0; 01793 for (i = 0; i < array_n(psVarBddArray); i++) { 01794 var = array_fetch(bdd_t *, psVarBddArray, i); 01795 colInfo[nc].data.col.var = var; 01796 colInfo[nc].data.col.type = 1; 01797 index = (int)bdd_top_var_id(var); 01798 varPos[index] = nc; 01799 nc++; 01800 } 01801 for (i = 0; i < array_n(quantifyVarBddArray); i++) { 01802 var = array_fetch(bdd_t *, quantifyVarBddArray, i); 01803 colInfo[nc].data.col.var = var; 01804 colInfo[nc].data.col.type = 2; 01805 index = (int)bdd_top_var_id(var); 01806 varPos[index] = nc; 01807 nc++; 01808 } 01809 01810 SetupMlp(mddManager, xy, nRows, nCols, rowOrder, colOrder, 01811 rowInfo, colInfo, varPos, nsVarBddArray, &nActiveRows, &nActiveCols, 01812 NIL(array_t), direction, option); 01813 SortCol(xy, nActiveRows, nActiveCols, rowInfo, colInfo, rowOrder, colOrder); 01814 01815 if (printFlag) { 01816 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 01817 rowInfo, colInfo, 0, nActiveRows - 1, 0, nActiveCols - 1); 01818 } 01819 if (fout) { 01820 WriteMatrix(fout, xy, nActiveRows, nActiveCols, rowOrder, colOrder, 01821 rowInfo, colInfo); 01822 } 01823 lambda1 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 01824 rowInfo, colInfo, rowOrder, colOrder, 01825 direction, 0, 0, option); 01826 lambda2 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 01827 rowInfo, colInfo, rowOrder, colOrder, 01828 direction, 1, 0, option); 01829 lambda3 = ComputeLambdaMlp(xy, nCols, nActiveRows, nActiveCols, 01830 rowInfo, colInfo, rowOrder, colOrder, 01831 direction, 2, 0, option); 01832 fprintf(vis_stdout, "Lambda = %f (%f, %f)\n", lambda1, lambda2, lambda3); 01833 01834 FREE(varPos); 01835 for (i = 0; i < nRows; i++) { 01836 if (xy[i]) 01837 FREE(xy[i]); 01838 } 01839 FREE(xy); 01840 FREE(rowOrder); 01841 FREE(colOrder); 01842 for (i = 0; i < nRows; i++) { 01843 bdd_free(rowInfo[i].data.row.func); 01844 if (rowInfo[i].data.row.nsVarBddArray) 01845 array_free(rowInfo[i].data.row.nsVarBddArray); 01846 } 01847 FREE(rowInfo); 01848 FREE(colInfo); 01849 } 01850 01851 01861 void 01862 ImgMlpWriteClusterFile(FILE *fout, 01863 mdd_manager *mddManager, 01864 array_t *relationArray, 01865 array_t *psVarBddArray, 01866 array_t *nsVarBddArray) 01867 { 01868 int i, j, k, nVars; 01869 int bddId, mddId, id, index; 01870 mdd_t *relation; 01871 mdd_t *psVar, *nsVar, **nsVars, **ns2ps; 01872 array_t *supportBddIdArray, *bddIdArray; 01873 char *name; 01874 int count; 01875 01876 nVars = bdd_num_vars(mddManager); 01877 nsVars = ALLOC(bdd_t *, nVars); 01878 memset(nsVars, 0, sizeof(bdd_t *) * nVars); 01879 ns2ps = ALLOC(bdd_t *, nVars); 01880 memset(ns2ps, 0, sizeof(bdd_t *) * nVars); 01881 01882 for (i = 0; i < array_n(nsVarBddArray); i++) { 01883 psVar = array_fetch(bdd_t *, psVarBddArray, i); 01884 nsVar = array_fetch(bdd_t *, nsVarBddArray, i); 01885 index = (int)bdd_top_var_id(nsVar); 01886 nsVars[index] = nsVar; 01887 ns2ps[index] = psVar; 01888 } 01889 01890 count = 0; 01891 for (i = 0; i < array_n(relationArray); i++) { 01892 relation = array_fetch(mdd_t *, relationArray, i); 01893 supportBddIdArray = mdd_get_bdd_support_ids(mddManager, relation); 01894 psVar = NULL; 01895 for (j = 0; j < array_n(supportBddIdArray); j++) { 01896 bddId = array_fetch(int, supportBddIdArray, j); 01897 psVar = ns2ps[bddId]; 01898 if (psVar) { 01899 break; 01900 } 01901 } 01902 if (psVar) { 01903 if (count == 0) 01904 fprintf(fout, "CLUSTER[%d] {\n", count); 01905 else 01906 fprintf(fout, "\nCLUSTER[%d] {\n", count); 01907 count++; 01908 } 01909 for (j = 0; j < array_n(supportBddIdArray); j++) { 01910 bddId = array_fetch(int, supportBddIdArray, j); 01911 psVar = ns2ps[bddId]; 01912 if (psVar) { 01913 name = mdd_read_var_name(psVar); 01914 nsVar = nsVars[bddId]; 01915 mddId = mdd_read_mdd_id(nsVar); 01916 bddIdArray = mdd_id_to_bdd_id_array(mddManager, mddId); 01917 for (k = 0; k < array_n(bddIdArray); k++) { 01918 id = array_fetch(int, bddIdArray, k); 01919 if (id == bddId) { 01920 fprintf(fout, "%s %d\n", name, k); 01921 break; 01922 } 01923 } 01924 array_free(bddIdArray); 01925 } 01926 } 01927 array_free(supportBddIdArray); 01928 fprintf(fout, "}\n"); 01929 } 01930 01931 FREE(nsVars); 01932 FREE(ns2ps); 01933 } 01934 01935 01936 01937 01947 void 01948 ImgMlpReadClusterFile(FILE *fin, mdd_manager *mddManager, 01949 ImgFunctionData_t *functionData, 01950 array_t *relationArray, 01951 array_t *psVarBddArray, 01952 array_t *nsVarBddArray, 01953 array_t *quantifyVarBddArray, 01954 Img_DirectionType direction, 01955 array_t **clusteredRelationArrayPtr, 01956 array_t **arraySmoothVarBddArrayPtr, 01957 ImgTrmOption_t *option) 01958 { 01959 array_t *clusteredRelationArray, *newRelationArray; 01960 array_t *arraySmoothVarBddArray; 01961 int i, j, k, nVars; 01962 long bddId; 01963 int mddId, id, index; 01964 mdd_t *relation, *cluster, *newCluster; 01965 mdd_t *var, *psVar, *nsVar, **nsVars, **ns2ps; 01966 array_t *supportBddIdArray, *bddIdArray; 01967 char *name; 01968 LatchList_t **latchList; 01969 st_table *intermediateTable, *nameTable, *quantifyVarsTable, *idTable; 01970 int nRelVars, relBddId, relMddId; 01971 mdd_t *relVar; 01972 char *resolved; 01973 char line[512], nameArray[512]; 01974 st_generator *stGen1, *stGen2; 01975 01976 nVars = bdd_num_vars(mddManager); 01977 nsVars = ALLOC(bdd_t *, nVars); 01978 memset(nsVars, 0, sizeof(bdd_t *) * nVars); 01979 ns2ps = ALLOC(bdd_t *, nVars); 01980 memset(ns2ps, 0, sizeof(bdd_t *) * nVars); 01981 latchList = ALLOC(LatchList_t *, nVars); 01982 memset(latchList, 0, sizeof(LatchList_t *) * nVars); 01983 resolved = ALLOC(char, nVars); 01984 memset(resolved, 0, sizeof(char) * nVars); 01985 01986 quantifyVarsTable = st_init_table(st_numcmp, st_numhash); 01987 for (i = 0; i < array_n(functionData->quantifyBddVars); i++) { 01988 var = array_fetch(mdd_t *, functionData->quantifyBddVars, i); 01989 index = (int)bdd_top_var_id(var); 01990 st_insert(quantifyVarsTable, (char *)(long)index, NIL(char)); 01991 } 01992 01993 nameTable = st_init_table(strcmp, st_strhash); 01994 for (i = 0; i < array_n(nsVarBddArray); i++) { 01995 psVar = array_fetch(bdd_t *, psVarBddArray, i); 01996 nsVar = array_fetch(bdd_t *, nsVarBddArray, i); 01997 index = (int)bdd_top_var_id(nsVar); 01998 nsVars[index] = nsVar; 01999 ns2ps[index] = psVar; 02000 name = mdd_read_var_name(psVar); 02001 mddId = mdd_read_mdd_id(nsVar); 02002 st_insert(nameTable, name, (char *)(long)mddId); 02003 02004 index = (int)bdd_top_var_id(psVar); 02005 st_insert(quantifyVarsTable, (char *)(long)index, NIL(char)); 02006 } 02007 02008 i = 0; 02009 st_foreach_item_int(nameTable, stGen1, &name, &mddId) { 02010 printf("[%d] name = %s mdd = %d\n", i, name, mddId); 02011 i++; 02012 } 02013 02014 intermediateTable = st_init_table(st_ptrcmp, st_ptrhash); 02015 for (i = 0; i < array_n(relationArray); i++) { 02016 relation = array_fetch(mdd_t *, relationArray, i); 02017 supportBddIdArray = mdd_get_bdd_support_ids(mddManager, relation); 02018 nRelVars = 0; 02019 psVar = NIL(bdd_t); 02020 nsVar = NIL(bdd_t); 02021 relVar = NIL(bdd_t); 02022 relBddId = -1; 02023 relMddId = -1; 02024 idTable = st_init_table(st_numcmp, st_numhash); 02025 for (j = 0; j < array_n(supportBddIdArray); j++) { 02026 bddId = (long) array_fetch(int, supportBddIdArray, j); 02027 if (st_lookup(quantifyVarsTable, (char *)bddId, NIL(char *))) 02028 continue; 02029 psVar = ns2ps[bddId]; 02030 if (psVar) { 02031 if (relVar) { 02032 bdd_free(relVar); 02033 relVar = NIL(bdd_t); 02034 } 02035 nsVar = nsVars[bddId]; 02036 relMddId = mdd_read_mdd_id(nsVar); 02037 relBddId = (int) bddId; 02038 break; 02039 } else { 02040 if (nRelVars > 0) { 02041 if (relVar) 02042 bdd_free(relVar); 02043 } 02044 relVar = bdd_var_with_index(mddManager, (int) bddId); 02045 relMddId = mdd_read_mdd_id(relVar); 02046 relBddId = (int) bddId; 02047 name = mdd_read_var_name(relVar); 02048 st_insert(nameTable, name, (char *)(long)relMddId); 02049 st_insert(idTable, (char *)bddId, NIL(char)); 02050 if (nRelVars >= 1) { 02051 bdd_free(relVar); 02052 relVar = NIL(bdd_t); 02053 } 02054 nRelVars++; 02055 } 02056 } 02057 array_free(supportBddIdArray); 02058 if (nsVar || relVar) { 02059 bddId = (int) relBddId; 02060 mddId = relMddId; 02061 02062 if (relVar) 02063 resolved[bddId] = 1; 02064 02065 bddIdArray = mdd_id_to_bdd_id_array(mddManager, mddId); 02066 for (k = 0; k < array_n(bddIdArray); k++) { 02067 id = array_fetch(int, bddIdArray, k); 02068 if (id == bddId) { 02069 if (latchList[mddId]) { 02070 if (latchList[mddId]->number == 1) { 02071 latchList[mddId]->table = st_init_table(st_numcmp, st_numhash); 02072 st_insert(latchList[mddId]->table, 02073 (char *)(long)latchList[mddId]->bddId, 02074 (char *)latchList[mddId]->relation); 02075 } 02076 st_insert(latchList[mddId]->table, (char *)bddId, 02077 (char *)relation); 02078 } else { 02079 latchList[mddId] = ALLOC(LatchList_t, 1); 02080 latchList[mddId]->bddId = (int) bddId; 02081 latchList[mddId]->relation = relation; 02082 latchList[mddId]->number = 1; 02083 latchList[mddId]->table = NIL(st_table); 02084 } 02085 break; 02086 } 02087 } 02088 array_free(bddIdArray); 02089 st_free_table(idTable); 02090 } else { 02091 st_insert(intermediateTable, (char *)relation, (char *)idTable); 02092 } 02093 } 02094 02095 i = 0; 02096 st_foreach_item_int(nameTable, stGen1, &name, &mddId) { 02097 printf("[%d] name = %s mdd = %d\n", i, name, mddId); 02098 i++; 02099 } 02100 02101 while (intermediateTable->num_entries > 0) { 02102 st_foreach_item(intermediateTable, stGen1, &relation, &idTable) { 02103 st_foreach_item(idTable, stGen2, &bddId, NIL(char *)) { 02104 if (resolved[bddId]) 02105 st_delete(idTable, &bddId, NIL(char *)); 02106 } 02107 if (idTable->num_entries == 1) { 02108 st_foreach_item(idTable, stGen2, &bddId, NULL); 02109 relVar = bdd_var_with_index(mddManager, (int) bddId); 02110 mddId = mdd_read_mdd_id(relVar); 02111 mdd_free(relVar); 02112 02113 st_delete(intermediateTable, &relation, NULL); 02114 02115 bddIdArray = mdd_id_to_bdd_id_array(mddManager, mddId); 02116 for (k = 0; k < array_n(bddIdArray); k++) { 02117 id = array_fetch(int, bddIdArray, k); 02118 if (id == bddId) { 02119 if (latchList[mddId]) { 02120 if (latchList[mddId]->number == 1) { 02121 latchList[mddId]->table = st_init_table(st_numcmp, st_numhash); 02122 st_insert(latchList[mddId]->table, 02123 (char *)(long)latchList[mddId]->bddId, 02124 (char *)latchList[mddId]->relation); 02125 } 02126 st_insert(latchList[mddId]->table, (char *)bddId, 02127 (char *)relation); 02128 } else { 02129 latchList[mddId] = ALLOC(LatchList_t, 1); 02130 latchList[mddId]->bddId = (int) bddId; 02131 latchList[mddId]->relation = relation; 02132 latchList[mddId]->number = 1; 02133 latchList[mddId]->table = NIL(st_table); 02134 } 02135 break; 02136 } 02137 } 02138 array_free(bddIdArray); 02139 } 02140 } 02141 } 02142 st_free_table(intermediateTable); 02143 02144 i = 0; 02145 st_foreach_item_int(nameTable, stGen1, &name, &mddId) { 02146 printf("[%d] name = %s mdd = %d\n", i, name, mddId); 02147 i++; 02148 } 02149 02150 cluster = NIL(mdd_t); 02151 clusteredRelationArray = array_alloc(mdd_t *, 0); 02152 while (fgets(line, 512, fin)) { 02153 if (line[0] == '\n' || line[0] == '#') 02154 continue; 02155 if (strncmp(line, "CLUSTER", 7) == 0) 02156 cluster = mdd_one(mddManager); 02157 else if (strncmp(line, "}", 1) == 0) 02158 array_insert_last(mdd_t *, clusteredRelationArray, cluster); 02159 else { 02160 sscanf(line, "%s %d", nameArray, &id); 02161 if (st_lookup_int(nameTable, nameArray, &mddId) == 0) 02162 assert(0); 02163 if (latchList[mddId]) { 02164 if (latchList[mddId]->table) { 02165 bddIdArray = mdd_id_to_bdd_id_array(mddManager, mddId); 02166 assert(id < array_n(bddIdArray)); 02167 bddId = (long) array_fetch(int, bddIdArray, id); 02168 if (st_lookup(latchList[mddId]->table, (char *)bddId, &relation)) { 02169 latchList[mddId]->number--; 02170 if (latchList[mddId]->number == 0) { 02171 st_free_table(latchList[mddId]->table); 02172 FREE(latchList[mddId]); 02173 latchList[mddId] = NIL(LatchList_t); 02174 } 02175 } else 02176 assert(0); 02177 } else { 02178 relation = latchList[mddId]->relation; 02179 FREE(latchList[mddId]); 02180 latchList[mddId] = NIL(LatchList_t); 02181 } 02182 newCluster = bdd_and(cluster, relation, 1, 1); 02183 mdd_free(cluster); 02184 cluster = newCluster; 02185 } else 02186 assert(0); 02187 } 02188 } 02189 02190 for (i = 0; i < nVars; i++) { 02191 if (latchList[i]) { 02192 if (latchList[i]->table) { 02193 st_foreach_item(latchList[i]->table, stGen1, &bddId, &relation) { 02194 cluster = bdd_dup(relation); 02195 array_insert_last(mdd_t *, clusteredRelationArray, cluster); 02196 } 02197 st_free_table(latchList[i]->table); 02198 } else { 02199 cluster = bdd_dup(latchList[i]->relation); 02200 array_insert_last(mdd_t *, clusteredRelationArray, cluster); 02201 } 02202 FREE(latchList[i]); 02203 } 02204 } 02205 02206 FREE(nsVars); 02207 FREE(ns2ps); 02208 FREE(resolved); 02209 FREE(latchList); 02210 02211 st_free_table(nameTable); 02212 st_free_table(quantifyVarsTable); 02213 02214 if (arraySmoothVarBddArrayPtr) { 02215 ImgMlpGetQuantificationSchedule(mddManager, 02216 clusteredRelationArray, psVarBddArray, quantifyVarBddArray, 02217 nsVarBddArray, &newRelationArray, &arraySmoothVarBddArray, 02218 direction, option); 02219 mdd_array_free(clusteredRelationArray); 02220 clusteredRelationArray = newRelationArray; 02221 } else 02222 arraySmoothVarBddArray = NIL(array_t); 02223 02224 *clusteredRelationArrayPtr = clusteredRelationArray; 02225 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 02226 } 02227 02228 02229 /*---------------------------------------------------------------------------*/ 02230 /* Definition of static functions */ 02231 /*---------------------------------------------------------------------------*/ 02232 02242 static void 02243 SetupMlp(mdd_manager *mddManager, 02244 char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, 02245 RcInfo_t *rowInfo, RcInfo_t *colInfo, int *varPos, 02246 array_t *nsVarBddArray, int *nActiveRows, int *nActiveCols, 02247 array_t *nonAppearingVarBddArray, 02248 Img_DirectionType direction, ImgTrmOption_t *option) 02249 { 02250 int i, j, x, y, s, t; 02251 int row, col, otherCol, nr, nc, index; 02252 long initialTime, finalTime; 02253 bdd_t *relation, *nsVar; 02254 array_t *supportArray, *localVarBddArray; 02255 int support; 02256 array_t **arrayLocalVarBddArray; 02257 float lambda1, lambda2, lambda3; 02258 bdd_t **nsVarArray; 02259 int nVars; 02260 02261 if (option->mlpVerbosity >= 2) 02262 initialTime = util_cpu_time(); 02263 else 02264 initialTime = 0; 02265 02266 nVars = bdd_num_vars(mddManager); 02267 nsVarArray = ALLOC(bdd_t *, nVars); 02268 memset(nsVarArray, 0, sizeof(bdd_t *) * nVars); 02269 for (i = 0; i < array_n(nsVarBddArray); i++) { 02270 nsVar = array_fetch(bdd_t *, nsVarBddArray, i); 02271 index = (int)bdd_top_var_id(nsVar); 02272 nsVarArray[index] = nsVar; 02273 } 02274 02275 for (i = 0; i < nRows; i++) { 02276 relation = rowInfo[i].data.row.func; 02277 rowInfo[i].data.row.nsVarBddArray = array_alloc(bdd_t *, 0); 02278 supportArray = mdd_get_bdd_support_ids(mddManager, relation); 02279 for (j = 0; j < array_n(supportArray); j++) { 02280 support = array_fetch(int, supportArray, j); 02281 nsVar = nsVarArray[support]; 02282 if (nsVar) { 02283 array_insert_last(bdd_t *, rowInfo[i].data.row.nsVarBddArray, nsVar); 02284 if (varPos[support]) 02285 xy[i][varPos[support]] = 1; 02286 else { 02287 index = (int)bdd_top_var_id(colInfo[0].data.col.var); 02288 if (index == support) 02289 xy[i][varPos[support]] = 1; 02290 } 02291 } else 02292 xy[i][varPos[support]] = 1; 02293 } 02294 array_free(supportArray); 02295 } 02296 FREE(nsVarArray); 02297 02298 for (x = 0; x < nRows; x++) { 02299 rowInfo[x].gMin = nCols; 02300 rowInfo[x].gMax = -1; 02301 rowInfo[x].pos = x; 02302 rowInfo[x].prevG = -1; 02303 rowInfo[x].nextG = nCols; 02304 } 02305 for (y = 0; y < nCols; y++) { 02306 colInfo[y].gMin = nRows; 02307 colInfo[y].gMax = -1; 02308 colInfo[y].pos = y; 02309 colInfo[y].prevG = -1; 02310 colInfo[y].nextG = nRows; 02311 } 02312 02313 for (x = 0; x < nRows; x++) { 02314 for (y = 0; y < nCols; y++) { 02315 if (xy[x][y]) { 02316 if (x < colInfo[y].gMin) 02317 colInfo[y].gMin = x; 02318 if (x > colInfo[y].gMax) 02319 colInfo[y].gMax = x; 02320 if (y < rowInfo[x].gMin) 02321 rowInfo[x].gMin = y; 02322 if (y > rowInfo[x].gMax) 02323 rowInfo[x].gMax = y; 02324 rowInfo[x].gNum++; 02325 colInfo[y].gNum++; 02326 } 02327 } 02328 } 02329 02330 nc = nCols; 02331 arrayLocalVarBddArray = ALLOC(array_t *, nRows); 02332 memset(arrayLocalVarBddArray, 0, sizeof(array_t *) * nRows); 02333 for (y = 0; y < nc; y++) { 02334 col = colOrder[y]; 02335 if (colInfo[col].data.col.type == 2 && colInfo[col].gNum == 1) { 02336 row = colInfo[col].gMin; 02337 rowInfo[row].gNum--; 02338 if (rowInfo[row].gNum == 1) { 02339 if (rowInfo[row].gMin == col) { 02340 rowInfo[row].gMin = rowInfo[row].gMax; 02341 rowInfo[row].lMin = rowInfo[row].lMax; 02342 } else { 02343 rowInfo[row].gMax = rowInfo[row].gMin; 02344 rowInfo[row].lMax = rowInfo[row].lMin; 02345 } 02346 } else if (rowInfo[row].gNum > 1) { 02347 if (rowInfo[row].gMin == col) { 02348 s = colInfo[rowInfo[row].gMin].pos; 02349 t = colInfo[rowInfo[row].gMax].pos; 02350 for (j = s + 1; j <= t; j++) { 02351 otherCol = colOrder[j]; 02352 if (xy[row][otherCol]) { 02353 rowInfo[row].gMin = otherCol; 02354 rowInfo[row].lMin = otherCol; 02355 break; 02356 } 02357 } 02358 } else if (rowInfo[row].gMax == col) { 02359 s = colInfo[rowInfo[row].gMin].pos; 02360 t = colInfo[rowInfo[row].gMax].pos; 02361 for (j = t - 1; j >= s; j--) { 02362 otherCol = colOrder[j]; 02363 if (xy[row][otherCol]) { 02364 rowInfo[row].gMax = otherCol; 02365 rowInfo[row].lMax = otherCol; 02366 break; 02367 } 02368 } 02369 } 02370 } 02371 02372 for (j = y; j < nc - 1; j++) { 02373 colOrder[j] = colOrder[j + 1]; 02374 colInfo[colOrder[j]].pos = j; 02375 } 02376 colOrder[nc - 1] = col; 02377 colInfo[col].pos = nc - 1; 02378 02379 nc--; 02380 y--; 02381 02382 if (!arrayLocalVarBddArray[row]) 02383 arrayLocalVarBddArray[row] = array_alloc(bdd_t *, 0); 02384 array_insert_last(bdd_t *, arrayLocalVarBddArray[row], 02385 colInfo[col].data.col.var); 02386 } 02387 } 02388 02389 if (direction == Img_Backward_c) { 02390 long lindex; 02391 st_table *unusedNsTable; 02392 st_generator *gen; 02393 02394 unusedNsTable = st_init_table(st_numcmp, st_numhash); 02395 for (i = 0; i < array_n(nsVarBddArray); i++) { 02396 nsVar = array_fetch(bdd_t *, nsVarBddArray, i); 02397 lindex = (long) bdd_top_var_id(nsVar); 02398 st_insert(unusedNsTable, (char *)lindex, (char *)nsVar); 02399 } 02400 for (i = 0; i < nRows; i++) { 02401 for (j = 0; j < array_n(rowInfo[i].data.row.nsVarBddArray); j++) { 02402 nsVar = array_fetch(bdd_t *, rowInfo[i].data.row.nsVarBddArray, j); 02403 lindex = (long) bdd_top_var_id(nsVar); 02404 st_delete(unusedNsTable, &lindex, NULL); 02405 } 02406 } 02407 st_foreach_item(unusedNsTable, gen, &lindex, &nsVar) { 02408 array_insert_last(bdd_t *, nonAppearingVarBddArray, bdd_dup(nsVar)); 02409 } 02410 st_free_table(unusedNsTable); 02411 } 02412 02413 for (i = 0; i < nRows; i++) { 02414 localVarBddArray = arrayLocalVarBddArray[i]; 02415 if (localVarBddArray) { 02416 relation = bdd_smooth(rowInfo[i].data.row.func, localVarBddArray); 02417 if (nonAppearingVarBddArray && direction == Img_Backward_c && 02418 bdd_is_tautology(relation, 1)) { 02419 for (j = 0; j < array_n(rowInfo[i].data.row.nsVarBddArray); j++) { 02420 nsVar = array_fetch(bdd_t *, rowInfo[i].data.row.nsVarBddArray, j); 02421 array_insert_last(bdd_t *, nonAppearingVarBddArray, bdd_dup(nsVar)); 02422 } 02423 } 02424 bdd_free(rowInfo[i].data.row.func); 02425 rowInfo[i].data.row.func = relation; 02426 UpdateDisapearingPsVars(mddManager, xy, nRows, nCols, 02427 rowOrder, colOrder, rowInfo, colInfo, 02428 i, option); 02429 if (localVarBddArray) 02430 array_free(localVarBddArray); 02431 } 02432 } 02433 FREE(arrayLocalVarBddArray); 02434 02435 for (y = 0; y < nc; y++) { 02436 col = colOrder[y]; 02437 if (colInfo[col].gNum == 0) { 02438 if (nonAppearingVarBddArray && 02439 direction == Img_Forward_c && colInfo[col].data.col.type == 1) { 02440 array_insert_last(bdd_t *, nonAppearingVarBddArray, 02441 bdd_dup(colInfo[col].data.col.var)); 02442 } 02443 for (j = y; j < nc - 1; j++) { 02444 colOrder[j] = colOrder[j + 1]; 02445 colInfo[colOrder[j]].pos = j; 02446 } 02447 colOrder[nc - 1] = col; 02448 colInfo[col].pos = nc - 1; 02449 nc--; 02450 y--; 02451 } 02452 } 02453 02454 nr = nRows; 02455 for (x = 0; x < nr; x++) { 02456 row = rowOrder[x]; 02457 if (rowInfo[row].gNum == 0) { 02458 for (i = x; i < nr - 1; i++) { 02459 rowOrder[i] = rowOrder[i + 1]; 02460 rowInfo[rowOrder[i]].pos = i; 02461 } 02462 rowOrder[nr - 1] = row; 02463 rowInfo[row].pos = nr - 1; 02464 nr--; 02465 x--; 02466 } 02467 } 02468 02469 for (x = 0; x < nr; x++) { 02470 row = rowOrder[x]; 02471 rowInfo[row].lMin = rowInfo[row].gMin; 02472 rowInfo[row].lMax = rowInfo[row].gMax; 02473 rowInfo[row].lNum = rowInfo[row].gNum; 02474 if (nc != nCols && rowInfo[row].nextG == nCols) 02475 rowInfo[row].nextG = nc; 02476 } 02477 for (y = 0; y < nc; y++) { 02478 col = colOrder[y]; 02479 colInfo[col].lMin = colInfo[col].gMin; 02480 colInfo[col].lMax = colInfo[col].gMax; 02481 colInfo[col].lNum = colInfo[col].gNum; 02482 if (nr != nRows && colInfo[col].nextG == nRows) 02483 colInfo[col].nextG = nr; 02484 } 02485 if (option->mlpVerbosity >= 2) { 02486 finalTime = util_cpu_time(); 02487 fprintf(vis_stdout, "time for setup = %10g\n", 02488 (double)(finalTime - initialTime) / 1000.0); 02489 02490 lambda1 = ComputeLambdaMlp(xy, nCols, nr, nc, rowInfo, colInfo, 02491 rowOrder, colOrder, direction, 0, 0, option); 02492 lambda2 = ComputeLambdaMlp(xy, nCols, nr, nc, rowInfo, colInfo, 02493 rowOrder, colOrder, direction, 1, 0, option); 02494 lambda3 = ComputeLambdaMlp(xy, nCols, nr, nc, rowInfo, colInfo, 02495 rowOrder, colOrder, direction, 2, 0, option); 02496 fprintf(vis_stdout, "Initial Lambda = %f (%f, %f)\n", 02497 lambda1, lambda2, lambda3); 02498 } 02499 02500 if (option->mlpDebug) { 02501 CheckMatrix(xy, NIL(SccList_t), nr, nc, rowInfo, colInfo, 02502 rowOrder, colOrder, 0, nr - 1, 0, nc - 1, 1); 02503 } 02504 02505 *nActiveRows = nr; 02506 *nActiveCols = nc; 02507 } 02508 02509 02519 static SccList_t * 02520 MlpDecomposeScc(mdd_manager *mddManager, char **xy, int nRows, 02521 int nActiveRows, int nActiveCols, int *rowOrder, int *colOrder, 02522 RcInfo_t *rowInfo, RcInfo_t *colInfo, 02523 int clusteredFlag, ImgTrmOption_t *option) 02524 { 02525 int i, j, x, y, size, nVars; 02526 int startRow, startCol; 02527 int nGroups, nChosen; 02528 int row, col, otherRow; 02529 int s1, t1, s2, t2; 02530 char *rowFlag, *colFlag, *stackFlag; 02531 int *stack; 02532 SccList_t *sccHeadList, *sccTailList, *sccList; 02533 array_t *rowScc, *colScc, *sccArray; 02534 long initialTime, finalTime; 02535 int *newRowOrder, *newColOrder; 02536 int nCurRows, nCurCols; 02537 02538 if (!option->mlpDecomposeScc) { 02539 sccList = ALLOC(SccList_t, 1); 02540 sccList->nFuncs = nActiveRows; 02541 sccList->nVars = nActiveCols; 02542 sccList->startFunc = 0; 02543 sccList->lastFunc = nActiveRows - 1; 02544 sccList->startVar = 0; 02545 sccList->lastVar = nActiveCols - 1; 02546 sccList->next = NIL(SccList_t); 02547 return(sccList); 02548 } 02549 02550 if (option->mlpVerbosity >= 2) 02551 initialTime = util_cpu_time(); 02552 else 02553 initialTime = 0; 02554 02555 sccHeadList = NIL(SccList_t); 02556 sccTailList = NIL(SccList_t); 02557 02558 rowFlag = ALLOC(char, nRows); 02559 memset(rowFlag, 0, sizeof(char) * nRows); 02560 nVars = bdd_num_vars(mddManager); 02561 colFlag = ALLOC(char, nVars); 02562 memset(colFlag, 0, sizeof(char) * nVars); 02563 stack = ALLOC(int, nActiveRows); 02564 stackFlag = ALLOC(char, nRows); 02565 memset(stackFlag, 0, sizeof(char) * nRows); 02566 02567 startRow = 0; 02568 startCol = 0; 02569 nGroups = 0; 02570 nChosen = 0; 02571 while (nChosen < nActiveRows) { 02572 rowScc = array_alloc(int, 0); 02573 colScc = array_alloc(int, 0); 02574 02575 size = 0; 02576 for (i = startRow; i < nActiveRows; i++) { 02577 row = rowOrder[i]; 02578 if (rowFlag[row] == 0) { 02579 stack[0] = row; 02580 size = 1; 02581 stackFlag[row] = 1; 02582 break; 02583 } 02584 } 02585 02586 while (size) { 02587 if (size + array_n(rowScc) == nRows) { 02588 FREE(stack); 02589 FREE(stackFlag); 02590 FREE(rowFlag); 02591 FREE(colFlag); 02592 array_free(rowScc); 02593 array_free(colScc); 02594 02595 sccList = ALLOC(SccList_t, 1); 02596 sccList->nFuncs = nActiveRows; 02597 sccList->nVars = nActiveCols; 02598 sccList->startFunc = 0; 02599 sccList->lastFunc = nActiveRows - 1; 02600 sccList->startVar = 0; 02601 sccList->lastVar = nActiveCols - 1; 02602 sccList->next = NIL(SccList_t); 02603 return(sccList); 02604 } 02605 02606 size--; 02607 row = stack[size]; 02608 x = rowInfo[row].pos; 02609 rowFlag[row] = nGroups + 1; 02610 array_insert_last(int, rowScc, x); 02611 nChosen++; 02612 s1 = colInfo[rowInfo[row].gMin].pos; 02613 t1 = colInfo[rowInfo[row].gMax].pos; 02614 for (y = s1; y <= t1; y++) { 02615 col = colOrder[y]; 02616 if (colInfo[col].gNum == nRows) { 02617 FREE(stack); 02618 FREE(stackFlag); 02619 FREE(rowFlag); 02620 FREE(colFlag); 02621 array_free(rowScc); 02622 array_free(colScc); 02623 02624 sccList = ALLOC(SccList_t, 1); 02625 sccList->nFuncs = nActiveRows; 02626 sccList->nVars = nActiveCols; 02627 sccList->startFunc = 0; 02628 sccList->lastFunc = nActiveRows - 1; 02629 sccList->startVar = 0; 02630 sccList->lastVar = nActiveCols - 1; 02631 sccList->next = NIL(SccList_t); 02632 return(sccList); 02633 } 02634 if (!xy[row][col] || colFlag[col]) 02635 continue; 02636 colFlag[col] = nGroups + 1; 02637 array_insert_last(int, colScc, y); 02638 s2 = rowInfo[colInfo[col].gMin].pos; 02639 t2 = rowInfo[colInfo[col].gMax].pos; 02640 for (i = s2; i <= t2; i++) { 02641 otherRow = rowOrder[i]; 02642 if (rowFlag[otherRow] || stackFlag[otherRow]) 02643 continue; 02644 if (xy[otherRow][col]) { 02645 stack[size] = otherRow; 02646 size++; 02647 stackFlag[otherRow] = 1; 02648 } 02649 } 02650 } 02651 } 02652 02653 nGroups++; 02654 if (nGroups == 1 && nChosen == nActiveRows) { 02655 sccList = ALLOC(SccList_t, 1); 02656 sccList->nFuncs = nActiveRows; 02657 sccList->nVars = nActiveCols; 02658 sccList->startFunc = 0; 02659 sccList->lastFunc = nActiveRows - 1; 02660 sccList->startVar = 0; 02661 sccList->lastVar = nActiveCols - 1; 02662 sccList->next = NIL(SccList_t); 02663 02664 sccHeadList = sccList; 02665 02666 array_free(rowScc); 02667 array_free(colScc); 02668 break; 02669 } 02670 02671 /* Move the rows and columns that belong to the current group to top-left */ 02672 array_sort(rowScc, SccSortRc); 02673 array_sort(colScc, SccSortRc); 02674 for (i = 0; i < array_n(rowScc); i++) { 02675 x = array_fetch(int, rowScc, i); 02676 if (x == startRow + i) 02677 continue; 02678 row = rowOrder[x]; 02679 for (j = x; j > startRow + i; j--) { 02680 rowOrder[j] = rowOrder[j - 1]; 02681 rowInfo[rowOrder[j]].pos = j; 02682 } 02683 rowOrder[startRow + i] = row; 02684 rowInfo[row].pos = startRow + i; 02685 } 02686 for (i = 0; i < array_n(colScc); i++) { 02687 y = array_fetch(int, colScc, i); 02688 if (y == startCol + i) 02689 continue; 02690 col = colOrder[y]; 02691 for (j = y; j > startCol + i; j--) { 02692 colOrder[j] = colOrder[j - 1]; 02693 colInfo[colOrder[j]].pos = j; 02694 } 02695 colOrder[startCol + i] = col; 02696 colInfo[col].pos = startCol + i; 02697 } 02698 02699 sccList = ALLOC(SccList_t, 1); 02700 sccList->nFuncs = array_n(rowScc); 02701 sccList->nVars = array_n(colScc); 02702 sccList->startFunc = startRow; 02703 sccList->lastFunc = startRow + sccList->nFuncs - 1; 02704 sccList->startVar = startCol; 02705 sccList->lastVar = startCol + sccList->nVars - 1; 02706 sccList->next = NIL(SccList_t); 02707 startRow += sccList->nFuncs; 02708 startCol += sccList->nVars; 02709 02710 if (sccTailList) 02711 sccTailList->next = sccList; 02712 else 02713 sccHeadList = sccList; 02714 sccTailList = sccList; 02715 02716 array_free(rowScc); 02717 array_free(colScc); 02718 02719 if (option->mlpDebug) { 02720 CheckMatrix(xy, NIL(SccList_t), nActiveRows, nActiveCols, 02721 rowInfo, colInfo, rowOrder, colOrder, 02722 0, nActiveRows - 1, 0, nActiveCols - 1, 1); 02723 } 02724 } 02725 02726 FREE(stack); 02727 FREE(stackFlag); 02728 FREE(rowFlag); 02729 FREE(colFlag); 02730 02731 if (option->mlpSortScc && clusteredFlag == 0) { 02732 sccArray = array_alloc(SccList_t *, 0); 02733 sccList = sccHeadList; 02734 while (sccList) { 02735 array_insert_last(SccList_t *, sccArray, sccList); 02736 sccList = sccList->next; 02737 } 02738 02739 if (option->mlpSortSccMode == 0) { 02740 if (option->mlpSortScc == 1) 02741 array_sort(sccArray, SccSortListIncreasingWithArea); 02742 else 02743 array_sort(sccArray, SccSortListDecreasingWithArea); 02744 } else if (option->mlpSortSccMode == 1) { 02745 if (option->mlpSortScc == 1) 02746 array_sort(sccArray, SccSortListIncreasingWithVars); 02747 else 02748 array_sort(sccArray, SccSortListDecreasingWithVars); 02749 } else { 02750 if (option->mlpSortScc == 1) 02751 array_sort(sccArray, SccSortListIncreasingWithRatio); 02752 else 02753 array_sort(sccArray, SccSortListDecreasingWithRatio); 02754 } 02755 02756 newRowOrder = ALLOC(int, nActiveRows); 02757 newColOrder = ALLOC(int, nActiveCols); 02758 02759 nCurRows = 0; 02760 nCurCols = 0; 02761 sccHeadList = NIL(SccList_t); 02762 for (i = 0; i < array_n(sccArray); i++) { 02763 sccList = array_fetch(SccList_t *, sccArray, i); 02764 if (sccHeadList) 02765 sccTailList->next = sccList; 02766 else 02767 sccHeadList = sccList; 02768 sccTailList = sccList; 02769 sccList->next = NIL(SccList_t); 02770 02771 for (j = sccList->startFunc; j <= sccList->lastFunc; j++) { 02772 row = rowOrder[j]; 02773 newRowOrder[nCurRows + j - sccList->startFunc] = rowOrder[j]; 02774 rowInfo[row].pos = nCurRows + j - sccList->startFunc; 02775 } 02776 sccList->startFunc = nCurRows; 02777 sccList->lastFunc = nCurRows + sccList->nFuncs - 1; 02778 nCurRows += sccList->nFuncs; 02779 02780 for (j = sccList->startVar; j <= sccList->lastVar; j++) { 02781 col = colOrder[j]; 02782 newColOrder[nCurCols + j - sccList->startVar] = colOrder[j]; 02783 colInfo[col].pos = nCurCols + j - sccList->startVar; 02784 } 02785 sccList->startVar = nCurCols; 02786 sccList->lastVar = nCurCols + sccList->nVars - 1; 02787 nCurCols += sccList->nVars; 02788 } 02789 02790 memcpy(rowOrder, newRowOrder, sizeof(int) * nActiveRows); 02791 memcpy(colOrder, newColOrder, sizeof(int) * nActiveCols); 02792 02793 if (option->mlpDebug) { 02794 CheckMatrix(xy, NIL(SccList_t), nActiveRows, nActiveCols, 02795 rowInfo, colInfo, rowOrder, colOrder, 02796 0, nActiveRows - 1, 0, nActiveCols - 1, 1); 02797 } 02798 02799 FREE(newRowOrder); 02800 FREE(newColOrder); 02801 array_free(sccArray); 02802 } 02803 02804 if (option->mlpVerbosity >= 2) { 02805 finalTime = util_cpu_time(); 02806 fprintf(vis_stdout, "time for scc decomposition = %10g (#scc=%d)\n", 02807 (double)(finalTime - initialTime) / 1000.0, nGroups); 02808 } 02809 02810 return(sccHeadList); 02811 } 02812 02813 02823 static int 02824 SccSortListIncreasingWithVars(const void *p1, const void *p2) 02825 { 02826 SccList_t **scc1 = (SccList_t **) p1; 02827 SccList_t **scc2 = (SccList_t **) p2; 02828 if ((*scc1)->nVars > (*scc2)->nVars) 02829 return(1); 02830 else if ((*scc1)->nVars < (*scc2)->nVars) 02831 return(-1); 02832 else 02833 return(0); 02834 } 02835 02836 02846 static int 02847 SccSortListDecreasingWithVars(const void *p1, const void *p2) 02848 { 02849 SccList_t **scc1 = (SccList_t **) p1; 02850 SccList_t **scc2 = (SccList_t **) p2; 02851 if ((*scc1)->nVars < (*scc2)->nVars) 02852 return(1); 02853 else if ((*scc1)->nVars > (*scc2)->nVars) 02854 return(-1); 02855 else 02856 return(0); 02857 } 02858 02859 02869 static int 02870 SccSortListIncreasingWithArea(const void *p1, const void *p2) 02871 { 02872 SccList_t **scc1 = (SccList_t **) p1; 02873 SccList_t **scc2 = (SccList_t **) p2; 02874 int area1, area2; 02875 02876 area1 = (*scc1)->nFuncs * (*scc1)->nVars; 02877 area2 = (*scc2)->nFuncs * (*scc2)->nVars; 02878 if (area1 > area2) 02879 return(1); 02880 else if (area1 < area2) 02881 return(-1); 02882 else 02883 return(0); 02884 } 02885 02886 02896 static int 02897 SccSortListDecreasingWithArea(const void *p1, const void *p2) 02898 { 02899 SccList_t **scc1 = (SccList_t **) p1; 02900 SccList_t **scc2 = (SccList_t **) p2; 02901 int area1, area2; 02902 02903 area1 = (*scc1)->nFuncs * (*scc1)->nVars; 02904 area2 = (*scc2)->nFuncs * (*scc2)->nVars; 02905 if (area1 < area2) 02906 return(1); 02907 else if (area1 > area2) 02908 return(-1); 02909 else 02910 return(0); 02911 } 02912 02913 02923 static int 02924 SccSortListIncreasingWithRatio(const void *p1, const void *p2) 02925 { 02926 SccList_t **scc1 = (SccList_t **) p1; 02927 SccList_t **scc2 = (SccList_t **) p2; 02928 float ratio1, ratio2; 02929 02930 ratio1 = (float)((*scc1)->nVars) / (float)((*scc1)->nFuncs); 02931 ratio2 = (float)((*scc2)->nVars) / (float)((*scc2)->nFuncs); 02932 if (ratio1 > ratio2) 02933 return(1); 02934 else if (ratio1 < ratio2) 02935 return(-1); 02936 else 02937 return(0); 02938 } 02939 02940 02950 static int 02951 SccSortListDecreasingWithRatio(const void *p1, const void *p2) 02952 { 02953 SccList_t **scc1 = (SccList_t **) p1; 02954 SccList_t **scc2 = (SccList_t **) p2; 02955 float ratio1, ratio2; 02956 02957 ratio1 = (float)((*scc1)->nVars) / (float)((*scc1)->nFuncs); 02958 ratio2 = (float)((*scc2)->nVars) / (float)((*scc2)->nFuncs); 02959 if (ratio1 < ratio2) 02960 return(1); 02961 else if (ratio1 > ratio2) 02962 return(-1); 02963 else 02964 return(0); 02965 } 02966 02967 02977 static int 02978 SccSortRc(const void * p1, const void * p2) 02979 { 02980 int *n1 = (int *) p1; 02981 int *n2 = (int *) p2; 02982 if (*n1 > *n2) 02983 return(1); 02984 else if (*n1 < *n2) 02985 return(-1); 02986 else 02987 return(0); 02988 } 02989 02990 03000 static void 03001 FreeSccList(SccList_t *sccHeadList) 03002 { 03003 SccList_t *sccList, *sccNextList; 03004 03005 sccList = sccHeadList; 03006 while (sccList) { 03007 sccNextList = sccList->next; 03008 FREE(sccList); 03009 sccList = sccNextList; 03010 } 03011 } 03012 03013 03023 static int 03024 NumOfSccs(SccList_t *sccHeadList) 03025 { 03026 SccList_t *sccList; 03027 int num = 0; 03028 03029 sccList = sccHeadList; 03030 while (sccList) { 03031 num++; 03032 sccList = sccList->next; 03033 } 03034 return(num); 03035 } 03036 03037 03048 static void 03049 BlockLowerTriangle(char **xy, int nRows, int nCols, 03050 int nActiveRows, int nActiveCols, 03051 SccList_t *sccList, int *rowOrder, int *colOrder, 03052 RcInfo_t *rowInfo, RcInfo_t *colInfo, 03053 ImgTrmOption_t *option) 03054 { 03055 long initialTime, finalTime; 03056 int startFunc, lastFunc, startVar, lastVar; 03057 int nLeftRows, nLeftCols; 03058 int saveStartFunc, saveLastFunc; 03059 int saveStartVar, saveLastVar; 03060 03061 if (sccList) { 03062 if (sccList->nFuncs == 1 || sccList->nVars == 1) 03063 return; 03064 startFunc = sccList->startFunc; 03065 lastFunc = sccList->lastFunc; 03066 startVar = sccList->startVar; 03067 lastVar = sccList->lastVar; 03068 } else { 03069 startFunc = 0; 03070 lastFunc = nActiveRows - 1; 03071 startVar = 0; 03072 lastVar = nActiveCols - 1; 03073 } 03074 03075 if (option->mlpVerbosity >= 2) { 03076 saveStartFunc = startFunc; 03077 saveLastFunc = lastFunc; 03078 saveStartVar = startVar; 03079 saveLastVar = lastVar; 03080 } else { 03081 /* To remove compiler warnings */ 03082 saveStartFunc = 0; 03083 saveLastFunc = 0; 03084 saveStartVar = 0; 03085 saveLastVar = 0; 03086 } 03087 03088 if (option->mlpDebug) { 03089 CheckMatrix(xy, sccList, nActiveRows, nActiveCols, rowInfo, colInfo, 03090 rowOrder, colOrder, startFunc, lastFunc, startVar, lastVar, 1); 03091 } 03092 03093 if (option->mlpCsFirst) { 03094 /* 03095 * Find singleton columns and move each column to the right of the active 03096 * window and move its row to the bottom of the active window. 03097 */ 03098 if (option->mlpSkipCs == 0) { 03099 if (option->mlpVerbosity >= 2) 03100 initialTime = util_cpu_time(); 03101 else /* to remove uninitialized variables warning */ 03102 initialTime = 0; 03103 FindAndMoveSingletonCols(xy, sccList, nActiveRows, nActiveCols, 03104 &startFunc, &lastFunc, &startVar, &lastVar, 03105 rowInfo, colInfo, rowOrder, colOrder, option); 03106 if (option->mlpVerbosity >= 2) { 03107 finalTime = util_cpu_time(); 03108 fprintf(vis_stdout, 03109 "time for col singleton = %10g (#row=%d, #col=%d)\n", 03110 (double)(finalTime - initialTime) / 1000.0, 03111 saveLastFunc - lastFunc, saveLastVar - lastVar); 03112 } 03113 } 03114 03115 /* 03116 * Find singleton rows and move each row to the top of the active window 03117 * and move its column to the left of the active window. 03118 */ 03119 if (option->mlpSkipRs == 0) { 03120 if (option->mlpVerbosity >= 2) 03121 initialTime = util_cpu_time(); 03122 else /* to remove uninitialized variables warning */ 03123 initialTime = 0; 03124 FindAndMoveSingletonRows(xy, sccList, nActiveRows, nActiveCols, 03125 &startFunc, &lastFunc, &startVar, &lastVar, 03126 rowInfo, colInfo, rowOrder, colOrder, option); 03127 if (option->mlpVerbosity >= 2) { 03128 finalTime = util_cpu_time(); 03129 fprintf(vis_stdout, 03130 "time for row singleton = %10g (#row=%d, #col=%d)\n", 03131 (double)(finalTime - initialTime) / 1000.0, 03132 startFunc - saveStartFunc, startVar - saveStartVar); 03133 } 03134 } 03135 } else { 03136 /* 03137 * Find singleton rows and move each row to the top of the active window 03138 * and move its column to the left of the active window. 03139 */ 03140 if (option->mlpSkipRs == 0) { 03141 if (option->mlpVerbosity >= 2) 03142 initialTime = util_cpu_time(); 03143 else /* to remove uninitialized variables warning */ 03144 initialTime = 0; 03145 FindAndMoveSingletonRows(xy, sccList, nActiveRows, nActiveCols, 03146 &startFunc, &lastFunc, &startVar, &lastVar, 03147 rowInfo, colInfo, rowOrder, colOrder, option); 03148 if (option->mlpVerbosity >= 2) { 03149 finalTime = util_cpu_time(); 03150 fprintf(vis_stdout, 03151 "time for row singleton = %10g (#row=%d, #col=%d)\n", 03152 (double)(finalTime - initialTime) / 1000.0, 03153 startFunc - saveStartFunc, startVar - saveStartVar); 03154 } 03155 } 03156 03157 /* 03158 * Find singleton columns and move each column to the right of the active 03159 * window and move its row to the bottom of the active window. 03160 */ 03161 if (option->mlpSkipCs == 0) { 03162 if (option->mlpVerbosity >= 2) 03163 initialTime = util_cpu_time(); 03164 else /* to remove uninitialized variables warning */ 03165 initialTime = 0; 03166 FindAndMoveSingletonCols(xy, sccList, nActiveRows, nActiveCols, 03167 &startFunc, &lastFunc, &startVar, &lastVar, 03168 rowInfo, colInfo, rowOrder, colOrder, option); 03169 if (option->mlpVerbosity >= 2) { 03170 finalTime = util_cpu_time(); 03171 fprintf(vis_stdout, 03172 "time for col singleton = %10g (#row=%d, #col=%d)\n", 03173 (double)(finalTime - initialTime) / 1000.0, 03174 saveLastFunc - lastFunc, saveLastVar - lastVar); 03175 } 03176 } 03177 } 03178 03179 if (option->mlpVerbosity >= 2) { 03180 initialTime = util_cpu_time(); 03181 nLeftRows = lastFunc - startFunc + 1; 03182 nLeftCols = lastVar - startVar + 1; 03183 } else { 03184 /* To remove compiler warnings */ 03185 initialTime = 0; 03186 nLeftRows = 0; 03187 nLeftCols = 0; 03188 } 03189 03190 if (option->mlpRowBased) { 03191 MoveBestRows(xy, sccList, nActiveRows, nActiveCols, rowOrder, colOrder, 03192 rowInfo, colInfo, 03193 startFunc, lastFunc, startVar, lastVar, option); 03194 } else { 03195 MoveBestCols(xy, sccList, nRows, nCols, nActiveRows, nActiveCols, 03196 rowOrder, colOrder, rowInfo, colInfo, 03197 startFunc, lastFunc, startVar, lastVar, option); 03198 } 03199 03200 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03201 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 03202 rowInfo, colInfo, startFunc, lastFunc, startVar, lastVar); 03203 } 03204 03205 if (option->mlpVerbosity >= 2) { 03206 finalTime = util_cpu_time(); 03207 if (option->mlpRowBased) { 03208 fprintf(vis_stdout, "time for best row = %10g (#row=%d, #col=%d)\n", 03209 (double)(finalTime - initialTime) / 1000.0, 03210 nLeftRows - lastFunc + startFunc - 1, 03211 nLeftCols - lastVar + startVar - 1); 03212 } else { 03213 fprintf(vis_stdout, "time for best col = %10g (#row=%d, #col=%d)\n", 03214 (double)(finalTime - initialTime) / 1000.0, 03215 nLeftRows - lastFunc + startFunc - 1, 03216 nLeftCols - lastVar + startVar - 1); 03217 } 03218 } 03219 } 03220 03221 03231 static void 03232 MoveBestRows(char **xy, SccList_t *sccList, int nRows, int nCols, 03233 int *rowOrder, int *colOrder, 03234 RcInfo_t *rowInfo, RcInfo_t *colInfo, 03235 int startFunc, int lastFunc, int startVar, int lastVar, 03236 ImgTrmOption_t *option) 03237 { 03238 int x, y, s1, t1, s2, t2; 03239 int min, bestX; 03240 int row, col, lastCol, moveRow, bestRow; 03241 int regionX, overlap, nOverlaps, nMore; 03242 03243 regionX = 0; 03244 bestX = -1; 03245 while (startFunc < lastFunc && startVar < lastVar) { 03246 min = nCols; 03247 overlap = 0; 03248 for (x = startFunc; x <= lastFunc; x++) { 03249 row = rowOrder[x]; 03250 assert(rowInfo[row].lNum); 03251 if (overlap) { 03252 if (rowInfo[row].lNum < min) { 03253 s1 = colInfo[rowInfo[row].gMin].pos; 03254 if (s1 < regionX) 03255 s1 = regionX; 03256 nOverlaps = 0; 03257 for (y = s1; y < startVar; y++) { 03258 col = colOrder[y]; 03259 if (xy[row][col]) { 03260 nOverlaps++; 03261 break; 03262 } 03263 } 03264 03265 if (nOverlaps) { 03266 bestX = x; 03267 min = rowInfo[row].lNum; 03268 } 03269 } 03270 } else { 03271 s1 = colInfo[rowInfo[row].gMin].pos; 03272 if (s1 < regionX) 03273 s1 = regionX; 03274 nOverlaps = 0; 03275 for (y = s1; y < startVar; y++) { 03276 col = colOrder[y]; 03277 if (xy[row][col]) { 03278 nOverlaps++; 03279 break; 03280 } 03281 } 03282 03283 if (nOverlaps) { 03284 bestX = x; 03285 min = rowInfo[row].lNum; 03286 overlap = 1; 03287 } else { 03288 if (rowInfo[row].lNum < min) { 03289 bestX = x; 03290 min = rowInfo[row].lNum; 03291 } 03292 } 03293 } 03294 } 03295 03296 assert(bestX != -1); 03297 if (!overlap) 03298 regionX = startFunc; 03299 03300 row = rowOrder[bestX]; 03301 while (1) { 03302 bestRow = row; 03303 s1 = colInfo[rowInfo[row].lMin].pos; 03304 t1 = colInfo[rowInfo[row].lMax].pos; 03305 min = rowInfo[row].lNum; 03306 for (x = startFunc; x <= lastFunc; x++) { 03307 moveRow = rowOrder[x]; 03308 if (moveRow == row) 03309 continue; 03310 s2 = colInfo[rowInfo[moveRow].lMin].pos; 03311 t2 = colInfo[rowInfo[moveRow].lMax].pos; 03312 if (s2 < s1 || t2 > t1) 03313 continue; 03314 nMore = 0; 03315 nOverlaps = 0; 03316 for (y = s2; y <= t2; y++) { 03317 col = colOrder[y]; 03318 if (xy[row][col]) { 03319 if (xy[moveRow][col]) 03320 nOverlaps++; 03321 } else { 03322 if (xy[moveRow][col]) { 03323 nMore++; 03324 break; 03325 } 03326 } 03327 } 03328 if (nMore || nOverlaps == 0 || nOverlaps >= min) 03329 continue; 03330 min = nOverlaps; 03331 bestRow = moveRow; 03332 } 03333 03334 lastCol = -1; 03335 s1 = colInfo[rowInfo[bestRow].lMin].pos; 03336 t1 = colInfo[rowInfo[bestRow].lMax].pos; 03337 for (y = s1; y <= t1; y++) { 03338 col = colOrder[y]; 03339 if (xy[bestRow][col]) { 03340 if (option->mlpVerbosity >= 3) { 03341 fprintf(vis_stdout, "[%d] Moving Col %d(%d) to %d (best row)\n", 03342 nMoves, y, col, startVar); 03343 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 03344 startFunc, lastFunc, startVar, lastVar); 03345 } 03346 MoveColToLeft(xy, y, startFunc, lastFunc, startVar, lastVar, 03347 rowInfo, colInfo, rowOrder, colOrder, 03348 NIL(RcListInfo_t), option->mlpMethod); 03349 startVar++; 03350 lastCol = col; 03351 03352 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03353 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, rowInfo, colInfo, 03354 startFunc, lastFunc, startVar, lastVar); 03355 } 03356 if (option->mlpDebug) { 03357 CheckMatrix(xy, sccList, nRows, nCols, rowInfo, colInfo, 03358 rowOrder, colOrder, 03359 startFunc, lastFunc, startVar, lastVar, 1); 03360 } 03361 } 03362 } 03363 03364 if (lastCol != -1) { 03365 s2 = rowInfo[colInfo[lastCol].lMin].pos; 03366 t2 = rowInfo[colInfo[lastCol].lMax].pos; 03367 for (x = s2; x <= t2; x++) { 03368 moveRow = rowOrder[x]; 03369 if (xy[moveRow][lastCol] && rowInfo[moveRow].lNum == 0) { 03370 if (option->mlpVerbosity >= 3) { 03371 fprintf(vis_stdout, "[%d] Moving row %d(%d) to %d (best row)\n", 03372 nMoves, x, moveRow, startFunc); 03373 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 03374 startFunc, lastFunc, startVar, lastVar); 03375 } 03376 MoveRowToTop(xy, x, startFunc, lastFunc, startVar, lastVar, 03377 rowInfo, colInfo, rowOrder, colOrder, 03378 NIL(RcListInfo_t), option->mlpMethod); 03379 startFunc++; 03380 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03381 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, 03382 rowInfo, colInfo, 03383 startFunc, lastFunc, startVar, lastVar); 03384 } 03385 if (option->mlpDebug) { 03386 CheckMatrix(xy, sccList, nRows, nCols, rowInfo, colInfo, 03387 rowOrder, colOrder, 03388 startFunc, lastFunc, startVar, lastVar, 1); 03389 } 03390 } 03391 } 03392 } 03393 03394 if (row == bestRow) 03395 break; 03396 } 03397 } 03398 } 03399 03400 03410 static void 03411 MoveBestCols(char **xy, SccList_t *sccList, int nRows, int nCols, 03412 int nActiveRows, int nActiveCols, 03413 int *rowOrder, int *colOrder, 03414 RcInfo_t *rowInfo, RcInfo_t *colInfo, 03415 int startFunc, int lastFunc, int startVar, int lastVar, 03416 ImgTrmOption_t *option) 03417 { 03418 int x, y, i, s1, t1, s2, t2; 03419 char *rowFlag, *colFlag; 03420 int min, bestY, bestCol; 03421 int row, col, tie, newTies, intersect = 0, maxIntersect, maxLength; 03422 int minX, maxX; 03423 RcListInfo_t *sortedRows, *sortedCols; 03424 RcList_t *cur, *list; 03425 03426 if (option->mlpSortedRows) { 03427 sortedRows = SortedListAlloc(); 03428 for (x = startFunc; x <= lastFunc; x++) { 03429 row = rowOrder[x]; 03430 SortedListInsert(sortedRows, row, row, rowInfo, 3); 03431 } 03432 03433 if (option->mlpSortedCols) 03434 sortedCols = SortedListAlloc(); 03435 else 03436 sortedCols = NIL(RcListInfo_t); 03437 03438 if (option->mlpDebug) 03439 CheckSortedList(sortedRows, rowInfo, 3); 03440 } else { 03441 sortedRows = NIL(RcListInfo_t); 03442 sortedCols = NIL(RcListInfo_t); 03443 } 03444 03445 rowFlag = ALLOC(char, nRows); 03446 if (sortedCols) 03447 memset(rowFlag, 0, sizeof(char) * nRows); 03448 colFlag = ALLOC(char, nCols); 03449 while (startFunc != lastFunc && startVar != lastVar) { 03450 min = nActiveCols; 03451 if (!sortedCols) 03452 memset(rowFlag, 0, sizeof(char) * nRows); 03453 tie = 0; 03454 minX = lastFunc; 03455 maxX = startFunc; 03456 if (sortedCols) { 03457 bestY = nActiveCols; 03458 bestCol = nActiveCols; 03459 if (sortedCols->num == 0) { 03460 if (sortedRows) { 03461 cur = sortedRows->head; 03462 while (cur) { 03463 row = cur->index; 03464 x = rowInfo[row].pos; 03465 if (rowInfo[row].lNum == 0) { 03466 cur = cur->next; 03467 continue; 03468 } 03469 if (rowInfo[row].lNum > min) 03470 break; 03471 rowFlag[row] = 1; 03472 s1 = colInfo[rowInfo[row].lMin].pos; 03473 t1 = colInfo[rowInfo[row].lMax].pos; 03474 for (y = s1; y <= t1; y++) { 03475 col = colOrder[y]; 03476 if (!xy[row][col]) 03477 continue; 03478 if (st_lookup(sortedCols->table, (char *)(long)col, &list)) { 03479 list->otherIndex++; 03480 SortedListMove(sortedCols, colInfo, col, 4); 03481 } else 03482 SortedListInsert(sortedCols, col, 1, colInfo, 4); 03483 } 03484 min = rowInfo[row].lNum; 03485 tie++; 03486 cur = cur->next; 03487 } 03488 } 03489 } else { 03490 if (sortedRows) { 03491 cur = sortedRows->head; 03492 while (cur) { 03493 row = cur->index; 03494 x = rowInfo[row].pos; 03495 if (rowInfo[row].lNum == 0) { 03496 cur = cur->next; 03497 continue; 03498 } 03499 if (rowInfo[row].lNum > min) 03500 break; 03501 min = rowInfo[row].lNum; 03502 tie++; 03503 cur = cur->next; 03504 } 03505 } 03506 } 03507 03508 if (option->mlpDebug) { 03509 if (sortedRows) 03510 CheckSortedList(sortedRows, rowInfo, 3); 03511 CheckSortedList(sortedCols, colInfo, 4); 03512 } 03513 03514 bestCol = sortedCols->head->index; 03515 bestY = colInfo[bestCol].pos; 03516 assert(bestY >= startVar && bestY <= lastVar); 03517 maxLength = colInfo[bestCol].lNum; 03518 intersect = sortedCols->head->otherIndex; 03519 } else { 03520 if (sortedRows) { 03521 if (option->mlpDebug) 03522 CheckSortedList(sortedRows, rowInfo, 3); 03523 03524 cur = sortedRows->head; 03525 while (cur) { 03526 row = cur->index; 03527 x = rowInfo[row].pos; 03528 if (rowInfo[row].lNum == 0) { 03529 cur = cur->next; 03530 continue; 03531 } 03532 if (rowInfo[row].lNum < min) { 03533 min = rowInfo[row].lNum; 03534 tie = 1; 03535 memset(rowFlag, 0, sizeof(char) * nRows); 03536 rowFlag[x] = 1; 03537 minX = x; 03538 maxX = x; 03539 } else if (rowInfo[row].lNum == min) { 03540 tie++; 03541 rowFlag[x] = 1; 03542 if (x < minX) 03543 minX = x; 03544 if (x > maxX) 03545 maxX = x; 03546 } else 03547 break; 03548 cur = cur->next; 03549 } 03550 } else { 03551 for (x = startFunc; x <= lastFunc; x++) { 03552 row = rowOrder[x]; 03553 if (rowInfo[row].lNum == 0) 03554 continue; 03555 if (rowInfo[row].lNum < min) { 03556 min = rowInfo[row].lNum; 03557 tie = 1; 03558 memset(rowFlag, 0, sizeof(char) * nRows); 03559 rowFlag[x] = 1; 03560 minX = x; 03561 maxX = x; 03562 } else if (rowInfo[row].lNum == min) { 03563 tie++; 03564 rowFlag[x] = 1; 03565 maxX = x; 03566 } 03567 } 03568 } 03569 03570 if (tie == 0) 03571 break; 03572 03573 maxLength = 0; 03574 maxIntersect = 0; 03575 memset(colFlag, 0, sizeof(char) * nCols); 03576 bestY = nActiveCols; 03577 bestCol = nActiveCols; 03578 for (x = minX; x <= maxX; x++) { 03579 if (!rowFlag[x]) 03580 continue; 03581 row = rowOrder[x]; 03582 s1 = colInfo[rowInfo[row].lMin].pos; 03583 t1 = colInfo[rowInfo[row].lMax].pos; 03584 for (y = s1; y <= t1; y++) { 03585 col = colOrder[y]; 03586 if (xy[row][col]) { 03587 if (colFlag[y]) 03588 continue; 03589 colFlag[y] = 1; 03590 intersect = 0; 03591 s2 = rowInfo[colInfo[col].lMin].pos; 03592 t2 = rowInfo[colInfo[col].lMax].pos; 03593 if (s2 < minX) 03594 s2 = minX; 03595 if (t2 > maxX) 03596 t2 = maxX; 03597 for (i = s2; i <= t2; i++) { 03598 if (xy[rowOrder[i]][col]) { 03599 if (rowFlag[i]) 03600 intersect++; 03601 } 03602 } 03603 if (intersect > maxIntersect || 03604 (intersect == maxIntersect && colInfo[col].lNum > maxLength) || 03605 (intersect == maxIntersect && colInfo[col].lNum == maxLength && 03606 y < bestY)) { 03607 bestY = y; 03608 bestCol = colOrder[bestY]; 03609 maxLength = colInfo[bestCol].lNum; 03610 maxIntersect = intersect; 03611 } 03612 } 03613 } 03614 } 03615 } 03616 03617 if (option->mlpVerbosity >= 3) { 03618 fprintf(vis_stdout, 03619 "[%d] Moving Col %d(%d) to %d (best col, min=%d, intersect=%d, length=%d)\n", 03620 nMoves, bestY, bestCol, startVar, min, intersect, maxLength); 03621 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 03622 startFunc, lastFunc, startVar, lastVar); 03623 } 03624 MoveColToLeft(xy, bestY, startFunc, lastFunc, startVar, lastVar, 03625 rowInfo, colInfo, rowOrder, colOrder, 03626 NIL(RcListInfo_t), option->mlpMethod); 03627 startVar++; 03628 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03629 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 03630 rowInfo, colInfo, startFunc, lastFunc, startVar, lastVar); 03631 } 03632 if (option->mlpDebug) { 03633 CheckMatrix(xy, sccList, nActiveRows, nActiveCols, rowInfo, colInfo, 03634 rowOrder, colOrder, 03635 startFunc, lastFunc, startVar, lastVar, 1); 03636 } 03637 03638 if (sortedCols) 03639 SortedListDelete(sortedCols, bestCol); 03640 03641 if (sortedRows) { 03642 if (min == 1) { 03643 cur = sortedRows->head; 03644 while (cur) { 03645 row = cur->index; 03646 if (rowInfo[row].lNum > min) 03647 break; 03648 else if (rowInfo[row].lNum == min) { 03649 cur = cur->next; 03650 continue; 03651 } 03652 x = rowInfo[row].pos; 03653 if (option->mlpVerbosity >= 3) { 03654 fprintf(vis_stdout, "[%d] Moving row %d(%d) to %d (empty row)\n", 03655 nMoves, x, row, startFunc); 03656 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 03657 startFunc, lastFunc, startVar, lastVar); 03658 } 03659 MoveRowToTop(xy, x, startFunc, lastFunc, startVar, lastVar, 03660 rowInfo, colInfo, rowOrder, colOrder, 03661 NIL(RcListInfo_t), option->mlpMethod); 03662 startFunc++; 03663 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03664 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 03665 rowInfo, colInfo, 03666 startFunc, lastFunc, startVar, lastVar); 03667 } 03668 if (option->mlpDebug) { 03669 CheckMatrix(xy, sccList, nActiveRows, nActiveCols, 03670 rowInfo, colInfo, rowOrder, colOrder, 03671 startFunc, lastFunc, startVar, lastVar, 1); 03672 } 03673 cur = cur->next; 03674 SortedListDelete(sortedRows, row); 03675 } 03676 } 03677 03678 /* Update sortedRows */ 03679 /* 03680 cur = sortedRows->head; 03681 while (cur) { 03682 row = cur->index; 03683 if (xy[row][bestCol]) { 03684 assert(rowInfo[row].lNum > 0); 03685 SortedListMove(sortedRows, rowInfo, row, 3); 03686 } 03687 cur = cur->next; 03688 } 03689 if (option->mlpDebug) 03690 CheckSortedList(sortedRows, rowInfo, 3); 03691 */ 03692 s1 = rowInfo[colInfo[bestCol].lMin].pos; 03693 t1 = rowInfo[colInfo[bestCol].lMax].pos; 03694 cur = sortedRows->head; 03695 while (cur) { 03696 row = cur->index; 03697 x = rowInfo[row].pos; 03698 if (x < s1) { 03699 cur = cur->next; 03700 continue; 03701 } 03702 if (xy[row][bestCol] && rowInfo[row].lNum > 0) { 03703 SortedListMove(sortedRows, rowInfo, row, 3); 03704 if (sortedCols && min == 1) { 03705 if (rowInfo[row].lNum == 1 && rowFlag[row] == 0) { 03706 rowFlag[row] = 1; 03707 s2 = colInfo[rowInfo[row].lMin].pos; 03708 t2 = colInfo[rowInfo[row].lMax].pos; 03709 for (y = s2; y <= t2; y++) { 03710 col = colOrder[y]; 03711 if (!xy[row][col]) 03712 continue; 03713 if (st_lookup(sortedCols->table, (char *)(long)col, &list)) { 03714 list->otherIndex++; 03715 SortedListMove(sortedCols, colInfo, col, 4); 03716 } else 03717 SortedListInsert(sortedCols, col, 1, colInfo, 4); 03718 } 03719 } 03720 } 03721 } 03722 cur = cur->next; 03723 } 03724 03725 newTies = 0; 03726 if (sortedCols && min > 1) { 03727 min = nActiveCols; 03728 cur = sortedRows->head; 03729 while (cur) { 03730 row = cur->index; 03731 x = rowInfo[row].pos; 03732 if (rowInfo[row].lNum == 0) { 03733 cur = cur->next; 03734 continue; 03735 } 03736 if (rowInfo[row].lNum > min) 03737 break; 03738 min = rowInfo[row].lNum; 03739 newTies++; 03740 cur = cur->next; 03741 } 03742 03743 if (newTies != tie) { 03744 SortedListFree(sortedCols); 03745 sortedCols = SortedListAlloc(); 03746 03747 cur = sortedRows->head; 03748 while (cur) { 03749 row = cur->index; 03750 x = rowInfo[row].pos; 03751 if (rowInfo[row].lNum == 0) { 03752 cur = cur->next; 03753 continue; 03754 } 03755 if (rowInfo[row].lNum > min) 03756 break; 03757 rowFlag[row] = 1; 03758 s1 = colInfo[rowInfo[row].lMin].pos; 03759 t1 = colInfo[rowInfo[row].lMax].pos; 03760 for (y = s1; y <= t1; y++) { 03761 col = colOrder[y]; 03762 if (!xy[row][col]) 03763 continue; 03764 if (st_lookup(sortedCols->table, (char *)(long)col, &list)) { 03765 list->otherIndex++; 03766 SortedListMove(sortedCols, colInfo, col, 4); 03767 } else 03768 SortedListInsert(sortedCols, col, 1, colInfo, 4); 03769 } 03770 cur = cur->next; 03771 } 03772 } 03773 } 03774 } else { 03775 if (min == 1) { 03776 s1 = rowInfo[colInfo[bestCol].lMin].pos; 03777 t1 = rowInfo[colInfo[bestCol].lMax].pos; 03778 for (x = s1; x <= t1; x++) { 03779 row = rowOrder[x]; 03780 if (xy[row][bestCol] && rowInfo[row].lNum == 0) { 03781 if (option->mlpVerbosity >= 3) { 03782 fprintf(vis_stdout, "[%d] Moving row %d(%d) to %d (empty row)\n", 03783 nMoves, x, row, startFunc); 03784 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 03785 startFunc, lastFunc, startVar, lastVar); 03786 } 03787 MoveRowToTop(xy, x, startFunc, lastFunc, startVar, lastVar, 03788 rowInfo, colInfo, rowOrder, colOrder, 03789 NIL(RcListInfo_t), option->mlpMethod); 03790 startFunc++; 03791 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03792 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 03793 rowInfo, colInfo, 03794 startFunc, lastFunc, startVar, lastVar); 03795 } 03796 if (option->mlpDebug) { 03797 CheckMatrix(xy, sccList, nActiveRows, nActiveCols, 03798 rowInfo, colInfo, rowOrder, colOrder, 03799 startFunc, lastFunc, startVar, lastVar, 1); 03800 } 03801 } 03802 } 03803 } 03804 } 03805 } 03806 03807 if (sortedRows) { 03808 cur = sortedRows->head; 03809 while (cur) { 03810 row = cur->index; 03811 x = rowInfo[row].pos; 03812 if (option->mlpVerbosity >= 3) { 03813 fprintf(vis_stdout, "[%d] Moving row %d(%d) to %d (bandwidth)\n", 03814 nMoves, x, row, startFunc); 03815 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 03816 startFunc, lastFunc, startVar, lastVar); 03817 } 03818 MoveRowToTop(xy, x, startFunc, lastFunc, startVar, lastVar, 03819 rowInfo, colInfo, rowOrder, colOrder, 03820 NIL(RcListInfo_t), option->mlpMethod); 03821 startFunc++; 03822 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03823 PrintMatrix(xy, nActiveRows, nActiveCols, rowOrder, colOrder, 03824 rowInfo, colInfo, 03825 startFunc, lastFunc, startVar, lastVar); 03826 } 03827 if (option->mlpDebug) { 03828 CheckMatrix(xy, sccList, nActiveRows, nActiveCols, rowInfo, colInfo, 03829 rowOrder, colOrder, 03830 startFunc, lastFunc, startVar, lastVar, 1); 03831 } 03832 cur = cur->next; 03833 SortedListDelete(sortedRows, row); 03834 } 03835 SortedListFree(sortedRows); 03836 } 03837 03838 if (sortedCols) { 03839 cur = sortedCols->head; 03840 while (cur) { 03841 col = cur->index; 03842 cur = cur->next; 03843 SortedListDelete(sortedCols, col); 03844 } 03845 SortedListFree(sortedCols); 03846 } 03847 03848 FREE(rowFlag); 03849 FREE(colFlag); 03850 } 03851 03852 03863 static void 03864 MlpPostProcess(char **xy, SccList_t *sccList, int nVars, int nRows, int nCols, 03865 RcInfo_t *rowInfo, RcInfo_t *colInfo, 03866 int *rowOrder, int *colOrder, 03867 Img_DirectionType direction, ImgTrmOption_t *option) 03868 { 03869 int x, y, i, j, r, c, row, col, otherRow, otherCol, tmpRow, tmpCol; 03870 int nqv1, nqv2, niv1, niv2, benefit1, benefit2; 03871 int s1, t1, s2, t2, s3, t3, s4, t4; 03872 long initialTime, finalTime; 03873 int nSwaps; 03874 float lambda1, lambda2, lambda3; 03875 int startFunc, lastFunc; 03876 03877 if (sccList) { 03878 startFunc = sccList->startFunc; 03879 lastFunc = sccList->lastFunc; 03880 } else { 03881 startFunc = 0; 03882 lastFunc = nRows - 1; 03883 } 03884 03885 if (option->mlpVerbosity) 03886 initialTime = util_cpu_time(); 03887 else 03888 initialTime = 0; 03889 03890 nSwaps = 0; 03891 for (x = lastFunc - 1; x >= startFunc; x--) { 03892 row = rowOrder[x]; 03893 if (rowInfo[row].data.row.nsVarBddArray) 03894 niv1 = array_n(rowInfo[row].data.row.nsVarBddArray); 03895 else 03896 niv1 = 0; 03897 03898 col = rowInfo[row].gMin; 03899 if (rowInfo[row].gNum == 1 && 03900 colInfo[col].gNum > 1 && colInfo[col].gMin == x) { 03901 t1 = rowInfo[colInfo[col].gMax].pos; 03902 for (i = x + 1; i <= t1; i++) { 03903 otherRow = rowOrder[i]; 03904 if (xy[otherRow][col]) { 03905 if (x < i - 1) { 03906 for (j = x; j < i - 1; j++) { 03907 rowOrder[j] = rowOrder[j + 1]; 03908 rowInfo[rowOrder[j]].pos = j; 03909 } 03910 rowOrder[i - 1] = row; 03911 rowInfo[row].pos = i - 1; 03912 03913 if (rowInfo[otherRow].gNum == 1) 03914 break; 03915 03916 s2 = colInfo[rowInfo[otherRow].gMin].pos; 03917 t2 = colInfo[rowInfo[otherRow].gMax].pos; 03918 for (j = t2; j >= s2; j--) { 03919 otherCol = colOrder[j]; 03920 if (colInfo[otherCol].gMin == otherRow) 03921 t2 = j - 1; 03922 else 03923 break; 03924 } 03925 03926 s3 = rowInfo[colInfo[col].gMin].pos; 03927 t3 = rowInfo[colInfo[col].gMax].pos; 03928 for (r = s3; r <= t3; r++) { 03929 tmpRow = rowOrder[r]; 03930 if (col == rowInfo[tmpRow].gMin) { 03931 s4 = colInfo[rowInfo[tmpRow].gMin].pos; 03932 t4 = colInfo[rowInfo[tmpRow].gMax].pos; 03933 if (t4 > t2) 03934 t4 = t2; 03935 for (c = s4 + 1; c <= t4; c++) { 03936 tmpCol = colOrder[c]; 03937 if (xy[tmpRow][tmpCol]) { 03938 rowInfo[tmpRow].gMin = tmpCol; 03939 rowInfo[tmpRow].lMin = tmpCol; 03940 break; 03941 } 03942 } 03943 } 03944 03945 if (xy[tmpRow][col] && t2 >= colInfo[rowInfo[tmpRow].gMax].pos) { 03946 rowInfo[tmpRow].gMax = col; 03947 rowInfo[tmpRow].lMax = col; 03948 } 03949 } 03950 03951 y = colInfo[col].pos; 03952 if (y < t2) { 03953 for (j = y; j < t2; j++) { 03954 colOrder[j] = colOrder[j + 1]; 03955 colInfo[colOrder[j]].pos = j; 03956 } 03957 colOrder[t2] = col; 03958 colInfo[col].pos = t2; 03959 } 03960 03961 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 03962 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, 03963 rowInfo, colInfo, 0, nRows - 1, 0, nCols - 1); 03964 } 03965 if (option->mlpDebug) { 03966 CheckMatrix(xy, sccList, nRows, nCols, rowInfo, colInfo, 03967 rowOrder, colOrder, 0, nRows - 1, 0, nCols - 1, 1); 03968 } 03969 03970 nSwaps++; 03971 } 03972 break; 03973 } 03974 } 03975 continue; 03976 } 03977 03978 for (i = x + 1; i <= lastFunc; i++) { 03979 otherRow = rowOrder[i]; 03980 if (rowInfo[otherRow].data.row.nsVarBddArray) 03981 niv2 = array_n(rowInfo[otherRow].data.row.nsVarBddArray); 03982 else 03983 niv2 = 0; 03984 03985 nqv1 = 0; 03986 s1 = colInfo[rowInfo[row].gMin].pos; 03987 t1 = colInfo[rowInfo[row].gMax].pos; 03988 for (y = t1; y >= s1; y--) { 03989 col = colOrder[y]; 03990 if (colInfo[col].gMin == row) { 03991 if (!xy[otherRow][col]) 03992 nqv1++; 03993 } else 03994 break; 03995 } 03996 benefit1 = nqv1 - niv1; 03997 03998 nqv2 = 0; 03999 s2 = colInfo[rowInfo[otherRow].gMin].pos; 04000 t2 = colInfo[rowInfo[otherRow].gMax].pos; 04001 for (y = t2; y >= s2; y--) { 04002 col = colOrder[y]; 04003 if (colInfo[col].gMin == otherRow) 04004 nqv2++; 04005 else 04006 break; 04007 } 04008 benefit2 = nqv2 - niv2; 04009 04010 if (benefit1 > benefit2 || 04011 (benefit1 == benefit2 && 04012 (rowInfo[row].gNum > rowInfo[otherRow].gNum || 04013 (rowInfo[row].gNum == rowInfo[otherRow].gNum && 04014 bdd_size(rowInfo[row].data.row.func) < 04015 bdd_size(rowInfo[otherRow].data.row.func))))) { 04016 nqv1 = 0; 04017 for (y = t1; y >= s1; y--) { 04018 if (t1 > t2) 04019 break; 04020 col = colOrder[y]; 04021 if (colInfo[col].gMin == row) { 04022 if (!xy[otherRow][col]) { 04023 s3 = rowInfo[colInfo[col].gMin].pos; 04024 t3 = rowInfo[colInfo[col].gMax].pos; 04025 for (r = s3; r <= t3; r++) { 04026 tmpRow = rowOrder[r]; 04027 if (col == rowInfo[tmpRow].gMin) { 04028 s4 = colInfo[rowInfo[tmpRow].gMin].pos; 04029 t4 = colInfo[rowInfo[tmpRow].gMax].pos; 04030 if (t4 > t2 - nqv1) 04031 t4 = t2 - nqv1; 04032 for (c = s4 + 1; c <= t4; c++) { 04033 tmpCol = colOrder[c]; 04034 if (xy[tmpRow][tmpCol] && colInfo[tmpCol].gMin != row) { 04035 rowInfo[tmpRow].gMin = tmpCol; 04036 rowInfo[tmpRow].lMin = tmpCol; 04037 break; 04038 } 04039 } 04040 } 04041 04042 if (nqv1 == 0 && xy[tmpRow][col] && 04043 t2 - nqv1 >= colInfo[rowInfo[tmpRow].gMax].pos) { 04044 rowInfo[tmpRow].gMax = col; 04045 rowInfo[tmpRow].lMax = col; 04046 } 04047 } 04048 04049 for (j = y; j < t2 - nqv1; j++) { 04050 colOrder[j] = colOrder[j + 1]; 04051 colInfo[colOrder[j]].pos = j; 04052 } 04053 colOrder[t2 - nqv1] = col; 04054 colInfo[col].pos = t2 - nqv1; 04055 nqv1++; 04056 } else { 04057 colInfo[col].gMin = otherRow; 04058 colInfo[col].lMin = otherRow; 04059 if (colInfo[col].gMax == otherRow) { 04060 colInfo[col].gMax = row; 04061 colInfo[col].lMax = row; 04062 } 04063 } 04064 } else { 04065 if (colInfo[col].gMax == otherRow && xy[row][col]) { 04066 colInfo[col].gMax = row; 04067 colInfo[col].lMax = row; 04068 } 04069 } 04070 } 04071 04072 rowOrder[i - 1] = otherRow; 04073 rowInfo[otherRow].pos = i - 1; 04074 rowOrder[i] = row; 04075 rowInfo[row].pos = i; 04076 nSwaps++; 04077 04078 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 04079 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, 04080 rowInfo, colInfo, 0, nRows - 1, 0, nCols - 1); 04081 } 04082 if (option->mlpDebug) { 04083 CheckMatrix(xy, sccList, nRows, nCols, rowInfo, colInfo, 04084 rowOrder, colOrder, 0, nRows - 1, 0, nCols - 1, 1); 04085 } 04086 } else 04087 break; 04088 } 04089 } 04090 04091 if (option->mlpVerbosity) { 04092 if (option->mlpVerbosity >= 2) { 04093 lambda1 = ComputeLambdaMlp(xy, nVars, nRows, nCols, rowInfo, colInfo, 04094 rowOrder, colOrder, direction, 0, 0, option); 04095 lambda2 = ComputeLambdaMlp(xy, nVars, nRows, nCols, rowInfo, colInfo, 04096 rowOrder, colOrder, direction, 1, 0, option); 04097 lambda3 = ComputeLambdaMlp(xy, nVars, nRows, nCols, rowInfo, colInfo, 04098 rowOrder, colOrder, direction, 2, 0, option); 04099 fprintf(vis_stdout, "Optimized Lambda = %f (%f, %f)\n", 04100 lambda1, lambda2, lambda3); 04101 } 04102 finalTime = util_cpu_time(); 04103 fprintf(vis_stdout, "time for postprocessing = %10g (#swap=%d)\n", 04104 (double)(finalTime - initialTime) / 1000.0, nSwaps); 04105 } 04106 } 04107 04108 04118 static float 04119 ComputeLambdaMlp(char **xy, int nVars, int nRows, int nCols, 04120 RcInfo_t *rowInfo, RcInfo_t *colInfo, 04121 int *rowOrder, int *colOrder, 04122 Img_DirectionType direction, 04123 int mode, int asIs, ImgTrmOption_t *option) 04124 { 04125 int lifetime, area; 04126 int highest, lowest; 04127 int x, y, row, col; 04128 int nIntroducedVars, nYVars; 04129 float lambda; 04130 04131 lifetime = 0; 04132 04133 if (direction == Img_Forward_c) { 04134 for (y = 0; y < nCols; y++) { 04135 col = colOrder[y]; 04136 lowest = rowInfo[colInfo[col].gMin].pos; 04137 if (mode == 1) { /* active lifetime (alpha) */ 04138 highest = rowInfo[colInfo[col].gMax].pos; 04139 lifetime += highest - lowest + 1; 04140 } else { /* total lifetime (lambda) */ 04141 lifetime += nRows - lowest; 04142 } 04143 } 04144 } else { 04145 for (y = 0; y < nCols; y++) { 04146 col = colOrder[y]; 04147 lowest = rowInfo[colInfo[col].gMin].pos; 04148 if (mode == 1) { /* active lifetime (alpha) */ 04149 highest = rowInfo[colInfo[col].gMax].pos; 04150 lifetime += highest - lowest + 1; 04151 } else { /* total lifetime (lambda) */ 04152 if (colInfo[col].data.col.type == 2) /* primary input variables */ 04153 lifetime += lowest + 1; 04154 else { /* present state variables */ 04155 if (mode == 2) 04156 lifetime += nRows - lowest; 04157 } 04158 } 04159 } 04160 } 04161 04162 /* total lifetime (lambda) with introducedVars */ 04163 nIntroducedVars = 0;; 04164 if (mode == 2 || (mode == 0 && direction == Img_Backward_c)) { 04165 if (asIs) { /* contains next state variables */ 04166 for (x = 0; x < nRows; x++) { 04167 row = rowOrder[x]; 04168 nYVars = array_n(rowInfo[row].data.row.nsVarBddArray); 04169 nIntroducedVars += nYVars; 04170 lifetime += (x + 1) * nYVars; 04171 } 04172 } else { /* does not contain next state variables */ 04173 nIntroducedVars = nRows; 04174 lifetime += nIntroducedVars * (nIntroducedVars + 1) / 2; 04175 } 04176 } 04177 04178 if (option->mlpLambdaMode == 0) 04179 area = nRows * (nCols + nIntroducedVars); 04180 else 04181 area = nRows * (nVars + nIntroducedVars); 04182 lambda = (float)lifetime / (float)area; 04183 return(lambda); 04184 } 04185 04186 04196 static void 04197 FindAndMoveSingletonRows(char **xy, SccList_t *sccList, int nRows, int nCols, 04198 int *startFunc, int *lastFunc, int *startVar, int *lastVar, 04199 RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04200 ImgTrmOption_t *option) 04201 { 04202 int x, row, col, add, found; 04203 RcListInfo_t *candList; 04204 04205 if (option->mlpMethod == 0) { 04206 while (*startFunc != *lastFunc && *startVar != *lastVar) { 04207 found = 0; 04208 for (x = *startFunc; x <= *lastFunc; x++) { 04209 row = rowOrder[x]; 04210 if (rowInfo[row].lNum == 1) { 04211 found = 1; 04212 add = MoveSingletonRow(xy, sccList, nRows, nCols, x, 04213 startFunc, lastFunc, startVar, lastVar, 04214 rowInfo, colInfo, rowOrder, colOrder, 04215 NIL(RcListInfo_t), option); 04216 if (*startFunc == *lastFunc || *startVar == *lastVar) { 04217 found = 0; 04218 break; 04219 } 04220 x += add; 04221 } 04222 } 04223 if (!found) 04224 break; 04225 } 04226 } else { 04227 if (*startFunc != *lastFunc && *startVar != *lastVar) { 04228 candList = SortedListAlloc(); 04229 for (x = *startFunc; x <= *lastFunc; x++) { 04230 row = rowOrder[x]; 04231 if (rowInfo[row].lNum == 1) { 04232 col = rowInfo[row].lMin; 04233 SortedListInsert(candList, row, col, colInfo, option->mlpMethod); 04234 } 04235 } 04236 if (option->mlpDebug) 04237 CheckSortedList(candList, colInfo, option->mlpMethod); 04238 while (candList->cur) { 04239 candList->curIndex = candList->cur->index; 04240 x = rowInfo[candList->curIndex].pos; 04241 MoveSingletonRow(xy, sccList, nRows, nCols, x, 04242 startFunc, lastFunc, startVar, lastVar, 04243 rowInfo, colInfo, rowOrder, colOrder, 04244 candList, option); 04245 if (option->mlpDebug) 04246 CheckSortedList(candList, colInfo, option->mlpMethod); 04247 if (*startFunc == *lastFunc || *startVar == *lastVar) { 04248 break; 04249 } 04250 } 04251 if (option->mlpVerbosity) { 04252 fprintf(vis_stdout, "max number of elements in list = %d\n", 04253 candList->maxNum); 04254 } 04255 SortedListFree(candList); 04256 } 04257 } 04258 } 04259 04260 04270 static int 04271 MoveSingletonRow(char **xy, SccList_t *sccList, int nRows, int nCols, int x, 04272 int *startFunc, int *lastFunc, int *startVar, int *lastVar, 04273 RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04274 RcListInfo_t *candList, ImgTrmOption_t *option) 04275 { 04276 int y, i, add; 04277 int row, col, otherRow; 04278 int startRow, lastRow, startCol, lastCol; 04279 04280 startRow = *startFunc; 04281 startCol = *startVar; 04282 lastRow = *lastFunc; 04283 lastCol = *lastVar; 04284 04285 row = rowOrder[x]; 04286 col = rowInfo[row].lMin; 04287 y = colInfo[col].pos; 04288 04289 if (option->mlpVerbosity >= 3) { 04290 fprintf(vis_stdout, "[%d] Moving Col %d(%d) to %d (row singleton)\n", 04291 nMoves, y, col, startCol); 04292 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 04293 startRow, lastRow, startCol, lastCol); 04294 } 04295 MoveColToLeft(xy, y, startRow, lastRow, startCol, lastCol, 04296 rowInfo, colInfo, rowOrder, colOrder, candList, 04297 option->mlpMethod); 04298 startCol++; 04299 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 04300 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, rowInfo, colInfo, 04301 startRow, lastRow, startCol, lastCol); 04302 } 04303 if (option->mlpDebug) { 04304 CheckMatrix(xy, sccList, nRows, nCols, rowInfo, colInfo, rowOrder, colOrder, 04305 startRow, lastRow, startCol, lastCol, 1); 04306 } 04307 04308 add = 0; 04309 for (i = rowInfo[colInfo[col].lMin].pos; 04310 colInfo[col].lNum && i <= rowInfo[colInfo[col].lMax].pos; i++) { 04311 otherRow = rowOrder[i]; 04312 if (!xy[otherRow][col]) 04313 continue; 04314 if (rowInfo[otherRow].lNum == 0) { 04315 if (option->mlpVerbosity >= 3) { 04316 fprintf(vis_stdout, "[%d] Moving row %d(%d) to %d (row singleton)\n", 04317 nMoves, i, otherRow, startRow); 04318 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 04319 startRow, lastRow, startCol, lastCol); 04320 } 04321 MoveRowToTop(xy, i, startRow, lastRow, startCol, lastCol, 04322 rowInfo, colInfo, rowOrder, colOrder, 04323 NIL(RcListInfo_t), option->mlpMethod); 04324 startRow++; 04325 if (i > x) 04326 add++; 04327 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 04328 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, rowInfo, colInfo, 04329 startRow, lastRow, startCol, lastCol); 04330 } 04331 if (option->mlpDebug) { 04332 CheckMatrix(xy, sccList, nRows, nCols, 04333 rowInfo, colInfo, rowOrder, colOrder, 04334 startRow, lastRow, startCol, lastCol, 1); 04335 } 04336 } 04337 } 04338 04339 *startFunc = startRow; 04340 *startVar = startCol; 04341 return(add); 04342 } 04343 04344 04354 static void 04355 FindAndMoveSingletonCols(char **xy, SccList_t *sccList, int nRows, int nCols, 04356 int *startFunc, int *lastFunc, int *startVar, int *lastVar, 04357 RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04358 ImgTrmOption_t *option) 04359 { 04360 int y, row, col, add, found; 04361 RcListInfo_t *candList; 04362 04363 if (option->mlpMethod == 0) { 04364 while (*startFunc != *lastFunc && *startVar != *lastVar) { 04365 found = 0; 04366 for (y = *startVar; y <= *lastVar; y++) { 04367 col = colOrder[y]; 04368 if (colInfo[col].lNum == 1) { 04369 found = 1; 04370 add = MoveSingletonCol(xy, sccList, nRows, nCols, y, 04371 startFunc, lastFunc, startVar, lastVar, 04372 rowInfo, colInfo, rowOrder, colOrder, 04373 NIL(RcListInfo_t), option); 04374 if (*startFunc == *lastFunc || *startVar == *lastVar) { 04375 found = 0; 04376 break; 04377 } 04378 y -= add; 04379 } 04380 } 04381 if (!found) 04382 break; 04383 } 04384 } else { 04385 if (*startFunc != *lastFunc && *startVar != *lastVar) { 04386 candList = SortedListAlloc(); 04387 for (y = *startVar; y <= *lastVar; y++) { 04388 col = colOrder[y]; 04389 if (colInfo[col].lNum == 1) { 04390 row = colInfo[col].lMin; 04391 SortedListInsert(candList, col, row, rowInfo, option->mlpMethod); 04392 } 04393 } 04394 if (option->mlpDebug) 04395 CheckSortedList(candList, rowInfo, option->mlpMethod); 04396 while (candList->cur) { 04397 candList->curIndex = candList->cur->index; 04398 y = colInfo[candList->curIndex].pos; 04399 MoveSingletonCol(xy, sccList, nRows, nCols, y, 04400 startFunc, lastFunc, startVar, lastVar, 04401 rowInfo, colInfo, rowOrder, colOrder, candList, option); 04402 if (option->mlpDebug) 04403 CheckSortedList(candList, rowInfo, option->mlpMethod); 04404 if (*startFunc == *lastFunc || *startVar == *lastVar) { 04405 break; 04406 } 04407 } 04408 if (option->mlpVerbosity >= 2) { 04409 fprintf(vis_stdout, "max number of elements in list = %d\n", 04410 candList->maxNum); 04411 } 04412 SortedListFree(candList); 04413 } 04414 } 04415 } 04416 04417 04427 static int 04428 MoveSingletonCol(char **xy, SccList_t *sccList, int nRows, int nCols, int y, 04429 int *startFunc, int *lastFunc, int *startVar, int *lastVar, 04430 RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04431 RcListInfo_t *candList, ImgTrmOption_t *option) 04432 { 04433 int x, j, add; 04434 int row, col, otherCol; 04435 int startRow, lastRow, startCol, lastCol; 04436 04437 startRow = *startFunc; 04438 startCol = *startVar; 04439 lastRow = *lastFunc; 04440 lastCol = *lastVar; 04441 04442 col = colOrder[y]; 04443 row = colInfo[col].lMin; 04444 x = rowInfo[row].pos; 04445 04446 if (option->mlpVerbosity >= 3) { 04447 fprintf(vis_stdout, "[%d] Moving Row %d(%d) to %d (col singleton)\n", 04448 nMoves, x, row, lastRow); 04449 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 04450 startRow, lastRow, startCol, lastCol); 04451 } 04452 MoveRowToBottom(xy, x, startRow, lastRow, startCol, lastCol, 04453 rowInfo, colInfo, rowOrder, colOrder, candList, 04454 option->mlpMethod); 04455 lastRow--; 04456 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 04457 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, rowInfo, colInfo, 04458 startRow, lastRow, startCol, lastCol); 04459 } 04460 if (option->mlpDebug) { 04461 CheckMatrix(xy, sccList, nRows, nCols, rowInfo, colInfo, rowOrder, colOrder, 04462 startRow, lastRow, startCol, lastCol, 1); 04463 } 04464 04465 add = 0; 04466 for (j = colInfo[rowInfo[row].lMin].pos; 04467 rowInfo[row].lNum && j <= colInfo[rowInfo[row].lMax].pos; j++) { 04468 otherCol = colOrder[j]; 04469 if (!xy[row][otherCol]) 04470 continue; 04471 if (colInfo[otherCol].lNum == 0) { 04472 if (option->mlpVerbosity >= 3) { 04473 fprintf(vis_stdout, "[%d] Moving Col %d(%d) to %d (col singleton)\n", 04474 nMoves, j, otherCol, lastCol); 04475 fprintf(vis_stdout, "active window [%d-%d, %d-%d]\n", 04476 startRow, lastRow, startCol, lastCol); 04477 } 04478 MoveColToRight(xy, j, startRow, lastRow, startCol, lastCol, 04479 rowInfo, colInfo, rowOrder, colOrder, 04480 NIL(RcListInfo_t), option->mlpMethod); 04481 lastCol--; 04482 j--; 04483 if (otherCol <= col) 04484 add++; 04485 if (option->mlpVerbosity >= 4 && option->mlpPrintMatrix) { 04486 PrintMatrix(xy, nRows, nCols, rowOrder, colOrder, rowInfo, colInfo, 04487 startRow, lastRow, startCol, lastCol); 04488 } 04489 if (option->mlpDebug) { 04490 CheckMatrix(xy, sccList, nRows, nCols, 04491 rowInfo, colInfo, rowOrder, colOrder, 04492 startRow, lastRow, startCol, lastCol, 1); 04493 } 04494 } 04495 } 04496 04497 *lastFunc = lastRow; 04498 *lastVar = lastCol; 04499 return(add); 04500 } 04501 04502 04512 static void 04513 MoveRowToTop(char **xy, int x, int startFunc, int lastFunc, 04514 int startVar, int lastVar, RcInfo_t *rowInfo, 04515 RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04516 RcListInfo_t *candList, int method) 04517 { 04518 int i, j, s, t; 04519 int row, col, tmpRow; 04520 04521 assert(x >= startFunc && x <= lastFunc); 04522 04523 row = rowOrder[x]; 04524 if (x != startFunc) { 04525 /* Change row order */ 04526 for (i = x; i > startFunc; i--) { 04527 rowOrder[i] = rowOrder[i - 1]; 04528 rowInfo[rowOrder[i]].pos = i; 04529 } 04530 rowOrder[startFunc] = row; 04531 rowInfo[row].pos = startFunc; 04532 } 04533 04534 s = colInfo[rowInfo[row].gMin].pos; 04535 t = colInfo[rowInfo[row].gMax].pos; 04536 for (j = s; j <= t; j++) { 04537 col = colOrder[j]; 04538 if (!xy[row][col]) 04539 continue; 04540 colInfo[col].prevG = startFunc; 04541 if (colInfo[col].lNum == 1) { 04542 colInfo[col].lMin = row; 04543 colInfo[col].lMax = row; 04544 } else { 04545 if (row == colInfo[col].lMin) { 04546 for (i = x + 1; i <= rowInfo[colInfo[col].lMax].pos; i++) { 04547 tmpRow = rowOrder[i]; 04548 if (xy[tmpRow][col]) { 04549 colInfo[col].lMin = tmpRow; 04550 break; 04551 } 04552 } 04553 } else if (row == colInfo[col].lMax) { 04554 for (i = x; i >= rowInfo[colInfo[col].lMin].pos; i--) { 04555 tmpRow = rowOrder[i]; 04556 if (xy[tmpRow][col]) { 04557 colInfo[col].lMax = tmpRow; 04558 break; 04559 } 04560 } 04561 } 04562 } 04563 04564 if (colInfo[col].gNum == 1) { 04565 colInfo[col].gMin = row; 04566 colInfo[col].gMax = row; 04567 } else { 04568 if (row == colInfo[col].gMin) 04569 colInfo[col].gMin = row; 04570 else if (row == colInfo[col].gMax) { 04571 colInfo[col].gMax = colInfo[col].lMax; 04572 if (startFunc <= rowInfo[colInfo[col].gMin].pos) 04573 colInfo[col].gMin = row; 04574 } else if (startFunc <= rowInfo[colInfo[col].gMin].pos) 04575 colInfo[col].gMin = row; 04576 } 04577 04578 if (rowInfo[row].lNum) { 04579 if (j == rowInfo[row].prevG) 04580 j = colInfo[rowInfo[row].lMin].pos - 1; 04581 else if (j == colInfo[rowInfo[row].lMax].pos) 04582 j = rowInfo[row].nextG - 1; 04583 } 04584 } 04585 04586 s = colInfo[rowInfo[row].lMin].pos; 04587 t = colInfo[rowInfo[row].lMax].pos; 04588 for (j = s; j <= t; j++) { 04589 col = colOrder[j]; 04590 if (xy[row][col]) { 04591 colInfo[col].lNum--; 04592 if (candList) { 04593 if (colInfo[col].lNum == 0) 04594 SortedListDelete(candList, col); 04595 else if (colInfo[col].lNum == 1) 04596 SortedListInsert(candList, col, row, rowInfo, method); 04597 } 04598 } 04599 } 04600 04601 nMoves++; 04602 } 04603 04604 04614 static void 04615 MoveColToLeft(char **xy, int y, int startFunc, int lastFunc, 04616 int startVar, int lastVar, RcInfo_t *rowInfo, 04617 RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04618 RcListInfo_t *candList, int method) 04619 { 04620 int i, j, s, t; 04621 int row, col, tmpCol; 04622 04623 assert(y >= startVar && y <= lastVar); 04624 04625 col = colOrder[y]; 04626 if (y != startVar) { 04627 /* Change col order */ 04628 for (j = y; j > startVar; j--) { 04629 colOrder[j] = colOrder[j - 1]; 04630 colInfo[colOrder[j]].pos = j; 04631 } 04632 colOrder[startVar] = col; 04633 colInfo[col].pos = startVar; 04634 } 04635 04636 s = rowInfo[colInfo[col].gMin].pos; 04637 t = rowInfo[colInfo[col].gMax].pos; 04638 for (i = s; i <= t; i++) { 04639 row = rowOrder[i]; 04640 if (!xy[row][col]) 04641 continue; 04642 rowInfo[row].prevG = startVar; 04643 if (rowInfo[row].lNum == 1) { 04644 rowInfo[row].lMin = col; 04645 rowInfo[row].lMax = col; 04646 } else { 04647 if (col == rowInfo[row].lMin) { 04648 for (j = y + 1; j <= colInfo[rowInfo[row].lMax].pos; j++) { 04649 tmpCol = colOrder[j]; 04650 if (xy[row][tmpCol]) { 04651 rowInfo[row].lMin = tmpCol; 04652 break; 04653 } 04654 } 04655 } else if (col == rowInfo[row].lMax) { 04656 for (j = y; j >= colInfo[rowInfo[row].lMin].pos; j--) { 04657 tmpCol = colOrder[j]; 04658 if (xy[row][tmpCol]) { 04659 rowInfo[row].lMax = tmpCol; 04660 break; 04661 } 04662 } 04663 } 04664 } 04665 04666 if (rowInfo[row].gNum == 1) { 04667 rowInfo[row].gMin = col; 04668 rowInfo[row].gMax = col; 04669 } else { 04670 if (col == rowInfo[row].gMin) 04671 rowInfo[row].gMin = col; 04672 else if (col == rowInfo[row].gMax) { 04673 rowInfo[row].gMax = rowInfo[row].lMax; 04674 if (startVar <= colInfo[rowInfo[row].gMin].pos) 04675 rowInfo[row].gMin = col; 04676 } else if (startVar <= colInfo[rowInfo[row].gMin].pos) 04677 rowInfo[row].gMin = col; 04678 } 04679 04680 if (colInfo[col].lNum) { 04681 if (i == colInfo[col].prevG) 04682 i = rowInfo[colInfo[col].lMin].pos - 1; 04683 else if (i == rowInfo[colInfo[col].lMax].pos) 04684 i = colInfo[col].nextG - 1; 04685 } 04686 } 04687 04688 s = rowInfo[colInfo[col].lMin].pos; 04689 t = rowInfo[colInfo[col].lMax].pos; 04690 for (i = s; i <= t; i++) { 04691 row = rowOrder[i]; 04692 if (xy[row][col]) { 04693 rowInfo[row].lNum--; 04694 if (candList) { 04695 if (rowInfo[row].lNum == 0) 04696 SortedListDelete(candList, row); 04697 else if (rowInfo[row].lNum == 1) 04698 SortedListInsert(candList, row, col, colInfo, method); 04699 } 04700 } 04701 } 04702 04703 nMoves++; 04704 } 04705 04706 04716 static void 04717 MoveRowToBottom(char **xy, int x, int startFunc, int lastFunc, 04718 int startVar, int lastVar, RcInfo_t *rowInfo, 04719 RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04720 RcListInfo_t *candList, int method) 04721 { 04722 int i, j, s, t; 04723 int row, col, tmpRow; 04724 04725 assert(x >= startFunc && x <= lastFunc); 04726 04727 row = rowOrder[x]; 04728 if (x != lastFunc) { 04729 /* Change row order */ 04730 for (i = x; i < lastFunc; i++) { 04731 rowOrder[i] = rowOrder[i + 1]; 04732 rowInfo[rowOrder[i]].pos = i; 04733 } 04734 rowOrder[lastFunc] = row; 04735 rowInfo[row].pos = lastFunc; 04736 } 04737 04738 s = colInfo[rowInfo[row].gMin].pos; 04739 t = colInfo[rowInfo[row].gMax].pos; 04740 for (j = s; j <= t; j++) { 04741 col = colOrder[j]; 04742 if (!xy[row][col]) 04743 continue; 04744 colInfo[col].nextG = lastFunc; 04745 if (colInfo[col].lNum == 1) { 04746 colInfo[col].lMin = row; 04747 colInfo[col].lMax = row; 04748 } else { 04749 if (row == colInfo[col].lMin) { 04750 for (i = x; i <= rowInfo[colInfo[col].lMax].pos; i++) { 04751 tmpRow = rowOrder[i]; 04752 if (xy[tmpRow][col]) { 04753 colInfo[col].lMin = tmpRow; 04754 break; 04755 } 04756 } 04757 } else if (row == colInfo[col].lMax) { 04758 for (i = x - 1; i >= rowInfo[colInfo[col].lMin].pos; i--) { 04759 tmpRow = rowOrder[i]; 04760 if (xy[tmpRow][col]) { 04761 colInfo[col].lMax = tmpRow; 04762 break; 04763 } 04764 } 04765 } 04766 } 04767 04768 if (colInfo[col].gNum == 1) { 04769 colInfo[col].gMin = row; 04770 colInfo[col].gMax = row; 04771 } else { 04772 if (row == colInfo[col].gMax) 04773 colInfo[col].gMax = row; 04774 else if (row == colInfo[col].gMin) { 04775 colInfo[col].gMin = colInfo[col].lMin; 04776 if (lastFunc >= rowInfo[colInfo[col].gMax].pos) 04777 colInfo[col].gMax = row; 04778 } else if (lastFunc >= rowInfo[colInfo[col].gMax].pos) 04779 colInfo[col].gMax = row; 04780 } 04781 04782 if (rowInfo[row].lNum) { 04783 if (j == rowInfo[row].prevG) 04784 j = colInfo[rowInfo[row].lMin].pos - 1; 04785 else if (j == colInfo[rowInfo[row].lMax].pos) 04786 j = rowInfo[row].nextG - 1; 04787 } 04788 } 04789 04790 s = colInfo[rowInfo[row].lMin].pos; 04791 t = colInfo[rowInfo[row].lMax].pos; 04792 for (j = s; j <= t; j++) { 04793 col = colOrder[j]; 04794 if (xy[row][col]) { 04795 colInfo[col].lNum--; 04796 if (candList) { 04797 if (colInfo[col].lNum == 0) 04798 SortedListDelete(candList, col); 04799 else if (colInfo[col].lNum == 1) 04800 SortedListInsert(candList, col, row, rowInfo, method); 04801 } 04802 } 04803 } 04804 04805 nMoves++; 04806 } 04807 04808 04818 static void 04819 MoveColToRight(char **xy, int y, int startFunc, int lastFunc, 04820 int startVar, int lastVar, RcInfo_t *rowInfo, 04821 RcInfo_t *colInfo, int *rowOrder, int *colOrder, 04822 RcListInfo_t *candList, int method) 04823 { 04824 int i, j, s, t; 04825 int row, col, tmpCol; 04826 04827 assert(y >= startVar && y <= lastVar); 04828 04829 col = colOrder[y]; 04830 if (y != lastVar) { 04831 /* Change col order */ 04832 for (j = y; j < lastVar; j++) { 04833 colOrder[j] = colOrder[j + 1]; 04834 colInfo[colOrder[j]].pos = j; 04835 } 04836 colOrder[lastVar] = col; 04837 colInfo[col].pos = lastVar; 04838 } 04839 04840 s = rowInfo[colInfo[col].gMin].pos; 04841 t = rowInfo[colInfo[col].gMax].pos; 04842 for (i = s; i <= t; i++) { 04843 row = rowOrder[i]; 04844 if (!xy[row][col]) 04845 continue; 04846 rowInfo[row].nextG = lastVar; 04847 if (rowInfo[row].lNum == 1) { 04848 rowInfo[row].lMin = col; 04849 rowInfo[row].lMax = col; 04850 } else { 04851 if (col == rowInfo[row].lMin) { 04852 for (j = y; j <= colInfo[rowInfo[row].lMax].pos; j++) { 04853 tmpCol = colOrder[j]; 04854 if (xy[row][tmpCol]) { 04855 rowInfo[row].lMin = tmpCol; 04856 break; 04857 } 04858 } 04859 } else if (col == rowInfo[row].lMax) { 04860 for (j = y - 1; j >= colInfo[rowInfo[row].lMin].pos; j--) { 04861 tmpCol = colOrder[j]; 04862 if (xy[row][tmpCol]) { 04863 rowInfo[row].lMax = tmpCol; 04864 break; 04865 } 04866 } 04867 } 04868 } 04869 04870 if (rowInfo[row].gNum == 1) { 04871 rowInfo[row].gMin = col; 04872 rowInfo[row].gMax = col; 04873 } else { 04874 if (col == rowInfo[row].gMax) 04875 rowInfo[row].gMax = col; 04876 else if (col == rowInfo[row].gMin) { 04877 rowInfo[row].gMin = rowInfo[row].lMin; 04878 if (lastVar >= colInfo[rowInfo[row].gMax].pos) 04879 rowInfo[row].gMax = col; 04880 } else if (lastVar >= colInfo[rowInfo[row].gMax].pos) 04881 rowInfo[row].gMax = col; 04882 } 04883 04884 if (colInfo[col].lNum) { 04885 if (i == colInfo[col].prevG) 04886 i = rowInfo[colInfo[col].lMin].pos - 1; 04887 else if (i == rowInfo[colInfo[col].lMax].pos) 04888 i = colInfo[col].nextG - 1; 04889 } 04890 } 04891 04892 s = rowInfo[colInfo[col].lMin].pos; 04893 t = rowInfo[colInfo[col].lMax].pos; 04894 for (i = s; i <= t; i++) { 04895 row = rowOrder[i]; 04896 if (xy[row][col]) { 04897 rowInfo[row].lNum--; 04898 if (candList) { 04899 if (rowInfo[row].lNum == 0) 04900 SortedListDelete(candList, row); 04901 else if (rowInfo[row].lNum == 1) 04902 SortedListInsert(candList, row, col, colInfo, method); 04903 } 04904 } 04905 } 04906 04907 nMoves++; 04908 } 04909 04910 04920 static void 04921 PrintMatrix(char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, 04922 RcInfo_t *rowInfo, RcInfo_t *colInfo, 04923 int startFunc, int lastFunc, int startVar, int lastVar) 04924 { 04925 int i, j, x, y; 04926 int row, col, index; 04927 char line[2048]; 04928 bdd_t *nsVar; 04929 04930 line[nCols] = '\0'; 04931 for (x = 0; x < nRows; x++) { 04932 if (startFunc != lastFunc && startVar != lastVar && 04933 x == startFunc && x != 0) { 04934 for (y = 0; y < nCols; y++) { 04935 if (y == startVar || y == lastVar) 04936 line[y] = '%'; 04937 else 04938 line[y] = '='; 04939 } 04940 fprintf(vis_stdout, "%s\n", line); 04941 } 04942 i = rowOrder[x]; 04943 for (y = 0; y < nCols; y++) { 04944 j = colOrder[y]; 04945 if (xy[i][j]) 04946 line[y] = '1'; 04947 else 04948 line[y] = '.'; 04949 } 04950 fprintf(vis_stdout, "%s\n", line); 04951 if (startFunc != lastFunc && startVar != lastVar && 04952 x == lastFunc && x < nRows - 1) { 04953 for (y = 0; y < nCols; y++) { 04954 if (y == startVar || y == lastVar) 04955 line[y] = '%'; 04956 else 04957 line[y] = '='; 04958 } 04959 fprintf(vis_stdout, "%s\n", line); 04960 } 04961 } 04962 fprintf(vis_stdout, "row order :"); 04963 for (x = 0; x < nRows; x++) { 04964 row = rowOrder[x]; 04965 fprintf(vis_stdout, " %d(", row); 04966 if (rowInfo[row].data.row.nsVarBddArray) { 04967 for (i = 0; i < array_n(rowInfo[row].data.row.nsVarBddArray); i++) { 04968 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, i); 04969 index = (int)bdd_top_var_id(nsVar); 04970 if (i == 0) 04971 fprintf(vis_stdout, "%d", index); 04972 else 04973 fprintf(vis_stdout, ",%d", index); 04974 } 04975 } 04976 fprintf(vis_stdout, ")"); 04977 } 04978 fprintf(vis_stdout, "\n"); 04979 fprintf(vis_stdout, "col order :"); 04980 for (y = 0; y < nCols; y++) { 04981 col = colOrder[y]; 04982 index = (int)bdd_top_var_id(colInfo[col].data.col.var); 04983 fprintf(vis_stdout, " %d(%d)", col, index); 04984 } 04985 fprintf(vis_stdout, "\n"); 04986 fprintf(vis_stdout, "#active rows : %d-%d\n", startFunc, lastFunc); 04987 fprintf(vis_stdout, "#active cols : %d-%d\n", startVar, lastVar); 04988 } 04989 04990 05000 static void 05001 PrintMatrixWithCluster(char **xy, ClusterList_t *headCluster, int nCols, 05002 int *rowOrder, int *colOrder, 05003 Img_DirectionType direction) 05004 { 05005 int i, j, x, y; 05006 char line[2048]; 05007 ClusterList_t *list, *tailCluster; 05008 05009 line[nCols] = '\0'; 05010 if (direction == Img_Forward_c) { 05011 tailCluster = headCluster; 05012 list = headCluster; 05013 while (list->next) { 05014 tailCluster = list->next; 05015 list = tailCluster; 05016 } 05017 list = tailCluster; 05018 while (list) { 05019 for (x = list->start; x <= list->end; x++) { 05020 i = rowOrder[x]; 05021 for (y = 0; y < nCols; y++) { 05022 j = colOrder[y]; 05023 if (xy[i][j]) 05024 line[y] = '1'; 05025 else 05026 line[y] = '.'; 05027 } 05028 fprintf(vis_stdout, "%s\n", line); 05029 } 05030 list = list->prev; 05031 if (list) { 05032 for (y = 0; y < nCols; y++) 05033 line[y] = '-'; 05034 fprintf(vis_stdout, "%s\n", line); 05035 } 05036 } 05037 } else { 05038 list = headCluster; 05039 while (list) { 05040 for (x = list->start; x <= list->end; x++) { 05041 i = rowOrder[x]; 05042 for (y = 0; y < nCols; y++) { 05043 j = colOrder[y]; 05044 if (xy[i][j]) 05045 line[y] = '1'; 05046 else 05047 line[y] = '.'; 05048 } 05049 fprintf(vis_stdout, "%s\n", line); 05050 } 05051 list = list->next; 05052 if (list) { 05053 for (y = 0; y < nCols; y++) 05054 line[y] = '-'; 05055 fprintf(vis_stdout, "%s\n", line); 05056 } 05057 } 05058 } 05059 } 05060 05061 05071 static void 05072 PrintClusterMatrix(ClusterList_t *headCluster, int nCols, 05073 int *colOrder, Img_DirectionType direction) 05074 { 05075 int j, y; 05076 char line[2048]; 05077 ClusterList_t *list, *tailCluster; 05078 05079 line[nCols] = '\0'; 05080 if (direction == Img_Forward_c) { 05081 tailCluster = headCluster; 05082 list = headCluster; 05083 while (list->next) { 05084 tailCluster = list->next; 05085 list = tailCluster; 05086 } 05087 list = tailCluster; 05088 while (list) { 05089 for (y = 0; y < nCols; y++) { 05090 j = colOrder[y]; 05091 if (list->supports[j]) 05092 line[y] = '1'; 05093 else 05094 line[y] = '.'; 05095 } 05096 fprintf(vis_stdout, "%s\n", line); 05097 list = list->prev; 05098 if (list) { 05099 for (y = 0; y < nCols; y++) 05100 line[y] = '-'; 05101 fprintf(vis_stdout, "%s\n", line); 05102 } 05103 } 05104 } else { 05105 list = headCluster; 05106 while (list) { 05107 for (y = 0; y < nCols; y++) { 05108 j = colOrder[y]; 05109 if (list->supports[j]) 05110 line[y] = '1'; 05111 else 05112 line[y] = '.'; 05113 } 05114 fprintf(vis_stdout, "%s\n", line); 05115 list = list->next; 05116 if (list) { 05117 for (y = 0; y < nCols; y++) 05118 line[y] = '-'; 05119 fprintf(vis_stdout, "%s\n", line); 05120 } 05121 } 05122 } 05123 } 05124 05125 05135 static void 05136 CheckMatrix(char **xy, SccList_t *sccList, int nRows, int nCols, 05137 RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder, 05138 int startFunc, int lastFunc, int startVar, int lastVar, int local) 05139 { 05140 int i, j, x, y; 05141 int lMin, lMax, gMin, gMax, lNum, gNum, prevG, nextG; 05142 int error = 0; 05143 05144 for (x = 0; x < nRows; x++) { 05145 i = rowOrder[x]; 05146 if (x != rowInfo[i].pos) { 05147 fprintf(vis_stderr, "Error : wrong rowOrder (%d != %d) in Row %d\n", 05148 x, rowInfo[i].pos, x); 05149 error = 1; 05150 } 05151 05152 lMin = gMin = nCols; 05153 lMax = gMax = -1; 05154 lNum = gNum = 0; 05155 prevG = -1; 05156 nextG = nCols; 05157 05158 for (y = 0; y < nCols; y++) { 05159 j = colOrder[y]; 05160 if (xy[i][j]) { 05161 gNum++; 05162 if (y < gMin) 05163 gMin = y; 05164 if (y > gMax) 05165 gMax = y; 05166 if (local) { 05167 if (x >= startFunc && x <= lastFunc && 05168 y >= startVar && y <= lastVar) { 05169 if (y < lMin) 05170 lMin = y; 05171 if (y > lMax) 05172 lMax = y; 05173 lNum++; 05174 } 05175 if (!sccList || 05176 (x >= sccList->startFunc && x <= sccList->lastFunc)) { 05177 if (y < startVar) 05178 prevG = y; 05179 if (y > lastVar && nextG == nCols) 05180 nextG = y; 05181 } 05182 } 05183 } 05184 } 05185 if (gNum != rowInfo[i].gNum) { 05186 fprintf(vis_stderr, "Error : wrong gNum (%d != %d) in Row %d\n", 05187 gNum, rowInfo[i].gNum, x); 05188 error = 1; 05189 } 05190 if (gNum > 0) { 05191 if (gMin != colInfo[rowInfo[i].gMin].pos) { 05192 fprintf(vis_stderr, "Error : wrong gMin (%d != %d) in Row %d\n", 05193 gMin, colInfo[rowInfo[i].gMin].pos, x); 05194 error = 1; 05195 } 05196 if (gMax != colInfo[rowInfo[i].gMax].pos) { 05197 fprintf(vis_stderr, "Error : wrong gMax (%d != %d) in Row %d\n", 05198 gMax, colInfo[rowInfo[i].gMax].pos, x); 05199 error = 1; 05200 } 05201 } 05202 if (local) { 05203 if (x >= startFunc && x <= lastFunc && 05204 lNum != rowInfo[i].lNum) { 05205 fprintf(vis_stderr, "Error : wrong lNum (%d != %d) in Row %d\n", 05206 lNum, rowInfo[i].lNum, x); 05207 error = 1; 05208 } 05209 if (x >= startFunc && x <= lastFunc && lMin < nCols && 05210 lMin != colInfo[rowInfo[i].lMin].pos) { 05211 fprintf(vis_stderr, "Error : wrong lMin (%d != %d) in Row %d\n", 05212 lMin, colInfo[rowInfo[i].lMin].pos, x); 05213 error = 1; 05214 } 05215 if (x >= startFunc && x <= lastFunc && lMax > -1 && 05216 lMax != colInfo[rowInfo[i].lMax].pos) { 05217 fprintf(vis_stderr, "Error : wrong lMax (%d != %d) in Row %d\n", 05218 lMax, colInfo[rowInfo[i].lMax].pos, x); 05219 error = 1; 05220 } 05221 if (!sccList || (x >= sccList->startFunc && x <= sccList->lastFunc)) { 05222 if (prevG != rowInfo[i].prevG) { 05223 fprintf(vis_stderr, "Error : wrong prevG (%d != %d) in Row %d\n", 05224 prevG, rowInfo[i].prevG, x); 05225 error = 1; 05226 } 05227 if (nextG != rowInfo[i].nextG) { 05228 fprintf(vis_stderr, "Error : wrong nextG (%d != %d) in Row %d\n", 05229 nextG, rowInfo[i].nextG, x); 05230 error = 1; 05231 } 05232 } 05233 } 05234 } 05235 05236 for (y = 0; y < nCols; y++) { 05237 j = colOrder[y]; 05238 if (y != colInfo[j].pos) { 05239 fprintf(vis_stderr, "Error : wrong colOrder (%d != %d) in Col %d\n", 05240 y, colInfo[y].pos, y); 05241 error = 1; 05242 } 05243 05244 lMin = gMin = nRows; 05245 lMax = gMax = -1; 05246 lNum = gNum = 0; 05247 prevG = -1; 05248 nextG = nRows; 05249 05250 for (x = 0; x < nRows; x++) { 05251 i = rowOrder[x]; 05252 if (xy[i][j]) { 05253 gNum++; 05254 if (x < gMin) 05255 gMin = x; 05256 if (x > gMax) 05257 gMax = x; 05258 if (local) { 05259 if (x >= startFunc && x <= lastFunc && 05260 y >= startVar && y <= lastVar) { 05261 if (x < lMin) 05262 lMin = x; 05263 if (x > lMax) 05264 lMax = x; 05265 lNum++; 05266 } 05267 if (!sccList || 05268 (y >= sccList->startVar && y <= sccList->lastVar)) { 05269 if (x < startFunc) 05270 prevG = x; 05271 if (x > lastFunc && nextG == nRows) 05272 nextG = x; 05273 } 05274 } 05275 } 05276 } 05277 if (gNum != colInfo[j].gNum) { 05278 fprintf(vis_stderr, "Error : wrong gNum (%d != %d) in Col %d\n", 05279 gNum, colInfo[j].gNum, y); 05280 error = 1; 05281 } 05282 if (gNum > 0) { 05283 if (gMin != rowInfo[colInfo[j].gMin].pos) { 05284 fprintf(vis_stderr, "Error : wrong gMin (%d != %d) in Col %d\n", 05285 gMin, rowInfo[colInfo[j].gMin].pos, y); 05286 error = 1; 05287 } 05288 if (gMax != rowInfo[colInfo[j].gMax].pos) { 05289 fprintf(vis_stderr, "Error : wrong gMax (%d != %d) in Col %d\n", 05290 gMax, rowInfo[colInfo[j].gMax].pos, y); 05291 error = 1; 05292 } 05293 } 05294 if (local) { 05295 if (y >= startVar && y <= lastVar && 05296 lNum != colInfo[j].lNum) { 05297 fprintf(vis_stderr, "Error : wrong lNum (%d != %d) in Col %d\n", 05298 lNum, colInfo[j].lNum, y); 05299 error = 1; 05300 } 05301 if (y >= startVar && y <= lastVar && lMin < nRows && 05302 lMin != rowInfo[colInfo[j].lMin].pos) { 05303 fprintf(vis_stderr, "Error : wrong lMin (%d != %d) in Col %d\n", 05304 lMin, rowInfo[colInfo[j].lMin].pos, y); 05305 error = 1; 05306 } 05307 if (y >= startVar && y <= lastVar && lMax > -1 && 05308 lMax != rowInfo[colInfo[j].lMax].pos) { 05309 fprintf(vis_stderr, "Error : wrong lMax (%d != %d) in Col %d\n", 05310 lMax, rowInfo[colInfo[j].lMax].pos, y); 05311 error = 1; 05312 } 05313 if (!sccList || (y >= sccList->startVar && y <= sccList->lastVar)) { 05314 if (prevG != colInfo[j].prevG) { 05315 fprintf(vis_stderr, "Error : wrong prevG (%d != %d) in Col %d\n", 05316 prevG, colInfo[j].prevG, y); 05317 error = 1; 05318 } 05319 if (nextG != colInfo[j].nextG) { 05320 fprintf(vis_stderr, "Error : wrong nextG (%d != %d) in Col %d\n", 05321 nextG, colInfo[j].nextG, y); 05322 error = 1; 05323 } 05324 } 05325 } 05326 } 05327 05328 assert(!error); 05329 } 05330 05331 05341 static void 05342 CheckCluster(ClusterList_t *headCluster, int nCols, 05343 RcInfo_t *colInfo, int *colOrder) 05344 { 05345 int j, y, n; 05346 int gMin, gMax, gNum; 05347 int error = 0; 05348 ClusterList_t *list; 05349 05350 n = 0; 05351 list = headCluster; 05352 while (list) { 05353 gMin = nCols; 05354 gMax = -1; 05355 gNum = 0; 05356 05357 for (y = 0; y < nCols; y++) { 05358 j = colOrder[y]; 05359 if (list->supports[j]) { 05360 gNum++; 05361 if (y < gMin) 05362 gMin = y; 05363 if (y > gMax) 05364 gMax = y; 05365 } 05366 } 05367 if (gNum != list->nSupports) { 05368 fprintf(vis_stderr, "Error : wrong nSupports (%d != %d) in Cluster %d\n", 05369 gNum, list->nSupports, n); 05370 error = 1; 05371 } 05372 if (gNum > 0) { 05373 if (gMin != colInfo[list->minCol].pos) { 05374 fprintf(vis_stderr, "Error : wrong gMin (%d != %d) in Cluster %d\n", 05375 gMin, colInfo[list->minCol].pos, n); 05376 error = 1; 05377 } 05378 if (gMax != colInfo[list->maxCol].pos) { 05379 fprintf(vis_stderr, "Error : wrong gMax (%d != %d) in Cluster %d\n", 05380 gMax, colInfo[list->maxCol].pos, n); 05381 error = 1; 05382 } 05383 } 05384 n++; 05385 list = list->next; 05386 } 05387 05388 assert(!error); 05389 } 05390 05391 05401 static void 05402 WriteMatrix(FILE *fout, char **xy, int nRows, int nCols, int *rowOrder, 05403 int *colOrder, RcInfo_t *rowInfo, RcInfo_t *colInfo) 05404 { 05405 int x, y; 05406 int row, col; 05407 05408 for (x = 0; x < nRows; x++) { 05409 row = rowOrder[x]; 05410 for (y = 0; y < nCols; y++) { 05411 col = colOrder[y]; 05412 if (xy[row][col]) 05413 fprintf(fout, "%d %d %d\n", y, x, colInfo[col].data.col.type); 05414 } 05415 } 05416 } 05417 05418 05428 static void 05429 PrintRow(char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, 05430 int from, int to) 05431 { 05432 int x, y, row, col; 05433 05434 for (x = from; x <= to; x++) { 05435 row = rowOrder[x]; 05436 fprintf(vis_stdout, "[%d]%d :", x, row); 05437 for (y = 0; y < nCols; y++) { 05438 col = colOrder[y]; 05439 if (xy[row][col]) 05440 fprintf(vis_stdout, " %d(%d)", y, col); 05441 } 05442 fprintf(vis_stdout, "\n"); 05443 } 05444 } 05445 05446 05456 static void 05457 PrintCol(char **xy, int nRows, int nCols, int *rowOrder, int *colOrder, 05458 int from, int to) 05459 { 05460 int x, y, row, col; 05461 05462 for (y = from; y <= to; y++) { 05463 col = colOrder[y]; 05464 fprintf(vis_stdout, "[%d]%d :", y, col); 05465 for (x = 0; x < nRows; x++) { 05466 row = rowOrder[x]; 05467 if (xy[row][col]) 05468 fprintf(vis_stdout, " %d(%d)", x, row); 05469 } 05470 fprintf(vis_stdout, "\n"); 05471 } 05472 } 05473 05474 05484 static RcListInfo_t * 05485 SortedListAlloc(void) 05486 { 05487 RcListInfo_t *listInfo; 05488 05489 listInfo = ALLOC(RcListInfo_t, 1); 05490 memset(listInfo, 0, sizeof(RcListInfo_t)); 05491 listInfo->table = st_init_table(st_numcmp, st_numhash); 05492 return(listInfo); 05493 } 05494 05495 05505 static void 05506 SortedListFree(RcListInfo_t *candList) 05507 { 05508 RcList_t *candidate, *next; 05509 05510 candidate = candList->head; 05511 while (candidate) { 05512 next = candidate->next; 05513 FREE(candidate); 05514 candidate = next; 05515 } 05516 st_free_table(candList->table); 05517 FREE(candList); 05518 } 05519 05520 05530 static void 05531 SortedListInsert(RcListInfo_t *candList, int index, 05532 int otherIndex, RcInfo_t *otherInfo, int method) 05533 { 05534 RcList_t *candidate, *cur; 05535 int lNum, gNum, diffH, diffT; 05536 05537 candidate = ALLOC(RcList_t, 1); 05538 candidate->index = index; 05539 candidate->otherIndex = otherIndex; 05540 st_insert(candList->table, (char *)(long)index, (char *)candidate); 05541 05542 if (candList->num == 0) { 05543 candidate->next = NIL(RcList_t); 05544 candidate->prev = NIL(RcList_t); 05545 candList->cur = candidate; 05546 candList->head = candidate; 05547 candList->tail = candidate; 05548 candList->num = 1; 05549 candList->maxNum = 1; 05550 return; 05551 } 05552 05553 candList->num++; 05554 if (candList->num > candList->maxNum) 05555 candList->maxNum = candList->num; 05556 05557 if (method == 1) { 05558 diffH = abs(index - candList->head->index); 05559 diffT = abs(index - candList->tail->index); 05560 05561 if (diffH < diffT) { 05562 cur = candList->head; 05563 while (cur) { 05564 if (index < cur->index) { 05565 candidate->next = cur; 05566 candidate->prev = cur->prev; 05567 if (cur->prev) 05568 cur->prev->next = candidate; 05569 cur->prev = candidate; 05570 if (cur == candList->head) 05571 candList->head = candidate; 05572 break; 05573 } 05574 cur = cur->next; 05575 } 05576 if (!cur) { 05577 candidate->next = NIL(RcList_t); 05578 candidate->prev = candList->tail; 05579 candList->tail->next = candidate; 05580 candList->tail = candidate; 05581 } 05582 } else { 05583 cur = candList->tail; 05584 while (cur) { 05585 if (index > cur->index) { 05586 candidate->next = cur->next; 05587 if (cur->next) 05588 cur->next->prev = candidate; 05589 candidate->prev = cur; 05590 cur->next = candidate; 05591 if (cur == candList->tail) 05592 candList->tail = candidate; 05593 break; 05594 } 05595 cur = cur->prev; 05596 } 05597 if (!cur) { 05598 candidate->next = candList->head; 05599 candidate->prev = NIL(RcList_t); 05600 candList->head->prev = candidate; 05601 candList->head = candidate; 05602 } 05603 } 05604 05605 if (candList->cur) { 05606 if (candList->cur->index == candList->curIndex) 05607 return; 05608 else if (candList->cur->index > candList->curIndex) { 05609 cur = candList->cur->prev; 05610 while (cur) { 05611 if (cur->index <= candList->curIndex) 05612 break; 05613 candList->cur = cur; 05614 cur = cur->prev; 05615 } 05616 } else { 05617 if (candidate->index > candList->curIndex) 05618 candList->cur = candidate; 05619 else 05620 candList->cur = candList->head; 05621 } 05622 } else 05623 candList->cur = candList->head; 05624 } else if (method == 2) { 05625 lNum = otherInfo[otherIndex].lNum; 05626 gNum = otherInfo[otherIndex].gNum; 05627 diffH = abs(lNum - otherInfo[candList->head->otherIndex].lNum); 05628 diffT = abs(lNum - otherInfo[candList->tail->otherIndex].lNum); 05629 05630 if (diffH < diffT) { 05631 cur = candList->head; 05632 while (cur) { 05633 if (lNum < otherInfo[cur->otherIndex].lNum || 05634 (lNum == otherInfo[cur->otherIndex].lNum && 05635 (gNum < otherInfo[cur->otherIndex].gNum || 05636 (gNum == otherInfo[cur->otherIndex].gNum && 05637 index < cur->index)))) { 05638 candidate->next = cur; 05639 candidate->prev = cur->prev; 05640 if (cur->prev) 05641 cur->prev->next = candidate; 05642 cur->prev = candidate; 05643 if (cur == candList->head) 05644 candList->head = candidate; 05645 break; 05646 } 05647 cur = cur->next; 05648 } 05649 if (!cur) { 05650 candidate->next = NIL(RcList_t); 05651 candidate->prev = candList->tail; 05652 candList->tail->next = candidate; 05653 candList->tail = candidate; 05654 } 05655 } else { 05656 cur = candList->tail; 05657 while (cur) { 05658 if (lNum > otherInfo[cur->otherIndex].lNum || 05659 (lNum == otherInfo[cur->otherIndex].lNum && 05660 (gNum > otherInfo[cur->otherIndex].gNum || 05661 (gNum == otherInfo[cur->otherIndex].gNum && 05662 index > cur->index)))) { 05663 candidate->next = cur->next; 05664 if (cur->next) 05665 cur->next->prev = candidate; 05666 candidate->prev = cur; 05667 cur->next = candidate; 05668 if (cur == candList->tail) 05669 candList->tail = candidate; 05670 break; 05671 } 05672 cur = cur->prev; 05673 } 05674 if (!cur) { 05675 candidate->next = candList->head; 05676 candidate->prev = NIL(RcList_t); 05677 candList->head->prev = candidate; 05678 candList->head = candidate; 05679 } 05680 } 05681 } else if (method == 3) { 05682 lNum = otherInfo[otherIndex].lNum; 05683 gNum = otherInfo[otherIndex].gNum; 05684 diffH = abs(lNum - otherInfo[candList->head->otherIndex].lNum); 05685 diffT = abs(lNum - otherInfo[candList->tail->otherIndex].lNum); 05686 05687 if (diffH < diffT) { 05688 cur = candList->head; 05689 while (cur) { 05690 if (lNum < otherInfo[cur->otherIndex].lNum || 05691 (lNum == otherInfo[cur->otherIndex].lNum && 05692 (gNum > otherInfo[cur->otherIndex].gNum || 05693 (gNum == otherInfo[cur->otherIndex].gNum && 05694 otherInfo[index].pos < otherInfo[cur->index].pos)))) { 05695 candidate->next = cur; 05696 candidate->prev = cur->prev; 05697 if (cur->prev) 05698 cur->prev->next = candidate; 05699 cur->prev = candidate; 05700 if (cur == candList->head) 05701 candList->head = candidate; 05702 break; 05703 } 05704 cur = cur->next; 05705 } 05706 if (!cur) { 05707 candidate->next = NIL(RcList_t); 05708 candidate->prev = candList->tail; 05709 candList->tail->next = candidate; 05710 candList->tail = candidate; 05711 } 05712 } else { 05713 cur = candList->tail; 05714 while (cur) { 05715 if (lNum > otherInfo[cur->otherIndex].lNum || 05716 (lNum == otherInfo[cur->otherIndex].lNum && 05717 (gNum < otherInfo[cur->otherIndex].gNum || 05718 (gNum == otherInfo[cur->otherIndex].gNum && 05719 otherInfo[index].pos > otherInfo[cur->index].pos)))) { 05720 candidate->next = cur->next; 05721 if (cur->next) 05722 cur->next->prev = candidate; 05723 candidate->prev = cur; 05724 cur->next = candidate; 05725 if (cur == candList->tail) 05726 candList->tail = candidate; 05727 break; 05728 } 05729 cur = cur->prev; 05730 } 05731 if (!cur) { 05732 candidate->next = candList->head; 05733 candidate->prev = NIL(RcList_t); 05734 candList->head->prev = candidate; 05735 candList->head = candidate; 05736 } 05737 } 05738 } else if (method == 4) { 05739 lNum = otherInfo[index].lNum; 05740 cur = candList->tail; 05741 while (cur) { 05742 if (cur->otherIndex > 1 || 05743 (cur->otherIndex == 1 && otherInfo[cur->index].lNum > lNum) || 05744 (cur->otherIndex == 1 && otherInfo[cur->index].lNum == lNum && 05745 otherInfo[index].pos > otherInfo[cur->index].pos)) { 05746 candidate->next = cur->next; 05747 if (cur->next) 05748 cur->next->prev = candidate; 05749 candidate->prev = cur; 05750 cur->next = candidate; 05751 if (cur == candList->tail) 05752 candList->tail = candidate; 05753 break; 05754 } 05755 cur = cur->prev; 05756 } 05757 if (!cur) { 05758 candidate->next = candList->head; 05759 candidate->prev = NIL(RcList_t); 05760 candList->head->prev = candidate; 05761 candList->head = candidate; 05762 } 05763 } else { 05764 fprintf(vis_stderr, "** mlp error: invalid sort mode %d\n", method); 05765 } 05766 05767 candList->cur = candList->head; 05768 } 05769 05770 05780 static void 05781 SortedListDelete(RcListInfo_t *candList, int index) 05782 { 05783 RcList_t *candidate; 05784 long lindex = (long) index; 05785 05786 if (st_lookup(candList->table, (char *)lindex, &candidate)) { 05787 if (candidate == candList->head) 05788 candList->head = candidate->next; 05789 else 05790 candidate->prev->next = candidate->next; 05791 if (candidate == candList->tail) 05792 candList->tail = candidate->prev; 05793 else 05794 candidate->next->prev = candidate->prev; 05795 if (candidate == candList->cur) { 05796 if (candidate->next) 05797 candList->cur = candidate->next; 05798 else 05799 candList->cur = candList->head; 05800 } 05801 st_delete(candList->table, &lindex, NULL); 05802 candList->num--; 05803 FREE(candidate); 05804 } 05805 } 05806 05807 05817 static void 05818 SortedListMove(RcListInfo_t *candList, RcInfo_t *info, int index, int method) 05819 { 05820 RcList_t *cur, *prev, *left, *right; 05821 05822 if (st_lookup(candList->table, (char *)(long)index, &cur)) { 05823 if (method == 1) { 05824 } else if (method == 2) { 05825 } else if (method == 3) { 05826 while (cur != candList->head) { 05827 prev = cur->prev; 05828 if (info[prev->index].lNum < info[cur->index].lNum || 05829 (info[prev->index].lNum == info[cur->index].lNum && 05830 (info[prev->index].gNum > info[cur->index].gNum || 05831 (info[prev->index].gNum == info[cur->index].gNum && 05832 info[prev->index].pos < info[cur->index].pos)))) { 05833 break; 05834 } 05835 05836 /* swap */ 05837 if (prev == candList->head) 05838 candList->head = cur; 05839 if (cur == candList->tail) 05840 candList->tail = prev; 05841 left = prev->prev; 05842 right = cur->next; 05843 if (left) 05844 left->next = cur; 05845 cur->next = prev; 05846 prev->next = right; 05847 if (right) 05848 right->prev = prev; 05849 prev->prev = cur; 05850 cur->prev = left; 05851 } 05852 } else if (method == 4) { 05853 while (cur != candList->head) { 05854 prev = cur->prev; 05855 if (prev->otherIndex > cur->otherIndex || 05856 (prev->otherIndex == cur->otherIndex && 05857 (info[prev->index].lNum > info[cur->index].lNum || 05858 (info[prev->index].lNum == info[cur->index].lNum && 05859 info[prev->index].pos < info[cur->index].pos)))) { 05860 break; 05861 } 05862 05863 /* swap */ 05864 if (prev == candList->head) 05865 candList->head = cur; 05866 if (cur == candList->tail) 05867 candList->tail = prev; 05868 left = prev->prev; 05869 right = cur->next; 05870 if (left) 05871 left->next = cur; 05872 cur->next = prev; 05873 prev->next = right; 05874 if (right) 05875 right->prev = prev; 05876 prev->prev = cur; 05877 cur->prev = left; 05878 } 05879 } 05880 } 05881 } 05882 05883 05893 static void 05894 CheckSortedList(RcListInfo_t *candList, RcInfo_t *info, int method) 05895 { 05896 RcList_t *cur, *next, *candidate; 05897 int error = 0; 05898 int num = 0; 05899 05900 cur = candList->head; 05901 while (cur) { 05902 num++; 05903 next = cur->next; 05904 if (next) { 05905 if (next->prev != cur) { 05906 error++; 05907 if (next->prev) { 05908 fprintf(vis_stderr, "Error : prev of %d is not %d (!= %d) in list\n", 05909 next->index, cur->index, next->prev->index); 05910 } else { 05911 fprintf(vis_stderr, "Error : prev of %d is not %d (!= nil) in list\n", 05912 next->index, cur->index); 05913 } 05914 } 05915 if (method == 1) { 05916 } else if (method == 2) { 05917 } else if (method == 3) { 05918 if (info[cur->index].lNum > info[next->index].lNum) { 05919 error++; 05920 fprintf(vis_stderr, 05921 "Error : cur(%d) lNum(%d) > next(%d) lNum(%d) in row list\n", 05922 cur->index, info[cur->index].lNum, 05923 next->index, info[next->index].lNum); 05924 } else if (info[cur->index].lNum == info[next->index].lNum && 05925 info[cur->index].gNum < info[next->index].gNum) { 05926 error++; 05927 fprintf(vis_stderr, 05928 "Error : cur(%d) gNum(%d) < next(%d) gNum(%d) in row list\n", 05929 cur->index, info[cur->index].gNum, 05930 next->index, info[next->index].gNum); 05931 } else if (info[cur->index].lNum == info[next->index].lNum && 05932 info[cur->index].gNum == info[next->index].gNum && 05933 info[cur->index].pos > info[next->index].pos) { 05934 error++; 05935 fprintf(vis_stderr, 05936 "Error : cur(%d) pos(%d) > next(%d) pos(%d) in row list\n", 05937 cur->index, info[cur->index].pos, 05938 next->index, info[next->index].pos); 05939 } 05940 } else if (method == 4) { 05941 if (cur->otherIndex < next->otherIndex) { 05942 error++; 05943 fprintf(vis_stderr, 05944 "Error : cur(%d) length(%d) < next(%d) length(%d) in col list\n", 05945 cur->index, cur->otherIndex, next->index, next->otherIndex); 05946 } else if (cur->otherIndex == next->otherIndex && 05947 info[cur->index].lNum < info[next->index].lNum) { 05948 error++; 05949 fprintf(vis_stderr, 05950 "Error : cur(%d) lNum(%d) < next(%d) lNum(%d) in col list\n", 05951 cur->index, info[cur->index].lNum, 05952 next->index, info[next->index].lNum); 05953 } else if (cur->otherIndex == next->otherIndex && 05954 info[cur->index].lNum == info[next->index].lNum && 05955 info[cur->index].pos > info[next->index].pos) { 05956 error++; 05957 fprintf(vis_stderr, 05958 "Error : cur(%d) pos(%d) > next(%d) pos(%d) in col list\n", 05959 cur->index, info[cur->index].pos, 05960 next->index, info[next->index].pos); 05961 } 05962 } 05963 } else { 05964 if (cur != candList->tail) { 05965 error++; 05966 if (candList->tail) { 05967 fprintf(vis_stderr, "Error : different tail in list (%d != %d)\n", 05968 cur->index, candList->tail->index); 05969 } else { 05970 fprintf(vis_stderr, "Error : different tail in list (%d != nil)\n", 05971 cur->index); 05972 } 05973 } 05974 } 05975 if (!st_lookup(candList->table, (char *)(long)cur->index, &candidate)) { 05976 error++; 05977 fprintf(vis_stderr, "Error : index %d not in table\n", cur->index); 05978 } 05979 cur = next; 05980 } 05981 if (num != candList->num) { 05982 error++; 05983 fprintf(vis_stderr, 05984 "Error : different number of elements in list (%d != %d)\n", 05985 num, candList->num); 05986 } 05987 if (num != st_count(candList->table)) { 05988 error++; 05989 fprintf(vis_stderr, 05990 "Error : different number of elements in table (%d != %d)\n", 05991 num, st_count(candList->table)); 05992 } 05993 assert(!error); 05994 } 05995 05996 06006 static void 06007 MlpCluster(mdd_manager *mddManager, char **xy, int nRows, int nCols, 06008 int nActiveRows, int nActiveCols, 06009 int *nClusterRows, int *nClusterCols, 06010 int *rowOrder, int *colOrder, 06011 RcInfo_t *rowInfo, RcInfo_t *colInfo, 06012 array_t *clusterArray, array_t *arraySmoothVarBddArray, 06013 Img_DirectionType direction, int *cRowOrder, 06014 array_t *nsVarBddArray, int *sccBorder, 06015 int *varPos, ImgTrmOption_t *option) 06016 { 06017 int i, j, row, col; 06018 int ncRows, ncCols; 06019 int index, qVarPos; 06020 int s1, t1, s2; 06021 array_t *smoothVarBddArray; 06022 mdd_t *nsVar, *relation, *cluster, *tempCluster; 06023 ClusterList_t *list, *headCluster, *tailCluster, *nextList, *prevList; 06024 ClusterSortedList_t *clusterSortedList; 06025 long initialTime, finalTime; 06026 int moveFlag = 1; 06027 array_t *nonAppearingVarBddArray; 06028 char *existFlag; 06029 array_t *supportArray, *tmpArray; 06030 int nVars = bdd_num_vars(mddManager); 06031 mdd_t *one; 06032 06033 if (option->mlpVerbosity) 06034 initialTime = util_cpu_time(); 06035 else 06036 initialTime = 0; 06037 06038 ncCols = nActiveCols; 06039 headCluster = NIL(ClusterList_t); 06040 tailCluster = NIL(ClusterList_t); 06041 clusterSortedList = NIL(ClusterSortedList_t); 06042 if (option->mlpCluster == 0) { 06043 if (direction == Img_Forward_c) { 06044 for (i = nActiveRows - 1; i >= 0;) { 06045 row = rowOrder[i]; 06046 06047 list = ALLOC(ClusterList_t, 1); 06048 memset(list, 0, sizeof(ClusterList_t)); 06049 list->flag = 3; 06050 list->start = i; 06051 list->end = i; 06052 list->supports = ALLOC(char, nCols); 06053 memcpy(list->supports, xy[row], sizeof(char) * nCols); 06054 list->minCol = rowInfo[row].gMin; 06055 list->maxCol = rowInfo[row].gMax; 06056 list->nSupports = MlpCountSupport(list, colOrder, ncCols); 06057 list->product = bdd_dup(rowInfo[row].data.row.func); 06058 list->nQuantifyVars = 0; 06059 list->affinity = 0.0; 06060 if (rowInfo[row].data.row.nsVarBddArray) 06061 list->nsVarBddArray = array_dup(rowInfo[row].data.row.nsVarBddArray); 06062 else 06063 list->nsVarBddArray = NIL(array_t); 06064 06065 if (headCluster) 06066 tailCluster->next = list; 06067 else 06068 headCluster = list; 06069 list->next = NIL(ClusterList_t); 06070 list->prev = tailCluster; 06071 tailCluster = list; 06072 06073 i--; 06074 06075 if (sccBorder && sccBorder[i + 1] == 1) 06076 continue; 06077 if (bdd_size(list->product) >= option->clusterSize) 06078 continue; 06079 06080 while (i >= 0) { 06081 row = rowOrder[i]; 06082 relation = rowInfo[row].data.row.func; 06083 if (bdd_size(list->product) >= option->clusterSize) 06084 break; 06085 cluster = bdd_and(list->product, relation, 1, 1); 06086 if (bdd_size(cluster) <= option->clusterSize) { 06087 mdd_free(list->product); 06088 list->product = cluster; 06089 list->start = i; 06090 06091 if (list->nsVarBddArray) { 06092 array_append(list->nsVarBddArray, 06093 rowInfo[row].data.row.nsVarBddArray); 06094 } 06095 06096 list->nSupports = 0; 06097 list->minCol = nActiveCols; 06098 list->maxCol = -1; 06099 s1 = nActiveCols; 06100 t1 = -1; 06101 supportArray = mdd_get_bdd_support_ids(mddManager, list->product); 06102 for (j = 0; j < array_n(supportArray); j++) { 06103 index = array_fetch(int, supportArray, j); 06104 if (varPos[index] == 0) { 06105 if ((int)bdd_top_var_id(colInfo[0].data.col.var) != index) 06106 continue; 06107 } 06108 index = varPos[index]; 06109 list->supports[index] = 1; 06110 list->nSupports++; 06111 s2 = colInfo[index].pos; 06112 if (s2 < s1) { 06113 s1 = s2; 06114 list->minCol = index; 06115 } 06116 if (s2 > t1) { 06117 t1 = s2; 06118 list->maxCol = index; 06119 } 06120 } 06121 array_free(supportArray); 06122 06123 i--; 06124 if (option->mlpDebug) 06125 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06126 } else { 06127 mdd_free(cluster); 06128 break; 06129 } 06130 } 06131 06132 ncCols = RemoveLocalVarsInCluster(mddManager, xy, 06133 list, nActiveRows, ncCols, 06134 rowInfo, colInfo, 06135 rowOrder, colOrder, 06136 moveFlag, option); 06137 } 06138 } else { 06139 for (i = 0; i < nActiveRows;) { 06140 row = rowOrder[i]; 06141 06142 list = ALLOC(ClusterList_t, 1); 06143 memset(list, 0, sizeof(ClusterList_t)); 06144 list->flag = 3; 06145 list->start = i; 06146 list->end = i; 06147 list->supports = ALLOC(char, nCols); 06148 memcpy(list->supports, xy[row], sizeof(char) * nCols); 06149 list->minCol = rowInfo[row].gMin; 06150 list->maxCol = rowInfo[row].gMax; 06151 list->nSupports = MlpCountSupport(list, colOrder, ncCols); 06152 list->product = bdd_dup(rowInfo[row].data.row.func); 06153 list->nQuantifyVars = 0; 06154 list->affinity = 0.0; 06155 if (rowInfo[row].data.row.nsVarBddArray) 06156 list->nsVarBddArray = array_dup(rowInfo[row].data.row.nsVarBddArray); 06157 else 06158 list->nsVarBddArray = NIL(array_t); 06159 06160 if (headCluster) 06161 tailCluster->next = list; 06162 else 06163 headCluster = list; 06164 list->next = NIL(ClusterList_t); 06165 list->prev = tailCluster; 06166 tailCluster = list; 06167 06168 i++; 06169 06170 if (sccBorder && sccBorder[i - 1] == 2) 06171 continue; 06172 if (bdd_size(list->product) >= option->clusterSize) 06173 continue; 06174 06175 while (i < nActiveRows) { 06176 row = rowOrder[i]; 06177 relation = rowInfo[row].data.row.func; 06178 if (bdd_size(list->product) >= option->clusterSize) 06179 break; 06180 cluster = bdd_and(list->product, relation, 1, 1); 06181 if (bdd_size(cluster) <= option->clusterSize) { 06182 mdd_free(list->product); 06183 list->product = cluster; 06184 list->end = i; 06185 06186 if (list->nsVarBddArray) { 06187 array_append(list->nsVarBddArray, 06188 rowInfo[row].data.row.nsVarBddArray); 06189 } 06190 06191 list->nSupports = 0; 06192 list->minCol = nActiveCols; 06193 list->maxCol = -1; 06194 s1 = nActiveCols; 06195 t1 = -1; 06196 supportArray = mdd_get_bdd_support_ids(mddManager, list->product); 06197 for (j = 0; j < array_n(supportArray); j++) { 06198 index = array_fetch(int, supportArray, j); 06199 if (varPos[index] == 0) { 06200 if ((int)bdd_top_var_id(colInfo[0].data.col.var) != index) 06201 continue; 06202 } 06203 index = varPos[index]; 06204 list->supports[index] = 1; 06205 list->nSupports++; 06206 s2 = colInfo[index].pos; 06207 if (s2 < s1) { 06208 s1 = s2; 06209 list->minCol = index; 06210 } 06211 if (s2 > t1) { 06212 t1 = s2; 06213 list->maxCol = index; 06214 } 06215 } 06216 array_free(supportArray); 06217 06218 i++; 06219 if (option->mlpDebug) 06220 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06221 } else { 06222 mdd_free(cluster); 06223 break; 06224 } 06225 } 06226 06227 ncCols = RemoveLocalVarsInCluster(mddManager, xy, 06228 list, nActiveRows, ncCols, 06229 rowInfo, colInfo, 06230 rowOrder, colOrder, 06231 moveFlag, option); 06232 } 06233 } 06234 } else { /* option->mlpCluster == 1 */ 06235 if (direction == Img_Forward_c) { 06236 for (i = 0; i < nActiveRows; i++) { 06237 row = rowOrder[i]; 06238 list = ALLOC(ClusterList_t, 1); 06239 memset(list, 0, sizeof(ClusterList_t)); 06240 06241 if (headCluster && headCluster->flag != 3) 06242 list->flag = 1; 06243 else 06244 list->flag = 2; 06245 list->start = i; 06246 list->end = i; 06247 list->supports = ALLOC(char, nCols); 06248 memcpy(list->supports, xy[row], sizeof(char) * nCols); 06249 list->minCol = rowInfo[row].gMin; 06250 list->maxCol = rowInfo[row].gMax; 06251 list->nSupports = MlpCountSupport(list, colOrder, ncCols); 06252 list->product = bdd_dup(rowInfo[row].data.row.func); 06253 list->nQuantifyVars = MlpNumQuantifyVars(list, rowInfo, colInfo, 06254 colOrder, ncCols); 06255 if (rowInfo[row].data.row.nsVarBddArray) 06256 list->nsVarBddArray = array_dup(rowInfo[row].data.row.nsVarBddArray); 06257 else 06258 list->nsVarBddArray = NIL(array_t); 06259 06260 if (bdd_size(list->product) >= option->clusterSize) { 06261 if (headCluster) { 06262 ncCols = RecursiveCluster(mddManager, headCluster, 06263 clusterSortedList, 06264 xy, rowInfo, colInfo, 06265 rowOrder, colOrder, nActiveRows, ncCols, 06266 direction, varPos, moveFlag, option); 06267 if (option->mlpDebug) 06268 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06269 } 06270 list->flag = 3; 06271 ncCols = RemoveLocalVarsInCluster(mddManager, xy, 06272 list, nActiveRows, ncCols, 06273 rowInfo, colInfo, 06274 rowOrder, colOrder, 06275 moveFlag, option); 06276 if (option->mlpDebug) 06277 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06278 list->affinity = 0.0; 06279 clusterSortedList = NIL(ClusterSortedList_t); 06280 } else if (sccBorder && i > 0 && sccBorder[i] == 1) { 06281 ncCols = RecursiveCluster(mddManager, headCluster, 06282 clusterSortedList, 06283 xy, rowInfo, colInfo, 06284 rowOrder, colOrder, nActiveRows, ncCols, 06285 direction, varPos, moveFlag, option); 06286 if (option->mlpDebug) 06287 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06288 list->flag = 2; 06289 list->affinity = 0.0; 06290 clusterSortedList = NIL(ClusterSortedList_t); 06291 if (option->mlpClusterSortedList) { 06292 clusterSortedList = ClusterSortedListInsert(clusterSortedList, list, 06293 option->mlpClusterQuantifyVars); 06294 } 06295 } else { 06296 if (headCluster && headCluster->flag != 3) { 06297 list->affinity = MlpSupportAffinity(list, headCluster, colInfo, 06298 colOrder, ncCols, 06299 option->mlpCluster); 06300 } else 06301 list->affinity = 0.0; 06302 if (option->mlpClusterSortedList) { 06303 clusterSortedList = ClusterSortedListInsert(clusterSortedList, list, 06304 option->mlpClusterQuantifyVars); 06305 } 06306 } 06307 06308 list->next = headCluster; 06309 list->prev = NIL(ClusterList_t); 06310 if (headCluster) { 06311 if (headCluster->flag == 1) 06312 headCluster->flag = 0; 06313 headCluster->prev = list; 06314 } 06315 headCluster = list; 06316 } 06317 } else { 06318 for (i = nActiveRows - 1; i >= 0; i--) { 06319 row = rowOrder[i]; 06320 list = ALLOC(ClusterList_t, 1); 06321 memset(list, 0, sizeof(ClusterList_t)); 06322 06323 if (headCluster && headCluster->flag != 3) 06324 list->flag = 1; 06325 else 06326 list->flag = 2; 06327 list->start = i; 06328 list->end = i; 06329 list->supports = ALLOC(char, nCols); 06330 memcpy(list->supports, xy[row], sizeof(char) * nCols); 06331 list->minCol = rowInfo[row].gMin; 06332 list->maxCol = rowInfo[row].gMax; 06333 list->nSupports = MlpCountSupport(list, colOrder, ncCols); 06334 list->product = bdd_dup(rowInfo[row].data.row.func); 06335 list->nQuantifyVars = MlpNumQuantifyVars(list, rowInfo, colInfo, 06336 colOrder, ncCols); 06337 if (rowInfo[row].data.row.nsVarBddArray) 06338 list->nsVarBddArray = array_dup(rowInfo[row].data.row.nsVarBddArray); 06339 else 06340 list->nsVarBddArray = NIL(array_t); 06341 06342 if ( bdd_size(list->product) >= option->clusterSize) { 06343 if (headCluster) { 06344 ncCols = RecursiveCluster(mddManager, headCluster, 06345 clusterSortedList, 06346 xy, rowInfo, colInfo, 06347 rowOrder, colOrder, nActiveRows, ncCols, 06348 direction, varPos, moveFlag, option); 06349 if (option->mlpDebug) 06350 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06351 } 06352 list->flag = 3; 06353 ncCols = RemoveLocalVarsInCluster(mddManager, xy, 06354 list, nActiveRows, ncCols, 06355 rowInfo, colInfo, 06356 rowOrder, colOrder, 06357 moveFlag, option); 06358 if (option->mlpDebug) 06359 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06360 list->affinity = 0.0; 06361 clusterSortedList = NIL(ClusterSortedList_t); 06362 } else if (sccBorder && i < (nActiveRows - 1) && sccBorder[i] == 2) { 06363 ncCols = RecursiveCluster(mddManager, headCluster, 06364 clusterSortedList, 06365 xy, rowInfo, colInfo, 06366 rowOrder, colOrder, nActiveRows, ncCols, 06367 direction, varPos, moveFlag, option); 06368 if (option->mlpDebug) 06369 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06370 list->flag = 2; 06371 list->affinity = 0.0; 06372 clusterSortedList = NIL(ClusterSortedList_t); 06373 if (option->mlpClusterSortedList) { 06374 clusterSortedList = ClusterSortedListInsert(clusterSortedList, list, 06375 option->mlpClusterQuantifyVars); 06376 } 06377 } else { 06378 if (headCluster && headCluster->flag != 3) { 06379 list->affinity = MlpSupportAffinity(list, headCluster, colInfo, 06380 colOrder, ncCols, 06381 option->mlpCluster); 06382 } else 06383 list->affinity = 0.0; 06384 if (option->mlpClusterSortedList) { 06385 clusterSortedList = ClusterSortedListInsert(clusterSortedList, list, 06386 option->mlpClusterQuantifyVars); 06387 } 06388 } 06389 06390 list->next = headCluster; 06391 list->prev = NIL(ClusterList_t); 06392 if (headCluster) { 06393 if (headCluster->flag == 1) 06394 headCluster->flag = 0; 06395 headCluster->prev = list; 06396 } 06397 headCluster = list; 06398 06399 if (option->mlpClusterSortedList && option->mlpDebug) { 06400 int n1, n2; 06401 06402 n1 = CountClusterList(headCluster); 06403 n2 = CountClusterSortedList(clusterSortedList); 06404 assert(n1 == n2); 06405 } 06406 } 06407 } 06408 06409 if (headCluster->flag == 1) { 06410 ncCols = RecursiveCluster(mddManager, headCluster, clusterSortedList, 06411 xy, rowInfo, colInfo, 06412 rowOrder, colOrder, nActiveRows, ncCols, 06413 direction, varPos, moveFlag, option); 06414 if (option->mlpDebug) 06415 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06416 } 06417 } 06418 06419 list = headCluster; 06420 one = bdd_one(mddManager); 06421 while (list) { 06422 if (bdd_equal(list->product, one)) { 06423 assert(list->nSupports == 0); 06424 06425 prevList = list->prev; 06426 nextList = list->next; 06427 if ((!prevList) && (!nextList)) /* unity relation */ 06428 break; 06429 06430 mdd_free(list->product); 06431 if (list->nsVarBddArray) 06432 array_free(list->nsVarBddArray); 06433 FREE(list->supports); 06434 06435 if (nextList) { 06436 if (list->start < nextList->start) 06437 nextList->start = list->start; 06438 if (list->end > nextList->end) 06439 nextList->end = list->end; 06440 06441 if (list == headCluster) 06442 headCluster = nextList; 06443 06444 FREE(list); 06445 } else { 06446 if (list->start < prevList->start) 06447 prevList->start = list->start; 06448 if (list->end > prevList->end) 06449 prevList->end = list->end; 06450 FREE(list); 06451 } 06452 if (prevList) 06453 prevList->next = nextList; 06454 if (nextList) 06455 nextList->prev = prevList; 06456 list = nextList; 06457 continue; 06458 } 06459 list = list->next; 06460 } 06461 bdd_free(one); 06462 06463 if (option->mlpVerbosity >= 3 && option->mlpPrintMatrix) { 06464 PrintMatrixWithCluster(xy, headCluster, ncCols, rowOrder, colOrder, 06465 direction); 06466 fprintf(vis_stdout, "******** cluster matrix ************\n"); 06467 PrintClusterMatrix(headCluster, ncCols, colOrder, direction); 06468 } 06469 if (option->mlpDebug) 06470 CheckCluster(headCluster, ncCols, colInfo, colOrder); 06471 06472 ncRows = 0; 06473 nonAppearingVarBddArray = NIL(array_t); 06474 if ((direction == Img_Forward_c && option->mlpReorder) || 06475 (direction == Img_Backward_c && option->mlpPreReorder) || 06476 option->mlpPostProcess >= 2) { 06477 list = headCluster; 06478 while (list) { 06479 row = rowOrder[ncRows]; 06480 06481 mdd_free(rowInfo[row].data.row.func); 06482 rowInfo[row].data.row.func = list->product; 06483 list->product = NIL(mdd_t); 06484 06485 if (xy[row]) 06486 FREE(xy[row]); 06487 xy[row] = list->supports; 06488 list->supports = NIL(char); 06489 06490 rowInfo[row].gNum = list->nSupports; 06491 rowInfo[row].gMin = list->minCol; 06492 rowInfo[row].gMax = list->maxCol; 06493 rowInfo[row].lNum = list->nSupports; 06494 rowInfo[row].lMin = list->minCol; 06495 rowInfo[row].lMax = list->maxCol; 06496 rowInfo[row].prevG = -1; 06497 rowInfo[row].nextG = ncCols; 06498 06499 if (list->nsVarBddArray) { 06500 if (rowInfo[row].data.row.nsVarBddArray) 06501 array_free(rowInfo[row].data.row.nsVarBddArray); 06502 rowInfo[row].data.row.nsVarBddArray = list->nsVarBddArray; 06503 list->nsVarBddArray = NIL(array_t); 06504 } 06505 06506 nextList = list->next; 06507 FREE(list); 06508 ncRows++; 06509 list = nextList; 06510 } 06511 06512 if (direction == Img_Forward_c) { 06513 for (i = 0; i < ncRows; i++) { 06514 cRowOrder[i] = rowOrder[ncRows - i - 1]; 06515 rowInfo[rowOrder[ncRows - i - 1]].pos = i; 06516 } 06517 } else { 06518 for (i = 0; i < ncRows; i++) { 06519 cRowOrder[i] = rowOrder[i]; 06520 rowInfo[rowOrder[i]].pos = i; 06521 } 06522 } 06523 06524 for (j = 0; j < ncCols; j++) { 06525 col = colOrder[j]; 06526 colInfo[col].gNum = 0; 06527 colInfo[col].gMin = ncRows; 06528 colInfo[col].gMax = -1; 06529 for (i = 0; i < ncRows; i++) { 06530 row = cRowOrder[i]; 06531 if (xy[row][col]) { 06532 colInfo[col].gNum++; 06533 if (colInfo[col].gMin == ncRows) 06534 colInfo[col].gMin = row; 06535 colInfo[col].gMax = row; 06536 } 06537 } 06538 colInfo[col].lNum = colInfo[col].gNum; 06539 colInfo[col].lMin = colInfo[col].gMin; 06540 colInfo[col].lMax = colInfo[col].gMax; 06541 colInfo[col].prevG = -1; 06542 colInfo[col].nextG = ncRows; 06543 } 06544 } else { 06545 if (direction == Img_Forward_c) { 06546 if (arraySmoothVarBddArray) { 06547 nonAppearingVarBddArray = array_fetch(array_t *, 06548 arraySmoothVarBddArray, 0); 06549 if (nCols > ncCols) { 06550 existFlag = ALLOC(char, nVars); 06551 memset(existFlag, 0, sizeof(char) * nVars); 06552 06553 for (i = 0; i < array_n(nonAppearingVarBddArray); i++) { 06554 nsVar = array_fetch(bdd_t *, nonAppearingVarBddArray, i); 06555 index = (int)bdd_top_var_id(nsVar); 06556 existFlag[index] = 1; 06557 } 06558 06559 for (i = ncCols; i < nCols; i++) { 06560 col = colOrder[i]; 06561 index = (int)bdd_top_var_id(colInfo[col].data.col.var); 06562 if (!existFlag[index]) { 06563 array_insert_last(bdd_t *, nonAppearingVarBddArray, 06564 bdd_dup(colInfo[col].data.col.var)); 06565 } 06566 } 06567 06568 FREE(existFlag); 06569 } 06570 qVarPos = ncCols - 1; 06571 if (qVarPos >= 0) { 06572 col = colOrder[qVarPos]; 06573 while (colInfo[col].gNum == 0) { 06574 array_insert_last(bdd_t *, nonAppearingVarBddArray, 06575 bdd_dup(colInfo[col].data.col.var)); 06576 if (qVarPos == 0) 06577 break; 06578 qVarPos--; 06579 col = colOrder[qVarPos]; 06580 } 06581 } 06582 } else 06583 qVarPos = 0; /* to avoid warning */ 06584 } else { 06585 if (arraySmoothVarBddArray) { 06586 nonAppearingVarBddArray = array_fetch(array_t *, 06587 arraySmoothVarBddArray, 0); 06588 if (nCols > ncCols) { 06589 for (i = ncCols; i < nCols; i++) { 06590 col = colOrder[i]; 06591 if (colInfo[col].data.col.type == 2) { 06592 array_insert_last(bdd_t *, nonAppearingVarBddArray, 06593 bdd_dup(colInfo[col].data.col.var)); 06594 } 06595 } 06596 } 06597 qVarPos = ncCols - 1; 06598 if (qVarPos >= 0) { 06599 col = colOrder[qVarPos]; 06600 while (colInfo[col].gNum == 0) { 06601 if (colInfo[col].data.col.type == 2) { 06602 array_insert_last(bdd_t *, nonAppearingVarBddArray, 06603 bdd_dup(colInfo[col].data.col.var)); 06604 } 06605 if (qVarPos == 0) 06606 break; 06607 qVarPos--; 06608 col = colOrder[qVarPos]; 06609 } 06610 } 06611 06612 existFlag = ALLOC(char, nVars); 06613 memset(existFlag, 0, sizeof(char) * nVars); 06614 06615 for (i = 0; i < array_n(nonAppearingVarBddArray); i++) { 06616 nsVar = array_fetch(bdd_t *, nonAppearingVarBddArray, i); 06617 index = (int)bdd_top_var_id(nsVar); 06618 existFlag[index] = 1; 06619 } 06620 06621 if (nRows > nActiveRows) { 06622 for (i = nActiveRows; i < nRows; i++) { 06623 row = rowOrder[i]; 06624 tmpArray = rowInfo[row].data.row.nsVarBddArray; 06625 for (j = 0; j < array_n(tmpArray); j++) { 06626 nsVar = array_fetch(bdd_t *, tmpArray, j); 06627 index = (int)bdd_top_var_id(nsVar); 06628 existFlag[index] = 1; 06629 } 06630 } 06631 } 06632 06633 list = headCluster; 06634 while (list) { 06635 supportArray = mdd_get_bdd_support_ids(mddManager, list->product); 06636 for (i = 0; i < array_n(supportArray); i++) { 06637 index = array_fetch(int, supportArray, i); 06638 existFlag[index] = 1; 06639 } 06640 array_free(supportArray); 06641 list = list->next; 06642 } 06643 06644 list = headCluster; 06645 while (list) { 06646 for (i = 0; i < array_n(list->nsVarBddArray); i++) { 06647 nsVar = array_fetch(bdd_t *, list->nsVarBddArray, i); 06648 index = (int)bdd_top_var_id(nsVar); 06649 if (!existFlag[index]) { 06650 tmpArray = array_alloc(mdd_t *, 0); 06651 for (j = 0; j < i; j++) { 06652 nsVar = array_fetch(bdd_t *, list->nsVarBddArray, j); 06653 array_insert_last(mdd_t *, tmpArray, nsVar); 06654 } 06655 for (j = i + 1; j < array_n(list->nsVarBddArray); j++) { 06656 nsVar = array_fetch(bdd_t *, list->nsVarBddArray, j); 06657 index = (int)bdd_top_var_id(nsVar); 06658 if (existFlag[index]) 06659 array_insert_last(mdd_t *, tmpArray, nsVar); 06660 } 06661 array_free(list->nsVarBddArray); 06662 list->nsVarBddArray = tmpArray; 06663 break; 06664 } 06665 } 06666 list = list->next; 06667 } 06668 06669 for (i = 0; i < array_n(nsVarBddArray); i++) { 06670 nsVar = array_fetch(bdd_t *, nsVarBddArray, i); 06671 index = (int)bdd_top_var_id(nsVar); 06672 if (!existFlag[index]) 06673 array_insert_last(mdd_t *, nonAppearingVarBddArray, bdd_dup(nsVar)); 06674 } 06675 06676 FREE(existFlag); 06677 } else 06678 qVarPos = 0; /* to avoid warning */ 06679 } 06680 06681 if (direction == Img_Backward_c && nRows > nActiveRows) { 06682 cluster = bdd_one(mddManager); 06683 if (arraySmoothVarBddArray) 06684 smoothVarBddArray = array_alloc(array_t *, 0); 06685 else 06686 smoothVarBddArray = NIL(array_t); 06687 for (i = nActiveRows; i < nRows; i++) { 06688 row = rowOrder[i]; 06689 relation = rowInfo[row].data.row.func; 06690 if (bdd_is_tautology(relation, 1)) 06691 continue; 06692 if (smoothVarBddArray) { 06693 tmpArray = rowInfo[row].data.row.nsVarBddArray; 06694 for (j = 0; j < array_n(tmpArray); j++) { 06695 nsVar = array_fetch(bdd_t *, tmpArray, j); 06696 array_insert_last(mdd_t *, smoothVarBddArray, bdd_dup(nsVar)); 06697 } 06698 } 06699 tempCluster = bdd_and(cluster, relation, 1, 1); 06700 bdd_free(cluster); 06701 cluster = tempCluster; 06702 } 06703 if (bdd_is_tautology(cluster, 1)) { 06704 mdd_free(cluster); 06705 if (smoothVarBddArray) 06706 mdd_array_free(smoothVarBddArray); 06707 } else { 06708 array_insert_last(bdd_t *, clusterArray, cluster); 06709 if (arraySmoothVarBddArray) { 06710 array_insert_last(array_t *, arraySmoothVarBddArray, 06711 smoothVarBddArray); 06712 } 06713 ncRows++; 06714 } 06715 } 06716 06717 list = headCluster; 06718 while (list) { 06719 array_insert_last(mdd_t *, clusterArray, list->product); 06720 list->product = NIL(mdd_t); 06721 06722 if (arraySmoothVarBddArray) { 06723 if (direction == Img_Forward_c) { 06724 smoothVarBddArray = array_alloc(array_t *, 0); 06725 if (qVarPos >= 0) { 06726 col = colOrder[qVarPos]; 06727 while (rowInfo[colInfo[col].gMin].pos >= list->start && 06728 rowInfo[colInfo[col].gMin].pos <= list->end) { 06729 array_insert_last(bdd_t *, smoothVarBddArray, 06730 bdd_dup(colInfo[col].data.col.var)); 06731 if (qVarPos == 0) 06732 break; 06733 qVarPos--; 06734 col = colOrder[qVarPos]; 06735 } 06736 } 06737 array_insert_last(array_t *, arraySmoothVarBddArray, 06738 smoothVarBddArray); 06739 } else { 06740 smoothVarBddArray = array_alloc(array_t *, 0); 06741 for (i = 0; i < array_n(list->nsVarBddArray); i++) { 06742 nsVar = array_fetch(bdd_t *, list->nsVarBddArray, i); 06743 array_insert_last(bdd_t *, smoothVarBddArray, bdd_dup(nsVar)); 06744 } 06745 06746 if (list->nSupports > 0) { 06747 s1 = colInfo[list->minCol].pos; 06748 t1 = colInfo[list->maxCol].pos; 06749 for (i = s1; i <= t1; i++) { 06750 col = colOrder[i]; 06751 if (colInfo[col].data.col.type == 2) { 06752 if (rowInfo[colInfo[col].gMax].pos >= list->start && 06753 rowInfo[colInfo[col].gMax].pos <= list->end) { 06754 array_insert_last(bdd_t *, smoothVarBddArray, 06755 bdd_dup(colInfo[col].data.col.var)); 06756 } 06757 } 06758 } 06759 } 06760 array_insert_last(array_t *, arraySmoothVarBddArray, 06761 smoothVarBddArray); 06762 } 06763 } 06764 06765 nextList = list->next; 06766 if (list->nsVarBddArray) 06767 array_free(list->nsVarBddArray); 06768 FREE(list->supports); 06769 FREE(list); 06770 ncRows++; 06771 list = nextList; 06772 } 06773 06774 if (direction == Img_Forward_c && nRows > nActiveRows) { 06775 cluster = bdd_one(mddManager); 06776 for (i = nActiveRows; i < nRows; i++) { 06777 row = rowOrder[i]; 06778 relation = rowInfo[row].data.row.func; 06779 if (bdd_is_tautology(relation, 1)) 06780 continue; 06781 tempCluster = bdd_and(cluster, relation, 1, 1); 06782 bdd_free(cluster); 06783 cluster = tempCluster; 06784 } 06785 if (bdd_is_tautology(cluster, 1)) 06786 mdd_free(cluster); 06787 else { 06788 array_insert_last(bdd_t *, clusterArray, cluster); 06789 if (arraySmoothVarBddArray) { 06790 smoothVarBddArray = array_alloc(array_t *, 0); 06791 array_insert_last(array_t *, arraySmoothVarBddArray, 06792 smoothVarBddArray); 06793 } 06794 ncRows++; 06795 } 06796 } 06797 } 06798 06799 *nClusterRows = ncRows; 06800 *nClusterCols = ncCols; 06801 06802 if (option->mlpVerbosity) { 06803 finalTime = util_cpu_time(); 06804 fprintf(vis_stdout, "time for clustering = %10g\n", 06805 (double)(finalTime - initialTime) / 1000.0); 06806 } 06807 } 06808 06809 06819 static int 06820 MlpCountSupport(ClusterList_t *list, int *colOrder, int nActiveCols) 06821 { 06822 int i, col; 06823 int nSupports = 0; 06824 06825 for (i = 0; i < nActiveCols; i++) { 06826 col = colOrder[i]; 06827 if (list->supports[col]) 06828 nSupports++; 06829 } 06830 return(nSupports); 06831 } 06832 06833 06843 static float 06844 MlpSupportAffinity(ClusterList_t *curList, ClusterList_t *nextList, 06845 RcInfo_t *colInfo, int *colOrder, 06846 int nActiveCols, int clusterMethod) 06847 { 06848 ClusterList_t *minList, *maxList; 06849 int i, col, s, t; 06850 int nOverlaps = 0; 06851 float affinity; 06852 06853 if (curList->nSupports <= nextList->nSupports) { 06854 minList = curList; 06855 maxList = nextList; 06856 } else { 06857 minList = nextList; 06858 maxList = curList; 06859 } 06860 06861 s = colInfo[minList->minCol].pos; 06862 t = colInfo[minList->maxCol].pos; 06863 for (i = s; i <= t; i++) { 06864 col = colOrder[i]; 06865 if (minList->supports[col] && maxList->supports[col]) 06866 nOverlaps++; 06867 } 06868 06869 if (clusterMethod == 1) 06870 affinity = (float)nOverlaps / (float)minList->nSupports; 06871 else { 06872 affinity = (float)nOverlaps / 06873 (float)(minList->nSupports + maxList->nSupports - nOverlaps); 06874 } 06875 return(affinity); 06876 } 06877 06878 06888 static int 06889 RecursiveCluster(mdd_manager *mddManager, ClusterList_t *headCluster, 06890 ClusterSortedList_t *clusterSortedList, 06891 char **xy, RcInfo_t *rowInfo, RcInfo_t *colInfo, 06892 int *rowOrder, int *colOrder, 06893 int nActiveRows, int nClusterCols, 06894 Img_DirectionType direction, int *varPos, 06895 int moveFlag, ImgTrmOption_t *option) 06896 { 06897 ClusterSortedList_t *sortedList, *nextSortedList, *prevSortedList; 06898 ClusterSortedList_t *firstSortedList, *secondSortedList, *saveSortedList; 06899 ClusterSortedList_t *tailSortedList1, *tailSortedList2; 06900 ClusterList_t *list, *best; 06901 int i, n1, n2; 06902 int s1, t1, s2; 06903 mdd_t *product; 06904 int merge, index; 06905 array_t *supportArray; 06906 06907 if (headCluster->flag == 3) 06908 return(nClusterCols); 06909 06910 assert(headCluster); 06911 if (option->mlpClusterSortedList && option->mlpDebug) { 06912 n1 = CountClusterList(headCluster); 06913 n2 = CountClusterSortedList(clusterSortedList); 06914 assert(n1 == n2); 06915 } 06916 06917 if (headCluster->flag == 2) { 06918 assert(!headCluster->next || headCluster->next->flag == 3); 06919 headCluster->flag = 3; 06920 nClusterCols = RemoveLocalVarsInCluster(mddManager, xy, headCluster, 06921 nActiveRows, nClusterCols, 06922 rowInfo, colInfo, 06923 rowOrder, colOrder, 06924 moveFlag, option); 06925 if (clusterSortedList) { 06926 assert(!clusterSortedList->next); 06927 FREE(clusterSortedList); 06928 } 06929 return(nClusterCols); 06930 } 06931 06932 merge = 0; 06933 best = NIL(ClusterList_t); 06934 if (option->mlpClusterMerge) { 06935 /* NEED */ 06936 } 06937 06938 if (!best) { 06939 if (clusterSortedList) 06940 best = clusterSortedList->list; 06941 else { 06942 best = headCluster; 06943 list = headCluster->next; 06944 while (list) { 06945 if (list->flag == 2) 06946 break; 06947 if (option->mlpClusterQuantifyVars) { 06948 if (list->nQuantifyVars < best->nQuantifyVars || 06949 (list->nQuantifyVars == best->nQuantifyVars && 06950 list->affinity > best->affinity)) { 06951 best = list; 06952 } 06953 } else { 06954 if (list->affinity < option->mlpAffinityThreshold) { 06955 list = list->next; 06956 continue; 06957 } 06958 if (list->affinity > best->affinity || 06959 (list->affinity == best->affinity && 06960 list->nQuantifyVars < best->nQuantifyVars)) { 06961 best = list; 06962 } 06963 } 06964 list = list->next; 06965 } 06966 } 06967 } 06968 assert(best->next && best->next->flag != 3); 06969 06970 list = best->next; 06971 product = mdd_and(best->product, list->product, 1, 1); 06972 06973 if (merge == 0 && bdd_size(product) > option->clusterSize) { 06974 mdd_free(product); 06975 06976 firstSortedList = NIL(ClusterSortedList_t); 06977 secondSortedList = NIL(ClusterSortedList_t); 06978 if (option->mlpClusterSortedList) { 06979 tailSortedList1 = NIL(ClusterSortedList_t); 06980 tailSortedList2 = NIL(ClusterSortedList_t); 06981 sortedList = clusterSortedList; 06982 while (sortedList) { 06983 nextSortedList = sortedList->next; 06984 if ((best->start > list->start && 06985 sortedList->list->start >= best->start) || 06986 (best->start < list->start && 06987 sortedList->list->start <= best->start)) { 06988 if (tailSortedList1) 06989 tailSortedList1->next = sortedList; 06990 else 06991 firstSortedList = sortedList; 06992 tailSortedList1 = sortedList; 06993 } else { 06994 if (tailSortedList2) 06995 tailSortedList2->next = sortedList; 06996 else 06997 secondSortedList = sortedList; 06998 tailSortedList2 = sortedList; 06999 } 07000 sortedList->next = NIL(ClusterSortedList_t); 07001 sortedList = nextSortedList; 07002 } 07003 } 07004 07005 if (best == headCluster) { 07006 best->flag = 3; 07007 if (option->mlpClusterSortedList) { 07008 sortedList = firstSortedList; 07009 firstSortedList = firstSortedList->next; 07010 FREE(sortedList); 07011 assert(!firstSortedList); 07012 } 07013 nClusterCols = RemoveLocalVarsInCluster(mddManager, xy, best, 07014 nActiveRows, nClusterCols, 07015 rowInfo, colInfo, 07016 rowOrder, colOrder, 07017 moveFlag, option); 07018 } else { 07019 best->flag = 2; 07020 if (option->mlpClusterSortedList) { 07021 sortedList = firstSortedList; 07022 prevSortedList = NIL(ClusterSortedList_t); 07023 saveSortedList = NIL(ClusterSortedList_t); 07024 while (sortedList) { 07025 nextSortedList = sortedList->next; 07026 if (sortedList->list == best) { 07027 if (nextSortedList) { 07028 if (prevSortedList) 07029 prevSortedList->next = sortedList->next; 07030 else 07031 firstSortedList = sortedList->next; 07032 } 07033 saveSortedList = sortedList; 07034 sortedList->next = NIL(ClusterSortedList_t); 07035 sortedList = nextSortedList; 07036 continue; 07037 } 07038 prevSortedList = sortedList; 07039 sortedList = nextSortedList; 07040 } 07041 prevSortedList->next = saveSortedList; 07042 } 07043 nClusterCols = RecursiveCluster(mddManager, headCluster, firstSortedList, 07044 xy, rowInfo, colInfo, 07045 rowOrder, colOrder, 07046 nActiveRows, nClusterCols, 07047 direction, varPos, moveFlag, option); 07048 } 07049 if (option->mlpDebug) { 07050 CheckCluster(headCluster, nClusterCols, colInfo, colOrder); 07051 CheckMatrix(xy, NIL(SccList_t), nActiveRows, nClusterCols, 07052 rowInfo, colInfo, rowOrder, colOrder, 07053 0, nActiveRows - 1, 0, nClusterCols - 1, 0); 07054 } 07055 07056 if (list->flag == 0) { 07057 list->flag = 1; 07058 nClusterCols = RecursiveCluster(mddManager, list, secondSortedList, 07059 xy, rowInfo, colInfo, 07060 rowOrder, colOrder, 07061 nActiveRows, nClusterCols, 07062 direction, varPos, moveFlag, option); 07063 } else { 07064 list->flag = 3; 07065 sortedList = secondSortedList; 07066 secondSortedList = secondSortedList->next; 07067 FREE(sortedList); 07068 assert(!secondSortedList); 07069 nClusterCols = RemoveLocalVarsInCluster(mddManager, xy, list, 07070 nActiveRows, nClusterCols, 07071 rowInfo, colInfo, 07072 rowOrder, colOrder, 07073 moveFlag, option); 07074 } 07075 if (option->mlpDebug) { 07076 CheckCluster(headCluster, nClusterCols, colInfo, colOrder); 07077 CheckMatrix(xy, NIL(SccList_t), nActiveRows, nClusterCols, 07078 rowInfo, colInfo, rowOrder, colOrder, 07079 0, nActiveRows - 1, 0, nClusterCols - 1, 0); 07080 } 07081 } else { 07082 if (merge == 0 && option->mlpClusterSortedList) { 07083 sortedList = clusterSortedList->next; 07084 FREE(clusterSortedList); 07085 clusterSortedList = sortedList; 07086 } 07087 07088 mdd_free(best->product); 07089 best->product = product; 07090 07091 if (list->flag == 2) { 07092 if (best->flag == 1) 07093 best->flag = 3; 07094 else 07095 best->flag = 2; 07096 } 07097 07098 best->nSupports = 0; 07099 best->minCol = nClusterCols; 07100 best->maxCol = -1; 07101 s1 = nClusterCols; 07102 t1 = -1; 07103 supportArray = mdd_get_bdd_support_ids(mddManager, best->product); 07104 for (i = 0; i < array_n(supportArray); i++) { 07105 index = array_fetch(int, supportArray, i); 07106 if (varPos[index] == 0) { 07107 if ((int)bdd_top_var_id(colInfo[0].data.col.var) != index) 07108 continue; 07109 } 07110 index = varPos[index]; 07111 best->supports[index] = 1; 07112 best->nSupports++; 07113 s2 = colInfo[index].pos; 07114 if (s2 < s1) { 07115 s1 = s2; 07116 best->minCol = index; 07117 } 07118 if (s2 > t1) { 07119 t1 = s2; 07120 best->maxCol = index; 07121 } 07122 } 07123 array_free(supportArray); 07124 07125 if (best->nsVarBddArray) 07126 array_append(best->nsVarBddArray, list->nsVarBddArray); 07127 07128 if (list->start < best->start) 07129 best->start = list->start; 07130 if (list->end > best->end) 07131 best->end = list->end; 07132 07133 if (option->mlpClusterSortedList) { 07134 sortedList = clusterSortedList; 07135 prevSortedList = NIL(ClusterSortedList_t); 07136 if (merge == 0) { 07137 while (sortedList) { 07138 nextSortedList = sortedList->next; 07139 if (option->mlpClusterDynamic) { 07140 if (sortedList->list == list || sortedList->list == best->prev) { 07141 if (prevSortedList) 07142 prevSortedList->next = sortedList->next; 07143 else 07144 clusterSortedList = sortedList->next; 07145 FREE(sortedList); 07146 sortedList = nextSortedList; 07147 continue; 07148 } 07149 } else { 07150 if (sortedList->list == list) { 07151 best->affinity = list->affinity; 07152 sortedList->list = best; 07153 break; 07154 } 07155 } 07156 prevSortedList = sortedList; 07157 sortedList = nextSortedList; 07158 } 07159 } else { 07160 while (sortedList) { 07161 nextSortedList = sortedList->next; 07162 if (option->mlpClusterDynamic) { 07163 if (sortedList->list == best || 07164 sortedList->list == list || sortedList->list == best->prev) { 07165 if (prevSortedList) 07166 prevSortedList->next = sortedList->next; 07167 else 07168 clusterSortedList = sortedList->next; 07169 FREE(sortedList); 07170 sortedList = nextSortedList; 07171 continue; 07172 } 07173 } else { 07174 if (sortedList->list == best) { 07175 if (prevSortedList) 07176 prevSortedList->next = sortedList->next; 07177 else 07178 clusterSortedList = sortedList->next; 07179 FREE(sortedList); 07180 sortedList = nextSortedList; 07181 continue; 07182 } else if (sortedList->list == list) { 07183 best->affinity = list->affinity; 07184 sortedList->list = best; 07185 break; 07186 } 07187 } 07188 prevSortedList = sortedList; 07189 sortedList = nextSortedList; 07190 } 07191 } 07192 } 07193 07194 best->next = list->next; 07195 if (list->next) 07196 list->next->prev = best; 07197 07198 mdd_free(list->product); 07199 if (list->nsVarBddArray) 07200 array_free(list->nsVarBddArray); 07201 FREE(list->supports); 07202 FREE(list); 07203 07204 if (merge && best->flag != 3) { 07205 nClusterCols = RemoveLocalVarsInCluster(mddManager, xy, best, 07206 nActiveRows, nClusterCols, 07207 rowInfo, colInfo, 07208 rowOrder, colOrder, 07209 moveFlag, option); 07210 } 07211 07212 if (best->flag == 3) { 07213 nClusterCols = RemoveLocalVarsInCluster(mddManager, xy, best, 07214 nActiveRows, nClusterCols, 07215 rowInfo, colInfo, 07216 rowOrder, colOrder, 07217 moveFlag, option); 07218 } else { 07219 if (option->mlpClusterDynamic) { 07220 if (best->flag == 2) 07221 best->affinity = 0.0; 07222 else { 07223 best->affinity = MlpSupportAffinity(best, best->next, colInfo, 07224 colOrder, nClusterCols, 07225 option->mlpCluster); 07226 } 07227 if (best != headCluster) { 07228 best->prev->affinity = MlpSupportAffinity(best->prev, best, colInfo, 07229 colOrder, nClusterCols, 07230 option->mlpCluster); 07231 } 07232 } 07233 if (option->mlpClusterQuantifyVars == 2) { 07234 best->nQuantifyVars = MlpNumQuantifyVars(best, rowInfo, colInfo, 07235 colOrder, nClusterCols); 07236 } 07237 if (option->mlpClusterSortedList && option->mlpClusterDynamic) { 07238 clusterSortedList = ClusterSortedListInsert(clusterSortedList, best, 07239 option->mlpClusterQuantifyVars); 07240 if (best != headCluster) { 07241 clusterSortedList = ClusterSortedListInsert(clusterSortedList, 07242 best->prev, 07243 option->mlpClusterQuantifyVars); 07244 } 07245 } 07246 } 07247 07248 if (headCluster->flag == 1) { 07249 if (option->mlpDebug) { 07250 CheckCluster(headCluster, nClusterCols, colInfo, colOrder); 07251 CheckMatrix(xy, NIL(SccList_t), nActiveRows, nClusterCols, 07252 rowInfo, colInfo, rowOrder, colOrder, 07253 0, nActiveRows - 1, 0, nClusterCols - 1, 0); 07254 } 07255 nClusterCols = RecursiveCluster(mddManager, headCluster, 07256 clusterSortedList, 07257 xy, rowInfo, colInfo, 07258 rowOrder, colOrder, 07259 nActiveRows, nClusterCols, 07260 direction, varPos, moveFlag, option); 07261 } else { 07262 if (!option->mlpClusterDynamic) { 07263 assert(!clusterSortedList->next); 07264 FREE(clusterSortedList); 07265 } 07266 } 07267 } 07268 07269 return(nClusterCols); 07270 } 07271 07272 07282 static int 07283 RemoveLocalVarsInCluster(mdd_manager *mddManager, char **xy, 07284 ClusterList_t *list, 07285 int nActiveRows, int nClusterCols, 07286 RcInfo_t *rowInfo, RcInfo_t *colInfo, 07287 int *rowOrder, int *colOrder, 07288 int moveFlag, ImgTrmOption_t *option) 07289 { 07290 int i, j, k, row, col, otherCol; 07291 int s1, t1, s2, t2, s3, t3; 07292 mdd_t *product; 07293 array_t *localVarBddArray = NIL(array_t); 07294 07295 s1 = colInfo[list->minCol].pos; 07296 t1 = colInfo[list->maxCol].pos; 07297 for (i = t1; i >= s1; i--) { 07298 col = colOrder[i]; 07299 if (colInfo[col].data.col.type == 2 && 07300 rowInfo[colInfo[col].gMin].pos >= list->start && 07301 rowInfo[colInfo[col].gMax].pos <= list->end) { 07302 if (!localVarBddArray) 07303 localVarBddArray = array_alloc(bdd_t *, 0); 07304 array_insert_last(bdd_t *, localVarBddArray, colInfo[col].data.col.var); 07305 07306 list->nSupports--; 07307 if (list->nSupports == 0) { 07308 list->minCol = -1; 07309 list->maxCol = -1; 07310 } else if (list->nSupports == 1) { 07311 if (list->minCol == col) 07312 list->minCol = list->maxCol; 07313 else 07314 list->maxCol = list->minCol; 07315 } else if (list->nSupports > 1) { 07316 if (list->minCol == col) { 07317 for (j = i + 1; j <= t1; j++) { 07318 otherCol = colOrder[j]; 07319 if (list->supports[otherCol]) { 07320 list->minCol = otherCol; 07321 break; 07322 } 07323 } 07324 } else if (list->maxCol == col) { 07325 for (j = i - 1; j >= s1; j--) { 07326 otherCol = colOrder[j]; 07327 if (list->supports[otherCol]) { 07328 list->maxCol = otherCol; 07329 break; 07330 } 07331 } 07332 } 07333 } 07334 07335 s2 = list->start; 07336 t2 = list->end; 07337 for (j = s2; j <= t2; j++) { 07338 row = rowOrder[j]; 07339 if (xy[row][col]) { 07340 rowInfo[row].gNum--; 07341 if (rowInfo[row].gNum > 0) { 07342 s3 = colInfo[rowInfo[row].gMin].pos; 07343 t3 = colInfo[rowInfo[row].gMax].pos; 07344 if (rowInfo[row].gMin == col) { 07345 for (k = i + 1; k <= t3; k++) { 07346 otherCol = colOrder[k]; 07347 if (xy[row][otherCol]) { 07348 rowInfo[row].gMin = otherCol; 07349 break; 07350 } 07351 } 07352 } else if (rowInfo[row].gMax == col) { 07353 for (k = i - 1; k >= s3; k--) { 07354 otherCol = colOrder[k]; 07355 if (xy[row][otherCol]) { 07356 rowInfo[row].gMax = otherCol; 07357 break; 07358 } 07359 } 07360 } 07361 } 07362 } 07363 } 07364 07365 for (j = i; j < nClusterCols - 1; j++) { 07366 colOrder[j] = colOrder[j + 1]; 07367 colInfo[colOrder[j]].pos = j; 07368 } 07369 colOrder[nClusterCols - 1] = col; 07370 colInfo[col].pos = nClusterCols - 1; 07371 07372 nClusterCols--; 07373 07374 if (option->mlpDebug) { 07375 CheckCluster(list, nClusterCols, colInfo, colOrder); 07376 CheckMatrix(xy, NIL(SccList_t), nActiveRows, nClusterCols, 07377 rowInfo, colInfo, rowOrder, colOrder, 07378 0, nActiveRows - 1, 0, nClusterCols - 1, 0); 07379 } 07380 } 07381 } 07382 07383 if (localVarBddArray) { 07384 product = bdd_smooth(list->product, localVarBddArray); 07385 mdd_free(list->product); 07386 list->product = product; 07387 array_free(localVarBddArray); 07388 UpdateDisapearingPsVarsInCluster(mddManager, xy, 07389 nActiveRows, nClusterCols, 07390 rowOrder, colOrder, rowInfo, colInfo, 07391 list, moveFlag, option); 07392 } 07393 07394 return(nClusterCols); 07395 } 07396 07397 07407 static int 07408 MlpNumQuantifyVars(ClusterList_t *list, RcInfo_t *rowInfo, RcInfo_t *colInfo, 07409 int *colOrder, int nClusterCols) 07410 { 07411 int i, s, t, col; 07412 int nQuantifyVars = 0; 07413 07414 s = colInfo[list->minCol].pos; 07415 t = colInfo[list->maxCol].pos; 07416 for (i = t; i >= s; i--) { 07417 col = colOrder[i]; 07418 if (rowInfo[colInfo[col].gMin].pos >= list->start && 07419 rowInfo[colInfo[col].gMin].pos <= list->end) { 07420 nQuantifyVars++; 07421 } else 07422 break; 07423 } 07424 07425 return(nQuantifyVars); 07426 } 07427 07428 07438 static ClusterSortedList_t * 07439 ClusterSortedListInsert(ClusterSortedList_t *clusterSortedList, 07440 ClusterList_t *list, int useQuantifyVars) 07441 { 07442 ClusterSortedList_t *sortedList, *cur, *prev; 07443 07444 sortedList = ALLOC(ClusterSortedList_t, 1); 07445 sortedList->list = list; 07446 07447 if (!clusterSortedList) { 07448 sortedList->next = NIL(ClusterSortedList_t); 07449 return(sortedList); 07450 } 07451 07452 cur = clusterSortedList; 07453 prev = NIL(ClusterSortedList_t); 07454 while (cur) { 07455 if (list->flag == 2) { 07456 prev = cur; 07457 cur = cur->next; 07458 continue; 07459 } 07460 if (useQuantifyVars) { 07461 if (cur->list->flag == 2 || 07462 list->nQuantifyVars < cur->list->nQuantifyVars || 07463 (list->nQuantifyVars == cur->list->nQuantifyVars && 07464 list->affinity >= cur->list->affinity)) { 07465 sortedList->next = cur; 07466 if (cur == clusterSortedList) 07467 clusterSortedList = sortedList; 07468 else 07469 prev->next = sortedList; 07470 break; 07471 } 07472 } else { 07473 if (cur->list->flag == 2 || 07474 list->affinity > cur->list->affinity || 07475 (list->affinity == cur->list->affinity && 07476 list->nQuantifyVars <= cur->list->nQuantifyVars)) { 07477 sortedList->next = cur; 07478 if (cur == clusterSortedList) 07479 clusterSortedList = sortedList; 07480 else 07481 prev->next = sortedList; 07482 break; 07483 } 07484 } 07485 prev = cur; 07486 cur = cur->next; 07487 } 07488 if (!cur) { 07489 prev->next = sortedList; 07490 sortedList->next = NIL(ClusterSortedList_t); 07491 } 07492 return(clusterSortedList); 07493 } 07494 07495 07505 static int 07506 CountClusterList(ClusterList_t *clusterList) 07507 { 07508 ClusterList_t *list; 07509 int n = 0; 07510 07511 list = clusterList; 07512 while (list) { 07513 if (list->flag == 3) 07514 break; 07515 n++; 07516 if (list->flag == 2) 07517 break; 07518 list = list->next; 07519 } 07520 07521 return(n); 07522 } 07523 07524 07534 static int 07535 CountClusterSortedList(ClusterSortedList_t *clusterSortedList) 07536 { 07537 ClusterSortedList_t *sortedList; 07538 int n = 0; 07539 07540 sortedList = clusterSortedList; 07541 while (sortedList) { 07542 n++; 07543 sortedList = sortedList->next; 07544 } 07545 07546 return(n); 07547 } 07548 07549 07559 static array_t * 07560 CreateInitialCluster(mdd_manager *mddManager, array_t *relationArray, 07561 ImgFunctionData_t *functionData, array_t *nsVarBddArray, 07562 ImgTrmOption_t *option) 07563 { 07564 array_t *clusteredRelationArray; 07565 array_t *partitionArray; 07566 Part_Subsystem_t *partitionSubsystem; 07567 st_table *vertexTable; 07568 int i, j; 07569 int mddId; 07570 long bddId; 07571 Ntk_Node_t *latch; 07572 mdd_t *cluster, *product, *relation, *var; 07573 char *latchName; 07574 st_generator *stGen; 07575 st_table *id2relation; 07576 array_t *bddIdArray; 07577 int nVars; 07578 char *nsVarFlag; 07579 array_t *domainVars; 07580 07581 if (array_n(functionData->domainVars) == array_n(functionData->rangeVars)) 07582 domainVars = functionData->domainVars; 07583 else { 07584 domainVars = array_alloc(int, 0); 07585 for (i = 0; i < array_n(functionData->rangeVars); i++) { 07586 mddId = array_fetch(int, functionData->domainVars, i); 07587 array_insert_last(int, domainVars, mddId); 07588 } 07589 } 07590 partitionArray = Fsm_ArdcDecomposeStateSpace(functionData->network, 07591 domainVars, 07592 functionData->roots, 07593 NIL(Fsm_ArdcOptions_t)); 07594 if (domainVars != functionData->domainVars) 07595 array_free(domainVars); 07596 07597 nVars = bdd_num_vars(mddManager); 07598 nsVarFlag = ALLOC(char, nVars); 07599 memset(nsVarFlag, 0, sizeof(char) * nVars); 07600 for (i = 0; i < array_n(nsVarBddArray); i++) { 07601 var = array_fetch(mdd_t *, nsVarBddArray, i); 07602 bddId = (long) bdd_top_var_id(var); 07603 nsVarFlag[bddId] = 1; 07604 } 07605 clusteredRelationArray = array_alloc(mdd_t *, 0); 07606 id2relation = st_init_table(st_numcmp, st_numhash); 07607 for (i = 0; i < array_n(relationArray); i++) { 07608 relation = array_fetch(mdd_t *, relationArray, i); 07609 bddIdArray = mdd_get_bdd_support_ids(mddManager, relation); 07610 for (j = 0; j < array_n(bddIdArray); j++) { 07611 bddId = (long) array_fetch(int, bddIdArray, j); 07612 if (nsVarFlag[bddId]) { 07613 st_insert(id2relation, (char *)bddId, (char *)relation); 07614 break; 07615 } 07616 } 07617 07618 /* the relation of intermediate variable */ 07619 if (j == array_n(bddIdArray)) { 07620 array_insert_last(mdd_t *, clusteredRelationArray, mdd_dup(relation)); 07621 } 07622 07623 array_free(bddIdArray); 07624 } 07625 FREE(nsVarFlag); 07626 07627 arrayForEachItem(Part_Subsystem_t *, partitionArray, i, partitionSubsystem) { 07628 cluster = mdd_one(mddManager); 07629 vertexTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem); 07630 st_foreach_item(vertexTable, stGen, &latchName, NIL(char *)) { 07631 latch = Ntk_NetworkFindNodeByName(functionData->network, latchName); 07632 mddId = Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)); 07633 bddIdArray = mdd_id_to_bdd_id_array(mddManager, mddId); 07634 for (j = 0; j < array_n(bddIdArray); j++) { 07635 bddId = (long) array_fetch(int, bddIdArray, j); 07636 if (st_lookup(id2relation, (char *)bddId, &relation)) { 07637 st_delete(id2relation, &bddId, NULL); 07638 product = mdd_and(cluster, relation, 1, 1); 07639 mdd_free(cluster); 07640 cluster = product; 07641 } 07642 } 07643 array_free(bddIdArray); 07644 } 07645 Part_PartitionSubsystemFree(partitionSubsystem); 07646 array_insert_last(mdd_t *, clusteredRelationArray, cluster); 07647 } 07648 array_free(partitionArray); 07649 07650 st_foreach_item(id2relation, stGen, &bddId, &relation) { 07651 array_insert_last(mdd_t *, clusteredRelationArray, mdd_dup(relation)); 07652 } 07653 st_free_table(id2relation); 07654 07655 /* 07656 if (option->mlpDebug) { 07657 mdd_t *tr1, *tr2, *tmp; 07658 07659 tr1 = mdd_one(mddManager); 07660 for (i = 0; i < array_n(relationArray); i++) { 07661 relation = array_fetch(mdd_t *, relationArray, i); 07662 tmp = mdd_and(tr1, relation, 1, 1); 07663 mdd_free(tr1); 07664 tr1 = tmp; 07665 } 07666 07667 tr2 = mdd_one(mddManager); 07668 for (i = 0; i < array_n(clusteredRelationArray); i++) { 07669 relation = array_fetch(mdd_t *, clusteredRelationArray, i); 07670 tmp = mdd_and(tr2, relation, 1, 1); 07671 mdd_free(tr2); 07672 tr2 = tmp; 07673 } 07674 07675 assert(mdd_equal(tr1, tr2)); 07676 mdd_free(tr1); 07677 mdd_free(tr2); 07678 } 07679 */ 07680 07681 return(clusteredRelationArray); 07682 } 07683 07684 07694 static void 07695 SortCol(char **xy, int nRows, int nCols, 07696 RcInfo_t *rowInfo, RcInfo_t *colInfo, int *rowOrder, int *colOrder) 07697 { 07698 int x, y, i, j, row, col, lastVar; 07699 int otherRow, otherCol; 07700 07701 lastVar = nCols - 1; 07702 07703 for (x = nRows - 1; x >= 0; x--) { 07704 row = rowOrder[x]; 07705 for (y = lastVar; y >= 0; y--) { 07706 col = colOrder[y]; 07707 if (colInfo[col].gMin == row) { 07708 if (y == lastVar) { 07709 lastVar--; 07710 continue; 07711 } 07712 for (j = y; j < lastVar; j++) { 07713 colOrder[j] = colOrder[j + 1]; 07714 colInfo[colOrder[j]].pos = j; 07715 } 07716 colOrder[lastVar] = col; 07717 colInfo[col].pos = lastVar; 07718 for (i = x; i < nRows; i++) { 07719 otherRow = rowOrder[i]; 07720 if (colInfo[rowInfo[otherRow].gMax].pos < lastVar) 07721 rowInfo[otherRow].gMax = col; 07722 if (rowInfo[otherRow].gMin == col) { 07723 for (j = 0; j < nCols; j++) { 07724 otherCol = colOrder[j]; 07725 if (xy[otherRow][otherCol]) { 07726 rowInfo[otherRow].gMin = otherCol; 07727 break; 07728 } 07729 } 07730 } 07731 } 07732 lastVar--; 07733 } 07734 } 07735 } 07736 } 07737 07738 07748 static void 07749 UpdateDisapearingPsVars(mdd_manager *mddManager, char **xy, 07750 int nActiveRows, int nActiveCols, 07751 int *rowOrder, int *colOrder, 07752 RcInfo_t *rowInfo, RcInfo_t *colInfo, 07753 int row, ImgTrmOption_t *option) 07754 { 07755 int i, id, x, y, s, t, col, tmpRow; 07756 mdd_t *relation; 07757 array_t *supportArray; 07758 char *supportIndex; 07759 int nVars; 07760 07761 nVars = bdd_num_vars(mddManager); 07762 relation = rowInfo[row].data.row.func; 07763 supportIndex = ALLOC(char, nVars); 07764 memset(supportIndex, 0, sizeof(char) * nVars); 07765 supportArray = mdd_get_bdd_support_ids(mddManager, relation); 07766 for (i = 0; i < array_n(supportArray); i++) { 07767 id = array_fetch(int, supportArray, i); 07768 supportIndex[id] = 1; 07769 } 07770 array_free(supportArray); 07771 07772 s = colInfo[rowInfo[row].gMin].pos; 07773 t = colInfo[rowInfo[row].gMax].pos; 07774 x = rowInfo[row].pos; 07775 rowInfo[row].gNum = 0; 07776 rowInfo[row].gMin = nActiveCols; 07777 rowInfo[row].gMax = -1; 07778 for (y = s; y <= t; y++) { 07779 col = colOrder[y]; 07780 if (!xy[row][col]) 07781 continue; 07782 id = (int)bdd_top_var_id(colInfo[col].data.col.var); 07783 if (supportIndex[id]) { 07784 rowInfo[row].gNum++; 07785 if (rowInfo[row].gMin == nActiveCols) 07786 rowInfo[row].gMin = col; 07787 rowInfo[row].gMax = col; 07788 } else { 07789 xy[row][col] = 0; 07790 if (colInfo[col].gNum == 1) { 07791 colInfo[col].gNum = 0; 07792 colInfo[col].gMin = nActiveRows; 07793 colInfo[col].gMax = -1; 07794 } else if (colInfo[col].gNum == 2) { 07795 colInfo[col].gNum = 1; 07796 if (colInfo[col].gMin == row) 07797 colInfo[col].gMin = colInfo[col].gMax; 07798 else 07799 colInfo[col].gMax = colInfo[col].gMin; 07800 } else { 07801 colInfo[col].gNum--; 07802 if (row == colInfo[col].gMin) { 07803 for (i = x + 1; i <= rowInfo[colInfo[col].gMax].pos; i++) { 07804 tmpRow = rowOrder[i]; 07805 if (xy[tmpRow][col]) { 07806 colInfo[col].gMin = tmpRow; 07807 break; 07808 } 07809 } 07810 } else if (row == colInfo[col].gMax) { 07811 for (i = x - 1; i >= rowInfo[colInfo[col].gMin].pos; i--) { 07812 tmpRow = rowOrder[i]; 07813 if (xy[tmpRow][col]) { 07814 colInfo[col].gMax = tmpRow; 07815 break; 07816 } 07817 } 07818 } 07819 } 07820 } 07821 } 07822 07823 FREE(supportIndex); 07824 } 07825 07826 07836 static void 07837 UpdateDisapearingPsVarsInCluster(mdd_manager *mddManager, char **xy, 07838 int nActiveRows, int nActiveCols, 07839 int *rowOrder, int *colOrder, 07840 RcInfo_t *rowInfo, RcInfo_t *colInfo, 07841 ClusterList_t *list, int moveFlag, 07842 ImgTrmOption_t *option) 07843 { 07844 int i, j, k, y, id, row, col, otherRow, otherCol; 07845 int s1, t1, s2, t2, s3, t3, t4; 07846 mdd_t *relation; 07847 array_t *supportArray; 07848 char *supportIndex; 07849 int nVars; 07850 ClusterList_t *otherList; 07851 07852 if (list->nSupports == 0) 07853 return; 07854 07855 nVars = bdd_num_vars(mddManager); 07856 relation = list->product; 07857 supportIndex = ALLOC(char, nVars); 07858 memset(supportIndex, 0, sizeof(char) * nVars); 07859 supportArray = mdd_get_bdd_support_ids(mddManager, relation); 07860 for (i = 0; i < array_n(supportArray); i++) { 07861 id = array_fetch(int, supportArray, i); 07862 supportIndex[id] = 1; 07863 } 07864 array_free(supportArray); 07865 07866 s1 = colInfo[list->minCol].pos; 07867 t1 = colInfo[list->maxCol].pos; 07868 for (y = t1; y >= s1; y--) { 07869 col = colOrder[y]; 07870 if (!list->supports[col]) 07871 continue; 07872 id = (int)bdd_top_var_id(colInfo[col].data.col.var); 07873 if (!supportIndex[id]) { 07874 list->nSupports--; 07875 list->supports[col] = 0; 07876 if (list->nSupports == 0) { 07877 list->minCol = -1; 07878 list->maxCol = -1; 07879 } else if (list->nSupports == 1) { 07880 if (list->minCol == col) 07881 list->minCol = list->maxCol; 07882 else 07883 list->maxCol = list->minCol; 07884 } else if (list->nSupports > 1) { 07885 if (list->minCol == col) { 07886 for (j = y + 1; j <= t1; j++) { 07887 otherCol = colOrder[j]; 07888 if (list->supports[otherCol]) { 07889 list->minCol = otherCol; 07890 break; 07891 } 07892 } 07893 } else if (list->maxCol == col) { 07894 for (j = y - 1; j >= s1; j--) { 07895 otherCol = colOrder[j]; 07896 if (list->supports[otherCol]) { 07897 list->maxCol = otherCol; 07898 break; 07899 } 07900 } 07901 } 07902 } 07903 07904 for (j = list->start; j <= list->end; j++) { 07905 row = rowOrder[j]; 07906 if (xy[row][col]) { 07907 xy[row][col] = 0; 07908 colInfo[col].gNum--; 07909 rowInfo[row].gNum--; 07910 if (rowInfo[row].gNum > 0) { 07911 s2 = colInfo[rowInfo[row].gMin].pos; 07912 t2 = colInfo[rowInfo[row].gMax].pos; 07913 if (rowInfo[row].gMin == col) { 07914 for (k = y + 1; k <= t2; k++) { 07915 otherCol = colOrder[k]; 07916 if (xy[row][otherCol]) { 07917 rowInfo[row].gMin = otherCol; 07918 break; 07919 } 07920 } 07921 } else if (rowInfo[row].gMax == col) { 07922 for (k = y - 1; k >= s2; k--) { 07923 otherCol = colOrder[k]; 07924 if (xy[row][otherCol]) { 07925 rowInfo[row].gMax = otherCol; 07926 break; 07927 } 07928 } 07929 } 07930 } else { 07931 rowInfo[row].gMin = -1; 07932 rowInfo[row].gMax = nActiveCols; 07933 } 07934 } 07935 } 07936 07937 if (colInfo[col].gNum == 0) { 07938 colInfo[col].lNum = 0; 07939 colInfo[col].gMin = nActiveRows; 07940 colInfo[col].lMin = nActiveRows; 07941 colInfo[col].gMax = -1; 07942 colInfo[col].lMax = -1; 07943 } else if (colInfo[col].gNum == 1) { 07944 colInfo[col].lNum = 1; 07945 if (rowInfo[colInfo[col].gMax].pos > list->end) { 07946 colInfo[col].gMin = colInfo[col].gMax; 07947 colInfo[col].lMin = colInfo[col].gMax; 07948 } else { 07949 colInfo[col].gMax = colInfo[col].gMin; 07950 colInfo[col].lMax = colInfo[col].gMin; 07951 } 07952 } else { 07953 colInfo[col].lNum = colInfo[col].gNum; 07954 if (rowInfo[colInfo[col].gMin].pos >= list->start && 07955 rowInfo[colInfo[col].gMin].pos <= list->end) { 07956 for (i = list->end + 1; i <= rowInfo[colInfo[col].gMax].pos; i++) { 07957 otherRow = rowOrder[i]; 07958 if (xy[otherRow][col]) { 07959 colInfo[col].gMin = otherRow; 07960 colInfo[col].lMin = otherRow; 07961 break; 07962 } 07963 } 07964 } else if (rowInfo[colInfo[col].gMax].pos >= list->start && 07965 rowInfo[colInfo[col].gMax].pos <= list->end) { 07966 for (i = list->start - 1; i >= rowInfo[colInfo[col].gMin].pos; i--) { 07967 otherRow = rowOrder[i]; 07968 if (xy[otherRow][col]) { 07969 colInfo[col].gMax = otherRow; 07970 colInfo[col].lMax = otherRow; 07971 break; 07972 } 07973 } 07974 } 07975 } 07976 07977 if (moveFlag) { 07978 if (colInfo[col].gNum == 0) { 07979 if (y < nActiveCols - 1) { 07980 for (j = y; j < nActiveCols - 1; j++) { 07981 colOrder[j] = colOrder[j + 1]; 07982 colInfo[colOrder[j]].pos = j; 07983 } 07984 colOrder[nActiveCols - 1] = col; 07985 colInfo[col].pos = nActiveCols - 1; 07986 } 07987 } else if (rowInfo[colInfo[col].gMin].pos > list->end) { 07988 if (list->prev && list->prev->start > list->start) { 07989 /* Image */ 07990 otherList = list->prev; 07991 while (!otherList->supports[col]) 07992 otherList = otherList->prev; 07993 } else if (list->next && list->next->start > list->start) { 07994 /* Preimage */ 07995 otherList = list->next; 07996 while (!otherList->supports[col]) 07997 otherList = otherList->next; 07998 } else 07999 otherList = NIL(ClusterList_t); 08000 08001 if (otherList) { 08002 t2 = colInfo[otherList->maxCol].pos; 08003 if (y != t2) { 08004 for (j = y; j < t2; j++) { 08005 colOrder[j] = colOrder[j + 1]; 08006 colInfo[colOrder[j]].pos = j; 08007 } 08008 colOrder[t2] = col; 08009 colInfo[col].pos = t2; 08010 otherList->maxCol = col; 08011 if (otherList->minCol == col) { 08012 for (j = y; j < t2; j++) { 08013 otherCol = colOrder[j]; 08014 if (otherList->supports[otherCol]) { 08015 otherList->minCol = otherCol; 08016 break; 08017 } 08018 } 08019 } 08020 08021 s3 = rowInfo[colInfo[col].gMin].pos; 08022 t3 = rowInfo[colInfo[col].gMax].pos; 08023 for (j = s3; j <= t3; j++) { 08024 otherRow = rowOrder[j]; 08025 if (xy[otherRow][col]) { 08026 if (rowInfo[otherRow].gNum > 1) { 08027 t4 = colInfo[rowInfo[otherRow].gMax].pos; 08028 if (t4 <= t2) 08029 rowInfo[otherRow].gMax = col; 08030 if (rowInfo[otherRow].gMin == col) { 08031 for (k = y; k <= t4; k++) { 08032 otherCol = colOrder[k]; 08033 if (xy[otherRow][otherCol]) { 08034 rowInfo[otherRow].gMin = col; 08035 break; 08036 } 08037 } 08038 } 08039 } 08040 } 08041 } 08042 } 08043 } 08044 } 08045 } 08046 08047 if (option->mlpDebug) { 08048 CheckCluster(list, nActiveCols, colInfo, colOrder); 08049 CheckMatrix(xy, NIL(SccList_t), nActiveRows, nActiveCols, 08050 rowInfo, colInfo, rowOrder, colOrder, 08051 0, nActiveRows - 1, 0, nActiveCols - 1, 0); 08052 } 08053 } 08054 } 08055 08056 FREE(supportIndex); 08057 } 08058 08059 08069 static void 08070 UpdateNonappearingNsVars(mdd_manager *mddManager, array_t *nsVarBddArray, 08071 int nRows, RcInfo_t *rowInfo, int *rowOrder, 08072 array_t *nonAppearingVarBddArray) 08073 { 08074 int i, j, k, row, index, nVars; 08075 mdd_t *nsVar, *relation; 08076 char *existFlag; 08077 array_t *supportArray, *tmpArray; 08078 08079 nVars = bdd_num_vars(mddManager); 08080 existFlag = ALLOC(char, nVars); 08081 memset(existFlag, 0, sizeof(char) * nVars); 08082 08083 for (i = 0; i < nRows; i++) { 08084 row = rowOrder[i]; 08085 relation = rowInfo[row].data.row.func; 08086 supportArray = mdd_get_bdd_support_ids(mddManager, relation); 08087 for (j = 0; j < array_n(supportArray); j++) { 08088 index = array_fetch(int, supportArray, j); 08089 existFlag[index] = 1; 08090 } 08091 array_free(supportArray); 08092 } 08093 08094 for (i = 0; i < nRows; i++) { 08095 row = rowOrder[i]; 08096 for (j = 0; j < array_n(rowInfo[row].data.row.nsVarBddArray); j++) { 08097 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, j); 08098 index = (int)bdd_top_var_id(nsVar); 08099 if (!existFlag[index]) { 08100 tmpArray = array_alloc(mdd_t *, 0); 08101 for (k = 0; k < j; k++) { 08102 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, k); 08103 array_insert_last(mdd_t *, tmpArray, nsVar); 08104 } 08105 for (k = j + 1; k < array_n(rowInfo[row].data.row.nsVarBddArray); k++) { 08106 nsVar = array_fetch(bdd_t *, rowInfo[row].data.row.nsVarBddArray, k); 08107 index = (int)bdd_top_var_id(nsVar); 08108 if (existFlag[index]) 08109 array_insert_last(mdd_t *, tmpArray, nsVar); 08110 } 08111 array_free(rowInfo[row].data.row.nsVarBddArray); 08112 rowInfo[row].data.row.nsVarBddArray = tmpArray; 08113 break; 08114 } 08115 } 08116 } 08117 08118 for (i = 0; i < array_n(nsVarBddArray); i++) { 08119 nsVar = array_fetch(bdd_t *, nsVarBddArray, i); 08120 index = (int)bdd_top_var_id(nsVar); 08121 if (!existFlag[index]) 08122 array_insert_last(mdd_t *, nonAppearingVarBddArray, bdd_dup(nsVar)); 08123 } 08124 08125 FREE(existFlag); 08126 } 08127 08128 08138 static void 08139 WriteOrder(FILE *fout, int nCols, int *colOrder, RcInfo_t *colInfo) 08140 { 08141 int i, col; 08142 mdd_t *var; 08143 char *name; 08144 08145 for (i = 0; i < nCols; i++) { 08146 col = colOrder[i]; 08147 var = colInfo[col].data.col.var; 08148 name = mdd_read_var_name(var); 08149 fprintf(fout, "%s\n", name); 08150 } 08151 }