// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %r9, %r15
movq %r8, 0x60(%rsp)
movq %rcx, 0x28(%rsp)
movq %rdx, 0x20(%rsp)
movsd %xmm1, 0x38(%rsp)
movsd %xmm0, (%rsp)
movq %rsi, 0x40(%rsp)
movslq 0xb8(%rsp), %rbx
movq 0xb0(%rsp), %rax
movq %rax, 0x50(%rsp)
movq %rdi, 0x10(%rsp)
movslq (%rdi), %rdi
shlq $0x3, %rdi
callq 0x21f0
movq %rax, %r14
movq %rbx, %rdi
shlq $0x3, %rdi
callq 0x21f0
movq %rax, %r13
xorl %eax, %eax
testl %ebx, %ebx
movl $0x0, %ecx
cmovgl %ebx, %ecx
movq %rcx, 0x30(%rsp)
cmpq %rax, 0x30(%rsp)
je 0x93fa
andq $0x0, (%r13,%rax,8)
incq %rax
jmp 0x93e8
movq 0x7d97(%rip), %rax      # 0x11198
movq 0x40(%rsp), %rbx
movl (%rbx), %ecx
xorpd %xmm0, %xmm0
testl %ecx, %ecx
je 0x9429
cmpl $0x2, %ecx
movsd (%rsp), %xmm1
je 0x942e
cmpl $0xb, %ecx
jne 0x9437
movsd 0x2c09(%rip), %xmm0     # 0xc030
jmp 0x942e
movsd (%rsp), %xmm1
movq 0x28(%rsp), %rcx
movsd %xmm0, (%rcx)
movq 0x20(%rsp), %rcx
movsd %xmm1, (%rcx)
testq %rax, %rax
leaq 0xf7a(%rip), %rcx       # 0xa3c4
cmovneq %rax, %rcx
movq %rcx, 0x58(%rsp)
movl $0x0, 0xc(%rsp)
movq %r13, 0x48(%rsp)
movq %r14, 0x18(%rsp)
movsd %xmm1, 0x10(%rbx)
movsd 0x38(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x979a
leaq 0x1fd8(%rip), %rax      # 0xb459
movq %rax, 0x7d10(%rip)      # 0x11198
xorl %ecx, %ecx
cmpq 0x30(%rsp), %rcx
je 0x962c
movq 0x60(%rsp), %rax
movslq (%rax,%rcx,4), %rbp
movslq 0x4(%rax,%rcx,4), %r12
movq (%r13,%rcx,8), %r13
movq %r13, 0x40(%rbx)
movq %rcx, %rax
shlq $0x5, %rax
movq %rax, 0x68(%rsp)
movq 0x50(%rsp), %rdx
leaq (%rdx,%rax), %rdi
movq %rcx, (%rsp)
movq %rbx, %rsi
callq 0x537c
movq %rax, %rbx
movl 0x50(%rax), %r14d
cmpl $0x2, %r14d
pushq $0x1
popq %rax
cmovel %eax, %r14d
movq %rbx, 0x70(%rsp)
movq 0x50(%rsp), %rax
movq 0x68(%rsp), %rcx
imull 0x4(%rax,%rcx), %r14d
testq %r13, %r13
je 0x9553
testl %r14d, %r14d
movl $0x0, %eax
cmovlel %eax, %r14d
cmpl $0x0, 0xc(%rsp)
js 0x9592
xorpd %xmm0, %xmm0
xorl %eax, %eax
cmpq %rax, %r14
je 0x9543
movq 0x58(%rbx), %rcx
movsd (%rcx,%rax,8), %xmm1
movapd %xmm1, %xmm2
subsd (%r13,%rax,8), %xmm2
mulsd %xmm2, %xmm2
addsd %xmm2, %xmm0
movsd %xmm1, (%r13,%rax,8)
incq %rax
jmp 0x9516
ucomisd 0x2aed(%rip), %xmm0     # 0xc038
jb 0x95b9
sqrtsd %xmm0, %xmm0
jmp 0x95be
movslq %r14d, %rdi
shlq $0x3, %rdi
callq 0x21f0
movq 0x48(%rsp), %rcx
movq (%rsp), %rsi
movq %rax, (%rcx,%rsi,8)
testl %r14d, %r14d
movl $0x0, %ecx
cmovlel %ecx, %r14d
xorl %ecx, %ecx
cmpq %rcx, %r14
je 0x95b2
movq 0x58(%rbx), %rdx
movsd (%rdx,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
incq %rcx
jmp 0x957a
xorl %eax, %eax
movq (%rsp), %rsi
cmpq %rax, %r14
je 0x95b2
movq 0x58(%rbx), %rcx
movsd (%rcx,%rax,8), %xmm0
movsd %xmm0, (%r13,%rax,8)
incq %rax
jmp 0x9598
movq 0x18(%rsp), %r14
jmp 0x95dd
callq 0x20d0
movq 0x18(%rsp), %r14
movq (%rsp), %rsi
ucomisd 0x3871(%rip), %xmm0     # 0xce40
pushq $-0x1
popq %rax
movl 0xc(%rsp), %ecx
cmoval %eax, %ecx
movl %ecx, 0xc(%rsp)
incq %rsi
movq %rsi, %r13
cmpq %r12, %rbp
jge 0x9610
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rax
movslq (%r15,%rbp,4), %rcx
movq (%rax,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x8d56
movslq (%r15,%rbp,4), %rax
movsd %xmm0, (%r14,%rax,8)
incq %rbp
jmp 0x95e3
leaq 0x70(%rsp), %rdi
callq 0x8da1
movq 0x40(%rsp), %rbx
movq %r13, %rcx
movq 0x48(%rsp), %r13
jmp 0x948a
movq 0x58(%rsp), %rax
movq %rax, 0x7b60(%rip)      # 0x11198
movl (%rbx), %eax
testl %eax, %eax
je 0x968d
cmpl $0x2, %eax
je 0x968d
cmpl $0xb, %eax
jne 0x977d
movq 0x10(%rsp), %rax
movl (%rax), %eax
testl %eax, %eax
movl $0x0, %ecx
cmovgl %eax, %ecx
xorpd %xmm1, %xmm1
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x9725
movq 0x10(%rsp), %rsi
movq 0x8(%rsi), %rsi
movsd (%r14,%rdx,8), %xmm0
subsd (%rsi,%rdx,8), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm0, %xmm1
incq %rdx
jmp 0x9663
movq 0x10(%rsp), %rax
movl (%rax), %eax
xorl %ecx, %ecx
testl %eax, %eax
movl $0x0, %edx
cmovgl %eax, %edx
xorl %esi, %esi
cmpq %rcx, %rdx
je 0x96c8
movq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rdi
movsd (%rdi,%rcx,8), %xmm0
cmpeqsd (%r14,%rcx,8), %xmm0
movq %xmm0, %rdi
subl %edi, %esi
incq %rcx
jmp 0x96a2
cvtsi2sd %esi, %xmm1
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movq 0x28(%rsp), %rax
ucomisd (%rax), %xmm1
movsd 0x10(%rbx), %xmm0
movsd %xmm1, (%rsp)
jbe 0x96fb
movq 0x20(%rsp), %rcx
movsd %xmm0, (%rcx)
movsd %xmm1, (%rax)
movsd 0x10(%rbx), %xmm0
callq 0x20e0
divsd 0x3730(%rip), %xmm0     # 0xce38
movsd (%rsp), %xmm1
mulsd 0x2933(%rip), %xmm1     # 0xc048
leaq 0x3eb1(%rip), %rdi      # 0xd5cd
movb $0x2, %al
callq 0x52d8
jmp 0x977d
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movq 0x28(%rsp), %rax
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
movsd 0x10(%rbx), %xmm0
movsd %xmm1, (%rsp)
jbe 0x9758
movq 0x20(%rsp), %rcx
movsd %xmm0, (%rcx)
movsd %xmm1, (%rax)
movsd 0x10(%rbx), %xmm0
callq 0x20e0
divsd 0x36d3(%rip), %xmm0     # 0xce38
movsd 0x30(%rbx), %xmm1
leaq 0x3e71(%rip), %rdi      # 0xd5e2
movsd (%rsp), %xmm2
movb $0x3, %al
callq 0x52d8
movl 0xc(%rsp), %eax
incl %eax
movsd 0x10(%rbx), %xmm1
movl %eax, 0xc(%rsp)
cmpl $0x5, %eax
je 0x979a
addsd %xmm1, %xmm1
jmp 0x9465
ucomisd 0x38(%rsp), %xmm1
jbe 0x97b0
leaq 0x3e64(%rip), %rdi      # 0xd60d
xorl %eax, %eax
callq 0x52d8
movq %r14, %rdi
callq 0x21a0
xorl %ebx, %ebx
cmpq %rbx, 0x30(%rsp)
je 0x97d0
movq (%r13,%rbx,8), %rdi
callq 0x21a0
incq %rbx
jmp 0x97ba
movq %r13, %rdi
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x21a0