// File: myudelson[P]hmm-scalable/HMMProblemSt.cpp
// Function: HMMProblemSt::init(task*)
void HMMProblemSt::init(struct task *task) {
//    printf("HMMProblemSt::init\n");
   // init
    this->task = task;
    this->non01constraints = true;
    this->null_obs_ratios = Calloc(NUMBER, (size_t)this->task->nO);
//    this->neg_log_lik = 0;
    this->null_skill_obs = 0;
    this->null_skill_obs_prob = 0;
    if( this->task->solver == METHOD_CGD && this->task->solver_setting == -1)
        this->task->solver_setting = 1; // default Fletcher-Reeves
    
    NPAR nS = this->task->nS, nO = this->task->nO;
    NCAT nK = this->task->nK, nG = this->task->nG;
    
    //
    // setup params
    //
    this->skill1_n = nS * (1 + nS + nO); // number of params per 1 skill slot
    this->param_skill = init1D<NUMBER>( (NDAT)(this->skill1_n*nK) );
    this->gradient_skill = init1D<NUMBER>( (NDAT)(this->skill1_n*nK) );
    this->active_set_block = initToValue1D<NPAR>((NDAT)nK, 1);
    this->unblocked_simplex = initToValue1D<NPAR>((NDAT)(nK * (1 + 2 * nS)), 1);
    
    NPAR i, j, m;
    int offset, idx;

    // write default parameters first
    NUMBER sum = 0;
    
    // vv populate skill parameters
    for(NCAT k=0; k<nK; k++) {
        // vv populate PI
        for(i=0; i<((nS)-1); i++) {
            this->param_skill[ k*this->skill1_n + i ] = this->task->init_param_values[i];
            sum  += this->task->init_param_values[i];
        } // ^^ populate PI
        this->param_skill[ k*this->skill1_n + nS - 1 ] = 1 - sum;
        // vv populate A
        offset = (int)(nS-1);
        for(i=0; i<nS; i++) {
            sum = 0;
            for(j=0; j<((nS)-1); j++) {
                idx = (int)(offset + i*((nS)-1) + j);
                this->param_skill[ k*this->skill1_n + nS + i*nS + j ] = this->task->init_param_values[idx];
                sum  += this->task->init_param_values[idx];
            }
            this->param_skill[ k*this->skill1_n + nS + i*nS + nS-1 ] = 1 - sum;
        } // ^^ populate A
        // vv populate B
        offset = (int)((nS-1) + nS*(nS-1));
        for(i=0; i<nS; i++) {
            sum = 0;
            for(m=0; m<((nO)-1); m++) {
                idx = (int)(offset + i*((nO)-1) + m);
                this->param_skill[ k*this->skill1_n + nS + nS*nS + i*nO + m ] = this->task->init_param_values[idx];
                sum += this->task->init_param_values[idx];
            }
            this->param_skill[ k*this->skill1_n + nS + nS*nS + i*nO + nO - 1 ] = 1 - sum;
        } // ^^ populate B
    } // ^^ populate skill parameters
    
    // check only first mass-produced skill
    if( this->task->do_not_check_constraints==0 && !checkSkillConstraints(this->param_skill)) {
        fprintf(stderr,"params do not meet constraints.\n");
        exit(1);
    }

    if(task->initfile[0]!=0) { // from setup file
        // if needs be -- read in init params from a file
        this->readModel(task->initfile, false /* read and upload but not overwrite*/);
    }
    
    // init and populate boundaries
    this->lb_param_skill = init1D<NUMBER>(this->skill1_n);
    cpy1D(this->task->param_values_lb, this->lb_param_skill, this->skill1_n);
    this->ub_param_skill = init1D<NUMBER>(this->skill1_n);
    cpy1D(this->task->param_values_ub, this->ub_param_skill, this->skill1_n);
    
    // init supportive data structures
    NDAT Nst = this->task->Nst;
    this->alpha = init2D<NUMBER>(Nst, nS); // forward variables, 2D array of Nst rows nS values in each ((1..nS)){Nst}
    this->po_param_gk = init2D<NUMBER>(nG, nK); //
    this->loglik_k = init1D<NUMBER>(nK); //
    this->ndat_k = init1D<NDAT>(nK);
    this->beta = init2D<NUMBER>(Nst, nS); // backward variables, 2D array of Nst rows nS values in each ((1..nS)){Nst}
    this->scale = (this->task->is_scaled==1) ? initToValue1D<NUMBER>(Nst, 0) : NULL;
    this->gamma = NULL;
    this->xi = NULL;
    if(this->task->solver == METHOD_BW) {
        this->gamma = init2D<NUMBER>(Nst, nS);
        this->xi = init3D<NUMBER>(Nst, nS, nS);
    }
    this->backward_ix = init1D<NDAT>(Nst); // Nst sized array of pointing to previous student-skill repetition, -1 means none before
    this->forward_ix = init1D<NDAT>(Nst); // Nst sized array of pointing to next student-skill repetition, -1 means no more
    this->is_fwd_bwd_built=false; // flag for noting whether backward_ix & forward_ix are already built
    
    this->group_skill_map = init3D<NUMBER>(nG, nK, nS);//UNBOOST

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, 0x68(%rax)
movb $0x1, 0x50(%rax)
movq 0x68(%rax), %rax
movsbq 0x901(%rax), %rdi
movl $0x8, %esi
callq 0x3170
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x10(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0x18(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x68(%rax), %rax
movsbl 0x4f(%rax), %eax
cmpl $0x3, %eax
jne 0x113df
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rax
movsbl 0x50(%rax), %eax
cmpl $-0x1, %eax
jne 0x113df
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rax
movb $0x1, 0x50(%rax)
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rcx
movb 0x900(%rcx), %cl
movb %cl, -0x11(%rbp)
movq 0x68(%rax), %rcx
movb 0x901(%rcx), %cl
movb %cl, -0x12(%rbp)
movq 0x68(%rax), %rcx
movl 0x908(%rcx), %ecx
movl %ecx, -0x18(%rbp)
movq 0x68(%rax), %rcx
movl 0x904(%rcx), %ecx
movl %ecx, -0x1c(%rbp)
movsbl -0x11(%rbp), %ecx
movsbl -0x11(%rbp), %edx
addl $0x1, %edx
movsbl -0x12(%rbp), %esi
addl %esi, %edx
imull %edx, %ecx
movl %ecx, 0x38(%rax)
movl 0x38(%rax), %edi
imull -0x18(%rbp), %edi
callq 0x9da0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x28(%rax)
movl 0x38(%rax), %edi
imull -0x18(%rbp), %edi
callq 0x9da0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x30(%rax)
movl -0x18(%rbp), %edi
movl $0x1, %esi
callq 0x18ff0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x58(%rax)
movl -0x18(%rbp), %edi
movsbl -0x11(%rbp), %eax
shll %eax
addl $0x1, %eax
imull %eax, %edi
movl $0x1, %esi
callq 0x18ff0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x60(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x1179a
movb $0x0, -0x1d(%rbp)
movsbl -0x1d(%rbp), %eax
movsbl -0x11(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x11519
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rcx
movq (%rcx), %rcx
movsbq -0x1d(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq 0x28(%rax), %rcx
movl -0x34(%rbp), %edx
imull 0x38(%rax), %edx
movsbl -0x1d(%rbp), %esi
addl %esi, %edx
movslq %edx, %rdx
movsd %xmm0, (%rcx,%rdx,8)
movq 0x68(%rax), %rax
movq (%rax), %rax
movsbq -0x1d(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movb -0x1d(%rbp), %al
addb $0x1, %al
movb %al, -0x1d(%rbp)
jmp 0x114b7
movq -0x40(%rbp), %rdx
movsd 0xa51b(%rip), %xmm0     # 0x1ba40
subsd -0x30(%rbp), %xmm0
movq 0x28(%rdx), %rax
movl -0x34(%rbp), %ecx
imull 0x38(%rdx), %ecx
movsbl -0x11(%rbp), %edx
addl %edx, %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movsbl -0x11(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x24(%rbp)
movb $0x0, -0x1d(%rbp)
movsbl -0x1d(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0x11653
xorps %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
movb $0x0, -0x1e(%rbp)
movsbl -0x1e(%rbp), %eax
movsbl -0x11(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x11606
movq -0x40(%rbp), %rax
movl -0x24(%rbp), %ecx
movsbl -0x1d(%rbp), %edx
movsbl -0x11(%rbp), %esi
subl $0x1, %esi
imull %esi, %edx
addl %edx, %ecx
movsbl -0x1e(%rbp), %edx
addl %edx, %ecx
movl %ecx, -0x28(%rbp)
movq 0x68(%rax), %rcx
movq (%rcx), %rcx
movslq -0x28(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq 0x28(%rax), %rcx
movl -0x34(%rbp), %edx
imull 0x38(%rax), %edx
movsbl -0x11(%rbp), %esi
addl %esi, %edx
movsbl -0x1d(%rbp), %esi
movsbl -0x11(%rbp), %edi
imull %edi, %esi
addl %esi, %edx
movsbl -0x1e(%rbp), %esi
addl %esi, %edx
movslq %edx, %rdx
movsd %xmm0, (%rcx,%rdx,8)
movq 0x68(%rax), %rax
movq (%rax), %rax
movslq -0x28(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movb -0x1e(%rbp), %al
addb $0x1, %al
movb %al, -0x1e(%rbp)
jmp 0x11570
movq -0x40(%rbp), %rdx
movsd 0xa42e(%rip), %xmm0     # 0x1ba40
subsd -0x30(%rbp), %xmm0
movq 0x28(%rdx), %rax
movl -0x34(%rbp), %ecx
imull 0x38(%rdx), %ecx
movsbl -0x11(%rbp), %edx
addl %edx, %ecx
movsbl -0x1d(%rbp), %edx
movsbl -0x11(%rbp), %esi
imull %esi, %edx
addl %edx, %ecx
movsbl -0x11(%rbp), %edx
addl %edx, %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movb -0x1d(%rbp), %al
addb $0x1, %al
movb %al, -0x1d(%rbp)
jmp 0x11554
movsbl -0x11(%rbp), %eax
subl $0x1, %eax
movsbl -0x11(%rbp), %ecx
movsbl -0x11(%rbp), %edx
subl $0x1, %edx
imull %edx, %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movb $0x0, -0x1d(%rbp)
movsbl -0x1d(%rbp), %eax
movsbl -0x11(%rbp), %ecx
cmpl %ecx, %eax
jge 0x1178a
xorps %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
movb $0x0, -0x1f(%rbp)
movsbl -0x1f(%rbp), %eax
movsbl -0x12(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x11730
movq -0x40(%rbp), %rax
movl -0x24(%rbp), %ecx
movsbl -0x1d(%rbp), %edx
movsbl -0x12(%rbp), %esi
subl $0x1, %esi
imull %esi, %edx
addl %edx, %ecx
movsbl -0x1f(%rbp), %edx
addl %edx, %ecx
movl %ecx, -0x28(%rbp)
movq 0x68(%rax), %rcx
movq (%rcx), %rcx
movslq -0x28(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq 0x28(%rax), %rcx
movl -0x34(%rbp), %edx
imull 0x38(%rax), %edx
movsbl -0x11(%rbp), %esi
addl %esi, %edx
movsbl -0x11(%rbp), %esi
movsbl -0x11(%rbp), %edi
imull %edi, %esi
addl %esi, %edx
movsbl -0x1d(%rbp), %esi
movsbl -0x12(%rbp), %edi
imull %edi, %esi
addl %esi, %edx
movsbl -0x1f(%rbp), %esi
addl %esi, %edx
movslq %edx, %rdx
movsd %xmm0, (%rcx,%rdx,8)
movq 0x68(%rax), %rax
movq (%rax), %rax
movslq -0x28(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movb -0x1f(%rbp), %al
addb $0x1, %al
movb %al, -0x1f(%rbp)
jmp 0x1168d
movq -0x40(%rbp), %rdx
movsd 0xa304(%rip), %xmm0     # 0x1ba40
subsd -0x30(%rbp), %xmm0
movq 0x28(%rdx), %rax
movl -0x34(%rbp), %ecx
imull 0x38(%rdx), %ecx
movsbl -0x11(%rbp), %edx
addl %edx, %ecx
movsbl -0x11(%rbp), %edx
movsbl -0x11(%rbp), %esi
imull %esi, %edx
addl %edx, %ecx
movsbl -0x1d(%rbp), %edx
movsbl -0x12(%rbp), %esi
imull %esi, %edx
addl %edx, %ecx
movsbl -0x12(%rbp), %edx
addl %edx, %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movb -0x1d(%rbp), %al
addb $0x1, %al
movb %al, -0x1d(%rbp)
jmp 0x11671
jmp 0x1178c
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x114a7
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rax
movsbl 0x42(%rax), %eax
cmpl $0x0, %eax
jne 0x117de
movq -0x40(%rbp), %rdi
movq 0x28(%rdi), %rsi
callq 0x119c0
testb $0x1, %al
jne 0x117de
movq 0x10815(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
leaq 0xaafe(%rip), %rsi      # 0x1c2cb
movb $0x0, %al
callq 0x33c0
movl $0x1, %edi
callq 0x3330
movq -0x10(%rbp), %rax
movsbl 0x7c(%rax), %eax
cmpl $0x0, %eax
je 0x117fe
movq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x7c, %rsi
xorl %edx, %edx
callq 0x11ab0
movq -0x40(%rbp), %rax
movl 0x38(%rax), %edi
callq 0x9da0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x40(%rax)
movq 0x68(%rax), %rcx
movq 0x10(%rcx), %rdi
movq 0x40(%rax), %rsi
movl 0x38(%rax), %edx
callq 0x9dd0
movq -0x40(%rbp), %rax
movl 0x38(%rax), %edi
callq 0x9da0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x48(%rax)
movq 0x68(%rax), %rcx
movq 0x18(%rcx), %rdi
movq 0x48(%rax), %rsi
movl 0x38(%rax), %edx
callq 0x9dd0
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rax
movl 0x8fc(%rax), %eax
movl %eax, -0x38(%rbp)
movl -0x38(%rbp), %edi
movsbl -0x11(%rbp), %esi
callq 0x19050
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x70(%rax)
movl -0x1c(%rbp), %edi
movl -0x18(%rbp), %esi
callq 0x19050
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x78(%rax)
movl -0x18(%rbp), %edi
callq 0x9da0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x80(%rax)
movl -0x18(%rbp), %edi
callq 0x190c0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x88(%rax)
movl -0x38(%rbp), %edi
movsbl -0x11(%rbp), %esi
callq 0x19050
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x90(%rax)
movq 0x68(%rax), %rax
movsbl 0x41(%rax), %eax
cmpl $0x1, %eax
jne 0x118f6
movl -0x38(%rbp), %edi
xorps %xmm0, %xmm0
callq 0x190f0
movq %rax, -0x48(%rbp)
jmp 0x118fe
xorl %eax, %eax
movq %rax, -0x48(%rbp)
jmp 0x118fe
movq -0x40(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rcx, 0xa8(%rax)
movq $0x0, 0x98(%rax)
movq $0x0, 0xa0(%rax)
movq 0x68(%rax), %rax
movsbl 0x4f(%rax), %eax
cmpl $0x1, %eax
jne 0x11968
movl -0x38(%rbp), %edi
movsbl -0x11(%rbp), %esi
callq 0x19050
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x98(%rax)
movl -0x38(%rbp), %edi
movsbl -0x11(%rbp), %esi
movsbl -0x11(%rbp), %edx
callq 0x19150
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0xa0(%rax)
movl -0x38(%rbp), %edi
callq 0x190c0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0xb0(%rax)
movl -0x38(%rbp), %edi
callq 0x190c0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0xb8(%rax)
movb $0x0, 0xc0(%rax)
movl -0x1c(%rbp), %edi
movl -0x18(%rbp), %esi
movsbl -0x11(%rbp), %edx
callq 0x19150
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0xc8(%rax)
addq $0x50, %rsp
popq %rbp
retq
nop