// File: 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
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x30(%rbp)
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rdx
callq 0x1af60
movq -0x30(%rbp), %rax
movq 0x88(%rax), %rax
movb 0x8b8(%rax), %al
movb %al, -0x19(%rbp)
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x1b9a4
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x0, 0x4(%rax)
je 0x1b6f5
jmp 0x1b996
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl (%rax), %eax
subl $0x1, %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jl 0x1b994
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
movslq -0x24(%rbp), %rcx
movl (%rax,%rcx,4), %ecx
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movl %ecx, 0x8(%rax)
movl -0x24(%rbp), %eax
movq -0x18(%rbp), %rcx
movslq -0x20(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x1b7de
movb $0x0, -0x25(%rbp)
movsbl -0x25(%rbp), %eax
movsbl -0x19(%rbp), %ecx
cmpl %ecx, %eax
jge 0x1b7d9
movq -0x30(%rbp), %rax
movq 0x88(%rax), %rax
movsbl 0x31(%rax), %eax
cmpl $0x1, %eax
jne 0x1b799
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movslq -0x24(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x38(%rbp)
jmp 0x1b7a8
movsd 0x34267(%rip), %xmm0    # 0x4fa08
movsd %xmm0, -0x38(%rbp)
jmp 0x1b7a8
movsd -0x38(%rbp), %xmm0
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x30(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x25(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movb -0x25(%rbp), %al
addb $0x1, %al
movb %al, -0x25(%rbp)
jmp 0x1b759
jmp 0x1b984
movq -0x30(%rbp), %rax
movq 0x88(%rax), %rax
movq 0x870(%rax), %rax
movq -0x18(%rbp), %rcx
movslq -0x20(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movq 0x10(%rcx), %rcx
movl -0x24(%rbp), %edx
addl $0x1, %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
movb (%rax,%rcx), %al
movb %al, -0x27(%rbp)
movb $0x0, -0x25(%rbp)
movsbl -0x25(%rbp), %eax
movsbl -0x19(%rbp), %ecx
cmpl %ecx, %eax
jge 0x1b982
movb $0x0, -0x26(%rbp)
movsbl -0x26(%rbp), %eax
movsbl -0x19(%rbp), %ecx
cmpl %ecx, %eax
jge 0x1b91f
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x30(%rax), %rax
movl -0x24(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x26(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x48(%rbp)
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movb -0x25(%rbp), %dl
movb -0x26(%rbp), %cl
movq (%rdi), %rax
movsbl %dl, %edx
movsbl %cl, %ecx
callq *0x18(%rax)
movaps %xmm0, %xmm1
movsd -0x48(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movsbl -0x27(%rbp), %eax
cmpl $0x0, %eax
jge 0x1b8b2
movsd 0x3415d(%rip), %xmm0    # 0x4fa08
movsd %xmm0, -0x50(%rbp)
jmp 0x1b8d9
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movb -0x26(%rbp), %dl
movb -0x27(%rbp), %cl
movq (%rdi), %rax
movsbl %dl, %edx
movsbl %cl, %ecx
callq *0x20(%rax)
movsd %xmm0, -0x50(%rbp)
movsd -0x40(%rbp), %xmm0
movsd -0x50(%rbp), %xmm2
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x30(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x25(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movb -0x26(%rbp), %al
addb $0x1, %al
movb %al, -0x26(%rbp)
jmp 0x1b82b
movq -0x30(%rbp), %rax
movq 0x88(%rax), %rax
movsbl 0x31(%rax), %eax
cmpl $0x1, %eax
jne 0x1b973
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movslq -0x24(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x30(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x25(%rbp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0x1b975
movb -0x25(%rbp), %al
addb $0x1, %al
movb %al, -0x25(%rbp)
jmp 0x1b817
jmp 0x1b984
jmp 0x1b986
movl -0x24(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x1b709
jmp 0x1b996
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x1b6d2
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)