blob: 55f68e526a0d5eff41c48f36df31eb8b4a7aef99 [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2015 Google Inc. All rights reserved.
3// http://code.google.com/p/ceres-solver/
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: vitus@google.com (Michael Vitus)
30
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080031#ifndef CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
32#define CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_
Austin Schuh70cc9552019-01-21 19:46:48 -080033
34#include "Eigen/Core"
35#include "glog/logging.h"
36
37namespace ceres {
38namespace internal {
39
40// Algorithm 5.1.1 from 'Matrix Computations' by Golub et al. (Johns Hopkins
41// Studies in Mathematical Sciences) but using the nth element of the input
42// vector as pivot instead of first. This computes the vector v with v(n) = 1
43// and beta such that H = I - beta * v * v^T is orthogonal and
44// H * x = ||x||_2 * e_n.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080045//
46// NOTE: Some versions of MSVC have trouble deducing the type of v if
47// you do not specify all the template arguments explicitly.
48template <typename XVectorType, typename Scalar, int N>
49void ComputeHouseholderVector(const XVectorType& x,
50 Eigen::Matrix<Scalar, N, 1>* v,
Austin Schuh70cc9552019-01-21 19:46:48 -080051 Scalar* beta) {
52 CHECK(beta != nullptr);
53 CHECK(v != nullptr);
54 CHECK_GT(x.rows(), 1);
55 CHECK_EQ(x.rows(), v->rows());
56
57 Scalar sigma = x.head(x.rows() - 1).squaredNorm();
58 *v = x;
59 (*v)(v->rows() - 1) = Scalar(1.0);
60
61 *beta = Scalar(0.0);
62 const Scalar& x_pivot = x(x.rows() - 1);
63
64 if (sigma <= Scalar(std::numeric_limits<double>::epsilon())) {
65 if (x_pivot < Scalar(0.0)) {
66 *beta = Scalar(2.0);
67 }
68 return;
69 }
70
71 const Scalar mu = sqrt(x_pivot * x_pivot + sigma);
72 Scalar v_pivot = Scalar(1.0);
73
74 if (x_pivot <= Scalar(0.0)) {
75 v_pivot = x_pivot - mu;
76 } else {
77 v_pivot = -sigma / (x_pivot + mu);
78 }
79
80 *beta = Scalar(2.0) * v_pivot * v_pivot / (sigma + v_pivot * v_pivot);
81
82 v->head(v->rows() - 1) /= v_pivot;
83}
84
85} // namespace internal
86} // namespace ceres
87
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080088#endif // CERES_PUBLIC_INTERNAL_HOUSEHOLDER_VECTOR_H_