// File: /workspace/github_c_makefile_star2_O0/sheneman[P]clearcut/clearcut.c
// Function: NJ_relaxed_nj
NJ_TREE *
NJ_relaxed_nj(NJ_ARGS *nj_args,
	      DMAT *dmat) {

  
  NJ_TREE *tree;
  NJ_VERTEX *vertex;
  long int a, b, t, bh, bv, i;
  float hmin, vmin, hvmin;
  float p, q, x;
  int join_flag;
  int additivity_mode;
  long int hmincount, vmincount;
  long int *permutation = NULL;



  /* initialize the r and r2 vectors */
  NJ_init_r(dmat);

  additivity_mode = 1;

  /* allocate the permutation vector, if we are in randomize mode */
  if(!nj_args->norandom) {
    permutation = (long int *)calloc(dmat->size, sizeof(long int));
    if(!permutation) {
      fprintf(stderr, "Clearcut:  Memory allocation error in NJ_relaxed_nj()\n");
      return(NULL);
    }
  }

  /* allocate and initialize our vertex vector used for tree construction */
  vertex = NJ_init_vertex(dmat);
  
  /* loop until there are only 2 nodes left to join */
  while(vertex->nactive > 2) {

    switch(nj_args->norandom) {

      /* RANDOMIZED JOINS */
    case 0:

      join_flag = 0;

      NJ_permute(permutation, dmat->size-1);
      for(i=0;i<dmat->size-1 && (vertex->nactive>2) ;i++) {

	a = permutation[i];

	/* find min trans dist along horiz. of row a */
	hmin = NJ_find_hmin(dmat, a, &bh, &hmincount);   
	if(a) {
	  /* find min trans dist along vert. of row a */
	  vmin = NJ_find_vmin(dmat, a, &bv, &vmincount); 
	} else {
	  vmin = hmin;
	  bv = bh;
	  vmincount = 0;
	}
	
	if(NJ_FLT_EQ(hmin, vmin)) {

	  /* 
	   * The minima along the vertical and horizontal are 
	   * the same.  Compute the proportion of minima along
	   * the horizonal (p) and the proportion of minima 
	   * along the vertical (q).
	   * 
	   * If the same minima exist along the horizonal and
	   * vertical, we break the tie in a way which is
	   * non-biased.  That is, we break the tie based on the
	   * proportion of horiz. minima versus vertical minima.
	   * 
	   */
	  p = (float)hmincount / ((float)hmincount + (float)vmincount);
	  q = 1.0 - p;
	  x = genrand_real2();
	  
	  if(x < p) {
	    hvmin = hmin;
	    b     = bh;
	  } else {
	    hvmin = vmin;
	    b     = bv;
	  }
	} else if(NJ_FLT_LT(hmin, vmin) ) {
	  hvmin   = hmin;
	  b       = bh;
	} else {
	  hvmin   = vmin;
	  b       = bv;
	}
	
	if(NJ_check(nj_args, dmat, a, b, hvmin, additivity_mode)) {

	  /* swap a and b, if necessary, to make sure a < b */
	  if(b < a) {
	    t = a;
	    a = b;
	    b = t;
	  }

	  join_flag = 1;
	
	  /* join taxa from rows a and b */
	  NJ_decompose(dmat, vertex, a, b, 0);

	  /* collapse matrix */
	  NJ_compute_r(dmat, a, b);
	  NJ_collapse(dmat, vertex, a, b);
	  
	  NJ_permute(permutation, dmat->size-1);
	}
      }
      
      /* turn off additivity if go through an entire cycle without joining */
      if(!join_flag) {
	additivity_mode = 0;
      }
      
      break;



      /* DETERMINISTIC JOINS */
    case 1:
      
      join_flag = 0;

      for(a=0;a<dmat->size-1 && (vertex->nactive > 2) ;) {
      
	/* find the min along the horizontal of row a */
	hmin = NJ_find_hmin(dmat, a, &b, &hmincount);
      
	if(NJ_check(nj_args, dmat, a, b, hmin, additivity_mode)) {
	
	  join_flag = 1;
	
	  /* join taxa from rows a and b */
	  NJ_decompose(dmat, vertex, a, b, 0);

	  /* collapse matrix */
	  NJ_compute_r(dmat, a, b);
	  NJ_collapse(dmat, vertex, a, b);

	  if(a) { 
	    a--; 
	  }
	
	} else {
	  a++;
	}
      }
    
      /* turn off additivity if go through an entire cycle without joining */
      if(!join_flag) {
	additivity_mode = 0;
      }

      break;
    }
 
  }  /* WHILE */

  /* Join the last two nodes on the vertex list */
  tree = NJ_decompose(dmat, vertex, 0, 1, NJ_LAST);
  
  if(nj_args->verbose_flag) {
    if(additivity_mode) {
      printf("Tree is additive\n");
    } else {
      printf("Tree is not additive\n");
    }
  }
  
  if(vertex) {
    NJ_free_vertex(vertex);
  }
  
  if(!nj_args->norandom && permutation) {
    free(permutation);
  }
  
  return(tree);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq $0x0, -0x90(%rbp)
movq -0x18(%rbp), %rdi
callq 0x3450
movl $0x1, -0x78(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x38(%rax)
jne 0x2dc2
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x8, %esi
callq 0x2130
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
jne 0x2dc0
movq 0xc256(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0x83ea(%rip), %rsi      # 0xb196
movb $0x0, %al
callq 0x2150
movq $0x0, -0x8(%rbp)
jmp 0x320b
jmp 0x2dc2
movq -0x18(%rbp), %rdi
callq 0x3570
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x2, 0x10(%rax)
jle 0x3183
movq -0x10(%rbp), %rax
movl 0x38(%rax), %eax
movl %eax, -0x94(%rbp)
testl %eax, %eax
je 0x2e05
jmp 0x2df1
movl -0x94(%rbp), %eax
subl $0x1, %eax
je 0x307a
jmp 0x317e
movl $0x0, -0x74(%rbp)
movq -0x90(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
subq $0x1, %rsi
callq 0x41a0
movq $0x0, -0x58(%rbp)
movq -0x58(%rbp), %rcx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
subq $0x1, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x95(%rbp)
jge 0x2e5b
movq -0x28(%rbp), %rax
cmpq $0x2, 0x10(%rax)
setg %al
movb %al, -0x95(%rbp)
movb -0x95(%rbp), %al
testb $0x1, %al
jne 0x2e6a
jmp 0x3068
movq -0x90(%rbp), %rax
movq -0x58(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rdi
movq -0x30(%rbp), %rsi
leaq -0x48(%rbp), %rdx
leaq -0x80(%rbp), %rcx
callq 0x42a0
movss %xmm0, -0x5c(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x2ebd
movq -0x18(%rbp), %rdi
movq -0x30(%rbp), %rsi
leaq -0x50(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x4450
movss %xmm0, -0x60(%rbp)
jmp 0x2eda
movss -0x5c(%rbp), %xmm0
movss %xmm0, -0x60(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x50(%rbp)
movq $0x0, -0x88(%rbp)
movss -0x5c(%rbp), %xmm0
movss -0x60(%rbp), %xmm1
callq 0x4600
cmpl $0x0, %eax
je 0x2f77
cvtsi2ssq -0x80(%rbp), %xmm0
cvtsi2ssq -0x80(%rbp), %xmm1
cvtsi2ssq -0x88(%rbp), %xmm2
addss %xmm2, %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x68(%rbp)
movss -0x68(%rbp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x80e3(%rip), %xmm0     # 0xb008
subsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x6c(%rbp)
callq 0x9320
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x70(%rbp)
movss -0x70(%rbp), %xmm1
movss -0x68(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x2f63
movss -0x5c(%rbp), %xmm0
movss %xmm0, -0x64(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x2f75
movss -0x60(%rbp), %xmm0
movss %xmm0, -0x64(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x2fb3
movss -0x5c(%rbp), %xmm0
movss -0x60(%rbp), %xmm1
callq 0x4650
cmpl $0x0, %eax
je 0x2f9f
movss -0x5c(%rbp), %xmm0
movss %xmm0, -0x64(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x2fb1
movss -0x60(%rbp), %xmm0
movss %xmm0, -0x64(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x2fb3
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
movss -0x64(%rbp), %xmm0
movl -0x78(%rbp), %r8d
callq 0x46b0
cmpl $0x0, %eax
je 0x3055
movq -0x38(%rbp), %rax
cmpq -0x30(%rbp), %rax
jge 0x2ff8
movq -0x30(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x1, -0x74(%rbp)
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
xorl %r8d, %r8d
callq 0x37a0
movq -0x18(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x3a00
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x3c30
movq -0x90(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
subq $0x1, %rsi
callq 0x41a0
jmp 0x3057
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x2e2c
cmpl $0x0, -0x74(%rbp)
jne 0x3075
movl $0x0, -0x78(%rbp)
jmp 0x317e
movl $0x0, -0x74(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rcx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
subq $0x1, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x96(%rbp)
jge 0x30b8
movq -0x28(%rbp), %rax
cmpq $0x2, 0x10(%rax)
setg %al
movb %al, -0x96(%rbp)
movb -0x96(%rbp), %al
testb $0x1, %al
jne 0x30c7
jmp 0x316f
movq -0x18(%rbp), %rdi
movq -0x30(%rbp), %rsi
leaq -0x38(%rbp), %rdx
leaq -0x80(%rbp), %rcx
callq 0x42a0
movss %xmm0, -0x5c(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
movss -0x5c(%rbp), %xmm0
movl -0x78(%rbp), %r8d
callq 0x46b0
cmpl $0x0, %eax
je 0x315e
movl $0x1, -0x74(%rbp)
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
xorl %r8d, %r8d
callq 0x37a0
movq -0x18(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x3a00
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x3c30
cmpq $0x0, -0x30(%rbp)
je 0x315c
movq -0x30(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x316a
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x3089
cmpl $0x0, -0x74(%rbp)
jne 0x317c
movl $0x0, -0x78(%rbp)
jmp 0x317e
jmp 0x2dcf
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
movl $0x1, %ecx
movl $0x65, %r8d
callq 0x37a0
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x20(%rax)
je 0x31d3
cmpl $0x0, -0x78(%rbp)
je 0x31c3
leaq 0x8013(%rip), %rdi      # 0xb1cd
movb $0x0, %al
callq 0x20e0
jmp 0x31d1
leaq 0x8015(%rip), %rdi      # 0xb1df
movb $0x0, %al
callq 0x20e0
jmp 0x31d3
cmpq $0x0, -0x28(%rbp)
je 0x31e3
movq -0x28(%rbp), %rdi
callq 0x4900
movq -0x10(%rbp), %rax
cmpl $0x0, 0x38(%rax)
jne 0x3203
cmpq $0x0, -0x90(%rbp)
je 0x3203
movq -0x90(%rbp), %rdi
callq 0x2030
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
nopl (%rax,%rax)