📄 signal_alloc.c
字号:
* * Very important procedure which has to be called each time one wants to use a signal. * It manages allocation. * It asks the signal 'signal' to be able to store a signal of type 'type' * and size 'size'. * * In any case it initializes all the fields except dx and x0 * */void SizeSignal(SIGNAL signal,int size,int type){ if (size < 0) Errorf("SizeSignal() : asked size is negative '%d'",size); signal->type = type; if (size == 0) { signal->lastp = signal->firstp = signal->size = 0; signal->param = 1; return; } switch(type) { case YSIG: if (signal->sizeMallocX != 0) { Free(signal->X); signal->X = NULL; signal->sizeMallocX = 0; } if (signal->sizeMallocY < size) { if (signal->sizeMallocY != 0) Free(signal->Y); signal->Y = NULL; signal->sizeMallocY = 0; signal->size = 0; signal->Y = FloatAlloc(size); signal->sizeMallocY = size; } break; case XYSIG: if (signal->sizeMallocX < size) { if (signal->sizeMallocX != 0) Free(signal->X); signal->X = NULL; signal->sizeMallocX = 0; signal->X = FloatAlloc(size); signal->sizeMallocX = size; } if (signal->sizeMallocY < size) { if (signal->sizeMallocY != 0) Free(signal->Y); signal->Y = NULL; signal->sizeMallocY = 0; signal->size = 0; signal->Y = FloatAlloc(size); signal->sizeMallocY = size; } break; default: Errorf("SizeSignal() : Bad Signal type"); } signal->lastp = size-1; signal->firstp = 0; signal->size = size; signal->param = 1;}/* * Function for Deleting a signal */void DeleteSignal(SIGNAL signal){ if (signal) { if (signal->nRef==0) { Warningf("DeleteSignal() : Trying to delete a temporary signal\n"); return; } RemoveRefValue(signal); if (signal->nRef > 0) return; if (signal->X) Free(signal->X); if (signal->Y) Free(signal->Y); if (signal->name != defaultName) Free(signal->name); if (flagOn) Printf("** Delete Signal %p\n",signal); #ifdef DEBUGALLOCDebugType = "Signal";#endif Free(signal); };}/***************************************************************************** * * Functions to access index, Y or X values of signals * *****************************************************************************//* * Dichotomic recursive algorithm to find an x value within a signal * (used only in the case of an XYSIG signal *//* Only called by the DichX routine */static int DichX_(SIGNAL signal,LWFLOAT x,int iMin,int iMax){ int i; if (iMin == iMax) return(iMin); if (iMax-iMin == 1) { if (signal->X[iMax] == x) return(iMax); return(iMin); } i = (iMax+iMin)/2; if (signal->X[i] > x) return(DichX_(signal,x,iMin,i)); return(DichX_(signal,x,i,iMax)); } /* * Get the index associated to a x-value within a signal * (Only for XYSIG signal) * returns -1 if x is too low */ static int DichX(SIGNAL signal,LWFLOAT x){ if (signal->size == 0) Errorf("DichX() : signal is empty"); if (signal->X[0] > x) return(-1); if (signal->size == 1) return(0); if (signal->X[1] > x) return(0); if (signal->size == 2) return(1); if (signal->X[signal->size-1] <= x) return(signal->size-1); return(DichX_(signal,x,0,signal->size-1));}/* * The main routine that can be called from outside to get an index * associated to an x value ('xValue') whatever the type of the signal is. * This routines behaves differently depending on the type of signal : * - YSIG : the index is a LWFLOAT number that can be out of range and that * is computed only using the dx and x0 fields of the signal * - XYSIG : the index is an integer that can be out of range (-1) * it is the index i such that x[i] <= xvalue < x[i+1] */ LWFLOAT X2FIndexSig(SIGNAL signal, LWFLOAT xValue){ if (signal->type == XYSIG) return(DichX(signal,xValue)); return((xValue-signal->x0)/signal->dx);}/* * The main routine that returns a Y value given an x value * given an interpolation mode and a border type. * If flagindex is YES then x corresponds to a LWFLOAT index * otherwise, it is an x-value */LWFLOAT X2YSig(SIGNAL signal,LWFLOAT x, InterMode im, BorderType bt, char flagIndex){ int i; LWFLOAT index; if (flagIndex) index = x; else index = X2FIndexSig(signal,x); /* * We first deal with the border type */ switch (signal->type) { /* case of a YSignal */ case YSIG : /* Manage border effects */ switch (bt) { case BorderNone : break; case BorderPer : index = fmod(index,signal->size); if (index < 0) index+=signal->size; break; case BorderMir1 : index = fmod(index,2*signal->size); if (index < 0) index+=2*signal->size; if (index>=signal->size) index = 2*signal->size-1-index; break; case BorderMir : index = fmod(index,2*signal->size-2); if (index < 0) index+=2*signal->size-2; if (index>=signal->size) index = 2*signal->size-2-index; break; case BorderCon : if (index < 0) return(signal->Y[0]); if (index>=signal->size) return(signal->Y[signal->size-1]); break; case Border0 : if (index < 0 || index>=signal->size) return(0); break; default : Errorf("X2YSig() : Weird"); } break; /* case of a XYSignal */ case XYSIG : /* Manage border effects */ switch (bt) { case BorderNone : break; case BorderCon : if (index < 0) return(signal->Y[0]); if (index>=signal->size) return(signal->Y[signal->size-1]); break; case Border0 : if (index < 0 || index>=signal->size) return(0); break; default : Errorf("X2YSig() : Only 'BorderNone', 'Border0' or 'BorderCon' are available for XY signals"); } break; } /* * Then the Y value */ i = (int) floor(index); if (i <0 || i > signal->size-1) Errorf("X2YSig() : Weird 1"); switch(im) { case InterNone : return(signal->Y[i]); case InterLinear : if (i == signal->size-1) return(signal->Y[i]); if (i+1> signal->size-1) Errorf("X2YSig() : Weird 2"); switch (signal->type) { case YSIG : return((signal->Y[i+1]-signal->Y[i])*(index-i)+signal->Y[i]); case XYSIG : if (signal->X[i+1]==signal->X[i]) return(signal->Y[i]); return((signal->Y[i+1]-signal->Y[i])*(x-signal->X[i])/(signal->X[i+1]-signal->X[i])+signal->Y[i]); } default : Errorf("YSig1() : Weird 2"); }}/* Returns the index corresponding to an xValue (always in range [0,signal->size-1]) */int ISig(SIGNAL signal, LWFLOAT xValue){ int i; if (signal->type == XYSIG) return(DichX(signal,xValue)); i = (int) ((xValue-signal->x0)/signal->dx); if (i < 0) i = 0; else if (i >= signal->size) i = signal->size-1; return(i);}/* Return the xValue to an index */LWFLOAT XSig(SIGNAL signal,int index){ if (signal->type == XYSIG) return(signal->X[index]); else return(signal->x0+signal->dx*index);}/* Return either the x or the y value corresponding to an index */LWFLOAT XYSig(SIGNAL signal,int index,char which){ switch(which) { case 'Y': return(signal->Y[index]); break; case 'X': return(XSig(signal,index)); break; default: Errorf("Bad value of 'which' in 'XYSig' function"); }} /******************************** * * Copy procedures * ********************************/ /* Copy the signal in in the signal out */void CopyFieldsSig(SIGNAL in,SIGNAL out){ out->firstp = in->firstp; out->lastp = in->lastp; out->type = in->type; out->size = in->size; out->dx = in->dx; out->x0 = in->x0; out->param = in->param;}SIGNAL CopySig(SIGNAL in, SIGNAL out){ if (in == out) return(out); if (out == NULL) out = NewSignal(); SizeSignal(out,in->size,in->type); CopyFieldsSig(in,out); memcpy(out->Y,in->Y,in->size*sizeof(LWFLOAT)); if (in->type == XYSIG) memcpy(out->X,in->X,in->size*sizeof(LWFLOAT)); return(out);}void CopySigXX(SIGNAL in,SIGNAL out,char *type){ int i; if (out == in) Errorf("CopySigXX() : The two signals must be different"); if (!strcmp(type,"YY")) { SizeSignal(out,in->size,YSIG); memcpy(out->Y,in->Y,sizeof(LWFLOAT)*in->size); } else if (!strcmp(type,"XY")) { SizeSignal(out,in->size,YSIG); if (in->type == XYSIG) memcpy(out->Y,in->X,sizeof(LWFLOAT)*in->size); else for(i=0;i<in->size;i++) out->Y[i] = XSig(in,i); } else if (!strcmp(type,"YX")) { SizeSignal(out,in->size,XYSIG); memcpy(out->X,in->Y,sizeof(LWFLOAT)*in->size); } else if (!strcmp(type,"XX")) { SizeSignal(out,in->size,XYSIG); if (in->type == XYSIG) memcpy(out->X,in->X,sizeof(LWFLOAT)*in->size); else for(i=0;i<in->size;i++) out->X[i] = XSig(in,i); } else Errorf("CopySigXX() : Bad type '%s'",type);}/*********************************************************************************** * * Parsing a signal * ***********************************************************************************//* * Parse an output Signal */char ParseSignalLevel_(LEVEL level, char *arg, SIGNAL defVal, SIGNAL *sig){ char *type; LWFLOAT f; type = TTEvalExpressionLevel_(level,arg,&f,(VALUE *) sig,SignalType,NO,NO,AnyType,YES); if (type == NULL) { *sig = defVal; if (defVal != NULL) (*sig)->nRef++; return(NO); } return(YES);}char ParseSignal_(char *arg, SIGNAL defVal, SIGNAL *sig){ return(ParseSignalLevel_(levelCur,arg,defVal,sig));}void ParseSignalLevel(LEVEL level,char *arg, SIGNAL *sig){ if (ParseSignalLevel_(level,arg,NULL,sig) == NO) Errorf1("");}void ParseSignal(char *arg, SIGNAL *sig){ ParseSignalLevel(levelCur,arg,sig);}/* * Parse an input Signal */char ParseSignalILevel_(LEVEL level, char *arg, SIGNAL defVal, SIGNAL *sig){ char *type; LWFLOAT f; type = TTEvalExpressionLevel_(level,arg,&f,(VALUE *) sig,SignalType,NO,NO,AnyType,NO); if (type == NULL || (*sig)->size == 0) { *sig = defVal; if (defVal != NULL) { if (defVal->size == 0) Errorf("ParseSignalILevel_() : default signal is empty"); (*sig)->nRef++; } return(NO); } return(YES);}char ParseSignalI_(char *arg, SIGNAL defVal, SIGNAL *sig){ return(ParseSignalILevel_(levelCur,arg,defVal,sig));}void ParseSignalILevel(LEVEL level, char *arg, SIGNAL *sig){ if (ParseSignalILevel_(level,arg,NULL,sig) == NO) Errorf1("");}void ParseSignalI(char *arg, SIGNAL *sig){ ParseSignalILevel(levelCur,arg,sig);}/* * The field list */struct field fieldsSignal[] = { "", GetExtractSignalV, SetExtractSignalV, GetExtractOptionsSignalV, GetExtractInfoSignalV, "X", GetExtractSignalV, SetExtractSignalV, GetExtractOptionsSignalV, GetExtractInfoSignalV, "Y", GetExtractSignalV, SetExtractSignalV, GetExtractOptionsSignalV, GetExtractInfoSignalV, "index", GetExtractSignalV, NULL, GetExtractOptionsSignalV, GetExtractInfoSignalV, "size", GetSizeSignalV, SetSizeSignalV, NULL, NULL, "dx", GetDxSignalV, SetDxSignalV, NULL, NULL, "x0", GetX0SignalV, SetX0SignalV, NULL, NULL, "name", GetNameSignalV, SetNameSignalV, NULL, NULL, "xy", GetXYSignalV, SetXYSignalV, NULL, NULL, "sizeAllocX", GetSizeAllocXSignalV, SetSizeAllocXSignalV, NULL, NULL, "sizeAllocY", GetSizeAllocYSignalV, SetSizeAllocYSignalV, NULL, NULL, "firstp", GetFirstpSignalV, SetFirstpSignalV, NULL, NULL, "lastp", GetLastpSignalV, SetLastpSignalV, NULL, NULL, "tolistv", GetTolistvSignalV, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};/* * The type structure for SIGNAL */TypeStruct tsSignal = { "{{{&signal} {This type is the basic type for signals. Uniformly sampled signals (i.e., Y-signals) \can be built using the <value1,...,valueN> syntax. The values can be either a LWFLOAT, a signal, a range or a listv of floats, \signals and ranges. The different operators are \n \- +,-,*,/ (and +=,-=,*=,/=) : regular operators \n \- ==,!=,<=,>=,<,> : regular tests \n \- x^f (and ^=) : each value of |x| is taken to the popwer f \n \- x*^n : each value of x to the power n where n is a positive integer \n\- ~ : transposition operator (returns a single columnimage) \n\- //,% : integer division and remainder \n \- is,isnot : test if 2 signals correspond or not to the same C object \n \- sinh,sin,cosh,cos,tanh,tan,acos,asin,atan : trigonometric operators \n \- min,max : if 1 argument, returns the min or max value of a signal, if 2 arguments returns \the signal made of the min/max of each value. \n\- log2,log,ln,sqrt,abs,exp,ceil,floor,round,frac,int : other math functions \n \- der,prim : derivative and primitive of a signal \n \- sum : computes the sum of all signal values \n \- mean : same as sum but divides by the total number of points\n \- any : returns 1 if at least one of the values is different from 0\n \- all : returns 1 if all of the values are different from 0\n \- find : returns a signal made of indices which correspond to non 0 values \n\- YSIG Constructors : <...>,Zero,One,I,Grand,Urand \n \- XYSIG Constructors : XY(xsignal,ysignal). In the ysig expression you can use the 'X' notation which refers to xsig.}} \{{&signali} {This type corresponds to non empty signals.}}}", /* Documentation */ &signalType, /* The basic (unique) type name */ GetTypeSignal, /* The GetType function */ DeleteSignal, /* The Delete function */ NewSignal, /* The New function */ CopySig, /* The copy function */ ClearSignal, /* The clear function */ ToStrSignal, /* String conversion */ PrintSignal, /* The Print function : print the object when 'print' is called */ PrintInfoSignal, /* The PrintInfo function : called by 'info' */ NULL, /* The NumExtract function : used to deal with syntax like 10a */ fieldsSignal, /* The list of fields */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -