/*
    This file is part of nncore.
    
    This code is written by Stefano Merler, <merler@fbk.it>.
    (C) 2008 Fondazione Bruno Kessler - Via Santa Croce 77, 38100 Trento, ITALY.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


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

int  iunique(int y[], int n, int **values)
     /*
       extract unique values from a vector y of n integers.
       
       Return value: the number of unique values on success, 0 otherwise.
     */
{
  int nvalues=1;
  int i,j;
  int addclass;
  int *indx;

  if(!(*values=ivector(1))){
    fprintf(stderr,"iunique: out of memory\n");
    return 0;
  }
    
  (*values)[0]=y[0];
  for(i=1;i<n;i++){
    addclass=1;
    for(j=0;j<nvalues;j++)
      if((*values)[j]==y[i])
        addclass=0;
    if(addclass){
      if(!(*values=(int*)realloc(*values,(nvalues+1)*sizeof(int)))){
	fprintf(stderr,"iunique: out of memory\n");
	return 0;
      }
      (*values)[nvalues++]=y[i];
    }
  }

  if(!(indx=ivector(nvalues))){
    fprintf(stderr,"iunique: out of memory\n");
    return 0;
  }

  isort(*values,indx,nvalues,SORT_ASCENDING);

  if(free_ivector(indx)!=0){
    fprintf(stderr,"iunique: free_ivector error\n");
    return 0;
  }

  return nvalues;
}


int  dunique(double y[], int n, double **values)
     /*
       extract unique values from a vector y of n doubles.
       
       Return value: the number of unique values on success, 0 otherwise.
     */
{
  int nvalues=1;
  int i,j;
  int addclass;
  int *indx;

  if(!(*values=dvector(1))){
    fprintf(stderr,"dunique: out of memory\n");
    return 0;
  }
    
  (*values)[0]=y[0];
  for(i=1;i<n;i++){
    addclass=1;
    for(j=0;j<nvalues;j++)
      if((*values)[j]==y[i])
        addclass=0;
    if(addclass){
      if(!(*values=(double*)realloc(*values,(nvalues+1)*sizeof(double)))){
	fprintf(stderr,"dunique: out of memory\n");
	return 0;
      }
      (*values)[nvalues++]=y[i];
    }
  }

  if(!(indx=ivector(nvalues))){
    fprintf(stderr,"iunique: out of memory\n");
    return 0;
  }

  dsort(*values,indx,nvalues,SORT_ASCENDING);

  if(free_ivector(indx)!=0){
    fprintf(stderr,"iunique: free_ivector error\n");
    return 0;
  }

  return nvalues;
}
