67 constexpr auto MAX_ITERATIONS = 10000;
68 for (
auto iter = 0u; iter < MAX_ITERATIONS; ++iter)
70 auto max_off_diag = 0.;
74 for (
auto i = 0u; i < n; i++)
76 for (
auto j = i + 1; j < n; j++)
78 const auto val = std::fabs(b(i, j));
79 if (val > max_off_diag)
88 if (max_off_diag < inTolerance)
93 const auto app = b(p, p);
94 const auto aqq = b(q, q);
95 const auto apq = b(p, q);
97 const auto theta = (aqq - app) / (2. * apq);
98 const auto onePlusThetaSqr = std::sqrt(1. +
utils::sqr(theta));
99 const auto t = (theta >= 0.) ? 1. / (theta + onePlusThetaSqr) : 1. / (theta - onePlusThetaSqr);
100 const auto c = 1.0 / std::sqrt(1. +
utils::sqr(t));
101 const auto s = t * c;
103 for (
auto i = 0u; i < n; ++i)
105 if (i != p && i != q)
107 const auto bip = b(i, p);
108 const auto biq = b(i, q);
109 b(i, p) = c * bip - s * biq;
111 b(i, q) = s * bip + c * biq;
116 b(p, p) = c * c * app + s * s * aqq - 2. * c * s * apq;
117 b(q, q) = s * s * app + c * c * aqq + 2. * c * s * apq;
121 for (
auto i = 0u; i < n; ++i)
123 const auto vip = eigenVectors(i, p);
124 const auto viq = eigenVectors(i, q);
125 eigenVectors(i, p) = c * vip - s * viq;
126 eigenVectors(i, q) = s * vip + c * viq;
130 for (
auto i = 0u; i < n; ++i)
132 eigenVals[i] = b(i, i);
135 for (
auto i = 0u; i < n - 1; ++i)
137 for (
auto j = i + 1; j < n; ++j)
139 if (eigenVals[i] < eigenVals[j])
141 std::swap(eigenVals[i], eigenVals[j]);
143 for (
auto k = 0u; k < n; ++k)
145 std::swap(eigenVectors(k, i), eigenVectors(k, j));
151 return std::make_pair(eigenVals, eigenVectors);