// File: /workspace/github_cpp_makefile_star2_O1/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 $0x88, %rsp
movq %r9, 0x58(%rsp)
movq %r8, 0x78(%rsp)
movq %rcx, 0x18(%rsp)
movq %rdx, 0x28(%rsp)
movsd %xmm1, 0x30(%rsp)
movsd %xmm0, 0x8(%rsp)
movq %rsi, (%rsp)
movq %rdi, %r13
movslq 0xc8(%rsp), %rbx
movq 0xc0(%rsp), %rax
movq %rax, 0x70(%rsp)
movslq (%rdi), %rdi
shlq $0x3, %rdi
callq 0x21f0
movq %rax, %r12
leaq (,%rbx,8), %rdi
callq 0x21f0
movq %rax, %r14
movl %ebx, %r15d
movq %rbx, 0x48(%rsp)
testq %rbx, %rbx
jle 0xa13b
leaq (,%r15,8), %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x20c0
movq 0x8056(%rip), %rax      # 0x12198
movq (%rsp), %rcx
movl (%rcx), %ecx
xorps %xmm0, %xmm0
testl %ecx, %ecx
je 0xa161
cmpl $0x2, %ecx
je 0xa161
cmpl $0xb, %ecx
jne 0xa16a
movsd 0x2ea7(%rip), %xmm0     # 0xd008
movq 0x18(%rsp), %rcx
movsd %xmm0, (%rcx)
movq 0x28(%rsp), %rcx
movsd 0x8(%rsp), %xmm1
movsd %xmm1, (%rcx)
movq (%rsp), %rcx
movsd %xmm1, 0x10(%rcx)
movsd 0x30(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0xa53e
testq %rax, %rax
leaq 0x1093(%rip), %rcx      # 0xb22f
cmovneq %rax, %rcx
movq %rcx, 0x50(%rsp)
xorl %ebx, %ebx
movq %r14, 0x68(%rsp)
movq %r15, 0x60(%rsp)
movq %r13, 0x40(%rsp)
movq %r12, 0x38(%rsp)
movq %rbx, 0x20(%rsp)
leaq 0x214f(%rip), %rax      # 0xc316
movq %rax, 0x7fca(%rip)      # 0x12198
cmpl $0x0, 0x48(%rsp)
jle 0xa385
xorl %r12d, %r12d
movq 0x78(%rsp), %rax
movslq (%rax,%r12,4), %rcx
movq %rcx, 0x10(%rsp)
movl 0x4(%rax,%r12,4), %r15d
movq (%r14,%r12,8), %rbp
movq (%rsp), %rsi
movq %rbp, 0x40(%rsi)
movq %r12, %r13
shlq $0x5, %r13
movq 0x70(%rsp), %rbx
leaq (%rbx,%r13), %rdi
callq 0x5b58
movq %r14, %rdx
movq %rax, %r14
movq %rax, 0x80(%rsp)
movl 0x50(%rax), %eax
cmpl $0x2, %eax
movl $0x1, %ecx
cmovel %ecx, %eax
movslq 0x4(%rbx,%r13), %rcx
movslq %eax, %r13
imulq %rcx, %r13
testq %rbp, %rbp
movq %r12, 0x8(%rsp)
je 0xa288
movq 0x20(%rsp), %rbx
testl %ebx, %ebx
js 0xa2bd
testl %r13d, %r13d
jle 0xa2e5
movq 0x58(%r14), %rax
movl %r13d, %ecx
xorpd %xmm0, %xmm0
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm1
movapd %xmm1, %xmm2
subsd (%rbp,%rdx,8), %xmm2
mulsd %xmm2, %xmm2
addsd %xmm2, %xmm0
movsd %xmm1, (%rbp,%rdx,8)
incq %rdx
cmpq %rdx, %rcx
jne 0xa261
jmp 0xa2e9
movq %r13, %rdi
shlq $0x3, %rdi
movq %rdx, %rbx
callq 0x21f0
movq %rax, (%rbx,%r12,8)
testl %r13d, %r13d
jle 0xa2de
movq 0x58(%r14), %rcx
movl %r13d, %edx
xorl %esi, %esi
movsd (%rcx,%rsi,8), %xmm0
movsd %xmm0, (%rax,%rsi,8)
incq %rsi
cmpq %rsi, %rdx
jne 0xa2a9
jmp 0xa2de
testl %r13d, %r13d
jle 0xa2de
movq 0x58(%r14), %rax
movl %r13d, %ecx
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, (%rbp,%rdx,8)
incq %rdx
cmpq %rdx, %rcx
jne 0xa2cb
movq 0x10(%rsp), %rcx
jmp 0xa318
xorpd %xmm0, %xmm0
ucomisd 0x2d1f(%rip), %xmm0     # 0xd010
jb 0xa2f9
sqrtsd %xmm0, %xmm0
jmp 0xa2fe
callq 0x20e0
movq 0x10(%rsp), %rcx
ucomisd 0x3b0d(%rip), %xmm0     # 0xde18
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmoval %eax, %ebx
movq %rbx, 0x20(%rsp)
cmpl %ecx, %r15d
movq 0x40(%rsp), %r12
movq 0x38(%rsp), %rbx
jle 0xa35d
movq 0x58(%rsp), %rax
leaq (%rax,%rcx,4), %r13
subl %ecx, %r15d
xorl %ebp, %ebp
movq 0x10(%r12), %rax
movslq (%r13,%rbp,4), %rcx
movq (%rax,%rcx,8), %rsi
movq %r14, %rdi
callq 0x9a4c
movslq (%r13,%rbp,4), %rax
movsd %xmm0, (%rbx,%rax,8)
incq %rbp
cmpl %ebp, %r15d
jne 0xa335
movq 0x8(%rsp), %r12
incq %r12
leaq 0x80(%rsp), %rdi
callq 0x9a97
movq 0x60(%rsp), %r15
cmpq %r15, %r12
movq 0x68(%rsp), %r14
jne 0xa1dc
movq 0x50(%rsp), %rax
movq %rax, 0x7e07(%rip)      # 0x12198
movq (%rsp), %rax
movl (%rax), %eax
testl %eax, %eax
je 0xa3ef
cmpl $0x2, %eax
je 0xa3ef
cmpl $0xb, %eax
movq 0x40(%rsp), %r13
movq 0x38(%rsp), %r12
movq 0x20(%rsp), %rbx
jne 0xa515
movslq (%r13), %rax
testq %rax, %rax
jle 0xa4a2
movq 0x8(%r13), %rcx
xorpd %xmm1, %xmm1
xorl %edx, %edx
movsd (%r12,%rdx,8), %xmm0
subsd (%rcx,%rdx,8), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm0, %xmm1
incq %rdx
cmpq %rdx, %rax
jne 0xa3cf
jmp 0xa4a6
movq 0x40(%rsp), %r13
movslq (%r13), %rax
testq %rax, %rax
movq 0x38(%rsp), %r12
movq 0x20(%rsp), %rbx
jle 0xa433
movq 0x8(%r13), %rcx
xorl %edx, %edx
xorl %esi, %esi
movsd (%rcx,%rdx,8), %xmm0
cmpeqsd (%r12,%rdx,8), %xmm0
movq %xmm0, %rdi
subl %edi, %esi
incq %rdx
cmpq %rdx, %rax
jne 0xa40f
xorps %xmm1, %xmm1
cvtsi2sd %esi, %xmm1
jmp 0xa437
xorpd %xmm1, %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movq 0x18(%rsp), %rax
ucomisd (%rax), %xmm1
jbe 0xa468
movq (%rsp), %rax
movsd 0x10(%rax), %xmm0
movq 0x28(%rsp), %rax
movsd %xmm0, (%rax)
movq 0x18(%rsp), %rax
movsd %xmm1, (%rax)
movq (%rsp), %rax
movsd 0x10(%rax), %xmm0
movsd %xmm1, 0x8(%rsp)
callq 0x20f0
divsd 0x398c(%rip), %xmm0     # 0xde10
movsd 0x8(%rsp), %xmm1
mulsd 0x2b8e(%rip), %xmm1     # 0xd020
leaq 0x40e4(%rip), %rdi      # 0xe57d
movb $0x2, %al
callq 0x5ab4
jmp 0xa515
xorpd %xmm1, %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movq 0x18(%rsp), %rax
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xa4db
movq (%rsp), %rax
movsd 0x10(%rax), %xmm0
movq 0x28(%rsp), %rax
movsd %xmm0, (%rax)
movq 0x18(%rsp), %rax
movsd %xmm1, (%rax)
movq (%rsp), %rbx
movsd 0x10(%rbx), %xmm0
movsd %xmm1, 0x8(%rsp)
callq 0x20f0
divsd 0x3919(%rip), %xmm0     # 0xde10
movsd 0x30(%rbx), %xmm1
leaq 0x408f(%rip), %rdi      # 0xe592
movsd 0x8(%rsp), %xmm2
movb $0x3, %al
callq 0x5ab4
movq 0x20(%rsp), %rbx
incl %ebx
cmpl $0x5, %ebx
je 0xa53e
movq (%rsp), %rax
movsd 0x10(%rax), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, 0x10(%rax)
movsd 0x30(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jae 0xa1bb
movq (%rsp), %rax
movsd 0x10(%rax), %xmm0
ucomisd 0x30(%rsp), %xmm0
jbe 0xa55d
leaq 0x4067(%rip), %rdi      # 0xe5bd
xorl %eax, %eax
callq 0x5ab4
movq %r12, %rdi
callq 0x21a0
cmpl $0x0, 0x48(%rsp)
jle 0xa57f
xorl %ebx, %ebx
movq (%r14,%rbx,8), %rdi
callq 0x21a0
incq %rbx
cmpq %rbx, %r15
jne 0xa56e
movq %r14, %rdi
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x21a0