numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
full_gen_tikhonov.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <type_traits>
23
24#include <Eigen/Core>
25#include <Eigen/Householder>
26
36
38
40constexpr auto full_gen_tikhonov_tag =
41 logging::log_tag_view("num_collect::regularization::full_gen_tikhonov");
42
51template <base::concepts::dense_matrix Coeff, base::concepts::dense_matrix Data>
53 : public explicit_regularized_solver_base<full_gen_tikhonov<Coeff, Data>,
54 Data> {
55public:
57 using base_type =
59
60 using typename base_type::data_type;
61 using typename base_type::scalar_type;
62
64 using coeff_type = Coeff;
65
66 static_assert(std::is_same_v<typename coeff_type::Scalar,
67 typename data_type::Scalar>);
68 static_assert(data_type::RowsAtCompileTime == Eigen::Dynamic);
69
74
85 void compute(const coeff_type& coeff, const data_type& data,
86 const coeff_type& reg_coeff) {
87 NUM_COLLECT_PRECONDITION(coeff.rows() == data.rows(), this->logger(),
88 "The number of rows in the coefficient matrix must match the "
89 "number of rows in data.");
90 NUM_COLLECT_PRECONDITION(coeff.cols() == reg_coeff.cols(),
91 this->logger(),
92 "The number of columns in the coefficient matrix must match the "
93 "number of columns in the coefficient matrix of the regularization "
94 "term.");
95 NUM_COLLECT_PRECONDITION(reg_coeff.rows() < reg_coeff.cols(),
96 this->logger(),
97 "Coefficient matrix for the regularization term must have rows "
98 "less than columns.");
99
100 // How can I implement those complex formulas with good variable names.
101
102 const index_type m = coeff.rows();
103 const index_type n = coeff.cols();
104 const index_type p = reg_coeff.rows();
105
106 Eigen::ColPivHouseholderQR<coeff_type> qr_reg_adj;
107 qr_reg_adj.compute(reg_coeff.adjoint());
108 NUM_COLLECT_PRECONDITION(qr_reg_adj.rank() >= qr_reg_adj.cols(),
109 this->logger(), "reg_coeff must have full row rank.");
110 const coeff_type v = qr_reg_adj.householderQ();
111
112 Eigen::ColPivHouseholderQR<coeff_type> qr_coeff_v2;
113 qr_coeff_v2.compute(coeff * v.rightCols(n - p));
114 NUM_COLLECT_PRECONDITION(qr_coeff_v2.rank() >= qr_coeff_v2.cols(),
115 this->logger(),
116 "reg_coeff and coeff must not have common elements "
117 "other than zero in their kernel.");
118 const coeff_type q = qr_coeff_v2.householderQ();
119
120 const coeff_type coeff_arr =
121 qr_reg_adj.solve(coeff.adjoint() * q.rightCols(m - n + p))
122 .adjoint();
123 const data_type data_arr = q.rightCols(m - n + p).adjoint() * data;
124 tikhonov_.compute(coeff_arr, data_arr);
125
126 const coeff_type coeff_v2_inv_coeff = qr_coeff_v2.solve(coeff);
127 const coeff_type i_minus_v2_coeff_v2_inv_coeff =
128 coeff_type::Identity(n, n) -
129 v.rightCols(n - p) * coeff_v2_inv_coeff;
131 qr_reg_adj.solve(i_minus_v2_coeff_v2_inv_coeff.adjoint()).adjoint();
132
133 const data_type coeff_v2_inv_data = qr_coeff_v2.solve(data);
134 offset_actual_solution_ = v.rightCols(n - p) * coeff_v2_inv_data;
135 }
136
138 void solve(const scalar_type& param, data_type& solution) const {
139 data_type tikhonov_solution;
140 tikhonov_.solve(param, tikhonov_solution);
141 solution = coeff_actual_solution_ * tikhonov_solution +
143 }
144
150 [[nodiscard]] auto singular_values() const -> const
151 typename Eigen::BDCSVD<coeff_type>::SingularValuesType& {
152 return tikhonov_.singular_values();
153 }
154
156 [[nodiscard]] auto residual_norm(const scalar_type& param) const
157 -> scalar_type {
158 return tikhonov_.residual_norm(param);
159 }
160
162 [[nodiscard]] auto regularization_term(const scalar_type& param) const
163 -> scalar_type {
164 return tikhonov_.regularization_term(param);
165 }
166
169 const scalar_type& param) const -> scalar_type {
170 return tikhonov_.first_derivative_of_residual_norm(param);
171 }
172
175 const scalar_type& param) const -> scalar_type {
176 return tikhonov_.first_derivative_of_regularization_term(param);
177 }
178
181 const scalar_type& param) const -> scalar_type {
182 return tikhonov_.second_derivative_of_residual_norm(param);
183 }
184
187 const scalar_type& param) const -> scalar_type {
188 return tikhonov_.second_derivative_of_regularization_term(param);
189 }
190
192 [[nodiscard]] auto sum_of_filter_factor(const scalar_type& param) const
193 -> scalar_type {
194 return tikhonov_.sum_of_filter_factor(param);
195 }
196
198 [[nodiscard]] auto data_size() const -> index_type {
199 return tikhonov_.data_size();
200 }
201
203 [[nodiscard]] auto param_search_region() const
204 -> std::pair<scalar_type, scalar_type> {
205 return tikhonov_.param_search_region();
206 }
207
213 [[nodiscard]] auto internal_solver() const
214 -> const tikhonov<coeff_type, data_type>& {
215 return tikhonov_;
216 }
217
218private:
221
224
227};
228
229} // namespace num_collect::regularization
Definition of assertion macros.
Class of tags of logs without memory management.
Data offset_actual_solution_
Offset vector to calculate actual solution.
auto second_derivative_of_regularization_term(const scalar_type &param) const -> scalar_type
Calculate the send-order derivative of the Regularization term.
auto sum_of_filter_factor(const scalar_type &param) const -> scalar_type
Calculate the sum of filter factors.
auto first_derivative_of_residual_norm(const scalar_type &param) const -> scalar_type
Calculate the first-order derivative of the squared norm of the residual.
tikhonov< coeff_type, data_type > tikhonov_
Object to perform Tikhonov regularization.
auto regularization_term(const scalar_type &param) const -> scalar_type
Calculate the regularization term.
void solve(const scalar_type &param, data_type &solution) const
Solve for a regularization parameter.
auto residual_norm(const scalar_type &param) const -> scalar_type
Calculate the squared norm of the residual.
void compute(const coeff_type &coeff, const data_type &data, const coeff_type &reg_coeff)
Compute internal matrices.
Coeff coeff_type
Type of coefficient matrices.
auto first_derivative_of_regularization_term(const scalar_type &param) const -> scalar_type
Calculate the first-order derivative of the Regularization term.
auto data_size() const -> index_type
Get the size of data.
auto second_derivative_of_residual_norm(const scalar_type &param) const -> scalar_type
Calculate the second-order derivative of the squared norm of the residual.
auto internal_solver() const -> const tikhonov< coeff_type, data_type > &
Access to the internal solver (for debug).
explicit_regularized_solver_base< full_gen_tikhonov< Coeff, Data >, Data > base_type
Type of base class.
auto singular_values() const -> const typename Eigen::BDCSVD< coeff_type >::SingularValuesType &
Get the singular values.
auto param_search_region() const -> std::pair< scalar_type, scalar_type >
Get the default region to search for the optimal regularization parameter.
Coeff coeff_actual_solution_
Coefficient matrix to calculate actual solution.
typename Eigen::NumTraits< typename data_type::Scalar >::Real scalar_type
Type of scalars.
Class to perform Tikhonov regularization.
Definition tikhonov.h:48
Definition of dense_matrix concept.
Definition of exceptions.
Definition of explicit_regularized_solver_base class.
Definition of index_type type.
Definition of log_tag_view class.
Definition of macros for logging.
Namespace of Eigen library.
Definition variable.h:416
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of regularization algorithms.
constexpr auto full_gen_tikhonov_tag
Tag of fista.
STL namespace.
Definition of NUM_COLLECT_PRECONDITION macro.
#define NUM_COLLECT_PRECONDITION(CONDITION,...)
Check whether a precondition is satisfied and throw an exception if not.
Definition of tikhonov class.