File: singlelinkage.cpp

package info (click to toggle)
mothur 1.33.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 11,248 kB
  • ctags: 12,231
  • sloc: cpp: 152,046; fortran: 665; makefile: 74; sh: 34
file content (97 lines) | stat: -rw-r--r-- 3,711 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

#include "mothur.h"
#include "cluster.hpp"


/***********************************************************************/

SingleLinkage::SingleLinkage(RAbundVector* rav, ListVector* lv, SparseDistanceMatrix* dm, float c, string s, float a) :
Cluster(rav, lv, dm, c, s, a)
{}


/***********************************************************************/
//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 {
		smallCol = dMatrix->getSmallestCell(smallRow);
        nColCells = dMatrix->seqVec[smallCol].size();
        nRowCells = dMatrix->seqVec[smallRow].size();	
	
		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();
		// remove also the cell with the smallest distance

		dMatrix->rmCell(smallRow, rowInd);
	}
	catch(exception& e) {
		m->errorOut(e, "SingleLinkage", "update");
		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);
	}
}
/***********************************************************************/