pomp
Inference for partially observed Markov processes
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
synth_lik.c File Reference
#include "internal.h"
#include "pomp_mat.h"
Include dependency graph for synth_lik.c:

Go to the source code of this file.

Functions

static void robust_synth_loglik (double *y, int *dim, double *ydat, double *loglik)
 
SEXP synth_loglik (SEXP ysim, SEXP ydat)
 

Function Documentation

◆ robust_synth_loglik()

static void robust_synth_loglik ( double *  y,
int *  dim,
double *  ydat,
double *  loglik 
)
static

Definition at line 11 of file synth_lik.c.

11 {
12 // 'ydat' is destroyed
13 // 'y' is preserved
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); // #nocov
31
32 // compute column means, center each column, precondition
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; // center the column
38 for (x = 0, i = 0; i < nrow; i++) x += yp[i]*yp[i];
39 d = sqrt(x/(nrow-1)); // column SD
40 for (i = 0; i < nrow; i++) yp[i] /= d; // precondition
41 }
42
43 // do first QR decomposition & backsolve
44 memcpy(y2,y1,nrow*ncol*sizeof(double));
45 // LAPACK QR decomposition without pivoting DGEQR2(M,N,A,LDA,TAU,WORK,INFO)
46 F77_CALL(dgeqr2)(&nrow,&ncol,y2,&nrow,tau,work,&info);
47 // Level-3 BLAS triangular matrix solver DTRSM(SIDE,UPLO,TRANS,DIAG,M,N,ALPHA,A,LDA,B,LDB)
48 F77_CALL(dtrsm)("right","upper","no transpose","non-unit",&nrow,&ncol,&one,y2,&nrow,y1,&nrow FCONE FCONE FCONE FCONE);
49
50 // create Campbell weight vector
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); // Mahalonobis distance of row i
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 // compute weighted column means, center each column, precondition
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; // column mean
77 for (i = 0; i < nrow; i++) yp[i] -= xx; // center the column
78 ydat[j] -= xx; // subtract mean from realized probe
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)); // column SD
84 for (i = 0; i < nrow; i++) yp[i] *= (w[i]/d); // precondition & weight
85 ydat[j] /= d;
86 half_log_det += log(d); // sum up logs(diag(D))
87 }
88
89 // do second QR decomposition & backsolve
90 // LAPACK QR decomposition without pivoting DGEQR2(M,N,A,LDA,TAU,WORK,INFO)
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 // compute residual sum of squares and add up logs of diag(R)
95 for (yp = y1, rss = 0, i = nrow+1, j = 0; j < ncol; j++, yp += i) { // yp marches along the diagonal of R
96 x = ydat[j];
97 rss += x*x;
98 half_log_det += log(fabs(*yp)); // log(diag(R))
99 }
100
101 *loglik = -0.5*rss-half_log_det;
102}
#define tau
Definition gompertz.c:94
#define err(...)
Definition pomp.h:21
#define FCONE
Definition pomp_mat.h:7
static R_INLINE void pomp_backsolve(double *a, int lda, int n, double *x, int incx, char *uplo, char *transpose, char *unit)
Definition pomp_mat.h:12
Here is the call graph for this function:
Here is the caller graph for this function:

◆ synth_loglik()

SEXP synth_loglik ( SEXP  ysim,
SEXP  ydat 
)

Definition at line 104 of file synth_lik.c.

104 {
105 SEXP loglik, dim, y;
106
107 PROTECT(y = duplicate(AS_NUMERIC(ydat)));
108 PROTECT(dim = GET_DIM(ysim));
109 PROTECT(ysim = AS_NUMERIC(ysim));
110 PROTECT(loglik = NEW_NUMERIC(1));
111
112 robust_synth_loglik(REAL(ysim),INTEGER(dim),REAL(y),REAL(loglik));
113
114 UNPROTECT(4);
115 return loglik;
116}
static void robust_synth_loglik(double *y, int *dim, double *ydat, double *loglik)
Definition synth_lik.c:11
Here is the call graph for this function: