// File: qmmlib[P]QmmLibrary/linear.cpp
// Function: predict_values
double predict_values(const struct model *model_, const struct feature_node *x, double *dec_values)
{
	int idx;
	int n;
	if(model_->bias>=0)
		n=model_->nr_feature+1;
	else
		n=model_->nr_feature;
	double *w=model_->w;
	int nr_class=model_->nr_class;
	int i;
	int nr_w;
	if(nr_class==2 && model_->param.solver_type != MCSVM_CS)
		nr_w = 1;
	else
		nr_w = nr_class;

	const feature_node *lx=x;
	for(i=0;i<nr_w;i++)
		dec_values[i] = 0;
	for(; (idx=lx->index)!=-1; lx++)
	{
		// the dimension of testing data may exceed that of training
		if(idx<=n)
			for(i=0;i<nr_w;i++)
				dec_values[i] += w[(idx-1)*nr_w+i]*lx->value;
	}

	if(nr_class==2)
	{
		if(model_->param.solver_type == L2R_L2LOSS_SVR ||
		   model_->param.solver_type == L2R_L1LOSS_SVR_DUAL ||
		   model_->param.solver_type == L2R_L2LOSS_SVR_DUAL)
			return dec_values[0];
		else
			return (dec_values[0]>0)?model_->label[0]:model_->label[1];
	}
	else
	{
		int dec_max_idx = 0;
		for(i=1;i<nr_class;i++)
		{
			if(dec_values[i] > dec_values[dec_max_idx])
				dec_max_idx = i;
		}
		return model_->label[dec_max_idx];
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movsd 0xc8(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xe477
movq -0x10(%rbp), %rax
movl 0xb4(%rax), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0xe484
movq -0x10(%rbp), %rax
movl 0xb4(%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0xb8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl 0xb0(%rax), %eax
movl %eax, -0x34(%rbp)
cmpl $0x2, -0x34(%rbp)
jne 0xe4b8
movq -0x10(%rbp), %rax
cmpl $0x4, (%rax)
je 0xe4b8
movl $0x1, -0x3c(%rbp)
jmp 0xe4be
movl -0x34(%rbp), %eax
movl %eax, -0x3c(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0xe4f0
movq -0x20(%rbp), %rax
movslq -0x38(%rbp), %rcx
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xe4cd
jmp 0xe4f2
movq -0x48(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x24(%rbp)
cmpl $-0x1, %eax
je 0xe570
movl -0x24(%rbp), %eax
cmpl -0x28(%rbp), %eax
jg 0xe560
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0xe55e
movq -0x30(%rbp), %rax
movl -0x24(%rbp), %ecx
subl $0x1, %ecx
imull -0x3c(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x48(%rbp), %rax
movsd 0x8(%rax), %xmm2
movq -0x20(%rbp), %rax
movslq -0x38(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xe50f
jmp 0xe560
jmp 0xe562
movq -0x48(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x48(%rbp)
jmp 0xe4f2
cmpl $0x2, -0x34(%rbp)
jne 0xe5e5
movq -0x10(%rbp), %rax
cmpl $0xb, (%rax)
je 0xe591
movq -0x10(%rbp), %rax
cmpl $0xd, (%rax)
je 0xe591
movq -0x10(%rbp), %rax
cmpl $0xc, (%rax)
jne 0xe5a3
movq -0x20(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0xe643
movq -0x20(%rbp), %rax
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xe5c6
movq -0x10(%rbp), %rax
movq 0xc0(%rax), %rax
movl (%rax), %eax
movl %eax, -0x50(%rbp)
jmp 0xe5d7
movq -0x10(%rbp), %rax
movq 0xc0(%rax), %rax
movl 0x4(%rax), %eax
movl %eax, -0x50(%rbp)
movl -0x50(%rbp), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0xe643
movl $0x0, -0x4c(%rbp)
movl $0x1, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0xe62a
movq -0x20(%rbp), %rax
movslq -0x38(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x20(%rbp), %rax
movslq -0x4c(%rbp), %rcx
ucomisd (%rax,%rcx,8), %xmm0
jbe 0xe61d
movl -0x38(%rbp), %eax
movl %eax, -0x4c(%rbp)
jmp 0xe61f
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xe5f3
movq -0x10(%rbp), %rax
movq 0xc0(%rax), %rax
movslq -0x4c(%rbp), %rcx
cvtsi2sdl (%rax,%rcx,4), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
popq %rbp
retq
nopw (%rax,%rax)