143 const VectorType& z,
int options) {
144 const Index n = d.size();
145 eigen_assert(z.size() == n &&
"d and z must have the same size");
146 eigen_assert((options & ~EigVecMask) == 0 && (options & EigVecMask) != EigVecMask &&
"invalid option parameter");
148 m_vectorsComputed =
false;
151 m_eivalues.resize(n);
152 if (computeVectors) m_eivec.setIdentity(n, n);
156 if (!(d.allFinite() && z.allFinite() && (numext::isfinite)(rho))) {
159 m_isInitialized =
true;
163 m_vectorsComputed = computeVectors;
164 m_isInitialized =
true;
168 const bool negated = rho < RealScalar(0);
169 const VectorType dW = negated ? VectorType(-d) : d;
172 std::vector<Index> pi;
173 pi.reserve(
static_cast<std::size_t
>(n));
174 for (Index i = 0; i < n; ++i) pi.push_back(i);
175 std::stable_sort(pi.begin(), pi.end(), [&dW](Index a, Index b) { return dW[a] < dW[b]; });
176 VectorType ds(n), zs(n);
177 for (Index i = 0; i < n; ++i) {
178 ds[i] = dW[pi[
static_cast<std::size_t
>(i)]];
179 zs[i] = z[pi[
static_cast<std::size_t
>(i)]];
185 const RealScalar znorm = zs.stableNorm();
186 if (znorm > RealScalar(0)) zs /= znorm;
187 RealScalar rhoW = rho == RealScalar(0) || znorm == RealScalar(0) ? RealScalar(0) : (numext::abs(rho) * znorm) * znorm;
188 if (!(numext::isfinite)(rhoW)) {
193 m_isInitialized =
true;
196 EIGEN_USING_STD(frexp)
197 EIGEN_USING_STD(ldexp)
198 RealScalar scaledNorm = numext::maxi(ds.cwiseAbs().maxCoeff(), rhoW);
200 if (scaledNorm > RealScalar(0)) scaledNorm = frexp(scaledNorm, &scaleExp);
201 ds = ds.array().ldexp(-scaleExp).matrix();
202 rhoW = ldexp(rhoW, -scaleExp);
211 std::vector<Rotation> rotations;
212 std::vector<bool> deflated;
215 deflated.assign(
static_cast<std::size_t
>(n),
true);
218 deflated.reserve(
static_cast<std::size_t
>(n));
219 for (Index i = 0; i < n; ++i) deflated.push_back(rhoW * numext::abs(zs[i]) <= tol);
222 for (Index i = 0; i < n; ++i) {
223 if (deflated[
static_cast<std::size_t
>(i)])
continue;
225 const RealScalar r = numext::hypot(zs[p], zs[i]);
226 const RealScalar c = zs[i] / r, s = zs[p] / r;
227 const RealScalar gap = ds[i] - ds[p];
228 if (numext::abs(c * s * gap) <= tol) {
234 const RealScalar left = ds[p], right = ds[i];
235 if (numext::abs(s) <= numext::abs(c)) {
236 const RealScalar shift = s * s * gap;
237 ds[p] = left + shift;
238 ds[i] = right - shift;
240 const RealScalar shift = c * c * gap;
241 ds[p] = right - shift;
242 ds[i] = left + shift;
245 zs[p] = RealScalar(0);
246 deflated[
static_cast<std::size_t
>(p)] =
true;
250 rotations.push_back(Rotation{p, i, c, s});
253 if (!deflated[
static_cast<std::size_t
>(i)]) p = i;
257 std::vector<Index> sub;
258 for (Index i = 0; i < n; ++i)
259 if (!deflated[
static_cast<std::size_t
>(i)]) sub.push_back(i);
260 const Index m =
static_cast<Index
>(sub.size());
262 VectorType lambdaW = ds;
264 MatrixType subVectors;
267 VectorType delta(m),
zeta(m), zeta2(m);
268 std::vector<Index> shiftIndex(
static_cast<std::size_t
>(m));
270 for (Index a = 0; a < m; ++a) {
271 delta[a] = ds[sub[
static_cast<std::size_t
>(a)]];
272 zeta[a] = zs[sub[
static_cast<std::size_t
>(a)]];
274 zeta2.array() =
zeta.array() *
zeta.array();
275 const RealScalar zeta2sum = zeta2.sum();
281 (std::numeric_limits<RealScalar>::digits > 0) ?
static_cast<int>(std::numeric_limits<RealScalar>::digits) : 128;
282 const int expRange = (std::numeric_limits<RealScalar>::max_exponent > std::numeric_limits<RealScalar>::min_exponent)
283 ?
static_cast<int>(std::numeric_limits<RealScalar>::max_exponent) -
284 static_cast<int>(std::numeric_limits<RealScalar>::min_exponent)
286 const int maxBisect = expRange + 2 * digits + 32;
287 VectorType lam(m), dsh(m);
288 for (Index k = 0; k < m; ++k) {
297 hi = rhoW * zeta2sum;
301 const RealScalar left = delta[k], right = delta[k + 1];
302 const RealScalar mid = left + (right - left) / RealScalar(2);
303 if (secular(delta, zeta2, rhoW, mid) > RealScalar(0)) {
313 const RealScalar shiftVal = delta[shift];
314 dsh.array() = delta.array() - shiftVal;
319 RealScalar a0 = lo, b0 = hi;
320 bool converged =
false;
321 for (
int iter = 0; iter < maxBisect; ++iter) {
322 const RealScalar t = a0 + (b0 - a0) / RealScalar(2);
323 if (t == a0 || t == b0) {
327 if (secular(dsh, zeta2, rhoW, t) > RealScalar(0))
333 const RealScalar t = a0 + (b0 - a0) / RealScalar(2);
334 shiftIndex[
static_cast<std::size_t
>(k)] = shift;
336 lam[k] = shiftVal + t;
344 for (Index i = 0; i < m; ++i) {
345 RealScalar acc = ((delta[shiftIndex[
static_cast<std::size_t
>(i)]] - delta[i]) + tau[i]) / rhoW;
346 for (Index j = 0; j < m; ++j) {
347 if (j == i)
continue;
348 const RealScalar num = (delta[shiftIndex[
static_cast<std::size_t
>(j)]] - delta[i]) + tau[j];
349 acc *= num / (delta[j] - delta[i]);
351 zhat[i] = numext::abs(acc) > RealScalar(0) ? RealScalar(numext::sqrt(numext::abs(acc))) : RealScalar(0);
352 if (
zeta[i] < RealScalar(0)) zhat[i] = -zhat[i];
356 if (computeVectors) {
358 for (Index j = 0; j < m; ++j) {
359 const Index sj = shiftIndex[
static_cast<std::size_t
>(j)];
360 if (tau[j] == RealScalar(0)) {
364 subVectors(sj, j) = RealScalar(1);
369 subVectors.col(j).array() = zhat.array() / ((delta.array() - delta[sj]) - tau[j]);
370 subVectors.col(j).stableNormalize();
373 for (Index k = 0; k < m; ++k) lambdaW[sub[static_cast<std::size_t>(k)]] = lam[k];
376 std::vector<Index> order;
377 order.reserve(
static_cast<std::size_t
>(n));
378 for (Index i = 0; i < n; ++i) order.push_back(i);
379 std::stable_sort(order.begin(), order.end(), [&lambdaW](Index a, Index b) { return lambdaW[a] < lambdaW[b]; });
381 std::vector<Index> subSlot(
static_cast<std::size_t
>(n), -1);
382 for (Index a = 0; a < m; ++a) subSlot[static_cast<std::size_t>(sub[
static_cast<std::size_t
>(a)])] = a;
384 for (Index t = 0; t < n; ++t) {
385 const Index w = order[
static_cast<std::size_t
>(t)];
386 const Index outCol = negated ? n - 1 - t : t;
387 m_eivalues[outCol] = negated ? -lambdaW[w] : lambdaW[w];
388 if (!computeVectors)
continue;
390 VectorType wvec = VectorType::Zero(n);
391 const Index slot = subSlot[
static_cast<std::size_t
>(w)];
393 wvec[w] = RealScalar(1);
395 for (Index a = 0; a < m; ++a) wvec[sub[static_cast<std::size_t>(a)]] = subVectors(a, slot);
400 for (
auto it = rotations.rbegin(); it != rotations.rend(); ++it) {
401 const RealScalar wi = wvec[it->i], wj = wvec[it->j];
402 wvec[it->i] = it->c * wi + it->s * wj;
403 wvec[it->j] = -it->s * wi + it->c * wj;
405 for (Index i = 0; i < n; ++i) m_eivec(pi[static_cast<std::size_t>(i)], outCol) = wvec[i];
408 m_eivalues = m_eivalues.array().ldexp(scaleExp).matrix();
409 if (!m_eivalues.allFinite()) {
410 m_eivalues.setConstant(NumTraits<RealScalar>::quiet_NaN());
411 m_info = InvalidInput;
414 m_vectorsComputed = computeVectors && m_info !=
InvalidInput;
415 m_isInitialized =
true;