// File: 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
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
movq 0x68(%rdi), %rax
movb 0x900(%rax), %al
movb %al, -0x11(%rbp)
movq 0x68(%rdi), %rax
movb 0x901(%rax), %al
movb %al, -0x12(%rbp)
movb $-0x1, -0x13(%rbp)
movq 0x68(%rdi), %rax
movl 0x8fc(%rax), %eax
movl %eax, -0x18(%rbp)
movq 0x68(%rdi), %rax
movl 0x8f8(%rax), %eax
movl %eax, -0x1c(%rbp)
movq 0x68(%rdi), %rax
movl 0x908(%rax), %eax
movl %eax, -0x28(%rbp)
movq 0x68(%rdi), %rax
movl 0x904(%rax), %eax
movl %eax, -0x2c(%rbp)
movq 0x68(%rdi), %rax
movb 0x6c(%rax), %al
movb %al, -0x2d(%rbp)
movq 0x68(%rdi), %rax
movsbl 0x41(%rax), %eax
cmpl $0x1, %eax
sete %al
andb $0x1, %al
movb %al, -0x2e(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x40(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x48(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x50(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x58(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x60(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x68(%rbp)
movq (%rdi), %rax
callq *0x78(%rax)
movq -0xe8(%rbp), %rcx
movq $0x0, -0x70(%rbp)
movq 0x68(%rcx), %rax
movq 0x8c8(%rax), %rax
movq %rax, -0x78(%rbp)
movq 0x68(%rcx), %rax
movq 0x8d0(%rax), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x10(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %eax
movq 0x68(%rcx), %rcx
cmpl $0x2, 0x70(%rcx)
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1268f
cmpq $0x0, -0x80(%rbp)
jne 0x12673
movq -0xe8(%rbp), %rax
movq 0x68(%rax), %rax
movl 0x8fc(%rax), %edi
xorps %xmm0, %xmm0
callq 0x190f0
movq %rax, -0x80(%rbp)
jmp 0x1268d
movq -0xe8(%rbp), %rax
movq -0x80(%rbp), %rdi
movq 0x68(%rax), %rax
movl 0x8fc(%rax), %esi
callq 0x19350
jmp 0x1268f
movl $0x14, %edi
callq 0x3270
movq %rax, %rcx
movq -0xe8(%rbp), %rax
movq %rcx, -0x88(%rbp)
testb $0x1, 0xc0(%rax)
jne 0x12715
movq -0xe8(%rbp), %rax
movq 0xb8(%rax), %rdi
movl -0x18(%rbp), %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x19420
movq -0xe8(%rbp), %rax
movq 0xb0(%rax), %rdi
movl -0x18(%rbp), %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x19420
movq -0xe8(%rbp), %rax
movq 0x88(%rax), %rdi
movl -0x28(%rbp), %esi
xorl %edx, %edx
callq 0x19420
movl -0x2c(%rbp), %edi
movl -0x28(%rbp), %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x19460
movq %rax, -0x70(%rbp)
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x132cb
movq -0xe8(%rbp), %rax
movq 0x68(%rax), %rcx
movq 0x880(%rcx), %rcx
movslq -0x8c(%rbp), %rdx
movb (%rcx,%rdx), %cl
movb %cl, -0x13(%rbp)
movq 0x68(%rax), %rcx
movsbl 0x6c(%rcx), %ecx
movsbl -0x13(%rbp), %edx
cmpl %edx, %ecx
sete %cl
andb $0x1, %cl
movb %cl, -0x14(%rbp)
movq 0x68(%rax), %rcx
movq 0x890(%rcx), %rcx
movslq -0x8c(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
movl %ecx, -0x20(%rbp)
movl -0x20(%rbp), %edx
movq -0x88(%rbp), %rcx
movl %edx, 0x4(%rcx)
movb -0x13(%rbp), %dl
movq -0x88(%rbp), %rcx
movb %dl, 0x10(%rcx)
movl -0x8c(%rbp), %edx
movq -0x88(%rbp), %rcx
movl %edx, 0xc(%rcx)
movq 0x68(%rax), %rdi
movl -0x8c(%rbp), %esi
leaq -0x98(%rbp), %rdx
leaq -0x99(%rbp), %rcx
callq 0x9ce0
movq -0x98(%rbp), %rax
cmpl $0x0, (%rax)
jge 0x129c4
cmpq $0x0, -0x10(%rbp)
je 0x129c4
movq -0xe8(%rbp), %rax
movsd 0x18(%rax), %xmm0
movsbl -0x13(%rbp), %ecx
cvtsi2sd %ecx, %xmm1
ucomisd %xmm1, %xmm0
sete %cl
setnp %dl
andb %dl, %cl
andb $0x1, %cl
movb %cl, -0x14(%rbp)
movsbl -0x14(%rbp), %ecx
cvtsi2sd %ecx, %xmm0
movq 0x10(%rax), %rax
movsbq -0x2d(%rbp), %rcx
subsd (%rax,%rcx,8), %xmm0
movl $0x2, %edi
callq 0xb8b0
movq -0xe8(%rbp), %rax
addsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
movsbl -0x14(%rbp), %ecx
movl %ecx, -0xfc(%rbp)
movq 0x10(%rax), %rcx
movsbq -0x2d(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movsd %xmm0, -0xf8(%rbp)
movq 0x10(%rax), %rdi
movsbl -0x12(%rbp), %esi
callq 0x7930
movaps %xmm0, %xmm1
movsd -0xf8(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0xe9(%rbp)
jne 0x128af
jp 0x128af
movq -0xe8(%rbp), %rax
movq 0x10(%rax), %rax
movsbq -0x2d(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsbl -0x12(%rbp), %ecx
movl $0x1, %eax
cltd
idivl %ecx
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
seta %al
movb %al, -0xe9(%rbp)
movq -0xe8(%rbp), %rax
movl -0xfc(%rbp), %ecx
movb -0xe9(%rbp), %dl
andb $0x1, %dl
movzbl %dl, %edx
cmpl %edx, %ecx
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
cvtsi2sd %ecx, %xmm0
addsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
movsbl -0x14(%rbp), %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, -0x118(%rbp)
movsd 0x20(%rax), %xmm0
callq 0x7690
movq -0xe8(%rbp), %rax
movsd %xmm0, -0x110(%rbp)
movsbl -0x14(%rbp), %edx
movl $0x1, %ecx
subl %edx, %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, -0x108(%rbp)
movsd 0x9117(%rip), %xmm0     # 0x1ba40
subsd 0x20(%rax), %xmm0
callq 0x7690
movsd -0x118(%rbp), %xmm1
movsd -0x110(%rbp), %xmm2
movaps %xmm0, %xmm3
movsd -0x108(%rbp), %xmm0
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd -0x38(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movb $0x0, -0x9b(%rbp)
movsbl -0x9b(%rbp), %eax
movsbl -0x12(%rbp), %ecx
cmpl %ecx, %eax
jge 0x129c2
movq -0xe8(%rbp), %rax
movq 0x10(%rax), %rax
movsbq -0x9b(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x9b(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movb -0x9b(%rbp), %al
addb $0x1, %al
movb %al, -0x9b(%rbp)
jmp 0x1296f
jmp 0x129c4
movq -0x98(%rbp), %rax
cmpl $0x0, (%rax)
jge 0x129d5
jmp 0x132b7
movq -0xe8(%rbp), %rdi
movq 0xc8(%rdi), %rsi
movq -0x98(%rbp), %rdx
movb -0x99(%rbp), %cl
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %r8
movq (%rax,%r8,8), %r8
movq -0x88(%rbp), %r9
movq (%rdi), %rax
movsbl %cl, %ecx
callq *0x50(%rax)
movl $0x0, -0xa0(%rbp)
movl $0x0, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
movsbl -0x99(%rbp), %ecx
cmpl %ecx, %eax
jge 0x12a7d
movq -0xe8(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x98(%rbp), %rcx
movslq -0xa4(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
setg %al
andb $0x1, %al
movzbl %al, %eax
addl -0xa0(%rbp), %eax
movl %eax, -0xa0(%rbp)
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0x12a23
movl $0x0, -0xa8(%rbp)
movl -0xa8(%rbp), %ecx
movsbl -0x99(%rbp), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x119(%rbp)
jge 0x12ab8
movl -0xa0(%rbp), %eax
movsbl -0x99(%rbp), %ecx
cmpl %ecx, %eax
sete %al
movb %al, -0x119(%rbp)
movb -0x119(%rbp), %al
testb $0x1, %al
jne 0x12ac7
jmp 0x12edd
movq -0xe8(%rbp), %rcx
movq -0x98(%rbp), %rax
movslq -0xa8(%rbp), %rdx
movl (%rax,%rdx,4), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %edx
movq -0x88(%rbp), %rax
movl %edx, (%rax)
movl -0xa8(%rbp), %eax
movq 0x68(%rcx), %rcx
movq 0x8b0(%rcx), %rcx
movslq -0x8c(%rbp), %rdx
addl (%rcx,%rdx,4), %eax
movl %eax, -0xac(%rbp)
cmpb $0x0, -0x2e(%rbp)
je 0x12b32
movq -0xe8(%rbp), %rax
movq 0xa8(%rax), %rax
movslq -0xac(%rbp), %rcx
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movq -0xe8(%rbp), %rax
testb $0x1, 0xc0(%rax)
je 0x12b62
movq -0xe8(%rbp), %rax
movq 0xb0(%rax), %rax
movslq -0xac(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x120(%rbp)
jmp 0x12b7b
movq -0x70(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x24(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x120(%rbp)
movl -0x120(%rbp), %eax
movl %eax, -0xb0(%rbp)
cmpl $-0x1, -0xb0(%rbp)
jne 0x12cab
movb $0x0, -0x9a(%rbp)
movsbl -0x9a(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0x12ca6
movq -0xe8(%rbp), %rdi
movq -0x88(%rbp), %rsi
movb -0x9a(%rbp), %cl
movq (%rdi), %rax
movsbl %cl, %edx
callq *0x28(%rax)
movsd %xmm0, -0x128(%rbp)
movsbl -0x13(%rbp), %eax
cmpl $0x0, %eax
jge 0x12bee
movsd 0x8e5c(%rip), %xmm0     # 0x1ba40
movsd %xmm0, -0x130(%rbp)
jmp 0x12c19
movq -0xe8(%rbp), %rdi
movq -0x88(%rbp), %rsi
movb -0x9a(%rbp), %dl
movb -0x13(%rbp), %cl
movq (%rdi), %rax
movsbl %dl, %edx
movsbl %cl, %ecx
callq *0x38(%rax)
movsd %xmm0, -0x130(%rbp)
movq -0xe8(%rbp), %rax
movsd -0x128(%rbp), %xmm0
movsd -0x130(%rbp), %xmm1
mulsd %xmm1, %xmm0
movq 0x70(%rax), %rax
movslq -0xac(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x9a(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
cmpb $0x0, -0x2e(%rbp)
je 0x12c91
movq -0xe8(%rbp), %rax
movq 0x70(%rax), %rcx
movslq -0xac(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movsbq -0x9a(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq 0xa8(%rax), %rax
movslq -0xac(%rbp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0x12c93
movb -0x9a(%rbp), %al
addb $0x1, %al
movb %al, -0x9a(%rbp)
jmp 0x12b9b
jmp 0x12e45
movb $0x0, -0xb1(%rbp)
movsbl -0xb1(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0x12e43
movb $0x0, -0xb2(%rbp)
movsbl -0xb2(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0x12d77
movq -0xe8(%rbp), %rdi
movq 0x70(%rdi), %rax
movslq -0xb0(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0xb2(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x138(%rbp)
movq -0x88(%rbp), %rsi
movb -0xb2(%rbp), %dl
movb -0xb1(%rbp), %cl
movq (%rdi), %rax
movsbl %dl, %edx
movsbl %cl, %ecx
callq *0x30(%rax)
movq -0xe8(%rbp), %rax
movaps %xmm0, %xmm2
movsd -0x138(%rbp), %xmm0
movq 0x70(%rax), %rax
movslq -0xac(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0xb1(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movb -0xb2(%rbp), %al
addb $0x1, %al
movb %al, -0xb2(%rbp)
jmp 0x12ccc
movsbl -0x13(%rbp), %eax
cmpl $0x0, %eax
jge 0x12d92
movsd 0x8cb8(%rip), %xmm0     # 0x1ba40
movsd %xmm0, -0x140(%rbp)
jmp 0x12dbd
movq -0xe8(%rbp), %rdi
movq -0x88(%rbp), %rsi
movb -0xb1(%rbp), %dl
movb -0x13(%rbp), %cl
movq (%rdi), %rax
movsbl %dl, %edx
movsbl %cl, %ecx
callq *0x38(%rax)
movsd %xmm0, -0x140(%rbp)
movq -0xe8(%rbp), %rax
movsd -0x140(%rbp), %xmm0
movq 0x70(%rax), %rax
movslq -0xac(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0xb1(%rbp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
cmpb $0x0, -0x2e(%rbp)
je 0x12e2e
movq -0xe8(%rbp), %rax
movq 0x70(%rax), %rcx
movslq -0xac(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movsbq -0xb1(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq 0xa8(%rax), %rax
movslq -0xac(%rbp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0x12e30
movb -0xb1(%rbp), %al
addb $0x1, %al
movb %al, -0xb1(%rbp)
jmp 0x12cb2
jmp 0x12e45
movq -0xe8(%rbp), %rax
testb $0x1, 0xc0(%rax)
jne 0x12ec7
cmpl $-0x1, -0xb0(%rbp)
je 0x12e93
movq -0xe8(%rbp), %rax
movl -0xac(%rbp), %esi
movq 0xb8(%rax), %rcx
movslq -0xb0(%rbp), %rdx
movl %esi, (%rcx,%rdx,4)
movl -0xb0(%rbp), %edx
movq 0xb0(%rax), %rax
movslq -0xac(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0xe8(%rbp), %rax
movl -0xac(%rbp), %esi
movq -0x70(%rbp), %rcx
movslq -0x20(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x24(%rbp), %rdx
movl %esi, (%rcx,%rdx,4)
movq 0x88(%rax), %rax
movslq -0x24(%rbp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
jmp 0x12ec9
movl -0xa8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa8(%rbp)
jmp 0x12a87
movq -0xe8(%rbp), %rdi
movq 0xc8(%rdi), %rsi
movq -0x98(%rbp), %rdx
movb -0x99(%rbp), %cl
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %r8
movq (%rax,%r8,8), %r8
movq -0x88(%rbp), %r9
movq (%rdi), %rax
movsbl %cl, %ecx
callq *0x58(%rax)
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x2d(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x7580
movsd %xmm0, -0x68(%rbp)
movsd -0x68(%rbp), %xmm0
callq 0x7690
movsd %xmm0, -0x150(%rbp)
movsbl -0x14(%rbp), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x148(%rbp)
movsd 0x8adc(%rip), %xmm0     # 0x1ba40
subsd -0x68(%rbp), %xmm0
callq 0x7690
movsd -0x150(%rbp), %xmm1
movsd -0x148(%rbp), %xmm2
movsbl -0x14(%rbp), %ecx
movl $0x1, %eax
subl %ecx, %eax
cvtsi2sd %eax, %xmm3
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd -0x38(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x132b5
movsd -0x68(%rbp), %xmm0
callq 0x7690
movsd %xmm0, -0x178(%rbp)
movsbl -0x14(%rbp), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x170(%rbp)
movsd 0x8a64(%rip), %xmm0     # 0x1ba40
subsd -0x68(%rbp), %xmm0
callq 0x7690
movsd -0x178(%rbp), %xmm1
movsd -0x170(%rbp), %xmm2
movsbl -0x14(%rbp), %ecx
movl $0x1, %eax
subl %ecx, %eax
cvtsi2sd %eax, %xmm3
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd -0x40(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movsbl -0x14(%rbp), %eax
cvtsi2sd %eax, %xmm0
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x2d(%rbp), %rcx
subsd (%rax,%rcx,8), %xmm0
movl $0x2, %edi
callq 0xb8b0
addsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
movsbl -0x14(%rbp), %eax
cvtsi2sd %eax, %xmm0
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x2d(%rbp), %rcx
subsd (%rax,%rcx,8), %xmm0
movl $0x2, %edi
callq 0xb8b0
addsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movsbl -0x14(%rbp), %eax
movl %eax, -0x164(%rbp)
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x2d(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x160(%rbp)
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movsbl -0x12(%rbp), %esi
callq 0x7930
movaps %xmm0, %xmm1
movsd -0x160(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x151(%rbp)
jne 0x1311d
jp 0x1311d
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x2d(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsbl -0x12(%rbp), %ecx
movl $0x1, %eax
cltd
idivl %ecx
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
seta %al
movb %al, -0x151(%rbp)
movl -0x164(%rbp), %eax
movb -0x151(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
cvtsi2sd %eax, %xmm0
addsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
movsbl -0x14(%rbp), %eax
movl %eax, -0x18c(%rbp)
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x2d(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x188(%rbp)
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movsbl -0x12(%rbp), %esi
callq 0x7930
movaps %xmm0, %xmm1
movsd -0x188(%rbp), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x179(%rbp)
jne 0x131db
jp 0x131db
movq -0x78(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbq -0x2d(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsbl -0x12(%rbp), %ecx
movl $0x1, %eax
cltd
idivl %ecx
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
seta %al
movb %al, -0x179(%rbp)
movq -0xe8(%rbp), %rax
movl -0x18c(%rbp), %ecx
movb -0x179(%rbp), %dl
andb $0x1, %dl
movzbl %dl, %edx
cmpl %edx, %ecx
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
cvtsi2sd %ecx, %xmm0
addsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x60(%rbp)
movq 0x68(%rax), %rax
cmpl $0x2, 0x70(%rax)
jne 0x132b3
movl $0x0, -0xb8(%rbp)
movl -0xb8(%rbp), %eax
movsbl -0x99(%rbp), %ecx
cmpl %ecx, %eax
jge 0x132b1
movq -0xe8(%rbp), %rax
movq -0x98(%rbp), %rcx
movslq -0xb8(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
movl %ecx, -0x24(%rbp)
movl -0xb8(%rbp), %ecx
movq 0x68(%rax), %rdx
movq 0x8b0(%rdx), %rdx
movslq -0x8c(%rbp), %rsi
addl (%rdx,%rsi,4), %ecx
movl %ecx, -0xbc(%rbp)
movq 0xc8(%rax), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsd (%rax), %xmm0
movq -0x80(%rbp), %rax
movslq -0xbc(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0xb8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb8(%rbp)
jmp 0x13225
jmp 0x132b3
jmp 0x132b5
jmp 0x132b7
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x1271f
movl $0x0, -0xc0(%rbp)
movl -0xc0(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x13553
movq -0xe8(%rbp), %rax
movq 0x68(%rax), %rcx
movq 0x890(%rcx), %rcx
movslq -0xc0(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
movl %ecx, -0x20(%rbp)
movq 0x68(%rax), %rdi
movl -0xc0(%rbp), %esi
leaq -0xc8(%rbp), %rdx
leaq -0xc9(%rbp), %rcx
callq 0x9ce0
movl $0x0, -0xd0(%rbp)
movl $0x0, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
movsbl -0xc9(%rbp), %ecx
cmpl %ecx, %eax
jge 0x1338e
movq -0xe8(%rbp), %rax
movq 0x58(%rax), %rax
movq -0xc8(%rbp), %rcx
movslq -0xd4(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
setg %al
andb $0x1, %al
movzbl %al, %eax
addl -0xd0(%rbp), %eax
movl %eax, -0xd0(%rbp)
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0x13334
movl $0x0, -0xd8(%rbp)
movl -0xd8(%rbp), %ecx
movsbl -0xc9(%rbp), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x18d(%rbp)
jge 0x133c9
movl -0xd0(%rbp), %eax
movsbl -0xc9(%rbp), %ecx
cmpl %ecx, %eax
sete %al
movb %al, -0x18d(%rbp)
movb -0x18d(%rbp), %al
testb $0x1, %al
jne 0x133d8
jmp 0x1353d
movq -0xe8(%rbp), %rcx
movq -0xc8(%rbp), %rax
movslq -0xd8(%rbp), %rdx
movl (%rax,%rdx,4), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %edx
movq -0x88(%rbp), %rax
movl %edx, (%rax)
movl -0xd8(%rbp), %eax
movq 0x68(%rcx), %rcx
movq 0x8b0(%rcx), %rcx
movslq -0xc0(%rbp), %rdx
addl (%rcx,%rdx,4), %eax
movl %eax, -0xdc(%rbp)
cmpb $0x0, -0x2e(%rbp)
je 0x1345f
movq -0xe8(%rbp), %rax
movq 0xa8(%rax), %rcx
movslq -0xdc(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq 0x78(%rax), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x24(%rbp), %rcx
mulsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0x13527
movq -0xe8(%rbp), %rax
movq 0xb8(%rax), %rax
movslq -0xdc(%rbp), %rcx
cmpl $-0x1, (%rax,%rcx,4)
jne 0x13525
movb $0x0, -0xca(%rbp)
movsbl -0xca(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0x134e1
movq -0xe8(%rbp), %rax
movq 0x70(%rax), %rcx
movslq -0xdc(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movsbq -0xca(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq 0x78(%rax), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x24(%rbp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movb -0xca(%rbp), %al
addb $0x1, %al
movb %al, -0xca(%rbp)
jmp 0x13485
movq -0xe8(%rbp), %rax
movq 0x78(%rax), %rax
movslq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x24(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x7690
movq -0xe8(%rbp), %rax
movaps %xmm0, %xmm1
movq 0x80(%rax), %rax
movslq -0x24(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0x13527
jmp 0x13529
movl -0xd8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd8(%rbp)
jmp 0x13398
jmp 0x1353f
movl -0xc0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc0(%rbp)
jmp 0x132d5
movq -0xe8(%rbp), %rax
movb $0x1, 0xc0(%rax)
cmpq $0x0, -0x70(%rbp)
je 0x13574
movq -0x70(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0x19500
cmpq $0x0, -0x10(%rbp)
je 0x135f7
movq -0xe8(%rbp), %rax
movsd -0x38(%rbp), %xmm0
movq -0x10(%rbp), %rcx
movsd %xmm0, (%rcx)
movsd -0x40(%rbp), %xmm0
movq -0x10(%rbp), %rcx
movsd %xmm0, 0x8(%rcx)
movsd -0x48(%rbp), %xmm0
movq -0x10(%rbp), %rcx
movsd %xmm0, 0x10(%rcx)
movsd -0x50(%rbp), %xmm0
movq -0x10(%rbp), %rcx
movsd %xmm0, 0x18(%rcx)
movsd -0x58(%rbp), %xmm0
movq -0x10(%rbp), %rcx
movsd %xmm0, 0x20(%rcx)
movsd -0x60(%rbp), %xmm0
movq -0x10(%rbp), %rcx
movsd %xmm0, 0x28(%rcx)
movq 0x68(%rax), %rax
cmpl $0x2, 0x70(%rax)
jne 0x135f5
movq -0xe8(%rbp), %rax
movq -0x80(%rbp), %rcx
movq 0x68(%rax), %rax
movq %rcx, 0x8d0(%rax)
jmp 0x135f7
movq -0x88(%rbp), %rax
movq %rax, -0x198(%rbp)
cmpq $0x0, %rax
je 0x1361c
movq -0x198(%rbp), %rdi
movl $0x14, %esi
callq 0x3280
movsd -0x38(%rbp), %xmm0
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
nopw (%rax,%rax)