// File: /workspace/github_c_makefile_star2_O3/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
xorpd %xmm0, %xmm0
xorpd %xmm3, %xmm3
testl %eax, %eax
jle 0x1894
movl %eax, %ecx
xorl %edi, %edi
movsd (%rsi,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rdi
cmpq %rdi, %rcx
jne 0x1860
xorpd %xmm3, %xmm3
testl %eax, %eax
jle 0x1894
xorl %edi, %edi
movsd (%rdx,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm3
incq %rdi
cmpq %rdi, %rcx
jne 0x187f
movslq 0x68(%r14), %rcx
xorpd %xmm4, %xmm4
cmpl %ecx, %eax
jge 0x18db
xorpd %xmm2, %xmm2
movq %rax, %rdi
movsd (%rsi,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm2
incq %rdi
cmpq %rdi, %rcx
jne 0x18a7
xorpd %xmm4, %xmm4
cmpl %ecx, %eax
jge 0x18db
cltq
movsd (%rdx,%rax,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm4
incq %rax
cmpq %rax, %rcx
jne 0x18c6
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movsd %xmm2, (%rsp)
movsd %xmm4, 0x8(%rsp)
jb 0x18f6
sqrtsd %xmm0, %xmm0
jmp 0x1910
movsd %xmm3, 0x18(%rsp)
callq 0x1220
xorpd %xmm1, %xmm1
movsd 0x18(%rsp), %xmm3
movsd (%rsp), %xmm2
movsd %xmm0, 0x10(%rsp)
ucomisd %xmm1, %xmm3
jae 0x192a
movapd %xmm3, %xmm0
callq 0x1220
movsd (%rsp), %xmm2
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm2
jb 0x193a
sqrtsd %xmm2, %xmm0
jmp 0x1947
movapd %xmm2, %xmm0
callq 0x1220
xorpd %xmm1, %xmm1
movsd %xmm0, (%rsp)
movsd 0x8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jae 0x195d
callq 0x1220
leaq 0x10ba4(%rip), %rdi     # 0x12508
xorl %esi, %esi
callq 0x10f0
movq 0x10b9e(%rip), %r15     # 0x12510
movq 0x78(%r14), %r13
movq 0x80(%r14), %r12
movq %r12, %rax
subq %r15, %rax
jle 0x19ad
movl $0xf4240, %ecx          # imm = 0xF4240
cqto
idivq %rcx
incl %eax
imull $0xf4240, %eax, %ecx    # imm = 0xF4240
movslq %ecx, %rcx
subq %rcx, %r12
movq %r12, 0x80(%r14)
cltq
addq %rax, %r13
movq %r13, 0x78(%r14)
movq %r15, %rax
subq %r12, %rax
cmpq $0xf4241, %rax          # imm = 0xF4241
jl 0x19ea
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movabsq $0xf424000000000, %rcx  # imm = 0xF424000000000
imulq %rax, %rcx
sarq $0x20, %rcx
addq %rcx, %r12
movq %r12, 0x80(%r14)
cltq
subq %rax, %r13
movq %r13, 0x78(%r14)
movq 0x10b17(%rip), %rbp     # 0x12508
cmpl $0x1, %ebx
jne 0x1a12
movq 0xf5fb(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0xbec6(%rip), %rdi      # 0xd8cd
pushq $0x25
popq %rsi
pushq $0x1
popq %rdx
callq 0x1210
subq %r13, %rbp
cvtsi2sd %rbp, %xmm1
subq %r12, %r15
cvtsi2sd %r15, %xmm0
divsd 0xba9e(%rip), %xmm0     # 0xd4c8
addsd %xmm1, %xmm0
movq 0xf5c3(%rip), %rax      # 0x10ff8
movq (%rax), %rdi
movsd 0x30(%rsp), %xmm1
divsd 0x20(%rsp), %xmm1
movsd 0x70(%r14), %xmm3
leaq 0xbea2(%rip), %rsi      # 0xd8f3
movl %ebx, %edx
movsd 0x28(%rsp), %xmm2
movsd 0x10(%rsp), %xmm4
movsd (%rsp), %xmm5
movb $0x6, %al
callq 0x1180
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq