blob: 211a7ff4e570ec347892da1ef01bcc6e607eb101 [file] [log] [blame]
Gael Guennebaud390724b2011-02-18 11:25:04 +01001// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
Benoit Jacob69124cf2012-07-13 14:42:47 -04006// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
Gael Guennebaud390724b2011-02-18 11:25:04 +01009
Gael Guennebaud8472e692014-10-17 15:31:11 +020010#include "lapack_common.h"
Gael Guennebaud390724b2011-02-18 11:25:04 +010011#include <Eigen/Eigenvalues>
12
Gael Guennebaud8472e692014-10-17 15:31:11 +020013// computes eigen values and vectors of a general N-by-N matrix A
Antonio Sánchez5361dea2024-02-14 19:51:36 +000014EIGEN_LAPACK_FUNC(syev)
15(char* jobz, char* uplo, int* n, Scalar* a, int* lda, Scalar* w, Scalar* /*work*/, int* lwork, int* info) {
Gael Guennebaud9ab50392011-02-23 09:32:55 +010016 // TODO exploit the work buffer
Antonio Sanchez186f8202024-02-09 10:32:56 -080017 bool query_size = *lwork == -1;
18
Gael Guennebaud390724b2011-02-18 11:25:04 +010019 *info = 0;
Antonio Sanchez186f8202024-02-09 10:32:56 -080020 if (*jobz != 'N' && *jobz != 'V')
21 *info = -1;
22 else if (UPLO(*uplo) == INVALID)
23 *info = -2;
24 else if (*n < 0)
25 *info = -3;
26 else if (*lda < std::max(1, *n))
27 *info = -5;
28 else if ((!query_size) && *lwork < std::max(1, 3 * *n - 1))
29 *info = -8;
30
31 if (*info != 0) {
Gael Guennebaud390724b2011-02-18 11:25:04 +010032 int e = -*info;
Antonio Sánchez5361dea2024-02-14 19:51:36 +000033 return xerbla_(SCALAR_SUFFIX_UP "SYEV ", &e);
Gael Guennebaud390724b2011-02-18 11:25:04 +010034 }
Antonio Sanchez186f8202024-02-09 10:32:56 -080035
36 if (query_size) {
Gael Guennebaud390724b2011-02-18 11:25:04 +010037 *lwork = 0;
Antonio Sánchez5361dea2024-02-14 19:51:36 +000038 return;
Gael Guennebaud390724b2011-02-18 11:25:04 +010039 }
Antonio Sanchez186f8202024-02-09 10:32:56 -080040
Antonio Sánchez5361dea2024-02-14 19:51:36 +000041 if (*n == 0) return;
Antonio Sanchez186f8202024-02-09 10:32:56 -080042
43 PlainMatrixType mat(*n, *n);
44 if (UPLO(*uplo) == UP)
45 mat = matrix(a, *n, *n, *lda).adjoint();
46 else
47 mat = matrix(a, *n, *n, *lda);
48
49 bool computeVectors = *jobz == 'V' || *jobz == 'v';
Antonio Sánchez8a73c642024-02-22 22:51:42 +000050 Eigen::SelfAdjointEigenSolver<PlainMatrixType> eig(
51 mat, computeVectors ? Eigen::ComputeEigenvectors : Eigen::EigenvaluesOnly);
Antonio Sanchez186f8202024-02-09 10:32:56 -080052
Antonio Sánchez8a73c642024-02-22 22:51:42 +000053 if (eig.info() == Eigen::NoConvergence) {
Antonio Sanchez186f8202024-02-09 10:32:56 -080054 make_vector(w, *n).setZero();
55 if (computeVectors) matrix(a, *n, *n, *lda).setIdentity();
Gael Guennebaud390724b2011-02-18 11:25:04 +010056 //*info = 1;
Antonio Sánchez5361dea2024-02-14 19:51:36 +000057 return;
Gael Guennebaud390724b2011-02-18 11:25:04 +010058 }
Antonio Sanchez186f8202024-02-09 10:32:56 -080059
60 make_vector(w, *n) = eig.eigenvalues();
61 if (computeVectors) matrix(a, *n, *n, *lda) = eig.eigenvectors();
Gael Guennebaud390724b2011-02-18 11:25:04 +010062}