// NAIVER Algorithmus matrix& mult(polynom const& p, matrix const& A, matrix& ret) { int deg=p.size(); deg-=1; int n =A.size(); ret=nullmatrix(n,n,ret); if(deg==-1) return ret; // Nullpolynom ret=p[0]*einsmatrix(n,ret); if(deg==0) return ret; // konstantes Polynom matrix Ai=A; ret=ret+p[1]*Ai; for(int i=2;i<=deg;++i) { Ai=Ai*A; ret=ret+p[i]*Ai; } return ret; }
matrix & jnf(const matrix & m, matrix & jnf_matrix, basis & retbasis) { /* jnf: Beschreibung: diese Funktion liefert zu einer gegebenen Matrix, die Jordansche Normalform und die zugehoerige Basis Eingabe: matrix m, die betrachtete Matrix vektor eigenwerte, die Eigenwerte der Matrix Rueckgabe. jnf_matrix, die Jordan Form der Matrix basis retbasis, die Jordan Basis der Matrix */ int dim=(int)m.size(); //Falls m und jnf_matrix auf die selbe Matrix zeigen if (&m==&jnf_matrix) { matrix source=m; return jnf(source,jnf_matrix, retbasis); } vector< pair<K, int> > eigen; eigenwerte(m,eigen); nullmatrix(dim, dim, jnf_matrix); vector<int> zykel_len; int pos=0; for (size_t k=0; k < eigen.size(); k++) { // durchlaufe alle Eigenwerte zykel_len.clear(); primbasis(m, eigen[k], retbasis, zykel_len); // erstellen die Jordan Form der Matrix for (size_t i=0; i < zykel_len.size(); i++) { jnf_matrix[pos][pos]=eigen[k].first; pos++; for (int j=1; j < zykel_len[i]; j++) { jnf_matrix[pos][pos]=eigen[k].first; jnf_matrix[pos][pos-1]=(K)1; pos++; } } } return jnf_matrix; }
// Eingabe: // A : nxn-Matrix // Korrektheit der Dimensionen wird nicht geprüft! // // Ausgabe: // NF: nxn-Matrix, die rationale Normalform von A // B: basis, bzgl der die lineare Abb f_A in RNF ist matrix& rationale_nf(matrix const& A, matrix& NF, basis& B) { int n=A.size(); basis V; stdbasis(n,n,V); // Die Standardbasis des R^n vector<polynom> polys; basis B1; elteiler(A,V,polys,B1); nullmatrix(n,n,NF); B.clear(); for(int i=0,j=0; i<polys.size();j+=deg(polys[i++])) { polynom const& m=polys[i]; // Keine Kopie, nur Referenz vektor & v=B1[i]; // Wird verändert (danach nicht mehr gebraucht) int d=deg(m); NF[j][j+d-1]=-m[0]; B.push_back(v); for(int k=1; k<d;++k) { NF[j+k][j+k-1]=1; NF[j+k][j+d-1]=-m[k]; B.push_back(mult(A,v,v)); } } return NF; }
int CooccurrenceCommand::getCooccurrence(vector<SharedRAbundVector*>& thisLookUp, ofstream& out){ try { int numOTUS = thisLookUp[0]->getNumBins(); if(numOTUS < 2) { m->mothurOut("Not enough OTUs for co-occurrence analysis, skipping"); m->mothurOutEndLine(); return 0; } vector< vector<int> > co_matrix; co_matrix.resize(thisLookUp[0]->getNumBins()); for (int i = 0; i < thisLookUp[0]->getNumBins(); i++) { co_matrix[i].resize((thisLookUp.size()), 0); } vector<int> columntotal; columntotal.resize(thisLookUp.size(), 0); vector<int> rowtotal; rowtotal.resize(numOTUS, 0); for (int i = 0; i < thisLookUp.size(); i++) { //nrows in the shared file for (int j = 0; j < thisLookUp[i]->getNumBins(); j++) { //cols of original shared file if (m->control_pressed) { return 0; } int abund = thisLookUp[i]->getAbundance(j); if(abund > 0) { co_matrix[j][i] = 1; rowtotal[j]++; columntotal[i]++; } } } //nrows is ncols of inital matrix. All the functions need this value. They assume the transposition has already taken place and nrows and ncols refer to that matrix. //comatrix and initmatrix are still vectors of vectors of ints as in the original script. The abundancevector is only what was read in ie not a co-occurrence matrix! int nrows = numOTUS;//rows of inital matrix int ncols = thisLookUp.size();//groups double initscore = 0.0; vector<double> stats; vector<double> probabilityMatrix; probabilityMatrix.resize(ncols * nrows, 0); vector<vector<int> > nullmatrix(nrows, vector<int>(ncols, 0)); TrialSwap2 trial; int n = accumulate( columntotal.begin(), columntotal.end(), 0 ); //============================================================ //generate a probability matrix. Only do this once. float start = 0.0; if (matrix == "sim1") { for(int i=0;i<nrows;i++) { for(int j=0;j<ncols;j++) { probabilityMatrix[ncols * i + j] = start + 1/double(nrows*ncols); start = start + 1/double(nrows*ncols); } } } //don't need a prob matrix because we just shuffle the rows, may use this in the future else if (matrix == "sim2") { } // for(int i=0;i<nrows;i++) { // start = 0.0; // for(int j=0;j<ncols;j++) { // probabilityMatrix[ncols * i + j] = start + 1/double(ncols); // start = start + 1/double(ncols); // } // } // } else if (matrix == "sim3") { for(int j=0;j<ncols;j++) { start = 0.0; for(int i=0;i<nrows;i++) { probabilityMatrix[ncols * i + j] = start + 1/double(nrows); start = start + 1/double(nrows); } } } else if (matrix == "sim4") { for(int i=0;i<nrows;i++) { start = 0.0; for(int j=0;j<ncols;j++) { probabilityMatrix[ncols * i + j] = start + columntotal[j]/double(n); start = start + columntotal[j]/double(n); } } } else if (matrix == "sim5") { for(int j=0;j<ncols;j++) { start = 0.0; for(int i=0;i<nrows;i++) { probabilityMatrix[ncols * i + j] = start + rowtotal[i]/double(n); start = start + rowtotal[i]/double(n); } } } else if (matrix == "sim6") { for(int i=0;i<nrows;i++) { for(int j=0;j<ncols;j++) { probabilityMatrix[ncols * i + j] = start + columntotal[j]/double(n*nrows); start = start + columntotal[j]/double(n*nrows); } } } else if (matrix == "sim7") { for(int i=0;i<nrows;i++) { for(int j=0;j<ncols;j++) { probabilityMatrix[ncols * i + j] = start + rowtotal[i]/double(n*ncols); start = start + rowtotal[i]/double(n*ncols); } } } else if (matrix == "sim8") { for(int i=0;i<nrows;i++) { for(int j=0;j<ncols;j++) { probabilityMatrix[ncols * i + j] = start + (rowtotal[i]*columntotal[j])/double(n*n); start = start + (rowtotal[i]*columntotal[j])/double(n*n); } } } else if (matrix == "sim9" || matrix == "sim2") { } else { m->mothurOut("[ERROR]: No model selected! \n"); m->control_pressed = true; } //co_matrix is the transposed shared file, initmatrix is the original shared file if (metric == "cscore") { initscore = trial.calc_c_score(co_matrix, rowtotal, ncols, nrows); } else if (metric == "checker") { initscore = trial.calc_checker(co_matrix, rowtotal, ncols, nrows); } else if (metric == "vratio") { initscore = trial.calc_vratio(nrows, ncols, rowtotal, columntotal); } else if (metric == "combo") { initscore = trial.calc_combo(nrows, ncols, co_matrix); } else { m->mothurOut("[ERROR]: No metric selected!\n"); m->control_pressed = true; return 1; } m->mothurOut("Initial c score: " + toString(initscore)); m->mothurOutEndLine(); double previous; double current; double randnum; int count; //burn-in for sim9 if(matrix == "sim9") { for(int i=0;i<10000;i++) trial.swap_checkerboards (co_matrix, ncols, nrows); } //populate null matrix from probability matrix, do this a lot. for(int k=0;k<runs;k++){ nullmatrix.clear(); //zero-fill the null matrix nullmatrix.assign(nrows, vector<int>(ncols, 0)); if(matrix == "sim1" || matrix == "sim6" || matrix == "sim8" || matrix == "sim7") { count = 0; while(count < n) { if (m->control_pressed) { return 0; } nextnum2: previous = 0.0; randnum = rand() / double(RAND_MAX); for(int i=0;i<nrows;i++) { for(int j=0;j<ncols;j++) { current = probabilityMatrix[ncols * i + j]; if(randnum <= current && randnum > previous) { nullmatrix[i][j] = 1; count++; if (count > n) break; else goto nextnum2; } previous = current; } } } } else if (matrix == "sim2") { for(int i=0;i<nrows;i++) { random_shuffle( co_matrix[i].begin(), co_matrix[i].end() ); } //do this for the scoring since those all have nullmatrix as a parameter //nullmatrix gets cleared at the begining of each run nullmatrix = co_matrix; } else if(matrix == "sim4") { for(int i=0;i<nrows;i++) { count = 0; while(count < rowtotal[i]) { previous = 0.0; if (m->control_pressed) { return 0; } randnum = rand() / double(RAND_MAX); for(int j=0;j<ncols;j++) { current = probabilityMatrix[ncols * i + j]; if(randnum <= current && randnum > previous && nullmatrix[i][j] != 1) { nullmatrix[i][j] = 1; count++; previous = 0.0; break; } previous = current; } } } } else if(matrix == "sim3" || matrix == "sim5") { //columns for(int j=0;j<ncols;j++) { count = 0; while(count < columntotal[j]) { if (m->control_pressed) { return 0; } randnum = rand() / double(RAND_MAX); for(int i=0;i<nrows;i++) { current = probabilityMatrix[ncols * i + j]; if(randnum <= current && randnum > previous && nullmatrix[i][j] != 1) { nullmatrix[i][j] = 1; count++; previous = 0.0; break; } previous = current; } } } } //swap_checkerboards takes the original matrix and swaps checkerboards else if(matrix == "sim9") { trial.swap_checkerboards (co_matrix, ncols, nrows); nullmatrix = co_matrix; } else { m->mothurOut("[ERROR]: No null model selected!\n\n"); m->control_pressed = true; return 1; } //run metric on null matrix and add score to the stats vector if (metric == "cscore"){ stats.push_back(trial.calc_c_score(nullmatrix, rowtotal, ncols, nrows)); } else if (metric == "checker") { stats.push_back(trial.calc_checker(nullmatrix, rowtotal, ncols, nrows)); } else if (metric == "vratio") { stats.push_back(trial.calc_vratio(nrows, ncols, rowtotal, columntotal)); } else if (metric == "combo") { stats.push_back(trial.calc_combo(nrows, ncols, nullmatrix)); } else { m->mothurOut("[ERROR]: No metric selected!\n\n"); m->control_pressed = true; return 1; } } double total = 0.0; for (int i=0; i<stats.size();i++) { total+=stats[i]; } double nullMean = double (total/(double)stats.size()); m->mothurOutEndLine(); m->mothurOut("average metric score: " + toString(nullMean)); m->mothurOutEndLine(); //calc_p_value is not a statistical p-value, it's just the average that are either > or < the initscore. //All it does is show what is expected in a competitively structured community //zscore is output so p-value can be looked up in a ztable double pvalue = 0.0; if (metric == "cscore" || metric == "checker") { pvalue = trial.calc_pvalue_greaterthan (stats, initscore); } else{ pvalue = trial.calc_pvalue_lessthan (stats, initscore); } double sd = trial.getSD(runs, stats, nullMean); double zscore = trial.get_zscore(sd, nullMean, initscore); m->mothurOut("zscore: " + toString(zscore)); m->mothurOutEndLine(); m->mothurOut("standard deviation: " + toString(sd)); m->mothurOutEndLine(); m->mothurOut("non-parametric p-value: " + toString(pvalue)); m->mothurOutEndLine(); out << metric << '\t' << thisLookUp[0]->getLabel() << '\t' << nullMean << '\t' << zscore << '\t' << sd << '\t' << pvalue << endl; return 0; } catch(exception& e) { m->errorOut(e, "CooccurrenceCommand", "Cooccurrence"); exit(1); } }