<commit_before>// $Id: energyMinimizer.C,v 1.6 1999/12/30 20:37:18 oliver Exp $

#include <BALL/MOLMEC/MINIMIZATION/energyMinimizer.h>
#include <BALL/COMMON/limits.h>

using namespace std;

namespace BALL
{

	const char* EnergyMinimizer::Option::MAXIMAL_NUMBER_OF_ITERATIONS =
                                                             "maximal_number_of_iterations";
	const char* EnergyMinimizer::Option::ENERGY_OUTPUT_FREQUENCY =
                                                             "energy_output_frequency";
	const char* EnergyMinimizer::Option::SNAPSHOT_FREQUENCY =
                                                             "snapshot_frequency";
	const char* EnergyMinimizer::Option::NUMBER_OF_ITERATION = "number_of_iteration";

  // if the current rms gradient is below this one, we are converged
  const char *EnergyMinimizer::Option::MAX_GRADIENT = "max_gradient";

	const char* EnergyMinimizer::Option::MAXIMAL_SHIFT = "MAXIMAL_SHIFT";

  // The maximum number of iteration with equal energy
  // If this number is reached, we assume convergence
  const char* EnergyMinimizer::Option::MAX_SAME_ENERGY = "max_same_energy";

  // The corresponding energy difference needed for assuming 'equal energy'
	const char* EnergyMinimizer::Option::ENERGY_DIFFERENCE_BOUND = "energy_difference_bound";

	Size EnergyMinimizer::Default::MAXIMAL_NUMBER_OF_ITERATIONS = 1000;
	Size EnergyMinimizer::Default::ENERGY_OUTPUT_FREQUENCY = 50;
	Size EnergyMinimizer::Default::SNAPSHOT_FREQUENCY = Limits<Size>::max();
	Size EnergyMinimizer::Default::NUMBER_OF_ITERATION = 0;              // start number
  Size EnergyMinimizer::Default::MAX_SAME_ENERGY = 20;
	float EnergyMinimizer::Default::ENERGY_DIFFERENCE_BOUND = 1e-4;      // in kJ/mol
  float EnergyMinimizer::Default::MAX_GRADIENT = 0.0001;               // in kJ/(mol A)
	float EnergyMinimizer::Default::MAXIMAL_SHIFT = 0.4;                 // Angstrom

	// default constructor
	EnergyMinimizer::EnergyMinimizer()
		:	valid_(false),
			force_field_(0)
	{
	}

	// copy constructor
	EnergyMinimizer::EnergyMinimizer(const EnergyMinimizer& energy_minimizer, bool /* deep */)
	{
		// Copy the attributes
		force_field_										= energy_minimizer.force_field_;
		options													= energy_minimizer.options;
		valid_													= energy_minimizer.valid_;
// BAUSTELLE
//		snapshot_												= energy_minimizer.snapshot_;
		number_of_iteration_						= energy_minimizer.number_of_iteration_;
		maximal_number_of_iterations_		= energy_minimizer.maximal_number_of_iterations_ ;
		energy_output_frequency_				= energy_minimizer.energy_output_frequency_;
		snapshot_frequency_							= energy_minimizer.snapshot_frequency_;
		energy_difference_bound_				= energy_minimizer.energy_difference_bound_ ;
    max_gradient_                   = energy_minimizer.max_gradient_;
    max_same_energy_                = energy_minimizer.max_same_energy_;
		maximal_shift_                  = energy_minimizer.maximal_shift_;
    force_update_counter_           = energy_minimizer.force_update_counter_;
    energy_update_counter_          = energy_minimizer.energy_update_counter_;
	}

	// assignment operator
	EnergyMinimizer& EnergyMinimizer::operator = (const EnergyMinimizer& energy_minimizer)
	{

		// guard against self assignment
		if (&energy_minimizer != this)
		{
			// Copy the attributes
			force_field_									= energy_minimizer.force_field_;
			options												= energy_minimizer.options;
			valid_												= energy_minimizer.valid_;
// BAUSTELLE
//			snapshot_											= energy_minimizer.snapshot_;
			number_of_iteration_						= energy_minimizer.number_of_iteration_;
			maximal_number_of_iterations_		= energy_minimizer.maximal_number_of_iterations_ ;
			energy_output_frequency_				= energy_minimizer.energy_output_frequency_;
			snapshot_frequency_							= energy_minimizer.snapshot_frequency_;
      max_same_energy_                = energy_minimizer.max_same_energy_;
			energy_difference_bound_				= energy_minimizer.energy_difference_bound_ ;
			max_gradient_				            = energy_minimizer.max_gradient_ ;
			maximal_shift_                  = energy_minimizer.maximal_shift_;
      force_update_counter_           = energy_minimizer.force_update_counter_;
      energy_update_counter_          = energy_minimizer.energy_update_counter_;

		}
		return (*this);
	}

	// Constructor initialized with a force field
	EnergyMinimizer::EnergyMinimizer(ForceField& force_field)
	{
		valid_ = setup(force_field);

		if (!valid_)
		{
			Log.level(LogStream::ERROR) << " Energy minimizer setup failed! " << endl;
		}
	}

	// Constructor initialized with a force field and a set of options
	EnergyMinimizer::EnergyMinimizer(ForceField& force_field, const Options& new_options)
	{
		valid_ = setup(force_field, new_options);

		if (!valid_)
		{
			Log.level(LogStream::ERROR) << " Energy minimizer setup failed! " << endl;
		}
	}

	// Destructor
	EnergyMinimizer::~EnergyMinimizer()
	{
	}

	// Set the number of the current iteration
	void	EnergyMinimizer::setNumberOfIteration(Size number_of_iteration)
	{
		number_of_iteration_ = number_of_iteration;
	}

	// Get the number of the current iteration
	Size	EnergyMinimizer::getNumberOfIteration() const
	{
		return number_of_iteration_;
	}

	// Set the maximal number of iterations
	void	EnergyMinimizer::setMaximalNumberOfIterations(Size maximal_number_of_iterations)
	{
		maximal_number_of_iterations_ = maximal_number_of_iterations;
	}

	// Get the maximal number of iterations
	Size	EnergyMinimizer::getMaximalNumberOfIterations() const
	{
		return maximal_number_of_iterations_;
	}

	// Is the energy minimizer valid: did the setup work?
	bool	EnergyMinimizer::isValid() const
	{
		return valid_;
	}
/*
BAUSTELLE
	// Return the trajectory of the minimization procedure
	Snapshot& EnergyMinimizer::getSnapShot() const
	{
		return snapshot_;
	}
	// Set the trajectory
	void EnergyMinimizer::setSnapShot(Snapshot& snapshot)
	{
		snapshot_ = snapshot;
	}
*/
	//	Set the energy output frequency
	void EnergyMinimizer::setEnergyOutputFrequency(Size energy_output_frequency)
	{
		energy_output_frequency_ = energy_output_frequency;
	}

	//	Get the energy ouput frequency
	Size EnergyMinimizer::getEnergyOutputFrequency() const
	{
		return energy_output_frequency_;
	}

	// Set the energy difference bound
	void EnergyMinimizer::setEnergyDifferenceBound(float energy_difference_bound)
	{
		energy_difference_bound_ = energy_difference_bound;
	}

  // Set explicitly the option max_gradient_
  void  EnergyMinimizer::setMaxGradient(float max_gradient)
    {
    max_gradient_ = max_gradient;
    }

  // Get the current value of the maximum gradient bound
  float EnergyMinimizer::getMaxGradient() const
    {
    return max_gradient_;
    }

  // Set explicitly the number of iterations for detecting convergence due
  // to invariant energy
  void  EnergyMinimizer::setMaxSameEnergy(Size number)
    {
    max_same_energy_ = number;
    }

  // Get the value of max_same_energy, i.e. the number
  // of iterations after which the algorithm is stopped when the
  // energy remains constant
  Size  EnergyMinimizer::getMaxSameEnergy() const
    {
    return max_same_energy_;
    }

	// Get the energy difference bound
	float	EnergyMinimizer::getEnergyDifferenceBound() const
	{
		return energy_difference_bound_;
	}

	//	Set the maximal shift
	void EnergyMinimizer::setMaximalShift( float maximal_shift )
	{
		maximal_shift_ = maximal_shift;
	}

	//	Get the maximal shift
	float	EnergyMinimizer::getMaximalShift() const
	{
		return maximal_shift_;
	}

	//	Set the trajectory ouput frequency
	void EnergyMinimizer::setSnapShotFrequency(Size snapshot_frequency)
	{
		snapshot_frequency_ = snapshot_frequency;
	}

	//	Get the trajectory ouput frequency
	Size EnergyMinimizer::getSnapShotFrequency() const
	{
		return snapshot_frequency_;
	}

	// Get the force field of the energy minimizer
	ForceField*	EnergyMinimizer::getForceField()
	{
		return force_field_;
	}

	// setup methods
	bool EnergyMinimizer::setup(ForceField& force_field)
	{

    // Default: no snapshot manager available
    snapShot_ptr_ = 0;

		// store the specified force field
		force_field_ = &force_field;

		valid_ = force_field_->isValid();

		if (!valid_)
		{
			Log.error() << "The force field of the energy minimizer is not valid! "
									<< "Check the definition and initialization of the force field! " << endl;
			return valid_;
		}

		// Check options

		options.setDefaultInteger(EnergyMinimizer::Option::MAXIMAL_NUMBER_OF_ITERATIONS,
                               (long)EnergyMinimizer::Default::MAXIMAL_NUMBER_OF_ITERATIONS);
		maximal_number_of_iterations_ = (Size)(options.getInteger(EnergyMinimizer::Option::MAXIMAL_NUMBER_OF_ITERATIONS));

		options.setDefaultInteger(EnergyMinimizer::Option::ENERGY_OUTPUT_FREQUENCY,
                               (long)EnergyMinimizer::Default::ENERGY_OUTPUT_FREQUENCY);
		energy_output_frequency_ = (Size)(options.getInteger(EnergyMinimizer::Option::ENERGY_OUTPUT_FREQUENCY));

		options.setDefaultInteger(EnergyMinimizer::Option::SNAPSHOT_FREQUENCY,
                               (long)EnergyMinimizer::Default::SNAPSHOT_FREQUENCY);
		snapshot_frequency_ = (Size)(options.getInteger(EnergyMinimizer::Option::SNAPSHOT_FREQUENCY));

		options.setDefaultInteger(EnergyMinimizer::Option::NUMBER_OF_ITERATION,
                               (long)EnergyMinimizer::Default::NUMBER_OF_ITERATION);
		number_of_iteration_ = (Size)(options.getInteger(EnergyMinimizer::Option::NUMBER_OF_ITERATION));

    options.setDefaultInteger(EnergyMinimizer::Option::MAX_SAME_ENERGY,
                                  (long) EnergyMinimizer::Default::MAX_SAME_ENERGY);
    max_same_energy_ = (Size) options.getInteger(EnergyMinimizer::Option::MAX_SAME_ENERGY);

		options.setDefaultReal(EnergyMinimizer::Option::ENERGY_DIFFERENCE_BOUND,
                                          EnergyMinimizer::Default::ENERGY_DIFFERENCE_BOUND);
		energy_difference_bound_ = options.getReal(EnergyMinimizer::Option::ENERGY_DIFFERENCE_BOUND);

    options.setDefaultReal(EnergyMinimizer::Option::MAX_GRADIENT,
                                             EnergyMinimizer::Default::MAX_GRADIENT);
    max_gradient_ = options.getReal(EnergyMinimizer::Option::MAX_GRADIENT);

		options.setDefaultReal(EnergyMinimizer::Option::MAXIMAL_SHIFT,
                                          EnergyMinimizer::Default::MAXIMAL_SHIFT);
		maximal_shift_ = options.getReal(EnergyMinimizer::Option::MAXIMAL_SHIFT);

    energy_update_counter_ = 0;
    force_update_counter_ = 0;

		// minimizer specific parts
		valid_ = specificSetup();
		if (!valid_)
		{
			Log.level(LogStream::ERROR) << "Energy minimizer specificSetup failed!" << endl;
			return valid_;
		}

		valid_ = true;
		return valid_;
	}

  // Setup with a force field and a snapshot manager
  bool EnergyMinimizer::setup(ForceField& force_field, SnapShotManager *ssm)
    {
    bool result = setup(force_field);

    // set a pointer to the indicated snapshot manager
    if(ssm->isValid())
      snapShot_ptr_ = ssm;

    return result;
    }

  // Setup with a force field and a snapshot manager and options
  bool EnergyMinimizer::setup(ForceField& force_field, SnapShotManager *ssm,
                            const Options &new_options)
    {
    bool result = setup(force_field,new_options);

    // set a pointer to the indicated snapshot manager
    if(ssm->isValid())
      snapShot_ptr_ = ssm;

    return result;
    }

  // Setup with a force field and a set of options
  bool EnergyMinimizer::setup(ForceField& force_field, const Options& new_options)
	{
		options = new_options;
		valid_ = setup(force_field);
		return valid_;
	}

	// virtual function for the specific setup of derived classes
	bool EnergyMinimizer::specificSetup()
	{
        cout << "EnergyMinimizer::specificSetup wird ausgefuehrt" << endl;
		return true;
	}

	/*	The minimizer optimizes the energy of the system bound to the force field.
			The function is virtual.
	*/

	bool EnergyMinimizer::minimize(Size /* steps */, bool /* restart */)
	{
		return true;
	}

} // namespace Ball
<commit_msg>changed: relaxed parameters for omptimization. Now they are more suitabled for larger proteins.<commit_after>// $Id: energyMinimizer.C,v 1.7 2000/02/12 18:07:15 oliver Exp $

#include <BALL/MOLMEC/MINIMIZATION/energyMinimizer.h>
#include <BALL/COMMON/limits.h>

using namespace std;

namespace BALL
{

	const char* EnergyMinimizer::Option::MAXIMAL_NUMBER_OF_ITERATIONS =
                                                             "maximal_number_of_iterations";
	const char* EnergyMinimizer::Option::ENERGY_OUTPUT_FREQUENCY =
                                                             "energy_output_frequency";
	const char* EnergyMinimizer::Option::SNAPSHOT_FREQUENCY =
                                                             "snapshot_frequency";
	const char* EnergyMinimizer::Option::NUMBER_OF_ITERATION = "number_of_iteration";

  // if the current rms gradient is below this one, we are converged
  const char *EnergyMinimizer::Option::MAX_GRADIENT = "max_gradient";

	const char* EnergyMinimizer::Option::MAXIMAL_SHIFT = "MAXIMAL_SHIFT";

  // The maximum number of iteration with equal energy
  // If this number is reached, we assume convergence
  const char* EnergyMinimizer::Option::MAX_SAME_ENERGY = "max_same_energy";

  // The corresponding energy difference needed for assuming 'equal energy'
	const char* EnergyMinimizer::Option::ENERGY_DIFFERENCE_BOUND = "energy_difference_bound";

	Size EnergyMinimizer::Default::MAXIMAL_NUMBER_OF_ITERATIONS = 1000;
	Size EnergyMinimizer::Default::ENERGY_OUTPUT_FREQUENCY = 50;
	Size EnergyMinimizer::Default::SNAPSHOT_FREQUENCY = Limits<Size>::max();
  Size EnergyMinimizer::Default::MAX_SAME_ENERGY = 5;
	Size EnergyMinimizer::Default::NUMBER_OF_ITERATION = 0;              // start number
	float EnergyMinimizer::Default::ENERGY_DIFFERENCE_BOUND = 1e-2;      // in kJ/mol
  float EnergyMinimizer::Default::MAX_GRADIENT = 0.01;                 // in kJ/(mol A)
	float EnergyMinimizer::Default::MAXIMAL_SHIFT = 0.4;                 // Angstrom

	// default constructor
	EnergyMinimizer::EnergyMinimizer()
		:	valid_(false),
			force_field_(0)
	{
	}

	// copy constructor
	EnergyMinimizer::EnergyMinimizer(const EnergyMinimizer& energy_minimizer, bool /* deep */)
	{
		// Copy the attributes
		force_field_										= energy_minimizer.force_field_;
		options													= energy_minimizer.options;
		valid_													= energy_minimizer.valid_;
// BAUSTELLE
//		snapshot_												= energy_minimizer.snapshot_;
		number_of_iteration_						= energy_minimizer.number_of_iteration_;
		maximal_number_of_iterations_		= energy_minimizer.maximal_number_of_iterations_ ;
		energy_output_frequency_				= energy_minimizer.energy_output_frequency_;
		snapshot_frequency_							= energy_minimizer.snapshot_frequency_;
		energy_difference_bound_				= energy_minimizer.energy_difference_bound_ ;
    max_gradient_                   = energy_minimizer.max_gradient_;
    max_same_energy_                = energy_minimizer.max_same_energy_;
		maximal_shift_                  = energy_minimizer.maximal_shift_;
    force_update_counter_           = energy_minimizer.force_update_counter_;
    energy_update_counter_          = energy_minimizer.energy_update_counter_;
	}

	// assignment operator
	EnergyMinimizer& EnergyMinimizer::operator = (const EnergyMinimizer& energy_minimizer)
	{

		// guard against self assignment
		if (&energy_minimizer != this)
		{
			// Copy the attributes
			force_field_									= energy_minimizer.force_field_;
			options												= energy_minimizer.options;
			valid_												= energy_minimizer.valid_;
// BAUSTELLE
//			snapshot_											= energy_minimizer.snapshot_;
			number_of_iteration_						= energy_minimizer.number_of_iteration_;
			maximal_number_of_iterations_		= energy_minimizer.maximal_number_of_iterations_ ;
			energy_output_frequency_				= energy_minimizer.energy_output_frequency_;
			snapshot_frequency_							= energy_minimizer.snapshot_frequency_;
      max_same_energy_                = energy_minimizer.max_same_energy_;
			energy_difference_bound_				= energy_minimizer.energy_difference_bound_ ;
			max_gradient_				            = energy_minimizer.max_gradient_ ;
			maximal_shift_                  = energy_minimizer.maximal_shift_;
      force_update_counter_           = energy_minimizer.force_update_counter_;
      energy_update_counter_          = energy_minimizer.energy_update_counter_;

		}
		return (*this);
	}

	// Constructor initialized with a force field
	EnergyMinimizer::EnergyMinimizer(ForceField& force_field)
	{
		valid_ = setup(force_field);

		if (!valid_)
		{
			Log.level(LogStream::ERROR) << " Energy minimizer setup failed! " << endl;
		}
	}

	// Constructor initialized with a force field and a set of options
	EnergyMinimizer::EnergyMinimizer(ForceField& force_field, const Options& new_options)
	{
		valid_ = setup(force_field, new_options);

		if (!valid_)
		{
			Log.level(LogStream::ERROR) << " Energy minimizer setup failed! " << endl;
		}
	}

	// Destructor
	EnergyMinimizer::~EnergyMinimizer()
	{
	}

	// Set the number of the current iteration
	void	EnergyMinimizer::setNumberOfIteration(Size number_of_iteration)
	{
		number_of_iteration_ = number_of_iteration;
	}

	// Get the number of the current iteration
	Size	EnergyMinimizer::getNumberOfIteration() const
	{
		return number_of_iteration_;
	}

	// Set the maximal number of iterations
	void	EnergyMinimizer::setMaximalNumberOfIterations(Size maximal_number_of_iterations)
	{
		maximal_number_of_iterations_ = maximal_number_of_iterations;
	}

	// Get the maximal number of iterations
	Size	EnergyMinimizer::getMaximalNumberOfIterations() const
	{
		return maximal_number_of_iterations_;
	}

	// Is the energy minimizer valid: did the setup work?
	bool	EnergyMinimizer::isValid() const
	{
		return valid_;
	}
/*
BAUSTELLE
	// Return the trajectory of the minimization procedure
	Snapshot& EnergyMinimizer::getSnapShot() const
	{
		return snapshot_;
	}
	// Set the trajectory
	void EnergyMinimizer::setSnapShot(Snapshot& snapshot)
	{
		snapshot_ = snapshot;
	}
*/
	//	Set the energy output frequency
	void EnergyMinimizer::setEnergyOutputFrequency(Size energy_output_frequency)
	{
		energy_output_frequency_ = energy_output_frequency;
	}

	//	Get the energy ouput frequency
	Size EnergyMinimizer::getEnergyOutputFrequency() const
	{
		return energy_output_frequency_;
	}

	// Set the energy difference bound
	void EnergyMinimizer::setEnergyDifferenceBound(float energy_difference_bound)
	{
		energy_difference_bound_ = energy_difference_bound;
	}

  // Set explicitly the option max_gradient_
  void  EnergyMinimizer::setMaxGradient(float max_gradient)
    {
    max_gradient_ = max_gradient;
    }

  // Get the current value of the maximum gradient bound
  float EnergyMinimizer::getMaxGradient() const
    {
    return max_gradient_;
    }

  // Set explicitly the number of iterations for detecting convergence due
  // to invariant energy
  void  EnergyMinimizer::setMaxSameEnergy(Size number)
    {
    max_same_energy_ = number;
    }

  // Get the value of max_same_energy, i.e. the number
  // of iterations after which the algorithm is stopped when the
  // energy remains constant
  Size  EnergyMinimizer::getMaxSameEnergy() const
    {
    return max_same_energy_;
    }

	// Get the energy difference bound
	float	EnergyMinimizer::getEnergyDifferenceBound() const
	{
		return energy_difference_bound_;
	}

	//	Set the maximal shift
	void EnergyMinimizer::setMaximalShift( float maximal_shift )
	{
		maximal_shift_ = maximal_shift;
	}

	//	Get the maximal shift
	float	EnergyMinimizer::getMaximalShift() const
	{
		return maximal_shift_;
	}

	//	Set the trajectory ouput frequency
	void EnergyMinimizer::setSnapShotFrequency(Size snapshot_frequency)
	{
		snapshot_frequency_ = snapshot_frequency;
	}

	//	Get the trajectory ouput frequency
	Size EnergyMinimizer::getSnapShotFrequency() const
	{
		return snapshot_frequency_;
	}

	// Get the force field of the energy minimizer
	ForceField*	EnergyMinimizer::getForceField()
	{
		return force_field_;
	}

	// setup methods
	bool EnergyMinimizer::setup(ForceField& force_field)
	{

    // Default: no snapshot manager available
    snapShot_ptr_ = 0;

		// store the specified force field
		force_field_ = &force_field;

		valid_ = force_field_->isValid();

		if (!valid_)
		{
			Log.error() << "The force field of the energy minimizer is not valid! "
									<< "Check the definition and initialization of the force field! " << endl;
			return valid_;
		}

		// Check options

		options.setDefaultInteger(EnergyMinimizer::Option::MAXIMAL_NUMBER_OF_ITERATIONS,
                               (long)EnergyMinimizer::Default::MAXIMAL_NUMBER_OF_ITERATIONS);
		maximal_number_of_iterations_ = (Size)(options.getInteger(EnergyMinimizer::Option::MAXIMAL_NUMBER_OF_ITERATIONS));

		options.setDefaultInteger(EnergyMinimizer::Option::ENERGY_OUTPUT_FREQUENCY,
                               (long)EnergyMinimizer::Default::ENERGY_OUTPUT_FREQUENCY);
		energy_output_frequency_ = (Size)(options.getInteger(EnergyMinimizer::Option::ENERGY_OUTPUT_FREQUENCY));

		options.setDefaultInteger(EnergyMinimizer::Option::SNAPSHOT_FREQUENCY,
                               (long)EnergyMinimizer::Default::SNAPSHOT_FREQUENCY);
		snapshot_frequency_ = (Size)(options.getInteger(EnergyMinimizer::Option::SNAPSHOT_FREQUENCY));

		options.setDefaultInteger(EnergyMinimizer::Option::NUMBER_OF_ITERATION,
                               (long)EnergyMinimizer::Default::NUMBER_OF_ITERATION);
		number_of_iteration_ = (Size)(options.getInteger(EnergyMinimizer::Option::NUMBER_OF_ITERATION));

    options.setDefaultInteger(EnergyMinimizer::Option::MAX_SAME_ENERGY,
                                  (long) EnergyMinimizer::Default::MAX_SAME_ENERGY);
    max_same_energy_ = (Size) options.getInteger(EnergyMinimizer::Option::MAX_SAME_ENERGY);

		options.setDefaultReal(EnergyMinimizer::Option::ENERGY_DIFFERENCE_BOUND,
                                          EnergyMinimizer::Default::ENERGY_DIFFERENCE_BOUND);
		energy_difference_bound_ = options.getReal(EnergyMinimizer::Option::ENERGY_DIFFERENCE_BOUND);

    options.setDefaultReal(EnergyMinimizer::Option::MAX_GRADIENT,
                                             EnergyMinimizer::Default::MAX_GRADIENT);
    max_gradient_ = options.getReal(EnergyMinimizer::Option::MAX_GRADIENT);

		options.setDefaultReal(EnergyMinimizer::Option::MAXIMAL_SHIFT,
                                          EnergyMinimizer::Default::MAXIMAL_SHIFT);
		maximal_shift_ = options.getReal(EnergyMinimizer::Option::MAXIMAL_SHIFT);

    energy_update_counter_ = 0;
    force_update_counter_ = 0;

		// minimizer specific parts
		valid_ = specificSetup();
		if (!valid_)
		{
			Log.level(LogStream::ERROR) << "Energy minimizer specificSetup failed!" << endl;
			return valid_;
		}

		valid_ = true;
		return valid_;
	}

  // Setup with a force field and a snapshot manager
  bool EnergyMinimizer::setup(ForceField& force_field, SnapShotManager *ssm)
    {
    bool result = setup(force_field);

    // set a pointer to the indicated snapshot manager
    if(ssm->isValid())
      snapShot_ptr_ = ssm;

    return result;
    }

  // Setup with a force field and a snapshot manager and options
  bool EnergyMinimizer::setup(ForceField& force_field, SnapShotManager *ssm,
                            const Options &new_options)
    {
    bool result = setup(force_field,new_options);

    // set a pointer to the indicated snapshot manager
    if(ssm->isValid())
      snapShot_ptr_ = ssm;

    return result;
    }

  // Setup with a force field and a set of options
  bool EnergyMinimizer::setup(ForceField& force_field, const Options& new_options)
	{
		options = new_options;
		valid_ = setup(force_field);
		return valid_;
	}

	// virtual function for the specific setup of derived classes
	bool EnergyMinimizer::specificSetup()
	{
        cout << "EnergyMinimizer::specificSetup wird ausgefuehrt" << endl;
		return true;
	}

	/*	The minimizer optimizes the energy of the system bound to the force field.
			The function is virtual.
	*/

	bool EnergyMinimizer::minimize(Size /* steps */, bool /* restart */)
	{
		return true;
	}

} // namespace Ball
<|endoftext|>


<commit_before>#include "reg_filter_mode_translator.h"
#include "orz/types.h"

namespace Reg {
	namespace Internal {
		boost::optional<FilterModeTranslator::external_type> FilterModeTranslator::get_value(internal_type const sval) {
			if (sval.empty()) return boost::none;
			if (sval == "Bilinear") {
				return Filter::Mode::Bilinear;
			}
			if (sval == "Nearest") {
				return Filter::Mode::NearestNeighbor;
			}
			if (sval == "Lanczos3") {
				return Filter::Mode::Lanczos3;
			}

			switch (FromAString<int>(sval)) {
			case 1:
				return Filter::Mode::NearestNeighbor;
			case 2:
				return Filter::Mode::Bilinear;
			case 3:
				return Filter::Mode::Lanczos3;
			}

			return boost::none;
		}

		boost::optional<FilterModeTranslator::internal_type> FilterModeTranslator::put_value(external_type const& val) {
			switch (val) {
			case Filter::Mode::NearestNeighbor:
				return "Nearest";
			case Filter::Mode::Bilinear:
				return "Bilinear";
			case Filter::Mode::Lanczos3:
				return "Lanczos3";
			}

			return boost::none;
		}
	}
}<commit_msg>Fix compile errors on Linux<commit_after>#include "reg_filter_mode_translator.h"
#include "orz/types.h"

namespace Reg {
	namespace Internal {
		boost::optional<FilterModeTranslator::external_type> FilterModeTranslator::get_value(internal_type const sval) {
			if (sval.empty()) return boost::none;
			if (sval == "Bilinear") {
				return Filter::Mode::Bilinear;
			}
			if (sval == "Nearest") {
				return Filter::Mode::NearestNeighbor;
			}
			if (sval == "Lanczos3") {
				return Filter::Mode::Lanczos3;
			}

			switch (FromAString<int>(sval)) {
			case 1:
				return Filter::Mode::NearestNeighbor;
			case 2:
				return Filter::Mode::Bilinear;
			case 3:
				return Filter::Mode::Lanczos3;
			}

			return boost::none;
		}

		boost::optional<FilterModeTranslator::internal_type> FilterModeTranslator::put_value(external_type const& val) {
			switch (val) {
			case Filter::Mode::NearestNeighbor:
				return std::string("Nearest");
			case Filter::Mode::Bilinear:
				return std::string("Bilinear");
			case Filter::Mode::Lanczos3:
				return std::string("Lanczos3");
			}

			return boost::none;
		}
	}
}<|endoftext|>


<commit_before>
#pragma once

namespace fiblib
{

template <>
class FIBLIB_TEMPLATE_API CTFibonacci<0>
{
public:
    enum {
        value = 0
    };
};

template <>
class FIBLIB_TEMPLATE_API CTFibonacci<1>
{
public:
    enum {
        value = 1
    };
};

} // namespace fiblib
<commit_msg>Fix check errors<commit_after>
#pragma once

#include <fiblib/CTFibonacci.h>

namespace fiblib
{

template <>
class FIBLIB_TEMPLATE_API CTFibonacci<0>
{
public:
    enum {
        value = 0
    };
};

template <>
class FIBLIB_TEMPLATE_API CTFibonacci<1>
{
public:
    enum {
        value = 1
    };
};

} // namespace fiblib
<|endoftext|>


<commit_before>
#pragma once

#include <gloperate/base/make_unique.hpp>
#include <gloperate/pipeline/AbstractPipeline.h>

#include "DummyStage.hpp"

using namespace gloperate;

class TestPipeline : public AbstractPipeline
{
public:
    TestPipeline()
    {
        auto stage0 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{}, std::vector<std::string>{"output0", "output1"});
        auto stage1 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage2 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage3 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage4 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage5 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage6 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage7 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage8 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage9 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage10 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage11 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage12 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage13 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1", "input2", "input3", "input4"}, std::vector<std::string>{"output0"});
        auto stage14 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0", "output1", "output2", "output3", "output4"});
        auto stage15 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0", "input1", "input2", "input3", "input4", "input5"}, std::vector<std::string>{"output0"});
        auto stage16 = gloperate::make_unique<DummyStage>("", std::vector<std::string>{"input0"}, std::vector<std::string>{});

        stage1->inputs.at("input0") = stage0->outputs.at("output0");

        stage2->inputs.at("input0") = stage1->outputs.at("output0");

        stage3->inputs.at("input0") = stage0->outputs.at("output0");
        stage3->inputs.at("input1") = stage2->outputs.at("output0");

        stage4->inputs.at("input0") = stage3->outputs.at("output0");

        stage5->inputs.at("input0") = stage3->outputs.at("output0");
        stage5->inputs.at("input1") = stage4->outputs.at("output0");

        stage6->inputs.at("input0") = stage3->outputs.at("output0");
        stage6->inputs.at("input1") = stage4->outputs.at("output0");

        stage7->inputs.at("input0") = stage3->outputs.at("output0");
        stage7->inputs.at("input0") = stage4->outputs.at("output0");

        stage8->inputs.at("input0") = stage3->outputs.at("output0");
        stage8->inputs.at("input1") = stage4->outputs.at("output0");
        stage8->inputs.at("input2") = stage5->outputs.at("output0");

        stage9->inputs.at("input0") = stage3->outputs.at("output0");
        stage9->inputs.at("input1") = stage4->outputs.at("output0");
        stage9->inputs.at("input2") = stage6->outputs.at("output0");

        stage10->inputs.at("input0") = stage3->outputs.at("output0");
        stage10->inputs.at("input1") = stage4->outputs.at("output0");
        stage10->inputs.at("input2") = stage7->outputs.at("output0");

        stage11->inputs.at("input0") = stage10->outputs.at("output0");

        stage12->inputs.at("input0") = stage3->outputs.at("output0");
        stage12->inputs.at("input1") = stage4->outputs.at("output0");
        stage12->inputs.at("input2") = stage8->outputs.at("output0");

        stage13->inputs.at("input0") = stage3->outputs.at("output0");
        stage13->inputs.at("input1") = stage4->outputs.at("output0");
        stage13->inputs.at("input2") = stage12->outputs.at("output0");
        stage13->inputs.at("input3") = stage9->outputs.at("output0");
        stage13->inputs.at("input4") = stage11->outputs.at("output0");

        stage14->inputs.at("input0") = stage13->outputs.at("output0");

        stage15->inputs.at("input0") = stage14->outputs.at("output0");
        stage15->inputs.at("input1") = stage14->outputs.at("output1");
        stage15->inputs.at("input2") = stage14->outputs.at("output2");
        stage15->inputs.at("input3") = stage14->outputs.at("output3");
        stage15->inputs.at("input4") = stage14->outputs.at("output4");
        stage15->inputs.at("input5") = stage0->outputs.at("output1");

        stage16->inputs.at("input0") = stage15->outputs.at("output0");

        addStages(
            std::move(stage0),
            std::move(stage1),
            std::move(stage2),
            std::move(stage3),
            std::move(stage4),
            std::move(stage5),
            std::move(stage6),
            std::move(stage7),
            std::move(stage8),
            std::move(stage9),
            std::move(stage10),
            std::move(stage11),
            std::move(stage12),
            std::move(stage13),
            std::move(stage14),
            std::move(stage15),
            std::move(stage16));
    }

};
<commit_msg>Fix test<commit_after>
#pragma once

#include <gloperate/base/make_unique.hpp>
#include <gloperate/pipeline/AbstractPipeline.h>

#include "DummyStage.hpp"

using namespace gloperate;

class TestPipeline : public AbstractPipeline
{
public:
    TestPipeline()
    {
        auto stage0 = new DummyStage("", std::vector<std::string>{}, std::vector<std::string>{"output0", "output1"});
        auto stage1 = new DummyStage("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage2 = new DummyStage("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage3 = new DummyStage("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage4 = new DummyStage("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage5 = new DummyStage("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage6 = new DummyStage("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage7 = new DummyStage("", std::vector<std::string>{"input0", "input1"}, std::vector<std::string>{"output0"});
        auto stage8 = new DummyStage("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage9 = new DummyStage("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage10 = new DummyStage("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage11 = new DummyStage("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0"});
        auto stage12 = new DummyStage("", std::vector<std::string>{"input0", "input1", "input2"}, std::vector<std::string>{"output0"});
        auto stage13 = new DummyStage("", std::vector<std::string>{"input0", "input1", "input2", "input3", "input4"}, std::vector<std::string>{"output0"});
        auto stage14 = new DummyStage("", std::vector<std::string>{"input0"}, std::vector<std::string>{"output0", "output1", "output2", "output3", "output4"});
        auto stage15 = new DummyStage("", std::vector<std::string>{"input0", "input1", "input2", "input3", "input4", "input5"}, std::vector<std::string>{"output0"});
        auto stage16 = new DummyStage("", std::vector<std::string>{"input0"}, std::vector<std::string>{});

        stage1->inputs.at("input0") = stage0->outputs.at("output0");

        stage2->inputs.at("input0") = stage1->outputs.at("output0");

        stage3->inputs.at("input0") = stage0->outputs.at("output0");
        stage3->inputs.at("input1") = stage2->outputs.at("output0");

        stage4->inputs.at("input0") = stage3->outputs.at("output0");

        stage5->inputs.at("input0") = stage3->outputs.at("output0");
        stage5->inputs.at("input1") = stage4->outputs.at("output0");

        stage6->inputs.at("input0") = stage3->outputs.at("output0");
        stage6->inputs.at("input1") = stage4->outputs.at("output0");

        stage7->inputs.at("input0") = stage3->outputs.at("output0");
        stage7->inputs.at("input0") = stage4->outputs.at("output0");

        stage8->inputs.at("input0") = stage3->outputs.at("output0");
        stage8->inputs.at("input1") = stage4->outputs.at("output0");
        stage8->inputs.at("input2") = stage5->outputs.at("output0");

        stage9->inputs.at("input0") = stage3->outputs.at("output0");
        stage9->inputs.at("input1") = stage4->outputs.at("output0");
        stage9->inputs.at("input2") = stage6->outputs.at("output0");

        stage10->inputs.at("input0") = stage3->outputs.at("output0");
        stage10->inputs.at("input1") = stage4->outputs.at("output0");
        stage10->inputs.at("input2") = stage7->outputs.at("output0");

        stage11->inputs.at("input0") = stage10->outputs.at("output0");

        stage12->inputs.at("input0") = stage3->outputs.at("output0");
        stage12->inputs.at("input1") = stage4->outputs.at("output0");
        stage12->inputs.at("input2") = stage8->outputs.at("output0");

        stage13->inputs.at("input0") = stage3->outputs.at("output0");
        stage13->inputs.at("input1") = stage4->outputs.at("output0");
        stage13->inputs.at("input2") = stage12->outputs.at("output0");
        stage13->inputs.at("input3") = stage9->outputs.at("output0");
        stage13->inputs.at("input4") = stage11->outputs.at("output0");

        stage14->inputs.at("input0") = stage13->outputs.at("output0");

        stage15->inputs.at("input0") = stage14->outputs.at("output0");
        stage15->inputs.at("input1") = stage14->outputs.at("output1");
        stage15->inputs.at("input2") = stage14->outputs.at("output2");
        stage15->inputs.at("input3") = stage14->outputs.at("output3");
        stage15->inputs.at("input4") = stage14->outputs.at("output4");
        stage15->inputs.at("input5") = stage0->outputs.at("output1");

        stage16->inputs.at("input0") = stage15->outputs.at("output0");

        addStages(
            stage0,
            stage1,
            stage2,
            stage3,
            stage4,
            stage5,
            stage6,
            stage7,
            stage8,
            stage9,
            stage10,
            stage11,
            stage12,
            stage13,
            stage14,
            stage15,
            stage16);
    }

};
<|endoftext|>


<commit_before>/*! \file idroutines.cxx
 *  \brief this file contains routines for manipulating/updating ids, particles and halos
 */

#include "TreeFrog.h"

/// \name if halo ids need to be adjusted
//@{
void UpdateHaloIDs(Options &opt, HaloTreeData *&pht) {
    Int_t i,j;
    if (opt.haloidval>0) {
        for (i=opt.numsnapshots-1;i>=0;i--) {
#ifdef USEMPI
        if (i>=StartSnap && i<EndSnap) {
#endif
            if(pht[i].numhalos>0) for (j=0;j<pht[i].numhalos;j++) pht[i].Halo[j].haloID+=opt.haloidval*(i+opt.snapshotvaloffset)+opt.haloidoffset;
#ifdef USEMPI
        }
#endif
        }
    }
}
//@}

/// \name if particle ids need to be mapped to indices
//@{
///builds a map by identifying the ids of particles in structure across snapshots
///which is memory efficient as only needs array size of maximum number of particles in structures
map<long long, long long> ConstructMemoryEfficientPIDStoIndexMap(Options &opt, HaloTreeData *&pht) {
    Int_t i,j,k;
    Int_t index,indexoffset,offsetsnap;
    double time1,time2;
#ifndef USEMPI
    int ThisTask=0,NProcs=1,NSnap=opt.numsnapshots,StartSnap=0,EndSnap=opt.numsnapshots;
#endif
    //to handle overlapping snapshots between mpi domains
    if (ThisTask==0) offsetsnap=0;
    else offsetsnap=opt.numsteps;

    if (ThisTask==0) cout<<"Mapping PIDS to index "<<endl;
    //place ids in a set so have unique ordered set of ids
    unordered_set<long long> idset;
    vector<long long> idvec;
    map<long long, long long> idmap;
    //index=0;
    time1=MyGetTime();
    time2=MyGetTime();
    for (i=StartSnap+offsetsnap;i<EndSnap;i++)
        for (j=0;j<pht[i].numhalos;j++)
            for (k=0;k<pht[i].Halo[j].NumberofParticles;k++) idset.insert(pht[i].Halo[j].ParticleID[k]);
    time1=MyGetTime()-time1;
    if (opt.iverbose) cout<<ThisTask<<" finished getting unique ids of "<<idset.size()<<" in "<<time1<<endl;
#ifdef USEMPI

    //now if using mpi then must broadcast the sets that a final unique set can be made
    //this is done each task sending information to its neighbouring task, the lower task
    //number then building a set of unique ids in the receving task.
    //once a task has sent information, it nolonger needs to send info
    //all the receiving tasks in the previous round make up the new set of sending and receiving tasks.
    //keep going till all info cascaded to task 0 and a unique set of ids are generated across all snapshots and mpi domains

    //used to transmit info
    long long *idarray;
    //int nmpiloops=(int)(floor(exp(log((Double_t)NProcs)-log(2.0))))
    int nrecvtasks,nsendtasks, numloops=0;
    MPI_Status status;
    int sendtask[NProcs],recvtask[NProcs], numhavesent=0;
    vector<int> sendset,recvset;
    Int_t commsize,oldsize;

    //for each task determine whether sending/receiving and to/from who
    //initialise the send/recv
    for (i=0;i<NProcs;i++) sendtask[i]=recvtask[i]=-1;
    //task zero is explicitly never a send task
    for (i=NProcs-1;i>=1;i-=2) {sendtask[i]=i-1;sendset.push_back(i);}
    for (i=NProcs-2;i>=0;i-=2) {recvtask[i]=i+1;recvset.push_back(i);}
    //if odd number of tasks, then need to explicity add 0 to the recv task set
    if (NProcs%2==1) recvset.push_back(0);

    //keep sending till number of sending tasks == NProcs-1 and task 0 has all the info
    do {
        //if process no longer sending or receiving do nothing in this round
        if (!(sendtask[ThisTask]==-1 && recvtask[ThisTask]==-1)) {
            //if a send task
            if (sendtask[ThisTask]>=0 && recvtask[ThisTask]==-1) {
                commsize=idset.size();
                idarray=new long long[commsize];
                j=0; for (auto idval: idset) idarray[j++]=idval;
                //send size
                MPI_Send(&commsize,1, MPI_Int_t, sendtask[ThisTask], numloops*NProcs*NProcs+ThisTask, MPI_COMM_WORLD);
                //send info
                MPI_Send(idarray,commsize, MPI_LONG, sendtask[ThisTask], numloops*NProcs*NProcs+NProcs+ThisTask, MPI_COMM_WORLD);
                delete[] idarray;
            }
            //if a recvtask
            if (recvtask[ThisTask]>=0 && sendtask[ThisTask]==-1) {
                //recv size
                MPI_Recv(&commsize,1, MPI_Int_t, recvtask[ThisTask], numloops*NProcs*NProcs+recvtask[ThisTask], MPI_COMM_WORLD,&status);
                idarray=new long long[commsize];
                //recv info
                MPI_Recv(idarray,commsize, MPI_LONG, recvtask[ThisTask], numloops*NProcs*NProcs+NProcs+recvtask[ThisTask], MPI_COMM_WORLD,&status);
                for (i=0;i<commsize;i++) idset.insert(idarray[i]);
                delete[] idarray;
            }
        }
        //update the send receive taks for the next time around
        //all tasks that were send tasks now must not be included.
        MPI_Barrier(MPI_COMM_WORLD);
        nsendtasks=sendset.size();
        numhavesent+=nsendtasks;
        nrecvtasks=recvset.size();
        //reset tasks
        for (j=0;j<nsendtasks;j++) sendtask[sendset[j]]=-1;
        for (j=0;j<nrecvtasks;j++) recvtask[recvset[j]]=-1;
        //only tasks that were receiving before are part of the new send/recv set
        for (j=0;j<nrecvtasks-1;j+=2) sendtask[recvset[j]]=recvset[j+1];
        for (j=1;j<nrecvtasks;j+=2) recvtask[recvset[j]]=recvset[j-1];
        sendset.clear();
        recvset.clear();
        for (j=NProcs-1;j>=0;j--) if (sendtask[j]>=0) sendset.push_back(j);
        for (j=NProcs-1;j>=0;j--) if (recvtask[j]>=0) recvset.push_back(j);
        //if current set of communicating tasks set by the old recv task set is odd must explicity include 0
        if (nrecvtasks%2==1)recvset.push_back(0);
        numloops++;
    } while(numhavesent<NProcs-1);

    //now broadcast from root to all processors
    if (ThisTask==0) {
        commsize=idset.size();
        idvec=vector<long long>(idset.begin(), idset.end());
    }
    MPI_Bcast(&commsize,1, MPI_Int_t, 0, MPI_COMM_WORLD);
    if (ThisTask!=0) idvec=vector<long long>(commsize);
    MPI_Bcast(idvec.data(),commsize, MPI_LONG, 0, MPI_COMM_WORLD);
#endif
    opt.MaxIDValue=idvec.size();
    for (i=0;i<opt.MaxIDValue;i++) idmap.insert(pair<long long, long long>(idvec[i],(long long)i));
    time2=MyGetTime()-time2;
    if (opt.iverbose && ThisTask==0) cout<<ThisTask<<" finished getting GLOBAL unique ids of "<<idvec.size()<<" in "<<time2<<endl;
    return idmap;
}

void MapPIDStoIndex(Options &opt, HaloTreeData *&pht, map<long long, long long> &idmap) {
#ifndef USEMPI
    int ThisTask=0;
#endif
    Int_t i,j,k;
    if (ThisTask==0) cout<<"Mapping PIDS to index "<<endl;
#ifdef USEOPENMP
#pragma omp parallel default(shared) \
private(i,j,k)
{
#pragma omp for schedule(dynamic) nowait
#endif
    for (i=0;i<opt.numsnapshots;i++) {
#ifdef USEMPI
    if (i>=StartSnap && i<EndSnap) {
#endif
        for (j=0;j<pht[i].numhalos;j++) {
            for (k=0;k<pht[i].Halo[j].NumberofParticles;k++){
                pht[i].Halo[j].ParticleID[k]=idmap[pht[i].Halo[j].ParticleID[k]];
            }
        }
#ifdef USEMPI
    }
#endif
    }
#ifdef USEOPENMP
}
#endif
}

void MapPIDStoIndex(Options &opt, HaloTreeData *&pht) {
#ifndef USEMPI
    int ThisTask=0;
#endif
    Int_t i,j,k;
    if (ThisTask==0) cout<<"Mapping PIDS to index "<<endl;
#ifdef USEOPENMP
#pragma omp parallel default(shared) \
private(i,j,k)
{
#pragma omp for schedule(dynamic) nowait
#endif
    for (i=0;i<opt.numsnapshots;i++) {
#ifdef USEMPI
    if (i>=StartSnap && i<EndSnap) {
#endif
        for (j=0;j<pht[i].numhalos;j++)
            for (k=0;k<pht[i].Halo[j].NumberofParticles;k++)
                opt.mappingfunc(pht[i].Halo[j].ParticleID[k]);
#ifdef USEMPI
    }
#endif
    }
#ifdef USEOPENMP
}
#endif
}

void simplemap(long unsigned int &i) {}

//@}

//check to see if ID data compatible with accessing index array allocated
void IDcheck(Options &opt, HaloTreeData *&pht){
    int ierrorflag=0,ierrorsumflag=0;
#ifndef USEMPI
    int ThisTask=0,NProcs=1,NSnap=opt.numsnapshots,StartSnap=0,EndSnap=opt.numsnapshots;
#endif
    for (int i=opt.numsnapshots-1;i>=0;i--) {
#ifdef USEMPI
    if (i>=StartSnap && i<EndSnap) {
#endif
        ierrorflag=0;
        for (Int_t j=0;j<pht[i].numhalos;j++) {
            for (Int_t k=0;k<pht[i].Halo[j].NumberofParticles;k++)
                if (pht[i].Halo[j].ParticleID[k]<0||pht[i].Halo[j].ParticleID[k]>opt.MaxIDValue) {
                    cout<<ThisTask<<" snapshot "<<i<<" particle id out of range "<<pht[i].Halo[j].ParticleID[k]<<" not in [0,"<<opt.MaxIDValue<<")"<<endl;
                    ierrorflag=1;
                    break;
                }
            if (ierrorflag==1) {ierrorsumflag+=1;break;}
        }
#ifdef USEMPI
    }
#endif
    }
#ifdef USEMPI
    int mpierrorflag;
    MPI_Allreduce(&ierrorsumflag,&mpierrorflag,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
    ierrorsumflag=mpierrorflag;
#endif
    if (ierrorsumflag>0) {
#ifdef USEMPI
        if (ThisTask==0)
#endif
        cout<<"Error in particle ids, outside of range. Exiting"<<endl;
#ifdef USEMPI
        MPI_Abort(MPI_COMM_WORLD,9);
#else
        exit(9);
#endif
    }
}
<commit_msg>Update to serial TreeFrog construction of unique particle ids<commit_after>/*! \file idroutines.cxx
 *  \brief this file contains routines for manipulating/updating ids, particles and halos
 */

#include "TreeFrog.h"

/// \name if halo ids need to be adjusted
//@{
void UpdateHaloIDs(Options &opt, HaloTreeData *&pht) {
    Int_t i,j;
    if (opt.haloidval>0) {
        for (i=opt.numsnapshots-1;i>=0;i--) {
#ifdef USEMPI
        if (i>=StartSnap && i<EndSnap) {
#endif
            if(pht[i].numhalos>0) for (j=0;j<pht[i].numhalos;j++) pht[i].Halo[j].haloID+=opt.haloidval*(i+opt.snapshotvaloffset)+opt.haloidoffset;
#ifdef USEMPI
        }
#endif
        }
    }
}
//@}

/// \name if particle ids need to be mapped to indices
//@{
///builds a map by identifying the ids of particles in structure across snapshots
///which is memory efficient as only needs array size of maximum number of particles in structures
map<long long, long long> ConstructMemoryEfficientPIDStoIndexMap(Options &opt, HaloTreeData *&pht) {
    Int_t i,j,k;
    Int_t index,indexoffset,offsetsnap;
    double time1,time2;
#ifndef USEMPI
    int ThisTask=0,NProcs=1,NSnap=opt.numsnapshots,StartSnap=0,EndSnap=opt.numsnapshots;
#endif
    //to handle overlapping snapshots between mpi domains
    if (ThisTask==0) offsetsnap=0;
    else offsetsnap=opt.numsteps;

    if (ThisTask==0) cout<<"Mapping PIDS to index "<<endl;
    //place ids in a set so have unique ordered set of ids
    unordered_set<long long> idset;
    vector<long long> idvec;
    map<long long, long long> idmap;
    //index=0;
    time1=MyGetTime();
    time2=MyGetTime();
    for (i=StartSnap+offsetsnap;i<EndSnap;i++)
        for (j=0;j<pht[i].numhalos;j++)
            for (k=0;k<pht[i].Halo[j].NumberofParticles;k++) idset.insert(pht[i].Halo[j].ParticleID[k]);
    time1=MyGetTime()-time1;
    if (opt.iverbose) cout<<ThisTask<<" finished getting unique ids of "<<idset.size()<<" in "<<time1<<endl;
#ifdef USEMPI

    //now if using mpi then must broadcast the sets that a final unique set can be made
    //this is done each task sending information to its neighbouring task, the lower task
    //number then building a set of unique ids in the receving task.
    //once a task has sent information, it nolonger needs to send info
    //all the receiving tasks in the previous round make up the new set of sending and receiving tasks.
    //keep going till all info cascaded to task 0 and a unique set of ids are generated across all snapshots and mpi domains

    //used to transmit info
    long long *idarray;
    //int nmpiloops=(int)(floor(exp(log((Double_t)NProcs)-log(2.0))))
    int nrecvtasks,nsendtasks, numloops=0;
    MPI_Status status;
    int sendtask[NProcs],recvtask[NProcs], numhavesent=0;
    vector<int> sendset,recvset;
    Int_t commsize,oldsize;

    //for each task determine whether sending/receiving and to/from who
    //initialise the send/recv
    for (i=0;i<NProcs;i++) sendtask[i]=recvtask[i]=-1;
    //task zero is explicitly never a send task
    for (i=NProcs-1;i>=1;i-=2) {sendtask[i]=i-1;sendset.push_back(i);}
    for (i=NProcs-2;i>=0;i-=2) {recvtask[i]=i+1;recvset.push_back(i);}
    //if odd number of tasks, then need to explicity add 0 to the recv task set
    if (NProcs%2==1) recvset.push_back(0);

    //keep sending till number of sending tasks == NProcs-1 and task 0 has all the info
    do {
        //if process no longer sending or receiving do nothing in this round
        if (!(sendtask[ThisTask]==-1 && recvtask[ThisTask]==-1)) {
            //if a send task
            if (sendtask[ThisTask]>=0 && recvtask[ThisTask]==-1) {
                commsize=idset.size();
                idarray=new long long[commsize];
                j=0; for (auto idval: idset) idarray[j++]=idval;
                //send size
                MPI_Send(&commsize,1, MPI_Int_t, sendtask[ThisTask], numloops*NProcs*NProcs+ThisTask, MPI_COMM_WORLD);
                //send info
                MPI_Send(idarray,commsize, MPI_LONG, sendtask[ThisTask], numloops*NProcs*NProcs+NProcs+ThisTask, MPI_COMM_WORLD);
                delete[] idarray;
            }
            //if a recvtask
            if (recvtask[ThisTask]>=0 && sendtask[ThisTask]==-1) {
                //recv size
                MPI_Recv(&commsize,1, MPI_Int_t, recvtask[ThisTask], numloops*NProcs*NProcs+recvtask[ThisTask], MPI_COMM_WORLD,&status);
                idarray=new long long[commsize];
                //recv info
                MPI_Recv(idarray,commsize, MPI_LONG, recvtask[ThisTask], numloops*NProcs*NProcs+NProcs+recvtask[ThisTask], MPI_COMM_WORLD,&status);
                for (i=0;i<commsize;i++) idset.insert(idarray[i]);
                delete[] idarray;
            }
        }
        //update the send receive taks for the next time around
        //all tasks that were send tasks now must not be included.
        MPI_Barrier(MPI_COMM_WORLD);
        nsendtasks=sendset.size();
        numhavesent+=nsendtasks;
        nrecvtasks=recvset.size();
        //reset tasks
        for (j=0;j<nsendtasks;j++) sendtask[sendset[j]]=-1;
        for (j=0;j<nrecvtasks;j++) recvtask[recvset[j]]=-1;
        //only tasks that were receiving before are part of the new send/recv set
        for (j=0;j<nrecvtasks-1;j+=2) sendtask[recvset[j]]=recvset[j+1];
        for (j=1;j<nrecvtasks;j+=2) recvtask[recvset[j]]=recvset[j-1];
        sendset.clear();
        recvset.clear();
        for (j=NProcs-1;j>=0;j--) if (sendtask[j]>=0) sendset.push_back(j);
        for (j=NProcs-1;j>=0;j--) if (recvtask[j]>=0) recvset.push_back(j);
        //if current set of communicating tasks set by the old recv task set is odd must explicity include 0
        if (nrecvtasks%2==1)recvset.push_back(0);
        numloops++;
    } while(numhavesent<NProcs-1);

    //now broadcast from root to all processors
    if (ThisTask==0) {
        commsize=idset.size();
        idvec=vector<long long>(idset.begin(), idset.end());
    }
    MPI_Bcast(&commsize,1, MPI_Int_t, 0, MPI_COMM_WORLD);
    if (ThisTask!=0) idvec=vector<long long>(commsize);
    MPI_Bcast(idvec.data(),commsize, MPI_LONG, 0, MPI_COMM_WORLD);
#else
    idvec=vector<long long>(idset.begin(), idset.end());
#endif
    opt.MaxIDValue=idvec.size();
    for (i=0;i<opt.MaxIDValue;i++) idmap.insert(pair<long long, long long>(idvec[i],(long long)i));
    time2=MyGetTime()-time2;
#ifdef USEMPI
    if (opt.iverbose && ThisTask==0) cout<<ThisTask<<" finished getting GLOBAL unique ids of "<<idvec.size()<<" in "<<time2<<endl;
#endif
    return idmap;
}

void MapPIDStoIndex(Options &opt, HaloTreeData *&pht, map<long long, long long> &idmap) {
#ifndef USEMPI
    int ThisTask=0;
#endif
    Int_t i,j,k;
    if (ThisTask==0) cout<<"Mapping PIDS to index "<<endl;
#ifdef USEOPENMP
#pragma omp parallel default(shared) \
private(i,j,k)
{
#pragma omp for schedule(dynamic) nowait
#endif
    for (i=0;i<opt.numsnapshots;i++) {
#ifdef USEMPI
    if (i>=StartSnap && i<EndSnap) {
#endif
        for (j=0;j<pht[i].numhalos;j++) {
            for (k=0;k<pht[i].Halo[j].NumberofParticles;k++){
                pht[i].Halo[j].ParticleID[k]=idmap[pht[i].Halo[j].ParticleID[k]];
            }
        }
#ifdef USEMPI
    }
#endif
    }
#ifdef USEOPENMP
}
#endif
}

void MapPIDStoIndex(Options &opt, HaloTreeData *&pht) {
#ifndef USEMPI
    int ThisTask=0;
#endif
    Int_t i,j,k;
    if (ThisTask==0) cout<<"Mapping PIDS to index "<<endl;
#ifdef USEOPENMP
#pragma omp parallel default(shared) \
private(i,j,k)
{
#pragma omp for schedule(dynamic) nowait
#endif
    for (i=0;i<opt.numsnapshots;i++) {
#ifdef USEMPI
    if (i>=StartSnap && i<EndSnap) {
#endif
        for (j=0;j<pht[i].numhalos;j++)
            for (k=0;k<pht[i].Halo[j].NumberofParticles;k++)
                opt.mappingfunc(pht[i].Halo[j].ParticleID[k]);
#ifdef USEMPI
    }
#endif
    }
#ifdef USEOPENMP
}
#endif
}

void simplemap(long unsigned int &i) {}

//@}

//check to see if ID data compatible with accessing index array allocated
void IDcheck(Options &opt, HaloTreeData *&pht){
    int ierrorflag=0,ierrorsumflag=0;
#ifndef USEMPI
    int ThisTask=0,NProcs=1,NSnap=opt.numsnapshots,StartSnap=0,EndSnap=opt.numsnapshots;
#endif
    for (int i=opt.numsnapshots-1;i>=0;i--) {
#ifdef USEMPI
    if (i>=StartSnap && i<EndSnap) {
#endif
        ierrorflag=0;
        for (Int_t j=0;j<pht[i].numhalos;j++) {
            for (Int_t k=0;k<pht[i].Halo[j].NumberofParticles;k++)
                if (pht[i].Halo[j].ParticleID[k]<0||pht[i].Halo[j].ParticleID[k]>opt.MaxIDValue) {
                    cout<<ThisTask<<" snapshot "<<i<<" particle id out of range "<<pht[i].Halo[j].ParticleID[k]<<" not in [0,"<<opt.MaxIDValue<<")"<<endl;
                    ierrorflag=1;
                    break;
                }
            if (ierrorflag==1) {ierrorsumflag+=1;break;}
        }
#ifdef USEMPI
    }
#endif
    }
#ifdef USEMPI
    int mpierrorflag;
    MPI_Allreduce(&ierrorsumflag,&mpierrorflag,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
    ierrorsumflag=mpierrorflag;
#endif
    if (ierrorsumflag>0) {
#ifdef USEMPI
        if (ThisTask==0)
#endif
        cout<<"Error in particle ids, outside of range. Exiting"<<endl;
#ifdef USEMPI
        MPI_Abort(MPI_COMM_WORLD,9);
#else
        exit(9);
#endif
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Core/Error.hpp>
#include <Nazara/Network/Enums.hpp>
#include <cstring>
#include <Nazara/Core/Debug.hpp>

namespace Nz
{
	/*!
	* \brief Constructs a NetPacket object by default
	*/

	inline NetPacket::NetPacket() :
	m_netCode(NetCode_Invalid)
	{
	}

	/*!
	* \brief Constructs a NetPacket object with a packet number and a minimal capacity
	*
	* \param netCode Packet number
	* \param minCapacity Minimal capacity of the packet
	*/

	inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity)
	{
		Reset(netCode, minCapacity);
	}

	/*!
	* \brief Constructs a NetPacket object with a packet number and raw memory
	*
	* \param netCode Packet number
	* \param ptr Raw memory
	* \param size Size of the memory
	*/

	inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size)
	{
		Reset(netCode, ptr, size);
	}

	/*!
	* \brief Constructs a NetPacket object with another one by move semantic
	*
	* \param packet NetPacket to move into this
	*/

	inline NetPacket::NetPacket(NetPacket&& packet) :
	ByteStream(std::move(packet)),
	m_buffer(std::move(packet.m_buffer)),
	m_memoryStream(std::move(packet.m_memoryStream)),
	m_netCode(packet.m_netCode)
	{
		///< Redirect memory stream to the moved buffer
		m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode());
		SetStream(&m_memoryStream);
	}

	/*!
	* \brief Destructs the object
	*/

	inline NetPacket::~NetPacket()
	{
		FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
		FreeStream();
	}

	/*!
	* \brief Gets the raw buffer
	* \return Constant raw buffer
	*
	* \remark Produces a NazaraAssert if internal buffer is invalid
	*/

	inline const UInt8* NetPacket::GetConstData() const
	{
		NazaraAssert(m_buffer, "Invalid buffer");

		return m_buffer->GetConstBuffer();
	}

	/*!
	* \brief Gets the raw buffer
	* \return Raw buffer
	*
	* \remark Produces a NazaraAssert if internal buffer is invalid
	*/

	inline UInt8* NetPacket::GetData() const
	{
		NazaraAssert(m_buffer, "Invalid buffer");

		return m_buffer->GetBuffer();
	}

	/*!
	* \brief Gets the size of the data
	* \return Size of the data
	*/

	inline size_t NetPacket::GetDataSize() const
	{
		if (m_buffer)
			return m_buffer->GetSize() - HeaderSize;
		else
			return 0;
	}

	/*!
	* \brief Gets the packet number
	* \return Packet number
	*/

	inline UInt16 NetPacket::GetNetCode() const
	{
		return m_netCode;
	}

	/*!
	* \brief Resets the packet
	*/

	inline void NetPacket::Reset()
	{
		FreeStream();
	}

	/*!
	* \brief Resets the packet with a packet number and a minimal capacity
	*
	* \param netCode Packet number
	* \param minCapacity Minimal capacity of the packet
	*/

	inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity)
	{
		InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite);
		m_netCode = netCode;
	}

	/*!
	* \brief Resets the packet with a packet number and raw memory
	*
	* \param netCode Packet number
	* \param ptr Raw memory
	* \param size Size of the memory
	*/

	inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size)
	{
		InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly);
		m_buffer->Resize(HeaderSize + size);

		if (ptr)
			std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size);

		m_netCode = netCode;
	}

	/*!
	* \brief Resizes the packet
	*
	* \param newSize Size for the resizing operation
	*
	* \remark Produces a NazaraAssert if internal buffer is invalid
	*/

	inline void NetPacket::Resize(std::size_t newSize)
	{
		NazaraAssert(m_buffer, "Invalid buffer");

		m_buffer->Resize(newSize);
	}

	/*!
	* \brief Sets the packet number
	*
	* \param netCode Packet number
	*/

	inline void NetPacket::SetNetCode(UInt16 netCode)
	{
		m_netCode = netCode;
	}

	/*!
	* \brief Moves the NetPacket into this
	* \return A reference to this
	*
	* \param packet NetPacket to move in this
	*/

	inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet)
	{
		FreeStream();

		ByteStream::operator=(std::move(packet));

		m_buffer = std::move(packet.m_buffer);
		m_memoryStream = std::move(packet.m_memoryStream);
		m_netCode = packet.m_netCode;

		///< Redirect memory stream to the moved buffer
		m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode());
		SetStream(&m_memoryStream);

