// File: /workspace/github_cpp_makefile_star2_O1/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 0xe38d(%rip), %rdi      # 0x1131c
callq 0x22f0
leaq 0x1429d(%rip), %rdi     # 0x17238
callq 0x6e8e
leaq 0x830(%rsp), %rdx
leaq 0x430(%rsp), %rcx
leaq 0x30(%rsp), %r8
movl %ebp, %edi
movq %r14, %rsi
callq 0x332d
cmpl $0x0, 0x142ea(%rip)     # 0x172b0
je 0x2fde
leaq 0x14269(%rip), %rsi     # 0x17238
leaq 0x830(%rsp), %rdi
callq 0x976e
jmp 0x2ff2
leaq 0x14253(%rip), %rsi     # 0x17238
leaq 0x830(%rsp), %rdi
callq 0x82b2
leaq 0xe03f(%rip), %rsi      # 0x11038
leaq 0x430(%rsp), %rdi
callq 0x2230
testq %rax, %rax
je 0x32f9
movq %rax, %r14
leaq 0xc(%rsp), %r15
movl $0x0, (%r15)
leaq 0xc30(%rsp), %r12
movq %r12, %rdi
callq 0x6e8e
movq %r14, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x7430
cmpb $0x0, 0x14af6(%rip)     # 0x17b39
jne 0x3052
movb 0x1531(%rsp), %al
movb %al, 0x14ae7(%rip)      # 0x17b39
movzbl 0xc7e(%rsp), %edi
movb %dil, 0x14225(%rip)     # 0x17286
movzwl 0xc7f(%rsp), %eax
movw %ax, 0x14217(%rip)      # 0x17287
movb 0x1530(%rsp), %al
movb %al, 0x14abb(%rip)      # 0x17b38
cmpb $0x3, 0x14ab5(%rip)     # 0x17b39
setge %cl
cmpb $0x3, %al
setge %al
orb %cl, %al
cmpb $0x1, %al
jne 0x3099
movb $0x1, 0x141e1(%rip)     # 0x1727a
movb 0x1540(%rsp), %al
movb %al, 0x14aa2(%rip)      # 0x17b48
movq $0x0, (%rsp)
cmpl $0xe, %edi
je 0x30da
cmpl $0x1, %edi
jne 0x3306
movl $0xd0, %edi
callq 0x21c0
movq %rax, %r15
leaq 0x14168(%rip), %rsi     # 0x17238
movq %rax, %rdi
callq 0xac7c
jmp 0x30f6
movl $0x110, %edi            # imm = 0x110
callq 0x21c0
movq %rax, %r15
leaq 0x1414a(%rip), %rsi     # 0x17238
movq %rax, %rdi
callq 0x106d2
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, 0x1415f(%rip)     # 0x17284
jne 0x3157
movsbl 0x14a0b(%rip), %esi     # 0x17b39
movl 0x14a08(%rip), %edx     # 0x17b3c
movl 0x14a06(%rip), %ecx     # 0x17b40
movl 0x14a03(%rip), %r8d     # 0x17b44
movsbl 0x149ff(%rip), %r9d     # 0x17b48
leaq 0xdf2d(%rip), %rdi      # 0x1107d
xorl %eax, %eax
callq 0x2050
callq 0x2120
movq %rax, %r14
movl $0x7, %edi
movl $0x8, %esi
callq 0x2110
movq %rax, 0x14a53(%rip)     # 0x17bc8
leaq 0x140bc(%rip), %rdx     # 0x17238
leaq 0x30(%rsp), %rsi
movq %rsp, %rcx
movq %rax, %rdi
movl $0x1, %r8d
xorl %r9d, %r9d
callq 0xdc80
cmpb $0x0, 0x140e8(%rip)     # 0x17284
jne 0x31c1
callq 0x2120
subq %r14, %rax
cvtsi2sd %rax, %xmm0
divsd 0xde55(%rip), %xmm0     # 0x11008
leaq 0xdef2(%rip), %rdi      # 0x110ac
movb $0x1, %al
callq 0x2050
movq 0x14a00(%rip), %rax     # 0x17bc8
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq (%rsp), %rdi
callq 0xe2c2
addl %eax, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movq 0x149d2(%rip), %rax     # 0x17bc8
movsd (%rax), %xmm1
addsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x18(%rsp)
movq (%rsp), %rdi
callq 0xe2c2
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x14013(%rip), %r14     # 0x17238
xorps %xmm0, %xmm0
cvtsi2sdl 0x14900(%rip), %xmm0 # 0x17b30
callq 0x608b
movq 0x1498c(%rip), %rax     # 0x17bc8
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 0xde64(%rip), %rdi      # 0x110d1
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 0x1492c(%rip), %rdi     # 0x17bc8
callq 0x2240
movq %r14, %rdi
callq 0x70fc
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x32b8
movq (%rdi), %rax
callq *0x8(%rax)
cmpb $0x0, 0x13fc5(%rip)     # 0x17284
jne 0x32e7
callq 0x2120
subq %rbx, %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0xdd2f(%rip), %xmm0     # 0x11008
leaq 0xde50(%rip), %rdi      # 0x11130
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 0x331d
movq %rax, %rbx
movl $0xd0, %esi
movq %r15, %rdi
callq 0x21d0
movq %rbx, %rdi
callq 0x2370