void FLIPSolver::constructVelocityGrid() {
  float influence, total_influence;
  bool particle_within_radius;
  std::vector<FLIPVelocityGridPoint>::iterator vi = velocity_grid.grid.begin();
  std::vector<FLIPParticle>::iterator pi;

  while(vi != velocity_grid.grid.end()) {
    particle_within_radius = false;
    total_influence = 0.0f;
    vi->velocity.x = 0.0f;
    vi->velocity.y = 0.0f;
    vi->pressure = 0.0f;
    vi->divergence = 0.0f;

    pi = particles.begin();

    while(pi != particles.end()) {
      influence = getInfluence(vi->position, pi->position);
      total_influence += influence;

      vi->velocity.x += pi->velocity.x * influence;
      vi->velocity.y += pi->velocity.y * influence;
      if (influence > 0.0f) {
        particle_within_radius = true;
      }
      ++pi;
    }

    // if a particle exists in that grid region add density;
    if (particle_within_radius && first_pass) { vi->density = 1.0f; }

    if (total_influence > 0.0f) {
      vi->velocity.scale(1.0f / total_influence);
    }

    ++vi;
  }

  first_pass = false;
}
void SelfOrganizingMaps::train(vector<double> inputVector){
	if(_epochs > _maxEpochs){
		return;
	}

	Neuron *currentNeuron = NULL;
	double distanceToNeuron = 0.0;
	double influence = 0.0;
	double distance = 0;
	double winnerNeuronX = 0.0;
	double winnerNeuronY = 0.0;
	double closestDistance = (255.0 * 255.0) + (255.0 * 255.0) + (255.0 * 255.0);

	// Getting BMU
	for(int row=0; row<_size; row++){
		for(int col=0; col<_size; col++){
			distance = _matrix->getNeuron(row, col)->distanceToInputVector(inputVector);
			if(distance < closestDistance){
				winnerNeuronX = row;
				winnerNeuronY = col;
				closestDistance = distance;
			}
		}
	}

	// Adjusting weigths of neurons
	// Get current Learning Rate scientific method
	double currenLearningRate = getCurrenLearningRate();

	// Get neighbourhood radius scientific method
	double neighbourhoodRadius = getNeighbourhoodRadius();

	// Update the BMU neuron
	_matrix->updateWeightVector(1.0, currenLearningRate, inputVector, winnerNeuronX,
		winnerNeuronY);

	//Check which neurons should update its weight vector
	Neuron *bmu = _matrix->getNeuron(winnerNeuronX, winnerNeuronY);
	for(int row=0; row<_size; row++){
		for(int col=0; col<_size; col++){
			currentNeuron = _matrix->getNeuron(row, col);
			distanceToNeuron = bmu->distanceToNeuron(currentNeuron);
			if(distanceToNeuron <= neighbourhoodRadius){
				// The current neuron is going to be updated

				// Get influence of the neuron based in its distance to BMU scientific method
				influence = getInfluence(distanceToNeuron, neighbourhoodRadius);

				// Update neuron
				_matrix->updateWeightVector(influence, currenLearningRate, inputVector,
					row, col);
			}
		}
	}

	_iterations++;
	if(_iterations == _totalSamples){
		_epochs++;
		_iterations = 0;
		if(_epochs%100 == 0)
			cout << "Epoch: " << _epochs << endl;
	}
}
void displayExample(ptr_example example)
{
	printf("<type : %d> ", getValue(getType(example)));
	printf("<influence : %d> ", getInfluence(example));
	printf("<alignment : %d>\n", getAlignment(example));
}