/***********************************************************//** * Compute the points and weights of Gauss-Hermite quadrature * * \param[in] N - number of elements * \param[in,out] pts - quadrature nodes (space already alloc) * \param[in,out] weights - weights (space alread alloc) * * \return 0 if successful * \note * weight function is \f$ w(x) = \frac{1}{\sqrt{2\pi}}e^{-x^2/2}\f$ *************************************************************/ int gauss_hermite(size_t N, double * pts, double * weights){ size_t ii; double * offdiag = calloc_double(N); double * evec = calloc_double(N*N); double * work = calloc_double(2*N-2); int info; for (ii = 0; ii < N; ii++){ pts[ii] = 0.0; offdiag[ii] = sqrt((double)(ii+1)); } int M = N; int M2 = N; dstev_("V", &M, pts, offdiag, evec, &M2, work, &info); if ( info > 0) { fprintf(stderr, "Gauss-Hermite quadrature failed because eigenvalues did not converge \n"); exit(1); } else if ( info < 0) { fprintf(stderr, "The %d-th argument of dstev_ has an illegal value",info); exit(1); } for (ii = 0; ii < N; ii++){ weights[ii] = evec[ii*N] * evec[ii*N];// * sqrt(2*M_PI); } free(offdiag); offdiag = NULL; free(evec); evec = NULL; free(work); work = NULL; return info; }
/***********************************************************//** * Compute the points and weights of Gauss-Legendre quadrature * * \param[in] N - number of elements * \param[in,out] pts - quadrature nodes (space already alloc) * \param[in,out] weights - weights (space alread alloc) * * \note * Here the quadrature and the points are computed * assuming a weight function of .5. Thus it will differ * from some results online because the weights computed * here will be half of the weights computed with a weight * function of 1 *************************************************************/ void gauss_legendre(size_t N, double * pts, double * weights){ //* if (N == 1){ pts[0] = 0.0; weights[0] = 1.0; } else if (N < 200){ getLegPtsWts(N,pts,weights); //size_t ii; //for (ii = 0; ii < N; ii++){ // weights[ii] /= 2.0; //} } else{ size_t ii; double temp; double * offdiag = calloc_double(N); double * evec = calloc_double(N*N); double * work = calloc_double(2*N-2); int info; for (ii = 0; ii < N; ii++){ pts[ii] = 0.0; temp = (double)ii + 1.0; //temp = (double)ii; offdiag[ii] = temp / sqrt( (2.0 * temp + 1.0) * (2.0 * temp -1.0) ); //offdiag[ii] = 0.5 / sqrt( 1.0 - pow(2.0 * temp, -2.0)); //offdiag[ii] = temp / sqrt((2.0 * temp +1.0)); } int M = N; int M2 = N; dstev_("V", &M, pts, offdiag, evec, &M2, work, &info); if ( info > 0) { fprintf(stderr, "Gauss-Hermite quadrature failed because eigenvalues did not converge \n"); exit(1); } else if ( info < 0) { fprintf(stderr, "The %d-th argument of dstev_ has an illegal value",info); exit(1); } for (ii = 0; ii < N; ii++){ //weights[ii] = evec[N*N-2 + ii] * evec[N*N-2 + ii]; //weights[ii] = evec[N*N-2 + ii] * evec[N*N-2 + ii]; //weights[ii] = 2.0* evec[ii] * evec[ii]; weights[ii] = evec[ii*N] * evec[ii*N]; } free(offdiag); offdiag = NULL; free(evec); evec = NULL; free(work); work = NULL; } }
void calc_eigenvalues(struct ed_s *ed, unsigned iter) { int n, ldz, info; char* job = "N"; n = iter + 1; ldz = 1; memcpy(ed->d, ed->alpha, sizeof(double) * (iter + 1)); memcpy(ed->e, ed->beta + 1, sizeof(double) * iter); dstev_("N", &n, ed->d, ed->e, NULL, &ldz, NULL, &info); // assert(info == 0); }