| 
    libflame
    12600
    
   
   | 
  
  
  
 
Functions | |
| FLA_Error | FLA_Wilkshift_tridiag (FLA_Obj delta1, FLA_Obj epsilon, FLA_Obj delta2, FLA_Obj kappa) | 
| FLA_Error | FLA_Wilkshift_tridiag_ops (float delta1, float epsilon, float delta2, float *kappa) | 
| double | fla_dlapy2 (double x, double y) | 
| FLA_Error | FLA_Wilkshift_tridiag_opd (double delta1, double epsilon, double delta2, double *kappa) | 
| double fla_dlapy2 | ( | double | x, | 
| double | y | ||
| ) | 
References FLA_Check_error_level(), FLA_Obj_datatype(), FLA_Wilkshift_tridiag_check(), FLA_Wilkshift_tridiag_opd(), and FLA_Wilkshift_tridiag_ops().
{
    FLA_Datatype datatype;
    datatype = FLA_Obj_datatype( delta1 );
    if ( FLA_Check_error_level() >= FLA_MIN_ERROR_CHECKING )
        FLA_Wilkshift_tridiag_check( delta1, epsilon, delta2, kappa );
    switch ( datatype )
    {
        case FLA_FLOAT:
        {
            float* delta1_p  = ( float* ) FLA_FLOAT_PTR( delta1 );
            float* epsilon_p = ( float* ) FLA_FLOAT_PTR( epsilon );
            float* delta2_p  = ( float* ) FLA_FLOAT_PTR( delta2 );
            float* kappa_p   = ( float* ) FLA_FLOAT_PTR( kappa );
            FLA_Wilkshift_tridiag_ops( *delta1_p,
                                       *epsilon_p,
                                       *delta2_p,
                                       kappa_p );
            break;
        }
        case FLA_DOUBLE:
        {
            double* delta1_p  = ( double* ) FLA_DOUBLE_PTR( delta1 );
            double* epsilon_p = ( double* ) FLA_DOUBLE_PTR( epsilon );
            double* delta2_p  = ( double* ) FLA_DOUBLE_PTR( delta2 );
            double* kappa_p   = ( double* ) FLA_DOUBLE_PTR( kappa );
            FLA_Wilkshift_tridiag_opd( *delta1_p,
                                       *epsilon_p,
                                       *delta2_p,
                                       kappa_p );
            break;
        }
    }
    return FLA_SUCCESS;
}
| FLA_Error FLA_Wilkshift_tridiag_opd | ( | double | delta1, | 
| double | epsilon, | ||
| double | delta2, | ||
| double * | kappa | ||
| ) | 
Referenced by FLA_Tevd_eigval_n_opd_var1(), FLA_Tevd_eigval_v_opd_var1(), FLA_Tevd_eigval_v_opd_var3(), FLA_Tevd_find_perfshift_opd(), and FLA_Wilkshift_tridiag().
{
    double a = delta1;
    double c = epsilon;
    double d = delta2;
    double p, q, r, s, k;
    // Begin with kappa equal to d.
    k = d;
    // Compute a scaling factor to promote numerical stability.
    s = fabs( a ) + 2.0 * fabs( c ) + fabs( d );
    if ( s == 0.0 ) return FLA_SUCCESS;
    // Compute q with scaling applied.
    q = ( c / s ) * ( c / s );
    if ( q != 0.0 )
    {
        // Compute p = 0.5*( a - d ) with scaling applied.
        p = 0.5 * ( ( a / s ) - ( d / s ) );
        // Compute r = sqrt( p*p - q ).
        r = sqrt( p * p + q );
        // If p*r is negative, then we need to negate r to ensure we use the
        // larger of the two eigenvalues.
        if ( p * r < 0.0 ) r = -r;
        // Compute the Wilkinson shift with scaling removed:
        //   k = lambda_min + d
        //     = d + lambda_min
        //     = d + (-q / lambda_max)
        //     = d - q / lambda_max
        //     = d - q / (p + r)
        k = k - s * ( q / ( p + r ) );
/*
        // LAPACK method:
        p = 0.5 * ( ( a ) - ( d ) ) / c ;
        //r = sqrt( p * p + 1.0 );
        r = fla_dlapy2( p, 1.0 );
        if ( p < 0.0 ) r = -r;
        k = k - ( c / ( p + r ) );
*/
    }
    // Save the result.
    *kappa = k;
    return FLA_SUCCESS;
}
| FLA_Error FLA_Wilkshift_tridiag_ops | ( | float | delta1, | 
| float | epsilon, | ||
| float | delta2, | ||
| float * | kappa | ||
| ) | 
Referenced by FLA_Wilkshift_tridiag().
{
    float  a = delta1;
    float  c = epsilon;
    float  d = delta2;
    float  p, q, r, s, k;
    // Begin with kappa equal to d.
    k = d;
    // Compute a scaling factor to promote numerical stability.
    s = fabs( a ) + 2.0F * fabs( c ) + fabs( d );
    if ( s == 0.0F ) return FLA_SUCCESS;
    // Compute q with scaling applied.
    q = ( c / s ) * ( c / s );
    if ( q != 0.0F )
    {
        // Compute p = 0.5*( a - d ) with scaling applied.
        p = 0.5F * ( ( a / s ) - ( d / s ) );
        // Compute r = sqrt( p*p - q ).
        r = sqrt( p * p + q );
        // If p*r is negative, then we need to negate r to ensure we use the
        // larger of the two eigenvalues.
        if ( p * r < 0.0F ) r = -r;
        // Compute the Wilkinson shift with scaling removed:
        //   k = lambda_min + d
        //     = d + lambda_min
        //     = d + (-q / lambda_max)
        //     = d - q / lambda_max
        //     = d - q / (p + r)
        k = k - s * ( q / ( p + r ) );
    }
    // Save the result.
    *kappa = k;
    return FLA_SUCCESS;
}
 1.7.6.1