10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Ceres Solver - A fast non-linear least squares minimizer 20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Copyright 2010, 2011, 2012 Google Inc. All rights reserved. 30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// http://code.google.com/p/ceres-solver/ 40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Redistribution and use in source and binary forms, with or without 60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// modification, are permitted provided that the following conditions are met: 70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions of source code must retain the above copyright notice, 90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// this list of conditions and the following disclaimer. 100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions in binary form must reproduce the above copyright notice, 110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// this list of conditions and the following disclaimer in the documentation 120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// and/or other materials provided with the distribution. 130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Neither the name of Google Inc. nor the names of its contributors may be 140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// used to endorse or promote products derived from this software without 150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// specific prior written permission. 160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// POSSIBILITY OF SUCH DAMAGE. 280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Author: sameeragarwal@google.com (Sameer Agarwal) 300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/loss_function.h" 320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <cstddef> 340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "glog/logging.h" 360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "gtest/gtest.h" 370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace ceres { 390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace internal { 400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace { 410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Helper function for testing a LossFunction callback. 430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Compares the values of rho'(s) and rho''(s) computed by the 450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// callback with estimates obtained by symmetric finite differencing 460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// of rho(s). 470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid AssertLossFunctionIsValid(const LossFunction& loss, double s) { 480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CHECK_GT(s, 0); 490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Evaluate rho(s), rho'(s) and rho''(s). 510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double rho[3]; 520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss.Evaluate(s, rho); 530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Use symmetric finite differencing to estimate rho'(s) and 550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // rho''(s). 560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const double kH = 1e-4; 570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Values at s + kH. 580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double fwd[3]; 590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Values at s - kH. 600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double bwd[3]; 610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss.Evaluate(s + kH, fwd); 620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss.Evaluate(s - kH, bwd); 630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // First derivative. 650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const double fd_1 = (fwd[0] - bwd[0]) / (2 * kH); 660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ASSERT_NEAR(fd_1, rho[1], 1e-6); 670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Second derivative. 690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong const double fd_2 = (fwd[0] - 2*rho[0] + bwd[0]) / (kH * kH); 700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ASSERT_NEAR(fd_2, rho[2], 1e-6); 710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} // namespace 730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Try two values of the scaling a = 0.7 and 1.3 750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// (where scaling makes sense) and of the squared norm 760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// s = 0.357 and 1.792 770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Note that for the Huber loss the test exercises both code paths 790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// (i.e. both small and large values of s). 800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, TrivialLoss) { 820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TrivialLoss(), 0.357); 830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TrivialLoss(), 1.792); 840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, HuberLoss) { 870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(HuberLoss(0.7), 0.357); 880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(HuberLoss(0.7), 1.792); 890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(HuberLoss(1.3), 0.357); 900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(HuberLoss(1.3), 1.792); 910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, SoftLOneLoss) { 940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(SoftLOneLoss(0.7), 0.357); 950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(SoftLOneLoss(0.7), 1.792); 960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(SoftLOneLoss(1.3), 0.357); 970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(SoftLOneLoss(1.3), 1.792); 980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, CauchyLoss) { 1010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(CauchyLoss(0.7), 0.357); 1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(CauchyLoss(0.7), 1.792); 1030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(CauchyLoss(1.3), 0.357); 1040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(CauchyLoss(1.3), 1.792); 1050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, ArctanLoss) { 1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(ArctanLoss(0.7), 0.357); 1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(ArctanLoss(0.7), 1.792); 1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(ArctanLoss(1.3), 0.357); 1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(ArctanLoss(1.3), 1.792); 1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, TolerantLoss) { 1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(0.7, 0.4), 0.357); 1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(0.7, 0.4), 1.792); 1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(0.7, 0.4), 55.5); 1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(1.3, 0.1), 0.357); 1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(1.3, 0.1), 1.792); 1200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(1.3, 0.1), 55.5); 1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Check the value at zero is actually zero. 1220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double rho[3]; 1230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong TolerantLoss(0.7, 0.4).Evaluate(0.0, rho); 1240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ASSERT_NEAR(rho[0], 0.0, 1e-6); 1250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Check that loss before and after the approximation threshold are good. 1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // A threshold of 36.7 is used by the implementation. 1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(20.0, 1.0), 20.0 + 36.6); 1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(20.0, 1.0), 20.0 + 36.7); 1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(20.0, 1.0), 20.0 + 36.8); 1300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(TolerantLoss(20.0, 1.0), 20.0 + 1000.0); 1310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, ComposedLoss) { 1340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong HuberLoss f(0.7); 1360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CauchyLoss g(1.3); 1370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ComposedLoss c(&f, DO_NOT_TAKE_OWNERSHIP, &g, DO_NOT_TAKE_OWNERSHIP); 1380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(c, 0.357); 1390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(c, 1.792); 1400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong CauchyLoss f(0.7); 1430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong HuberLoss g(1.3); 1440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ComposedLoss c(&f, DO_NOT_TAKE_OWNERSHIP, &g, DO_NOT_TAKE_OWNERSHIP); 1450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(c, 0.357); 1460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(c, 1.792); 1470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, ScaledLoss) { 1510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Wrap a few loss functions, and a few scale factors. This can't combine 1520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // construction with the call to AssertLossFunctionIsValid() because Apple's 1530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // GCC is unable to eliminate the copy of ScaledLoss, which is not copyable. 1540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss(NULL, 6, TAKE_OWNERSHIP); 1560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 0.323); 1570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss(new TrivialLoss(), 10, TAKE_OWNERSHIP); 1600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 0.357); 1610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss(new HuberLoss(0.7), 0.1, TAKE_OWNERSHIP); 1640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 1.792); 1650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss(new SoftLOneLoss(1.3), 0.1, TAKE_OWNERSHIP); 1680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 1.792); 1690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss(new CauchyLoss(1.3), 10, TAKE_OWNERSHIP); 1720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 1.792); 1730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss(new ArctanLoss(1.3), 10, TAKE_OWNERSHIP); 1760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 1.792); 1770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss( 1800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong new TolerantLoss(1.3, 0.1), 10, TAKE_OWNERSHIP); 1810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 1.792); 1820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong { 1840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong ScaledLoss scaled_loss( 1850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong new ComposedLoss( 1860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong new HuberLoss(0.8), TAKE_OWNERSHIP, 1870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong new TolerantLoss(1.3, 0.5), TAKE_OWNERSHIP), 10, TAKE_OWNERSHIP); 1880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong AssertLossFunctionIsValid(scaled_loss, 1.792); 1890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 1900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 1910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongTEST(LossFunction, LossFunctionWrapper) { 1930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Initialization 1940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong HuberLoss loss_function1(1.0); 1950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong LossFunctionWrapper loss_function_wrapper(new HuberLoss(1.0), 1960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong TAKE_OWNERSHIP); 1970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 1980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double s = 0.862; 1990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double rho_gold[3]; 2000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double rho[3]; 2010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function1.Evaluate(s, rho_gold); 2020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function_wrapper.Evaluate(s, rho); 2030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < 3; ++i) { 2040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong EXPECT_NEAR(rho[i], rho_gold[i], 1e-12); 2050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Resetting 2080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong HuberLoss loss_function2(0.5); 2090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function_wrapper.Reset(new HuberLoss(0.5), TAKE_OWNERSHIP); 2100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function_wrapper.Evaluate(s, rho); 2110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function2.Evaluate(s, rho_gold); 2120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < 3; ++i) { 2130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong EXPECT_NEAR(rho[i], rho_gold[i], 1e-12); 2140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Not taking ownership. 2170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong HuberLoss loss_function3(0.3); 2180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function_wrapper.Reset(&loss_function3, DO_NOT_TAKE_OWNERSHIP); 2190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function_wrapper.Evaluate(s, rho); 2200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong loss_function3.Evaluate(s, rho_gold); 2210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong for (int i = 0; i < 3; ++i) { 2220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong EXPECT_NEAR(rho[i], rho_gold[i], 1e-12); 2230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 2240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 2250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 2260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} // namespace internal 2270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} // namespace ceres 228