libqt: The Quantum-Trio Miscellaneous Library


Files

file  3d_array.cc
 Routines for 3d arrays.
file  blas_intfc.cc
 The PSI3 BLAS interface routines.
file  cc_excited.cc
 Determine if a wavefunction is a CC-excited wavefunction type.
file  cc_wfn.cc
 Check if wavefunction is coupled-cluster type.
file  ci_wfn.cc
 Check if wavefunction is CI-type.
file  david.cc
 In-core Davidson-Liu diagonalization of symm matrices.
file  dirprd_block.cc
 Take a direct product of two matrices.
file  dot_block.cc
 Take dot product of two block matrices.
file  eri.cc
 Inefficient electron repulsion integral evaluation By Edward Valeev.
file  fill_sym_matrix.cc
 Fill a symmetric matrix from a lower triangle.
file  filter.cc
 Filter out unneeded frozen core/virt integrals.
file  get_frzpi.cc
 Get frozen core/virtuals per irrep.
file  invert.cc
 Invert a small matrix.
file  lapack_intfc.cc
 Interface to LAPACK routines.
file  mat_in.cc
 read in a matrix from an input stream (deprecated)
file  mat_print.cc
 Print a matrix to a file in a formatted style.
file  newmm_rking.cc
 Matrix multiplication routine (deprecated).
file  normalize.cc
 Normalize a set of vectors.
file  pople.cc
 Pople's method for solving linear equations.
file  probabil.cc
 Contains some probability functions.
file  qt.h
 Header file for the Quantum Trio Library.
file  ras_set.cc
 Obtain orbital space and reordering for CI/MCSCF wavefunctions.
file  reorder_qt.cc
 Obtain the QT orbital reordering array between Pitzer and correlated order.
file  rootfind.cc
 Simple root finding methods.
file  schmidt.cc
 Gram-Schmidt orthogonalize a set of vectors.
file  lib/libqt/schmidt_add.cc
 Gram-Schmidt orthogonalize vector and add to set.
file  slaterdset.cc
 Utility functions for importing/exporting sets of Slater determinants from the CI codes.
file  slaterdset.h
 Header file for SlaterDetSets.
file  solve_pep.cc
 Solve a 2x2 pseudo-eigenvalue problem.
file  lib/libqt/sort.cc
 Sort eigenvalues and eigenvectors into ascending order.
file  strncpy.cc
 Override strncpy to ensure strings are terminated.
file  timer.cc
 Obtain user and system timings for blocks of code.

Functions

double *** init_3d_array (int p, int q, int r)
void free_3d_array (double ***A, int p, int q)
void C_DAXPY (int length, double a, double *x, int inc_x, double *y, int inc_y)
void C_DCOPY (int length, double *x, int inc_x, double *y, int inc_y)
void C_DSCAL (int length, double alpha, double *vec, int inc)
void C_DROT (int length, double *x, int inc_x, double *y, int inc_y, double costheta, double sintheta)
void C_DGEMM (char transa, char transb, int m, int n, int k, double alpha, double *A, int nca, double *B, int ncb, double beta, double *C, int ncc)
void C_DGEMV (char transa, int m, int n, double alpha, double *A, int nca, double *X, int inc_x, double beta, double *Y, int inc_y)
void C_DSPMV (char uplo, int n, double alpha, double *A, double *X, int inc_x, double beta, double *Y, int inc_y)
double C_DDOT (int n, double *x, int inc_x, double *y, int inc_y)
int cc_excited (char *wfn)
int cc_wfn (char *wfn)
int ci_wfn (char *wfn)
int david (double **A, int N, int M, double *eps, double **v, double cutoff, int print)
void dirprd_block (double **A, double **B, int rows, int cols)
double dot_block (double **A, double **B, int rows, int cols, double alpha)
double eri (unsigned int l1, unsigned int m1, unsigned int n1, double alpha1, double A[3], unsigned int l2, unsigned int m2, unsigned int n2, double alpha2, double B[3], unsigned int l3, unsigned int m3, unsigned int n3, double alpha3, double C[3], unsigned int l4, unsigned int m4, unsigned int n4, double alpha4, double D[3], int norm_flag)
double norm_const (unsigned int l1, unsigned int m1, unsigned int n1, double alpha1, double A[3])
void fill_sym_matrix (double **A, int size)
void filter (double *input, double *output, int *ioff, int norbs, int nfzc, int nfzv)
int * get_frzcpi ()
int * get_frzvpi ()
double invert_matrix (double **a, double **y, int N, FILE *outfile)
int C_DGEEV (int n, double **a, int lda, double *wr, double *wi, double **vl, int ldvl, double **vr, int ldvr, double *work, int lwork, int info)
int C_DGESV (int n, int nrhs, double *a, int lda, int *ipiv, double *b, int ldb)
int C_DGETRF (int nrow, int ncol, double *a, int lda, int *ipiv)
int C_DGETRI (int n, double *a, int lda, int *ipiv, double *work, int lwork)
int C_DGESVD (char jobu, char jobvt, int m, int n, double *A, int lda, double *s, double *u, int ldu, double *vt, int ldvt, double *work, int lwork)
int C_DSYEV (char jobz, char uplo, int n, double *A, int lda, double *w, double *work, int lwork)
int mat_in (FILE *fp, double **array, int width, int max_length, int *stat)
int mat_print (double **matrix, int rows, int cols, FILE *outfile)
void normalize (double **A, int rows, int cols)
int pople (double **A, double *x, int dimen, int num_vecs, double tolerance, FILE *outfile, int print_lvl)
double combinations (int n, int k)
double factorial (int n)
int ras_set (int nirreps, int nbfso, int freeze_core, int *orbspi, int *docc, int *socc, int *frdocc, int *fruocc, int **ras_opi, int *order, int ras_type)
int ras_set2 (int nirreps, int nmo, int delete_fzdocc, int delete_restrdocc, int *orbspi, int *docc, int *socc, int *frdocc, int *fruocc, int *restrdocc, int *restruocc, int **ras_opi, int *order, int ras_type, int hoffmann)
void reorder_qt (int *docc_in, int *socc_in, int *frozen_docc_in, int *frozen_uocc_in, int *order, int *orbs_per_irrep, int nirreps)
void reorder_qt_uhf (int *docc, int *socc, int *frozen_docc, int *frozen_uocc, int *order_alpha, int *order_beta, int *orbspi, int nirreps)
double bisect (double(*function)(double), double low, double high, double tolerance, int maxiter, int printflag)
double newton (double(*F)(double), double(*dF)(double), double x, double tolerance, int maxiter, int printflag)
double secant (double(*F)(double), double x0, double x1, double tolerance, int maxiter, int printflag)
void schmidt (double **A, int rows, int cols, FILE *outfile)
int schmidt_add (double **A, int rows, int cols, double *v)
void stringset_init (StringSet *sset, int size, int nelec, int nfzc, short int *frozen_occ)
void stringset_delete (StringSet *sset)
void stringset_add (StringSet *sset, int index, unsigned char *Occ)
void stringset_reindex (StringSet *sset, short int *mo_map)
void stringset_write (ULI unit, char *prefix, StringSet *sset)
void stringset_read (ULI unit, char *prefix, StringSet **stringset)
void slaterdetset_init (SlaterDetSet *sdset, int size, StringSet *alphastrings, StringSet *betastrings)
void slaterdetset_delete (SlaterDetSet *sdset)
void slaterdetset_delete_full (SlaterDetSet *sdset)
void slaterdetset_add (SlaterDetSet *sdset, int index, int alphastring, int betastring)
void slaterdetset_write (ULI unit, char *prefix, SlaterDetSet *sdset)
void slaterdetset_read (ULI unit, char *prefix, SlaterDetSet **slaterdetset)
void slaterdetvector_init (SlaterDetVector *sdvector, SlaterDetSet *sdset)
void slaterdetvector_delete (SlaterDetVector *sdvector)
void slaterdetvector_delete_full (SlaterDetVector *sdvector)
void slaterdetvector_add (SlaterDetVector *sdvector, int index, double coeff)
void slaterdetvector_set (SlaterDetVector *sdvector, double *coeffs)
void slaterdetvector_write (ULI unit, char *prefix, SlaterDetVector *vector)
void slaterdetset_write_vect (ULI unit, char *prefix, double *coeffs, int size, int vectnum)
void slaterdetvector_read (ULI unit, char *prefix, SlaterDetVector **sdvector)
void slaterdetset_read_vect (ULI unit, char *prefix, double *coeffs, int size, int vectnum)
void solve_2x2_pep (double **H, double S, double *evals, double **evecs)
void sort_vector (double *A, int n)
void timer_init (void)
void timer_done (void)
struct timer * timer_scan (char *key)
void timer_on (char *key)
void timer_off (char *key)

Detailed Description


Function Documentation

double bisect ( double(*)(double)  function,
double  low,
double  high,
double  tolerance,
int  maxiter,
int  printflag 
)

bisect(): Finds the root of a function between two points to within a given tolerance. Iterations are limited to a given maximum, and a print flag specifies whether this function should print the results of each iteration to stdout. Note that the values of the function at the two endpoints of the interval must have _different_ signs for the bisection method to work! This routine checks for this initially.

Parameters:
function = pointer to function we want to examine (must return double)
low = lower bound of interval to search for root
high = upper bound of interval
tolerance = how small is the maximum allowable error
maxiter = maximum number of iterations
printflag = whether or not to print results for each iteration (1 or 0)
Returns: the value of the root

Definition at line 56 of file rootfind.cc.

00058 {
00059    int iter = 1 ;
00060    double tmpval ;
00061    double center ;      /* half way between low and high, i.e. current guess */
00062    double fl, fc, fh ;  /* values of function at the three points */
00063    double errorval ; 
00064 
00065    /* check the input parameters */
00066    if (low > high) {  /* make sure low is the smaller of the 2 limits */
00067       tmpval = low ;
00068       low = high ; 
00069       high = tmpval ;
00070       }
00071  
00072    fl = function(low) ;
00073    fh = function(high) ;
00074    if (fl * fh > 0.0) {
00075       printf("(bisect): Product of function values is greater than 0\n") ;
00076       return(0.0) ;
00077       }
00078 
00079    if (printflag) {
00080       printf("Bisection method root finder\n") ;
00081       printf("%4s %12s  %12s\n", "iter", "x", "max error") ;
00082       }
00083 
00084    /* now iterate until we hit maxiter or until we get within the tolerance */
00085    while (iter < maxiter) {  
00086       center = (low + high) / 2.0 ;
00087       fc = function(center) ;
00088       errorval = (high - low) / 2.0 ;
00089       if (printflag) 
00090          printf("%4d %12.8f  %12.8f\n", iter, center, errorval) ;
00091       if (errorval < tolerance) return(center) ;
00092       if (fl * fc > 0.0) {
00093          low = center ;
00094          fl = fc ;
00095          }
00096       else {
00097          high = center ;
00098          fh = fc ;
00099          }
00100       iter++ ;
00101       }
00102 
00103    printf("(bisect): Failed to converge within %d iterations\n", iter) ;
00104    return(center) ;
00105 } 

void C_DAXPY ( int  length,
double  a,
double *  x,
int  inc_x,
double *  y,
int  inc_y 
)

C_DAXPY(): This function performs y = a * x + y.

Steps every inc_x in x and every inc_y in y (normally both 1).

Parameters:
length = length of arrays
a = scalar a to multiply vector x
x = vector x
inc_x = how many places to skip to get to next element in x
y = vector y
inc_y = how many places to skip to get to next element in y
Returns:none

Definition at line 93 of file blas_intfc.cc.

00095 {
00096   F_DAXPY(&length, &a, x, &inc_x, y, &inc_y);
00097 }

void C_DCOPY ( int  length,
double *  x,
int  inc_x,
double *  y,
int  inc_y 
)

C_DCOPY(): This function copies x into y.

Steps every inc_x in x and every inc_y in y (normally both 1).

Parameters:
length = length of array
x = vector x
inc_x = how many places to skip to get to next element in x
y = vector y
inc_y = how many places to skip to get to next element in y
Returns: none

Definition at line 115 of file blas_intfc.cc.

00117 {
00118   F_DCOPY(&length, x, &inc_x, y, &inc_y);
00119 }

double C_DDOT ( int  n,
double *  x,
int  inc_x,
double *  y,
int  inc_y 
)

C_DDOT(): This function returns the dot product of two vectors, x and y.

Parameters:
length = Number of elements in x and y.
x = A pointer to the beginning of the data in x. Must be of at least length (1+(N-1)*abs(inc_x).
inc_x = how many places to skip to get to next element in x
y = A pointer to the beginning of the data in y.
inc_y = how many places to skip to get to next element in y
Returns: the dot product

Interface written by ST Brown. July 2000

Definition at line 365 of file blas_intfc.cc.

00366 {
00367    if(n == 0) return 0.0;
00368 
00369    return F_DDOT(&n,x,&inc_x,y,&inc_y);
00370 }

int C_DGEEV ( int  n,
double **  a,
int  lda,
double *  wr,
double *  wi,
double **  vl,
int  ldvl,
double **  vr,
int  ldvr,
double *  work,
int  lwork,
int  info 
)

C_DGEEV()

This function computes the eigenvalues and the left and right right eigenvectors of a real, nonsymmetric matrix A. For symmetric matrices, refer to C_DSYEV().

Parameters:
n = The order of the matrix A. n >= 0.
a = The n-by-n matrix A. As with all other lapack routines, must be allocated by contiguous memory (i.e., block_matrix()).
lda = The leading dimension of matrix A. lda >= max(1,n).
wr = array of length n containing the real parts of computed eigenvalues.
wi = array of length n containing the imaginary parts of computed eigenvalues.
vl = matrix of dimensions ldvl*n. The columns store the left eigenvectors u(j). If the j-th eigenvalues is real, then u(j) = vl(:,j), the j-th column of vl. If the j-th and (j+1)-st eigenvalues form a complex conjugate pair, then u(j) = vl(:,j) + i*vl(:,j+1) and u(j+1) = vl(:,j) - i*vl(:,j+1). Note: this is the Fortran documentation, may need to change cols <-> rows.
ldvl = The leading dimension of matrix vl.
vr = matrix of dimensions ldvr*n. The columns store the right eigenvectors v(j). If the j-th eigenvalues is real, then v(j) = vr(:,j), the j-th column of vr. If the j-th and (j+1)-st eigenvalues form a complex conjugate pair, then v(j) = vr(:,j) + i*vr(:,j+1) and v(j+1) = vr(:,j) - i*vr(:,j+1). Note: this is the Fortran documentation, may need to change cols <-> rows.
ldvr = The leading dimension of matrix vr.
work = Array for scratch computations, of dimension lwork. On successful exit, work[0] returns the optimal value of lwork.
lwork = The dimension of the array work. lwork >= max(1,3*n), and if eigenvectors are required (default for this wrapper at present) then actually lwork >= 4*n. For good performance, lwork must 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 ans the first entry of the work array, and no error message related to lword is issued by xerbla.
info = On output (returned by C_DGEEV), a status flag. info = 0 for successful exit, if info = -i, the ith argument had an illegal value. If info = i, the QR algorithm failed to compute all the eigenvalues, and no eigenvectors have been computed. Elements i+1:n of wr and wi contain eigenvalues which have converged.

Definition at line 119 of file lapack_intfc.cc.

00122 {
00123   char jobvl, jobvr;
00124   jobvl = 'V';
00125   jobvr = 'V';
00126   F_DGEEV(&jobvl, &jobvr, &n, &(a[0][0]), &lda, &(wr[0]), &(wi[0]),
00127        &(vl[0][0]), &ldvl, &(vr[0][0]), &ldvr, &(work[0]), &lwork, &info);
00128 
00129   return info;
00130 }

void C_DGEMM ( char  transa,
char  transb,
int  m,
int  n,
int  k,
double  alpha,
double *  A,
int  nca,
double *  B,
int  ncb,
double  beta,
double *  C,
int  ncc 
)

C_DGEMM(): This function calculates C(m,n)=alpha*(opT)A(m,k)*(opT)B(k,n)+ beta*C(m,n)

These arguments mimic their Fortran conterparts; parameters have been reversed (nca, ncb, ncc, A, B, C), to make it correct for C.

Parameters:
transa = On entry, specifies the form of (op)A used in the matrix multiplication: If transa = 'N' or 'n', (op)A = A. If transa = 'T' or 't', (op)A = transp(A). If transa = 'R' or 'r', (op)A = conjugate(A). If transa = 'C' or 'c', (op)A = conjug_transp(A). On exit, transa is unchanged.
transb = On entry, specifies the form of (op)B used in the matrix multiplication: If transb = 'N' or 'n', (op)B = B. If transb = 'T' or 't', (op)B = transp(B). If transb = 'R' or 'r', (op)B = conjugate(B)
m = On entry, the number of rows of the matrix (op)A and of the matrix C; m >= 0. On exit, m is unchanged.
n = On entry, the number of columns of the matrix (op)B and of the matrix C; n >= 0. On exit, n is unchanged.
k = On entry, the number of columns of the matrix (op)A and the number of rows of the matrix (op)B; k >= 0. On exit, k is unchanged.
alpha = On entry, specifies the scalar alpha. On exit, alpha is unchanged.
A = On entry, a two-dimensional array A with dimensions ka by nca. For (op)A = A or conjugate(A), nca >= k and the leading m by k portion of the array A contains the matrix A. For (op)A = transp(A) or conjug_transp(A), nca >= m and the leading k by m part of the array A contains the matrix A. On exit, a is unchanged.
nca = On entry, the second dimension of array A. For (op)A = A or conjugate(A), nca >= MAX(1,k). For (op)A=transp(A) or conjug_transp(A), nca >= MAX(1,m). On exit, nca is unchanged.
B = On entry, a two-dimensional array B with dimensions kb by ncb. For (op)B = B or conjugate(B), kb >= k and the leading k by n portion of the array contains the matrix B. For (op)B = transp(B) or conjug_transp(B), ncb >= k and the leading n by k part of the array contains the matrix B. On exit, B is unchanged.
ncb = On entry, the second dimension of array B. For (op)B = B or <conjugate(B), ncb >= MAX(1,n). For (op)B = transp(B) or conjug_transp(B), ncb >= MAX(1,k). On exit, ncb is unchanged.
beta = On entry, specifies the scalar beta. On exit, beta is unchanged.
C = On entry, a two-dimensional array with the dimension at least m by ncc. On exit, the leading m by n part of array C is overwritten by the matrix alpha*(op)A*(op)B + beta*C.
ncc = On entry, the second dimension of array C; ncc >=MAX(1,n). On exit, ncc is unchanged.
Returns: none

Definition at line 235 of file blas_intfc.cc.

Referenced by ael(), david(), dpd_contract244(), and dpd_contract424().

00238 {
00239 
00240   /* the only strange thing we need to do is reverse everything
00241      since the stride runs differently in C vs. Fortran
00242    */
00243   
00244   /* also, do nothing if a dimension is 0 */
00245   if (m == 0 || n == 0 || k == 0) return;
00246 
00247   F_DGEMM(&transb,&transa,&n,&m,&k,&alpha,B,&ncb,A,&nca,&beta,C,&ncc);
00248 
00249 }

void C_DGEMV ( char  transa,
int  m,
int  n,
double  alpha,
double *  A,
int  nca,
double *  X,
int  inc_x,
double  beta,
double *  Y,
int  inc_y 
)

C_DGEMV(): This function calculates the matrix-vector product.

Y = alpha * A * X + beta * Y

where X and Y are vectors, A is a matrix, and alpha and beta are constants.

Parameters:
transa = Indicates whether the matrix A should be transposed ('t') or left alone ('n').
m = The row dimension of A (regardless of transa).
n = The column dimension of A (regardless of transa).
alpha = The scalar alpha.
A = A pointer to the beginning of the data in A.
nca = The number of columns *actually* in A. This is useful if one only wishes to multiply the first n columns of A times X even though A contains nca columns.
X = A pointer to the beginning of the data in X.
inc_x = The desired stride for X. Useful for skipping sections of data to treat only one column of a complete matrix. Usually 1, though.
beta = The scalar beta.
Y = A pointer to the beginning of the data in Y.
inc_y = The desired stride for Y.
Returns: none

Interface written by TD Crawford and EF Valeev. June 1999

Definition at line 286 of file blas_intfc.cc.

00289 {
00290   if (m == 0 || n == 0) return;
00291 
00292   if(transa == 'n') transa = 't';
00293   else transa = 'n';
00294 
00295   F_DGEMV(&transa,&n,&m,&alpha,A,&nca,X,&inc_x,&beta,Y,&inc_y);
00296 
00297 }

int C_DGESV ( int  n,
int  nrhs,
double *  a,
int  lda,
int *  ipiv,
double *  b,
int  ldb 
)

C_DGESV()

This function solves a system of linear equations A * X = B, where A is an n x n matrix and X and B are n x nrhs matrices.

Parameters:
n = The number of linear equations, i.e., the order of the matrix A. n >= 0.
nrhs = The number of right hand sides, i.e., the number of columns of the matrix B. nrhs >= 0.
A = On entry, the n-by-n coefficient matrix A. On exit, the factors L and U from the factorization A = P*L*U; the unit diagonal elements of L are not stored.
lda = The leading dimension of the array A. lda >= max(1,n).

Parameters:
int ipiv = An integer array of length n. The pivot indices that define the permutation matrix P; row i of the matrix was interchanged with row ipiv(i).
B = On entry, the n-by-nrhs matrix of right hand side matrix B. On exit, if info = 0, the n-by-nrhs solution matrix X.
ldb = The leading dimension of the array B. ldb >= max(1,n).
Returns: int info. info = 0: successful exit. info < 0: if info = -i, the i-th argument had an illegal value. info > 0: if info = i, U(i,i) is exactly zero. The factorization has been completed, but the factor U is exactly singular, so the solution could not be computed.

Definition at line 169 of file lapack_intfc.cc.

00170 {
00171   int info;
00172 
00173   F_DGESV(&n, &nrhs, &(a[0]), &lda, &(ipiv[0]), &(b[0]), &ldb, &info);
00174 
00175   return info;
00176 }

int C_DGESVD ( char  jobu,
char  jobvt,
int  m,
int  n,
double *  A,
int  lda,
double *  s,
double *  u,
int  ldu,
double *  vt,
int  ldvt,
double *  work,
int  lwork 
)

C_DGESVD() This function computes the singular value decomposition (SVD) of a real mxn matrix A, ** optionally computing the left and/or right singular vectors. The SVD is written

A = U * S * transpose(V)

where S is an mxn 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;

These arguments mimic their Fortran counterparts. See the LAPACK manual for additional information.

Parameters:
jobu = 'A' = all m columns of U are returned 'S' = the first min(m,n) columns of U are returned 'O' = the first min(m,n) columns of U are returned in the input matrix A 'N' = no columns of U are returned
jobvt = 'A' = all n rows of VT are returned 'S' = the first min(m,n) rows of VT are returned 'O' = the first min(m,n) rows of VT are returned in the input matrix A 'N' = no rows of VT are returned
Obviously jobu and jobvt cannot both be 'O'.

Parameters:
m = The row dimension of the matrix A.
n = The column dimension of the matrix A.
A = On entry, the mxn matrix A with dimensions m by lda. On exit, if jobu='O' the first min(m,n) columns of A are overwritten with the left singular vectors; if jobvt='O' the first min(m,n) rows of A are overwritten with the right singular vectors; otherwise, the contents of A are destroyed.
lda = The number of columns allocated for A.
s = The singular values of A.
u = The right singular vectors of A, returned as column of the matrix u if jobu='A'. If jobu='N' or 'O', u is not referenced.
ldu = The number of columns allocated for u.
vt = The left singular vectors of A, returned as rows of the matrix VT is jobvt='A'. If jobvt='N' or 'O', vt is not referenced.
ldvt = The number of columns allocated for vt.
work = Workspace array of length lwork.
lwork = The length of the workspace array work, which should be at least as large as max(3*min(m,n)+max(m,n),5*min(m,n)). For good performance, lwork should generally be larger. If lwork=-1, a workspace query is assumed, and the value of work[0] upon return is the optimal size of the work array.
Return value: int info. If info=0, successful exit. If info = -i, the i-th argument had an illegal value. If info > 0, Related to failure in the convergence of the upper bidiagonal matrix B. See the LAPACK manual for additiona information.

Interface written by TDC, July 2001, updated April 2004

Definition at line 339 of file lapack_intfc.cc.

00341 {
00342   int info;
00343 
00344   F_DGESVD(&jobvt, &jobu, &n, &m, A, &lda, s, vt, &ldvt, u, &ldu, work, 
00345     &lwork, &info);
00346 
00347   return info;
00348 }

int C_DGETRF ( int  nrow,
int  ncol,
double *  a,
int  lda,
int *  ipiv 
)

C_DGETRF(): Compute 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 nrow > ncol), and U is upper triangular (upper trapezoidal if nrow < ncol).

