inline SafeProduct<F> 
AfterLUPartialPiv( const Matrix<F>& A, const Matrix<Int>& p )
{
#ifndef RELEASE
    CallStackEntry entry("determinant::AfterLUPartialPiv");
#endif
    if( A.Height() != A.Width() )
        LogicError("Cannot compute determinant of nonsquare matrix");
    if( A.Height() != p.Height() )
        LogicError("Pivot vector is incorrect length");

    typedef BASE(F) R;
    const Int n = A.Height();

    Matrix<F> d;
    A.GetDiagonal( d );
    const R scale(n);
    SafeProduct<F> det( n );
    for( Int i=0; i<n; ++i )
    {
        const F delta = d.Get(i,0);
        R alpha = Abs(delta);
        det.rho *= delta/alpha;
        det.kappa += Log(alpha)/scale;
    }
    const bool isOdd = PivotParity( p );
    if( isOdd )
        det.rho = -det.rho;

    return det;
}
Beispiel #2
0
inline SafeProduct<F> 
SafeDeterminant( DistMatrix<F,MC,MR>& A )
{
#ifndef RELEASE
    PushCallStack("SafeDeterminant");
#endif
    if( A.Height() != A.Width() )
        throw std::logic_error
        ("Cannot compute determinant of nonsquare matrix");

    typedef typename Base<F>::type R;
    const int n = A.Height();
    SafeProduct<F> det( n );
    const Grid& g = A.Grid();

    try
    {
        DistMatrix<int,VC,STAR> p;
        LU( A, p );
        const bool isOdd = PivotParity( p );

        DistMatrix<F,MD,STAR> d(g);
        A.GetDiagonal( d );
        F localRho = 1;
        R localKappa = 0; 
        if( d.InDiagonal() )
        {
            const int nLocalDiag = d.LocalHeight();
            for( int iLocal=0; iLocal<nLocalDiag; ++iLocal )
            {
                const F delta = d.GetLocalEntry(iLocal,0);
                R alpha = Abs(delta);
                localRho *= delta/alpha;
                localKappa += std::log(alpha)/n;
            }
        }
        mpi::AllReduce( &localRho, &det.rho, 1, mpi::PROD, g.VCComm() );
        mpi::AllReduce( &localKappa, &det.kappa, 1, mpi::SUM, g.VCComm() );
        if( isOdd )
            det.rho = -det.rho;
    }
    catch( SingularMatrixException& e )
    {
        det.rho = 0;
        det.kappa = 0;
    }
#ifndef RELEASE
    PopCallStack();
#endif
    return det;
}
Beispiel #3
0
inline SafeProduct<F> 
LUPartialPiv( DistMatrix<F>& A )
{
#ifndef RELEASE
    CallStackEntry entry("determinant::LUPartialPiv");
#endif
    if( A.Height() != A.Width() )
        throw std::logic_error
        ("Cannot compute determinant of nonsquare matrix");

    typedef BASE(F) R;
    const int n = A.Height();
    const R scale(n);
    SafeProduct<F> det( n );
    const Grid& g = A.Grid();

    try
    {
        DistMatrix<int,VC,STAR> p(g);
        elem::LU( A, p );
        const bool isOdd = PivotParity( p );

        DistMatrix<F,MD,STAR> d(g);
        A.GetDiagonal( d );
        F localRho = 1;
        R localKappa = 0; 
        if( d.Participating() )
        {
            const int nLocalDiag = d.LocalHeight();
            for( int iLocal=0; iLocal<nLocalDiag; ++iLocal )
            {
                const F delta = d.GetLocal(iLocal,0);
                R alpha = Abs(delta);
                localRho *= delta/alpha;
                localKappa += Log(alpha)/scale;
            }
        }
        mpi::AllReduce( &localRho, &det.rho, 1, mpi::PROD, g.VCComm() );
        mpi::AllReduce( &localKappa, &det.kappa, 1, mpi::SUM, g.VCComm() );
        if( isOdd )
            det.rho = -det.rho;
    }
    catch( SingularMatrixException& e )
    {
        det.rho = 0;
        det.kappa = 0;
    }
    return det;
}
inline SafeProduct<F> 
AfterLUPartialPiv( const DistMatrix<F>& A, const DistMatrix<Int,VC,STAR>& p )
{
#ifndef RELEASE
    CallStackEntry entry("determinant::AfterLUPartialPiv");
#endif
    if( A.Height() != A.Width() )
        LogicError("Cannot compute determinant of nonsquare matrix");
    if( A.Grid() != p.Grid() )
        LogicError("A and p must have the same grid");
    if( A.Height() != p.Height() )
        LogicError("Pivot vector is incorrect length");

    typedef BASE(F) R;
    const Int n = A.Height();
    const Grid& g = A.Grid();

    DistMatrix<F,MD,STAR> d(g);
    A.GetDiagonal( d );
    F localRho = 1;
    R localKappa = 0; 
    if( d.Participating() )
    {
        const R scale(n);
        const Int nLocalDiag = d.LocalHeight();
        for( Int iLoc=0; iLoc<nLocalDiag; ++iLoc )
        {
            const F delta = d.GetLocal(iLoc,0);
            R alpha = Abs(delta);
            localRho *= delta/alpha;
            localKappa += Log(alpha)/scale;
        }
    }
    SafeProduct<F> det( n );
    det.rho = mpi::AllReduce( localRho, mpi::PROD, g.VCComm() );
    det.kappa = mpi::AllReduce( localKappa, mpi::SUM, g.VCComm() );

    const bool isOdd = PivotParity( p );
    if( isOdd )
        det.rho = -det.rho;

    return det;
}
Beispiel #5
0
inline SafeProduct<F> 
SafeDeterminant( Matrix<F>& A )
{
#ifndef RELEASE
    PushCallStack("SafeDeterminant");
#endif
    if( A.Height() != A.Width() )
        throw std::logic_error
        ("Cannot compute determinant of nonsquare matrix");

    typedef typename Base<F>::type R;
    const int n = A.Height();
    SafeProduct<F> det( n );

    try
    {
        Matrix<int> p;
        LU( A, p ); 
        const bool isOdd = PivotParity( p );
        
        Matrix<F> d;
        A.GetDiagonal( d );
        for( int i=0; i<n; ++i )
        {
            const F delta = d.Get(i,0);
            R alpha = Abs(delta);
            det.rho *= delta/alpha;
            det.kappa += std::log(alpha)/n;
        }
        if( isOdd )
            det.rho = -det.rho;
    }
    catch( SingularMatrixException& e )
    {
        det.rho = 0;
        det.kappa = 0;
    }
#ifndef RELEASE
    PopCallStack();
#endif
    return det;
}
Beispiel #6
0
inline SafeProduct<F> 
LUPartialPiv( Matrix<F>& A )
{
#ifndef RELEASE
    CallStackEntry entry("determinant::LUPartialPiv");
#endif
    if( A.Height() != A.Width() )
        throw std::logic_error
        ("Cannot compute determinant of nonsquare matrix");

    typedef BASE(F) R;
    const int n = A.Height();
    const R scale(n);
    SafeProduct<F> det( n );

    try
    {
        Matrix<int> p;
        elem::LU( A, p ); 
        const bool isOdd = PivotParity( p );
        
        Matrix<F> d;
        A.GetDiagonal( d );
        for( int i=0; i<n; ++i )
        {
            const F delta = d.Get(i,0);
            R alpha = Abs(delta);
            det.rho *= delta/alpha;
            det.kappa += Log(alpha)/scale;
        }
        if( isOdd )
            det.rho = -det.rho;
    }
    catch( SingularMatrixException& e )
    {
        det.rho = 0;
        det.kappa = 0;
    }
    return det;
}