// File: cjlin1[P]liblinear/linear.cpp
// Function: find_parameter_C(problem const*, parameter*, double, double, double*, double*, int const*, int const*, problem const*, int)
static void find_parameter_C(const problem *prob, parameter *param_tmp, double start_C, double max_C, double *best_C, double *best_score, const int *fold_start, const int *perm, const problem *subprob, int nr_fold)
{
	// variables for CV
	int i;
	double *target = Malloc(double, prob->l);

	// variables for warm start
	double ratio = 2;
	double **prev_w = Malloc(double*, nr_fold);
	for(i = 0; i < nr_fold; i++)
		prev_w[i] = NULL;
	int num_unchanged_w = 0;
	void (*default_print_string) (const char *) = liblinear_print_string;

	if(param_tmp->solver_type == L2R_LR || param_tmp->solver_type == L2R_L2LOSS_SVC)
		*best_score = 0.0;
	else if(param_tmp->solver_type == L2R_L2LOSS_SVR)
		*best_score = INF;
	*best_C = start_C;

	param_tmp->C = start_C;
	while(param_tmp->C <= max_C)
	{
		//Output disabled for running CV at a particular C
		set_print_string_function(&print_null);

		for(i=0; i<nr_fold; i++)
		{
			int j;
			int begin = fold_start[i];
			int end = fold_start[i+1];

			param_tmp->init_sol = prev_w[i];
			struct model *submodel = train(&subprob[i],param_tmp);

			int total_w_size;
			if(submodel->nr_class == 2)
				total_w_size = subprob[i].n;
			else
				total_w_size = subprob[i].n * submodel->nr_class;

			if(prev_w[i] == NULL)
			{
				prev_w[i] = Malloc(double, total_w_size);
				for(j=0; j<total_w_size; j++)
					prev_w[i][j] = submodel->w[j];
			}
			else if(num_unchanged_w >= 0)
			{
				double norm_w_diff = 0;
				for(j=0; j<total_w_size; j++)
				{
					norm_w_diff += (submodel->w[j] - prev_w[i][j])*(submodel->w[j] - prev_w[i][j]);
					prev_w[i][j] = submodel->w[j];
				}
				norm_w_diff = sqrt(norm_w_diff);

				if(norm_w_diff > 1e-15)
					num_unchanged_w = -1;
			}
			else
			{
				for(j=0; j<total_w_size; j++)
					prev_w[i][j] = submodel->w[j];
			}

			for(j=begin; j<end; j++)
				target[perm[j]] = predict(submodel,prob->x[perm[j]]);

			free_and_destroy_model(&submodel);
		}
		set_print_string_function(default_print_string);

		if(param_tmp->solver_type == L2R_LR || param_tmp->solver_type == L2R_L2LOSS_SVC)
		{
			int total_correct = 0;
			for(i=0; i<prob->l; i++)
				if(target[i] == prob->y[i])
					++total_correct;
			double current_rate = (double)total_correct/prob->l;
			if(current_rate > *best_score)
			{
				*best_C = param_tmp->C;
				*best_score = current_rate;
			}

			info("log2c=%7.2f\trate=%g\n",log(param_tmp->C)/log(2.0),100.0*current_rate);
		}
		else if(param_tmp->solver_type == L2R_L2LOSS_SVR)
		{
			double total_error = 0.0;
			for(i=0; i<prob->l; i++)
			{
				double y = prob->y[i];
				double v = target[i];
				total_error += (v-y)*(v-y);
			}
			double current_error = total_error/prob->l;
			if(current_error < *best_score)
			{
				*best_C = param_tmp->C;
				*best_score = current_error;
			}

			info("log2c=%7.2f\tp=%7.2f\tMean squared error=%g\n",log(param_tmp->C)/log(2.0),param_tmp->p,current_error);
		}

		num_unchanged_w++;
		if(num_unchanged_w == 5)
			break;
		param_tmp->C = param_tmp->C*ratio;
	}

	if(param_tmp->C > max_C)
		info("WARNING: maximum C reached.\n");
	free(target);
	for(i=0; i<nr_fold; i++)
		free(prev_w[i]);
	free(prev_w);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movl 0x18(%rbp), %eax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movsd %xmm0, -0x18(%rbp)
movsd %xmm1, -0x20(%rbp)
movq %rdx, -0x28(%rbp)
movq %rcx, -0x30(%rbp)
movq %r8, -0x38(%rbp)
movq %r9, -0x40(%rbp)
movq -0x8(%rbp), %rax
movslq (%rax), %rdi
shlq $0x3, %rdi
callq 0x21c0
movq %rax, -0x50(%rbp)
movsd 0x88c0(%rip), %xmm0     # 0x12df0
movsd %xmm0, -0x58(%rbp)
movslq 0x18(%rbp), %rdi
shlq $0x3, %rdi
callq 0x21c0
movq %rax, -0x60(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl 0x18(%rbp), %eax
jge 0xa570
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xa54d
movl $0x0, -0x64(%rbp)
movq 0xbcba(%rip), %rax      # 0x16238
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa594
movq -0x10(%rbp), %rax
cmpl $0x2, (%rax)
jne 0xa5a1
movq -0x30(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
jmp 0xa5bc
movq -0x10(%rbp), %rax
cmpl $0xb, (%rax)
jne 0xa5ba
movq -0x30(%rbp), %rax
movsd 0x7a5a(%rip), %xmm0     # 0x12010
movsd %xmm0, (%rax)
jmp 0xa5bc
movsd -0x18(%rbp), %xmm0
movq -0x28(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0x18(%rbp), %xmm0
movq -0x10(%rbp), %rax
movsd %xmm0, 0x10(%rax)
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm1
movsd -0x20(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jb 0xab66
leaq 0x6efa(%rip), %rdi      # 0x114f0
callq 0xc130
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl 0x18(%rbp), %eax
jge 0xa8db
movq -0x38(%rbp), %rax
movslq -0x44(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x78(%rbp)
movq -0x38(%rbp), %rax
movl -0x44(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x7c(%rbp)
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x40(%rax)
movq 0x10(%rbp), %rdi
movslq -0x44(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
movq -0x10(%rbp), %rsi
callq 0x7200
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpl $0x2, 0x50(%rax)
jne 0xa689
movq 0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x8c(%rbp)
jmp 0xa6ac
movq 0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movq -0x88(%rbp), %rcx
imull 0x50(%rcx), %eax
movl %eax, -0x8c(%rbp)
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0xa725
movslq -0x8c(%rbp), %rdi
shlq $0x3, %rdi
callq 0x21c0
movq %rax, %rdx
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
cmpl -0x8c(%rbp), %eax
jge 0xa720
movq -0x88(%rbp), %rax
movq 0x58(%rax), %rax
movslq -0x74(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x74(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0xa6e1
jmp 0xa86f
cmpl $0x0, -0x64(%rbp)
jl 0xa825
xorps %xmm0, %xmm0
movsd %xmm0, -0x98(%rbp)
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
cmpl -0x8c(%rbp), %eax
jge 0xa7f1
movq -0x88(%rbp), %rax
movq 0x58(%rax), %rax
movslq -0x74(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x74(%rbp), %rcx
subsd (%rax,%rcx,8), %xmm0
movq -0x88(%rbp), %rax
movq 0x58(%rax), %rax
movslq -0x74(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm2
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x74(%rbp), %rcx
subsd (%rax,%rcx,8), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movq 0x58(%rax), %rax
movslq -0x74(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x74(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0xa741
movsd -0x98(%rbp), %xmm0
callq 0x20d0
movsd %xmm0, -0x98(%rbp)
movsd -0x98(%rbp), %xmm0
movsd 0x8612(%rip), %xmm1     # 0x12e28
ucomisd %xmm1, %xmm0
jbe 0xa823
movl $0xffffffff, -0x64(%rbp) # imm = 0xFFFFFFFF
jmp 0xa86d
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
cmpl -0x8c(%rbp), %eax
jge 0xa86b
movq -0x88(%rbp), %rax
movq 0x58(%rax), %rax
movslq -0x74(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x74(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0xa82c
jmp 0xa86d
jmp 0xa86f
movl -0x78(%rbp), %eax
movl %eax, -0x74(%rbp)
movl -0x74(%rbp), %eax
cmpl -0x7c(%rbp), %eax
jge 0xa8c1
movq -0x88(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x40(%rbp), %rcx
movslq -0x74(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x9b50
movq -0x50(%rbp), %rax
movq -0x40(%rbp), %rcx
movslq -0x74(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0xa875
leaq -0x88(%rbp), %rdi
callq 0x9ba0
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xa602
movq -0x70(%rbp), %rdi
callq 0xc130
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0xa8fa
movq -0x10(%rbp), %rax
cmpl $0x2, (%rax)
jne 0xa9f8
movl $0x0, -0x9c(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl (%rcx), %eax
jge 0xa954
movq -0x50(%rbp), %rax
movslq -0x44(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x44(%rbp), %rcx
ucomisd (%rax,%rcx,8), %xmm0
jne 0xa947
jp 0xa947
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0xa949
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xa90b
cvtsi2sdl -0x9c(%rbp), %xmm0
movq -0x8(%rbp), %rax
cvtsi2sdl (%rax), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xa8(%rbp)
movsd -0xa8(%rbp), %xmm0
movq -0x30(%rbp), %rax
ucomisd (%rax), %xmm0
jbe 0xa9a3
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm0
movq -0x28(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0xa8(%rbp), %xmm0
movq -0x30(%rbp), %rax
movsd %xmm0, (%rax)
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm0
callq 0x20e0
movsd %xmm0, -0xd0(%rbp)
movsd 0x842f(%rip), %xmm0     # 0x12df0
callq 0x20e0
movaps %xmm0, %xmm1
movsd -0xd0(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd 0x7663(%rip), %xmm1     # 0x12040
mulsd -0xa8(%rbp), %xmm1
leaq 0x8b95(%rip), %rdi      # 0x13581
movb $0x2, %al
callq 0x7120
jmp 0xab39
movq -0x10(%rbp), %rax
cmpl $0xb, (%rax)
jne 0xab37
xorps %xmm0, %xmm0
movsd %xmm0, -0xb0(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl (%rcx), %eax
jge 0xaa93
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x44(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0xb8(%rbp)
movq -0x50(%rbp), %rax
movslq -0x44(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0xc0(%rbp)
movsd -0xc0(%rbp), %xmm0
subsd -0xb8(%rbp), %xmm0
movsd -0xc0(%rbp), %xmm2
subsd -0xb8(%rbp), %xmm2
movsd -0xb0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xb0(%rbp)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xaa17
movsd -0xb0(%rbp), %xmm0
movq -0x8(%rbp), %rax
cvtsi2sdl (%rax), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xc8(%rbp)
movsd -0xc8(%rbp), %xmm1
movq -0x30(%rbp), %rax
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xaae6
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm0
movq -0x28(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0xc8(%rbp), %xmm0
movq -0x30(%rbp), %rax
movsd %xmm0, (%rax)
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm0
callq 0x20e0
movsd %xmm0, -0xd8(%rbp)
movsd 0x82ec(%rip), %xmm0     # 0x12df0
callq 0x20e0
movaps %xmm0, %xmm1
movsd -0xd8(%rbp), %xmm0
divsd %xmm1, %xmm0
movq -0x10(%rbp), %rax
movsd 0x30(%rax), %xmm1
movsd -0xc8(%rbp), %xmm2
leaq 0x8a66(%rip), %rdi      # 0x13596
movb $0x3, %al
callq 0x7120
jmp 0xab39
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
cmpl $0x5, -0x64(%rbp)
jne 0xab4a
jmp 0xab66
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm0
mulsd -0x58(%rbp), %xmm0
movq -0x10(%rbp), %rax
movsd %xmm0, 0x10(%rax)
jmp 0xa5d7
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm0
ucomisd -0x20(%rbp), %xmm0
jbe 0xab84
leaq 0x8a44(%rip), %rdi      # 0x135c1
movb $0x0, %al
callq 0x7120
movq -0x50(%rbp), %rdi
callq 0x2180
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl 0x18(%rbp), %eax
jge 0xabb8
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2180
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xab94
movq -0x60(%rbp), %rdi
callq 0x2180
addq $0xe0, %rsp
popq %rbp
retq
nopw (%rax,%rax)