dpocon function
void
dpocon()
Implementation
void dpocon(
final String UPLO,
final int N,
final Matrix<double> A_,
final int LDA,
final double ANORM,
final Box<double> RCOND,
final Array<double> WORK_,
final Array<int> IWORK_,
final Box<int> INFO,
) {
final A = A_.having(ld: LDA);
final WORK = WORK_.having();
final IWORK = IWORK_.having();
const ONE = 1.0, ZERO = 0.0;
bool UPPER;
String NORMIN;
int IX;
double SCALE, SMLNUM;
final ISAVE = Array<int>(3);
final SCALEL = Box(0.0), SCALEU = Box(0.0), AINVNM = Box(0.0);
final KASE = Box(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 (LDA < max(1, N)) {
INFO.value = -4;
} else if (ANORM < ZERO) {
INFO.value = -5;
}
if (INFO.value != 0) {
xerbla('DPOCON', -INFO.value);
return;
}
// Quick return if possible
RCOND.value = ZERO;
if (N == 0) {
RCOND.value = ONE;
return;
} else if (ANORM == ZERO) {
return;
}
SMLNUM = dlamch('Safe minimum');
// Estimate the 1-norm of inv(A).
KASE.value = 0;
NORMIN = 'N';
while (true) {
dlacn2(N, WORK(N + 1), WORK, IWORK, AINVNM, KASE, ISAVE);
if (KASE.value == 0) break;
if (UPPER) {
// Multiply by inv(U**T).
dlatrs('Upper', 'Transpose', 'Non-unit', NORMIN, N, A, LDA, WORK, SCALEL,
WORK(2 * N + 1), INFO);
NORMIN = 'Y';
// Multiply by inv(U).
dlatrs('Upper', 'No transpose', 'Non-unit', NORMIN, N, A, LDA, WORK,
SCALEU, WORK(2 * N + 1), INFO);
} else {
// Multiply by inv(L).
dlatrs('Lower', 'No transpose', 'Non-unit', NORMIN, N, A, LDA, WORK,
SCALEL, WORK(2 * N + 1), INFO);
NORMIN = 'Y';
// Multiply by inv(L**T).
dlatrs('Lower', 'Transpose', 'Non-unit', NORMIN, N, A, LDA, WORK, SCALEU,
WORK(2 * N + 1), INFO);
}
// Multiply by 1/SCALE if doing so will not cause overflow.
SCALE = SCALEL.value * SCALEU.value;
if (SCALE != ONE) {
IX = idamax(N, WORK, 1);
if (SCALE < WORK[IX].abs() * SMLNUM || SCALE == ZERO) return;
drscl(N, SCALE, WORK, 1);
}
}
// Compute the estimate of the reciprocal condition number.
if (AINVNM.value != ZERO) RCOND.value = (ONE / AINVNM.value) / ANORM;
}