// File: /workspace/github_cpp_makefile_star2_O2/qmmlib[P]QmmLibrary/linear.cpp
// Function: solve_l2r_l1l2_svr(problem const*, double*, parameter const*, int)
static void solve_l2r_l1l2_svr(
	const problem *prob, double *w, const parameter *param,
	int 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 max_iter = 1000;
	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;
	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++)
	{
		QD[i] = 0;
		feature_node *xi = prob->x[i];
		while(xi->index != -1)
		{
			double val = xi->value;
			QD[i] += val*val;
			w[xi->index-1] += beta[i]*val;
			xi++;
		}

		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 *xi = prob->x[i];
			while(xi->index != -1)
			{
				int ind = xi->index-1;
				double val = xi->value;
				G += val*w[ind];
				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)
			{
				xi = prob->x[i];
				while(xi->index != -1)
				{
					w[xi->index-1] += d*xi->value;
					xi++;
				}
			}
		}

		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);
	if(iter >= max_iter)
		info("\nWARNING: reaching max number of iterations\nUsing -s 11 may be faster\n\n");

	// 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;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movl %ecx, %r13d
movq %rsi, %r12
movslq (%rdi), %rbp
movsd 0x80(%rdx), %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0x88(%rdx), %xmm0
movaps %xmm0, 0x50(%rsp)
movsd 0xa8(%rdx), %xmm0
movsd %xmm0, 0x70(%rsp)
movq %rdi, 0x48(%rsp)
movl 0x4(%rdi), %eax
movq %rax, 0x30(%rsp)
leaq (,%rbp,4), %rdi
testq %rbp, %rbp
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
leaq (,%rbp,8), %r15
cmovsq %rax, %r15
callq 0x3030
movq %rax, %rbx
movq %r15, %rdi
callq 0x3030
movq %rax, %r14
movq %r15, %rdi
callq 0x3030
movl %r13d, %esi
movq %rax, %r15
xorpd %xmm6, %xmm6
cmpl $0xd, %r13d
je 0x1296e
movsd 0x3798(%rip), %xmm6     # 0x16100
divsd 0x50(%rsp), %xmm6
movq 0x48(%rsp), %rax
movq 0x8(%rax), %r13
xorl %eax, %eax
testl %ebp, %ebp
movl $0x0, %ecx
movq %rbp, 0x68(%rsp)
cmovgl %ebp, %ecx
movq %rcx, 0x40(%rsp)
movq 0x30(%rsp), %rcx
cmpq %rax, 0x40(%rsp)
je 0x129a3
andq $0x0, (%r14,%rax,8)
incq %rax
jmp 0x12992
xorl %eax, %eax
testl %ecx, %ecx
cmovlel %eax, %ecx
cmpq %rax, %rcx
je 0x129b9
andq $0x0, (%r12,%rax,8)
incq %rax
jmp 0x129aa
xorl %eax, %eax
movq %rcx, 0x30(%rsp)
cmpq 0x40(%rsp), %rax
je 0x12a1f
andq $0x0, (%r15,%rax,8)
movq 0x48(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq (%rcx,%rax,8), %rcx
xorpd %xmm0, %xmm0
movslq (%rcx), %rdx
cmpq $-0x1, %rdx
je 0x12a17
movsd 0x8(%rcx), %xmm1
movapd %xmm1, %xmm2
mulsd %xmm1, %xmm2
addsd %xmm2, %xmm0
movsd %xmm0, (%r15,%rax,8)
mulsd (%r14,%rax,8), %xmm1
addsd -0x8(%r12,%rdx,8), %xmm1
movsd %xmm1, -0x8(%r12,%rdx,8)
addq $0x10, %rcx
jmp 0x129dd
movl %eax, (%rbx,%rax,4)
incq %rax
jmp 0x129c0
movsd 0x2609(%rip), %xmm0     # 0x15030
cmpl $0xd, %esi
je 0x12a41
movsd 0x25fc(%rip), %xmm0     # 0x15030
movaps %xmm0, 0x50(%rsp)
movsd 0x25ef(%rip), %xmm0     # 0x15030
movaps 0x36e8(%rip), %xmm1     # 0x16130
xorps 0x50(%rsp), %xmm1
movaps %xmm1, 0x90(%rsp)
movapd %xmm0, 0x20(%rsp)
movq 0x68(%rsp), %rax
movl %eax, %ebp
xorl %r10d, %r10d
movq %r15, 0x88(%rsp)
movsd %xmm6, 0x18(%rsp)
movq %r13, 0x80(%rsp)
cmpl $0x3e8, %r10d           # imm = 0x3E8
je 0x12dc0
movsd %xmm1, 0x38(%rsp)
movl %r10d, 0x10(%rsp)
testl %ebp, %ebp
movl $0x0, %r13d
cmovgl %ebp, %r13d
movl %ebp, 0xc(%rsp)
xorl %r15d, %r15d
cmpq %r15, %r13
je 0x12ace
callq 0x30a0
cltd
idivl %ebp
movslq %edx, %rax
addq %r15, %rax
movl (%rbx,%r15,4), %ecx
movl (%rbx,%rax,4), %edx
movl %edx, (%rbx,%r15,4)
movl %ecx, (%rbx,%rax,4)
incq %r15
decl %ebp
jmp 0x12aa6
movapd 0x20(%rsp), %xmm0
xorpd 0x3654(%rip), %xmm0     # 0x16130
xorl %eax, %eax
xorpd %xmm10, %xmm10
xorpd %xmm9, %xmm9
movsd 0x70(%rsp), %xmm7
movq 0x88(%rsp), %r15
movsd 0x18(%rsp), %xmm6
movq 0x80(%rsp), %r13
movl 0x10(%rsp), %r10d
xorpd %xmm8, %xmm8
movl 0xc(%rsp), %ebp
cmpl %ebp, %eax
jge 0x12cf9
movslq %eax, %rsi
movl (%rbx,%rsi,4), %edi
movslq %edi, %rdx
movsd (%r14,%rdx,8), %xmm1
movapd %xmm6, %xmm3
mulsd %xmm1, %xmm3
subsd (%r13,%rdx,8), %xmm3
movsd (%r15,%rdx,8), %xmm4
movq 0x48(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq (%rcx,%rdx,8), %rcx
movq %rcx, %r8
movslq (%r8), %r9
cmpq $-0x1, %r9
je 0x12b6e
movsd 0x8(%r8), %xmm2
mulsd -0x8(%r12,%r9,8), %xmm2
addsd %xmm2, %xmm3
addq $0x10, %r8
jmp 0x12b4e
movapd %xmm7, %xmm2
addsd %xmm3, %xmm2
subsd %xmm7, %xmm3
ucomisd %xmm8, %xmm1
jne 0x12b98
jp 0x12b98
ucomisd %xmm2, %xmm8
jbe 0x12bbc
movapd %xmm2, %xmm5
xorpd 0x359a(%rip), %xmm5     # 0x16130
jmp 0x12c16
ucomisd 0x50(%rsp), %xmm1
jae 0x12bdf
movapd 0x90(%rsp), %xmm5
ucomisd %xmm1, %xmm5
jae 0x12bf9
ucomisd %xmm8, %xmm1
jbe 0x12c0a
movapd %xmm2, %xmm5
jmp 0x12c0e
ucomisd %xmm8, %xmm3
movapd %xmm3, %xmm5
ja 0x12c16
ucomisd 0x20(%rsp), %xmm2
xorpd %xmm5, %xmm5
jbe 0x12c16
ucomisd %xmm3, %xmm0
ja 0x12ce0
jmp 0x12c16
ucomisd %xmm8, %xmm2
movapd %xmm2, %xmm5
ja 0x12c16
xorpd %xmm5, %xmm5
ucomisd %xmm2, %xmm0
jbe 0x12c16
jmp 0x12ce0
ucomisd %xmm3, %xmm8
jbe 0x12cd0
movapd %xmm3, %xmm5
jmp 0x12b8e
movapd %xmm3, %xmm5
andpd 0x350a(%rip), %xmm5     # 0x16120
addsd %xmm6, %xmm4
movapd %xmm1, %xmm6
mulsd %xmm4, %xmm6
ucomisd %xmm2, %xmm6
jbe 0x12c36
xorpd 0x3500(%rip), %xmm2     # 0x16130
divsd %xmm4, %xmm2
jmp 0x12c5a
ucomisd %xmm6, %xmm3
jbe 0x12c4e
xorpd 0x34ec(%rip), %xmm3     # 0x16130
divsd %xmm4, %xmm3
movapd %xmm3, %xmm2
jmp 0x12c5a
movapd %xmm1, %xmm2
xorpd 0x34d6(%rip), %xmm2     # 0x16130
movsd 0x18(%rsp), %xmm6
maxsd %xmm5, %xmm9
addsd %xmm5, %xmm10
movapd %xmm2, %xmm3
andpd 0x34aa(%rip), %xmm3     # 0x16120
movsd 0x3492(%rip), %xmm4     # 0x16110
ucomisd %xmm3, %xmm4
ja 0x12cf2
addsd %xmm1, %xmm2
maxsd 0x90(%rsp), %xmm2
minsd 0x50(%rsp), %xmm2
movsd %xmm2, (%r14,%rdx,8)
subsd %xmm1, %xmm2
ucomisd %xmm8, %xmm2
jne 0x12caa
jnp 0x12cf2
movslq (%rcx), %rdx
cmpq $-0x1, %rdx
je 0x12cf2
movsd 0x8(%rcx), %xmm1
mulsd %xmm2, %xmm1
addsd -0x8(%r12,%rdx,8), %xmm1
movsd %xmm1, -0x8(%r12,%rdx,8)
addq $0x10, %rcx
jmp 0x12caa
xorpd %xmm5, %xmm5
ucomisd 0x20(%rsp), %xmm3
jbe 0x12c16
movslq %ebp, %rcx
decl %ebp
movl -0x4(%rbx,%rcx,4), %edx
movl %edx, (%rbx,%rsi,4)
movl %edi, -0x4(%rbx,%rcx,4)
decl %eax
incl %eax
jmp 0x12b12
movapd %xmm10, %xmm2
testl %r10d, %r10d
je 0x12d09
movsd 0x38(%rsp), %xmm2
incl %r10d
movl %r10d, %eax
xorl %edx, %edx
pushq $0xa
popq %rcx
divl %ecx
testl %edx, %edx
jne 0x12d5e
leaq 0x3c6d(%rip), %rdi      # 0x1698e
xorl %eax, %eax
movl %ebp, 0xc(%rsp)
movl %r10d, %ebp
movsd %xmm9, 0x10(%rsp)
movsd %xmm10, 0x38(%rsp)
movsd %xmm2, 0x20(%rsp)
callq 0x6a9e
movsd 0x20(%rsp), %xmm2
movsd 0x38(%rsp), %xmm10
movsd 0x10(%rsp), %xmm9
movl %ebp, %r10d
movl 0xc(%rsp), %ebp
movsd 0x78(%rsp), %xmm0
mulsd %xmm2, %xmm0
ucomisd %xmm10, %xmm0
movapd %xmm2, %xmm1
movapd %xmm9, 0x20(%rsp)
jb 0x12a7b
movl %ebp, %eax
movq 0x68(%rsp), %rbp
cmpl %ebp, %eax
je 0x12dc6
leaq 0x3728(%rip), %rdi      # 0x164b8
xorl %eax, %eax
movl %r10d, 0x10(%rsp)
movsd %xmm2, 0x20(%rsp)
callq 0x6a9e
movl 0x10(%rsp), %r10d
movsd 0x20(%rsp), %xmm1
movsd 0x227b(%rip), %xmm0     # 0x15030
movapd %xmm0, 0x20(%rsp)
jmp 0x12a7b
movl $0x3e8, %r10d           # imm = 0x3E8
leaq 0x36ed(%rip), %rdi      # 0x164ba
movl %r10d, %esi
xorl %eax, %eax
movl %r10d, %ebp
callq 0x6a9e
cmpl $0x3e8, %ebp            # imm = 0x3E8
jl 0x12df0
leaq 0x39ad(%rip), %rdi      # 0x16796
xorl %eax, %eax
callq 0x6a9e
xorpd %xmm0, %xmm0
xorl %eax, %eax
movsd 0x70(%rsp), %xmm5
movsd 0x18(%rsp), %xmm6
movq 0x30(%rsp), %rcx
cmpq %rax, %rcx
je 0x12e1f
movsd (%r12,%rax,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rax
jmp 0x12e07
movsd 0x32d9(%rip), %xmm1     # 0x16100
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm6
xorl %eax, %eax
xorpd %xmm1, %xmm1
xorl %r12d, %r12d
cmpq %rax, 0x40(%rsp)
je 0x12e8a
movsd (%r14,%rax,8), %xmm2
movapd %xmm2, %xmm3
andpd 0x32cf(%rip), %xmm3     # 0x16120
movsd (%r13,%rax,8), %xmm4
mulsd %xmm2, %xmm4
mulsd %xmm5, %xmm3
subsd %xmm4, %xmm3
movapd %xmm6, %xmm4
mulsd %xmm2, %xmm4
mulsd %xmm2, %xmm4
addsd %xmm3, %xmm4
addsd %xmm4, %xmm0
cmpneqsd %xmm1, %xmm2
movq %xmm2, %rcx
subl %ecx, %r12d
incq %rax
jmp 0x12e38
leaq 0x367a(%rip), %rdi      # 0x1650b
movb $0x1, %al
callq 0x6a9e
leaq 0x3683(%rip), %rdi      # 0x16522
movl %r12d, %esi
xorl %eax, %eax
callq 0x6a9e
movq %r14, %rdi
callq 0x32f0
movq %r15, %rdi
callq 0x32f0
movq %rbx, %rdi
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x32f0