double dlmvnorm_singular(double *x, int p, double *mu, double *LTsigma) { /* Calculates the p-variate Gaussian log-density at the p-variate point x with mean mu and the lower triangle (px(p+1)/2) LTsigma of the pxp-dimensional dispersion matrix Sigma. Note that this function actually incorporates the case for singular determinants */ double *eivec,*eival,value=0; int i,ind=0; MAKE_VECTOR(eivec,p*p); MAKE_VECTOR(eival,p); i=eigens(LTsigma,eivec,eival,p); if (eival[0]==0) { /* only possible if LTsigma is all zero, which means that the distribution is degenerate at mu */ for(i=0;((i<p) && (!ind));i++) if (x[i]!=mu[i]) ind =1; if (ind) value=-Inf; else value=0; } else { int j,dmin; double *y,*z,sum=0,sump=0; for(i=0;i<p;i++) sum+=eival[i]; for(i=0;((i<p) && (sump<0.99));i++) { sump+=eival[i]/sum; value-=0.5*log(eival[i]); } dmin=i; MAKE_VECTOR(y,p); for(i=0;i<p;i++) y[i]=x[i]-mu[i]; MAKE_VECTOR(z,dmin); for(i=0;i<dmin;i++) z[i]=0; for(i=0;i<dmin;i++) { for(j=0;j<p;j++) z[i]+=eivec[j*p+i]*y[j]; } FREE_VECTOR(y); for(i=0;i<dmin;i++) value-=0.5*z[i]*z[i]/eival[i]; FREE_VECTOR(z); value-=0.5*dmin*log(2*PI); } FREE_VECTOR(eival); FREE_VECTOR(eivec); return value; }
/** * \ingroup eigen * Eigenvectors * \param m \f$m\f$ * \return a variable matrix with the * eigenvectors of \f$m\f$ stored in its columns. */ dmatrix eigenvectors(const dmatrix &m) { if (m.rowsize() != m.colsize()) { cerr << "error -- non square matrix passed to dmatrix eigenvectors(const dmatrix& m)\n"; ad_exit(1); } int rmin = m.rowmin(); int rmax = m.rowmax(); dmatrix evecs(rmin, rmax, rmin, rmax); dvector evals(rmin, rmax); eigens(m, evecs, evals); return evecs; }
int main() { int testCount = 1; int p = 1; int low = -10; int high = 10; int fails = 0; double eps = 1e-8; for (int n = 2; n <= pow(2, p); n *= 2) { for (int i = 0; i < testCount; i++) { Mat_DP A(n, n); Vec_CPLX_DP eigens(n); ranmat2(A, low, high); eigen(A, eigens); if(testSum(&A, &eigens, eps)){ fails++; cout << "FAIL! n = " << n << endl; } } } }