// File: mattcha[P]sgd-svm/sgd_svm_predict.cpp
// Function: predict(char const*, Weight const&)
int predict(const char* filename, const Weight &weight)
{
    if (filename == NULL) {
        fprintf(stderr, "filename is null\n", filename);
        return -1;
    }

    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        fprintf(stderr, "can't open filename [%s]\n", filename);
        return -1;
    }

    char *buff = NULL;
    size_t buff_len = 0;

    size_t lineno = 0;
    uint32_t max_feature = 0;

    int eval_tp = 0;
    int eval_fn = 0;
    int eval_tn = 0;
    int eval_fp = 0;

    for (ssize_t read = 0; 
            (read = getline(&buff, &buff_len, fp)) != -1; 
            ++lineno) {
        if(read > 1 && buff[read-2] == '\r') {
            buff[read-2] = '\0';
        } else if (read > 0 && (buff[read-1] == '\r' || buff[read-1] == '\n')) {
            buff[read-1] = '\0';
        }

        Instance instance;
        int ret = load_line(buff, instance, max_feature);
        if (ret != 0) {
            fprintf(stderr, "load line [%s] fail\n", buff);
            break;
        }    

        double result = inner_product(instance, weight);
        // output format : predict_result label score 

        if (instance.y_label >= 0 && result >= 0) 
            eval_tp++;
        if (instance.y_label < 0 && result < 0)
            eval_fn++;
        if (instance.y_label >= 0 && result < 0)
            eval_tn++;
        if (instance.y_label < 0 && result >= 0)
            eval_fp++;

        printf("%s\t%f\t%f\n", (result*instance.y_label > 0)?"right":"wrong", 
                instance.y_label, result);
    }

    fprintf(stderr, " 1 recall %f, precision %f\n", 
            eval_tp/(double)(eval_tp+eval_tn), eval_tp/(double)(eval_tp+eval_fp));
    fprintf(stderr, "-1 recall %f, precision %f\n",
            eval_fn/(double)(eval_fn+eval_tn), eval_fn/(double)(eval_fn+eval_fp));

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x26e2
movq 0x5917(%rip), %rax      # 0x7fd8
movq (%rax), %rdi
movq -0x10(%rbp), %rdx
leaq 0x2959(%rip), %rsi      # 0x5028
movb $0x0, %al
callq 0x2240
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2a46
movq -0x10(%rbp), %rdi
leaq 0x294d(%rip), %rsi      # 0x503a
callq 0x21e0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x2725
movq 0x58d4(%rip), %rax      # 0x7fd8
movq (%rax), %rdi
movq -0x10(%rbp), %rdx
leaq 0x292a(%rip), %rsi      # 0x503c
movb $0x0, %al
callq 0x2240
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2a46
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movl $0x0, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x20(%rbp), %rdx
leaq -0x28(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x2220
movq %rax, -0x58(%rbp)
cmpq $-0x1, %rax
je 0x29c3
cmpq $0x1, -0x58(%rbp)
jle 0x27b5
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
subq $0x2, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0xd, %eax
jne 0x27b5
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
subq $0x2, %rcx
movb $0x0, (%rax,%rcx)
jmp 0x27f8
cmpq $0x0, -0x58(%rbp)
jle 0x27f6
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
subq $0x1, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0xd, %eax
je 0x27e6
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
subq $0x1, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0xa, %eax
jne 0x27f6
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
subq $0x1, %rcx
movb $0x0, (%rax,%rcx)
jmp 0x27f8
leaq -0x78(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0x2bf0
movq -0xa8(%rbp), %rsi
movq -0x28(%rbp), %rdi
leaq -0x3c(%rbp), %rdx
callq 0x3b50
movl %eax, -0x9c(%rbp)
jmp 0x2824
movl -0x9c(%rbp), %eax
movl %eax, -0x7c(%rbp)
cmpl $0x0, -0x7c(%rbp)
je 0x287e
movq 0x579e(%rip), %rax      # 0x7fd8
movq (%rax), %rdi
movq -0x28(%rbp), %rdx
leaq 0x280e(%rip), %rsi      # 0x5056
movb $0x0, %al
callq 0x2240
movl $0x2, -0x90(%rbp)
jmp 0x2999
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x2c10
jmp 0x2a52
movq -0x18(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x3ab0
movsd %xmm0, -0xb0(%rbp)
jmp 0x2895
movsd -0xb0(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x78(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x28cd
movsd -0x98(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x28cd
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x78(%rbp), %xmm0
jbe 0x28ed
xorps %xmm0, %xmm0
ucomisd -0x98(%rbp), %xmm0
jbe 0x28ed
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
movsd -0x78(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2911
xorps %xmm0, %xmm0
ucomisd -0x98(%rbp), %xmm0
jbe 0x2911
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x78(%rbp), %xmm0
jbe 0x2935
movsd -0x98(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2935
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
movsd -0x98(%rbp), %xmm0
mulsd -0x78(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x295b
leaq 0x2723(%rip), %rax      # 0x5075
movq %rax, -0xb8(%rbp)
jmp 0x296b
leaq 0x2719(%rip), %rax      # 0x507b
movq %rax, -0xb8(%rbp)
jmp 0x296b
movq -0xb8(%rbp), %rsi
movsd -0x78(%rbp), %xmm0
movsd -0x98(%rbp), %xmm1
leaq 0x26e5(%rip), %rdi      # 0x506b
movb $0x2, %al
callq 0x2030
jmp 0x298f
movl $0x0, -0x90(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x2c10
movl -0x90(%rbp), %eax
testl %eax, %eax
je 0x29b0
jmp 0x29ae
jmp 0x29c3
jmp 0x29b2
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x2768
movq 0x560e(%rip), %rax      # 0x7fd8
movq (%rax), %rdi
cvtsi2sdl -0x40(%rbp), %xmm0
movl -0x40(%rbp), %eax
addl -0x48(%rbp), %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
cvtsi2sdl -0x40(%rbp), %xmm1
movl -0x40(%rbp), %eax
addl -0x4c(%rbp), %eax
cvtsi2sd %eax, %xmm2
divsd %xmm2, %xmm1
leaq 0x2687(%rip), %rsi      # 0x5081
movb $0x2, %al
callq 0x2240
movq 0x55d0(%rip), %rax      # 0x7fd8
movq (%rax), %rdi
cvtsi2sdl -0x44(%rbp), %xmm0
movl -0x44(%rbp), %eax
addl -0x48(%rbp), %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
cvtsi2sdl -0x44(%rbp), %xmm1
movl -0x44(%rbp), %eax
addl -0x4c(%rbp), %eax
cvtsi2sd %eax, %xmm2
divsd %xmm2, %xmm1
leaq 0x2665(%rip), %rsi      # 0x509d
movb $0x2, %al
callq 0x2240
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xc0, %rsp
popq %rbp
retq
movq -0x88(%rbp), %rdi
callq 0x22b0
nop