// File: Luthaf[P]zeopp/networkanalysis.cc
// Function: clusterElements(std::set<int, std::less<int>, std::allocator<int>>, std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>, double)
vector< set<int> > clusterElements(set<int> cageNodes, vector< vector<double> > overlapFractions, double MIN_FRACTION){
  vector< set<int> > clusters;
  set<int>::iterator nodeIter = cageNodes.begin();
  
  while(nodeIter != cageNodes.end()) {
    int elementID = *nodeIter;
    bool merged = false;
    vector<int> clusterIDs;
    for(unsigned int i = 0; i < clusters.size(); i++){
      set<int>::iterator clusterIter = clusters[i].begin();
      while(clusterIter != clusters[i].end()){
	if(overlapFractions[elementID][*clusterIter] > MIN_FRACTION){
	  clusters[i].insert(elementID);
	  merged = true;
	  clusterIDs.push_back(i);
	  break;
	}
	clusterIter++;
      }
    }
    if(!merged){
      // Node not added to any clusters so form a new cluster
      set<int> newCluster; newCluster.insert(elementID);
      clusters.push_back(newCluster);
    }
    else if (clusterIDs.size() > 1){
      // Node was added to more than one cluster. Therefore,
      // join the resulting clusters into a single cluster

      for(unsigned int i = 1; i < clusterIDs.size(); i++){
	clusters[clusterIDs[0]].insert(clusters[clusterIDs[i]].begin(), clusters[clusterIDs[i]].end());
      }
      int removeCount = 0;
      for(unsigned int i = 1; i < clusterIDs.size(); i++){
	clusters.erase(clusters.begin() + clusterIDs[i] - removeCount);
	removeCount++;
      }
    }
    nodeIter++;
  }
  return clusters;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1b0, %rsp            # imm = 0x1B0
movq %rdx, -0x150(%rbp)
movq %rsi, -0x138(%rbp)
movq %rdi, -0x148(%rbp)
movq %rdi, %rax
movq %rax, -0x140(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movsd %xmm0, -0x20(%rbp)
movb $0x0, -0x21(%rbp)
callq 0x655d0
movq -0x138(%rbp), %rdi
callq 0x655f0
movq %rax, -0x30(%rbp)
movq -0x138(%rbp), %rdi
callq 0xf520
movq %rax, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xf4b0
testb $0x1, %al
jne 0x60b6a
jmp 0x60fa9
leaq -0x30(%rbp), %rdi
callq 0x65620
movl (%rax), %eax
movl %eax, -0x3c(%rbp)
movb $0x0, -0x3d(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xd0d0
movl $0x0, -0x5c(%rbp)
movq -0x148(%rbp), %rdi
movl -0x5c(%rbp), %eax
movq %rax, -0x158(%rbp)
callq 0x1c3e0
movq %rax, %rcx
movq -0x158(%rbp), %rax
cmpq %rcx, %rax
jae 0x60cde
movq -0x148(%rbp), %rdi
movl -0x5c(%rbp), %eax
movl %eax, %esi
callq 0x65640
movq %rax, %rdi
callq 0x655f0
movq %rax, -0x68(%rbp)
movq -0x148(%rbp), %rdi
movl -0x5c(%rbp), %eax
movl %eax, %esi
callq 0x65640
movq %rax, %rdi
callq 0xf520
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xf4b0
testb $0x1, %al
jne 0x60c05
jmp 0x60cce
movq -0x150(%rbp), %rdi
movslq -0x3c(%rbp), %rsi
callq 0x162d0
movq %rax, -0x160(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x65620
movq -0x160(%rbp), %rdi
movslq (%rax), %rsi
callq 0xedb0
movsd (%rax), %xmm0
ucomisd -0x20(%rbp), %xmm0
jbe 0x60cb7
movq -0x148(%rbp), %rdi
movl -0x5c(%rbp), %eax
movl %eax, %esi
callq 0x65640
movq %rax, %rdi
leaq -0x3c(%rbp), %rsi
callq 0xf300
movb %dl, -0x169(%rbp)
movq %rax, -0x168(%rbp)
jmp 0x60c6b
movb -0x169(%rbp), %al
movq -0x168(%rbp), %rcx
movq %rcx, -0x90(%rbp)
movb %al, -0x88(%rbp)
movb $0x1, -0x3d(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x94(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x94(%rbp), %rsi
callq 0xffc0
jmp 0x60ca4
jmp 0x60cce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x60f92
leaq -0x68(%rbp), %rdi
xorl %esi, %esi
callq 0x65660
movq %rax, -0xa0(%rbp)
jmp 0x60bd2
jmp 0x60cd0
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x60b8c
testb $0x1, -0x3d(%rbp)
jne 0x60d77
leaq -0xd0(%rbp), %rdi
movq %rdi, -0x188(%rbp)
callq 0xf690
movq -0x188(%rbp), %rdi
leaq -0x3c(%rbp), %rsi
callq 0xf300
movb %dl, -0x179(%rbp)
movq %rax, -0x178(%rbp)
jmp 0x60d1a
movq -0x148(%rbp), %rdi
movb -0x179(%rbp), %al
movq -0x178(%rbp), %rcx
movq %rcx, -0xe0(%rbp)
movb %al, -0xd8(%rbp)
leaq -0xd0(%rbp), %rsi
callq 0x656a0
jmp 0x60d49
leaq -0xd0(%rbp), %rdi
callq 0xf880
jmp 0x60f72
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0xf880
jmp 0x60f92
leaq -0x58(%rbp), %rdi
callq 0x10090
cmpq $0x1, %rax
jbe 0x60f70
movl $0x1, -0xe4(%rbp)
movl -0xe4(%rbp), %eax
movq %rax, -0x190(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x10090
movq %rax, %rcx
movq -0x190(%rbp), %rax
cmpq %rcx, %rax
jae 0x60e7d
xorl %eax, %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0xed60
movq -0x148(%rbp), %rdi
movslq (%rax), %rsi
callq 0x65640
movq -0x1a0(%rbp), %rdi
movq %rax, -0x198(%rbp)
movl -0xe4(%rbp), %eax
movl %eax, %esi
callq 0xed60
movq -0x148(%rbp), %rdi
movslq (%rax), %rsi
callq 0x65640
movq %rax, %rdi
callq 0x655f0
movq -0x1a0(%rbp), %rdi
movq %rax, -0xf0(%rbp)
movl -0xe4(%rbp), %eax
movl %eax, %esi
callq 0xed60
movq -0x148(%rbp), %rdi
movslq (%rax), %rsi
callq 0x65640
movq %rax, %rdi
callq 0xf520
movq -0x198(%rbp), %rdi
movq %rax, -0xf8(%rbp)
movq -0xf0(%rbp), %rsi
movq -0xf8(%rbp), %rdx
callq 0x65710
jmp 0x60e67
jmp 0x60e69
movl -0xe4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe4(%rbp)
jmp 0x60d94
movl $0x0, -0xfc(%rbp)
movl $0x1, -0x100(%rbp)
movl -0x100(%rbp), %eax
movq %rax, -0x1a8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x10090
movq %rax, %rcx
movq -0x1a8(%rbp), %rax
cmpq %rcx, %rax
jae 0x60f6e
movq -0x148(%rbp), %rdi
callq 0x21820
movq %rax, -0x120(%rbp)
movl -0x100(%rbp), %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
callq 0xed60
movslq (%rax), %rsi
leaq -0x120(%rbp), %rdi
callq 0x21b90
movq %rax, -0x118(%rbp)
movslq -0xfc(%rbp), %rsi
leaq -0x118(%rbp), %rdi
callq 0x657c0
movq %rax, -0x110(%rbp)
leaq -0x108(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x65800
movq -0x148(%rbp), %rdi
movq -0x108(%rbp), %rsi
callq 0x65750
movq %rax, -0x1b0(%rbp)
jmp 0x60f3d
movq -0x1b0(%rbp), %rax
movq %rax, -0x128(%rbp)
movl -0xfc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xfc(%rbp)
movl -0x100(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x100(%rbp)
jmp 0x60e91
jmp 0x60f70
jmp 0x60f72
leaq -0x30(%rbp), %rdi
xorl %esi, %esi
callq 0x65660
movq %rax, -0x130(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xec80
jmp 0x60b44
leaq -0x58(%rbp), %rdi
callq 0xec80
movq -0x148(%rbp), %rdi
callq 0x13b70
jmp 0x60fcf
movb $0x1, -0x21(%rbp)
testb $0x1, -0x21(%rbp)
jne 0x60fbf
movq -0x148(%rbp), %rdi
callq 0x13b70
movq -0x140(%rbp), %rax
addq $0x1b0, %rsp            # imm = 0x1B0
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x58f0
nopl (%rax,%rax)