// File: cjlin1[P]liblinear/predict.c
// Function: do_predict(_IO_FILE*, _IO_FILE*)
void do_predict(FILE *input, FILE *output)
{
	int correct = 0;
	int total = 0;
	double error = 0;
	double sump = 0, sumt = 0, sumpp = 0, sumtt = 0, sumpt = 0;

	int nr_class=get_nr_class(model_);
	double *prob_estimates=NULL;
	int j, n;
	int nr_feature=get_nr_feature(model_);
	if(model_->bias>=0)
		n=nr_feature+1;
	else
		n=nr_feature;

	if(flag_predict_probability)
	{
		int *labels;

		if(!check_probability_model(model_))
		{
			fprintf(stderr, "probability output is only supported for logistic regression\n");
			exit(1);
		}

		labels=(int *) malloc(nr_class*sizeof(int));
		get_labels(model_,labels);
		prob_estimates = (double *) malloc(nr_class*sizeof(double));
		fprintf(output,"labels");
		for(j=0;j<nr_class;j++)
			fprintf(output," %d",labels[j]);
		fprintf(output,"\n");
		free(labels);
	}

	max_line_len = 1024;
	line = (char *)malloc(max_line_len*sizeof(char));
	while(readline(input) != NULL)
	{
		int i = 0;
		double target_label, predict_label;
		char *idx, *val, *label, *endptr;
		int inst_max_index = 0; // strtol gives 0 if wrong format

		label = strtok(line," \t\n");
		if(label == NULL) // empty line
			exit_input_error(total+1);

		target_label = strtod(label,&endptr);
		if(endptr == label || *endptr != '\0')
			exit_input_error(total+1);

		while(1)
		{
			if(i>=max_nr_attr-2)    // need one more for index = -1
			{
				max_nr_attr *= 2;
				x = (struct feature_node *) realloc(x,max_nr_attr*sizeof(struct feature_node));
			}

			idx = strtok(NULL,":");
			val = strtok(NULL," \t");

			if(val == NULL)
				break;
			errno = 0;
			x[i].index = (int) strtol(idx,&endptr,10);
			if(endptr == idx || errno != 0 || *endptr != '\0' || x[i].index <= inst_max_index)
				exit_input_error(total+1);
			else
				inst_max_index = x[i].index;

			errno = 0;
			x[i].value = strtod(val,&endptr);
			if(endptr == val || errno != 0 || (*endptr != '\0' && !isspace(*endptr)))
				exit_input_error(total+1);

			// feature indices larger than those in training are not used
			if(x[i].index <= nr_feature)
				++i;
		}

		if(model_->bias>=0)
		{
			x[i].index = n;
			x[i].value = model_->bias;
			i++;
		}
		x[i].index = -1;

		if(flag_predict_probability)
		{
			int j;
			predict_label = predict_probability(model_,x,prob_estimates);
			fprintf(output,"%g",predict_label);
			for(j=0;j<model_->nr_class;j++)
				fprintf(output," %g",prob_estimates[j]);
			fprintf(output,"\n");
		}
		else
		{
			predict_label = predict(model_,x);
			fprintf(output,"%.17g\n",predict_label);
		}

		if(predict_label == target_label)
			++correct;
		error += (predict_label-target_label)*(predict_label-target_label);
		sump += predict_label;
		sumt += target_label;
		sumpp += predict_label*predict_label;
		sumtt += target_label*target_label;
		sumpt += predict_label*target_label;
		++total;
	}
	if(check_regression_model(model_))
	{
		info("Mean squared error = %g (regression)\n",error/total);
		info("Squared correlation coefficient = %g (regression)\n",
			((total*sumpt-sump*sumt)*(total*sumpt-sump*sumt))/
			((total*sumpp-sump*sump)*(total*sumtt-sumt*sumt))
			);
	}
	else
		info("Accuracy = %g%% (%d/%d)\n",(double) correct/total*100,correct,total);
	if(flag_predict_probability)
		free(prob_estimates);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x20(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x28(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x40(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x48(%rbp)
movq 0x13e30(%rip), %rdi     # 0x16248
callq 0xb5c0
movl %eax, -0x4c(%rbp)
movq $0x0, -0x58(%rbp)
movq 0x13e19(%rip), %rdi     # 0x16248
callq 0xb5a0
movl %eax, -0x64(%rbp)
movq 0x13e0a(%rip), %rax     # 0x16248
movsd 0x68(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2457
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x245d
movl -0x64(%rbp), %eax
movl %eax, -0x60(%rbp)
cmpl $0x0, 0x13dec(%rip)     # 0x16250
je 0x2533
movq 0x13dd7(%rip), %rdi     # 0x16248
callq 0xaa70
cmpl $0x0, %eax
jne 0x249d
movq 0x13b5e(%rip), %rax     # 0x15fe0
movq (%rax), %rdi
leaq 0xfba3(%rip), %rsi      # 0x1202f
movb $0x0, %al
callq 0x21b0
movl $0x1, %edi
callq 0x2160
movslq -0x4c(%rbp), %rdi
shlq $0x2, %rdi
callq 0x2180
movq %rax, -0x70(%rbp)
movq 0x13d93(%rip), %rdi     # 0x16248
movq -0x70(%rbp), %rsi
callq 0xb5e0
movslq -0x4c(%rbp), %rdi
shlq $0x3, %rdi
callq 0x2180
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
leaq 0xfb93(%rip), %rsi      # 0x1206d
movb $0x0, %al
callq 0x21b0
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0x2518
movq -0x10(%rbp), %rdi
movq -0x70(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl (%rax,%rcx,4), %edx
leaq 0xfb6e(%rip), %rsi      # 0x12074
movb $0x0, %al
callq 0x21b0
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x24e8
movq -0x10(%rbp), %rdi
leaq 0xfb57(%rip), %rsi      # 0x1207a
movb $0x0, %al
callq 0x21b0
movq -0x70(%rbp), %rdi
callq 0x2150
movl $0x400, 0x13d17(%rip)   # imm = 0x400
movslq 0x13d10(%rip), %rdi     # 0x16254
shlq $0x0, %rdi
callq 0x2180
movq %rax, 0x13d04(%rip)     # 0x16258
movq -0x8(%rbp), %rdi
callq 0x2b40
cmpq $0x0, %rax
je 0x29cd
movl $0x0, -0x74(%rbp)
movl $0x0, -0xac(%rbp)
movq 0x13cd9(%rip), %rdi     # 0x16258
leaq 0xfaf2(%rip), %rsi      # 0x12078
callq 0x21d0
movq %rax, -0xa0(%rbp)
cmpq $0x0, -0xa0(%rbp)
jne 0x25a7
movl -0x18(%rbp), %edi
addl $0x1, %edi
callq 0x2390
movq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x20a0
movsd %xmm0, -0x80(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0xa0(%rbp), %rax
je 0x25de
movq -0xa8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x25e9
movl -0x18(%rbp), %edi
addl $0x1, %edi
callq 0x2390
jmp 0x25eb
movl -0x74(%rbp), %eax
movl 0x13b5c(%rip), %ecx     # 0x16150
subl $0x2, %ecx
cmpl %ecx, %eax
jl 0x2627
movl 0x13b4f(%rip), %eax     # 0x16150
shll %eax
movl %eax, 0x13b47(%rip)     # 0x16150
movq 0x13c30(%rip), %rdi     # 0x16240
movslq 0x13b39(%rip), %rsi     # 0x16150
shlq $0x4, %rsi
callq 0x21f0
movq %rax, 0x13c19(%rip)     # 0x16240
xorl %eax, %eax
movl %eax, %edi
leaq 0xfa4a(%rip), %rsi      # 0x1207c
callq 0x21d0
movq %rax, -0x90(%rbp)
xorl %eax, %eax
movl %eax, %edi
leaq 0xfa35(%rip), %rsi      # 0x1207e
callq 0x21d0
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x98(%rbp)
jne 0x2664
jmp 0x27ad
callq 0x2040
movl $0x0, (%rax)
movq -0x90(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
movl $0xa, %edx
callq 0x21a0
movl %eax, %ecx
movq 0x13bb0(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movq -0xa8(%rbp), %rax
cmpq -0x90(%rbp), %rax
je 0x26e2
callq 0x2040
cmpl $0x0, (%rax)
jne 0x26e2
movq -0xa8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x26e2
movq 0x13b73(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
cmpl -0xac(%rbp), %eax
jg 0x26ef
movl -0x18(%rbp), %edi
addl $0x1, %edi
callq 0x2390
jmp 0x2709
movq 0x13b4a(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, -0xac(%rbp)
callq 0x2040
movl $0x0, (%rax)
movq -0x98(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x20a0
movq 0x13b12(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movq -0xa8(%rbp), %rax
cmpq -0x98(%rbp), %rax
je 0x277b
callq 0x2040
cmpl $0x0, (%rax)
jne 0x277b
movq -0xa8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x2786
movq -0xa8(%rbp), %rax
movsbl (%rax), %edi
callq 0x2060
cmpl $0x0, %eax
jne 0x2786
movl -0x18(%rbp), %edi
addl $0x1, %edi
callq 0x2390
movq 0x13ab3(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
cmpl -0x64(%rbp), %eax
jg 0x27a8
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x25eb
movq 0x13a94(%rip), %rax     # 0x16248
movsd 0x68(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2805
movl -0x60(%rbp), %ecx
movq 0x13a74(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movq 0x13a68(%rip), %rax     # 0x16248
movsd 0x68(%rax), %xmm0
movq 0x13a54(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
movq 0x13a34(%rip), %rax     # 0x16240
movslq -0x74(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
cmpl $0x0, 0x13a2c(%rip)     # 0x16250
je 0x28c6
movq 0x13a17(%rip), %rdi     # 0x16248
movq 0x13a08(%rip), %rsi     # 0x16240
movq -0x58(%rbp), %rdx
callq 0xa8f0
movsd %xmm0, -0x88(%rbp)
movq -0x10(%rbp), %rdi
movsd -0x88(%rbp), %xmm0
leaq 0xf826(%rip), %rsi      # 0x12082
movb $0x1, %al
callq 0x21b0
movl $0x0, -0xb0(%rbp)
movl -0xb0(%rbp), %eax
movq 0x139ce(%rip), %rcx     # 0x16248
cmpl 0x50(%rcx), %eax
jge 0x28b2
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rax
movslq -0xb0(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
leaq 0xf7e7(%rip), %rsi      # 0x12081
movb $0x1, %al
callq 0x21b0
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0x286d
movq -0x10(%rbp), %rdi
leaq 0xf7bd(%rip), %rsi      # 0x1207a
movb $0x0, %al
callq 0x21b0
jmp 0x28fb
movq 0x1397b(%rip), %rdi     # 0x16248
movq 0x1396c(%rip), %rsi     # 0x16240
callq 0x9580
movsd %xmm0, -0x88(%rbp)
movq -0x10(%rbp), %rdi
movsd -0x88(%rbp), %xmm0
leaq 0xfd4b(%rip), %rsi      # 0x1263f
movb $0x1, %al
callq 0x21b0
movsd -0x88(%rbp), %xmm0
ucomisd -0x80(%rbp), %xmm0
jne 0x2915
jp 0x2915
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movsd -0x88(%rbp), %xmm0
subsd -0x80(%rbp), %xmm0
movsd -0x88(%rbp), %xmm2
subsd -0x80(%rbp), %xmm2
movsd -0x20(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rbp)
movsd -0x88(%rbp), %xmm0
addsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x80(%rbp), %xmm0
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movsd -0x88(%rbp), %xmm0
movsd -0x88(%rbp), %xmm2
movsd -0x38(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x80(%rbp), %xmm0
movsd -0x80(%rbp), %xmm2
movsd -0x40(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movsd -0x88(%rbp), %xmm0
movsd -0x80(%rbp), %xmm2
movsd -0x48(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x2554
movq 0x13874(%rip), %rdi     # 0x16248
callq 0x7510
cmpl $0x0, %eax
je 0x2aee
movq 0x1376f(%rip), %rcx     # 0x16158
movsd -0x20(%rbp), %xmm0
cvtsi2sdl -0x18(%rbp), %xmm1
divsd %xmm1, %xmm0
leaq 0xf687(%rip), %rdi      # 0x12085
movb $0x1, %al
callq *%rcx
movq 0x1374f(%rip), %rcx     # 0x16158
cvtsi2sdl -0x18(%rbp), %xmm0
movsd -0x48(%rbp), %xmm2
movsd -0x28(%rbp), %xmm1
mulsd -0x30(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsi2sdl -0x18(%rbp), %xmm1
movsd -0x48(%rbp), %xmm3
movsd -0x28(%rbp), %xmm2
mulsd -0x30(%rbp), %xmm2
movq %xmm2, %rax
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rax
movq %rax, %xmm2
mulsd %xmm3, %xmm1
addsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
cvtsi2sdl -0x18(%rbp), %xmm1
movsd -0x38(%rbp), %xmm3
movsd -0x28(%rbp), %xmm2
mulsd -0x28(%rbp), %xmm2
movq %xmm2, %rax
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rax
movq %rax, %xmm2
mulsd %xmm3, %xmm1
addsd %xmm2, %xmm1
cvtsi2sdl -0x18(%rbp), %xmm2
movsd -0x40(%rbp), %xmm4
movsd -0x30(%rbp), %xmm3
mulsd -0x30(%rbp), %xmm3
movq %xmm3, %rax
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rax
movq %rax, %xmm3
mulsd %xmm4, %xmm2
addsd %xmm3, %xmm2
mulsd %xmm2, %xmm1
divsd %xmm1, %xmm0
leaq 0xf5c3(%rip), %rdi      # 0x120ab
movb $0x1, %al
callq *%rcx
jmp 0x2b20
movq 0x13663(%rip), %rcx     # 0x16158
cvtsi2sdl -0x14(%rbp), %xmm0
cvtsi2sdl -0x18(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd 0xf4fd(%rip), %xmm1     # 0x12008
mulsd %xmm1, %xmm0
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
leaq 0xf5c2(%rip), %rdi      # 0x120de
movb $0x1, %al
callq *%rcx
cmpl $0x0, 0x13729(%rip)     # 0x16250
je 0x2b32
movq -0x58(%rbp), %rdi
callq 0x2150
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax,%rax)