ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkCholeskySolve.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkCholeskySolve_h
19#define itkCholeskySolve_h
20
21#include "itkMacro.h"
22#include "vnl/vnl_matrix.h"
23#include "vnl/vnl_vector.h"
24#include "itk_eigen.h"
25#include ITK_EIGEN(Dense)
26
27namespace itk
28{
29namespace Math
30{
31
38namespace detail
39{
40// vnl storage is row-major and contiguous, so map the data block directly
41// (no copy). For a symmetric A the storage order is immaterial; b/x map as
42// plain contiguous vectors.
43template <typename TReal>
44using CholeskyRowMajor = Eigen::Matrix<TReal, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
45template <typename TReal>
46using CholeskyVector = Eigen::Matrix<TReal, Eigen::Dynamic, 1>;
47} // namespace detail
48
51template <typename T>
52vnl_vector<T>
53SolveSymmetricPositiveDefinite(const vnl_matrix<T> & A, const vnl_vector<T> & b)
54{
55 itkAssertOrThrowMacro(A.rows() == A.cols(), "SolveSymmetricPositiveDefinite requires a square matrix");
56 itkAssertOrThrowMacro(A.rows() == b.size(), "SolveSymmetricPositiveDefinite requires matching b length");
57 const unsigned int n = A.rows();
58 Eigen::Map<const detail::CholeskyRowMajor<T>> aMap(A.data_block(), n, n);
59 Eigen::Map<const detail::CholeskyVector<T>> bMap(b.data_block(), n);
60 vnl_vector<T> x(n);
61 Eigen::Map<detail::CholeskyVector<T>> xMap(x.data_block(), n);
62 xMap = aMap.template selfadjointView<Eigen::Lower>().ldlt().solve(bMap);
63 return x;
64}
65
68template <typename T>
69vnl_matrix<T>
70CholeskyLowerTriangle(const vnl_matrix<T> & A)
71{
72 itkAssertOrThrowMacro(A.rows() == A.cols(), "CholeskyLowerTriangle requires a square matrix");
73 const unsigned int n = A.rows();
74 Eigen::Map<const detail::CholeskyRowMajor<T>> aMap(A.data_block(), n, n);
75 const auto llt = aMap.template selfadjointView<Eigen::Lower>().llt();
76 if (llt.info() != Eigen::Success)
77 {
78 itkGenericExceptionMacro("CholeskyLowerTriangle requires a positive-definite matrix");
79 }
80 const detail::CholeskyRowMajor<T> lower = llt.matrixL();
81 vnl_matrix<T> result(n, n);
82 Eigen::Map<detail::CholeskyRowMajor<T>> rMap(result.data_block(), n, n);
83 rMap = lower;
84 return result;
85}
86
87} // namespace Math
88} // namespace itk
89
90#endif // itkCholeskySolve_h
Cholesky-based linear algebra for symmetric matrices, backed by Eigen.
Eigen::Matrix< TReal, Eigen::Dynamic, 1 > CholeskyVector
Eigen::Matrix< TReal, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > CholeskyRowMajor
vnl_matrix< T > CholeskyLowerTriangle(const vnl_matrix< T > &A)
vnl_vector< T > SolveSymmetricPositiveDefinite(const vnl_matrix< T > &A, const vnl_vector< T > &b)
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....