std::size_t cyclic_eigen_jacobi( const Matrix1& A, Matrix2& V, Otor o, std::size_t max_rot = 80, const T eps = T( 1.0e-10 ) ) { typedef typename Matrix1::value_type value_type; typedef typename Matrix1::size_type size_type; auto const compare_func = [eps]( const value_type lhs, const value_type rhs ) { return std::abs(lhs-rhs) < eps; }; assert( A.row() == A.col() ); //assert( is_symmetric( A, compare_func ) ); size_type i = 0; auto a = A; auto const n = a.row(); auto const one = value_type( 1 ); auto const zero = value_type( 0 ); // @V = diag{1, 1, ..., 1} V.resize( n, n ); V = zero; std::fill( V.diag_begin(), V.diag_end(), one ); for ( ; i != max_rot; ++i ) { if ( !(i&7) && eigen_jacobi_private::norm(a) == zero ) { break; } for ( size_type p = 0; p != n; ++p ) for ( size_type q = p+1; q != n; ++q ) eigen_jacobi_private::rotate(a, V, p, q); } std::copy( a.diag_begin(), a.diag_end(), o ); return i*n*n; }
std::size_t eigen_jacobi( const Matrix1& A, Matrix2& V, Otor o, const T eps = T( 1.0e-10 ) ) { typedef typename Matrix1::value_type value_type; typedef typename Matrix1::size_type size_type; assert( A.row() == A.col() ); //assert( is_symmetric( A ) ); auto a = A; auto const n = a.row(); auto const one = value_type( 1 ); auto const zero = value_type( 0 ); // @V = diag{1, 1, ..., 1} V.resize( n, n ); V = zero; std::fill( V.diag_begin(), V.diag_end(), one ); #if 1 for ( size_type i = 0; i != size_type( -1 ); ++i ) { // @find max non-diag value in A size_type p = 0; size_type q = 1; value_type current_max = std::abs( a[p][q] ); for ( size_type ip = 0; ip != n; ++ip ) for ( size_type iq = ip + 1; iq != n; ++iq ) { auto const tmp = std::abs( a[ip][iq] ); if ( current_max > tmp ) continue; current_max = tmp; p = ip; q = iq; } // @if all non-diag value small, then break iteration with success if ( current_max < eps ) { std::copy( a.diag_begin(), a.diag_end(), o ); return i; } // a and V iterations eigen_jacobi_private::rotate(a, V, p, q); }//end for #endif // @just to kill warnings, should never reach here return size_type( -1 ); }//eigen_jacobi