// File: /workspace/github_cpp_makefile_star2_O2/myudelson[P]hmm-scalable/HMMProblemSt.cpp
// Function: HMMProblemSt::computeAlphaAndPOParam(double*)
NUMBER HMMProblemSt::computeAlphaAndPOParam(NUMBER *metrics_res) {
    NPAR nS = this->task->nS, nO = this->task->nO, o = -1, isTarget;
    NDAT Nst = this->task->Nst, N = this->task->N;
    NCAT g,k, nK = this->task->nK, nG = this->task->nG;
    NPAR f_metrics_target_obs = this->task->metrics_target_obs;
    NPAR f_is_scaled = this->task->is_scaled==1;
    // prepare values
    NUMBER loglik = 0.0, loglik_nonull = 0.0, sse = 0.0, sse_nonull = 0.0, ncorr = 0.0, ncorr_nonull = 0.0;
    NUMBER p = 0.0;///, corr = 0.0;
    
    // initialize reused parameters before run
//    NUMBER ***group_skill_map; // traced state values for student (group) * skill //UNBOOST
//    group_skill_map = init3D<NUMBER>(nG, nK, nS);//UNBOOST
//    toValue3D(group_skill_map, (NDAT)nG, (NDAT)nK, (NDAT)nS, -1.0); // -1 means not set (use pLo)
    initAlphaEtAl();

    NDAT **alpha_gk_ix = NULL;
    
    NUMBER **predict = this->task->dat_predict; // running value of prediction, do we save it?
    NUMBER *predict_k = this->task->dat_predict_k; // running value of prediction, do we save it?
    if(metrics_res!=NULL & this->task->predictions==2) {
        if(predict_k==NULL) predict_k = initToValue1D<NUMBER>(this->task->Nst,0.0);
        else toZero1D<NUMBER>(predict_k, this->task->Nst);
    }
    // toZero2D(predict,N,nO); // don't blast everything, the predictions are inited to 0 line by line as the overall data is updated according to the active set

    struct context* ctx = new context;

    if(!this->is_fwd_bwd_built) { // if helper structures were not built
        toValue1D(this->forward_ix, Nst, -1);
        toValue1D(this->backward_ix, Nst, -1);
        toValue1D(this->ndat_k, nK, 0);
        alpha_gk_ix = initToValue2D<NDAT>(nG, nK, -1);
    }
    
    for(NDAT t=0; t<N; t++) {
        o = this->task->dat_obs[t]; // observation y in the data is 1-right, 0-wrong; math assumes HMM-Scalable 1-right, 2-wrong, with -1 taken out, so 0-right, 1-wrong
        isTarget = this->task->metrics_target_obs == o;
        //corr = 1-o; // corr 1 - right, 0 - wrong
        g = this->task->dat_group[t]; // -1, because in data they were 1-starting
        ctx->g=g;
        ctx->o=o;
        ctx->t=t;
        // grab skill array (if exists)
        NCAT *ar;
        NPAR n, i;
        getSkillsAtRow(this->task, t, &ar, &n);
        // deal with null skill
        if(ar[0]<0 && metrics_res!=NULL) { // account for no skill label only if we need metrics (likely called from predict)
            isTarget = this->null_skill_obs==o;
            // old: rmse += pow(isTarget - hmm->null_skill_obs_prob,2);
            sse += pow(isTarget - this->null_obs_ratios[f_metrics_target_obs],2);
            // old: accuracy += isTarget == (hmm->null_skill_obs_prob>=0.5);
            ncorr += isTarget == (this->null_obs_ratios[f_metrics_target_obs]==maxn(this->null_obs_ratios,nO) && this->null_obs_ratios[f_metrics_target_obs] > 1/nO);
            loglik -= isTarget*safelog(this->null_skill_obs_prob) + (1-isTarget)*safelog(1 - this->null_skill_obs_prob);
            
            for(NPAR m=0; m<nO; m++) {
                predict[t][m] = this->null_obs_ratios[m];
            }
        }
        if(ar[0]<0) {
            continue;
        }
        
        // produce corrects first
        producePCorrect(group_skill_map, ar, n, predict[t], ctx); //UNBOOST
        
        NCAT n_active = 0;
        for(int l=0; l<n; l++) n_active+=(this->active_set_block[ar[l]]>0);
        
        for(int l=0; l<n && n_active==n/**/; l++) {
            k = ar[l];
            ctx->k=k;
            NDAT tt = l + this->task->dat_skill_rix[t]; // tt – index into stacked skill array
            if(f_is_scaled) this->scale[tt] = 0;
            
            NDAT pre_tt = (this->is_fwd_bwd_built) ? this->backward_ix[tt]: alpha_gk_ix[g][k]; // previous tt index of forward variable alpha, alpha_gk_ix[g][k] is running (prior) tt index of this group/skill (gk)
            
            if(pre_tt==-1) { // it's alpha(1,i)
                // compute \alpha_1(i) = \pi_i b_i(o_1)
                for(i=0; i<nS; i++) {
                    this->alpha[tt][i] = getPI(ctx,i) * ((o<0)?1:getB(ctx,i,o)); // if observatiob unknown use 1
                    if(f_is_scaled) {
                        this->scale[tt] += this->alpha[tt][i];
                    }
                }
            } else { // it's alpha(t,i)
                // compute \alpha_{t}(i) = b_j(o_{t})\sum_{j=1}^N{\alpha_{t-1}(j) a_{ji}}
                for(NPAR i=0; i<nS; i++) {
                    for(NPAR j=0; j<nS; j++) {
                        alpha[tt][i] += alpha[pre_tt][j] * getA(ctx,j,i);
                    }
                    this->alpha[tt][i] *= ((o<0)?1:getB(ctx,i,o)); // if observatiob unknown use 1
//                    if( this->alpha[t][i] < 0 || this->alpha[t][i] > 1)
//                        fprintf(stderr, "ERROR! alpha value is not within [0, 1] range!\n");
                    if(f_is_scaled) this->scale[tt] += alpha[tt][i];
                }
            }
            // update backward_ix, forward_ix if necessary
            if(!this->is_fwd_bwd_built) {
                if( pre_tt != -1 ) { // there exists a prior datapoint for this student and skill
                  this->forward_ix[pre_tt] = tt; // point from that previous position to current tt index
                  this->backward_ix[tt] = pre_tt; // point from current position to the previous
                }
                // now update the last tt index
                alpha_gk_ix[g][k] = tt;
                // count datapoints per k
                this->ndat_k[k]++;
            }// update backward_ix, forward_ix if necessary
        } // all skills in a row
        
        // update per row values, skill, group, Elo, etc
        updateValuesLocal(group_skill_map, ar, n, predict[t], ctx); //UNBOOST
        
        // update obj val
        p = safe01num( predict[t][f_metrics_target_obs]);
        loglik -= safelog(  p)*   isTarget  +  safelog(1-p)*(1-isTarget);
        if(metrics_res!=NULL) { // we are predicting
            loglik_nonull -= safelog(  p)*   isTarget  +  safelog(1-p)*(1-isTarget);
            sse += pow(isTarget-predict[t][f_metrics_target_obs],2);
            sse_nonull += pow(isTarget-predict[t][f_metrics_target_obs],2);
            ncorr += isTarget == (predict[t][f_metrics_target_obs]==maxn(predict[t],nO) && predict[t][f_metrics_target_obs]>1/nO);
            ncorr_nonull += isTarget == (predict[t][f_metrics_target_obs]==maxn(predict[t],nO) && predict[t][f_metrics_target_obs]>1/nO);
            if(this->task->predictions==2) {
                for(int l=0; l<n; l++) {
                    k = ar[l];
                    NDAT tt = l + this->task->dat_skill_rix[t];
                    predict_k[tt] = group_skill_map[g][k][0];
                }
            }
        }



    } // all rows in the data
    
    // compute this->po_param_gk and this->loglik_k
    for(int t=0; t<N; t++) {
        g = this->task->dat_group[t]; // -1, because in data they were 1-starting
        NCAT *ar;
        NPAR n, i;
        getSkillsAtRow(this->task, t, &ar, &n);
        
        NCAT n_active = 0;
        for(int l=0; l<n; l++) n_active+=(this->active_set_block[ar[l]]>0);
        
        for(int l=0; l<n && (n_active==n)/**/; l++) {
            k = ar[l];
            ctx->k=k;
            NDAT tt = l + this->task->dat_skill_rix[t]; // tt – index into stacked skill array
            if(f_is_scaled) // if scaled – multiply all scales
                this->po_param_gk[g][k] *= this->scale[tt];
            else { // if not scaled, add alpha's for the last row in g/k sequence
                if(this->forward_ix[tt]==-1) {
                    for(i=0; i<nS; i++) this->po_param_gk[g][k] += this->alpha[tt][i];
                    this->loglik_k[k] -= safelog(this->po_param_gk[g][k]);
                }
            }
        }
    } // compute this->po_param_gk & compute this->loglik_k
    // compute this->loglik_k

    // recycle
    this->is_fwd_bwd_built = true; // set in any way
    if(alpha_gk_ix!=NULL) free2D(alpha_gk_ix, nG);
    if(metrics_res != NULL) {
        metrics_res[0] = loglik;
        metrics_res[1] = loglik_nonull;
        metrics_res[2] = sse;
        metrics_res[3] = sse_nonull;
        metrics_res[4] = ncorr;
        metrics_res[5] = ncorr_nonull;
        if(this->task->predictions==2) {
            this->task->dat_predict_k = predict_k;
        }
    }
    
//    free3D(group_skill_map, this->task->nG, this->task->nK); //UNBOOST
    delete ctx;
    return loglik; //TODO, figure out a diff way to sum it, and not multiple times
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %rsi, %r14
movq %rdi, %rbx
movq (%rdi), %rax
movq 0x68(%rdi), %rcx
movzbl 0x900(%rcx), %edx
movq %rdx, 0x128(%rsp)
movsbl 0x901(%rcx), %edx
movq %rdx, 0xb8(%rsp)
movl 0x8fc(%rcx), %ebp
movl 0x8f8(%rcx), %r12d
movl 0x908(%rcx), %r13d
movl 0x904(%rcx), %edx
movl %edx, 0x6c(%rsp)
movsbq 0x6c(%rcx), %rdx
movq %rdx, 0x80(%rsp)
movb 0x41(%rcx), %cl
movb %cl, 0xf(%rsp)
callq *0x78(%rax)
movq 0x68(%rbx), %rax
movq 0x8c8(%rax), %rcx
movq %rcx, 0xc0(%rsp)
movq 0x8d0(%rax), %rcx
movq %rcx, 0x88(%rsp)
movq %r14, 0x38(%rsp)
testq %r14, %r14
je 0xa78d
cmpl $0x2, 0x70(%rax)
jne 0xa78d
movl 0x8fc(%rax), %esi
movq 0x88(%rsp), %rdi
testq %rdi, %rdi
je 0xa77b
callq 0xedbf
jmp 0xa78d
xorps %xmm0, %xmm0
movl %esi, %edi
callq 0xec30
movq %rax, 0x88(%rsp)
pushq $0x14
popq %rdi
callq 0x31c0
movq %rax, %r15
cmpb $0x0, 0xc0(%rbx)
je 0xa7a5
xorl %edi, %edi
jmp 0xa7f1
movq 0xb8(%rbx), %rdi
movl %r13d, %r14d
pushq $-0x1
popq %r13
movl %ebp, %esi
movl %r13d, %edx
callq 0xee1a
movq 0xb0(%rbx), %rdi
movl %ebp, %esi
movl %r13d, %edx
callq 0xee1a
movq 0x88(%rbx), %rdi
movl %r14d, %esi
xorl %edx, %edx
callq 0xee1a
movl 0x6c(%rsp), %edi
movl %r14d, %esi
movl %r13d, %edx
callq 0xee2f
movq %rax, %rdi
movq 0xb8(%rsp), %rcx
leal 0x1(%rcx), %eax
cmpl $0x3, %eax
movl $0x0, %eax
cmovbl %ecx, %eax
cvtsi2sd %eax, %xmm0
movapd %xmm0, 0x130(%rsp)
leaq 0xb0(%rbx), %rax
movq %rax, 0x150(%rsp)
testb %cl, %cl
movl $0x0, %eax
cmovgl %ecx, %eax
movq 0x128(%rsp), %rcx
testb %cl, %cl
movl $0x0, %edx
cmovlel %edx, %ecx
movq %rcx, 0xd8(%rsp)
testl %r12d, %r12d
cmovlel %edx, %r12d
movq %r12, 0x118(%rsp)
movzbl %al, %eax
movq %rax, 0x148(%rsp)
xorpd %xmm3, %xmm3
xorpd %xmm0, %xmm0
movsd %xmm0, 0x58(%rsp)
xorl %r14d, %r14d
movsd %xmm0, 0xb0(%rsp)
movsd %xmm0, 0xa8(%rsp)
movsd %xmm0, 0x40(%rsp)
movq 0x38(%rsp), %rax
movq %r15, %r12
movq %rdi, 0x48(%rsp)
movapd %xmm3, 0x70(%rsp)
cmpq 0x118(%rsp), %r14
je 0xb0a1
testq %rax, %rax
sete %bpl
movq 0x68(%rbx), %rdi
movq 0x880(%rdi), %rax
movb (%rax,%r14), %r13b
cmpb %r13b, 0x6c(%rdi)
sete %al
movq %rax, 0xc8(%rsp)
movq 0x890(%rdi), %rax
movslq (%rax,%r14,4), %rcx
movq %rcx, 0x120(%rsp)
movl %ecx, 0x4(%r12)
movb %r13b, 0x10(%r12)
movl %r14d, 0xc(%r12)
movl %r14d, %esi
leaq 0x10(%rsp), %rdx
leaq 0xe(%rsp), %rcx
callq 0x6a19
movq 0x10(%rsp), %rdx
movl (%rdx), %eax
testl %eax, %eax
setns %cl
orb %bpl, %cl
movb %r13b, 0xf0(%rsp)
movsbl %r13b, %ecx
movl %ecx, 0xe0(%rsp)
jne 0xa9b1
cvtsi2sd %ecx, %xmm1
movsd 0x18(%rbx), %xmm0
movapd %xmm0, 0x20(%rsp)
movsd %xmm1, 0x18(%rsp)
ucomisd %xmm0, %xmm1
xorpd %xmm0, %xmm0
movq %r14, %r13
jne 0xa958
jp 0xa958
movsd 0x5ff8(%rip), %xmm0     # 0x10950
movsd %xmm0, 0x50(%rsp)
movq 0x10(%rbx), %rdi
movq 0x80(%rsp), %r14
movsd (%rdi,%r14,8), %xmm0
movsd %xmm0, 0x90(%rsp)
movq 0xb8(%rsp), %rsi
callq 0x574a
movsd 0x90(%rsp), %xmm2
ucomisd %xmm0, %xmm2
jne 0xa9c8
jp 0xa9c8
movq 0x10(%rbx), %rax
movsd (%rax,%r14,8), %xmm0
xorl %eax, %eax
ucomisd 0x130(%rsp), %xmm0
seta %al
jmp 0xa9ca
movapd 0x70(%rsp), %xmm3
movapd %xmm3, %xmm0
movq 0xc0(%rsp), %rsi
jmp 0xaadb
xorl %eax, %eax
movapd 0x70(%rsp), %xmm1
movq %r13, %r14
movsd 0x18(%rsp), %xmm0
cmpeqsd 0x20(%rsp), %xmm0
movq %xmm0, %rcx
andl $0x1, %ecx
movsd 0x5f60(%rip), %xmm0     # 0x10950
movq %rcx, 0xc8(%rsp)
cmpl %ecx, %eax
je 0xa9ff
xorps %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0x50(%rsp), %xmm0
subsd %xmm2, %xmm0
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movapd %xmm0, 0x90(%rsp)
movsd 0x20(%rbx), %xmm0
callq 0x55d5
movsd %xmm0, 0x100(%rsp)
movapd 0x20(%rsp), %xmm1
cmpneqsd 0x18(%rsp), %xmm1
movsd 0x5f08(%rip), %xmm0     # 0x10950
andpd %xmm0, %xmm1
movapd %xmm1, 0x20(%rsp)
subsd 0x20(%rbx), %xmm0
callq 0x55d5
movsd 0x100(%rsp), %xmm1
mulsd 0x20(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm1
addsd %xmm0, %xmm1
movq 0x10(%rbx), %rax
xorl %ecx, %ecx
movq 0xc0(%rsp), %rsi
movq 0x148(%rsp), %rdi
cmpq %rcx, %rdi
je 0xaaa3
movsd (%rax,%rcx,8), %xmm0
movq (%rsi,%r14,8), %rdx
movsd %xmm0, (%rdx,%rcx,8)
incq %rcx
jmp 0xaa8b
movsd 0x58(%rsp), %xmm0
addsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x40(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x10(%rsp), %rdx
movl (%rdx), %eax
movapd 0x70(%rsp), %xmm3
movapd 0x90(%rsp), %xmm0
movsd %xmm0, %xmm3            # xmm3 = xmm0[0],xmm3[1]
testl %eax, %eax
js 0xb088
movapd %xmm3, 0x70(%rsp)
movq (%rbx), %rax
movq %rsi, %rdi
movq 0xc8(%rbx), %rsi
movsbl 0xe(%rsp), %ecx
movq (%rdi,%r14,8), %r8
movq %rbx, %rdi
movq %r12, %r9
callq *0x50(%rax)
movzbl 0xe(%rsp), %eax
movq 0x58(%rbx), %rcx
movq 0x10(%rsp), %rdx
xorl %esi, %esi
testb %al, %al
movl %eax, %edi
cmovlel %esi, %edi
movzbl %dil, %edi
xorl %r10d, %r10d
cmpq %rsi, %rdi
je 0xab47
movslq (%rdx,%rsi,4), %r8
xorl %r9d, %r9d
cmpb $0x0, (%rcx,%r8)
setg %r9b
addl %r9d, %r10d
incq %rsi
jmp 0xab2a
movq 0x48(%rsp), %rcx
movq 0x120(%rsp), %rdx
leaq (%rcx,%rdx,8), %rcx
movq %rcx, 0x18(%rsp)
xorl %edx, %edx
movq %r14, 0xd0(%rsp)
movl %r10d, 0x100(%rsp)
movsbl %al, %ecx
movsbq %cl, %rax
cmpq %rax, %rdx
jge 0xadb2
cmpl %ecx, %r10d
jne 0xadb2
movq 0x10(%rsp), %rax
movslq (%rax,%rdx,4), %rcx
movl %ecx, (%r12)
movq 0x68(%rbx), %rax
movq 0x8b0(%rax), %rax
movslq (%rax,%r14,4), %rax
movq %rdx, 0x50(%rsp)
movslq %edx, %rdx
addq %rax, %rdx
cmpb $0x1, 0xf(%rsp)
jne 0xabc2
movq 0xa8(%rbx), %rax
andq $0x0, (%rax,%rdx,8)
cmpb $0x0, 0xc0(%rbx)
movq 0x18(%rsp), %rax
cmovneq 0x150(%rsp), %rax
movq %rcx, 0x90(%rsp)
cmovnel %edx, %ecx
movq (%rax), %rax
movslq %ecx, %rcx
movslq (%rax,%rcx,4), %rbp
movq %rdx, 0x60(%rsp)
movslq %edx, %r13
xorl %r14d, %r14d
cmpq $-0x1, %rbp
je 0xad3d
cmpq 0xd8(%rsp), %r14
je 0xad4b
xorl %r12d, %r12d
cmpq %r12, 0x128(%rsp)
je 0xac63
movq (%rbx), %rax
movq 0x70(%rbx), %rcx
movq (%rcx,%rbp,8), %rcx
movsd (%rcx,%r12,8), %xmm0
movsd %xmm0, 0x20(%rsp)
movsbl %r14b, %ecx
movsbl %r12b, %edx
movq %rbx, %rdi
movq %r15, %rsi
callq *0x30(%rax)
movq 0x70(%rbx), %rax
movq (%rax,%r13,8), %rax
mulsd 0x20(%rsp), %xmm0
addsd (%rax,%r14,8), %xmm0
movsd %xmm0, (%rax,%r14,8)
incq %r12
jmp 0xac12
movsd 0x5ce5(%rip), %xmm0     # 0x10950
cmpb $0x0, 0xf0(%rsp)
movq %r15, %r12
js 0xac8f
movq (%rbx), %rax
movsbl %r14b, %edx
movq %rbx, %rdi
movq %r12, %rsi
movl 0xe0(%rsp), %ecx
callq *0x38(%rax)
movq 0x70(%rbx), %rax
movq (%rax,%r13,8), %rax
mulsd (%rax,%r14,8), %xmm0
movsd %xmm0, (%rax,%r14,8)
cmpb $0x1, 0xf(%rsp)
jne 0xacbd
movq 0xa8(%rbx), %rax
addsd (%rax,%r13,8), %xmm0
movsd %xmm0, (%rax,%r13,8)
incq %r14
jmp 0xac01
movq (%rbx), %rax
movsbl %r14b, %edx
movq %rbx, %rdi
movq %r12, %rsi
callq *0x28(%rax)
movapd %xmm0, %xmm1
movsd 0x5c6f(%rip), %xmm0     # 0x10950
cmpb $0x0, 0xf0(%rsp)
js 0xad0e
movq (%rbx), %rax
movsbl %r14b, %edx
movq %rbx, %rdi
movq %r12, %rsi
movl 0xe0(%rsp), %ecx
movsd %xmm1, 0x20(%rsp)
callq *0x38(%rax)
movsd 0x20(%rsp), %xmm1
mulsd %xmm0, %xmm1
movq 0x70(%rbx), %rax
movq (%rax,%r13,8), %rax
movsd %xmm1, (%rax,%r14,8)
cmpb $0x1, 0xf(%rsp)
jne 0xad3a
movq 0xa8(%rbx), %rax
addsd (%rax,%r13,8), %xmm1
movsd %xmm1, (%rax,%r13,8)
incq %r14
cmpq %r14, 0xd8(%rsp)
jne 0xacc5
cmpb $0x0, 0xc0(%rbx)
movq 0xd0(%rsp), %r14
jne 0xad99
cmpl $-0x1, %ebp
je 0xad77
movq 0xb8(%rbx), %rax
movl %r13d, (%rax,%rbp,4)
movq 0xb0(%rbx), %rax
movl %ebp, (%rax,%r13,4)
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq 0x90(%rsp), %rcx
movq 0x60(%rsp), %rdx
movl %edx, (%rax,%rcx,4)
movq 0x88(%rbx), %rax
incl (%rax,%rcx,4)
movq 0x50(%rsp), %rdx
incq %rdx
movb 0xe(%rsp), %al
movl 0x100(%rsp), %r10d
jmp 0xab6f
movq (%rbx), %rax
movq 0xc8(%rbx), %rsi
movq 0x10(%rsp), %rdx
movq 0xc0(%rsp), %rbp
movq (%rbp,%r14,8), %r8
movq %rbx, %rdi
movq %r12, %r9
callq *0x58(%rax)
movq (%rbp,%r14,8), %rax
movq 0x80(%rsp), %r13
movsd (%rax,%r13,8), %xmm0
callq 0x557b
movsd %xmm0, 0x20(%rsp)
callq 0x55d5
movsd %xmm0, 0xf0(%rsp)
movsd 0x5b45(%rip), %xmm0     # 0x10950
subsd 0x20(%rsp), %xmm0
movapd %xmm0, 0xe0(%rsp)
callq 0x55d5
movq 0xc8(%rsp), %rcx
movl %ecx, %eax
xorb $0x1, %al
movzbl %cl, %ecx
cvtsi2sd %ecx, %xmm1
movzbl %al, %eax
cvtsi2sd %eax, %xmm2
mulsd %xmm2, %xmm0
movsd 0xf0(%rsp), %xmm3
mulsd %xmm1, %xmm3
addsd %xmm0, %xmm3
movsd 0x40(%rsp), %xmm0
subsd %xmm3, %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x38(%rsp), %rax
testq %rax, %rax
je 0xaf38
movl %ecx, 0x18(%rsp)
movsd %xmm2, 0x50(%rsp)
movapd %xmm1, 0xf0(%rsp)
movsd 0x20(%rsp), %xmm0
callq 0x55d5
movsd %xmm0, 0x90(%rsp)
movaps 0xe0(%rsp), %xmm0
callq 0x55d5
movsd %xmm0, 0x60(%rsp)
movq (%rbp,%r14,8), %rdi
movsd (%rdi,%r13,8), %xmm0
movaps %xmm0, 0x20(%rsp)
movq %rbp, %r13
movq %r14, %rbp
movq 0xb8(%rsp), %r14
movl %r14d, %esi
callq 0x574a
movaps %xmm0, 0xe0(%rsp)
movq (%r13,%rbp,8), %rdi
movq 0x80(%rsp), %rax
movsd (%rdi,%rax,8), %xmm0
movapd %xmm0, 0x100(%rsp)
movl %r14d, %esi
callq 0x574a
movapd 0x100(%rsp), %xmm5
ucomisd %xmm0, %xmm5
jne 0xaf48
jp 0xaf48
movq 0xd0(%rsp), %r14
movq (%r13,%r14,8), %rax
movq 0x80(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
xorl %eax, %eax
ucomisd 0x130(%rsp), %xmm0
seta %al
movapd 0x70(%rsp), %xmm3
jmp 0xaf58
movq 0x48(%rsp), %rdi
movapd 0x70(%rsp), %xmm3
jmp 0xb099
xorl %eax, %eax
movapd 0x70(%rsp), %xmm3
movq 0xd0(%rsp), %r14
movl 0x18(%rsp), %ecx
movsd 0x59ec(%rip), %xmm0     # 0x10950
cmpl %ecx, %eax
movq 0x48(%rsp), %rdi
movapd 0xf0(%rsp), %xmm2
je 0xaf7a
xorpd %xmm0, %xmm0
movsd 0x60(%rsp), %xmm1
mulsd 0x50(%rsp), %xmm1
movsd 0x90(%rsp), %xmm4
mulsd %xmm2, %xmm4
addsd %xmm1, %xmm4
movsd 0xa8(%rsp), %xmm1
subsd %xmm4, %xmm1
movsd %xmm1, 0xa8(%rsp)
movapd 0x20(%rsp), %xmm1
subsd %xmm1, %xmm2
mulsd %xmm2, %xmm2
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
addpd %xmm2, %xmm3
movapd 0xe0(%rsp), %xmm2
cmpneqpd %xmm1, %xmm2
movapd 0x130(%rsp), %xmm1
cmpnltpd %xmm5, %xmm1
orpd %xmm2, %xmm1
movd %xmm1, %eax
xorb 0xc8(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cvtsi2sd %eax, %xmm1
movsd 0x58(%rsp), %xmm2
addsd %xmm1, %xmm2
movsd %xmm2, 0x58(%rsp)
movsd 0xb0(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0xb0(%rsp)
movq 0x68(%rbx), %rax
cmpl $0x2, 0x70(%rax)
jne 0xb094
movzbl 0xe(%rsp), %esi
movq 0x10(%rsp), %rcx
movq 0xc8(%rbx), %rdx
testb %sil, %sil
movl $0x0, %edi
cmovlel %edi, %esi
movzbl %sil, %esi
xorl %edi, %edi
cmpq %rdi, %rsi
je 0xb088
movslq (%rcx,%rdi,4), %r8
movq 0x8b0(%rax), %r9
movslq (%r9,%r14,4), %r9
movq 0x120(%rsp), %r10
movq (%rdx,%r10,8), %r10
movq (%r10,%r8,8), %r8
movsd (%r8), %xmm0
addq %rdi, %r9
movq 0x88(%rsp), %r8
movsd %xmm0, (%r8,%r9,8)
incq %rdi
jmp 0xb049
movq 0x38(%rsp), %rax
movq 0x48(%rsp), %rdi
jmp 0xb099
movq 0x38(%rsp), %rax
incq %r14
jmp 0xa897
xorl %esi, %esi
cmpq 0x118(%rsp), %rsi
je 0xb206
movq 0x68(%rbx), %rdi
movq 0x890(%rdi), %rax
movslq (%rax,%rsi,4), %r14
movq %rsi, 0x20(%rsp)
leaq 0x10(%rsp), %rdx
leaq 0xe(%rsp), %rcx
callq 0x6a19
movzbl 0xe(%rsp), %eax
movq 0x58(%rbx), %rcx
movq 0x10(%rsp), %rdx
xorl %esi, %esi
testb %al, %al
movl %eax, %edi
cmovlel %esi, %edi
movzbl %dil, %edi
xorl %r13d, %r13d
cmpq %rsi, %rdi
je 0xb10f
movslq (%rdx,%rsi,4), %r8
xorl %r9d, %r9d
cmpb $0x0, (%rcx,%r8)
setg %r9b
addl %r9d, %r13d
incq %rsi
jmp 0xb0f2
xorl %ebp, %ebp
movq 0x20(%rsp), %rsi
movsbq %al, %rcx
cmpq %rcx, %rbp
jge 0xb1f4
movsbl %al, %ecx
cmpl %ecx, %r13d
jne 0xb1f4
movq 0x10(%rsp), %rcx
movslq (%rcx,%rbp,4), %r15
movl %r15d, (%r12)
movq 0x68(%rbx), %rcx
movq 0x8b0(%rcx), %rcx
movslq (%rcx,%rsi,4), %rdx
movslq %ebp, %rcx
addq %rdx, %rcx
cmpb $0x1, 0xf(%rsp)
jne 0xb17a
movq 0x78(%rbx), %rdx
movq 0xa8(%rbx), %rdi
movsd (%rdi,%rcx,8), %xmm0
movq (%rdx,%r14,8), %rcx
mulsd (%rcx,%r15,8), %xmm0
movsd %xmm0, (%rcx,%r15,8)
jmp 0xb1ec
movq 0xb8(%rbx), %rdx
cmpl $-0x1, (%rdx,%rcx,4)
jne 0xb1ec
movq 0x70(%rbx), %rax
movq 0x78(%rbx), %rdx
xorl %esi, %esi
cmpq %rsi, 0xd8(%rsp)
je 0xb1b9
movq (%rax,%rcx,8), %rdi
movsd (%rdi,%rsi,8), %xmm0
movq (%rdx,%r14,8), %rdi
addsd (%rdi,%r15,8), %xmm0
movsd %xmm0, (%rdi,%r15,8)
incq %rsi
jmp 0xb191
movq 0x78(%rbx), %rax
movq (%rax,%r14,8), %rax
movsd (%rax,%r15,8), %xmm0
callq 0x55d5
movq 0x20(%rsp), %rsi
movq 0x80(%rbx), %rax
movsd (%rax,%r15,8), %xmm1
subsd %xmm0, %xmm1
movsd %xmm1, (%rax,%r15,8)
movb 0xe(%rsp), %al
incq %rbp
jmp 0xb116
incq %rsi
movq 0x38(%rsp), %rax
movq 0x48(%rsp), %rdi
jmp 0xb0a3
movb $0x1, 0xc0(%rbx)
testq %rdi, %rdi
je 0xb220
movl 0x6c(%rsp), %esi
callq 0xeea2
movq 0x38(%rsp), %rax
testq %rax, %rax
je 0xb278
movsd 0x40(%rsp), %xmm0
movsd %xmm0, (%rax)
movsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x8(%rax)
movaps 0x70(%rsp), %xmm0
movups %xmm0, 0x10(%rax)
movsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x20(%rax)
movsd 0xb0(%rsp), %xmm0
movsd %xmm0, 0x28(%rax)
movq 0x68(%rbx), %rax
cmpl $0x2, 0x70(%rax)
jne 0xb278
movq 0x88(%rsp), %rcx
movq %rcx, 0x8d0(%rax)
pushq $0x14
popq %rsi
movq %r12, %rdi
callq 0x31d0
movsd 0x40(%rsp), %xmm0
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop