double HCluster::update(int row, int col, float distance){ try { bool cluster = false; smallRow = row; smallCol = col; smallDist = distance; //find upmost parent of row and col smallRow = getUpmostParent(smallRow); smallCol = getUpmostParent(smallCol); //you don't want to cluster with yourself if (smallRow != smallCol) { if ((method == "furthest") || (method == "nearest")) { //can we cluster??? if (method == "nearest") { cluster = true; } else{ //assume furthest //are they active in the link table int linkValue = makeActive(); //after this point this nodes info is active in linkTable if (linkValue == (clusterArray[smallRow].numSeq * clusterArray[smallCol].numSeq)) { cluster = true; } } if (cluster) { updateArrayandLinkTable(); clusterBins(); clusterNames(); } }else { cluster = true; updateArrayandLinkTable(); clusterBins(); clusterNames(); combineFile(); } } return cutoff; //printInfo(); } catch(exception& e) { m->errorOut(e, "HCluster", "update"); exit(1); } }
//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); } }
void Cluster::update(double& cutOFF){ try { smallCol = dMatrix->getSmallestCell(smallRow); nColCells = dMatrix->seqVec[smallCol].size(); nRowCells = dMatrix->seqVec[smallRow].size(); vector<int> foundCol(nColCells, 0); //cout << dMatrix->getNNodes() << " small cell: " << smallRow << '\t' << smallCol << endl; int search; bool changed; for (int i=nRowCells-1;i>=0;i--) { if (m->control_pressed) { break; } //if you are not the smallCell if (dMatrix->seqVec[smallRow][i].index != smallCol) { search = dMatrix->seqVec[smallRow][i].index; bool merged = false; for (int j=0;j<nColCells;j++) { if (dMatrix->seqVec[smallCol][j].index != smallRow) { //if you are not the smallest distance if (dMatrix->seqVec[smallCol][j].index == search) { foundCol[j] = 1; merged = true; changed = updateDistance(dMatrix->seqVec[smallCol][j], dMatrix->seqVec[smallRow][i]); dMatrix->updateCellCompliment(smallCol, j); break; }else if (dMatrix->seqVec[smallCol][j].index < search) { j+=nColCells; } //we don't have a distance for this cell } } //if not merged it you need it for warning if ((!merged) && (method == "average" || method == "weighted")) { if (cutOFF > dMatrix->seqVec[smallRow][i].dist) { cutOFF = dMatrix->seqVec[smallRow][i].dist; //cout << "changing cutoff to " << cutOFF << endl; } } dMatrix->rmCell(smallRow, i); } } clusterBins(); clusterNames(); // Special handling for singlelinkage case, not sure whether this // could be avoided for (int i=nColCells-1;i>=0;i--) { if (foundCol[i] == 0) { if (method == "average" || method == "weighted") { if (dMatrix->seqVec[smallCol][i].index != smallRow) { //if you are not hte smallest distance if (cutOFF > dMatrix->seqVec[smallCol][i].dist) { cutOFF = dMatrix->seqVec[smallCol][i].dist; } } } dMatrix->rmCell(smallCol, i); } } } catch(exception& e) { m->errorOut(e, "Cluster", "update"); exit(1); } }