void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  double *A, *C, z = 0.0, *Z;
  int n, i, j, q;
  char *U = "U";
  A = mxGetPr(prhs[0]);
  n = mxGetN(prhs[0]);
  if (nrhs != 1 || nlhs > 2) {
    mexWarnMsgTxt("Usage: [invA logdetA] = inv_logdet_pd(A)");
    return;
  }
  if (n != mxGetM(prhs[0])) {
    mexWarnMsgTxt("Error: Argument matrix must be square");
    return;
  }
  n = mxGetN(prhs[0]);
  plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL);
  C = mxGetPr(plhs[0]);
  memcpy(C,A,n*n*sizeof(double));
  dpotrf_(U, &n, C, &n, &q);                                     /* cholesky */
  if (q > 0) {
    mexWarnMsgTxt("Error: Argument matrix must be positive definite");
    return;
  }
  if (nlhs > 1) {                                         /* compute log det */
    plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL);
    Z = mxGetPr(plhs[1]);
    for (i=0; i<n; i++) z += log(C[i*(n+1)]);
    Z[0] = 2.0*z;
  }
  dpotri_(U, &n, C, &n, &q);                          /* cholesky to inverse */
  for (i=0; i<n; i++) for (j=i+1; j<n; j++) C[j+i*n] = C[i+j*n];
}
Beispiel #2
0
bool CMatrixFactorization<double>::InvertSymmetric(CDenseArray<double>& A) {

   if(A.NCols()!=A.NRows()) {

    	cout << "ERROR: Matrix is not symmetric." << endl;
    	return 1;

    }

   Cholesky(A);

   int lda, info, n;
   lda = A.NRows();
   n = lda;
   info = 0;

   double* a = A.Data().get();

   dpotri_("U",&n,a,&lda,&info);

   if(info>0) {

   	cout << "ERROR: Inversion failed." << endl;
   	return 1;

   }

   return 0;

}
Beispiel #3
0
bool my_inverse(const double in[N][N], double out[N][N], double &det)
{
  int errorHandler;
  int     n = N;
  char chU[] = "L";

  for (int j = 0; j < N; j++)
    for (int i = 0; i < N; i++)
      out[j][i] = in[j][i];

  dpotrf_(chU, &n, &out[0][0], &n, &errorHandler);
  assert(errorHandler >= 0);

  if (errorHandler > 0)
    return true;

  det = 1.0;
  for (int i = 0; i < N; i++)
    det *= out[i][i];
  det *= det;
  assert(det > 0.0);


  dpotri_(chU, &n, &out[0][0], &n, &errorHandler);
  assert(0 == errorHandler);
  for (int i = 0; i < N; i++)
    for (int j = i; j < N; j++)
      out[i][j] = out[j][i];

  return false;
}
Beispiel #4
0
int GMRFLib_comp_posdef_inverse(double *matrix, int dim)
{
	/*
	 * overwrite a symmetric MATRIX with its inverse 
	 */
	int info = 0, i, j;

	switch (GMRFLib_blas_level) {
	case BLAS_LEVEL2:
		dpotf2_("L", &dim, matrix, &dim, &info, 1);
		break;
	case BLAS_LEVEL3:
		dpotrf_("L", &dim, matrix, &dim, &info, 1);
		break;
	default:
		GMRFLib_ASSERT(1 == 0, GMRFLib_ESNH);
		break;
	}
	if (info)
		GMRFLib_ERROR(GMRFLib_ESINGMAT);

	dpotri_("L", &dim, matrix, &dim, &info, 1);
	if (info)
		GMRFLib_ERROR(GMRFLib_ESINGMAT);

	for (i = 0; i < dim; i++)			       /* fill the U-part */
		for (j = i + 1; j < dim; j++)
			matrix[i + j * dim] = matrix[j + i * dim];

	return GMRFLib_SUCCESS;
}
Beispiel #5
0
// chol2inv: compute inverse of n by n pd symm mat A using Cholesky
// assumes A is stored in non-packed upper triangular format
int chol2inv(int n, double *A, bool do_log_det, double *log_det) {
	char uplo = 'U';
	int  info;

	// compute factorization
	dpotrf_(&uplo, &n, A, &n, &info);
	if (info) {
		MSG("Error with chol(A): info = %d\n", info);
		return(info);
	}

	if (do_log_det) {
		// fill in log determinant
		*log_det = 0;

		for (int i = 0; i < n; i++)
			*log_det += log(A[i + i*n]);

		*log_det *= 2;
	}

	// complete inverse
	dpotri_(&uplo, &n, A, &n, &info);
	if (info) {
		MSG("Error with inv(chol(A)): info = %d\n", info);
		return(info);
	}

	return(0);
}
Beispiel #6
0
/** Calculates inverse of a symmetric matrix via Cholesky decomposition.
 * @param m - matrix size
 * @param S - input: matrix; output: S^-1
 * @return lapack_info from dgesvd_()
 */
static int invm(int m, double** S)
{
    char uplo = 'U';
    int lapack_info;
    int i, j;

    dpotrf_(&uplo, &m, S[0], &m, &lapack_info);
    if (lapack_info != 0)
        return lapack_info;
    dpotri_(&uplo, &m, S[0], &m, &lapack_info);
    if (lapack_info != 0)
        return lapack_info;
#if 0
    for (j = 1; j < m; ++j)
        for (i = 0; i < j; ++i)
            S[i][j] = S[j][i];
#else
    for (j = 1; j < m; ++j) {
        double* colj_rowi = S[j];
        double* rowj_coli = &S[0][j];

        for (i = 0; i < j; ++i, colj_rowi++, rowj_coli += m)
            *rowj_coli = *colj_rowi;
    }
#endif
    return 0;
}
Beispiel #7
0
int posymatinv(int size,double **A,double (*determinant))
{
    int i, j,INFO,N,LDA ;
    char uplo='L';
    double *AT;  /* AT=transpose vectorized matrix (to accomodate Fortran) */

    MAKE_VECTOR(AT,size*size);
    for (i=0; i<size; i++)		/* to call a Fortran routine from C */
    {   /* have to transform the matrix */
        for(j=0; j<size; j++) AT[j+size*i]=A[j][i];
    }

    N=size;
    LDA=size;

    dpotrf_ (&uplo, &N, AT, &LDA, &INFO);
    /* LAPACK routine DPOTRF computes an Cholesky decomposition of
       a symmetric positive definite matrix A.
       Parameters in the order as they appear in the function call:
       uplo="U" indicates that the strictly lower triangular part of
       A will be ignored, N is the order of the matrix A, the
       matrix A, the leading dimension of A, and the flag for the
       result. On exit, the upper triangle of A contains U.*/
    if (INFO==0) {
        int i;
        (*determinant)=1.0;
        for (i=0; i<N; i++) {
            (*determinant)*=AT[i+i*N]*AT[i+i*N];
        }
        dpotri_ (&uplo, &N, AT, &LDA, &INFO);
        /* LAPACK routine DPOTRI computes the inverse of a matrix A
           using the output of DPOTRF. This method inverts U using the
           Cholesky factorization of A.
           Parameters in the order as they appear in the function call:
           uplo="U" indicates that the strictly lower triangular part of
           A will be ignored, c1 is the order of the matrix A, the
           matrix A, the leading dimension of A, and the flag for the
           result. On exit, the upper triangle of A contains U.*/
        if (INFO!=0) {
            /* Marked by Wei-Chen Chen on 2009/06/07.
            *     printf("Problem in posymatinv: dpotri error %d\n",INFO);
            */
        }
    }
    else {
        /* Marked by Wei-Chen Chen on 2009/06/07.
        *   printf("Problem in posymatinv: dpotrf error %d\n",INFO);
        */
    }

    for (i=0; i<size; i++) {    /*transform the matrix back*/
        for(j=i; j<size; j++) {
            A[j][i]=AT[j+size*i];
            A[i][j]=AT[j+size*i];
        }
    }
    FREE_VECTOR(AT);
    return 0;
}
void dpotri(const char *in,
                   int &n,
                   double *a,
                   int &lda,
                   int *info)

{
	dpotri_(in,n,a,lda,info);
}
Beispiel #9
0
void ProtoMol::Lapack::dpotri(char *transA, int *n, double *A, int *lda,
                              int *info) {
  FAHCheckIn();
#if defined(HAVE_LAPACK)
  dpotri_(transA, n, A, lda, info);
#elif defined(HAVE_MKL_LAPACK)
  DPOTRI(transA, n, A, lda, info);
#else
  THROW(std::string(__func__) + " not supported");
#endif
}
Beispiel #10
0
/* Cholesky factorization based Matrix Inverse */
void THLapack_(potri)(char uplo, int n, real *a, int lda, int *info)
{
#ifdef  USE_LAPACK
#if defined(TH_REAL_IS_DOUBLE)
  dpotri_(&uplo, &n, a, &lda, info);
#else
  spotri_(&uplo, &n, a, &lda, info);
#endif
#else
  THError("potri: Lapack library not found in compile time\n");
#endif
}
Beispiel #11
0
int prepare_gene_reml(double *Y, double *Z, int ns, int num_covars, double *YTY, double *ZTY, double *ZTZ, double *detZTZ, double *YTCY )
{
int i, j, k;
int one=1, info;
double alpha, beta;


//calc YTY
*YTY=0;for(i=0;i<ns;i++){*YTY+=pow(Y[i],2);}

//calc ZTY, ZTZ, detZTZ, invZTZ (stored in ZTZ)
alpha=1.0;beta=0.0;
dgemv_("T", &ns, &num_covars, &alpha, Z, &ns, Y, &one, &beta, ZTY, &one);
dgemm_("T", "N", &num_covars, &num_covars, &ns, &alpha, Z, &ns, Z, &ns, &beta, ZTZ, &num_covars);

dpotrf_("U", &num_covars, ZTZ, &num_covars, &info);
if(info!=0)
{printf("Error with covariates 1\n\n");exit(1);}
*detZTZ=0;for(j=0;j<num_covars;j++){*detZTZ+=2*log(ZTZ[j+j*num_covars]);}
dpotri_("U", &num_covars, ZTZ, &num_covars, &info);
if(info!=0)
{printf("Error with covariates 2\n\n");exit(1);}

for(j=0;j<num_covars;j++)
{
for(k=0;k<j;k++){ZTZ[j+k*num_covars]=ZTZ[k+j*num_covars];}
}

//get YTCY = YTY - YTZ (inv)ZTZ ZTY and null likelihood
*YTCY=*YTY;
for(j=0;j<num_covars;j++)
{
for(k=0;k<num_covars;k++){*YTCY-=ZTY[j]*ZTZ[j+k*num_covars]*ZTY[k];}
}

return(0);
}	//end of prepare_gene_reml
void orderMatrix(const gsl_matrix* x, gsl_matrix* y, const gsl_matrix* M)
{
	int n = x->size1;
	int m = x->size2;
	gsl_matrix* invM = gsl_matrix_alloc(n,n);
	gsl_matrix_memcpy(invM,M);	
	int info=0;
	char lower = 'U';
	int lda = invM->tda;
	dpotrf_(&lower, &n, invM->data, &lda, &info);
	dpotri_(&lower, &n, invM->data, &lda, &info);
	for (int i=0; i<n; i++) {
		for (int j=i+1 ; j<n; j++) {
			gsl_matrix_set(invM,i,j,gsl_matrix_get(invM,j,i)) ;
		}
	}
	gsl_vector* x_ell_norms = gsl_vector_alloc(m);
	gsl_vector* temp = gsl_vector_alloc(n);
	for	(int i =0;i<m;i++)
	{
		gsl_vector_const_view xcol = gsl_matrix_const_column(x,i);
		My_dgemv(CblasNoTrans, 1.0, invM, &xcol.vector, 0.0, temp);
		gsl_vector_set(x_ell_norms, i, -My_ddot(&xcol.vector, temp));
	}
	gsl_permutation* p = gsl_permutation_alloc(m);
	gsl_sort_vector_index(p, x_ell_norms);
	for (int i=0; i<n; i++) {
		for (int j=0; j<m; j++) {
			gsl_matrix_set(y, i, j, gsl_matrix_get(x, i, gsl_permutation_get(p, j)));
		}
	}
	gsl_vector_free(x_ell_norms);
	gsl_vector_free(temp);
	gsl_matrix_free(invM);
	gsl_permutation_free(p);
	
}
/// Determinant of a real symmetric positive definite matrix.
void quantfin::interfaceCLAPACK::PositiveSymmetricMatrixInverse(const Array<double,2>& A,Array<double,2>& inverseA)
{
  int i,j;
  long int n = A.rows();
  if (n!=A.columns()) throw(std::logic_error("Array must be square"));
  double* ap  = new double[n*n];
  double* pos = ap;
  for (i=0;i<n;i++) {
    for (j=0;j<n;j++) *pos++ = A(j,i); }
  long int info = 0;
  char LorU = 'L';
  dpotrf_(&LorU,&n,ap,&n,&info);
  if (info) {
    delete[] ap;
	throw(std::logic_error("Cholesky factorization failed")); }
  dpotri_(&LorU,&n,ap,&n,&info);
  pos = ap;
  for (i=0;i<n;i++) {
	for (j=0;j<n;j++) {
	  if (j>=i) inverseA(j,i) = inverseA(i,j) = *pos; 
	  pos++; }}
  delete[] ap;
  if (info) throw(std::logic_error("Matrix inversion failed"));
}
void 
dpotri(char uplo, int  n,  double  *da,  int  lda,  int *info) 
{
    dpotri_ ( &uplo, &n, da, &lda, info );
}
Beispiel #15
0
/* Subroutine */ int dchkpo_(logical *dotype, integer *nn, integer *nval, 
	integer *nnb, integer *nbval, integer *nns, integer *nsval, 
	doublereal *thresh, logical *tsterr, integer *nmax, doublereal *a, 
	doublereal *afac, doublereal *ainv, doublereal *b, doublereal *x, 
	doublereal *xact, doublereal *work, doublereal *rwork, integer *iwork, 
	 integer *nout)
{
    /* Initialized data */

    static integer iseedy[4] = { 1988,1989,1990,1991 };
    static char uplos[1*2] = "U" "L";

    /* Format strings */
    static char fmt_9999[] = "(\002 UPLO = '\002,a1,\002', N =\002,i5,\002, "
	    "NB =\002,i4,\002, type \002,i2,\002, test \002,i2,\002, ratio "
	    "=\002,g12.5)";
    static char fmt_9998[] = "(\002 UPLO = '\002,a1,\002', N =\002,i5,\002, "
	    "NRHS=\002,i3,\002, type \002,i2,\002, test(\002,i2,\002) =\002,g"
	    "12.5)";
    static char fmt_9997[] = "(\002 UPLO = '\002,a1,\002', N =\002,i5,\002"
	    ",\002,10x,\002 type \002,i2,\002, test(\002,i2,\002) =\002,g12.5)"
	    ;

    /* System generated locals */
    integer i__1, i__2, i__3, i__4;

    /* Builtin functions */
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
    integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void);

    /* Local variables */
    integer i__, k, n, nb, in, kl, ku, lda, inb, ioff, mode, imat, info;
    char path[3], dist[1];
    integer irhs, nrhs;
    char uplo[1], type__[1];
    integer nrun;
    extern /* Subroutine */ int alahd_(integer *, char *), dget04_(
	    integer *, integer *, doublereal *, integer *, doublereal *, 
	    integer *, doublereal *, doublereal *);
    integer nfail, iseed[4];
    extern doublereal dget06_(doublereal *, doublereal *);
    doublereal rcond;
    extern /* Subroutine */ int dpot01_(char *, integer *, doublereal *, 
	    integer *, doublereal *, integer *, doublereal *, doublereal *);
    integer nimat;
    extern /* Subroutine */ int dpot02_(char *, integer *, integer *, 
	    doublereal *, integer *, doublereal *, integer *, doublereal *, 
	    integer *, doublereal *, doublereal *), dpot03_(char *, 
	    integer *, doublereal *, integer *, doublereal *, integer *, 
	    doublereal *, integer *, doublereal *, doublereal *, doublereal *), dpot05_(char *, integer *, integer *, doublereal *, 
	    integer *, doublereal *, integer *, doublereal *, integer *, 
	    doublereal *, integer *, doublereal *, doublereal *, doublereal *);
    doublereal anorm;
    integer iuplo, izero, nerrs;
    logical zerot;
    char xtype[1];
    extern /* Subroutine */ int dlatb4_(char *, integer *, integer *, integer 
	    *, char *, integer *, integer *, doublereal *, integer *, 
	    doublereal *, char *), alaerh_(char *, 
	    char *, integer *, integer *, char *, integer *, integer *, 
	    integer *, integer *, integer *, integer *, integer *, integer *, 
	    integer *);
    doublereal rcondc;
    extern /* Subroutine */ int dlacpy_(char *, integer *, integer *, 
	    doublereal *, integer *, doublereal *, integer *), 
	    dlarhs_(char *, char *, char *, char *, integer *, integer *, 
	    integer *, integer *, integer *, doublereal *, integer *, 
	    doublereal *, integer *, doublereal *, integer *, integer *, 
	    integer *), alasum_(char *, 
	    integer *, integer *, integer *, integer *);
    doublereal cndnum;
    extern /* Subroutine */ int dlatms_(integer *, integer *, char *, integer 
	    *, char *, doublereal *, integer *, doublereal *, doublereal *, 
	    integer *, integer *, char *, doublereal *, integer *, doublereal 
	    *, integer *), dpocon_(char *, integer *, 
	    doublereal *, integer *, doublereal *, doublereal *, doublereal *, 
	     integer *, integer *);
    extern doublereal dlansy_(char *, char *, integer *, doublereal *, 
	    integer *, doublereal *);
    extern /* Subroutine */ int derrpo_(char *, integer *), dporfs_(
	    char *, integer *, integer *, doublereal *, integer *, doublereal 
	    *, integer *, doublereal *, integer *, doublereal *, integer *, 
	    doublereal *, doublereal *, doublereal *, integer *, integer *), dpotrf_(char *, integer *, doublereal *, integer *, 
	    integer *), xlaenv_(integer *, integer *), dpotri_(char *, 
	     integer *, doublereal *, integer *, integer *), dpotrs_(
	    char *, integer *, integer *, doublereal *, integer *, doublereal 
	    *, integer *, integer *);
    doublereal result[8];

    /* Fortran I/O blocks */
    static cilist io___33 = { 0, 0, 0, fmt_9999, 0 };
    static cilist io___36 = { 0, 0, 0, fmt_9998, 0 };
    static cilist io___38 = { 0, 0, 0, fmt_9997, 0 };



/*  -- LAPACK test routine (version 3.1) -- */
/*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
/*     November 2006 */

/*     .. Scalar Arguments .. */
/*     .. */
/*     .. Array Arguments .. */
/*     .. */

/*  Purpose */
/*  ======= */

/*  DCHKPO tests DPOTRF, -TRI, -TRS, -RFS, and -CON */

/*  Arguments */
/*  ========= */

/*  DOTYPE  (input) LOGICAL array, dimension (NTYPES) */
/*          The matrix types to be used for testing.  Matrices of type j */
/*          (for 1 <= j <= NTYPES) are used for testing if DOTYPE(j) = */
/*          .TRUE.; if DOTYPE(j) = .FALSE., then type j is not used. */

/*  NN      (input) INTEGER */
/*          The number of values of N contained in the vector NVAL. */

/*  NVAL    (input) INTEGER array, dimension (NN) */
/*          The values of the matrix dimension N. */

/*  NNB     (input) INTEGER */
/*          The number of values of NB contained in the vector NBVAL. */

/*  NBVAL   (input) INTEGER array, dimension (NBVAL) */
/*          The values of the blocksize NB. */

/*  NNS     (input) INTEGER */
/*          The number of values of NRHS contained in the vector NSVAL. */

/*  NSVAL   (input) INTEGER array, dimension (NNS) */
/*          The values of the number of right hand sides NRHS. */

/*  THRESH  (input) DOUBLE PRECISION */
/*          The threshold value for the test ratios.  A result is */
/*          included in the output file if RESULT >= THRESH.  To have */
/*          every test ratio printed, use THRESH = 0. */

/*  TSTERR  (input) LOGICAL */
/*          Flag that indicates whether error exits are to be tested. */

/*  NMAX    (input) INTEGER */
/*          The maximum value permitted for N, used in dimensioning the */
/*          work arrays. */

/*  A       (workspace) DOUBLE PRECISION array, dimension (NMAX*NMAX) */

/*  AFAC    (workspace) DOUBLE PRECISION array, dimension (NMAX*NMAX) */

/*  AINV    (workspace) DOUBLE PRECISION array, dimension (NMAX*NMAX) */

/*  B       (workspace) DOUBLE PRECISION array, dimension (NMAX*NSMAX) */
/*          where NSMAX is the largest entry in NSVAL. */

/*  X       (workspace) DOUBLE PRECISION array, dimension (NMAX*NSMAX) */

/*  XACT    (workspace) DOUBLE PRECISION array, dimension (NMAX*NSMAX) */

/*  WORK    (workspace) DOUBLE PRECISION array, dimension */
/*                      (NMAX*max(3,NSMAX)) */

/*  RWORK   (workspace) DOUBLE PRECISION array, dimension */
/*                      (max(NMAX,2*NSMAX)) */

/*  IWORK   (workspace) INTEGER array, dimension (NMAX) */

/*  NOUT    (input) INTEGER */
/*          The unit number for output. */

/*  ===================================================================== */

/*     .. Parameters .. */
/*     .. */
/*     .. Local Scalars .. */
/*     .. */
/*     .. Local Arrays .. */
/*     .. */
/*     .. External Functions .. */
/*     .. */
/*     .. External Subroutines .. */
/*     .. */
/*     .. Scalars in Common .. */
/*     .. */
/*     .. Common blocks .. */
/*     .. */
/*     .. Intrinsic Functions .. */
/*     .. */
/*     .. Data statements .. */
    /* Parameter adjustments */
    --iwork;
    --rwork;
    --work;
    --xact;
    --x;
    --b;
    --ainv;
    --afac;
    --a;
    --nsval;
    --nbval;
    --nval;
    --dotype;

    /* Function Body */
/*     .. */
/*     .. Executable Statements .. */

/*     Initialize constants and the random number seed. */

    s_copy(path, "Double precision", (ftnlen)1, (ftnlen)16);
    s_copy(path + 1, "PO", (ftnlen)2, (ftnlen)2);
    nrun = 0;
    nfail = 0;
    nerrs = 0;
    for (i__ = 1; i__ <= 4; ++i__) {
	iseed[i__ - 1] = iseedy[i__ - 1];
/* L10: */
    }

/*     Test the error exits */

    if (*tsterr) {
	derrpo_(path, nout);
    }
    infoc_1.infot = 0;
    xlaenv_(&c__2, &c__2);

/*     Do for each value of N in NVAL */

    i__1 = *nn;
    for (in = 1; in <= i__1; ++in) {
	n = nval[in];
	lda = max(n,1);
	*(unsigned char *)xtype = 'N';
	nimat = 9;
	if (n <= 0) {
	    nimat = 1;
	}

	izero = 0;
	i__2 = nimat;
	for (imat = 1; imat <= i__2; ++imat) {

/*           Do the tests only if DOTYPE( IMAT ) is true. */

	    if (! dotype[imat]) {
		goto L110;
	    }

/*           Skip types 3, 4, or 5 if the matrix size is too small. */

	    zerot = imat >= 3 && imat <= 5;
	    if (zerot && n < imat - 2) {
		goto L110;
	    }

/*           Do first for UPLO = 'U', then for UPLO = 'L' */

	    for (iuplo = 1; iuplo <= 2; ++iuplo) {
		*(unsigned char *)uplo = *(unsigned char *)&uplos[iuplo - 1];

/*              Set up parameters with DLATB4 and generate a test matrix */
/*              with DLATMS. */

		dlatb4_(path, &imat, &n, &n, type__, &kl, &ku, &anorm, &mode, 
			&cndnum, dist);

		s_copy(srnamc_1.srnamt, "DLATMS", (ftnlen)6, (ftnlen)6);
		dlatms_(&n, &n, dist, iseed, type__, &rwork[1], &mode, &
			cndnum, &anorm, &kl, &ku, uplo, &a[1], &lda, &work[1], 
			 &info);

/*              Check error code from DLATMS. */

		if (info != 0) {
		    alaerh_(path, "DLATMS", &info, &c__0, uplo, &n, &n, &c_n1, 
			     &c_n1, &c_n1, &imat, &nfail, &nerrs, nout);
		    goto L100;
		}

/*              For types 3-5, zero one row and column of the matrix to */
/*              test that INFO is returned correctly. */

		if (zerot) {
		    if (imat == 3) {
			izero = 1;
		    } else if (imat == 4) {
			izero = n;
		    } else {
			izero = n / 2 + 1;
		    }
		    ioff = (izero - 1) * lda;

/*                 Set row and column IZERO of A to 0. */

		    if (iuplo == 1) {
			i__3 = izero - 1;
			for (i__ = 1; i__ <= i__3; ++i__) {
			    a[ioff + i__] = 0.;
/* L20: */
			}
			ioff += izero;
			i__3 = n;
			for (i__ = izero; i__ <= i__3; ++i__) {
			    a[ioff] = 0.;
			    ioff += lda;
/* L30: */
			}
		    } else {
			ioff = izero;
			i__3 = izero - 1;
			for (i__ = 1; i__ <= i__3; ++i__) {
			    a[ioff] = 0.;
			    ioff += lda;
/* L40: */
			}
			ioff -= izero;
			i__3 = n;
			for (i__ = izero; i__ <= i__3; ++i__) {
			    a[ioff + i__] = 0.;
/* L50: */
			}
		    }
		} else {
		    izero = 0;
		}

/*              Do for each value of NB in NBVAL */

		i__3 = *nnb;
		for (inb = 1; inb <= i__3; ++inb) {
		    nb = nbval[inb];
		    xlaenv_(&c__1, &nb);

/*                 Compute the L*L' or U'*U factorization of the matrix. */

		    dlacpy_(uplo, &n, &n, &a[1], &lda, &afac[1], &lda);
		    s_copy(srnamc_1.srnamt, "DPOTRF", (ftnlen)6, (ftnlen)6);
		    dpotrf_(uplo, &n, &afac[1], &lda, &info);

/*                 Check error code from DPOTRF. */

		    if (info != izero) {
			alaerh_(path, "DPOTRF", &info, &izero, uplo, &n, &n, &
				c_n1, &c_n1, &nb, &imat, &nfail, &nerrs, nout);
			goto L90;
		    }

/*                 Skip the tests if INFO is not 0. */

		    if (info != 0) {
			goto L90;
		    }

/* +    TEST 1 */
/*                 Reconstruct matrix from factors and compute residual. */

		    dlacpy_(uplo, &n, &n, &afac[1], &lda, &ainv[1], &lda);
		    dpot01_(uplo, &n, &a[1], &lda, &ainv[1], &lda, &rwork[1], 
			    result);

/* +    TEST 2 */
/*                 Form the inverse and compute the residual. */

		    dlacpy_(uplo, &n, &n, &afac[1], &lda, &ainv[1], &lda);
		    s_copy(srnamc_1.srnamt, "DPOTRI", (ftnlen)6, (ftnlen)6);
		    dpotri_(uplo, &n, &ainv[1], &lda, &info);

/*                 Check error code from DPOTRI. */

		    if (info != 0) {
			alaerh_(path, "DPOTRI", &info, &c__0, uplo, &n, &n, &
				c_n1, &c_n1, &c_n1, &imat, &nfail, &nerrs, 
				nout);
		    }

		    dpot03_(uplo, &n, &a[1], &lda, &ainv[1], &lda, &work[1], &
			    lda, &rwork[1], &rcondc, &result[1]);

/*                 Print information about the tests that did not pass */
/*                 the threshold. */

		    for (k = 1; k <= 2; ++k) {
			if (result[k - 1] >= *thresh) {
			    if (nfail == 0 && nerrs == 0) {
				alahd_(nout, path);
			    }
			    io___33.ciunit = *nout;
			    s_wsfe(&io___33);
			    do_fio(&c__1, uplo, (ftnlen)1);
			    do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer))
				    ;
			    do_fio(&c__1, (char *)&nb, (ftnlen)sizeof(integer)
				    );
			    do_fio(&c__1, (char *)&imat, (ftnlen)sizeof(
				    integer));
			    do_fio(&c__1, (char *)&k, (ftnlen)sizeof(integer))
				    ;
			    do_fio(&c__1, (char *)&result[k - 1], (ftnlen)
				    sizeof(doublereal));
			    e_wsfe();
			    ++nfail;
			}
/* L60: */
		    }
		    nrun += 2;

/*                 Skip the rest of the tests unless this is the first */
/*                 blocksize. */

		    if (inb != 1) {
			goto L90;
		    }

		    i__4 = *nns;
		    for (irhs = 1; irhs <= i__4; ++irhs) {
			nrhs = nsval[irhs];

/* +    TEST 3 */
/*                 Solve and compute residual for A * X = B . */

			s_copy(srnamc_1.srnamt, "DLARHS", (ftnlen)6, (ftnlen)
				6);
			dlarhs_(path, xtype, uplo, " ", &n, &n, &kl, &ku, &
				nrhs, &a[1], &lda, &xact[1], &lda, &b[1], &
				lda, iseed, &info);
			dlacpy_("Full", &n, &nrhs, &b[1], &lda, &x[1], &lda);

			s_copy(srnamc_1.srnamt, "DPOTRS", (ftnlen)6, (ftnlen)
				6);
			dpotrs_(uplo, &n, &nrhs, &afac[1], &lda, &x[1], &lda, 
				&info);

/*                 Check error code from DPOTRS. */

			if (info != 0) {
			    alaerh_(path, "DPOTRS", &info, &c__0, uplo, &n, &
				    n, &c_n1, &c_n1, &nrhs, &imat, &nfail, &
				    nerrs, nout);
			}

			dlacpy_("Full", &n, &nrhs, &b[1], &lda, &work[1], &
				lda);
			dpot02_(uplo, &n, &nrhs, &a[1], &lda, &x[1], &lda, &
				work[1], &lda, &rwork[1], &result[2]);

/* +    TEST 4 */
/*                 Check solution from generated exact solution. */

			dget04_(&n, &nrhs, &x[1], &lda, &xact[1], &lda, &
				rcondc, &result[3]);

/* +    TESTS 5, 6, and 7 */
/*                 Use iterative refinement to improve the solution. */

			s_copy(srnamc_1.srnamt, "DPORFS", (ftnlen)6, (ftnlen)
				6);
			dporfs_(uplo, &n, &nrhs, &a[1], &lda, &afac[1], &lda, 
				&b[1], &lda, &x[1], &lda, &rwork[1], &rwork[
				nrhs + 1], &work[1], &iwork[1], &info);

/*                 Check error code from DPORFS. */

			if (info != 0) {
			    alaerh_(path, "DPORFS", &info, &c__0, uplo, &n, &
				    n, &c_n1, &c_n1, &nrhs, &imat, &nfail, &
				    nerrs, nout);
			}

			dget04_(&n, &nrhs, &x[1], &lda, &xact[1], &lda, &
				rcondc, &result[4]);
			dpot05_(uplo, &n, &nrhs, &a[1], &lda, &b[1], &lda, &x[
				1], &lda, &xact[1], &lda, &rwork[1], &rwork[
				nrhs + 1], &result[5]);

/*                    Print information about the tests that did not pass */
/*                    the threshold. */

			for (k = 3; k <= 7; ++k) {
			    if (result[k - 1] >= *thresh) {
				if (nfail == 0 && nerrs == 0) {
				    alahd_(nout, path);
				}
				io___36.ciunit = *nout;
				s_wsfe(&io___36);
				do_fio(&c__1, uplo, (ftnlen)1);
				do_fio(&c__1, (char *)&n, (ftnlen)sizeof(
					integer));
				do_fio(&c__1, (char *)&nrhs, (ftnlen)sizeof(
					integer));
				do_fio(&c__1, (char *)&imat, (ftnlen)sizeof(
					integer));
				do_fio(&c__1, (char *)&k, (ftnlen)sizeof(
					integer));
				do_fio(&c__1, (char *)&result[k - 1], (ftnlen)
					sizeof(doublereal));
				e_wsfe();
				++nfail;
			    }
/* L70: */
			}
			nrun += 5;
/* L80: */
		    }

/* +    TEST 8 */
/*                 Get an estimate of RCOND = 1/CNDNUM. */

		    anorm = dlansy_("1", uplo, &n, &a[1], &lda, &rwork[1]);
		    s_copy(srnamc_1.srnamt, "DPOCON", (ftnlen)6, (ftnlen)6);
		    dpocon_(uplo, &n, &afac[1], &lda, &anorm, &rcond, &work[1]
, &iwork[1], &info);

/*                 Check error code from DPOCON. */

		    if (info != 0) {
			alaerh_(path, "DPOCON", &info, &c__0, uplo, &n, &n, &
				c_n1, &c_n1, &c_n1, &imat, &nfail, &nerrs, 
				nout);
		    }

		    result[7] = dget06_(&rcond, &rcondc);

/*                 Print the test ratio if it is .GE. THRESH. */

		    if (result[7] >= *thresh) {
			if (nfail == 0 && nerrs == 0) {
			    alahd_(nout, path);
			}
			io___38.ciunit = *nout;
			s_wsfe(&io___38);
			do_fio(&c__1, uplo, (ftnlen)1);
			do_fio(&c__1, (char *)&n, (ftnlen)sizeof(integer));
			do_fio(&c__1, (char *)&imat, (ftnlen)sizeof(integer));
			do_fio(&c__1, (char *)&c__8, (ftnlen)sizeof(integer));
			do_fio(&c__1, (char *)&result[7], (ftnlen)sizeof(
				doublereal));
			e_wsfe();
			++nfail;
		    }
		    ++nrun;
L90:
		    ;
		}
L100:
		;
	    }
L110:
	    ;
	}
/* L120: */
    }

/*     Print a summary of the results. */

    alasum_(path, nout, &nfail, &nrun, &nerrs);

    return 0;

/*     End of DCHKPO */

} /* dchkpo_ */
Beispiel #16
0
bool CFitProblem::calculateStatistics(const C_FLOAT64 & factor,
                                      const C_FLOAT64 & resolution)
{
  // Set the current values to the solution values.
  unsigned C_INT32 i, imax = mSolutionVariables.size();
  unsigned C_INT32 j, jmax = mExperimentDependentValues.size();
  unsigned C_INT32 l;

  mRMS = std::numeric_limits<C_FLOAT64>::quiet_NaN();
  mSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();


  mParameterSD.resize(imax);
  mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  mFisher = std::numeric_limits<C_FLOAT64>::quiet_NaN();
  mGradient.resize(imax);
  mGradient = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  // Recalcuate the best solution.
  for (i = 0; i < imax; i++)
    (*mUpdateMethods[i])(mSolutionVariables[i]);

  mStoreResults = true;
  calculate();

  // Keep the results
  CVector< C_FLOAT64 > DependentValues = mExperimentDependentValues;

  if (mSolutionValue == mInfinity)
    return false;

  // The statistics need to be calculated for the result, i.e., now.
  mpExperimentSet->calculateStatistics();

  if (jmax)
    mRMS = sqrt(mSolutionValue / jmax);

  if (jmax > imax)
    mSD = sqrt(mSolutionValue / (jmax - imax));


  mHaveStatistics = true;

  CMatrix< C_FLOAT64 > dyp;
  bool CalculateFIM = true;

  try
    {
      dyp.resize(imax, jmax);
    }

  catch (CCopasiException Exception)
    {
      CalculateFIM = false;
    }

  C_FLOAT64 Current;
  C_FLOAT64 Delta;

  // Calculate the gradient
  for (i = 0; i < imax; i++)
    {
      Current = mSolutionVariables[i];

      if (fabs(Current) > resolution)
        {
          (*mUpdateMethods[i])(Current *(1.0 + factor));
          Delta = 1.0 / (Current * factor);
        }
      else
        {
          (*mUpdateMethods[i])(resolution);
          Delta = 1.0 / resolution;
        }

      calculate();

      mGradient[i] = (mCalculateValue - mSolutionValue) * Delta;

      if (CalculateFIM)
        for (j = 0; j < jmax; j++)
          dyp(i, j) = (mExperimentDependentValues[j] - DependentValues[j]) * Delta;

      // Restore the value
      (*mUpdateMethods[i])(Current);
    }

  // This is necessary so that CExperiment::printResult shows the correct data.
  calculate();
  mStoreResults = false;

  if (!CalculateFIM)
    {
      // Make sure the timer is acurate.
      (*mCPUTime.getRefresh())();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 13);
      return false;
    }

  // Construct the fisher information matrix
  for (i = 0; i < imax; i++)
    for (l = 0; l <= i; l++)
      {
        C_FLOAT64 & tmp = mFisher(i, l);

        tmp = 0.0;

        for (j = 0; j < jmax; j++)
          tmp += dyp(i, j) * dyp(l, j);

        tmp *= 2.0;

        if (l != i)
          mFisher(l, i) = tmp;
      }

  mCorrelation = mFisher;

#ifdef XXXX
  /* int dgetrf_(integer *m,
   *             integer *n,
   *             doublereal *a,
   *             integer * lda,
   *             integer *ipiv,
   *             integer *info)
   *
   *  Purpose
   *  =======
   *
   *  DGETRF computes an LU factorization of a general M-by-N matrix A
   *  using partial pivoting with row interchanges.
   *
   *  The factorization has the form
   *     A = P * L * U
   *  where P is a permutation matrix, L is lower triangular with unit
   *  diagonal elements (lower trapezoidal if m > n), and U is upper
   *  triangular (upper trapezoidal if m < n).
   *
   *  This is the right-looking Level 3 BLAS version of the algorithm.
   *
   *  Arguments
   *  =========
   *
   *  m       (input) INTEGER
   *          The number of rows of the matrix A.  m >= 0.
   *
   *  n       (input) INTEGER
   *          The number of columns of the matrix A.  n >= 0.
   *
   *  a       (input/output) DOUBLE PRECISION array, dimension (lda,n)
   *          On entry, the m by n matrix to be factored.
   *          On exit, the factors L and U from the factorization
   *          A = P*L*U; the unit diagonal elements of L are not stored.
   *
   *  lda     (input) INTEGER
   *          The leading dimension of the array A.  lda >= max(1,m).
   *
   *  ipiv    (output) INTEGER array, dimension (min(m,n))
   *          The pivot indices; for 1 <= i <= min(m,n), row i of the
   *          matrix was interchanged with row ipiv(i).
   *
   *  info    (output) INTEGER
   *          = 0: successful exit
   *          < 0: if info = -k, the k-th argument had an illegal value
   *          > 0: if info = k, U(k,k) is exactly zero. The factorization
   *               has been completed, but the factor U is exactly
   *               singular, and division by zero will occur if it is used
   *               to solve a system of equations.
   */
  C_INT info = 0;
  C_INT N = imax;

  CVector< C_INT > ipiv(imax);

  dgetrf_(&N, &N, mCorrelation.array(), &N, ipiv.array(), &info);

  if (info)
    {
      mCorrelation = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 1, info);

      return false;
    }

  /* dgetri_(integer *n, doublereal *a, integer *lda, integer *ipiv,
   *         doublereal *work, integer *lwork, integer *info);
   *
   *
   *  Purpose
   *  =======
   *
   *  DGETRI computes the inverse of a matrix using the LU factorization
   *  computed by DGETRF.
   *
   *  This method inverts U and then computes inv(A) by solving the system
   *  inv(A)*L = inv(U) for inv(A).
   *
   *  Arguments
   *  =========
   *
   *  N       (input) INTEGER
   *          The order of the matrix A.  N >= 0.
   *
   *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
   *          On entry, the factors L and U from the factorization
   *          A = P*L*U as computed by DGETRF.
   *          On exit, if INFO = 0, the inverse of the original matrix A.
   *
   *  LDA     (input) INTEGER
   *          The leading dimension of the array A.  LDA >= max(1,N).
   *
   *  IPIV    (input) INTEGER array, dimension (N)
   *          The pivot indices from DGETRF; for 1<=i<=N, row i of the
   *          matrix was interchanged with row IPIV(i).
   *
   *  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
   *          On exit, if INFO=0, then WORK(1) returns the optimal LWORK.
   *
   *  LWORK   (input) INTEGER
   *          The dimension of the array WORK.  LWORK >= max(1,N).
   *          For optimal performance LWORK >= N*NB, where NB is
   *          the optimal blocksize returned by ILAENV.
   *
   *          If LWORK = -1, then a workspace query is assumed; the routine
   *          only calculates the optimal size of the WORK array, returns
   *          this value as the first entry of the WORK array, and no error
   *          message related to LWORK is issued by XERBLA.
   *
   *  INFO    (output) INTEGER
   *          = 0:  successful exit
   *          < 0:  if INFO = -i, the i-th argument had an illegal value
   *          > 0:  if INFO = i, U(i,i) is exactly zero; the matrix is
   *                singular and its inverse could not be computed.
   *
   */

  C_INT lwork = -1; // Instruct dgesvd_ to determine work array size.
  CVector< C_FLOAT64 > work;
  work.resize(1);

  dgetri_(&N, mCorrelation.array(), &N, ipiv.array(), work.array(), &lwork, &info);

  if (info)
    {
      mCorrelation = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 1, info);

      return false;
    }

  lwork = (C_INT) work[0];
  work.resize(lwork);

  dgetri_(&N, mCorrelation.array(), &N, ipiv.array(), work.array(), &lwork, &info);

  if (info)
    {
      mCorrelation = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 1, info);

      return false;
    }

#endif // XXXX

  // The Fisher Information matrix is a symmetric positive semidefinit matrix.

  /* int dpotrf_(char *uplo, integer *n, doublereal *a,
   *             integer *lda, integer *info);
   *
   *
   *  Purpose
   *  =======
   *
   *  DPOTRF computes the Cholesky factorization of a real symmetric
   *  positive definite 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.
   *
   *  This is the block version of the algorithm, calling Level 3 BLAS.
   *
   *  Arguments
   *  =========
   *
   *  UPLO    (input) CHARACTER*1
   *          = 'U':  Upper triangle of A is stored;
   *          = 'L':  Lower triangle of A is stored.
   *
   *  N       (input) INTEGER
   *          The order of the matrix A.  N >= 0.
   *
   *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
   *          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
   *          N-by-N upper triangular part of A contains the upper
   *          triangular part of the matrix A, and the strictly lower
   *          triangular part of A is not referenced.  If UPLO = 'L', the
   *          leading N-by-N lower triangular part of A contains the lower
   *          triangular part of the matrix A, and the strictly upper
   *          triangular part of A is not referenced.
   *
   *          On exit, if INFO = 0, the factor U or L from the Cholesky
   *          factorization A = U**T*U or A = L*L**T.
   *
   *  LDA     (input) INTEGER
   *          The leading dimension of the array A.  LDA >= max(1,N).
   *
   *  INFO    (output) INTEGER
   *          = 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.
   *
   */

  char U = 'U';
  C_INT info = 0;
  C_INT N = imax;

  dpotrf_(&U, &N, mCorrelation.array(), &N, &info);

  if (info)
    {
      mCorrelation = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 12);

      return false;
    }

  /* int dpotri_(char *uplo, integer *n, doublereal *a,
   *             integer *lda, integer *info);
   *
   *
   *  Purpose
   *  =======
   *
   *  DPOTRI computes the inverse of a real symmetric positive definite
   *  matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
   *  computed by DPOTRF.
   *
   *  Arguments
   *  =========
   *
   *  UPLO    (input) CHARACTER*1
   *          = 'U':  Upper triangle of A is stored;
   *          = 'L':  Lower triangle of A is stored.
   *
   *  N       (input) INTEGER
   *          The order of the matrix A.  N >= 0.
   *
   *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
   *          On entry, the triangular factor U or L from the Cholesky
   *          factorization A = U**T*U or A = L*L**T, as computed by
   *          DPOTRF.
   *          On exit, the upper or lower triangle of the (symmetric)
   *          inverse of A, overwriting the input factor U or L.
   *
   *  LDA     (input) INTEGER
   *          The leading dimension of the array A.  LDA >= max(1,N).
   *
   *  INFO    (output) INTEGER
   *          = 0:  successful exit
   *          < 0:  if INFO = -i, the i-th argument had an illegal value
   *          > 0:  if INFO = i, the (i,i) element of the factor U or L is
   *                zero, and the inverse could not be computed.
   *
   */

  dpotri_(&U, &N, mCorrelation.array(), &N, &info);

  if (info)
    {
      mCorrelation = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 1, info);

      return false;
    }

  // Assure that the inverse is completed.

  for (i = 0; i < imax; i++)
    for (l = 0; l < i; l++)
      mCorrelation(l, i) = mCorrelation(i, l);

  CVector< C_FLOAT64 > S(imax);