Parameters:
nrow = number of rows
ncol = number of colums
a = matrix to factorize
lda = leading dimension of a, lda >= max(1,ncol)
ipiv = output integer array of the pivot indices; for 1 <= i <= min(nrow, ncol), col i of the matrix was interchanged with col ipiv(i).
Returns: int info. info = 0: successful exit. info < 0: if info=-i, the ith-argument had an illegal vale. info>0: if info=i, U(i,i) 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.

Definition at line 205 of file lapack_intfc.cc.

00206 {
00207   int info;
00208 
00209   F_DGETRF(&ncol, &nrow, &(a[0]), &lda, &(ipiv[0]), &info);
00210 
00211   return info;
00212 }

int C_DGETRI ( int  n,
double *  a,
int  lda,
int *  ipiv,
double *  work,
int  lwork 
)

C_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).

Parameters:
n = order of the matrix a. n >= 0.
a = array of dimension (n,lda). 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 hte original matrix A.
lda = the leading dimension of the array a. lda >= max(1,n).
ipiv = The pivot indices from DGETRF. For 1<=i<=n, row i of the matrix was interchanged with row ipiv(i)
work = workspace of dimension max(1,lwork). On exit, if info=0, then work(0) returns the optimal lwork.
lwork = 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.
Returns: int info. info=0: successful exit. info<0: if info=-i, the i-th argument had an illegal value. info>0: if info=i, U(i,i) is exactly zero; the matrix is singular and its inverse could not be computed.

Definition at line 246 of file lapack_intfc.cc.

00247 {
00248   int info;
00249 
00250   F_DGETRI(&n, &(a[0]), &lda, &(ipiv[0]), &(work[0]), &lwork, &info);
00251 
00252   return info;
00253 }

void C_DROT ( int  length,
double *  x,
int  inc_x,
double *  y,
int  inc_y,
double  costheta,
double  sintheta 
)

C_DROT(): Calculates a plane Givens rotation for vectors x, y and angle theta. x = x*cos + y*sin, y = -x*sin + y*cos.

Parameters:
x = vector x
y = vector Y
length = length of x,y
inc_x = how many places to skip to get to the next element of x
inc_y = how many places to skip to get to the next element of y
Returns: none

Definition at line 154 of file blas_intfc.cc.

00156 {
00157 
00158   F_DROT(&length,x,&inc_x,y,&inc_y,&costheta,&sintheta);
00159 }

void C_DSCAL ( int  length,
double  alpha,
double *  vec,
int  inc 
)

C_DSCAL(): This function scales a vector by a real scalar.

Parameters:
length = length of array
alpha = scale factor
vec = vector to scale
inc = how many places to skip to get to next element in vec
Returns: none

Definition at line 134 of file blas_intfc.cc.

Referenced by psi::detcas::calc_gradient(), and dpd_buf4_scm().

00135 {
00136   F_DSCAL(&length, &alpha, vec, &inc);
00137 }

void C_DSPMV ( char  uplo,
int  n,
double  alpha,
double *  A,
double *  X,
int  inc_x,
double  beta,
double *  Y,
int  inc_y 
)

C_DSPMV(): This function calculates the matrix-vector product

Y = alpha * A * X + beta * Y

where X and Y are vectors, A is a matrix, and alpha and beta are constants.

Parameters:
uplo = Indicates whether the matrix A is packed in upper ('U' or 'u') or lower ('L' or 'l') triangular form. We reverse what is passed before sending it on to Fortran because of the different Fortran/C conventions
n = The order of the matrix A (number of rows/columns)
alpha = The scalar alpha.
A = A pointer to the beginning of the data in A.
X = A pointer to the beginning of the data in X.
inc_x = The desired stride for X. Useful for skipping sections of data to treat only one column of a complete matrix. Usually 1, though.
beta = The scalar beta.
Y = A pointer to the beginning of the data in Y.
inc_y = The desired stride for Y.
Returns: none

Interface written by CD Sherrill July 2003

Definition at line 331 of file blas_intfc.cc.

00334 {
00335   if (n == 0) return;
00336 
00337   if (uplo != 'U' && uplo != 'u' && uplo != 'L' && uplo != 'l')
00338     fprintf(stderr, "C_DSPMV: called with unrecognized option for uplo!\n");
00339 
00340   if (uplo == 'U' || uplo == 'u') uplo = 'L';
00341   else uplo = 'U';
00342 
00343   F_DSPMV(&uplo,&n,&alpha,A,X,&inc_x,&beta,Y,&inc_y);
00344 
00345 }

int C_DSYEV ( char  jobz,
char  uplo,
int  n,
double *  A,
int  lda,
double *  w,
double *  work,
int  lwork 
)

C_DSYEV(): Computes all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A.

These arguments mimic their Fortran counterparts.

Parameters:
jobz = 'N' or 'n' = compute eigenvalues only; 'V' or 'v' = compute both eigenvalues and eigenvectors.
uplo = 'U' or 'u' = A contains the upper triangular part of the matrix; 'L' or 'l' = A contains the lower triangular part of the matrix.
n = The order of the matrix A.
A = On entry, the two-dimensional array with dimensions n by lda. On exit, if jobz = 'V', the columns of the matrix contain the eigenvectors of A, but if jobz = 'N', the contents of the matrix are destroyed.
lda = The second dimension of A (i.e., the number of columns allocated for A).
w = The computed eigenvalues in ascending order.
work = An array of length lwork. On exit, if the return value is 0, work[0] contains the optimal value of lwork.
lwork = The length of the array work. A useful value of lwork seems to be 3*N.
Returns: 0 = successful exit <0 = the value of the i-th argument to the function was illegal >0 = the algorithm failed to converge.

Interface written by TDC, 10/2002

Definition at line 392 of file lapack_intfc.cc.

00394 {
00395   int info;
00396 
00397   F_DSYEV(&jobz, &uplo, &n, A, &lda, w, work, &lwork, &info);
00398 
00399   return info;
00400 }

int cc_excited ( char *  wfn  ) 

cc_excited(): This function takes a WFN string and returns 1 if the WFN is an excited-state method and 0 if the WFN is a ground-state method.

Parameters:
*wfn = wavefunction string
Returns: 1 if an excited state method, else 0

Definition at line 23 of file cc_excited.cc.

Referenced by main().

00024 {
00025 
00026   if ( !strcmp(wfn, "CCSD")   || !strcmp(wfn, "CCSD_T") || !strcmp(wfn, "BCCD") 
00027     || !strcmp(wfn, "BCCD_T") || !strcmp(wfn, "CC2")    || !strcmp(wfn, "CC3") 
00028     || !strcmp(wfn, "CCSD_MVD") ) {
00029     return 0;
00030   }
00031   else if ( !strcmp(wfn, "EOM_CCSD") || !strcmp(wfn, "LEOM_CCSD") ||
00032             !strcmp(wfn, "EOM_CC2")  || !strcmp(wfn, "EOM_CC3") ) {
00033     return 1;
00034   }
00035   else {
00036     printf("Invalid value of input keyword WFN: %s\n", wfn);
00037     exit(PSI_RETURN_FAILURE);
00038   }
00039 }

int cc_wfn ( char *  wfn  ) 

cc_wfn(): Checks if the given wavefunction string is a coupled-cluster type and returns 1 if yes and 0 if no.

Note: "coupled-cluster type" means it is handled by PSI like the coupled-cluster codes, not necessarily that it is literally a coupled-cluster wavefunction

Parameters:
*wfn = wavefunction string
Returns: 1 if the WFN is a CC method, 0 otherwise

Definition at line 28 of file cc_wfn.cc.

00029 {
00030 
00031   if ( !strcmp(wfn, "CCSD")     || !strcmp(wfn, "CCSD_T") || 
00032        !strcmp(wfn, "BCCD")     || !strcmp(wfn, "BCCD_T") || 
00033        !strcmp(wfn, "CC2")      || !strcmp(wfn, "CC3")    ||
00034        !strcmp(wfn, "EOM_CCSD") || !strcmp(wfn, "LEOM_CCSD") ||
00035        !strcmp(wfn, "EOM_CC2")  || !strcmp(wfn, "EOM_CC3") ||
00036        !strcmp(wfn, "CIS") ) {
00037     return 1;
00038   }
00039   else {
00040     return 0;
00041   }
00042 }

int ci_wfn ( char *  wfn  ) 

ci_wfn(): Examine the wavefunction type and return 1 if a CI/MCSCF-type, otherwise 0

Parameters:
*wfn = wavefunction string
Returns: 1 if a CI/MCSCF-type wavefunction, otherwise 0

Definition at line 24 of file ci_wfn.cc.

00025 {
00026 
00027   if (strcmp(wfn, "CI")==0     || strcmp(wfn, "DETCAS")==0 || 
00028       strcmp(wfn, "CASSCF")==0 || strcmp(wfn, "RASSCF")==0 ||
00029       strcmp(wfn, "DETCI")==0 || strcmp(wfn, "MCSCF")==0 ||
00030       strcmp(wfn, "OOCCD")==0 || strcmp(wfn,"ZAPTN")==0) 
00031   {
00032     return(1);
00033   }
00034   else  {
00035     return 0;
00036   }
00037 }

double combinations ( int  n,
int  k 
)

combinations() : Calculates the number of ways to choose k objects from n objects, or "n choose k"

Parameters:

Parameters:
n = number of objects in total
k = number of objects taken at a time
Returns: number of combinations of n objects taken k at a time ("n choose k") (returned as a double).

Definition at line 23 of file probabil.cc.

References factorial().

00024 {
00025    double factorial(int) ;
00026    double comb ;
00027 
00028    if (n == k) return (1.0) ;
00029    else if (k > n) return(0.0) ;
00030    else if (k == 0) return(1.0) ; 
00031    comb = factorial(n) / (factorial(k) * factorial(n-k)) ;
00032  
00033    return(comb) ;
00034 }

int david ( double **  A,
int  N,
int  M,
double *  eps,
double **  v,
double  cutoff,
int  print 
)

david(): Computes the lowest few eigenvalues and eigenvectors of a symmetric matrix, A, using the Davidson-Liu algorithm.

The matrix must be small enough to fit entirely in core. This algorithm is useful if one is interested in only a few roots of the matrix rather than the whole spectrum.

NB: This implementation will keep up to eight guess vectors for each root desired before collapsing to one vector per root. In addition, if smart_guess=1 (the default), guess vectors are constructed by diagonalization of a sub-matrix of A; otherwise, unit vectors are used.

TDC, July-August 2002

Parameters:
A = matrix to diagonalize
N = dimension of A
M = number of roots desired
eps = eigenvalues
v = eigenvectors
cutoff = tolerance for convergence of eigenvalues
print = Boolean for printing additional information
Returns: number of converged roots

Definition at line 47 of file david.cc.

References block_matrix(), C_DGEMM(), init_array(), init_int_array(), schmidt_add(), sq_rsp(), and zero_int_array().

