void GeneralizedEigenSystemSolverRealSymmetricMatrices(const Array2 < doublevar > & Ain, const Array2 < doublevar> & Bin, Array1 < doublevar> & evals, Array2 < doublevar> & evecs){
  //solves generalized eigensystem problem A.x=labda*B.x
  //returns eigenvalues from largest to lowest and
  //eigenvectors, where for i-th eigenvalue, the eigenvector components are evecs(*,i)
  //eigenvectors are normalized such that: evecs**T*B*evecs = I;
#ifdef USE_LAPACK //if LAPACK
  int N=Ain.dim[0];
  
  /* allocate and initialise the matrix */
  Array2 <doublevar> A_temp(N,N), B_temp(N,N);
  Array1 <doublevar>  W,WORK;
  
  
  /* allocate space for the output parameters and workspace arrays */
  W.Resize(N);
  A_temp=Ain;
  B_temp=Bin;
  
  int info;
  int NB=64;
  int NMAX=N;
  int lda=NMAX;
  int ldb=NMAX;
  int LWORK=(NB+2)*NMAX;
  WORK.Resize(LWORK);

  /* get the eigenvalues and eigenvectors */
  info=dsygv(1, 'V', 'U' , N,  A_temp.v,  lda,  B_temp.v, ldb, W.v, WORK.v, LWORK);

  if(info>0)
    error("Internal error in the LAPACK routine dsyevr");
  if(info<0)
    error("Problem with the input parameter of LAPACK routine dsyevr in position "-info);

  for (int i=0; i<N; i++)
    evals(i)=W[N-1-i];

  for (int i=0; i<N; i++) {
    for (int j=0; j<N; j++) {
      evecs(j,i)=A_temp(N-1-i,j);
    }
  }
 //END OF LAPACK 
#else //IF NO LAPACK
  //for now we will solve it only approximatively
   int N=Ain.dim[0];
   Array2 <doublevar> B_inverse(N,N),A_renorm(N,N);
   InvertMatrix(Bin,B_inverse,N);
   MultiplyMatrices(B_inverse,Ain,A_renorm,N);
   //note A_renorm is not explicitly symmetric
   EigenSystemSolverRealSymmetricMatrix(A_renorm,evals,evecs);
#endif //END OF NO LAPACK
}
Пример #2
0
RcppExport SEXP nniv(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 VectorXd t=as< Map<VectorXd> >(list2["t"]),
    y=as< Map<VectorXd> >(list2["y"]);

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

  // parameters
  List list1(arg1), 
    beta_info=list1["beta"], 
    Tprec_info=list1["Tprec"], 
    mu_info=list1["mu"], 
    theta_info=list1["theta"];

  // prior parameters
  List beta_prior=beta_info["prior"],
    Tprec_prior=Tprec_info["prior"],
    mu_prior=mu_info["prior"],
    theta_prior=theta_info["prior"];

  const double Tprec_prior_nu=as<double>(Tprec_prior["nu"]);
  const Matrix2d Tprec_prior_Psi=as< Map<MatrixXd> >(Tprec_prior["Psi"]);

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

  const Vector2d mu_prior_mean=as< Map<VectorXd> >(mu_prior["mean"]);
  const Matrix2d mu_prior_prec=as< Map<MatrixXd> >(mu_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"]); 

  Matrix2d Tprec=as< Map<MatrixXd> >(Tprec_info["init"]);
  Vector2d mu   =as< Map<VectorXd> >(mu_info["init"]);
  VectorXd theta=as< Map<VectorXd> >(theta_info["init"]);

  // Gibbs
  List list3(arg3); //, save=list3["save"];

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

  MatrixXd GS(M, m);

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

  VectorXd theta_prior_prod=theta_prior_prec * theta_prior_mean;

  Vector2d mu_prior_prod=mu_prior_prec*mu_prior_mean;

  // parameter intermediate values
  Matrix2d Sigma, B_inverse;

  Sigma=Tprec.inverse();
  B_inverse.setIdentity();

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

  /*
    MatrixXd Theta(2, r);

    Theta.row(0)=theta.segment(0, r);
    Theta.bottomLeftCorner(1, q)=RowVectorXd::Zero(q);
    Theta.bottomRightCorner(1, p)=eta.transpose();
  */

  Vector2d eps, eps_sum;

  MatrixXd D(N, 2), theta_cond_var_root(s, s), W(2, s);

  W.setZero();

  MatrixXd theta_cond_prec(s, s);

  VectorXd theta_cond_prod(s), w(r);

  Matrix2d mu_cond_prec, mu_cond_var_root, E;

  Vector2d u, R, mu_cond_prod, mu_u;

  double beta_scale, beta_prec, beta_prod, beta_cond_var, beta_cond_mean;

  int h=0, i, l; 


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

  l=-burnin;

  do{
    // sample beta
    D.col(0).setConstant(-mu[0]);
    D.col(1).setConstant(-mu[1]);

    D.col(0) += (t - X*gamma - Z*delta);
    D.col(1) += (y - X*eta);

    beta_scale=1./(Sigma(0, 0)*t.dot(t));

    beta_prec=1./(beta_scale*Sigma.determinant());

    beta_prod=beta_prec*beta_scale
      *((Sigma(0, 0)*D.col(1)-Sigma(0, 1)*D.col(0)).array()*t.array()).sum();

    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) {
      /*
	W.topLeftCorner(1, p)=X.row(i);
	W.block(0, p, 1, q)=Z.row(i);
	W.bottomRightCorner(1, p)=X.row(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);

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

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

      R=B_inverse*u-mu;

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

    theta_cond_var_root=inv_root_chol(theta_cond_prec);
    // theta_cond_var_root=inv_root_svd(theta_cond_prec); // for validation only

    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);

    /*
      Theta.topRows(1)=theta.segment(0, r).transpose();
      Theta.bottomRightCorner(1, p)=eta.transpose();
    */

    // sample mu
    eps_sum.setZero();
    //W.setZero();

    E.setZero();

    for(i=0; i<N; ++i) {
      /*
	W.topLeftCorner(1, p)=X.row(i);
	W.block(0, p, 1, q)=Z.row(i);
	W.bottomRightCorner(1, p)=X.row(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);

      /*
	w.segment(0, q)=Z.row(i);
	w.segment(q, p)=X.row(i);
      */

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

      //eps += B_inverse*u - Theta*w;
      eps = B_inverse*u - W*theta;
      eps_sum += eps;
      eps -= mu;
      E += eps*eps.transpose();
    }

    mu_cond_prod=Tprec*eps_sum+mu_prior_prod;

    mu_cond_prec=(N*Tprec+mu_prior_prec);

    mu_cond_var_root=inv_root_chol(mu_cond_prec);
    // mu_cond_var_root=inv_root_svd(mu_cond_prec); // for validation only

    mu=mu_cond_var_root*(rnormXd(2)+mu_cond_var_root.transpose()*mu_cond_prod);

    // sample Tprec
    Tprec = rwishart((E+Tprec_prior_Psi).inverse(), N+Tprec_prior_nu);
    Sigma = Tprec.inverse();

    if(l>=0 && l%thin == 0) {
      h = (l/thin);

      GS.block(h, 0, 1, s)=theta.transpose();

      GS(h, s)=beta;
      GS(h, s+1)=mu[0];
      GS(h, s+2)=mu[1];
      GS(h, s+3)=Tprec(0, 0);
      GS(h, s+4)=Tprec(0, 1);
      GS(h, s+5)=Tprec(0, 1);
      GS(h, s+6)=Tprec(1, 1);
    }

    l++;

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

  if(beta != beta) GS.conservativeResize(h+1, m);

  return wrap(GS);
}
Пример #3
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);
}