VIS
|
00001 00037 #include "imgInt.h" 00038 00039 static char rcsid[] UNUSED = "$Id: imgHybrid.c,v 1.27 2008/11/27 02:19:53 fabio Exp $"; 00040 00041 /*---------------------------------------------------------------------------*/ 00042 /* Constant declarations */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 /*---------------------------------------------------------------------------*/ 00046 /* Type declarations */ 00047 /*---------------------------------------------------------------------------*/ 00048 00049 /*---------------------------------------------------------------------------*/ 00050 /* Structure declarations */ 00051 /*---------------------------------------------------------------------------*/ 00052 00053 /*---------------------------------------------------------------------------*/ 00054 /* Variable declarations */ 00055 /*---------------------------------------------------------------------------*/ 00056 00057 /*---------------------------------------------------------------------------*/ 00058 /* Macro declarations */ 00059 /*---------------------------------------------------------------------------*/ 00060 00063 /*---------------------------------------------------------------------------*/ 00064 /* Static function prototypes */ 00065 /*---------------------------------------------------------------------------*/ 00066 00067 static float ComputeSupportLambda(ImgTfmInfo_t *info, array_t *relationArray, mdd_t *cofactorCube, mdd_t *abstractCube, mdd_t *from, array_t *vector, int newRelationFlag, int preFlag, float *improvedLambda); 00068 00072 /*---------------------------------------------------------------------------*/ 00073 /* Definition of exported functions */ 00074 /*---------------------------------------------------------------------------*/ 00075 00076 00088 void 00089 Img_PrintHybridOptions(void) 00090 { 00091 ImgTfmOption_t *options; 00092 char dummy[80]; 00093 00094 options = ImgTfmGetOptions(Img_Hybrid_c); 00095 00096 switch (options->hybridMode) { 00097 case 0 : 00098 sprintf(dummy, "with only transition function"); 00099 break; 00100 case 1 : 00101 sprintf(dummy, "with both transition function and relation"); 00102 break; 00103 case 2 : 00104 sprintf(dummy, "with only transition relation"); 00105 break; 00106 default : 00107 sprintf(dummy, "invalid"); 00108 break; 00109 } 00110 fprintf(vis_stdout, "HYB: hybrid_mode = %d (%s)\n", 00111 options->hybridMode, dummy); 00112 00113 switch (options->trSplitMethod) { 00114 case 0 : 00115 sprintf(dummy, "support"); 00116 break; 00117 case 1 : 00118 sprintf(dummy, "estimate BDD size"); 00119 break; 00120 default : 00121 sprintf(dummy, "invalid"); 00122 break; 00123 } 00124 fprintf(vis_stdout, "HYB: hybrid_tr_split_method = %d (%s)\n", 00125 options->trSplitMethod, dummy); 00126 00127 if (options->buildPartialTR) 00128 sprintf(dummy, "yes"); 00129 else 00130 sprintf(dummy, "no"); 00131 fprintf(vis_stdout, "HYB: hybrid_build_partial_tr = %s\n", dummy); 00132 00133 fprintf(vis_stdout, "HYB: hybrid_partial_num_vars = %d\n", 00134 options->nPartialVars); 00135 00136 switch (options->partialMethod) { 00137 case 0 : 00138 sprintf(dummy, "BDD size"); 00139 break; 00140 case 1 : 00141 sprintf(dummy, "support"); 00142 break; 00143 default : 00144 sprintf(dummy, "invalid"); 00145 break; 00146 } 00147 fprintf(vis_stdout, "HYB: hybrid_partial_method = %d (%s)\n", 00148 options->partialMethod, dummy); 00149 00150 if (options->delayedSplit) 00151 sprintf(dummy, "yes"); 00152 else 00153 sprintf(dummy, "no"); 00154 fprintf(vis_stdout, "HYB: hybrid_delayed_split = %s\n", dummy); 00155 00156 fprintf(vis_stdout, "HYB: hybrid_split_min_depth = %d\n", 00157 options->splitMinDepth); 00158 fprintf(vis_stdout, "HYB: hybrid_split_max_depth = %d\n", 00159 options->splitMaxDepth); 00160 fprintf(vis_stdout, "HYB: hybrid_pre_split_min_depth = %d\n", 00161 options->preSplitMinDepth); 00162 fprintf(vis_stdout, "HYB: hybrid_pre_split_max_depth = %d\n", 00163 options->preSplitMaxDepth); 00164 00165 fprintf(vis_stdout, "HYB: hybrid_lambda_threshold = %.2f\n", 00166 options->lambdaThreshold); 00167 fprintf(vis_stdout, "HYB: hybrid_pre_lambda_threshold = %.2f\n", 00168 options->preLambdaThreshold); 00169 fprintf(vis_stdout, "HYB: hybrid_conjoin_vector_size = %d\n", 00170 options->conjoinVectorSize); 00171 fprintf(vis_stdout, "HYB: hybrid_conjoin_relation_size = %d\n", 00172 options->conjoinRelationSize); 00173 fprintf(vis_stdout, "HYB: hybrid_conjoin_relation_bdd_size = %d\n", 00174 options->conjoinRelationBddSize); 00175 fprintf(vis_stdout, "HYB: hybrid_improve_lambda = %.2f\n", 00176 options->improveLambda); 00177 fprintf(vis_stdout, "HYB: hybrid_improve_vector_size = %d\n", 00178 options->improveVectorSize); 00179 fprintf(vis_stdout, "HYB: hybrid_improve_vector_bdd_size = %.2f\n", 00180 options->improveVectorBddSize); 00181 00182 switch (options->decideMode) { 00183 case 0 : 00184 sprintf(dummy, "use only lambda"); 00185 break; 00186 case 1 : 00187 sprintf(dummy, "lambda + special check"); 00188 break; 00189 case 2 : 00190 sprintf(dummy, "lambda + improvement"); 00191 break; 00192 case 3 : 00193 sprintf(dummy, "use all"); 00194 break; 00195 default : 00196 sprintf(dummy, "invalid"); 00197 break; 00198 } 00199 fprintf(vis_stdout, "HYB: hybrid_decide_mode = %d (%s)\n", 00200 options->decideMode, dummy); 00201 00202 if (options->reorderWithFrom) 00203 sprintf(dummy, "yes"); 00204 else 00205 sprintf(dummy, "no"); 00206 fprintf(vis_stdout, "HYB: hybrid_reorder_with_from = %s\n", dummy); 00207 00208 if (options->preReorderWithFrom) 00209 sprintf(dummy, "yes"); 00210 else 00211 sprintf(dummy, "no"); 00212 fprintf(vis_stdout, "HYB: hybrid_pre_reorder_with_from = %s\n", dummy); 00213 00214 switch (options->lambdaMode) { 00215 case 0 : 00216 sprintf(dummy, "total lifetime with ps/pi variables"); 00217 break; 00218 case 1 : 00219 sprintf(dummy, "active lifetime with ps/pi variables"); 00220 break; 00221 case 2 : 00222 sprintf(dummy, "total lifetime with ps/ns/pi variables"); 00223 break; 00224 default : 00225 sprintf(dummy, "invalid"); 00226 break; 00227 } 00228 fprintf(vis_stdout, "HYB: hybrid_lambda_mode = %d (%s)\n", 00229 options->lambdaMode, dummy); 00230 00231 switch (options->preLambdaMode) { 00232 case 0 : 00233 sprintf(dummy, "total lifetime with ns/pi variables"); 00234 break; 00235 case 1 : 00236 sprintf(dummy, "active lifetime with ps/pi variables"); 00237 break; 00238 case 2 : 00239 sprintf(dummy, "total lifetime with ps/ns/pi variables"); 00240 break; 00241 case 3 : 00242 sprintf(dummy, "total lifetime with ps/pi variables"); 00243 break; 00244 default : 00245 sprintf(dummy, "invalid"); 00246 break; 00247 } 00248 fprintf(vis_stdout, "HYB: hybrid_pre_lambda_mode = %d (%s)\n", 00249 options->preLambdaMode, dummy); 00250 00251 if (options->lambdaWithFrom) 00252 sprintf(dummy, "yes"); 00253 else 00254 sprintf(dummy, "no"); 00255 fprintf(vis_stdout, "HYB: hybrid_lambda_with_from = %s\n", dummy); 00256 00257 if (options->lambdaWithTr) 00258 sprintf(dummy, "yes"); 00259 else 00260 sprintf(dummy, "no"); 00261 fprintf(vis_stdout, "HYB: hybrid_lambda_with_tr = %s\n", dummy); 00262 00263 if (options->lambdaWithClustering) 00264 sprintf(dummy, "yes"); 00265 else 00266 sprintf(dummy, "no"); 00267 fprintf(vis_stdout, "HYB: hybrid_lambda_with_clustering = %s\n", dummy); 00268 00269 if (options->synchronizeTr) 00270 sprintf(dummy, "yes"); 00271 else 00272 sprintf(dummy, "no"); 00273 fprintf(vis_stdout, "HYB: hybrid_synchronize_tr = %s\n", dummy); 00274 00275 if (options->imgKeepPiInTr) 00276 sprintf(dummy, "yes"); 00277 else 00278 sprintf(dummy, "no"); 00279 fprintf(vis_stdout, "HYB: hybrid_img_keep_pi = %s\n", dummy); 00280 00281 if (options->preKeepPiInTr) 00282 sprintf(dummy, "yes"); 00283 else 00284 sprintf(dummy, "no"); 00285 fprintf(vis_stdout, "HYB: hybrid_pre_keep_pi = %s\n", dummy); 00286 00287 if (options->preCanonical) 00288 sprintf(dummy, "yes"); 00289 else 00290 sprintf(dummy, "no"); 00291 fprintf(vis_stdout, "HYB: hybrid_pre_canonical = %s\n", dummy); 00292 00293 switch (options->trMethod) { 00294 case Img_Iwls95_c : 00295 sprintf(dummy, "IWLS95"); 00296 break; 00297 case Img_Mlp_c : 00298 sprintf(dummy, "MLP"); 00299 break; 00300 default : 00301 sprintf(dummy, "invalid"); 00302 break; 00303 } 00304 fprintf(vis_stdout, "HYB: hybrid_tr_method = %s\n", dummy); 00305 00306 FREE(options); 00307 } 00308 00309 00310 /*---------------------------------------------------------------------------*/ 00311 /* Definition of internal functions */ 00312 /*---------------------------------------------------------------------------*/ 00313 00314 00324 int 00325 ImgDecideSplitOrConjoin(ImgTfmInfo_t *info, array_t *vector, mdd_t *from, 00326 int preFlag, array_t *relationArray, 00327 mdd_t *cofactorCube, mdd_t *abstractCube, 00328 int useBothFlag, int depth) 00329 { 00330 int conjoin = 0; 00331 float lambda, improvedLambda; 00332 int vectorBddSize, vectorSize; 00333 int improved; 00334 int minDepth; 00335 int checkSpecialCases; 00336 int checkImprovement; 00337 int relationSize = 0; 00338 00339 if (!preFlag) { 00340 if (vector && array_n(vector) <= 2) 00341 return(0); /* terminal case */ 00342 } 00343 00344 if (info->option->decideMode == 1 || info->option->decideMode == 3) 00345 checkSpecialCases = 1; 00346 else 00347 checkSpecialCases = 0; 00348 if (info->option->decideMode == 2 || info->option->decideMode == 3) 00349 checkImprovement = 1; 00350 else 00351 checkImprovement = 0; 00352 00353 if (checkSpecialCases) { 00354 if (vector && array_n(vector) <= info->option->conjoinVectorSize) { 00355 if (preFlag) 00356 info->nConjoinsB++; 00357 else 00358 info->nConjoins++; 00359 if (info->option->printLambda) { 00360 fprintf(vis_stdout, "%d: conjoin - small vector size (%d)\n", 00361 depth, array_n(vector)); 00362 } 00363 return(1); 00364 } 00365 } 00366 00367 if (preFlag) 00368 minDepth = info->option->preSplitMinDepth; 00369 else 00370 minDepth = info->option->splitMinDepth; 00371 00372 if (useBothFlag && relationArray && vector) { 00373 lambda = ComputeSupportLambda(info, relationArray, cofactorCube, 00374 abstractCube, from, vector, 00375 0, preFlag, &improvedLambda); 00376 } else if (relationArray) { 00377 if (checkSpecialCases) { 00378 if (array_n(relationArray) <= info->option->conjoinRelationSize || 00379 (relationSize = (int)bdd_size_multiple(relationArray)) <= 00380 info->option->conjoinRelationBddSize) { 00381 if (preFlag) 00382 info->nConjoinsB++; 00383 else 00384 info->nConjoins++; 00385 if (info->option->printLambda) { 00386 fprintf(vis_stdout, "%d: conjoin - small relation array (%d, %ld)\n", 00387 depth, array_n(relationArray), 00388 bdd_size_multiple(relationArray)); 00389 } 00390 return(1); 00391 } 00392 } 00393 00394 lambda = ComputeSupportLambda(info, relationArray, cofactorCube, 00395 abstractCube, from, NIL(array_t), 00396 0, preFlag, &improvedLambda); 00397 } else { 00398 int i; 00399 ImgComponent_t *comp; 00400 00401 relationArray = array_alloc(mdd_t *, 0); 00402 for (i = 0; i < array_n(vector); i++) { 00403 comp = array_fetch(ImgComponent_t *, vector, i); 00404 array_insert_last(mdd_t *, relationArray, comp->func); 00405 } 00406 00407 lambda = ComputeSupportLambda(info, relationArray, NIL(mdd_t), 00408 NIL(mdd_t), from, NIL(array_t), 00409 1, preFlag, &improvedLambda); 00410 00411 array_free(relationArray); 00412 } 00413 00414 if ((preFlag == 0 && lambda <= info->option->lambdaThreshold) || 00415 (preFlag == 1 && lambda <= info->option->preLambdaThreshold)) { 00416 if (preFlag) 00417 info->nConjoinsB++; 00418 else 00419 info->nConjoins++; 00420 if (info->option->printLambda) { 00421 fprintf(vis_stdout, "%d: conjoin - small lambda (%.2f)\n", 00422 depth, lambda); 00423 } 00424 conjoin = 1; 00425 } else { 00426 if (checkImprovement) { 00427 if (vector) { 00428 vectorBddSize = ImgVectorBddSize(vector); 00429 vectorSize = array_n(vector); 00430 if (depth == minDepth || 00431 improvedLambda >= info->option->improveLambda || 00432 ((float)vectorBddSize * 100.0 / (float)info->prevVectorBddSize) <= 00433 info->option->improveVectorBddSize || 00434 (info->prevVectorSize - vectorSize) >= 00435 info->option->improveVectorSize) { 00436 improved = 1; 00437 } else 00438 improved = 0; 00439 info->prevVectorBddSize = vectorBddSize; 00440 info->prevVectorSize = vectorSize; 00441 } else { 00442 if (relationSize) 00443 vectorBddSize = relationSize; 00444 else 00445 vectorBddSize = (int)bdd_size_multiple(relationArray); 00446 if (depth == minDepth || 00447 improvedLambda >= info->option->improveLambda || 00448 ((float)vectorBddSize * 100.0 / (float)info->prevVectorBddSize) <= 00449 info->option->improveVectorBddSize) { 00450 improved = 1; 00451 } else 00452 improved = 0; 00453 info->prevVectorBddSize = vectorBddSize; 00454 } 00455 if (improved) { 00456 if (preFlag) 00457 info->nSplitsB++; 00458 else 00459 info->nSplits++; 00460 if (info->option->printLambda) { 00461 fprintf(vis_stdout, "%d: split - big lambda (%.2f) - improved\n", 00462 depth, lambda); 00463 } 00464 conjoin = 0; 00465 } else { 00466 if (preFlag) 00467 info->nConjoinsB++; 00468 else 00469 info->nConjoins++; 00470 if (info->option->printLambda) { 00471 fprintf(vis_stdout, "%d: conjon - big lambda (%.2f) - not improved\n", 00472 depth, lambda); 00473 } 00474 conjoin = 1; 00475 } 00476 } else { 00477 if (preFlag) 00478 info->nSplitsB++; 00479 else 00480 info->nSplits++; 00481 if (info->option->printLambda) { 00482 fprintf(vis_stdout, "%d: split - big lambda (%.2f)\n", 00483 depth, lambda); 00484 } 00485 conjoin = 0; 00486 } 00487 } 00488 00489 return(conjoin); /* 0 : split, 1 : conjoin */ 00490 } 00491 00492 00502 mdd_t * 00503 ImgImageByHybrid(ImgTfmInfo_t *info, array_t *vector, mdd_t *from) 00504 { 00505 int i, j, nVars; 00506 array_t *relationArray; 00507 mdd_t *result, *domain, *relation, *var, *nextVar; 00508 ImgComponent_t *comp; 00509 char *support; 00510 array_t *smoothVarsBddArray, *introducedVarsBddArray; 00511 array_t *domainVarsBddArray; 00512 int bddId; 00513 00514 if (from && bdd_is_tautology(from, 0)) 00515 return(mdd_zero(info->manager)); 00516 00517 nVars = info->nVars; 00518 support = ALLOC(char, sizeof(char) * nVars); 00519 memset(support, 0, sizeof(char) * nVars); 00520 00521 relationArray = array_alloc(mdd_t *, 0); 00522 introducedVarsBddArray = array_alloc(mdd_t *, 0); 00523 00524 for (i = 0; i < array_n(vector); i++) { 00525 comp = array_fetch(ImgComponent_t *, vector, i); 00526 if (comp->intermediate) { 00527 relation = mdd_xnor(comp->var, comp->func); 00528 bddId = (int)bdd_top_var_id(comp->var); 00529 support[bddId] = 1; 00530 } else { 00531 nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 00532 relation = mdd_xnor(nextVar, comp->func); 00533 array_insert_last(mdd_t *, introducedVarsBddArray, nextVar); 00534 } 00535 array_insert_last(mdd_t *, relationArray, relation); 00536 00537 for (j = 0; j < nVars; j++) 00538 support[j] = support[j] | comp->support[j]; 00539 } 00540 00541 if (from && (!bdd_is_tautology(from, 1))) { 00542 if (info->option->reorderWithFrom) 00543 array_insert_last(mdd_t *, relationArray, mdd_dup(from)); 00544 00545 comp = ImgComponentAlloc(info); 00546 comp->func = from; 00547 ImgComponentGetSupport(comp); 00548 for (i = 0; i < nVars; i++) 00549 support[i] = support[i] | comp->support[i]; 00550 comp->func = NIL(mdd_t); 00551 ImgComponentFree(comp); 00552 } 00553 00554 smoothVarsBddArray = array_alloc(mdd_t *, 0); 00555 if (!info->option->reorderWithFrom) 00556 domainVarsBddArray = array_alloc(mdd_t *, 0); 00557 else 00558 domainVarsBddArray = NIL(array_t); 00559 for (i = 0; i < nVars; i++) { 00560 if (support[i]) { 00561 var = bdd_var_with_index(info->manager, i); 00562 if ((!from) || info->option->reorderWithFrom) 00563 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00564 else { 00565 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *)) || 00566 (info->intermediateVarsTable && 00567 st_lookup(info->intermediateVarsTable, (char *)(long)i, 00568 NIL(char *)))) { 00569 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00570 } else { 00571 array_insert_last(mdd_t *, domainVarsBddArray, var); 00572 } 00573 } 00574 } 00575 } 00576 FREE(support); 00577 00578 if ((!from) || info->option->reorderWithFrom) { 00579 result = ImgMultiwayLinearAndSmooth(info->manager, 00580 relationArray, 00581 smoothVarsBddArray, 00582 introducedVarsBddArray, 00583 info->option->trMethod, 00584 Img_Forward_c, 00585 info->trmOption); 00586 } else { 00587 result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, 00588 relationArray, from, 00589 smoothVarsBddArray, 00590 domainVarsBddArray, 00591 introducedVarsBddArray, 00592 info->option->trMethod, 00593 Img_Forward_c, 00594 info->trmOption); 00595 mdd_array_free(domainVarsBddArray); 00596 } 00597 mdd_array_free(relationArray); 00598 mdd_array_free(smoothVarsBddArray); 00599 mdd_array_free(introducedVarsBddArray); 00600 domain = ImgSubstitute(result, info->functionData, Img_R2D_c); 00601 mdd_free(result); 00602 return(domain); 00603 } 00604 00605 00615 mdd_t * 00616 ImgImageByHybridWithStaticSplit(ImgTfmInfo_t *info, array_t *vector, 00617 mdd_t *from, array_t *relationArray, 00618 mdd_t *cofactorCube, mdd_t *abstractCube) 00619 { 00620 int i, j; 00621 array_t *mergedRelationArray; 00622 mdd_t *result, *domain, *relation, *var, *nextVar; 00623 ImgComponent_t *comp, *supportComp; 00624 int nVars; 00625 char *support; 00626 array_t *smoothVarsBddArray, *introducedVarsBddArray; 00627 array_t *domainVarsBddArray; 00628 00629 if (from && bdd_is_tautology(from, 0)) 00630 return(mdd_zero(info->manager)); 00631 00632 if (cofactorCube && abstractCube) { 00633 if (!bdd_is_tautology(cofactorCube, 1) && 00634 !bdd_is_tautology(abstractCube, 1)) { 00635 mergedRelationArray = ImgGetCofactoredAbstractedRelationArray( 00636 info->manager, relationArray, 00637 cofactorCube, abstractCube); 00638 } else if (!bdd_is_tautology(cofactorCube, 1)) { 00639 mergedRelationArray = ImgGetCofactoredRelationArray(relationArray, 00640 cofactorCube); 00641 } else if (!bdd_is_tautology(abstractCube, 1)) { 00642 mergedRelationArray = ImgGetAbstractedRelationArray(info->manager, 00643 relationArray, 00644 abstractCube); 00645 } else 00646 mergedRelationArray = mdd_array_duplicate(relationArray); 00647 } else 00648 mergedRelationArray = mdd_array_duplicate(relationArray); 00649 00650 nVars = info->nVars; 00651 support = ALLOC(char, sizeof(char) * nVars); 00652 memset(support, 0, sizeof(char) * nVars); 00653 00654 supportComp = ImgComponentAlloc(info); 00655 for (i = 0; i < array_n(mergedRelationArray); i++) { 00656 supportComp->func = array_fetch(mdd_t *, mergedRelationArray, i);; 00657 ImgSupportClear(info, supportComp->support); 00658 ImgComponentGetSupport(supportComp); 00659 for (j = 0; j < nVars; j++) 00660 support[j] = support[j] | supportComp->support[j]; 00661 } 00662 00663 if (vector && array_n(vector) > 0) { 00664 for (i = 0; i < array_n(vector); i++) { 00665 comp = array_fetch(ImgComponent_t *, vector, i); 00666 if (comp->intermediate) { 00667 relation = mdd_xnor(comp->var, comp->func); 00668 support[(int)bdd_top_var_id(comp->var)] = 1; 00669 } else { 00670 nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 00671 relation = mdd_xnor(nextVar, comp->func); 00672 support[(int)bdd_top_var_id(nextVar)] = 1; 00673 mdd_free(nextVar); 00674 } 00675 array_insert_last(mdd_t *, mergedRelationArray, relation); 00676 00677 for (j = 0; j < nVars; j++) 00678 support[j] = support[j] | comp->support[j]; 00679 } 00680 } 00681 00682 if (from) { 00683 if ((!bdd_is_tautology(from, 1)) && info->option->reorderWithFrom) 00684 array_insert_last(mdd_t *, mergedRelationArray, mdd_dup(from)); 00685 00686 supportComp->func = from; 00687 ImgSupportClear(info, supportComp->support); 00688 ImgComponentGetSupport(supportComp); 00689 for (i = 0; i < nVars; i++) 00690 support[i] = support[i] | supportComp->support[i]; 00691 } 00692 supportComp->func = NIL(mdd_t); 00693 ImgComponentFree(supportComp); 00694 00695 smoothVarsBddArray = array_alloc(mdd_t *, 0); 00696 introducedVarsBddArray = array_alloc(mdd_t *, 0); 00697 if (!info->option->reorderWithFrom) 00698 domainVarsBddArray = array_alloc(mdd_t *, 0); 00699 else 00700 domainVarsBddArray = NIL(array_t); 00701 for (i = 0; i < nVars; i++) { 00702 if (support[i]) { 00703 var = bdd_var_with_index(info->manager, i); 00704 if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) 00705 array_insert_last(mdd_t *, introducedVarsBddArray, var); 00706 else if ((!from) || info->option->reorderWithFrom) 00707 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00708 else { 00709 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *)) || 00710 (info->intermediateVarsTable && 00711 st_lookup(info->intermediateVarsTable, (char *)(long)i, 00712 NIL(char *)))) { 00713 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00714 } else { 00715 array_insert_last(mdd_t *, domainVarsBddArray, var); 00716 } 00717 } 00718 } 00719 } 00720 FREE(support); 00721 00722 if ((!from) || info->option->reorderWithFrom) { 00723 result = ImgMultiwayLinearAndSmooth(info->manager, 00724 mergedRelationArray, 00725 smoothVarsBddArray, 00726 introducedVarsBddArray, 00727 info->option->trMethod, 00728 Img_Forward_c, 00729 info->trmOption); 00730 } else { 00731 result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, 00732 mergedRelationArray, from, 00733 smoothVarsBddArray, 00734 domainVarsBddArray, 00735 introducedVarsBddArray, 00736 info->option->trMethod, 00737 Img_Forward_c, 00738 info->trmOption); 00739 mdd_array_free(domainVarsBddArray); 00740 } 00741 mdd_array_free(mergedRelationArray); 00742 mdd_array_free(smoothVarsBddArray); 00743 mdd_array_free(introducedVarsBddArray); 00744 00745 domain = ImgSubstitute(result, info->functionData, Img_R2D_c); 00746 mdd_free(result); 00747 return(domain); 00748 } 00749 00750 00760 mdd_t * 00761 ImgPreImageByHybrid(ImgTfmInfo_t *info, array_t *vector, mdd_t *from) 00762 { 00763 int i, j, nVars; 00764 array_t *relationArray; 00765 mdd_t *result, *relation, *var, *nextVar; 00766 ImgComponent_t *comp; 00767 char *support; 00768 array_t *smoothVarsBddArray, *introducedVarsBddArray; 00769 array_t *rangeVarsBddArray; 00770 mdd_t *fromRange; 00771 00772 if (bdd_is_tautology(from, 1)) 00773 return(mdd_one(info->manager)); 00774 else if (bdd_is_tautology(from, 0)) 00775 return(mdd_zero(info->manager)); 00776 00777 nVars = info->nVars; 00778 support = ALLOC(char, sizeof(char) * nVars); 00779 memset(support, 0, sizeof(char) * nVars); 00780 00781 relationArray = array_alloc(mdd_t *, 0); 00782 00783 for (i = 0; i < array_n(vector); i++) { 00784 comp = array_fetch(ImgComponent_t *, vector, i); 00785 if (comp->intermediate) { 00786 relation = mdd_xnor(comp->var, comp->func); 00787 support[(int)bdd_top_var_id(comp->var)] = 1; 00788 } else { 00789 nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 00790 relation = mdd_xnor(nextVar, comp->func); 00791 support[(int)bdd_top_var_id(nextVar)] = 1; 00792 mdd_free(nextVar); 00793 } 00794 array_insert_last(mdd_t *, relationArray, relation); 00795 00796 for (j = 0; j < nVars; j++) 00797 support[j] = support[j] | comp->support[j]; 00798 } 00799 00800 fromRange = ImgSubstitute(from, info->functionData, Img_D2R_c); 00801 comp = ImgComponentAlloc(info); 00802 comp->func = fromRange; 00803 ImgComponentGetSupport(comp); 00804 for (i = 0; i < nVars; i++) 00805 support[i] = support[i] | comp->support[i]; 00806 comp->func = NIL(mdd_t); 00807 ImgComponentFree(comp); 00808 00809 smoothVarsBddArray = array_alloc(mdd_t *, 0); 00810 introducedVarsBddArray = array_alloc(mdd_t *, 0); 00811 if (!info->option->preReorderWithFrom) 00812 rangeVarsBddArray = array_alloc(mdd_t *, 0); 00813 else 00814 rangeVarsBddArray = NIL(array_t); 00815 for (i = 0; i < nVars; i++) { 00816 if (support[i]) { 00817 var = bdd_var_with_index(info->manager, i); 00818 if (info->intermediateVarsTable && 00819 st_lookup(info->intermediateVarsTable, (char *)(long)i, 00820 NIL(char *))) { 00821 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00822 } else if (st_lookup(info->rangeVarsTable, (char *)(long)i, 00823 NIL(char *))) { 00824 if (info->option->preReorderWithFrom) 00825 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00826 else 00827 array_insert_last(mdd_t *, rangeVarsBddArray, var); 00828 } else { 00829 if (info->preKeepPiInTr) 00830 array_insert_last(mdd_t *, introducedVarsBddArray, var); 00831 else { 00832 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, 00833 NIL(char *))) { 00834 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00835 } else 00836 array_insert_last(mdd_t *, introducedVarsBddArray, var); 00837 } 00838 } 00839 } 00840 } 00841 FREE(support); 00842 00843 if (info->option->preReorderWithFrom) { 00844 array_insert_last(mdd_t *, relationArray, fromRange); 00845 result = ImgMultiwayLinearAndSmooth(info->manager, 00846 relationArray, 00847 smoothVarsBddArray, 00848 introducedVarsBddArray, 00849 info->option->trMethod, 00850 Img_Backward_c, 00851 info->trmOption); 00852 } else { 00853 result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, 00854 relationArray, fromRange, 00855 smoothVarsBddArray, 00856 rangeVarsBddArray, 00857 introducedVarsBddArray, 00858 info->option->trMethod, 00859 Img_Backward_c, 00860 info->trmOption); 00861 mdd_free(fromRange); 00862 mdd_array_free(rangeVarsBddArray); 00863 } 00864 mdd_array_free(relationArray); 00865 mdd_array_free(smoothVarsBddArray); 00866 mdd_array_free(introducedVarsBddArray); 00867 return(result); 00868 } 00869 00870 00880 mdd_t * 00881 ImgPreImageByHybridWithStaticSplit(ImgTfmInfo_t *info, array_t *vector, 00882 mdd_t *from, array_t *relationArray, 00883 mdd_t *cofactorCube, mdd_t *abstractCube) 00884 { 00885 int i, j; 00886 array_t *mergedRelationArray; 00887 mdd_t *result, *relation, *var, *nextVar, *fromRange; 00888 ImgComponent_t *comp, *supportComp; 00889 int nVars; 00890 char *support; 00891 array_t *smoothVarsBddArray, *introducedVarsBddArray; 00892 array_t *rangeVarsBddArray; 00893 00894 if (bdd_is_tautology(from, 1)) 00895 return(mdd_one(info->manager)); 00896 if (bdd_is_tautology(from, 0)) 00897 return(mdd_zero(info->manager)); 00898 00899 if (cofactorCube && abstractCube) { 00900 if (!bdd_is_tautology(cofactorCube, 1) && 00901 !bdd_is_tautology(abstractCube, 1)) { 00902 mergedRelationArray = ImgGetCofactoredAbstractedRelationArray( 00903 info->manager, relationArray, 00904 cofactorCube, abstractCube); 00905 } else if (!bdd_is_tautology(cofactorCube, 1)) { 00906 mergedRelationArray = ImgGetCofactoredRelationArray(relationArray, 00907 cofactorCube); 00908 } else if (!bdd_is_tautology(abstractCube, 1)) { 00909 mergedRelationArray = ImgGetAbstractedRelationArray(info->manager, 00910 relationArray, 00911 abstractCube); 00912 } else 00913 mergedRelationArray = mdd_array_duplicate(relationArray); 00914 } else 00915 mergedRelationArray = mdd_array_duplicate(relationArray); 00916 00917 nVars = info->nVars; 00918 support = ALLOC(char, sizeof(char) * nVars); 00919 memset(support, 0, sizeof(char) * nVars); 00920 00921 supportComp = ImgComponentAlloc(info); 00922 for (i = 0; i < array_n(mergedRelationArray); i++) { 00923 supportComp->func = array_fetch(mdd_t *, mergedRelationArray, i);; 00924 ImgSupportClear(info, supportComp->support); 00925 ImgComponentGetSupport(supportComp); 00926 for (j = 0; j < nVars; j++) 00927 support[j] = support[j] | supportComp->support[j]; 00928 } 00929 00930 if (vector && array_n(vector) > 0) { 00931 for (i = 0; i < array_n(vector); i++) { 00932 comp = array_fetch(ImgComponent_t *, vector, i); 00933 if (comp->intermediate) { 00934 relation = mdd_xnor(comp->var, comp->func); 00935 support[(int)bdd_top_var_id(comp->var)] = 1; 00936 } else { 00937 nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 00938 relation = mdd_xnor(nextVar, comp->func); 00939 support[(int)bdd_top_var_id(nextVar)] = 1; 00940 mdd_free(nextVar); 00941 } 00942 array_insert_last(mdd_t *, mergedRelationArray, relation); 00943 00944 for (j = 0; j < nVars; j++) 00945 support[j] = support[j] | comp->support[j]; 00946 } 00947 } 00948 00949 fromRange = ImgSubstitute(from, info->functionData, Img_D2R_c); 00950 supportComp->func = fromRange; 00951 ImgSupportClear(info, supportComp->support); 00952 ImgComponentGetSupport(supportComp); 00953 for (i = 0; i < nVars; i++) 00954 support[i] = support[i] | supportComp->support[i]; 00955 supportComp->func = NIL(mdd_t); 00956 ImgComponentFree(supportComp); 00957 00958 smoothVarsBddArray = array_alloc(mdd_t *, 0); 00959 introducedVarsBddArray = array_alloc(mdd_t *, 0); 00960 if (!info->option->preReorderWithFrom) 00961 rangeVarsBddArray = array_alloc(mdd_t *, 0); 00962 else 00963 rangeVarsBddArray = NIL(array_t); 00964 for (i = 0; i < nVars; i++) { 00965 if (support[i]) { 00966 var = bdd_var_with_index(info->manager, i); 00967 if (info->intermediateVarsTable && 00968 st_lookup(info->intermediateVarsTable, (char *)(long)i, 00969 NIL(char *))) { 00970 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00971 } else if (st_lookup(info->rangeVarsTable, (char *)(long)i, 00972 NIL(char *))) { 00973 if (info->option->preReorderWithFrom) 00974 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00975 else 00976 array_insert_last(mdd_t *, rangeVarsBddArray, var); 00977 } else { 00978 if (info->preKeepPiInTr) 00979 array_insert_last(mdd_t *, introducedVarsBddArray, var); 00980 else { 00981 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, 00982 NIL(char *))) { 00983 array_insert_last(mdd_t *, smoothVarsBddArray, var); 00984 } else 00985 array_insert_last(mdd_t *, introducedVarsBddArray, var); 00986 } 00987 } 00988 } 00989 } 00990 FREE(support); 00991 00992 if (info->option->preReorderWithFrom) { 00993 array_insert_last(mdd_t *, mergedRelationArray, fromRange); 00994 result = ImgMultiwayLinearAndSmooth(info->manager, 00995 mergedRelationArray, 00996 smoothVarsBddArray, 00997 introducedVarsBddArray, 00998 info->option->trMethod, 00999 Img_Backward_c, 01000 info->trmOption); 01001 } else { 01002 result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, 01003 mergedRelationArray, fromRange, 01004 smoothVarsBddArray, 01005 rangeVarsBddArray, 01006 introducedVarsBddArray, 01007 info->option->trMethod, 01008 Img_Backward_c, 01009 info->trmOption); 01010 mdd_free(fromRange); 01011 mdd_array_free(rangeVarsBddArray); 01012 } 01013 mdd_array_free(mergedRelationArray); 01014 mdd_array_free(smoothVarsBddArray); 01015 mdd_array_free(introducedVarsBddArray); 01016 01017 return(result); 01018 } 01019 01020 01030 int 01031 ImgCheckEquivalence(ImgTfmInfo_t *info, array_t *vector, array_t *relationArray, 01032 mdd_t *cofactorCube, mdd_t *abstractCube, int preFlag) 01033 { 01034 int i, equal; 01035 mdd_t *product1, *product2; 01036 mdd_t *var, *tmp, *relation; 01037 ImgComponent_t *comp; 01038 array_t *newRelationArray, *tmpRelationArray; 01039 array_t *domainVarBddArray, *quantifyVarBddArray; 01040 01041 tmpRelationArray = array_alloc(mdd_t *, 0); 01042 for (i = 0; i < array_n(vector); i++) { 01043 comp = array_fetch(ImgComponent_t *, vector, i); 01044 if (comp->intermediate) 01045 relation = mdd_xnor(comp->var, comp->func); 01046 else { 01047 var = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01048 relation = mdd_xnor(var, comp->func); 01049 mdd_free(var); 01050 } 01051 array_insert_last(mdd_t *, tmpRelationArray, relation); 01052 } 01053 01054 if (preFlag) { 01055 if (info->preKeepPiInTr) { 01056 quantifyVarBddArray = array_alloc(mdd_t *, 0); 01057 domainVarBddArray = array_join(info->domainVarBddArray, 01058 info->quantifyVarBddArray); 01059 } else { 01060 quantifyVarBddArray = info->quantifyVarBddArray; 01061 domainVarBddArray = info->domainVarBddArray; 01062 } 01063 newRelationArray = ImgClusterRelationArray(info->manager, 01064 info->functionData, info->option->trMethod, Img_Backward_c, 01065 info->trmOption, tmpRelationArray, domainVarBddArray, 01066 quantifyVarBddArray, info->rangeVarBddArray, 01067 NIL(array_t *), NIL(array_t *), 0); 01068 if (info->preKeepPiInTr) { 01069 array_free(quantifyVarBddArray); 01070 array_free(domainVarBddArray); 01071 } 01072 } else { 01073 newRelationArray = ImgClusterRelationArray(info->manager, 01074 info->functionData, info->option->trMethod, Img_Forward_c, 01075 info->trmOption, tmpRelationArray, info->domainVarBddArray, 01076 info->quantifyVarBddArray, info->rangeVarBddArray, 01077 NIL(array_t *), NIL(array_t *), 0); 01078 } 01079 mdd_array_free(tmpRelationArray); 01080 01081 product1 = mdd_one(info->manager); 01082 for (i = 0; i < array_n(newRelationArray); i++) { 01083 relation = array_fetch(mdd_t *, newRelationArray, i); 01084 tmp = product1; 01085 product1 = mdd_and(tmp, relation, 1, 1); 01086 mdd_free(tmp); 01087 } 01088 mdd_array_free(newRelationArray); 01089 01090 if (cofactorCube && abstractCube) { 01091 newRelationArray = ImgGetCofactoredAbstractedRelationArray(info->manager, 01092 relationArray, cofactorCube, abstractCube); 01093 } else 01094 newRelationArray = relationArray; 01095 01096 product2 = mdd_one(info->manager); 01097 for (i = 0; i < array_n(newRelationArray); i++) { 01098 relation = array_fetch(mdd_t *, newRelationArray, i); 01099 tmp = product2; 01100 product2 = mdd_and(tmp, relation, 1, 1); 01101 mdd_free(tmp); 01102 } 01103 01104 if (newRelationArray != relationArray) 01105 mdd_array_free(newRelationArray); 01106 01107 if (mdd_equal(product1, product2)) 01108 equal = 1; 01109 else 01110 equal = 0; 01111 01112 mdd_free(product1); 01113 mdd_free(product2); 01114 01115 return(equal); 01116 } 01117 01118 01131 int 01132 ImgCheckMatching(ImgTfmInfo_t *info, array_t *vector, array_t *relationArray) 01133 { 01134 int i, equal = 1; 01135 mdd_t *var, *relation; 01136 ImgComponent_t *comp; 01137 st_table *relationTable; 01138 int *ptr; 01139 01140 relationTable = st_init_table(st_ptrcmp, st_ptrhash); 01141 01142 for (i = 0; i < array_n(relationArray); i++) { 01143 relation = array_fetch(mdd_t *, relationArray, i); 01144 ptr = (int *)bdd_pointer(relation); 01145 st_insert(relationTable, (char *)ptr, NULL); 01146 } 01147 01148 for (i = 0; i < array_n(vector); i++) { 01149 comp = array_fetch(ImgComponent_t *, vector, i); 01150 if (comp->intermediate) 01151 relation = mdd_xnor(comp->var, comp->func); 01152 else { 01153 var = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 01154 relation = mdd_xnor(var, comp->func); 01155 mdd_free(var); 01156 } 01157 ptr = (int *)bdd_pointer(relation); 01158 if (!st_lookup(relationTable, (char *)ptr, NULL)) { 01159 if (comp->intermediate) { 01160 fprintf(vis_stderr, 01161 "Error : relation of varId[%d - intermediate] not found\n", 01162 (int)bdd_top_var_id(comp->var)); 01163 } else { 01164 fprintf(vis_stderr, "Error : relation of varId[%d] not found\n", 01165 (int)bdd_top_var_id(comp->var)); 01166 } 01167 equal = 0; 01168 } 01169 mdd_free(relation); 01170 } 01171 01172 st_free_table(relationTable); 01173 return(equal); 01174 } 01175 01176 01177 /*---------------------------------------------------------------------------*/ 01178 /* Definition of static functions */ 01179 /*---------------------------------------------------------------------------*/ 01180 01181 01193 static float 01194 ComputeSupportLambda(ImgTfmInfo_t *info, array_t *relationArray, 01195 mdd_t *cofactorCube, mdd_t *abstractCube, 01196 mdd_t *from, array_t *vector, int newRelationFlag, 01197 int preFlag, float *improvedLambda) 01198 { 01199 array_t *newRelationArray, *clusteredRelationArray; 01200 ImgComponent_t *comp; 01201 int i, j, nVars, nSupports; 01202 mdd_t *newFrom, *var; 01203 char *support; 01204 array_t *smoothVarsBddArray, *introducedVarsBddArray; 01205 array_t *domainVarsBddArray; 01206 array_t *smoothSchedule, *smoothVars; 01207 float lambda; 01208 int size, total, lifetime; 01209 Img_DirectionType direction; 01210 int lambdaWithFrom, prevArea; 01211 array_t *orderedRelationArray; 01212 int nIntroducedVars; 01213 int *highest, *lowest; 01214 mdd_t *relation; 01215 int asIs; 01216 01217 if (cofactorCube && abstractCube) { 01218 newRelationArray = ImgGetCofactoredAbstractedRelationArray(info->manager, 01219 relationArray, cofactorCube, abstractCube); 01220 if (from && info->option->lambdaWithFrom) { 01221 if (preFlag) 01222 newFrom = ImgSubstitute(from, info->functionData, Img_D2R_c); 01223 else 01224 newFrom = mdd_dup(from); 01225 array_insert_last(mdd_t *, newRelationArray, newFrom); 01226 lambdaWithFrom = 1; 01227 } else { 01228 lambdaWithFrom = 0; 01229 newFrom = NIL(mdd_t); 01230 } 01231 } else { 01232 if (from && info->option->lambdaWithFrom) { 01233 if (newRelationFlag) { 01234 newRelationArray = relationArray; 01235 if (preFlag) 01236 newFrom = ImgSubstitute(from, info->functionData, Img_D2R_c); 01237 else 01238 newFrom = from; 01239 } else { 01240 /* We don't want to modify the original relation array */ 01241 newRelationArray = mdd_array_duplicate(relationArray); 01242 if (preFlag) 01243 newFrom = ImgSubstitute(from, info->functionData, Img_D2R_c); 01244 else 01245 newFrom = mdd_dup(from); 01246 } 01247 array_insert_last(mdd_t *, newRelationArray, newFrom); 01248 lambdaWithFrom = 1; 01249 } else { 01250 newRelationArray = relationArray; 01251 newFrom = NIL(mdd_t); 01252 lambdaWithFrom = 0; 01253 } 01254 } 01255 01256 if (vector) { 01257 for (i = 0; i < array_n(vector); i++) { 01258 comp = array_fetch(ImgComponent_t *, vector, i); 01259 array_insert_last(mdd_t *, newRelationArray, mdd_dup(comp->func)); 01260 } 01261 } 01262 01263 nVars = info->nVars; 01264 support = ALLOC(char, sizeof(char) * nVars); 01265 memset(support, 0, sizeof(char) * nVars); 01266 01267 comp = ImgComponentAlloc(info); 01268 for (i = 0; i < array_n(newRelationArray); i++) { 01269 comp->func = array_fetch(mdd_t *, newRelationArray, i);; 01270 ImgSupportClear(info, comp->support); 01271 ImgComponentGetSupport(comp); 01272 for (j = 0; j < nVars; j++) 01273 support[j] = support[j] | comp->support[j]; 01274 } 01275 comp->func = NIL(mdd_t); 01276 ImgComponentFree(comp); 01277 01278 nSupports = 0; 01279 smoothVarsBddArray = array_alloc(mdd_t *, 0); 01280 domainVarsBddArray = array_alloc(mdd_t *, 0); 01281 introducedVarsBddArray = array_alloc(mdd_t *, 0); 01282 for (i = 0; i < nVars; i++) { 01283 if (support[i]) { 01284 var = bdd_var_with_index(info->manager, i); 01285 if (preFlag) { 01286 if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) { 01287 if (lambdaWithFrom) 01288 array_insert_last(mdd_t *, smoothVarsBddArray, var); 01289 else 01290 array_insert_last(mdd_t *, domainVarsBddArray, var); 01291 if (info->option->preLambdaMode == 0 || 01292 info->option->preLambdaMode == 2) 01293 nSupports++; 01294 } else { 01295 if (info->preKeepPiInTr) { 01296 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, 01297 NIL(char *))) { 01298 array_insert_last(mdd_t *, introducedVarsBddArray, var); 01299 nSupports++; 01300 } else if (info->intermediateVarsTable && 01301 st_lookup(info->intermediateVarsTable, (char *)(long)i, 01302 NIL(char *))) { 01303 array_insert_last(mdd_t *, smoothVarsBddArray, var); 01304 nSupports++; 01305 } else { /* ps variables */ 01306 array_insert_last(mdd_t *, introducedVarsBddArray, var); 01307 if (info->option->preLambdaMode != 0) 01308 nSupports++; 01309 } 01310 } else { 01311 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, 01312 NIL(char *)) || 01313 (info->intermediateVarsTable && 01314 st_lookup(info->intermediateVarsTable, (char *)(long)i, 01315 NIL(char *)))) { 01316 array_insert_last(mdd_t *, smoothVarsBddArray, var); 01317 nSupports++; 01318 } else { /* ps variables */ 01319 array_insert_last(mdd_t *, introducedVarsBddArray, var); 01320 if (info->option->preLambdaMode != 0) 01321 nSupports++; 01322 } 01323 } 01324 } 01325 } else { /* image computation */ 01326 if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) { 01327 array_insert_last(mdd_t *, introducedVarsBddArray, var); 01328 if (info->option->lambdaMode == 2) 01329 nSupports++; 01330 } else { 01331 if (lambdaWithFrom) 01332 array_insert_last(mdd_t *, smoothVarsBddArray, var); 01333 else { 01334 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, 01335 NIL(char *)) || 01336 (info->intermediateVarsTable && 01337 st_lookup(info->intermediateVarsTable, (char *)(long)i, 01338 NIL(char *)))) { 01339 array_insert_last(mdd_t *, smoothVarsBddArray, var); 01340 } else 01341 array_insert_last(mdd_t *, domainVarsBddArray, var); 01342 } 01343 nSupports++; 01344 } 01345 } 01346 } 01347 } 01348 01349 if (preFlag) 01350 direction = Img_Backward_c; 01351 else 01352 direction = Img_Forward_c; 01353 01354 if (info->option->lambdaFromMlp) { 01355 FREE(support); 01356 if (info->option->lambdaWithClustering) { 01357 ImgMlpClusterRelationArray(info->manager, info->functionData, 01358 newRelationArray, domainVarsBddArray, 01359 smoothVarsBddArray, introducedVarsBddArray, 01360 direction, &clusteredRelationArray, NIL(array_t *), 01361 info->trmOption); 01362 if (newRelationArray != relationArray) 01363 mdd_array_free(newRelationArray); 01364 newRelationArray = clusteredRelationArray; 01365 } 01366 prevArea = info->prevTotal; 01367 asIs = newRelationFlag ? 0 : 1; /* 0 when relationArray is an array of 01368 functions, i.e. without next state 01369 variables */ 01370 lambda = ImgMlpComputeLambda(info->manager, newRelationArray, 01371 domainVarsBddArray, smoothVarsBddArray, 01372 introducedVarsBddArray, direction, 01373 info->option->lambdaMode, asIs, &prevArea, 01374 improvedLambda, info->trmOption); 01375 info->prevTotal = prevArea; 01376 } else { 01377 smoothSchedule = ImgGetQuantificationSchedule(info->manager, 01378 info->functionData, info->option->trMethod, 01379 direction, info->trmOption, newRelationArray, 01380 smoothVarsBddArray, domainVarsBddArray, 01381 introducedVarsBddArray, 01382 info->option->lambdaWithClustering, 01383 &orderedRelationArray); 01384 01385 if (direction == Img_Forward_c) { 01386 size = array_n(smoothSchedule); 01387 lifetime = 0; 01388 if (info->option->lambdaMode == 0) { /* total lifetime (lambda) */ 01389 for (i = 1; i < size; i++) { 01390 smoothVars = array_fetch(array_t *, smoothSchedule, i); 01391 lifetime += array_n(smoothVars) * i; 01392 } 01393 total = nSupports * (size - 1); 01394 } else if (info->option->lambdaMode == 1) { /* active lifetime (lambda) */ 01395 lowest = ALLOC(int, sizeof(int) * nVars); 01396 for (i = 0; i < nVars; i++) 01397 lowest[i] = nVars; 01398 highest = ALLOC(int, sizeof(int) * nVars); 01399 memset(highest, 0, sizeof(int) * nVars); 01400 01401 comp = ImgComponentAlloc(info); 01402 for (i = 0; i < size - 1; i++) { 01403 relation = array_fetch(mdd_t *, orderedRelationArray, i); 01404 comp->func = relation; 01405 ImgSupportClear(info, comp->support); 01406 ImgComponentGetSupport(comp); 01407 for (j = 0; j < nVars; j++) { 01408 if (!comp->support[j]) 01409 continue; 01410 if (st_lookup(info->rangeVarsTable, (char *)(long)j, NIL(char *))) 01411 continue; 01412 if (i < lowest[j]) 01413 lowest[j] = i; 01414 if (i > highest[j]) 01415 highest[j] = i; 01416 } 01417 } 01418 comp->func = NIL(mdd_t); 01419 ImgComponentFree(comp); 01420 01421 for (i = 0; i < nVars; i++) { 01422 if (lowest[i] == nVars) 01423 continue; 01424 if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) 01425 continue; 01426 lifetime += highest[i] - lowest[i] + 1; 01427 } 01428 01429 if (newRelationFlag) 01430 lifetime += array_n(newRelationArray); 01431 total = nSupports * (size - 1); 01432 01433 FREE(lowest); 01434 FREE(highest); 01435 } else { /* total lifetime (lambda) with introduced variables */ 01436 for (i = 1; i < size; i++) { 01437 smoothVars = array_fetch(array_t *, smoothSchedule, i); 01438 lifetime += array_n(smoothVars) * i; 01439 } 01440 01441 if (newRelationFlag) { 01442 nIntroducedVars = array_n(newRelationArray); 01443 lifetime += nIntroducedVars * (nIntroducedVars + 1) / 2; 01444 } else { 01445 comp = ImgComponentAlloc(info); 01446 for (i = 0; i < size - 1; i++) { 01447 relation = array_fetch(mdd_t *, orderedRelationArray, i); 01448 comp->func = relation; 01449 ImgSupportClear(info, comp->support); 01450 ImgComponentGetSupport(comp); 01451 nIntroducedVars = 0; 01452 for (j = 0; j < nVars; j++) { 01453 if (!comp->support[j]) 01454 continue; 01455 if (st_lookup(info->rangeVarsTable, (char *)(long)j, NIL(char *))) 01456 nIntroducedVars++; 01457 } 01458 lifetime += (size - i - 1) * nIntroducedVars; 01459 } 01460 comp->func = NIL(mdd_t); 01461 ImgComponentFree(comp); 01462 } 01463 total = nSupports * (size - 1); 01464 } 01465 mdd_array_array_free(smoothSchedule); 01466 } else if (info->option->preLambdaMode == 0) { /* total lifetime (lambda) */ 01467 /* direction == Img_Backward_c */ 01468 size = array_n(smoothSchedule); 01469 lifetime = 0; 01470 for (i = 1; i < size; i++) { 01471 smoothVars = array_fetch(array_t *, smoothSchedule, i); 01472 lifetime += array_n(smoothVars) * i; 01473 } 01474 total = nSupports * (size - 1); 01475 mdd_array_array_free(smoothSchedule); 01476 } else { /* direction == Img_Backward_c */ 01477 size = array_n(smoothSchedule); 01478 mdd_array_array_free(smoothSchedule); 01479 lifetime = 0; 01480 01481 lowest = ALLOC(int, sizeof(int) * nVars); 01482 for (i = 0; i < nVars; i++) 01483 lowest[i] = nVars; 01484 highest = ALLOC(int, sizeof(int) * nVars); 01485 memset(highest, 0, sizeof(int) * nVars); 01486 01487 comp = ImgComponentAlloc(info); 01488 for (i = 0; i < size - 1; i++) { 01489 relation = array_fetch(mdd_t *, orderedRelationArray, i); 01490 comp->func = relation; 01491 ImgSupportClear(info, comp->support); 01492 ImgComponentGetSupport(comp); 01493 for (j = 0; j < nVars; j++) { 01494 if (!comp->support[j]) 01495 continue; 01496 if (i < lowest[j]) 01497 lowest[j] = i; 01498 if (i > highest[j]) 01499 highest[j] = i; 01500 } 01501 } 01502 comp->func = NIL(mdd_t); 01503 ImgComponentFree(comp); 01504 01505 if (info->option->preLambdaMode == 1) { /* active lifetime (lambda) */ 01506 for (i = 0; i < nVars; i++) { 01507 if (lowest[i] == nVars) 01508 continue; 01509 if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *)) || 01510 st_lookup(info->quantifyVarsTable, (char *)(long)i, 01511 NIL(char *)) || 01512 (info->intermediateVarsTable && 01513 st_lookup(info->intermediateVarsTable, (char *)(long)i, 01514 NIL(char *)))) { 01515 lifetime += highest[i] - lowest[i] + 1; 01516 } 01517 } 01518 if (newRelationFlag) 01519 lifetime += array_n(newRelationArray); 01520 total = nSupports * (size - 1); 01521 } else if (info->option->preLambdaMode == 2) { 01522 /* total lifetime (lambda) with introduced variables */ 01523 for (i = 0; i < nVars; i++) { 01524 if (lowest[i] == nVars) 01525 continue; 01526 if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *)) || 01527 st_lookup(info->quantifyVarsTable, (char *)(long)i, 01528 NIL(char *)) || 01529 (info->intermediateVarsTable && 01530 st_lookup(info->intermediateVarsTable, (char *)(long)i, 01531 NIL(char *)))) { 01532 lifetime += highest[i] + 1; 01533 } else { 01534 lifetime += size - lowest[i] - 1; 01535 } 01536 } 01537 if (newRelationFlag) { 01538 nIntroducedVars = array_n(newRelationArray); 01539 lifetime += nIntroducedVars * (nIntroducedVars + 1) / 2; 01540 } 01541 total = nSupports * (size - 1); 01542 } else { /* total lifetime (lambda) with ps/pi variables */ 01543 for (i = 0; i < nVars; i++) { 01544 if (lowest[i] == nVars) 01545 continue; 01546 if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) 01547 continue; 01548 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, 01549 NIL(char *)) || 01550 (info->intermediateVarsTable && 01551 st_lookup(info->intermediateVarsTable, (char *)(long)i, 01552 NIL(char *)))) { 01553 lifetime += highest[i] + 1; 01554 } else { 01555 lifetime += size - lowest[i] - 1; 01556 } 01557 } 01558 if (newRelationFlag) { 01559 nIntroducedVars = array_n(newRelationArray); 01560 lifetime += nIntroducedVars * (nIntroducedVars + 1) / 2; 01561 } 01562 total = nSupports * (size - 1); 01563 } 01564 01565 FREE(lowest); 01566 FREE(highest); 01567 } 01568 01569 FREE(support); 01570 mdd_array_free(orderedRelationArray); 01571 01572 if (total == 0.0) { 01573 lambda = 0.0; 01574 *improvedLambda = 0.0; 01575 } else { 01576 lambda = (float)lifetime / (float)total; 01577 if (info->prevTotal) { 01578 *improvedLambda = info->prevLambda - 01579 (float)lifetime / (float)info->prevTotal; 01580 } else 01581 *improvedLambda = 0.0; 01582 } 01583 info->prevTotal = total; 01584 } 01585 01586 mdd_array_free(smoothVarsBddArray); 01587 mdd_array_free(domainVarsBddArray); 01588 mdd_array_free(introducedVarsBddArray); 01589 if (newRelationArray != relationArray) 01590 mdd_array_free(newRelationArray); 01591 if (newRelationFlag && from && info->option->lambdaWithFrom && 01592 newFrom != from) { 01593 mdd_free(newFrom); 01594 } 01595 01596 if (info->option->verbosity >= 2) { 01597 if (preFlag) 01598 fprintf(vis_stdout, "** tfm info: lambda for preimage = %.2f\n", lambda); 01599 else 01600 fprintf(vis_stdout, "** tfm info: lambda for image = %.2f\n", lambda); 01601 } 01602 01603 info->prevLambda = lambda; 01604 return(lambda); 01605 }