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]; } }
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; }