SALSA Analysis Modules
|
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; PetscTruth 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*,PetscTruth*); 00168 int nval,ival; PetscTruth 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,PetscTruth *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*,PetscTruth*) = NULL; 00217 #undef __FUNCT__ 00218 #define __FUNCT__ "AnaModSetRetrievalFunction" 00219 PetscErrorCode AnaModSetRetrievalFunction 00220 (PetscErrorCode(*fun)(void*,char*,char*,AnalysisItem*,AnalysisDataType*,PetscTruth*)) 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*,PetscTruth*),PetscTruth *flg) 00231 { 00232 PetscTruth has; 00233 PetscFunctionBegin; 00234 has = (PetscTruth)(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 }