// File: /workspace/github_c_makefile_star2_O1/debbiemarkslab[P]plmc/src/inference.c
// Function: ReportProgresslBFGS
static int ReportProgresslBFGS(void *instance, const lbfgsfloatval_t *x,
    const lbfgsfloatval_t *g, const lbfgsfloatval_t fx,
    const lbfgsfloatval_t xnorm, const lbfgsfloatval_t gnorm,
    const lbfgsfloatval_t step, int n, int k, int ls) {
    void **d = (void **)instance;
    alignment_t *ali = (alignment_t *)d[0];

    /* Compute norms of relevant parameters */
    lbfgsfloatval_t hNorm = 0.0, eNorm = 0.0, hGNorm = 0.0, eGNorm = 0.0;
    for (int i = 0; i < ali->nSites * ali->nCodes; i++)
        hNorm += x[i]*x[i];
    for (int i = 0; i < ali->nSites * ali->nCodes; i++)
        hGNorm += g[i]*g[i];
    for (int i = ali->nSites * ali->nCodes; i < ali->nParams; i++)
        eNorm += x[i]*x[i];
    for (int i = ali->nSites * ali->nCodes; i < ali->nParams; i++)
        eGNorm += g[i]*g[i];
    hNorm = sqrt(hNorm);
    hGNorm = sqrt(hGNorm);
    eNorm = sqrt(eNorm);
    eGNorm = sqrt(eGNorm);

    /* Retrieve elapsed time */
    static struct timeval now;
    gettimeofday(&now, NULL);
    if (now.tv_usec < ali->start.tv_usec) {
        int nsec = (ali->start.tv_usec - now.tv_usec) / 1000000 + 1;
        ali->start.tv_usec -= 1000000 * nsec;
        ali->start.tv_sec += nsec;
    }
    if (now.tv_usec - ali->start.tv_usec > 1000000) {
        int nsec = (now.tv_usec - ali->start.tv_usec) / 1000000;
        ali->start.tv_usec += 1000000 * nsec;
        ali->start.tv_sec -= nsec;
    }
    numeric_t elapsed = (numeric_t) (now.tv_sec - ali->start.tv_sec)
                      + ((numeric_t) (now.tv_usec - ali->start.tv_usec)) / 1E6;

    if (k == 1) fprintf(stderr,
        "iter\ttime\tcond\tfx\t-loglk"
        "\t||h||\t||e||\n");
    fprintf(stderr, "%d\t%.1f\t%.2f\t%.1f\t%.1f\t%.1f\t%.1f\n",
        k, elapsed, gnorm / xnorm, fx, ali->negLogLk, hNorm, eNorm);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %r8d, %ebx
movsd %xmm2, 0x30(%rsp)
movsd %xmm1, 0x20(%rsp)
movsd %xmm0, 0x28(%rsp)
movq (%rdi), %r14
movslq 0x4(%r14), %rcx
movslq 0x8(%r14), %rax
imulq %rcx, %rax
xorpd %xmm2, %xmm2
movl %eax, %ecx
xorpd %xmm0, %xmm0
testl %eax, %eax
jle 0x181d
xorl %edi, %edi
movsd (%rsi,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rdi
cmpq %rdi, %rcx
jne 0x1808
testl %eax, %eax
jle 0x183c
xorpd %xmm2, %xmm2
xorl %edi, %edi
movsd (%rdx,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm2
incq %rdi
cmpq %rdi, %rcx
jne 0x1827
movslq 0x68(%r14), %rcx
xorpd %xmm3, %xmm3
xorpd %xmm4, %xmm4
cmpl %ecx, %eax
jge 0x1864
movq %rax, %rdi
movsd (%rsi,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm4
incq %rdi
cmpq %rdi, %rcx
jne 0x184f
cmpl %ecx, %eax
jge 0x1883
cltq
xorpd %xmm3, %xmm3
movsd (%rdx,%rax,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm3
incq %rax
cmpq %rax, %rcx
jne 0x186e
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movsd %xmm3, 0x8(%rsp)
movsd %xmm4, (%rsp)
jb 0x189e
sqrtsd %xmm0, %xmm0
jmp 0x18b8
movsd %xmm2, 0x18(%rsp)
callq 0x1210
xorpd %xmm1, %xmm1
movsd (%rsp), %xmm4
movsd 0x18(%rsp), %xmm2
movsd %xmm0, 0x10(%rsp)
ucomisd %xmm1, %xmm2
jae 0x18d2
movapd %xmm2, %xmm0
callq 0x1210
movsd (%rsp), %xmm4
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm4
jb 0x18e2
sqrtsd %xmm4, %xmm0
jmp 0x18ef
movapd %xmm4, %xmm0
callq 0x1210
xorpd %xmm1, %xmm1
movsd %xmm0, (%rsp)
movsd 0x8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jae 0x1905
callq 0x1210
leaq 0x11bfc(%rip), %rdi     # 0x13508
xorl %esi, %esi
callq 0x10f0
movq 0x11bf6(%rip), %r15     # 0x13510
movq 0x80(%r14), %rcx
movq %rcx, %rax
subq %r15, %rax
jle 0x194e
movl $0xf4240, %esi          # imm = 0xF4240
cqto
idivq %rsi
incl %eax
imull $0xf4240, %eax, %edx    # imm = 0xF4240
movslq %edx, %rdx
subq %rdx, %rcx
movq %rcx, 0x80(%r14)
cltq
addq %rax, 0x78(%r14)
movq 0x80(%r14), %rcx
movq %r15, %rax
subq %rcx, %rax
cmpq $0xf4241, %rax          # imm = 0xF4241
jl 0x198f
movl $0xf4240, %esi          # imm = 0xF4240
xorl %edx, %edx
divq %rsi
movabsq $0xf424000000000, %rdx  # imm = 0xF424000000000
imulq %rax, %rdx
sarq $0x20, %rdx
addq %rcx, %rdx
movq %rdx, 0x80(%r14)
cltq
subq %rax, 0x78(%r14)
movq 0x11b72(%rip), %r13     # 0x13508
movq 0x78(%r14), %rbp
movq 0x80(%r14), %r12
cmpl $0x1, %ebx
jne 0x19c2
movq 0x1064b(%rip), %rax     # 0x11ff8
movq (%rax), %rcx
leaq 0xcf26(%rip), %rdi      # 0xe8dd
pushq $0x25
popq %rsi
pushq $0x1
popq %rdx
callq 0x1200
subq %rbp, %r13
cvtsi2sd %r13, %xmm1
subq %r12, %r15
cvtsi2sd %r15, %xmm0
divsd 0xcafe(%rip), %xmm0     # 0xe4d8
addsd %xmm1, %xmm0
movq 0x10613(%rip), %rax     # 0x11ff8
movq (%rax), %rdi
movsd 0x30(%rsp), %xmm1
divsd 0x20(%rsp), %xmm1
movsd 0x70(%r14), %xmm3
leaq 0xcf02(%rip), %rsi      # 0xe903
movl %ebx, %edx
movsd 0x28(%rsp), %xmm2
movsd 0x10(%rsp), %xmm4
movsd (%rsp), %xmm5
movb $0x6, %al
callq 0x1170
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq