// File: /workspace/github_cpp_makefile_star2_O3/myudelson[P]hmm-scalable/trainhmmst.cpp
// Function: main
int main (int argc, char ** argv) {
	clock_t tm_all = clock();//overall time //SEQ
//    double _tm_all = omp_get_wtime(); //PAR
    
	char input_file[1024]; // data
	char output_file[1024]; // model
    char colsole_file[1024]; // console copy
	char predict_file[1024]; // predictions
    
	set_task_defaults(&task);
    
    
    // parse parameters, step 1
	parse_arguments_step1(argc, argv, input_file, output_file, predict_file, colsole_file);

    FILE *fid_console = NULL;
    if(task.duplicate_console==1)
        fid_console = fopen(colsole_file,"w");
    
    if(!task.quiet) {
        printf("trainhmmst starting...\n");
        if(task.duplicate_console==1) fprintf(fid_console, "trainhmmst starting...\n");
    }

    clock_t tm_read = clock();//overall time //SEQ
//    double _tm_read = omp_get_wtime(); //PAR
    int read_ok = read_and_structure_data(input_file, fid_console);
    tm_read = (clock_t)(clock()-tm_read);//SEQ
    
//    _tm_read = omp_get_wtime()-_tm_read;//PAR

    if( ! read_ok )
        return 0;
    
    // once we know nO (number of observations) parse parameters, step 2
    parse_arguments_step2(argc, argv, fid_console);
    
//    write_pLo_irt();
    
    
//    //
//    // read item mean % correct
//    //
//    FILE *fid = fopen("a89_kts_train01_voc_i.txt","r");
//	max_line_length = 1024;
//	char *col;
//    string item;
//    map<string,NCAT>::iterator it;
//    task.item_complexity = Calloc(NUMBER, task.map_step_bwd->size());
//    line = (char *)malloc(max_line_length);// Malloc(char,max_line_length);
//    while( readline(fid)!=NULL) {
//		// Group
//		col = strtok(line,"\t\n\r");
//		item = string( col );
//		it = task.map_step_fwd->find(item);
//		if( it==task.map_step_fwd->end() ) { // not found
//            fprintf(stderr,"DID NOT FIND THE STEP!!\n");
//            return false;
//		}
//		else {
////            if( it->second > task.map_step_bwd->size()) {
////                int z = 0 ;
////            }
//            NUMBER v = atof( strtok(NULL,"\t\n\r") );
//            task.item_complexity[ it->second ] = v;
//		}
//    }
//    free(line);
//    fclose(fid);

    if(!task.quiet) {
        printf("input read, nO=%d, nG=%d, nK=%d, nI=%d, nZ=%d\n",task.nO, task.nG, task.nK, task.nI, task.nZ);
        if(task.duplicate_console==1) fprintf(fid_console, "input read, nO=%d, nG=%d, nK=%d, nI=%d, nZ=%d\n",task.nO, task.nG, task.nK, task.nI, task.nZ);
    }
    
    //    // write time
    //    if(task.time==1) {
    //        const char * fn = "a89_kts_times.txt";
    ////        const char * fn = "a89_uskts_times.txt";
    //        write_time_interval_data(&param, fn);
    //    }
    
    // erase blocking labels
//    zeroLabels(&task);

    clock_t tm_fit = 0; //SEQ
    clock_t tm_predict = 0; //SEQ
//    double _tm_fit;//PAR
//    double _tm_predict;//PAR
    
    if(task.cv_folds==0) { // not cross-validation
        // create problem
        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_PIg: // Gradient Descent: PI by group, A,B by skill
                //                hmm = new HMMProblemPiG(&param);
                //                break;
//            case STRUCTURE_SKABslc: // Conjugate Gradient Descent
//                hmm = new HMMProblemSlicedAB(&param);
//                break;
//            case STRUCTURE_SKAslc: // Conjugate Gradient Descent
//                hmm = new HMMProblemSlicedA(&param);
//                break;
//            case STRUCTURE_PIgk: // Gradient Descent, pLo=f(K,G), other by K
//                hmm = new HMMProblemPiGK(&param);
//                break;
//            case STRUCTURE_PIgkww: // Gradient Descent, pLo=f(K,G), other by K
//                hmm = new HMMProblemPiGKww(&param);
//                break;
//            case STRUCTURE_PIAgk: // Gradient Descent, pLo=f(K,G), pT=f(K,G), other by K
//                hmm = new HMMProblemPiAGK(&param);
//                break;
//            case STRUCTURE_Agk: // Gradient Descent, pT=f(K,G), other by K
//                hmm = new HMMProblemAGK(&param);
//                break;
////                case STRUCTURE_Agki: // Gradient Descent, pT=f(K,G), other by K
////                    hmm = new HMMProblemAGKi(&param);
////                    break;
//            case STRUCTURE_PIABgk: // Gradient Descent, pT=f(K,G), other by K
//                hmm = new HMMProblemPiABGK(&param);
//                break;
//                //            case BKT_GD_T: // Gradient Descent with Transfer
//                //                hmm = new HMMProblemKT(&param);
//                //                break;
//            case STRUCTURE_COMP: // Gradient Descent, pT=f(K,G), other by K
//                hmm = new HMMProblemComp(&param);
//                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;
        }
        tm_fit = clock(); //SEQ
//        _tm_fit = omp_get_wtime(); //PAR
        hmm->fit();
        tm_fit = clock()-tm_fit;//SEQ
//        _tm_fit = omp_get_wtime()-_tm_fit;//PAR
        
        // write model
        hmm->toFile(output_file);
        
        if(task.metrics>0 || task.predictions>0) {
            NUMBER* metrics = Calloc(NUMBER, (size_t)8); // LL, LLnonull, RMSE, RMSEnonull, Acc, Acc_nonull, AIC, BIC;
            // takes care of predictions and metrics, writes predictions if task.predictions==1
            
            // temporary
//            if(task.per_kc_rmse_acc) {
//                task.kc_counts = Calloc(NDAT, (size_t)task.nK);
//                task.kc_rmse = Calloc(NUMBER, (size_t)task.nK);
//                task.kc_acc  = Calloc(NUMBER, (size_t)task.nK);
//            }

            // NUMBER l1 = hmm->getSumLogPOPara(task.nSeq, task.k_data);
//            printf("hmm-style ll_no_null %15.7f\n",l1);
            
            tm_predict = clock(); //SEQ
//            _tm_predict = omp_get_wtime(); //PAR
//            if(task.structure==STRUCTURE_SKAslc) {
//                ((HMMProblemSlicedA *)hmm)->predict(metrics, predict_file, task.dat_obs, task.dat_group, task.dat_skill, task.dat_skill_stacked, task.dat_skill_rcount, task.dat_skill_rix);
//            } else if(task.structure==STRUCTURE_SKABslc) {
//                ((HMMProblemSlicedAB *)hmm)->predict(metrics, predict_file, task.dat_obs, task.dat_group, task.dat_skill, task.dat_skill_stacked, task.dat_skill_rcount, task.dat_skill_rix);
//            } else {
                HMMProblemSt::predict(metrics, predict_file,
                                      //task.N, task.dat_obs, task.dat_group, task.dat_skill, task.dat_skill_stacked, task.dat_skill_rcount, task.dat_skill_rix,
                                      &task,
                                      &hmm, 1, NULL);
            
//            }
            tm_predict = clock()-tm_predict;//SEQ
//            _tm_predict = omp_get_wtime()-_tm_predict;//PAR
            
            if( task.metrics>0 /*&& !task.quiet*/) {
                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
                if(task.duplicate_console==1) fprintf(fid_console, "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],
                       metrics[2], metrics[3], // rmse's
                       metrics[4], metrics[5]); // acc's

            }
            free(metrics);

            // temporary
//            if(task.per_kc_rmse_acc) {
//                for(NCAT i=0; i<task.nK; i++) {
//                    printf("KC %4u RMSE=%8.6f Acc=%8.6f\n",i,task.kc_rmse[i],task.kc_acc[i]);
//                    if(task.duplicate_console==1) fprintf(fid_console, "KC %4u RMSE=%8.6f Acc=%8.6f\n",i,task.kc_rmse[i],task.kc_acc[i]);
//                }
//                free(task.kc_counts);
//                free(task.kc_rmse);
//                free(task.kc_acc);
//            }
        
        } // if predict or metrics
        
        delete hmm;
    } else { // cross-validation
        NUMBER* metrics = Calloc(NUMBER, (size_t)7); // AIC, BIC, RMSE, RMSE no null
		NUMBER n_par = 0;
        switch (task.cv_strat) {
            case CV_GROUP:
                n_par = cross_validate(metrics, predict_file, output_file, &tm_fit, &tm_predict, fid_console);//SEQ
//                n_par = cross_validate(metrics, predict_file, output_file, &_tm_fit, &_tm_predict, fid_console);//PAR
                break;
            case CV_ITEM:
                n_par = cross_validate_item(metrics, predict_file, output_file, &tm_fit, &tm_predict, fid_console);//SEQ
//                n_par = cross_validate_item(metrics, predict_file, output_file, &_tm_fit, &_tm_predict, fid_console);//PAR
                break;
            case CV_NSTR:
                n_par = cross_validate_nstrat(metrics, predict_file, output_file, &tm_fit, &tm_predict, fid_console);//SEQ
//                n_par = cross_validate_nstrat(metrics, predict_file, output_file, &_tm_fit, &_tm_predict, fid_console);//PAR
                break;
            default:
                
                break;
        }

		printf("%d-fold cross-validation: LL=%15.7f (%15.7f), AIC=%8.6f, BIC=%8.6f, RMSE=%8.6f (%8.6f), Acc=%8.6f (%8.6f)\n",
			   task.cv_folds,
			   metrics[0], metrics[1], // ll's
			   2*n_par + 2*metrics[0], n_par*safelog(task.N) + 2*metrics[0],
			   metrics[2], metrics[3], // rmse's
			   metrics[4], metrics[5]); // acc's
		if(task.duplicate_console==1) fprintf(fid_console, "%d-fold cross-validation: LL=%15.7f (%15.7f), AIC=%8.6f, BIC=%8.6f, RMSE=%8.6f (%8.6f), Acc=%8.6f (%8.6f)\n",
											   task.cv_folds,
											   metrics[0], metrics[1], // ll's
											   2*n_par + 2*metrics[0], n_par*safelog(task.N) + 2*metrics[0],
											   metrics[2], metrics[3], // rmse's
											   metrics[4], metrics[5]); // acc's
		
		
        free(metrics);
    }
	// free data
	destroy_input_data(&task);
	
