// File: /workspace/github_cpp_makefile_star2_O2/cjlin1[P]liblinear/linear.cpp
// Function: solve_l2r_l1l2_svr(problem const*, parameter const*, double*, int)
static int solve_l2r_l1l2_svr(const problem *prob, const parameter *param, double *w, int max_iter=300)
{
	const int solver_type = param->solver_type;
	int l = prob->l;
	double C = param->C;
	double p = param->p;
	int w_size = prob->n;
	double eps = param->eps;
	int i, s, iter = 0;
	int active_size = l;
	int *index = new int[l];

	double d, G, H;
	double Gmax_old = INF;
	double Gmax_new, Gnorm1_new;
	double Gnorm1_init = -1.0; // Gnorm1_init is initialized at the first iteration
	double *beta = new double[l];
	double *QD = new double[l];
	double *y = prob->y;

	// L2R_L2LOSS_SVR_DUAL
	double lambda[1], upper_bound[1];
	lambda[0] = 0.5/C;
	upper_bound[0] = INF;

	if(solver_type == L2R_L1LOSS_SVR_DUAL)
	{
		lambda[0] = 0;
		upper_bound[0] = C;
	}

	// Initial beta can be set here. Note that
	// -upper_bound <= beta[i] <= upper_bound
	for(i=0; i<l; i++)
		beta[i] = 0;

	for(i=0; i<w_size; i++)
		w[i] = 0;
	for(i=0; i<l; i++)
	{
		feature_node * const xi = prob->x[i];
		QD[i] = sparse_operator::nrm2_sq(xi);
		sparse_operator::axpy(beta[i], xi, w);

		index[i] = i;
	}


	while(iter < max_iter)
	{
		Gmax_new = 0;
		Gnorm1_new = 0;

		for(i=0; i<active_size; i++)
		{
			int j = i+rand()%(active_size-i);
			swap(index[i], index[j]);
		}

		for(s=0; s<active_size; s++)
		{
			i = index[s];
			G = -y[i] + lambda[GETI(i)]*beta[i];
			H = QD[i] + lambda[GETI(i)];

			feature_node * const xi = prob->x[i];
			G += sparse_operator::dot(w, xi);

			double Gp = G+p;
			double Gn = G-p;
			double violation = 0;
			if(beta[i] == 0)
			{
				if(Gp < 0)
					violation = -Gp;
				else if(Gn > 0)
					violation = Gn;
				else if(Gp>Gmax_old && Gn<-Gmax_old)
				{
					active_size--;
					swap(index[s], index[active_size]);
					s--;
					continue;
				}
			}
			else if(beta[i] >= upper_bound[GETI(i)])
			{
				if(Gp > 0)
					violation = Gp;
				else if(Gp < -Gmax_old)
				{
					active_size--;
					swap(index[s], index[active_size]);
					s--;
					continue;
				}
			}
			else if(beta[i] <= -upper_bound[GETI(i)])
			{
				if(Gn < 0)
					violation = -Gn;
				else if(Gn > Gmax_old)
				{
					active_size--;
					swap(index[s], index[active_size]);
					s--;
					continue;
				}
			}
			else if(beta[i] > 0)
				violation = fabs(Gp);
			else
				violation = fabs(Gn);

			Gmax_new = max(Gmax_new, violation);
			Gnorm1_new += violation;

			// obtain Newton direction d
			if(Gp < H*beta[i])
				d = -Gp/H;
			else if(Gn > H*beta[i])
				d = -Gn/H;
			else
				d = -beta[i];

			if(fabs(d) < 1.0e-12)
				continue;

			double beta_old = beta[i];
			beta[i] = min(max(beta[i]+d, -upper_bound[GETI(i)]), upper_bound[GETI(i)]);
			d = beta[i]-beta_old;

			if(d != 0)
				sparse_operator::axpy(d, xi, w);
		}

		if(iter == 0)
			Gnorm1_init = Gnorm1_new;
		iter++;
		if(iter % 10 == 0)
			info(".");

		if(Gnorm1_new <= eps*Gnorm1_init)
		{
			if(active_size == l)
				break;
			else
			{
				active_size = l;
				info("*");
				Gmax_old = INF;
				continue;
			}
		}

		Gmax_old = Gmax_new;
	}

	info("\noptimization finished, #iter = %d\n", iter);

	// calculate objective value
	double v = 0;
	int nSV = 0;
	for(i=0; i<w_size; i++)
		v += w[i]*w[i];
	v = 0.5*v;
	for(i=0; i<l; i++)
	{
		v += p*fabs(beta[i]) - y[i]*beta[i] + 0.5*lambda[GETI(i)]*beta[i]*beta[i];
		if(beta[i] != 0)
			nSV++;
	}

	info("Objective value = %lf\n", v);
	info("nSV = %d\n",nSV);

	delete [] beta;
	delete [] QD;
	delete [] index;

	return iter;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rdx, 0x28(%rsp)
movl (%rsi), %r12d
movslq (%rdi), %r13
movsd 0x10(%rsi), %xmm0
movaps %xmm0, 0x70(%rsp)
movsd 0x30(%rsi), %xmm0
movsd %xmm0, 0x90(%rsp)
movq %rdi, 0x48(%rsp)
movl 0x4(%rdi), %r14d
movsd 0x8(%rsi), %xmm0
movsd %xmm0, 0xa0(%rsp)
leaq (,%r13,4), %rdi
testq %r13, %r13
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
leaq (,%r13,8), %r15
cmovsq %rax, %r15
callq 0x2030
movq %rax, 0x10(%rsp)
movq %r15, %rdi
callq 0x2030
movq %rax, 0x18(%rsp)
movq %r15, %rdi
callq 0x2030
movq %rax, 0x50(%rsp)
movsd 0x1f32(%rip), %xmm1     # 0xcc30
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
cmpl $0xd, %r12d
je 0xad1e
movapd %xmm1, %xmm0
divsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x88(%rsp)
xorl %eax, %eax
testl %r13d, %r13d
movq %r13, %rcx
movl $0x0, %r13d
movq %rcx, 0x80(%rsp)
cmovgl %ecx, %r13d
movq 0x18(%rsp), %rcx
cmpq %rax, %r13
je 0xad5d
andq $0x0, (%rcx,%rax,8)
incq %rax
jmp 0xad4e
xorl %eax, %eax
testl %r14d, %r14d
cmovlel %eax, %r14d
movq 0x28(%rsp), %rcx
cmpq %rax, %r14
je 0xad7a
andq $0x0, (%rcx,%rax,8)
incq %rax
jmp 0xad6b
movq %r14, 0x98(%rsp)
xorl %r14d, %r14d
cmpq %r14, %r13
je 0xadd0
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
movq (%rax,%r14,8), %rbp
movq %rbp, %rdi
callq 0xb4ba
movq 0x50(%rsp), %rax
movsd %xmm0, (%rax,%r14,8)
movq 0x18(%rsp), %rax
movsd (%rax,%r14,8), %xmm0
movq %rbp, %rdi
movq 0x28(%rsp), %rsi
callq 0xb47e
movq 0x10(%rsp), %rax
movl %r14d, (%rax,%r14,4)
incq %r14
jmp 0xad85
movsd 0x1258(%rip), %xmm0     # 0xc030
cmpl $0xd, %r12d
je 0xadf3
movsd 0x124a(%rip), %xmm0     # 0xc030
movaps %xmm0, 0x70(%rsp)
movsd 0x123d(%rip), %xmm0     # 0xc030
movaps 0x1e86(%rip), %xmm1     # 0xcc80
xorps 0x70(%rsp), %xmm1
movaps %xmm1, 0xc0(%rsp)
movsd 0x1231(%rip), %xmm1     # 0xc040
movsd %xmm1, 0x40(%rsp)
movapd %xmm0, 0x60(%rsp)
movq 0x80(%rsp), %rax
movl %eax, %ebx
movl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %r12
movq %r13, 0xa8(%rsp)
cmpl $0x12c, 0xc(%rsp)       # imm = 0x12C
je 0xb1c1
testl %ebx, %ebx
movl $0x0, %r14d
cmovgl %ebx, %r14d
movl %ebx, %ebp
xorl %r15d, %r15d
cmpq %r15, %r14
je 0xae83
callq 0x2090
cltd
idivl %ebp
movslq %edx, %rax
addq %r15, %rax
movl (%r12,%r15,4), %ecx
movl (%r12,%rax,4), %edx
movl %edx, (%r12,%r15,4)
movl %ecx, (%r12,%rax,4)
incq %r15
decl %ebp
jmp 0xae59
movaps 0x60(%rsp), %xmm0
xorps 0x1df1(%rip), %xmm0     # 0xcc80
movaps %xmm0, 0xb0(%rsp)
xorl %r13d, %r13d
xorps %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd %xmm0, 0x58(%rsp)
cmpl %ebx, %r13d
jge 0xb110
movslq %r13d, %r15
movl (%r12,%r15,4), %r14d
movslq %r14d, %r12
movq 0x18(%rsp), %rax
movsd (%rax,%r12,8), %xmm2
movapd %xmm2, 0xd0(%rsp)
movsd 0x20(%rsp), %xmm0
movapd %xmm0, %xmm1
mulsd %xmm2, %xmm1
movq 0x88(%rsp), %rax
subsd (%rax,%r12,8), %xmm1
movsd %xmm1, (%rsp)
movq 0x50(%rsp), %rax
movsd (%rax,%r12,8), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x30(%rsp)
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
movq (%rax,%r12,8), %rbp
movq 0x28(%rsp), %rdi
movq %rbp, %rsi
callq 0xb45a
movapd 0xd0(%rsp), %xmm5
movapd %xmm0, %xmm1
addsd (%rsp), %xmm1
movsd 0x90(%rsp), %xmm2
movapd %xmm2, %xmm0
addsd %xmm1, %xmm0
subsd %xmm2, %xmm1
xorpd %xmm4, %xmm4
ucomisd %xmm4, %xmm5
movl %ebx, (%rsp)
movslq %ebx, %rax
jne 0xaf76
jp 0xaf76
ucomisd %xmm0, %xmm4
jbe 0xaf9f
movapd %xmm0, %xmm2
xorpd 0x1d15(%rip), %xmm2     # 0xcc80
movsd 0x30(%rsp), %xmm6
jmp 0xb022
ucomisd 0x70(%rsp), %xmm5
jae 0xafd0
movapd 0xc0(%rsp), %xmm2
ucomisd %xmm5, %xmm2
jae 0xaff8
ucomisd %xmm4, %xmm5
movsd 0x30(%rsp), %xmm6
jbe 0xb016
movapd %xmm0, %xmm2
jmp 0xb01a
ucomisd %xmm4, %xmm1
movapd %xmm1, %xmm2
movsd 0x30(%rsp), %xmm6
ja 0xb022
ucomisd 0x60(%rsp), %xmm0
xorpd %xmm2, %xmm2
jbe 0xb022
movapd 0xb0(%rsp), %xmm3
ucomisd %xmm1, %xmm3
ja 0xb0f3
jmp 0xb022
ucomisd %xmm4, %xmm0
movapd %xmm0, %xmm2
movsd 0x30(%rsp), %xmm6
ja 0xb022
xorpd %xmm2, %xmm2
movapd 0xb0(%rsp), %xmm3
ucomisd %xmm0, %xmm3
jbe 0xb022
jmp 0xb0f3
ucomisd %xmm1, %xmm4
movsd 0x30(%rsp), %xmm6
jbe 0xb0e3
movapd %xmm1, %xmm2
xorpd 0x1c6c(%rip), %xmm2     # 0xcc80
jmp 0xb022
movapd %xmm1, %xmm2
andpd 0x1c4e(%rip), %xmm2     # 0xcc70
movapd %xmm6, %xmm3
mulsd %xmm5, %xmm3
ucomisd %xmm0, %xmm3
jbe 0xb03e
xorpd 0x1c48(%rip), %xmm0     # 0xcc80
divsd %xmm6, %xmm0
jmp 0xb062
ucomisd %xmm3, %xmm1
jbe 0xb056
xorpd 0x1c34(%rip), %xmm1     # 0xcc80
divsd %xmm6, %xmm1
movapd %xmm1, %xmm0
jmp 0xb062
movapd %xmm5, %xmm0
xorpd 0x1c1e(%rip), %xmm0     # 0xcc80
movsd 0x58(%rsp), %xmm1
maxsd %xmm2, %xmm1
movsd %xmm1, 0x58(%rsp)
movsd 0x38(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x38(%rsp)
movapd %xmm0, %xmm1
andpd 0x1be2(%rip), %xmm1     # 0xcc70
movsd 0x1bba(%rip), %xmm2     # 0xcc50
ucomisd %xmm1, %xmm2
ja 0xb0d3
addsd %xmm5, %xmm0
maxsd 0xc0(%rsp), %xmm0
minsd 0x70(%rsp), %xmm0
movq 0x18(%rsp), %rax
movsd %xmm0, (%rax,%r12,8)
subsd %xmm5, %xmm0
ucomisd %xmm4, %xmm0
jne 0xb0c6
jnp 0xb0d3
movq %rbp, %rdi
movq 0x28(%rsp), %rsi
callq 0xb47e
movl (%rsp), %ebx
movq 0x10(%rsp), %r12
incl %r13d
jmp 0xaea9
xorpd %xmm2, %xmm2
ucomisd 0x60(%rsp), %xmm1
jbe 0xb022
movl (%rsp), %ebx
decl %ebx
movq 0x10(%rsp), %r12
movl -0x4(%r12,%rax,4), %ecx
movl %ecx, (%r12,%r15,4)
movl %r14d, -0x4(%r12,%rax,4)
decl %r13d
jmp 0xb0db
movsd 0x38(%rsp), %xmm1
movl 0xc(%rsp), %eax
testl %eax, %eax
je 0xb124
movsd 0x40(%rsp), %xmm1
incl %eax
movl %eax, 0xc(%rsp)
xorl %edx, %edx
pushq $0xa
popq %rcx
divl %ecx
testl %edx, %edx
movq 0xa8(%rsp), %r13
jne 0xb155
leaq 0x1df4(%rip), %rdi      # 0xcf38
xorl %eax, %eax
movsd %xmm1, (%rsp)
callq 0x52d8
movsd (%rsp), %xmm1
movsd 0xa0(%rsp), %xmm0
mulsd %xmm1, %xmm0
ucomisd 0x38(%rsp), %xmm0
movsd %xmm1, 0x40(%rsp)
movsd 0x58(%rsp), %xmm0
movapd %xmm0, 0x60(%rsp)
jb 0xae3a
movq 0x80(%rsp), %r14
cmpl %r14d, %ebx
je 0xb1c8
leaq 0x1da6(%rip), %rdi      # 0xcf3a
xorl %eax, %eax
movsd %xmm1, (%rsp)
callq 0x52d8
movsd (%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0xe7d(%rip), %xmm0      # 0xc030
movapd %xmm0, 0x60(%rsp)
movl %r14d, %ebx
jmp 0xae3a
movl $0x12c, %esi            # imm = 0x12C
jmp 0xb1cc
movl 0xc(%rsp), %esi
leaq 0x1d69(%rip), %rdi      # 0xcf3c
xorl %r14d, %r14d
movl %esi, %r15d
xorl %eax, %eax
callq 0x52d8
xorpd %xmm0, %xmm0
movq 0x98(%rsp), %rcx
movsd 0x1a3c(%rip), %xmm2     # 0xcc30
movq 0x28(%rsp), %rax
cmpq %r14, %rcx
je 0xb211
movsd (%rax,%r14,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %r14
jmp 0xb1f9
mulsd %xmm2, %xmm0
movsd 0x20(%rsp), %xmm1
mulsd %xmm2, %xmm1
movsd %xmm1, 0x20(%rsp)
xorl %eax, %eax
xorpd %xmm1, %xmm1
xorl %ebp, %ebp
cmpq %rax, %r13
je 0xb28d
movq 0x18(%rsp), %rcx
movsd (%rcx,%rax,8), %xmm2
movapd %xmm2, %xmm3
andpd 0x1a28(%rip), %xmm3     # 0xcc70
movq 0x88(%rsp), %rcx
movsd (%rcx,%rax,8), %xmm4
mulsd %xmm2, %xmm4
mulsd 0x90(%rsp), %xmm3
subsd %xmm4, %xmm3
movsd 0x20(%rsp), %xmm4
mulsd %xmm2, %xmm4
mulsd %xmm2, %xmm4
addsd %xmm3, %xmm4
addsd %xmm4, %xmm0
cmpneqsd %xmm1, %xmm2
movq %xmm2, %rcx
subl %ecx, %ebp
incq %rax
jmp 0xb22d
leaq 0x1cf9(%rip), %rdi      # 0xcf8d
movb $0x1, %al
callq 0x52d8
leaq 0x1d02(%rip), %rdi      # 0xcfa4
movl %ebp, %esi
xorl %eax, %eax
callq 0x52d8
movq 0x18(%rsp), %rdi
callq 0x21e0
movq 0x50(%rsp), %rdi
callq 0x21e0
movq %r12, %rdi
callq 0x21e0
movl %r15d, %eax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq