/*----------------------------MegaWave2 module----------------------------*/
/* mwcommand
name = {nn_image};
version = {"1.0"};
author = {"Lionel Moisan"};
function = {"Image classification using nearest neighbor"};
usage = {
 train->train       "training set (Cmovie)",
 labels->labels     "labels for training set (Fsignal)",
 test->test         "test set (Cmovie)",
 classif<-nn_image  "output estimated labels for test set (Fsignal)",
 {
   true->true    "true labels (Fsignal) for test set (performance evaluation)",
   error<-error  "output: error made on test set"
 }
        };
*/
 
#include <stdio.h>
#include <math.h>
#include "mw.h"


double dist(u,v)
     Cimage u,v;
{
  double d,e;
  int i;
  
  for (d=0.,i=u->nrow*u->ncol;i--;) {
    e = (double)u->gray[i]-(double)v->gray[i];
    d += e*e;
  }

  return(d);
}


/*------------------------------ MAIN MODULE ------------------------------*/

Fsignal nn_image(train,labels,test,true,error)
     Cmovie train,test;
     Fsignal labels,true;
     float *error;
{
  Fsignal classif;
  Cimage u,v;
  int k,i,imin;
  double d,dmin;

  /* size of test set */
  for (u=test->first,k=0;u;u=u->next,k++);
  classif = mw_change_fsignal(NULL,k);
  if (true) *error=0.;

  /* loop on test images */
  for (u=test->first,k=0;u;u=u->next,k++) {

    /* look for nearest training image */
    for (v=train->first,i=0;v;v=v->next,i++) {
      d = dist(u,v);
      if (i==0 || d<dmin) {
	dmin = d;
	imin = i;
      }
    }

    classif->values[k] = labels->values[imin];
    if (true) *error += (classif->values[k]!=true->values[k]?1.:0.);
  }
  if (true) *error/=(float)k;
  
  return(classif);
}
