// [[Rcpp::depends(RcppArmadillo)]] #include using namespace Rcpp; /* ## Introduction of the function ## # The 'fn_GetBeta()' function computes the values of parameters that are identifiable in a case-control study without any additional assumption. ## Input Variables ## # rctr/rcas: the control/case cell probabilities (Order {GE: 00, 01, 10, 11}). They can also be control/case cell counts if necessary. ## Output ## # a vector of (\beta_{e}, \beta_{g}, \beta_{eg}) */ // [[Rcpp::export]] NumericVector fn_GetBeta(NumericVector rctr, NumericVector rcas) { rctr = rctr/sum(rctr); rcas = rcas/sum(rcas); NumericVector lrctr = log(rctr), lrcas = log(rcas); double beta0 = lrcas[0]-lrctr[0]; double beta1 = lrcas[1]-lrctr[1]-beta0; double beta2 = lrcas[2]-lrctr[2]-beta0; double beta3 = lrcas[3]-lrctr[3]-beta0-beta1-beta2; return NumericVector::create( Named("beta1") = beta1, Named("beta2") = beta2, Named("beta3") = beta3); } /* ## Introduction of the function ## # The 'fn_LambdaToTheta()' function computes the value(s) of \theta given the case-control cell probabilities and the G-E odds ratio in the source population. ## Input Variables ## # rctr/rcas: the control/case cell probabilities (Order {GE: 00, 01, 10, 11}). They can also be control/case cell counts if necessary. # rho: the GE odds ratio in the source population, with the default being 1 (the GEI assumption) ## Output ## # a list containing zero, one, or two values of \theta. */ // [[Rcpp::export]] List fn_LambdaToTheta(NumericVector rctr, NumericVector rcas, double rho=1) { NumericVector rdif; rctr = rctr/sum(rctr); rcas = rcas/sum(rcas); rdif = rcas-rctr; double a = rdif[0]*rdif[3]-rho*rdif[1]*rdif[2]; double b = rdif[0]*rctr[3]-rho*rdif[1]*rctr[2]+rdif[3]*rctr[0]-rho*rdif[2]*rctr[1]; double c = rctr[0]*rctr[3]-rho*rctr[1]*rctr[2]; double d = b*b-4*a*c; List ThetaList = List::create(); if(a==0) { double theta = -c/b; if((00) { double theta; theta = (-b+sqrt(d))/(2*a); if((00) { double theta; theta = (-b+sqrt(d))/(2*a); if((0(Jcob)))); } /* ## Introduction of the function ## # The 'fn_LogInverseProp()' function computes the factor that accounts for the transformation from (\lambda, \rho) to \xi = (\lambda, \theta), on a logarithmic scale ## Input Variables ## # rctr/rcas: the control/case cell probabilities (Order {GE: 00, 01, 10, 11}). # rho: the GE odds ratio in the source population, with the default being 1 (the GEI assumption) ## Output ## # the factor that accounts for the transformation from (\lambda, \rho) to \xi = (\lambda, \theta), on a logarithmic scale */ // [[Rcpp::export]] double fn_LogInverseProp(NumericVector rctr, NumericVector rcas, double rho=1) { NumericVector rdif; rctr = rctr/sum(rctr); rcas = rcas/sum(rcas); rdif = rcas-rctr; double InvProp = 0; List ThetaList = fn_LambdaToTheta(rctr, rcas, rho); int nsol = ThetaList.size(); for(int i=0; i 0.5) index = 1; } NumericVector Phi = PhiList[index]; for(int j=0; j<7; j++) MatrixPhi(nlp,j) = Phi[j]; NumericVector Betas(4); Betas[0] = Phi[0]; Betas[1] = Phi[1]; Betas[2] = Phi[2]; Betas[3] = Phi[3]; double prvle = Phi[4]; double prvlg = Phi[5]; LogWeight[nlp] = fn_LogCondtPri(Betas, prvle, prvlg, hypr1, hypr2, hypr3)-\ fn_LogDetJacobian(Betas, prvle, prvlg, rho)+\ fn_LogInverseProp(rctr, rcas, rho); nlp++; } { NumericVector rWeight = exp(LogWeight-max(LogWeight)); NumericVector Weight = rWeight/sum(rWeight); ess = pow(sum(Weight),2)/sum(pow(Weight,2)); } // dynamically increase the sample size until reach the desired effective sample size while (ess < ESS) { LogWeight = fn_VectorExpand(LogWeight, 5000); MatrixPhi = fn_MatrixExpand(MatrixPhi, 5000); for(int i=0; i<5000; i++) { int nsol; double rho; NumericVector rctr(4), rcas(4); List PhiList; do { rho = exp(R::rnorm(0, hyprr)); rctr[0] = R::rgamma(dctr[0]+1,1); rctr[1] = R::rgamma(dctr[1]+1,1); rctr[2] = R::rgamma(dctr[2]+1,1); rctr[3] = R::rgamma(dctr[3]+1,1); rctr = rctr/sum(rctr); rcas[0] = R::rgamma(dcas[0]+1,1); rcas[1] = R::rgamma(dcas[1]+1,1); rcas[2] = R::rgamma(dcas[2]+1,1); rcas[3] = R::rgamma(dcas[3]+1,1); rcas = rcas/sum(rcas); PhiList = fn_LambdaToPhi(rctr, rcas, rho); nsol = PhiList.size(); } while(nsol==0); int index = 0; if(nsol==2) { double tmp = R::runif(0,1); if(tmp > 0.5) index = 1; } NumericVector Phi = PhiList[index]; for(int j=0; j<7; j++) MatrixPhi(nlp,j) = Phi[j]; NumericVector Betas(4); Betas[0] = Phi[0]; Betas[1] = Phi[1]; Betas[2] = Phi[2]; Betas[3] = Phi[3]; double prvle = Phi[4]; double prvlg = Phi[5]; LogWeight[nlp] = fn_LogCondtPri(Betas, prvle, prvlg, hypr1, hypr2, hypr3)-\ fn_LogDetJacobian(Betas, prvle, prvlg, rho)+\ fn_LogInverseProp(rctr, rcas, rho); nlp++; } NumericVector rWeight = exp(LogWeight-max(LogWeight)); NumericVector Weight = rWeight/sum(rWeight); ess = pow(sum(Weight),2)/sum(pow(Weight,2)); } NumericVector rWeight = exp(LogWeight-max(LogWeight)); NumericVector Weight = rWeight/sum(rWeight); return List::create( Named("Phi") = MatrixPhi, Named("Weight") = Weight); }