37 #ifndef GMM_CONDITION_NUMBER_H__
38 #define GMM_CONDITION_NUMBER_H__
52 template <
typename MAT>
53 typename number_traits<
typename
54 linalg_traits<MAT>::value_type>::magnitude_type
56 typename number_traits<
typename
57 linalg_traits<MAT>::value_type>::magnitude_type& emin,
58 typename number_traits<
typename
59 linalg_traits<MAT>::value_type>::magnitude_type& emax) {
60 typedef typename linalg_traits<MAT>::value_type T;
61 typedef typename number_traits<T>::magnitude_type R;
64 if (
sizeof(T) !=
sizeof(R) && gmm::abs(gmm::lu_det(M)) == R(0))
65 return gmm::default_max(R());
67 size_type m = mat_nrows(M), n = mat_ncols(M);
69 std::vector<R> eig(m+n);
71 if (m+n == 0)
return R(0);
74 gmm::symmetric_qr_algorithm(M, eig);
77 dense_matrix<T> B(m+n, m+n);
78 gmm::copy(
conjugated(M), sub_matrix(B, sub_interval(m, n), sub_interval(0, m)));
79 gmm::copy(M, sub_matrix(B, sub_interval(0, m),
81 gmm::symmetric_qr_algorithm(B, eig);
83 emin = emax = gmm::abs(eig[0]);
84 for (size_type i = 1; i < eig.size(); ++i) {
85 R e = gmm::abs(eig[i]);
86 emin = std::min(emin, e);
87 emax = std::max(emax, e);
90 if (emin == R(0))
return gmm::default_max(R());
94 template <
typename MAT>
95 typename number_traits<
typename
96 linalg_traits<MAT>::value_type>::magnitude_type
97 condition_number(
const MAT& M) {
98 typename number_traits<
typename
99 linalg_traits<MAT>::value_type>::magnitude_type emax, emin;
100 return condition_number(M, emin, emax);
103 template <
typename MAT>
104 typename number_traits<
typename
105 linalg_traits<MAT>::value_type>::magnitude_type
106 Frobenius_condition_number_sqr(
const MAT& M) {
107 typedef typename linalg_traits<MAT>::value_type T;
108 typedef typename number_traits<T>::magnitude_type R;
109 size_type m = mat_nrows(M), n = mat_ncols(M);
110 dense_matrix<T> B(std::min(m,n), std::min(m,n));
111 if (m < n) mult(M,gmm::conjugated(M),B);
112 else mult(gmm::conjugated(M),M,B);
118 template <
typename MAT>
119 typename number_traits<
typename
120 linalg_traits<MAT>::value_type>::magnitude_type
121 Frobenius_condition_number(
const MAT& M)
122 {
return sqrt(Frobenius_condition_number_sqr(M)); }
126 template <
typename MAT>
127 typename number_traits<
typename
128 linalg_traits<MAT>::value_type>::magnitude_type
130 typename number_traits<
typename
131 linalg_traits<MAT>::value_type>::magnitude_type& emin,
132 typename number_traits<
typename
133 linalg_traits<MAT>::value_type>::magnitude_type& emax) {
137 template <
typename MAT>
138 typename number_traits<
typename
139 linalg_traits<MAT>::value_type>::magnitude_type
140 condest(
const MAT& M) {
141 typename number_traits<
typename
142 linalg_traits<MAT>::value_type>::magnitude_type emax, emin;
143 return condest(M, emin, emax);