⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp_dict.c

📁 LastWave
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Change the dx of a dictionary : change dx for dict->channels as well as all sub-dictionaries. */void SetDictDX(DICT dict,LWFLOAT dx){  unsigned char channel;  SIGNAL signal;  unsigned short i;  SUBDICT subDict;  STFT stft;  MAXIMADICT maximaDict;  //WTRANS wtrans;  if(dict == NULL)         Errorf("SetDictDX : NULL dict");  if(dict->channels==NULL) Errorf("SetDictDX : NULL dict->channels");  if (dx <= 0)             Errorf("SetDictDX : dx %g <= 0\n",dx);    /* First, the dx of all channels */  for(channel=0;channel<dict->nChannels;channel++) {    signal = GetChannel(dict,channel);    signal->dx = dx;  }  /* Then, that of the sub-dictionaries */  for(i = 0; i < dict->size; i++) {    subDict = dict->subDicts[i];    /* Case of STFT subDicts */    if(GetTypeValue(subDict->dataContainer)==stftType) {      stft=(STFT)(subDict->dataContainer);      stft->dx = dx;      continue;    }     /* Case of MAXIMADICT subDicts */    if(GetTypeValue(subDict->dataContainer)==maximaDictType) {      maximaDict=(MAXIMADICT)subDict->dataContainer;      Errorf("SetMaximaDictDX not implemented");      //SetMaximaDictDX(maximaDict,dx); TODO !      continue;    }    Errorf("SetDictDX : (Weired)");  }}/* Change the dx of a dictionary : change x0 for dict->channels as well as all sub-dictionaries. */void SetDictX0(DICT dict,LWFLOAT x0){  unsigned char channel;  SIGNAL signal;  unsigned short i;  SUBDICT subDict;  STFT stft;  MAXIMADICT maximaDict;  //WTRANS wtrans;    /* Checking arguments */  if(dict == NULL)         Errorf("SetDictX0 : NULL dict");  if(dict->channels==NULL) Errorf("SetDictX0 : NULL dict->channels");  /* First, the x0 of all channels */  for(channel=0;channel<dict->nChannels;channel++) {    signal = GetChannel(dict,channel);    signal->x0 = x0;  }  /* Then, that of the sub-dictionaries */  for(i = 0; i < dict->size; i++) {    subDict = dict->subDicts[i];    /* Case of STFT subDicts */    if(GetTypeValue(subDict->dataContainer)==stftType) {      stft=(STFT)(subDict->dataContainer);      stft->x0 = x0;      continue;    }     /* Case of MAXIMADICT subDicts */    if(GetTypeValue(subDict->dataContainer)==maximaDictType) {      maximaDict=(MAXIMADICT)subDict->dataContainer;      Errorf("SetMaximaDictX0 not implemented");      //SetMaximaDictX0(maximaDict,x0); TODO!      continue;    }    Errorf("SetDictX0 : (Weired)");  }}/*************************************************//* *	The main functionalities of a dictionary */				    /*************************************************//* * Update all the 'main' sub-dictionaries, and the necessary 'aux' sub-dictionaries, * using the 'removedMolecule' if necessary, and resets [updateTimeIdMin,updateTimeIdMax]. * The state of the dictionary after a call to this function is as follows : * 0/ removedMolecule = NULL. * 1/if there is no sub-dictionary of local maxima : all sub-dictionaries are up to date * and [updaTimeIdMin,updateTimeIdMax] = [dict->channels[0]->size-1,0]  * (when a molecule is removed from the dictionary, updateTimeIdMin/Max decreases/increases) * 2/if there is a sub-dictionary of local maxima  : this sub-dictionary is up to date, * and the state of [updaTimeIdMin,updateTimeIdMax] depends on whether the update of the  * sub-dictionary of local maxima involved an 'initialization' or not. */void UpdateDict(DICT dict) {  unsigned short i;  SUBDICT subDict;  /* If already up to date, do nothing */  if(dict->updateTimeIdMin > dict->updateTimeIdMax) return;    /* When there is a sub-dictionary of local maxima */  if(subDict=GetMaximaDictSubDict(dict)) {    /* This takes care of the proper management of [updateTimeIdMin,updateTimeIdMax] */    UpdateSubDict(subDict);  }  /* When there is no sub-dictionary of local maxima */  else {    for(i = 0; i < dict->size; i++) {      subDict = dict->subDicts[i];      /* Display a clock for waiting */      switch(i%4) {//      case 0 : Printf("\\"); Flush(); break;//      case 1 : Printf("|"); Flush(); break;//      case 2 : Printf("/"); Flush(); break;//      case 3 : Printf("-"); Flush(); break;      }      UpdateSubDict(subDict);//      Printf("\b");    }    dict->updateTimeIdMin = dict->channels[0]->size-1;    dict->updateTimeIdMax = 0;  }  /* Deletes the removedMolecule if exists */  if(dict->removedMolecule) dict->removedMolecule = DeleteMolecule(dict->removedMolecule);}/* * Returns a MOLECULE corresponding to the maximum of a DICT over a search range. * If the specified search range is empty or the  maximum value is zero, we return NULL. * The returned MOLECULE is not optimized (interpolate,chirped,...). * The maximum is looked for only in 'main' sub-dictionaries, which should be up to date * (else an error is generated). * An error is also generated if [updateTimeIdMin,updateTimeIdMax] is not empty in the case * when there is no sub-dictionary of local maxima. */MOLECULE GetMaxDict(DICT dict,LISTV searchRange) {  unsigned short i;  SUBDICT subDict,subDictMax=NULL;  static LISTV tmpParamMax = NULL;  LISTV paramMax = NULL;  char  maxFound = NO;  LWFLOAT tmpMaxValue = 0.0,maxValue = 0.0;  MOLECULE molecule = NULL;  MAXIMADICT maximaDict;  /* Allocate (once only) the list of parameters that will be used     */  /* to locate quickly the &mol after the first exhaustive search */  if(tmpParamMax == NULL)     tmpParamMax = NewListv();  else                        ClearListv(tmpParamMax);  /* First, locate the subdict that contains the maximum. */  if((subDictMax=GetMaximaDictSubDict(dict))!=NULL) {    /*      * If there is a sub-dictionary of local maxima, this is the only sub-dictionary where to look.     * and there is a maximum as soon as it is not empty      */    maximaDict = (MAXIMADICT)(subDictMax->dataContainer);    if(maximaDict->nMaxima>0) {      maxFound = YES;    }  } else {    /*     * Check that[updateTimeIdMin,updateTimeIdMax] is empty     * (an individual check of each sub-dictionary being up to date will be done during the search for the max)     */    if(dict->updateTimeIdMin <= dict->updateTimeIdMax)       Errorf("GetMaxDict : dict should be updated first in [%d %d]",dict->updateTimeIdMin,dict->updateTimeIdMax);    for(i = 0; i < dict->size; i++) {      subDict = dict->subDicts[i];      /* Skip auxiliary subDicts */      if(subDict->flagMain==NO) continue;      /* If the search range is empty for the subDict, we skip to the next subDict */      if(GetMaxSubDict(subDict,searchRange,&tmpMaxValue,tmpParamMax)==NO) continue;      /* The search range was non empty, hence we can compare the local maximum to the best we have so far */      if(maxFound == NO || tmpMaxValue > maxValue) {	maxValue = tmpMaxValue;	paramMax = TNewListv();	CopyListv(tmpParamMax,paramMax);	subDictMax = subDict;      }      maxFound = YES;    }  }   /* If no maximum has been found (i.e. the search range was empty or the max was zero) we return NULL */  if(maxFound == NO) return(NULL);  /* Now we have to fill the maximum variable */  molecule = TNewMolecule();  GetMaxSubDict(subDictMax,paramMax,NULL,molecule);  return(molecule);}// TODO : clean this upvoid AddShiftedSignals(SIGNAL input,SIGNAL output,long shift){  long iOut,iOutMin,iOutMax;    /* Some Tests */  if (output == input)   Errorf("AddShiftedSignals : you must have output != input\n");  if (output->size == 0) Errorf("AddShiftedSignals : output should not be empty\n");    iOutMin = MAX(shift,0);  iOutMax = MIN(output->size,shift+input->size);    for (iOut = iOutMin; iOut < iOutMax; iOut++)    output->Y[iOut] += input->Y[iOut-shift];}static void SubstractShiftedSignals(SIGNAL input,SIGNAL output,long shift){  long iOut,iOutMin,iOutMax;  /* Some Tests */  if (output == input)   Errorf("SubstractShiftedSignals : you must have output != input\n");  if (output->size == 0) Errorf("SubstractShiftedSignals : output should not be empty\n");  iOutMin = MAX(shift,0);  iOutMax = MIN(output->size,shift+input->size);    for (iOut = iOutMin; iOut < iOutMax; iOut++)    output->Y[iOut] -= input->Y[iOut-shift];}/* * Builds an atom and removes it from a given channel of a dictionary. * The [updateTimeIdMin,updateTimeIdMax] of the dict is enlarged if necessary. * All sub-dictionaries are marked as out of date. */static void RemoveAtomFromDictChannel(DICT dict,unsigned char channel,ATOM atom) {  static ATOM copy = NULL;  static SIGNAL atomSignal = NULL;  // These are signed integers for they may be negative  // TODO : change to unsigned ?  int atomTimeIdMin,atomTimeIdMax;  LWFLOAT shift;  // TODO : What borderType do we really want ? Shall we store it in dict ?  char borderType = BorderPad0;  LWFLOAT real1,imag1,real2,imag2;  /* Checking arguments */  CheckDictNotEmpty(dict);  CheckAtom(atom);  /* Allocating (just once) */  if(atomSignal == NULL) atomSignal = NewSignal();    // DEBUG : COMPRENDRE POURQUOI CA ARRIVE  copy = CopyAtom(atom,copy);  SCAtomInnerProduct(GetChannel(dict,channel),copy,borderType,&(copy->coeffR),&(copy->coeffI));  CastAtomReal(copy);  if(fabsf((atom->coeffR-copy->coeffR)/atom->coeffR)>1e-5 || fabsf((atom->coeffI-copy->coeffI)/atom->coeffI)>1e-5) {    //    Printf("FreqId %g Phase %g %g\n",atom->freqId,atom->cosPhase,atom->sinPhase);    //    Printf("Given (%g,%g) (%g,%g,%g) [%g,%g]\n",atom->coeffR,atom->coeffI,atom->coeff2,atom->cosPhase,atom->sinPhase,atom->realGG,atom->imagGG);    //    Printf("Computed (%g,%g) (%g,%g,%g) [%g,%g]\n",copy->coeffR,copy->coeffI,copy->coeff2,copy->cosPhase,copy->sinPhase,copy->realGG,copy->imagGG);  }  /* Build a real valued atom  */  BuildAtom(atom,atomSignal,NULL,borderType,YES);  /* Substract it to the dict->signal */  // TODO : check the shift is integer! and clean this up anyway  shift = (atomSignal->x0-atom->x0)/atom->dx;  if (shift < 0) shift = (int) (shift-.5);  else shift = (int) (shift+.5);  SubstractShiftedSignals(atomSignal,GetChannel(dict,channel),(long) shift);      /* Compute the limits where the signal has changed */  ComputeWindowSupport(atom->windowSize,atom->windowShape,atom->timeId,&atomTimeIdMin,&atomTimeIdMax);  dict->updateTimeIdMin = MIN(dict->updateTimeIdMin,atomTimeIdMin);  dict->updateTimeIdMax = MAX(dict->updateTimeIdMax,atomTimeIdMax);  // TODO : treat other border effects (pass it as an argument to the function ?)  // TODO : clean this up !!!  switch(borderType) {  case BorderPad0 :    if(atomTimeIdMin < 0 || dict->updateTimeIdMax >= dict->signalSize)      Errorf("RemoveAtomFromDictChannels : signal updated out of its limits!");    break;  default :    Errorf("RemoveAtomFromDictChannels : border type '%s' not treated yet",BorderType2Name(borderType));  }}/* * Builds a molecule and removes it from the signal of a dictionary. * The signalEnergy is updated. An error is generated if it does not decrease. * The [updateTimeIdMin,updateTimeIdMax] of the dict is enlarged if necessary. * All sub-dictionaries are marked as out of date. * The molecule is memorized in the dict->removedMolecule field for possible * use at the next UpdateDict step. * If a molecule has already been memorized, an error is generated. */void RemoveMoleculeFromDict(DICT dict,MOLECULE molecule) {  unsigned char channel;  unsigned short k;  SIGNAL signal;  ATOM atom;  unsigned long i;  LWFLOAT prevSigEnergy;  SUBDICT subDict;  // TODO : remove that when possible  STFT stft;  /* No other molecule should have been memorized */  if(dict->removedMolecule) Errorf("RemoveMoleculeFromDict : a molecule has already been removed");    for(channel = 0; channel < molecule->nChannels; channel++) {    for(k = 0; k < molecule->dim; k++) {      atom = GetMoleculeAtom(molecule,channel,k);      RemoveAtomFromDictChannel(dict,channel,atom);    }  }  /* Sub-dictionaries of the dict are now out of date */  for(i = 0; i < dict->size; i++) {    subDict = dict->subDicts[i];    subDict->flagUpToDate = NO;    // TODO : remove that when possible    if(GetTypeValue(subDict->dataContainer)==stftType) {      stft=(STFT)(subDict->dataContainer);      stft->flagUpToDate=NO;    }  }  /* Update the signalEnergy */  // TODO fast update using [updateTimeIdMin updateTimeIdMax] ???  prevSigEnergy = dict->signalEnergy;  dict->signalEnergy = 0.0;  for(channel=0; channel<dict->nChannels;channel++) {    signal = GetChannel(dict,channel);    for(i = 0; i < dict->signalSize; i++)      dict->signalEnergy += signal->Y[i]*signal->Y[i];  }  /* The energy should strictly decrease */  // TODO : remove when we are confident enough this will never happen  if(isnan(dict->signalEnergy) || prevSigEnergy<dict->signalEnergy) {    PrintInfoValue(molecule);    Errorf("RemoveMoleculeFromDict : (WEIRED) increases the signalEnergy from %g to %g",prevSigEnergy,dict->signalEnergy);  }   /* Memorize the molecule */  dict->removedMolecule = molecule;  AddRefValue(molecule);  }/* * If dict->channels is already set or the new signal(s) have inconsistent size/dx/x0, an error is generated * The [updateTimeIdMin,updateTimeIdMax] is set to [0,dict->signalSize-1] * The signalEnergy is initialized.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -