// File: /workspace/github_cpp_makefile_star2_O3/myudelson[P]hmm-scalable/predicthmmst.cpp
// Function: main
int main (int argc, char ** argv) {
	clock_t tm0 = clock();
	printf("predicthmm starting...\n");
	set_task_defaults(&task);
	
	char input_file[1024];
	char model_file[1024];
	char predict_file[1024];
	
	parse_arguments(argc, argv, input_file, model_file, predict_file);
    // task.predictions = 2; // do not force it on

    // read data
    if(task.binaryinput==0) {
        InputUtilSt::readTxt(input_file, &task);
    } else {
        InputUtilSt::readBin(input_file, &task);
    }
    
    // read model header
	FILE *fid = fopen(model_file,"r");
	if(fid == NULL)
	{
		fprintf(stderr,"Can't read model file %s\n",model_file);
		exit(1);
	}
	int max_line_length = 1024;
	char *line = Malloc(char,(size_t)max_line_length);
	NDAT line_no = 0;
    struct task task_model;
    set_task_defaults(&task_model);
    bool overwrite = false;
//    if(overwrite)
        readSolverInfo(fid, &task_model, &line_no);
//    else
//        readSolverInfo(fid, &inittask, &line_no);
    
    // copy partial info from task_model to task
    if(task.nO==0) task.nO = task_model.nO;
    task.structure = task_model.structure;
    task.solver = task_model.solver;
    task.solver_setting = task_model.solver_setting;
    
    // copy number of states from the model
    task.nS = task_model.nS;
    
    // if number of states or observations >2, then no check
    if( task.nO>2 || task.nS>2) {
        task.do_not_check_constraints = 1;
    }
    
	// copy number of slices from the model
	task.nZ = task_model.nZ;
    //
    // create hmm Object
    //
    HMMProblemSt *hmm = NULL;
	switch(task.structure)
	{
		case STRUCTURE_SKILL: // Conjugate Gradient Descent
//            case STRUCTURE_GROUP: // Conjugate Gradient Descent
			hmm = new HMMProblemSt(&task);
			break;
        case STRUCTURE_ELO: // Gradient Descent, pT=f(K,G), other by K
            hmm = new HMMProblemEloSt(&task);
            break;
        default:
            fprintf(stderr,"Solver specified (%d) is not supported!\n",task.structure);
            exit(1);
            break;
	}
    // read model body
    hmm->readModelBody(fid, &task_model, &line_no, overwrite);
  	fclose(fid);
	free(line);
	
	if(task.quiet == 0)
        printf("input read, nO=%d, nG=%d, nK=%d, nI=%d, nZ=%d\n",task.nO, task.nG, task.nK, task.nI, task.nZ);
	
	clock_t tm = clock();
//    if(task.metrics>0 || task.predictions>0) {
        metrics = Calloc(NUMBER, (size_t)7);// LL, AIC, BIC, RMSE, RMSEnonull, Acc, Acc_nonull;
//    }
    HMMProblemSt::predict(metrics, predict_file, &task, &hmm, 1, NULL);

//    predict(predict_file, hmm);
	if(task.quiet == 0)
		printf("predicting is done in %8.6f seconds\n",(NUMBER)(clock()-tm)/CLOCKS_PER_SEC);
    //if( task.predictions>0 ) {
        printf("trained model LL=%15.7f (%15.7f), AIC=%8.6f, BIC=%8.6f, RMSE=%8.6f (%8.6f), Acc=%8.6f (%8.6f)\n",
               metrics[0], metrics[1], // ll's
               2*hmm->getModelParamN() + 2*metrics[0], // AIC
               hmm->getModelParamN()*safelog(task.N) + 2*metrics[0], //BIC
               metrics[2], metrics[3], // rmse's
               metrics[4], metrics[5]); // acc's
    //}
    
    // post-prediction runs
    hmm->postPredictionSave(predict_file);
    
    // recycle memory
    free(metrics);
	destroy_input_data(&task);
    delete hmm;

    if(task.quiet == 0)
		printf("overall time running is %8.6f seconds\n",(NUMBER)(clock()-tm0)/CLOCKS_PER_SEC);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x15c0, %rsp           # imm = 0x15C0
movq %rsi, %r14
movl %edi, %ebp
callq 0x2120
movq %rax, %rbx
leaq 0xf34d(%rip), %rdi      # 0x1231c
callq 0x22f0
leaq 0x1525d(%rip), %rdi     # 0x18238
callq 0x6fa9
leaq 0x830(%rsp), %rdx
leaq 0x430(%rsp), %rcx
leaq 0x30(%rsp), %r8
movl %ebp, %edi
movq %r14, %rsi
callq 0x3363
cmpl $0x0, 0x152aa(%rip)     # 0x182b0
je 0x301e
leaq 0x15229(%rip), %rsi     # 0x18238
leaq 0x830(%rsp), %rdi
callq 0x96c2
jmp 0x3032
leaq 0x15213(%rip), %rsi     # 0x18238
leaq 0x830(%rsp), %rdi
callq 0x832e
leaq 0xefff(%rip), %rsi      # 0x12038
leaq 0x430(%rsp), %rdi
callq 0x2230
testq %rax, %rax
je 0x332f
movq %rax, %r14
leaq 0xc(%rsp), %r15
movl $0x0, (%r15)
leaq 0xc30(%rsp), %r12
movq %r12, %rdi
callq 0x6fa9
movq %r14, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x74e6
movb 0x15ab7(%rip), %al      # 0x18b39
testb %al, %al
jne 0x3093
movb 0x1531(%rsp), %al
movb %al, 0x15aa6(%rip)      # 0x18b39
movzbl 0xc7e(%rsp), %edi
movb %dil, 0x151e4(%rip)     # 0x18286
movzwl 0xc7f(%rsp), %ecx
movw %cx, 0x151d6(%rip)      # 0x18287
movb 0x1530(%rsp), %cl
movb %cl, 0x15a7a(%rip)      # 0x18b38
cmpb $0x3, %al
setge %al
cmpb $0x3, %cl
setge %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x30d7
movb $0x1, 0x151a3(%rip)     # 0x1827a
movb 0x1540(%rsp), %al
movb %al, 0x15a64(%rip)      # 0x18b48
cmpl $0xe, %edi
je 0x3110
cmpl $0x1, %edi
jne 0x333c
movl $0xd0, %edi
callq 0x21c0
movq %rax, %r15
leaq 0x15132(%rip), %rsi     # 0x18238
movq %rax, %rdi
callq 0xac64
jmp 0x312c
movl $0x110, %edi            # imm = 0x110
callq 0x21c0
movq %rax, %r15
leaq 0x15114(%rip), %rsi     # 0x18238
movq %rax, %rdi
callq 0x10b6e
movq %r15, (%rsp)
movq (%r15), %rax
leaq 0xc30(%rsp), %rdx
leaq 0xc(%rsp), %rcx
movq %r15, %rdi
movq %r14, %rsi
xorl %r8d, %r8d
callq *0x60(%rax)
movq %r14, %rdi
callq 0x21b0
cmpb $0x0, 0x15129(%rip)     # 0x18284
jne 0x318d
movsbl 0x159d5(%rip), %esi     # 0x18b39
movl 0x159d2(%rip), %edx     # 0x18b3c
movl 0x159d0(%rip), %ecx     # 0x18b40
movl 0x159cd(%rip), %r8d     # 0x18b44
movsbl 0x159c9(%rip), %r9d     # 0x18b48
leaq 0xeef7(%rip), %rdi      # 0x1207d
xorl %eax, %eax
callq 0x2050
callq 0x2120
movq %rax, %r14
movl $0x7, %edi
movl $0x8, %esi
callq 0x2110
movq %rax, 0x15a1d(%rip)     # 0x18bc8
leaq 0x15086(%rip), %rdx     # 0x18238
leaq 0x30(%rsp), %rsi
movq %rsp, %rcx
movq %rax, %rdi
movl $0x1, %r8d
xorl %r9d, %r9d
callq 0xde12
cmpb $0x0, 0x150b2(%rip)     # 0x18284
jne 0x31f7
callq 0x2120
subq %r14, %rax
cvtsi2sd %rax, %xmm0
divsd 0xee1f(%rip), %xmm0     # 0x12008
leaq 0xeebc(%rip), %rdi      # 0x120ac
movb $0x1, %al
callq 0x2050
movq 0x159ca(%rip), %rax     # 0x18bc8
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq (%rsp), %rdi
callq 0xe3d0
addl %eax, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movq 0x1599c(%rip), %rax     # 0x18bc8
movsd (%rax), %xmm1
addsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x18(%rsp)
movq (%rsp), %rdi
callq 0xe3d0
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x14fdd(%rip), %r14     # 0x18238
xorps %xmm0, %xmm0
cvtsi2sdl 0x158ca(%rip), %xmm0 # 0x18b30
callq 0x619d
movq 0x15956(%rip), %rax     # 0x18bc8
movsd (%rax), %xmm1
movsd 0x10(%rax), %xmm4
addsd %xmm1, %xmm1
movsd 0x10(%rsp), %xmm3
mulsd %xmm0, %xmm3
addsd %xmm1, %xmm3
movsd 0x18(%rax), %xmm5
movsd 0x20(%rax), %xmm6
movsd 0x28(%rax), %xmm7
leaq 0xee2e(%rip), %rdi      # 0x120d1
movsd 0x28(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x18(%rsp), %xmm2
movb $0x8, %al
callq 0x2050
movq (%rsp), %rdi
movq (%rdi), %rax
leaq 0x30(%rsp), %rsi
callq *0x68(%rax)
movq 0x158f6(%rip), %rdi     # 0x18bc8
callq 0x2240
movq %r14, %rdi
callq 0x71b0
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x32ee
movq (%rdi), %rax
callq *0x8(%rax)
cmpb $0x0, 0x14f8f(%rip)     # 0x18284
jne 0x331d
callq 0x2120
subq %rbx, %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0xecf9(%rip), %xmm0     # 0x12008
leaq 0xee1a(%rip), %rdi      # 0x12130
movb $0x1, %al
callq 0x2050
xorl %eax, %eax
addq $0x15c0, %rsp           # imm = 0x15C0
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x430(%rsp), %rdi
callq 0x2415
callq 0x23f0
movq %rax, %rbx
movl $0x110, %esi            # imm = 0x110
jmp 0x3353
movq %rax, %rbx
movl $0xd0, %esi
movq %r15, %rdi
callq 0x21d0
movq %rbx, %rdi
callq 0x2370