Blame examples/more_garbow_hillstrom.cc

Packit ea1746
// Ceres Solver - A fast non-linear least squares minimizer
Packit ea1746
// Copyright 2015 Google Inc. All rights reserved.
Packit ea1746
// http://ceres-solver.org/
Packit ea1746
//
Packit ea1746
// Redistribution and use in source and binary forms, with or without
Packit ea1746
// modification, are permitted provided that the following conditions are met:
Packit ea1746
//
Packit ea1746
// * Redistributions of source code must retain the above copyright notice,
Packit ea1746
//   this list of conditions and the following disclaimer.
Packit ea1746
// * Redistributions in binary form must reproduce the above copyright notice,
Packit ea1746
//   this list of conditions and the following disclaimer in the documentation
Packit ea1746
//   and/or other materials provided with the distribution.
Packit ea1746
// * Neither the name of Google Inc. nor the names of its contributors may be
Packit ea1746
//   used to endorse or promote products derived from this software without
Packit ea1746
//   specific prior written permission.
Packit ea1746
//
Packit ea1746
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit ea1746
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit ea1746
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit ea1746
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Packit ea1746
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit ea1746
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit ea1746
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit ea1746
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Packit ea1746
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit ea1746
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit ea1746
// POSSIBILITY OF SUCH DAMAGE.
Packit ea1746
//
Packit ea1746
// Author: sameeragarwal@google.com (Sameer Agarwal)
Packit ea1746
//
Packit ea1746
// Test problems from the paper
Packit ea1746
//
Packit ea1746
// Testing Unconstrained Optimization Software
Packit ea1746
// Jorge J. More, Burton S. Garbow and Kenneth E. Hillstrom
Packit ea1746
// ACM Transactions on Mathematical Software, 7(1), pp. 17-41, 1981
Packit ea1746
//
Packit ea1746
// A subset of these problems were augmented with bounds and used for
Packit ea1746
// testing bounds constrained optimization algorithms by
Packit ea1746
//
Packit ea1746
// A Trust Region Approach to Linearly Constrained Optimization
Packit ea1746
// David M. Gay
Packit ea1746
// Numerical Analysis (Griffiths, D.F., ed.), pp. 72-105
Packit ea1746
// Lecture Notes in Mathematics 1066, Springer Verlag, 1984.
Packit ea1746
//
Packit ea1746
// The latter paper is behind a paywall. We obtained the bounds on the
Packit ea1746
// variables and the function values at the global minimums from
Packit ea1746
//
Packit ea1746
// http://www.mat.univie.ac.at/~neum/glopt/bounds.html
Packit ea1746
//
Packit ea1746
// A problem is considered solved if of the log relative error of its
Packit ea1746
// objective function is at least 4.
Packit ea1746
Packit ea1746
Packit ea1746
#include <cmath>
Packit ea1746
#include <iostream>  // NOLINT
Packit ea1746
#include <sstream>   // NOLINT
Packit ea1746
#include <string>
Packit ea1746
#include "ceres/ceres.h"
Packit ea1746
#include "gflags/gflags.h"
Packit ea1746
#include "glog/logging.h"
Packit ea1746
Packit ea1746
DEFINE_string(problem, "all", "Which problem to solve");
Packit ea1746
DEFINE_bool(use_numeric_diff, false,
Packit ea1746
            "Use numeric differentiation instead of automatic "
Packit ea1746
            "differentiation.");
Packit ea1746
DEFINE_string(numeric_diff_method, "ridders", "When using numeric "
Packit ea1746
              "differentiation, selects algorithm. Options are: central, "
Packit ea1746
              "forward, ridders.");
Packit ea1746
DEFINE_int32(ridders_extrapolations, 3, "Maximal number of extrapolations in "
Packit ea1746
             "Ridders' method.");
