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

📄 int_range.c

📁 LastWave
💻 C
字号:
/*..........................................................................*//*                                                                          *//*      L a s t W a v e   K e r n e l   3 . 0                               *//*                                                                          *//*      Copyright (C) 1998-2003 Emmanuel Bacry.                             *//*      email : lastwave@cmap.polytechnique.fr                              *//*                                                                          *//*..........................................................................*//*                                                                          *//*      This program is a free software, you can redistribute it and/or     *//*      modify it under the terms of the GNU General Public License as      *//*      published by the Free Software Foundation; either version 2 of the  *//*      License, or (at your option) any later version                      *//*                                                                          *//*      This program is distributed in the hope that it will be useful,     *//*      but WITHOUT ANY WARRANTY; without even the implied warranty of      *//*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *//*      GNU General Public License for more details.                        *//*                                                                          *//*      You should have received a copy of the GNU General Public License   *//*      along with this program (in a file named COPYRIGHT);                *//*      if not, write to the Free Software Foundation, Inc.,                *//*      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA             *//*                                                                          *//*..........................................................................*//********************************************************* * * RANGE contents * *********************************************************/#include "lastwave.h"#include <stdarg.h>#include "signals.h"#include "images.h"#include "int_fsilist.h"/* Type of a range */char *rangeType = "&range";/* * Answers to the different print messages */ char *ToStrRange(RANGE rg, char flagShort){  static char str[40];    if (rg->step == 1) sprintf(str,"%g:%g",rg->first,RangeVal(rg,rg->size-1));  else sprintf(str,"%g:%g:%g",rg->first,rg->step,RangeVal(rg,rg->size-1));    return(str);}void PrintInfoRange(RANGE rg){  Printf("   first =  %g\n",rg->first);  Printf("   step  =  %g\n",rg->step);  Printf("   last  =  %g\n",RangeVal(rg,rg->size-1));  Printf("   size  =  %d\n",rg->size);}/* * The different extract options  */static char *extractOptionsRange[] = {"*nolimit","*bperiodic","*bmirror","*bmirror1","*bconst","*b0",NULL};enum {  FSIOptRangeNoLimit = FSIOption1,  FSIOptRangeBPer = FSIOption2,  FSIOptRangeBMir = FSIOption3,  FSIOptRangeBMir1 = FSIOption4,  FSIOptRangeBConst = FSIOption5,  FSIOptRangeB0 = FSIOption6};/* * Get and extraction of fields NULL */static char *doc = "{[*opt,...]} {Get range values}"; static void *GetExtractRangeV(VALUE val, void **arg){  RANGE rg;  FSIList *fsiList;  LWFLOAT *pFlt;  char **pStr;  VALUE *pValue;  int max;  FSI_DECL;  BorderType bt;  SIGNAL sig;  RANGE rg1;    /* doc */  if (val == NULL) return(doc);  rg = (RANGE) val;  fsiList = ARG_G_GetFsiList(arg);  pFlt = ARG_G_GetResPFloat(arg);  pStr = ARG_G_GetResPStr(arg);  pValue = ARG_G_GetResPValue(arg);  if (fsiList->options & FSIOptRangeBPer) bt = BorderPer;  else if (fsiList->options & FSIOptRangeBMir) bt = BorderMir;  else if (fsiList->options & FSIOptRangeBMir1) bt = BorderMir1;  else if (fsiList->options & FSIOptRangeBConst) bt = BorderCon;  else if (fsiList->options & FSIOptRangeB0) bt = Border0;  else bt = BorderNone;  /* Get the max size */  max = rg->size;   /*   * Case the result will be a simple LWFLOAT   */   if (fsiList->options & (FSIOptRangeBPer | FSIOptRangeBMir | FSIOptRangeBMir1 | FSIOptRangeBConst | FSIOptRangeB0) && fsiList->nx == 1 ||       !(fsiList->options & (FSIOptRangeBPer | FSIOptRangeBMir | FSIOptRangeBMir1 | FSIOptRangeBConst | FSIOptRangeB0)) && fsiList->nx1 == 1) {     _i = (int) FSIArray((&(fsiList->fsi[0])),0);     /* The loop in the case of *nolimit */    if (fsiList->options & FSIOptRangeNoLimit) {      FSI_FOR_START(fsiList);       if (_i<0 || _i > max-1) continue;      *pFlt = RangeVal(rg,_i);      break;             FSI_FOR_END;    }        /* Other cases */    else {      switch (bt) {      case BorderPer : *pFlt = RangeVal(rg,BPER(_i,max)); break;      case BorderMir : *pFlt = RangeVal(rg,BMIR(_i,max)); break;      case BorderMir1 : *pFlt = RangeVal(rg,BMIR1(_i,max)); break;      case Border0 :         if (_i<0 || _i>=max) *pFlt = 0;        else *pFlt = RangeVal(rg,_i);        break;      case BorderCon : *pFlt = RangeVal(rg,BCONST(_i,max)); break;      default : *pFlt = RangeVal(rg,_i);      }    }        return(numType);  }  /* Case the result will be a range */  if (fsiList->size == 1 && fsiList->fsi[0].type == FSIRange) {    if (!(fsiList->options & (FSIOptRangeNoLimit | FSIOptRangeBPer | FSIOptRangeBMir | FSIOptRangeBMir1 | FSIOptRangeBConst | FSIOptRangeB0)) ||         RangeMin(fsiList->fsi[0].val.r) >= 0 && RangeMax(fsiList->fsi[0].val.r) < rg->size)  {      rg1 = TNewRange();      if (fsiList->fsi[0].val.r->step > 0) {        rg1->first = RangeVal(rg,MAX(0,fsiList->fsi[0].val.r->first));        rg1->size = (int) MIN(fsiList->fsi[0].val.r->size,rg->size-MAX(0,fsiList->fsi[0].val.r->first));        rg1->step = rg->step;      }      else {        rg1->first = RangeVal(rg,MIN(rg->size-1,RangeFirst(fsiList->fsi[0].val.r)));        rg1->size = (int) MIN(fsiList->fsi[0].val.r->size,MIN(rg->size-1,RangeFirst(fsiList->fsi[0].val.r))+1);        rg1->step = -rg->step;      }      *pValue = (VALUE) rg1;      return(rangeType);    }  }        /* Allocation of the result */  sig = TNewSignal();  if (fsiList->options & (FSIOptRangeBPer | FSIOptRangeBMir | FSIOptRangeBMir1 | FSIOptRangeBConst | FSIOptRangeB0)) SizeSignal(sig,fsiList->nx,YSIG);  else SizeSignal(sig,fsiList->nx1,YSIG);  /* The loop in the case of *nolimit */  if (fsiList->options & FSIOptRangeNoLimit) {    FSI_FOR_START(fsiList);     if (_i<0 || _i > max-1) continue;    sig->Y[_k] = RangeVal(rg,_i);    FSI_FOR_END;  }      /* Other cases */  else {    FSI_FOR_START(fsiList);     switch (bt) {    case BorderPer : sig->Y[_k] = RangeVal(rg,BPER(_i,max)); break;    case BorderMir : sig->Y[_k] = RangeVal(rg,BMIR(_i,max)); break;    case BorderMir1 : sig->Y[_k] = RangeVal(rg,BMIR1(_i,max)); break;    case Border0 :       if (_i<0 || _i>=max) sig->Y[_k] = 0;      else sig->Y[_k] = RangeVal(rg,_i);      break;    case BorderCon : sig->Y[_k] = RangeVal(rg,BCONST(_i,max)); break;    default : sig->Y[_k] = RangeVal(rg,_i);    }    FSI_FOR_END;  }               *pValue = (VALUE) sig;          return(signaliType);}/* * Get the options for extraction (called for field NULLonly) */static char *optionDoc = "{{*nolimit,*b0,*bconst,*bmirror,*bmirror1,*bperiodic,*x,*xlin} \{*nolimit : indexes can be out of range} \{*b0 : border effect with 0 value} \{*bconst : border effect with constant values (last range value for right handside and first range value for left handside)} \{*bperiodic : periodic border effect)} \{*bmirror1 : mirror+periodic border effect (first and last points are repeated)} \{*bmirror : mirror+periodic border effect (first and last points are NOT repeated)}\}";static void *GetExtractOptionsRangeV(VALUE val, void **arg){  /* doc */  if (val == NULL) return(optionDoc);  return(extractOptionsRange);}/* * Function to get the ExtractInfo for fields NULL */static void *GetExtractInfoRangeV(VALUE val, void **arg){  static ExtractInfo extractInfo;  static char flagInit = YES;      RANGE rg = (RANGE) val;  char *field = ARG_EI_GetField(arg);  unsigned long *options = ARG_EI_GetPOptions(arg);  /* If *bperiodic,... then *nolimit must be off */  if (*options & (FSIOptRangeBPer | FSIOptRangeBMir | FSIOptRangeBMir1 | FSIOptRangeB0 | FSIOptRangeBConst)) *options &= ~FSIOptRangeNoLimit;         /* Init of the extraction info */  if (flagInit) {    extractInfo.xmin = 0;    extractInfo.dx = 1;    extractInfo.nSignals = 1;    flagInit = NO;  }  if (rg->size == 0) {    SetErrorf("No extraction on empty range");    return(NULL);  }    extractInfo.xmax = rg->size-1;  /* '*nolimit' option : set some flags */  if (*options & (FSIOptRangeBPer | FSIOptRangeBMir | FSIOptRangeBMir1 | FSIOptRangeB0 | FSIOptRangeBConst | FSIOptRangeNoLimit)) extractInfo.flags = EIIntIndex;  else extractInfo.flags = EIErrorBound | EIIntIndex;       return(&extractInfo);} /* * 'size' field */static char *sizeDoc = "{[= <size>]} {Sets/Gets the size of a range}";static void * GetSizeRangeV(VALUE val, void **arg){  /* Documentation */  if (val == NULL) return(sizeDoc);    return(GetIntField(((RANGE) val)->size,arg));}static void * SetSizeRangeV(VALUE val, void **arg){  /* doc */  if (val == NULL) return(sizeDoc); return(SetIntField(&(((RANGE) val)->size),arg,FieldSPositive));}/* * 'first' field */static char *firstDoc = "{[= <first>]} {Sets/Gets the first value of a range}";static void * GetFirstRangeV(VALUE val, void **arg){  /* Documentation */  if (val == NULL) return(firstDoc);    return(GetFloatField(((RANGE) val)->first,arg));}static void * SetFirstRangeV(VALUE val, void **arg){  /* doc */  if (val == NULL) return(firstDoc); return(SetFloatField(&(((RANGE) val)->first),arg,0));}/* * 'last' field */static char *lastDoc = "{[= <last>]} {Sets/Gets the last value of a range}";static void * GetLastRangeV(VALUE val, void **arg){  /* Documentation */  if (val == NULL) return(lastDoc);    return(GetFloatField(RangeLast((RANGE) val),arg));}static void * SetLastRangeV(VALUE val, void **arg){ RANGE rg; LWFLOAT last;    /* doc */  if (val == NULL) return(lastDoc); rg = ((RANGE) val); last = RangeLast(rg); if (SetFloatField(&last,arg,0) == NULL) return(NULL);  rg->first = last-rg->step*(rg->size-1);}/* * 'step' field */static char *stepDoc = "{[= <step>]} {Sets/Gets the step of a range}";static void * GetStepRangeV(VALUE val, void **arg){  /* Documentation */  if (val == NULL) return(stepDoc);    return(GetFloatField(((RANGE) val)->step,arg));}static void * SetStepRangeV(VALUE val, void **arg){  /* doc */  if (val == NULL) return(stepDoc); return(SetFloatField(&(((RANGE) val)->step),arg,FieldSPositive));}        /* Allocate a new range */RANGE NewRange(void){  RANGE r;  #ifdef DEBUGALLOCDebugType = "Range";#endif  r = Malloc(sizeof(struct rangeValue));  InitValue(r,&tsRange);    r->step = 1;  r->first = 0;  r->size = 1;    return(r);}RANGE TNewRange(void){  RANGE r;    r = NewRange();    TempValue(r);    return(r);}void DeleteRange(RANGE r){  r->nRef--;  if (r->nRef >0) return;  #ifdef DEBUGALLOCDebugType = "Range";#endif Free(r);  }/* * The field list */struct field fieldsRange[] = {  "", GetExtractRangeV, NULL, GetExtractOptionsRangeV, GetExtractInfoRangeV,  "size", GetSizeRangeV, SetSizeRangeV, NULL, NULL,  "first", GetFirstRangeV, SetFirstRangeV, NULL, NULL,  "step", GetStepRangeV, SetStepRangeV, NULL, NULL,  "last", GetLastRangeV, SetLastRangeV, NULL, NULL,  NULL, NULL, NULL, NULL, NULL};/* * The type structure for Range */TypeStruct tsRange = {  "{{{&range} {This type corresponds to ranges. \n \- Constructors : syntax is first:step:last or first:#size:last. \One can use first!:... to except the first point or ...:!last to except the last one. \If implicit the first, last, size or step can be ommitted. \Moreover @> (resp. @< or @+) refers to the 'implicit' last (resp. first or step) point. \n \- Most of the operators valid for signals are valid for ranges.}}}",  /* Documentation */  &rangeType,       /* The basic (unique) type name */  NULL,    DeleteRange,     /* The Delete function */  NewRange,     /* The New function */    NULL,       /* The copy function */  NULL,       /* The clear function */    ToStrRange,       /* String conversion */  NULL,   /* The Print function : print the object when 'print' is called */  PrintInfoRange,   /* The PrintInfo function : called by 'info' */  NULL,              /* The NumExtract function : used to deal with syntax like 10a */     fieldsRange,      /* The list of fields */};

⌨️ 快捷键说明

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