		return *this;
	}
}

#include <Nazara/Core/DebugOff.hpp>
<commit_msg>Remove useless namespace prefix<commit_after>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Core/Error.hpp>
#include <Nazara/Network/Enums.hpp>
#include <cstring>
#include <Nazara/Core/Debug.hpp>

namespace Nz
{
	/*!
	* \brief Constructs a NetPacket object by default
	*/

	inline NetPacket::NetPacket() :
	m_netCode(NetCode_Invalid)
	{
	}

	/*!
	* \brief Constructs a NetPacket object with a packet number and a minimal capacity
	*
	* \param netCode Packet number
	* \param minCapacity Minimal capacity of the packet
	*/

	inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity)
	{
		Reset(netCode, minCapacity);
	}

	/*!
	* \brief Constructs a NetPacket object with a packet number and raw memory
	*
	* \param netCode Packet number
	* \param ptr Raw memory
	* \param size Size of the memory
	*/

	inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size)
	{
		Reset(netCode, ptr, size);
	}

	/*!
	* \brief Constructs a NetPacket object with another one by move semantic
	*
	* \param packet NetPacket to move into this
	*/

	inline NetPacket::NetPacket(NetPacket&& packet) :
	ByteStream(std::move(packet)),
	m_buffer(std::move(packet.m_buffer)),
	m_memoryStream(std::move(packet.m_memoryStream)),
	m_netCode(packet.m_netCode)
	{
		///< Redirect memory stream to the moved buffer
		m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode());
		SetStream(&m_memoryStream);
	}

	/*!
	* \brief Destructs the object
	*/

	inline NetPacket::~NetPacket()
	{
		FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
		FreeStream();
	}

	/*!
	* \brief Gets the raw buffer
	* \return Constant raw buffer
	*
	* \remark Produces a NazaraAssert if internal buffer is invalid
	*/

	inline const UInt8* NetPacket::GetConstData() const
	{
		NazaraAssert(m_buffer, "Invalid buffer");

		return m_buffer->GetConstBuffer();
	}

	/*!
	* \brief Gets the raw buffer
	* \return Raw buffer
	*
	* \remark Produces a NazaraAssert if internal buffer is invalid
	*/

	inline UInt8* NetPacket::GetData() const
	{
		NazaraAssert(m_buffer, "Invalid buffer");

		return m_buffer->GetBuffer();
	}

	/*!
	* \brief Gets the size of the data
	* \return Size of the data
	*/

	inline size_t NetPacket::GetDataSize() const
	{
		if (m_buffer)
			return m_buffer->GetSize() - HeaderSize;
		else
			return 0;
	}

	/*!
	* \brief Gets the packet number
	* \return Packet number
	*/

	inline UInt16 NetPacket::GetNetCode() const
	{
		return m_netCode;
	}

	/*!
	* \brief Resets the packet
	*/

	inline void NetPacket::Reset()
	{
		FreeStream();
	}

	/*!
	* \brief Resets the packet with a packet number and a minimal capacity
	*
	* \param netCode Packet number
	* \param minCapacity Minimal capacity of the packet
	*/

	inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity)
	{
		InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite);
		m_netCode = netCode;
	}

	/*!
	* \brief Resets the packet with a packet number and raw memory
	*
	* \param netCode Packet number
	* \param ptr Raw memory
	* \param size Size of the memory
	*/

	inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size)
	{
		InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly);
		m_buffer->Resize(HeaderSize + size);

		if (ptr)
			std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size);

		m_netCode = netCode;
	}

	/*!
	* \brief Resizes the packet
	*
	* \param newSize Size for the resizing operation
	*
	* \remark Produces a NazaraAssert if internal buffer is invalid
	*/

	inline void NetPacket::Resize(std::size_t newSize)
	{
		NazaraAssert(m_buffer, "Invalid buffer");

		m_buffer->Resize(newSize);
	}

	/*!
	* \brief Sets the packet number
	*
	* \param netCode Packet number
	*/

	inline void NetPacket::SetNetCode(UInt16 netCode)
	{
		m_netCode = netCode;
	}

	/*!
	* \brief Moves the NetPacket into this
	* \return A reference to this
	*
	* \param packet NetPacket to move in this
	*/

	inline NetPacket& NetPacket::operator=(NetPacket&& packet)
	{
		FreeStream();

		ByteStream::operator=(std::move(packet));

		m_buffer = std::move(packet.m_buffer);
		m_memoryStream = std::move(packet.m_memoryStream);
		m_netCode = packet.m_netCode;

		///< Redirect memory stream to the moved buffer
		m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode());
		SetStream(&m_memoryStream);

		return *this;
	}
}

