blob: 1b0ee65e4db9d0c85adf216e485609be5f4526b0 [file] [log] [blame]
Sameer Agarwal6d06e9b2022-01-21 18:33:16 -08001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2022 Google Inc. All rights reserved.
3// http://ceres-solver.org/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: sameeragarwal@google.com (Sameer Agarwal)
30
31#include "ceres/dense_cholesky.h"
32
33#include <memory>
34#include <numeric>
35#include <vector>
36
37#include "Eigen/Dense"
38#include "ceres/internal/eigen.h"
39#include "ceres/linear_solver.h"
40#include "glog/logging.h"
41#include "gmock/gmock.h"
42#include "gtest/gtest.h"
43
44namespace ceres {
45namespace internal {
46
47typedef DenseLinearAlgebraLibraryType Param;
48
49std::string ParamInfoToString(testing::TestParamInfo<Param> info) {
50 return DenseLinearAlgebraLibraryTypeToString(info.param);
51}
52
53class DenseCholeskyTest : public ::testing::TestWithParam<Param> {};
54
55TEST_P(DenseCholeskyTest, FactorAndSolve) {
56 // TODO(sameeragarwal): Convert these tests into type parameterized tests so
57 // that we can test the single and double precision solvers.
58
59 using Scalar = double;
60 using MatrixType = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
61 using VectorType = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
62
63 LinearSolver::Options options;
64 options.dense_linear_algebra_library_type = GetParam();
65 std::unique_ptr<DenseCholesky> dense_cholesky =
66 DenseCholesky::Create(options);
67
68 const int kNumTrials = 10;
69 const int kMinNumCols = 1;
70 const int kMaxNumCols = 10;
71
72 for (int num_cols = kMinNumCols; num_cols < kMaxNumCols; ++num_cols) {
73 for (int trial = 0; trial < kNumTrials; ++trial) {
74 const MatrixType a = MatrixType::Random(num_cols, num_cols);
75 MatrixType lhs = a.transpose() * a;
76 lhs += VectorType::Ones(num_cols).asDiagonal();
77 Vector x = VectorType::Random(num_cols);
78 Vector rhs = lhs * x;
79 Vector actual = Vector::Random(num_cols);
80
81 LinearSolver::Summary summary;
82 summary.termination_type = dense_cholesky->FactorAndSolve(
83 num_cols, lhs.data(), rhs.data(), actual.data(), &summary.message);
84 EXPECT_EQ(summary.termination_type, LINEAR_SOLVER_SUCCESS);
85 EXPECT_NEAR((x - actual).norm() / x.norm(),
86 0.0,
87 std::numeric_limits<double>::epsilon() * 10)
88 << "\nexpected: " << x.transpose()
89 << "\nactual : " << actual.transpose();
90 }
91 }
92}
93
94#ifndef CERES_NO_LAPACK
95INSTANTIATE_TEST_SUITE_P(_,
96 DenseCholeskyTest,
97 ::testing::Values(EIGEN, LAPACK),
98 ParamInfoToString);
99#else
100INSTANTIATE_TEST_SUITE_P(_,
101 DenseCholeskyTest,
102 ::testing::Values(EIGEN),
103 ParamInfoToString);
104#endif
105
106} // namespace internal
107} // namespace ceres