1 //////////////////////////////////////////////////////////////////////////
2 // cMCMCdynamicIRT1d-b.cc is C++ code to estimate a dynamic 1d IRT model
3 //
4 // Kevin Quinn
5 // 1/29/2008
6 //
7 // Copyright (C) 2003-2007 Andrew D. Martin and Kevin M. Quinn
8 // Copyright (C) 2007-present Andrew D. Martin, Kevin M. Quinn,
9 //    and Jong Hee Park
10 //////////////////////////////////////////////////////////////////////////
11 
12 
13 #ifndef CMCMCDYNAMICIRT1DB_CC
14 #define CMCMCDYNAMICIRT1DB_CC
15 
16 #include<vector>
17 #include<algorithm>
18 
19 #include "MCMCrng.h"
20 #include "MCMCfcds.h"
21 #include "matrix.h"
22 #include "distributions.h"
23 #include "stat.h"
24 #include "la.h"
25 #include "ide.h"
26 #include "smath.h"
27 #include "rng.h"
28 #include "mersenne.h"
29 #include "lecuyer.h"
30 
31 #include <R.h>           // needed to use Rprintf()
32 #include <R_ext/Utils.h> // needed to allow user interrupts
33 
34 using namespace std;
35 using namespace scythe;
36 
37 
38 // used to access 1d arrays holding R matrices like a 2d array
39 #define M(ROW,COL,NROWS) (COL*NROWS+ROW)
40 
41 
42 // cMCMCdynamicIRT1d implementation
43 template <typename RNGTYPE>
MCMCdynamicIRT1d_b_impl(rng<RNGTYPE> & stream,double * thetadraws,const int * nrowthetadraws,const int * ncolthetadraws,double * alphadraws,const int * nrowalphadraws,const int * ncolalphadraws,double * betadraws,const int * nrowbetadraws,const int * ncolbetadraws,double * tau2draws,const int * nrowtau2draws,const int * ncoltau2draws,const int * nsubj,const int * nitems,const int * ntime,const int * Ydata,const int * nrowYdata,const int * ncolYdata,const int * ITdata,const int * lengthITdata,const int * burnin,const int * mcmc,const int * thin,const int * verbose,const double * thetadata,const int * lengththeta,const int * thetainfodata,const int * nrowthetainfo,const int * ncolthetainfo,double * alphadata,const int * lengthalpha,double * betadata,const int * lengthbeta,double * tau2data,const int * lengthtau2,const double * c0,const int * lengthc0,const double * d0,const int * lengthd0,const double * a0,const double * A0,const double * b0,const double * B0,const double * e0,const double * E0inv,const double * thetaeqdata,const int * nrowthetaeq,const int * ncolthetaeq,const double * thetaineqdata,const int * nrowthetaineq,const int * ncolthetaineq,const int * storeitem,const int * storeability)44 void MCMCdynamicIRT1d_b_impl(rng<RNGTYPE>& stream,
45 			   double* thetadraws, const int* nrowthetadraws,
46 			   const int* ncolthetadraws,
47 			   double* alphadraws, const int* nrowalphadraws,
48 			   const int* ncolalphadraws,
49 			   double* betadraws, const int* nrowbetadraws,
50 			   const int* ncolbetadraws,
51 			   double* tau2draws, const int* nrowtau2draws,
52 			   const int* ncoltau2draws,
53 			   const int* nsubj, const int* nitems,
54 			   const int* ntime,
55 			   const int* Ydata, const int* nrowYdata,
56 			   const int* ncolYdata,
57 			   const int* ITdata, const int* lengthITdata,
58 			   const int* burnin, const int* mcmc, const int* thin,
59 			   const int* verbose,
60 			   const double* thetadata,
61 			   const int* lengththeta,
62 			   const int* thetainfodata,
63 			   const int* nrowthetainfo,
64 			   const int* ncolthetainfo,
65 			   double* alphadata,
66 			   const int* lengthalpha,
67 			   double* betadata,
68 			   const int* lengthbeta,
69 			   double* tau2data,
70 			   const int* lengthtau2,
71 			   const double* c0,
72 			   const int* lengthc0,
73 			   const double* d0,
74 			   const int* lengthd0,
75 			   const double* a0,
76 			   const double* A0,
77 			   const double* b0,
78 			   const double* B0,
79 			   const double* e0,
80 			   const double* E0inv,
81 			   const double* thetaeqdata,
82 			   const int* nrowthetaeq,
83 			   const int* ncolthetaeq,
84 			   const double* thetaineqdata,
85 			   const int* nrowthetaineq,
86 			   const int* ncolthetaineq,
87 			   const int* storeitem,
88 			   const int* storeability){
89 
90 
91 
92   const int tot_iter = *burnin + *mcmc;
93 // JHP  const int nsamp = *mcmc / *thin;
94   //sparse matrix of latent outcome variables
95   double** Z;
96   Z = new double*[*nsubj];
97   for (int s=0; s<*nsubj; ++s){
98     Z[s] = new double[*nitems];
99     for (int i=0; i<*nitems; ++i){
100       Z[s][i] = -999;
101     }
102   }
103   for (int j=0; j<*nrowYdata; ++j){
104     const int s = Ydata[M(j, 0, *nrowYdata)]; // subject id
105     const int i = Ydata[M(j, 1, *nrowYdata)]; // item id
106 // JHP    const int y = Ydata[M(j, 2, *nrowYdata)]; // y value
107     Z[s][i] = 0.0;
108   }
109 
110 
111   // stuff to make working with theta easy
112   // theta[s][t] gives the tth theta for subject s
113   // the actual time period corresponding to theta[s][t] is theta_offset[s]+t
114   vector< vector<double> > theta;
115   vector<int> theta_offset;
116   int count = 0;
117   for (int s=0; s<*nsubj; ++s){
118     vector<double> holder;
119     int ntime_s = thetainfodata[M(s, 1, *nrowthetainfo)];
120     theta_offset.push_back(thetainfodata[M(s, 2, *nrowthetainfo)]);
121     for (int t=0; t<ntime_s; ++t){
122       holder.push_back(thetadata[count]);
123       ++count;
124     }
125     theta.push_back(holder);
126   }
127 
128 
129 
130   // define constants used in the sampling
131   const double A0a0 = *A0 * *a0;
132   const double B0b0 = *B0 * *b0;
133 
134 
135   // set up mappings
136   //
137   // IS gives the mapping from items to subjects
138   // IS[i] provides a vector of integers corresponding to the subjects
139   //    who voted on item i.
140   // IS[i][s] gets the subject index of the sth subject to vote on item i
141   vector< vector<int> > IS;
142   for (int i=0; i<*nitems; ++i){
143     vector<int> subjholder;
144     for (int j=0; j<*nrowYdata; ++j){
145       if (Ydata[M(j,1,*nrowYdata)] == i){
146 	subjholder.push_back(Ydata[M(j,0,*nrowYdata)]);
147       }
148     }
149     sort(subjholder.begin(), subjholder.end());
150     IS.push_back(subjholder);
151   }
152 
153   // SI gives the mapping from subjects to items
154   // SI[s] provides a vector of integers corresponding to the items
155   //    voted on by subject s.
156   // SI[s][i] gets the item index of the ith item voted on by subject s
157   vector< vector<int> > SI;
158   for (int i=0; i<*nsubj; ++i){
159     vector<int> itemholder;
160     for (int j=0; j<*nrowYdata; ++j){
161       if (Ydata[M(j,0,*nrowYdata)] == i){
162 	itemholder.push_back(Ydata[M(j,1,*nrowYdata)]);
163       }
164     }
165     sort(itemholder.begin(), itemholder.end());
166     SI.push_back(itemholder);
167   }
168 
169   // TI gives the mapping from times to items
170   // TI[t] provides a vector of integers corresponding to the items
171   //    voted on in time period t.
172   // TI[t][i] gets the item index of the ith item voted on in time period t
173   vector< vector<int> > TI;
174   for (int t=0; t<*ntime; ++t){
175     vector<int> itemholder;
176     for (int i=0; i<*lengthITdata; ++i){
177       if (ITdata[i] == t){
178 	itemholder.push_back(i);
179       }
180     }
181     sort(itemholder.begin(), itemholder.end());
182     TI.push_back(itemholder);
183   }
184 
185   // IT gives the mapping from items to times and is just fancy
186   // way of holding the stuff in *ITdata
187   vector<int> IT;
188   for (int i=0; i<*nitems; ++i){
189     IT.push_back(ITdata[i]);
190   }
191 
192 
193   // ST gives the mapping from subjects to times
194   // ST[s] provides a vector of integers corresponding to the times
195   //    in which items were voted on by subject s.
196   // ST[s][t] gets the time index of the tth time period served by subject s
197   /*
198   vector <vector <int> > ST;
199   for (int s=0; s<*nsubj; ++s){
200     vector <int> timeholder;
201     for (int iind=0; iind<SI[s].size(); ++iind){
202       const int i = SI[s][iind];
203       const int t = IT[i];
204       if (timeholder.empty()){
205 	timeholder.push_back(t);
206       }
207       vector<int>::iterator myiter;
208       myiter = find(timeholder.begin(), timeholder.end(), t);
209       if (myiter == timeholder.end()){ // t not currently in timeholder
210 	timeholder.push_back(t);
211       }
212     }
213     sort(timeholder.begin(), timeholder.end());
214     ST.push_back(timeholder);
215   }
216   */
217 
218   // STI gives the list of item indices of items voted on by by subject s
219   // in the tth time period served by s
220   vector< vector < vector <int> > > STI;
221   for (int s=0; s<*nsubj; ++s){
222     vector < vector <int> > timeitemholder;
223     for (unsigned int tt=0; tt<theta[s].size(); ++tt){
224       const int t = tt + theta_offset[s];
225       vector <int> itemholder;
226       for (unsigned int ii=0; ii<TI[t].size(); ++ii){
227 	const int i = TI[t][ii];
228 	if (Z[s][i] != -999){
229 	  itemholder.push_back(i);
230 	}
231       }
232       timeitemholder.push_back(itemholder);
233     }
234     STI.push_back(timeitemholder);
235   }
236 
237 
238 
239 
240 
241   // MCMC iterations start here
242   int sampcount = 0;
243   for (int iter=0; iter < tot_iter; ++iter){
244 
245 
246 
247     // sample latent Z
248     for (int j=0; j<*nrowYdata; ++j){
249       const int s = Ydata[M(j, 0, *nrowYdata)]; // subject id
250       const int i = Ydata[M(j, 1, *nrowYdata)]; // item id
251       const int y = Ydata[M(j, 2, *nrowYdata)]; // y value
252       const int t = IT[i];                      // time period
253       const double mu = -alphadata[i] +
254 	betadata[i] * theta[s][t-theta_offset[s]];
255       if (y == 1.0){
256 	Z[s][i] = stream.rtbnorm_combo(mu, 1.0, 0);
257       }
258       if (y == 0.0){
259 	Z[s][i] = stream.rtanorm_combo(mu, 1.0, 0);
260       }
261     }
262 
263 
264 
265 
266 
267     // sample item parameters (alpha, beta)
268     for (int i=0; i<*nitems; ++i){
269       const int nsubj_i = IS[i].size();
270       double sumthetasq = 0.0;
271       double sumtheta = 0.0;
272       double sumz = 0.0;
273       double sumthetaz = 0.0;
274       const int t = IT[i];
275 
276       for (int ss=0; ss<nsubj_i; ++ss){
277 	const int s = IS[i][ss];
278 	const double theta_st = theta[s][t - theta_offset[s]];
279 	sumthetasq += std::pow(theta_st, 2.0);
280 	sumtheta += -1*theta_st;
281 	sumz += -1*Z[s][i];
282 	sumthetaz += Z[s][i] * theta_st;
283       } // end ss loop
284 
285       const double sumthetaallsq = std::pow(sumtheta, 2.0);
286       const double invdet = 1.0 / ((nsubj_i + *A0) *
287 				   (sumthetasq + *B0) -
288 				   sumthetaallsq);
289       const double v11star = invdet * (sumthetasq + *B0);
290       const double v12star = invdet * (-1.0 * sumtheta);
291       const double v22star = invdet * (nsubj_i + *B0);
292       const double s1star = std::sqrt(v11star);
293       const double s2star = std::sqrt(v22star);
294       const double rho = v12star / (s1star * s2star);
295       const double holder1 = sumz + A0a0;
296       const double holder2 = sumthetaz + B0b0;
297       const double m1star = v11star * holder1 + v12star * holder2;
298       const double m2star = v12star * holder1 + v22star * holder2;
299       // (alpha[i], beta[i]) ~
300       //     N((m1star, m2star), c(v11star, v12star, v22star) )
301       alphadata[i] = 1000;
302       betadata[i] = 100;
303       while (std::fabs(alphadata[i]) > 4 ||
304 	     std::fabs(betadata[i]) > 2 ||
305 	     std::fabs(alphadata[i] / betadata[i]) > 2){
306 	alphadata[i] = stream.rnorm(m1star, s1star);
307 	if (iter < 20 ){
308 	  alphadata[i] = 0.2*((m1star > 0) - (m1star < 0));
309 	}
310 	const double cond_mean = m2star - m1star * (v12star / v11star) +
311 	  alphadata[i] * (v12star / v11star);
312 	const double cond_sd = std::sqrt(v22star * ( 1 - std::pow(rho, 2.0)));
313 	betadata[i] = stream.rnorm(cond_mean, cond_sd);
314 	if (iter < 20 ){
315 	  betadata[i] = 1.0*((cond_mean > 0) - (cond_mean < 0));
316 	}
317       }
318     } // end i loop
319 
320 
321 
322 
323 
324     // sample subject parameters (theta, tau2)
325     for (int s=0; s<*nsubj; ++s){
326       const int ntime_s = theta[s].size();
327       if (thetaeqdata[s] != -999){
328 	for (int t=0; t<ntime_s; ++t){
329 	  theta[s][t] = thetaeqdata[s];
330 	}
331       }
332       else{
333 
334 	// time period 0
335 	vector<double> beta_s0;
336 	beta_s0.reserve(STI[s][0].size());
337 	vector<double> zalpha_s0;
338 	zalpha_s0.reserve(STI[s][0].size());
339 	for (unsigned int ii=0; ii<STI[s][0].size(); ++ii){
340 	  const int i = STI[s][0][ii];
341 	  beta_s0.push_back(betadata[i]);
342 	  zalpha_s0.push_back(Z[s][i] + alphadata[i]);
343 	}
344 	vector<double> a;
345 	a.reserve(ntime_s);
346 	a.push_back(e0[s]);
347 	vector<double> R;
348 	R.reserve(ntime_s);
349 	R.push_back(E0inv[s] + tau2data[s]);
350 	vector <double> f_0 = beta_s0;
351 	for (unsigned int i=0; i<f_0.size(); ++i){
352 	  f_0[i] = f_0[i] * a[0];
353 	}
354 	Matrix <> Q_0(beta_s0.size(), beta_s0.size());
355 	for (unsigned int i=0; i<beta_s0.size(); ++i){
356 	  for (unsigned int j=i; j<beta_s0.size(); ++j){
357 	    if (i!=j){
358 	      Q_0(i,j) = Q_0(j,i) = beta_s0[i] * beta_s0[j] * R[0];
359 	    }
360 	    else{
361 	      Q_0(i,j) = beta_s0[i] * beta_s0[j] * R[0] + 1.0;
362 	    }
363 	  }
364 	}
365 	vector <double> e_0 = zalpha_s0;
366 	for (unsigned int i=0; i<e_0.size(); ++i){
367 	  e_0[i] = e_0[i] - f_0[i];
368 	}
369 	const Matrix <> Q_0_inv = invpd(Q_0);
370 
371 	vector <double> A_0;
372 	A_0.reserve(beta_s0.size());
373 	for (unsigned int i=0; i<beta_s0.size(); ++i){
374 	  double sumholder = 0.0;
375 	  for (unsigned int j=0; j<beta_s0.size(); ++j){
376 	    sumholder += beta_s0[j] * Q_0_inv(j,i);
377 	  }
378 	  A_0.push_back(sumholder * R[0]);
379 	}
380 	vector<double> m;
381 	m.reserve(ntime_s);
382 	double mhold = a[0];
383 	for (unsigned int i=0; i<A_0.size(); ++i){
384 	  mhold += A_0[i] * e_0[i];
385 	}
386 	m.push_back(mhold);
387 
388 
389 	vector<double> C;
390 	C.reserve(ntime_s);
391 	double Chold = 0.0;
392 
393 	for (unsigned int i=0; i<A_0.size(); ++i){
394 	  double hold2 = 0.0;
395 	  for (unsigned int j=0; j<A_0.size(); ++j){
396 	    //cout << "i = " << i << "   j = " << j << endl;
397 	    hold2 += Q_0(i,j) * A_0[j];
398 	  }
399 
400 	  Chold += hold2 * A_0[i];
401 	}
402 	C.push_back(R[0] - Chold);
403 
404 
405 
406 	// THE FORWARD RECURSION
407 	// time periods 1 to T
408 	for (int tt=1; tt<ntime_s; ++tt){
409 	  if (STI[s][tt].size() == 0){
410 	    a.push_back(m[tt-1]);
411 	    R.push_back(C[tt-1] + tau2data[s]);
412 	    m.push_back(a[tt]);
413 	    C.push_back(R[tt]);
414 	  }
415 	  else{
416 	    vector<double> beta_s;
417 	    beta_s.reserve(STI[s][tt].size());
418 	    vector<double> zalpha_s;
419 	    zalpha_s.reserve(STI[s][tt].size());
420 	    for (unsigned int ii=0; ii<STI[s][tt].size(); ++ii){
421 	      const int i = STI[s][tt][ii];
422 	      beta_s.push_back(betadata[i]);
423 	      zalpha_s.push_back(Z[s][i] + alphadata[i]);
424 	    }
425 	    // a
426 	    a.push_back(m[tt-1]);
427 	    // R
428 	    R.push_back(C[tt-1] + tau2data[s]);
429 	    vector <double> f = beta_s;
430 	    for (unsigned int i=0; i<f.size(); ++i){
431 	      f[i] = f[i] * a[tt];
432 	    }
433 	    Matrix <> Q(beta_s.size(), beta_s.size());
434 	    for (unsigned int i=0; i<beta_s.size(); ++i){
435 	      for (unsigned int j=i; j<beta_s.size(); ++j){
436 		if (i!=j){
437 		  Q(i,j) = Q(j,i) = beta_s[i] * beta_s[j] * R[tt];
438 		}
439 		else{
440 		  Q(i,j) = beta_s[i] * beta_s[j] * R[tt] + 1.0;
441 		}
442 	      }
443 	    }
444 	    vector <double> e = zalpha_s;
445 	    for (unsigned int i=0; i<e.size(); ++i){
446 	      e[i] = e[i] - f[i];
447 	    }
448 	    const Matrix <> Q_inv = invpd(Q);
449 
450 	    vector <double> A;
451 	    A.reserve(beta_s.size());
452 	    for (unsigned int i=0; i<beta_s.size(); ++i){
453 	      double sumholder = 0.0;
454 	      for (unsigned int j=0; j<beta_s.size(); ++j){
455 		sumholder += beta_s[j] * Q_inv(j,i);
456 	      }
457 	      A.push_back(sumholder * R[tt]);
458 	    }
459 	    mhold = a[tt];
460 	    for (unsigned int i=0; i<A.size(); ++i){
461 	      mhold += A[i] * e[i];
462 	    }
463 	    m.push_back(mhold);
464 
465 	    Chold = 0.0;
466 	    for (unsigned int i=0; i<A.size(); ++i){
467 	      double hold2 = 0.0;
468 	      for (unsigned int j=0; j<A.size(); ++j){
469 		hold2 += Q(i,j) * A[j];
470 	      }
471 	      Chold += hold2 * A[i];
472 	    }
473 	    C.push_back(R[tt] - Chold);
474 	  }
475 	} // end tt loop
476 
477 	if (thetaineqdata[s] == 0){
478 	theta[s][ntime_s-1] = stream.rnorm(m[ntime_s-1],
479 					   std::sqrt(C[ntime_s-1]));
480 	}
481 	else if (thetaineqdata[s] > 0){
482 	  theta[s][ntime_s-1] = stream.rtbnorm_combo(m[ntime_s-1],
483 						     C[ntime_s-1], 0.0);
484 	}
485 	else{
486 	  theta[s][ntime_s-1] = stream.rtanorm_combo(m[ntime_s-1],
487 						     C[ntime_s-1], 0.0);
488 	}
489 
490 
491 
492 
493 	for (int tt=(ntime_s-2); tt>=0; --tt){
494 	  const double B = C[tt] * (1.0 / R[tt+1]);
495 	  const double h = m[tt] + B * (theta[s][tt+1] - a[tt+1]);
496 	  const double H = C[tt] - B * R[tt+1] * B;
497 	  if (thetaineqdata[s] == 0){
498 	    theta[s][tt] = stream.rnorm(h, std::sqrt(H));
499 	  }
500 	  else if (thetaineqdata[s] > 0){
501 	    theta[s][tt] = stream.rtbnorm_combo(h, H, 0.0);
502 	  }
503 	  else {
504 	    theta[s][tt] = stream.rtanorm_combo(h, H, 0.0);
505 	  }
506 	} // end backwards tt loop
507 
508       } // end theteqdataa[s] == -999
509 
510 
511 
512       // sample smoothing parameters (tau2)
513       if (c0[s] > 0 && d0[s] > 0){
514 	double SSE = 0.0;
515 	for (int t=1; t<ntime_s; ++t){
516 	  SSE += std::pow((theta[s][t] - theta[s][t-1]), 2.0);
517 	}
518 	const double param1 = (c0[s] + ntime_s - 1) * 0.5;
519 	const double param2 = (d0[s] + SSE) * 0.5;
520 	tau2data[s] = stream.rigamma(param1, param2);
521       }
522 
523 
524 
525 
526     } // end s loop (end of theta tau2 loop)
527 
528 
529 
530 
531 
532 
533 
534 
535 
536 
537 
538 
539 
540     // store draws
541     if (iter >= *burnin && (iter % *thin == 0)) {
542       if (*storeability == 1){
543 	int internalcount = 0;
544 	for (int s=0; s<*nsubj; ++s){
545 	  for (unsigned int t=0; t<theta[s].size(); ++t){
546 	    thetadraws[M(sampcount, internalcount, *nrowthetadraws)] =
547 	      theta[s][t];
548 	    ++internalcount;
549 	  }
550 	}
551       }
552       if (*storeitem == 1){
553 	for (int i=0; i<*nitems; ++i){
554 	  alphadraws[M(sampcount, i, *nrowalphadraws)] = alphadata[i];
555 	  betadraws[M(sampcount, i, *nrowbetadraws)] = betadata[i];
556 	}
557       }
558       for (int s=0; s<*nsubj; ++s){
559 	tau2draws[M(sampcount, s, *nrowtau2draws)] = tau2data[s];
560       }
561       ++sampcount;
562     }
563 
564 
565     // print output to stdout
566     // print output to stdout
567     if(*verbose > 0 && iter % *verbose == 0){
568       Rprintf("\n\nMCMCdynamicIRT1d iteration %i of %i \n", (iter+1), tot_iter);
569       /*
570       for (int t=0; t<theta[1].size(); ++t){
571 	Rprintf("%f ", theta[1][t]);
572       }
573       Rprintf("\n");
574       for (int t=0; t<theta[7].size(); ++t){
575 	Rprintf("%f ", theta[7][t]);
576       }
577       Rprintf("\n");
578       for (int t=0; t<theta[5].size(); ++t){
579 	Rprintf("%f ", theta[5][t]);
580       }
581       Rprintf("\n");
582       for (int t=0; t<theta[8].size(); ++t){
583 	Rprintf("%f ", theta[8][t]);
584       }
585       Rprintf("\n");
586       for (int t=0; t<theta[2].size(); ++t){
587 	Rprintf("%f ", theta[2][t]);
588       }
589       Rprintf("\n");
590       for (int t=0; t<theta[4].size(); ++t){
591 	Rprintf("%f ", theta[4][t]);
592       }
593       Rprintf("\n");
594       for (int t=0; t<theta[0].size(); ++t){
595 	Rprintf("%f ", theta[0][t]);
596       }
597       Rprintf("\n");
598       for (int t=0; t<theta[3].size(); ++t){
599 	Rprintf("%f ", theta[3][t]);
600       }
601       Rprintf("\n");
602       for (int t=0; t<theta[6].size(); ++t){
603 	Rprintf("%f ", theta[6][t]);
604       }
605       Rprintf("\n");
606       Rprintf("\n\n");
607       Rprintf("alpha[0] = %f \n", alphadata[0]);
608       Rprintf("beta[0] = %f \n", betadata[0]);
609       Rprintf("alpha[0]/beta[0] = %f \n", alphadata[0]/betadata[0]);
610       Rprintf("tau2[1] = %f \n", tau2data[1]);
611       Rprintf("tau2[7] = %f \n", tau2data[7]);
612       Rprintf("tau2[5] = %f \n", tau2data[5]);
613       Rprintf("tau2[8] = %f \n", tau2data[8]);
614       Rprintf("tau2[2] = %f \n", tau2data[2]);
615       Rprintf("tau2[4] = %f \n", tau2data[4]);
616       Rprintf("tau2[0] = %f \n", tau2data[0]);
617       Rprintf("tau2[3] = %f \n", tau2data[3]);
618       Rprintf("tau2[6] = %f \n", tau2data[6]);
619       Rprintf("\n\n");
620       */
621     }
622 
623     R_CheckUserInterrupt(); // allow user interrupts
624 
625 
626 
627   } // end iter loop
628 
629   for (int s=0; s<*nsubj; ++s)
630     delete[] Z[s];
631   delete[] Z;
632 
633 } // end MCMCdynamicIRT1d_impl function
634 
635 
636 
637 
638 
639 
640 
641 
642 extern "C" {
643 
cMCMCdynamicIRT1d_b(double * thetadraws,const int * nrowthetadraws,const int * ncolthetadraws,double * alphadraws,const int * nrowalphadraws,const int * ncolalphadraws,double * betadraws,const int * nrowbetadraws,const int * ncolbetadraws,double * tau2draws,const int * nrowtau2draws,const int * ncoltau2draws,const int * nsubj,const int * nitems,const int * ntime,const int * Ydata,const int * nrowYdata,const int * ncolYdata,const int * ITdata,const int * lengthITdata,const int * burnin,const int * mcmc,const int * thin,const int * uselecuyer,const int * seedarray,const int * lecuyerstream,const int * verbose,const double * thetastartdata,const int * lengththetastart,const int * thetainfodata,const int * nrowthetainfo,const int * ncolthetainfo,double * alphastartdata,const int * lengthalphastart,double * betastartdata,const int * lengthbetastart,double * tau2startdata,const int * lengthtau2start,const double * c0,const int * lengthc0,const double * d0,const int * lengthd0,const double * a0,double * A0,const double * b0,double * B0,const double * e0,const double * E0inv,const double * thetaeqdata,const int * nrowthetaeq,const int * ncolthetaeq,const double * thetaineqdata,const int * nrowthetaineq,const int * ncolthetaineq,const int * storeitem,const int * storeability)644   void cMCMCdynamicIRT1d_b(double* thetadraws, const int* nrowthetadraws,
645 			const int* ncolthetadraws,
646 			double* alphadraws, const int* nrowalphadraws,
647 			const int* ncolalphadraws,
648 			double* betadraws, const int* nrowbetadraws,
649 			const int* ncolbetadraws,
650 			double* tau2draws, const int* nrowtau2draws,
651 			const int* ncoltau2draws,
652 			const int* nsubj, const int* nitems,
653 			const int* ntime,
654  			const int* Ydata, const int* nrowYdata,
655 			const int* ncolYdata,
656 			const int* ITdata, const int* lengthITdata,
657 			const int* burnin, const int* mcmc, const int* thin,
658 			const int* uselecuyer, const int* seedarray,
659 			const int* lecuyerstream,
660 			const int* verbose,
661 			const double* thetastartdata,
662 			const int* lengththetastart,
663 			const int* thetainfodata,
664 			const int* nrowthetainfo,
665 			const int* ncolthetainfo,
666 			double* alphastartdata,
667 			const int* lengthalphastart,
668 			double* betastartdata,
669 			const int* lengthbetastart,
670 			double* tau2startdata,
671 			const int* lengthtau2start,
672 			const double* c0,
673 			const int* lengthc0,
674 			const double* d0,
675 			const int* lengthd0,
676 			const double* a0,
677 			 double* A0,
678 			const double* b0,
679 			 double* B0,
680 			const double* e0,
681 			const double* E0inv,
682 			const double* thetaeqdata,
683 			const int* nrowthetaeq,
684 			const int* ncolthetaeq,
685 			const double* thetaineqdata,
686 			const int* nrowthetaineq,
687 			const int* ncolthetaineq,
688 			const int* storeitem,
689 			const int* storeability
690 			){
691 
692     *A0 = 0.0;
693     *B0 = 0.0;
694 
695     MCMCPACK_PASSRNG2MODEL(MCMCdynamicIRT1d_b_impl, thetadraws, nrowthetadraws,
696 			   ncolthetadraws, alphadraws, nrowalphadraws,
697 			   ncolalphadraws, betadraws, nrowbetadraws,
698 			   ncolbetadraws, tau2draws, nrowtau2draws,
699 			   ncoltau2draws, nsubj, nitems, ntime,
700 			   Ydata, nrowYdata, ncolYdata,
701 			   ITdata,  lengthITdata, burnin,  mcmc, thin,
702 			   verbose, thetastartdata, lengththetastart,
703 			   thetainfodata, nrowthetainfo, ncolthetainfo,
704 			   alphastartdata, lengthalphastart, betastartdata,
705 			   lengthbetastart, tau2startdata, lengthtau2start,
706 			   c0, lengthc0, d0, lengthd0,
707 			   a0, A0, b0, B0, e0, E0inv,
708 			   thetaeqdata, nrowthetaeq,
709 			   ncolthetaeq, thetaineqdata, nrowthetaineq,
710 			   ncolthetaineq, storeitem, storeability );
711 
712 
713   } // end cMCMCdynamicIRT1d-b
714 
715 } // end extern "C"
716 
717 
718 #endif
719