11 {
12
13
14 int nrow = dim[0];
15 int ncol = dim[1];
16 double w[nrow],
tau[ncol], work[ncol];
17 int info = 0;
18 double one = 1.0;
19 double *y1, *y2, *yp;
20 long double x, xx, wbar, d, d0, rss, half_log_det;
21 long double alpha = 2.0, beta = 1.25;
22 int i, j;
23
24 half_log_det = ncol*M_LN_SQRT_2PI;
25
26 y1 = (double *) R_alloc(nrow*ncol,sizeof(double));
27 y2 = (double *) R_alloc(nrow*ncol,sizeof(double));
28
29 if (nrow <= ncol)
30 err(
"'nsim' (=%d) should be (much) larger than the number of probes (=%d)",nrow,ncol);
31
32
33 memcpy(y1,y,nrow*ncol*sizeof(double));
34 for (yp = y1, j = 0; j < ncol; j++, yp += nrow) {
35 for (x = 0, i = 0; i < nrow; i++) x += yp[i];
36 x /= nrow;
37 for (i = 0; i < nrow; i++) yp[i] -= x;
38 for (x = 0, i = 0; i < nrow; i++) x += yp[i]*yp[i];
39 d = sqrt(x/(nrow-1));
40 for (i = 0; i < nrow; i++) yp[i] /= d;
41 }
42
43
44 memcpy(y2,y1,nrow*ncol*sizeof(double));
45
46 F77_CALL(dgeqr2)(&nrow,&ncol,y2,&nrow,
tau,work,&info);
47
48 F77_CALL(dtrsm)(
"right",
"upper",
"no transpose",
"non-unit",&nrow,&ncol,&one,y2,&nrow,y1,&nrow
FCONE FCONE FCONE FCONE);
49
50
51 d0 = sqrt(ncol)+alpha/sqrt(2.0);
52 for (wbar = 0, i = 0; i < nrow; i++) {
53 for (xx = 0, j = 0; j < ncol; j++) {
54 x = y1[i+nrow*j];
55 xx += x*x;
56 }
57 d = sqrt((nrow-1)*xx);
58 if (d > d0) {
59 x = d-d0;
60 xx = exp(-0.5*x*x/beta)*d0/d;
61 } else {
62 xx = 1.0;
63 }
64 w[i] = xx;
65 wbar += xx*xx;
66 }
67 wbar = sqrt(wbar-1);
68
69
70 memcpy(y1,y,nrow*ncol*sizeof(double));
71 for (yp = y1, j = 0; j < ncol; j++, yp += nrow) {
72 for (x = 0, xx = 0, i = 0; i < nrow; i++) {
73 x += w[i];
74 xx += w[i]*yp[i];
75 }
76 xx /= x;
77 for (i = 0; i < nrow; i++) yp[i] -= xx;
78 ydat[j] -= xx;
79 for (xx = 0, i = 0; i < nrow; i++) {
80 xx += yp[i]*yp[i];
81 yp[i] /= wbar;
82 }
83 d = sqrt(xx/(nrow-1));
84 for (i = 0; i < nrow; i++) yp[i] *= (w[i]/d);
85 ydat[j] /= d;
86 half_log_det += log(d);
87 }
88
89
90
91 F77_CALL(dgeqr2)(&nrow,&ncol,y1,&nrow,
tau,work,&info);
92 pomp_backsolve(y1,nrow,ncol,ydat,1,
"upper",
"transpose",
"non-unit");
93
94
95 for (yp = y1, rss = 0, i = nrow+1, j = 0; j < ncol; j++, yp += i) {
96 x = ydat[j];
97 rss += x*x;
98 half_log_det += log(fabs(*yp));
99 }
100
101 *loglik = -0.5*rss-half_log_det;
102}
static R_INLINE void pomp_backsolve(double *a, int lda, int n, double *x, int incx, char *uplo, char *transpose, char *unit)