//	if(task.quiet == 0) {
        printf("timing: overall %f seconds, read %f, fit %f, predict %f\n",(NUMBER)((clock()-tm_all)/CLOCKS_PER_SEC), (NUMBER)tm_read/CLOCKS_PER_SEC,  (NUMBER)tm_fit/CLOCKS_PER_SEC,  (NUMBER)tm_predict/CLOCKS_PER_SEC);//SEQ
        if(task.duplicate_console==1) fprintf(fid_console, "timing: overall %f seconds, read %f, fit %f, predict %f\n",(NUMBER)((clock()-tm_all)/CLOCKS_PER_SEC), (NUMBER)tm_read/CLOCKS_PER_SEC,  (NUMBER)tm_fit/CLOCKS_PER_SEC,  (NUMBER)tm_predict/CLOCKS_PER_SEC);//SEQ
//        if(task.duplicate_console==1) fprintf(fid_console, "timing: overall %lf sec, read %lf sec, fit %lf sec, predict %lf sec\n",omp_get_wtime()-_tm_all, _tm_read, _tm_fit, _tm_predict);//PAR
//        printf("timing: overall %lf sec, read %lf sec, fit %lf sec, predict %lf sec\n",omp_get_wtime()-_tm_all, _tm_read, _tm_fit, _tm_predict);//PAR
//    }
    
    if(task.duplicate_console==1)
        fclose(fid_console);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1058, %rsp           # imm = 0x1058
