#ifndef NN_H
#define NN_H

#include <stdlib.h>
#include <stdio.h>

#define SORT_ASCENDING 1
#define SORT_DESCENDING 2

#define DIST_SQUARED_EUCLIDEAN 1
#define DIST_EUCLIDEAN 2


/*NN*/

typedef struct
{
  int n; /*number of examples*/
  int d; /*number of variables*/
  double **x; /*the data*/
  int *y; /*their classes*/
  int nclasses; /*the number of classes*/
  int *classes; /*the classes*/;
  int k;  /*number of nn (for the test phase)*/
  int dist;  /*type of distance (for the test phase)*/
} NearestNeighbor;


/***************
FUNCTIONS
***************/

/*memory*/
int *ivector(long n);
double *dvector(long n);
double **dmatrix(long n, long m);
int **imatrix(long n, long m);
int free_ivector(int *v);
int free_dvector(double *v);
int free_dmatrix(double **M, long n, long m);
int free_imatrix(int **M, long n, long m);

/*sorting*/
void dsort(double a[], int ib[],int n, int action);
void isort(int a[], int ib[],int n, int action);

/*unique*/
int iunique(int y[], int n, int **values);
int dunique(double y[], int n, double **values);

/*distance*/
double l1_distance(double x[],double y[],int n);
double euclidean_squared_distance(double x[],double y[],int n);
double euclidean_distance(double x[],double y[],int n);
double scalar_product(double x[],double y[],int n);
double euclidean_norm(double x[],int n);

/*nn*/
int compute_nn(NearestNeighbor *nn,int n,int d,double *x[],int y[],
	       int k, int dist);
int predict_nn(NearestNeighbor *nn, double x[],double **margin);

#endif /* NN_H */
