@@ -148,7 +148,7 @@ public ErrorHandler(int errorHorizon, int forecastHorizon, int sequenceIndex, do
148
148
pastForecasts [i ] = new RangeVector (values , upper , lower );
149
149
System .arraycopy (actualsFlattened , i * inputLength , actuals [i ], 0 , inputLength );
150
150
}
151
- calibrate ();
151
+ calibrate (null );
152
152
}
153
153
}
154
154
@@ -171,7 +171,7 @@ public void update(ForecastDescriptor descriptor, Calibration calibrationMethod)
171
171
actuals [errorIndex ][i ] = (float ) input [i ];
172
172
}
173
173
++sequenceIndex ;
174
- calibrate ();
174
+ calibrate (descriptor . deviations );
175
175
if (calibrationMethod != Calibration .NONE ) {
176
176
if (calibrationMethod == Calibration .SIMPLE ) {
177
177
adjust (descriptor .timedForecast .rangeVector , errorDistribution );
@@ -260,8 +260,8 @@ public RangeVector computeErrorPercentile(double percentile, int newHorizon,
260
260
double fracRank = percentile * len ;
261
261
Arrays .sort (copy );
262
262
values [pos ] = interpolatedMedian (copy );
263
- lower [pos ] = interpolatedLowerRank (copy , fracRank );
264
- upper [pos ] = interpolatedUpperRank (copy , len , fracRank );
263
+ lower [pos ] = interpolatedLowerRank (copy , fracRank , 0 );
264
+ upper [pos ] = interpolatedUpperRank (copy , len , fracRank , 0 );
265
265
}
266
266
}
267
267
}
@@ -286,8 +286,11 @@ protected double[] getErrorVector(int len, int leadtime, int inputCoordinate, in
286
286
* this method computes a lot of different quantities, some of which would be
287
287
* useful in the future.In particular it splits the RMSE into positive and
288
288
* negative contribution which is informative about directionality of error.
289
+ *
290
+ *
291
+ * @param errorDeviations the weighted standard deviations seen so far
289
292
*/
290
- protected void calibrate () {
293
+ protected void calibrate (double [] errorDeviations ) {
291
294
int inputLength = actuals [0 ].length ;
292
295
int arrayLength = pastForecasts .length ;
293
296
int errorIndex = (sequenceIndex - 1 + arrayLength ) % arrayLength ;
@@ -327,16 +330,19 @@ protected void calibrate() {
327
330
errorRMSE .high [pos ] = (positiveCount > 0 ) ? Math .sqrt (positiveSqSum / positiveCount ) : 0 ;
328
331
errorRMSE .low [pos ] = (positiveCount < len ) ? -Math .sqrt (negativeSqSum / (len - positiveCount )) : 0 ;
329
332
Arrays .sort (medianError , 0 , len );
333
+ // medianError array is now sorted
330
334
errorDistribution .values [pos ] = interpolatedMedian (medianError );
331
- errorDistribution .upper [pos ] = interpolatedUpperRank (medianError , len , len * percentile );
332
- errorDistribution .lower [pos ] = interpolatedLowerRank (medianError , len * percentile );
335
+ double deviation = (errorDeviations == null ) ? 0 : errorDeviations [j ];
336
+ errorDistribution .upper [pos ] = interpolatedUpperRank (medianError , len , len * percentile , deviation );
337
+ errorDistribution .lower [pos ] = interpolatedLowerRank (medianError , len * percentile , deviation );
333
338
intervalPrecision [pos ] = intervalPrecision [pos ] / len ;
334
339
} else {
335
340
errorMean [pos ] = 0 ;
336
341
errorRMSE .high [pos ] = errorRMSE .low [pos ] = 0 ;
337
342
errorDistribution .values [pos ] = 0 ;
338
- errorDistribution .upper [pos ] = Float .MAX_VALUE ;
339
- errorDistribution .lower [pos ] = -Float .MAX_VALUE ;
343
+ double deviation = (errorDeviations == null ) ? 0 : errorDeviations [j ];
344
+ errorDistribution .upper [pos ] = (float ) (1.3 * deviation );
345
+ errorDistribution .lower [pos ] = -(float ) (1.3 * deviation );
340
346
adders .upper [pos ] = adders .lower [pos ] = adders .values [pos ] = 0 ;
341
347
intervalPrecision [pos ] = 0 ;
342
348
}
@@ -354,28 +360,30 @@ float interpolatedMedian(double[] array) {
354
360
}
355
361
}
356
362
357
- float interpolatedLowerRank (double [] array , double fracRank ) {
363
+ float interpolatedLowerRank (double [] ascendingArray , double fracRank , double deviation ) {
358
364
if (fracRank < 1 ) {
359
- return - Float . MAX_VALUE ;
365
+ return ( float ) (- 1.3 * deviation * ( 1 - fracRank ) + fracRank * ascendingArray [ 0 ]) ;
360
366
}
361
367
int rank = (int ) Math .floor (fracRank );
362
368
if (!RCFCaster .USE_INTERPOLATION_IN_DISTRIBUTION ) {
363
369
// turn off interpolation
364
370
fracRank = rank ;
365
371
}
366
- return (float ) (array [rank - 1 ] + (fracRank - rank ) * (array [rank ] - array [rank - 1 ]));
372
+ return (float ) (ascendingArray [rank - 1 ]
373
+ + (fracRank - rank ) * (ascendingArray [rank ] - ascendingArray [rank - 1 ]));
367
374
}
368
375
369
- float interpolatedUpperRank (double [] array , int len , double fracRank ) {
376
+ float interpolatedUpperRank (double [] ascendingArray , int len , double fracRank , double deviation ) {
370
377
if (fracRank < 1 ) {
371
- return Float . MAX_VALUE ;
378
+ return ( float ) ( 1.3 * deviation * ( 1 - fracRank ) + fracRank * ascendingArray [ len - 1 ]) ;
372
379
}
373
380
int rank = (int ) Math .floor (fracRank );
374
381
if (!RCFCaster .USE_INTERPOLATION_IN_DISTRIBUTION ) {
375
382
// turn off interpolation
376
383
fracRank = rank ;
377
384
}
378
- return (float ) (array [len - rank ] + (fracRank - rank ) * (array [len - rank - 1 ] - array [len - rank ]));
385
+ return (float ) (ascendingArray [len - rank ]
386
+ + (fracRank - rank ) * (ascendingArray [len - rank - 1 ] - ascendingArray [len - rank ]));
379
387
}
380
388
381
389
void adjust (RangeVector rangeVector , RangeVector other ) {
0 commit comments