00049 {
00050   int i, j, k, L, I;
00051   double minimum;
00052   int min_pos, numf, iter, *conv, converged, maxdim, skip_check;
00053   int *small2big, init_dim;
00054   int smart_guess = 1;
00055   double *Adiag, **b, **bnew, **sigma, **G;
00056   double *lambda, **alpha, **f, *lambda_old;
00057   double norm, denom, diff;
00058 
00059   maxdim = 8 * M;
00060 
00061   b = block_matrix(maxdim, N);  /* current set of guess vectors,
00062                                    stored by row */
00063   bnew = block_matrix(M, N); /* guess vectors formed from old vectors,
00064                                 stored by row*/
00065   sigma = block_matrix(N, maxdim); /* sigma vectors, stored by column */
00066   G = block_matrix(maxdim, maxdim); /* Davidson mini-Hamitonian */
00067   f = block_matrix(maxdim, N); /* residual eigenvectors, stored by row */
00068   alpha = block_matrix(maxdim, maxdim); /* eigenvectors of G */
00069   lambda = init_array(maxdim); /* eigenvalues of G */
00070   lambda_old = init_array(maxdim); /* approximate roots from previous
00071                                       iteration */
00072 
00073   if(smart_guess) { /* Use eigenvectors of a sub-matrix as initial guesses */
00074 
00075     if(N > 7*M) init_dim = 7*M;
00076     else init_dim = M;
00077     Adiag = init_array(N);
00078     small2big = init_int_array(7*M);
00079     for(i=0; i < N; i++) { Adiag[i] = A[i][i]; }
00080     for(i=0; i < init_dim; i++) {
00081       minimum = Adiag[0];
00082       min_pos = 0;
00083       for(j=1; j < N; j++)
00084         if(Adiag[j] < minimum) {        
00085           minimum = Adiag[j]; 
00086           min_pos = j; 
00087           small2big[i] = j; 
00088         }
00089 
00090       Adiag[min_pos] = BIGNUM;
00091       lambda_old[i] = minimum;
00092     }
00093     for(i=0; i < init_dim; i++) {
00094       for(j=0; j < init_dim; j++)
00095         G[i][j] = A[small2big[i]][small2big[j]];
00096     }
00097 
00098     sq_rsp(init_dim, init_dim, G, lambda, 1, alpha, 1e-12);
00099 
00100     for(i=0; i < init_dim; i++) {
00101       for(j=0; j < init_dim; j++)
00102         b[i][small2big[j]] = alpha[j][i];
00103     }
00104 
00105     free(Adiag);
00106     free(small2big);
00107   }
00108   else { /* Use unit vectors as initial guesses */
00109     Adiag = init_array(N);
00110     for(i=0; i < N; i++) { Adiag[i] = A[i][i]; }
00111     for(i=0; i < M; i++) {
00112       minimum = Adiag[0];
00113       min_pos = 0;
00114       for(j=1; j < N; j++)
00115         if(Adiag[j] < minimum) { minimum = Adiag[j]; min_pos = j; }
00116 
00117       b[i][min_pos] = 1.0; 
00118       Adiag[min_pos] = BIGNUM; 
00119       lambda_old[i] = minimum;
00120     }
00121     free(Adiag);
00122   }
00123 
00124   L = init_dim;
00125   iter =0;
00126   converged = 0;
00127   conv = init_int_array(M); /* boolean array for convergence of each
00128                                root */
00129   while(converged < M && iter < MAXIT) {
00130 
00131     skip_check = 0;
00132     if(print) printf("\niter = %d\n", iter); 
00133 
00134     /* form mini-matrix */
00135     C_DGEMM('n','t', N, L, N, 1.0, &(A[0][0]), N, &(b[0][0]), N,
00136             0.0, &(sigma[0][0]), maxdim);
00137     C_DGEMM('n','n', L, L, N, 1.0, &(b[0][0]), N,
00138             &(sigma[0][0]), maxdim, 0.0, &(G[0][0]), maxdim);
00139 
00140     /* diagonalize mini-matrix */
00141     sq_rsp(L, L, G, lambda, 1, alpha, 1e-12);
00142 
00143     /* form preconditioned residue vectors */
00144     for(k=0; k < M; k++)
00145       for(I=0; I < N; I++) {
00146         f[k][I] = 0.0;
00147         for(i=0; i < L; i++) {
00148           f[k][I] += alpha[i][k] * (sigma[I][i] - lambda[k] * b[i][I]);
00149         }
00150         denom = lambda[k] - A[I][I];
00151         if(fabs(denom) > 1e-6) f[k][I] /= denom;
00152         else f[k][I] = 0.0;
00153       }
00154 
00155     /* normalize each residual */
00156     for(k=0; k < M; k++) {
00157       norm = 0.0;
00158       for(I=0; I < N; I++) {
00159         norm += f[k][I] * f[k][I];
00160       }
00161       norm = sqrt(norm);
00162       for(I=0; I < N; I++) {
00163         if(norm > 1e-6) f[k][I] /= norm;
00164         else f[k][I] = 0.0;
00165       }
00166     }
00167 
00168     /* schmidt orthogonalize the f[k] against the set of b[i] and add
00169        new vectors */
00170     for(k=0,numf=0; k < M; k++)
00171       if(schmidt_add(b, L, N, f[k])) { L++; numf++; }
00172 
00173     /* If L is close to maxdim, collapse to one guess per root */
00174     if(maxdim - L < M) {
00175       if(print) {
00176         printf("Subspace too large: maxdim = %d, L = %d\n", maxdim, L);
00177         printf("Collapsing eigenvectors.\n");
00178       }
00179       for(i=0; i < M; i++) {
00180         memset((void *) bnew[i], 0, N*sizeof(double));
00181         for(j=0; j < L; j++) {
00182           for(k=0; k < N; k++) {
00183             bnew[i][k] += alpha[j][i] * b[j][k];
00184           }
00185         }
00186       }
00187 
00188       /* copy new vectors into place */
00189       for(i=0; i < M; i++) 
00190         for(k=0; k < N; k++)
00191           b[i][k] = bnew[i][k];
00192 
00193       skip_check = 1;
00194 
00195       L = M;
00196     }
00197 
00198     /* check convergence on all roots */
00199     if(!skip_check) {
00200       converged = 0;
00201       zero_int_array(conv, M);
00202       if(print) {
00203         printf("Root      Eigenvalue       Delta  Converged?\n");
00204         printf("---- -------------------- ------- ----------\n");
00205       }
00206       for(k=0; k < M; k++) {
00207         diff = fabs(lambda[k] - lambda_old[k]);
00208         if(diff < cutoff) {
00209           conv[k] = 1;
00210           converged++;
00211         }
00212         lambda_old[k] = lambda[k];
00213         if(print) {
00214           printf("%3d  %20.14f %4.3e    %1s\n", k, lambda[k], diff,
00215                  conv[k] == 1 ? "Y" : "N");
00216         }
00217       }
00218     }
00219 
00220     iter++;
00221   }
00222 
00223   /* generate final eigenvalues and eigenvectors */
00224   if(converged == M) {
00225     for(i=0; i < M; i++) {
00226       eps[i] = lambda[i];
00227       for(j=0; j < L; j++) {
00228         for(I=0; I < N; I++) {
00229           v[I][i] += alpha[j][i] * b[j][I];
00230         }
00231       }
00232     }
00233     if(print) printf("Davidson algorithm converged in %d iterations.\n", iter);
00234   }
00235 
00236   free(conv);
00237   free_block(b);
00238   free_block(bnew);
00239   free_block(sigma);
00240   free_block(G);
00241   free_block(f);
00242   free_block(alpha);
00243   free(lambda);
00244   free(lambda_old);
00245 
00246   return converged;
00247 }

void dirprd_block ( double **  A,
double **  B,
int  rows,
int  cols 
)

dirprd_block()

This function takes two block matrices A and B and multiplies each element of B by the corresponding element of A

Parameters:
A = block matrix A
B = block matrix B
nrows = number of rows of A and B
ncols = number of columns of A and B
Returns: none

Definition at line 25 of file dirprd_block.cc.

00026 {
00027   register long int i;
00028   double *a, *b;
00029   long size;
00030 
00031   size = ((long) rows) * ((long) cols);
00032 
00033   if(!size) return;
00034 
00035   a = A[0]; b= B[0];
00036 
00037   for(i=0; i < size; i++, a++, b++) (*b) = (*a) * (*b);
00038 }

double dot_block ( double **  A,
double **  B,
int  rows,
int  cols,
double  alpha 
)

dot_block(): Find dot product of two block matrices

Parameters:
A = block matrix A
B = block matrix B
nrows = number of rows of A and B
ncols = number of columns of A and B
alpha = scale factor by which the dot product is multiplied
Returns: dot product

Definition at line 21 of file dot_block.cc.

00022 {
00023   register long int i;
00024   double *a, *b;
00025   double value;
00026   long int size;
00027 
00028   size = ((long) rows) * ((long) cols);
00029 
00030   if(!size) return 0.0;
00031 
00032   a = A[0]; b = B[0];
00033 
00034   value = 0.0;
00035   for(i=0; i < size; i++,a++,b++) value += (*a) * (*b);
00036 
00037   return alpha*value;
00038 }

double eri ( unsigned int  l1,
unsigned int  m1,
unsigned int  n1,
double  alpha1,
double  A[3],
unsigned int  l2,
unsigned int  m2,
unsigned int  n2,
double  alpha2,
double  B[3],
unsigned int  l3,
unsigned int  m3,
unsigned int  n3,
double  alpha3,
double  C[3],
unsigned int  l4,
unsigned int  m4,
unsigned int  n4,
double  alpha4,
double  D[3],
int  norm_flag 
)

eri()

This is a very inefficient function for computing ERIs over primitive Gaussian functions. The argument list is self-explanatory, except for norm_flag:

Parameters:
norm_flag = tells what kind of normalization to use, 0 - no normalization, >0 - normalized ERI

Definition at line 39 of file eri.cc.

References block_matrix(), init_array(), and norm_const().

00047 {
00048 
00049   const double gammap = alpha1 + alpha2;
00050   const double Px = (alpha1*A[0] + alpha2*B[0])/gammap;
00051   const double Py = (alpha1*A[1] + alpha2*B[1])/gammap;
00052   const double Pz = (alpha1*A[2] + alpha2*B[2])/gammap;
00053   const double PAx = Px - A[0];
00054   const double PAy = Py - A[1];
00055   const double PAz = Pz - A[2];
00056   const double PBx = Px - B[0];
00057   const double PBy = Py - B[1];
00058   const double PBz = Pz - B[2];
00059   const double AB2 = (A[0]-B[0])*(A[0]-B[0]) + (A[1]-B[1])*(A[1]-B[1]) + (A[2]-B[2])*(A[2]-B[2]); 
00060   
00061   const double gammaq = alpha3 + alpha4;
00062   const double gammapq = gammap*gammaq/(gammap+gammaq);
00063   const double Qx = (alpha3*C[0] + alpha4*D[0])/gammaq;
00064   const double Qy = (alpha3*C[1] + alpha4*D[1])/gammaq;
00065   const double Qz = (alpha3*C[2] + alpha4*D[2])/gammaq;
00066   const double QCx = Qx - C[0];
00067   const double QCy = Qy - C[1];
00068   const double QCz = Qz - C[2];
00069   const double QDx = Qx - D[0];
00070   const double QDy = Qy - D[1];
00071   const double QDz = Qz - D[2];
00072   const double CD2 = (C[0]-D[0])*(C[0]-D[0]) + (C[1]-D[1])*(C[1]-D[1]) + (C[2]-D[2])*(C[2]-D[2]);
00073 
00074   const double PQx = Px - Qx;
00075   const double PQy = Py - Qy;
00076   const double PQz = Pz - Qz;
00077   const double PQ2 = PQx*PQx + PQy*PQy + PQz*PQz;
00078 
00079   int u1,u2,v1,v2,w1,w2,tx,ty,tz,txmax,tymax,tzmax;
00080   int i,j,k;
00081   int lp,lq,mp,mq,np,nq;
00082   int zeta;
00083   double *flp, *flq, *fmp, *fmq, *fnp, *fnq;
00084   double *F;
00085   double K1, K2;
00086   double Gx,Gy,Gz;
00087   double pfac;
00088   double result = 0.0;
00089   double tmp;
00090   int u1max,u2max,v1max,v2max,w1max,w2max;
00091 
00092   K1 = exp(-alpha1*alpha2*AB2/gammap);
00093   K2 = exp(-alpha3*alpha4*CD2/gammaq);
00094   pfac = 2*pow(M_PI,2.5)*K1*K2/(gammap*gammaq*sqrt(gammap+gammaq));
00095 
00096 
00097   if (fac == NULL) {
00098     fac = init_array(MAXFAC);
00099     fac[0] = 1.0;
00100     for(i=1;i<MAXFAC;i++)
00101       fac[i] = fac[i-1]*i;
00102     bc = block_matrix(MAXFAC,MAXFAC);
00103     for(i=0;i<MAXFAC;i++)
00104       for(j=0;j<=i;j++)
00105         bc[i][j] = fac[i]/(fac[i-j]*fac[j]);
00106   }
00107 
00108   if (norm_flag > 0) {
00109     pfac *= norm_const(l1,m1,n1,alpha1,A);
00110     pfac *= norm_const(l2,m2,n2,alpha2,B);
00111     pfac *= norm_const(l3,m3,n3,alpha3,C);
00112     pfac *= norm_const(l4,m4,n4,alpha4,D);
00113   }
00114   
00115 
00116   F = init_array(l1+l2+l3+l4+m1+m2+m3+m4+n1+n2+n3+n4+1);
00117   calc_f(F,l1+l2+l3+l4+m1+m2+m3+m4+n1+n2+n3+n4,PQ2*gammapq);
00118 
00119   
00120   flp = init_array(l1+l2+1);
00121   for(k=0;k<=l1+l2;k++)
00122     for(i=0;i<=MIN(k,l1);i++) {
00123       j = k-i;
00124       if (j > l2) continue;
00125       tmp = bc[l1][i]*bc[l2][j];
00126       if (l1-i > 0)
00127         tmp *= pow(PAx,l1-i);
00128       if (l2-j > 0)
00129         tmp *= pow(PBx,l2-j);
00130       flp[k] += tmp;
00131     }
00132   fmp = init_array(m1+m2+1);
00133   for(k=0;k<=m1+m2;k++)
00134     for(i=0;i<=MIN(k,m1);i++) {
00135       j = k-i;
00136       if (j > m2) continue;
00137       tmp = bc[m1][i]*bc[m2][j];
00138       if (m1-i > 0)
00139         tmp *= pow(PAy,m1-i);
00140       if (m2-j > 0)
00141         tmp *= pow(PBy,m2-j);
00142       fmp[k] += tmp;
00143     }
00144   fnp = init_array(n1+n2+1);
00145   for(k=0;k<=n1+n2;k++)
00146     for(i=0;i<=MIN(k,n1);i++) {
00147       j = k-i;
00148       if (j > n2) continue;
00149       tmp = bc[n1][i]*bc[n2][j];
00150       if (n1-i > 0)
00151         tmp *= pow(PAz,n1-i);
00152       if (n2-j > 0)
00153         tmp *= pow(PBz,n2-j);
00154       fnp[k] += tmp;
00155     }
00156   flq = init_array(l3+l4+1);
00157   for(k=0;k<=l3+l4;k++)
00158     for(i=0;i<=MIN(k,l3);i++) {
00159       j = k-i;
00160       if (j > l4) continue;
00161       tmp = bc[l3][i]*bc[l4][j];
00162       if (l3-i > 0)
00163         tmp *= pow(QCx,l3-i);
00164       if (l4-j > 0)
00165         tmp *= pow(QDx,l4-j);
00166       flq[k] += tmp;
00167     }
00168   fmq = init_array(m3+m4+1);
00169   for(k=0;k<=m3+m4;k++)
00170     for(i=0;i<=MIN(k,m3);i++) {
00171       j = k-i;
00172       if (j > m4) continue;
00173       tmp = bc[m3][i]*bc[m4][j];
00174       if (m3-i > 0)
00175         tmp *= pow(QCy,m3-i);
00176       if (m4-j > 0)
00177         tmp *= pow(QDy,m4-j);
00178       fmq[k] += tmp;
00179     }
00180   fnq = init_array(n3+n4+1);
00181   for(k=0;k<=n3+n4;k++)
00182     for(i=0;i<=MIN(k,n3);i++) {
00183       j = k-i;
00184       if (j > n4) continue;
00185       tmp = bc[n3][i]*bc[n4][j];
00186       if (n3-i > 0)
00187         tmp *= pow(QCz,n3-i);
00188       if (n4-j > 0)
00189         tmp *= pow(QDz,n4-j);
00190       fnq[k] += tmp;
00191     }
00192 
00193 
00194   for(lp=0;lp<=l1+l2;lp++)
00195     for(lq=0;lq<=l3+l4;lq++) {
00196       u1max = lp/2;
00197       u2max = lq/2;
00198       for(u1=0;u1<=u1max;u1++)
00199         for(u2=0;u2<=u2max;u2++) {
00200           Gx = pow(-1,lp)*flp[lp]*flq[lq]*fac[lp]*fac[lq]*pow(gammap,u1-lp)*pow(gammaq,u2-lq)*fac[lp+lq-2*u1-2*u2]*
00201                pow(gammapq,lp+lq-2*u1-2*u2)/(fac[u1]*fac[u2]*fac[lp-2*u1]*fac[lq-2*u2]);
00202           for(mp=0;mp<=m1+m2;mp++)
00203             for(mq=0;mq<=m3+m4;mq++) {
00204               v1max = mp/2;
00205               v2max = mq/2;
00206               for(v1=0;v1<=v1max;v1++)
00207                 for(v2=0;v2<=v2max;v2++) {
00208                   Gy = pow(-1,mp)*fmp[mp]*fmq[mq]*fac[mp]*fac[mq]*pow(gammap,v1-mp)*pow(gammaq,v2-mq)*fac[mp+mq-2*v1-2*v2]*
00209                        pow(gammapq,mp+mq-2*v1-2*v2)/(fac[v1]*fac[v2]*fac[mp-2*v1]*fac[mq-2*v2]);
00210                   for(np=0;np<=n1+n2;np++)
00211                     for(nq=0;nq<=n3+n4;nq++) {
00212                       w1max = np/2;
00213                       w2max = nq/2;
00214                       for(w1=0;w1<=w1max;w1++)
00215                         for(w2=0;w2<=w2max;w2++) {
00216                           Gz = pow(-1,np)*fnp[np]*fnq[nq]*fac[np]*fac[nq]*pow(gammap,w1-np)*pow(gammaq,w2-nq)*fac[np+nq-2*w1-2*w2]*
00217                                pow(gammapq,np+nq-2*w1-2*w2)/(fac[w1]*fac[w2]*fac[np-2*w1]*fac[nq-2*w2]);
00218                           txmax = (lp+lq-2*u1-2*u2)/2;
00219                           tymax = (mp+mq-2*v1-2*v2)/2;
00220                           tzmax = (np+nq-2*w1-2*w2)/2;
00221                           for(tx=0;tx<=txmax;tx++)
00222                           for(ty=0;ty<=tymax;ty++)
00223                           for(tz=0;tz<=tzmax;tz++) {
00224                             zeta = lp+lq+mp+mq+np+nq-2*u1-2*u2-2*v1-2*v2-2*w1-2*w2-tx-ty-tz;
00225                             result += Gx*Gy*Gz*F[zeta]*
00226                                       pow(-1,tx+ty+tz)*
00227                                       pow(PQx,lp+lq-2*u1-2*u2-2*tx)*
00228                                       pow(PQy,mp+mq-2*v1-2*v2-2*ty)*
00229                                       pow(PQz,np+nq-2*w1-2*w2-2*tz)/
00230                                       (pow(4,u1+u2+tx+v1+v2+ty+w1+w2+tz)*
00231                                       pow(gammapq,tx)*
00232                                       pow(gammapq,ty)*
00233                                       pow(gammapq,tz)*
00234                                       fac[lp+lq-2*u1-2*u2-2*tx]*fac[tx]*
00235                                       fac[mp+mq-2*v1-2*v2-2*ty]*fac[ty]*
00236                                       fac[np+nq-2*w1-2*w2-2*tz]*fac[tz]);
00237                           }
00238                         }
00239                     }
00240                 }
00241             }
00242         }
00243     }
00244 
00245   free(F);
00246   free(flp);
00247   free(fmp);
00248   free(fnp);
00249   free(flq);
00250   free(fmq);
00251   free(fnq);
00252 
00253   return result*pfac;
00254 }

double factorial ( int  n  ) 

factorial(): Returns n!

Parameters:

Parameters:
n = number to take factorial of
Returns: n factorial, as a double word (since n! can get very large).

Definition at line 47 of file probabil.cc.

References factorial().

Referenced by combinations(), and factorial().

00048 {
00049 
00050    if (n == 0 || n == 1) return(1.0);
00051    if (n < 0) return(0.0) ;
00052    else {
00053       return ((double) n * factorial(n-1)) ;
00054       }
00055 }

void fill_sym_matrix ( double **  A,
int  size 
)

fill_sym_matrix(): Fills a symmetric matrix by placing the elements of the lower triangle into the upper triangle.

Parameters:
A = matrix to symmetrize
size = number of rows or columns (assume square)
Returns: none

Definition at line 19 of file fill_sym_matrix.cc.

00020 {
00021    double **row, *col; 
00022    int rc, cc;
00023 
00024    row = A;
00025    for (rc = 0; rc < (size-1); rc++) {
00026      col = *row;
00027      for (cc = 0; cc < size; cc++) {
00028        if (cc > rc) {
00029          *col = A[cc][rc];
00030        }
00031        col++;
00032      }
00033    row++;
00034   }
00035 }

void filter ( double *  input,
double *  output,
int *  ioff,
int  norbs,
int  nfzc,
int  nfzv 
)

filter(): Filter out undesired (frozen core/virt) integrals

Given a lower-triangle array of integrals in the full space of orbitals as well as numbers of frozen core and virtual orbitals, this function returns a list of integrals involving only active orbitals.

TDC, June 2001

Note: Based on the code written by CDS in the original iwl_rd_one_all_act() function in LIBIWL.

Definition at line 25 of file filter.cc.

00027 {
00028   int i, j, ij, IJ;
00029   int nact;
00030 
00031   nact = norbs - nfzc - nfzv;
00032 
00033   for(i=0,ij=0; i < nact; i++) {
00034     for(j=0; j <= i; j++,ij++) {
00035       IJ = ioff[i+nfzc] + (j + nfzc);
00036       output[ij] = input[IJ];
00037     }
00038   }
00039 }

void free_3d_array ( double ***  A,
int  p,
int  q 
)

free_3d_array(): Free a (non-contiguous) 3D array

Parameters:
A = triple-star pointer to the 3D array
p = size of first dimension
q = size of second dimension
Returns: none

Definition at line 55 of file 3d_array.cc.

00056 {
00057   int i,j;
00058 
00059   for(i=0; i < p; i++)
00060     for(j=0; j < q; j++)
00061       free(A[i][j]);
00062 
00063   for(i=0; i < p; i++) free(A[i]);
00064 
00065   free(A);
00066 }

int* get_frzcpi (  ) 

get_frzcpi(): Get frozen core per irrep array.

Parameters: none

Returns: pointer to int array

Definition at line 42 of file get_frzpi.cc.