#include <Nazara/Core/DebugOff.hpp>
<|endoftext|>


<commit_before>/*
 * File: CommentedConfigFile.cc
 *
 * Copyright (c) 2017 Stefan Hundhammer <Stefan.Hundhammer@gmx.de>
 *
 * This is part of the commented-config-file project.
 * License: GPL V2
 *
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * 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.
 *
 */

#include <fstream>
#include <iostream>
#include <algorithm>
#include <boost/algorithm/string.hpp>

#include "storage/Utils/CommentedConfigFile.h"
#include "storage/Utils/ExceptionImpl.h"
#include "storage/Utils/Logger.h"
#include "storage/Utils/AsciiFile.h"

using std::cout;
using std::endl;

#define WHITESPACE " \t"

using namespace storage;

CommentedConfigFile::CommentedConfigFile():
    comment_marker( "#" )
{
}

CommentedConfigFile::~CommentedConfigFile()
{
    clear_entries();
}

CommentedConfigFile::Entry * CommentedConfigFile::get_entry( int index ) const
{
    if ( index < 0 || index >= (int) entries.size() )
        return 0;
    else
        return entries[ index ];
}

int CommentedConfigFile::get_index_of( const Entry * wanted_entry ) const
{
    for ( size_t i=0; i < entries.size(); ++i )
    {
	if ( entries[i] == wanted_entry )
	    return i;
    }

    return -1;
}

