📄 mp_dict.c
字号:
*/void AddChannels(DICT dict,LISTV lv){ unsigned char channel; char *type; SIGNAL signal; LWFLOAT f; unsigned long i; /* Basic checking */ if(dict->nChannels>0) Errorf("AddChannels : should clear the dict before"); if(lv->length>DICT_MAX_NCHANNELS) Errorf("AddChannels : too many channels (the max is %d)",DICT_MAX_NCHANNELS); /* If we need to (re)allocate dict->channels */ if(lv->length>dict->nChannelsAlloc) { if(dict->nChannelsAlloc==0) { dict->channels = (SIGNAL*) Calloc(lv->length,sizeof(SIGNAL)); dict->nChannelsAlloc = lv->length; } else { dict->channels = (SIGNAL*) Realloc(dict->channels,lv->length*sizeof(SIGNAL)); dict->nChannelsAlloc = lv->length; } } /* The signalEnergy is the sum of all signal energies */ dict->signalEnergy = 0.0; for(channel=0; channel<lv->length; channel++) { type = GetListvNth(lv,channel,(VALUE *)&signal,&f); /* Basic checkings */ if((type!=signalType && type!=signaliType) || signal==NULL || signal->size<=0 || signal->type!=YSIG) Errorf("AddChannels : listv[%d] should contain a non empty YSIG signal",channel); /* All channels should have the same structure as the first channel */ if(channel>0) { if(signal->size!=dict->signalSize) Errorf("AddChannels : bad size %d for listv[%d]!",signal->size,channel); if(signal->x0!=dict->x0) Errorf("AddChannels : bad size %d for listv[%d]!",signal->x0,channel); if(signal->dx!=dict->dx) Errorf("AddChannels : bad size %d for listv[%d]!",signal->dx,channel); } /* Now we can add a signal */ dict->channels[channel] = NewSignal(); CopySig(signal,dict->channels[channel]); dict->nChannels++; /* Update the signalEnergy */ for(i = 0; i < signal->size; i++) dict->signalEnergy += signal->Y[i]*signal->Y[i]; /* If this is the first channel we should initialize the TFContent */ if(channel==0) { dict->x0 = signal->x0; dict->dx = signal->dx; dict->signalSize = signal->size; } } dict->updateTimeIdMin = 0; dict->updateTimeIdMax = dict->signalSize-1;}/* * Adds to a 'dict' a sub-dictionary that matches the type and parameters. * Id subDictType is unknown, or if the parameters are irrelevant for the type, an error is generated. * * If the sub-dictionary that we want to add already exists, it is simply kept, and is set to 'main' * if necessary. If auxiliary sub-dictionaries are needed, they are added too. * * Nota : if the added sub-dictionary is a MAXIMADICT (i.e. it consists of local maxima * of other sub-dictionaries), it becomes the only 'main' sub-dictionary : * -all previously existing 'main' sub-dictionaries are added to it and converted to 'auxiliary' * -all subsequently added sub-dictionaries are automatically added to the MAXIMADICT sub-dictionary. */extern SUBDICT PrivateAddStftSubDict(DICT dict,unsigned char channel,char flagMain,char type,char windowShape,unsigned long windowSize,LISTV harmoOptions);extern SUBDICT PrivateAddMaximaDictSubDict(DICT dict,unsigned long nMaximaTarget);void AddSubDict(DICT dict,char* subDictType,LISTV parameters){ char type; char windowShape; unsigned long windowSize; char *harmoOptionsType; LISTV harmoOptions; LWFLOAT f; unsigned long nMaximaTarget; SUBDICT subDict; SUBDICT subDictMaxima; MAXIMADICT maximaDict; unsigned char channel; /* Some channel(s) should have been set first */ if(dict->nChannels==0) Errorf("AddSubDict : add channels(s) first!"); /* For a monochannel dictionary we add monochannel sub-dictionaries */ if(dict->nChannels==1) channel=0; /* For a multichannel dictionary we add (joint) multichannel sub-dictionaries */ else channel=dict->nChannels; /* Special case of a sub-dictionary of local maxima */ if(!strcmp(subDictType,maximaDictType)) { if(parameters==NULL||parameters->length!=1) Errorf("AddSubDict : bad parameters for '%s' sub-dictionary",maximaDictType); nMaximaTarget = (unsigned long) GetListvNthFloat(parameters,0); /* If it is already existing there is nothing to do */ if(GetMaximaDictSubDict(dict)) return; PrivateAddMaximaDictSubDict(dict,nMaximaTarget); /* There is nothing more to do ! */ return; } /* Case when such a subDict already exists */ if((subDict=GetSubDict(dict,channel,subDictType,parameters))!=NULL) { /* If 'subDict' was 'auxiliary' 'dict' contains no sub-dict of local maxima we convert 'subDict' to 'main'. */ if((subDictMaxima=GetMaximaDictSubDict(dict))==NULL) subDict->flagMain = YES; /* Else we add it to the sub-dictionary of local maxima, and convert it to 'auxiliary' */ else { maximaDict = (MAXIMADICT)(subDictMaxima->dataContainer); AddSubDict2MaximaDict(maximaDict,subDict);/* This takes care of switching to an 'auxiliary' subDict. */ } return; } /* Case where the sub-dictionary did not exist : we have to create one depending on the type asked for */ /* Case of Stft sub-dictionary */ if(!strcmp(subDictType,stftType)) { if(parameters==NULL||!INRANGE(3,parameters->length,4)) Errorf("AddSubDict : bad parameters for '%s' sub-dictionary",stftType); type = Name2StftType(GetListvNthStr(parameters,0)); windowShape = Name2WindowShape(GetListvNthStr(parameters,1)); windowSize = (unsigned long) GetListvNthFloat(parameters,2); harmoOptions= NULL; if(parameters->length==4) GetListvNth(parameters,3,(VALUE *)&harmoOptions,&f); subDict = PrivateAddStftSubDict(dict,channel,YES,type,windowShape,windowSize,harmoOptions); } else { Errorf("AddSubDict : unknown sub-dictionary type '%s'",subDictType); } /* If there is no sub-dictionary of local maxima, we have nothing more to do. */ if((subDictMaxima=GetMaximaDictSubDict(dict))==NULL) return; /* Else we add the new sub-dict to the sub-dict of local maxima (and convert it to 'auxiliary') */ else { maximaDict = (MAXIMADICT)(subDictMaxima->dataContainer); AddSubDict2MaximaDict(maximaDict,subDict);/* This takes care of switching to an 'auxiliary' subDict. */ return; }}/* * Command to perform the main functions */void C_SetDict(char **argv){ DICT dict; char *action; char *subDictType; LISTV signalList; LISTV parameters; LISTV searchRange,optimizations; MOLECULE molecule; ATOM atom; unsigned char channel; argv = ParseArgv(argv,tWORD,&action,tDICT,&dict,-1); if(!strcmp(action,"channels")) { argv = ParseArgv(argv,tLISTV,&signalList,0); AddChannels(dict,signalList); return; } if(!strcmp(action,"add")) { argv = ParseArgv(argv,tSTR,&subDictType,tLISTV_,NULL,¶meters,0); AddSubDict(dict,subDictType,parameters); return; } if(!strcmp(action,"update")) { NoMoreArgs(argv); UpdateDict(dict); return; } if(!strcmp(action,"getmax")) { argv = ParseArgv(argv,tLISTV_,NULL,&searchRange,0); molecule = GetMaxDict(dict,searchRange); if(molecule==NULL) SetResultValue(nullValue); else SetResultValue(molecule); return; } if(!strcmp(action,"optmol")) { argv = ParseArgv(argv,tMOLECULE,&molecule,tLISTV_,NULL,&optimizations,0); OptimizeMolecule(molecule,dict,optimizations); return; } if(!strcmp(action,"rmmol")) { argv = ParseArgv(argv,tMOLECULE,&molecule,0); RemoveMoleculeFromDict(dict,molecule); return; } Errorf("C_SetDict : unknown action '%s'",action);}/* * The dict fields */static char *dictNChannelsDoc = "{} {Gets the number of channels of a &dict.}";static char *dictNChannelsAllocDoc = "{} {Gets the allocation size for the array of channels of a &dict.}";static char *dictChannelsDoc = "{} {Gets a &listv containing the channels of a &dict.}";static char *dictSignalEnergyDoc = "{} {Gets the energy of the signal of a &dict.}";static char *dictMaximaDoc = "{} {Gets the &maximadict sub-dictionary of a &dict.}";static char *dictStftDoc = "{} {Gets a &listv containing all the &stft sub-dictionaries of a &dict.}";void *GetDictSubDictContainerV(DICT dict,void **arg){ unsigned char channel; SUBDICT subDict; char *field = ARG_G_GetField(arg); LISTV lv; STFT stft; MAXIMADICT maximaDict; unsigned short i; /* Documentation */ if (dict == NULL) { if(!strcmp(field,"channels")) return(dictChannelsDoc); if(!strcmp(field,"signalEnergy")) return(dictSignalEnergyDoc); if(!strcmp(field,"maximadict")) return(dictMaximaDoc); if(!strcmp(field,"stft")) return(dictStftDoc); } if(!strcmp(field,"channels")) { if(dict->channels==NULL) return(GetValueField(nullValue,arg)); lv = TNewListv(); for(channel=0;channel<dict->nChannels;channel++) AppendValue2Listv(lv,(VALUE)GetChannel(dict,channel)); return(GetValueField(lv,arg)); } if(!strcmp(field,"signalEnergy")) { return(GetFloatField(dict->signalEnergy,arg)); } if(!strcmp(field,"maximadict")) { subDict=GetSubDict(dict,dict->nChannels,maximaDictType,NULL); if(subDict==NULL) return(GetValueField(nullValue,arg)); maximaDict=(MAXIMADICT)(subDict->dataContainer); return(GetValueField(maximaDict,arg)); } if(!strcmp(field,"stft")) { lv = TNewListv(); for(i = 0; i < dict->size;i++) { subDict=dict->subDicts[i]; stft=(STFT)(subDict->dataContainer); if(GetTypeValue(stft)!=stftType) continue; AppendValue2Listv(lv,(VALUE)stft); } return(GetValueField(lv,arg)); } return(NULL);}/* * The field list */struct field fieldsDict[] = { "channels",GetDictSubDictContainerV,NULL,NULL,NULL, "signalEnergy",GetDictSubDictContainerV,NULL,NULL,NULL, "maximadict",GetDictSubDictContainerV,NULL,NULL,NULL, "stft",GetDictSubDictContainerV,NULL,NULL,NULL, NULL, NULL, NULL, NULL, NULL};/* * The type structure for DICT */TypeStruct tsDict = { "{{{&dict} {This type is the basic type for time-frequency dictionaries for Matching Pursuit decompositions.}}}", /* Documentation */ &dictType, /* The basic (unique) type name */ NULL, /* The GetType function */ DeleteDict, /* The Delete function */ NewDict, /* The New function */ NULL, /* The copy function */ ClearDict, /* The clear function */ ToStrDict, /* String conversion */ ShortPrintDict, /* The Print function : print the object when 'print' is called */ PrintInfoDict, /* The PrintInfo function : called by 'info' */ NULL, /* The NumExtract function : used to deal with syntax like 10a */ fieldsDict, /* The list of fields */};/************************************************************************//* * This part is specific to MAXIMADICT sub-dictionaries *//************************************************************************//* * Setting/Getting a MAXIMADICT sub-dictionary *//* Get a sub-dictionary that contains Local Maxima. If none exists, return NULL. */SUBDICT GetMaximaDictSubDict(DICT dict){ unsigned short i; SUBDICT subDict; /* Does such a subDict exist ? */ for(i = 0; i < dict->size; i++) { subDict = dict->subDicts[i]; if(GetTypeValue(subDict->dataContainer)!=maximaDictType) continue; return(subDict); } return(NULL);}/* * Adds to a 'dict' a sub-dictionary that will contain (about) 'nTargetMaxima' local maxima * of the other sub-dictionaries. (does NOT check whether it already exists) * WARNING : this is very special, because * -it will contain local maxima associated to the previously existing 'main' sub-dictionaries; * -all previously existing 'main' sub-dictionaries become 'auxiliary; * -all sub-dictionaries that are added subsequently (through AddSubDict) are forced to be 'auxiliary'. */SUBDICT PrivateAddMaximaDictSubDict(DICT dict,unsigned long nMaximaTarget){ unsigned short i; SUBDICT subDict; MAXIMADICT maximaDict; /* * Create a new maximaDict * It will contain local maxima associated to all the previously * existing 'main' sub-dictionaries, which become 'auxiliary' ones. */ maximaDict = NewMaximaDict(); for(i = 0; i < dict->size; i++) { subDict = dict->subDicts[i]; if(subDict->flagMain) AddSubDict2MaximaDict(maximaDict,subDict); } maximaDict->nMaximaTarget = nMaximaTarget; /* Now we can create a new sub-dictionary */ subDict = NewSubDict(); subDict->methods = &MaximaDictMethods; /* It is ALWAYS the (ONLY) main sub-dictionary and MULTICHANNEL */ subDict->flagMain = YES; subDict->channel = dict->nChannels; subDict->dataContainer = (VALUE)maximaDict; /* In the next update of the dictionary, the newly added MAXIMADICT sub-dictionary */ /* will have to be updated, so we need to to reset [updateTimeIdMin updateTimeIdMax] */ dict->updateTimeIdMin = 0; dict->updateTimeIdMax = dict->signalSize-1; return(PrivateAddSubDict(dict,subDict));}//struct subDictMethods WtransMethods;//struct subDictMethods FourierMethods;/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -