]> git.donarmstrong.com Git - mothur.git/blobdiff - singlelinkage.cpp
added modify names parameter to set.dir
[mothur.git] / singlelinkage.cpp
index 3c2697714f4e252a7e2aa0ee06002ba4a8a6fa46..3af1ea0c346030eb6f8eda3527ffc7a882c1b950 100644 (file)
@@ -1,70 +1,97 @@
 
+#include "mothur.h"
 #include "cluster.hpp"
-#include <exception>
+
 
 /***********************************************************************/
 
-SingleLinkage::SingleLinkage(RAbundVector* rav, ListVector* lv, SparseMatrix* dm) :
-Cluster(rav, lv, dm)
+SingleLinkage::SingleLinkage(RAbundVector* rav, ListVector* lv, SparseDistanceMatrix* dm, float c, string s) :
+Cluster(rav, lv, dm, c, s)
 {}
 
+
+/***********************************************************************/
+//This function returns the tag of the method.
+string SingleLinkage::getTag() {
+       return("nn");
+}
+
 /***********************************************************************/
-//This function clusters based on nearest method.
-void SingleLinkage::update(){
+//This function clusters based on the single linkage method.
+void SingleLinkage::update(double& cutOFF){
        try {
-               getRowColCells();               
+               smallCol = dMatrix->getSmallestCell(smallRow);
+        nColCells = dMatrix->seqVec[smallCol].size();
+        nRowCells = dMatrix->seqVec[smallRow].size();  
        
-               for(int i=1;i<nRowCells;i++){
-               
-                       int search;
-               
-                       if(rowCells[i]->row == smallRow){
-                               search = rowCells[i]->column;
-                       }
-                       else{
-                               search = rowCells[i]->row;
-                       }
-               
-                       for(int j=1;j<nColCells;j++){
-                       
-                               if(colCells[j]->row == search || colCells[j]->column == search){
-                               
-                                       if(colCells[j]->dist > rowCells[i]->dist){
-                                               colCells[j]->dist = rowCells[i]->dist;
-                                       
-                                               if(colCells[j]->vectorMap != NULL){
-                                                       *(colCells[j]->vectorMap) = NULL;
-                                                       colCells[j]->vectorMap = NULL;
-                                               }
-                                       
-                                       }
-                                       dMatrix->rmCell(rowCells[i]);
-                                       break;
-                               }
-                       }                       
-               
-                       if(search < smallCol){
-                               rowCells[i]->row = smallCol;
-                               rowCells[i]->column = search;
-                       }
-                       else{
-                               rowCells[i]->row = search;
-                               rowCells[i]->column = smallCol;
-                       }
-               
-               }       
+               vector<bool> deleted(nRowCells, false);
+               int rowInd;
+               int search;
+               bool changed;
+
+               // 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 (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;j<nColCells;j++) {
+                        if (dMatrix->seqVec[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();
-               dMatrix->rmCell(rowCells[0]);
+               // remove also the cell with the smallest distance
+
+               dMatrix->rmCell(smallRow, rowInd);
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the SingleLinkage class Function update. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               m->errorOut(e, "SingleLinkage", "update");
                exit(1);
        }
-       catch(...) {
-               cout << "An unknown error has occurred in the SingleLinkage class function update. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
-               exit(1);
-       }       
 }
 
+
+/***********************************************************************/
+//This function updates the distance based on the nearest neighbor method.
+bool SingleLinkage::updateDistance(PDistCell& colCell, PDistCell& rowCell) {
+       try {
+               bool changed = false;
+               if (colCell.dist > rowCell.dist) {
+                       colCell.dist = rowCell.dist;
+               }
+               return(changed);
+       }
+       catch(exception& e) {
+               m->errorOut(e, "SingleLinkage", "updateDistance");
+               exit(1);
+       }
+}
 /***********************************************************************/