/* --
Purpose
=======
DPBTRF computes the Cholesky factorization of a real symmetric
positive definite band matrix A.
The factorization has the form
A = U**T * U, if UPLO = 'U', or
A = L * L**T, if UPLO = 'L',
where U is an upper triangular matrix and L is lower triangular.
Arguments
=========
UPLO (input) CHARACTER*1
= 'U': Upper triangle of A is stored;
= 'L': Lower triangle of A is stored.
N (input) int
The order of the matrix A. N >= 0.
KD (input) int
The number of superdiagonals of the matrix A if UPLO = 'U',
or the number of subdiagonals if UPLO = 'L'. KD >= 0.
AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
On entry, the upper or lower triangle of the symmetric band
matrix A, stored in the first KD+1 rows of the array. The
j-th column of A is stored in the j-th column of the array AB
as follows:
if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).
On exit, if INFO = 0, the triangular factor U or L from the
Cholesky factorization A = U**T*U or A = L*L**T of the band
matrix A, in the same storage format as A.
LDAB (input) int
The leading dimension of the array AB. LDAB >= KD+1.
INFO (output) int
= 0: successful exit
< 0: if INFO = -i, the i-th argument had an illegal value
> 0: if INFO = i, the leading minor of order i is not
positive definite, and the factorization could not be
completed.
Further Details
===============
The band storage scheme is illustrated by the following example, when
N = 6, KD = 2, and UPLO = 'U':
On entry: On exit:
* * a13 a24 a35 a46 * * u13 u24 u35 u46
* a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56
a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66
Similarly, if UPLO = 'L' the format of A is as follows:
On entry: On exit:
a11 a22 a33 a44 a55 a66 l11 l22 l33 l44 l55 l66
a21 a32 a43 a54 a65 * l21 l32 l43 l54 l65 *
a31 a42 a53 a64 * * l31 l42 l53 l64 * *
Array elements marked * are not used by the routine.
Contributed by
Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989
=====================================================================
Test the input parameters.
*/
/*
Note: nb = ilaenv_(&c__1, "DPBTRF", uplo, n, kd, &c_n1, &c_n1, (ftnlen)6, (
ftnlen)1);
is modified to be
nb = 32;
*/
#include "stdafx.h"
#include "ZMath.h"
#include "CLAPACK_FACTORY.h"
int
CLAPACK_FACTORY::dpbtrf_(char *uplo, int *n, int *kd, double *ab, int *ldab, int *info)
{
static int c__1 = 1;
static int c_n1 = -1;
static double c_b18 = 1.;
static double c_b21 = -1.;
static int c__33 = 33;
/* System generated locals */
int ab_dim1, ab_offset, i__1, i__2, i__3, i__4;
/* Local variables */
static double work[1056] /* was [33][32] */;
static int i__, j;
//extern /* Subroutine */ int dgemm_(char *, char *, int *, int *,
// int *, double *, double *, int *, double *,
// int *, double *, double *, int *);
//extern logical lsame_(char *, char *);
//extern /* Subroutine */ int dtrsm_(char *, char *, char *, char *,
// int *, int *, double *, double *, int *,
// double *, int *);
static int i2, i3;
//extern /* Subroutine */ int dsyrk_(char *, char *, int *, int *,
// double *, double *, int *, double *, double *,
// int *), dpbtf2_(char *, int *, int *,
// double *, int *, int *), dpotf2_(char *,
// int *, double *, int *, int *);
static int ib, nb, ii, jj;
//extern /* Subroutine */ int xerbla_(char *, int *);
//extern int ilaenv_(int *, char *, char *, int *, int *,
// int *, int *, ftnlen, ftnlen);
#define work_ref(a_1,a_2) work[(a_2)*33 + a_1 - 34]
#define ab_ref(a_1,a_2) ab[(a_2)*ab_dim1 + a_1]
ab_dim1 = *ldab;
ab_offset = 1 + ab_dim1 * 1;
ab -= ab_offset;
/* Function Body */
*info = 0;
if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) {
*info = -1;
} else if (*n < 0) {
*info = -2;
} else if (*kd < 0) {
*info = -3;
} else if (*ldab < *kd + 1) {
*info = -5;
}
if (*info != 0) {
i__1 = -(*info);
xerbla_("DPBTRF", &i__1);
return 0;
}
/* Quick return if possible */
if (*n == 0) {
return 0;
}
/* Determine the block size for this environment */
/*
nb = ilaenv_(&c__1, "DPBTRF", uplo, n, kd, &c_n1, &c_n1, (ftnlen)6, (
ftnlen)1);
*/
nb = 32;
/* The block size must not exceed the semi-bandwidth KD, and must not
exceed the limit set by the size of the local array WORK. */
nb = CZMath::zMin(nb,32);
if (nb <= 1 || nb > *kd) {
/* Use unblocked code */
dpbtf2_(uplo, n, kd, &ab[ab_offset], ldab, info);
} else {
/* Use blocked code */
if (lsame_(uplo, "U")) {
/* Compute the Cholesky factorization of a symmetric band
matrix, given the upper triangle of the matrix in band
storage.
Zero the upper triangle of the work array. */
i__1 = nb;
for (j = 1; j <= i__1; ++j) {
i__2 = j - 1;
for (i__ = 1; i__ <= i__2; ++i__) {
work_ref(i__, j) = 0.;
/* L10: */
}
/* L20: */
}
/* Process the band matrix one diagonal block at a time. */
i__1 = *n;
i__2 = nb;
for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
/* Computing MIN */
i__3 = nb, i__4 = *n - i__ + 1;
ib = CZMath::zMin(i__3,i__4);
/* Factorize the diagonal block */
i__3 = *ldab - 1;
dpotf2_(uplo, &ib, &ab_ref(*kd + 1, i__), &i__3, &ii);
if (ii != 0) {
*info = i__ + ii - 1;
goto L150;
}
if (i__ + ib <= *n) {
/* Update the relevant part of the trailing submatrix.
If A11 denotes the diagonal block which has just been
factorized, then we need to update the remaining
blocks in the diagram:
A11 A12 A13
A22 A23
A33
The numbers of rows and columns in the partitioning
are IB, I2, I3 respectively. The blocks A12, A22 and
A23 are empty if IB = KD. The upper triangle of A13
lies outside the band.
Computing MIN */
i__3 = *kd - ib, i__4 = *n - i__ - ib + 1;
i2 = CZMath::zMin(i__3,i__4);
/* Computing MIN */
i__3 = ib, i__4 = *n - i__ - *kd + 1;
i3 = CZMath::zMin(i__3,i__4);
if (i2 > 0) {
/* Update A12 */
i__3 = *ldab - 1;
i__4 = *ldab - 1;
dtrsm_("Left", "Upper", "Transpose", "Non-unit", &ib,
&i2, &c_b18, &ab_ref(*kd + 1, i__), &i__3, &
ab_ref(*kd + 1 - ib, i__ + ib), &i__4);
/* Update A22 */
i__3 = *ldab - 1;
i__4 = *ldab - 1;
dsyrk_("Upper", "Transpose", &i2, &ib, &c_b21, &
ab_ref(*kd + 1 - ib, i__ + ib), &i__3, &c_b18,
&ab_ref(*kd + 1, i__ + ib), &i__4);
}
if (i3 > 0) {
/* Copy the lower