split_fn get_split_fn( const std::vector< vl::vec< T, N > >& patterns,
                           const std::vector< uint32_t >& positives,
                           const std::vector< uint32_t >& negatives,
                           double weight_positive = 1 ) const
    {
        if ( positives.size() == 0 || negatives.size() == 0 )
        {
            return split_fn( true );
        }

        vl::vec< T, N > mu_t( 0 );
        vl::vec< T, N > mu_f( 0 );

        FOR_EACH( it, positives )
        {
            uint32_t idx = ( *it );
            mu_t += patterns[ idx ];
        }
Beispiel #2
0
RcppExport SEXP bbivDPM(SEXP arg1, SEXP arg2, SEXP arg3) {
  // 3 arguments
  // arg1 for parameters
  // arg2 for data
  // arg3 for Gibbs

  // data
  List list2(arg2); 

  const MatrixXd X=as< Map<MatrixXd> >(list2["X"]),
    Z=as< Map<MatrixXd> >(list2["Z"]);

  const VectorXi v1=as< Map<VectorXi> >(list2["tbin"]),
    v2=as< Map<VectorXi> >(list2["ybin"]);

  const int N=X.rows(), p=X.cols(), q=Z.cols(), r=p+q, s=p+r;

#ifdef DEBUG_NEAL8
  List P, Phi, B;
  VectorXi S, one;
  one.setConstant(N, 1);
#endif

  // parameters
  List list1(arg1), 
    beta_info=list1["beta"], 
    rho_info=list1["rho"], 
    mu_info=list1["mu"], 
    theta_info=list1["theta"],
    dpm_info=list1["dpm"], // DPM
    alpha_info=dpm_info["alpha"], // alpha random
    alpha_prior; // alpha random

  const int m=as<int>(dpm_info["m"]); // DPM
  //  const double alpha=as<double>(dpm_info["alpha"]); // DPM
  const int alpha_fixed=as<int>(alpha_info["fixed"]); // alpha random
  double alpha=as<double>(alpha_info["init"]); // alpha random

  if(alpha_fixed==0) alpha_prior=alpha_info["prior"]; // alpha random

  VectorXi C=as< Map<VectorXi> >(dpm_info["C"]), 
    states=as< Map<VectorXi> >(dpm_info["states"]);
  
  /* checks done in neal8
  if(states.sum()!=N || C.size()!=N) { // limited reality check of C and states
    C.setConstant(N, 0); 
    states.setConstant(1, N); 
  }
  */

  // prior parameters
  List beta_prior=beta_info["prior"],
    // no prior parameters for rho
    dpm_prior=dpm_info["prior"],
    theta_prior=theta_info["prior"];

  const double beta_prior_mean=as<double>(beta_prior["mean"]);
  const double beta_prior_prec=as<double>(beta_prior["prec"]);

  const VectorXd theta_prior_mean=as< Map<VectorXd> >(theta_prior["mean"]);
  const MatrixXd theta_prior_prec=as< Map<MatrixXd> >(theta_prior["prec"]);

  // initialize parameters
  double beta    =as<double>(beta_info["init"]); 
  double rho_init=as<double>(rho_info["init"]);  // DPM
  //int    rho_MH  =as<int>(rho_info["MH"]);

  Vector2d mu_init=as< Map<VectorXd> >(mu_info["init"]); // DPM
  VectorXd theta  =as< Map<VectorXd> >(theta_info["init"]);
  VectorXd rho(N);  // DPM

  /*
  VectorXi C, states; // DPM
  C.setConstant(N, 0); // DPM
  states.setConstant(1, N); // DPM
  */

  MatrixXd mu(N, 2), phi(1, 3); // DPM
  phi(0, 0)=mu_init[0]; // DPM
  phi(0, 1)=mu_init[1]; // DPM
  phi(0, 2)=rho_init; // DPM

  // Gibbs
  List list3(arg3);

  const int burnin=as<int>(list3["burnin"]), M=as<int>(list3["M"]), 
    thin=as<int>(list3["thin"]);

  VectorXi quadrant(N);

  VectorXd t(N), y(N); // latents

  // prior parameter intermediate values
  double beta_prior_prod=beta_prior_prec * beta_prior_mean;

  VectorXd theta_prior_prod=theta_prior_prec * theta_prior_mean;

  Matrix2d Sigma, Tprec, B_inverse;

  B_inverse.setIdentity();

  VectorXd gamma=theta.segment(0, p), 
    delta=theta.segment(p, q), 
    eta  =theta.segment(r, p);

  MatrixXd eps(N, 2), D(N, 2), theta_cond_var_root(s, s), W(2, s), A(N, r+4); // DPM semi

  W.setZero();

  MatrixXd theta_cond_prec(s, s);

  VectorXd theta_cond_prod(s), w(r), mu_t(N), mu_y(N), sd_y(N);

  Vector2d u, R, mu_u; // DPM

  double beta_prec, beta_prod, beta_cond_var, beta_cond_mean, beta2; // DPM

  int h=0, i, l; 

  List GS(M); //DPM

  // assign quadrants
  for(i=0; i<N; ++i) {
    if(v1[i]==0 && v2[i]==0) quadrant[i] = 3;
    else if(v1[i]==0 && v2[i]==1) quadrant[i] = 2;
    else if(v1[i]==1 && v2[i]==0) quadrant[i] = 4;
    else if(v1[i]==1 && v2[i]==1) quadrant[i] = 1;
  }

  // Gibbs loop
  //for(int l=-burnin; l<=(M-1)*thin; ++l) {

  l=-burnin;

  do{
    // populate mu/rho //DPM
    for(i=0; i<N; ++i) {
      mu(i, 0)=phi(C[i], 0);
      mu(i, 1)=phi(C[i], 1);
      rho[i]=phi(C[i], 2);

      mu_t[i]=mu(i, 0);
      mu_y[i]=mu(i, 1);
    }

    // generate latents
    // mu_t = mu.col(0); //DPM
    mu_t += (Z*delta + X*gamma);

    // mu_y = mu.col(1); //DPM
    mu_y += (beta*mu_t + X*eta);

    beta2=pow(beta, 2.);

    for(i=0; i<N; ++i) {
      sd_y[i] = sqrt(beta2+2.*beta*rho[i]+1.); //DPM

      mu_u[0]=mu_t[i];
      mu_u[1]=mu_y[i]/sd_y[i]; //DPM
      //             z,    quadrant,    rho,                   burnin 
      u=rbvtruncnorm(mu_u, quadrant[i], (beta+rho[i])/sd_y[i], 10);
  
      t[i]=u[0];
      y[i]=sd_y[i]*u[1];
    }

    // sample beta
    D.col(0) = (t - mu.col(0) - X*gamma - Z*delta); //DPM
    D.col(1) = (y - mu.col(1) - X*eta); //DPM

    beta_prec=0.;
    beta_prod=0.;

    for(i=0; i<N; ++i) {
      double Sigma_det=1.-pow(rho[i], 2.); //DPM

      beta_prec += pow(t[i], 2.)/Sigma_det; //DPM
      beta_prod += -t[i]*(rho[i]*D(i, 0)-D(i, 1))/Sigma_det; //DPM
    }

    beta_cond_var=1./(beta_prec+beta_prior_prec);

    beta_cond_mean=beta_cond_var*(beta_prod+beta_prior_prod);

    beta=rnorm1d(beta_cond_mean, sqrt(beta_cond_var));

    B_inverse(1, 0)=-beta;

    // sample theta
    theta_cond_prec=theta_prior_prec;
    theta_cond_prod=theta_prior_prod;

    for(i=0; i<N; ++i) {
      double Sigma_det=1.-pow(rho[i], 2.); //DPM

      Tprec(0, 0)=1./Sigma_det;      Tprec(0, 1)=-rho[i]/Sigma_det; //DPM
      Tprec(1, 0)=-rho[i]/Sigma_det; Tprec(1, 1)=1./Sigma_det; //DPM

      mu_u[0]=mu(i, 0);  //DPM
      mu_u[1]=mu(i, 1);  //DPM

      W.block(0, 0, 1, p)=X.row(i);
      W.block(0, p, 1, q)=Z.row(i);
      W.block(1, r, 1, p)=X.row(i);

      theta_cond_prec += (W.transpose() * Tprec * W);

      u[0]=t[i];
      u[1]=y[i];

      R=B_inverse*u-mu_u; //DPM

      theta_cond_prod += (W.transpose() * Tprec * R);
    }

    theta_cond_var_root=inv_root_chol(theta_cond_prec);

    theta=theta_cond_var_root*(rnormXd(s)+theta_cond_var_root.transpose()*theta_cond_prod);

    gamma=theta.segment(0, p); 
    delta=theta.segment(p, q); 
    eta  =theta.segment(r, p);

    // sample mu and rho
    // this for block should be placed in P0
    // however, to keep changes minimal, we keep it here
    for(i=0; i<N; ++i) {

      W.block(0, 0, 1, p)=X.row(i);
      W.block(0, p, 1, q)=Z.row(i);
      W.block(1, r, 1, p)=X.row(i);

      u[0]=t[i];
      u[1]=y[i];

      eps.row(i) = (B_inverse*u - W*theta).transpose(); //DPM
    }

    /* semi block begins */
    A.block(0, 0, N, 2)=eps;
    A.col(2)=t;
    A.col(3)=y;
    A.block(0, 4, N, p)=X;
    A.block(0, p+4, N, q)=Z;

    List psi=List::create(Named("mu0")=as< Map<VectorXd> >(dpm_prior["mu0"]), 
			  Named("T0")=as< Map<MatrixXd> >(dpm_prior["T0"]),   
			  Named("S0")=as< Map<MatrixXd> >(dpm_prior["S0"]),  
			  Named("beta")=beta,   
			  Named("gamma")=gamma, 
			  Named("delta")=delta, 
			  Named("eta")=eta);   

    if(alpha_fixed==0) 
      alpha=bbiv_alpha(states.size(), N, alpha, alpha_prior); // alpha random

    List dpm_step=neal8(A, C, phi, states, m, alpha, psi, 
     			&bbivF, &bbivG0, &bbivP0);
    /* semi block end */

    /*
    C=as< Map<VectorXi> >(dpm_step[0]);
    phi=as< Map<MatrixXd> >(dpm_step[1]);
    states=as< Map<VectorXi> >(dpm_step[2]);
    */

    C=as< Map<VectorXi> >(dpm_step["C"]);
    phi=as< Map<MatrixXd> >(dpm_step["phi"]);
    states=as< Map<VectorXi> >(dpm_step["states"]);

#ifdef DEBUG_NEAL8
    S=as< Map<VectorXi> >(dpm_step["S"]);
    P=dpm_step["P"]; 
    Phi=dpm_step["Phi"];
    B=dpm_step["B"]; 
#endif
    
    if(l>=0 && l%thin == 0) {
      h = (l/thin);

#ifdef DEBUG_NEAL8
      GS[h]=List::create(Named("beta")=beta, Named("theta")=theta,
			 Named("C")=C+one, Named("phi")=phi, 
			 Named("states")=states, Named("alpha")=alpha, 
			 Named("S")=S+one, Named("P")=P, 
			 Named("Phi")=Phi, Named("B")=B);
#else
      if(alpha_fixed==0) // alpha random
	GS[h]=List::create(Named("beta")=beta, Named("theta")=theta, 
			   Named("C")=C, Named("phi")=phi, 
			   Named("states")=states, Named("alpha")=alpha);
      else GS[h]=List::create(Named("beta")=beta, Named("theta")=theta, 
                       Named("C")=C, Named("phi")=phi, Named("states")=states);
#endif

      // GS[h]=List::create(Named("beta")=beta, Named("theta")=theta, 
      //  			 Named("C")=C, Named("phi")=phi, Named("states")=states,
      // 			 Named("m")=m, Named("alpha")=alpha, Named("psi")=psi);
    }

    l++;

  } while (l<=(M-1)*thin); 

  return wrap(GS);
}