File: singlelinkage.cpp

package info (click to toggle)
mothur 1.24.1-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 7,868 kB
  • sloc: cpp: 110,948; ansic: 2,037; fortran: 665; makefile: 74; sh: 59
file content (105 lines) | stat: -rw-r--r-- 3,119 bytes parent folder | download
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);
	}
}
/***********************************************************************/