// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)

#include "ceres/cost_function_to_functor.h"
#include "ceres/autodiff_cost_function.h"
#include "gtest/gtest.h"

namespace ceres {
namespace internal {

const double kTolerance = 1e-18;

void ExpectCostFunctionsAreEqual(const CostFunction& cost_function,
                                 const CostFunction& actual_cost_function) {
  EXPECT_EQ(cost_function.num_residuals(),
            actual_cost_function.num_residuals());
  const int num_residuals = cost_function.num_residuals();
  const vector<int32>& parameter_block_sizes =
      cost_function.parameter_block_sizes();
  const vector<int32>& actual_parameter_block_sizes =
      actual_cost_function.parameter_block_sizes();
  EXPECT_EQ(parameter_block_sizes.size(),
            actual_parameter_block_sizes.size());

  int num_parameters = 0;
  for (int i = 0; i < parameter_block_sizes.size(); ++i) {
    EXPECT_EQ(parameter_block_sizes[i], actual_parameter_block_sizes[i]);
    num_parameters += parameter_block_sizes[i];
  }

  scoped_array<double> parameters(new double[num_parameters]);
  for (int i = 0; i < num_parameters; ++i) {
    parameters[i] = static_cast<double>(i) + 1.0;
  }

  scoped_array<double> residuals(new double[num_residuals]);
  scoped_array<double> jacobians(new double[num_parameters * num_residuals]);

  scoped_array<double> actual_residuals(new double[num_residuals]);
  scoped_array<double> actual_jacobians
      (new double[num_parameters * num_residuals]);

  scoped_array<double*> parameter_blocks(
      new double*[parameter_block_sizes.size()]);
  scoped_array<double*> jacobian_blocks(
      new double*[parameter_block_sizes.size()]);
  scoped_array<double*> actual_jacobian_blocks(
      new double*[parameter_block_sizes.size()]);

  num_parameters = 0;
  for (int i = 0; i < parameter_block_sizes.size(); ++i) {
    parameter_blocks[i] = parameters.get() + num_parameters;
    jacobian_blocks[i] = jacobians.get() + num_parameters * num_residuals;
    actual_jacobian_blocks[i] =
        actual_jacobians.get() + num_parameters * num_residuals;
    num_parameters += parameter_block_sizes[i];
  }

  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.get(),
                                     residuals.get(), NULL));
  EXPECT_TRUE(actual_cost_function.Evaluate(parameter_blocks.get(),
                                            actual_residuals.get(), NULL));
  for (int i = 0; i < num_residuals; ++i) {
    EXPECT_NEAR(residuals[i], actual_residuals[i], kTolerance)
        << "residual id: " << i;
  }


  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.get(),
                                     residuals.get(),
                                     jacobian_blocks.get()));
  EXPECT_TRUE(actual_cost_function.Evaluate(parameter_blocks.get(),
                                            actual_residuals.get(),
                                            actual_jacobian_blocks.get()));
  for (int i = 0; i < num_residuals; ++i) {
    EXPECT_NEAR(residuals[i], actual_residuals[i], kTolerance)
        << "residual : " << i;
  }

  for (int i = 0; i < num_residuals * num_parameters; ++i) {
    EXPECT_NEAR(jacobians[i], actual_jacobians[i], kTolerance)
        << "jacobian : " << i << " "
        << jacobians[i] << " " << actual_jacobians[i];
  }
};

struct OneParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, T* residuals) const {
    residuals[0] = x1[0] * x1[0];
    residuals[1] = x1[1] * x1[1];
    return true;
  }
};

struct TwoParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1];
    return true;
  }
};

struct ThreeParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1];
    return true;
  }
};

struct FourParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
                  T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
        + x4[0] * x4[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
        + x4[1] * x4[1];
    return true;
  }
};

struct FiveParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
                  const T* x5, T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
        + x4[0] * x4[0] + x5[0] * x5[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
        + x4[1] * x4[1] + x5[1] * x5[1];
    return true;
  }
};

struct SixParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
                  const T* x5, const T* x6,  T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1];
    return true;
  }
};

struct SevenParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
                  const T* x5, const T* x6, const T* x7, T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1];
    return true;
  }
};

struct EightParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
                  const T* x5, const T* x6, const T* x7, const T* x8,
                  T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0]
        + x8[0] * x8[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1]
        + x8[1] * x8[1];
    return true;
  }
};

struct NineParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
                  const T* x5, const T* x6, const T* x7, const T* x8,
                  const T* x9, T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0]
        + x8[0] * x8[0] + x9[0] * x9[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1]
        + x8[1] * x8[1] + x9[1] * x9[1];
    return true;
  }
};

struct TenParameterBlockFunctor {
 public:
  template <typename T>
  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
                  const T* x5, const T* x6, const T* x7, const T* x8,
                  const T* x9, const T* x10, T* residuals) const {
    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0]
        + x8[0] * x8[0] + x9[0] * x9[0] + x10[0] * x10[0];
    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1]
        + x8[1] * x8[1] + x9[1] * x9[1] + x10[1] * x10[1];
    return true;
  }
};

#define TEST_BODY(NAME)                                                 \
  TEST(CostFunctionToFunctor, NAME) {                                   \
    scoped_ptr<CostFunction> cost_function(                             \
        new AutoDiffCostFunction<                                       \
            CostFunctionToFunctor<2, PARAMETER_BLOCK_SIZES >,           \
                2, PARAMETER_BLOCK_SIZES>(new CostFunctionToFunctor<    \
                    2, PARAMETER_BLOCK_SIZES >(                         \
                        new AutoDiffCostFunction<                       \
                            NAME##Functor, 2, PARAMETER_BLOCK_SIZES >(  \
                  new NAME##Functor))));                                \
                                                                        \
scoped_ptr<CostFunction> actual_cost_function(                          \
    new AutoDiffCostFunction<NAME##Functor, 2, PARAMETER_BLOCK_SIZES >( \
        new NAME##Functor));                                            \
ExpectCostFunctionsAreEqual(*cost_function, *actual_cost_function);     \
}

#define PARAMETER_BLOCK_SIZES 2
TEST_BODY(OneParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2
TEST_BODY(TwoParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2
TEST_BODY(ThreeParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2,2
TEST_BODY(FourParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2,2,2
TEST_BODY(FiveParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2
TEST_BODY(SixParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2
TEST_BODY(SevenParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2,2
TEST_BODY(EightParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2,2,2
TEST_BODY(NineParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2,2,2,2
TEST_BODY(TenParameterBlock)
#undef PARAMETER_BLOCK_SIZES

#undef TEST_BODY

TEST(CostFunctionToFunctor, DynamicNumberOfResiduals) {
  scoped_ptr<CostFunction> cost_function(
      new AutoDiffCostFunction<
      CostFunctionToFunctor<ceres::DYNAMIC, 2, 2 >, ceres::DYNAMIC, 2, 2>(
          new CostFunctionToFunctor<ceres::DYNAMIC, 2, 2 >(
              new AutoDiffCostFunction<TwoParameterBlockFunctor, 2, 2, 2 >(
                  new TwoParameterBlockFunctor)), 2));

  scoped_ptr<CostFunction> actual_cost_function(
      new AutoDiffCostFunction<TwoParameterBlockFunctor, 2, 2, 2 >(
          new TwoParameterBlockFunctor));
  ExpectCostFunctionsAreEqual(*cost_function, *actual_cost_function);
}

}  // namespace internal
}  // namespace ceres
