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