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 {
171 }
172
175 const scalar_type& param) const -> scalar_type {
177 }
178
181 const scalar_type& param) const -> scalar_type {
183 }
184
187 const scalar_type& param) const -> scalar_type {
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> {
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.
Base class of solvers using explicit formulas for regularization.
Class to perform generalized Tikhonov regularization on the condition that the matrix in the regulari...
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).
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.
Class to perform Tikhonov regularization.
Definition tikhonov.h:48
auto singular_values() const -> const typename Eigen::BDCSVD< coeff_type >::SingularValuesType &
Get the singular values.
Definition tikhonov.h:102
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.
Definition tikhonov.h:166
auto data_size() const -> index_type
Get the size of data.
Definition tikhonov.h:211
auto sum_of_filter_factor(const scalar_type &param) const -> scalar_type
Calculate the sum of filter factors.
Definition tikhonov.h:198
void solve(const scalar_type &param, data_type &solution) const
Solve for a regularization parameter.
Definition tikhonov.h:86
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.
Definition tikhonov.h:136
auto param_search_region() const -> std::pair< scalar_type, scalar_type >
Get the default region to search for the optimal regularization parameter.
Definition tikhonov.h:214
auto regularization_term(const scalar_type &param) const -> scalar_type
Calculate the regularization term.
Definition tikhonov.h:122
auto first_derivative_of_regularization_term(const scalar_type &param) const -> scalar_type
Calculate the first-order derivative of the Regularization term.
Definition tikhonov.h:151
auto residual_norm(const scalar_type &param) const -> scalar_type
Calculate the squared norm of the residual.
Definition tikhonov.h:108
auto second_derivative_of_regularization_term(const scalar_type &param) const -> scalar_type
Calculate the send-order derivative of the Regularization term.
Definition tikhonov.h:183
void compute(const coeff_type &coeff, const data_type &data)
Compute internal matrices.
Definition tikhonov.h:75
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.