LogLinearWithSeasonalitiesInterpolator1D extends Interpolator1D { @Override public Double interpolate(final Interpolator1DDataBundle model, final Double value) { Validate.notNull(value, "value"); Validate.notNull(model, "data bundle"); final InterpolationBoundedValues boundedValues = model.getBoundedValues(value); final Double x1 = boundedValues.getLowerBoundKey(); final Double y1 = boundedValues.getLowerBoundValue(); if (model.getLowerBoundIndex(value) == model.size() - 1) { return y1; } final Double x2 = boundedValues.getHigherBoundKey(); final Double y2 = boundedValues.getHigherBoundValue(); final double[] nodes = new double[12]; final double[] values = new double[12]; nodes[0] = x1; values[0] = y1; final BrentSolver solver = new BrentSolver(); final Function1D<Double, Double> function = new Function1D<Double, Double>() { @SuppressWarnings("synthetic-access") @Override public Double evaluate(final Double x) { double result = y1; for (int loopmonth = 0; loopmonth < NB_MONTH; loopmonth++) { result = result * (1 + x + _seasonalValues[loopmonth]); } return result - y2; } }; final double initialGuess = Math.pow(y2 / y1, 1 / 12.0) - 1.0; final UnivariateRealFunction f = CommonsMathWrapper.wrapUnivariate(function); double growth; try { growth = solver.solve(f, -.5, .5, initialGuess); for (int loopmonth = 1; loopmonth < NB_MONTH; loopmonth++) { nodes[loopmonth] = x1 + loopmonth * (x2 - x1) / 12.0; values[loopmonth] = values[loopmonth - 1] * (1 + growth + _seasonalValues[loopmonth]); } } catch (final MaxIterationsExceededException ex) { ex.printStackTrace(); } catch (final FunctionEvaluationException ex) { ex.printStackTrace(); } final Interpolator1DDataBundle dataBundle = getDataBundleFromSortedArrays(nodes, values); final StepInterpolator1D stepInterpolator = new StepInterpolator1D(); return stepInterpolator.interpolate(dataBundle, value); } LogLinearWithSeasonalitiesInterpolator1D(final double[] monthlyFactors); @Override Double interpolate(final Interpolator1DDataBundle model, final Double value); @Override Interpolator1DDataBundle getDataBundle(final double[] x, final double[] y); @Override Interpolator1DDataBundle getDataBundleFromSortedArrays(final double[] x, final double[] y); @Override double[] getNodeSensitivitiesForValue(final Interpolator1DDataBundle data, final Double value);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullDataBundle() { INTERPOLATOR.interpolate(null, 3.4); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { INTERPOLATOR.interpolate(MODEL, null); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testLowValue() { INTERPOLATOR.interpolate(MODEL, -2.); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testHighValue() { INTERPOLATOR.interpolate(MODEL, 12.); }
@Test public void test() { assertEquals(INTERPOLATOR.interpolate(MODEL, 3.9), STEP.interpolate(TRANSFORMED_MODEL, 3.9), EPS); }