zpbcon function
void
zpbcon()
Implementation
void zpbcon(
final String UPLO,
final int N,
final int KD,
final Matrix<Complex> AB_,
final int LDAB,
final Box<double> ANORM,
final Box<double> RCOND,
final Array<Complex> WORK_,
final Array<double> RWORK_,
final Box<int> INFO,
) {
final AB = AB_.having(ld: LDAB);
final WORK = WORK_.having();
final RWORK = RWORK_.having();
const ONE = 1.0, ZERO = 0.0;
bool UPPER;
String NORMIN;
int IX;
double SCALE, SMLNUM;
final ISAVE = Array<int>(3);
final KASE = Box(0);
final AINVNM = Box(0.0), SCALEL = Box(0.0), SCALEU = Box(0.0);
// Test the input parameters.
INFO.value = 0;
UPPER = lsame(UPLO, 'U');
if (!UPPER && !lsame(UPLO, 'L')) {
INFO.value = -1;
} else if (N < 0) {
INFO.value = -2;
} else if (KD < 0) {
INFO.value = -3;
} else if (LDAB < KD + 1) {
INFO.value = -5;
} else if (ANORM.value < ZERO) {
INFO.value = -6;
}
if (INFO.value != 0) {
xerbla('ZPBCON', -INFO.value);
return;
}
// Quick return if possible
RCOND.value = ZERO;
if (N == 0) {
RCOND.value = ONE;
return;
} else if (ANORM.value == ZERO) {
return;
}
SMLNUM = dlamch('Safe minimum');
// Estimate the 1-norm of the inverse.
KASE.value = 0;
NORMIN = 'N';
while (true) {
zlacn2(N, WORK(N + 1), WORK, AINVNM, KASE, ISAVE);
if (KASE.value == 0) break;
if (UPPER) {
// Multiply by inv(U**H).
zlatbs('Upper', 'Conjugate transpose', 'Non-unit', NORMIN, N, KD, AB,
LDAB, WORK, SCALEL, RWORK, INFO);
NORMIN = 'Y';
// Multiply by inv(U).
zlatbs('Upper', 'No transpose', 'Non-unit', NORMIN, N, KD, AB, LDAB, WORK,
SCALEU, RWORK, INFO);
} else {
// Multiply by inv(L).
zlatbs('Lower', 'No transpose', 'Non-unit', NORMIN, N, KD, AB, LDAB, WORK,
SCALEL, RWORK, INFO);
NORMIN = 'Y';
// Multiply by inv(L**H).
zlatbs('Lower', 'Conjugate transpose', 'Non-unit', NORMIN, N, KD, AB,
LDAB, WORK, SCALEU, RWORK, INFO);
}
// Multiply by 1/SCALE if doing so will not cause overflow.
SCALE = SCALEL.value * SCALEU.value;
if (SCALE != ONE) {
IX = izamax(N, WORK, 1);
if (SCALE < WORK[IX].cabs1() * SMLNUM || SCALE == ZERO) return;
zdrscl(N, SCALE, WORK, 1);
}
}
// Compute the estimate of the reciprocal condition number.
if (AINVNM.value != ZERO) RCOND.value = (ONE / AINVNM.value) / ANORM.value;
}