4
4
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5
5
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
7
// Eigen is free software; you can redistribute it and/or
8
// modify it under the terms of the GNU Lesser General Public
9
// License as published by the Free Software Foundation; either
10
// version 3 of the License, or (at your option) any later version.
12
// Alternatively, you can redistribute it and/or
13
// modify it under the terms of the GNU General Public License as
14
// published by the Free Software Foundation; either version 2 of
15
// the License, or (at your option) any later version.
17
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20
// GNU General Public License for more details.
22
// You should have received a copy of the GNU Lesser General Public
23
// License and a copy of the GNU General Public License along with
24
// Eigen. If not, see <http://www.gnu.org/licenses/>.
7
// This Source Code Form is subject to the terms of the Mozilla
8
// Public License v. 2.0. If a copy of the MPL was not distributed
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
26
11
#ifndef EIGEN_REAL_SCHUR_H
27
12
#define EIGEN_REAL_SCHUR_H
29
#include "./EigenvaluesCommon.h"
30
14
#include "./HessenbergDecomposition.h"
32
18
/** \eigenvalues_module \ingroup Eigenvalues_Module
235
221
// Rows iu+1,...,end are already brought in triangular form.
236
222
Index iu = m_matT.cols() - 1;
237
223
Index iter = 0; // iteration count
238
Scalar exshift = 0.0; // sum of exceptional shifts
224
Scalar exshift(0); // sum of exceptional shifts
239
225
Scalar norm = computeNormOfT();
243
Index il = findSmallSubdiagEntry(iu, norm);
245
// Check for convergence
246
if (il == iu) // One root found
248
m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift;
250
m_matT.coeffRef(iu, iu-1) = Scalar(0);
254
else if (il == iu-1) // Two roots found
256
splitOffTwoRows(iu, computeU, exshift);
260
else // No convergence yet
262
// The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG )
263
Vector3s firstHouseholderVector(0,0,0), shiftInfo;
264
computeShift(iu, iter, exshift, shiftInfo);
266
if (iter > m_maxIterations) break;
268
initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
269
performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
273
if(iter <= m_maxIterations)
231
Index il = findSmallSubdiagEntry(iu, norm);
233
// Check for convergence
234
if (il == iu) // One root found
236
m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift;
238
m_matT.coeffRef(iu, iu-1) = Scalar(0);
242
else if (il == iu-1) // Two roots found
244
splitOffTwoRows(iu, computeU, exshift);
248
else // No convergence yet
250
// The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG )
251
Vector3s firstHouseholderVector(0,0,0), shiftInfo;
252
computeShift(iu, iter, exshift, shiftInfo);
254
if (iter > m_maxIterations * m_matT.cols()) break;
256
initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
257
performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
261
if(iter <= m_maxIterations * m_matT.cols())
274
262
m_info = Success;
276
264
m_info = NoConvergence;