CommentedConfigFile::Entry * CommentedConfigFile::take( int index )
{
    if ( index < 0 || index >= (int) entries.size() )
        return 0;

    Entry * entry = entries[ index ];
    entries.erase( entries.begin() + index );
    entry->set_parent( 0 );

    return entry;
}

void CommentedConfigFile::remove( int index )
{
    Entry * entry = take( index );

    if ( entry )
        delete entry;
}

void CommentedConfigFile::remove( Entry * entry )
{
    if ( ! entry )
        return;

    int index = get_index_of( entry );

    if ( index != -1 )
        remove( index );
}

void CommentedConfigFile::insert( int before, Entry * entry )
{
    entries.insert( entries.begin() + before, entry );
    entry->set_parent( this );
}

void CommentedConfigFile::append( Entry * entry )
{
    entries.push_back( entry );
    entry->set_parent( this );
}

bool CommentedConfigFile::read( const string & filename )
{
    this->filename = filename;

    // reading is done via AsciiFile to the mockup playback and recording

    AsciiFile ascii_file(filename);
    bool success = parse(ascii_file.get_lines());

    return success;
}

bool CommentedConfigFile::write( const string & new_filename )
{
    string name = new_filename;

    if ( new_filename.empty() )
        name = this->filename;
    else
        this->filename = name;

    if ( name.empty() ) // Support for mocking:
        return true;    // Pretend everything worked just fine.

    std::ofstream file( name, std::ofstream::out | std::ofstream::trunc );

    if ( ! file.is_open() )
        return false;

    string_vec lines = format_lines();

    for ( size_t i=0; i < lines.size(); ++i )
        file << lines[i] << "\n"; // no endl: Don't flush after every line

    return true;
}

bool CommentedConfigFile::parse( const string_vec & lines )
{
    clear_all();

    int header_end    = find_header_comment_end( lines );
    int footer_start  = find_footer_comment_start( lines, header_end + 1 );
    int content_start = 0;
    int content_end   = lines.size() - 1;

    if ( header_end > -1 )
    {
        for ( int i=0; i <= header_end; ++i )
            header_comments.push_back( lines[i] );

        content_start = header_end + 1;
    }

    if ( footer_start > -1 )
    {
        for ( size_t i = footer_start; i < lines.size(); ++i )
            footer_comments.push_back( lines[i] );

        content_end = footer_start - 1;
    }

    bool success = parse_entries( lines, content_start, content_end );

    return success;
}

bool CommentedConfigFile::parse_entries( const string_vec & lines,
                                         int from,
                                         int end )
{
    string_vec comment_before;
    bool success;

    for ( int i = from; i <= end; ++i )
    {
        const string & line = lines[i];

        if ( is_empty_line( line ) || is_comment_line( line ) )
            comment_before.push_back( line );
        else // found a content line
        {
            CommentedConfigFile::Entry * entry = create_entry();
            ST_CHECK_PTR( entry );

            entry->set_comment_before( comment_before );
            comment_before.clear();
            string content;
            string line_comment;
            split_off_comment( line, content, line_comment );
            entry->set_line_comment( line_comment );
            bool ok = entry->parse( content, i+1 );

            if ( ok )
                append( entry );
            else
            {
                success = false;
                delete entry;
            }
        }
    }

    return success;
}

int CommentedConfigFile::find_header_comment_end( const string_vec & lines )
{
    int header_end      = -1;
    int last_empty_line = -1;

    for ( int i=0; i < (int) lines.size(); ++i )
    {
        const string & line = lines[i];

        if ( is_empty_line( line ) )
            last_empty_line = i;
        else if ( is_comment_line( line ) )
            header_end = i;
        else // found the first content line
            break;
    }

    if ( last_empty_line > 0 )
    {
        header_end = last_empty_line;

        // This covers two cases:
        //
        // - If there were empty lines and no more comment lines before the
        //   first content line, the empty lines belong to the header comment.
        //
        // - If there were empty lines and then some more comment lines before
        //   the first content line, the comments after the last empty line no
        //   longer belong to the header comment, but to the first content
        //   entry. So let's go back to that last empty line.
    }

    return header_end;
}

int CommentedConfigFile::find_footer_comment_start( const string_vec & lines,
                                                    int from )
{
    int footer_start = -1;

    for ( int i = lines.size()-1; i >= from; --i )
    {
        const string & line = lines[i];

        if ( is_empty_line( line ) || is_comment_line( line ) )
            footer_start = i;
        else // found the last content line
            break;
    }

    return footer_start;
}

string_vec CommentedConfigFile::format_lines()
{
    string_vec lines = header_comments;

    for ( size_t i=0; i < entries.size(); ++i )
    {
        Entry * entry = entries[i];

        for ( size_t j=0; j < entry->get_comment_before().size(); ++j )
            lines.push_back( entry->get_comment_before()[j] );

        string line = entry->format();

        if ( ! entry->get_line_comment().empty() )
            line += " " + entry->get_line_comment();

        lines.push_back( line );
    }

    for ( size_t i=0; i < footer_comments.size(); ++i )
        lines.push_back( footer_comments[i] );

    return lines;
}

void CommentedConfigFile::clear_entries()
{
    for ( size_t i=0; i < entries.size(); ++i )
	delete entries[i];

    entries.clear();
}

void CommentedConfigFile::clear_all()
{
    clear_entries();
    header_comments.clear();
    footer_comments.clear();
}

bool CommentedConfigFile::is_comment_line( const string & line )
{
    size_t pos = line.find_first_not_of( WHITESPACE );

    if ( pos == string::npos ) // No non-whitespace character in line
        return false;

    if ( pos == 0 )
        return boost::starts_with( line, comment_marker );
    else
        return boost::starts_with( line.substr( pos ), comment_marker );
}

bool CommentedConfigFile::is_empty_line( const string & line )
{
    if ( line.empty() )
        return true;

    return line.find_first_not_of( WHITESPACE ) == string::npos;
}

void CommentedConfigFile::split_off_comment( const string & line,
					     string & content_ret,
					     string & comment_ret )
{
    size_t pos = line.find( comment_marker );

    if ( pos == string::npos )
    {
        comment_ret = "";
        content_ret = line;
    }
    else
    {
        content_ret = line.substr( 0, pos-1 );
        comment_ret = line.substr( pos );
    }

    strip_trailing_whitespace( content_ret );
}

void CommentedConfigFile::strip_trailing_whitespace( string & line )
{
    size_t pos = line.find_last_not_of( WHITESPACE );

    if ( pos != string::npos )
        line = line.substr( 0,  pos+1 );
    else
        line.clear();
}
<commit_msg>- initialize value<commit_after>/*
 * File: CommentedConfigFile.cc
 *
 * Copyright (c) 2017 Stefan Hundhammer <Stefan.Hundhammer@gmx.de>
 *
 * This is part of the commented-config-file project.
 * License: GPL V2
 *
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * 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.
 *
 */

#include <fstream>
#include <iostream>
#include <algorithm>
#include <boost/algorithm/string.hpp>

#include "storage/Utils/CommentedConfigFile.h"
#include "storage/Utils/ExceptionImpl.h"
#include "storage/Utils/Logger.h"
#include "storage/Utils/AsciiFile.h"

using std::cout;
using std::endl;

#define WHITESPACE " \t"

using namespace storage;

CommentedConfigFile::CommentedConfigFile():
    comment_marker( "#" )
{
}

CommentedConfigFile::~CommentedConfigFile()
{
    clear_entries();
}

CommentedConfigFile::Entry * CommentedConfigFile::get_entry( int index ) const
{
    if ( index < 0 || index >= (int) entries.size() )
        return 0;
    else
        return entries[ index ];
}

int CommentedConfigFile::get_index_of( const Entry * wanted_entry ) const
{
    for ( size_t i=0; i < entries.size(); ++i )
    {
	if ( entries[i] == wanted_entry )
	    return i;
    }

    return -1;
}

