X-Git-Url: https://git.donarmstrong.com/?p=mothur.git;a=blobdiff_plain;f=singlelinkage.cpp;h=3af1ea0c346030eb6f8eda3527ffc7a882c1b950;hp=9f015db7359879be53da5e6001889117c7e5f7c6;hb=a8e2df1b96a57f5f29576b08361b86a96a8eff4f;hpb=832d53a9dfac6b1795735eec643d8cf627b0d8e3 diff --git a/singlelinkage.cpp b/singlelinkage.cpp index 9f015db..3af1ea0 100644 --- a/singlelinkage.cpp +++ b/singlelinkage.cpp @@ -5,8 +5,8 @@ /***********************************************************************/ -SingleLinkage::SingleLinkage(RAbundVector* rav, ListVector* lv, SparseMatrix* dm, float c) : -Cluster(rav, lv, dm, c) +SingleLinkage::SingleLinkage(RAbundVector* rav, ListVector* lv, SparseDistanceMatrix* dm, float c, string s) : +Cluster(rav, lv, dm, c, s) {} @@ -18,9 +18,11 @@ string SingleLinkage::getTag() { /***********************************************************************/ //This function clusters based on the single linkage method. -void SingleLinkage::update(){ +void SingleLinkage::update(double& cutOFF){ try { - getRowColCells(); + smallCol = dMatrix->getSmallestCell(smallRow); + nColCells = dMatrix->seqVec[smallCol].size(); + nRowCells = dMatrix->seqVec[smallRow].size(); vector deleted(nRowCells, false); int rowInd; @@ -30,57 +32,48 @@ void SingleLinkage::update(){ // The vector has to be traversed in reverse order to preserve the index // for faster removal in removeCell() for (int i=nRowCells-1;i>=0;i--) { - if ((rowCells[i]->row == smallRow) && (rowCells[i]->column == smallCol)) { - rowInd = i; // The index of the smallest distance cell in rowCells - } else { - if (rowCells[i]->row == smallRow) { - search = rowCells[i]->column; - } else { - search = rowCells[i]->row; - } - - for (int j=0;jrow == smallRow) && (colCells[j]->column == smallCol))) { - if (colCells[j]->row == search || colCells[j]->column == search) { - changed = updateDistance(colCells[j], rowCells[i]); - // If the cell's distance changed and it had the same distance as - // the smallest distance, invalidate the mins vector in SparseMatrix - if (changed) { - if (colCells[j]->vectorMap != NULL) { - *(colCells[j]->vectorMap) = NULL; - colCells[j]->vectorMap = NULL; - } - } - removeCell(rowCells[i], i , -1); - deleted[i] = true; - break; - } - } - } - if (!deleted[i]) { - // Assign the cell to the new cluster - // remove the old cell from seqVec and add the cell - // with the new row and column assignment again - removeCell(rowCells[i], i , -1, false); - if (search < smallCol){ - rowCells[i]->row = smallCol; - rowCells[i]->column = search; - } else { - rowCells[i]->row = search; - rowCells[i]->column = smallCol; - } - seqVec[rowCells[i]->row].push_back(rowCells[i]); - seqVec[rowCells[i]->column].push_back(rowCells[i]); - } - } + if (dMatrix->seqVec[smallRow][i].index == smallCol) { + rowInd = i; // The index of the smallest distance cell in rowCells + } else { + search = dMatrix->seqVec[smallRow][i].index; + + for (int j=0;jseqVec[smallCol][j].index != smallRow) { //if you are not the small cell + if (dMatrix->seqVec[smallCol][j].index == search) { + changed = updateDistance(dMatrix->seqVec[smallCol][j], dMatrix->seqVec[smallRow][i]); + dMatrix->updateCellCompliment(smallCol, j); + dMatrix->rmCell(smallRow, i); + deleted[i] = true; + break; + } + } + } + if (!deleted[i]) { + // Assign the cell to the new cluster + // remove the old cell from seqVec and add the cell + // with the new row and column assignment again + float distance = dMatrix->seqVec[smallRow][i].dist; + dMatrix->rmCell(smallRow, i); + if (search < smallCol){ + PDistCell value(smallCol, distance); + dMatrix->addCell(search, value); + } else { + PDistCell value(search, distance); + dMatrix->addCell(smallCol, value); + } + sort(dMatrix->seqVec[smallCol].begin(), dMatrix->seqVec[smallCol].end(), compareIndexes); + sort(dMatrix->seqVec[search].begin(), dMatrix->seqVec[search].end(), compareIndexes); + } + } } clusterBins(); clusterNames(); // remove also the cell with the smallest distance - removeCell(rowCells[rowInd], -1 , -1); + + dMatrix->rmCell(smallRow, rowInd); } catch(exception& e) { - errorOut(e, "SingleLinkage", "update"); + m->errorOut(e, "SingleLinkage", "update"); exit(1); } } @@ -88,16 +81,16 @@ void SingleLinkage::update(){ /***********************************************************************/ //This function updates the distance based on the nearest neighbor method. -bool SingleLinkage::updateDistance(MatData& colCell, MatData& rowCell) { +bool SingleLinkage::updateDistance(PDistCell& colCell, PDistCell& rowCell) { try { bool changed = false; - if (colCell->dist > rowCell->dist) { - colCell->dist = rowCell->dist; + if (colCell.dist > rowCell.dist) { + colCell.dist = rowCell.dist; } return(changed); } catch(exception& e) { - errorOut(e, "SingleLinkage", "updateDistance"); + m->errorOut(e, "SingleLinkage", "updateDistance"); exit(1); } }