// File: /workspace/github_cpp_makefile_star2_O1/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 $0x118, %rsp            # imm = 0x118
movq %rsi, %r12
movq %rdi, %rbx
movq (%rdi), %rax
movq 0x68(%rdi), %rcx
movzbl 0x900(%rcx), %ebp
movsbl 0x901(%rcx), %edx
movq %rdx, 0x60(%rsp)
movl 0x8fc(%rcx), %r15d
movl 0x8f8(%rcx), %edx
movq %rdx, 0xa8(%rsp)
movl 0x908(%rcx), %r14d
movl 0x904(%rcx), %edx
movl %edx, 0x7c(%rsp)
movsbq 0x6c(%rcx), %rdx
movq %rdx, 0xb8(%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), %rdi
movq %r12, 0xc8(%rsp)
testq %r12, %r12
je 0xb879
cmpl $0x2, 0x70(%rax)
jne 0xb879
movslq 0x8fc(%rax), %r12
testq %rdi, %rdi
je 0xb880
testl %r12d, %r12d
movq %rdi, 0x58(%rsp)
jle 0xb8a8
shlq $0x3, %r12
jmp 0xb89e
movq %rdi, 0x58(%rsp)
jmp 0xb8a8
movl $0x8, %esi
movq %r12, %rdi
callq 0x2110
testl %r12d, %r12d
movq %rax, 0x58(%rsp)
jle 0xb8a8
shlq $0x3, %r12
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x2100
movl $0x14, %edi
callq 0x21c0
movq %rax, %r12
cmpb $0x0, 0xc0(%rbx)
je 0xb8c2
xorl %eax, %eax
jmp 0xb91f
testl %r15d, %r15d
jle 0xb8f3
movq 0xb8(%rbx), %rdi
shlq $0x2, %r15
movl $0xff, %esi
movq %r15, %rdx
callq 0x2100
movq 0xb0(%rbx), %rdi
movl $0xff, %esi
movq %r15, %rdx
callq 0x2100
testl %r14d, %r14d
jle 0xb90e
movq 0x88(%rbx), %rdi
leaq (,%r14,4), %rdx
xorl %esi, %esi
callq 0x2100
movl 0x7c(%rsp), %edi
movl %r14d, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x105e0
movq %rax, 0xd0(%rsp)
cmpl $0x0, 0xa8(%rsp)
jle 0xc1b6
movq 0x60(%rsp), %rdx
leal 0x1(%rdx), %eax
xorl %r15d, %r15d
cmpl $0x3, %eax
movl $0x0, %ecx
cmovbl %edx, %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, 0x100(%rsp)
leaq 0xb0(%rbx), %rcx
movq %rcx, 0x108(%rsp)
cmpl $0x3, %eax
movl $0x0, %eax
cmovbl %edx, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0xe8(%rsp)
movzbl %dl, %r13d
xorpd %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd %xmm0, 0x90(%rsp)
movsd %xmm0, 0xa0(%rsp)
movsd %xmm0, 0x50(%rsp)
movsd %xmm0, 0x98(%rsp)
movsd %xmm0, 0x48(%rsp)
movq %r13, 0xb0(%rsp)
movq %r12, 0xf8(%rsp)
movq 0x68(%rbx), %rdi
movq 0x880(%rdi), %rax
movb (%rax,%r15), %r14b
cmpb %r14b, 0x6c(%rdi)
sete %al
movq %rax, 0xf0(%rsp)
movq 0x890(%rdi), %rax
movslq (%rax,%r15,4), %rcx
movq %rcx, 0xd8(%rsp)
movl %ecx, 0x4(%r12)
movb %r14b, 0x10(%r12)
movl %r15d, 0xc(%r12)
movl %r15d, %esi
leaq 0x20(%rsp), %rdx
leaq 0xe(%rsp), %rcx
callq 0x76ed
movb %r14b, 0x18(%rsp)
movsbl %r14b, %eax
movl %eax, 0x70(%rsp)
cmpq $0x0, 0xc8(%rsp)
movq %r15, 0x28(%rsp)
je 0xbbce
movq 0x20(%rsp), %rax
cmpl $0x0, (%rax)
jns 0xbbce
xorps %xmm1, %xmm1
cvtsi2sdl 0x70(%rsp), %xmm1
movsd 0x18(%rbx), %xmm0
movapd %xmm0, 0x80(%rsp)
movsd %xmm1, 0x30(%rsp)
ucomisd %xmm0, %xmm1
xorpd %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0xb8(%rsp), %rax
jne 0xba8d
jp 0xba8d
movsd 0x5ec9(%rip), %xmm0     # 0x11950
movsd %xmm0, 0x10(%rsp)
movq 0x10(%rbx), %rdi
movsd (%rdi,%rax,8), %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x60(%rsp), %rsi
movq %rax, %r15
callq 0x6210
movsd 0x40(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jne 0xbad1
jp 0xbad1
movq 0x10(%rbx), %rax
movsd (%rax,%r15,8), %xmm0
xorl %eax, %eax
ucomisd 0x100(%rsp), %xmm0
seta %al
jmp 0xbad3
xorl %eax, %eax
movq 0x28(%rsp), %r15
movsd 0x30(%rsp), %xmm0
cmpeqsd 0x80(%rsp), %xmm0
movq %xmm0, %rcx
andl $0x1, %ecx
movsd 0x5e58(%rip), %xmm0     # 0x11950
movq %rcx, 0xf0(%rsp)
cmpl %ecx, %eax
je 0xbb07
xorps %xmm0, %xmm0
movsd %xmm0, 0x68(%rsp)
movsd 0x10(%rsp), %xmm0
subsd %xmm1, %xmm0
mulsd %xmm0, %xmm0
movsd 0x48(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x48(%rsp)
movsd 0x20(%rbx), %xmm0
callq 0x608b
movsd %xmm0, 0x40(%rsp)
movsd 0x5e0d(%rip), %xmm0     # 0x11950
subsd 0x20(%rbx), %xmm0
callq 0x608b
movsd 0x50(%rsp), %xmm1
addsd 0x68(%rsp), %xmm1
movsd %xmm1, 0x50(%rsp)
movapd 0x80(%rsp), %xmm1
cmpneqsd 0x30(%rsp), %xmm1
movsd 0x5dd9(%rip), %xmm2     # 0x11950
andpd %xmm2, %xmm1
mulsd %xmm0, %xmm1
movsd 0x40(%rsp), %xmm0
mulsd 0x10(%rsp), %xmm0
addsd %xmm1, %xmm0
movapd %xmm0, %xmm1
movsd 0x38(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
cmpb $0x0, 0x60(%rsp)
jle 0xbbce
movq 0x10(%rbx), %rax
movq 0xc0(%rsp), %rcx
movq (%rcx,%r15,8), %rcx
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%rdx,8)
incq %rdx
cmpq %rdx, %r13
jne 0xbbbc
movq 0x20(%rsp), %rdx
cmpl $0x0, (%rdx)
js 0xc1a3
movq (%rbx), %rax
movq 0xc8(%rbx), %rsi
movsbl 0xe(%rsp), %ecx
movq 0xc0(%rsp), %rdi
movq (%rdi,%r15,8), %r8
movq %rbx, %rdi
movq %r12, %r9
callq *0x50(%rax)
movsbq 0xe(%rsp), %rax
testq %rax, %rax
jle 0xbc35
movq 0x58(%rbx), %rcx
xorl %edx, %edx
movq 0x20(%rsp), %rsi
xorl %r9d, %r9d
movslq (%rsi,%rdx,4), %rdi
xorl %r8d, %r8d
cmpb $0x0, (%rcx,%rdi)
setg %r8b
addl %r8d, %r9d
incq %rdx
cmpq %rdx, %rax
jne 0xbc19
jmp 0xbc38
xorl %r9d, %r9d
movsbl 0xe(%rsp), %eax
testl %eax, %eax
jle 0xbed2
cmpl %eax, %r9d
jne 0xbed2
movq 0xd0(%rsp), %rax
movq 0xd8(%rsp), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0x110(%rsp)
xorl %ecx, %ecx
movl %r9d, 0xe0(%rsp)
movq 0x20(%rsp), %rax
movslq (%rax,%rcx,4), %rdx
movl %edx, (%r12)
movq 0x68(%rbx), %rax
movq 0x8b0(%rax), %rax
movslq (%rax,%r15,4), %rax
movq %rcx, 0x68(%rsp)
movslq %ecx, %rsi
addq %rax, %rsi
cmpb $0x1, 0xf(%rsp)
jne 0xbcb1
movq 0xa8(%rbx), %rax
movq $0x0, (%rax,%rsi,8)
cmpb $0x0, 0xc0(%rbx)
movq 0x110(%rsp), %rax
cmovneq 0x108(%rsp), %rax
movq %rdx, 0x40(%rsp)
movl %edx, %ecx
movq %rsi, 0x30(%rsp)
cmovnel %esi, %ecx
movq (%rax), %rax
movslq %ecx, %rcx
movslq (%rax,%rcx,4), %rax
movq %rax, 0x80(%rsp)
cmpq $-0x1, %rax
je 0xbdcd
testb %bpl, %bpl
jle 0xbe51
movslq 0x30(%rsp), %r13
xorl %r15d, %r15d
movq %rbp, %r12
xorl %ebp, %ebp
movq 0x80(%rsp), %r14
movq (%rbx), %rax
movq 0x70(%rbx), %rcx
movq (%rcx,%r14,8), %rcx
movsd (%rcx,%rbp,8), %xmm0
movsd %xmm0, 0x10(%rsp)
movsbl %r15b, %ecx
movsbl %bpl, %edx
movq %rbx, %rdi
movq 0xf8(%rsp), %rsi
callq *0x30(%rax)
movq 0x70(%rbx), %rax
movq (%rax,%r13,8), %rax
mulsd 0x10(%rsp), %xmm0
addsd (%rax,%r15,8), %xmm0
movsd %xmm0, (%rax,%r15,8)
incq %rbp
cmpq %rbp, %r12
jne 0xbd12
movq %r12, %rbp
movsd 0x5be5(%rip), %xmm0     # 0x11950
cmpb $0x0, 0x18(%rsp)
movq 0xf8(%rsp), %r12
js 0xbd8e
movq (%rbx), %rax
movsbl %r15b, %edx
movq %rbx, %rdi
movq %r12, %rsi
movl 0x70(%rsp), %ecx
callq *0x38(%rax)
movq 0x70(%rbx), %rax
movq (%rax,%r13,8), %rax
mulsd (%rax,%r15,8), %xmm0
movsd %xmm0, (%rax,%r15,8)
cmpb $0x1, 0xf(%rsp)
jne 0xbdbc
movq 0xa8(%rbx), %rax
addsd (%rax,%r13,8), %xmm0
movsd %xmm0, (%rax,%r13,8)
incq %r15
cmpq %rbp, %r15
jne 0xbd05
jmp 0xbe51
testb %bpl, %bpl
jle 0xbe51
movslq 0x30(%rsp), %r14
xorl %r15d, %r15d
movq (%rbx), %rax
movsbl %r15b, %edx
movq %rbx, %rdi
movq %r12, %rsi
callq *0x28(%rax)
movapd %xmm0, %xmm1
movsd 0x5b5a(%rip), %xmm0     # 0x11950
cmpb $0x0, 0x18(%rsp)
js 0xbe1d
movq (%rbx), %rax
movsbl %r15b, %edx
movq %rbx, %rdi
movq %r12, %rsi
movl 0x70(%rsp), %ecx
movsd %xmm1, 0x10(%rsp)
callq *0x38(%rax)
movsd 0x10(%rsp), %xmm1
mulsd %xmm0, %xmm1
movq 0x70(%rbx), %rax
movq (%rax,%r14,8), %rax
movsd %xmm1, (%rax,%r15,8)
cmpb $0x1, 0xf(%rsp)
jne 0xbe49
movq 0xa8(%rbx), %rax
addsd (%rax,%r14,8), %xmm1
movsd %xmm1, (%rax,%r14,8)
incq %r15
cmpq %r15, %rbp
jne 0xbdda
cmpb $0x0, 0xc0(%rbx)
movq 0x28(%rsp), %r15
movl 0xe0(%rsp), %r9d
jne 0xbeb6
movq 0x80(%rsp), %rsi
cmpl $-0x1, %esi
movq 0x30(%rsp), %rdx
je 0xbe90
movq 0xb8(%rbx), %rax
movl %edx, (%rax,%rsi,4)
movq 0xb0(%rbx), %rax
movslq %edx, %rcx
movl %esi, (%rax,%rcx,4)
movq 0xd0(%rsp), %rax
movq 0xd8(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x40(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movq 0x88(%rbx), %rax
incl (%rax,%rcx,4)
movq 0x68(%rsp), %rcx
incq %rcx
movsbq 0xe(%rsp), %rax
cmpq %rax, %rcx
jge 0xbed2
cmpl %eax, %r9d
je 0xbc74
movq (%rbx), %r10
movq 0xc8(%rbx), %rsi
movq 0x20(%rsp), %rdx
movq 0xc0(%rsp), %r13
movq (%r13,%r15,8), %r8
movsbl %al, %ecx
movq %rbx, %rdi
movq %r12, %r9
callq *0x58(%r10)
movq (%r13,%r15,8), %rax
movq 0xb8(%rsp), %r15
movsd (%rax,%r15,8), %xmm0
callq 0x6020
movsd %xmm0, 0x10(%rsp)
callq 0x608b
movsd %xmm0, 0x18(%rsp)
movsd 0x5a24(%rip), %xmm0     # 0x11950
subsd 0x10(%rsp), %xmm0
movapd %xmm0, 0x80(%rsp)
callq 0x608b
movq 0xf0(%rsp), %rax
movzbl %al, %r14d
xorb $0x1, %al
xorps %xmm1, %xmm1
cvtsi2sd %r14d, %xmm1
movzbl %al, %eax
xorps %xmm2, %xmm2
cvtsi2sd %eax, %xmm2
mulsd %xmm2, %xmm0
movsd 0x18(%rsp), %xmm3
mulsd %xmm1, %xmm3
addsd %xmm0, %xmm3
movsd 0x38(%rsp), %xmm0
subsd %xmm3, %xmm0
movsd %xmm0, 0x38(%rsp)
cmpq $0x0, 0xc8(%rsp)
je 0xc00b
movsd %xmm2, 0x70(%rsp)
movsd %xmm1, 0x18(%rsp)
movsd 0x10(%rsp), %xmm0
callq 0x608b
movsd %xmm0, 0x30(%rsp)
movaps 0x80(%rsp), %xmm0
callq 0x608b
movsd %xmm0, 0x68(%rsp)
movq 0x28(%rsp), %rax
movq (%r13,%rax,8), %rdi
movsd (%rdi,%r15,8), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x60(%rsp), %rsi
callq 0x6210
movsd 0x10(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jne 0xc01d
jp 0xc01d
movq 0x28(%rsp), %rax
movq (%r13,%rax,8), %rax
movsd (%rax,%r15,8), %xmm0
xorl %eax, %eax
ucomisd 0xe8(%rsp), %xmm0
seta %al
jmp 0xc01f
movq 0x28(%rsp), %r15
movq 0xb0(%rsp), %r13
jmp 0xc1a3
xorl %eax, %eax
movsd 0x5929(%rip), %xmm0     # 0x11950
movl %r14d, 0x80(%rsp)
cmpl %r14d, %eax
je 0xc037
xorps %xmm0, %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x28(%rsp), %r14
movq (%r13,%r14,8), %rdi
movq 0xb8(%rsp), %r15
movsd (%rdi,%r15,8), %xmm0
movsd %xmm0, 0xe0(%rsp)
movq 0x60(%rsp), %rsi
callq 0x6210
movsd 0xe0(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jne 0xc094
jp 0xc094
movq (%r13,%r14,8), %rax
movsd (%rax,%r15,8), %xmm0
xorl %eax, %eax
ucomisd 0xe8(%rsp), %xmm0
seta %al
jmp 0xc096
xorl %eax, %eax
movq 0xb0(%rsp), %r13
movsd 0x18(%rsp), %xmm2
movsd 0x58a4(%rip), %xmm0     # 0x11950
cmpl 0x80(%rsp), %eax
je 0xc0b9
xorpd %xmm0, %xmm0
movsd 0x68(%rsp), %xmm1
mulsd 0x70(%rsp), %xmm1
movsd 0x30(%rsp), %xmm3
mulsd %xmm2, %xmm3
addsd %xmm1, %xmm3
movsd 0x90(%rsp), %xmm1
subsd %xmm3, %xmm1
movsd %xmm1, 0x90(%rsp)
subsd 0x10(%rsp), %xmm2
mulsd %xmm2, %xmm2
movsd 0x48(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x48(%rsp)
movsd 0x98(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x98(%rsp)
movsd 0x50(%rsp), %xmm1
addsd 0x40(%rsp), %xmm1
movsd %xmm1, 0x50(%rsp)
movsd 0xa0(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0xa0(%rsp)
movq 0x68(%rbx), %rdx
cmpl $0x2, 0x70(%rdx)
movq 0x28(%rsp), %r15
jne 0xc1a3
movsbq 0xe(%rsp), %rax
testq %rax, %rax
jle 0xc1a3
movq 0x20(%rsp), %rcx
movq 0x8b0(%rdx), %rdx
movslq (%rdx,%r15,4), %rsi
movq 0xc8(%rbx), %rdx
movq 0xd8(%rsp), %rdi
movq (%rdx,%rdi,8), %rdx
movq 0x58(%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 0xc189
incq %r15
cmpq 0xa8(%rsp), %r15
jne 0xb9c7
jmp 0xc1e7
xorpd %xmm0, %xmm0
movsd %xmm0, 0x48(%rsp)
movsd %xmm0, 0x98(%rsp)
movsd %xmm0, 0x50(%rsp)
movsd %xmm0, 0xa0(%rsp)
movsd %xmm0, 0x90(%rsp)
movsd %xmm0, 0x38(%rsp)
cmpl $0x0, 0xa8(%rsp)
jle 0xc35f
xorl %esi, %esi
movq 0x68(%rbx), %rdi
movq 0x890(%rdi), %rax
movslq (%rax,%rsi,4), %rax
movq %rax, 0x18(%rsp)
movq %rsi, 0x10(%rsp)
leaq 0x20(%rsp), %rdx
leaq 0xe(%rsp), %rcx
callq 0x76ed
movsbq 0xe(%rsp), %rax
movl $0x0, %r15d
testq %rax, %rax
jle 0xc258
movq 0x58(%rbx), %rcx
xorl %edx, %edx
movq 0x20(%rsp), %rsi
xorl %r15d, %r15d
movslq (%rsi,%rdx,4), %rdi
xorl %r8d, %r8d
cmpb $0x0, (%rcx,%rdi)
setg %r8b
addl %r8d, %r15d
incq %rdx
cmpq %rdx, %rax
jne 0xc23e
movsbl 0xe(%rsp), %eax
testl %eax, %eax
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdi
jle 0xc34e
cmpl %eax, %r15d
jne 0xc34e
xorl %r13d, %r13d
movq 0x20(%rsp), %rax
movslq (%rax,%r13,4), %r14
movl %r14d, (%r12)
movq 0x68(%rbx), %rax
movq 0x8b0(%rax), %rax
movslq (%rax,%rsi,4), %rcx
movslq %r13d, %rax
addq %rcx, %rax
cmpb $0x1, 0xf(%rsp)
jne 0xc2c6
movq 0x78(%rbx), %rcx
movq 0xa8(%rbx), %rdx
movsd (%rdx,%rax,8), %xmm0
movq (%rcx,%rdi,8), %rax
mulsd (%rax,%r14,8), %xmm0
movsd %xmm0, (%rax,%r14,8)
jmp 0xc337
movq 0xb8(%rbx), %rcx
cmpl $-0x1, (%rcx,%rax,4)
jne 0xc337
testb %bpl, %bpl
jle 0xc303
movq 0x70(%rbx), %rcx
movq 0x78(%rbx), %rdx
movq (%rcx,%rax,8), %rax
movq (%rdx,%rdi,8), %rcx
movsd (%rcx,%r14,8), %xmm0
xorl %edx, %edx
addsd (%rax,%rdx,8), %xmm0
movsd %xmm0, (%rcx,%r14,8)
incq %rdx
cmpq %rdx, %rbp
jne 0xc2f0
movq 0x78(%rbx), %rax
movq (%rax,%rdi,8), %rax
movsd (%rax,%r14,8), %xmm0
callq 0x608b
movq 0x18(%rsp), %rdi
movq 0x80(%rbx), %rax
movsd (%rax,%r14,8), %xmm1
subsd %xmm0, %xmm1
movsd %xmm1, (%rax,%r14,8)
movq 0x10(%rsp), %rsi
incq %r13
movsbq 0xe(%rsp), %rax
cmpq %rax, %r13
jge 0xc34e
cmpl %eax, %r15d
je 0xc27b
incq %rsi
cmpq 0xa8(%rsp), %rsi
jne 0xc1f7
movb $0x1, 0xc0(%rbx)
movq 0xd0(%rsp), %rdi
testq %rdi, %rdi
je 0xc37c
movl 0x7c(%rsp), %esi
callq 0x10652
movq 0xc8(%rsp), %rax
testq %rax, %rax
je 0xc3e9
movsd 0x38(%rsp), %xmm0
movsd %xmm0, (%rax)
movsd 0x90(%rsp), %xmm0
movsd %xmm0, 0x8(%rax)
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x10(%rax)
movsd 0x98(%rsp), %xmm0
movsd %xmm0, 0x18(%rax)
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x20(%rax)
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x28(%rax)
movq 0x68(%rbx), %rax
cmpl $0x2, 0x70(%rax)
jne 0xc3e9
movq 0x58(%rsp), %rcx
movq %rcx, 0x8d0(%rax)
movl $0x14, %esi
movq %r12, %rdi
callq 0x21d0
movsd 0x38(%rsp), %xmm0
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq