/*
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/math/linear_interpolator.h"

#include <limits>

#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace math {

TEST(LinearInterpolator, SimpleInterpolation) {
  LinearInterpolator<float, float> interp;
  interp.Add(0, 0);
  interp.Add(1, 2);

  // Expect that value of 0.0f maps to 0.0f
  EXPECT_FLOAT_EQ(0.f, interp.Map(0.0f));
  // Expect that value of 0.5f maps to 1.0f
  EXPECT_FLOAT_EQ(1.f, interp.Map(0.5f));
  // Expect that value of 1.5f maps to 2.0f
  EXPECT_FLOAT_EQ(2.f, interp.Map(1.0f));
}

// Tests the expectation that clearing the interpolator works.
TEST(LinearInterpolator, Clear) {
  LinearInterpolator<int, int> interp;
  interp.Add(-1, 0);
  interp.Add(1, 2);

  interp.Clear();

  EXPECT_FLOAT_EQ(0, interp.Map(-1));
  EXPECT_FLOAT_EQ(0, interp.Map(1));
}

// Tests the expectation that interpolating on one value in the table works
// as expected: to always return that value.
TEST(LinearInterpolator, InterpolateSingularValue) {
  LinearInterpolator<size_t, size_t> interp;
  interp.Add(2, 10);

  EXPECT_EQ(10, interp.Map(2));
  EXPECT_EQ(10, interp.Map(1));
  EXPECT_EQ(10, interp.Map(3));
}

// Tests the expectation that we can introduce an discontinuity by passing
// in duplicate keys.
TEST(LinearInterpolator, Discontinuity) {
  LinearInterpolator<double, float> interp;
  interp.Add(0, 0);
  interp.Add(1, 1);  // Discontinuity at input = 1.
  interp.Add(1, 3);
  interp.Add(2, 4);

  static const double kErrorThreshold = .1f;
  static const double kEpsilon = std::numeric_limits<double>::epsilon()*4.0;

  EXPECT_NEAR(1.0, interp.Map(1.f - kEpsilon), kErrorThreshold);
  // Expect that at the discontinuity point value of 1, that the value that
  // the interpolator produces is 3.
  EXPECT_FLOAT_EQ(3, interp.Map(1.f));
  EXPECT_NEAR(3.0, interp.Map(1.f + kEpsilon), kErrorThreshold);
}

// Tests that extrapolation is forbidden with this interpolator.
TEST(LinearInterpolator, ExtrapolationForbidden) {
  LinearInterpolator<float, float> interp;
  interp.Add(0, 0);
  interp.Add(1, 2);

  // Expect that values less than the minimal key value is clamped.
  EXPECT_FLOAT_EQ(0.0f, interp.Map(-1.0f));
  // Expect that values greater than the maximum key value is clamped.
  EXPECT_FLOAT_EQ(2.0f, interp.Map(2.0f));
}

// Some more real world values.
TEST(LinearInterpolator, UseComplexFloat) {
  LinearInterpolator<float, float> interp;
  interp.Add(0, 0);
  interp.Add(41, 1);
  interp.Add(1023, 15);

  EXPECT_FLOAT_EQ(0.0f, interp.Map(0.f));
  EXPECT_FLOAT_EQ(0.5f, interp.Map(41.f/2.f));
  EXPECT_FLOAT_EQ(1.0f, interp.Map(41.f));
  EXPECT_FLOAT_EQ(15.f, interp.Map(1023.f));
}

// Tests that this interpolator works with integer keys and float values.
TEST(LinearInterpolator, UseIntegerKeyWithFloatValue) {
  LinearInterpolator<int, float> interp;
  interp.Add(0, 0.f);
  interp.Add(10, 1.f);
  interp.Add(100, 2.f);

  EXPECT_FLOAT_EQ(0.0f, interp.Map(0));
  EXPECT_FLOAT_EQ(0.5f, interp.Map(5));
  EXPECT_FLOAT_EQ(1.0f, interp.Map(10));
  EXPECT_FLOAT_EQ(2.0f, interp.Map(100));
}

// Tests that this interpolator works with integer keys and int values.
TEST(LinearInterpolator, UseIntegerKeyWithIntegerValue) {
  LinearInterpolator<int, int> interp;
  interp.Add(0, 0);
  interp.Add(10, 100);
  interp.Add(100, 1000);

  EXPECT_EQ(0, interp.Map(0));
  EXPECT_EQ(50, interp.Map(5));
  EXPECT_EQ(100, interp.Map(10));
  EXPECT_EQ(550, interp.Map(55));
  EXPECT_EQ(1000, interp.Map(100));
}

}  // namespace math
}  // namespace cobalt
