// File: /workspace/github_c_makefile_star2_O2/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
xorl %edi, %edi
testl %eax, %eax
movl $0x0, %ecx
cmovgl %eax, %ecx
xorpd %xmm0, %xmm0
cmpq %rdi, %rcx
je 0x939c
movsd (%rsi,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rdi
jmp 0x9385
xorpd %xmm2, %xmm2
xorl %edi, %edi
cmpq %rdi, %rcx
je 0x93b9
movsd (%rdx,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm2
incq %rdi
jmp 0x93a2
movslq 0x68(%r14), %rcx
xorpd %xmm3, %xmm3
movq %rax, %rdi
cmpq %rcx, %rdi
jge 0x93db
movsd (%rsi,%rdi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm3
incq %rdi
jmp 0x93c4
xorpd %xmm4, %xmm4
cmpq %rcx, %rax
jge 0x93f6
movsd (%rdx,%rax,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm4
incq %rax
jmp 0x93df
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movsd %xmm3, (%rsp)
movsd %xmm4, 0x8(%rsp)
jb 0x9411
sqrtsd %xmm0, %xmm0
jmp 0x942b
movsd %xmm2, 0x18(%rsp)
callq 0x1210
xorpd %xmm1, %xmm1
movsd (%rsp), %xmm3
movsd 0x18(%rsp), %xmm2
movsd %xmm0, 0x10(%rsp)
ucomisd %xmm1, %xmm2
jae 0x9445
movapd %xmm2, %xmm0
callq 0x1210
movsd (%rsp), %xmm3
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm3
jb 0x9455
sqrtsd %xmm3, %xmm0
jmp 0x9462
movapd %xmm3, %xmm0
callq 0x1210
xorpd %xmm1, %xmm1
movsd %xmm0, (%rsp)
movsd 0x8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jae 0x9478
callq 0x1210
leaq 0x8089(%rip), %rdi      # 0x11508
xorl %esi, %esi
callq 0x10f0
movq 0x8083(%rip), %r15      # 0x11510
movq 0x78(%r14), %r13
movq 0x80(%r14), %r12
movq %r12, %rax
subq %r15, %rax
jle 0x94c8
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 0x9505
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 0x7ffc(%rip), %rbp      # 0x11508
cmpl $0x1, %ebx
jne 0x952d
movq 0x6ae0(%rip), %rax      # 0xfff8
movq (%rax), %rcx
leaq 0x331f(%rip), %rdi      # 0xc841
pushq $0x25
popq %rsi
pushq $0x1
popq %rdx
callq 0x1200
subq %r13, %rbp
cvtsi2sd %rbp, %xmm1
subq %r12, %r15
cvtsi2sd %r15, %xmm0
divsd 0x2f0b(%rip), %xmm0     # 0xc450
addsd %xmm1, %xmm0
movq 0x6aa8(%rip), %rax      # 0xfff8
movq (%rax), %rdi
movsd 0x30(%rsp), %xmm1
divsd 0x20(%rsp), %xmm1
movsd 0x70(%r14), %xmm3
leaq 0x32fb(%rip), %rsi      # 0xc867
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