1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#include "mothur.h"
#include "cluster.hpp"
/***********************************************************************/
SingleLinkage::SingleLinkage(RAbundVector* rav, ListVector* lv, SparseMatrix* 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 the single linkage method.
void SingleLinkage::update(double& cutOFF){
try {
getRowColCells();
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 ((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;j<nColCells;j++) {
if (!((colCells[j]->row == 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]);
}
}
}
clusterBins();
clusterNames();
// remove also the cell with the smallest distance
removeCell(rowCells[rowInd], -1 , -1);
}
catch(exception& e) {
m->errorOut(e, "SingleLinkage", "update");
exit(1);
}
}
/***********************************************************************/
//This function updates the distance based on the nearest neighbor method.
bool SingleLinkage::updateDistance(MatData& colCell, MatData& 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);
}
}
/***********************************************************************/
|