Exemple #1
0
void CParam::S4_alpha_i(CData &Data) {
  
  is_accept_vec(3) = 0 ; 
  // if ( normC < 0 ) normC = normC_fn(Beta, Data) ;	// Ver_1_4_1
  for (int i_pheno=0; i_pheno<n_pheno; i_pheno++){  // V_1_3_5 ; Update each alpha_i
    arma::mat Beta_prop = Beta ;
    RandVec = Rcpp::rnorm(1, Beta(i_pheno,i_pheno), Data.stepsize_alpha ) ;
    Beta_prop(i_pheno,i_pheno) = RandVec(0) ; 
    double logP_numer = R::dnorm(Beta_prop(i_pheno,i_pheno), Data.theta_alpha, sqrt(Data.tau2_alpha),1) ; // log=TRUE
    double logP_denom = R::dnorm(Beta(i_pheno,i_pheno), Data.theta_alpha, sqrt(Data.tau2_alpha),1) ; // log=TRUE
    double normC_prop = normC_fn(Beta_prop, Data) ;
    for (int i_SNP=0; i_SNP<n_SNP; i_SNP++){
      double e_it = E_mat(i_pheno,i_SNP) ;
      logP_numer = logP_numer + log( normC ) + Beta_prop(i_pheno,i_pheno) * e_it  ; 
      logP_denom = logP_denom + log( normC_prop ) + Beta(i_pheno,i_pheno) * e_it ;
    }
    double accept_prob = exp( logP_numer - logP_denom ) ; 
    accept_prob_vec(3) = accept_prob ;  
    RandVec = Rcpp::runif(1, 0, 1) ; 
    if ( accept_prob >= RandVec(0) ){
      Beta = Beta_prop ; normC = normC_prop ; 
      is_accept_vec(3) = is_accept_vec(3) + 1 ; 
    } 
  } // for (int i=0; i<n_pheno; i++){

  is_accept_vec(3) = 1.0 / n_pheno * is_accept_vec(3) ;
} 
Exemple #2
0
void CParam::S1_e_it(CData &Data) {
	
  for (int i_SNP=0; i_SNP<n_SNP; i_SNP++){
    for (int i=0; i<n_pheno; i++){
      if ( ( Data.Y(i,i_SNP) > 0 ) & ( Data.Y(i,i_SNP) <= Data.threshold_on ) ){ 
				// V 1.3.1 -> other case: e_it is fixed in CParam::Initialize, 
				//             i.e., e_it=0 if y_it<=0 and 1 if y_it>=Data.threshold_on
        double unnorm_logprob0 = 0.0 ;
        double unnorm_logprob1 = Beta(i,i) ;
        for (int j=0; j<n_pheno; j++){
          if (G_mat(i,j)==1) unnorm_logprob1 = unnorm_logprob1 + Beta(i,j) * E_mat(j,i_SNP) ; 
        }
				  // Note: Not count G_mat(i,j)=0 or G_mat(i,j)=9,i.e., diagonal
        unnorm_logprob0 = unnorm_logprob0 + R::dnorm(Data.Y(i,i_SNP),0,1,1) ; // log = T
        unnorm_logprob1 = unnorm_logprob1 + R::dlnorm(Data.Y(i,i_SNP),mu_vec(i),sqrt(sig2_vec(i)),1) ; // log = T
        double prob_e_it = 1.0 / ( 1.0 + exp(unnorm_logprob0-unnorm_logprob1) ) ; 
        	// Note: p1 = f1/(f1+f0) = 1 / (1+f0/f1) = 1 / (1+exp(log f0 - log f1)) 
				RandVec = Rcpp::runif(1,0,1) ;
        if ( prob_e_it >= RandVec(0) ){
          E_mat(i,i_SNP) = 1 ; 
        } else {
          E_mat(i,i_SNP) = 0 ; 
        }
      }         
      // To check loglikelihood
      if (E_mat(i,i_SNP)==1){
        loglikelihood = loglikelihood + R::dlnorm(Data.Y(i,i_SNP),mu_vec(i),sqrt(sig2_vec(i)),1)  ;
      } else {
        loglikelihood = loglikelihood + R::dnorm(Data.Y(i,i_SNP),0,1,1) ;
      }
		} 
  }
	
  is_accept_vec(0) = 1 ; 
} 
Exemple #3
0
double CParam::rtruncNorm_uppertail_fn(double mean, double sd, double lowerlimit){
  RandVec = Rcpp::runif(1,0,1) ; 
  double std_lowerlimit = (lowerlimit-mean) / sd ; 
  double temp_pnorm = (1.0-R::pnorm(std_lowerlimit,0,1,1,0)) * RandVec(0) ; // x,mu,sigma,lt,lg
  double std_x = -1.0 * R::qnorm(temp_pnorm,0,1,1,0) ;  // p,mu,sigma,lt,lg
  return( mean + std_x * sd ) ;
}
Exemple #4
0
double CParam::rinvgamma(double alpha, double beta){
  RandVec = Rcpp::rgamma(1, alpha, (1.0/beta) ) ; 
  return ( 1.0 / RandVec(0) ) ; 
  // Note that b in Rcpp::rgamma(a,b) is scale, 
  // i.e., its mean is ab, NOT a/b  
  // If X ~ Gamma(a,b), then 1/X ~ IG(a,1/b)
}
Exemple #5
0
void CParam::S5_beta_ij(CData &Data) {
  
	is_accept_vec(4) = 0 ; 
	int w_cur = 0 ; // just for calculation of is_accept_vec( ) 
	for (int i=0; i<(n_pheno-1); i++){
		for (int j=(i+1); j<n_pheno; j++){
			if ( G_mat(i,j)==1 ){
				w_cur ++ ; 
			  arma::mat Beta_prop = Beta ;
			  
				double temp_beta_prop = 0.0 ; 
				while ( temp_beta_prop <= 0.0 ){
					temp_beta_prop = rtruncNorm_uppertail_fn(Beta(i,j), Data.stepsize_beta, 0) ;
				}
				Beta_prop(i,j) = temp_beta_prop ; 
				Beta_prop(j,i) = temp_beta_prop ;
				double logP_numer = R::dgamma(Beta_prop(i,j),Data.a_beta,(1.0/Data.b_beta),1) ;   // (shape,scale,log), i.e., b_beta = rate // V_1_3_5
			  double logP_denom = R::dgamma(Beta(i,j),Data.a_beta,(1.0/Data.b_beta),1) ;         // 
        double normC_prop = normC_fn(Beta_prop, Data) ;
			  for (int i_SNP=0; i_SNP<n_SNP; i_SNP++){
			    double e_it = E_mat(i,i_SNP) ;
			    double e_jt = E_mat(j,i_SNP) ; 
			    logP_numer = logP_numer + log(normC) + Beta_prop(i,j) * e_it * e_jt ; 
			    logP_denom = logP_denom + log(normC_prop) + Beta(i,j) * e_it * e_jt ; 
			  }
			  double logQ_numer = log( dtruncnorm_uppertail_fn(Beta(i,j), 0, Beta_prop(i,j), Data.stepsize_beta) ) ; // CHECK
			  double logQ_denom = log( dtruncnorm_uppertail_fn(Beta_prop(i,j), 0, Beta(i,j), Data.stepsize_beta) ) ;
				double accept_prob = exp( logP_numer - logP_denom + logQ_numer - logQ_denom ) ; 
			  accept_prob_vec(4) = accept_prob ;  
        RandVec = Rcpp::runif(1, 0, 1) ; 
			  if ( accept_prob >= RandVec(0) ){
			    Beta = Beta_prop ; normC = normC_prop ; 
					is_accept_vec(4) = is_accept_vec(4) + 1 ; 
			  } 
			}
		}
	}
	
	if ( w_cur == 0 ){
	  is_accept_vec(4) = 0.2 ; 
	} else {
	  is_accept_vec(4) = 1.0 / w_cur * is_accept_vec(4) ; 
	}
} 
Exemple #6
0
void CParam::S2_mu_i(CData &Data) {

	for (int i=0; i<n_pheno; i++){
		double sig2_i = sig2_vec(i) ;
		arma::vec e_i = E_mat.row(i).t() ; 
		double n_i = sum(e_i) ; 
		arma::vec logy_i = Data.logY.row(i).t() ;  
		arma::vec e1_logy = logy_i % e_i ; 
		double sum_e1_logy = sum(e1_logy) ; 
			// Note: % Schur product: element-wise multiplication of two objects
			//         sum of log_y_it with e_it=1
		double mean_star = (sig2_i * Data.theta_mu + Data.tau2_mu * sum_e1_logy) / (sig2_i + Data.tau2_mu * n_i) ; 
		double var_star = (sig2_i * Data.tau2_mu)/(sig2_i + Data.tau2_mu * n_i) ; 
		RandVec = Rcpp::rnorm(1, mean_star, sqrt(var_star)) ; 
		mu_vec(i) = RandVec(0) ;
  } 
	
	is_accept_vec(1) = 1 ; 
} 
// Generate a random point uniformly distrbuted within the domain
void pDomain::Generate(pVector &pos) const
{
	switch (type)
	{
	case PDPoint:
		pos = p1;
		break;
	case PDLine:
		pos = p1 + p2 * drand48();
		break;
	case PDBox:
		// Scale and translate [0,1] random to fit box
		pos.x = p1.x + (p2.x - p1.x) * drand48();
		pos.y = p1.y + (p2.y - p1.y) * drand48();
		pos.z = p1.z + (p2.z - p1.z) * drand48();
		break;
	case PDTriangle:
		{
			float r1 = drand48();
			float r2 = drand48();
			if(r1 + r2 < 1.0f)
				pos = p1 + u * r1 + v * r2;
			else
				pos = p1 + u * (1.0f-r1) + v * (1.0f-r2);
		}
		break;
	case PDRectangle:
		pos = p1 + u * drand48() + v * drand48();
		break;
	case PDPlane: // How do I sensibly make a point on an infinite plane?
		pos = p1;
		break;
	case PDSphere:
		// Place on [-1..1] sphere
		pos = RandVec() - vHalf;
		pos.normalize();
		
		// Scale unit sphere pos by [0..r] and translate
		// (should distribute as r^2 law)
		if(radius1 == radius2)
			pos = p1 + pos * radius1;
		else
			pos = p1 + pos * (radius2 + drand48() * (radius1 - radius2));
		break;
	case PDCylinder:
	case PDCone:
		{
			// For a cone, p2 is the apex of the cone.
			float dist = drand48(); // Distance between base and tip
			float theta = drand48() * 2.0f * float(M_PI); // Angle around axis
			// Distance from axis
			float r = radius2 + drand48() * (radius1 - radius2);
			
			float x = r * cosf(theta); // Weighting of each frame vector
			float y = r * sinf(theta);
			
			// Scale radius along axis for cones
			if(type == PDCone)
			{
				x *= dist;
				y *= dist;
			}
			
			pos = p1 + p2 * dist + u * x + v * y;
		}
		break;
	case PDBlob:
		pos.x = p1.x + NRand(radius1);
		pos.y = p1.y + NRand(radius1);
		pos.z = p1.z + NRand(radius1);
		
		break;
	case PDDisc:
		{
			float theta = drand48() * 2.0f * float(M_PI); // Angle around normal
			// Distance from center
			float r = radius2 + drand48() * (radius1 - radius2);
			
			float x = r * cosf(theta); // Weighting of each frame vector
			float y = r * sinf(theta);
			
			pos = p1 + u * x + v * y;
		}
		break;
	default:
		pos = pVector(0,0,0);
	}
}
Exemple #8
0
int CParam::rDiscrete(int max_no){
  // generate an integer from 0 to (max_no-1)
  double max_no_ = 1.0 * max_no ; 
  RandVec = Rcpp::runif(1, 0.0, max_no_) ; 
  return ( floor(RandVec(0)) ) ; 
}
Exemple #9
0
void CParam::check_random_generate(CData &Data){
  RandVec = Rcpp::rnorm(2,2,1000) ;
  std::cout << RandVec(0) << "  " << RandVec(1) << std::endl ; 
  // std::cout << pow(10,-3) << std::endl ; 
}
Exemple #10
0
void CParam::S6_G_beta_ij(CData &Data) {
  
  arma::mat G_prop = G_mat ; arma::mat Beta_prop = Beta ; 
  double logQ_numer, logQ_denom ; 
  double logP_numer, logP_denom ;
  double normC_prop ;
  
  bool is_forcein_edge_selected = false ;
  
	// double P_G_q, P_G ; // For updated E(i,j)
	
  // Step 1
  int w_cur = 0 ; int w_max = 0 ; int w_prop ; 
  for (int i=0; i<(n_pheno-1); i++){
    for (int j=(i+1); j<n_pheno; j++){
      w_max ++ ; w_cur = w_cur + G_mat(i,j) ; 
    }
  }
  if ( w_cur==0 ){ w_prop = 1 ; logQ_numer = log(0.5) ; logQ_denom = log(1.0) ; } // q(w|w^q) // q(w^q|w)
  if ( w_cur==w_max ){ w_prop = w_max - 1 ; logQ_numer = log(0.5) ;  logQ_denom = log(1.0) ; } // q(w|w^q) // q(w^q|w)
  if ( (w_cur > 0) && (w_cur < w_max) ){
    RandVec = Rcpp::runif(1, 0, 1) ; 
    if ( RandVec(0) < 0.5 ){ w_prop = w_cur + 1 ; } else { w_prop = w_cur - 1 ; }
    logQ_denom = log(0.5) ; // q(w^q|w)
    if ( (w_prop==0) || (w_prop==w_max) ){ logQ_numer = log(1.0) ; } else { logQ_numer = log(0.5) ; } // q(w|w^q)
  }
  
  // Step 2
  if ( w_prop > w_cur  ){ // step 2-a
    
		int id_added = rDiscrete(w_max-w_cur) + 1 ; // 1 ~ total. of empty edges
    int count_empty_edge = 0 ;
		
    for (int i=0; i<(n_pheno-1); i++){
      for (int j=(i+1); j<n_pheno; j++){
        if ( G_mat(i,j)==0 ){
          count_empty_edge++;
          if ( id_added==count_empty_edge ){
            G_prop(i,j) = 1 ; G_prop(j,i) = G_prop(i,j) ; 
            RandVec = Rcpp::rgamma(1, Data.a_betaG, 1.0/Data.b_betaG) ; // q(beta_ij^q)
            Beta_prop(i,j) = RandVec(0) ; 
            Beta_prop(j,i) = Beta_prop(i,j) ; 
            id_added = -9 ; 
            
						// if ( Data.PriorSetting==2 ){
						//	P_G = 1.0 - Data.priorprob_G(i,j) ; // Bernoulli(E_ij=0; p_ij)
						//	P_G_q = Data.priorprob_G(i,j) ; // Bernoulli(E_ij^q=1; p_ij)
						// }
												
            logP_numer = R::dgamma(Beta_prop(i,j),Data.a_beta,(1.0/Data.b_beta),1) ; // f(beta_ij^q|G_ij^q)
            logP_denom = 0 ; // f(beta_ij|G_ij) cancelled with q(beta_ij)
            normC_prop = normC_fn(Beta_prop, Data) ;
            for (int i_SNP=0; i_SNP<n_SNP; i_SNP++){
              double e_it = E_mat(i,i_SNP) ;
              double e_jt = E_mat(j,i_SNP) ; 
              logP_numer = logP_numer - log(normC_prop) + Beta_prop(i,j) * e_it * e_jt ; // f(e_t|alpha,beta^q,G^q)
              logP_denom = logP_denom - log(normC) + Beta(i,j) * e_it * e_jt ; // f(e_t|alpha,beta,G)
            }
            logQ_numer = logQ_numer + 0 ; // q(beta_ij) cancelled with f(beta_ij|G_ij)  
            logQ_denom = logQ_denom + R::dgamma(Beta_prop(i,j),Data.a_betaG,(1.0/Data.b_betaG),1) ; // q(beta_ij^q)
          } // if ( id_added==count_empty_edge ) 
        } // for ( G_mat(i,j)==0 )
      } // for (j)
    } // for (i)
		
    logQ_numer = logQ_numer - log(w_cur) ; // q(G|G^q,w)
    logQ_denom = logQ_denom - log(w_max-w_cur)  ; // q(G^q|G,w^q)
  
	} else { // step 2-b
	
    int id_deleted = rDiscrete(w_cur)+1 ; // 1 ~ total no. of connected edges
    int count_connected_edge = 0 ; 
    for (int i=0; i<(n_pheno-1); i++){
      for (int j=(i+1); j<n_pheno; j++){
        if ( G_mat(i,j)==1 ){
          count_connected_edge++;
          if ( id_deleted==count_connected_edge ){
            G_prop(i,j) = 0 ; G_prop(j,i) = G_prop(i,j) ; 
            Beta_prop(i,j) = 0 ; // q(beta_ij^q)
            Beta_prop(j,i) = Beta_prop(i,j) ; 
            id_deleted = -9 ; 
            
            if (Data.isforcein==true){
              if (Data.E_forcein_mat(i,j)==1) is_forcein_edge_selected = true ; 
            }
            
						// if ( Data.PriorSetting==2 ){
						//	P_G = Data.priorprob_G(i,j) ; // Bernoulli(E_ij=1; p_ij)
						//	P_G_q = 1.0 - Data.priorprob_G(i,j) ; // Bernoulli(E_ij^q=0; p_ij)
						// }
						
            logP_numer = 0 ; // f(beta_ij^q|G_ij^q) cancelled with q(beta_ij^q)
            logP_denom = R::dgamma(Beta(i,j),Data.a_beta,(1.0/Data.b_beta),1) ; // f(beta_ij|G_ij)
            normC_prop = normC_fn(Beta_prop, Data) ;
            for (int i_SNP=0; i_SNP<n_SNP; i_SNP++){
              double e_it = E_mat(i,i_SNP) ;
              double e_jt = E_mat(j,i_SNP) ; 
              logP_numer = logP_numer - log(normC_prop) + Beta_prop(i,j) * e_it * e_jt ; // f(e_t|alpha,beta^q,G^q)
              logP_denom = logP_denom - log(normC) + Beta(i,j) * e_it * e_jt ; // f(e_t|alpha,beta,G)
            }
            logQ_numer = logQ_numer + R::dgamma(Beta(i,j),Data.a_betaG,(1.0/Data.b_betaG),1) ; // q(beta_ij) 
            logQ_denom = logQ_denom + 0 ; // q(beta_ij^q) cancelled with f(beta_ij^q|G_ij^q) 
          }
        } 
      }
    }
    logQ_numer = logQ_numer - log(w_max-w_cur) ; // q(G|G^q,w)
    logQ_denom = logQ_denom - log(w_cur) ; // q(G^q|G,w^q)
    
  }
	
	// if ( Data.PriorSetting==1 ){
	  if ( w_prop > 0 ) logP_numer = logP_numer - log(w_prop) ; // f(G^q) // if w_prop=0, let 1/w_prop = 1, so that log(w_prop) = 0
	  if ( w_cur > 0 ) logP_denom = logP_denom - log(w_cur) ; // f(G) // if w_cur=0, let 1/w_cur = 1, so that log(w_cur) = 0
	// }
	// if ( Data.PriorSetting==2 ){
	//  if ( w_prop > 0 ) logP_numer = logP_numer + log(P_G_q) ; 
	//  if ( w_cur > 0 ) logP_denom = logP_denom + log(P_G) ; 
	// }

  // Step 3  
  double accept_prob = exp( logP_numer - logP_denom + logQ_numer - logQ_denom ) ; 
  
  if (is_forcein_edge_selected==true) accept_prob = 0 ;
  
  accept_prob_vec(5) = accept_prob ;  
  RandVec = Rcpp::runif(1, 0, 1) ; 
  if ( accept_prob >= RandVec(0) ){
    Beta = Beta_prop ; G_mat = G_prop ; normC = normC_prop ; 
    is_accept_vec(5) = 1 ; 
  } else {
    is_accept_vec(5) = 0 ; 
  }
} 
Exemple #11
0
int main(int argc, char *argv[])
{
  int ierr = 0, i, j, forierr = 0;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;




  //char tmp;
  //if (Comm.MyPID()==0) cout << "Press any key to continue..."<< endl;
  //if (Comm.MyPID()==0) cin >> tmp;
  //Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if (verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
              << " is alive."<<endl;

  // Redefine verbose to only print on PE 0
  if (verbose && Comm.MyPID()!=0) verbose = false;

  int NumMyEquations = 20;
  long long NumGlobalEquations = NumMyEquations*NumProc+EPETRA_MIN(NumProc,3);
  if (MyPID < 3) NumMyEquations++;
  // Construct a Source Map that puts approximately the same Number of equations on each processor in
  // uniform global ordering

  Epetra_Map SourceMap(NumGlobalEquations, NumMyEquations, 0LL, Comm);

  // Get update list and number of local equations from newly created Map
  int NumMyElements = SourceMap.NumMyElements();
  long long * SourceMyGlobalElements = new long long[NumMyElements];
  SourceMap.MyGlobalElements(SourceMyGlobalElements);

  // Construct a Target Map that will contain:
  //  some unchanged elements (relative to the soure map),
  //  some permuted elements
  //  some off-processor elements
  Epetra_Vector RandVec(SourceMap);
  RandVec.Random(); // This creates a vector of random numbers between negative one and one.

  long long *TargetMyGlobalElements = new long long[NumMyElements];

  long long MinGID = SourceMap.MinMyGID64();
  for (i=0; i< NumMyEquations/2; i++) TargetMyGlobalElements[i] = i + MinGID; // Half will be the same...
  for (i=NumMyEquations/2; i<NumMyEquations; i++) {
    int index = abs((int)(((double) (NumGlobalEquations-1) ) * RandVec[i]));
    TargetMyGlobalElements[i] = EPETRA_MIN(NumGlobalEquations-1,(long long) EPETRA_MAX(0,index));
  }

  int NumSameIDs = 0;
  int NumPermutedIDs = 0;
  int NumRemoteIDs = 0;
  bool StillContiguous = true;
  for (i=0; i < NumMyEquations; i++) {
    if (SourceMyGlobalElements[i]==TargetMyGlobalElements[i] && StillContiguous)
      NumSameIDs++;
    else if (SourceMap.MyGID(TargetMyGlobalElements[i])) {
      StillContiguous = false;
      NumPermutedIDs++;
    }
    else {
      StillContiguous = false;
      NumRemoteIDs++;
    }
  }
  EPETRA_TEST_ERR(!(NumMyEquations==NumSameIDs+NumPermutedIDs+NumRemoteIDs),ierr);

  Epetra_Map TargetMap((long long) -1, NumMyElements, TargetMyGlobalElements, 0LL, Comm);

  // Create a multivector whose elements are GlobalID * (column number +1)

  int NumVectors = 3;
  Epetra_MultiVector SourceMultiVector(SourceMap, NumVectors);
  for (j=0; j < NumVectors; j++)
    for (i=0; i < NumMyElements; i++)
      SourceMultiVector[j][i] = (double) SourceMyGlobalElements[i]*(j+1);

  // Create a target multivector that we will fill using an Import

  Epetra_MultiVector TargetMultiVector(TargetMap, NumVectors);

  Epetra_Import Importer(TargetMap, SourceMap);

  EPETRA_TEST_ERR(!(TargetMultiVector.Import(SourceMultiVector, Importer, Insert)==0),ierr);

  // Test Target against expected values
  forierr = 0;
  for (j=0; j < NumVectors; j++)
    for (i=0; i < NumMyElements; i++) {
      if (TargetMultiVector[j][i]!= (double) TargetMyGlobalElements[i]*(j+1))
	cout << "TargetMultiVector["<<i<<"]["<<j<<"] = " << TargetMultiVector[j][i]
	     <<  "  TargetMyGlobalElements[i]*(j+1) = " <<  TargetMyGlobalElements[i]*(j+1) << endl;
      forierr += !(TargetMultiVector[j][i]== (double) TargetMyGlobalElements[i]*(j+1));
    }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "MultiVector Import using Importer Check OK" << endl << endl;


  //////////////////////////////////////////////////////////////////////////////

  // Now use Importer to do an export

  Epetra_Vector TargetVector(SourceMap);
  Epetra_Vector ExpectedTarget(SourceMap);
  Epetra_Vector SourceVector(TargetMap);

  NumSameIDs = Importer.NumSameIDs();
  int NumPermuteIDs = Importer.NumPermuteIDs();
  int NumExportIDs = Importer.NumExportIDs();
  int *PermuteFromLIDs = Importer.PermuteFromLIDs();
  int *ExportLIDs = Importer.ExportLIDs();
  int *ExportPIDs = Importer.ExportPIDs();

  for (i=0; i < NumSameIDs; i++) ExpectedTarget[i] = (double) (MyPID+1);
  for (i=0; i < NumPermuteIDs; i++) ExpectedTarget[PermuteFromLIDs[i]] =
				      (double) (MyPID+1);
  for (i=0; i < NumExportIDs; i++) ExpectedTarget[ExportLIDs[i]] +=
				     (double) (ExportPIDs[i]+1);

  for (i=0; i < NumMyElements; i++) SourceVector[i] =  (double) (MyPID+1);

  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, Importer, Add)==0),ierr);

  forierr = 0;
  for (i=0; i < NumMyElements; i++) {
    if (TargetVector[i]!= ExpectedTarget[i])
      cout <<  "     TargetVector["<<i<<"] = " << TargetVector[i]
	   <<  "   ExpectedTarget["<<i<<"] = " <<  ExpectedTarget[i] << " on PE " << MyPID << endl;
    forierr += !(TargetVector[i]== ExpectedTarget[i]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Vector Export using Importer Check OK" << endl << endl;

  //////////////////////////////////////////////////////////////////////////////
  // Now use Importer to create a reverse exporter
  TargetVector.PutScalar(0.0);
  Epetra_Export ReversedImport(Importer);

  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, ReversedImport, Add)==0),ierr);

  forierr = 0;
  for (i=0; i < NumMyElements; i++) {
    if (TargetVector[i]!= ExpectedTarget[i])
      cout <<  "     TargetVector["<<i<<"] = " << TargetVector[i]
	   <<  "   ExpectedTarget["<<i<<"] = " <<  ExpectedTarget[i] << " on PE " << MyPID << endl;
    forierr += !(TargetVector[i]== ExpectedTarget[i]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Vector Export using Reversed Importer Check OK" << endl << endl;

  //////////////////////////////////////////////////////////////////////////////
  // Now use Exporter to create a reverse importer
  TargetVector.PutScalar(0.0);
  Epetra_Import ReversedExport(ReversedImport);

  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, ReversedExport, Add)==0),ierr);

  forierr = 0;
  for (i=0; i < NumMyElements; i++) {
    if (TargetVector[i]!= ExpectedTarget[i])
      cout <<  "     TargetVector["<<i<<"] = " << TargetVector[i]
	   <<  "   ExpectedTarget["<<i<<"] = " <<  ExpectedTarget[i] << " on PE " << MyPID << endl;
    forierr += !(TargetVector[i]== ExpectedTarget[i]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Vector Export using Reversed Exporter Check OK" << endl << endl;


  //////////////////////////////////////////////////////////////////////////////////////////
  //  Build a tridiagonal system two ways:
  //  1) From "standard" matrix view where equations are uniquely owned.
  //  2) From 1D PDE view where nodes (equations) between processors are shared and partial contributions are done
  //     in parallel, then merged together at the end of the construction process.
  //
  //////////////////////////////////////////////////////////////////////////////////////////



  // Construct a Standard Map that puts approximately the same number of equations on each processor in
  // uniform global ordering

  Epetra_Map StandardMap(NumGlobalEquations, NumMyEquations, 0LL, Comm);

  // Get update list and number of local equations from newly created Map
  NumMyElements = StandardMap.NumMyElements();
  long long * StandardMyGlobalElements = new long long[NumMyElements];
  StandardMap.MyGlobalElements(StandardMyGlobalElements);


  // Create a standard Epetra_CrsGraph

  Epetra_CrsGraph StandardGraph(Copy, StandardMap, 3);
  EPETRA_TEST_ERR(StandardGraph.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(StandardGraph.IndicesAreLocal(),ierr);

  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  long long *Indices = new long long[2];
  int NumEntries;

  forierr = 0;
  for (i=0; i<NumMyEquations; i++)
    {
    if (StandardMyGlobalElements[i]==0)
      {
	Indices[0] = 1;
	NumEntries = 1;
      }
    else if (StandardMyGlobalElements[i] == NumGlobalEquations-1)
      {
	Indices[0] = NumGlobalEquations-2;
	NumEntries = 1;
      }
    else
      {
	Indices[0] = StandardMyGlobalElements[i]-1;
	Indices[1] = StandardMyGlobalElements[i]+1;
	NumEntries = 2;
      }
    forierr += !(StandardGraph.InsertGlobalIndices(StandardMyGlobalElements[i], NumEntries, Indices)==0);
    forierr += !(StandardGraph.InsertGlobalIndices(StandardMyGlobalElements[i], 1, StandardMyGlobalElements+i)==0); // Put in the diagonal entry
    }
  EPETRA_TEST_ERR(forierr,ierr);

  // Finish up
  EPETRA_TEST_ERR(!(StandardGraph.IndicesAreGlobal()),ierr);
  EPETRA_TEST_ERR(!(StandardGraph.FillComplete()==0),ierr);
  EPETRA_TEST_ERR(!(StandardGraph.IndicesAreLocal()),ierr);
  EPETRA_TEST_ERR(StandardGraph.StorageOptimized(),ierr);
  StandardGraph.OptimizeStorage();
  EPETRA_TEST_ERR(!(StandardGraph.StorageOptimized()),ierr);
  EPETRA_TEST_ERR(StandardGraph.UpperTriangular(),ierr);
  EPETRA_TEST_ERR(StandardGraph.LowerTriangular(),ierr);

  // Create Epetra_CrsMatrix using the just-built graph

  Epetra_CrsMatrix StandardMatrix(Copy, StandardGraph);
  EPETRA_TEST_ERR(StandardMatrix.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);

  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  double *Values = new double[2];
  Values[0] = -1.0; Values[1] = -1.0;
  double two = 2.0;

  forierr = 0;
  for (i=0; i<NumMyEquations; i++)
    {
    if (StandardMyGlobalElements[i]==0)
      {
	Indices[0] = 1;
	NumEntries = 1;
      }
    else if (StandardMyGlobalElements[i] == NumGlobalEquations-1)
      {
	Indices[0] = NumGlobalEquations-2;
	NumEntries = 1;
      }
    else
      {
	Indices[0] = StandardMyGlobalElements[i]-1;
	Indices[1] = StandardMyGlobalElements[i]+1;
	NumEntries = 2;
      }
    forierr += !(StandardMatrix.ReplaceGlobalValues(StandardMyGlobalElements[i], NumEntries, Values, Indices)==0);
    // Put in the diagonal entry
    forierr += !(StandardMatrix.ReplaceGlobalValues(StandardMyGlobalElements[i], 1, &two, StandardMyGlobalElements+i)==0);
    }
  EPETRA_TEST_ERR(forierr,ierr);

  // Finish up
  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.FillComplete()==0),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);
  //  EPETRA_TEST_ERR((StandardMatrix.StorageOptimized()),ierr);
  EPETRA_TEST_ERR((StandardMatrix.OptimizeStorage()),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.StorageOptimized()),ierr);
  EPETRA_TEST_ERR(StandardMatrix.UpperTriangular(),ierr);
  EPETRA_TEST_ERR(StandardMatrix.LowerTriangular(),ierr);

  // Construct an Overlapped Map of StandardMap that include the endpoints from two neighboring processors.

  int OverlapNumMyElements;
  long long OverlapMinMyGID;

  OverlapNumMyElements = NumMyElements + 1;
  if (MyPID==0) OverlapNumMyElements--;

  if (MyPID==0) OverlapMinMyGID = StandardMap.MinMyGID64();
  else OverlapMinMyGID = StandardMap.MinMyGID64()-1;

  long long * OverlapMyGlobalElements = new long long[OverlapNumMyElements];

  for (i=0; i< OverlapNumMyElements; i++) OverlapMyGlobalElements[i] = OverlapMinMyGID + i;

  Epetra_Map OverlapMap((long long) -1, OverlapNumMyElements, OverlapMyGlobalElements, 0LL, Comm);

  // Create the Overlap Epetra_Matrix

  Epetra_CrsMatrix OverlapMatrix(Copy, OverlapMap, 4);
  EPETRA_TEST_ERR(OverlapMatrix.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(OverlapMatrix.IndicesAreLocal(),ierr);

  // Add  matrix element one cell at a time.
  // Each cell does an incoming and outgoing flux calculation


  double pos_one = 1.0;
  double neg_one = -1.0;

  forierr = 0;
  for (i=0; i<OverlapNumMyElements; i++)
    {
      long long node_left = OverlapMyGlobalElements[i]-1;
      long long node_center = node_left + 1;
      long long node_right = node_left + 2;
      if (i>0) {
	if (node_left>-1)
	  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &neg_one, &node_left)==0);
	forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0);
      }
      if (i<OverlapNumMyElements-1) {
	forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0);
	if (node_right<NumGlobalEquations)
	  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &neg_one, &node_right)==0);
      }
    }
  EPETRA_TEST_ERR(forierr,ierr);

  // Handle endpoints
  if (MyPID==0) {
    long long node_center = 0;
    EPETRA_TEST_ERR(!(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0),ierr);
  }
  if (MyPID==NumProc-1) {
    long long node_center = OverlapMyGlobalElements[OverlapNumMyElements-1];
    EPETRA_TEST_ERR(!(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0),ierr);
  }

  EPETRA_TEST_ERR(!(OverlapMatrix.FillComplete()==0),ierr);

  // Make a gathered matrix from OverlapMatrix.  It should be identical to StandardMatrix

  Epetra_CrsMatrix GatheredMatrix(Copy, StandardGraph);
  Epetra_Export Exporter(OverlapMap, StandardMap);
  EPETRA_TEST_ERR(!(GatheredMatrix.Export(OverlapMatrix, Exporter, Add)==0),ierr);
  EPETRA_TEST_ERR(!(GatheredMatrix.FillComplete()==0),ierr);

  // Check if entries of StandardMatrix and GatheredMatrix are identical

  int StandardNumEntries, GatheredNumEntries;
  int * StandardIndices, * GatheredIndices;
  double * StandardValues, * GatheredValues;

  int StandardNumMyNonzeros = StandardMatrix.NumMyNonzeros();
  int GatheredNumMyNonzeros = GatheredMatrix.NumMyNonzeros();
  EPETRA_TEST_ERR(!(StandardNumMyNonzeros==GatheredNumMyNonzeros),ierr);

  int StandardNumMyRows = StandardMatrix.NumMyRows();
  int GatheredNumMyRows = GatheredMatrix.NumMyRows();
  EPETRA_TEST_ERR(!(StandardNumMyRows==GatheredNumMyRows),ierr);

  forierr = 0;
  for (i=0; i< StandardNumMyRows; i++)
    {
      forierr += !(StandardMatrix.ExtractMyRowView(i, StandardNumEntries, StandardValues, StandardIndices)==0);
      forierr += !(GatheredMatrix.ExtractMyRowView(i, GatheredNumEntries, GatheredValues, GatheredIndices)==0);
      forierr += !(StandardNumEntries==GatheredNumEntries);
      for (j=0; j < StandardNumEntries; j++) {
	//if (StandardIndices[j]!=GatheredIndices[j])
	// cout << "MyPID = " << MyPID << " i = " << i << "   StandardIndices[" << j << "] = " << StandardIndices[j]
	//      << "   GatheredIndices[" << j << "] = " << GatheredIndices[j] << endl;
	//if (StandardValues[j]!=GatheredValues[j])
	//cout << "MyPID = " << MyPID << " i = " << i << "    StandardValues[" << j << "] = " <<  StandardValues[j]
	//     << "    GatheredValues[" << j << "] = " <<  GatheredValues[j] << endl;
	forierr += !(StandardIndices[j]==GatheredIndices[j]);
	forierr += !(StandardValues[j]==GatheredValues[j]);
      }
    }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Matrix Export Check OK" << endl << endl;

  //Do Again with use of Epetra_OffsetIndex object for speed
  Epetra_OffsetIndex OffsetIndex( OverlapMatrix.Graph(), GatheredMatrix.Graph(), Exporter );
  EPETRA_TEST_ERR(!(GatheredMatrix.Export(OverlapMatrix, Exporter, Add)==0),ierr);

  if (verbose) cout << "Optimized Matrix Export Check OK" << endl << endl;

  bool passed;
  Epetra_LongLongVector v1(StandardMap); v1.PutValue(2);
  Epetra_LongLongVector v2(StandardMap); v2.PutValue(3);

  Epetra_Export identExporter(StandardMap,StandardMap); // Identity exporter
  EPETRA_TEST_ERR(!(v2.Export(v1, identExporter, Insert)==0),ierr);
  passed = (v2.MinValue()==2);
  EPETRA_TEST_ERR(!passed,ierr);

  v1.PutValue(1);
  Epetra_Import identImporter(StandardMap,StandardMap); // Identity importer
  EPETRA_TEST_ERR(!(v2.Import(v1, identExporter, Insert)==0),ierr);
  passed = passed && (v2.MaxValue()==1);
  EPETRA_TEST_ERR(!passed,ierr);

  if (verbose) {
    if (passed) cout << "Identity Import/Export Check OK" << endl << endl;
    else cout << "Identity Import/Export Check Failed" << endl << endl;
  }

  int NumSubMapElements = StandardMap.NumMyElements()/2;
  int SubStart = Comm.MyPID();
  NumSubMapElements = EPETRA_MIN(NumSubMapElements,StandardMap.NumMyElements()-SubStart);
  Epetra_Map SubMap((long long) -1, NumSubMapElements, StandardMyGlobalElements+SubStart, 0LL, Comm);

  Epetra_LongLongVector v3(View, SubMap, SubMap.MyGlobalElements64()); // Fill v3 with GID values for variety
  Epetra_Export subExporter(SubMap, StandardMap); // Export to a subset of indices of standard map
  EPETRA_TEST_ERR(!(v2.Export(v3,subExporter,Insert)==0),ierr);

  forierr = 0;
  for (i=0; i<SubMap.NumMyElements(); i++) {
    int i1 = StandardMap.LID(SubMap.GID64(i));
    forierr += !(v3[i]==v2[i1]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  Epetra_Import subImporter(StandardMap, SubMap); // Import to a subset of indices of standard map
  EPETRA_TEST_ERR(!(v1.Import(v3,subImporter,Insert)==0),ierr);

  for (i=0; i<SubMap.NumMyElements(); i++) {
    int i1 = StandardMap.LID(SubMap.GID64(i));
    forierr += !(v3[i]==v1[i1]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) {
    if (forierr==0) cout << "SubMap Import/Export Check OK" << endl << endl;
    else cout << "SubMap Import/Export Check Failed" << endl << endl;
  }

#ifdef DOESNT_WORK_IN_PARALLEL
  forierr = special_submap_import_test(Comm);
  EPETRA_TEST_ERR(forierr, ierr);

  if (verbose) {
    if (forierr==0) cout << "Special SubMap Import Check OK" << endl << endl;
    else cout << "Special SubMap Import Check Failed" << endl << endl;
  }
#endif

  forierr =  alternate_import_constructor_test(Comm);
  EPETRA_TEST_ERR(forierr, ierr);

  if (verbose) {
    if (forierr==0) cout << "Alternative Import Constructor Check OK" << endl << endl;
    else cout << "Alternative Import Constructor Check Failed" << endl << endl;
  }

  // Release all objects

  delete [] SourceMyGlobalElements;
  delete [] TargetMyGlobalElements;
  delete [] OverlapMyGlobalElements;
  delete [] StandardMyGlobalElements;

  delete [] Values;
  delete [] Indices;

#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

/* end main
*/
return ierr ;
}