References chkpt_rd_frzcpi(), chkpt_rd_nirreps(), init_int_array(), ip_exist(), and ip_int_array().

Referenced by ras_set(), and ras_set2().

00043 {
00044   int errcod;
00045   int nirreps, nirr;
00046   int need_to_init_psio = 0;
00047   int need_to_init_chkpt = 0;
00048   int if_exists;
00049   int* frzcpi;
00050 
00051 PSIO_INIT
00052 CHKPT_INIT(PSIO_OPEN_OLD);
00053   nirreps = chkpt_rd_nirreps();
00054   
00055   frzcpi = init_int_array(nirreps);
00056   
00057   if_exists = ip_exist("FROZEN_DOCC",0);
00058   if (if_exists) {
00059     errcod = ip_int_array("FROZEN_DOCC",frzcpi,nirreps);
00060   }
00061   else {
00062     free(frzcpi);
00063     frzcpi = chkpt_rd_frzcpi();
00064   }
00065 
00066 CHKPT_DONE
00067 PSIO_DONE
00068 
00069   return frzcpi;
00070 }

int* get_frzvpi (  ) 

get_frzvpi(): Get frozen virtuals per irrep array.

Parameters: none

Returns: pointer to int array

Definition at line 82 of file get_frzpi.cc.

References chkpt_rd_frzvpi(), chkpt_rd_nirreps(), init_int_array(), ip_exist(), and ip_int_array().

Referenced by ras_set(), and ras_set2().

00083 {
00084   int errcod;
00085   int nirreps, nirr;
00086   int need_to_init_psio = 0;
00087   int need_to_init_chkpt = 0;
00088   int if_exists;
00089   int* frzvpi;
00090 
00091 PSIO_INIT
00092 CHKPT_INIT(PSIO_OPEN_OLD);
00093   nirreps = chkpt_rd_nirreps();
00094   
00095   frzvpi = init_int_array(nirreps);
00096   
00097   if_exists = ip_exist("FROZEN_UOCC",0);
00098   if (if_exists) {
00099     errcod = ip_int_array("FROZEN_UOCC",frzvpi,nirreps);
00100   }
00101   else {
00102     free(frzvpi);
00103     frzvpi = chkpt_rd_frzvpi();
00104   }
00105 
00106 CHKPT_DONE
00107 PSIO_DONE
00108 
00109   return frzvpi;
00110 }

double*** init_3d_array ( int  p,
int  q,
int  r 
)

3d_array(): Initialize a (non-contiguous) 3D array

Parameters:
p = size of first dimension
q = size of second dimension
r = size of third dimension
Returns: triple-star pointer to 3D array

Definition at line 24 of file 3d_array.cc.

00025 {
00026   double ***A;
00027   int i,j,k;
00028 
00029   A = (double ***) malloc(p * sizeof(double **));
00030   for(i=0; i < p; i++) {
00031     A[i] = (double **) malloc(q * sizeof(double *));
00032     for(j=0; j < q; j++) {
00033       A[i][j] = (double *) malloc(r * sizeof(double));
00034       for(k=0; k < r; k++) {
00035         A[i][j][k] = 0.0;
00036       }
00037     }
00038   }
00039 
00040   return A;
00041 }

double invert_matrix ( double **  a,
double **  y,
int  N,
FILE *  outfile 
)

INVERT_MATRIX(): The function takes the inverse of a matrix using the C routines in Numerical Recipes in C.

Matt Leininger, Summer 1994

Parameters:

Parameters:
a = matrix to take the inverse of (is modified by invert_matrix())
y = the inverse matrix
N = the size of the matrices
outfile = file for error messages
Other variables: col and indx are temporary arrays d is 1 or -1

Returns: double (determinant) Note: The original matrix is modified by invert_matrix()

Definition at line 38 of file invert.cc.

References init_array(), and init_int_array().

Referenced by psi::detcas::bfgs_hessian().

00039 {
00040    double  d, *col, *colptr;
00041    register int i, j;
00042    int *indx ;
00043 
00044    col = init_array(N) ;
00045    indx = init_int_array(N) ;
00046 
00047    ludcmp(a,N,indx,&d) ;
00048    for (j=0; j<N; j++) d *= a[j][j];
00049   
00050    /* fprintf(outfile,"detH0 in invert = %lf\n", fabs(d));
00051    fflush(outfile); */
00052 
00053     if (fabs(d) < SMALL_DET) {
00054       fprintf(outfile,"Warning (invert_matrix): Determinant is %g\n", d);
00055       printf("Warning (invert_matrix): Determinant is %g\n", d);
00056       fflush(outfile);
00057       }
00058 
00059    for (j=0; j<N; j++) {
00060        bzero(col,sizeof(double)*N);
00061        col[j] = 1.0 ;
00062        lubksb(a,N,indx,col) ;
00063        colptr = col;
00064        for (i=0; i<N; i++) y[i][j] = *colptr++;
00065        }
00066 
00067    d = fabs(d);
00068    return(d);
00069 }

int mat_in ( FILE *  fp,
double **  array,
int  width,
int  max_length,
int *  stat 
)

MAT_IN(): Function to read in a matrix. Simple version for now.

Parameters:

Parameters:
fp = file pointer to input stream
array = matrix to hold data
width = number of columns to read
max_length = maximum number of rows to read
stat = pointer to int to hold status flag (0=read ok, 1=error)
Returns: number of rows read Also modifies stat to = error code (0 = ok, 1 = error)

Definition at line 28 of file mat_in.cc.

00029 {
00030    int i=0, j, errcod=0 ;
00031    int nr ;
00032    double data ;
00033 
00034    while ( (i < max_length) && (!errcod) ) {
00035       for (j=0; j<width; j++) {
00036          nr = fscanf(fp, "%lf", &data) ;
00037          if (feof(fp)) break ;
00038          if (nr != 1) {
00039             errcod = 1 ;
00040             break ;
00041             }
00042          else {
00043             array[i][j] = data ;
00044             }
00045          }
00046       if (feof(fp)) break ;
00047       if (!errcod) i++ ;
00048       }
00049 
00050    *stat = errcod ;
00051    return(i) ;
00052 }

int mat_print ( double **  matrix,
int  rows,
int  cols,
FILE *  outfile 
)

mat_print(): Prints a matrix to a file in a formatted style

Parameters:
matrix = matrix to print
rows = number of rows
cols = number of columns
outfile = output file pointer for printing
Returns: Always returns zero...

Definition at line 24 of file mat_print.cc.

00025 {
00026   div_t fraction;
00027   int i,j;
00028   int cols_per_page, num_pages, last_page, page, first_col;
00029 
00030   cols_per_page = 5;
00031 
00032   /* Determine the number of cols_per_page groups */
00033   fraction = div(cols,cols_per_page);
00034   num_pages = fraction.quot;  /* Number of complete column groups */
00035   last_page = fraction.rem;  /* Number of columns in last group */
00036 
00037   /* Loop over the complete column groups */
00038   for(page=0; page < num_pages; page++) {
00039       first_col = page*cols_per_page;
00040 
00041       fprintf(outfile,"\n      ");
00042       for(i=first_col; i < first_col+cols_per_page; i++) 
00043           fprintf(outfile,"      %5d        ",i);
00044 
00045       fprintf (outfile,"\n");
00046       for(i=0; i < rows; i++) {
00047           fprintf(outfile,"\n%5d ",i);
00048 
00049           for(j=first_col; j < first_col+cols_per_page; j++)        
00050               fprintf (outfile,"%19.15f",matrix[i][j]);
00051         }
00052 
00053       fprintf (outfile,"\n");
00054     }
00055 
00056   /* Now print the remaining columns */
00057   if(last_page) {
00058       first_col = page*cols_per_page;
00059 
00060       fprintf(outfile,"\n      ");
00061       for(i=first_col; i < first_col+last_page; i++) 
00062           fprintf(outfile,"      %5d        ",i);
00063       
00064       fprintf (outfile,"\n");
00065       for(i=0; i < rows; i++) {
00066           fprintf(outfile,"\n%5d ",i);
00067 
00068           for(j=first_col; j < first_col+last_page; j++)
00069               fprintf (outfile,"%19.15f",matrix[i][j]);
00070         }
00071 
00072       fprintf (outfile,"\n");
00073     }
00074 
00075   return 0;
00076 
00077 }

double newton ( double(*)(double)  F,
double(*)(double)  dF,
double  x,
double  tolerance,
int  maxiter,
int  printflag 
)

newton(): Find the root of a function by Newton's method. Iterations are limited to a maximum value. The algorithm stops when the difference between successive estimates of the root is less than the specified tolerance. An initial guess for the root must be given, as well as the function AND it's derivative.

Parameters:
F = pointer to function we want to examine (must return double)
dF = pointer to _derivative_ of function F
x = initial guess for root
tolerance = how close successive guesses must get before convergence
maxiter = maximum number of iterations
printflag = whether or not to print results for each iteration (1 or 0)
Returns: the value of the root

Definition at line 127 of file rootfind.cc.

00129 {
00130    int iter = 1 ;
00131    double newx ;
00132 
00133    if (printflag) {
00134       printf("Newton's method root finder\n") ;
00135       printf("%4s %12s\n", "iter", "x") ;
00136       printf("%4d %12.8f\n", iter, x) ;
00137       }
00138 
00139    while (iter < maxiter) {
00140       newx = x - F(x) / dF(x) ;
00141       iter++ ;
00142       if (printflag) printf("%4d %12.8f\n", iter, newx) ;
00143       if (fabs(newx - x) < tolerance) return (newx) ;
00144       x = newx ;
00145       }
00146 
00147    printf("(newton): Failed to converge within %d iterations\n", iter) ;
00148    return(newx) ;
00149 }

double norm_const ( unsigned int  l1,
unsigned int  m1,
unsigned int  n1,
double  alpha1,
double  A[3] 
)

norm_const()

Returns: normalization constant

Definition at line 319 of file eri.cc.

References init_array().

Referenced by eri().

00321 {
00322   int i;
00323   
00324   if (df == NULL) {
00325     df = init_array(2*MAXFAC);
00326     df[0] = 1.0;
00327     df[1] = 1.0;
00328     df[2] = 1.0;
00329     for(i=3; i<MAXFAC*2; i++) {
00330       df[i] = (i-1)*df[i-2];
00331     }
00332   }
00333   
00334   return pow(2*alpha1/M_PI,0.75)*pow(4*alpha1,0.5*(l1+m1+n1))/sqrt(df[2*l1]*df[2*m1]*df[2*n1]);
00335 }

void normalize ( double **  A,
int  rows,
int  cols 
)

normalize(): Normalize a set of vectors

Assume we're normalizing the ROWS

Parameters:
A = matrix holding vectors to normalize
rows = number of rows in A
cols = number of columns in A
Returns: none

David Sherrill, Feb 1994

Definition at line 30 of file normalize.cc.

References dot_arr().

00031 {
00032   double normval;
00033   register int i, j;
00034 
00035   /* divide each row by the square root of its norm */
00036   for (i=0; i<rows; i++) {
00037     dot_arr(A[i], A[i], cols, &normval);
00038     normval = sqrt(normval);
00039     for (j=0; j<cols; j++) A[i][j] /= normval;
00040   }
00041 
00042 }

int pople ( double **  A,
double *  x,
int  dimen,
int  num_vecs,
double  tolerance,
FILE *  outfile,
int  print_lvl 
)

POPLE(): Uses Pople's method to iteratively solve linear equations Ax = b

Matt Leininger, April 1998

Parameters:
A = matrix
x = initially has vector b, but returns vector x.
dimen = dimension of vector x.
num_vecs = number of vectors x to obtain.
tolerance = cutoff threshold for norm of expansion vector.
Returns: 0 for success, 1 for failure

Definition at line 32 of file pople.cc.

References block_matrix(), dot_arr(), flin(), init_array(), print_mat(), zero_arr(), and zero_mat().

00034 {
00035    double det, tval;
00036    double **Bmat; /* Matrix of expansion vectors */ 
00037    double **Ab;   /* Matrix of A x expansion vectors */ 
00038    double **M;    /* Pople subspace matrix */ 
00039    double *n;     /* overlap of b or transformed b in Ax = b 
00040                      with expansion vector zero */
00041    double *r;     /* residual vector */ 
00042    double *b;     /* b vector in Ax = b, or transformed b vector */  
00043    double *sign;  /* sign array  to insure diagonal element of A are positive */
00044    double **Mtmp; /* tmp M matrix passed to flin */
00045    register int i, j, L=0, I;
00046    double norm, rnorm=1.0, norm_Ab=1.0, *dotprod, *alpha;
00047    double *dvec;
00048    int llast=0, last=0, maxdimen;
00049    int quit=0;
00050    
00051    maxdimen = 200;
00052    /* initialize working array */
00053    Bmat = block_matrix(maxdimen, dimen);
00054    alpha = init_array(maxdimen);
00055    M = block_matrix(maxdimen, maxdimen);
00056    Mtmp = block_matrix(maxdimen, maxdimen);
00057    dvec = init_array(dimen);
00058    Ab = block_matrix(maxdimen, dimen);
00059    r = init_array(dimen);
00060    b = init_array(dimen);
00061    n = init_array(dimen);
00062    dotprod = init_array(maxdimen);
00063    sign = init_array(dimen);
00064 
00065    if (print_lvl > 6) {
00066    fprintf(outfile,"\n\n Using Pople's Method for solving linear equations.\n");
00067    fprintf(outfile,"     --------------------------------------------------\n");
00068    fprintf(outfile,"         Iter             Norm of Residual Vector      \n");
00069    fprintf(outfile,"        ------           -------------------------     \n");
00070    }
00071 
00072    norm = 0.0;
00073    for (i=0; i<dimen; i++) norm += x[i]*x[i];
00074    if (norm < ZERO) quit = 1;
00075 
00076    if (!quit) {
00077        for (i=0; i<dimen; i++) {
00078            if (A[i][i] > ZERO) sign[i] = 1.0;
00079            else sign[i] = -1.0;
00080            x[i] *= sign[i];
00081          }
00082 
00083        for (i=0; i<dimen; i++) { 
00084            Bmat[0][i] = x[i]; 
00085            b[i] = x[i];
00086            dvec[i] = sqrt(fabs(A[i][i]));
00087            b[i] /= dvec[i];
00088            /*   fprintf(outfile,"A[%d][%d] = %lf\n",i,i, A[i][i]);
00089                 fprintf(outfile,"dvec[%d] = %lf\n",i, dvec[i]);
00090                 fprintf(outfile,"x[%d] = %lf\n",i, x[i]);
00091            */
00092          }
00093 
00094        if (print_lvl > 8) {
00095            fprintf(outfile," A matrix in POPLE(LIBQT):\n");
00096            print_mat(A, dimen, dimen, outfile);
00097          }
00098 
00099        /* Constructing P matrix */
00100        for (i=0; i<dimen; i++) { 
00101            for (j=0; j<dimen; j++) {
00102                if (i==j) A[i][i] = 0.0;
00103                else A[i][j] = -A[i][j]*sign[i];
00104              }
00105          }
00106        if (print_lvl > 8) {
00107            fprintf(outfile," P matrix in POPLE(LIBQT):\n");
00108            print_mat(A, dimen, dimen, outfile);
00109          }
00110 
00111        /* Precondition P matrix with diagonal elements of A */
00112        for (i=0; i<dimen; i++)
00113            for (j=0; j<dimen; j++) {
00114                tval = 1.0/(dvec[j]*dvec[i]);
00115                A[i][j] *= tval;
00116              }
00117 
00118        if (print_lvl > 8) {
00119            fprintf(outfile," Preconditioned P matrix in POPLE(LIBQT):\n");
00120            print_mat(A, dimen, dimen, outfile);
00121          }
00122 
00123        /* 
00124           for (i=0; i<dimen; i++) { 
00125           for (j=0; j<dimen; j++) {
00126           if (i==j) A[i][i] = 1.0 - A[i][i]; 
00127           else A[i][j] = -A[i][j];
00128           }
00129           }
00130        */
00131 
00132        for (i=0; i<dimen; i++) Bmat[0][i] /= dvec[i];
00133 
00134 
00135        dot_arr(Bmat[0],Bmat[0],dimen,&norm);
00136        norm = sqrt(norm);
00137        for (i=0; i<dimen; i++) {
00138            x[i] = Bmat[0][i];
00139            Bmat[0][i] /= norm;
00140          }
00141 
00142        dot_arr(Bmat[0],x,dimen,&(n[0]));
00143  
00144        while (!last) {
00145            /* form A*b_i */
00146            for (i=0; i<dimen; i++) 
00147                dot_arr(A[i], Bmat[L], dimen, &(Ab[L][i]));
00148 
00149 
00150            /* Construct M matrix */
00151            /* M = delta_ij - <b_new|Ab_j> */
00152            zero_mat(M, maxdimen, maxdimen);
00153            for (i=0; i<=L; i++) {
00154                for (j=0; j<=L; j++) {
00155                    dot_arr(Bmat[i], Ab[j], dimen, &(dotprod[i]));
00156                    if (i==j) M[i][j] = 1.0 - dotprod[i]; 
00157                    else M[i][j] = -dotprod[i];
00158                  }
00159              }
00160 
00161            if (llast) last = llast;
00162 
00163            for (i=0; i<=L; i++) { 
00164                alpha[i] = n[i];
00165                for (j=0; j<=L; j++)
00166                    Mtmp[i][j] = M[i][j];
00167              }
00168 
00169            flin(Mtmp, alpha, L+1, 1, &det);
00170  
00171  
00172            /* Need to form and backtransform x to orig basis x = D^(-1/2) x */
00173            zero_arr(x, dimen);
00174            for (i=0; i<=L; i++)
00175                for (I=0; I<dimen; I++)
00176                    x[I] += alpha[i]*Bmat[i][I]/dvec[I];
00177 
00178            /* Form residual vector Ax - b = r */
00179            zero_arr(r, dimen);
00180            for (I=0; I<dimen; I++)
00181                for (i=0; i<=L; i++) 
00182                    r[I] += alpha[i]*(Bmat[i][I] - Ab[i][I]);
00183 
00184            for (I=0; I<dimen; I++) r[I] -= b[I]; 
00185  
00186            dot_arr(r, r, dimen, &rnorm);
00187            rnorm = sqrt(rnorm);
00188            if (print_lvl > 6) {
00189                fprintf(outfile,
00190                  "        %3d                     %10.3E\n",L+1,rnorm);
00191                fflush(outfile);
00192              }
00193 
00194            if (L+1>dimen) {
00195                fprintf(outfile,"POPLE: Too many vectors in expansion space.\n");
00196                return 1;
00197              }
00198 
00199            /* place residual in b vector space */
00200            if (L+1>= maxdimen) {
00201                fprintf(outfile,
00202                  "POPLE (LIBQT): Number of expansion vectors exceeds"
00203                        " maxdimen (%d)\n", L+1);
00204                return 1;
00205              }
00206            for (i=0; i<dimen; i++) Bmat[L+1][i] = Ab[L][i];  
00207            /* 
00208               for (i=0; i<dimen; i++) Bmat[L+1][i] = r[i]; 
00209               for (i=0; i<dimen; i++) Bmat[L+1][i] = r[i]/(dvec[i]*dvec[i]); 
00210            */
00211 
00212 
00213            /* Schmidt orthonormalize new b vec to expansion space */
00214            for (j=0; j<=L; j++) {
00215                dot_arr(Bmat[j], Bmat[L+1], dimen, &(dotprod[j]));
00216                for (I=0; I<dimen; I++)
00217                    Bmat[L+1][I] -= dotprod[j] * Bmat[j][I];
00218              }
00219 
00220            /* Normalize new expansion vector */
00221            dot_arr(Bmat[L+1], Bmat[L+1], dimen, &norm);  
00222            norm = sqrt(norm);
00223            for (I=0; I<dimen; I++) Bmat[L+1][I] /= norm;
00224 
00225            /* check orthogonality of subspace */
00226            if (0) {
00227                for (i=0; i<=L+1; i++) { 
00228                    for (j=0; j<=i; j++) { 
00229                        dot_arr(Bmat[i], Bmat[j], dimen, &tval);
00230                        fprintf(outfile, "Bvec[%d] * Bvec[%d] = %lf\n",i,j,tval); 
00231                      }
00232                  }
00233              } 
00234 
00235 
00236            if (rnorm<tolerance) llast = last = 1;
00237            L++;
00238          }
00239 
00240        zero_arr(x, dimen);
00241        for (i=0; i<=L; i++) 
00242            for (I=0; I<dimen; I++)
00243                x[I] += alpha[i]*Bmat[i][I];
00244    
00245        /* Need to backtransform x to orginal basis x = D^(-1/2) x */
00246        for (I=0; I<dimen; I++)
00247            x[I] /= dvec[I]; 
00248 
00249      }
00250    free_block(Bmat);
00251    free(alpha);
00252    free_block(M);
00253    free_block(Mtmp);
00254    free(n);
00255    free(dvec);
00256    free_block(Ab);
00257    free(r);
00258    free(b);
00259    free(dotprod);
00260 
00261    return 0;
00262 }

