// File: qmmlib[P]QmmLibrary/train.c
// Function: parse_command_line(int, char**, char*, char*)
void parse_command_line(int argc, char **argv, char *input_file_name, char *model_file_name)
{
	int i;
	void (*print_func)(const char*) = NULL;	// default printing to stdout

	// default values
	param.solver_type = MMCD;
	param.C = 1;
	param.eps = INF; // see setting below
	param.p = 0.1;
	param.nr_weight = 0;
	param.weight_label = NULL;
	param.weight = NULL;
	flag_cross_validation = 0;
	bias = -1;
	param.reg_param   = 1; // L2 regularizer
	param.loss_param  = 0.5; // tau for HU1, HU2
	param.curv_param  = 1e-3; // epsilon for minimum curvature value for NC
	param.loss_type   = HU2; // Huberized-hinge loss
	param.curv_type   = OC; // optimal curv
	param.turn_to_nc  = 0;
	param.save_each_iter = 0;
	param.init_model_file = NULL;
	param.chat_level = 0; // minimal talk
	param.cg_tol = 0.001;
	param.cd_tol = 0.01;
	param.cd_reset = 10;
	param.structured_w = 0;
	param.transform_matrix = 0;
	param.tmx_c = 0;
	param.tmx_r = 0;
	
	// parse options
	for(i=1;i<argc;i++)
	{
		if(argv[i][0] != '-') break;
		if(++i>=argc)
			exit_with_help();
		switch(argv[i-1][1])
		{
			case 's':
				param.solver_type = atoi(argv[i]);
				break;

			case 'c':
				param.C = atof(argv[i]);
				break;

			case 'p':
				param.p = atof(argv[i]);
				break;

			case 'e':
				param.eps = atof(argv[i]);
				break;

			case 'B':
				bias = atof(argv[i]);
				break;

			case 'w':
				++param.nr_weight;
				param.weight_label = (int *) realloc(param.weight_label,sizeof(int)*param.nr_weight);
				param.weight = (double *) realloc(param.weight,sizeof(double)*param.nr_weight);
				param.weight_label[param.nr_weight-1] = atoi(&argv[i-1][2]);
				param.weight[param.nr_weight-1] = atof(argv[i]);
				break;

			case 'v':
				flag_cross_validation = 1;
				nr_fold = atoi(argv[i]);
				if(nr_fold < 2)
				{
					fprintf(stderr,"n-fold cross validation: n must >= 2\n");
					exit_with_help();
				}
				break;

			case 'q':
				print_func = &print_null;
				i--;
				break;

			case 'l':
				param.loss_type = (loss_var) atoi(argv[i]);
				break;

			case 'u':
				if(atoi(argv[i]) < 3)
				{
					param.curv_type = (curv_var) atoi(argv[i]);
					param.turn_to_nc = 0;
				}
				else if(atoi(argv[i]) == 3)
				{
					param.curv_type = (curv_var) 0;
					param.turn_to_nc = 1;
				}
				else if(atoi(argv[i]) == 4)
				{
					param.curv_type = (curv_var) 1;
					param.turn_to_nc = 1;
				}		
				break;
				
			case 'r':
				param.reg_param = atof(argv[i]);
				break;

			case 'd':
				param.cd_tol = atof(argv[i]);
				break;

			case 'f':
				param.cd_reset = atoi(argv[i]);
				break;

			case 'g':
				param.cg_tol = atof(argv[i]);
				break;

			case 'x':
				param.test_file = Malloc(char,1024);
				strcpy(param.test_file, argv[i]);
				break;

			case 't':
				param.loss_param = atof(argv[i]);
				break;

			case 'n':
				param.curv_param = atof(argv[i]);
				break;

			case 'i':
				param.init_model_file = Malloc(char,1024);
				strcpy(param.init_model_file, argv[i]);
				break;

			case 'h':
				param.chat_level = atoi(argv[i]);
				break;

			case 'S': 
				if(strcmp(argv[i],"s")==0 || strcmp(argv[i],"a")==0)
				{
					param.structured_w = argv[i][0];
					printf("\nUsing symmetric or asymmetric matrix as %c\n",param.structured_w);
				}
				else
				{
					param.transform_matrix = read_transform_matrix(argv[i],param.tmx_r,param.tmx_c);
					param.structured_w = 'f';
					printf("\nUsing free transform matrix %s\n",argv[i]);
				}
				break;

			case 'X':
				param.save_each_iter = Malloc(char,1024);
				strcpy(param.save_each_iter, argv[i]);
				break;

			default:
				fprintf(stderr,"unknown option: -%c\n", argv[i-1][1]);
				exit_with_help();
				break;
		}
	}

	set_print_string_function(print_func);

	// determine filenames
	if(i>=argc)
		exit_with_help();

	strcpy(input_file_name, argv[i]);

	if(i<argc-1)
		strcpy(model_file_name,argv[i+1]);
	else
	{
		char *p = strrchr(argv[i],'/');
		if(p==NULL)
			p = argv[i];
		else
			++p;
		sprintf(model_file_name,"%s.model",p);
	}

	if(param.eps == INF)
	{
		switch(param.solver_type)
		{
			case L2R_LR: 
			case L2R_L2LOSS_SVC:
				param.eps = 0.01;
				break;
			case L2R_L2LOSS_SVR:
				param.eps = 0.001;
				break;
			case L2R_L2LOSS_SVC_DUAL: 
			case L2R_L1LOSS_SVC_DUAL: 
			case MCSVM_CS: 
			case L2R_LR_DUAL: 
				param.eps = 0.1;
				break;
			case L1R_L2LOSS_SVC: 
			case L1R_LR:
				param.eps = 0.01;
				break;
			case L2R_L1LOSS_SVR_DUAL:
			case L2R_L2LOSS_SVR_DUAL:
				param.eps = 0.1;
				break;
		}
		
		if(param.solver_type == MMCD ||param.solver_type == MMCD_SM || param.solver_type == MMCD_SG || param.solver_type == MMCD_SIMPLE || param.solver_type == MMGCD || param.solver_type == MMCG )
			param.eps = 0.01;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq $0x0, -0x30(%rbp)
movl $0x32, 0x27bdf(%rip)    # 0x2b4a8
movsd 0x20757(%rip), %xmm0    # 0x24028
movsd %xmm0, 0x27c57(%rip)    # 0x2b530
movsd 0x2075f(%rip), %xmm0    # 0x24040
movsd %xmm0, 0x27c3f(%rip)    # 0x2b528
movsd 0x20747(%rip), %xmm0    # 0x24038
movsd %xmm0, 0x27c57(%rip)    # 0x2b550
movl $0x0, 0x27c35(%rip)     # 0x2b538
movq $0x0, 0x27c32(%rip) # 0x2b540
movq $0x0, 0x27c2f(%rip) # 0x2b548
movl $0x0, 0x27c65(%rip)     # 0x2b588
movsd 0x20705(%rip), %xmm0    # 0x24030
movsd %xmm0, 0x27c5d(%rip)    # 0x2b590
movsd 0x206ed(%rip), %xmm0    # 0x24028
movsd %xmm0, 0x27b85(%rip)    # 0x2b4c8
movsd 0x206d5(%rip), %xmm0    # 0x24020
movsd %xmm0, 0x27b5d(%rip)    # 0x2b4b0
movsd 0x206bd(%rip), %xmm0    # 0x24018
movsd %xmm0, 0x27b5d(%rip)    # 0x2b4c0
movl $0x4, 0x27b3f(%rip)     # 0x2b4ac
movl $0x1, 0x27b41(%rip)     # 0x2b4b8
movl $0x0, 0x27b6b(%rip)     # 0x2b4ec
movq $0x0, 0x27b64(%rip) # 0x2b4f0
movq $0x0, 0x27b39(%rip) # 0x2b4d0
movl $0x0, 0x27b47(%rip)     # 0x2b4e8
movsd 0x2066f(%rip), %xmm0    # 0x24018
movsd %xmm0, 0x27b57(%rip)    # 0x2b508
movsd 0x20657(%rip), %xmm0    # 0x24010
movsd %xmm0, 0x27b37(%rip)    # 0x2b4f8
movl $0xa, 0x27b35(%rip)     # 0x2b500
movb $0x0, 0x27b42(%rip)     # 0x2b514
movq $0x0, 0x27b3b(%rip) # 0x2b518
movl $0x0, 0x27b3d(%rip)     # 0x2b524
movl $0x0, 0x27b2f(%rip)     # 0x2b520
movl $0x1, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x4(%rbp), %eax
jge 0x3f0b
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0x3a1d
jmp 0x3f0b
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
cmpl -0x4(%rbp), %eax
jl 0x3a30
callq 0x36a0
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %eax
addl $-0x42, %eax
movl %eax, %ecx
movq %rcx, -0x40(%rbp)
subl $0x36, %eax
ja 0x3ec9
movq -0x40(%rbp), %rax
leaq 0x205ef(%rip), %rcx     # 0x24050
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
movl %eax, 0x27a27(%rip)     # 0x2b4a8
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x27a91(%rip)    # 0x2b530
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x27a93(%rip)    # 0x2b550
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x27a4d(%rip)    # 0x2b528
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x27a97(%rip)    # 0x2b590
jmp 0x3efb
movl 0x27a34(%rip), %eax     # 0x2b538
addl $0x1, %eax
movl %eax, 0x27a2b(%rip)     # 0x2b538
movq 0x27a2c(%rip), %rdi     # 0x2b540
movslq 0x27a1d(%rip), %rsi     # 0x2b538
shlq $0x2, %rsi
callq 0x3490
movq %rax, 0x27a15(%rip)     # 0x2b540
movq 0x27a16(%rip), %rdi     # 0x2b548
movslq 0x279ff(%rip), %rsi     # 0x2b538
shlq $0x3, %rsi
callq 0x3490
movq %rax, 0x279ff(%rip)     # 0x2b548
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
addq $0x2, %rdi
callq 0x3430
movl %eax, %edx
movq 0x279d4(%rip), %rax     # 0x2b540
movl 0x279c6(%rip), %ecx     # 0x2b538
subl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movq 0x279b5(%rip), %rax     # 0x2b548
movl 0x2799f(%rip), %ecx     # 0x2b538
subl $0x1, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x3efb
movl $0x1, 0x279d5(%rip)     # 0x2b588
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
movl %eax, 0x279c2(%rip)     # 0x2b58c
cmpl $0x2, 0x279bb(%rip)     # 0x2b58c
jge 0x3bf0
movq 0x273fe(%rip), %rax     # 0x2afd8
movq (%rax), %rdi
leaq 0x21392(%rip), %rsi     # 0x24f76
movb $0x0, %al
callq 0x3400
callq 0x36a0
jmp 0x3efb
leaq -0x56c(%rip), %rax      # 0x3690
movq %rax, -0x30(%rbp)
movl -0x24(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
movl %eax, 0x27887(%rip)     # 0x2b4ac
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
cmpl $0x3, %eax
jge 0x3c63
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
movl %eax, 0x27861(%rip)     # 0x2b4b8
movl $0x0, 0x2788b(%rip)     # 0x2b4ec
jmp 0x3cbd
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
cmpl $0x3, %eax
jne 0x3c8f
movl $0x0, 0x27835(%rip)     # 0x2b4b8
movl $0x1, 0x2785f(%rip)     # 0x2b4ec
jmp 0x3cbb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
cmpl $0x4, %eax
jne 0x3cb9
movl $0x1, 0x27809(%rip)     # 0x2b4b8
movl $0x1, 0x27833(%rip)     # 0x2b4ec
jmp 0x3cbb
jmp 0x3cbd
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x277ed(%rip)    # 0x2b4c8
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x277ff(%rip)    # 0x2b4f8
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
movl %eax, 0x277eb(%rip)     # 0x2b500
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x277d5(%rip)    # 0x2b508
jmp 0x3efb
movl $0x400, %edi            # imm = 0x400
callq 0x33d0
movq %rax, 0x2778f(%rip)     # 0x2b4d8
movq 0x27788(%rip), %rdi     # 0x2b4d8
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3280
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x27731(%rip)    # 0x2b4b0
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33a0
movsd %xmm0, 0x27723(%rip)    # 0x2b4c0
jmp 0x3efb
movl $0x400, %edi            # imm = 0x400
callq 0x33d0
movq %rax, 0x2771d(%rip)     # 0x2b4d0
movq 0x27716(%rip), %rdi     # 0x2b4d0
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3280
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3430
movl %eax, 0x27701(%rip)     # 0x2b4e8
jmp 0x3efb
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x2174e(%rip), %rsi     # 0x2554d
callq 0x33e0
cmpl $0x0, %eax
je 0x3e26
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x21180(%rip), %rsi     # 0x24f9c
callq 0x33e0
cmpl $0x0, %eax
jne 0x3e51
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb (%rax), %al
movb %al, 0x276da(%rip)      # 0x2b514
movsbl 0x276d3(%rip), %esi     # 0x2b514
leaq 0x21156(%rip), %rdi     # 0x24f9e
movb $0x0, %al
callq 0x3050
jmp 0x3e9c
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x27644(%rip), %rdx     # 0x2b4a8
movq %rdx, %rsi
addq $0x78, %rsi
addq $0x7c, %rdx
callq 0x4880
movq %rax, 0x2769d(%rip)     # 0x2b518
movb $0x66, 0x27692(%rip)    # 0x2b514
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x21136(%rip), %rdi     # 0x24fcb
movb $0x0, %al
callq 0x3050
jmp 0x3efb
movl $0x400, %edi            # imm = 0x400
callq 0x33d0
movq %rax, 0x27641(%rip)     # 0x2b4f0
movq 0x2763a(%rip), %rdi     # 0x2b4f0
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3280
jmp 0x3efb
movq 0x27108(%rip), %rax     # 0x2afd8
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %edx
leaq 0x210fd(%rip), %rsi     # 0x24fec
movb $0x0, %al
callq 0x3400
callq 0x36a0
jmp 0x3efd
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x39f8
movq -0x30(%rbp), %rdi
callq 0xf560
movl -0x24(%rbp), %eax
cmpl -0x4(%rbp), %eax
jl 0x3f21
callq 0x36a0
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3280
movl -0x24(%rbp), %eax
movl -0x4(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x3f5f
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3280
jmp 0x3fb4
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movl $0x2f, %esi
callq 0x3330
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x3f92
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x38(%rbp)
jmp 0x3f9e
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rdx
leaq 0x21054(%rip), %rsi     # 0x25001
movb $0x0, %al
callq 0x30a0
movsd 0x2756c(%rip), %xmm0    # 0x2b528
movsd 0x2007c(%rip), %xmm1    # 0x24040
ucomisd %xmm1, %xmm0
jne 0x4098
jp 0x4098
movl 0x274ce(%rip), %eax     # 0x2b4a8
movq %rax, -0x48(%rbp)
subq $0xd, %rax
ja 0x4050
movq -0x48(%rbp), %rax
leaq 0x2013d(%rip), %rcx     # 0x2412c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movsd 0x20010(%rip), %xmm0    # 0x24010
movsd %xmm0, 0x27520(%rip)    # 0x2b528
jmp 0x4050
movsd 0x20006(%rip), %xmm0    # 0x24018
movsd %xmm0, 0x2750e(%rip)    # 0x2b528
jmp 0x4050
movsd 0x20014(%rip), %xmm0    # 0x24038
movsd %xmm0, 0x274fc(%rip)    # 0x2b528
jmp 0x4050
movsd 0x1ffda(%rip), %xmm0    # 0x24010
movsd %xmm0, 0x274ea(%rip)    # 0x2b528
jmp 0x4050
movsd 0x1fff0(%rip), %xmm0    # 0x24038
movsd %xmm0, 0x274d8(%rip)    # 0x2b528
cmpl $0x32, 0x27451(%rip)    # 0x2b4a8
je 0x4086
cmpl $0x33, 0x27448(%rip)    # 0x2b4a8
je 0x4086
cmpl $0x34, 0x2743f(%rip)    # 0x2b4a8
je 0x4086
cmpl $0x35, 0x27436(%rip)    # 0x2b4a8
je 0x4086
cmpl $0x36, 0x2742d(%rip)    # 0x2b4a8
je 0x4086
cmpl $0x37, 0x27424(%rip)    # 0x2b4a8
jne 0x4096
movsd 0x1ff82(%rip), %xmm0    # 0x24010
movsd %xmm0, 0x27492(%rip)    # 0x2b528
jmp 0x4098
addq $0x50, %rsp
popq %rbp
retq
nop