179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Ceres Solver - A fast non-linear least squares minimizer 279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Copyright 2014 Google Inc. All rights reserved. 379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// http://code.google.com/p/ceres-solver/ 479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Redistribution and use in source and binary forms, with or without 679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// modification, are permitted provided that the following conditions are met: 779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// * Redistributions of source code must retain the above copyright notice, 979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// this list of conditions and the following disclaimer. 1079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// * Redistributions in binary form must reproduce the above copyright notice, 1179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// this list of conditions and the following disclaimer in the documentation 1279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// and/or other materials provided with the distribution. 1379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// * Neither the name of Google Inc. nor the names of its contributors may be 1479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// used to endorse or promote products derived from this software without 1579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// specific prior written permission. 1679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 1779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// POSSIBILITY OF SUCH DAMAGE. 2879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 2979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Author: sameeragarwal@google.com (Sameer Agarwal) 3079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 3179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Bounds constrained test problems from the paper 3279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 3379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Testing Unconstrained Optimization Software 3479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Jorge J. More, Burton S. Garbow and Kenneth E. Hillstrom 3579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// ACM Transactions on Mathematical Software, 7(1), pp. 17-41, 1981 3679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 3779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// A subset of these problems were augmented with bounds and used for 3879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// testing bounds constrained optimization algorithms by 3979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 4079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// A Trust Region Approach to Linearly Constrained Optimization 4179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// David M. Gay 4279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Numerical Analysis (Griffiths, D.F., ed.), pp. 72-105 4379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Lecture Notes in Mathematics 1066, Springer Verlag, 1984. 4479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 4579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// The latter paper is behind a paywall. We obtained the bounds on the 4679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// variables and the function values at the global minimums from 4779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 4879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// http://www.mat.univie.ac.at/~neum/glopt/bounds.html 4979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// 5079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// A problem is considered solved if of the log relative error of its 5179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// objective function is at least 5. 5279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 5379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 5479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include <cmath> 5579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include <iostream> // NOLINT 5679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/ceres.h" 5779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "gflags/gflags.h" 5879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "glog/logging.h" 5979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 6079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandeznamespace ceres { 6179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandeznamespace examples { 6279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 6379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double kDoubleMax = std::numeric_limits<double>::max(); 6479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 6579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define BEGIN_MGH_PROBLEM(name, num_parameters, num_residuals) \ 6679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez struct name { \ 6779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez static const int kNumParameters = num_parameters; \ 6879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez static const double initial_x[kNumParameters]; \ 6979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez static const double lower_bounds[kNumParameters]; \ 7079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez static const double upper_bounds[kNumParameters]; \ 7179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez static const double constrained_optimal_cost; \ 7279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez static const double unconstrained_optimal_cost; \ 7379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez static CostFunction* Create() { \ 7479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return new AutoDiffCostFunction<name, \ 7579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_residuals, \ 7679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_parameters>(new name); \ 7779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } \ 7879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez template <typename T> \ 7979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez bool operator()(const T* const x, T* residual) const { 8079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 8179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define END_MGH_PROBLEM return true; } }; // NOLINT 8279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 8379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Rosenbrock function. 8479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem1, 2, 2) 8579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 8679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 8779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[0] = T(10.0) * (x2 - x1 * x1); 8879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[1] = T(1.0) - x1; 8979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 9079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 9179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem1::initial_x[] = {-1.2, 1.0}; 9279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem1::lower_bounds[] = {-kDoubleMax, -kDoubleMax}; 9379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem1::upper_bounds[] = {kDoubleMax, kDoubleMax}; 9479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem1::constrained_optimal_cost = 9579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::numeric_limits<double>::quiet_NaN(); 9679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem1::unconstrained_optimal_cost = 0.0; 9779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 9879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Freudenstein and Roth function. 9979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem2, 2, 2) 10079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 10179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 10279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[0] = T(-13.0) + x1 + ((T(5.0) - x2) * x2 - T(2.0)) * x2; 10379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[1] = T(-29.0) + x1 + ((x2 + T(1.0)) * x2 - T(14.0)) * x2; 10479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 10579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 10679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem2::initial_x[] = {0.5, -2.0}; 10779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem2::lower_bounds[] = {-kDoubleMax, -kDoubleMax}; 10879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem2::upper_bounds[] = {kDoubleMax, kDoubleMax}; 10979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem2::constrained_optimal_cost = 11079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::numeric_limits<double>::quiet_NaN(); 11179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem2::unconstrained_optimal_cost = 0.0; 11279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 11379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Powell badly scaled function. 11479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem3, 2, 2) 11579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 11679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 11779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[0] = T(10000.0) * x1 * x2 - T(1.0); 11879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[1] = exp(-x1) + exp(-x2) - T(1.0001); 11979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 12079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 12179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem3::initial_x[] = {0.0, 1.0}; 12279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem3::lower_bounds[] = {0.0, 1.0}; 12379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem3::upper_bounds[] = {1.0, 9.0}; 12479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem3::constrained_optimal_cost = 0.15125900e-9; 12579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem3::unconstrained_optimal_cost = 0.0; 12679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 12779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Brown badly scaled function. 12879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem4, 2, 3) 12979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 13079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 13179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[0] = x1 - T(1000000.0); 13279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[1] = x2 - T(0.000002); 13379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[2] = x1 * x2 - T(2.0); 13479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 13579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 13679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem4::initial_x[] = {1.0, 1.0}; 13779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem4::lower_bounds[] = {0.0, 0.00003}; 13879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem4::upper_bounds[] = {1000000.0, 100.0}; 13979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem4::constrained_optimal_cost = 0.78400000e3; 14079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem4::unconstrained_optimal_cost = 0.0; 14179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 14279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Beale function. 14379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem5, 2, 3) 14479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 14579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 14679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[0] = T(1.5) - x1 * (T(1.0) - x2); 14779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[1] = T(2.25) - x1 * (T(1.0) - x2 * x2); 14879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[2] = T(2.625) - x1 * (T(1.0) - x2 * x2 * x2); 14979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 15079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 15179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem5::initial_x[] = {1.0, 1.0}; 15279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem5::lower_bounds[] = {0.6, 0.5}; 15379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem5::upper_bounds[] = {10.0, 100.0}; 15479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem5::constrained_optimal_cost = 0.0; 15579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem5::unconstrained_optimal_cost = 0.0; 15679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 15779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Jennrich and Sampson function. 15879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem6, 2, 10) 15979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 16079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 16179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez for (int i = 1; i <= 10; ++i) { 16279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[i - 1] = T(2.0) + T(2.0 * i) - 16379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez exp(T(static_cast<double>(i)) * x1) - 16479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez exp(T(static_cast<double>(i) * x2)); 16579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 16679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 16779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 16879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem6::initial_x[] = {1.0, 1.0}; 16979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem6::lower_bounds[] = {-kDoubleMax, -kDoubleMax}; 17079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem6::upper_bounds[] = {kDoubleMax, kDoubleMax}; 17179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem6::constrained_optimal_cost = 17279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::numeric_limits<double>::quiet_NaN(); 17379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem6::unconstrained_optimal_cost = 124.362; 17479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 17579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Helical valley function. 17679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem7, 3, 3) 17779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 17879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 17979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x3 = x[2]; 18079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T theta = T(0.5 / M_PI) * atan(x2 / x1) + (x1 > 0.0 ? T(0.0) : T(0.5)); 18179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 18279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[0] = T(10.0) * (x3 - T(10.0) * theta); 18379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[1] = T(10.0) * (sqrt(x1 * x1 + x2 * x2) - T(1.0)); 18479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[2] = x3; 18579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 18679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 18779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem7::initial_x[] = {-1.0, 0.0, 0.0}; 18879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem7::lower_bounds[] = {-100.0, -1.0, -1.0}; 18979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem7::upper_bounds[] = {0.8, 1.0, 1.0}; 19079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem7::constrained_optimal_cost = 0.99042212; 19179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem7::unconstrained_optimal_cost = 0.0; 19279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 19379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Bard function 19479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem8, 3, 15) 19579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 19679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 19779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x3 = x[2]; 19879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 19979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez double y[] = {0.14, 0.18, 0.22, 0.25, 20079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 0.29, 0.32, 0.35, 0.39, 0.37, 0.58, 20179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 0.73, 0.96, 1.34, 2.10, 4.39}; 20279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 20379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez for (int i = 1; i <=15; ++i) { 20479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T u = T(static_cast<double>(i)); 20579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T v = T(static_cast<double>(16 - i)); 20679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T w = T(static_cast<double>(std::min(i, 16 - i))); 20779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[i - 1] = T(y[i - 1]) - x1 + u / (v * x2 + w * x3); 20879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 20979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 21079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 21179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem8::initial_x[] = {1.0, 1.0, 1.0}; 21279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem8::lower_bounds[] = { 21379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez -kDoubleMax, -kDoubleMax, -kDoubleMax}; 21479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem8::upper_bounds[] = { 21579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez kDoubleMax, kDoubleMax, kDoubleMax}; 21679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem8::constrained_optimal_cost = 21779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::numeric_limits<double>::quiet_NaN(); 21879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem8::unconstrained_optimal_cost = 8.21487e-3; 21979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 22079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Gaussian function. 22179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem9, 3, 15) 22279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 22379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 22479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x3 = x[2]; 22579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 22679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const double y[] = {0.0009, 0.0044, 0.0175, 0.0540, 0.1295, 0.2420, 0.3521, 22779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 0.3989, 22879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 0.3521, 0.2420, 0.1295, 0.0540, 0.0175, 0.0044, 0.0009}; 22979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez for (int i = 0; i < 15; ++i) { 23079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T t_i = T((8.0 - i - 1.0) / 2.0); 23179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T y_i = T(y[i]); 23279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[i] = x1 * exp(-x2 * (t_i - x3) * (t_i - x3) / T(2.0)) - y_i; 23379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 23479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM; 23579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 23679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem9::initial_x[] = {0.4, 1.0, 0.0}; 23779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem9::lower_bounds[] = {0.398, 1.0, -0.5}; 23879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem9::upper_bounds[] = {4.2, 2.0, 0.1}; 23979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem9::constrained_optimal_cost = 0.11279300e-7; 24079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem9::unconstrained_optimal_cost = 0.112793e-7; 24179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 24279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Meyer function. 24379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezBEGIN_MGH_PROBLEM(TestProblem10, 3, 16) 24479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x1 = x[0]; 24579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x2 = x[1]; 24679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const T x3 = x[2]; 24779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 24879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const double y[] = {34780, 28610, 23650, 19630, 16370, 13720, 11540, 9744, 24979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 8261, 7030, 6005, 5147, 4427, 3820, 3307, 2872}; 25079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 25179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez for (int i = 0; i < 16; ++i) { 25279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez T t = T(45 + 5.0 * (i + 1)); 25379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez residual[i] = x1 * exp(x2 / (t + x3)) - y[i]; 25479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 25579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezEND_MGH_PROBLEM 25679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 25779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 25879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem10::initial_x[] = {0.02, 4000, 250}; 25979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem10::lower_bounds[] ={ 26079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez -kDoubleMax, -kDoubleMax, -kDoubleMax}; 26179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem10::upper_bounds[] ={ 26279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez kDoubleMax, kDoubleMax, kDoubleMax}; 26379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem10::constrained_optimal_cost = 26479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::numeric_limits<double>::quiet_NaN(); 26579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezconst double TestProblem10::unconstrained_optimal_cost = 87.9458; 26679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 26779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef BEGIN_MGH_PROBLEM 26879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef END_MGH_PROBLEM 26979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 27079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandeztemplate<typename TestProblem> string ConstrainedSolve() { 27179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez double x[TestProblem::kNumParameters]; 27279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::copy(TestProblem::initial_x, 27379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez TestProblem::initial_x + TestProblem::kNumParameters, 27479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez x); 27579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 27679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Problem problem; 27779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez problem.AddResidualBlock(TestProblem::Create(), NULL, x); 27879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez for (int i = 0; i < TestProblem::kNumParameters; ++i) { 27979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez problem.SetParameterLowerBound(x, i, TestProblem::lower_bounds[i]); 28079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez problem.SetParameterUpperBound(x, i, TestProblem::upper_bounds[i]); 28179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 28279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 28379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Solver::Options options; 28479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.parameter_tolerance = 1e-18; 28579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.function_tolerance = 1e-18; 28679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.gradient_tolerance = 1e-18; 28779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.max_num_iterations = 1000; 28879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.linear_solver_type = DENSE_QR; 28979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Solver::Summary summary; 29079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Solve(options, &problem, &summary); 29179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 29279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const double kMinLogRelativeError = 5.0; 29379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const double log_relative_error = -std::log10( 29479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::abs(2.0 * summary.final_cost - 29579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez TestProblem::constrained_optimal_cost) / 29679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez (TestProblem::constrained_optimal_cost > 0.0 29779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ? TestProblem::constrained_optimal_cost 29879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez : 1.0)); 29979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 30079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return (log_relative_error >= kMinLogRelativeError 30179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ? "Success\n" 30279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez : "Failure\n"); 30379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} 30479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 30579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandeztemplate<typename TestProblem> string UnconstrainedSolve() { 30679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez double x[TestProblem::kNumParameters]; 30779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::copy(TestProblem::initial_x, 30879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez TestProblem::initial_x + TestProblem::kNumParameters, 30979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez x); 31079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 31179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Problem problem; 31279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez problem.AddResidualBlock(TestProblem::Create(), NULL, x); 31379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 31479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Solver::Options options; 31579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.parameter_tolerance = 1e-18; 31679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.function_tolerance = 0.0; 31779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.gradient_tolerance = 1e-18; 31879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.max_num_iterations = 1000; 31979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.linear_solver_type = DENSE_QR; 32079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Solver::Summary summary; 32179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez Solve(options, &problem, &summary); 32279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 32379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const double kMinLogRelativeError = 5.0; 32479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez const double log_relative_error = -std::log10( 32579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::abs(2.0 * summary.final_cost - 32679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez TestProblem::unconstrained_optimal_cost) / 32779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez (TestProblem::unconstrained_optimal_cost > 0.0 32879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ? TestProblem::unconstrained_optimal_cost 32979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez : 1.0)); 33079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 33179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return (log_relative_error >= kMinLogRelativeError 33279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ? "Success\n" 33379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez : "Failure\n"); 33479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} 33579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 33679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} // namespace examples 33779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} // namespace ceres 33879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 33979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezint main(int argc, char** argv) { 34079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez google::ParseCommandLineFlags(&argc, &argv, true); 34179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez google::InitGoogleLogging(argv[0]); 34279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 34379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez using ceres::examples::UnconstrainedSolve; 34479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez using ceres::examples::ConstrainedSolve; 34579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 34679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define UNCONSTRAINED_SOLVE(n) \ 34779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::cout << "Problem " << n << " : " \ 34879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << UnconstrainedSolve<ceres::examples::TestProblem##n>(); 34979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 35079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define CONSTRAINED_SOLVE(n) \ 35179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::cout << "Problem " << n << " : " \ 35279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << ConstrainedSolve<ceres::examples::TestProblem##n>(); 35379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 35479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::cout << "Unconstrained problems\n"; 35579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(1); 35679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(2); 35779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(3); 35879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(4); 35979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(5); 36079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(6); 36179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(7); 36279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(8); 36379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(9); 36479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez UNCONSTRAINED_SOLVE(10); 36579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 36679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::cout << "\nConstrained problems\n"; 36779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CONSTRAINED_SOLVE(3); 36879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CONSTRAINED_SOLVE(4); 36979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CONSTRAINED_SOLVE(5); 37079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CONSTRAINED_SOLVE(7); 37179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CONSTRAINED_SOLVE(9); 37279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 37379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return 0; 37479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} 375