// Copyright (c) 2005 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; version 2.1 of the License. // See the file LICENSE.LGPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Bruno Levy, Pierre Alliez #ifndef CGAL_EIGEN_H #define CGAL_EIGEN_H #include CGAL_BEGIN_NAMESPACE namespace CGALi { template void eigen_symmetric(const FT *mat, const int n, FT *eigen_vectors, FT *eigen_values, const int MAX_ITER = 100) { static const FT EPSILON = (FT)0.00001; // number of entries in mat int nn = (n*(n+1))/2; // copy matrix FT *a = new FT[nn]; int ij; for(ij=0; ij a_normEPS && nb_iter < MAX_ITER) { nb_iter++; FT thr_nn = thr / nn; for(int l=1; l< n; l++) { for(int m=l+1; m<=n; m++) { // compute sinx and cosx int lq = (l*l-l)/2; int mq = (m*m-m)/2; int lm = l + mq; FT a_lm = a[lm]; FT a_lm_2 = a_lm * a_lm; if(a_lm_2 < thr_nn) continue; int ll = l + lq; int mm = m + mq; FT a_ll = a[ll]; FT a_mm = a[mm]; FT delta = a_ll - a_mm; FT x; if(delta == 0.0) x = (FT) - CGAL_PI / 4; else x = (FT)(- std::atan( (a_lm+a_lm) / delta ) / 2.0); FT sinx = std::sin(x); FT cosx = std::cos(x); FT sinx_2 = sinx * sinx; FT cosx_2 = cosx * cosx; FT sincos = sinx * cosx; // rotate L and M columns int ilv = n*(l-1); int imv = n*(m-1); int i; for( i=1; i<=n;i++ ) { if( (i!=l) && (i!=m) ) { int iq = (i*i-i)/2; int im; if( i