VIS

src/img/imgMonolithic.c

Go to the documentation of this file.
00001 
00033 #include "imgInt.h"
00034 
00035 static char rcsid[] UNUSED = "$Id: imgMonolithic.c,v 1.23 2002/08/27 08:43:12 fabio Exp $";
00036 
00039 /*---------------------------------------------------------------------------*/
00040 /* Static function prototypes                                                */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 static mdd_t * ImageComputeMonolithic(mdd_t *methodData, mdd_t *fromLowerBound, mdd_t *fromUpperBound, array_t *toCareSetArray, array_t *smoothVars, mdd_t *smoothCube);
00044 
00048 /*---------------------------------------------------------------------------*/
00049 /* Definition of exported functions                                          */
00050 /*---------------------------------------------------------------------------*/
00051 
00052 
00053     
00054 /*---------------------------------------------------------------------------*/
00055 /* Definition of internal functions                                          */
00056 /*---------------------------------------------------------------------------*/
00057 
00058 
00071 void *
00072 ImgImageInfoInitializeMono(void *methodData, ImgFunctionData_t * functionData,
00073                            Img_DirectionType directionType)
00074 {
00075   if (!methodData){ /* Need to compute */
00076     int          i;
00077     mdd_t       *monolithicT;
00078     array_t     *rootRelations = array_alloc(mdd_t*, 0);
00079     graph_t     *mddNetwork    = functionData->mddNetwork;
00080     mdd_manager *mddManager    = Part_PartitionReadMddManager(mddNetwork);
00081     array_t     *roots         = functionData->roots;
00082     array_t     *leaves        = array_join(functionData->domainVars,
00083                                             functionData->quantifyVars);
00084     array_t     *rootFunctions = Part_PartitionBuildFunctions(mddNetwork, roots,
00085                                                               leaves,
00086                                                               NIL(mdd_t)); 
00087     
00088     array_free(leaves);
00089     
00090     
00091     /*
00092      * Take the product of the transition relation of all the root nodes
00093      * and smooth out the quantify variables.
00094      */
00095     
00096     /*
00097      * Iterate over the function of all the root nodes.
00098      */  
00099     for (i=0; i<array_n(rootFunctions); i++) {
00100       Mvf_Function_t *rootFunction  = array_fetch(Mvf_Function_t*, rootFunctions, i);
00101       int             rangeVarMddId = array_fetch(int, functionData->rangeVars, i);
00102       mdd_t          *rootRelation =
00103           Mvf_FunctionBuildRelationWithVariable(rootFunction,
00104                                                 rangeVarMddId); 
00105       array_insert_last(mdd_t*, rootRelations, rootRelation);
00106     }
00107     
00108     Mvf_FunctionArrayFree(rootFunctions);
00109     monolithicT = Img_MultiwayLinearAndSmooth(mddManager, rootRelations,
00110                                               functionData->quantifyVars,
00111                                               functionData->domainVars,
00112                                               Img_Iwls95_c, Img_Forward_c);
00113     mdd_array_free(rootRelations);
00114     return ((void *)monolithicT);
00115   }
00116   else {
00117     return methodData;
00118   }
00119 }
00120 
00121 
00122 
00138 mdd_t *
00139 ImgImageInfoComputeFwdMono(
00140   ImgFunctionData_t * functionData,
00141   Img_ImageInfo_t * imageInfo,
00142   mdd_t *fromLowerBound,
00143   mdd_t *fromUpperBound,
00144   array_t * toCareSetArray)
00145 {
00146   return  ImageComputeMonolithic((mdd_t *) imageInfo->methodData,
00147                                  fromLowerBound, fromUpperBound,
00148                                  toCareSetArray, functionData->domainBddVars,
00149                                  functionData->domainCube);  
00150 }
00151 
00152   
00167 mdd_t *
00168 ImgImageInfoComputeFwdWithDomainVarsMono(
00169   ImgFunctionData_t *functionData,
00170   Img_ImageInfo_t *imageInfo,
00171   mdd_t *fromLowerBound,
00172   mdd_t *fromUpperBound,
00173   array_t *toCareSetArray)
00174 {
00175   array_t *toCareSetArrayRV = ImgSubstituteArray(toCareSetArray,
00176                                                  functionData, Img_D2R_c);
00177   mdd_t *imageRV = ImgImageInfoComputeFwdMono(functionData,
00178                                               imageInfo,
00179                                               fromLowerBound,
00180                                               fromUpperBound,
00181                                               toCareSetArrayRV);
00182   mdd_t *imageDV = ImgSubstitute(imageRV, functionData, Img_R2D_c);
00183 
00184   mdd_array_free(toCareSetArrayRV);
00185   mdd_free(imageRV);
00186   return imageDV;
00187 }
00188 
00205 mdd_t *
00206 ImgImageInfoComputeBwdMono(
00207   ImgFunctionData_t * functionData,
00208   Img_ImageInfo_t *imageInfo,
00209   mdd_t *fromLowerBound,
00210   mdd_t *fromUpperBound,
00211   array_t *toCareSetArray)
00212 {
00213   return ImageComputeMonolithic((mdd_t*)imageInfo->methodData, fromLowerBound,
00214                                 fromUpperBound, toCareSetArray,  
00215                                 functionData->rangeBddVars,
00216                                 functionData->rangeCube);  
00217 }
00218 
00233 mdd_t *
00234 ImgImageInfoComputeBwdWithDomainVarsMono(
00235   ImgFunctionData_t * functionData,
00236   Img_ImageInfo_t *imageInfo,
00237   mdd_t *fromLowerBound,
00238   mdd_t *fromUpperBound,
00239   array_t *toCareSetArray)
00240 {
00241   mdd_t *fromLowerBoundRV = ImgSubstitute(fromLowerBound,
00242                                           functionData, Img_D2R_c);
00243   mdd_t *fromUpperBoundRV = ImgSubstitute(fromUpperBound,
00244                                           functionData, Img_D2R_c);
00245   mdd_t *image = ImgImageInfoComputeBwdMono(functionData,
00246                                             imageInfo,
00247                                             fromLowerBoundRV,
00248                                             fromUpperBoundRV,
00249                                             toCareSetArray);
00250   mdd_free(fromLowerBoundRV);
00251   mdd_free(fromUpperBoundRV);
00252   return image;
00253 }
00254 
00255 
00256 
00264 void
00265 ImgImageInfoFreeMono(void * methodData)
00266 {
00267   mdd_free((mdd_t *)methodData);
00268 }
00269 
00280 void
00281 ImgImageInfoPrintMethodParamsMono(void *methodData, FILE *fp)
00282 {
00283   mdd_t *monolithicRelation = (mdd_t *)methodData;
00284   (void) fprintf(fp,"Printing information about image method: Monolithic\n");  
00285   (void) fprintf(fp,"\tSize of monolithic relation = %10ld\n",
00286                  (long) bdd_size(monolithicRelation));
00287 }
00288 
00298 void
00299 ImgRestoreTransitionRelationMono(Img_ImageInfo_t *imageInfo,
00300         Img_DirectionType directionType)
00301 {
00302   mdd_free((mdd_t *) imageInfo->methodData);
00303   imageInfo->methodData = (mdd_t *)imageInfo->savedRelation;
00304   imageInfo->savedRelation = NIL(void);
00305   return;
00306 }
00307 
00318 void
00319 ImgDuplicateTransitionRelationMono(Img_ImageInfo_t *imageInfo)
00320 {
00321   imageInfo->savedRelation = (void *)mdd_dup((mdd_t *) imageInfo->methodData);
00322   return;
00323 }
00324 
00334 void
00335 ImgMinimizeTransitionRelationMono(Img_ImageInfo_t *imageInfo,
00336         array_t *constrainArray, Img_MinimizeType minimizeMethod,
00337         int printStatus)
00338 {
00339   mdd_t *relation, *simplifiedRelation;
00340   int i, size = 0;
00341   mdd_t *constrain;
00342 
00343   relation = (mdd_t *)imageInfo->methodData;
00344 
00345   if (printStatus)
00346     size = bdd_size(relation);
00347 
00348   for (i = 0; i < array_n(constrainArray); i++) {
00349     constrain = array_fetch(mdd_t *, constrainArray, i);
00350     simplifiedRelation = Img_MinimizeImage(relation, constrain, minimizeMethod,
00351                                            TRUE);
00352     if (printStatus) {
00353       (void) fprintf(vis_stdout, "Info: minimized relation %d | %d => %d\n",
00354                      bdd_size(relation), bdd_size(constrain),
00355                      bdd_size(simplifiedRelation));
00356     }
00357     mdd_free(relation);
00358     relation = simplifiedRelation;
00359   }
00360   imageInfo->methodData = (void *)relation;
00361 
00362   if (printStatus) {
00363     (void) fprintf(vis_stdout,
00364         "IMG Info: minimized relation [%d | %ld => %d]\n",
00365                    size, bdd_size_multiple(constrainArray),
00366                    bdd_size(relation));
00367   }
00368 }
00369 
00380 void
00381 ImgAddDontCareToTransitionRelationMono(Img_ImageInfo_t *imageInfo,
00382         array_t *constrainArray, Img_MinimizeType minimizeMethod,
00383         int printStatus)
00384 {
00385   mdd_t *relation, *simplifiedRelation;
00386   int i, size = 0;
00387   mdd_t *constrain;
00388 
00389   relation = (mdd_t *)imageInfo->methodData;
00390 
00391   if (printStatus)
00392     size = bdd_size(relation);
00393 
00394   for (i = 0; i < array_n(constrainArray); i++) {
00395     constrain = array_fetch(mdd_t *, constrainArray, i);
00396     simplifiedRelation = Img_AddDontCareToImage(relation,
00397                                              constrain, minimizeMethod);
00398     if (printStatus) {
00399       (void) fprintf(vis_stdout, "Info: minimized relation %d | %d => %d\n",
00400                      bdd_size(relation), bdd_size(constrain),
00401                      bdd_size(simplifiedRelation));
00402     }
00403     mdd_free(relation);
00404     relation = simplifiedRelation;
00405   }
00406   imageInfo->methodData = (void *)relation;
00407 
00408   if (printStatus) {
00409     (void) fprintf(vis_stdout,
00410         "IMG Info: minimized relation [%d | %ld => %d]\n",
00411                    size, bdd_size_multiple(constrainArray),
00412                    bdd_size(relation));
00413   }
00414 }
00415 
00416 
00427 void
00428 ImgAbstractTransitionRelationMono(Img_ImageInfo_t *imageInfo,
00429         array_t *abstractVars, mdd_t *abstractCube, int printStatus)
00430 {
00431   mdd_t *relation, *abstractedRelation;
00432 
00433   relation = (mdd_t *)imageInfo->methodData;
00434   if (abstractCube)
00435     abstractedRelation = bdd_smooth_with_cube(relation, abstractCube);
00436   else
00437     abstractedRelation = bdd_smooth(relation, abstractVars);
00438   if (printStatus) {
00439     (void) fprintf(vis_stdout, "Info: abstracted relation %d => %d\n",
00440                      bdd_size(relation), bdd_size(abstractedRelation));
00441   }
00442   mdd_free(relation);
00443   imageInfo->methodData = (void *)abstractedRelation;
00444 }
00445 
00446 
00456 int
00457 ImgApproximateTransitionRelationMono(mdd_manager *mgr,
00458         Img_ImageInfo_t *imageInfo,
00459         bdd_approx_dir_t approxDir,
00460         bdd_approx_type_t approxMethod,
00461         int approxThreshold,
00462         double approxQuality,
00463         double approxQualityBias,
00464         mdd_t *bias)
00465 {
00466   mdd_t *relation, *approxRelation;
00467   int   unchanged;
00468 
00469   relation = (mdd_t *)imageInfo->methodData;
00470   approxRelation = Img_ApproximateImage(mgr, relation, approxDir, approxMethod,
00471                                         approxThreshold, approxQuality,
00472                                         approxQualityBias, bias);
00473   if (bdd_is_tautology(approxRelation, 1)) {
00474     fprintf(vis_stdout, "** img warning : bdd_one from subsetting.\n");
00475     mdd_free(approxRelation);
00476     unchanged = 1;
00477   } else if (bdd_is_tautology(approxRelation, 0)) {
00478     fprintf(vis_stdout, "** img warning : bdd_zero from subsetting.\n");
00479     mdd_free(approxRelation);
00480     unchanged = 1;
00481   } else if (mdd_equal(approxRelation, relation)) {
00482     mdd_free(approxRelation);
00483     unchanged = 1;
00484   } else {
00485     mdd_free(relation);
00486     imageInfo->methodData = (void *)approxRelation;
00487     unchanged = 0;
00488   }
00489   return(unchanged);
00490 }
00491 
00519 void 
00520 ImgImageConstrainAndClusterTransitionRelationMono(Img_ImageInfo_t *imageInfo,
00521                                                   mdd_t *constrain,
00522                                                   Img_MinimizeType minimizeMethod,
00523                                                   boolean underApprox,
00524                                                   boolean cleanUp,
00525                                                   boolean forceReorder,
00526                                                   int printStatus)
00527 {
00528   ImgFunctionData_t *functionData = &(imageInfo->functionData);
00529   mdd_t *methodData = (mdd_t *)imageInfo->methodData;
00530   int          i;
00531   mdd_t       *monolithicT;
00532   array_t     *rootRelations = array_alloc(mdd_t*, 0);
00533   graph_t     *mddNetwork    = functionData->mddNetwork;
00534   mdd_manager *mddManager    = Part_PartitionReadMddManager(mddNetwork);
00535   array_t     *roots         = functionData->roots;
00536   array_t     *leaves        = array_join(functionData->domainVars,
00537                                           functionData->quantifyVars);
00538   array_t     *rootFunctions;
00539   mdd_t       *relation;
00540   
00541   /*free existing  relation. */
00542   if (!methodData) ImgImageInfoFreeMono(methodData);    
00543   if (forceReorder) bdd_reorder(mddManager);
00544   rootFunctions = Part_PartitionBuildFunctions(mddNetwork, roots,
00545                                                leaves,
00546                                                NIL(mdd_t)); 
00547   
00548   array_free(leaves);
00549     
00550   /*
00551    * Take the product of the transition relation of all the root nodes
00552    * and smooth out the quantify variables.
00553    */
00554   
00555   /*
00556    * Iterate over the function of all the root nodes.
00557    */  
00558   for (i=0; i<array_n(rootFunctions); i++) {
00559     Mvf_Function_t *rootFunction  = array_fetch(Mvf_Function_t*, rootFunctions, i);
00560     int             rangeVarMddId = array_fetch(int, functionData->rangeVars, i);
00561     mdd_t          *rootRelation =
00562       Mvf_FunctionBuildRelationWithVariable(rootFunction,
00563                                             rangeVarMddId); 
00564     array_insert_last(mdd_t*, rootRelations, rootRelation);
00565   }
00566   Mvf_FunctionArrayFree(rootFunctions);
00567 
00568   /* Constrain the bit relaitons */
00569   if (constrain) {
00570     arrayForEachItem(mdd_t *, rootRelations, i, relation) {
00571       mdd_t *simplifiedRelation;
00572       simplifiedRelation = Img_MinimizeImage(relation, constrain,
00573                                              minimizeMethod, underApprox);
00574       if (printStatus) {
00575         (void) fprintf(vis_stdout, "Info: minimized relation %d | %d => %d\n",
00576                        bdd_size(relation), bdd_size(constrain),
00577                        bdd_size(simplifiedRelation));
00578       }
00579       mdd_free(relation);
00580       array_insert(mdd_t *, rootRelations, i, simplifiedRelation);
00581     }
00582   }
00583 
00584   /* build the monolithic transition relation. */
00585   monolithicT = Img_MultiwayLinearAndSmooth(mddManager, rootRelations,
00586                                             functionData->quantifyVars,
00587                                             functionData->domainVars,
00588                                             Img_Iwls95_c, Img_Forward_c);
00589   mdd_array_free(rootRelations);
00590   imageInfo->methodData = (void *)monolithicT;
00591   if (printStatus) {
00592     ImgImageInfoPrintMethodParamsMono(monolithicT, vis_stdout);
00593   }
00594 
00595 }
00596 
00597 
00598 
00599 /*---------------------------------------------------------------------------*/
00600 /* Definition of static functions                                            */
00601 /*---------------------------------------------------------------------------*/
00619 static mdd_t *
00620 ImageComputeMonolithic(mdd_t *methodData, mdd_t *fromLowerBound, mdd_t
00621                 *fromUpperBound, array_t *toCareSetArray,
00622                 array_t *smoothVars, mdd_t *smoothCube)
00623 {
00624   mdd_t       *domainSubset, *image;
00625   mdd_t       *optimizedRelation, *subOptimizedRelation;
00626   mdd_t       *monolithicT = (mdd_t *)methodData;
00627   
00628   assert(monolithicT != NIL(mdd_t));
00629   
00630   /*
00631    * Optimization steps:
00632    * Choose the domainSubset optimally.
00633    * Reduce the transition relation wrt to care set and domainSubset.
00634    */
00635   domainSubset = bdd_between(fromLowerBound,fromUpperBound);
00636   subOptimizedRelation = bdd_cofactor_array(monolithicT, toCareSetArray);
00637   optimizedRelation = bdd_cofactor(subOptimizedRelation, domainSubset);  
00638   mdd_free(domainSubset);
00639   mdd_free(subOptimizedRelation);
00640   /*optimizedRelation = bdd_and(fromLowerBound, monolithicT, 1, 1);*/
00641   if (smoothCube)
00642     image = bdd_smooth_with_cube(optimizedRelation, smoothCube);
00643   else {
00644     if (array_n(smoothVars) == 0)
00645       image = mdd_dup(optimizedRelation);
00646     else
00647       image = bdd_smooth(optimizedRelation, smoothVars);
00648   }
00649 
00650   mdd_free(optimizedRelation);
00651   return image;
00652 }
00653