ColPivHouseholderQR_LAPACKE.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011, Intel Corporation. All rights reserved.
3 
4  Redistribution and use in source and binary forms, with or without modification,
5  are permitted provided that the following conditions are met:
6 
7  * Redistributions of source code must retain the above copyright notice, this
8  list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright notice,
10  this list of conditions and the following disclaimer in the documentation
11  and/or other materials provided with the distribution.
12  * Neither the name of Intel Corporation nor the names of its contributors may
13  be used to endorse or promote products derived from this software without
14  specific prior written permission.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27  ********************************************************************************
28  * Content : Eigen bindings to LAPACKe
29  * Householder QR decomposition of a matrix with column pivoting based on
30  * LAPACKE_?geqp3 function.
31  ********************************************************************************
32 */
33 
34 #ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_LAPACKE_H
35 #define EIGEN_COLPIVOTINGHOUSEHOLDERQR_LAPACKE_H
36 
37 // IWYU pragma: private
38 #include "./InternalHeaderCheck.h"
39 
40 namespace Eigen {
41 
42 #if defined(EIGEN_USE_LAPACKE)
43 
44 template <typename Scalar>
45 inline lapack_int call_geqp3(int matrix_layout, lapack_int m, lapack_int n, Scalar* a, lapack_int lda, lapack_int* jpvt,
46  Scalar* tau);
47 template <>
48 inline lapack_int call_geqp3(int matrix_layout, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* jpvt,
49  float* tau) {
50  return LAPACKE_sgeqp3(matrix_layout, m, n, a, lda, jpvt, tau);
51 }
52 template <>
53 inline lapack_int call_geqp3(int matrix_layout, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* jpvt,
54  double* tau) {
55  return LAPACKE_dgeqp3(matrix_layout, m, n, a, lda, jpvt, tau);
56 }
57 template <>
58 inline lapack_int call_geqp3(int matrix_layout, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda,
59  lapack_int* jpvt, lapack_complex_float* tau) {
60  return LAPACKE_cgeqp3(matrix_layout, m, n, a, lda, jpvt, tau);
61 }
62 template <>
63 inline lapack_int call_geqp3(int matrix_layout, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda,
64  lapack_int* jpvt, lapack_complex_double* tau) {
65  return LAPACKE_zgeqp3(matrix_layout, m, n, a, lda, jpvt, tau);
66 }
67 
68 template <typename MatrixType>
69 struct ColPivHouseholderQR_LAPACKE_impl {
70  typedef typename MatrixType::Scalar Scalar;
71  typedef typename MatrixType::RealScalar RealScalar;
73  static constexpr int LapackeStorage = MatrixType::IsRowMajor ? (LAPACK_ROW_MAJOR) : (LAPACK_COL_MAJOR);
74 
75  typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
76  typedef PermutationMatrix<Dynamic, Dynamic, lapack_int> PermutationType;
77 
78  static void run(MatrixType& qr, HCoeffsType& hCoeffs, PermutationType& colsPermutation, Index& nonzero_pivots,
79  RealScalar& maxpivot, bool usePrescribedThreshold, RealScalar prescribedThreshold, Index& det_p,
80  bool& isInitialized) {
81  isInitialized = false;
82  hCoeffs.resize(qr.diagonalSize());
83  nonzero_pivots = 0;
84  maxpivot = RealScalar(0);
85  colsPermutation.resize(qr.cols());
86  colsPermutation.indices().setZero();
87 
90  LapackeType* qr_data = (LapackeType*)(qr.data());
92  lapack_int* perm_data = colsPermutation.indices().data();
93  LapackeType* hCoeffs_data = (LapackeType*)(hCoeffs.data());
94 
95  lapack_int info = call_geqp3(LapackeStorage, rows, cols, qr_data, lda, perm_data, hCoeffs_data);
96  if (info != 0) return;
97 
98  maxpivot = qr.diagonal().cwiseAbs().maxCoeff();
99  hCoeffs.adjointInPlace();
100  RealScalar defaultThreshold = NumTraits<RealScalar>::epsilon() * RealScalar(qr.diagonalSize());
101  RealScalar threshold = usePrescribedThreshold ? prescribedThreshold : defaultThreshold;
102  RealScalar premultiplied_threshold = maxpivot * threshold;
103  nonzero_pivots = (qr.diagonal().cwiseAbs().array() > premultiplied_threshold).count();
104  colsPermutation.indices().array() -= 1;
105  det_p = colsPermutation.determinant();
106  isInitialized = true;
107  };
108 
109  static void init(Index rows, Index cols, HCoeffsType& hCoeffs, PermutationType& colsPermutation,
110  bool& usePrescribedThreshold, bool& isInitialized) {
112  hCoeffs.resize(diag);
113  colsPermutation.resize(cols);
114  usePrescribedThreshold = false;
115  isInitialized = false;
116  }
117 };
118 
119 #define COLPIVQR_LAPACKE_COMPUTEINPLACE(EIGTYPE) \
120  template <> \
121  inline void ColPivHouseholderQR<EIGTYPE, lapack_int>::computeInPlace() { \
122  ColPivHouseholderQR_LAPACKE_impl<MatrixType>::run(m_qr, m_hCoeffs, m_colsPermutation, m_nonzero_pivots, \
123  m_maxpivot, m_usePrescribedThreshold, m_prescribedThreshold, \
124  m_det_p, m_isInitialized); \
125  }
126 
127 #define COLPIVQR_LAPACKE_INIT(EIGTYPE) \
128  template <> \
129  inline void ColPivHouseholderQR<EIGTYPE, lapack_int>::init(Index rows, Index cols) { \
130  ColPivHouseholderQR_LAPACKE_impl<MatrixType>::init(rows, cols, m_hCoeffs, m_colsPermutation, m_isInitialized, \
131  m_usePrescribedThreshold); \
132  }
133 
134 #define COLPIVQR_LAPACKE(EIGTYPE) \
135  COLPIVQR_LAPACKE_COMPUTEINPLACE(EIGTYPE) \
136  COLPIVQR_LAPACKE_INIT(EIGTYPE) \
137  COLPIVQR_LAPACKE_COMPUTEINPLACE(Ref<EIGTYPE>) \
138  COLPIVQR_LAPACKE_INIT(Ref<EIGTYPE>)
139 
140 typedef Matrix<float, Dynamic, Dynamic, ColMajor> MatrixXfC;
141 typedef Matrix<double, Dynamic, Dynamic, ColMajor> MatrixXdC;
142 typedef Matrix<std::complex<float>, Dynamic, Dynamic, ColMajor> MatrixXcfC;
143 typedef Matrix<std::complex<double>, Dynamic, Dynamic, ColMajor> MatrixXcdC;
144 typedef Matrix<float, Dynamic, Dynamic, RowMajor> MatrixXfR;
145 typedef Matrix<double, Dynamic, Dynamic, RowMajor> MatrixXdR;
146 typedef Matrix<std::complex<float>, Dynamic, Dynamic, RowMajor> MatrixXcfR;
147 typedef Matrix<std::complex<double>, Dynamic, Dynamic, RowMajor> MatrixXcdR;
148 
149 COLPIVQR_LAPACKE(MatrixXfC)
150 COLPIVQR_LAPACKE(MatrixXdC)
151 COLPIVQR_LAPACKE(MatrixXcfC)
152 COLPIVQR_LAPACKE(MatrixXcdC)
153 COLPIVQR_LAPACKE(MatrixXfR)
154 COLPIVQR_LAPACKE(MatrixXdR)
155 COLPIVQR_LAPACKE(MatrixXcfR)
156 COLPIVQR_LAPACKE(MatrixXcdR)
157 
158 #endif
159 } // end namespace Eigen
160 
161 #endif // EIGEN_COLPIVOTINGHOUSEHOLDERQR_LAPACKE_H
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
HouseholderQR< MatrixXf > qr(A)
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
@ ColMajor
Definition: Constants.h:318
@ RowMajor
Definition: Constants.h:320
#define LAPACK_COL_MAJOR
Definition: lapacke.h:124
lapack_int LAPACKE_sgeqp3(int matrix_order, lapack_int m, lapack_int n, float *a, lapack_int lda, lapack_int *jpvt, float *tau)
#define lapack_int
Definition: lapacke.h:52
#define LAPACK_ROW_MAJOR
Definition: lapacke.h:123
lapack_int LAPACKE_zgeqp3(int matrix_order, lapack_int m, lapack_int n, lapack_complex_double *a, lapack_int lda, lapack_int *jpvt, lapack_complex_double *tau)
lapack_int LAPACKE_dgeqp3(int matrix_order, lapack_int m, lapack_int n, double *a, lapack_int lda, lapack_int *jpvt, double *tau)
#define lapack_complex_double
Definition: lapacke.h:94
#define lapack_complex_float
Definition: lapacke.h:79
lapack_int LAPACKE_cgeqp3(int matrix_order, lapack_int m, lapack_int n, lapack_complex_float *a, lapack_int lda, lapack_int *jpvt, lapack_complex_float *tau)
const Scalar * a
Definition: level2_cplx_impl.h:32
const char const int const RealScalar const RealScalar const int * lda
Definition: level2_cplx_impl.h:20
int * m
Definition: level2_cplx_impl.h:294
int info
Definition: level2_cplx_impl.h:39
const char const char const char * diag
Definition: level2_impl.h:86
EIGEN_ALWAYS_INLINE auto to_lapack(Source value)
Definition: lapacke_helpers.h:61
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T mini(const T &x, const T &y)
Definition: MathFunctions.h:920
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
auto run(Kernel kernel, Args &&... args) -> decltype(kernel(args...))
Definition: gpu_test_helper.h:414
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
const int Dynamic
Definition: Constants.h:25
type
Definition: compute_granudrum_aor.py:141
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
std::conditional_t< is_same< typename traits< MatrixType >::XprKind, MatrixXpr >::value, MatrixDiagType, ArrayDiagType > type
Definition: XprHelper.h:797
Definition: TutorialInplaceLU.cpp:2