Пример #1
0
    //should be optimized
    const complex_matrix_type make_new_a() const 
    {
       auto A   = make_a();
       auto gs  = make_gscale();
       auto gy  = make_gyvec();
       auto const gd = make_gd(make_beam_vector());
       auto const Gm = make_gm(gd);
       auto gm  = make_unique_beams(Gm);

       array_type gxu = scale_multiply( gx, gs );
       array_type gyu = scale_multiply( gy, gs );

       array_type gu = array_type( gxu.norm(), gyu.norm(), 0 );

       array_vector_type gxy( gd );
       std::for_each( gxy.begin(), gxy.end(), [gu](array_type& a){ a[0]*=gu[1]; a[1]*=gu[0]; a[2]=0; } );
       vector_type gxy2( gxy.size() );
       feng::for_each( gxy2.begin(), gxy2.end(), gxy.begin(), [](value_type& v, const array_type& a){ v = a.norm(); v*=v; } );

       feng::for_each( A.diag_begin(), A.diag_end(), gxy2.begin(), [](complex_type& c, const value_type& v){ c = complex_type(-v, 0); } );

       std::cout << "\nA=\n" << A;

       return A;
    }
Пример #2
0
    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;
    }
Пример #3
0
    bool is_orthogonal( const matrix<T,N,A>& m, F f )
    {
        if ( m.row() != m.col() ) return false;

        auto mm = m.transpose() * m;

        std::for_each( mm.diag_begin(), mm.diag_end(), [](T& v){ v -= T(1); } );

        return std::all_of( mm.begin(), mm.end(), f );
    }
Пример #4
0
 typename Matrix::value_type norm( const Matrix& A )
 {
     typedef typename Matrix::value_type value_type;
     //typedef typename Matrix::size_type  size_type;
     auto A_ = feng::abs(A);
     std::fill( A_.diag_begin(), A_.diag_end(), value_type(0) ); //diag element set to 0
     auto const max_elem = *( std::max_element( A_.cbegin(), A_.cend() )); //find the max element
     if ( value_type(0) == max_elem ) return value_type(0); //return 0 if all elements are 0
     A_ /= max_elem; //in case of round-off error
     auto const sum = std::inner_product( A_.cbegin(), A_.cend(), A_.cbegin(), value_type(0) ); //\sum A_{i,j}^2
     return std::sqrt(sum) * max_elem; 
 }
Пример #5
0
    const array_matrix_type make_gm( const array_vector_type& gd ) const
    {
        auto const N = gd.size();
        array_matrix_type gr( N, N );
        array_matrix_type gc( N, N );

        for ( size_type i = 0; i != N; ++i )
        {
            std::fill( gr.row_begin( i ), gr.row_end( i ), gd[i] );
            std::fill( gc.col_begin( i ), gc.col_end( i ), gd[i] );
        }

        auto gm = gr - gc;
        //std::copy( gd.begin(), gd.end(), gm.diag_begin() );
        std::fill( gm.diag_begin(), gm.diag_end(), gm[0][1] );
        return gm;
    }
Пример #6
0
    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