// File: myudelson[P]hmm-scalable/HMMProblem.cpp
// Function: HMMProblem::FitNullSkill(double*, bool)
void HMMProblem::FitNullSkill(NUMBER* loglik_rmse, bool keep_SE) {
    if(this->p->n_null_skill_group==0) {
        this->null_obs_ratio[0] = 1; // set first obs to 1, simplex preserved
        return; // 0 loglik
    }
    NDAT count_all_null_skill = 0;
    struct data *dat; // used as pointer
    // count occurrences
    NCAT g;
    NDAT t;
    NPAR isTarget, o, m;
    for(g=0; g<this->p->n_null_skill_group; g++) {
        dat = &this->p->null_skills[g];
        if(dat->cnt != 0)
            continue; // observe block
//        count_all_null_skill += dat->n; // does not work for item- and non- stratified cross-validations
        for(t=0; t<dat->n; t++) {
            o = this->p->dat_obs[ dat->ix[t] ];//->get( dat->ix[t] );
            if(((int)o)>=0) { // -1 we skip \xff in char notation
                this->null_obs_ratio[ o ]++;
                count_all_null_skill++; // crude, but works properly for all cross validations
            }
        }
    }
    // produce means
    this->null_skill_obs = 0;
    this->null_skill_obs_prob = 0;
    for(m=0; m<this->p->nO; m++) {
        this->null_obs_ratio[m] /= count_all_null_skill;
        if( this->null_obs_ratio[m] > this->null_skill_obs_prob ) {
            this->null_skill_obs_prob = this->null_obs_ratio[m];
            this->null_skill_obs = m;
        }
    }
    this->null_skill_obs_prob = safe01num(this->null_skill_obs_prob); // safety for logging
    // compute loglik
    NDAT N = 0;
    for(g=0; g<this->p->n_null_skill_group; g++) {
        dat = &this->p->null_skills[g];
        if(dat->cnt != 0)
            continue; // observe block
        for(t=0; t<dat->n; t++) {
            N += dat->n;
            isTarget = this->p->dat_obs[ dat->ix[t] ]/*->get( dat->ix[t] )*/ == this->null_skill_obs;
            loglik_rmse[0] -= isTarget*safelog(this->null_skill_obs_prob) + (1-isTarget)*safelog(1-this->null_skill_obs_prob);
            loglik_rmse[1] += pow(isTarget - this->null_skill_obs_prob, 2);
        }
    }
    if(!keep_SE) loglik_rmse[1] = sqrt(loglik_rmse[1]/N);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movq 0x88(%rax), %rax
cmpl $0x0, 0x8d8(%rax)
jne 0x1e878
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rax
movsd 0x31199(%rip), %xmm0    # 0x4fa08
movsd %xmm0, (%rax)
jmp 0x1eb9b
movl $0x0, -0x18(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x38(%rbp), %rcx
movl -0x24(%rbp), %eax
movq 0x88(%rcx), %rcx
cmpl 0x8d8(%rcx), %eax
jge 0x1e955
movq -0x38(%rbp), %rax
movq 0x88(%rax), %rax
movq 0x8d0(%rax), %rax
movslq -0x24(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x1e8cd
jmp 0x1e947
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x1e945
movq -0x38(%rbp), %rax
movq 0x88(%rax), %rax
movq 0x870(%rax), %rax
movq -0x20(%rbp), %rcx
movq 0x10(%rcx), %rcx
movslq -0x28(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movb (%rax,%rcx), %al
movb %al, -0x2a(%rbp)
movsbl -0x2a(%rbp), %eax
cmpl $0x0, %eax
jl 0x1e938
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rax
movsbq -0x2a(%rbp), %rcx
movsd 0x310e3(%rip), %xmm0    # 0x4fa08
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x1e93a
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x1e8d4
jmp 0x1e947
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x1e886
movq -0x38(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x28(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0x30(%rax)
movb $0x0, -0x2b(%rbp)
movq -0x38(%rbp), %rcx
movsbl -0x2b(%rbp), %eax
movq 0x88(%rcx), %rcx
movsbl 0x8b9(%rcx), %ecx
cmpl %ecx, %eax
jge 0x1e9ec
movq -0x38(%rbp), %rax
cvtsi2sdl -0x18(%rbp), %xmm1
movq 0x18(%rax), %rcx
movsbq -0x2b(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%rcx,%rdx,8)
movq 0x18(%rax), %rcx
movsbq -0x2b(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
ucomisd 0x30(%rax), %xmm0
jbe 0x1e9e0
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rcx
movsbq -0x2b(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movsd %xmm0, 0x30(%rax)
movsbl -0x2b(%rbp), %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, 0x28(%rax)
jmp 0x1e9e2
movb -0x2b(%rbp), %al
addb $0x1, %al
movb %al, -0x2b(%rbp)
jmp 0x1e96d
movq -0x38(%rbp), %rax
movsd 0x30(%rax), %xmm0
callq 0x99d0
movq -0x38(%rbp), %rax
movsd %xmm0, 0x30(%rax)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x38(%rbp), %rcx
movl -0x24(%rbp), %eax
movq 0x88(%rcx), %rcx
cmpl 0x8d8(%rcx), %eax
jge 0x1eb75
movq -0x38(%rbp), %rax
movq 0x88(%rax), %rax
movq 0x8d0(%rax), %rax
movslq -0x24(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x1ea5b
jmp 0x1eb67
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x1eb65
movq -0x38(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rcx), %ecx
addl -0x30(%rbp), %ecx
movl %ecx, -0x30(%rbp)
movq 0x88(%rax), %rcx
movq 0x870(%rcx), %rcx
movq -0x20(%rbp), %rdx
movq 0x10(%rdx), %rdx
movslq -0x28(%rbp), %rsi
movslq (%rdx,%rsi,4), %rdx
movsbl (%rcx,%rdx), %ecx
cvtsi2sd %ecx, %xmm0
ucomisd 0x28(%rax), %xmm0
sete %cl
setnp %dl
andb %dl, %cl
andb $0x1, %cl
movb %cl, -0x29(%rbp)
movsbl -0x29(%rbp), %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, -0x50(%rbp)
movsd 0x30(%rax), %xmm0
callq 0x9ae0
movq -0x38(%rbp), %rax
movsd %xmm0, -0x48(%rbp)
movsbl -0x29(%rbp), %edx
movl $0x1, %ecx
subl %edx, %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, -0x40(%rbp)
movsd 0x30f12(%rip), %xmm0    # 0x4fa08
subsd 0x30(%rax), %xmm0
callq 0x9ae0
movsd -0x50(%rbp), %xmm1
movsd -0x48(%rbp), %xmm2
movq -0x38(%rbp), %rax
movaps %xmm0, %xmm3
movsd -0x40(%rbp), %xmm0
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movq -0x10(%rbp), %rcx
movsd (%rcx), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, (%rcx)
movsbl -0x29(%rbp), %ecx
cvtsi2sd %ecx, %xmm0
subsd 0x30(%rax), %xmm0
movl $0x2, %edi
callq 0xf6b0
movq -0x10(%rbp), %rax
addsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rax)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x1ea62
jmp 0x1eb67
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x1ea11
testb $0x1, -0x11(%rbp)
jne 0x1eb9b
movq -0x10(%rbp), %rax
movsd 0x8(%rax), %xmm0
cvtsi2sdl -0x30(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x5220
movq -0x10(%rbp), %rax
movsd %xmm0, 0x8(%rax)
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)