#ifdef XXXX
  // We invert the Fisher information matrix with the help of singular
  // value decomposition.

  /* int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
   *            doublereal *a, integer *lda, doublereal *s, doublereal *u,
   *            integer *ldu, doublereal *vt, integer *ldvt,
   *            doublereal *work, integer *lwork, integer *info);
   *
   *
   *  Purpose
   *  =======
   *
   *  DGESVD computes the singular value decomposition (SVD) of a real
   *  M-by-N matrix A, optionally computing the left and/or right singular
   *  vectors. The SVD is written
   *
   *       A = U * SIGMA * transpose(V)
   *
   *  where SIGMA is an M-by-N matrix which is zero except for its
   *  min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
   *  V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA
   *  are the singular values of A; they are real and non-negative, and
   *  are returned in descending order.  The first min(m,n) columns of
   *  U and V are the left and right singular vectors of A.
   *
   *  Note that the routine returns V**T, not V.
   *
   *  Arguments
   *  =========
   *
   *  JOBU    (input) CHARACTER*1
   *          Specifies options for computing all or part of the matrix U:
   *          = 'A':  all M columns of U are returned in array U:
   *          = 'S':  the first min(m,n) columns of U (the left singular
   *                  vectors) are returned in the array U;
   *          = 'O':  the first min(m,n) columns of U (the left singular
   *                  vectors) are overwritten on the array A;
   *          = 'N':  no columns of U (no left singular vectors) are
   *                  computed.
   *
   *  JOBVT   (input) CHARACTER*1
   *          Specifies options for computing all or part of the matrix
   *          V**T:
   *          = 'A':  all N rows of V**T are returned in the array VT;
   *          = 'S':  the first min(m,n) rows of V**T (the right singular
   *                  vectors) are returned in the array VT;
   *          = 'O':  the first min(m,n) rows of V**T (the right singular
   *                  vectors) are overwritten on the array A;
   *          = 'N':  no rows of V**T (no right singular vectors) are
   *                  computed.
   *
   *          JOBVT and JOBU cannot both be 'O'.
   *
   *  M       (input) INTEGER
   *          The number of rows of the input matrix A.  M >= 0.
   *
   *  N       (input) INTEGER
   *          The number of columns of the input matrix A.  N >= 0.
   *
   *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
   *          On entry, the M-by-N matrix A.
   *          On exit,
   *          if JOBU = 'O', A is overwritten with the first min(m,n)
   *                          columns of U (the left singular vectors,
   *                          stored columnwise);
   *          if JOBVT = 'O', A is overwritten with the first min(m,n)
   *                          rows of V**T (the right singular vectors,
   *                          stored rowwise);
   *          if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
   *                          are destroyed.
   *
   *  LDA     (input) INTEGER
   *          The leading dimension of the array A.  LDA >= max(1,M).
   *
   *  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
   *          The singular values of A, sorted so that S(i) >= S(i+1).
   *
   *  U       (output) DOUBLE PRECISION array, dimension (LDU,UCOL)
   *          (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
   *          If JOBU = 'A', U contains the M-by-M orthogonal matrix U;
   *          if JOBU = 'S', U contains the first min(m,n) columns of U
   *          (the left singular vectors, stored columnwise);
   *          if JOBU = 'N' or 'O', U is not referenced.
   *
   *  LDU     (input) INTEGER
   *          The leading dimension of the array U.  LDU >= 1; if
   *          JOBU = 'S' or 'A', LDU >= M.
   *
   *  VT      (output) DOUBLE PRECISION array, dimension (LDVT,N)
   *          If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
   *          V**T;
   *          if JOBVT = 'S', VT contains the first min(m,n) rows of
   *          V**T (the right singular vectors, stored rowwise);
   *          if JOBVT = 'N' or 'O', VT is not referenced.
   *
   *  LDVT    (input) INTEGER
   *          The leading dimension of the array VT.  LDVT >= 1; if
   *          JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
   *
   *  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
   *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
   *          if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged
   *          superdiagonal elements of an upper bidiagonal matrix B
   *          whose diagonal is in S (not necessarily sorted). B
   *          satisfies A = U * B * VT, so it has the same singular values
   *          as A, and singular vectors related by U and VT.
   *
   *  LWORK   (input) INTEGER
   *          The dimension of the array WORK.
   *          LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)).
   *          For good performance, LWORK should generally be larger.
   *
   *          If LWORK = -1, then a workspace query is assumed; the routine
   *          only calculates the optimal size of the WORK array, returns
   *          this value as the first entry of the WORK array, and no error
   *          message related to LWORK is issued by XERBLA.
   *
   *  INFO    (output) INTEGER
   *          = 0:  successful exit.
   *          < 0:  if INFO = -i, the i-th argument had an illegal value.
   *          > 0:  if DBDSQR did not converge, INFO specifies how many
   *                superdiagonals of an intermediate bidiagonal form B
   *                did not converge to zero. See the description of WORK
   *                above for details.
   *
   */

  char job = 'A';
  C_INT info = 0;
  C_INT N = imax;

  CVector< C_FLOAT64 > S(imax);
  CMatrix< C_FLOAT64 > U(imax, imax);
  CMatrix< C_FLOAT64 > VT(imax, imax);

  C_INT lwork = -1; // Instruct dgesvd_ to determine work array size.
  CVector< C_FLOAT64 > work;
  work.resize(1);

  dgesvd_(&job, &job, &N, &N, mCorrelation.array(), &N, S.array(), U.array(),
          &N, VT.array(), &N, work.array(), &lwork, &info);

  if (info)
    {
      mCorrelation = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 1, info);

      return false;
    }

  lwork = (C_INT) work[0];
  work.resize(lwork);

  // This actually calculates the SVD of mCorrelation^T, since dgesvd uses
  // fortran notation, i.e., mCorrelation = V^T * B^T * U
  dgesvd_(&job, &job, &N, &N, mCorrelation.array(), &N, S.array(), U.array(),
          &N, VT.array(), &N, work.array(), &lwork, &info);

  // Even if info is not zero we are still able to invert
  if (info)
    {
      mCorrelation = std::numeric_limits<C_FLOAT64>::quiet_NaN();
      mParameterSD = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      CCopasiMessage(CCopasiMessage::WARNING, MCFitting + 1, info);

      return false;
    }

  // Now we invert the Fisher Information Matrix. Please note,
  // that we are calculating a pseudo inverse in the case that one or
  // more singular values are zero.

  mCorrelation = 0.0;

  for (i = 0; i < imax; i++)
    if (S[i] == 0.0)
      mCorrelation(i, i) = 0.0;
    else
      mCorrelation(i, i) = 1.0 / S[i];

  CMatrix< C_FLOAT64 > Tmp(imax, imax);

  char opN = 'N';

  C_FLOAT64 Alpha = 1.0;
  C_FLOAT64 Beta = 0.0;

  dgemm_(&opN, &opN, &N, &N, &N, &Alpha, U.array(), &N,
         mCorrelation.array(), &N, &Beta, Tmp.array(), &N);

  dgemm_(&opN, &opN, &N, &N, &N, &Alpha, Tmp.array(), &N,
         VT.array(), &N, &Beta, mCorrelation.array(), &N);
#endif // XXXX

  // rescale the lower bound of the covariant matrix to have unit diagonal
  for (i = 0; i < imax; i++)
    {
      C_FLOAT64 & tmp = S[i];

      if (mCorrelation(i, i) > 0.0)
        {
          tmp = 1.0 / sqrt(mCorrelation(i, i));
          mParameterSD[i] = mSD / tmp;
        }
      else if (mCorrelation(i, i) < 0.0)
        {
          tmp = 1.0 / sqrt(- mCorrelation(i, i));
          mParameterSD[i] = mSD / tmp;
        }
      else
        {
          mParameterSD[i] = mInfinity;
          tmp = 1.0;
          mCorrelation(i, i) = 1.0;
        }
    }

  for (i = 0; i < imax; i++)
    for (l = 0; l < imax; l++)
      mCorrelation(i, l) *= S[i] * S[l];

  // Make sure the timer is acurate.
  (*mCPUTime.getRefresh())();

  return true;
}
Beispiel #17
0
/*
 * Cholesky-based solution of the 
 *  sequence of Feasible Generalized Least-Squares problem
 *  in the context of GWAS:
 */
int fgls_chol( FGLS_config_t cf )
{
	int n = cf.n,
		   m = cf.m,
		   p = cf.p,
		   t = cf.t,
		   x_b = cf.x_b,
		   /*y_b = cf.y_b,*/
		   wXL = cf.wXL,
		   wXR = cf.wXR;
    /* In-core operands */
    double *Phi;
    double *M;
	double *ests;
    double *h2;
	double *res_sigma;
    double alpha;
    double beta;

    /* Out-of-core operands */
    double *Bij; // Auxiliary variables

    /* Reusable data thanks to constant XL */
    double *XL;
    double *XL_orig; // XL and a copy (XL is overwritten at every iteration of j)
    double *B_t;  // Top part of b ( in inv(S) b )
    double *V_tl; // Top-Left part of V

    /* BLAS / LAPACK constants */
    double ZERO = 0.0;
    double ONE = 1.0;
    int iONE = 1;
    /* LAPACK error value */
    int info;

    /* iterators and auxiliar vars */
    int ib, i, j, k, l; // size_t
    int nn = cf.n * cf.n; // size_t
	size_t size_one_b_record = p + (p*(p+1))/2;

	// Threading
	int id;
	double *tmpBs, *tmpVs; // Buffer with one B and one V per thread
	double *oneB, *oneV;   // Each thread pointer to its B and V

    if ( cf.y_b != 1 )
	{
        fprintf(stderr, "\n[Warning] y_b not used (set to 1)\n");
		cf.y_b = 1;
	}

    /* Memory allocation */
    // In-core
	build_SPD_Phi( cf.n, cf.Z, cf.W, cf.Phi );
	Phi   = cf.Phi;
    M     = ( double * ) fgls_malloc ( (size_t)cf.n * cf.n * sizeof(double) );
    ests  = cf.ests;

	h2 = ests;
	res_sigma = &ests[2*cf.t];

    XL_orig = cf.XL;
    XL      = ( double * ) fgls_malloc ( cf.wXL * cf.n * sizeof(double) );
    B_t  = ( double * ) fgls_malloc ( cf.wXL * sizeof(double) );
    V_tl = ( double * ) fgls_malloc ( cf.wXL * cf.wXL * sizeof(double) );

	// Temporary storage prior to copying in db_B
    tmpBs = ( double * ) fgls_malloc ( cf.p * cf.num_threads * sizeof(double) );
    tmpVs = ( double * ) fgls_malloc ( cf.p * cf.p * cf.num_threads * sizeof(double) );

    /* Files and pointers for out-of-core */
    double *XR_comp, *Y_comp, *B_comp;

    /* Asynchronous IO data structures */
	double_buffering db_XR, db_Y, db_B;
	double_buffering_init( &db_XR, (size_t)cf.n * cf.wXR * cf.x_b * sizeof(double),
			                cf.XR, &cf ); // _fp
	double_buffering_init( &db_Y, (size_t)cf.n * cf.y_b * sizeof(double),
			                cf.Y,  &cf );
	double_buffering_init( &db_B, (size_t)size_one_b_record * cf.x_b * cf.y_b * sizeof(double),
			                cf.B,  &cf );

#if VAMPIR
    VT_USER_START("READ_X");
#endif
    /* Read first block of XR's */
	double_buffering_read_XR( &db_XR, IO_BUFF, 0, (size_t)MIN( cf.x_b, cf.m ) - 1 );
	double_buffering_swap( &db_XR );
#if VAMPIR
    VT_USER_END("READ_X");
#endif
#if VAMPIR
    VT_USER_START("READ_Y");
#endif
    /* Read first Y */
	double_buffering_read_Y( &db_Y, IO_BUFF, 0, 0 );
	double_buffering_swap( &db_Y );
#if VAMPIR
    VT_USER_END("READ_Y");
#endif

    int iter = 0;
    for ( j = 0; j < t; j++ )
    {
        /* Set the number of threads for the multi-threaded BLAS */
		set_multi_threaded_BLAS( cf.num_threads );

#if VAMPIR
        VT_USER_START("READ_Y");
#endif
        /* Read next Y */
		size_t next_j = (j+1) >= t ? 0 : j+1;
		double_buffering_read_Y( &db_Y, IO_BUFF, next_j, next_j );
#if VAMPIR
        VT_USER_END("READ_Y");
#endif

#if VAMPIR
        VT_USER_START("COMP_J");
#endif
        /* M := sigma * ( h^2 Phi - (1 - h^2) I ) */
        memcpy( M, Phi, (size_t)n * n * sizeof(double) );
		alpha = res_sigma[j] * h2[j];
        beta  = res_sigma[j] * (1 - h2[j]);
        dscal_(&nn, &alpha, M, &iONE);
        for ( i = 0; i < n; i++ )
            M[i*n + i] = M[i*n + i] + beta;

        /* L * L' = M */
        dpotrf_(LOWER, &n, M, &n, &info);
        if (info != 0)
        {
            char err[STR_BUFFER_SIZE];
            snprintf(err, STR_BUFFER_SIZE, "dpotrf(M) failed (info: %d)", info);
            error_msg(err, 1);
        }

        /* XL := inv(L) * XL */
        memcpy( XL, XL_orig, wXL * n * sizeof(double) );
        dtrsm_(LEFT, LOWER, NO_TRANS, NON_UNIT, &n, &wXL, &ONE, M, &n, XL, &n);

#if VAMPIR
        VT_USER_START("WAIT_Y");
#endif
        // Wait until current Y is available for computation
		double_buffering_wait( &db_Y, COMP_BUFF );
#if VAMPIR
        VT_USER_END("WAIT_Y");
#endif

        /* y := inv(L) * y */
		Y_comp = double_buffering_get_comp_buffer( &db_Y );
		// Sanity check
		average( Y_comp, n, 1, cf.threshold, "TRAIT", 
				&cf.Y_fvi->fvi_data[n*NAMELENGTH], NAMELENGTH, 0 );
        dtrsv_(LOWER, NO_TRANS, NON_UNIT, &n, M, &n, Y_comp, &iONE);

        /* B_t := XL' * y */
        dgemv_(TRANS, &n, &wXL, &ONE, XL, &n, Y_comp, &iONE, &ZERO, B_t, &iONE);

        /* V_tl := XL' * XL */
        dsyrk_(LOWER, TRANS, &wXL, &n, &ONE, XL, &n, &ZERO, V_tl, &wXL);
#if VAMPIR
        VT_USER_END("COMP_J");
#endif
		/* Solve for x_b X's at once */
        for (ib = 0; ib < m; ib += x_b) 
        {
#if VAMPIR
            VT_USER_START("READ_X");
#endif
            /* Read next block of XR's */
			size_t next_x_from = ((size_t)ib + x_b) >= m ?  0 : (size_t)ib + x_b;
			size_t next_x_to   = ((size_t)ib + x_b) >= m ? MIN( (size_t)x_b, (size_t)m ) - 1 : 
				                                           next_x_from + MIN( (size_t)x_b, (size_t)m - next_x_from ) - 1;
			double_buffering_read_XR( &db_XR, IO_BUFF, next_x_from, next_x_to );
#if VAMPIR
            VT_USER_END("READ_X");
#endif

#if VAMPIR
            VT_USER_START("WAIT_X");
#endif
            /* Wait until current block of XR's is available for computation */
			double_buffering_wait( &db_XR, COMP_BUFF );
#if VAMPIR
            VT_USER_END("WAIT_X");
#endif

            /* Set the number of threads for the multi-threaded BLAS */
			set_multi_threaded_BLAS( cf.num_threads );

#if VAMPIR
            VT_USER_START("COMP_IB");
#endif
            /* XR := inv(L) XR */
			XR_comp = double_buffering_get_comp_buffer( &db_XR );
			// Auxiliar variables
            int x_inc = MIN(x_b, m - ib);
            int rhss  = wXR * x_inc;
			// Sanity check
			average( XR_comp, n, x_inc, cf.threshold, "SNP", 
					&cf.XR_fvi->fvi_data[(n+ib)*NAMELENGTH], NAMELENGTH, 1 );
			// Computation
            dtrsm_(LEFT, LOWER, NO_TRANS, NON_UNIT, &n, &rhss, &ONE, M, &n, XR_comp, &n);

#if VAMPIR
            VT_USER_END("COMP_IB");
#endif

#if CHOL_MIX_PARALLELISM
            /* Set the number of threads for the multi-threaded BLAS to 1.
             * The innermost loop is parallelized using OPENMP */
			set_single_threaded_BLAS();
#endif
#if VAMPIR
            VT_USER_START("COMP_I");
#endif
            B_comp = double_buffering_get_comp_buffer( &db_B );
#if CHOL_MIX_PARALLELISM
            #pragma omp parallel for private(Bij, oneB, oneV, i, k, info, id) schedule(static) num_threads(cf.num_threads)
#endif
            for (i = 0; i < x_inc; i++)
            {
				id = omp_get_thread_num();
				oneB = &tmpBs[ id * p ];
				oneV = &tmpVs[ id * p * p ];
                Bij = &B_comp[i * size_one_b_record];

                // Building B
                // Copy B_T
                memcpy(oneB, B_t, wXL * sizeof(double));
                // B_B := XR' * y
                dgemv_("T", 
                        &n, &wXR, 
                        &ONE, &XR_comp[i * wXR * n], &n, Y_comp, &iONE, 
                        &ZERO, &oneB[wXL], &iONE);

                // Building V
                // Copy V_TL
                for( k = 0; k < wXL; k++ )
                    dcopy_(&wXL, &V_tl[k*wXL], &iONE, &oneV[k*p], &iONE); // V_TL
                // V_BL := XR' * XL
                dgemm_("T", "N",
                        &wXR, &wXL, &n,
                        &ONE, &XR_comp[i * wXR * n], &n, XL, &n,
                        &ZERO, &oneV[wXL], &p); // V_BL
                // V_BR := XR' * XR
                dsyrk_("L", "T", 
                        &wXR, &n, 
                        &ONE, &XR_comp[i * wXR * n], &n, 
                        &ZERO, &oneV[wXL * p + wXL], &p); // V_BR

                // B := inv(V) * B
                dpotrf_(LOWER, &p, oneV, &p, &info);
                if (info != 0)
                {
					for ( k = 0; k < size_one_b_record; k++ )
						Bij[k] = 0.0/0.0; //nan("char-sequence");
					continue;
                }
                dtrsv_(LOWER, NO_TRANS, NON_UNIT, &p, oneV, &p, oneB, &iONE);
                dtrsv_(LOWER,    TRANS, NON_UNIT, &p, oneV, &p, oneB, &iONE);

                /* V := res_sigma * inv( X' inv(M) X) */
                dpotri_(LOWER, &p, oneV, &p, &info);
                if (info != 0)
                {
                    char err[STR_BUFFER_SIZE];
                    snprintf(err, STR_BUFFER_SIZE, "dpotri failed (info: %d)", info);
                    error_msg(err, 1);
                }

				// Copy output
				for ( k = 0; k < p; k++ )
					Bij[k] = (float) oneB[k];
                for ( k = 0; k < p; k++ )
                    Bij[p+k] = (float)sqrt(oneV[k*p+k]);
				int idx = 0;
				for ( k = 0; k < p-1; k++ ) // Cols of V
					for ( l = k+1; l < p; l++ ) // Rows of V
					{
						Bij[p+p+idx] = (float)oneV[k*p+l];
						idx++;
					}
#if 0
			  printf("Chi square: %.6f\n", ( (oneB[p-1] / Bij[p+p-1]) * (oneB[p-1] / Bij[p+p-1]) ) );
#endif
            }
#if VAMPIR
            VT_USER_END("COMP_I");
#endif

#if VAMPIR
            VT_USER_START("WAIT_BV");
#endif
            /* Wait until the previous blocks of B's and V's are written */
            if ( iter > 0)
                double_buffering_wait( &db_B, IO_BUFF );
#if VAMPIR
            VT_USER_END("WAIT_BV");
#endif
            /* Write current blocks of B's and V's */
#if VAMPIR
            VT_USER_START("WRITE_BV");
#endif
			double_buffering_write_B( &db_B, COMP_BUFF, ib, ib+x_inc - 1, j, j );
#if VAMPIR
            VT_USER_END("WRITE_BV");
#endif

            /* Swap buffers */
			double_buffering_swap( &db_XR );
			double_buffering_swap( &db_B  );
            iter++;
        }
        /* Swap buffers */
		double_buffering_swap( &db_Y );
    }

#if VAMPIR
    VT_USER_START("WAIT_ALL");
#endif
    /* Wait for the remaining IO operations issued */
	double_buffering_wait( &db_XR, COMP_BUFF );
	double_buffering_wait( &db_Y,  COMP_BUFF );
	double_buffering_wait( &db_B,  IO_BUFF );
#if VAMPIR
    VT_USER_END("WAIT_ALL");
#endif

    /* Clean-up */
    free( M );

    free( XL );
    free( B_t  );
    free( V_tl );
    free( tmpBs );
    free( tmpVs );

	double_buffering_destroy( &db_XR );
	double_buffering_destroy( &db_Y  );
	double_buffering_destroy( &db_B  );

    return 0;
}
Beispiel #18
0
/* Subroutine */ int derrpo_(char *path, integer *nunit)
{
    /* Builtin functions */
    integer s_wsle(cilist *), e_wsle(void);
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);

    /* Local variables */
    doublereal a[16]	/* was [4][4] */, b[4];
    integer i__, j;
    doublereal w[12], x[4];
    char c2[2];
    doublereal r1[4], r2[4], af[16]	/* was [4][4] */;
    integer iw[4], info;
    doublereal anrm, rcond;
    extern /* Subroutine */ int dpbtf2_(char *, integer *, integer *, 
	    doublereal *, integer *, integer *), dpotf2_(char *, 
	    integer *, doublereal *, integer *, integer *), alaesm_(
	    char *, logical *, integer *), dpbcon_(char *, integer *, 
	    integer *, doublereal *, integer *, doublereal *, doublereal *, 
	    doublereal *, integer *, integer *);
    extern logical lsamen_(integer *, char *, char *);
    extern /* Subroutine */ int dpbequ_(char *, integer *, integer *, 
	    doublereal *, integer *, doublereal *, doublereal *, doublereal *, 
	     integer *), dpbrfs_(char *, integer *, integer *, 
	    integer *, doublereal *, integer *, doublereal *, integer *, 
	    doublereal *, integer *, doublereal *, integer *, doublereal *, 
	    doublereal *, doublereal *, integer *, integer *), 
	    dpbtrf_(char *, integer *, integer *, doublereal *, integer *, 
	    integer *), dpocon_(char *, integer *, doublereal *, 
	    integer *, doublereal *, doublereal *, doublereal *, integer *, 
	    integer *), chkxer_(char *, integer *, integer *, logical 
	    *, logical *), dppcon_(char *, integer *, doublereal *, 
	    doublereal *, doublereal *, doublereal *, integer *, integer *), dpoequ_(integer *, doublereal *, integer *, doublereal *, 
	     doublereal *, doublereal *, integer *), dpbtrs_(char *, integer *
, integer *, integer *, doublereal *, integer *, doublereal *, 
	    integer *, integer *), dporfs_(char *, integer *, integer 
	    *, doublereal *, integer *, doublereal *, integer *, doublereal *, 
	     integer *, doublereal *, integer *, doublereal *, doublereal *, 
	    doublereal *, integer *, integer *), dpotrf_(char *, 
	    integer *, doublereal *, integer *, integer *), dpotri_(
	    char *, integer *, doublereal *, integer *, integer *), 
	    dppequ_(char *, integer *, doublereal *, doublereal *, doublereal 
	    *, doublereal *, integer *), dpprfs_(char *, integer *, 
	    integer *, doublereal *, doublereal *, doublereal *, integer *, 
	    doublereal *, integer *, doublereal *, doublereal *, doublereal *, 
	     integer *, integer *), dpptrf_(char *, integer *, 
	    doublereal *, integer *), dpptri_(char *, integer *, 
	    doublereal *, integer *), dpotrs_(char *, integer *, 
	    integer *, doublereal *, integer *, doublereal *, integer *, 
	    integer *), dpptrs_(char *, integer *, integer *, 
	    doublereal *, doublereal *, integer *, integer *);

    /* Fortran I/O blocks */
    static cilist io___1 = { 0, 0, 0, 0, 0 };



