// File: riyadparvez[P]louvain-method/community.cpp
// Function: Community::one_level()
bool
Community::one_level() {
  bool improvement=false ;
  int nb_moves;
  int nb_pass_done = 0;
  double new_mod   = modularity();
  double cur_mod   = new_mod;

  vector<int> random_order(size);
  for (int i=0 ; i<size ; i++)
    random_order[i]=i;
  for (int i=0 ; i<size-1 ; i++) {
    int rand_pos = rand()%(size-i)+i;
    int tmp      = random_order[i];
    random_order[i] = random_order[rand_pos];
    random_order[rand_pos] = tmp;
  }

  // repeat while 
  //   there is an improvement of modularity
  //   or there is an improvement of modularity greater than a given epsilon 
  //   or a predefined number of pass have been done
  do {
    cur_mod = new_mod;
    nb_moves = 0;
    nb_pass_done++;

    // for each node: remove the node from its community and insert it in the best community
    for (int node_tmp=0 ; node_tmp<size ; node_tmp++) {
//      int node = node_tmp;
      int node = random_order[node_tmp];
      int node_comm     = n2c[node];
      double w_degree = g.weighted_degree(node);

      // computation of all neighboring communities of current node
      neigh_comm(node);
      // remove node from its current community
      remove(node, node_comm, neigh_weight[node_comm]);

      // compute the nearest community for node
      // default choice for future insertion is the former community
      int best_comm        = node_comm;
      double best_nblinks  = 0.;
      double best_increase = 0.;
      for (unsigned int i=0 ; i<neigh_last ; i++) {
        double increase = modularity_gain(node, neigh_pos[i], neigh_weight[neigh_pos[i]], w_degree);
        if (increase>best_increase) {
          best_comm     = neigh_pos[i];
          best_nblinks  = neigh_weight[neigh_pos[i]];
          best_increase = increase;
        }
      }

      // insert node in the nearest community
      insert(node, best_comm, best_nblinks);
     
      if (best_comm!=node_comm)
        nb_moves++;
    }

    double total_tot=0;
    double total_in=0;
    for (unsigned int i=0 ; i<tot.size() ;i++) {
      total_tot+=tot[i];
      total_in+=in[i];
    }

    new_mod = modularity();
    if (nb_moves>0)
      improvement=true;
    
  } while (nb_moves>0 && new_mod-cur_mod>min_modularity);

  return improvement;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xd0(%rbp)
movb $0x0, -0x9(%rbp)
movl $0x0, -0x14(%rbp)
callq 0x8980
movq -0xd0(%rbp), %rax
movsd %xmm0, -0x20(%rbp)
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movslq 0xb0(%rax), %rax
movq %rax, -0xc8(%rbp)
leaq -0x41(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
callq 0x4130
movq -0xc8(%rbp), %rsi
movq -0xc0(%rbp), %rdx
leaq -0x40(%rbp), %rdi
callq 0xab00
jmp 0x9997
leaq -0x41(%rbp), %rdi
callq 0x7290
movl $0x0, -0x58(%rbp)
movq -0xd0(%rbp), %rcx
movl -0x58(%rbp), %eax
cmpl 0xb0(%rcx), %eax
jge 0x99fc
movl -0x58(%rbp), %eax
movl %eax, -0xd4(%rbp)
movslq -0x58(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x3ab0
movl -0xd4(%rbp), %ecx
movl %ecx, (%rax)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x99a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x41(%rbp), %rdi
callq 0x7290
jmp 0x9e71
movl $0x0, -0x5c(%rbp)
movq -0xd0(%rbp), %rcx
movl -0x5c(%rbp), %eax
movl 0xb0(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x9aa4
callq 0x2090
movq -0xd0(%rbp), %rcx
movl 0xb0(%rcx), %ecx
subl -0x5c(%rbp), %ecx
cltd
idivl %ecx
addl -0x5c(%rbp), %edx
movl %edx, -0x60(%rbp)
movslq -0x5c(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x3ab0
movl (%rax), %eax
movl %eax, -0x64(%rbp)
movslq -0x60(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x3ab0
movl (%rax), %eax
movl %eax, -0xdc(%rbp)
movslq -0x5c(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x3ab0
movl -0xdc(%rbp), %ecx
movl %ecx, (%rax)
movl -0x64(%rbp), %eax
movl %eax, -0xd8(%rbp)
movslq -0x60(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x3ab0
movl -0xd8(%rbp), %ecx
movl %ecx, (%rax)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x9a03
jmp 0x9aa6
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movl $0x0, -0x10(%rbp)
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl $0x0, -0x68(%rbp)
movq -0xd0(%rbp), %rcx
movl -0x68(%rbp), %eax
cmpl 0xb0(%rcx), %eax
jge 0x9d32
movslq -0x68(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x3ab0
movq -0xd0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x6c(%rbp)
addq $0xb8, %rdi
movslq -0x6c(%rbp), %rsi
callq 0x3ab0
movq -0xd0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x70(%rbp)
addq $0x38, %rdi
movl -0x6c(%rbp), %esi
callq 0x36a0
movsd %xmm0, -0xe8(%rbp)
jmp 0x9b28
movq -0xd0(%rbp), %rdi
movsd -0xe8(%rbp), %xmm0
movsd %xmm0, -0x78(%rbp)
movl -0x6c(%rbp), %esi
callq 0x8620
jmp 0x9b46
movq -0xd0(%rbp), %rdi
movl -0x6c(%rbp), %eax
movl %eax, -0xf0(%rbp)
movl -0x70(%rbp), %eax
movl %eax, -0xec(%rbp)
movslq %eax, %rsi
callq 0xa150
movq -0xd0(%rbp), %rdi
movl -0xf0(%rbp), %esi
movl -0xec(%rbp), %edx
movsd (%rax), %xmm0
callq 0xa390
jmp 0x9b85
movl -0x70(%rbp), %eax
movl %eax, -0x7c(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x88(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x90(%rbp)
movl $0x0, -0x94(%rbp)
movq -0xd0(%rbp), %rcx
movl -0x94(%rbp), %eax
cmpl 0x30(%rcx), %eax
jae 0x9cf5
movq -0xd0(%rbp), %rdi
movl -0x6c(%rbp), %eax
movl %eax, -0x100(%rbp)
addq $0x18, %rdi
movq %rdi, -0x108(%rbp)
movl -0x94(%rbp), %eax
movl %eax, %esi
callq 0x34b0
movq -0x108(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0xfc(%rbp)
movl -0x94(%rbp), %eax
movl %eax, %esi
callq 0x34b0
movq -0xd0(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xa150
movq -0xd0(%rbp), %rdi
movl -0x100(%rbp), %esi
movl -0xfc(%rbp), %edx
movsd (%rax), %xmm0
movsd -0x78(%rbp), %xmm1
callq 0xab70
movsd %xmm0, -0xf8(%rbp)
jmp 0x9c40
movsd -0xf8(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
movsd -0xa0(%rbp), %xmm0
ucomisd -0x90(%rbp), %xmm0
jbe 0x9cdf
movq -0xd0(%rbp), %rdi
addq $0x18, %rdi
movl -0x94(%rbp), %eax
movl %eax, %esi
callq 0x34b0
movq -0xd0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x7c(%rbp)
addq $0x18, %rdi
movl -0x94(%rbp), %eax
movl %eax, %esi
callq 0x34b0
movq -0xd0(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xa150
movsd (%rax), %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0xa0(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
jmp 0x9cdf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3640
jmp 0x9e71
jmp 0x9ce1
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x9bab
movq -0xd0(%rbp), %rdi
movl -0x6c(%rbp), %esi
movl -0x7c(%rbp), %edx
movsd -0x88(%rbp), %xmm0
callq 0xa4b0
jmp 0x9d11
movl -0x7c(%rbp), %eax
cmpl -0x70(%rbp), %eax
je 0x9d22
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x9d24
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x9ac7
xorps %xmm0, %xmm0
movsd %xmm0, -0xa8(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0xb0(%rbp)
movl $0x0, -0xb4(%rbp)
movq -0xd0(%rbp), %rdi
movl -0xb4(%rbp), %eax
movq %rax, -0x110(%rbp)
addq $0xe8, %rdi
callq 0xac40
movq %rax, %rcx
movq -0x110(%rbp), %rax
cmpq %rcx, %rax
jae 0x9df3
movq -0xd0(%rbp), %rdi
addq $0xe8, %rdi
movl -0xb4(%rbp), %eax
movl %eax, %esi
callq 0xa150
movq -0xd0(%rbp), %rdi
movsd (%rax), %xmm0
addsd -0xa8(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
addq $0xd0, %rdi
movl -0xb4(%rbp), %eax
movl %eax, %esi
callq 0xa150
movsd (%rax), %xmm0
addsd -0xb0(%rbp), %xmm0
movsd %xmm0, -0xb0(%rbp)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x9d52
movq -0xd0(%rbp), %rdi
callq 0x8980
movsd %xmm0, -0x20(%rbp)
cmpl $0x0, -0x10(%rbp)
jle 0x9e0e
movb $0x1, -0x9(%rbp)
jmp 0x9e10
xorl %eax, %eax
cmpl $0x0, -0x10(%rbp)
movb %al, -0x111(%rbp)
jle 0x9e40
movq -0xd0(%rbp), %rax
movsd -0x20(%rbp), %xmm0
subsd -0x28(%rbp), %xmm0
ucomisd 0x108(%rax), %xmm0
seta %al
movb %al, -0x111(%rbp)
movb -0x111(%rbp), %al
testb $0x1, %al
jne 0x9aa6
movb -0x9(%rbp), %al
movb %al, -0x112(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3640
movb -0x112(%rbp), %al
andb $0x1, %al
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x2300
nopw (%rax,%rax)