int ras_set ( int  nirreps,
int  nbfso,
int  freeze_core,
int *  orbspi,
int *  docc,
int *  socc,
int *  frdocc,
int *  fruocc,
int **  ras_opi,
int *  order,
int  ras_type 
)

ras_set(): Deprecated

This function sets up the number of orbitals per irrep for each of the RAS subspaces [frozen core, RAS I, RAS II, RAS III, RAS IV, frozen virts]. It also obtains the appropriate orbital reordering array. The reordering array takes a basis function in Pitzer ordering (orbitals grouped according to irrep) and gives the corresponding index in the RAS numbering scheme. Orbitals are numbered according to irrep within each of the subspaces.

Formerly, docc, socc, frdocc, and fruocc were read in this function. Now docc and socc will be left as-is if they are not present in input.

C. David Sherrill Center for Computational Quantum Chemistry University of Georgia, 25 June 1995

Parameters:
nirreps = num of irreps in computational point group
nbfso = num of basis functions in symmetry orbitals (num MOs)
freeze_core = 1 to remove frozen core orbitals from ras_opi
orbspi = array giving num symmetry orbitals (or MOs) per irrep
docc = array of doubly occupied orbitals per irrep
socc = array of singly occupied orbitals per irrep
frdocc = array of frozen core per irrep
fruocc = array of frozen virtuals per irrep
ras_opi = matrix giving num of orbitals per irrep per ras space, addressed as ras_opi[ras_space][irrep]
order = array nbfso big which maps Pitzer to Correlated order
ras_type = if 1, put docc and socc together in same RAS space (RAS I), as appropriate for DETCI. If 0, put socc in its own RAS space (RAS II), as appropriate for CC.
Returns: 1 for success, 0 otherwise

Definition at line 54 of file ras_set.cc.

References free_int_matrix(), get_frzcpi(), get_frzvpi(), init_int_array(), init_int_matrix(), ip_exist(), ip_int_array(), and zero_int_array().

00057 {
00058   int i, irrep, point, tmpi, cnt=0;
00059   int errcod, errbad, parsed_ras1=0, parsed_ras2=0, do_ras4;
00060   int *used, *offset, **tras;
00061   int *tmp_frdocc, *tmp_fruocc;
00062 
00063   used = init_int_array(nirreps);
00064   offset = init_int_array(nirreps);
00065   
00066   /* if we have trouble reading DOCC and SOCC, we'll take them as
00067    * provided to this routine.  Zero out everything else
00068    */
00069   for (i=0; i<4; i++) {
00070     zero_int_array(ras_opi[i], nirreps);
00071   }
00072   zero_int_array(order, nbfso);
00073   
00074   
00075   /* now use the parser to get the arrays we require */
00076   tmp_frdocc = get_frzcpi();
00077   tmp_fruocc = get_frzvpi();
00078   for (i=0; i<nirreps; i++) {
00079     frdocc[i] = tmp_frdocc[i];
00080     fruocc[i] = tmp_fruocc[i];
00081   }
00082   free(tmp_frdocc);
00083   free(tmp_fruocc);
00084 
00085   /* replace DOCC and SOCC only if they are in input */
00086   if (ip_exist("DOCC",0)) 
00087     errcod = ip_int_array("DOCC",docc,nirreps); 
00088   if (ip_exist("DOCC",0))
00089     errcod = ip_int_array("SOCC",socc,nirreps);
00090 
00091   errbad=0; do_ras4=1;
00092   errcod = ip_int_array("RAS1", ras_opi[0], nirreps);
00093   if (errcod == IPE_OK) parsed_ras1 = 1;
00094   else if (errcod == IPE_KEY_NOT_FOUND) {
00095     errcod = ip_int_array("ACTIVE_CORE", ras_opi[0], nirreps);
00096     if (errcod == IPE_OK) parsed_ras1 = 1;
00097     else if (errcod != IPE_KEY_NOT_FOUND) errbad = 1;
00098   }
00099   else errbad = 1;
00100   errcod = ip_int_array("RAS2", ras_opi[1], nirreps);
00101   if (errcod == IPE_OK) parsed_ras2 = 1;
00102   else if (errcod == IPE_KEY_NOT_FOUND) {
00103     errcod = ip_int_array("MODEL_SPACE", ras_opi[1], nirreps);
00104     if (errcod == IPE_OK) parsed_ras2 = 1;
00105     else if (errcod != IPE_KEY_NOT_FOUND) errbad = 1;
00106   }
00107   else errbad = 1;
00108   errcod = ip_int_array("RAS3", ras_opi[2], nirreps);
00109   if (errcod != IPE_OK && errcod != IPE_KEY_NOT_FOUND) errbad=1;
00110   if (errcod == IPE_KEY_NOT_FOUND) do_ras4=0;
00111   
00112   if (errbad == 1) {
00113     fprintf(stderr, "(ras_set): trouble parsing RAS keyword\n");
00114     return(0);
00115   }
00116   
00117   /* if the user has not specified RAS I, we must deduce it.
00118    * RAS I does not include any FZC orbs but does include COR orbs
00119    */
00120   
00121   if (!parsed_ras1) {
00122     for (irrep=0; irrep<nirreps; irrep++) {
00123       if (ras_type==1) ras_opi[0][irrep] = docc[irrep] + socc[irrep];
00124       if (ras_type==0) ras_opi[0][irrep] = docc[irrep];
00125       ras_opi[0][irrep] -= frdocc[irrep]; /* add back later for COR */ 
00126     }
00127   }
00128   
00129   
00130   /* if the user hasn't specified RAS II, look for val_orb             */
00131   /* val_orb should typically be RAS I + RAS II, so subtract out RAS I */ 
00132   if (!parsed_ras2) {
00133     errcod = ip_int_array("VAL_ORB",ras_opi[1],nirreps);
00134     if (errcod != IPE_OK) {
00135       for (irrep=0; irrep<nirreps; irrep++) {
00136         if (ras_type==1) ras_opi[1][irrep] = 0;
00137         if (ras_type==0) ras_opi[1][irrep] = socc[irrep];
00138       }
00139     }
00140     else {
00141       for (irrep = 0; irrep<nirreps; irrep++) { 
00142          ras_opi[1][irrep] -= ras_opi[0][irrep];
00143          if (ras_opi[1][irrep] < 0) {
00144            fprintf(stderr, "(ras_set): val_orb must be larger than RAS I\n");
00145            return(0);
00146          }
00147       }
00148     }
00149   }
00150   
00151   /* set up the RAS III or IV array: if RAS IV is used, RAS III must
00152    * be specified and then RAS IV is deduced.
00153    */
00154   
00155   for (irrep=0; irrep<nirreps; irrep++) { 
00156     tmpi = frdocc[irrep] + fruocc[irrep] + ras_opi[0][irrep] + 
00157       ras_opi[1][irrep];
00158     if (do_ras4) tmpi += ras_opi[2][irrep];
00159     if (tmpi > orbspi[irrep]) {
00160       fprintf(stderr, "(ras_set): orbitals don't add up for irrep %d\n",
00161               irrep);
00162       return(0);
00163     }
00164     if (do_ras4) ras_opi[3][irrep] = orbspi[irrep] - tmpi;
00165     else ras_opi[2][irrep] = orbspi[irrep] - tmpi;
00166   } 
00167   
00168   /* copy everything to the temporary RAS arrays: */
00169   /* add subspaces for frozen orbitals            */
00170   tras = init_int_matrix(6, nirreps);
00171   for (irrep=0; irrep<nirreps; irrep++) {
00172     tras[0][irrep] = frdocc[irrep];
00173     tras[5][irrep] = fruocc[irrep];
00174   }
00175   for (i=0; i<4; i++) {
00176     for (irrep=0; irrep<nirreps; irrep++) {
00177       tras[i+1][irrep] = ras_opi[i][irrep];
00178     }
00179   }
00180  
00181   /* construct the offset array */
00182   offset[0] = 0;
00183   for (irrep=1; irrep<nirreps; irrep++) {
00184     offset[irrep] = offset[irrep-1] + orbspi[irrep-1];
00185   }
00186   
00187   for (i=0; i<6; i++) {
00188     for (irrep=0; irrep<nirreps; irrep++) { 
00189       while (tras[i][irrep]) {
00190         point = used[irrep] + offset[irrep];
00191         if (point < 0 || point >= nbfso) {
00192           fprintf(stderr, "(ras_set): Invalid point value\n");
00193           exit(PSI_RETURN_FAILURE);
00194         }
00195         order[point] = cnt++;
00196         used[irrep]++;
00197         tras[i][irrep]--;
00198       }
00199     }
00200   }
00201   
00202 
00203   /* do a final check */
00204 
00205   for (irrep=0; irrep<nirreps; irrep++) {
00206     if (used[irrep] > orbspi[irrep]) {
00207       fprintf(stderr, "(ras_set): on final check, used more orbitals");
00208       fprintf(stderr, "   than were available (%d vs %d) for irrep %d\n",
00209               used[irrep], orbspi[irrep], irrep);
00210       errbad = 1;
00211     } 
00212     if (used[irrep] < orbspi[irrep]) {
00213       fprintf(stderr, "(ras_set): on final check, used fewer orbitals");
00214       fprintf(stderr, "   than were available (%d vs %d) for irrep %d\n",
00215               used[irrep], orbspi[irrep], irrep);
00216       errbad = 1;
00217     }
00218   }
00219   
00220   /* for restricted COR orbitals */
00221   if (!freeze_core) {
00222     for (irrep=0; irrep<nirreps; irrep++) {
00223       ras_opi[0][irrep] += frdocc[irrep];
00224     }
00225   }
00226   
00227   free(used);  free(offset);
00228   free_int_matrix(tras);
00229 
00230   return(!errbad);
00231 
00232 }

int ras_set2 ( int  nirreps,
int  nmo,
int  delete_fzdocc,
int  delete_restrdocc,
int *  orbspi,
int *  docc,
int *  socc,
int *  frdocc,
int *  fruocc,
int *  restrdocc,
int *  restruocc,
int **  ras_opi,
int *  order,
int  ras_type,
int  hoffmann 
)

ras_set2()

This function sets up the number of orbitals per irrep for each of the RAS subspaces [frozen core (FZC), restricted core (COR), RAS I, RAS II, RAS III, RAS IV, restricted virts (VIR), frozen virts (FZV)]. It also obtains the appropriate orbital reordering array. The reordering array takes a basis function in Pitzer ordering (orbitals grouped according to irrep) and gives the corresponding index in the RAS numbering scheme. Orbitals are numbered according to irrep within each of the subspaces.

Formerly, docc, socc, frdocc, and fruocc were read in this function. Now docc and socc will be left as-is if they are not present in input.

Assume we always want integrals (at least some of them...) involving restricted orbitals, but we may not need them for frozen orbitals unless perhaps it's a gradient. The frozen orbitals will never enter explicitly in DETCI, but restricted orbitals may or may not, depending on the type of computation (CI vs CAS vs CASPT2, etc). For conventional CI, FCI, MRCI, RASCI, CASSCF, restricted orbitals will not participate explicitly in DETCI. For CASPT2, perhaps they will. CLAG and DETCAS will still need to have some indices in the restricted (and possibly frozen) orbital subspaces?

C. David Sherrill

Updated June 2002 to distinguish between frozen and restricted spaces

Parameters:
nirreps = num of irreps in computational point group
nmo = number of MO's
delete_fzdocc = 1 to remove frozen core orbitals from ras_opi[0]
delete_restrdocc = 1 to remove restricted core orbs from ras_opi[0]
orbspi = array giving num symmetry orbitals (or MOs) per irrep
docc = array of doubly occupied orbitals per irrep (guess should be provided)
socc = array of singly occupied orbitals per irrep (guess should be provided)
frdocc = array of frozen core per irrep (returned by function, but allocate before call)
fruocc = array of frozen virtuals per irrep (returned by function, but allocate before call)
rstrdocc = array of restricted core per irrep (returned by function, but allocate before call)
rstruocc = array of restricted core per irrep (returned by function, but allocate before call)
ras_opi = matrix giving num of orbitals per irrep per ras space, addressed as ras_opi[ras_space][irrep] (returned by function, but allocate before call)
order = array nmo big which maps Pitzer to Correlated order (returned by function, but allocate before call)
ras_type = if 1, put docc and socc together in same RAS space (RAS I), as appropriate for DETCI. If 0, put socc in its own RAS space (RAS II), as appropriate for CC.
hoffmann = if > 0, order orbitals according to Mark Hoffmann. hoffmann==1: ras1, ras2, ..., rasn, COR, FZC, VIR, FZV. hoffmann==2: VIR, ras1, ras2, ..., rasn, COR, FZC, FZV. Note odd placement of FZC in middle!
Returns: 1 for success, 0 otherwise

Definition at line 299 of file ras_set.cc.

References free_int_matrix(), get_frzcpi(), get_frzvpi(), init_int_array(), init_int_matrix(), ip_exist(), ip_int_array(), and zero_int_array().