/*  -- LAPACK test routine (version 3.1) -- */
/*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
/*     November 2006 */

/*     .. Scalar Arguments .. */
/*     .. */

/*  Purpose */
/*  ======= */

/*  DERRPO tests the error exits for the DOUBLE PRECISION routines */
/*  for symmetric positive definite matrices. */

/*  Arguments */
/*  ========= */

/*  PATH    (input) CHARACTER*3 */
/*          The LAPACK path name for the routines to be tested. */

/*  NUNIT   (input) INTEGER */
/*          The unit number for output. */

/*  ===================================================================== */

/*     .. Parameters .. */
/*     .. */
/*     .. Local Scalars .. */
/*     .. */
/*     .. Local Arrays .. */
/*     .. */
/*     .. External Functions .. */
/*     .. */
/*     .. External Subroutines .. */
/*     .. */
/*     .. Scalars in Common .. */
/*     .. */
/*     .. Common blocks .. */
/*     .. */
/*     .. Intrinsic Functions .. */
/*     .. */
/*     .. Executable Statements .. */

    infoc_1.nout = *nunit;
    io___1.ciunit = infoc_1.nout;
    s_wsle(&io___1);
    e_wsle();
    s_copy(c2, path + 1, (ftnlen)2, (ftnlen)2);

/*     Set the variables to innocuous values. */

    for (j = 1; j <= 4; ++j) {
	for (i__ = 1; i__ <= 4; ++i__) {
	    a[i__ + (j << 2) - 5] = 1. / (doublereal) (i__ + j);
	    af[i__ + (j << 2) - 5] = 1. / (doublereal) (i__ + j);
/* L10: */
	}
	b[j - 1] = 0.;
	r1[j - 1] = 0.;
	r2[j - 1] = 0.;
	w[j - 1] = 0.;
	x[j - 1] = 0.;
	iw[j - 1] = j;
/* L20: */
    }
    infoc_1.ok = TRUE_;

    if (lsamen_(&c__2, c2, "PO")) {

/*        Test error exits of the routines that use the Cholesky */
/*        decomposition of a symmetric positive definite matrix. */

/*        DPOTRF */

	s_copy(srnamc_1.srnamt, "DPOTRF", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpotrf_("/", &c__0, a, &c__1, &info);
	chkxer_("DPOTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpotrf_("U", &c_n1, a, &c__1, &info);
	chkxer_("DPOTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 4;
	dpotrf_("U", &c__2, a, &c__1, &info);
	chkxer_("DPOTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPOTF2 */

	s_copy(srnamc_1.srnamt, "DPOTF2", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpotf2_("/", &c__0, a, &c__1, &info);
	chkxer_("DPOTF2", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpotf2_("U", &c_n1, a, &c__1, &info);
	chkxer_("DPOTF2", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 4;
	dpotf2_("U", &c__2, a, &c__1, &info);
	chkxer_("DPOTF2", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPOTRI */

	s_copy(srnamc_1.srnamt, "DPOTRI", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpotri_("/", &c__0, a, &c__1, &info);
	chkxer_("DPOTRI", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpotri_("U", &c_n1, a, &c__1, &info);
	chkxer_("DPOTRI", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 4;
	dpotri_("U", &c__2, a, &c__1, &info);
	chkxer_("DPOTRI", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPOTRS */

	s_copy(srnamc_1.srnamt, "DPOTRS", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpotrs_("/", &c__0, &c__0, a, &c__1, b, &c__1, &info);
	chkxer_("DPOTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpotrs_("U", &c_n1, &c__0, a, &c__1, b, &c__1, &info);
	chkxer_("DPOTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpotrs_("U", &c__0, &c_n1, a, &c__1, b, &c__1, &info);
	chkxer_("DPOTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 5;
	dpotrs_("U", &c__2, &c__1, a, &c__1, b, &c__2, &info);
	chkxer_("DPOTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 7;
	dpotrs_("U", &c__2, &c__1, a, &c__2, b, &c__1, &info);
	chkxer_("DPOTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPORFS */

	s_copy(srnamc_1.srnamt, "DPORFS", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dporfs_("/", &c__0, &c__0, a, &c__1, af, &c__1, b, &c__1, x, &c__1, 
		r1, r2, w, iw, &info);
	chkxer_("DPORFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dporfs_("U", &c_n1, &c__0, a, &c__1, af, &c__1, b, &c__1, x, &c__1, 
		r1, r2, w, iw, &info);
	chkxer_("DPORFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dporfs_("U", &c__0, &c_n1, a, &c__1, af, &c__1, b, &c__1, x, &c__1, 
		r1, r2, w, iw, &info);
	chkxer_("DPORFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 5;
	dporfs_("U", &c__2, &c__1, a, &c__1, af, &c__2, b, &c__2, x, &c__2, 
		r1, r2, w, iw, &info);
	chkxer_("DPORFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 7;
	dporfs_("U", &c__2, &c__1, a, &c__2, af, &c__1, b, &c__2, x, &c__2, 
		r1, r2, w, iw, &info);
	chkxer_("DPORFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 9;
	dporfs_("U", &c__2, &c__1, a, &c__2, af, &c__2, b, &c__1, x, &c__2, 
		r1, r2, w, iw, &info);
	chkxer_("DPORFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 11;
	dporfs_("U", &c__2, &c__1, a, &c__2, af, &c__2, b, &c__2, x, &c__1, 
		r1, r2, w, iw, &info);
	chkxer_("DPORFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPOCON */

	s_copy(srnamc_1.srnamt, "DPOCON", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpocon_("/", &c__0, a, &c__1, &anrm, &rcond, w, iw, &info);
	chkxer_("DPOCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpocon_("U", &c_n1, a, &c__1, &anrm, &rcond, w, iw, &info);
	chkxer_("DPOCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 4;
	dpocon_("U", &c__2, a, &c__1, &anrm, &rcond, w, iw, &info);
	chkxer_("DPOCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPOEQU */

	s_copy(srnamc_1.srnamt, "DPOEQU", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpoequ_(&c_n1, a, &c__1, r1, &rcond, &anrm, &info);
	chkxer_("DPOEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpoequ_(&c__2, a, &c__1, r1, &rcond, &anrm, &info);
	chkxer_("DPOEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

    } else if (lsamen_(&c__2, c2, "PP")) {

/*        Test error exits of the routines that use the Cholesky */
/*        decomposition of a symmetric positive definite packed matrix. */

/*        DPPTRF */

	s_copy(srnamc_1.srnamt, "DPPTRF", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpptrf_("/", &c__0, a, &info);
	chkxer_("DPPTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpptrf_("U", &c_n1, a, &info);
	chkxer_("DPPTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPPTRI */

	s_copy(srnamc_1.srnamt, "DPPTRI", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpptri_("/", &c__0, a, &info);
	chkxer_("DPPTRI", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpptri_("U", &c_n1, a, &info);
	chkxer_("DPPTRI", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPPTRS */

	s_copy(srnamc_1.srnamt, "DPPTRS", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpptrs_("/", &c__0, &c__0, a, b, &c__1, &info);
	chkxer_("DPPTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpptrs_("U", &c_n1, &c__0, a, b, &c__1, &info);
	chkxer_("DPPTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpptrs_("U", &c__0, &c_n1, a, b, &c__1, &info);
	chkxer_("DPPTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 6;
	dpptrs_("U", &c__2, &c__1, a, b, &c__1, &info);
	chkxer_("DPPTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPPRFS */

	s_copy(srnamc_1.srnamt, "DPPRFS", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpprfs_("/", &c__0, &c__0, a, af, b, &c__1, x, &c__1, r1, r2, w, iw, &
		info);
	chkxer_("DPPRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpprfs_("U", &c_n1, &c__0, a, af, b, &c__1, x, &c__1, r1, r2, w, iw, &
		info);
	chkxer_("DPPRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpprfs_("U", &c__0, &c_n1, a, af, b, &c__1, x, &c__1, r1, r2, w, iw, &
		info);
	chkxer_("DPPRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 7;
	dpprfs_("U", &c__2, &c__1, a, af, b, &c__1, x, &c__2, r1, r2, w, iw, &
		info);
	chkxer_("DPPRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 9;
	dpprfs_("U", &c__2, &c__1, a, af, b, &c__2, x, &c__1, r1, r2, w, iw, &
		info);
	chkxer_("DPPRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPPCON */

	s_copy(srnamc_1.srnamt, "DPPCON", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dppcon_("/", &c__0, a, &anrm, &rcond, w, iw, &info);
	chkxer_("DPPCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dppcon_("U", &c_n1, a, &anrm, &rcond, w, iw, &info);
	chkxer_("DPPCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPPEQU */

	s_copy(srnamc_1.srnamt, "DPPEQU", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dppequ_("/", &c__0, a, r1, &rcond, &anrm, &info);
	chkxer_("DPPEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dppequ_("U", &c_n1, a, r1, &rcond, &anrm, &info);
	chkxer_("DPPEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

    } else if (lsamen_(&c__2, c2, "PB")) {

/*        Test error exits of the routines that use the Cholesky */
/*        decomposition of a symmetric positive definite band matrix. */

/*        DPBTRF */

	s_copy(srnamc_1.srnamt, "DPBTRF", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpbtrf_("/", &c__0, &c__0, a, &c__1, &info);
	chkxer_("DPBTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpbtrf_("U", &c_n1, &c__0, a, &c__1, &info);
	chkxer_("DPBTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpbtrf_("U", &c__1, &c_n1, a, &c__1, &info);
	chkxer_("DPBTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 5;
	dpbtrf_("U", &c__2, &c__1, a, &c__1, &info);
	chkxer_("DPBTRF", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPBTF2 */

	s_copy(srnamc_1.srnamt, "DPBTF2", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpbtf2_("/", &c__0, &c__0, a, &c__1, &info);
	chkxer_("DPBTF2", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpbtf2_("U", &c_n1, &c__0, a, &c__1, &info);
	chkxer_("DPBTF2", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpbtf2_("U", &c__1, &c_n1, a, &c__1, &info);
	chkxer_("DPBTF2", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 5;
	dpbtf2_("U", &c__2, &c__1, a, &c__1, &info);
	chkxer_("DPBTF2", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPBTRS */

	s_copy(srnamc_1.srnamt, "DPBTRS", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpbtrs_("/", &c__0, &c__0, &c__0, a, &c__1, b, &c__1, &info);
	chkxer_("DPBTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpbtrs_("U", &c_n1, &c__0, &c__0, a, &c__1, b, &c__1, &info);
	chkxer_("DPBTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpbtrs_("U", &c__1, &c_n1, &c__0, a, &c__1, b, &c__1, &info);
	chkxer_("DPBTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 4;
	dpbtrs_("U", &c__0, &c__0, &c_n1, a, &c__1, b, &c__1, &info);
	chkxer_("DPBTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 6;
	dpbtrs_("U", &c__2, &c__1, &c__1, a, &c__1, b, &c__1, &info);
	chkxer_("DPBTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 8;
	dpbtrs_("U", &c__2, &c__0, &c__1, a, &c__1, b, &c__1, &info);
	chkxer_("DPBTRS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPBRFS */

	s_copy(srnamc_1.srnamt, "DPBRFS", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpbrfs_("/", &c__0, &c__0, &c__0, a, &c__1, af, &c__1, b, &c__1, x, &
		c__1, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpbrfs_("U", &c_n1, &c__0, &c__0, a, &c__1, af, &c__1, b, &c__1, x, &
		c__1, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpbrfs_("U", &c__1, &c_n1, &c__0, a, &c__1, af, &c__1, b, &c__1, x, &
		c__1, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 4;
	dpbrfs_("U", &c__0, &c__0, &c_n1, a, &c__1, af, &c__1, b, &c__1, x, &
		c__1, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 6;
	dpbrfs_("U", &c__2, &c__1, &c__1, a, &c__1, af, &c__2, b, &c__2, x, &
		c__2, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 8;
	dpbrfs_("U", &c__2, &c__1, &c__1, a, &c__2, af, &c__1, b, &c__2, x, &
		c__2, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 10;
	dpbrfs_("U", &c__2, &c__0, &c__1, a, &c__1, af, &c__1, b, &c__1, x, &
		c__2, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 12;
	dpbrfs_("U", &c__2, &c__0, &c__1, a, &c__1, af, &c__1, b, &c__2, x, &
		c__1, r1, r2, w, iw, &info);
	chkxer_("DPBRFS", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPBCON */

	s_copy(srnamc_1.srnamt, "DPBCON", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpbcon_("/", &c__0, &c__0, a, &c__1, &anrm, &rcond, w, iw, &info);
	chkxer_("DPBCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpbcon_("U", &c_n1, &c__0, a, &c__1, &anrm, &rcond, w, iw, &info);
	chkxer_("DPBCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpbcon_("U", &c__1, &c_n1, a, &c__1, &anrm, &rcond, w, iw, &info);
	chkxer_("DPBCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 5;
	dpbcon_("U", &c__2, &c__1, a, &c__1, &anrm, &rcond, w, iw, &info);
	chkxer_("DPBCON", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);

/*        DPBEQU */

	s_copy(srnamc_1.srnamt, "DPBEQU", (ftnlen)32, (ftnlen)6);
	infoc_1.infot = 1;
	dpbequ_("/", &c__0, &c__0, a, &c__1, r1, &rcond, &anrm, &info);
	chkxer_("DPBEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 2;
	dpbequ_("U", &c_n1, &c__0, a, &c__1, r1, &rcond, &anrm, &info);
	chkxer_("DPBEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 3;
	dpbequ_("U", &c__1, &c_n1, a, &c__1, r1, &rcond, &anrm, &info);
	chkxer_("DPBEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
	infoc_1.infot = 5;
	dpbequ_("U", &c__2, &c__1, a, &c__1, r1, &rcond, &anrm, &info);
	chkxer_("DPBEQU", &infoc_1.infot, &infoc_1.nout, &infoc_1.lerr, &
		infoc_1.ok);
    }

/*     Print a summary line. */

    alaesm_(path, &infoc_1.ok, &infoc_1.nout);

    return 0;

/*     End of DERRPO */

} /* derrpo_ */
Beispiel #19
0
/* Subroutine */ int ddrvpo_(logical *dotype, integer *nn, integer *nval, 
	integer *nrhs, doublereal *thresh, logical *tsterr, integer *nmax, 
	doublereal *a, doublereal *afac, doublereal *asav, doublereal *b, 
	doublereal *bsav, doublereal *x, doublereal *xact, doublereal *s, 
	doublereal *work, doublereal *rwork, integer *iwork, integer *nout)
{
    /* Initialized data */

    static integer iseedy[4] = { 1988,1989,1990,1991 };
    static char uplos[1*2] = "U" "L";
    static char facts[1*3] = "F" "N" "E";
    static char equeds[1*2] = "N" "Y";

    /* Format strings */
    static char fmt_9999[] = "(1x,a,\002, UPLO='\002,a1,\002', N =\002,i5"
	    ",\002, type \002,i1,\002, test(\002,i1,\002)=\002,g12.5)";
    static char fmt_9997[] = "(1x,a,\002, FACT='\002,a1,\002', UPLO='\002,"
	    "a1,\002', N=\002,i5,\002, EQUED='\002,a1,\002', type \002,i1,"
	    "\002, test(\002,i1,\002) =\002,g12.5)";
    static char fmt_9998[] = "(1x,a,\002, FACT='\002,a1,\002', UPLO='\002,"
	    "a1,\002', N=\002,i5,\002, type \002,i1,\002, test(\002,i1,\002)"
	    "=\002,g12.5)";

    /* System generated locals */
    address a__1[2];
    integer i__1, i__2, i__3, i__4, i__5[2];
    char ch__1[2];

    /* Builtin functions */
    /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
    integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void);
    /* Subroutine */ int s_cat(char *, char **, integer *, integer *, ftnlen);

    /* Local variables */
    integer i__, k, n, k1, nb, in, kl, ku, nt, lda;
    char fact[1];
    integer ioff, mode;
    doublereal amax;
    char path[3];
    integer imat, info;
    char dist[1], uplo[1], type__[1];
    integer nrun, ifact;
    extern /* Subroutine */ int dget04_(integer *, integer *, doublereal *, 
	    integer *, doublereal *, integer *, doublereal *, doublereal *);
    integer nfail, iseed[4], nfact;
    extern doublereal dget06_(doublereal *, doublereal *);
    extern logical lsame_(char *, char *);
    char equed[1];
    integer nbmin;
    doublereal rcond, roldc, scond;
    integer nimat;
    extern /* Subroutine */ int dpot01_(char *, integer *, doublereal *, 
	    integer *, doublereal *, integer *, doublereal *, doublereal *), dpot02_(char *, integer *, integer *, doublereal *, 
	    integer *, doublereal *, integer *, doublereal *, integer *, 
	    doublereal *, doublereal *), dpot05_(char *, integer *, 
	    integer *, doublereal *, integer *, doublereal *, integer *, 
	    doublereal *, integer *, doublereal *, integer *, doublereal *, 
	    doublereal *, doublereal *);
    doublereal anorm;
    logical equil;
    integer iuplo, izero, nerrs;
    extern /* Subroutine */ int dposv_(char *, integer *, integer *, 
	    doublereal *, integer *, doublereal *, integer *, integer *);
    logical zerot;
    char xtype[1];
    extern /* Subroutine */ int dlatb4_(char *, integer *, integer *, integer 
	    *, char *, integer *, integer *, doublereal *, integer *, 
	    doublereal *, char *), aladhd_(integer *, 
	    char *), alaerh_(char *, char *, integer *, integer *, 
	    char *, integer *, integer *, integer *, integer *, integer *, 
	    integer *, integer *, integer *, integer *);
    logical prefac;
    doublereal rcondc;
    logical nofact;
    integer iequed;
    extern /* Subroutine */ int dlacpy_(char *, integer *, integer *, 
	    doublereal *, integer *, doublereal *, integer *), 
	    dlarhs_(char *, char *, char *, char *, integer *, integer *, 
	    integer *, integer *, integer *, doublereal *, integer *, 
	    doublereal *, integer *, doublereal *, integer *, integer *, 
	    integer *), dlaset_(char *, 
	    integer *, integer *, doublereal *, doublereal *, doublereal *, 
	    integer *), alasvm_(char *, integer *, integer *, integer 
	    *, integer *);
    doublereal cndnum;
    extern /* Subroutine */ int dlatms_(integer *, integer *, char *, integer 
	    *, char *, doublereal *, integer *, doublereal *, doublereal *, 
	    integer *, integer *, char *, doublereal *, integer *, doublereal 
	    *, integer *);
    doublereal ainvnm;
    extern doublereal dlansy_(char *, char *, integer *, doublereal *, 
	    integer *, doublereal *);
    extern /* Subroutine */ int dlaqsy_(char *, integer *, doublereal *, 
	    integer *, doublereal *, doublereal *, doublereal *, char *), dpoequ_(integer *, doublereal *, integer *, 
	    doublereal *, doublereal *, doublereal *, integer *), dpotrf_(
	    char *, integer *, doublereal *, integer *, integer *), 
	    dpotri_(char *, integer *, doublereal *, integer *, integer *), xlaenv_(integer *, integer *), derrvx_(char *, integer *);
    doublereal result[6];
    extern /* Subroutine */ int dposvx_(char *, char *, integer *, integer *, 
	    doublereal *, integer *, doublereal *, integer *, char *, 
	    doublereal *, doublereal *, integer *, doublereal *, integer *, 
	    doublereal *, doublereal *, doublereal *, doublereal *, integer *, 
	     integer *);

    /* Fortran I/O blocks */
    static cilist io___48 = { 0, 0, 0, fmt_9999, 0 };
    static cilist io___51 = { 0, 0, 0, fmt_9997, 0 };
    static cilist io___52 = { 0, 0, 0, fmt_9998, 0 };



/*  -- LAPACK test routine (version 3.1) -- */
/*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
/*     November 2006 */

/*     .. Scalar Arguments .. */
/*     .. */
/*     .. Array Arguments .. */
/*     .. */

/*  Purpose */
/*  ======= */

/*  DDRVPO tests the driver routines DPOSV and -SVX. */

/*  Arguments */
/*  ========= */

/*  DOTYPE  (input) LOGICAL array, dimension (NTYPES) */
/*          The matrix types to be used for testing.  Matrices of type j */
/*          (for 1 <= j <= NTYPES) are used for testing if DOTYPE(j) = */
/*          .TRUE.; if DOTYPE(j) = .FALSE., then type j is not used. */

/*  NN      (input) INTEGER */
/*          The number of values of N contained in the vector NVAL. */

/*  NVAL    (input) INTEGER array, dimension (NN) */
/*          The values of the matrix dimension N. */

/*  NRHS    (input) INTEGER */
/*          The number of right hand side vectors to be generated for */
/*          each linear system. */

/*  THRESH  (input) DOUBLE PRECISION */
/*          The threshold value for the test ratios.  A result is */
/*          included in the output file if RESULT >= THRESH.  To have */
/*          every test ratio printed, use THRESH = 0. */

/*  TSTERR  (input) LOGICAL */
/*          Flag that indicates whether error exits are to be tested. */

/*  NMAX    (input) INTEGER */
/*          The maximum value permitted for N, used in dimensioning the */
/*          work arrays. */

/*  A       (workspace) DOUBLE PRECISION array, dimension (NMAX*NMAX) */

/*  AFAC    (workspace) DOUBLE PRECISION array, dimension (NMAX*NMAX) */

/*  ASAV    (workspace) DOUBLE PRECISION array, dimension (NMAX*NMAX) */

/*  B       (workspace) DOUBLE PRECISION array, dimension (NMAX*NRHS) */

/*  BSAV    (workspace) DOUBLE PRECISION array, dimension (NMAX*NRHS) */

/*  X       (workspace) DOUBLE PRECISION array, dimension (NMAX*NRHS) */

/*  XACT    (workspace) DOUBLE PRECISION array, dimension (NMAX*NRHS) */

/*  S       (workspace) DOUBLE PRECISION array, dimension (NMAX) */

/*  WORK    (workspace) DOUBLE PRECISION array, dimension */
/*                      (NMAX*max(3,NRHS)) */

/*  RWORK   (workspace) DOUBLE PRECISION array, dimension (NMAX+2*NRHS) */

/*  IWORK   (workspace) INTEGER array, dimension (NMAX) */

/*  NOUT    (input) INTEGER */
/*          The unit number for output. */

/*  ===================================================================== */

/*     .. Parameters .. */
/*     .. */
/*     .. Local Scalars .. */
/*     .. */
/*     .. Local Arrays .. */
/*     .. */
/*     .. External Functions .. */
/*     .. */
/*     .. External Subroutines .. */
/*     .. */
/*     .. Intrinsic Functions .. */
/*     .. */
/*     .. Scalars in Common .. */
/*     .. */
/*     .. Common blocks .. */
/*     .. */
/*     .. Data statements .. */
    /* Parameter adjustments */
    --iwork;
    --rwork;
    --work;
    --s;
    --xact;
    --x;
    --bsav;
    --b;
    --asav;
    --afac;
    --a;
    --nval;
    --dotype;

    /* Function Body */
/*     .. */
/*     .. Executable Statements .. */

/*     Initialize constants and the random number seed. */

    s_copy(path, "Double precision", (ftnlen)1, (ftnlen)16);
    s_copy(path + 1, "PO", (ftnlen)2, (ftnlen)2);
    nrun = 0;
    nfail = 0;
    nerrs = 0;
    for (i__ = 1; i__ <= 4; ++i__) {
	iseed[i__ - 1] = iseedy[i__ - 1];
/* L10: */
    }

/*     Test the error exits */

    if (*tsterr) {
	derrvx_(path, nout);
    }
    infoc_1.infot = 0;

/*     Set the block size and minimum block size for testing. */

    nb = 1;
    nbmin = 2;
    xlaenv_(&c__1, &nb);
    xlaenv_(&c__2, &nbmin);

/*     Do for each value of N in NVAL */

    i__1 = *nn;
    for (in = 1; in <= i__1; ++in) {
	n = nval[in];
	lda = max(n,1);
	*(unsigned char *)xtype = 'N';
	nimat = 9;
	if (n <= 0) {
	    nimat = 1;
	}

	i__2 = nimat;
	for (imat = 1; imat <= i__2; ++imat) {

/*           Do the tests only if DOTYPE( IMAT ) is true. */

	    if (! dotype[imat]) {
		goto L120;
	    }

/*           Skip types 3, 4, or 5 if the matrix size is too small. */

	    zerot = imat >= 3 && imat <= 5;
	    if (zerot && n < imat - 2) {
		goto L120;
	    }

/*           Do first for UPLO = 'U', then for UPLO = 'L' */

	    for (iuplo = 1; iuplo <= 2; ++iuplo) {
		*(unsigned char *)uplo = *(unsigned char *)&uplos[iuplo - 1];

/*              Set up parameters with DLATB4 and generate a test matrix */
/*              with DLATMS. */

		dlatb4_(path, &imat, &n, &n, type__, &kl, &ku, &anorm, &mode, 
			&cndnum, dist);

		s_copy(srnamc_1.srnamt, "DLATMS", (ftnlen)32, (ftnlen)6);
		dlatms_(&n, &n, dist, iseed, type__, &rwork[1], &mode, &
			cndnum, &anorm, &kl, &ku, uplo, &a[1], &lda, &work[1], 
			 &info);

/*              Check error code from DLATMS. */

		if (info != 0) {
		    alaerh_(path, "DLATMS", &info, &c__0, uplo, &n, &n, &c_n1, 
			     &c_n1, &c_n1, &imat, &nfail, &nerrs, nout);
		    goto L110;
		}

/*              For types 3-5, zero one row and column of the matrix to */
/*              test that INFO is returned correctly. */

		if (zerot) {
		    if (imat == 3) {
			izero = 1;
		    } else if (imat == 4) {
			izero = n;
		    } else {
			izero = n / 2 + 1;
		    }
		    ioff = (izero - 1) * lda;

/*                 Set row and column IZERO of A to 0. */

		    if (iuplo == 1) {
			i__3 = izero - 1;
			for (i__ = 1; i__ <= i__3; ++i__) {
			    a[ioff + i__] = 0.;
/* L20: */
			}
			ioff += izero;
			i__3 = n;
			for (i__ = izero; i__ <= i__3; ++i__) {
			    a[ioff] = 0.;
			    ioff += lda;
/* L30: */
			}
		    } else {
			ioff = izero;
			i__3 = izero - 1;
			for (i__ = 1; i__ <= i__3; ++i__) {
			    a[ioff] = 0.;
			    ioff += lda;
/* L40: */
			}
			ioff -= izero;
			i__3 = n;
			for (i__ = izero; i__ <= i__3; ++i__) {
			    a[ioff + i__] = 0.;
/* L50: */
			}
		    }
		} else {
		    izero = 0;
		}

/*              Save a copy of the matrix A in ASAV. */

		dlacpy_(uplo, &n, &n, &a[1], &lda, &asav[1], &lda);

		for (iequed = 1; iequed <= 2; ++iequed) {
		    *(unsigned char *)equed = *(unsigned char *)&equeds[
			    iequed - 1];
		    if (iequed == 1) {
			nfact = 3;
		    } else {
			nfact = 1;
		    }

		    i__3 = nfact;
		    for (ifact = 1; ifact <= i__3; ++ifact) {
			*(unsigned char *)fact = *(unsigned char *)&facts[
				ifact - 1];
			prefac = lsame_(fact, "F");
			nofact = lsame_(fact, "N");
			equil = lsame_(fact, "E");

			if (zerot) {
			    if (prefac) {
				goto L90;
			    }
			    rcondc = 0.;

			} else if (! lsame_(fact, "N")) 
				{

/*                       Compute the condition number for comparison with */
/*                       the value returned by DPOSVX (FACT = 'N' reuses */
/*                       the condition number from the previous iteration */
/*                       with FACT = 'F'). */

			    dlacpy_(uplo, &n, &n, &asav[1], &lda, &afac[1], &
				    lda);
			    if (equil || iequed > 1) {

/*                          Compute row and column scale factors to */
/*                          equilibrate the matrix A. */

				dpoequ_(&n, &afac[1], &lda, &s[1], &scond, &
					amax, &info);
				if (info == 0 && n > 0) {
				    if (iequed > 1) {
					scond = 0.;
				    }

/*                             Equilibrate the matrix. */

				    dlaqsy_(uplo, &n, &afac[1], &lda, &s[1], &
					    scond, &amax, equed);
				}
			    }

/*                       Save the condition number of the */
/*                       non-equilibrated system for use in DGET04. */

			    if (equil) {
				roldc = rcondc;
			    }

/*                       Compute the 1-norm of A. */

			    anorm = dlansy_("1", uplo, &n, &afac[1], &lda, &
				    rwork[1]);

/*                       Factor the matrix A. */

			    dpotrf_(uplo, &n, &afac[1], &lda, &info);

/*                       Form the inverse of A. */

			    dlacpy_(uplo, &n, &n, &afac[1], &lda, &a[1], &lda);
			    dpotri_(uplo, &n, &a[1], &lda, &info);

/*                       Compute the 1-norm condition number of A. */

			    ainvnm = dlansy_("1", uplo, &n, &a[1], &lda, &
				    rwork[1]);
			    if (anorm <= 0. || ainvnm <= 0.) {
				rcondc = 1.;
			    } else {
				rcondc = 1. / anorm / ainvnm;
			    }
			}

/*                    Restore the matrix A. */

			dlacpy_(uplo, &n, &n, &asav[1], &lda, &a[1], &lda);

/*                    Form an exact solution and set the right hand side. */

			s_copy(srnamc_1.srnamt, "DLARHS", (ftnlen)32, (ftnlen)
				6);
			dlarhs_(path, xtype, uplo, " ", &n, &n, &kl, &ku, 
				nrhs, &a[1], &lda, &xact[1], &lda, &b[1], &
				lda, iseed, &info);
			*(unsigned char *)xtype = 'C';
			dlacpy_("Full", &n, nrhs, &b[1], &lda, &bsav[1], &lda);

			if (nofact) {

/*                       --- Test DPOSV  --- */

/*                       Compute the L*L' or U'*U factorization of the */
/*                       matrix and solve the system. */

			    dlacpy_(uplo, &n, &n, &a[1], &lda, &afac[1], &lda);
			    dlacpy_("Full", &n, nrhs, &b[1], &lda, &x[1], &
				    lda);

			    s_copy(srnamc_1.srnamt, "DPOSV ", (ftnlen)32, (
				    ftnlen)6);
			    dposv_(uplo, &n, nrhs, &afac[1], &lda, &x[1], &
				    lda, &info);

/*                       Check error code from DPOSV . */

			    if (info != izero) {
				alaerh_(path, "DPOSV ", &info, &izero, uplo, &
					n, &n, &c_n1, &c_n1, nrhs, &imat, &
					nfail, &nerrs, nout);
				goto L70;
			    } else if (info != 0) {
				goto L70;
			    }

/*                       Reconstruct matrix from factors and compute */
/*                       residual. */

			    dpot01_(uplo, &n, &a[1], &lda, &afac[1], &lda, &
				    rwork[1], result);

/*                       Compute residual of the computed solution. */

			    dlacpy_("Full", &n, nrhs, &b[1], &lda, &work[1], &
				    lda);
			    dpot02_(uplo, &n, nrhs, &a[1], &lda, &x[1], &lda, 
				    &work[1], &lda, &rwork[1], &result[1]);

/*                       Check solution from generated exact solution. */

			    dget04_(&n, nrhs, &x[1], &lda, &xact[1], &lda, &
				    rcondc, &result[2]);
			    nt = 3;

/*                       Print information about the tests that did not */
/*                       pass the threshold. */

			    i__4 = nt;
			    for (k = 1; k <= i__4; ++k) {
				if (result[k - 1] >= *thresh) {
				    if (nfail == 0 && nerrs == 0) {
					aladhd_(nout, path);
				    }
				    io___48.ciunit = *nout;
				    s_wsfe(&io___48);
				    do_fio(&c__1, "DPOSV ", (ftnlen)6);
				    do_fio(&c__1, uplo, (ftnlen)1);
				    do_fio(&c__1, (char *)&n, (ftnlen)sizeof(
					    integer));
				    do_fio(&c__1, (char *)&imat, (ftnlen)
					    sizeof(integer));
				    do_fio(&c__1, (char *)&k, (ftnlen)sizeof(
					    integer));
				    do_fio(&c__1, (char *)&result[k - 1], (
					    ftnlen)sizeof(doublereal));
				    e_wsfe();
				    ++nfail;
				}
/* L60: */
			    }
			    nrun += nt;
L70:
			    ;
			}

/*                    --- Test DPOSVX --- */

			if (! prefac) {
			    dlaset_(uplo, &n, &n, &c_b50, &c_b50, &afac[1], &
				    lda);
			}
			dlaset_("Full", &n, nrhs, &c_b50, &c_b50, &x[1], &lda);
			if (iequed > 1 && n > 0) {

/*                       Equilibrate the matrix if FACT='F' and */
/*                       EQUED='Y'. */

			    dlaqsy_(uplo, &n, &a[1], &lda, &s[1], &scond, &
				    amax, equed);
			}

/*                    Solve the system and compute the condition number */
/*                    and error bounds using DPOSVX. */

			s_copy(srnamc_1.srnamt, "DPOSVX", (ftnlen)32, (ftnlen)
				6);
			dposvx_(fact, uplo, &n, nrhs, &a[1], &lda, &afac[1], &
				lda, equed, &s[1], &b[1], &lda, &x[1], &lda, &
				rcond, &rwork[1], &rwork[*nrhs + 1], &work[1], 
				 &iwork[1], &info);

/*                    Check the error code from DPOSVX. */

			if (info != izero) {
/* Writing concatenation */
			    i__5[0] = 1, a__1[0] = fact;
			    i__5[1] = 1, a__1[1] = uplo;
			    s_cat(ch__1, a__1, i__5, &c__2, (ftnlen)2);
			    alaerh_(path, "DPOSVX", &info, &izero, ch__1, &n, 
				    &n, &c_n1, &c_n1, nrhs, &imat, &nfail, &
				    nerrs, nout);
			    goto L90;
			}

			if (info == 0) {
			    if (! prefac) {

/*                          Reconstruct matrix from factors and compute */
/*                          residual. */

				dpot01_(uplo, &n, &a[1], &lda, &afac[1], &lda, 
					 &rwork[(*nrhs << 1) + 1], result);
				k1 = 1;
			    } else {
				k1 = 2;
			    }

/*                       Compute residual of the computed solution. */

			    dlacpy_("Full", &n, nrhs, &bsav[1], &lda, &work[1]
, &lda);
			    dpot02_(uplo, &n, nrhs, &asav[1], &lda, &x[1], &
				    lda, &work[1], &lda, &rwork[(*nrhs << 1) 
				    + 1], &result[1]);

/*                       Check solution from generated exact solution. */

			    if (nofact || prefac && lsame_(equed, "N")) {
				dget04_(&n, nrhs, &x[1], &lda, &xact[1], &lda, 
					 &rcondc, &result[2]);
			    } else {
				dget04_(&n, nrhs, &x[1], &lda, &xact[1], &lda, 
					 &roldc, &result[2]);
			    }

/*                       Check the error bounds from iterative */
/*                       refinement. */

			    dpot05_(uplo, &n, nrhs, &asav[1], &lda, &b[1], &
				    lda, &x[1], &lda, &xact[1], &lda, &rwork[
				    1], &rwork[*nrhs + 1], &result[3]);
			} else {
			    k1 = 6;
			}

/*                    Compare RCOND from DPOSVX with the computed value */
/*                    in RCONDC. */

			result[5] = dget06_(&rcond, &rcondc);

/*                    Print information about the tests that did not pass */
/*                    the threshold. */

			for (k = k1; k <= 6; ++k) {
			    if (result[k - 1] >= *thresh) {
				if (nfail == 0 && nerrs == 0) {
				    aladhd_(nout, path);
				}
				if (prefac) {
				    io___51.ciunit = *nout;
				    s_wsfe(&io___51);
				    do_fio(&c__1, "DPOSVX", (ftnlen)6);
				    do_fio(&c__1, fact, (ftnlen)1);
				    do_fio(&c__1, uplo, (ftnlen)1);
				    do_fio(&c__1, (char *)&n, (ftnlen)sizeof(
					    integer));
				    do_fio(&c__1, equed, (ftnlen)1);
				    do_fio(&c__1, (char *)&imat, (ftnlen)
					    sizeof(integer));
				    do_fio(&c__1, (char *)&k, (ftnlen)sizeof(
					    integer));
				    do_fio(&c__1, (char *)&result[k - 1], (
					    ftnlen)sizeof(doublereal));
				    e_wsfe();
				} else {
				    io___52.ciunit = *nout;
				    s_wsfe(&io___52);
				    do_fio(&c__1, "DPOSVX", (ftnlen)6);
				    do_fio(&c__1, fact, (ftnlen)1);
				    do_fio(&c__1, uplo, (ftnlen)1);
				    do_fio(&c__1, (char *)&n, (ftnlen)sizeof(
					    integer));
				    do_fio(&c__1, (char *)&imat, (ftnlen)
					    sizeof(integer));
				    do_fio(&c__1, (char *)&k, (ftnlen)sizeof(
					    integer));
				    do_fio(&c__1, (char *)&result[k - 1], (
					    ftnlen)sizeof(doublereal));
				    e_wsfe();
				}
				++nfail;
			    }
/* L80: */
			}
			nrun = nrun + 7 - k1;
L90:
			;
		    }
/* L100: */
		}
L110:
		;
	    }
L120:
	    ;
	}
/* L130: */
    }

/*     Print a summary of the results. */

    alasvm_(path, nout, &nfail, &nrun, &nerrs);

    return 0;

/*     End of DDRVPO */

} /* ddrvpo_ */
Beispiel #20
0
/* Q:        problem data, 1-dim array of length n*n
 * wneg:     slope of negative part, 1-dim array of length n
 * wpos:     slope of positive part, 1-dim array of length n
 * sigma:    initial penalty parameter
 * maxIter:  max number of iterations
 * d:        initial feasible vector d, 1-dim array of length n
 * iter_arr, obj_arr and time_arr are output variables, CURRENTLY NOT USED!!! */
int CDlogdet_nonsmooth(int n, double* Q, double* wneg, double* wpos, double sigma,
    int maxIter, double* d, double* Vinit,
    int* iter_arr, double* obj_arr, double* time_arr)
{
  int         iter         = 0;
  int         k            = 0;
  double      Vkk          = 0;
  double      dk           = 0;
  double      dchange      = 0;
  clock_t     iterTimer    = 0;
  double      GRAD_TOL     = 3E-2;
  double      MIN_TAU      = 1E-5;
  double      TERM_PROG    = 1E-4;
  double      relgrad      = 1E17;
  double      tmpScalar1   = 0;
  double      VERYSMALLNUM = 1E-9;
  double      obj          = 0;
  double      prevobj      = 1E17;
  double      nrmW         = 0;
  double      TAU_UPDATE   = 0.8;
  int         nsq          = n*n;
  vDSP_Length tmpPosition  = 0;

  double* V = NULL;
  double* vk = NULL;
  double* tmpVec1 = NULL;
  double* tmpVec2 = NULL;
  double* tmpVec3 = NULL;
  double* tmpVec4 = NULL;
  double* tmpVec5 = NULL;
  double* tmpVec6 = NULL;
  double* subg = NULL;

  V       = (double*) malloc(nsq*sizeof(double));
  vk      = (double*) malloc(n*sizeof(double));
  subg    = (double*) malloc(n*sizeof(double));
  tmpVec1 = (double*) malloc(n*sizeof(double));
  tmpVec2 = (double*) malloc(n*sizeof(double));
  tmpVec3 = (double*) malloc(n*sizeof(double));
  tmpVec4 = (double*) malloc(n*sizeof(double));
  tmpVec5 = (double*) malloc(n*sizeof(double));
  tmpVec6 = (double*) malloc(n*sizeof(double));

  char UPLO = 'L';
  int LDA = n;
  int INFO = 0;

  if (PRINTLEVEL)
  {
    PRINT("Entering CDlogdet_nonsmooth: n=%d, sigma=%f, maxIter=%d\n",n,sigma,maxIter);
  }

  iterTimer = clock();

  /*Compute V = inv(Q+d), only stores the lower triangular part*/
  if (NULL==Vinit)
  {
    cblas_dcopy(nsq, Q, 1, V, 1);
    cblas_daxpy(n, 1, d, 1, V, n+1);

    UPLO = 'L';
    LDA = n;
    INFO = 0;
    dpotrf_(&UPLO, &n, V, &LDA, &INFO);
    dpotri_(&UPLO, &n, V, &LDA, &INFO);
  }
  else
  {
    cblas_dcopy(nsq, Vinit, 1, V, 1);
  }

  //printMat(V,n);
  //printMat(Vinit,n);

  nrmW = MAX(cblas_dnrm2(n, wneg, 1), cblas_dnrm2(n, wpos, 1));
  vDSP_vmulD(wneg,1,d,1,tmpVec1,1,n);
  vDSP_vmulD(wpos,1,d,1,tmpVec2,1,n);
  vDSP_vmaxD(tmpVec1, 1, tmpVec2, 1, tmpVec3, 1, n);
  vDSP_sveD(tmpVec3,1,&prevobj,n);
  while(iter<maxIter)
  {
    /*Compute sub-gradient*/
    /*tmpVec1 <= wneg*/
    cblas_dcopy(n, wneg, 1, tmpVec1, 1);


    /*tmpVec1 <= wneg-sigma*diag(V)*/
    cblas_daxpy(n, -sigma, V, n+1, tmpVec1,1);

    /*tmpVec2 <= wpos*/
    cblas_dcopy(n, wpos, 1, tmpVec2, 1);
    /*tmpVec2 <= wpos-sigma*diag(V)*/
    cblas_daxpy(n, -sigma, V, n+1, tmpVec2,1);

    /*tmpVec3 <= max(0,wneg-sigma*diag(V)) */
    tmpScalar1 = 0;
    vDSP_vthresD(tmpVec1,1,&tmpScalar1,tmpVec3,1,n);

    /*tmpVec4 <= -min(0,wpos-sigma*diag(V))*/
    vDSP_vnegD(tmpVec2,1,tmpVec4,1,n);
    tmpScalar1 = 0;
    vDSP_vthresD(tmpVec4,1,&tmpScalar1,tmpVec4,1,n);

    /*tmpVec3 <= max(0,wneg-sigma*diag(V)) + min(0,wpos-sigma*diag(V))*/
    cblas_daxpy(n,-1,tmpVec4,1,tmpVec3,1);

    /*If d<0, use wneg-sigma*diag(V)*/
    /*tmpVec4_i = 1 <==> d_i < -VERYSMALLNUM */
    /*tmpVec4 <= (-d)*/
    vDSP_vnegD(d,1,tmpVec4,1,n);
    tmpScalar1 = 1;
    vDSP_vlimD(tmpVec4,1, &VERYSMALLNUM, &tmpScalar1,tmpVec4,1,n);
    tmpScalar1 = 1;
    vDSP_vsaddD(tmpVec4,1,&tmpScalar1, tmpVec4, 1, n);
    tmpScalar1 = 2;
    vDSP_vsdivD(tmpVec4,1,&tmpScalar1, tmpVec4, 1, n);

    /*tmpVec5[i] = 1 <==> d_i > VERYSMALLNUM*/
    cblas_dcopy(n,d,1,tmpVec5,1);
    tmpScalar1 = 1;
    vDSP_vlimD(tmpVec5, 1, &VERYSMALLNUM, &tmpScalar1, tmpVec5, 1, n);
    tmpScalar1 = 1;
    vDSP_vsaddD(tmpVec5, 1, &tmpScalar1, tmpVec5, 1, n);
    tmpScalar1 = 2;
    vDSP_vsdivD(tmpVec5,1,&tmpScalar1, tmpVec5, 1, n);

    /*tmpVec6[i] = 1 <==> abs(d_i) < VERYSMALLNUM*/
    vDSP_vaddD(tmpVec4, 1, tmpVec5, 1, tmpVec6, 1, n);
    tmpScalar1 = -1;
    vDSP_vsaddD(tmpVec6,1, &tmpScalar1, tmpVec6, 1, n);
    vDSP_vnegD(tmpVec6,1,tmpVec6,1,n);

    /*Multiply, Multiply, Multiply, then add */
    vDSP_vmmaD(tmpVec1, 1, tmpVec4, 1, tmpVec2, 1, tmpVec5, 1, subg,1, n);

    vDSP_vmaD(tmpVec3, 1, tmpVec6, 1, subg, 1, subg, 1, n);


    /*Choose the index with largest abs(subg)*/
    vDSP_maxmgviD(subg,1,&tmpScalar1,&tmpPosition,n);

    /*k is the selected index*/
    k = (int) tmpPosition;
    Vkk = V[k*n+k];
    dk  = d[k];
    if (1-dk*Vkk<=0 || (sigma*Vkk/(1-dk*Vkk)>wpos[k]) )
    {
      dchange = sigma/wpos[k] - 1/Vkk;
    }
    else if(sigma*Vkk/(1-dk*Vkk)<wneg[k])
    {
      dchange = sigma/wneg[k] - 1/Vkk;
    }
    else
    {
      dchange = -dk;
    }
    d[k] += dchange;

    cblas_dcopy(k+1, &V[k], n, vk, 1);
    cblas_dcopy(n-k-1, &V[k*n+k+1], 1, &vk[k+1], 1);

    tmpScalar1 = -(dchange/(1+dchange*Vkk));
    cblas_dsyr(CblasColMajor, CblasLower, n, tmpScalar1, vk, 1, V, n);

    iter ++;

    relgrad = cblas_dnrm2(n,subg,1)/nrmW;

    vDSP_vmulD(wneg,1,d,1,tmpVec1,1,n);
    vDSP_vmulD(wpos,1,d,1,tmpVec2,1,n);
    vDSP_vmaxD(tmpVec1, 1, tmpVec2, 1, tmpVec3, 1, n);
    vDSP_sveD(tmpVec3,1,&obj,n);

    if (relgrad<GRAD_TOL)
    {
      sigma = MAX(MIN_TAU, sigma*TAU_UPDATE);
      if (PRINTLEVEL)
      {
        PRINT("Iter = %5d, sig=%1.2e(#) , obj = %1.5e, relgrad = %1.3f\n",
            iter, sigma, obj, relgrad);
      }
    }
    else if (iter==1 || iter%n==0)
    {
      if (PRINTLEVEL)
      {
        PRINT("Iter = %5d, sig=%1.2e    , obj = %1.5e, relgrad = %1.3f, t=%0.3f\n",
            iter, sigma, obj, relgrad,((double)(clock()-iterTimer))/CLOCKS_PER_SEC);
      }
    }

    if (iter%n==0)
    {
      if (obj<prevobj && ABS(prevobj-obj)<TERM_PROG*ABS(obj))
      {
        if(PRINTLEVEL)
        {
          PRINT("Terminate due to small progress.\n");
        }
        break;
      }
      else
      {
        prevobj = obj;
      }
    }
  }

  free(V);
  free(vk);
  free(tmpVec1);
  free(tmpVec2);
  free(tmpVec3);
  free(tmpVec4);
  free(tmpVec5);
  free(tmpVec6);
  free(subg);
  return 0;
}
void RealTime<double>::iniDensity() {
    bool inOrthoBas;
    bool idempotent;

    auto NTCSxNBASIS = this->nTCS_*this->nBasis_;
    // Set up Eigen Maps
    ComplexMap oTrans1(this->oTrans1Mem_,NTCSxNBASIS,NTCSxNBASIS);
    ComplexMap oTrans2(this->oTrans2Mem_,NTCSxNBASIS,NTCSxNBASIS);
    ComplexMap POA    (this->POAMem_    ,NTCSxNBASIS,NTCSxNBASIS);
    ComplexMap POAsav (this->POAsavMem_ ,NTCSxNBASIS,NTCSxNBASIS);
    ComplexMap FOA    (this->FOAMem_    ,NTCSxNBASIS,NTCSxNBASIS);
    ComplexMap initMOA(this->initMOAMem_,NTCSxNBASIS,NTCSxNBASIS);
    ComplexMap scratch(this->scratchMem_,NTCSxNBASIS,NTCSxNBASIS);

    ComplexMap POB    (this->POBMem_    ,0,0);
    ComplexMap POBsav (this->POBsavMem_ ,0,0);
    ComplexMap FOB    (this->FOBMem_    ,0,0);
    ComplexMap initMOB(this->initMOBMem_,0,0);

    if(!this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS) {
        new (&POB    ) ComplexMap(this->POBMem_    ,NTCSxNBASIS,NTCSxNBASIS);
        new (&POBsav ) ComplexMap(this->POBsavMem_ ,NTCSxNBASIS,NTCSxNBASIS);
        new (&FOB    ) ComplexMap(this->FOBMem_    ,NTCSxNBASIS,NTCSxNBASIS);
        new (&initMOB) ComplexMap(this->initMOBMem_,NTCSxNBASIS,NTCSxNBASIS);
    }

// Form the orthonormal transformation matrices
    if (this->typeOrtho_ == Lowdin) {
        // Lowdin transformation
        // V1 = S^(-1/2)
        // V2 = S^(1/2)

        char JOBZ = 'V';
        char UPLO = 'L';
        int INFO;

        double *A =    this->REAL_LAPACK_SCR;
        double *W =    A + NTCSxNBASIS * NTCSxNBASIS;
        double *WORK = W + NTCSxNBASIS;

        RealVecMap E(W,NTCSxNBASIS);
        RealMap    V(A,NTCSxNBASIS,NTCSxNBASIS);
        RealMap    S(WORK,NTCSxNBASIS,NTCSxNBASIS); // Requires WORK to be NBSq

        E.setZero();
        V.setZero();
        S.setZero();

        std::memcpy(A,this->aointegrals_->overlap_->data(),
                    NTCSxNBASIS*NTCSxNBASIS*sizeof(double));

        dsyev_(&JOBZ,&UPLO,&NTCSxNBASIS,A,&NTCSxNBASIS,W,WORK,&this->lWORK,&INFO);

        V.transposeInPlace(); // BC Col major
        std::memcpy(WORK,A,NTCSxNBASIS*NTCSxNBASIS*sizeof(double));

        for(auto i = 0; i < NTCSxNBASIS; i++) {
            S.col(i) *= std::sqrt(W[i]);
        }
        oTrans2.real() = S * V.adjoint();

        for(auto i = 0; i < NTCSxNBASIS; i++) {
            S.col(i) /= W[i];
        }
        oTrans1.real() = S * V.adjoint();

        if(this->printLevel_>3) {
            prettyPrintComplex(this->fileio_->out,oTrans1,"S^(-1/2)");
            prettyPrintComplex(this->fileio_->out,oTrans2,"S^(1/2)");
        }
    } else if (this->typeOrtho_ == Cholesky) {

        char UPLO = 'L';
        int  INFO;

        double *A = this->REAL_LAPACK_SCR;

        RealMap V(A,NTCSxNBASIS,NTCSxNBASIS);

        V.setZero();

        std::memcpy(A,this->aointegrals_->overlap_->data(),
                    NTCSxNBASIS*NTCSxNBASIS*sizeof(double));

        // compute L = A * L^(-T)
        dpotrf_(&UPLO,&NTCSxNBASIS,A,&NTCSxNBASIS,&INFO);

        V.transposeInPlace(); // BC Col major
        V = V.triangularView<Lower>(); // Upper elements are junk
        oTrans2.real() = V; // oTrans2 = L
        V.transposeInPlace(); // BC Row major

        // Given L, compute S^(-1) = L^(-T) * L^(-1)
        dpotri_(&UPLO,&NTCSxNBASIS,A,&NTCSxNBASIS,&INFO);

        V.transposeInPlace(); // BC Col major
        // oTrans1 = L^(-1) = L^(T) * S^(-1)
        oTrans1.real() = oTrans2.adjoint().real() * V;
        oTrans1 = oTrans1.triangularView<Lower>(); // Upper elements junk

    }
    else if (this->typeOrtho_ == Canonical) {
        CErr("Canonical orthogonalization NYI",this->fileio_->out);
        // Canonical orthogonalization
        // V1 = U*s^(-1/2)
        // V2 = S*V1
    }

// Form the initial density
    if (this->initDensity_ == 0) {
// Use converged ground-state density
        inOrthoBas = false;
        idempotent = true;
    }
    else if (this->initDensity_ == 1) {
// Form the initial density by swaping MOs
        inOrthoBas = false;
        idempotent = true;
        if (this->swapMOA_ != 0) {
            // MOs to swap
            int iA = ((this->swapMOA_)/1000);
            int jA = ((this->swapMOA_)%1000);

            this->fileio_->out << endl << "Alpha MOs swapped: "
                               << iA << " <-> " << jA << endl;

            if(this->printLevel_ > 3) {
                prettyPrint(this->fileio_->out,
                            (*this->ssPropagator_->moA()),"Initial Alpha MO");
            }
            this->ssPropagator_->moA()->col(jA-1).swap(
                this->ssPropagator_->moA()->col(iA-1)
            );
        }
        if (this->swapMOB_ != 0 &&
                !this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS) {
            // MOs to swap
            int iB = (this->swapMOB_/1000);
            int jB = (this->swapMOB_%1000);
            this->fileio_->out << endl << "Beta MOs swapped: "
                               << iB << " <-> " << jB << endl;

            if(this->printLevel_ > 3) {
                prettyPrint(this->fileio_->out,
                            (*this->ssPropagator_->moB()),"Initial Beta MO");
            }
            this->ssPropagator_->moB()->col(jB-1).swap(
                this->ssPropagator_->moB()->col(iB-1)
            );
        }
        this->ssPropagator_->formDensity();
    }
    else if (this->initDensity_ == 2) {
// Read in the AO density from checkpoint file
        CErr("Read in the AO density from checkpint file NYI",this->fileio_->out);
    }
    else if (this->initDensity_ == 3) {
// Read in the orthonormal density from checkpoint file
        CErr("Read in the orthonormal density from checkpoint file NYI",
             this->fileio_->out);
    }

    if (!inOrthoBas) {
// Transform density from AO to orthonormal basis
        POA    = oTrans2.adjoint() * (*this->ssPropagator_->densityA()) * oTrans2;
        POAsav = POA;
        if(!this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS) {
            POB    = oTrans2.adjoint() * (*this->ssPropagator_->densityB()) * oTrans2;
            POBsav = POB;
        }
    } else {
// Transform density from orthonormal to AO basis
        (*this->ssPropagator_->densityA()) = oTrans1.adjoint() * POAsav * oTrans1;
        if(!this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS)
            (*this->ssPropagator_->densityB()) = oTrans1.adjoint() * POB * oTrans1;
    }

// Need ground state MO in orthonormal basis for orbital occupation
    initMOA.setZero();
    initMOA.real() = *this->groundState_->moA();
    initMOA = oTrans2.adjoint() * initMOA;
    if(!this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS) {
        initMOB.setZero();
        initMOB.real() = *this->groundState_->moB();
        initMOB = oTrans2.adjoint() * initMOB;
    }

};