/*
  Copyright(C) 2007-2012 National Institute of Information and Communications Technology
*/

/*
  svmtools
  Classification program
*/


#include <stdio.h>
#include <stdlib.h>
#include "exception.h"
#include "svm_common.h"


int main(int argc, char **argv) {
  int i;
  char *exmfile, *mdlfile, *outfile;
  FILE *fp;
  SVM_EXM *exm;
  SVM_MDL *mdl;
  int cnt_cor, cnt_cap, cnt_sys, cnt_gld;
  int count;
  double p, r, f;

  /* 引数の処理 */
  if (argc != 3 && argc != 4) {
    fprintf(stderr, "usage: %s <example file> <model file> [<output file>]\n", argv[0]);
    return 1;
  }
  exmfile = argv[1];
  mdlfile = argv[2];
  outfile = (argc == 4) ? argv[3] : NULL;

  /* テストデータの読み込み */
  fprintf(stderr, "Reading the example file... ");
  fp = fopen(exmfile, "rt");
  exception(fp == NULL, "cannot open the example file '%s'", exmfile);
  exm = svm_readexm(fp);
  exception(exm == NULL, "cannot read the example file '%s'", exmfile);
  fclose(fp);
  fprintf(stderr, "done (%d examples).\n", exm->num);

  /* モデルデータの読み込み */
  fprintf(stderr, "Reading the model file... ");
  fp = fopen(mdlfile, "rt");
  exception(fp == NULL, "cannot open the model file '%s'", mdlfile);
  mdl = svm_readmdl(fp);
  exception(mdl == NULL, "cannot read the model file '%s'", mdlfile);
  fclose(fp);
  fprintf(stderr, "done (%d SVs).\n", mdl->num);

  /* output fileのopen */
  if (outfile != NULL) {
    fp = fopen(outfile, "wt");
    exception(fp == NULL, "cannot open the output file '%s'", outfile);
  } else {
    fp = NULL;
  }

  /* 分類 */
  cnt_cor = 0;
  cnt_cap = 0;
  cnt_sys = 0;
  cnt_gld = 0;
  fprintf(stderr, "Classifying... ");
  for (i = 0, count = 1; i < exm->num; i++) {
    double d;

    d = svm_decision(mdl, exm->sv[i]);
    if (outfile != NULL) fprintf(fp, "%.7g\n", d);
    if (d * exm->label[i] > 0) cnt_cor++;
    if (d > 0.0 && exm->label[i] > 0) cnt_cap++;
    if (d > 0.0) cnt_sys++;
    if (exm->label[i] > 0) cnt_gld++;

    if (i + 1 == count) {
      fprintf(stderr, "%d ", i + 1);
      count *= 10;
    }
  }
  fprintf(stderr, "done.\n");
  if (outfile != NULL) fclose(fp);

  /* 結果表示 */
  printf("Accuracy:  %6.2f%%(%6d/%6d)\n", (exm->num > 0) ? (double)cnt_cor / exm->num * 100.0 : 0.0, cnt_cor, exm->num);

  p = (cnt_sys > 0) ? (double)cnt_cap / cnt_sys : 0.0;
  r = (cnt_gld > 0) ? (double)cnt_cap / cnt_gld : 0.0;
  f = (p + r > 0.0) ? 2.0 * p * r / (p + r) : 0.0;

  printf("Precision: %6.2f%%(%6d/%6d)\n", p * 100.0, cnt_cap, cnt_sys);
  printf("Recall:    %6.2f%%(%6d/%6d)\n", r * 100.0, cnt_cap, cnt_gld);
  printf("F-measure: %6.2f%%\n", f * 100.0);

  return 0;
}
