// File: /workspace/github_cpp_makefile_star2_O2/myudelson[P]hmm-scalable/HMMProblemSt.cpp
// Function: HMMProblemSt::doBarzilaiBorweinStep(FitBitSt*)
void HMMProblemSt::doBarzilaiBorweinStep(FitBitSt *fb) {
    // Barzilai Borwein value: s' * s / ( s' * (g-g_m1) )
    
    NPAR i;
    NCAT l,k, nK = this->task->nK;

    // first scale down gradients -- MOVED TO Cycle Bit
    // fb->scaleGradients(false, this->active_set_block);
    
    // compute s_k_m1
    NUMBER *s_k_m1 = init1D<NUMBER>(fb->nPARAM);
    NUMBER *alpha_step = init1D<NUMBER>(nK);
    NUMBER *alpha_denom = init1D<NUMBER>(nK);
    for(l=0; l<fb->nPARAM; l++){
        s_k_m1[l] = fb->PARAMm1[l] - fb->PARAMm2[l];
    }

    // compute alpha_step
    for(k=0; k<nK; k++) {
        if (this->active_set_block[k]==0) continue; // if not in the active set, skip
        for(i=0; i<skill1_n; i++) {
            l = skill1_n*k + i;
            alpha_step[k] += s_k_m1[l]*s_k_m1[l];
            alpha_denom[k] += s_k_m1[l]*(fb->GRAD[l] - fb->GRADm1[l]);;
        }
        alpha_step[k] = alpha_step[k] / safe0num(alpha_denom[k]);
    }

    // make the step
    for(k=0; k<nK; k++) {
        if (this->active_set_block[k]==0) continue; // if not in the active set, skip
        for(i=0; i<skill1_n; i++) {
            l = skill1_n*k + i;
            fb->PARAM[l] -= alpha_step[k] * fb->GRAD[l];
        }
    }
    
    // recycle
    free(s_k_m1);
    free(alpha_step);
    free(alpha_denom);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %rbp
movq 0x68(%rdi), %rax
movl 0x908(%rax), %r14d
movl 0xc(%rsi), %edi
callq 0x6a57
movq %rax, %r15
movl %r14d, %edi
callq 0x6a57
movq %rax, %r12
movq %r14, 0x8(%rsp)
movl %r14d, %edi
callq 0x6a57
movq %rax, %r13
movl 0xc(%rbx), %eax
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
cmpq %rcx, %rax
je 0xd6cf
movq 0x18(%rbx), %rdx
movq 0x20(%rbx), %rsi
movsd (%rdx,%rcx,8), %xmm0
subsd (%rsi,%rcx,8), %xmm0
movsd %xmm0, (%r15,%rcx,8)
incq %rcx
jmp 0xd6ad
xorl %r14d, %r14d
movq 0x8(%rsp), %r11
testl %r11d, %r11d
cmovlel %r14d, %r11d
movq %rbp, 0x10(%rsp)
movq 0x58(%rbp), %rax
cmpq %r11, %r14
je 0xd78f
cmpb $0x0, (%rax,%r14)
je 0xd787
movl 0x38(%rbp), %eax
movl %r14d, %ecx
imull %eax, %ecx
xorl %edx, %edx
movsbl %dl, %edx
cmpl %edx, %eax
jle 0xd754
leal (%rcx,%rdx), %esi
movslq %esi, %rsi
movsd (%r15,%rsi,8), %xmm0
mulsd %xmm0, %xmm0
addsd (%r12,%r14,8), %xmm0
movsd %xmm0, (%r12,%r14,8)
movq 0x30(%rbx), %rdi
movq 0x38(%rbx), %r8
movsd (%rdi,%rsi,8), %xmm0
subsd (%r8,%rsi,8), %xmm0
mulsd (%r15,%rsi,8), %xmm0
addsd (%r13,%r14,8), %xmm0
movsd %xmm0, (%r13,%r14,8)
incb %dl
jmp 0xd706
movsd (%r12,%r14,8), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd (%r13,%r14,8), %xmm0
movq %r11, %rbp
callq 0x55a1
movq %rbp, %r11
movq 0x10(%rsp), %rbp
movsd 0x8(%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%r12,%r14,8)
incq %r14
jmp 0xd6e3
movslq 0x38(%rbp), %rcx
xorl %edx, %edx
cmpq %r11, %rdx
je 0xd7e7
cmpb $0x0, (%rax,%rdx)
je 0xd7e2
movq %rdx, %rsi
imulq %rcx, %rsi
xorl %edi, %edi
movsbl %dil, %r8d
cmpl %r8d, %ecx
jle 0xd7e2
movsbq %dil, %r8
addq %rsi, %r8
movsd (%r12,%rdx,8), %xmm0
movq 0x10(%rbx), %r9
movq 0x30(%rbx), %r10
mulsd (%r10,%r8,8), %xmm0
movsd (%r9,%r8,8), %xmm1
subsd %xmm0, %xmm1
movsd %xmm1, (%r9,%r8,8)
incb %dil
jmp 0xd7a9
incq %rdx
jmp 0xd795
movq %r15, %rdi
callq 0x3230
movq %r12, %rdi
callq 0x3230
movq %r13, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3230
nop