// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, %rbx
callq 0x3f92
movsd %xmm0, 0x18(%rsp)
movslq 0xb0(%rbx), %rsi
leaq 0x40(%rsp), %r14
leaq 0xb(%rsp), %rdx
movq %r14, %rdi
callq 0x4d3e
xorl %eax, %eax
movq (%r14), %rcx
movslq 0xb0(%rbx), %r14
cmpq %r14, %rax
jge 0x4730
movl %eax, (%rcx,%rax,4)
incq %rax
jmp 0x471c
xorl %r15d, %r15d
xorl %r12d, %r12d
leal -0x1(%r14), %eax
cltq
cmpq %rax, %r12
jge 0x477a
callq 0x2070
movl 0xb0(%rbx), %ecx
addl %r15d, %ecx
cltd
idivl %ecx
movq 0x40(%rsp), %rax
movl (%rax,%r12,4), %ecx
movslq %edx, %rdx
addq %r12, %rdx
movl (%rax,%rdx,4), %esi
movl %esi, (%rax,%r12,4)
movl %ecx, (%rax,%rdx,4)
incq %r12
movl 0xb0(%rbx), %r14d
decl %r15d
jmp 0x4736
leaq 0x38(%rbx), %rax
movq %rax, 0x30(%rsp)
movq $0x0, 0x10(%rsp)
xorl %r15d, %r15d
xorl %ebp, %ebp
movslq %r14d, %rax
cmpq %rax, %r15
jge 0x4881
movq 0x40(%rsp), %rax
movslq (%rax,%r15,4), %r12
movq 0xb8(%rbx), %rax
movl (%rax,%r12,4), %r14d
movq 0x30(%rsp), %rdi
movl %r12d, %esi
callq 0x2cc0
movsd %xmm0, 0x38(%rsp)
movq %rbx, %rdi
movl %r12d, %esi
callq 0x3dd0
movslq %r14d, %rdx
movq (%rbx), %rax
movsd (%rax,%rdx,8), %xmm0
movq %rbx, %rdi
movl %r12d, %esi
callq 0x4ae6
movl %ebp, 0xc(%rsp)
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
xorl %ebp, %ebp
movl %r14d, %r13d
movsd %xmm0, 0x28(%rsp)
movl 0x30(%rbx), %eax
cmpq %rax, %rbp
jae 0x4850
movq (%rbx), %rax
movq 0x18(%rbx), %rcx
movl (%rcx,%rbp,4), %edx
movsd (%rax,%rdx,8), %xmm0
movq %rbx, %rdi
movl %r12d, %esi
movsd 0x38(%rsp), %xmm1
callq 0x4d90
ucomisd 0x28(%rsp), %xmm0
jbe 0x484b
movq (%rbx), %rax
movq 0x18(%rbx), %rcx
movl (%rcx,%rbp,4), %r13d
movsd (%rax,%r13,8), %xmm1
movsd %xmm1, 0x20(%rsp)
movsd %xmm0, 0x28(%rsp)
incq %rbp
jmp 0x47fe
movq %rbx, %rdi
movl %r12d, %esi
movl %r13d, %edx
movsd 0x20(%rsp), %xmm0
callq 0x4b92
xorl %eax, %eax
cmpl %r14d, %r13d
setne %al
movl 0xc(%rsp), %ebp
addl %eax, %ebp
incq %r15
movl 0xb0(%rbx), %r14d
jmp 0x4791
testl %ebp, %ebp
je 0x48b2
movq %rbx, %rdi
callq 0x3f92
movapd %xmm0, %xmm1
subsd 0x18(%rsp), %xmm1
movb $0x1, %al
movq %rax, 0x10(%rsp)
ucomisd 0x108(%rbx), %xmm1
movsd %xmm0, 0x18(%rsp)
ja 0x478c
leaq 0x40(%rsp), %rdi
callq 0x34f2
movq 0x10(%rsp), %rax
andb $0x1, %al
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x48d4
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x34f2
movq %rbx, %rdi
callq 0x22f0
nop