SALSA Analysis Modules
feature.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include "string.h"
00003 #include "anamod.h"
00004 #include "petsc.h"
00005 
00006 /*! \page featureset Feature sets
00007   
00008   AnaMod has a mechanism for querying single category/component pairs,
00009   but often a specific set of features is needed quickly, and/or multiple
00010   times. For this, the `feature set' mechanism exists.
00011 
00012   A feature set is a set of category/component pairs. It does not contain
00013   actual values. A feature set can be instantiated to a `feature values' 
00014   object, which contains the actual values that the feature set takes
00015   on a given problem.
00016 
00017   This is the workflow:
00018   - a FeatureSet object is created, once, with NewFeatureSet().
00019   - category/component pairs are added to it with AddToFeatureSet().
00020   - a FeatureValues object is created with NewFeatureValues().
00021   - a call to InstantiateFeatureSet() fills in the feature set on a 
00022   specified numerical problem.
00023   - user code can retrieve values with GetFeatureValue()
00024 
00025   Here is a piece of example code:
00026 \code
00027   {
00028     FeatureSet symmetry; int sidx,aidx;
00029     ierr = NewFeatureSet(&symmetry); CHKERRQ(ierr);
00030     ierr = AddToFeatureSet
00031       (symmetry,"simple","symmetry-snorm",&sidx); CHKERRQ(ierr);
00032     ierr = AddToFeatureSet
00033       (symmetry,"simple","symmetry-anorm",&aidx); CHKERRQ(ierr);
00034     ierr = TransformObjectSetSuitabilityFunction
00035       (cur,(void*)symmetry,&onlyforsymmetricproblem); CHKERRQ(ierr);
00036   }
00037 
00038 PetscErrorCode onlyforsymmetricproblem
00039 (NumericalProblem problem,void *ctx,SuitabilityValue *v)
00040 {
00041   FeatureSet features = (FeatureSet)ctx; FeatureValues values;
00042   AnalysisItem sn,an; PetscBool f1,f2; PetscErrorCode ierr;
00043   
00044   PetscFunctionBegin;
00045   ierr = NewFeatureValues(&values); CHKERRQ(ierr);
00046   ierr = InstantiateFeatureSet((void*)problem,features,values); CHKERRQ(ierr);
00047   ierr = GetFeatureValue(values,sidx,&sn,&f1); CHKERRQ(ierr);
00048   ierr = GetFeatureValue(values,aidx,&an,&f2); CHKERRQ(ierr);
00049   ierr = DeleteFeatureValues(values); CHKERRQ(ierr);
00050   if (f1 && f2 && an.r>1.e-12*sn.r) {
00051     printf("problem too unsymmetric\n");
00052   }
00053 \endcode
00054 
00055  */
00056 
00057 #define NALLOC 25
00058 #define FSETCOOKIE 9876
00059 #define CHECKVALIDFSET(i) {ANAMODCHECKVALID(i,FSETCOOKIE,"feature set");}
00060 struct FeatureSet_ {
00061   int cookie;
00062   AnalysisDataType *types; IntArray IDs; StringArray features;
00063 };
00064 #define FVALCOOKIE 9877
00065 #define CHECKVALIDFVAL(i) {ANAMODCHECKVALID(i,FVALCOOKIE,"feature values");}
00066 struct FeatureValues_ {
00067   int cookie;
00068   AnalysisItemArray values; AnalysisDataTypeArray types;
00069 };
00070 
00071 #undef __FUNCT__ 
00072 #define __FUNCT__ "NewFeatureSet"
00073 /*! Allocate a featureset object. See \ref featureset */
00074 PetscErrorCode NewFeatureSet(FeatureSet *set)
00075 {
00076   FeatureSet fnew; PetscErrorCode ierr;
00077   PetscFunctionBegin;
00078   ierr = PetscMalloc(sizeof(struct FeatureSet_),&fnew); CHKERRQ(ierr);
00079   ierr = PetscMemzero(fnew,sizeof(struct FeatureSet_)); CHKERRQ(ierr);
00080   fnew->cookie = FSETCOOKIE;
00081   ierr = CreateIntArray("IDs",50,&(fnew->IDs)); CHKERRQ(ierr);
00082   ierr = CreateStringArray("features",50,&(fnew->features)); CHKERRQ(ierr);
00083   *set = fnew;
00084   PetscFunctionReturn(0);
00085 }
00086 
00087 #undef __FUNCT__ 
00088 #define __FUNCT__ "DeleteFeatureSet"
00089 /*! Delete a featureset object. See \ref featureset */
00090 PetscErrorCode DeleteFeatureSet(FeatureSet set)
00091 {
00092   PetscErrorCode ierr;
00093   PetscFunctionBegin;
00094   CHECKVALIDFSET(set);
00095   ierr = DeleteIntArray(set->IDs); CHKERRQ(ierr);
00096   ierr = DeleteStringArray(set->features); CHKERRQ(ierr);
00097   ierr = PetscFree(set); CHKERRQ(ierr);
00098   PetscFunctionReturn(0);
00099 }
00100 
00101 #undef __FUNCT__ 
00102 #define __FUNCT__ "AddToFeatureSet"
00103 /*! Add a requested feature to a featureset object. See \ref featureset
00104 
00105   Arguments:
00106   - \c set : the featureset
00107   - \c cat,cmp : the category and component name. It is an error to 
00108   supply unknown names
00109   - \c idx : the index under which the feature is known in this featureset.
00110   This index can be supplied to GetFeatureValue().
00111   This parameter can be null.
00112 
00113 */
00114 PetscErrorCode AddToFeatureSet
00115 (FeatureSet set,const char *cat,const char *cmp,int *idx)
00116 {
00117   PetscErrorCode ierr;
00118   char *name; int l1,l2;
00119   PetscFunctionBegin;
00120   CHECKVALIDFSET(set);
00121 
00122   l1 = strlen(cat); l2 = strlen(cmp);
00123   ierr = PetscMalloc((l1+l2+1)*sizeof(char),&name); CHKERRQ(ierr);
00124   sprintf(name,"%s/%s",cat,cmp);
00125   ierr = StringArrayAdd(set->features,name,idx); CHKERRQ(ierr);
00126   ierr = PetscFree(name); CHKERRQ(ierr);
00127   PetscFunctionReturn(0);
00128 }
00129 
00130 #undef __FUNCT__ 
00131 #define __FUNCT__ "NewFeatureValues"
00132 /*! Allocate a featurevalues object. See \ref featureset */
00133 PetscErrorCode NewFeatureValues(FeatureValues *values)
00134 {
00135   FeatureValues fnew; PetscErrorCode ierr;
00136   PetscFunctionBegin;
00137   ierr = PetscMalloc(sizeof(struct FeatureValues_),&fnew); CHKERRQ(ierr);
00138   ierr = PetscMemzero(fnew,sizeof(struct FeatureValues_)); CHKERRQ(ierr);
00139   fnew->cookie = FVALCOOKIE;
00140   ierr = CreateAnalysisItemArray("values",50,&fnew->values); CHKERRQ(ierr);
00141   ierr = CreateAnalysisDataTypeArray("values",50,&fnew->types); CHKERRQ(ierr);
00142   *values = fnew;
00143   PetscFunctionReturn(0);
00144 }
00145 
00146 #undef __FUNCT__
00147 #define __FUNCT__ "DeleteFeatureValues"
00148 /*! Free a featurevalues object. See \ref featureset */
00149 PetscErrorCode DeleteFeatureValues(FeatureValues values)
00150 {
00151   PetscErrorCode ierr;
00152   PetscFunctionBegin;
00153   CHECKVALIDFVAL(values);
00154   ierr = DeleteAnalysisItemArray(values->values); CHKERRQ(ierr);
00155   ierr = DeleteAnalysisDataTypeArray(values->types); CHKERRQ(ierr);
00156   ierr = PetscFree(values); CHKERRQ(ierr);
00157   PetscFunctionReturn(0);
00158 }
00159 
00160 #undef __FUNCT__ 
00161 #define __FUNCT__ "InstantiateFeatureSet"
00162 /*! Fill in a featurevalues object. See \ref featureset */
00163 PetscErrorCode InstantiateFeatureSet
00164 (AnaModNumericalProblem prob,FeatureSet set,FeatureValues values)
00165 {
00166   PetscErrorCode (*retriever)
00167     (void*,char*,char*,AnalysisItem*,AnalysisDataType*,PetscBool*);
00168   int nval,ival; PetscBool flg; PetscErrorCode ierr;
00169   PetscFunctionBegin;
00170   CHECKVALIDFSET(set);
00171   CHECKVALIDFVAL(values);
00172   ierr = AnaModGetRetrievalFunction(&retriever,&flg); CHKERRQ(ierr);
00173   if (!flg) PetscFunctionReturn(0);
00174   ierr = StringArrayGetFill(set->features,&nval); CHKERRQ(ierr);
00175   for (ival=0; ival<nval; ival++) {
00176     char *feature,*cat,*cmp; int l;
00177     AnalysisItem res; AnalysisDataType t;
00178     ierr = StringArrayGetAt(set->features,ival,&feature); CHKERRQ(ierr);
00179     for (l=0; l<strlen(feature); l++) {
00180       if (feature[l]=='/') {
00181         feature[l] = 0; cat = feature; cmp = feature+l+1;
00182         ierr = (*retriever)(prob,cat,cmp,&res,&t,&flg); CHKERRQ(ierr);
00183         if (flg) {
00184           ierr = AnalysisItemArraySetAt(values->values,ival,res); CHKERRQ(ierr);
00185           ierr = AnalysisDataTypeArraySetAt(values->types,ival,t); CHKERRQ(ierr);
00186         }
00187         feature[l] = '/'; break;
00188       }
00189     }
00190   }
00191   PetscFunctionReturn(0);
00192 }
00193 
00194 #undef __FUNCT__
00195 #define __FUNCT__ "GetFeatureValue"
00196 /*! Extract a value from a featurevalues object. See \ref featureset.
00197 
00198   Arguments:
00199   - \c values : the FeatureValues object.
00200   - \c index : the index, as returned by AddToFeatureSet().
00201   - \c val (output) : the value; this argument can be null.
00202   - \c f (output) : indicates whether the return value was indeed
00203   preset in the featurevalues object; this argument can be null.
00204 
00205 */
00206 PetscErrorCode GetFeatureValue
00207 (FeatureValues values,int index,AnalysisItem *val,PetscBool *f)
00208 {
00209   PetscErrorCode ierr;
00210   PetscFunctionBegin;
00211   CHECKVALIDFVAL(values);
00212   ierr = AnalysisItemArrayTryGetAt(values->values,index,val,f); CHKERRQ(ierr);
00213   PetscFunctionReturn(0);
00214 }
00215 
00216 static PetscErrorCode(*retriever)(void*,char*,char*,AnalysisItem*,AnalysisDataType*,PetscBool*) = NULL;
00217 #undef __FUNCT__ 
00218 #define __FUNCT__ "AnaModSetRetrievalFunction"
00219 PetscErrorCode AnaModSetRetrievalFunction
00220 (PetscErrorCode(*fun)(void*,char*,char*,AnalysisItem*,AnalysisDataType*,PetscBool*))
00221 {
00222   PetscFunctionBegin;
00223   retriever = fun;
00224   PetscFunctionReturn(0);
00225 }
00226 
00227 #undef __FUNCT__ 
00228 #define __FUNCT__ "AnaModGetRetrievalFunction"
00229 PetscErrorCode AnaModGetRetrievalFunction
00230 (PetscErrorCode(**fun)(void*,char*,char*,AnalysisItem*,AnalysisDataType*,PetscBool*),PetscBool *flg)
00231 {
00232   PetscBool has;
00233   PetscFunctionBegin;
00234   has = (PetscBool)(retriever!=NULL);
00235   if (flg) *flg = has;
00236   if (has &&fun) *fun = retriever;
00237   PetscFunctionReturn(0);
00238 }
00239 
00240 #undef __FUNCT__
00241 #define __FUNCT__ "AnaModCheckValidFeatureSet"
00242 PetscErrorCode AnaModCheckValidFeatureSet(void *f)
00243 {
00244   PetscFunctionBegin;
00245   CHECKVALIDFSET((FeatureSet)f);
00246   PetscFunctionReturn(0);
00247 }