mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-30 00:50:37 +08:00
Add readme for the sampled_function example.
Change-Id: I9468b6a7b9f2ffdd2bf9f0dd1f4e1d5f894e540c
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# Ceres Solver - A fast non-linear least squares minimizer
|
||||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
# http://ceres-solver.org/
|
||||
#
|
||||
# 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: vitus@google.com (Michael Vitus)
|
||||
|
||||
# Only Ceres itself should be compiled with CERES_BUILDING_SHARED_LIBRARY
|
||||
# defined, any users of Ceres will have CERES_USING_SHARED_LIBRARY defined
|
||||
# for them in Ceres' config.h if appropriate.
|
||||
if (BUILD_SHARED_LIBS)
|
||||
remove_definitions(-DCERES_BUILDING_SHARED_LIBRARY)
|
||||
endif()
|
||||
|
||||
add_executable(sampled_function sampled_function.cc)
|
||||
target_link_libraries(sampled_function ceres)
|
||||
@@ -0,0 +1,42 @@
|
||||
Sampled Functions
|
||||
--
|
||||
|
||||
It is common to not have an analytical representation of the optimization
|
||||
problem but rather a table of values at specific inputs. This commonly occurs
|
||||
when working with images or when the functions in the problem are expensive to
|
||||
evaluate. To use this data in an optimization problem we can use interpolation
|
||||
to evaluate the function and derivatives at intermediate input values.
|
||||
|
||||
There are many libraries that implement a variety of interpolation schemes, but
|
||||
it is difficult to use them in Ceres' automatic differentiation framework.
|
||||
Instead, Ceres provides the ability to interpolate one and two dimensional data.
|
||||
|
||||
The one dimensional interpolation is based on the Cubic Hermite Spline. This
|
||||
interpolation method requires knowledge of the function derivatives at the
|
||||
control points, however we only know the function values. Consequently, we will
|
||||
use the data to estimate derivatives at the control points. The choice of how to
|
||||
compute the derivatives is not unique and Ceres uses the Catmull–Rom Spline
|
||||
variant which uses `0.5 * (p_{k+1} - p_{k-1})` as the derivative for control
|
||||
point `p_k.` This produces a first order differentiable interpolating
|
||||
function. The two dimensional interpolation scheme is a generalization of the
|
||||
one dimensional scheme where the interpolating function is assumed to be
|
||||
separable in the two dimensions.
|
||||
|
||||
This example shows how to use interpolation schemes within the Ceres automatic
|
||||
differentiation framework. This is a one dimensional example and the objective
|
||||
function is to minimize `0.5 * f(x)^2` where `f(x) = (x - 4.5)^2`.
|
||||
|
||||
It is also possible to use analytical derivatives with the provided
|
||||
interpolation schemes by using a `SizedCostFunction` and defining the
|
||||
``Evaluate` function. For this example, the evaluate function would be:
|
||||
|
||||
```c++
|
||||
bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const {
|
||||
if (jacobians == NULL || jacobians[0] == NULL)
|
||||
interpolator_.Evaluate(parameters[0][0], residuals);
|
||||
else
|
||||
interpolator_.Evaluate(parameters[0][0], residuals, jacobians[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,94 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// http://ceres-solver.org/
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// A simple example of optimizing a sampled function by using cubic
|
||||
// interpolation.
|
||||
|
||||
#include "ceres/ceres.h"
|
||||
#include "ceres/cubic_interpolation.h"
|
||||
#include "glog/logging.h"
|
||||
|
||||
using ceres::Grid1D;
|
||||
using ceres::CubicInterpolator;
|
||||
using ceres::AutoDiffCostFunction;
|
||||
using ceres::CostFunction;
|
||||
using ceres::Problem;
|
||||
using ceres::Solver;
|
||||
using ceres::Solve;
|
||||
|
||||
// A simple cost functor that interfaces an interpolated table of
|
||||
// values with automatic differentiation.
|
||||
struct InterpolatedCostFunctor {
|
||||
explicit InterpolatedCostFunctor(
|
||||
const CubicInterpolator<Grid1D<double> >& interpolator)
|
||||
: interpolator_(interpolator) {
|
||||
}
|
||||
|
||||
template<typename T> bool operator()(const T* x, T* residuals) const {
|
||||
interpolator_.Evaluate(*x, residuals);
|
||||
return true;
|
||||
}
|
||||
|
||||
static CostFunction* Create(
|
||||
const CubicInterpolator<Grid1D<double> >& interpolator) {
|
||||
return new AutoDiffCostFunction<InterpolatedCostFunctor, 1, 1>(
|
||||
new InterpolatedCostFunctor(interpolator));
|
||||
}
|
||||
|
||||
private:
|
||||
const CubicInterpolator<Grid1D<double> >& interpolator_;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
// Evaluate the function f(x) = (x - 4.5)^2;
|
||||
const int kNumSamples = 10;
|
||||
double values[kNumSamples];
|
||||
for (int i = 0; i < kNumSamples; ++i) {
|
||||
values[i] = (i - 4.5) * (i - 4.5);
|
||||
}
|
||||
|
||||
Grid1D<double> array(values, 0, kNumSamples);
|
||||
CubicInterpolator<Grid1D<double> > interpolator(array);
|
||||
|
||||
double x = 1.0;
|
||||
Problem problem;
|
||||
CostFunction* cost_function = InterpolatedCostFunctor::Create(interpolator);
|
||||
problem.AddResidualBlock(cost_function, NULL, &x);
|
||||
|
||||
Solver::Options options;
|
||||
options.minimizer_progress_to_stdout = true;
|
||||
Solver::Summary summary;
|
||||
Solve(options, &problem, &summary);
|
||||
std::cout << summary.BriefReport() << "\n";
|
||||
std::cout << "Expected x: 4.5. Actual x : " << x << std::endl;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user