00304 {
00305   int i, irrep, point, tmpi, cnt=0;
00306   int errcod, errbad, parsed_ras1=0, parsed_ras2=0, do_ras4;
00307   int parsed_restr_uocc=0;
00308   int *used, *offset, **tras;
00309   int *tmp_frdocc, *tmp_fruocc;
00310 
00311   /* Hoffmann's code never wants FZC or COR lumped in with RAS I,
00312      even if those orbitals need to be transformed also */
00313   if (hoffmann > 0) {
00314     delete_fzdocc = 1;
00315     delete_restrdocc = 1;
00316   }
00317 
00318   used = init_int_array(nirreps);
00319   offset = init_int_array(nirreps);
00320   
00321   /* if we have trouble reading DOCC and SOCC, we'll take them as
00322    * provided to this routine.  Zero out everything else
00323    */
00324   zero_int_array(restrdocc, nirreps);
00325   zero_int_array(restruocc, nirreps);
00326 
00327   for (i=0; i<MAX_RAS_SPACES; i++) {
00328     zero_int_array(ras_opi[i], nirreps);
00329   }
00330   zero_int_array(order, nmo);
00331   
00332   /* now use the parser to get the arrays we require */
00333   tmp_frdocc = get_frzcpi();
00334   tmp_fruocc = get_frzvpi();
00335   for (i=0; i<nirreps; i++) {
00336     frdocc[i] = tmp_frdocc[i];
00337     fruocc[i] = tmp_fruocc[i];
00338   }
00339   free(tmp_frdocc);
00340   free(tmp_fruocc);
00341 
00342 
00343   /* replace DOCC and SOCC only if they are in input */
00344   if (ip_exist("DOCC",0))
00345     errcod = ip_int_array("DOCC",docc,nirreps); 
00346   if (ip_exist("SOCC",0))
00347     errcod = ip_int_array("SOCC",socc,nirreps);
00348   
00349   /* now use the parser to get the arrays we require */
00350   errcod = ip_int_array("RESTRICTED_DOCC",restrdocc,nirreps);
00351   
00352   errbad=0; do_ras4=1;
00353   errcod = ip_int_array("RAS1", ras_opi[0], nirreps);
00354   if (errcod == IPE_OK) parsed_ras1 = 1;
00355   else if (errcod != IPE_KEY_NOT_FOUND) errbad = 1;
00356   errcod = ip_int_array("RAS2", ras_opi[1], nirreps);
00357   if (errcod == IPE_OK) parsed_ras2 = 1;
00358   else if (errcod != IPE_KEY_NOT_FOUND) errbad = 1;
00359   errcod = ip_int_array("RAS3", ras_opi[2], nirreps);
00360   if (errcod != IPE_OK && errcod != IPE_KEY_NOT_FOUND) errbad=1;
00361   if (errcod == IPE_KEY_NOT_FOUND) do_ras4=0;
00362   
00363   if (errbad == 1) {
00364     fprintf(stderr, "(ras_set): trouble parsing RAS keyword\n");
00365     return(0);
00366   }
00367   
00368   /*
00369    * If the user has not specified RAS I, we must deduce it.
00370    * As of 2004, RAS I will not include any FZC ("frozen core")
00371    * orbitals *OR* any COR ("restricted core") orbitals.  However,
00372    * we'll add these back into RAS I later if the user requests it
00373    * by setting delete_fzdocc or delete_rstrdocc = 0.
00374    */
00375   
00376   if (!parsed_ras1) {
00377     for (irrep=0; irrep<nirreps; irrep++) {
00378       if (ras_type==1) ras_opi[0][irrep] = docc[irrep] + socc[irrep];
00379       if (ras_type==0) ras_opi[0][irrep] = docc[irrep];
00380       ras_opi[0][irrep] -= (frdocc[irrep] + restrdocc[irrep]);
00381     }
00382   }
00383   
00384   
00385   /* 
00386    * if the user hasn't specified RAS II, look for ACTIVE (replaces
00387    * VAL_ORB).  Assume this always goes after FZC + COR. 
00388    */ 
00389   if (!parsed_ras2) {
00390     errcod = ip_int_array("ACTIVE",ras_opi[1],nirreps);
00391     if (errcod != IPE_OK) { /* we didn't find ACTIVE keyword */
00392       for (irrep=0; irrep<nirreps; irrep++) {
00393         if (ras_type==1) ras_opi[1][irrep] = 0;
00394         if (ras_type==0) ras_opi[1][irrep] = socc[irrep];
00395       }
00396     }
00397     else { /* we found a ACTIVE keyword */
00398       if (parsed_ras1) 
00399         fprintf(outfile, "ras_set(): Warning: ACTIVE overrides RAS 1\n");
00400 
00401       for (irrep=0; irrep<nirreps; irrep++) 
00402         ras_opi[0][irrep] = 0; /* ACTIVE overrides RAS 1 */
00403 
00404       if (!ip_exist("RESTRICTED_UOCC",0)) { /* default restrict other virs */
00405         for (irrep=0; irrep<nirreps; irrep++) {
00406           ras_opi[0][irrep] = 0; /* ACTIVE overrides RAS 1 */
00407           restruocc[irrep] = orbspi[irrep] - frdocc[irrep] - 
00408                              restrdocc[irrep] - ras_opi[0][irrep] - 
00409                              ras_opi[1][irrep] - fruocc[irrep];
00410         }
00411         parsed_restr_uocc = 1;
00412       } 
00413 
00414       /* do a quick check */
00415       for (irrep=0; irrep<nirreps; irrep++) {
00416         if (frdocc[irrep]+restrdocc[irrep]+ras_opi[0][irrep]+ras_opi[1][irrep] 
00417             < docc[irrep] + socc[irrep])
00418           fprintf(outfile, 
00419                   "ras_set():Warning:Occupied electrons beyond ACTIVE orbs!\n");
00420       }
00421     }
00422   } /* end looking for "ACTIVE" */
00423 
00424   if (!parsed_restr_uocc) 
00425     errcod = ip_int_array("RESTRICTED_UOCC",restruocc,nirreps);
00426   
00427   /* set up the RAS III or IV array: if RAS IV is used, RAS III must
00428    * be specified and then RAS IV is deduced.
00429    */
00430   
00431   for (irrep=0; irrep<nirreps; irrep++) { 
00432     tmpi = frdocc[irrep] + restrdocc[irrep] + fruocc[irrep] + restruocc[irrep]
00433            + ras_opi[0][irrep] + ras_opi[1][irrep];
00434     if (do_ras4) tmpi += ras_opi[2][irrep];
00435     if (tmpi > orbspi[irrep]) {
00436       fprintf(stderr, "(ras_set): orbitals don't add up for irrep %d\n",
00437               irrep);
00438       return(0);
00439     }
00440     if (do_ras4) ras_opi[3][irrep] = orbspi[irrep] - tmpi;
00441     else ras_opi[2][irrep] = orbspi[irrep] - tmpi;
00442   } 
00443   
00444   /* copy everything to the temporary RAS arrays: */
00445   /* add subspaces for frozen orbitals            */
00446   tras = init_int_matrix(MAX_RAS_SPACES+4, nirreps);
00447 
00448   /* for usual DETCI, DETCAS, etc */
00449   if (hoffmann==0) {
00450     for (irrep=0; irrep<nirreps; irrep++) {
00451       tras[0][irrep] = frdocc[irrep];
00452       tras[1][irrep] = restrdocc[irrep];
00453       tras[MAX_RAS_SPACES+2][irrep] = restruocc[irrep];
00454       tras[MAX_RAS_SPACES+3][irrep] = fruocc[irrep];
00455     }
00456     for (i=0; i<MAX_RAS_SPACES; i++) {
00457       for (irrep=0; irrep<nirreps; irrep++) {
00458         tras[i+2][irrep] = ras_opi[i][irrep];
00459       }
00460     }
00461   }
00462   /* for Mark Hoffmann's UND order for GVVPT2, etc. */
00463   else if (hoffmann == 1) {
00464     for (i=0; i<MAX_RAS_SPACES; i++) {
00465       for (irrep=0; irrep<nirreps; irrep++) {
00466         tras[i][irrep] = ras_opi[i][irrep];
00467       }
00468     }
00469     for (irrep=0; irrep<nirreps; irrep++) {
00470       tras[MAX_RAS_SPACES+0][irrep] = restrdocc[irrep];
00471       tras[MAX_RAS_SPACES+1][irrep] = frdocc[irrep];
00472       tras[MAX_RAS_SPACES+2][irrep] = restruocc[irrep];
00473       tras[MAX_RAS_SPACES+3][irrep] = fruocc[irrep];
00474     }
00475   }
00476   /* for Mark Hoffmann's UND GUGA code */
00477   else if (hoffmann == 2) {
00478     for (i=0; i<MAX_RAS_SPACES; i++) {
00479       for (irrep=0; irrep<nirreps; irrep++) {
00480         tras[i+1][irrep] = ras_opi[i][irrep];
00481       }
00482     }
00483     for (irrep=0; irrep<nirreps; irrep++) {
00484       tras[0][irrep] = restruocc[irrep];
00485       tras[1+MAX_RAS_SPACES][irrep] = restrdocc[irrep];
00486       tras[2+MAX_RAS_SPACES][irrep] = frdocc[irrep];
00487       tras[MAX_RAS_SPACES+3][irrep] = fruocc[irrep];
00488     }
00489   }
00490    
00491   /* construct the offset array */
00492   offset[0] = 0;
00493   for (irrep=1; irrep<nirreps; irrep++) {
00494     offset[irrep] = offset[irrep-1] + orbspi[irrep-1];
00495   }
00496   
00497   for (i=0; i<MAX_RAS_SPACES+4; i++) {
00498     for (irrep=0; irrep<nirreps; irrep++) { 
00499       while (tras[i][irrep]) {
00500         point = used[irrep] + offset[irrep];
00501         if (point < 0 || point >= nmo) {
00502           fprintf(stderr, "(ras_set): Invalid point value\n");
00503           abort();
00504         }
00505         order[point] = cnt++;
00506         used[irrep]++;
00507         tras[i][irrep]--;
00508       }
00509     }
00510   }
00511   
00512 
00513   /* do a final check */
00514   for (irrep=0; irrep<nirreps; irrep++) {
00515     if (used[irrep] > orbspi[irrep]) {
00516       fprintf(stderr, "(ras_set): on final check, used more orbitals");
00517       fprintf(stderr, "   than were available (%d vs %d) for irrep %d\n",
00518               used[irrep], orbspi[irrep], irrep);
00519       errbad = 1;
00520     } 
00521     if (used[irrep] < orbspi[irrep]) {
00522       fprintf(stderr, "(ras_set): on final check, used fewer orbitals");
00523       fprintf(stderr, "   than were available (%d vs %d) for irrep %d\n",
00524               used[irrep], orbspi[irrep], irrep);
00525       errbad = 1;
00526     }
00527   }
00528   
00529   /* add back FZC and COR orbitals to RAS I if they are to be included */
00530   for (irrep=0; irrep<nirreps; irrep++) {
00531     if (!delete_restrdocc) ras_opi[0][irrep] += restrdocc[irrep];
00532     if (!delete_fzdocc)    ras_opi[0][irrep] += frdocc[irrep];
00533   }
00534   
00535   free(used);  free(offset);
00536   free_int_matrix(tras);
00537 
00538   return(!errbad);
00539 
00540 }

void reorder_qt ( int *  docc_in,
int *  socc_in,
int *  frozen_docc_in,
int *  frozen_uocc_in,
int *  order,
int *  orbs_per_irrep,
int  nirreps 
)

reorder_qt()

This function constructs a reordering array according to the "Quantum Trio" standard ordering, in which the orbitals are divided into the following sets: frozen core, then doubly occupied, then singly occupied, then virtuals, then deleted (frozen) virtuals. The reordering array takes a basis function in Pitzer ordering (orbitals grouped according to irrep) and gives the corresponding index in the Quantum Trio numbering scheme.

Should give the same reordering array as in the old libread30 routines.

C. David Sherrill Center for Computational Quantum Chemistry University of Georgia, 1995

Parameters:
docc_in = doubly occupied orbitals per irrep
socc_in = singly occupied orbitals per irrep
frozen_docc_in = frozen occupied orbitals per irrep
frozen_uocc_in = frozen unoccupied orbitals per irrep
order = reordering array (Pitzer->QT order)
nirreps = number of irreducible representations

Definition at line 40 of file reorder_qt.cc.

References init_int_array().

00042 {
00043 
00044    int cnt=0, irrep, point, tmpi;
00045    int *used, *offset; 
00046    int *docc, *socc, *frozen_docc, *frozen_uocc; 
00047    int *uocc;
00048 
00049    used = init_int_array(nirreps);
00050    offset = init_int_array(nirreps);
00051 
00052    docc = init_int_array(nirreps);
00053    socc = init_int_array(nirreps);
00054    frozen_docc = init_int_array(nirreps);
00055    frozen_uocc = init_int_array(nirreps);
00056    uocc = init_int_array(nirreps);
00057 
00058    for (irrep=0; irrep<nirreps; irrep++) {
00059       docc[irrep] = docc_in[irrep];
00060       socc[irrep] = socc_in[irrep];
00061       frozen_docc[irrep] = frozen_docc_in[irrep];
00062       frozen_uocc[irrep] = frozen_uocc_in[irrep];
00063       }
00064  
00065    /* construct the offset array */
00066    offset[0] = 0;
00067    for (irrep=1; irrep<nirreps; irrep++) {
00068       offset[irrep] = offset[irrep-1] + orbs_per_irrep[irrep-1];
00069       }
00070    
00071    /* construct the uocc array */
00072    for (irrep=0; irrep<nirreps; irrep++) {
00073       tmpi = frozen_uocc[irrep] + docc[irrep] + socc[irrep];
00074       if (tmpi > orbs_per_irrep[irrep]) {
00075          fprintf(stderr, "(reorder_qt): orbitals don't add up for irrep %d\n",
00076             irrep);
00077          return;
00078          }
00079       else
00080          uocc[irrep] = orbs_per_irrep[irrep] - tmpi;
00081       }
00082 
00083    /* do the frozen core */
00084    for (irrep=0; irrep<nirreps; irrep++) { 
00085       while (frozen_docc[irrep]) {
00086          point = used[irrep] + offset[irrep];
00087          order[point] = cnt++;
00088          used[irrep]++;
00089          frozen_docc[irrep]--;
00090          docc[irrep]--;
00091          }
00092       }
00093 
00094    /* do doubly occupied orbitals */
00095    for (irrep=0; irrep<nirreps; irrep++) {
00096       while (docc[irrep]) {
00097          point = used[irrep] + offset[irrep];
00098          order[point] = cnt++;
00099          used[irrep]++;
00100          docc[irrep]--;
00101          }
00102       }
00103 
00104    /* do singly-occupied orbitals */
00105    for (irrep=0; irrep<nirreps; irrep++) {
00106       while (socc[irrep]) {
00107          point = used[irrep] + offset[irrep];
00108          order[point] = cnt++;
00109          used[irrep]++;
00110          socc[irrep]--;
00111          }
00112       }
00113 
00114    /* do virtual orbitals */
00115    for (irrep=0; irrep<nirreps; irrep++) {
00116       while (uocc[irrep]) {
00117          point = used[irrep] + offset[irrep];
00118          order[point] = cnt++;
00119          used[irrep]++;
00120          uocc[irrep]--;
00121          }
00122       }
00123 
00124    /* do frozen uocc */
00125    for (irrep=0; irrep<nirreps; irrep++) {
00126       while (frozen_uocc[irrep]) {
00127          point = used[irrep] + offset[irrep];
00128          order[point] = cnt++;
00129          used[irrep]++;
00130          frozen_uocc[irrep]--;
00131          }
00132       }
00133 
00134 
00135    /* do a final check */
00136    for (irrep=0; irrep<nirreps; irrep++) {
00137       if (used[irrep] > orbs_per_irrep[irrep]) {
00138          fprintf(stderr, "(reorder_qt): on final check, used more orbitals");
00139          fprintf(stderr, "   than were available (%d vs %d) for irrep %d\n",
00140             used[irrep], orbs_per_irrep[irrep], irrep);
00141          } 
00142       }
00143 
00144    free(used);  free(offset);
00145    free(docc);  free(socc);  free(frozen_docc);  free(frozen_uocc);
00146    free(uocc);
00147 }

void reorder_qt_uhf ( int *  docc,
int *  socc,
int *  frozen_docc,
int *  frozen_uocc,
int *  order_alpha,
int *  order_beta,
int *  orbspi,
int  nirreps 
)

reorder_qt_uhf()

Generalization of reorder_qt() for UHF case

Parameters:
docc = doubly occupied orbitals per irrep
socc = singly occupied orbitals per irrep
frozen_docc = frozen occupied orbitals per irrep
frozen_uocc = frozen unoccupied orbitals per irrep
order_alpha = reordering array for alpha (Pitzer->QT order)
order_beta = reordering array for beta (Pitzer->QT order)
nirreps = number of irreducible representations

Definition at line 164 of file reorder_qt.cc.

References init_int_array().

00167 {
00168   int p, nmo;
00169   int cnt_alpha, cnt_beta, irrep, point, point_alpha, point_beta, tmpi;
00170   int *offset, this_offset; 
00171   int *uocc;
00172 
00173   offset = init_int_array(nirreps);
00174 
00175   uocc = init_int_array(nirreps);
00176 
00177   /* construct the offset array */
00178   offset[0] = 0;
00179   for (irrep=1; irrep<nirreps; irrep++) {
00180     offset[irrep] = offset[irrep-1] + orbspi[irrep-1];
00181   }
00182    
00183   /* construct the uocc array */
00184   nmo = 0;
00185   for (irrep=0; irrep<nirreps; irrep++) {
00186     nmo += orbspi[irrep];
00187     tmpi = frozen_uocc[irrep] + docc[irrep] + socc[irrep];
00188     if (tmpi > orbspi[irrep]) {
00189       fprintf(stderr, "(reorder_qt_uhf): orbitals don't add up for irrep %d\n",
00190               irrep);
00191       return;
00192     }
00193     else
00194       uocc[irrep] = orbspi[irrep] - tmpi;
00195   }
00196 
00197   cnt_alpha = cnt_beta = 0;
00198 
00199   /* do the frozen core */
00200   for(irrep=0; irrep<nirreps; irrep++) { 
00201     this_offset = offset[irrep];
00202     for(p=0; p < frozen_docc[irrep]; p++) {
00203       order_alpha[this_offset+p] = cnt_alpha++;
00204       order_beta[this_offset+p] = cnt_beta++;
00205     }
00206   }
00207 
00208   /* alpha occupied orbitals */
00209   for(irrep=0; irrep<nirreps; irrep++) {
00210     this_offset = offset[irrep] + frozen_docc[irrep];
00211     for(p=0; p < docc[irrep] + socc[irrep] - frozen_docc[irrep]; p++) {
00212       order_alpha[this_offset + p] = cnt_alpha++;
00213     }
00214   }
00215 
00216   /* beta occupied orbitals */
00217   for(irrep=0; irrep<nirreps; irrep++) {
00218     this_offset = offset[irrep] + frozen_docc[irrep];
00219     for(p=0; p < docc[irrep] - frozen_docc[irrep]; p++) {
00220       order_beta[this_offset + p] = cnt_beta++;
00221     }
00222   }
00223 
00224   /* alpha unoccupied orbitals */
00225   for(irrep=0; irrep<nirreps; irrep++) {
00226     this_offset = offset[irrep] + docc[irrep] + socc[irrep];
00227     for(p=0; p < uocc[irrep]; p++) {
00228       order_alpha[this_offset + p] = cnt_alpha++;
00229     }
00230   }
00231 
00232   /* beta unoccupied orbitals */
00233   for(irrep=0; irrep<nirreps; irrep++) {
00234     this_offset = offset[irrep] + docc[irrep];
00235     for(p=0; p < uocc[irrep] + socc[irrep]; p++) {
00236       order_beta[this_offset + p] = cnt_beta++;
00237     }
00238   }
00239 
00240   /* do the frozen uocc */
00241   for (irrep=0; irrep<nirreps; irrep++) {
00242     this_offset = offset[irrep] + docc[irrep] + socc[irrep] + uocc[irrep];
00243     for(p=0; p < frozen_uocc[irrep]; p++) {
00244       order_alpha[this_offset + p] = cnt_alpha++;
00245       order_beta[this_offset + p] = cnt_beta++;
00246     }
00247   }
00248 
00249   /* do a final check */
00250   for (irrep=0; irrep<nirreps; irrep++) {
00251     if (cnt_alpha > nmo) {
00252       fprintf(stderr, "(reorder_qt_uhf): on final check, used more orbitals");
00253       fprintf(stderr, "   than were available (%d vs %d) for irrep %d\n",
00254               cnt_alpha, nmo, irrep);
00255     } 
00256     if (cnt_beta > nmo) {
00257       fprintf(stderr, "(reorder_qt_uhf): on final check, used more orbitals");
00258       fprintf(stderr, "   than were available (%d vs %d) for irrep %d\n",
00259               cnt_beta, nmo, irrep);
00260     } 
00261   }
00262 
00263   free(offset);
00264   free(uocc);
00265 }

void schmidt ( double **  A,
int  rows,
int  cols,
FILE *  outfile 
)

SCHMIDT(): Gram-Schmidt orthogonalize a set of vectors

Assume we're orthogonalizing the ROWS, since in C a vector is usually a row more often than a column.

David Sherrill, Feb 1994

Parameters:
A = matrix to orthogonalize (matrix of doubles)
rows = rows of A
cols = columns of A
Returns: none

Definition at line 31 of file schmidt.cc.

References dot_arr(), and init_array().

00032 {
00033    double *tmp;
00034    double normval, dotval;
00035    int i, j;
00036    register int I;
00037 
00038    /* initialize working array */
00039    tmp = init_array(cols);
00040   
00041    /* always take the first vector (normalized) as given */
00042    dot_arr(A[0], A[0], cols, &normval) ; /* normval = dot (A0 * A0) */
00043    normval = sqrt(normval) ;
00044 
00045    for (i=0; i<cols; i++) A[0][i] /= normval; 
00046 
00047    /* now, one at a time, get the new rows */
00048    for (i=1; i<rows; i++) {
00049       for (I=0; I<cols; I++) tmp[I] = A[i][I] ;
00050       for (j=0; j<i; j++) {
00051          dot_arr(A[i], A[j], cols, &dotval) ; 
00052          for (I=0; I<cols; I++) tmp[I] -= dotval * A[j][I];
00053          }
00054       dot_arr(tmp, tmp, cols, &normval);
00055       normval = sqrt(normval);
00056       /* fprintf(outfile,"\n norm[%d] = %20.15f\n",i, (1.0/normval));
00057       fflush(outfile); */
00058       for (I=0; I<cols; I++) A[i][I] = tmp[I] / normval; 
00059       }
00060 
00061    free(tmp);
00062 
00063 }

int schmidt_add ( double **  A,
int  rows,
int  cols,
double *  v 
)

