Exemple #1
0
inline const auto
join_rows(const Base<typename T1::elem_type,T1>& A,
          const Base<typename T1::elem_type,T2>& B,
          const Base<typename T1::elem_type,T3>& C)
{
    return join_rows(join_rows(A, B), C);
}
Exemple #2
0
    KUKADU_SHARED_PTR<Dmp> GeneralDmpLearner::fitTrajectories() {

        int dataPointsNum = joints.n_rows;

        vec g(degFreedom);
        vec y0(degFreedom);
        vec dy0(degFreedom);
        vec ddy0(degFreedom);

        vector<vec> dmpCoeffs;
        vector<vec> sampleYs;
        vector<vec> fitYs;

        vector<mat> designMatrices;
        vec timeVec = joints.col(0);

        mat all_y;
        mat all_dy;
        mat all_ddy;

        // retrieve all columns for different degrees of freedom
        vector<vec> trajectories;
        for(int i = 1; i <= degFreedom; ++i) {

            vec trajectory = joints.col(i);
            trajectories.push_back(trajectory);

            vec vec_dy = computeDiscreteDerivatives(timeVec, trajectory);
            vec vec_ddy = computeDiscreteDerivatives(timeVec, vec_dy);

            all_y = join_rows(all_y, trajectory);
            all_dy = join_rows(all_dy, vec_dy);
            all_ddy = join_rows(all_ddy, vec_ddy);

        }

        vector<trajectory_learner_internal> dmpResAll = fitTrajectory(timeVec, all_y, all_dy, all_ddy);

        for(int i = 0; i < dmpResAll.size(); ++i) {

            trajectory_learner_internal dmpRes = dmpResAll.at(i);
            vec dmpCoeff = dmpRes.coeff;
            vec fity = dmpRes.fity;

            g(i) = (all_y.col(i))(dataPointsNum - 1);
            y0(i) = all_y.col(i)(0);
            dy0(i) = all_dy.col(i)(0);
            ddy0(i) = all_ddy.col(i)(0);
            dmpCoeffs.push_back(dmpCoeff);

            fitYs.push_back(fity);
            designMatrices.push_back(dmpRes.desMat);

        }

        for (int i = 0; i < all_y.n_cols; ++i) sampleYs.push_back(all_y.col(i));
        return createDmpInstance(timeVec, sampleYs, fitYs, dmpCoeffs, dmpBase, designMatrices, tau, az, bz, ax);

    }
    arma::mat CartesianDMPLearner::computeFitY(arma::vec& time, arma::mat &y, arma::mat &dy, arma::mat &ddy, arma::vec& vec_g) {

        // position
        mat retMat(y.n_cols - 1, y.n_rows);

        for(int i = 0; i < y.n_rows; ++i) {

            for(int j = 0; j < 3; ++j) {

                double yVal = y(i, j);
                double dyVal = dy(i, j);
                double ddyVal = ddy(i, j);
                retMat(j, i) = /*1 / (vec_g(j) - y(0, j)) */ tau * tau * ddyVal - az * (bz * (vec_g(j) - yVal) - tau * dyVal);

            }

        }

        // orientation
        arma::mat omega(y.n_rows, 3);
        arma::mat domega;
        arma::mat eta;
        arma::mat deta;

        for (int j = 0; j < y.n_rows - 1; ++j) {

            vec logL= log(tf::Quaternion(y(j + 1, 3), y(j + 1,  4), y(j + 1, 5), y(j + 1, 6)) * tf::Quaternion(y(j, 3), y(j, 4), y(j, 5), y(j, 6)).inverse());

            for (int i = 0; i < 3; i++)
                omega(j, i) = 2 * logL(i) / (time(1)-time(0));

            if (j == y.n_rows - 2)
                for (int i = 0; i < 3; i++)
                    omega(y.n_rows - 1, i) = 2 * logL(i) / (time(1)-time(0));

        }

        for(int i = 0; i < 3 ; ++i) {

            vec trajectory = omega.col(i);
            vec domegaV = computeDiscreteDerivatives(time, trajectory);
            domega = join_rows(domega, domegaV);

        }


        eta = tau * omega;
        deta = tau * domega;

        for (int i = 0; i < y.n_rows; ++i) {

            vec logL = log(tf::Quaternion(vec_g(3), vec_g(4), vec_g(5), vec_g(6)) * tf::Quaternion(y(i, 3), y(i, 4), y(i, 5), y(i, 6)).inverse());
            for (int j = 3; j < retMat.n_rows; ++j)
                retMat(j, i) = tau * deta (i, j - 3) - az * (bz * 2 * logL(j - 3) - eta(i, j - 3));

        }

        return retMat;

    }
