--- /dev/null
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cmath>
+#include <fstream>
+
+#include <omp.h>
+
+typedef std::vector< float > TimeSerieType;
+typedef std::pair< unsigned int , float> DistanceIndexType;
+
+#pragma omp declare simd
+float distsq(float x, float y)
+{
+ return (x-y) * (x-y);
+}
+
+#pragma omp declare simd
+bool DistancePairComp (const DistanceIndexType &x, const DistanceIndexType &y)
+{
+ return x.second < y.second;
+}
+
+float EuclidianDistanceTimeSerie( const TimeSerieType &a, const TimeSerieType &b)
+{
+ float dist = 0;
+ unsigned int n = a.size();
+ #pragma omp parallel for simd reduction(+:dist) schedule(simd:static, 5)
+ for (unsigned int i=0; i<n ; i++)
+ dist += distsq( a[i], b[i]) ;
+
+ return std::sqrt(dist);
+}
+
+
+int main(int argc, char *argv[])
+{
+std::vector< TimeSerieType > ClassSeries;
+std::vector< unsigned int > ClassLabels;
+std::vector< unsigned int > ClassEffectif;
+
+unsigned int K = 5;
+unsigned int N = 2;
+std::cout << "argv[1] : csv filemane " << std::endl;
+std::cout << "argv[2] : K the number of neigboors" << std::endl;
+std::cout << "argv[3] : N the minimum effectif of classes "<< std::endl;
+
+///////////////////////////////////////////////////////////////
+/// \brief reading csv file
+///////////////////////////////////////////////////////////////
+std::ifstream ifs;
+ifs.open (argv[1], std::ifstream::in);
+std::cout << "argv[1] : csv filemane = " << argv[1] << std::endl;
+
+
+std::string ID_str, Effectif_str, Value_str;
+
+std::string::size_type sz = 0; // use to identify the endline
+while( ifs.good() )
+{
+ if(sz == 0) std::getline(ifs, ID_str, ',');
+// std::cout << ID_str << " " ;
+ ClassLabels.push_back( std::stof(ID_str) );
+
+ std::getline(ifs, Effectif_str, ',');
+ // std::cout << Effectif_str << " " ;
+ ClassEffectif.push_back( std::stof(Effectif_str) );
+
+ TimeSerieType tmpSerie;
+ int a;
+ do
+ {
+ std::getline(ifs, Value_str, ',');
+// std::cout << Value_str << " " ;
+ a= Value_str.find('\n');
+ tmpSerie.push_back( std::stof(Value_str, &sz) );
+ } while( a == -1 );
+// std::cout << std::endl;
+ ClassSeries.push_back( tmpSerie );
+ ID_str = Value_str.substr(sz+1); // " 2\n12" -> "12"
+}
+ifs.close();
+///////////////////////////////////////////////////////////////
+
+
+std::cout << " starting analysis " << std::endl;
+///////////////////////////////////////////////////////////////
+/// \brief compute k nearest neigboor of each entry (effectif > N)
+///////////////////////////////////////////////////////////////
+for(unsigned int i=0; i<ClassSeries.size(); i++)
+{
+
+ if( ClassEffectif[i] > N ) // if class's cardinal is > to N
+ {
+ std::vector< DistanceIndexType > DistanceToSeries(ClassSeries.size()) ; // we will use the current sample to validate (so sizes are the same)
+ unsigned int n= ClassSeries.size();
+ #pragma omp parallel for shared(DistanceToSeries)
+ for(unsigned int j=0; j<n; j++) // compute each distance
+ {
+ DistanceIndexType tmp;
+ tmp.first = ClassLabels[j];
+ tmp.second = EuclidianDistanceTimeSerie( ClassSeries[i], ClassSeries[j]);
+ DistanceToSeries[j] = tmp;
+ }
+
+ // now sort the vector DistanceToSeries according to ::second
+ std::sort(DistanceToSeries.begin(), DistanceToSeries.end(), DistancePairComp);
+
+ // copy 2 to K in a file
+ std::cout << " [" << ClassLabels[i] << "] : ";
+ for( unsigned int j=0 ; j<K; j++)
+ std::cout << DistanceToSeries[j].first << " - ";
+ std::cout << std::endl;
+ //std::cin.get();
+ }
+ else { std::cout << " [" << ClassLabels[i] << "] : X " << std::endl; }
+
+}
+
+return 0;
+}