// File: /workspace/github_cpp_makefile_star2_O1/myudelson[P]hmm-scalable/HMMProblem.cpp
// Function: HMMProblem::computeBeta(int, data**)
void HMMProblem::computeBeta(NCAT xndat, struct data** x_data) {
	initBeta(xndat, x_data);
    NPAR nS = this->p->nS;
//    int parallel_now = this->p->parallel==2; //PAR
//    #pragma omp parallel for schedule(dynamic) if(parallel_now) //PAR
	for(NCAT x=0; x<xndat; x++) {
        int t;
        NPAR i, j, o;
		if( x_data[x]->cnt!=0 ) continue; // ... and the thing has not been computed yet (e.g. from group to skill)
		for(t=(NDAT)((x_data[x]->n)-1); t>=0; t--) {
			x_data[x]->t = x_data[x]->ix[t]; // statefullness
			if( t==(x_data[x]->n-1) ) { // last \beta
				// \beta_T(i) = 1
				for(i=0; i<nS; i++)
					x_data[x]->beta[t][i] = (this->p->scaled==1)?x_data[x]->c[t]:1.0;;
			} else {
				// \beta_t(i) = \sum_{j=1}^N{beta_{t+1}(j) a_{ij} b_j(o_{t+1})}
                //				o = x_data[x]->obs[t+1]; // next observation
                o = this->p->dat_obs[ x_data[x]->ix[t+1] ];//->get( x_data[x]->ix[t+1] );
				for(i=0; i<nS; i++) {
					for(j=0; j<nS; j++)
						x_data[x]->beta[t][i] += x_data[x]->beta[t+1][j] * getA(x_data[x],i,j) * ((o<0)?1:getB(x_data[x],j,o)); // if observatiob unknown use 1
                    // scale
                    if(this->p->scaled==1) x_data[x]->beta[t][i] *= x_data[x]->c[t];
                }
			}
		} // for all observations, starting with last one
	} // for all groups within skill
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %rbx
movl %esi, %ebp
movq %rdi, %r14
callq 0x119a0
testl %ebp, %ebp
jle 0x11fa7
movq 0x88(%r14), %rax
movzbl 0x8b8(%rax), %eax
movq %rax, 0x8(%rsp)
movl %ebp, %eax
movq %rax, 0x20(%rsp)
xorl %r13d, %r13d
movq (%rbx,%r13,8), %rax
cmpl $0x0, 0x4(%rax)
jne 0x11f99
movslq (%rax), %rcx
movq %rcx, (%rsp)
testq %rcx, %rcx
jle 0x11f99
movq (%rsp), %rsi
leaq -0x1(%rsi), %rax
movq %rax, (%rsp)
movq (%rbx,%r13,8), %rax
movq 0x10(%rax), %rcx
movl -0x4(%rcx,%rsi,4), %edx
movl %edx, 0x8(%rax)
movl (%rax), %edx
movq %rsi, 0x10(%rsp)
cmpq %rdx, %rsi
jne 0x11e83
cmpb $0x0, 0x8(%rsp)
jle 0x11f8d
movq 0x88(%r14), %rcx
movb 0x31(%rcx), %cl
movq 0x30(%rax), %rdx
movq (%rsp), %rsi
movq (%rdx,%rsi,8), %rdx
xorl %esi, %esi
movsd 0x22a94(%rip), %xmm0    # 0x348f0
cmpb $0x1, %cl
jne 0x11e6f
movq 0x20(%rax), %rdi
movq (%rsp), %r8
movsd (%rdi,%r8,8), %xmm0
movsd %xmm0, (%rdx,%rsi,8)
incq %rsi
cmpq %rsi, 0x8(%rsp)
jne 0x11e54
jmp 0x11f8d
cmpb $0x0, 0x8(%rsp)
jle 0x11f8d
movq 0x88(%r14), %rax
movq 0x870(%rax), %rax
movq 0x10(%rsp), %rdx
movslq (%rcx,%rdx,4), %rcx
movb (%rax,%rcx), %r15b
xorl %r12d, %r12d
movsbl %r12b, %eax
movl %eax, 0x1c(%rsp)
xorl %ebp, %ebp
movq (%rbx,%r13,8), %rsi
movq 0x30(%rsi), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movsd (%rax,%rbp,8), %xmm0
movsd %xmm0, 0x30(%rsp)
movq (%r14), %rax
movsbl %bpl, %ecx
movq %r14, %rdi
movl 0x1c(%rsp), %edx
callq *0x18(%rax)
movapd %xmm0, %xmm2
movsd 0x22a01(%rip), %xmm0    # 0x348f0
testb %r15b, %r15b
js 0x11f15
movq (%rbx,%r13,8), %rsi
movq (%r14), %rax
movsbl %r15b, %ecx
movsbl %bpl, %edx
movq %r14, %rdi
movsd %xmm2, 0x28(%rsp)
callq *0x20(%rax)
movsd 0x28(%rsp), %xmm2
movsd 0x30(%rsp), %xmm1
mulsd %xmm2, %xmm1
mulsd %xmm0, %xmm1
movq (%rbx,%r13,8), %rax
movq 0x30(%rax), %rax
movq (%rsp), %rcx
movq (%rax,%rcx,8), %rax
addsd (%rax,%r12,8), %xmm1
movsd %xmm1, (%rax,%r12,8)
incq %rbp
cmpq %rbp, 0x8(%rsp)
jne 0x11eb6
movq 0x88(%r14), %rax
cmpb $0x1, 0x31(%rax)
jne 0x11f7f
movq (%rbx,%r13,8), %rax
movq 0x20(%rax), %rcx
movq 0x30(%rax), %rax
movq (%rsp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq (%rax,%rdx,8), %rax
mulsd (%rax,%r12,8), %xmm0
movsd %xmm0, (%rax,%r12,8)
incq %r12
cmpq 0x8(%rsp), %r12
jne 0x11eac
cmpq $0x1, 0x10(%rsp)
jg 0x11e0a
incq %r13
cmpq 0x20(%rsp), %r13
jne 0x11dec
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq