|
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