5#ifndef LINE_UTIL_LSTSQ_H
6#define LINE_UTIL_LSTSQ_H
72 for (std::size_t i = 0; i < A.
rows(); ++i)
73 for (std::size_t j = 0; j < A.
cols(); ++j) {
74 const T a =
num_abs(T(A(i, j)));
84void normal_equations(
const Matrix<T>& A,
const std::vector<T>& b, Matrix<T>& G,
86 const std::size_t m = A.rows(), n = A.cols();
87 const T zero = num_traits<T>::from_int(0);
90 for (std::size_t i = 0; i < n; ++i) {
91 for (std::size_t j = i; j < n; ++j) {
93 for (std::size_t k = 0; k < m; ++k) s += A(k, i) * A(k, j);
98 for (std::size_t k = 0; k < m; ++k) s += A(k, i) * b[k];
111 const std::size_t m = A.
rows(), n = A.
cols();
113 std::vector<std::size_t> piv;
115 for (std::size_t c = 0; c < n && r < m; ++c) {
118 for (std::size_t i = r + 1; i < m; ++i) {
119 const T a =
num_abs(T(A(i, c)));
125 if (!(best > tol))
continue;
127 for (std::size_t j = 0; j < n; ++j) std::swap(A(r, j), A(p, j));
129 for (std::size_t j = 0; j < n; ++j) A(r, j) /= d;
131 for (std::size_t i = 0; i < m; ++i) {
132 if (i == r)
continue;
134 if (f == zero)
continue;
135 for (std::size_t j = 0; j < n; ++j) A(i, j) -= f * A(r, j);
153 const std::size_t m = A.
rows(), n = A.
cols();
154 if (b.size() != m)
throw InputError(
"lstsq: rhs length mismatch");
155 if (n == 0)
throw InputError(
"lstsq: empty system");
159 const std::vector<std::size_t> pivcols =
rref(Rf, tol);
160 const std::size_t k = pivcols.size();
169 detail::normal_equations(A, b, G, c);
174 res.
x.assign(n, zero);
181 for (std::size_t j = 0; j < k; ++j)
182 for (std::size_t i = 0; i < m; ++i) C(i, j) = A(i, pivcols[j]);
183 for (std::size_t i = 0; i < k; ++i)
184 for (std::size_t j = 0; j < n; ++j) F(i, j) = Rf(i, j);
189 detail::normal_equations(C, b, CtC, Ctb);
190 const std::vector<T> y =
solve(CtC, Ctb);
194 for (std::size_t i = 0; i < k; ++i)
195 for (std::size_t j = i; j < k; ++j) {
197 for (std::size_t t = 0; t < n; ++t) s += F(i, t) * F(j, t);
201 const std::vector<T> w =
solve(FFt, y);
202 res.
x.assign(n, zero);
203 for (std::size_t t = 0; t < n; ++t) {
205 for (std::size_t i = 0; i < k; ++i) s += F(i, t) * w[i];
214 return lstsq(A, b, detail::lstsq_tolerance(A));
The exception types the port throws.
LU factorization with partial pivoting, templated on the number type.
Dense matrix and non-owning view.
std::vector< std::size_t > rref(Matrix< T > &A, const T &tol)
Reduced row echelon form of A, in place, returning the pivot columns.
LstsqResult< T > lstsq(const Matrix< T > &A, const std::vector< T > &b, const T &tol)
Least-squares solution of A x = b, minimum-norm when A is rank deficient.
std::vector< T > solve(const Matrix< T > &A, const std::vector< T > &b)
Convenience: solve Ax = b, leaving A and b untouched.
Number-type abstraction for the templated API port.
Outcome of lstsq: the solution and whether the system was rank deficient.