SCHMIDT_ADD(): Assume A is a orthogonal matrix. This function Gram-Schmidt orthogonalizes a new vector v and adds it to matrix A. A must contain a free row pointer for a new row. Don't add orthogonalized v' if norm(v') < NORM_TOL.

David Sherrill, Feb 1994

Parameters:
A = matrix to add new vector to
rows = current number of rows in A (A must have ptr for 'rows+1' row.)
cols = columns in A v = vector to add to A after it has been made orthogonal to rest of A
Returns: 1 if a vector is added to A, 0 otherwise

Definition at line 33 of file lib/libqt/schmidt_add.cc.

References dot_arr(), and init_array().

Referenced by david().

00034 {
00035    double dotval, normval ;
00036    int i, I ;
00037 
00038    for (i=0; i<rows; i++) {
00039       dot_arr(A[i], v, cols, &dotval) ;
00040       for (I=0; I<cols; I++) v[I] -= dotval * A[i][I] ;
00041       }                 
00042 
00043    dot_arr(v, v, cols, &normval) ;
00044    normval = sqrt(normval) ;
00045 
00046    if (normval < NORM_TOL) 
00047       return(0) ;
00048    else {
00049       if (A[rows] == NULL) A[rows] = init_array(cols) ;
00050       for (I=0; I<cols; I++) A[rows][I] = v[I] / normval ;
00051       return(1) ;
00052       }
00053 }

double secant ( double(*)(double)  F,
double  x0,
double  x1,
double  tolerance,
int  maxiter,
int  printflag 
)

secant(): Find the root of a function by the Secant Method. Iterations are limited to a maximum value. The algorithm stops when the relative difference between successive guesses is less than the specified tolerance. An initial TWO guesses for the root must be given, as well as the function itself.

Parameters:
F = pointer to function we want to examine (must return double)
x0 = 1st guess for root
x1 = 2nd guess for root
tolerance = how close successive guesses must get before convergence
maxiter = maximum number of iterations
printflag = whether or not to print results for each iteration (1 or 0)
Returns: the value of the root

Definition at line 171 of file rootfind.cc.

00173 {
00174    int iter = 2 ;
00175    double x2=0.0 ;
00176    double fx1, fx0 ;
00177 
00178    if (printflag) {
00179       printf("Secant Method root finder\n") ;
00180       printf("%4s %12s\n", "iter", "x") ;
00181       printf("%4d %12.8f\n", 1, x0) ;
00182       printf("%4d %12.8f\n", 2, x1) ;
00183       }
00184 
00185 
00186    while (iter < maxiter) {
00187       fx1 = F(x1) ; 
00188       fx0 = F(x0) ;
00189       x2 = x1 - fx1 * (x1 - x0) / (fx1 - fx0) ;
00190       iter++ ;
00191       if (printflag) printf("%4d %12.8f\n", iter, x2) ;
00192       if (fabs((x2 - x1)/x1) < tolerance) return(x2) ;
00193       x0 = x1 ;
00194       x1 = x2 ;
00195       }
00196 
00197    printf("(secant): Failed to converge within %d iterations\n", iter) ;
00198    return(x2) ;
00199 }

void slaterdetset_add ( SlaterDetSet sdset,
int  index,
int  alphastring,
int  betastring 
)

slaterdetset_add(): Add info for a particular Slater determinant to a SlaterDetSet.

Parameters:
sdset = pointer to SlaterDetSet to add to
index = location in the set to add to
alphastring = alpha string ID for the new determinant
betastring = beta string ID for the new determinant
Returns: none

Definition at line 358 of file slaterdset.cc.

References SlaterDet::alphastring, SlaterDetSet::alphastrings, SlaterDet::betastring, SlaterDetSet::betastrings, SlaterDetSet::dets, and SlaterDet::index.

00360 {
00361   SlaterDet *det;
00362   StringSet *alphaset = sdset->alphastrings;
00363   StringSet *betaset = sdset->betastrings;
00364 
00365   if (index < sdset->size && index >= 0) {
00366     det = sdset->dets + index;
00367   }
00368   det->index = index;
00369   if (alphastring < alphaset->size && alphastring >= 0)
00370     det->alphastring = alphastring;
00371   if (betastring < betaset->size && betastring >= 0)
00372     det->betastring = betastring;
00373 }

void slaterdetset_delete ( SlaterDetSet sdset  ) 

slaterdetset_delete(): Delete a Slater Determinant Set.

Does not free the members alphastrings and betastrings. See also: slaterdetset_delete_full() which does this.

Parameters:
sdset = pointer to SlaterDetSet to be de-allocated
Returns: none

Definition at line 306 of file slaterdset.cc.

References SlaterDetSet::alphastrings, SlaterDetSet::betastrings, SlaterDetSet::dets, and SlaterDetSet::size.

00307 {
00308   sdset->size = 0;
00309   if (sdset->dets) {
00310     free(sdset->dets);
00311     sdset->dets = NULL;
00312   }
00313   sdset->alphastrings = NULL;
00314   sdset->betastrings = NULL;
00315 }

void slaterdetset_delete_full ( SlaterDetSet sdset  ) 

slaterdetset_delete_full(): De-allocate a Slater Determinant Set.

Frees memory including alpha and beta strings. See slaterdetset_delete() for a similar version which does not free the alpha and beta strings.

Parameters:
sdset = pointer to SlaterDetSet to be de-allocated
Returns: none

Definition at line 329 of file slaterdset.cc.

References SlaterDetSet::alphastrings, SlaterDetSet::betastrings, SlaterDetSet::dets, SlaterDetSet::size, and stringset_delete().

Referenced by slaterdetvector_delete_full().

00330 {
00331   sdset->size = 0;
00332   if (sdset->dets) {
00333     free(sdset->dets);
00334     sdset->dets = NULL;
00335   }
00336   if (sdset->alphastrings) {
00337     stringset_delete(sdset->alphastrings);
00338     sdset->alphastrings = NULL;
00339   }
00340   if (sdset->betastrings) {
00341     stringset_delete(sdset->betastrings);
00342     sdset->betastrings = NULL;
00343   }
00344 }

void slaterdetset_init ( SlaterDetSet sdset,
int  size,
StringSet alphastrings,
StringSet betastrings 
)

slaterdetset_init(): Initialize a Slater Determinant Set

Parameters:
sdset = pointer to SlaterDetSet being initialized
size = number of SlaterDets to be held
alphastrings = pointer to StringSet of alpha strings
betastrings = pointer to StringSet of beta strings
Returns: none

Definition at line 285 of file slaterdset.cc.

References SlaterDetSet::alphastrings, SlaterDetSet::betastrings, SlaterDetSet::dets, and SlaterDetSet::size.

Referenced by slaterdetset_read().

00287 {
00288   sdset->size = size;
00289   sdset->dets = (SlaterDet *) malloc(size*sizeof(SlaterDet));
00290   memset(sdset->dets,0,size*sizeof(SlaterDet));
00291   sdset->alphastrings = alphastrings;
00292   sdset->betastrings = betastrings;
00293 }

void slaterdetset_read ( ULI  unit,
char *  prefix,
SlaterDetSet **  slaterdetset 
)

slaterdetset_read(): Read a Slater Determinant Set

Parameters:
unit = file number of the PSIO file
prefix = prefix string to come before libpsio entry keys
sdset = pointer to SlaterDetSet to read into
Returns: none

Definition at line 437 of file slaterdset.cc.

References SlaterDetSet::dets, psio_read_entry(), SlaterDetSet::size, slaterdetset_init(), and stringset_read().

Referenced by slaterdetvector_read().

00438 {
00439   int i, size;
00440   int need_to_init_psio = 0;
00441   int unit_opened = 1;
00442   char *size_key, *set_key;
00443   char *alphaprefix, *betaprefix;
00444   psio_address ptr;
00445   StringSet *alphastrings, *betastrings;
00446   SlaterDetSet *sdset = (SlaterDetSet *) malloc(sizeof(SlaterDetSet));
00447 
00448 PSIO_INIT
00449 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00450 
00451   alphaprefix = (char *) malloc( strlen(prefix) + 
00452     strlen(SDSET_KEY_ALPHASTRINGS) + 2);
00453   sprintf(alphaprefix,"%s:%s",prefix,SDSET_KEY_ALPHASTRINGS);
00454   betaprefix = (char *) malloc( strlen(prefix) + 
00455     strlen(SDSET_KEY_BETASTRINGS) + 2);
00456   sprintf(betaprefix,"%s:%s",prefix,SDSET_KEY_BETASTRINGS);
00457 
00458   stringset_read( unit, alphaprefix, &alphastrings);
00459   stringset_read( unit, betaprefix, &betastrings);
00460   
00461   free(alphaprefix);
00462   free(betaprefix);
00463 
00464   size_key = (char *) malloc( strlen(prefix) + strlen(SDSET_KEY_SIZE) + 3);
00465   sprintf(size_key,":%s:%s",prefix,SDSET_KEY_SIZE);
00466   set_key = (char *) malloc( strlen(prefix) + strlen(SDSET_KEY_DETERMINANTS) 
00467     + 3);
00468   sprintf(set_key,":%s:%s",prefix,SDSET_KEY_DETERMINANTS);
00469 
00470   psio_read_entry( unit, size_key, (char *)&size, sizeof(int));
00471   slaterdetset_init(sdset,size,alphastrings,betastrings);
00472   psio_read_entry( unit, set_key, (char *)sdset->dets, 
00473     sdset->size*sizeof(SlaterDet));
00474 
00475 PSIO_CLOSE(unit)
00476 PSIO_DONE
00477 
00478   free(size_key);
00479   free(set_key);
00480 
00481   *slaterdetset = sdset;
00482 }

void slaterdetset_read_vect ( ULI  unit,
char *  prefix,
double *  coeffs,
int  size,
int  vectnum 
)

slaterdetset_read_vect(): Read in the coefficients for a single vector associated with a SlaterDetSet.

This function already assumes we've already called slaterdetset_read() to read in the string and determinant information. This is only going to read in the coefficients. This has been split out because we might want to read several roots for a given determinant setup. This does not actually depend on the presence of a SlaterDetVector object and is called a SlaterDetSet function.

Parameters:
unit = file number of the UNINITIALIZED PSIO file
prefix = prefix string to come before libpsio entry keys
coeffs = array to hold coefficients read
size = number of elements in coeffs array
vectnum = the vector number (for the PSIO key). Start from 0.
Returns: none

CDS 8/03

Definition at line 733 of file slaterdset.cc.

References psio_read_entry().

Referenced by slaterdetvector_read().

00735 {
00736   int need_to_init_psio = 0;
00737   int unit_opened = 1;
00738   char *vector_key;
00739 
00740 PSIO_INIT
00741 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00742 
00743   vector_key = (char *) malloc(strlen(prefix)+strlen(SDVECTOR_KEY_VECTOR)+5);
00744   sprintf(vector_key,":%s:%s%2d",prefix,SDVECTOR_KEY_VECTOR,vectnum);
00745 
00746   psio_read_entry(unit, vector_key, (char *)coeffs, size*sizeof(double));
00747 
00748 PSIO_CLOSE(unit)
00749 PSIO_DONE
00750   
00751   free(vector_key);
00752 
00753 }

void slaterdetset_write ( ULI  unit,
char *  prefix,
SlaterDetSet sdset 
)

slaterdetset_write(): Write a Slater Determinant Set to disk.

Parameters:
unit = file number to write to
prefix = prefix string to come before libpsio entry keys
sdset = pointer to SlaterDetSet to write
Returns: none

Definition at line 385 of file slaterdset.cc.

References SlaterDetSet::alphastrings, SlaterDetSet::betastrings, SlaterDetSet::dets, psio_write_entry(), SlaterDetSet::size, and stringset_write().

Referenced by slaterdetvector_write().

00386 {
00387   int i;
00388   int need_to_init_psio = 0;
00389   int unit_opened = 1;
00390   char *size_key, *set_key;
00391   char *alphaprefix, *betaprefix;
00392   psio_address ptr;
00393 
00394 PSIO_INIT
00395 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00396 
00397   alphaprefix = (char *) malloc( strlen(prefix) + 
00398     strlen(SDSET_KEY_ALPHASTRINGS) + 2);
00399   sprintf(alphaprefix,"%s:%s",prefix,SDSET_KEY_ALPHASTRINGS);
00400   betaprefix = (char *) malloc( strlen(prefix) + 
00401     strlen(SDSET_KEY_BETASTRINGS) + 2);
00402   sprintf(betaprefix,"%s:%s",prefix,SDSET_KEY_BETASTRINGS);
00403 
00404   stringset_write( unit, alphaprefix, sdset->alphastrings);
00405   stringset_write( unit, betaprefix, sdset->betastrings);
00406   
00407   free(alphaprefix);
00408   free(betaprefix);
00409 
00410   size_key = (char *) malloc( strlen(prefix) + strlen(SDSET_KEY_SIZE) + 3);
00411   sprintf(size_key,":%s:%s",prefix,SDSET_KEY_SIZE);
00412   set_key = (char *) malloc( strlen(prefix) + strlen(SDSET_KEY_DETERMINANTS) 
00413     + 3);
00414   sprintf(set_key,":%s:%s",prefix,SDSET_KEY_DETERMINANTS);
00415 
00416   psio_write_entry( unit, size_key, (char *)&sdset->size, sizeof(int));
00417   psio_write_entry( unit, set_key, (char *)sdset->dets, 
00418     sdset->size*sizeof(SlaterDet));
00419 
00420 PSIO_CLOSE(unit)
00421 PSIO_DONE
00422 
00423   free(size_key);
00424   free(set_key);
00425 }

void slaterdetset_write_vect ( ULI  unit,
char *  prefix,
double *  coeffs,
int  size,
int  vectnum 
)

slaterdetset_write_vect(): Write to disk the coefficients for a single vector associated with a set of Slater determinants.

This function already assumes we've already called slaterdetset_write() to write out the string and determinant information. This is only going to write out the coefficients. This has been split out because we might want to write several roots for a given determinant setup. This does not actually dpend on the presence of a SlaterDetVector object so it is called a SlaterDetSet function.

Parameters:
unit = file number of the UNINITIALIZED PSIO file
prefix = prefix string to come before libpsio entry keys
coeffs = array of coefficients to write
size = number of elements in coeffs array
vectnum = the vector number (to make a PSIO key). Start numbering from zero.
Returns: none

CDS 8/03

Definition at line 647 of file slaterdset.cc.

References psio_write_entry().

Referenced by slaterdetvector_write().

00649 {
00650   int need_to_init_psio = 0;
00651   int unit_opened = 1;
00652   char *vector_key;
00653 
00654 PSIO_INIT
00655 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00656 
00657   if (vectnum < 0 || vectnum > 99) {
00658     fprintf(stderr, "(slaterdetset_write_vect): vectnum out of bounds\n");
00659     abort();
00660   }
00661 
00662   vector_key = (char *) malloc(strlen(prefix)+strlen(SDVECTOR_KEY_VECTOR)+5);
00663   sprintf(vector_key,":%s:%s%2d",prefix,SDVECTOR_KEY_VECTOR,vectnum);
00664 
00665   psio_write_entry(unit, vector_key, (char *)coeffs, size*sizeof(double));
00666 
00667 PSIO_CLOSE(unit)
00668 PSIO_DONE
00669 
00670   free(vector_key);
00671 }

void slaterdetvector_add ( SlaterDetVector sdvector,
int  index,
double  coeff 
)

slaterdetvector_add(): Add a coefficient to a SlaterDetVector

Parameters:
sdvector = Pointer to SlaterDetVector to add to
index = location in vector for writing the coefficient
coeff = the coefficient to write to location index
Returns: none

Definition at line 561 of file slaterdset.cc.

References SlaterDetVector::coeffs.

00562 {
00563   if (index < sdvector->size && index >= 0) {
00564     sdvector->coeffs[index] = coeff;
00565   }
00566 }

void slaterdetvector_delete ( SlaterDetVector sdvector  ) 

slaterdetvector_delete(): De-allocate a SlaterDetVector

Parameters:
sdvector = pointer to SlaterDetVector to de-allocate
Note: does NOT fully free the associated SlaterDetSet. For that, see function slaterdetvector_delete_full()

Returns: none

Definition at line 514 of file slaterdset.cc.

References SlaterDetVector::coeffs, SlaterDetVector::sdset, and SlaterDetVector::size.

00515 {
00516   sdvector->size = 0;
00517   sdvector->sdset = NULL;
00518   if (sdvector->coeffs) {
00519     free(sdvector->coeffs);
00520     sdvector->coeffs = NULL;
00521   }
00522 }

void slaterdetvector_delete_full ( SlaterDetVector sdvector  ) 

slaterdetvector_delete_full(): De-allocate a SlaterDetVector and its associated SlaterDetSet.

To keep the SlaterDetSet itself, use similar function slaterdetvector_delete().

Parameters:
sdvector = pointer to SlaterDetVector to delete
Returns: none

Definition at line 537 of file slaterdset.cc.

References SlaterDetVector::coeffs, SlaterDetVector::sdset, SlaterDetVector::size, and slaterdetset_delete_full().

00538 {
00539   sdvector->size = 0;
00540   if (sdvector->sdset) {
00541     slaterdetset_delete_full(sdvector->sdset);
00542     sdvector->sdset = NULL;
00543   }
00544   if (sdvector->coeffs) {
00545     free(sdvector->coeffs);
00546     sdvector->coeffs = NULL;
00547   }
00548 }

void slaterdetvector_init ( SlaterDetVector sdvector,
SlaterDetSet sdset 
)

slaterdetvector_init(): Initialize a vector of coefficients corresponding to a Slater Determinant set

Parameters:
sdvector = pointer to SlaterDetVector to initialize (coeffs member will be allocated)
sdset = pointer to SlaterDetSet the vector is associated with
Returns: none

Definition at line 496 of file slaterdset.cc.

References SlaterDetVector::coeffs, init_array(), SlaterDetVector::sdset, SlaterDetSet::size, and SlaterDetVector::size.

Referenced by slaterdetvector_read().

00497 {
00498   sdvector->size = sdset->size;
00499   sdvector->sdset = sdset;
00500   sdvector->coeffs = init_array(sdvector->size);
00501 }

void slaterdetvector_read ( ULI  unit,
char *  prefix,
SlaterDetVector **  sdvector 
)

slaterdetvector_read(): Read a SlaterDetVector from disk

Use this if we only need to read a single vector. Otherwise, call slaterdetset_read(); slaterdetset_read_vect(); to allow for multiple vectors per slaterdetset to be read from disk.

Parameters:
unit = file number to read from
prefix = prefix string to come before libpsio entry keys
sdvector = pointer to hold pointer to SlaterDetVector allocated by this function
Returns: none

Definition at line 690 of file slaterdset.cc.

References SlaterDetVector::coeffs, SlaterDetVector::size, slaterdetset_read(), slaterdetset_read_vect(), and slaterdetvector_init().

00691 {
00692   int need_to_init_psio = 0;
00693   int unit_opened = 1;
00694   SlaterDetSet *sdset;
00695   SlaterDetVector *vector = (SlaterDetVector *) malloc(sizeof(SlaterDetVector));
00696 
00697 PSIO_INIT
00698 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00699 
00700   slaterdetset_read(unit, prefix, &sdset);
00701   slaterdetvector_init(vector,sdset);
00702   slaterdetset_read_vect(unit, prefix, vector->coeffs, vector->size, 0);
00703 
00704 PSIO_CLOSE(unit)
00705 PSIO_DONE
00706   
00707   *sdvector = vector;
00708 }

void slaterdetvector_set ( SlaterDetVector sdvector,
double *  coeffs 
)

slaterdetvector_set(): Set a SlaterDetVector's vector to a set of coefficients supplied by array coeffs

Parameters:
sdvector = pointer to SlaterDetVector for writing coefficients
coeffs = array of coefficients to write to sdvector

Definition at line 578 of file slaterdset.cc.

References SlaterDetVector::coeffs, and SlaterDetVector::size.

00579 {
00580   int i;
00581   const int size = sdvector->size;
00582   double *v = sdvector->coeffs;
00583   if (v) {
00584     for(i=0; i<size; i++)
00585       v[i] = coeffs[i];
00586   }
00587 }

void slaterdetvector_write ( ULI  unit,
char *  prefix,
SlaterDetVector vector 
)

slaterdetvector_write(): Write a SlaterDetVector to disk.

This writes a vector in the space of Slater determinants, along with the set of determinants itself, to a PSIO file.

Use this if we only need to write a single vector. Otherwise, call slaterdetset_write(); slaterdetset_write_vect(); to allow for multiple vectors per slaterdetset to be written to disk.

Parameters:
unit = file number of the UNINITIALIZED PSIO file
prefix = prefix string to come before libpsio entry keys
vector = SlaterDetVector to write to disk
Returns: none

Definition at line 607 of file slaterdset.cc.

References SlaterDetVector::coeffs, SlaterDetVector::sdset, SlaterDetVector::size, slaterdetset_write(), and slaterdetset_write_vect().

00608 {
00609   int need_to_init_psio = 0;
00610   int unit_opened = 1;
00611 
00612 PSIO_INIT
00613 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00614 
00615   slaterdetset_write(unit, prefix, vector->sdset);
00616   slaterdetset_write_vect(unit, prefix, vector->coeffs, vector->size, 0);
00617 
00618 PSIO_CLOSE(unit)
00619 PSIO_DONE
00620 
00621 }

void solve_2x2_pep ( double **  H,
double  S,
double *  evals,
double **  evecs 
)

solve_2x2_pep(): Solve a 2x2 pseudo-eigenvalue problem of the form [ H11 - E H12 - E*S ] [c1] [ H12 - E*S H22 - E ] [c2] = 0

Parameters:
H = matrix to get eigenvalues of
S = overlap between states 1 & 2
evals = pointer to array to hold 2 eigenvalues
evecs = matrix to hold 2 eigenvectors
Returns: none

Definition at line 28 of file solve_pep.cc.

00029 {
00030    int i ;
00031    double a, b, c, p, q, x ;
00032    double norm, tval, tval2; 
00033 
00034    /* put in quadratic form */
00035    a = 1.0 - S * S ;
00036    b = 2.0 * S * H[0][1] - H[0][0] - H[1][1] ;
00037    c = H[0][0] * H[1][1] - H[0][1] * H[0][1] ; 
00038   
00039    /* solve the quadratic equation for E0 and E1 */
00040 
00041    tval = b*b ;
00042    tval -= 4.0 * a * c ;
00043    tval2 = sqrt(tval) ;
00044    if (tval < 0.0) {
00045       fprintf(stderr, "(solve_2x2_pep): radical less than 0\n") ;
00046       return ;
00047       }
00048    else if (fabs(a) < A_MIN) {
00049       printf("min a reached\n") ;
00050       evals[0] = evals[1] = H[1][1] ;
00051       }
00052    else { 
00053       evals[0] = -b / (2.0 * a) ;
00054       evals[0] -= tval2 / (2.0 * a) ; 
00055       evals[1] = -b / (2.0 * a) ;
00056       evals[1] += tval2 / (2.0 * a) ;
00057       }
00058  
00059    /* Make sure evals[0] < evals[1] */
00060    if (evals[1] < evals[0]) { 
00061       tval = evals[0] ;  
00062       evals[0] = evals[1] ;
00063       evals[1] = tval ;
00064       } 
00065 
00066    /* Make sure evals[0] < H[1][1] */
00067    if (evals[0] > H[1][1]) {
00068       printf("Warning: using H11 as eigenvalues\n") ;
00069       evals[0] = evals[1] = H[1][1] ;
00070       printf("Got evals[0] = H[1][1] = %12.7f\n", evals[0]) ;
00071       }
00072 
00073    /* get the eigenvectors */
00074    for (i=0; i<2; i++) {
00075       p = H[0][0] - evals[i] ;
00076       q = H[0][1] - S * evals[i] ;
00077       x = -p/q ; 
00078       norm = 1.0 + x * x ;
00079       norm = sqrt(norm) ;
00080       evecs[i][0] = 1.0 / norm ;
00081       evecs[i][1] = x / norm ;
00082       }
00083 
00084    /* test 
00085    for (i=0; i<2; i++) {
00086       p = H[i][0] * evecs[0][0] + H[i][1] * evecs[0][1] ;
00087       if (i==0) q = evecs[0][0] + S * evecs[0][1] ;
00088       else q = S * evecs[0][0] + evecs[0][1] ;
00089       q *= evals[0] ;
00090       printf("2x2 check %d: LHS = %12.6f  RHS = %12.6f\n", i, p, q) ;
00091       }
00092     */
00093 
00094 }

void sort_vector ( double *  A,
int  n 
)

sort_vector(): Sort the elements of a vector into increasing order

Parameters:
A = array to sort
n = length of array
Returns: none

Definition at line 55 of file lib/libqt/sort.cc.

00056 {
00057   int i, j, k;
00058   double val;
00059 
00060   for(i=0; i < n-1; i++) {
00061     val = A[k=i];
00062 
00063     for(j=i+1; j < n; j++)
00064       if(A[j] <= val) val = A[k=j];
00065 
00066     if(k != i) {
00067       A[k] = A[i];
00068       A[i] = val;
00069     }
00070   }
00071 }

void stringset_add ( StringSet sset,
int  index,
unsigned char *  Occ 
)

stringset_add(): Add a string (in Pitzer order, given by Occ) to the StringSet, writing to position index.

Parameters:
sset = StringSet to add to
index = location in StringSet to add to
Occ = orbital occupations (Pitzer order) of the string to add
Returns: none

Definition at line 98 of file slaterdset.cc.

References String::index, StringSet::nelec, StringSet::nfzc, String::occ, and StringSet::strings.

00099 {
00100   int i;
00101   int nact = sset->nelec - sset->nfzc;
00102   String *s;
00103 
00104   if (index < sset->size && index >= 0) {
00105     s = sset->strings + index;
00106   }
00107   s->index = index;
00108   s->occ = (short int*) malloc(nact*sizeof(short int));
00109   for(i=0;i<nact;i++)
00110     s->occ[i] = Occ[i];
00111 }

void stringset_delete ( StringSet sset  ) 

stringset_delete(): Delete a StringSet

Parameters:
sset = pointer to StringSet to delete
Returns: none

Definition at line 77 of file slaterdset.cc.

References StringSet::fzc_occ, StringSet::nelec, StringSet::nfzc, StringSet::size, and StringSet::strings.

Referenced by slaterdetset_delete_full().

00078 {
00079   if (sset->nfzc > 0) free(sset->fzc_occ);
00080   sset->size = 0;
00081   sset->nelec = 0;
00082   sset->nfzc = 0;
00083   if (sset->strings) free(sset->strings);
00084   sset->strings = NULL;
00085 }

void stringset_init ( StringSet sset,
int  size,
int  nelec,
int  nfzc,
short int *  frozen_occ 
)

stringset_init(): Initialize a set of alpha/beta strings

Parameters:
sset = pointer to StringSet (contains occs in Pitzer order)
size = number of strings
nelec = number of electrons
nfzc = number of frozen core orbitals
frozen_occ = array of frozen occupied orbitals (Pitzer numbering!)
Returns: none

Definition at line 49 of file slaterdset.cc.

References StringSet::fzc_occ, StringSet::nelec, StringSet::nfzc, StringSet::size, and StringSet::strings.

Referenced by stringset_read().

00051 {
00052   int i;
00053 
00054   sset->size = size;
00055   sset->nelec = nelec;
00056   sset->nfzc = nfzc;
00057   sset->strings = (String *) malloc(size*sizeof(String));
00058   memset(sset->strings,0,size*sizeof(String));
00059   if (nfzc > 0) {
00060     sset->fzc_occ = (short int *) malloc(nfzc * sizeof(short int));
00061     for (i=0; i<nfzc; i++) {
00062       sset->fzc_occ[i] = frozen_occ[i];  
00063     }
00064   }
00065 }

void stringset_read ( ULI  unit,
char *  prefix,
StringSet **  stringset 
)

stringset_read(): Read a StringSet from disk

Parameters:
unit = file number to read from
prefix = prefix string to come before libpsio entry keys
stringset = double pointer to StringSet allocated by this function
Returns: none

Definition at line 213 of file slaterdset.cc.

References String::index, String::occ, psio_read(), psio_read_entry(), PSIO_ZERO, StringSet::strings, and stringset_init().

Referenced by slaterdetset_read().

00214 {
00215   int i, size, nelec, nfzc, nact;
00216   int need_to_init_psio = 0;
00217   int unit_opened = 1;
00218   char *size_key, *nelec_key, *nfzc_key, *fzc_occ_key, *strings_key;
00219   short int *fzc_occ;
00220   psio_address ptr;
00221   StringSet *sset = (StringSet *) malloc(sizeof(StringSet));
00222 
00223 PSIO_INIT
00224 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00225 
00226   size_key = (char *) malloc( strlen(prefix) + strlen(STRINGSET_KEY_SIZE) + 3);
00227   sprintf(size_key,":%s:%s",prefix,STRINGSET_KEY_SIZE);
00228   nelec_key = (char *) malloc( strlen(prefix) + strlen(STRINGSET_KEY_NELEC)+ 3);
00229   sprintf(nelec_key,":%s:%s",prefix,STRINGSET_KEY_NELEC);
00230   nfzc_key = (char *) malloc( strlen(prefix) + strlen(STRINGSET_KEY_NFZC) + 3);
00231   sprintf(nfzc_key,":%s:%s",prefix,STRINGSET_KEY_NFZC);
00232   fzc_occ_key = (char *) malloc(strlen(prefix) +
00233     strlen(STRINGSET_KEY_FZC_OCC) + 3);
00234   sprintf(fzc_occ_key,":%s:%s",prefix,STRINGSET_KEY_FZC_OCC);
00235   strings_key = (char *) malloc( strlen(prefix) + strlen(STRINGSET_KEY_STRINGS)
00236     + 3);
00237   sprintf(strings_key,":%s:%s",prefix,STRINGSET_KEY_STRINGS);
00238 
00239   psio_read_entry( unit, size_key, (char *)&size, sizeof(int));
00240   psio_read_entry( unit, nelec_key, (char *)&nelec, sizeof(int));
00241   psio_read_entry( unit, nfzc_key, (char *)&nfzc, sizeof(int));
00242   if (nfzc > 0) {
00243     fzc_occ = (short int *) malloc(nfzc*sizeof(short int));
00244     psio_read_entry( unit, fzc_occ_key, (char *)fzc_occ, 
00245       nfzc*sizeof(short int));
00246   }
00247   else fzc_occ = NULL;
00248 
00249   stringset_init(sset, size, nelec, nfzc, fzc_occ);
00250 
00251   nact = nelec - nfzc;
00252   ptr = PSIO_ZERO;
00253   for(i=0; i<size; i++) {
00254     psio_read( unit, strings_key, (char *) &(sset->strings[i].index), 
00255       sizeof(int), ptr, &ptr);
00256     sset->strings[i].occ = (short int*) malloc(nact*sizeof(short int));
00257     psio_read( unit, strings_key, (char *) sset->strings[i].occ, 
00258       nact*sizeof(short int), ptr, &ptr);
00259   }
00260 
00261 PSIO_CLOSE(unit)
00262 PSIO_DONE
00263 
00264   free(size_key);
00265   free(nelec_key);
00266   free(nfzc_key);
00267   free(fzc_occ_key);
00268   free(strings_key);
00269   if (nfzc > 0) free(fzc_occ);
00270   *stringset = sset;
00271 }

void stringset_reindex ( StringSet sset,
short int *  mo_map 
)

stringset_reindex(): Remap orbital occupations from one ordering to another.

Parameters:
sset = pointer to StringSet
mo_map = mapping array from original orbital order to new order
Returns: none

Definition at line 123 of file slaterdset.cc.

References StringSet::fzc_occ, StringSet::nelec, StringSet::nfzc, StringSet::size, and StringSet::strings.

00124 {
00125   int s, mo, core;
00126   short int* occ;
00127   int nstrings = sset->size;
00128   int nact = sset->nelec - sset->nfzc;
00129 
00130   for (core=0; core<sset->nfzc; core++) {
00131     sset->fzc_occ[core] = mo_map[sset->fzc_occ[core]];
00132   }
00133 
00134   for(s=0; s<nstrings; s++) {
00135     occ = (sset->strings + s)->occ;
00136     for(mo=0; mo<nact; mo++)
00137       occ[mo] = mo_map[occ[mo]];
00138   }
00139 }

void stringset_write ( ULI  unit,
char *  prefix,
StringSet sset 
)

stringset_write(): Write a stringset to a PSI file

Parameters:
unit = file number to write to
prefix = prefix string to come before libpsio entry keys
sset = pointer to StringSet to write
Returns: none

Definition at line 151 of file slaterdset.cc.

References StringSet::fzc_occ, String::index, StringSet::nelec, StringSet::nfzc, String::occ, psio_write(), psio_write_entry(), PSIO_ZERO, StringSet::size, and StringSet::strings.

Referenced by slaterdetset_write().

00152 {
00153   int i, size, nact;
00154   int need_to_init_psio = 0;
00155   int unit_opened = 1;
00156   char *size_key, *nelec_key, *nfzc_key, *strings_key, *fzc_occ_key;
00157   psio_address ptr;
00158 
00159 PSIO_INIT
00160 PSIO_OPEN(unit,PSIO_OPEN_OLD)
00161 
00162   size_key = (char *) malloc(strlen(prefix) + strlen(STRINGSET_KEY_SIZE) + 3);
00163   sprintf(size_key,":%s:%s",prefix,STRINGSET_KEY_SIZE);
00164   nelec_key = (char *) malloc(strlen(prefix) + strlen(STRINGSET_KEY_NELEC) + 3);
00165   sprintf(nelec_key,":%s:%s",prefix,STRINGSET_KEY_NELEC);
00166   nfzc_key = (char *) malloc(strlen(prefix) + strlen(STRINGSET_KEY_NFZC) + 3);
00167   sprintf(nfzc_key,":%s:%s",prefix,STRINGSET_KEY_NFZC);
00168   fzc_occ_key = (char *) malloc(strlen(prefix) +
00169     strlen(STRINGSET_KEY_FZC_OCC) + 3);
00170   sprintf(fzc_occ_key,":%s:%s",prefix,STRINGSET_KEY_FZC_OCC);
00171   strings_key = (char *) malloc(strlen(prefix) + strlen(STRINGSET_KEY_STRINGS) + 3);
00172   sprintf(strings_key,":%s:%s",prefix,STRINGSET_KEY_STRINGS);
00173 
00174   psio_write_entry( unit, size_key, (char *)&sset->size, sizeof(int));
00175   psio_write_entry( unit, nelec_key, (char *)&sset->nelec, sizeof(int));
00176   psio_write_entry( unit, nfzc_key, (char *)&sset->nfzc, sizeof(int));
00177   if (sset->nfzc) {
00178     psio_write_entry( unit, fzc_occ_key, (char *)sset->fzc_occ, 
00179       sset->nfzc*sizeof(short int));
00180   }
00181 
00182   ptr = PSIO_ZERO;
00183   size = sset->size;
00184   nact = sset->nelec - sset->nfzc;
00185   for(i=0; i<size; i++) {
00186     psio_write( unit, strings_key, (char *) &(sset->strings[i].index), 
00187       sizeof(int), ptr, &ptr);
00188     psio_write( unit, strings_key, (char *) sset->strings[i].occ, 
00189       nact*sizeof(short int), ptr, &ptr);
00190   }
00191 
00192 PSIO_CLOSE(unit)
00193 PSIO_DONE
00194 
00195   free(size_key);
00196   free(nelec_key);
00197   free(nfzc_key);
00198   free(strings_key);
00199   free(fzc_occ_key);
00200 }

void timer_done ( void   ) 

timer_done(): Close down all timers and write results to timer.dat

Definition at line 91 of file timer.cc.

References ffile().

Referenced by main().

00092 {
00093   FILE *timer_out;
00094   char *host;
00095   extern time_t timer_start, timer_end;
00096   struct timer *this_timer, *next_timer;
00097   extern struct timer *global_timer;
00098 
00099   timer_end = time(NULL);
00100 
00101   host = (char *) malloc(40 * sizeof(char));
00102   gethostname(host, 40);
00103 
00104   /* Dump the timing data to timer.dat and free the timers */
00105   ffile(&timer_out, "timer.dat", 1);
00106   fprintf(timer_out, "\n");
00107   fprintf(timer_out, "Host: %s\n", host);
00108   fprintf(timer_out, "\n");
00109   fprintf(timer_out, "Timers On : %s", ctime(&timer_start));
00110   fprintf(timer_out, "Timers Off: %s", ctime(&timer_end));
00111   fprintf(timer_out, "\nWall Time:  %10.2f seconds\n\n",
00112           (double) timer_end - timer_start);
00113 
00114   this_timer = global_timer;
00115   while(this_timer != NULL) {
00116       if(this_timer->calls > 1) 
00117           fprintf(timer_out, "%-12s: %10.2fu %10.2fs %10.2fw %6d calls\n",
00118                   this_timer->key, this_timer->utime, this_timer->stime,
00119                   this_timer->wtime, this_timer->calls);
00120       else if(this_timer->calls == 1)
00121           fprintf(timer_out, "%-12s: %10.2fu %10.2fs %10.2fw %6d call\n",
00122                   this_timer->key, this_timer->utime, this_timer->stime,
00123                   this_timer->wtime, this_timer->calls);
00124       next_timer = this_timer->next;
00125       free(this_timer);
00126       this_timer = next_timer;
00127     }
00128 
00129   fprintf(timer_out, 
00130           "\n***********************************************************\n");
00131   fclose(timer_out);
00132 
00133   free(host);
00134 }

void timer_init ( void   ) 

timer_init(): Initialize the linked list of timers

Definition at line 76 of file timer.cc.

Referenced by main().

00077 {
00078   extern struct timer *global_timer;
00079   extern time_t timer_start;
00080 
00081   timer_start = time(NULL);
00082 
00083   global_timer = NULL;
00084 }

void timer_off ( char *  key  ) 

timer_off(): Turn off the timer with the name given as an argument. Can be turned on and off, time will accumulate while on.

Parameters:
key = Name of timer

Definition at line 229 of file timer.cc.

References timer_scan().

Referenced by dpd_buf4_scm(), and main().

00230 {
00231   struct tms ontime, offtime;
00232   struct timer *this_timer;
00233   time_t wall_stop;
00234 
00235   this_timer = timer_scan(key);
00236 
00237   if(this_timer == NULL) {
00238       fprintf(stderr, "Bad timer key: %s\n", key);
00239       exit(PSI_RETURN_FAILURE);
00240     }
00241 
00242   if(this_timer->status == TIMER_OFF) {
00243      fprintf(stderr, "Timer %s is already off.\n", this_timer->key);
00244      exit(PSI_RETURN_FAILURE);
00245     }
00246 
00247   ontime = this_timer->ontime;
00248 
00249   times(&offtime);
00250 
00251   this_timer->utime += ((double) (offtime.tms_utime-ontime.tms_utime))/HZ;
00252   this_timer->stime += ((double) (offtime.tms_stime-ontime.tms_stime))/HZ;
00253 
00254   wall_stop = time(NULL);
00255   this_timer->wtime += ((double) (wall_stop - this_timer->wall_start));
00256 
00257   this_timer->status = TIMER_OFF;
00258 }

void timer_on ( char *  key  ) 

timer_on(): Turn on the timer with the name given as an argument. Can be turned on and off, time will accumulate while on.

Parameters:
key = Name of timer

Definition at line 189 of file timer.cc.

References timer_scan().

Referenced by dpd_buf4_scm(), and main().

00190 {
00191   struct timer *this_timer;
00192 
00193   this_timer = timer_scan(key);
00194 
00195   if(this_timer == NULL) { /* New timer */
00196       this_timer = (struct timer *) malloc(sizeof(struct timer));
00197       strcpy(this_timer->key,key);
00198       this_timer->calls = 0;
00199       this_timer->utime = 0;
00200       this_timer->stime = 0;
00201       this_timer->wtime = 0;
00202       this_timer->next = NULL;
00203       this_timer->last = timer_last();
00204       if(this_timer->last != NULL) this_timer->last->next = this_timer;
00205       else global_timer = this_timer;
00206     }
00207   else {
00208     if((this_timer->status == TIMER_ON) && (this_timer->calls)) {
00209         fprintf(stderr, "Timer %s is already on.\n", key);
00210         exit(PSI_RETURN_FAILURE);
00211     }
00212   }
00213 
00214   this_timer->status = TIMER_ON;
00215   this_timer->calls++;
00216   
00217   times(&(this_timer->ontime));
00218   this_timer->wall_start = time(NULL);
00219 }

struct timer* timer_scan ( char *  key  )  [read]

timer_scan(): Return a timer structure whose name matches that given by supplied string

Parameters:
key = name of timer to search for
Returns: the timer structure with the given name, else NULL

Definition at line 145 of file timer.cc.

Referenced by timer_off(), and timer_on().

00146 {
00147   extern struct timer *global_timer;
00148   struct timer *this_timer;
00149 
00150   this_timer = global_timer;
00151   
00152   while(this_timer != NULL) {
00153       if(!strcmp(this_timer->key,key)) return(this_timer);
00154       this_timer = this_timer->next;
00155     }
00156 
00157   return(this_timer);
00158 }


Generated on Wed Feb 13 16:36:14 2008 for PSI by  doxygen 1.5.4