CommentedConfigFile::Entry * CommentedConfigFile::take( int index )
{
    if ( index < 0 || index >= (int) entries.size() )
        return 0;

    Entry * entry = entries[ index ];
    entries.erase( entries.begin() + index );
    entry->set_parent( 0 );

    return entry;
}

void CommentedConfigFile::remove( int index )
{
    Entry * entry = take( index );

    if ( entry )
        delete entry;
}

void CommentedConfigFile::remove( Entry * entry )
{
    if ( ! entry )
        return;

    int index = get_index_of( entry );

    if ( index != -1 )
        remove( index );
}

void CommentedConfigFile::insert( int before, Entry * entry )
{
    entries.insert( entries.begin() + before, entry );
    entry->set_parent( this );
}

void CommentedConfigFile::append( Entry * entry )
{
    entries.push_back( entry );
    entry->set_parent( this );
}

bool CommentedConfigFile::read( const string & filename )
{
    this->filename = filename;

    // reading is done via AsciiFile to the mockup playback and recording

    AsciiFile ascii_file(filename);
    bool success = parse(ascii_file.get_lines());

    return success;
}

bool CommentedConfigFile::write( const string & new_filename )
{
    string name = new_filename;

    if ( new_filename.empty() )
        name = this->filename;
    else
        this->filename = name;

    if ( name.empty() ) // Support for mocking:
        return true;    // Pretend everything worked just fine.

    std::ofstream file( name, std::ofstream::out | std::ofstream::trunc );

    if ( ! file.is_open() )
        return false;

    string_vec lines = format_lines();

    for ( size_t i=0; i < lines.size(); ++i )
        file << lines[i] << "\n"; // no endl: Don't flush after every line

    return true;
}

bool CommentedConfigFile::parse( const string_vec & lines )
{
    clear_all();

    int header_end    = find_header_comment_end( lines );
    int footer_start  = find_footer_comment_start( lines, header_end + 1 );
    int content_start = 0;
    int content_end   = lines.size() - 1;

    if ( header_end > -1 )
    {
        for ( int i=0; i <= header_end; ++i )
            header_comments.push_back( lines[i] );

        content_start = header_end + 1;
    }

    if ( footer_start > -1 )
    {
        for ( size_t i = footer_start; i < lines.size(); ++i )
            footer_comments.push_back( lines[i] );

        content_end = footer_start - 1;
    }

    bool success = parse_entries( lines, content_start, content_end );

    return success;
}

bool CommentedConfigFile::parse_entries( const string_vec & lines,
                                         int from,
                                         int end )
{
    string_vec comment_before;
    bool success = true;

    for ( int i = from; i <= end; ++i )
    {
        const string & line = lines[i];

        if ( is_empty_line( line ) || is_comment_line( line ) )
            comment_before.push_back( line );
        else // found a content line
        {
            CommentedConfigFile::Entry * entry = create_entry();
            ST_CHECK_PTR( entry );

            entry->set_comment_before( comment_before );
            comment_before.clear();
            string content;
            string line_comment;
            split_off_comment( line, content, line_comment );
            entry->set_line_comment( line_comment );
            bool ok = entry->parse( content, i+1 );

            if ( ok )
                append( entry );
            else
            {
                success = false;
                delete entry;
            }
        }
    }

    return success;
}

int CommentedConfigFile::find_header_comment_end( const string_vec & lines )
{
    int header_end      = -1;
    int last_empty_line = -1;

    for ( int i=0; i < (int) lines.size(); ++i )
    {
        const string & line = lines[i];

        if ( is_empty_line( line ) )
            last_empty_line = i;
        else if ( is_comment_line( line ) )
            header_end = i;
        else // found the first content line
            break;
    }

    if ( last_empty_line > 0 )
    {
        header_end = last_empty_line;

        // This covers two cases:
        //
        // - If there were empty lines and no more comment lines before the
        //   first content line, the empty lines belong to the header comment.
        //
        // - If there were empty lines and then some more comment lines before
        //   the first content line, the comments after the last empty line no
        //   longer belong to the header comment, but to the first content
        //   entry. So let's go back to that last empty line.
    }

    return header_end;
}

int CommentedConfigFile::find_footer_comment_start( const string_vec & lines,
                                                    int from )
{
    int footer_start = -1;

    for ( int i = lines.size()-1; i >= from; --i )
    {
        const string & line = lines[i];

        if ( is_empty_line( line ) || is_comment_line( line ) )
            footer_start = i;
        else // found the last content line
            break;
    }

    return footer_start;
}

string_vec CommentedConfigFile::format_lines()
{
    string_vec lines = header_comments;

    for ( size_t i=0; i < entries.size(); ++i )
    {
        Entry * entry = entries[i];

        for ( size_t j=0; j < entry->get_comment_before().size(); ++j )
            lines.push_back( entry->get_comment_before()[j] );

        string line = entry->format();

        if ( ! entry->get_line_comment().empty() )
            line += " " + entry->get_line_comment();

        lines.push_back( line );
    }

    for ( size_t i=0; i < footer_comments.size(); ++i )
        lines.push_back( footer_comments[i] );

    return lines;
}

void CommentedConfigFile::clear_entries()
{
    for ( size_t i=0; i < entries.size(); ++i )
	delete entries[i];

    entries.clear();
}

void CommentedConfigFile::clear_all()
{
    clear_entries();
    header_comments.clear();
    footer_comments.clear();
}

bool CommentedConfigFile::is_comment_line( const string & line )
{
    size_t pos = line.find_first_not_of( WHITESPACE );

    if ( pos == string::npos ) // No non-whitespace character in line
        return false;

    if ( pos == 0 )
        return boost::starts_with( line, comment_marker );
    else
        return boost::starts_with( line.substr( pos ), comment_marker );
}

bool CommentedConfigFile::is_empty_line( const string & line )
{
    if ( line.empty() )
        return true;

    return line.find_first_not_of( WHITESPACE ) == string::npos;
}

void CommentedConfigFile::split_off_comment( const string & line,
					     string & content_ret,
					     string & comment_ret )
{
    size_t pos = line.find( comment_marker );

    if ( pos == string::npos )
    {
        comment_ret = "";
        content_ret = line;
    }
    else
    {
        content_ret = line.substr( 0, pos-1 );
        comment_ret = line.substr( pos );
    }

    strip_trailing_whitespace( content_ret );
}

void CommentedConfigFile::strip_trailing_whitespace( string & line )
{
    size_t pos = line.find_last_not_of( WHITESPACE );

    if ( pos != string::npos )
        line = line.substr( 0,  pos+1 );
    else
        line.clear();
}
<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <Eigen/Dense>

namespace cilantro {
    std::vector<size_t> getPointToClusterIndexMap(const std::vector<std::vector<size_t>> &cluster_to_point,
                                                  size_t num_points)
    {
        std::vector<size_t> point_to_segment(num_points, cluster_to_point.size());
        for (size_t i = 0; i < cluster_to_point.size(); i++) {
            for (size_t j = 0; j < cluster_to_point[i].size(); j++) {
                point_to_segment[cluster_to_point[i][j]] = i;
            }
        }
        return point_to_segment;
    }

    std::vector<std::vector<size_t>> getClusterToPointIndicesMap(const std::vector<size_t> &point_to_cluster,
                                                                 size_t num_clusters)
    {
        std::vector<std::vector<size_t>> segment_to_point(num_clusters);
        for (size_t i = 0; i < point_to_cluster.size(); i++) {
            segment_to_point[point_to_cluster[i]].emplace_back(i);
        }
        return segment_to_point;
    }

    std::vector<size_t> getUnlabeledPointIndices(const std::vector<std::vector<size_t>> &segment_to_point_map,
                                                 const std::vector<size_t> &point_to_segment_map)
    {
        const size_t no_label = segment_to_point_map.size();
        std::vector<size_t> res;
        res.reserve(point_to_segment_map.size());
        for (size_t i = 0; i < point_to_segment_map.size(); i++) {
            if (point_to_segment_map[i] == no_label) res.emplace_back(i);
        }
        return res;
    }

    // CRTP base class that holds clustering results and accessors
    template <typename Derived = void>
    struct ClusteringBase {
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW

        ClusteringBase() = default;

        std::vector<std::vector<size_t>> clusterToPointIndicesMap;

        std::vector<size_t> pointToClusterIndexMap;

        inline const std::vector<std::vector<size_t>>& getClusterToPointIndicesMap() const { return clusterToPointIndicesMap; }

        inline const std::vector<size_t>& getPointToClusterIndexMap() const { return pointToClusterIndexMap; }

        inline size_t getNumberOfClusters() const { return clusterToPointIndicesMap.size(); }

        inline size_t getNumberOfPoints() const { return pointToClusterIndexMap.size(); }

        inline std::vector<size_t> getUnlabeledPointIndices() const {
            return cilantro::getUnlabeledPointIndices(clusterToPointIndicesMap, pointToClusterIndexMap);
        }
    };
}
<commit_msg>Removed unnecessary default ctor<commit_after>#pragma once

#include <vector>
#include <Eigen/Dense>

namespace cilantro {
    std::vector<size_t> getPointToClusterIndexMap(const std::vector<std::vector<size_t>> &cluster_to_point,
                                                  size_t num_points)
    {
        std::vector<size_t> point_to_segment(num_points, cluster_to_point.size());
        for (size_t i = 0; i < cluster_to_point.size(); i++) {
            for (size_t j = 0; j < cluster_to_point[i].size(); j++) {
                point_to_segment[cluster_to_point[i][j]] = i;
            }
        }
        return point_to_segment;
    }

    std::vector<std::vector<size_t>> getClusterToPointIndicesMap(const std::vector<size_t> &point_to_cluster,
                                                                 size_t num_clusters)
    {
        std::vector<std::vector<size_t>> segment_to_point(num_clusters);
        for (size_t i = 0; i < point_to_cluster.size(); i++) {
            segment_to_point[point_to_cluster[i]].emplace_back(i);
        }
        return segment_to_point;
    }

    std::vector<size_t> getUnlabeledPointIndices(const std::vector<std::vector<size_t>> &segment_to_point_map,
                                                 const std::vector<size_t> &point_to_segment_map)
    {
        const size_t no_label = segment_to_point_map.size();
        std::vector<size_t> res;
        res.reserve(point_to_segment_map.size());
        for (size_t i = 0; i < point_to_segment_map.size(); i++) {
            if (point_to_segment_map[i] == no_label) res.emplace_back(i);
        }
        return res;
    }

    // CRTP base class that holds clustering results and accessors
    template <typename Derived = void>
    struct ClusteringBase {
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW

        std::vector<std::vector<size_t>> clusterToPointIndicesMap;

        std::vector<size_t> pointToClusterIndexMap;

        inline const std::vector<std::vector<size_t>>& getClusterToPointIndicesMap() const { return clusterToPointIndicesMap; }

        inline const std::vector<size_t>& getPointToClusterIndexMap() const { return pointToClusterIndexMap; }

        inline size_t getNumberOfClusters() const { return clusterToPointIndicesMap.size(); }

        inline size_t getNumberOfPoints() const { return pointToClusterIndexMap.size(); }

        inline std::vector<size_t> getUnlabeledPointIndices() const {
            return cilantro::getUnlabeledPointIndices(clusterToPointIndicesMap, pointToClusterIndexMap);
        }
    };
}
<|endoftext|>