pomp
Inference for partially observed Markov processes
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
probe_marginal.c
Go to the documentation of this file.
1// -*- mode: C++ -*-
2
3#include "internal.h"
4#include "pomp_mat.h"
5#include <stdio.h>
6
7static void order_reg_solve (double *beta, double *x, double *mm, double *tau, int *pivot, int n, int np, int diff);
8static void order_reg_model_matrix (double *z, double *X, double *tau, int *pivot, int n, int np, int diff);
9
10SEXP probe_marginal_setup (SEXP ref, SEXP order, SEXP diff) {
11 SEXP z, mm, tau, pivot, retval, retvalnames;
12 int n, nx, np, df, dim[2];
13
14 np = *(INTEGER(AS_INTEGER(order))); // order of polynomial regression
15 df = *(INTEGER(AS_INTEGER(diff))); // order of differencing
16 n = LENGTH(ref); // n = number of observations
17 nx = n - df; // nx = rows in model matrix
18 dim[0] = nx; dim[1] = np; // dimensions of model matrix
19
20 if (nx < 1) err("must have diff < number of observations");
21
22 PROTECT(z = duplicate(AS_NUMERIC(ref)));
23 PROTECT(mm = makearray(2,dim));
24 PROTECT(tau = NEW_NUMERIC(np));
25 PROTECT(pivot = NEW_INTEGER(np));
26
27 PROTECT(retval = NEW_LIST(3));
28 PROTECT(retvalnames = NEW_CHARACTER(3));
29 SET_STRING_ELT(retvalnames,0,mkChar("mm"));
30 SET_STRING_ELT(retvalnames,1,mkChar("tau"));
31 SET_STRING_ELT(retvalnames,2,mkChar("pivot"));
32 SET_ELEMENT(retval,0,mm);
33 SET_ELEMENT(retval,1,tau);
34 SET_ELEMENT(retval,2,pivot);
35 SET_NAMES(retval,retvalnames);
36
37 order_reg_model_matrix(REAL(z),REAL(mm),REAL(tau),INTEGER(pivot),n,np,df);
38
39 UNPROTECT(6);
40 return(retval);
41}
42
43SEXP probe_marginal_solve (SEXP x, SEXP setup, SEXP diff) {
44 SEXP X, mm, tau, pivot, beta, beta_names;
45 int n, nx, np, df;
46 int i;
47 char tmp[BUFSIZ];
48
49 df = *(INTEGER(AS_INTEGER(diff))); // order of differencing
50 n = LENGTH(x); // n = number of observations
51
52 // unpack the setup information
53 PROTECT(mm = VECTOR_ELT(setup,0)); // QR-decomposed model matrix
54 PROTECT(tau = VECTOR_ELT(setup,1)); // diagonals
55 PROTECT(pivot = VECTOR_ELT(setup,2)); // pivots
56
57 nx = INTEGER(GET_DIM(mm))[0]; // nx = number of rows in model matrix
58 np = INTEGER(GET_DIM(mm))[1]; // np = order of polynomial
59
60 if (n-df != nx) err("length of 'ref' must equal length of data");
61 PROTECT(X = duplicate(AS_NUMERIC(x)));
62
63 PROTECT(beta = NEW_NUMERIC(np));
64 PROTECT(beta_names = NEW_STRING(np));
65 for (i = 0; i < np; i++) {
66 snprintf(tmp,BUFSIZ,"marg.%d",i+1);
67 SET_STRING_ELT(beta_names,i,mkChar(tmp));
68 }
69 SET_NAMES(beta,beta_names);
70
71 order_reg_solve(REAL(beta),REAL(X),REAL(mm),REAL(tau),INTEGER(pivot),n,np,df);
72
73 UNPROTECT(6);
74 return(beta);
75}
76
77// thanks to Simon N. Wood for the original version of the following code
78static void order_reg_model_matrix (double *z, double *X, double *tau, int *pivot, int n, int np, int diff) {
79 // z is an n vector, containing no NAs
80 // X is an (n-diff) by np double matrix
81 // pivot is an (n-diff) integer vector
82 // tau is an (n-diff) double vector
83 // This routine first differences z 'diff' times.
84 // z is centred and sorted
85 // then the model matrix is set up and QR decomposed
86 int nx;
87 double *X1, *X2, xx;
88 int i, j;
89
90 for (i = 0, nx = n; i < diff; i++) { // differencing loop
91 nx--;
92 for (j = 0; j < nx; j++) z[j] = z[j+1] - z[j];
93 }
94 // nx = number of rows in model matrix
95 // z is now an nx-vector
96
97 // center z
98 for (j = 0, xx = 0.0; j < nx; j++) xx += z[j];
99 xx /= nx; // xx = mean(z)
100 for (j = 0; j < nx; j++) z[j] -= xx;
101
102 // now sort
103 R_qsort(z,1,nx);
104
105 // Now create the model matrix, using contents of z
106 if (np < 1) np = 1;
107 for (j = 0; j < nx; j++) X[j] = z[j]; // first column
108 for (i = 1, X1 = X, X2 = X+nx; i < np; i++, X1 += nx, X2 += nx)
109 for (j = 0; j < nx; j++) X2[j] = X1[j]*z[j];
110
111 // QR decompose the model matrix
112 pomp_qr(X,nx,np,pivot,tau);
113
114}
115
116// thanks to Simon N. Wood for the original version of the following code
117static void order_reg_solve (double *beta, double *x, double *mm, double *tau, int *pivot, int n, int np, int diff) {
118 int nx;
119 double xx;
120 int i, j;
121
122 for (i = 0, nx = n; i < diff; i++) { // differencing loop
123 nx--;
124 for (j = 0; j < nx; j++) x[j] = x[j+1] - x[j];
125 }
126 // nx = number of rows in model matrix
127 // x is now an nx-vector
128
129 // center x
130 for (j = 0, xx = 0.0; j < nx; j++) xx += x[j];
131 xx /= nx; // xx = mean(x)
132 for (j = 0; j < nx; j++) x[j] -= xx;
133
134 // now sort
135 R_qsort(x,1,nx);
136
137 // solve R b = Q'x for b
138 pomp_qrqy(x,mm,nx,tau,nx,1,np,"left","transpose"); // y <- Q'y
139 pomp_backsolve(mm,nx,np,x,1,"Upper","No transpose","Non-unit"); // y <- R^{-1} y
140
141 // unpivot and store the coefficients in beta
142 for (i = 0; i < np; i++) beta[pivot[i]] = x[i];
143
144}
#define X
Definition gompertz.c:14
#define tau
Definition gompertz.c:94
#define X1
Definition ou2.c:59
#define X2
Definition ou2.c:60
#define err(...)
Definition pomp.h:21
static R_INLINE SEXP makearray(int rank, const int *dim)
static R_INLINE void pomp_qr(double *a, int m, int n, int *pivot, double *tau)
Definition pomp_mat.h:28
static R_INLINE void pomp_qrqy(double *c, double *a, int lda, double *tau, int m, int n, int k, char *side, char *transpose)
Definition pomp_mat.h:47
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
SEXP probe_marginal_setup(SEXP ref, SEXP order, SEXP diff)
SEXP probe_marginal_solve(SEXP x, SEXP setup, SEXP diff)
static void order_reg_model_matrix(double *z, double *X, double *tau, int *pivot, int n, int np, int diff)
static void order_reg_solve(double *beta, double *x, double *mm, double *tau, int *pivot, int n, int np, int diff)