movq %rsi, %r13
movl %edi, %ebp
callq 0x3130
movq %rax, %rbx
leaq 0x18857(%rip), %rdi     # 0x1d258
callq 0xab99
leaq 0xc50(%rsp), %rdx
leaq 0x450(%rsp), %rcx
leaq 0x50(%rsp), %r8
leaq 0x850(%rsp), %r9
movl %ebp, %edi
movq %r13, %rsi
callq 0x5105
cmpb $0x1, 0x18868(%rip)     # 0x1d29c
jne 0x4a4f
leaq 0x10703(%rip), %rsi     # 0x15140
leaq 0x850(%rsp), %rdi
callq 0x3260
movq %rax, %r14
jmp 0x4a52
xorl %r14d, %r14d
movq %rbx, 0x48(%rsp)
cmpb $0x0, 0x18846(%rip)     # 0x1d2a4
jne 0x4a8e
leaq 0x11334(%rip), %rdi     # 0x15d9b
callq 0x3320
cmpb $0x1, 0x18829(%rip)     # 0x1d29c
jne 0x4a8e
leaq 0x106c6(%rip), %rdi     # 0x15142
movl $0x17, %esi
movl $0x1, %edx
movq %r14, %rcx
callq 0x3400
callq 0x3130
movq %rax, %r12
leaq 0xc50(%rsp), %rdi
callq 0x580a
movl %eax, %ebx
callq 0x3130
testb %bl, %bl
je 0x50c7
movq %rax, %r15
movl %ebp, %edi
movq %r13, %rsi
movq %r14, %rdx
callq 0x58b2
cmpb $0x0, 0x187db(%rip)     # 0x1d2a4
jne 0x4b3a
movsbl 0x19087(%rip), %esi     # 0x1db59
movl 0x19084(%rip), %edx     # 0x1db5c
movl 0x19082(%rip), %ecx     # 0x1db60
movl 0x1907f(%rip), %r8d     # 0x1db64
movsbl 0x1907b(%rip), %r9d     # 0x1db68
leaq 0x10666(%rip), %rdi     # 0x1515a
xorl %eax, %eax
callq 0x3050
cmpb $0x1, 0x1879a(%rip)     # 0x1d29c
jne 0x4b3a
movsbl 0x1904e(%rip), %edx     # 0x1db59
movl 0x1904b(%rip), %ecx     # 0x1db5c
movl 0x19048(%rip), %r8d     # 0x1db60
movl 0x19045(%rip), %r9d     # 0x1db64
movsbl 0x19042(%rip), %eax     # 0x1db68
movl %eax, (%rsp)
leaq 0x1062a(%rip), %rsi     # 0x1515a
movq %r14, %rdi
xorl %eax, %eax
callq 0x32e0
xorl %eax, %eax
movq %rax, 0x38(%rsp)
movq %rax, 0x30(%rsp)
cmpb $0x0, 0x18b87(%rip)     # 0x1d6d4
je 0x4bae
movl $0x7, %edi
movl $0x8, %esi
callq 0x3120
movq %rax, %r13
movzbl 0x18b6d(%rip), %eax     # 0x1d6d5
cmpl $0x6e, %eax
je 0x4e64
cmpl $0x69, %eax
je 0x4e40
xorpd %xmm0, %xmm0
cmpl $0x67, %eax
jne 0x4e86
leaq 0x50(%rsp), %rsi
leaq 0x450(%rsp), %rdx
leaq 0x38(%rsp), %rcx
leaq 0x30(%rsp), %r8
movq %r13, %rdi
movq %r14, %r9
callq 0x6315
jmp 0x4e86
movzbl 0x186f1(%rip), %eax     # 0x1d2a6
cmpl $0xe, %eax
je 0x4be1
cmpl $0x1, %eax
jne 0x50db
movl $0xd0, %edi
callq 0x31f0
movq %rax, %r13
leaq 0x18681(%rip), %rsi     # 0x1d258
movq %rax, %rdi
callq 0xe950
jmp 0x4bfd
movl $0x110, %edi            # imm = 0x110
callq 0x31f0
movq %rax, %r13
leaq 0x18663(%rip), %rsi     # 0x1d258
movq %rax, %rdi
callq 0x1485a
movq %r13, 0x28(%rsp)
callq 0x3130
movq %rax, %rbx
movq (%r13), %rax
movq %r13, %rdi
callq *0x48(%rax)
callq 0x3130
subq %rbx, %rax
movq %rax, 0x38(%rsp)
movq (%r13), %rax
leaq 0x450(%rsp), %rsi
movq %r13, %rdi
callq *0x40(%rax)
cmpl $0x0, 0x18686(%rip)     # 0x1d2c0
jg 0x4c49
cmpl $0x0, 0x18685(%rip)     # 0x1d2c8
jle 0x4e31
movl $0x8, %edi
movl $0x8, %esi
callq 0x3120
movq %rax, %r13
callq 0x3130
movq %rax, %rbx
leaq 0x185ee(%rip), %rdx     # 0x1d258
leaq 0x50(%rsp), %rsi
leaq 0x28(%rsp), %rcx
movq %r13, %rdi
movl $0x1, %r8d
xorl %r9d, %r9d
callq 0x11afe
callq 0x3130
subq %rbx, %rax
movq %rax, 0x30(%rsp)
cmpl $0x0, 0x18627(%rip)     # 0x1d2c0
jle 0x4e1b
movsd (%r13), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x8(%r13), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x28(%rsp), %rdi
callq 0x120bc
addl %eax, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd (%r13), %xmm1
addsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movq 0x28(%rsp), %rdi
callq 0x120bc
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x20(%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl 0x18e50(%rip), %xmm0 # 0x1db50
callq 0x9d8d
movsd (%r13), %xmm1
movsd 0x10(%r13), %xmm4
addsd %xmm1, %xmm1
movsd 0x20(%rsp), %xmm3
mulsd %xmm0, %xmm3
addsd %xmm1, %xmm3
movsd 0x18(%r13), %xmm5
movsd 0x20(%r13), %xmm6
movsd 0x28(%r13), %xmm7
leaq 0x10476(%rip), %rdi     # 0x151b2
movsd 0x18(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
movsd 0x8(%rsp), %xmm2
movb $0x8, %al
callq 0x3050
cmpb $0x1, 0x18540(%rip)     # 0x1d29c
jne 0x4e1b
movsd (%r13), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x8(%r13), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x28(%rsp), %rdi
callq 0x120bc
addl %eax, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd (%r13), %xmm1
addsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movq 0x28(%rsp), %rdi
callq 0x120bc
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x20(%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl 0x18d8d(%rip), %xmm0 # 0x1db50
callq 0x9d8d
movsd (%r13), %xmm1
movsd 0x10(%r13), %xmm4
addsd %xmm1, %xmm1
movsd 0x20(%rsp), %xmm3
mulsd %xmm0, %xmm3
addsd %xmm1, %xmm3
movsd 0x18(%r13), %xmm5
movsd 0x20(%r13), %xmm6
movsd 0x28(%r13), %xmm7
leaq 0x103b3(%rip), %rsi     # 0x151b2
movq %r14, %rdi
movsd 0x18(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
movsd 0x8(%rsp), %xmm2
movb $0x8, %al
callq 0x32e0
movq %r13, %rdi
callq 0x3270
movq 0x28(%rsp), %r13
testq %r13, %r13
je 0x4fda
movq (%r13), %rax
movq %r13, %rdi
callq *0x8(%rax)
jmp 0x4fda
leaq 0x50(%rsp), %rsi
leaq 0x450(%rsp), %rdx
leaq 0x38(%rsp), %rcx
leaq 0x30(%rsp), %r8
movq %r13, %rdi
movq %r14, %r9
callq 0x6885
jmp 0x4e86
leaq 0x50(%rsp), %rsi
leaq 0x450(%rsp), %rdx
leaq 0x38(%rsp), %rcx
leaq 0x30(%rsp), %r8
movq %r13, %rdi
movq %r14, %r9
callq 0x6dce
movsd %xmm0, 0x18(%rsp)
movsbl 0x18841(%rip), %ebx     # 0x1d6d4
movsd (%r13), %xmm1
movsd %xmm1, 0x20(%rsp)
movsd 0x8(%r13), %xmm2
movsd %xmm2, 0x8(%rsp)
movapd %xmm1, %xmm2
addsd %xmm1, %xmm2
movapd %xmm0, %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
addsd %xmm1, %xmm2
movsd %xmm2, 0x40(%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl 0x18c7a(%rip), %xmm0 # 0x1db50
callq 0x9d8d
movsd (%r13), %xmm3
movsd 0x10(%r13), %xmm4
addsd %xmm3, %xmm3
mulsd 0x18(%rsp), %xmm0
addsd %xmm0, %xmm3
movsd 0x18(%r13), %xmm5
movsd 0x20(%r13), %xmm6
movsd 0x28(%r13), %xmm7
leaq 0x10303(%rip), %rdi     # 0x15211
movl %ebx, %esi
movsd 0x20(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
movsd 0x40(%rsp), %xmm2
movb $0x8, %al
callq 0x3050
cmpb $0x1, 0x1836c(%rip)     # 0x1d29c
jne 0x4fd2
movsbl 0x18797(%rip), %ebx     # 0x1d6d4
movsd (%r13), %xmm1
movsd %xmm1, 0x20(%rsp)
movsd 0x8(%r13), %xmm0
movsd %xmm0, 0x8(%rsp)
movapd %xmm1, %xmm0
addsd %xmm1, %xmm0
movsd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl 0x18bd8(%rip), %xmm0 # 0x1db50
callq 0x9d8d
movsd (%r13), %xmm1
movsd 0x10(%r13), %xmm4
addsd %xmm1, %xmm1
movsd 0x18(%rsp), %xmm3
mulsd %xmm0, %xmm3
addsd %xmm1, %xmm3
movsd 0x18(%r13), %xmm5
movsd 0x20(%r13), %xmm6
movsd 0x28(%r13), %xmm7
leaq 0x1025d(%rip), %rsi     # 0x15211
movq %r14, %rdi
movl %ebx, %edx
movsd 0x20(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
movsd 0x10(%rsp), %xmm2
movb $0x8, %al
callq 0x32e0
movq %r13, %rdi
callq 0x3270
subq %r12, %r15
leaq 0x18274(%rip), %rdi     # 0x1d258
callq 0xada0
callq 0x3130
movq 0x48(%rsp), %r12
subq %r12, %rax
movabsq $0x431bde82d7b634db, %rbx # imm = 0x431BDE82D7B634DB
imulq %rbx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x12, %rdx
addq %rax, %rdx
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %r15, %xmm1
movsd 0xffdf(%rip), %xmm4     # 0x15008
divsd %xmm4, %xmm1
xorps %xmm2, %xmm2
cvtsi2sdq 0x38(%rsp), %xmm2
divsd %xmm4, %xmm2
xorps %xmm3, %xmm3
cvtsi2sdq 0x30(%rsp), %xmm3
divsd %xmm4, %xmm3
leaq 0x1022c(%rip), %rdi     # 0x1527c
movsd %xmm1, 0x18(%rsp)
movsd %xmm2, 0x10(%rsp)
movsd %xmm3, 0x8(%rsp)
movb $0x4, %al
callq 0x3050
cmpb $0x1, 0x1822c(%rip)     # 0x1d29c
jne 0x50c7
callq 0x3130
subq %r12, %rax
imulq %rbx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x12, %rdx
addq %rax, %rdx
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
leaq 0x101e2(%rip), %rsi     # 0x1527c
movq %r14, %rdi
movsd 0x18(%rsp), %xmm1
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm3
movb $0x4, %al
callq 0x32e0
cmpb $0x1, 0x181df(%rip)     # 0x1d29c
jne 0x50c7
movq %r14, %rdi
callq 0x31e0
xorl %eax, %eax
addq $0x1058, %rsp           # imm = 0x1058
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzbl %al, %edi
callq 0x3420
movq %rax, %rbx
movl $0x110, %esi            # imm = 0x110
jmp 0x50f5
movq %rax, %rbx
movl $0xd0, %esi
movq %r13, %rdi
callq 0x3200
movq %rbx, %rdi
callq 0x33a0