// File: /workspace/github_cpp_makefile_star2_O3/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 $0x148, %rsp            # imm = 0x148
movq %rsi, %r15
movq %rdi, %rbx
movq (%rdi), %rax
movq 0x68(%rdi), %rcx
movzbl 0x900(%rcx), %r12d
movsbl 0x901(%rcx), %edx
movq %rdx, 0xc0(%rsp)
movl 0x8fc(%rcx), %r13d
movl 0x8f8(%rcx), %edx
movq %rdx, 0xd0(%rsp)
movl 0x908(%rcx), %r14d
movl 0x904(%rcx), %edx
movl %edx, 0x8c(%rsp)
movsbq 0x6c(%rcx), %rdx
movq %rdx, 0xd8(%rsp)
movb 0x41(%rcx), %cl
movb %cl, 0xf(%rsp)
callq *0x78(%rax)
movq 0x68(%rbx), %rax
movq 0x8c8(%rax), %rcx
movq %rcx, 0xe8(%rsp)
movq 0x8d0(%rax), %rcx
movq %rcx, 0x70(%rsp)
testq %r15, %r15
je 0xb9c4
cmpl $0x2, 0x70(%rax)
jne 0xb9c4
movslq 0x8fc(%rax), %rdx
cmpq $0x0, 0x70(%rsp)
je 0xb9b2
testl %edx, %edx
jle 0xb9c4
shlq $0x3, %rdx
movq 0x70(%rsp), %rdi
xorl %esi, %esi
callq 0x2100
jmp 0xb9c4
movl $0x8, %esi
movq %rdx, %rdi
callq 0x2110
movq %rax, 0x70(%rsp)
movl $0x14, %edi
callq 0x21c0
movq %rax, 0x68(%rsp)
cmpb $0x0, 0xc0(%rbx)
je 0xb9e0
xorl %edi, %edi
jmp 0xba43
testl %r13d, %r13d
jle 0xba11
movq 0xb8(%rbx), %rdi
shlq $0x2, %r13
movl $0xff, %esi
movq %r13, %rdx
callq 0x2100
movq 0xb0(%rbx), %rdi
movl $0xff, %esi
movq %r13, %rdx
callq 0x2100
testl %r14d, %r14d
jle 0xba2c
movq 0x88(%rbx), %rdi
leaq (,%r14,4), %rdx
xorl %esi, %esi
callq 0x2100
movl 0x8c(%rsp), %edi
movl %r14d, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x10981
movq %rax, %rdi
movq 0x68(%rsp), %r13
cmpl $0x0, 0xd0(%rsp)
jle 0xc492
movq %rdi, 0xe0(%rsp)
movq 0xc0(%rsp), %rcx
leal 0x1(%rcx), %eax
xorl %r14d, %r14d
cmpl $0x3, %eax
movl $0x0, %eax
cmovbl %ecx, %eax
cvtsi2sd %eax, %xmm0
movapd %xmm0, 0x110(%rsp)
leaq 0xb0(%rbx), %rax
movq %rax, 0x140(%rsp)
movzbl %cl, %ebp
xorpd %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd %xmm0, 0xb0(%rsp)
movsd %xmm0, 0xb8(%rsp)
movsd %xmm0, 0x50(%rsp)
movsd %xmm0, 0xa8(%rsp)
movsd %xmm0, 0x48(%rsp)
movq %r15, 0xc8(%rsp)
movq %rbp, 0xf8(%rsp)
movq %r12, 0x108(%rsp)
movq 0x68(%rbx), %rdi
movq 0x880(%rdi), %rax
movb (%rax,%r14), %r15b
cmpb %r15b, 0x6c(%rdi)
sete %al
movq %rax, 0xf0(%rsp)
movq 0x890(%rdi), %rax
movslq (%rax,%r14,4), %rcx
movq %rcx, 0x100(%rsp)
movl %ecx, 0x4(%r13)
movb %r15b, 0x10(%r13)
movl %r14d, 0xc(%r13)
movl %r14d, %esi
leaq 0x10(%rsp), %rdx
leaq 0xe(%rsp), %rcx
callq 0x7797
movb %r15b, 0x60(%rsp)
movsbl %r15b, %eax
movl %eax, 0x80(%rsp)
cmpq $0x0, 0xc8(%rsp)
movq %r14, 0x78(%rsp)
je 0xbcef
movq 0x10(%rsp), %rax
cmpl $0x0, (%rax)
jns 0xbcef
xorps %xmm1, %xmm1
cvtsi2sdl 0x80(%rsp), %xmm1
movsd 0x18(%rbx), %xmm0
movapd %xmm0, 0x90(%rsp)
movsd %xmm1, 0x40(%rsp)
ucomisd %xmm0, %xmm1
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0xd8(%rsp), %rax
jne 0xbba8
jp 0xbba8
movsd 0x6dae(%rip), %xmm0     # 0x12950
movsd %xmm0, 0x20(%rsp)
movq 0x10(%rbx), %rdi
movsd (%rdi,%rax,8), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0xc0(%rsp), %rsi
movq %rax, %r14
callq 0x6312
movsd 0x18(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jne 0xbbef
jp 0xbbef
movq 0x10(%rbx), %rax
movsd (%rax,%r14,8), %xmm0
xorl %eax, %eax
ucomisd 0x110(%rsp), %xmm0
seta %al
jmp 0xbbf1
xorl %eax, %eax
movq 0x78(%rsp), %r14
movsd 0x40(%rsp), %xmm0
cmpeqsd 0x90(%rsp), %xmm0
movq %xmm0, %rcx
andl $0x1, %ecx
movsd 0x6d3a(%rip), %xmm0     # 0x12950
movq %rcx, 0xf0(%rsp)
cmpl %ecx, %eax
je 0xbc25
xorps %xmm0, %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x20(%rsp), %xmm0
subsd %xmm1, %xmm0
mulsd %xmm0, %xmm0
movsd 0x48(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x48(%rsp)
movsd 0x20(%rbx), %xmm0
callq 0x619d
movsd %xmm0, 0x18(%rsp)
movsd 0x6cef(%rip), %xmm0     # 0x12950
subsd 0x20(%rbx), %xmm0
callq 0x619d
movsd 0x50(%rsp), %xmm1
addsd 0x58(%rsp), %xmm1
movsd %xmm1, 0x50(%rsp)
movapd 0x90(%rsp), %xmm1
cmpneqsd 0x40(%rsp), %xmm1
movsd 0x6cbb(%rip), %xmm2     # 0x12950
andpd %xmm2, %xmm1
mulsd %xmm0, %xmm1
movsd 0x18(%rsp), %xmm0
mulsd 0x20(%rsp), %xmm0
addsd %xmm1, %xmm0
movapd %xmm0, %xmm1
movsd 0x38(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
cmpb $0x0, 0xc0(%rsp)
jle 0xbcef
movq 0x10(%rbx), %rax
movq 0xe8(%rsp), %rcx
movq (%rcx,%r14,8), %rcx
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%rdx,8)
incq %rdx
cmpq %rdx, %rbp
jne 0xbcdd
movq 0x10(%rsp), %rdx
cmpl $0x0, (%rdx)
js 0xc2fc
movq (%rbx), %rax
movq 0xc8(%rbx), %rsi
movsbl 0xe(%rsp), %ecx
movq 0xe8(%rsp), %rdi
movq (%rdi,%r14,8), %r8
movq %rbx, %rdi
movq %r13, %r9
callq *0x50(%rax)
movsbl 0xe(%rsp), %r10d
testl %r10d, %r10d
jle 0xc027
movq 0x58(%rbx), %rax
movq 0x10(%rsp), %rcx
movl %r10d, %edx
xorl %edi, %edi
xorl %esi, %esi
movslq (%rcx,%rdi,4), %r8
xorl %r9d, %r9d
cmpb $0x0, (%rax,%r8)
setg %r9b
addl %r9d, %esi
incq %rdi
cmpq %rdi, %rdx
jne 0xbd40
testb %r10b, %r10b
jle 0xc027
cmpl %r10d, %esi
jne 0xc027
movq 0xe0(%rsp), %rax
movq 0x100(%rsp), %rcx
leaq (%rax,%rcx,8), %rdx
xorl %esi, %esi
movl %r10d, 0x120(%rsp)
movq %rdx, 0x138(%rsp)
movq 0x10(%rsp), %rax
movslq (%rax,%rsi,4), %rdi
movl %edi, (%r13)
movq 0x68(%rbx), %rax
movq 0x8b0(%rax), %rax
movslq (%rax,%r14,4), %rax
movslq %esi, %r8
addq %rax, %r8
cmpb $0x1, 0xf(%rsp)
jne 0xbdcb
movq 0xa8(%rbx), %rax
movq $0x0, (%rax,%r8,8)
cmpb $0x0, 0xc0(%rbx)
movq %rdx, %rax
cmovneq 0x140(%rsp), %rax
movl %edi, %ecx
cmovnel %r8d, %ecx
movq (%rax), %rax
movslq %ecx, %rcx
movslq (%rax,%rcx,4), %r9
cmpq $-0x1, %r9
movq %r9, 0x90(%rsp)
je 0xbefb
testb %r12b, %r12b
jle 0xbfd0
movq %rdi, 0x58(%rsp)
movq %rsi, 0x40(%rsp)
movq %r8, 0x18(%rsp)
movslq %r8d, %rdx
movq 0x70(%rbx), %rax
xorl %ebp, %ebp
xorl %r12d, %r12d
movq 0x90(%rsp), %r15
movq (%rax,%r15,8), %rax
movsd (%rax,%r12,8), %xmm0
movsd %xmm0, 0x20(%rsp)
movq (%rbx), %rax
movsbl %bpl, %r14d
movq %rdx, %r13
movsbl %r12b, %edx
movq %rbx, %rdi
movq 0x68(%rsp), %rsi
movl %r14d, %ecx
callq *0x30(%rax)
movq %r13, %rdx
movq 0x70(%rbx), %rax
movq (%rax,%r13,8), %rcx
mulsd 0x20(%rsp), %xmm0
addsd (%rcx,%rbp,8), %xmm0
movsd %xmm0, (%rcx,%rbp,8)
incq %r12
cmpq %r12, 0x108(%rsp)
jne 0xbe2c
movq 0x108(%rsp), %r12
movsd 0x6ac0(%rip), %xmm1     # 0x12950
cmpb $0x0, 0x60(%rsp)
movq 0x68(%rsp), %r15
js 0xbec6
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
movl %r14d, %edx
movl 0x80(%rsp), %ecx
callq *0x38(%rax)
movq %r13, %rdx
movapd %xmm0, %xmm1
movq 0x70(%rbx), %rax
movq (%rax,%r13,8), %rcx
movsd (%rcx,%rbp,8), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, (%rcx,%rbp,8)
cmpb $0x1, 0xf(%rsp)
jne 0xbee7
movq 0xa8(%rbx), %rcx
addsd (%rcx,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%rdx,8)
incq %rbp
cmpq %r12, %rbp
movq %r15, %r13
jne 0xbe21
jmp 0xbf93
testb %r12b, %r12b
jle 0xc01c
movq %rdi, 0x58(%rsp)
movq %rsi, 0x40(%rsp)
movq %r8, 0x18(%rsp)
movslq %r8d, %r14
xorl %r15d, %r15d
movq (%rbx), %rax
movsbl %r15b, %edx
movq %rbx, %rdi
movq %r13, %rsi
callq *0x28(%rax)
movapd %xmm0, %xmm1
movsd 0x6a1b(%rip), %xmm0     # 0x12950
cmpb $0x0, 0x60(%rsp)
js 0xbf5f
movq (%rbx), %rax
movsbl %r15b, %edx
movq %rbx, %rdi
movq %r13, %rsi
movl 0x80(%rsp), %ecx
movsd %xmm1, 0x20(%rsp)
callq *0x38(%rax)
movsd 0x20(%rsp), %xmm1
mulsd %xmm0, %xmm1
movq 0x70(%rbx), %rax
movq (%rax,%r14,8), %rax
movsd %xmm1, (%rax,%r15,8)
cmpb $0x1, 0xf(%rsp)
jne 0xbf8b
movq 0xa8(%rbx), %rax
addsd (%rax,%r14,8), %xmm1
movsd %xmm1, (%rax,%r14,8)
incq %r15
cmpq %r15, %r12
jne 0xbf19
cmpb $0x0, 0xc0(%rbx)
movq 0x78(%rsp), %r14
movl 0x120(%rsp), %r10d
movq 0x138(%rsp), %rdx
movq 0x40(%rsp), %rsi
movq 0x58(%rsp), %rdi
movq 0x18(%rsp), %r8
movq 0x90(%rsp), %r9
jne 0xc003
cmpl $-0x1, %r9d
jne 0xbfd9
jmp 0xbff2
cmpb $0x0, 0xc0(%rbx)
jne 0xc003
movq 0xb8(%rbx), %rax
movl %r8d, (%rax,%r9,4)
movq 0xb0(%rbx), %rax
movslq %r8d, %rcx
movl %r9d, (%rax,%rcx,4)
movq (%rdx), %rax
movl %r8d, (%rax,%rdi,4)
movq 0x88(%rbx), %rax
incl (%rax,%rdi,4)
incq %rsi
movsbq 0xe(%rsp), %rax
cmpq %rax, %rsi
jge 0xc02a
cmpb %al, %r10b
je 0xbd93
jmp 0xc02a
cmpb $0x0, 0xc0(%rbx)
je 0xbff2
jmp 0xc003
movl %r10d, %eax
movq (%rbx), %r10
movq 0xc8(%rbx), %rsi
movq 0x10(%rsp), %rdx
movq 0xe8(%rsp), %rbp
movq (%rbp,%r14,8), %r8
movsbl %al, %ecx
movq %rbx, %rdi
movq %r13, %r9
callq *0x58(%r10)
movq (%rbp,%r14,8), %rax
movq 0xd8(%rsp), %r15
movsd (%rax,%r15,8), %xmm0
callq 0x6132
movsd %xmm0, 0x20(%rsp)
callq 0x619d
movsd %xmm0, 0x60(%rsp)
movsd 0x68cc(%rip), %xmm0     # 0x12950
subsd 0x20(%rsp), %xmm0
movapd %xmm0, 0x90(%rsp)
callq 0x619d
movq 0xf0(%rsp), %rcx
movl %ecx, %eax
xorb $0x1, %al
movzbl %cl, %ecx
xorps %xmm1, %xmm1
cvtsi2sd %ecx, %xmm1
movzbl %al, %eax
xorps %xmm2, %xmm2
cvtsi2sd %eax, %xmm2
mulsd %xmm2, %xmm0
movsd 0x60(%rsp), %xmm3
mulsd %xmm1, %xmm3
addsd %xmm0, %xmm3
movsd 0x38(%rsp), %xmm0
subsd %xmm3, %xmm0
movsd %xmm0, 0x38(%rsp)
cmpq $0x0, 0xc8(%rsp)
je 0xc1a7
movl %ecx, 0x40(%rsp)
movsd %xmm2, 0x80(%rsp)
movsd %xmm1, 0x60(%rsp)
movsd 0x20(%rsp), %xmm0
callq 0x619d
movsd %xmm0, 0x58(%rsp)
movaps 0x90(%rsp), %xmm0
callq 0x619d
movsd %xmm0, 0x18(%rsp)
movq (%rbp,%r14,8), %rdi
movsd (%rdi,%r15,8), %xmm0
movaps %xmm0, 0x20(%rsp)
movq %rbp, %r15
movq %r14, %rbp
movq 0xc0(%rsp), %r14
movl %r14d, %esi
callq 0x6312
movaps %xmm0, 0x90(%rsp)
movq (%r15,%rbp,8), %rdi
movq 0xd8(%rsp), %rax
movsd (%rdi,%rax,8), %xmm0
movapd %xmm0, 0x120(%rsp)
movl %r14d, %esi
callq 0x6312
movapd 0x120(%rsp), %xmm4
ucomisd %xmm0, %xmm4
jne 0xc1b4
jp 0xc1b4
movq 0x78(%rsp), %r14
movq (%r15,%r14,8), %rax
movq 0xd8(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
xorl %eax, %eax
ucomisd 0x110(%rsp), %xmm0
seta %al
jmp 0xc1bb
movq 0xf8(%rsp), %rbp
jmp 0xc2fc
xorl %eax, %eax
movq 0x78(%rsp), %r14
movsd 0x678d(%rip), %xmm0     # 0x12950
cmpl 0x40(%rsp), %eax
movq 0xf8(%rsp), %rbp
movsd 0x60(%rsp), %xmm2
je 0xc1db
xorpd %xmm0, %xmm0
movsd 0x18(%rsp), %xmm1
mulsd 0x80(%rsp), %xmm1
movsd 0x58(%rsp), %xmm3
mulsd %xmm2, %xmm3
addsd %xmm1, %xmm3
movsd 0xb0(%rsp), %xmm1
subsd %xmm3, %xmm1
movsd %xmm1, 0xb0(%rsp)
movapd 0x20(%rsp), %xmm3
subsd %xmm3, %xmm2
mulsd %xmm2, %xmm2
movsd 0x48(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x48(%rsp)
movsd 0xa8(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0xa8(%rsp)
movapd 0x90(%rsp), %xmm2
cmpneqpd %xmm3, %xmm2
movapd 0x110(%rsp), %xmm1
cmpnltpd %xmm4, %xmm1
orpd %xmm2, %xmm1
movd %xmm1, %eax
xorb 0xf0(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
movsd 0x50(%rsp), %xmm2
addsd %xmm1, %xmm2
movsd %xmm2, 0x50(%rsp)
movsd 0xb8(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0xb8(%rsp)
movq 0x68(%rbx), %rdx
cmpl $0x2, 0x70(%rdx)
jne 0xc2fc
movsbq 0xe(%rsp), %rax
testq %rax, %rax
jle 0xc2fc
movq 0x10(%rsp), %rcx
movq 0x8b0(%rdx), %rdx
movslq (%rdx,%r14,4), %rsi
movq 0xc8(%rbx), %rdx
movq 0x100(%rsp), %rdi
movq (%rdx,%rdi,8), %rdx
movq 0x70(%rsp), %rdi
leaq (%rdi,%rsi,8), %rsi
xorl %edi, %edi
movslq (%rcx,%rdi,4), %r8
movq (%rdx,%r8,8), %r8
movsd (%r8), %xmm0
movsd %xmm0, (%rsi,%rdi,8)
incq %rdi
cmpq %rdi, %rax
jne 0xc2e2
incq %r14
cmpq 0xd0(%rsp), %r14
jne 0xbadf
cmpl $0x0, 0xd0(%rsp)
jle 0xc4c5
xorl %r13d, %r13d
movq 0x68(%rbx), %rdi
movq 0x890(%rdi), %rax
movslq (%rax,%r13,4), %rax
movq %rax, 0x20(%rsp)
movl %r13d, %esi
leaq 0x10(%rsp), %rdx
leaq 0xe(%rsp), %rcx
callq 0x7797
movsbl 0xe(%rsp), %r14d
testl %r14d, %r14d
jle 0xc46a
movq 0x58(%rbx), %rax
movq 0x10(%rsp), %rcx
movl %r14d, %esi
xorl %edi, %edi
xorl %edx, %edx
movslq (%rcx,%rdi,4), %r8
xorl %r9d, %r9d
cmpb $0x0, (%rax,%r8)
setg %r9b
addl %r9d, %edx
incq %rdi
cmpq %rdi, %rsi
jne 0xc363
testb %r14b, %r14b
jle 0xc46a
cmpl %r14d, %edx
jne 0xc46a
movl %r14d, %eax
xorl %r15d, %r15d
movq 0x10(%rsp), %rcx
movslq (%rcx,%r15,4), %rbp
movq 0x68(%rsp), %rcx
movl %ebp, (%rcx)
movq 0x68(%rbx), %rcx
movq 0x8b0(%rcx), %rcx
movslq (%rcx,%r13,4), %rdx
movslq %r15d, %rcx
addq %rdx, %rcx
cmpb $0x1, 0xf(%rsp)
jne 0xc3e7
movq 0x78(%rbx), %rdx
movq 0xa8(%rbx), %rsi
movsd (%rsi,%rcx,8), %xmm0
movq 0x20(%rsp), %rcx
movq (%rdx,%rcx,8), %rcx
mulsd (%rcx,%rbp,8), %xmm0
movsd %xmm0, (%rcx,%rbp,8)
jmp 0xc455
movq 0xb8(%rbx), %rdx
cmpl $-0x1, (%rdx,%rcx,4)
jne 0xc455
movq 0x78(%rbx), %rdx
testb %r12b, %r12b
jle 0xc429
movq 0x70(%rbx), %rax
movq (%rax,%rcx,8), %rax
movq 0x20(%rsp), %rcx
movq (%rdx,%rcx,8), %rcx
movsd (%rcx,%rbp,8), %xmm0
xorl %edx, %edx
addsd (%rax,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%rbp,8)
incq %rdx
cmpq %rdx, %r12
jne 0xc415
jmp 0xc437
movq 0x20(%rsp), %rax
movq (%rdx,%rax,8), %rax
movsd (%rax,%rbp,8), %xmm0
callq 0x619d
movq 0x80(%rbx), %rax
movsd (%rax,%rbp,8), %xmm1
subsd %xmm0, %xmm1
movsd %xmm1, (%rax,%rbp,8)
movb 0xe(%rsp), %al
incq %r15
movsbq %al, %rcx
cmpq %rcx, %r15
jge 0xc46a
cmpb %al, %r14b
je 0xc396
incq %r13
cmpq 0xd0(%rsp), %r13
jne 0xc31e
movq 0xc8(%rsp), %r15
movq 0x68(%rsp), %r13
movq 0xe0(%rsp), %rdi
jmp 0xc4d5
xorpd %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd %xmm0, 0xb0(%rsp)
movsd %xmm0, 0xb8(%rsp)
movsd %xmm0, 0x50(%rsp)
movsd %xmm0, 0xa8(%rsp)
movsd %xmm0, 0x48(%rsp)
jmp 0xc4d5
movq 0xe0(%rsp), %rdi
movq 0xc8(%rsp), %r15
movb $0x1, 0xc0(%rbx)
testq %rdi, %rdi
je 0xc4ed
movl 0x8c(%rsp), %esi
callq 0x10aee
testq %r15, %r15
je 0xc558
movsd 0x38(%rsp), %xmm0
movsd %xmm0, (%r15)
movsd 0xb0(%rsp), %xmm0
movsd %xmm0, 0x8(%r15)
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x10(%r15)
movsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x18(%r15)
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x20(%r15)
movsd 0xb8(%rsp), %xmm0
movsd %xmm0, 0x28(%r15)
movq 0x68(%rbx), %rax
cmpl $0x2, 0x70(%rax)
jne 0xc558
movq 0x70(%rsp), %rcx
movq %rcx, 0x8d0(%rax)
movl $0x14, %esi
movq %r13, %rdi
callq 0x21d0
movsd 0x38(%rsp), %xmm0
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop