// File: /workspace/github_cpp_makefile_star2_O3/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, 0x28(%rsp)
movq %rdx, 0x20(%rsp)
movsd %xmm1, 0x30(%rsp)
movsd %xmm0, (%rsp)
movq %rsi, %r13
movq %rdi, %rbp
movslq 0xc8(%rsp), %rbx
movq 0xc0(%rsp), %rax
movq %rax, 0x70(%rsp)
movslq (%rdi), %rdi
shlq $0x3, %rdi
callq 0x21f0
movq %rax, 0x10(%rsp)
leaq (,%rbx,8), %rdi
callq 0x21f0
movq %rax, %r15
movl %ebx, %r12d
movq %rbx, 0x40(%rsp)
testq %rbx, %rbx
jle 0xac8f
leaq (,%r12,8), %rdx
movq %r15, %rdi
xorl %esi, %esi
callq 0x20c0
movq 0x8502(%rip), %rax      # 0x13198
movl (%r13), %ecx
xorps %xmm0, %xmm0
testl %ecx, %ecx
je 0xacbf
cmpl $0x2, %ecx
movq 0x10(%rsp), %rbx
movsd (%rsp), %xmm1
je 0xacc9
cmpl $0xb, %ecx
jne 0xacd2
movsd 0x3373(%rip), %xmm0     # 0xe030
jmp 0xacc9
movq 0x10(%rsp), %rbx
movsd (%rsp), %xmm1
movq 0x28(%rsp), %rcx
movsd %xmm0, (%rcx)
movq 0x20(%rsp), %rcx
movsd %xmm1, (%rcx)
movsd %xmm1, 0x10(%r13)
movsd 0x30(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0xb07e
testq %rax, %rax
leaq 0x102e(%rip), %rcx      # 0xbd29
cmovneq %rax, %rcx
movq %rcx, 0x50(%rsp)
movq $0x0, 0x18(%rsp)
movq %r15, 0x68(%rsp)
movq %r12, 0x60(%rsp)
movq %r13, 0x48(%rsp)
movq %rbp, 0x38(%rsp)
leaq 0x2173(%rip), %rax      # 0xce9b
movq %rax, 0x8469(%rip)      # 0x13198
cmpl $0x0, 0x40(%rsp)
jle 0xaee4
xorl %r14d, %r14d
movq 0x78(%rsp), %rax
movslq (%rax,%r14,4), %rcx
movq %rcx, 0x8(%rsp)
movl 0x4(%rax,%r14,4), %r12d
movq (%r15,%r14,8), %rbp
movq 0x48(%rsp), %rsi
movq %rbp, 0x40(%rsi)
movq %r14, %r13
shlq $0x5, %r13
movq 0x70(%rsp), %rbx
leaq (%rbx,%r13), %rdi
callq 0x5e06
movq %r15, %rdx
movq %rax, %r15
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 %r14, (%rsp)
je 0xade9
movq 0x18(%rsp), %rbx
testl %ebx, %ebx
js 0xae1e
testl %r13d, %r13d
jle 0xae46
movq 0x58(%r15), %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 0xadc2
jmp 0xae4a
movq %r13, %rdi
shlq $0x3, %rdi
movq %rdx, %rbx
callq 0x21f0
movq %rax, (%rbx,%r14,8)
testl %r13d, %r13d
jle 0xae3f
movq 0x58(%r15), %rcx
movl %r13d, %edx
xorl %esi, %esi
movsd (%rcx,%rsi,8), %xmm0
movsd %xmm0, (%rax,%rsi,8)
incq %rsi
cmpq %rsi, %rdx
jne 0xae0a
jmp 0xae3f
testl %r13d, %r13d
jle 0xae3f
movq 0x58(%r15), %rax
movl %r13d, %ecx
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, (%rbp,%rdx,8)
incq %rdx
cmpq %rdx, %rcx
jne 0xae2c
movq 0x8(%rsp), %rcx
jmp 0xae79
xorpd %xmm0, %xmm0
ucomisd 0x31e6(%rip), %xmm0     # 0xe038
jb 0xae5a
sqrtsd %xmm0, %xmm0
jmp 0xae5f
callq 0x20e0
movq 0x8(%rsp), %rcx
ucomisd 0x3fdc(%rip), %xmm0     # 0xee48
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmoval %eax, %ebx
movq %rbx, 0x18(%rsp)
cmpl %ecx, %r12d
movq 0x38(%rsp), %r14
movq 0x10(%rsp), %rbx
jle 0xaebd
movq 0x58(%rsp), %rax
leaq (%rax,%rcx,4), %r13
subl %ecx, %r12d
xorl %ebp, %ebp
movq 0x10(%r14), %rax
movslq (%r13,%rbp,4), %rcx
movq (%rax,%rcx,8), %rsi
movq %r15, %rdi
callq 0xa445
movslq (%r13,%rbp,4), %rax
movsd %xmm0, (%rbx,%rax,8)
incq %rbp
cmpl %ebp, %r12d
jne 0xae96
movq (%rsp), %r14
incq %r14
leaq 0x80(%rsp), %rdi
callq 0xa490
movq 0x60(%rsp), %r12
cmpq %r12, %r14
movq 0x68(%rsp), %r15
jne 0xad3d
movq 0x50(%rsp), %rax
movq %rax, 0x82a8(%rip)      # 0x13198
movq 0x48(%rsp), %r13
movl (%r13), %eax
testl %eax, %eax
je 0xaf4b
cmpl $0x2, %eax
je 0xaf4b
cmpl $0xb, %eax
movq 0x38(%rsp), %rbp
movq 0x10(%rsp), %rbx
jne 0xb04d
movslq (%rbp), %rax
testq %rax, %rax
jle 0xafeb
movq 0x8(%rbp), %rcx
xorpd %xmm1, %xmm1
xorl %edx, %edx
movsd (%rbx,%rdx,8), %xmm0
subsd (%rcx,%rdx,8), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm0, %xmm1
incq %rdx
cmpq %rdx, %rax
jne 0xaf2c
jmp 0xafef
movq 0x38(%rsp), %rbp
movslq (%rbp), %rax
testq %rax, %rax
movq 0x10(%rsp), %rbx
jle 0xaf89
movq 0x8(%rbp), %rcx
xorl %edx, %edx
xorl %esi, %esi
movsd (%rcx,%rdx,8), %xmm0
cmpeqsd (%rbx,%rdx,8), %xmm0
movq %xmm0, %rdi
subl %edi, %esi
incq %rdx
cmpq %rdx, %rax
jne 0xaf66
xorps %xmm1, %xmm1
cvtsi2sd %esi, %xmm1
jmp 0xaf8d
xorpd %xmm1, %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movq 0x28(%rsp), %rax
ucomisd (%rax), %xmm1
movsd 0x10(%r13), %xmm0
movsd %xmm1, (%rsp)
jbe 0xafc1
movq 0x20(%rsp), %rcx
movsd %xmm0, (%rcx)
movsd %xmm1, (%rax)
movsd 0x10(%r13), %xmm0
callq 0x20f0
divsd 0x3e72(%rip), %xmm0     # 0xee40
movsd (%rsp), %xmm1
mulsd 0x306d(%rip), %xmm1     # 0xe048
leaq 0x464b(%rip), %rdi      # 0xf62d
movb $0x2, %al
callq 0x5d62
jmp 0xb04d
xorpd %xmm1, %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movq 0x28(%rsp), %rax
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
movsd 0x10(%r13), %xmm0
movsd %xmm1, (%rsp)
jbe 0xb027
movq 0x20(%rsp), %rcx
movsd %xmm0, (%rcx)
movsd %xmm1, (%rax)
movsd 0x10(%r13), %xmm0
callq 0x20f0
divsd 0x3e0c(%rip), %xmm0     # 0xee40
movsd 0x30(%r13), %xmm1
leaq 0x4601(%rip), %rdi      # 0xf642
movsd (%rsp), %xmm2
movb $0x3, %al
callq 0x5d62
movq 0x18(%rsp), %rax
incl %eax
movsd 0x10(%r13), %xmm1
movq %rax, 0x18(%rsp)
cmpl $0x5, %eax
je 0xb07e
addsd %xmm1, %xmm1
movsd %xmm1, 0x10(%r13)
movsd 0x30(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jae 0xad21
ucomisd 0x30(%rsp), %xmm1
jbe 0xb094
leaq 0x45e0(%rip), %rdi      # 0xf66d
xorl %eax, %eax
callq 0x5d62
movq %rbx, %rdi
callq 0x21a0
cmpl $0x0, 0x40(%rsp)
jle 0xb0b6
xorl %ebx, %ebx
movq (%r15,%rbx,8), %rdi
callq 0x21a0
incq %rbx
cmpq %rbx, %r12
jne 0xb0a5
movq %r15, %rdi
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x21a0