double GetCurrentExtInputValue( IData *GS, double t, int idx ) {
  int i, curidx = 0;


  /* If there is only one time point for the external input, then return its 
     associated value iff t is that exact time. */
  if( GS->gExtInputLens[idx] == 1 && GS->gExtInputTimes[idx][0] == t ) {
    return GS->gExtInputVals[idx][0];
  }
  
  /* Forward integration case */
  if( GS->direction > 0 ) {
    /* If the given time is outside the valid time domain for the external input,
       return 0.0 */
    if( t < GS->gExtInputTimes[idx][0] || t > GS->gExtInputTimes[idx][GS->gExtInputLens[idx]-1] ) {
      return 0.0;
    }
    
    curidx = FindCurrentExtInputIndex(GS, t, idx); 
/*     //    for( i = 0; i < GS->gExtInputLens[idx]; i++ ) { */
/*     //  if( GS->gExtInputTimes[idx][i]  >= t ) { */
/*     //	curidx = i - 1; */
/*     //	break; */
/*     // } */
/*     //} */
  }
  /* Backwards case */
  else if( GS->direction < 0 ) {
    /* If the given time is outside the valid time domain for the external input,
       return 0.0 */
    if( t > GS->gExtInputTimes[idx][0] || t < GS->gExtInputTimes[idx][GS->gExtInputLens[idx]-1] ) {
      return 0.0;
    }

    curidx = FindCurrentExtInputIndex(GS, t, idx); 
/*     //    for( i = 0; i < GS->gExtInputLens[idx]; i++ ) { */
/*     //  if( GS->gExtInputTimes[idx][i]  <= t ) { */
/*     //	curidx = i - 1; */
/*     //	break; */
/*     // } */
/*     //} */
  }
  /* If direction not set, return 0.0 */
  else
    return 0.0;

  /* Record the current index */
  GS->gCurrentExtInputIndex[idx] = curidx;

  /* If we are right on t for which ext input value exists */
  if( GS->gExtInputTimes[idx][curidx+1] == t ) {
    return GS->gExtInputVals[idx][curidx+1];
  }
  /* Since we assume the time, value arrays are oriented correctly for the given direction,
     the interpolation proceeds identically in both cases. */
  else {
    double temp = t - GS->gExtInputTimes[idx][curidx];
    /* Linear interpolation. We assume each time in gExtInputTimes is distinct */
    return (GS->gExtInputVals[idx][curidx+1] - GS->gExtInputVals[idx][curidx]) / 
      (GS->gExtInputTimes[idx][curidx+1] - GS->gExtInputTimes[idx][curidx]) * temp + GS->gExtInputVals[idx][curidx];
  }
}
Esempio n. 2
0
void adjust_h( IData *GS, double t, double *h ) {
  int i, t_idx = 0, tph_idx = 0;
  double newh, hh, tph, next_t;
  hh = *h;
  tph = t+hh;
  newh = hh;

  /* Would it be more efficient to test
    if( tph_idx * GS->direction > t_idx * GS->direction ) {
	  newh = min_d( newh, GS->gExtInputTimes[i][t_idx + GS->direction*1] )
    }
    without the if statement for GS->direction?
    (we know direction is +/- 1)
  */
  	
  /* Forward case */
/*
  fprintf(stderr, "******\nOriginal t, h, tph: %.8f, %.8f, %.8f\n", t, hh, tph);
  fprintf(stderr, "GS direction, nExtInputs, gExtInputLens: %d, %d, %d\n", GS->direction, GS->nExtInputs, GS->gExtInputLens[0]);
  fprintf(stderr, "Ip ix @t = %d\n", FindCurrentExtInputIndex(GS, t, 0));
  fprintf(stderr, "Ip ix @tph = %d\n", FindCurrentExtInputIndex(GS, tph, 0));
  fprintf(stderr, "Ip time @ix for tph = %.8f\n", GS->gExtInputTimes[0][FindCurrentExtInputIndex(GS, t, 0)+1]);
*/
  if( GS->direction > 0 ) {
	for( i = 0; i < GS->nExtInputs; i++ ) {
      if( GS->gExtInputLens[i] > 0 ) {
		t_idx = FindCurrentExtInputIndex(GS, t, i);
		tph_idx = FindCurrentExtInputIndex(GS, tph, i);
		if( tph_idx > t_idx ) {
			next_t = GS->gExtInputTimes[i][t_idx+1];
			//fprintf(stderr, " Input time @ t_idx: %.8f\n", GS->gExtInputTimes[i][t_idx]);
			//fprintf(stderr, " Input time @ t_idx+1: %.8f\n", next_t);
			if( isnan(next_t) == 0 ) {
			  
			  //fprintf(stderr, " %.8f: %d, %.8f: %d\n", t, t_idx, tph, tph_idx);
			  //fprintf(stderr, " Original h: %.8f\n", hh);
			  //fprintf(stderr, " Input time @ t_idx: %.8f\n", GS->gExtInputTimes[i][t_idx]);
			  //fprintf(stderr, " Input time @ t_idx+1: %.8f\n", next_t);
			  
			  if( (fabs(next_t-t) > ROUND_TOL) && (newh > next_t-t) ) {
				  newh = next_t-t;
			  	  //fprintf(stderr, "Smaller h: %.8f\n", newh);
		       }
		     }
		  }
		}
	}
  }
  else {
  /* Backward case */
    for( i = 0; i < GS->nExtInputs; i++ ) {
      if( GS->gExtInputLens[i] > 0 ) {
		t_idx = FindCurrentExtInputIndex(GS, t, i);
		tph_idx = FindCurrentExtInputIndex(GS, tph, i);
		if( tph_idx < t_idx ) {
		  next_t = GS->gExtInputTimes[i][t_idx-1];
		  if( isnan(next_t) == 0 ) {
			  if( (fabs(next_t-t) > ROUND_TOL) && (fabs(newh) > fabs(next_t-t)) ) {
				  newh = -fabs(next_t-t);
		      }
    		  //newh = -min_d( fabs(newh), fabs(GS->gExtInputTimes[i][t_idx-1]-t) );
		  }
		}
	   }
    }
  }

  *h = newh;
}