// File: /workspace/github_c_makefile_star2_O0/c-zhou[P]oatk/path.c
// Function: graph_sequence_coverage_precise
double graph_sequence_coverage_precise(asg_t *asg, double min_cf, int min_copy, int max_copy, int **_copy_number)
{
    uint32_t i, n_seg, iter;
    int *copy_number;
    double total_covs, total_lens, avg_cov, new_avg_cov, min_avg_cov;
    asmg_t *g;
    
    n_seg = asg->n_seg;
    g = asg->asmg;
    min_avg_cov = graph_sequence_coverage_lower_bound(asg, 0.3);
    avg_cov = graph_sequence_coverage_rough(asg, min_cf);
#ifdef DEBUG_SEG_COPY_EST
    fprintf(stderr, "[DEBUG_SEG_COPY_EST::%s] min coverage: %.3f; rough avg coverage: %.3f\n",
            __func__, min_avg_cov, avg_cov);
#endif
    avg_cov = MAX(avg_cov, min_avg_cov);
    MYCALLOC(copy_number, n_seg);
    for (i = 0; i < n_seg; ++i) {
        if (g->vtx[i].del) continue;
        copy_number[i] = MIN(MAX(min_copy, lround((double) g->vtx[i].cov / avg_cov)), max_copy);
    }

    iter = 0;
    while (iter++ < EM_MAX_ITER) {
#ifdef DEBUG_SEG_COPY_EST
        fprintf(stderr, "[DEBUG_SEG_COPY_EST::%s] iteration %u avg coverage: %.3f\n", __func__, iter, avg_cov);
#endif
        total_covs = total_lens = 0;
        for (i = 0; i < n_seg; ++i) {
            if (g->vtx[i].del) continue;
            total_lens += (double) g->vtx[i].len * copy_number[i];
            total_covs += (double) g->vtx[i].len * g->vtx[i].cov;
        }
        // FIXME total_lens could be zero
        new_avg_cov = total_lens < FLT_EPSILON? DBL_MAX : (total_covs / total_lens);
        new_avg_cov = MAX(new_avg_cov, min_avg_cov);
        if (fabs(new_avg_cov - avg_cov) < FLT_EPSILON) 
            break; // converged
        avg_cov = new_avg_cov;
        for (i = 0; i < n_seg; ++i) {
            if (g->vtx[i].del) continue;
            copy_number[i] = MIN(MAX(min_copy, lround((double) g->vtx[i].cov / avg_cov)), max_copy);
        }
    }

#ifdef DEBUG_SEG_COPY_EST
    fprintf(stderr, "[DEBUG_SEG_COPY_EST::%s] sequence copy number estimation finished in %u iterations with an average sequence coverage %.3f\n",
            __func__, iter, avg_cov);
    for (i = 0; i < n_seg; ++i) {
        if (g->vtx[i].del) continue;
        fprintf(stderr, "[DEBUG_SEG_COPY_EST::%s] %s %u %d\n", __func__, asg->seg[i].name, g->vtx[i].cov, copy_number[i]);
    }
#endif
    
    if (_copy_number)
        *_copy_number = copy_number;
    else
        free(copy_number);

    return avg_cov;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x8(%rbp), %rdi
movsd 0x1f4f7(%rip), %xmm0    # 0x23488
callq 0x44d0
movsd %xmm0, -0x60(%rbp)
movq -0x8(%rbp), %rdi
movsd -0x10(%rbp), %xmm0
callq 0x4760
movsd %xmm0, -0x50(%rbp)
movsd -0x50(%rbp), %xmm0
ucomisd -0x60(%rbp), %xmm0
jbe 0x3fc6
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
jmp 0x3fd0
movsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
movsd -0x70(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movl -0x28(%rbp), %eax
movl %eax, %edi
movl $0x4, %esi
callq 0x2240
movq %rax, -0x38(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x28(%rbp), %eax
jae 0x415a
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x20(%rax), %eax
shrl $0x1e, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x4025
jmp 0x414c
movslq -0x14(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, %rcx
movq -0x78(%rbp), %rax
cmpq %rcx, %rax
jle 0x4069
movslq -0x14(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x4093
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movslq -0x18(%rbp), %rcx
cmpq %rcx, %rax
jge 0x412e
movslq -0x14(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, %rcx
movq -0x88(%rbp), %rax
cmpq %rcx, %rax
jle 0x40f1
movslq -0x14(%rbp), %rax
movq %rax, -0x90(%rbp)
jmp 0x411e
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x98(%rbp)
jmp 0x4139
movslq -0x18(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movl %eax, %edx
movq -0x38(%rbp), %rax
movl -0x24(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x3ff4
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x2c(%rbp)
cmpl $0x3e8, %eax            # imm = 0x3E8
jae 0x449f
xorps %xmm0, %xmm0
movsd %xmm0, -0x48(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x40(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x28(%rbp), %eax
jae 0x4277
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x20(%rax), %eax
shrl $0x1e, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x41bf
jmp 0x4269
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rdx
movq 0x18(%rax,%rdx,8), %xmm0
movaps 0x1f395(%rip), %xmm2    # 0x23570
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x1f399(%rip), %xmm1    # 0x23580
subpd %xmm1, %xmm0
movaps %xmm0, %xmm3
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm3, %xmm0
movq -0x38(%rbp), %rax
cvtsi2sdl (%rax,%rcx,4), %xmm4
movsd -0x48(%rbp), %xmm3
mulsd %xmm4, %xmm0
addsd %xmm3, %xmm0
movsd %xmm0, -0x48(%rbp)
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movq 0x18(%rax,%rcx,8), %xmm0
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x20(%rax), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm2
movsd -0x40(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x418e
movsd 0x1f211(%rip), %xmm0    # 0x23490
ucomisd -0x48(%rbp), %xmm0
jbe 0x4298
movsd 0x1f20a(%rip), %xmm0    # 0x23498
movsd %xmm0, -0xa0(%rbp)
jmp 0x42aa
movsd -0x40(%rbp), %xmm0
divsd -0x48(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
movsd -0xa0(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
movsd -0x58(%rbp), %xmm0
ucomisd -0x60(%rbp), %xmm0
jbe 0x42d2
movsd -0x58(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
jmp 0x42df
movsd -0x60(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
movsd -0xa8(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
movsd -0x58(%rbp), %xmm1
subsd -0x50(%rbp), %xmm1
movaps 0x1f263(%rip), %xmm0    # 0x23560
pand %xmm0, %xmm1
movsd 0x1f187(%rip), %xmm0    # 0x23490
ucomisd %xmm1, %xmm0
jbe 0x4314
jmp 0x449f
movsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x28(%rbp), %eax
jae 0x449a
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x20(%rax), %eax
shrl $0x1e, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x4356
jmp 0x448c
movslq -0x14(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, %rcx
movq -0xb0(%rbp), %rax
cmpq %rcx, %rax
jle 0x43a3
movslq -0x14(%rbp), %rax
movq %rax, -0xb8(%rbp)
jmp 0x43d0
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movslq -0x18(%rbp), %rcx
cmpq %rcx, %rax
jge 0x446e
movslq -0x14(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, %rcx
movq -0xc0(%rbp), %rax
cmpq %rcx, %rax
jle 0x4431
movslq -0x14(%rbp), %rax
movq %rax, -0xc8(%rbp)
jmp 0x445e
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
leaq (%rcx,%rcx,4), %rcx
movl 0x20(%rax,%rcx,8), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cvtsi2sd %eax, %xmm0
divsd -0x50(%rbp), %xmm0
callq 0x2100
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0xd0(%rbp)
jmp 0x4479
movslq -0x18(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rax
movl %eax, %edx
movq -0x38(%rbp), %rax
movl -0x24(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x4325
jmp 0x4161
cmpq $0x0, -0x20(%rbp)
je 0x44b3
movq -0x38(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
jmp 0x44bc
movq -0x38(%rbp), %rdi
callq 0x2060
movsd -0x50(%rbp), %xmm0
addq $0xd0, %rsp
popq %rbp
retq
nopw (%rax,%rax)