// The step size should be chosen carefully to guarantee convergence given a 
// reasonable number of computations.
int GradientDescent::RunGradientDescent(const Data &data) {
  assert(num_iters_ >= 1);
  const int kNumTrainEx = data.num_train_ex();
  assert(kNumTrainEx >= 1);
  const arma::mat kTrainingFeatures = data.training_features();
  const arma::vec kTrainingLabels = data.training_labels();

  double *j_theta_array = new double[num_iters_];

  // Recall that we are trying to minimize the following cost function:
  // ((training features) * (current weights) - (training labels))^2
  // Each iteration of this algorithm updates the weights as a scaled 
  // version of the gradient of this cost function.
  // This gradient is computed with respect to the weights.
  // Thus, each iteration of gradient descent performs the following:
  // (update) = (step size) * ((training features) * (current weights) - (training labels)) * (training features)
  // (new weights) = (current weights) - (update)
  for(int theta_index=0; theta_index<num_iters_; theta_index++)
  {
    const arma::vec kDiffVec = kTrainingFeatures*theta_-kTrainingLabels;
    const arma::mat kDiffVecTimesTrainFeat = \
      join_rows(kDiffVec % kTrainingFeatures.col(0),\
      kDiffVec % kTrainingFeatures.col(1));
    const arma::vec kThetaNew = theta_-alpha_*(1/(float)kNumTrainEx)*\
      (sum(kDiffVecTimesTrainFeat)).t();
    j_theta_array[theta_index] = ComputeCost(data);
    set_theta(kThetaNew);
  }

  delete [] j_theta_array;

  return 0;
}
Exemple #5
0
SCVectorizedMat Converter::multiGray2SCMat(char* dirpath){
    /**
    * Vectorize and concatenate multiple images.
    */
    SCVectorizedMat data;
    path p(dirpath);

    if (exists(p) && is_directory(p)){
        for (directory_entry& x : directory_iterator(p)){
            if (is_regular_file(x.path())){
                string path = x.path().string();
                if (path.find( ".DS_Store" ) != string::npos )
                    continue;
                SCMat frame = readGray2SCMat(path);
                cout << path << endl;
                frame.gray.reshape(frame.rows * frame.cols, 1);
                if (data.nMat == 0) {
                    data.rows = frame.rows;
                    data.cols = frame.cols;
                    data.gray = frame.gray;
                    data.nMat ++;
                }
                else{
                    data.gray = join_rows(data.gray, frame.gray);
                    data.nMat ++;
                }
            }
        }
    }
    return data;
}
Exemple #6
0
/*
    "getBestStump()" function saves the best decision stump's threshold, weak hypothesis and its error;
*/
void DSC::getBestStump(Threshold &threshold, ivec &hypothesis, double &error)
{
    /* Separating weights by classes: */
    mat class1Weights = weights(find(classes == -1));
    mat class2Weights = weights(find(classes == +1));

    /* Accumulate weights for given thresholds ("number of thresholds" x "number of features"): */
    mat thresholdWeights1 = accumarray(join_rows(class1Thresholds, featureIndexes1),
                                       repmat(class1Weights, features.n_cols, 1),
                                       SizeMat(N_THRESHOLDS, features.n_cols));
    mat thresholdWeights2 = accumarray(join_rows(class2Thresholds, featureIndexes2),
                                       repmat(class2Weights, features.n_cols, 1),
                                       SizeMat(N_THRESHOLDS, features.n_cols));

    /*
        Looking for threshold with minimum error;
        Here we construct cummulative sum of weights for seaprate classes, then we add them;
        In order to find the smallest error, we consider both directions of a threshold;
    */
    mat thresholdErrors = flipud(cumsum(flipud(thresholdWeights1))) + cumsum(thresholdWeights2);
    thresholdErrors = join_cols(thresholdErrors, sum(weights) - thresholdErrors);
    uword index;
    uword featureType;
    error = thresholdErrors.min(index, featureType);
    threshold.featureType = featureType;
    if (index > N_THRESHOLDS - 1)
    {
        threshold.direction = -1;
        index -= N_THRESHOLDS;
    }
    else
    {
        threshold.direction = +1;
    }

    threshold.value = minFeatures(featureType) + (ranges(featureType) / N_THRESHOLDS) * index;

    /* Evaluating hypothesis for derived threshold: */
    classify(threshold, features, hypothesis);

    return;
}
Exemple #7
0
inline const Glue<T, U..., glue_join> join_rows(const Base<typename T::elem_type,T>& A,
                                                const Base<typename T::elem_type,U...>&... B)
{
    return join_rows(A,
                     join_rows(B...));
}
Exemple #8
0
double Controller::update(Angle angle, double speed, double inReward, vec inLmr, int color) {
	if(t%inv_sampling_rate == 0 && !SILENT){
		pi_array = join_rows(pi_array, pin->get_output());
		if(gvlearn_on){
			gv_array = join_rows(gv_array, gvl->w(0));
		}
		if(lvlearn_on){
			for(int i = 0; i < lv_array.size(); i++)
				lv_array.at(i) = join_rows(lv_array.at(i), lvl->w(i));
			ref_array = join_rows(ref_array, lvl->RefPI());
		}
	}
	t++;

	/*** Check, if inward ***/
	if(t > t_home || accum_reward(0) > 1.){
		inward = 1.;
		//printf("t= %u > %u or sum(R)= %g\n", t, t_home, accum_reward(0));
	}

	/*** Path Integration Mechanism ***/
	if(pin_on)
		pin->update(angle, speed);

	if(gvlearn_on && gl_w > 0.)
		pi_w = HV().len() * (1. - expl_factor(0))*(1.-accu(lv_value));
	else
		pi_w = 0.0;
	pi_m =  ((HV().ang()).i() - angle).S();		//NEW PI COMMAND
	if(homing_on && inward!=0.){
		//printf("this should not be! %g\n", inward);
		pi_w = 0.5;
		pi_m = ((HV().ang()).i() - angle).S();
		rand_m = 0.0;//0.25;
	}
	if(pi_w < 0.)
		pi_w = 0.;
	output_hv = pi_w * pi_m;



	/*** Reward and value update ***/
	if(lvlearn_on){
		for(int i = 0; i < num_lv_units; i++)
			lv_value(i) = 1. - exp(-0.5*lvl->eligibility_value(i));
	}
	delta_beta = mu_beta*((1./expl_beta) + lambda * value(0) * expl_factor(0));
	if(beta_on)
		expl_beta += delta_beta;
	if(expl_factor(0) < 0.0001 && delta_beta < 0.01)
		beta_on = false;

	for(int i = 0; i < num_colors; i++){
		if(i == color){
			reward(i) = inReward;
			if(inward==0.){
				value(i) = (reward(i) /*+ accu(lv_value)*/) + disc_factor * value(i);
				if(!const_expl)
					expl_factor(i) = exp(- expl_beta * value(i));
				else
					expl_factor(i) += d_expl_factor(i);
				expl_factor.elem( find(expl_factor > 1.) ).ones();    //clip expl
				expl_factor.elem( find(expl_factor < 0.) ).zeros();   //clip expl
			}
		}
		else{
			reward(i) = 0.0;
		}
	}
	accum_reward += reward;

	/*** Global Vector Learning Circuits TODO ***/
	if(gvlearn_on){
		for(int i = 0; i < num_colors; i++){
			gvl->update(pin->get_output(), reward(i), expl_factor(i));
			cGV.at(i) = (GV(i) - HV());
		}

		gl_w = (1. - inward)*GV(0).len() * (1.-expl_factor(0));
		gl_m = (GV(0).ang() - angle).S();			//NEW GV COMMAND
	}
	//stream << cGV.at(0).ang().deg() << endl;
	output_gv = gl_w * gl_m;

	/*** Local Vector Learning Circuits TODO ***/
	if(lvlearn_on){

		lvl->update(angle, speed, inReward, inLmr);

		rl_m = 0.0;
		rl_w = (1. - inward);
		for(int i = 0; i < num_lv_units; i++){
			//cLV.at(i) = (LV(i) - HV());
			if(inward == 0.){
				gl_w = 0.0;
				pi_w = 0.0;
				rl_m += lv_value(i) * (LV().len()*(LV().ang() - angle).S() + RV().len()*(RV().ang().i() - angle).S());
			}
		}
		//if(VERBOSE && t%100==0)
			//printf("t = %u\tHV = (%f, %f)\tLV = (%f, %f)\tRV = (%f, %f)\n", t, HV().ang().deg(), HV().len(), LV().ang().deg(), LV().len(), RV().ang().deg(), RV().len());
		output_lv = rl_w * rl_m;
	}
	else
		output_lv = 0.;

	/*** Random foraging ***/
	if(lvlearn_on){
		rand_w = (1. - inward)*0.6*expl_factor(0)*(1.-accu(lv_value));
	}
	else
		rand_w = (1. - inward)*0.6*expl_factor(0);
	rand_m = randn(0.0, 1.);
	if(inward == 1)
		rand_m = 0.;

	output_rand = rand_w * rand_m;

	/*** Navigation Control Output ***/
	output = output_rand + output_hv + output_gv + output_lv;
	//output = output_rand + output_hv + 0.0 + output_lv; // Route formation

	return output;
}
Exemple #9
0
void Device2D::matrixDiff_2D() {
	int numBlock = dev1DList.size();
	// initialize the matrixC2D;
	mat matrixC2D(dev1DList[0].getMatrixC()); // has to make it dense mat to use join_rows/join_cols
	// TODO: was j= 0
	for (int j = 0; j < numBlock; j++) {
		std::cout << "Constructing differential matrix @ Block #" << j+1 << "; sumPoint = " << dev1DList[j].getSumPoint()
				<< " * " << nxList[j] << std::endl;
		dev1DList[j].matrixDiff();
		mat matrixC1D(dev1DList[j].getMatrixC());
		// std::cout << matrixC1D.size() << std::endl;
		for (int i=0; i < nxList[j]; i++) {
			matrixC2D=join_cols( join_rows(matrixC2D, zeros(matrixC2D.n_rows, dev1DList[j].getSumPoint())),
					join_rows(zeros(dev1DList[j].getSumPoint(), matrixC2D.n_cols), matrixC1D) );
		}
	}

	// initialize the C_L
	// was sumPointLateral * unitSize, here sumPoint = sumPointLateral * unitSize
	mat C_L = zeros(sumPoint, sumPoint);
	// similar to Device1D 1 => unitSize
    for ( int i=unitSize; i< sumPoint + unitSize; i++) {
        for ( int j=unitSize; j< sumPoint + unitSize; j++) {
            if (i==j) {
                C_L(i-unitSize,j-unitSize)= - 2*dieleArrayIP[i]/( spacingArrayIP[i]*( spacingArrayIP[i]+spacingArrayIP[i-unitSize] ) )
                 - 2*dieleArrayIP[i-unitSize]/( spacingArrayIP[i]*( spacingArrayIP[i]+spacingArrayIP[i-unitSize] ) );
            } else if (j==i-unitSize) {
                C_L(i-unitSize,j-unitSize)=2*dieleArrayIP[i-unitSize]/( spacingArrayIP[i]*( spacingArrayIP[i]+spacingArrayIP[i-unitSize] ) );
            } else if (j==i+unitSize) {
                C_L(i-unitSize,j-unitSize)=2*dieleArrayIP[i]/( spacingArrayIP[i]*( spacingArrayIP[i]+spacingArrayIP[i-unitSize] ) );
            }
        }
    }
    // Lateral boundary
    // boundary condition can differ at the semi and at the dielectric, apply point by point at right and left edge.

    /* IMPORTANT: Ohmic -> Neumann; Schottchy -> Dirichlet
     *
     * TODO: implement Schottchy: 1. add workfucntion for contact metal in input file;
     * 							  2. add this workfunction to boundary;
     * 							  3. Vds apply to boundary condition array instead of VdsArray (see notebook IV)
    */

    for (int i = 0; i < unitSize; i++) {
    	// left boundary
    	if ( leftBTArray[i] == Dirichlet ) {
    		C_L(i,unitSize + i)=LARGE;
    	} else if ( leftBTArray[i] == Neumann) {
    		C_L(i,unitSize + i)= - C_L(i,i);
    	} else {
    		std::cerr << "Error: left boundary type not found." << std::endl;
    	}
    	// right boundary
    	if ( rightBTArray[i] == Dirichlet ) {
    		C_L(i + sumPoint - unitSize, i + sumPoint - 2*unitSize) = LARGE;
    	} else if ( rightBTArray[i] == Neumann) {
    		C_L(i + sumPoint - unitSize, i + sumPoint - 2*unitSize) = -C_L(i + sumPoint - unitSize, i + sumPoint - unitSize);
    	} else {
    		std::cerr << "Error: right boundary type not found." << std::endl;
    	}
    }
    // std::cout << matrixC2D.size() << ", " << C_L.size() << std::endl;
    sp_mat tempMatrixC(matrixC2D + C_L);
    matrixC = tempMatrixC;
}
//Testing
inline
void
BoW::create_histograms_testing(int N_cent, const string path_run_folders, int segm_length) 
{
  
  //prepare BOW descriptor extractor from the dictionary    
  cv::Mat dictionary; 
  std::stringstream name_vocabulary;
  name_vocabulary << "./run"<< run <<"/visual_vocabulary/means_Ng" << N_cent << "_dim" <<dim << "_all_sc" << ".yml"; 
  cout << name_vocabulary.str() << endl;
  cv::FileStorage fs(name_vocabulary.str(), cv::FileStorage::READ);
  fs["vocabulary"] >> dictionary;
  fs.release();    
  //cout << "Loaded" << endl;
  
  
  
  mat multi_features;
  vec real_labels, fr_idx, fr_idx_2;
  
  for (uword sc = 1 ; sc <= 4;  ++sc) 
  { 
    for (uword pe=0; pe<peo_test.n_rows; ++pe)    
    {
      
      //Loading matrix with all features (for all frames)
      std::stringstream ssName_feat_video;
      //ssName_feat_video << "./run"<< run <<"/features/train/feat_vec" << peo_train(pe) << "_" << actions(act) << "_d" << sc;
      ssName_feat_video << path_run_folders << "/run" << run <<  "/multi_features/feat_" << peo_test(pe) << "_d" << sc << ".dat";
      multi_features.load( ssName_feat_video.str() );
            cout << ssName_feat_video.str()  << endl;

      
      //Loading labels. In a frame basis
      std::stringstream ssload_name_lab;       
      ssload_name_lab << path_run_folders << "/run" << run <<  "/multi_features/lab_" << peo_test(pe) << "_d" << sc << ".dat";
      real_labels.load( ssload_name_lab.str() );
      int n_frames = real_labels.n_elem;
      
      //Loading frame index for each of the feature vector in feat_video
      
      std::stringstream ssload_name_fr_idx;
      
      ssload_name_fr_idx << path_run_folders << "/run" << run <<  "/multi_features/fr_idx_" << peo_test(pe) << "_d" <<  sc << ".dat";
      fr_idx.load( ssload_name_fr_idx.str() );  // Solo uso las pares: 2,4,6...
      fr_idx_2 = fr_idx/2; // Empieza en uno
      
      
      for (int f=1; f<=n_frames - segm_length; ++f)
      {
	int ini = f;
	int fin = ini + segm_length; 
	mat feat_frame_fr;
	
	for (int i=ini; i<=fin; ++i)
	{
	  
	  uvec q1 = find(fr_idx_2 == i);
	  //cout << "ini " << ini << ". q1 " << q1.n_elem << endl;
	  //getchar();
	  mat sub_multi_features;
	  sub_multi_features = multi_features.cols(q1);
	  feat_frame_fr = join_rows( feat_frame_fr, sub_multi_features );
	}
	
	//Aqui Obtener el histogram y guardarlo!!!!!!!!!!!!!!!
	
	fmat f_feat_frame_fr = conv_to< fmat >::from(feat_frame_fr);
	feat_frame_fr.reset();
	
	
	cv::Mat features_segm_f_OpenCV(f_feat_frame_fr.n_cols, dim, CV_32FC1, f_feat_frame_fr.memptr() );
	
	
	int rows = features_segm_f_OpenCV.rows;
	int cols = features_segm_f_OpenCV.cols;
	
	//cout << "Features rows & cols " << rows << " & " << cols << endl;
	
	
	// init the matcher with you pre-trained codebook
	cv::Ptr<cv::DescriptorMatcher > matcher = new cv::BFMatcher(cv::NORM_L2);
	matcher->add(std::vector<cv::Mat>(1, dictionary));
	
	
	// matches
	std::vector<cv::DMatch> matches;	 
	
	matcher->match(features_segm_f_OpenCV,matches);
	
	//cout << matches.size() << endl;
	//Mira aqui: http://ttic.uchicago.edu/~mostajabi/Tutorial.html
	vec hist;
	hist.zeros(N_cent) ;
	
	for (int i=0; i< matches.size(); ++i)
	{
	  int bin =  matches[i].trainIdx ;
	  hist(bin)++;
	}
	

	hist = hist/hist.max();
	std::stringstream ssName_hist;
	ssName_hist << "./run"<<run << "/multi_Histograms_BoW_OpenCV/multi_hist_" << peo_test(pe) << "_d" << sc << "_Ng"<< N_cent << "fr_" << ini << "_"  << fin  << ".h5";
	//cout << ssName_hist.str() << endl;
	hist.save(ssName_hist.str(), hdf5_binary);
      }
    }

  }
  
}
inline
void
BoW::create_vocabulary(int N_cent, const string path_run_folders)
{ 
  
  cout << "Calculating Vocabulary " << endl;
  cout << "# clusters: " << N_cent << endl;
  
  mat uni_features;
  
  for (uword pe=0; pe<peo_train.n_rows; ++pe)    {
    
    mat mat_features_tmp;
    mat mat_features;
    
    for (uword act = 0 ; act < actions.n_rows;  ++act) {
      
      for (uword sc = 1 ; sc <= 4;  ++sc) {
	
	mat mat_features_video_i;
	std::stringstream ssName_feat_video;
	//ssName_feat_video << "./run"<< run <<"/features/train/feat_vec" << peo_train(pe) << "_" << actions(act) << "_d" << sc;
	ssName_feat_video << path_run_folders <<"/features_all_nor/feat_vec_" << peo_train(pe) << "_" << actions(act) << "_d" << sc;
	mat_features_video_i.load( ssName_feat_video.str() );
	
	if ( mat_features_video_i.n_cols>0 )
	{
	  mat_features_tmp	 = join_rows( mat_features_tmp, mat_features_video_i );
	  
	}
	else 
	{
	  cout << "# vectors = 0 in " << ssName_feat_video.str() << endl;
	  
	}
	
      }
      
    }
    
    cout << "mat_features_tmp.n_cols "<< mat_features_tmp.n_cols << endl;   
    const uword N_max = 100000;  // maximum number of vectors per action to create universal GMM
    //const uword N_max = 100000; //???
    if (mat_features_tmp.n_cols > N_max)
    {
      ivec tmp1 = randi( N_max, distr_param(0,mat_features_tmp.n_cols-1) );
      ivec tmp2 = unique(tmp1);
      uvec my_indices = conv_to<uvec>::from(tmp2);
      mat_features = mat_features_tmp.cols(my_indices);  // extract a subset of the columns
      
    }
    else
    {
      mat_features = mat_features_tmp;
      
    }
    
    cout << "mat_features.n_cols "<< mat_features.n_cols << endl;
    
    
    if ( mat_features.n_cols>0 )
    {
      uni_features	 = join_rows( uni_features, mat_features );
      
    }
    else 
    {
      cout << "# vectors = 0 in uni_features" << endl;
      
    }
    
    //uni_features =  join_rows( uni_features, mat_features );
    mat_features_tmp.reset();
    mat_features.reset();
    
    
  }
  
  
  cout << "r&c "<<  uni_features.n_rows << " & " << uni_features.n_cols << endl;
  bool is_finite = uni_features.is_finite();
  
  if (!is_finite )
  {
    cout << "is_finite?? " << is_finite << endl;
    cout << uni_features.n_rows << " " << uni_features.n_cols << endl;
    getchar();
    
  }
  
  

  
  fmat f_uni_features = conv_to< fmat >::from(uni_features);
  //uni_features.reset();
  
  
  cv::Mat featuresUnclustered(f_uni_features.n_cols, dim, CV_32FC1, f_uni_features.memptr() );
  
  //cv::Mat featuresUnclustered( featuresUnclusteredTMP.t() );
  
  int rows = featuresUnclustered.rows;
  int cols = featuresUnclustered.cols;
  
  cout << "OpenCV rows & cols " << rows << " & " << cols << endl;
  //cout << "Press a Key" << endl;
  //getchar();
  
  //cout << f_uni_features.col(1000) << endl;
  //cout << uni_features.col(1000) << endl;
  //cout << featuresUnclustered.row(1000) << endl;
  
  //cout << "Press a Key" << endl;
  //getchar();
  
  
  
  
  
  //Construct BOWKMeansTrainer
  //the number of bags
  int dictionarySize = N_cent;
  
  //define Term Criteria
  cv::TermCriteria tc(CV_TERMCRIT_ITER,100,0.001);
  //retries number
  int retries=1;
  //necessary flags
  int flags=cv::KMEANS_PP_CENTERS;
  //Create the BoW (or BoF) trainer
  cv::BOWKMeansTrainer bowTrainer(dictionarySize,tc,retries,flags);
  //cluster the feature vectors
  cv::Mat dictionary = bowTrainer.cluster(featuresUnclustered);  
  
  //Displaying # of Rows&Cols
  int rows_dic = dictionary.rows;
  int cols_dic = dictionary.cols;
  cout << "OpenCV Dict rows & cols " << rows_dic << " & " << cols_dic << endl;
  
  
  
  
  //store the vocabulary
  std::stringstream name_vocabulary;
  name_vocabulary << "./run"<< run <<"/visual_vocabulary/means_Ng" << N_cent << "_dim" <<dim << "_all_sc" << ".yml"; 
  
  cv::FileStorage fs(name_vocabulary.str(), cv::FileStorage::WRITE);
  fs << "vocabulary" << dictionary;
  fs.release();
  cout << "DONE"<< endl;
  
}
inline
void
BoW::create_universal_gmm(int N_cent, const string path_run_folders)
{ 
  
  cout << "Calculating Universal GMM " << endl;
  cout << "# clusters: " << N_cent << endl;
  
  mat uni_features;
  
   for (uword pe=0; pe<peo_train.n_rows; ++pe)    {
     
     mat mat_features_tmp;
     mat mat_features;
     
     for (uword act = 0 ; act < actions.n_rows;  ++act) {
       
       for (uword sc = 1 ; sc <= 4;  ++sc) {
	 
       mat mat_features_video_i;
       std::stringstream ssName_feat_video;
       //ssName_feat_video << "./run"<< run <<"/features/train/feat_vec" << peo_train(pe) << "_" << actions(act) << "_d" << sc;
       ssName_feat_video << path_run_folders <<"/features_all_nor/feat_vec_" << peo_train(pe) << "_" << actions(act) << "_d" << sc;
       mat_features_video_i.load( ssName_feat_video.str() );
       
       if ( mat_features_video_i.n_cols>0 )
       {
	 mat_features_tmp	 = join_rows( mat_features_tmp, mat_features_video_i );
	 
      }
      else 
      {
	cout << "# vectors = 0 in " << ssName_feat_video.str() << endl;
	
      }
	 
      }
       
    }
    
    cout << "mat_features_tmp.n_cols "<< mat_features_tmp.n_cols << endl;   
    const uword N_max = 100000*4;  // 4 sc. maximum number of vectors per action to create universal GMM
    //const uword N_max = 100000; //???
    if (mat_features_tmp.n_cols > N_max)
    {
      ivec tmp1 = randi( N_max, distr_param(0,mat_features_tmp.n_cols-1) );
      ivec tmp2 = unique(tmp1);
      uvec my_indices = conv_to<uvec>::from(tmp2);
      mat_features = mat_features_tmp.cols(my_indices);  // extract a subset of the columns
      
    }
    else
    {
      mat_features = mat_features_tmp;
      
    }
    
    cout << "mat_features.n_cols "<< mat_features.n_cols << endl;
    
    
      if ( mat_features.n_cols>0 )
      {
	uni_features	 = join_rows( uni_features, mat_features );
	
      }
      else 
      {
	cout << "# vectors = 0 in uni_features" << endl;
	
      }
    
    //uni_features =  join_rows( uni_features, mat_features );
    mat_features_tmp.reset();
    mat_features.reset();
    
    
  }
  
  
  cout << "r&c "<<  uni_features.n_rows << " & " << uni_features.n_cols << endl;
  bool is_finite = uni_features.is_finite();
 
    if (!is_finite )
    {
      cout << "is_finite?? " << is_finite << endl;
      cout << uni_features.n_rows << " " << uni_features.n_cols << endl;
      getchar();
    
    }
  
  
  cout << "universal GMM" << endl;
  gmm_diag gmm_model;
  gmm_diag bg_model;
  
  
  
  bool status_em = false;
  int rep_em=0;
  
  
  int km_iter = 10;
  double var_floor = 1e-10;
  bool print_mode = true;
  
  
  
  
 bool status_kmeans = false;

 int rep_km = 0;
 
 while (!status_kmeans)
 {
   arma_rng::set_seed_random();
   status_kmeans = gmm_model.learn(uni_features, N_cent, eucl_dist, random_subset, km_iter, 0, var_floor, print_mode);   //Only Kmeans
   bg_model = gmm_model;
   
   rep_km++;
    }
    
 
  cout <<"K-means was repeated " << rep_km << endl;
   
  means = gmm_model.means;
 
  
  //Saving statistics

  std::stringstream ss_means;
  ss_means << "./run"<< run <<"/visual_vocabulary/means_Ng" << N_cent << "_dim" <<dim << "_all_sc" << ".dat"; 
  means.save( ss_means.str(), raw_ascii );

}