Packit ea1746
Packit ea1746
namespace ceres {
Packit ea1746
namespace examples {
Packit ea1746
Packit ea1746
const double kDoubleMax = std::numeric_limits<double>::max();
Packit ea1746
Packit ea1746
static void SetNumericDiffOptions(ceres::NumericDiffOptions* options) {
Packit ea1746
  options->max_num_ridders_extrapolations = FLAGS_ridders_extrapolations;
Packit ea1746
}
Packit ea1746
Packit ea1746
#define BEGIN_MGH_PROBLEM(name, num_parameters, num_residuals)            \
Packit ea1746
  struct name {                                                           \
Packit ea1746
    static const int kNumParameters = num_parameters;                     \
Packit ea1746
    static const double initial_x[kNumParameters];                        \
Packit ea1746
    static const double lower_bounds[kNumParameters];                     \
Packit ea1746
    static const double upper_bounds[kNumParameters];                     \
Packit ea1746
    static const double constrained_optimal_cost;                         \
Packit ea1746
    static const double unconstrained_optimal_cost;                       \
Packit ea1746
    static CostFunction* Create() {                                       \
Packit ea1746
      if (FLAGS_use_numeric_diff) {                                       \
Packit ea1746
        ceres::NumericDiffOptions options;                                \
Packit ea1746
        SetNumericDiffOptions(&options);                                  \
Packit ea1746
        if (FLAGS_numeric_diff_method == "central") {                     \
Packit ea1746
          return new NumericDiffCostFunction
Packit ea1746
                                             ceres::CENTRAL,              \
Packit ea1746
                                             num_residuals,               \
Packit ea1746
                                             num_parameters>(             \
Packit ea1746
              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);   \
Packit ea1746
        } else if (FLAGS_numeric_diff_method == "forward") {              \
Packit ea1746
          return new NumericDiffCostFunction
Packit ea1746
                                             ceres::FORWARD,              \
Packit ea1746
                                             num_residuals,               \
Packit ea1746
                                             num_parameters>(             \
Packit ea1746
              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);   \
Packit ea1746
        } else if (FLAGS_numeric_diff_method == "ridders") {              \
Packit ea1746
          return new NumericDiffCostFunction
Packit ea1746
                                             ceres::RIDDERS,              \
Packit ea1746
                                             num_residuals,               \
Packit ea1746
                                             num_parameters>(             \
Packit ea1746
              new name, ceres::TAKE_OWNERSHIP, num_residuals, options);   \
Packit ea1746
        } else {                                                          \
Packit ea1746
          LOG(ERROR) << "Invalid numeric diff method specified";          \
Packit ea1746
          return NULL;                                                    \
Packit ea1746
        }                                                                 \
Packit ea1746
      } else {                                                            \
Packit ea1746
        return new AutoDiffCostFunction
Packit ea1746
                                        num_residuals,                    \
Packit ea1746
                                        num_parameters>(new name);        \
Packit ea1746
      }                                                                   \
Packit ea1746
    }                                                                     \
Packit ea1746
    template <typename T>                                                 \
Packit ea1746
    bool operator()(const T* const x, T* residual) const {
Packit ea1746
Packit ea1746
#define END_MGH_PROBLEM return true; } };  // NOLINT
Packit ea1746
Packit ea1746
// Rosenbrock function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem1, 2, 2)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  residual[0] = 10.0 * (x2 - x1 * x1);
Packit ea1746
  residual[1] = 1.0 - x1;
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem1::initial_x[] = {-1.2, 1.0};
Packit ea1746
const double TestProblem1::lower_bounds[] = {-kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem1::upper_bounds[] = {kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem1::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem1::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Freudenstein and Roth function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem2, 2, 2)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  residual[0] = -13.0 + x1 + ((5.0 - x2) * x2 - 2.0) * x2;
Packit ea1746
  residual[1] = -29.0 + x1 + ((x2 + 1.0) * x2 - 14.0) * x2;
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem2::initial_x[] = {0.5, -2.0};
Packit ea1746
const double TestProblem2::lower_bounds[] = {-kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem2::upper_bounds[] = {kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem2::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem2::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Powell badly scaled function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem3, 2, 2)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  residual[0] = 10000.0 * x1 * x2 - 1.0;
Packit ea1746
  residual[1] = exp(-x1) + exp(-x2) - 1.0001;
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem3::initial_x[] = {0.0, 1.0};
Packit ea1746
const double TestProblem3::lower_bounds[] = {0.0, 1.0};
Packit ea1746
const double TestProblem3::upper_bounds[] = {1.0, 9.0};
Packit ea1746
const double TestProblem3::constrained_optimal_cost = 0.15125900e-9;
Packit ea1746
const double TestProblem3::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Brown badly scaled function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem4, 2, 3)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  residual[0] = x1  - 1000000.0;
Packit ea1746
  residual[1] = x2 - 0.000002;
Packit ea1746
  residual[2] = x1 * x2 - 2.0;
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem4::initial_x[] = {1.0, 1.0};
Packit ea1746
const double TestProblem4::lower_bounds[] = {0.0, 0.00003};
Packit ea1746
const double TestProblem4::upper_bounds[] = {1000000.0, 100.0};
Packit ea1746
const double TestProblem4::constrained_optimal_cost = 0.78400000e3;
Packit ea1746
const double TestProblem4::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Beale function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem5, 2, 3)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  residual[0] = 1.5 - x1 * (1.0 - x2);
Packit ea1746
  residual[1] = 2.25 - x1 * (1.0 - x2 * x2);
Packit ea1746
  residual[2] = 2.625 - x1 * (1.0 - x2 * x2 * x2);
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem5::initial_x[] = {1.0, 1.0};
Packit ea1746
const double TestProblem5::lower_bounds[] = {0.6, 0.5};
Packit ea1746
const double TestProblem5::upper_bounds[] = {10.0, 100.0};
Packit ea1746
const double TestProblem5::constrained_optimal_cost = 0.0;
Packit ea1746
const double TestProblem5::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Jennrich and Sampson function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem6, 2, 10)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  for (int i = 1; i <= 10; ++i) {
Packit ea1746
    residual[i - 1] = 2.0 + 2.0 * i -
Packit ea1746
        (exp(static_cast<double>(i) * x1) +
Packit ea1746
         exp(static_cast<double>(i) * x2));
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem6::initial_x[] = {1.0, 1.0};
Packit ea1746
const double TestProblem6::lower_bounds[] = {-kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem6::upper_bounds[] = {kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem6::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem6::unconstrained_optimal_cost = 124.362;
Packit ea1746
Packit ea1746
// Helical valley function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem7, 3, 3)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T theta = (0.5 / M_PI)  * atan(x2 / x1) + (x1 > 0.0 ? 0.0 : 0.5);
Packit ea1746
  residual[0] = 10.0 * (x3 - 10.0 * theta);
Packit ea1746
  residual[1] = 10.0 * (sqrt(x1 * x1 + x2 * x2) - 1.0);
Packit ea1746
  residual[2] = x3;
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem7::initial_x[] = {-1.0, 0.0, 0.0};
Packit ea1746
const double TestProblem7::lower_bounds[] = {-100.0, -1.0, -1.0};
Packit ea1746
const double TestProblem7::upper_bounds[] = {0.8, 1.0, 1.0};
Packit ea1746
const double TestProblem7::constrained_optimal_cost = 0.99042212;
Packit ea1746
const double TestProblem7::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Bard function
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem8, 3, 15)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
Packit ea1746
  double y[] = {0.14, 0.18, 0.22, 0.25,
Packit ea1746
                0.29, 0.32, 0.35, 0.39, 0.37, 0.58,
Packit ea1746
                0.73, 0.96, 1.34, 2.10, 4.39};
Packit ea1746
Packit ea1746
  for (int i = 1; i <=15; ++i) {
Packit ea1746
    const double u = i;
Packit ea1746
    const double v = 16 - i;
Packit ea1746
    const double w = std::min(i, 16 - i);
Packit ea1746
    residual[i - 1] = y[i - 1] - (x1 + u / (v * x2 + w * x3));
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem8::initial_x[] = {1.0, 1.0, 1.0};
Packit ea1746
const double TestProblem8::lower_bounds[] = {
Packit ea1746
  -kDoubleMax, -kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem8::upper_bounds[] = {
Packit ea1746
  kDoubleMax, kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem8::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem8::unconstrained_optimal_cost = 8.21487e-3;
Packit ea1746
Packit ea1746
// Gaussian function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem9, 3, 15)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
Packit ea1746
  const double y[] = {0.0009, 0.0044, 0.0175, 0.0540, 0.1295, 0.2420, 0.3521,
Packit ea1746
                      0.3989,
Packit ea1746
                      0.3521, 0.2420, 0.1295, 0.0540, 0.0175, 0.0044, 0.0009};
Packit ea1746
  for (int i = 0; i < 15; ++i) {
Packit ea1746
    const double t_i = (8.0 - i - 1.0) / 2.0;
Packit ea1746
    residual[i] = x1 * exp(-x2 * (t_i - x3) * (t_i - x3) / 2.0) - y[i];
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem9::initial_x[] = {0.4, 1.0, 0.0};
Packit ea1746
const double TestProblem9::lower_bounds[] = {0.398, 1.0, -0.5};
Packit ea1746
const double TestProblem9::upper_bounds[] = {4.2, 2.0, 0.1};
Packit ea1746
const double TestProblem9::constrained_optimal_cost = 0.11279300e-7;
Packit ea1746
const double TestProblem9::unconstrained_optimal_cost = 0.112793e-7;
Packit ea1746
Packit ea1746
// Meyer function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem10, 3, 16)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
Packit ea1746
  const double y[] = {34780, 28610, 23650, 19630, 16370, 13720, 11540, 9744,
Packit ea1746
                      8261, 7030, 6005, 5147, 4427, 3820, 3307, 2872};
Packit ea1746
Packit ea1746
  for (int i = 0; i < 16; ++i) {
Packit ea1746
    const double ti = 45.0 + 5.0 * (i + 1);
Packit ea1746
    residual[i] = x1 * exp(x2 / (ti + x3)) - y[i];
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM
Packit ea1746
Packit ea1746
const double TestProblem10::initial_x[] = {0.02, 4000, 250};
Packit ea1746
const double TestProblem10::lower_bounds[] = {
Packit ea1746
  -kDoubleMax, -kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem10::upper_bounds[] = {
Packit ea1746
  kDoubleMax, kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem10::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem10::unconstrained_optimal_cost = 87.9458;
Packit ea1746
Packit ea1746
// Gulf research and development function
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem11, 3, 100)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  for (int i = 1; i <= 100; ++i) {
Packit ea1746
    const double ti = i / 100.0;
Packit ea1746
    const double yi = 25.0 + pow(-50.0 * log(ti), 2.0 / 3.0);
Packit ea1746
    residual[i - 1] = exp(-pow(abs((yi * 100.0 * i) * x2), x3) / x1) - ti;
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM
Packit ea1746
Packit ea1746
const double TestProblem11::initial_x[] = {5.0, 2.5, 0.15};
Packit ea1746
const double TestProblem11::lower_bounds[] = {1e-16, 0.0, 0.0};
Packit ea1746
const double TestProblem11::upper_bounds[] = {10.0, 10.0, 10.0};
Packit ea1746
const double TestProblem11::constrained_optimal_cost = 0.58281431e-4;
Packit ea1746
const double TestProblem11::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Box three-dimensional function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem12, 3, 3)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
Packit ea1746
  const double t1 = 0.1;
Packit ea1746
  const double t2 = 0.2;
Packit ea1746
  const double t3 = 0.3;
Packit ea1746
Packit ea1746
  residual[0] = exp(-t1 * x1) - exp(-t1 * x2) - x3 * (exp(-t1) - exp(-10.0 * t1));
Packit ea1746
  residual[1] = exp(-t2 * x1) - exp(-t2 * x2) - x3 * (exp(-t2) - exp(-10.0 * t2));
Packit ea1746
  residual[2] = exp(-t3 * x1) - exp(-t3 * x2) - x3 * (exp(-t3) - exp(-10.0 * t3));
Packit ea1746
END_MGH_PROBLEM
Packit ea1746
Packit ea1746
const double TestProblem12::initial_x[] = {0.0, 10.0, 20.0};
Packit ea1746
const double TestProblem12::lower_bounds[] = {0.0, 5.0, 0.0};
Packit ea1746
const double TestProblem12::upper_bounds[] = {2.0, 9.5, 20.0};
Packit ea1746
const double TestProblem12::constrained_optimal_cost = 0.30998153e-5;
Packit ea1746
const double TestProblem12::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Powell Singular function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem13, 4, 4)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T x4 = x[3];
Packit ea1746
Packit ea1746
  residual[0] = x1 + 10.0 * x2;
Packit ea1746
  residual[1] = sqrt(5.0) * (x3 - x4);
Packit ea1746
  residual[2] = (x2 - 2.0 * x3) * (x2 - 2.0 * x3);
Packit ea1746
  residual[3] = sqrt(10.0) * (x1 - x4) * (x1 - x4);
Packit ea1746
END_MGH_PROBLEM
Packit ea1746
Packit ea1746
const double TestProblem13::initial_x[] = {3.0, -1.0, 0.0, 1.0};
Packit ea1746
const double TestProblem13::lower_bounds[] = {
Packit ea1746
  -kDoubleMax, -kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem13::upper_bounds[] = {
Packit ea1746
  kDoubleMax, kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem13::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem13::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
// Wood function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem14, 4, 6)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T x4 = x[3];
Packit ea1746
Packit ea1746
  residual[0] = 10.0 * (x2 - x1 * x1);
Packit ea1746
  residual[1] = 1.0 - x1;
Packit ea1746
  residual[2] = sqrt(90.0) * (x4 - x3 * x3);
Packit ea1746
  residual[3] = 1.0 - x3;
Packit ea1746
  residual[4] = sqrt(10.0) * (x2 + x4 - 2.0);
Packit ea1746
  residual[5] = 1.0 / sqrt(10.0) * (x2 - x4);
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
  const double TestProblem14::initial_x[] = {-3.0, -1.0, -3.0, -1.0};
Packit ea1746
  const double TestProblem14::lower_bounds[] = {-100.0, -100.0, -100.0, -100.0};
Packit ea1746
  const double TestProblem14::upper_bounds[] = {0.0, 10.0, 100.0, 100.0};
Packit ea1746
  const double TestProblem14::constrained_optimal_cost = 0.15567008e1;
Packit ea1746
  const double TestProblem14::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
  // Kowalik and Osborne function.
Packit ea1746
  BEGIN_MGH_PROBLEM(TestProblem15, 4, 11)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T x4 = x[3];
Packit ea1746
Packit ea1746
  const double y[] = {0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627,
Packit ea1746
                      0.0456, 0.0342, 0.0323, 0.0235, 0.0246};
Packit ea1746
  const double u[] = {4.0, 2.0, 1.0, 0.5, 0.25, 0.167, 0.125, 0.1,
Packit ea1746
                      0.0833, 0.0714, 0.0625};
Packit ea1746
Packit ea1746
  for (int i = 0; i < 11; ++i) {
Packit ea1746
    residual[i]  = y[i] - x1 * (u[i] * u[i] + u[i] * x2) /
Packit ea1746
        (u[i] * u[i]  + u[i] * x3 + x4);
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem15::initial_x[] = {0.25, 0.39, 0.415, 0.39};
Packit ea1746
const double TestProblem15::lower_bounds[] = {
Packit ea1746
  -kDoubleMax, -kDoubleMax, -kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem15::upper_bounds[] = {
Packit ea1746
  kDoubleMax, kDoubleMax, kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem15::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem15::unconstrained_optimal_cost = 3.07505e-4;
Packit ea1746
Packit ea1746
// Brown and Dennis function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem16, 4, 20)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T x4 = x[3];
Packit ea1746
Packit ea1746
  for (int i = 0; i < 20; ++i) {
Packit ea1746
    const double ti = (i + 1) / 5.0;
Packit ea1746
    residual[i] = (x1 + ti * x2 - exp(ti)) * (x1 + ti * x2 - exp(ti)) +
Packit ea1746
        (x3 + x4 * sin(ti) - cos(ti)) * (x3 + x4 * sin(ti) - cos(ti));
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem16::initial_x[] = {25.0, 5.0, -5.0, -1.0};
Packit ea1746
const double TestProblem16::lower_bounds[] = {-10.0, 0.0, -100.0, -20.0};
Packit ea1746
const double TestProblem16::upper_bounds[] = {100.0, 15.0, 0.0, 0.2};
Packit ea1746
const double TestProblem16::constrained_optimal_cost = 0.88860479e5;
Packit ea1746
const double TestProblem16::unconstrained_optimal_cost = 85822.2;
Packit ea1746
Packit ea1746
// Osborne 1 function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem17, 5, 33)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T x4 = x[3];
Packit ea1746
  const T x5 = x[4];
Packit ea1746
Packit ea1746
  const double y[] = {0.844, 0.908, 0.932, 0.936, 0.925, 0.908, 0.881, 0.850, 0.818,
Packit ea1746
                      0.784, 0.751, 0.718, 0.685, 0.658, 0.628, 0.603, 0.580, 0.558,
Packit ea1746
                      0.538, 0.522, 0.506, 0.490, 0.478, 0.467, 0.457, 0.448, 0.438,
Packit ea1746
                      0.431, 0.424, 0.420, 0.414, 0.411, 0.406};
Packit ea1746
Packit ea1746
  for (int i = 0; i < 33; ++i) {
Packit ea1746
     const double ti = 10.0 * i;
Packit ea1746
    residual[i] = y[i] - (x1 + x2 * exp(-ti * x4) + x3 * exp(-ti * x5));
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem17::initial_x[] = {0.5, 1.5, -1.0, 0.01, 0.02};
Packit ea1746
const double TestProblem17::lower_bounds[] = {
Packit ea1746
  -kDoubleMax, -kDoubleMax, -kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem17::upper_bounds[] = {
Packit ea1746
  kDoubleMax, kDoubleMax, kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem17::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem17::unconstrained_optimal_cost = 5.46489e-5;
Packit ea1746
Packit ea1746
// Biggs EXP6 function.
Packit ea1746
BEGIN_MGH_PROBLEM(TestProblem18, 6, 13)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T x4 = x[3];
Packit ea1746
  const T x5 = x[4];
Packit ea1746
  const T x6 = x[5];
Packit ea1746
Packit ea1746
  for (int i = 0; i < 13; ++i) {
Packit ea1746
    const double ti = 0.1 * (i + 1.0);
Packit ea1746
    const double yi = exp(-ti) - 5.0 * exp(-10.0 * ti) + 3.0 * exp(-4.0 * ti);
Packit ea1746
    residual[i] =
Packit ea1746
        x3 * exp(-ti * x1) - x4 * exp(-ti * x2) + x6 * exp(-ti * x5) - yi;
Packit ea1746
  }
Packit ea1746
  END_MGH_PROBLEM
Packit ea1746
Packit ea1746
  const double TestProblem18::initial_x[] = {1.0, 2.0, 1.0, 1.0, 1.0, 1.0};
Packit ea1746
  const double TestProblem18::lower_bounds[] = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0};
Packit ea1746
  const double TestProblem18::upper_bounds[] = {2.0, 8.0, 1.0, 7.0, 5.0, 5.0};
Packit ea1746
  const double TestProblem18::constrained_optimal_cost = 0.53209865e-3;
Packit ea1746
  const double TestProblem18::unconstrained_optimal_cost = 0.0;
Packit ea1746
Packit ea1746
  // Osborne 2 function.
Packit ea1746
  BEGIN_MGH_PROBLEM(TestProblem19, 11, 65)
Packit ea1746
  const T x1 = x[0];
Packit ea1746
  const T x2 = x[1];
Packit ea1746
  const T x3 = x[2];
Packit ea1746
  const T x4 = x[3];
Packit ea1746
  const T x5 = x[4];
Packit ea1746
  const T x6 = x[5];
Packit ea1746
  const T x7 = x[6];
Packit ea1746
  const T x8 = x[7];
Packit ea1746
  const T x9 = x[8];
Packit ea1746
  const T x10 = x[9];
Packit ea1746
  const T x11 = x[10];
Packit ea1746
Packit ea1746
  const double y[] = {1.366, 1.191, 1.112, 1.013, 0.991,
Packit ea1746
                      0.885, 0.831, 0.847, 0.786, 0.725,
Packit ea1746
                      0.746, 0.679, 0.608, 0.655, 0.616,
Packit ea1746
                      0.606, 0.602, 0.626, 0.651, 0.724,
Packit ea1746
                      0.649, 0.649, 0.694, 0.644, 0.624,
Packit ea1746
                      0.661, 0.612, 0.558, 0.533, 0.495,
Packit ea1746
                      0.500, 0.423, 0.395, 0.375, 0.372,
Packit ea1746
                      0.391, 0.396, 0.405, 0.428, 0.429,
Packit ea1746
                      0.523, 0.562, 0.607, 0.653, 0.672,
Packit ea1746
                      0.708, 0.633, 0.668, 0.645, 0.632,
Packit ea1746
                      0.591, 0.559, 0.597, 0.625, 0.739,
Packit ea1746
                      0.710, 0.729, 0.720, 0.636, 0.581,
Packit ea1746
                      0.428, 0.292, 0.162, 0.098, 0.054};
Packit ea1746
Packit ea1746
  for (int i = 0; i < 65; ++i) {
Packit ea1746
    const double ti = i / 10.0;
Packit ea1746
    residual[i] = y[i] - (x1 * exp(-(ti * x5)) +
Packit ea1746
                          x2 * exp(-(ti - x9)  * (ti - x9)  * x6) +
Packit ea1746
                          x3 * exp(-(ti - x10) * (ti - x10) * x7) +
Packit ea1746
                          x4 * exp(-(ti - x11) * (ti - x11) * x8));
Packit ea1746
  }
Packit ea1746
END_MGH_PROBLEM;
Packit ea1746
Packit ea1746
const double TestProblem19::initial_x[] = {1.3, 0.65, 0.65, 0.7, 0.6,
Packit ea1746
                                           3.0, 5.0, 7.0, 2.0, 4.5, 5.5};
Packit ea1746
const double TestProblem19::lower_bounds[] = {
Packit ea1746
  -kDoubleMax, -kDoubleMax, -kDoubleMax, -kDoubleMax};
Packit ea1746
const double TestProblem19::upper_bounds[] = {
Packit ea1746
  kDoubleMax, kDoubleMax, kDoubleMax, kDoubleMax};
Packit ea1746
const double TestProblem19::constrained_optimal_cost =
Packit ea1746
    std::numeric_limits<double>::quiet_NaN();
Packit ea1746
const double TestProblem19::unconstrained_optimal_cost = 4.01377e-2;
Packit ea1746
Packit ea1746
Packit ea1746
#undef BEGIN_MGH_PROBLEM
Packit ea1746
#undef END_MGH_PROBLEM
Packit ea1746
Packit ea1746
template<typename TestProblem> bool Solve(bool is_constrained, int trial) {
Packit ea1746
  double x[TestProblem::kNumParameters];
Packit ea1746
  for (int i = 0; i < TestProblem::kNumParameters; ++i) {
Packit ea1746
    x[i] = pow(10, trial) * TestProblem::initial_x[i];
Packit ea1746
  }
Packit ea1746
Packit ea1746
  Problem problem;
Packit ea1746
  problem.AddResidualBlock(TestProblem::Create(), NULL, x);
Packit ea1746
  double optimal_cost = TestProblem::unconstrained_optimal_cost;
Packit ea1746
Packit ea1746
  if (is_constrained) {
Packit ea1746
    for (int i = 0; i < TestProblem::kNumParameters; ++i) {
Packit ea1746
      problem.SetParameterLowerBound(x, i, TestProblem::lower_bounds[i]);
Packit ea1746
      problem.SetParameterUpperBound(x, i, TestProblem::upper_bounds[i]);
Packit ea1746
    }
Packit ea1746
    optimal_cost = TestProblem::constrained_optimal_cost;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  Solver::Options options;
Packit ea1746
  options.parameter_tolerance = 1e-18;
Packit ea1746
  options.function_tolerance = 1e-18;
Packit ea1746
  options.gradient_tolerance = 1e-18;
Packit ea1746
  options.max_num_iterations = 1000;
Packit ea1746
  options.linear_solver_type = DENSE_QR;
Packit ea1746
  Solver::Summary summary;
Packit ea1746
  Solve(options, &problem, &summary);
Packit ea1746
Packit ea1746
  const double kMinLogRelativeError = 4.0;
Packit ea1746
  const double log_relative_error = -std::log10(
Packit ea1746
      std::abs(2.0 * summary.final_cost - optimal_cost) /
Packit ea1746
      (optimal_cost > 0.0 ? optimal_cost : 1.0));
Packit ea1746
Packit ea1746
  const bool success = log_relative_error >= kMinLogRelativeError;
Packit ea1746
  LOG(INFO) << "Expected : " <<  optimal_cost
Packit ea1746
            << " actual: " << 2.0 * summary.final_cost
Packit ea1746
            << " " << success
Packit ea1746
            << " in " << summary.total_time_in_seconds
Packit ea1746
            << " seconds";
Packit ea1746
  return success;
Packit ea1746
}
Packit ea1746
Packit ea1746
}  // namespace examples
Packit ea1746
}  // namespace ceres
Packit ea1746
Packit ea1746
int main(int argc, char** argv) {
Packit ea1746
  CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
Packit ea1746
  google::InitGoogleLogging(argv[0]);
Packit ea1746
Packit ea1746
  using ceres::examples::Solve;
Packit ea1746
Packit ea1746
  int unconstrained_problems = 0;
Packit ea1746
  int unconstrained_successes = 0;
Packit ea1746
  int constrained_problems = 0;
Packit ea1746
  int constrained_successes = 0;
Packit ea1746
  std::stringstream ss;
Packit ea1746
Packit ea1746
#define UNCONSTRAINED_SOLVE(n)                                          \
Packit ea1746
  ss << "Unconstrained Problem " << n << " : ";                          \
Packit ea1746
  if (FLAGS_problem == #n || FLAGS_problem == "all") {                  \
Packit ea1746
    unconstrained_problems += 3;                                        \
Packit ea1746
    if (Solve<ceres::examples::TestProblem##n>(false, 0)) {             \
Packit ea1746
      unconstrained_successes += 1;                                     \
Packit ea1746
      ss <<  "Yes ";                                                    \
Packit ea1746
    } else {                                                            \
Packit ea1746
      ss << "No  ";                                                     \
Packit ea1746
    }                                                                   \
Packit ea1746
    if (Solve<ceres::examples::TestProblem##n>(false, 1)) {             \
Packit ea1746
      unconstrained_successes += 1;                                     \
Packit ea1746
      ss << "Yes ";                                                     \
Packit ea1746
    } else {                                                            \
Packit ea1746
      ss << "No  ";                                                     \
Packit ea1746
    }                                                                   \
Packit ea1746
    if (Solve<ceres::examples::TestProblem##n>(false, 2)) {             \
Packit ea1746
      unconstrained_successes += 1;                                     \
Packit ea1746
      ss << "Yes ";                                                     \
Packit ea1746
    } else {                                                            \
Packit ea1746
      ss << "No  ";                                                     \
Packit ea1746
    }                                                                   \
Packit ea1746
  }                                                                     \
Packit ea1746
  ss << std::endl;
Packit ea1746
Packit ea1746
  UNCONSTRAINED_SOLVE(1);
Packit ea1746
  UNCONSTRAINED_SOLVE(2);
Packit ea1746
  UNCONSTRAINED_SOLVE(3);
Packit ea1746
  UNCONSTRAINED_SOLVE(4);
Packit ea1746
  UNCONSTRAINED_SOLVE(5);
Packit ea1746
  UNCONSTRAINED_SOLVE(6);
Packit ea1746
  UNCONSTRAINED_SOLVE(7);
Packit ea1746
  UNCONSTRAINED_SOLVE(8);
Packit ea1746
  UNCONSTRAINED_SOLVE(9);
Packit ea1746
  UNCONSTRAINED_SOLVE(10);
Packit ea1746
  UNCONSTRAINED_SOLVE(11);
Packit ea1746
  UNCONSTRAINED_SOLVE(12);
Packit ea1746
  UNCONSTRAINED_SOLVE(13);
Packit ea1746
  UNCONSTRAINED_SOLVE(14);
Packit ea1746
  UNCONSTRAINED_SOLVE(15);
Packit ea1746
  UNCONSTRAINED_SOLVE(16);
Packit ea1746
  UNCONSTRAINED_SOLVE(17);
Packit ea1746
  UNCONSTRAINED_SOLVE(18);
Packit ea1746
  UNCONSTRAINED_SOLVE(19);
Packit ea1746
Packit ea1746
  ss << "Unconstrained : "
Packit ea1746
     << unconstrained_successes
Packit ea1746
     << "/"
Packit ea1746
     << unconstrained_problems << std::endl;
Packit ea1746
Packit ea1746
#define CONSTRAINED_SOLVE(n)                                            \
Packit ea1746
  ss << "Constrained Problem " << n << " : ";                           \
Packit ea1746
  if (FLAGS_problem == #n || FLAGS_problem == "all") {                  \
Packit ea1746
    constrained_problems += 1;                                          \
Packit ea1746
    if (Solve<ceres::examples::TestProblem##n>(true, 0)) {              \
Packit ea1746
      constrained_successes += 1;                                       \
Packit ea1746
      ss << "Yes ";                                                     \
Packit ea1746
    } else {                                                            \
Packit ea1746
      ss << "No  ";                                                     \
Packit ea1746
    }                                                                   \
Packit ea1746
  }                                                                     \
Packit ea1746
  ss << std::endl;
Packit ea1746
Packit ea1746
  CONSTRAINED_SOLVE(3);
Packit ea1746
  CONSTRAINED_SOLVE(4);
Packit ea1746
  CONSTRAINED_SOLVE(5);
Packit ea1746
  CONSTRAINED_SOLVE(7);
Packit ea1746
  CONSTRAINED_SOLVE(9);
Packit ea1746
  CONSTRAINED_SOLVE(11);
Packit ea1746
  CONSTRAINED_SOLVE(12);
Packit ea1746
  CONSTRAINED_SOLVE(14);
Packit ea1746
  CONSTRAINED_SOLVE(16);
Packit ea1746
  CONSTRAINED_SOLVE(18);
Packit ea1746
  ss << "Constrained : "
Packit ea1746
     << constrained_successes
Packit ea1746
     << "/"
Packit ea1746
     << constrained_problems << std::endl;
Packit ea1746
Packit ea1746
  std::cout << ss.str();
Packit ea1746
  return 0;
Packit ea1746
}