<commit_before>// This file is part of OpenMVG, an Open Multiple View Geometry C++ library.

// Copyright (c) 2019 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_GRAPHICS_COLOR_GRADIENT_HPP
#define OPENMVG_GRAPHICS_COLOR_GRADIENT_HPP

#include <vector>

namespace openMVG
{
namespace graphics
{

// Port made from http://www.andrewnoske.com/wiki/Code_-_heatmaps_and_color_gradients
// - Use c++11 style
// - Add multiple possible color gradient initialization
//
// --------------------
// How to use the code:
// --------------------
// 1. Create the object and configure the color gradient
// --------------------
// Color_Gradient heatMapGradient(Color_Gradient::k2BlueRedHeatMap());
// // Re-Initialize to use a gradient based on 5 colors
// //heatMapGradient = Color_Gradient(Color_Gradient::k5ColorHeatMap());
// --------------------
// 2. Get the color corresponding to the % range you want
// --------------------
// float r,g,b;
// const float interpolated_ratio = .5f;
// heatMapGradient.getColor(interpolated_ratio, r, g, b);
// // [r,g,b] are in the range [0, 1]
//
class Color_Gradient
{
public:
  struct Color_Point  // Internal class used to store colors at different points in the gradient.
  {
    float r, g, b;   // Red, green and blue values of our color.
    float val;       // Position of our color along the gradient (between 0 and 1).
    Color_Point(float red, float green, float blue, float value)
      : r(red), g(green), b(blue), val(value) {}
  };

  using Color_Points = std::vector<Color_Point>;

  //-- Places a 5 color heatmap gradient into the "color" vector:
  static const Color_Points k5ColorHeatMap()
  {
    return
    {
      {0, 0, 1,   0.0f},      // Blue
      {0, 1, 1,   0.25f},     // Cyan
      {0, 1, 0,   0.5f},      // Green
      {1, 1, 0,   0.75f},     // Yellow
      {1, 0, 0,   1.0f}       // Red
    };
  }

  //-- Places a 2 color heatmap gradient (Blue to Red):
  static const Color_Points k2BlueRedHeatMap()
  {
    return
    {
      {0, 0, 1,   0.0f}, // Blue
      {1, 0, 0,   1.0f}  // Red
    };
  }

private:
  Color_Points color_map;      // An array of color points in ascending value

public:
  //-- Default constructor:
  explicit Color_Gradient(const Color_Points & rhs_color = k5ColorHeatMap())
    : color_map(rhs_color)  {}

  //-- Inputs a (value) between 0 and 1 and outputs the (red), (green) and (blue)
  //-- values representing that position in the gradient.
  void getColor
  (
    const float value,
    float & red,
    float & green,
    float & blue
  ) const
  {
    if (color_map.empty())
      return;

    for (int i = 0; i < color_map.size(); ++i)
    {
      const Color_Point &currC = color_map[i];
      if (value < currC.val)
      {
        const Color_Point &prevC  = color_map[ std::max(0, i-1) ];
        const float valueDiff    = (prevC.val - currC.val);
        const float fractBetween = (valueDiff==0) ? 0 : (value - currC.val) / valueDiff;
        red   = (prevC.r - currC.r) * fractBetween + currC.r;
        green = (prevC.g - currC.g) * fractBetween + currC.g;
        blue  = (prevC.b - currC.b) * fractBetween + currC.b;
        return;
      }
    }
    red   = color_map.back().r;
    green = color_map.back().g;
    blue  = color_map.back().b;
    return;
  }
};

} // namespace graphics
} // namespace openMVG

#endif // OPENMVG_GRAPHICS_COLOR_GRADIENT_HPP
<commit_msg>[Build/CI] Fix for Microsoft Visual Studio compiler. #1594<commit_after>// This file is part of OpenMVG, an Open Multiple View Geometry C++ library.

// Copyright (c) 2019 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_GRAPHICS_COLOR_GRADIENT_HPP
#define OPENMVG_GRAPHICS_COLOR_GRADIENT_HPP

#include <algorithm>
#include <vector>

namespace openMVG
{
namespace graphics
{

// Port made from http://www.andrewnoske.com/wiki/Code_-_heatmaps_and_color_gradients
// - Use c++11 style
// - Add multiple possible color gradient initialization
//
// --------------------
// How to use the code:
// --------------------
// 1. Create the object and configure the color gradient
// --------------------
// Color_Gradient heatMapGradient(Color_Gradient::k2BlueRedHeatMap());
// // Re-Initialize to use a gradient based on 5 colors
// //heatMapGradient = Color_Gradient(Color_Gradient::k5ColorHeatMap());
// --------------------
// 2. Get the color corresponding to the % range you want
// --------------------
// float r,g,b;
// const float interpolated_ratio = .5f;
// heatMapGradient.getColor(interpolated_ratio, r, g, b);
// // [r,g,b] are in the range [0, 1]
//
class Color_Gradient
{
public:
  struct Color_Point  // Internal class used to store colors at different points in the gradient.
  {
    float r, g, b;   // Red, green and blue values of our color.
    float val;       // Position of our color along the gradient (between 0 and 1).
    Color_Point(float red, float green, float blue, float value)
      : r(red), g(green), b(blue), val(value) {}
  };

  using Color_Points = std::vector<Color_Point>;

  //-- Places a 5 color heatmap gradient into the "color" vector:
  static const Color_Points k5ColorHeatMap()
  {
    return
    {
      {0, 0, 1,   0.0f},      // Blue
      {0, 1, 1,   0.25f},     // Cyan
      {0, 1, 0,   0.5f},      // Green
      {1, 1, 0,   0.75f},     // Yellow
      {1, 0, 0,   1.0f}       // Red
    };
  }

  //-- Places a 2 color heatmap gradient (Blue to Red):
  static const Color_Points k2BlueRedHeatMap()
  {
    return
    {
      {0, 0, 1,   0.0f}, // Blue
      {1, 0, 0,   1.0f}  // Red
    };
  }

private:
  Color_Points color_map;      // An array of color points in ascending value

public:
  //-- Default constructor:
  explicit Color_Gradient(const Color_Points & rhs_color = k5ColorHeatMap())
    : color_map(rhs_color)  {}

  //-- Inputs a (value) between 0 and 1 and outputs the (red), (green) and (blue)
  //-- values representing that position in the gradient.
  void getColor
  (
    const float value,
    float & red,
    float & green,
    float & blue
  ) const
  {
    if (color_map.empty())
      return;

    for (int i = 0; i < color_map.size(); ++i)
    {
      const Color_Point &currC = color_map[i];
      if (value < currC.val)
      {
        const Color_Point &prevC  = color_map[ std::max(0, i-1) ];
        const float valueDiff    = (prevC.val - currC.val);
        const float fractBetween = (valueDiff==0) ? 0 : (value - currC.val) / valueDiff;
        red   = (prevC.r - currC.r) * fractBetween + currC.r;
        green = (prevC.g - currC.g) * fractBetween + currC.g;
        blue  = (prevC.b - currC.b) * fractBetween + currC.b;
        return;
      }
    }
    red   = color_map.back().r;
    green = color_map.back().g;
    blue  = color_map.back().b;
    return;
  }
};

} // namespace graphics
} // namespace openMVG

#endif // OPENMVG_GRAPHICS_COLOR_GRADIENT_HPP
<|endoftext|>


<commit_before><commit_msg>Fix BMC 21362 [L10N] CHT/JPN: Pasting JPN texts generates Tofu at the end<commit_after><|endoftext|>


<commit_before>/*
 * knob.hpp
 *
 * Created on: 02/11/2015
 *
 * =========================================================================
 *  Copyright (C) 2015-, Daniele De Sensi (d.desensi.software@gmail.com)
 *
 *  This file is part of AdaptiveFastFlow.
 *
 *  AdaptiveFastFlow is free software: you can redistribute it and/or
 *  modify it under the terms of the Lesser GNU General Public
 *  License as published by the Free Software Foundation, either
 *  version 3 of the License, or (at your option) any later version.

 *  AdaptiveFastFlow 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
 *  Lesser GNU General Public License for more details.
 *
 *  You should have received a copy of the Lesser GNU General Public
 *  License along with AdaptiveFastFlow.
 *  If not, see <http://www.gnu.org/licenses/>.
 *
 * =========================================================================
 */

#ifndef SRC_KNOB_HPP_
#define SRC_KNOB_HPP_

#include "node.hpp"

#include <ff/farm.hpp>

namespace adpff{

class Knob: public mammut::utils::NonCopyable{
public:
    Knob():_realValue(-1){;}

    /**
     * Changes the value of this knob.
     * @param v Is a value in the range [0, 100], representing the value to be
     *          set for the knob.
     */
    void setRelativeValue(double v);

    /**
     * Changes the value of this knob.
     * @param v Is the real value of the knob.
     */
    void setRealValue(double v);

    /**
     * Sets this knob to its maximum.
     */
    void setToMax();

    /**
     * Returns the current relative value [0, 100] of this knob.
     * @return The current relative value [0, 100] of this knob.
     */
    double getRelativeValue() const;

    /**
     * Returns the current real value of this knob.
     * @return The current real value of this knob.
     */
    double getRealValue() const;

    /**
     * Returns true if the best value for this knob needs to be automatically
     * found.
     * @return True if the best value for this knob needs to be automatically
     * found.
     */
    bool autoFind() const;

    /**
     * Returns a vector of allowed values for this knob.
     * @return A vector of allowed values for this knob.
     */
    virtual std::vector<double> getAllowedValues() const = 0;

    virtual ~Knob(){;}
protected:
    /**
     * Changes the value of this knob.
     * @param v Is the real value that this knob will have.
     */
    virtual void changeValueReal(double v) = 0;

    double _realValue;
};

class KnobWorkers: public Knob{
public:
    KnobWorkers(KnobConfWorkers confWorkers, AdaptiveNode* emitter,
                AdaptiveNode* collector, ff::ff_gatherer* gt,
                const std::vector<AdaptiveNode*> workers);

    void changeValueReal(double v);
    std::vector<double> getAllowedValues() const;
    uint getNumActiveWorkers() const;
    const std::vector<AdaptiveNode*>& getActiveWorkers() const;
private:
    /**
     * Prepares the nodes to freeze.
     */
    void prepareToFreeze();

    /**
     * Freezes all the nodes.
     */
    void freeze();

    /**
     * Prepares the nodes to run.
     * @param numWorkers The new number of workers.
     */
    void prepareToRun(uint numWorkers);

    /**
     * Runs the farm with a new number of workers.
     * @param numWorkers The new number of workers.
     */
    void run(uint numWorkers);

    /**
     * Notifies a change in the number of workers to all the nodes.
     * @param numWorkers The new number of workers.
     */
    void notifyNewConfiguration(uint numWorkers);

    KnobConfWorkers _confWorkers;
    AdaptiveNode* _emitter;
    AdaptiveNode* _collector;
    ff::ff_gatherer* _gt;
    const std::vector<AdaptiveNode*>& _allWorkers;
    std::vector<AdaptiveNode*> _activeWorkers;
    std::vector<double> _knobValues;
};

class KnobMapping: public Knob{
public:
    KnobMapping(KnobConfMapping confMapping,
                KnobConfSNodeMapping confEmitterMapping,
                KnobConfSNodeMapping confCollectorMapping,
                KnobConfHyperthreading confHyperthreading,
                const mammut::Mammut& mammut,
                AdaptiveNode* emitter,
                AdaptiveNode* collector,
                const KnobWorkers& knobWorkers);
    void changeValueReal(double v);
    std::vector<double> getAllowedValues() const;

    mammut::topology::VirtualCore* getEmitterVirtualCore() const;
    mammut::topology::VirtualCore* getCollectorVirtualCore() const;
    const std::vector<mammut::topology::VirtualCore*>& getWorkersVirtualCore() const;

    const std::vector<mammut::topology::VirtualCore*>& getActiveVirtualCores() const;
    const std::vector<mammut::topology::VirtualCore*>& getUnusedVirtualCores() const;
private:
    /**
     * Generates mapping indexes. They are indexes to be used on
     * _availableVirtualCores vector to get the corresponding virtual core
     * where a specific node must be mapped.
     * @param emitterIndex The index of the emitter.
     * @param firstWorkerIndex The index of the first worker (the others follow).
     * @param collectorIndex The index of the collector (if present).
     */
    void getMappingIndexes(size_t& emitterIndex,
                           size_t& firstWorkerIndex,
                           size_t& collectorIndex);

    /**
     * Computes the mapping order of virtual cores for linear
     * mapping.
     */
    void computeVcOrderLinear();

    /**
     * Performs a linear mapping of the nodes on the available virtual cores.
     */
    void performLinearMapping();

    KnobConfMapping _confMapping;
    KnobConfSNodeMapping _confEmitterMapping;
    KnobConfSNodeMapping _confCollectorMapping;
    KnobConfHyperthreading _confHyperthreading;

    // The available virtual cores, sorted according to the mapping strategy.
    std::vector<mammut::topology::VirtualCore*>& _vcOrder;
    std::vector<mammut::topology::VirtualCore*> _vcOrderLinear;
    std::vector<mammut::topology::VirtualCore*> _vcOrderCacheEfficient;

    std::vector<mammut::topology::VirtualCore*> _activeVirtualCores;
    std::vector<mammut::topology::VirtualCore*> _unusedVirtualCores;

    mammut::topology::VirtualCore* _emitterVirtualCore;
    mammut::topology::VirtualCore* _collectorVirtualCore;
    std::vector<mammut::topology::VirtualCore*> _workersVirtualCores;
    AdaptiveNode* _emitter;
    AdaptiveNode* _collector;
    const KnobWorkers& _knobWorkers;
    mammut::topology::Topology* _topologyHandler;
};

class KnobFrequency: public Knob{
public:
    KnobFrequency(KnobConfFrequencies confFrequency,
                  const mammut::Mammut& mammut,
                  bool useTurboBoost,
                  StrategyUnusedVirtualCores unusedVc,
                  const KnobMapping& knobMapping);
    void changeValueReal(double v);
    std::vector<double> getAllowedValues() const;
private:
    void applyUnusedVCStrategyOff(const std::vector<mammut::topology::VirtualCore*>& unusedVc);
    void applyUnusedVCStrategyLowestFreq(const std::vector<mammut::topology::VirtualCore*>& vc);
    void applyUnusedVCStrategy();

    KnobConfFrequencies _confFrequency;
    std::vector<double> _allowedValues;
    mammut::cpufreq::CpuFreq* _frequencyHandler;
    mammut::topology::Topology* _topologyHandler;
    mammut::cpufreq::CpuFreq* _cpufreqHandle;
    StrategyUnusedVirtualCores _unusedVc;
    const KnobMapping& _knobMapping;
};

typedef enum{
    KNOB_TYPE_WORKERS = 0,
    KNOB_TYPE_MAPPING,
    KNOB_TYPE_FREQUENCY,
    KNOB_TYPE_NUM // <---- This must always be the last value
}KnobType;

typedef enum{
    KNOB_VALUE_UNDEF = 0,
    KNOB_VALUE_REAL,
    KNOB_VALUE_RELATIVE
}KnobValueType;

class KnobsValues{
private:
    KnobValueType _type;
    double _values[KNOB_TYPE_NUM];
public:
    KnobsValues(KnobValueType type = KNOB_VALUE_UNDEF):_type(type){;}

    inline bool areRelative() const{return _type == KNOB_VALUE_RELATIVE;}

    inline bool areReal() const{return _type == KNOB_VALUE_REAL;}

    inline double& operator[](KnobType idx){
        return _values[idx];
    }

    inline double operator[](KnobType idx) const{
        return _values[idx];
    }
};

inline std::ostream& operator<<(std::ostream& os, const KnobsValues& obj){
    os << "[";
    for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
        os << obj[(KnobType) i] << ", ";
    }
    os << "]";
    return os;
}

inline bool operator==(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
        if(lhs[(KnobType) i] !=
           rhs[(KnobType) i]){
            return false;
        }
    }
    return true;
}

inline bool operator!=(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    return !operator==(lhs,rhs);
}

inline bool operator<(const KnobsValues& lhs,
                      const KnobsValues& rhs){
    for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
        if(lhs[(KnobType) i] <
           rhs[(KnobType) i]){
            return true;
        }else if(lhs[(KnobType) i] >
                 rhs[(KnobType) i]){
            return false;
        }
    }
    return false;
}

inline bool operator>(const KnobsValues& lhs,
                      const KnobsValues& rhs){
    return operator< (rhs,lhs);
}

inline bool operator<=(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    return !operator> (lhs,rhs);
}

inline bool operator>=(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    return !operator< (lhs,rhs);
}

}

#endif /* SRC_KNOB_HPP_ */
<commit_msg>[FIX] Fixed bug on KnobWorkers<commit_after>/*
 * knob.hpp
 *
 * Created on: 02/11/2015
 *
 * =========================================================================
 *  Copyright (C) 2015-, Daniele De Sensi (d.desensi.software@gmail.com)
 *
 *  This file is part of AdaptiveFastFlow.
 *
 *  AdaptiveFastFlow is free software: you can redistribute it and/or
 *  modify it under the terms of the Lesser GNU General Public
 *  License as published by the Free Software Foundation, either
 *  version 3 of the License, or (at your option) any later version.

 *  AdaptiveFastFlow 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
 *  Lesser GNU General Public License for more details.
 *
 *  You should have received a copy of the Lesser GNU General Public
 *  License along with AdaptiveFastFlow.
 *  If not, see <http://www.gnu.org/licenses/>.
 *
 * =========================================================================
 */

#ifndef SRC_KNOB_HPP_
#define SRC_KNOB_HPP_

#include "node.hpp"

#include <ff/farm.hpp>

namespace adpff{

class Knob: public mammut::utils::NonCopyable{
public:
    Knob():_realValue(-1){;}

    /**
     * Changes the value of this knob.
     * @param v Is a value in the range [0, 100], representing the value to be
     *          set for the knob.
     */
    void setRelativeValue(double v);

    /**
     * Changes the value of this knob.
     * @param v Is the real value of the knob.
     */
    void setRealValue(double v);

    /**
     * Sets this knob to its maximum.
     */
    void setToMax();

    /**
     * Returns the current relative value [0, 100] of this knob.
     * @return The current relative value [0, 100] of this knob.
     */
    double getRelativeValue() const;

    /**
     * Returns the current real value of this knob.
     * @return The current real value of this knob.
     */
    double getRealValue() const;

    /**
     * Returns true if the best value for this knob needs to be automatically
     * found.
     * @return True if the best value for this knob needs to be automatically
     * found.
     */
    bool autoFind() const;

    /**
     * Returns a vector of allowed values for this knob.
     * @return A vector of allowed values for this knob.
     */
    virtual std::vector<double> getAllowedValues() const = 0;

    virtual ~Knob(){;}
protected:
    /**
     * Changes the value of this knob.
     * @param v Is the real value that this knob will have.
     */
    virtual void changeValueReal(double v) = 0;

    double _realValue;
};

class KnobWorkers: public Knob{
public:
    KnobWorkers(KnobConfWorkers confWorkers, AdaptiveNode* emitter,
                AdaptiveNode* collector, ff::ff_gatherer* gt,
                const std::vector<AdaptiveNode*> workers);

    void changeValueReal(double v);
    std::vector<double> getAllowedValues() const;
    uint getNumActiveWorkers() const;
    const std::vector<AdaptiveNode*>& getActiveWorkers() const;
private:
    /**
     * Prepares the nodes to freeze.
     */
    void prepareToFreeze();

    /**
     * Freezes all the nodes.
     */
    void freeze();

    /**
     * Prepares the nodes to run.
     * @param numWorkers The new number of workers.
     */
    void prepareToRun(uint numWorkers);

    /**
     * Runs the farm with a new number of workers.
     * @param numWorkers The new number of workers.
     */
    void run(uint numWorkers);

    /**
     * Notifies a change in the number of workers to all the nodes.
     * @param numWorkers The new number of workers.
     */
    void notifyNewConfiguration(uint numWorkers);

    KnobConfWorkers _confWorkers;
    AdaptiveNode* _emitter;
    AdaptiveNode* _collector;
    ff::ff_gatherer* _gt;
    const std::vector<AdaptiveNode*> _allWorkers;
    std::vector<AdaptiveNode*> _activeWorkers;
    std::vector<double> _knobValues;
};

class KnobMapping: public Knob{
public:
    KnobMapping(KnobConfMapping confMapping,
                KnobConfSNodeMapping confEmitterMapping,
                KnobConfSNodeMapping confCollectorMapping,
                KnobConfHyperthreading confHyperthreading,
                const mammut::Mammut& mammut,
                AdaptiveNode* emitter,
                AdaptiveNode* collector,
                const KnobWorkers& knobWorkers);
    void changeValueReal(double v);
    std::vector<double> getAllowedValues() const;

    mammut::topology::VirtualCore* getEmitterVirtualCore() const;
    mammut::topology::VirtualCore* getCollectorVirtualCore() const;
    const std::vector<mammut::topology::VirtualCore*>& getWorkersVirtualCore() const;

    const std::vector<mammut::topology::VirtualCore*>& getActiveVirtualCores() const;
    const std::vector<mammut::topology::VirtualCore*>& getUnusedVirtualCores() const;
private:
    /**
     * Generates mapping indexes. They are indexes to be used on
     * _availableVirtualCores vector to get the corresponding virtual core
     * where a specific node must be mapped.
     * @param emitterIndex The index of the emitter.
     * @param firstWorkerIndex The index of the first worker (the others follow).
     * @param collectorIndex The index of the collector (if present).
     */
    void getMappingIndexes(size_t& emitterIndex,
                           size_t& firstWorkerIndex,
                           size_t& collectorIndex);

    /**
     * Computes the mapping order of virtual cores for linear
     * mapping.
     */
    void computeVcOrderLinear();

    /**
     * Performs a linear mapping of the nodes on the available virtual cores.
     */
    void performLinearMapping();

    KnobConfMapping _confMapping;
    KnobConfSNodeMapping _confEmitterMapping;
    KnobConfSNodeMapping _confCollectorMapping;
    KnobConfHyperthreading _confHyperthreading;

    // The available virtual cores, sorted according to the mapping strategy.
    std::vector<mammut::topology::VirtualCore*>& _vcOrder;
    std::vector<mammut::topology::VirtualCore*> _vcOrderLinear;
    std::vector<mammut::topology::VirtualCore*> _vcOrderCacheEfficient;

    std::vector<mammut::topology::VirtualCore*> _activeVirtualCores;
    std::vector<mammut::topology::VirtualCore*> _unusedVirtualCores;

    mammut::topology::VirtualCore* _emitterVirtualCore;
    mammut::topology::VirtualCore* _collectorVirtualCore;
    std::vector<mammut::topology::VirtualCore*> _workersVirtualCores;
    AdaptiveNode* _emitter;
    AdaptiveNode* _collector;
    const KnobWorkers& _knobWorkers;
    mammut::topology::Topology* _topologyHandler;
};

class KnobFrequency: public Knob{
public:
    KnobFrequency(KnobConfFrequencies confFrequency,
                  const mammut::Mammut& mammut,
                  bool useTurboBoost,
                  StrategyUnusedVirtualCores unusedVc,
                  const KnobMapping& knobMapping);
    void changeValueReal(double v);
    std::vector<double> getAllowedValues() const;
private:
    void applyUnusedVCStrategyOff(const std::vector<mammut::topology::VirtualCore*>& unusedVc);
    void applyUnusedVCStrategyLowestFreq(const std::vector<mammut::topology::VirtualCore*>& vc);
    void applyUnusedVCStrategy();

    KnobConfFrequencies _confFrequency;
    std::vector<double> _allowedValues;
    mammut::cpufreq::CpuFreq* _frequencyHandler;
    mammut::topology::Topology* _topologyHandler;
    mammut::cpufreq::CpuFreq* _cpufreqHandle;
    StrategyUnusedVirtualCores _unusedVc;
    const KnobMapping& _knobMapping;
};

typedef enum{
    KNOB_TYPE_WORKERS = 0,
    KNOB_TYPE_MAPPING,
    KNOB_TYPE_FREQUENCY,
    KNOB_TYPE_NUM // <---- This must always be the last value
}KnobType;

typedef enum{
    KNOB_VALUE_UNDEF = 0,
    KNOB_VALUE_REAL,
    KNOB_VALUE_RELATIVE
}KnobValueType;

class KnobsValues{
private:
    KnobValueType _type;
    double _values[KNOB_TYPE_NUM];
public:
    KnobsValues(KnobValueType type = KNOB_VALUE_UNDEF):_type(type){;}

    inline bool areRelative() const{return _type == KNOB_VALUE_RELATIVE;}

    inline bool areReal() const{return _type == KNOB_VALUE_REAL;}

    inline double& operator[](KnobType idx){
        return _values[idx];
    }

    inline double operator[](KnobType idx) const{
        return _values[idx];
    }
};

inline std::ostream& operator<<(std::ostream& os, const KnobsValues& obj){
    os << "[";
    for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
        os << obj[(KnobType) i] << ", ";
    }
    os << "]";
    return os;
}

inline bool operator==(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
        if(lhs[(KnobType) i] !=
           rhs[(KnobType) i]){
            return false;
        }
    }
    return true;
}

inline bool operator!=(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    return !operator==(lhs,rhs);
}

inline bool operator<(const KnobsValues& lhs,
                      const KnobsValues& rhs){
    for(size_t i = 0; i < KNOB_TYPE_NUM; i++){
        if(lhs[(KnobType) i] <
           rhs[(KnobType) i]){
            return true;
        }else if(lhs[(KnobType) i] >
                 rhs[(KnobType) i]){
            return false;
        }
    }
    return false;
}

inline bool operator>(const KnobsValues& lhs,
                      const KnobsValues& rhs){
    return operator< (rhs,lhs);
}

inline bool operator<=(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    return !operator> (lhs,rhs);
}

inline bool operator>=(const KnobsValues& lhs,
                       const KnobsValues& rhs){
    return !operator< (lhs,rhs);
}

}

#endif /* SRC_KNOB_HPP_ */
<|endoftext|>


<commit_before>#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>

#include "link.h"
#include "util/log.h"

#define MAX_PACKET_SIZE		32 * 1024 * 1024

int Link::min_recv_buf = 128 * 1024;
int Link::min_send_buf = 128 * 1024;

Link::Link(bool is_server){
	sock = -1;
	noblock_ = false;
	if(is_server){
		input = output = NULL;
	}else{
		input = new Buffer(Link::min_recv_buf);
		output = new Buffer(Link::min_send_buf);
	}
}

Link::~Link(){
	if(input){
		delete input;
	}
	if(output){
		delete output;
	}
	this->close();
}

void Link::close(){
	if(sock >= 0){
		::close(sock);
	}
}

void Link::nodelay(bool enable){
	int opt = enable? 1 : 0;
	::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt));
}

void Link::keepalive(bool enable){
	int opt = enable? 1 : 0;
	::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt));
}

void Link::noblock(bool enable){
	noblock_ = enable;
	if(enable){
		::fcntl(sock, F_SETFL, O_NONBLOCK | O_RDWR);
	}else{
		::fcntl(sock, F_SETFL, O_RDWR);
	}
}

Link* Link::connect(const char *ip, int port){
	Link *link;
	int sock = -1;

	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons((short)port);
	inet_pton(AF_INET, ip, &addr.sin_addr);

	if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){
		goto sock_err;
	}
	if(::connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
		goto sock_err;
	}

	log_debug("fd: %d, connect to %s:%d", sock, ip, port);
	link = new Link();
	link->sock = sock;
	link->keepalive(true);
	return link;
sock_err:
	log_debug("connect to %s:%d failed: %s", ip, port, strerror(errno));
	if(sock >= 0){
		::close(sock);
	}
	return NULL;
}

Link* Link::listen(const char *ip, int port){
	Link *link;
	int sock = -1;

	int opt = 1;
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons((short)port);
	inet_pton(AF_INET, ip, &addr.sin_addr);

	if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){
		goto sock_err;
	}
	if(::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){
		goto sock_err;
	}
	if(::bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
		goto sock_err;
	}
	if(::listen(sock, 5) == -1){
		goto sock_err;
	}
	log_debug("server socket fd: %d, listen on: %s:%d", sock, ip, port);

	link = new Link(true);
	link->sock = sock;
	return link;
sock_err:
	log_debug("listen %s:%d failed: %s", ip, port, strerror(errno));
	if(sock >= 0){
		::close(sock);
	}
	return NULL;
}

Link* Link::accept(){
	Link *link;
	int client_sock;
	struct sockaddr_in addr;
	socklen_t addrlen = sizeof(addr);
	char ip_str[INET_ADDRSTRLEN];

	while((client_sock = ::accept(sock, (struct sockaddr *)&addr, &addrlen)) == -1){
		if(errno != EINTR){
			log_error("socket %d accept failed: %s", sock, strerror(errno));
			return NULL;
		}
	}
	inet_ntop(AF_INET, &addr.sin_addr, ip_str, sizeof(ip_str));
	log_debug("accept: %d, from %s:%d", client_sock, ip_str, ntohs(addr.sin_port));

	struct linger opt = {1, 0};
	int ret = ::setsockopt(client_sock, SOL_SOCKET, SO_LINGER, (void *)&opt, sizeof(opt));
	if (ret != 0) {
		log_error("socket %d set linger failed: %s", client_sock, strerror(errno));
	}

	link = new Link();
	link->sock = client_sock;
	link->keepalive(true);
	return link;
}

int Link::read(){
	int ret = 0;
	int want;
	input->nice();
	while((want = input->space()) > 0){
		if(want > 128 * 1024){
			want = 128 * 1024;
		}
		// test
		//want = 1;
		int len = ::read(sock, input->slot(), want);
		if(len == -1){
			if(errno == EINTR){
				continue;
			}else if(errno == EWOULDBLOCK){
				break;
			}else{
				log_debug("fd: %d, read: -1, want: %d, error: %s", sock, want, strerror(errno));
				return -1;
			}
		}else{
			//log_debug("fd: %d, want=%d, read: %d", sock, want, len);
			if(len == 0){
				return 0;
			}
			ret += len;
			input->incr(len);
		}
		if(!noblock_){
			break;
		}
	}
	//log_debug("read %d", ret);
	return ret;
}

int Link::write(){
	int ret = 0;
	int want;
	while((want = output->size()) > 0){
		// test
		//want = 1;
		int len = ::write(sock, output->data(), want);
		if(len == -1){
			if(errno == EINTR){
				continue;
			}else if(errno == EWOULDBLOCK){
				break;
			}else{
				log_debug("fd: %d, write: -1, error: %s", sock, strerror(errno));
				return -1;
			}
		}else{
			//log_debug("fd: %d, want: %d, write: %d", sock, want, len);
			if(len == 0){
				// ?
				break;
			}
			ret += len;
			output->decr(len);
		}
		if(!noblock_){
			break;
		}
	}
	output->nice();
	return ret;
}

int Link::flush(){
	int len = 0;
	while(!output->empty()){
		int ret = this->write();
		if(ret == -1){
			return -1;
		}
		len += ret;
	}
	return len;
}

const std::vector<Bytes>* Link::recv(){
	this->recv_data.clear();

	if(input->empty()){
		return &this->recv_data;
	}

	// TODO: 记住上回的解析状态
	int parsed = 0;
	int size = input->size();
	char *head = input->data();

	// ignore leading empty lines
	while(size > 0 && (head[0] == '\n' || head[0] == '\r')){
		head ++;
		size --;
		parsed ++;
	}

	while(size > 0){
		char *body = (char *)memchr(head, '\n', size);
		if(body == NULL){
			break;
		}
		body ++;

		int head_len = body - head;
		if(head_len == 1 || (head_len == 2 && head[0] == '\r')){
			// packet end
			parsed += head_len;
			input->decr(parsed);
			return &this->recv_data;;
		}
		if(head[0] < '0' || head[0] > '9'){
			log_warn("bad format");
			return NULL;
		}

		char head_str[20];
		if(head_len > sizeof(head_str) - 1){
			return NULL;
		}
		memcpy(head_str, head, head_len - 1); // no '\n'
		head_str[head_len - 1] = '\0';

		int body_len = atoi(head_str);
		if(body_len < 0){
			log_warn("bad format");
			return NULL;
		}
		//log_debug("size: %d, head_len: %d, body_len: %d", size, head_len, body_len);
		size -= head_len + body_len;
		if(size < 0){
			break;
		}

		this->recv_data.push_back(Bytes(body, body_len));

		head += head_len + body_len;
		parsed += head_len + body_len;
		if(size > 0 && head[0] == '\n'){
			head += 1;
			size -= 1;
			parsed += 1;
		}else if(size > 1 && head[0] == '\r' && head[1] == '\n'){
			head += 2;
			size -= 2;
			parsed += 2;
		}else{
			break;
		}
		if(parsed > MAX_PACKET_SIZE){
			 log_warn("fd: %d, exceed max packet size, parsed: %d", this->sock, parsed);
			 return NULL;
		}
	}

	if(input->space() == 0){
		input->nice();
		if(input->space() == 0){
			if(input->grow() == -1){
				log_error("fd: %d, unable to resize input buffer!", this->sock);
				return NULL;
			}
			log_debug("fd: %d, resize input buffer, %s", this->sock, input->stats().c_str());
		}
	}

	// not ready
	this->recv_data.clear();
	return &this->recv_data;
}

int Link::send(const std::vector<std::string> &resp){
	for(int i=0; i<resp.size(); i++){
		output->append_record(resp[i]);
	}
	output->append('\n');
	return this->write();
}

int Link::send(const std::vector<Bytes> &resp){
	for(int i=0; i<resp.size(); i++){
		output->append_record(resp[i]);
	}
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1){
	output->append_record(s1);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2){
	output->append_record(s1);
	output->append_record(s2);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3){
	output->append_record(s1);
	output->append_record(s2);
	output->append_record(s3);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4){
	output->append_record(s1);
	output->append_record(s2);
	output->append_record(s3);
	output->append_record(s4);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5){
	output->append_record(s1);
	output->append_record(s2);
	output->append_record(s3);
	output->append_record(s4);
	output->append_record(s5);
	output->append('\n');
	return this->write();
}

#if 0
int main(){
	//Link link;
	//link.listen("127.0.0.1", 8888);
	Link *link = Link::connect("127.0.0.1", 8080);
	printf("%d\n", link);
	getchar();
	return 0;
}
#endif
<commit_msg>udpate<commit_after>#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>

#include "link.h"
#include "util/log.h"

#define MAX_PACKET_SIZE		32 * 1024 * 1024

int Link::min_recv_buf = 128 * 1024;
int Link::min_send_buf = 128 * 1024;

Link::Link(bool is_server){
	sock = -1;
	noblock_ = false;
	if(is_server){
		input = output = NULL;
	}else{
		input = new Buffer(Link::min_recv_buf);
		output = new Buffer(Link::min_send_buf);
	}
}

Link::~Link(){
	if(input){
		delete input;
	}
	if(output){
		delete output;
	}
	this->close();
}

void Link::close(){
	if(sock >= 0){
		::close(sock);
	}
}

void Link::nodelay(bool enable){
	int opt = enable? 1 : 0;
	::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt));
}

void Link::keepalive(bool enable){
	int opt = enable? 1 : 0;
	::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt));
}

void Link::noblock(bool enable){
	noblock_ = enable;
	if(enable){
		::fcntl(sock, F_SETFL, O_NONBLOCK | O_RDWR);
	}else{
		::fcntl(sock, F_SETFL, O_RDWR);
	}
}

Link* Link::connect(const char *ip, int port){
	Link *link;
	int sock = -1;

	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons((short)port);
	inet_pton(AF_INET, ip, &addr.sin_addr);

	if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){
		goto sock_err;
	}
	if(::connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
		goto sock_err;
	}

	log_debug("fd: %d, connect to %s:%d", sock, ip, port);
	link = new Link();
	link->sock = sock;
	link->keepalive(true);
	return link;
sock_err:
	log_debug("connect to %s:%d failed: %s", ip, port, strerror(errno));
	if(sock >= 0){
		::close(sock);
	}
	return NULL;
}

Link* Link::listen(const char *ip, int port){
	Link *link;
	int sock = -1;

	int opt = 1;
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons((short)port);
	inet_pton(AF_INET, ip, &addr.sin_addr);

	if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){
		goto sock_err;
	}
	if(::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){
		goto sock_err;
	}
	if(::bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
		goto sock_err;
	}
	if(::listen(sock, 1024) == -1){
		goto sock_err;
	}
	log_debug("server socket fd: %d, listen on: %s:%d", sock, ip, port);

	link = new Link(true);
	link->sock = sock;
	return link;
sock_err:
	log_debug("listen %s:%d failed: %s", ip, port, strerror(errno));
	if(sock >= 0){
		::close(sock);
	}
	return NULL;
}

Link* Link::accept(){
	Link *link;
	int client_sock;
	struct sockaddr_in addr;
	socklen_t addrlen = sizeof(addr);
	char ip_str[INET_ADDRSTRLEN];

	while((client_sock = ::accept(sock, (struct sockaddr *)&addr, &addrlen)) == -1){
		if(errno != EINTR){
			log_error("socket %d accept failed: %s", sock, strerror(errno));
			return NULL;
		}
	}
	inet_ntop(AF_INET, &addr.sin_addr, ip_str, sizeof(ip_str));
	log_debug("accept: %d, from %s:%d", client_sock, ip_str, ntohs(addr.sin_port));

	struct linger opt = {1, 0};
	int ret = ::setsockopt(client_sock, SOL_SOCKET, SO_LINGER, (void *)&opt, sizeof(opt));
	if (ret != 0) {
		log_error("socket %d set linger failed: %s", client_sock, strerror(errno));
	}

	link = new Link();
	link->sock = client_sock;
	link->keepalive(true);
	return link;
}

int Link::read(){
	int ret = 0;
	int want;
	input->nice();
	while((want = input->space()) > 0){
		if(want > 128 * 1024){
			want = 128 * 1024;
		}
		// test
		//want = 1;
		int len = ::read(sock, input->slot(), want);
		if(len == -1){
			if(errno == EINTR){
				continue;
			}else if(errno == EWOULDBLOCK){
				break;
			}else{
				log_debug("fd: %d, read: -1, want: %d, error: %s", sock, want, strerror(errno));
				return -1;
			}
		}else{
			//log_debug("fd: %d, want=%d, read: %d", sock, want, len);
			if(len == 0){
				return 0;
			}
			ret += len;
			input->incr(len);
		}
		if(!noblock_){
			break;
		}
	}
	//log_debug("read %d", ret);
	return ret;
}

int Link::write(){
	int ret = 0;
	int want;
	while((want = output->size()) > 0){
		// test
		//want = 1;
		int len = ::write(sock, output->data(), want);
		if(len == -1){
			if(errno == EINTR){
				continue;
			}else if(errno == EWOULDBLOCK){
				break;
			}else{
				log_debug("fd: %d, write: -1, error: %s", sock, strerror(errno));
				return -1;
			}
		}else{
			//log_debug("fd: %d, want: %d, write: %d", sock, want, len);
			if(len == 0){
				// ?
				break;
			}
			ret += len;
			output->decr(len);
		}
		if(!noblock_){
			break;
		}
	}
	output->nice();
	return ret;
}

int Link::flush(){
	int len = 0;
	while(!output->empty()){
		int ret = this->write();
		if(ret == -1){
			return -1;
		}
		len += ret;
	}
	return len;
}

const std::vector<Bytes>* Link::recv(){
	this->recv_data.clear();

	if(input->empty()){
		return &this->recv_data;
	}

	// TODO: 记住上回的解析状态
	int parsed = 0;
	int size = input->size();
	char *head = input->data();

	// ignore leading empty lines
	while(size > 0 && (head[0] == '\n' || head[0] == '\r')){
		head ++;
		size --;
		parsed ++;
	}

	while(size > 0){
		char *body = (char *)memchr(head, '\n', size);
		if(body == NULL){
			break;
		}
		body ++;

		int head_len = body - head;
		if(head_len == 1 || (head_len == 2 && head[0] == '\r')){
			// packet end
			parsed += head_len;
			input->decr(parsed);
			return &this->recv_data;;
		}
		if(head[0] < '0' || head[0] > '9'){
			log_warn("bad format");
			return NULL;
		}

		char head_str[20];
		if(head_len > sizeof(head_str) - 1){
			return NULL;
		}
		memcpy(head_str, head, head_len - 1); // no '\n'
		head_str[head_len - 1] = '\0';

		int body_len = atoi(head_str);
		if(body_len < 0){
			log_warn("bad format");
			return NULL;
		}
		//log_debug("size: %d, head_len: %d, body_len: %d", size, head_len, body_len);
		size -= head_len + body_len;
		if(size < 0){
			break;
		}

		this->recv_data.push_back(Bytes(body, body_len));

		head += head_len + body_len;
		parsed += head_len + body_len;
		if(size > 0 && head[0] == '\n'){
			head += 1;
			size -= 1;
			parsed += 1;
		}else if(size > 1 && head[0] == '\r' && head[1] == '\n'){
			head += 2;
			size -= 2;
			parsed += 2;
		}else{
			break;
		}
		if(parsed > MAX_PACKET_SIZE){
			 log_warn("fd: %d, exceed max packet size, parsed: %d", this->sock, parsed);
			 return NULL;
		}
	}

	if(input->space() == 0){
		input->nice();
		if(input->space() == 0){
			if(input->grow() == -1){
				log_error("fd: %d, unable to resize input buffer!", this->sock);
				return NULL;
			}
			log_debug("fd: %d, resize input buffer, %s", this->sock, input->stats().c_str());
		}
	}

	// not ready
	this->recv_data.clear();
	return &this->recv_data;
}

int Link::send(const std::vector<std::string> &resp){
	for(int i=0; i<resp.size(); i++){
		output->append_record(resp[i]);
	}
	output->append('\n');
	return this->write();
}

int Link::send(const std::vector<Bytes> &resp){
	for(int i=0; i<resp.size(); i++){
		output->append_record(resp[i]);
	}
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1){
	output->append_record(s1);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2){
	output->append_record(s1);
	output->append_record(s2);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3){
	output->append_record(s1);
	output->append_record(s2);
	output->append_record(s3);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4){
	output->append_record(s1);
	output->append_record(s2);
	output->append_record(s3);
	output->append_record(s4);
	output->append('\n');
	return this->write();
}

int Link::send(const Bytes &s1, const Bytes &s2, const Bytes &s3, const Bytes &s4, const Bytes &s5){
	output->append_record(s1);
	output->append_record(s2);
	output->append_record(s3);
	output->append_record(s4);
	output->append_record(s5);
	output->append('\n');
	return this->write();
}

#if 0
int main(){
	//Link link;
	//link.listen("127.0.0.1", 8888);
	Link *link = Link::connect("127.0.0.1", 8080);
	printf("%d\n", link);
	getchar();
	return 0;
}
#endif
<|endoftext|>


<commit_before>#include <cassert>
#include <iostream>
#include <stdexcept>
#include <fstream>

#include <string>
#include "FileStream.h"
#include "ClassFile.h"
#include "InputStream.h"
#include "OutputStream.h"
#include "JarFile.h"

using namespace std;

ClassFile parseClass(InputStream* fp);
void writeClass(OutputStream* fp, ClassFile const& class_);
void dumpClass(ClassFile const& class_);

map<string, string> classRemap;

void renameClasses(ClassFile& class_)
{
  for(auto& constant : class_.const_pool_)
  {
    if(constant.tag_ != (int)CONSTANT::Class)
      continue;

    auto& classNameEntry = class_.const_pool_[constant.name_index_];

    auto const& origClassName = classNameEntry.utf8_;
    auto i_newName = classRemap.find(origClassName);

    if(i_newName == classRemap.end())
      continue;

    classNameEntry.utf8_ = i_newName->second;
  }
}

void renameFiles(map<string, ClassFile>& files)
{
  for(auto& remapping : classRemap)
  {
    auto const from = remapping.first;
    auto const to = remapping.second;
    auto i_file = files.find(from);

    if(i_file == files.end())
    {
      cerr << "Available classes: ";

      for(auto& file : files)
        cerr << file.first << " ";

      cerr << endl;
      throw runtime_error("Class '" + from + "' doesn't exist");
    }

    auto file = move(i_file->second);
    files.erase(i_file);

    files[to] = move(file);
  }
}

void loadRemappings(string path)
{
  ifstream fp(path);

  if(!fp.is_open())
    throw runtime_error("can't open '" + path + "' for reading");

  string line;

  while(!fp.eof())
  {
    string type, from, to;
    fp >> type >> ws >> from >> to;

    if(type == "class")
      classRemap[from] = to;
  }

  for(auto& remapping : classRemap)
  {
    cout << remapping.first << " -> " << remapping.second << endl;
  }
}

struct Config
{
  string inputPath, outputPath;
  string remapPath;
};

Config parseCommandLine(int argc, char** argv)
{
  Config config;
  int k = 1;
  auto moreArgs = [&] () -> bool { return k < argc; };
  auto popArg =
    [&] () -> string {
      if(!moreArgs())
        throw runtime_error("unepxected end of command line");

      return argv[k++];
    };

  while(moreArgs())
  {
    auto word = popArg();

    if(word == "-r")
      config.remapPath = popArg();
    else if(word == "-i")
      config.inputPath = popArg();
    else if(word == "-o")
      config.outputPath = popArg();
    else
      throw runtime_error("Unknown switch: '" + word + "'");
  }

  return config;
}

int main(int argc, char** argv)
{
  try
  {
    auto config = parseCommandLine(argc, argv);

    if(config.inputPath.empty())
      throw runtime_error("no input path specified");

    if(endsWith(config.inputPath, ".jar"))
    {
      JarFile jar(config.inputPath);

      if(!config.remapPath.empty())
      {
        loadRemappings(config.remapPath);
        auto& classes = jar.getAllClasses();

        for(auto& class_ : classes)
          renameClasses(class_.second);

        renameFiles(classes);
      }

      if(!config.outputPath.empty())
        jar.save(config.outputPath);
    }
    else
    {
      FileStream fp;
      fp.open(config.inputPath);

      auto class_ = parseClass(&fp);

      if(!fp.eof())
        throw runtime_error("parse error");

      dumpClass(class_);

      if(!config.remapPath.empty())
      {
        loadRemappings(config.remapPath);
        renameClasses(class_);
      }

      if(!config.outputPath.empty())
      {
        OutputFileStream out;
        out.open(config.outputPath);
        writeClass(&out, class_);
      }
    }

    return 0;
  }
  catch(runtime_error const& e)
  {
    cerr << "Fatal: " << e.what() << endl;
    return 1;
  }
}

<commit_msg>Dump the class after remapping<commit_after>#include <cassert>
#include <iostream>
#include <stdexcept>
#include <fstream>

#include <string>
#include "FileStream.h"
#include "ClassFile.h"
#include "InputStream.h"
#include "OutputStream.h"
#include "JarFile.h"

using namespace std;

ClassFile parseClass(InputStream* fp);
void writeClass(OutputStream* fp, ClassFile const& class_);
void dumpClass(ClassFile const& class_);

map<string, string> classRemap;

void renameClasses(ClassFile& class_)
{
  for(auto& constant : class_.const_pool_)
  {
    if(constant.tag_ != (int)CONSTANT::Class)
      continue;

    auto& classNameEntry = class_.const_pool_[constant.name_index_];

    auto const& origClassName = classNameEntry.utf8_;
    auto i_newName = classRemap.find(origClassName);

    if(i_newName == classRemap.end())
      continue;

    classNameEntry.utf8_ = i_newName->second;
  }
}

void renameFiles(map<string, ClassFile>& files)
{
  for(auto& remapping : classRemap)
  {
    auto const from = remapping.first;
    auto const to = remapping.second;
    auto i_file = files.find(from);

    if(i_file == files.end())
    {
      cerr << "Available classes: ";

      for(auto& file : files)
        cerr << file.first << " ";

      cerr << endl;
      throw runtime_error("Class '" + from + "' doesn't exist");
    }

    auto file = move(i_file->second);
    files.erase(i_file);

    files[to] = move(file);
  }
}

void loadRemappings(string path)
{
  ifstream fp(path);

  if(!fp.is_open())
    throw runtime_error("can't open '" + path + "' for reading");

  string line;

  while(!fp.eof())
  {
    string type, from, to;
    fp >> type >> ws >> from >> to;

    if(type == "class")
      classRemap[from] = to;
  }

  for(auto& remapping : classRemap)
  {
    cout << remapping.first << " -> " << remapping.second << endl;
  }
}

struct Config
{
  string inputPath, outputPath;
  string remapPath;
};

Config parseCommandLine(int argc, char** argv)
{
  Config config;
  int k = 1;
  auto moreArgs = [&] () -> bool { return k < argc; };
  auto popArg =
    [&] () -> string {
      if(!moreArgs())
        throw runtime_error("unepxected end of command line");

      return argv[k++];
    };

  while(moreArgs())
  {
    auto word = popArg();

    if(word == "-r")
      config.remapPath = popArg();
    else if(word == "-i")
      config.inputPath = popArg();
    else if(word == "-o")
      config.outputPath = popArg();
    else
      throw runtime_error("Unknown switch: '" + word + "'");
  }

  return config;
}

int main(int argc, char** argv)
{
  try
  {
    auto config = parseCommandLine(argc, argv);

    if(config.inputPath.empty())
      throw runtime_error("no input path specified");

    if(endsWith(config.inputPath, ".jar"))
    {
      JarFile jar(config.inputPath);

      if(!config.remapPath.empty())
      {
        loadRemappings(config.remapPath);
        auto& classes = jar.getAllClasses();

        for(auto& class_ : classes)
          renameClasses(class_.second);

        renameFiles(classes);
      }

      if(!config.outputPath.empty())
        jar.save(config.outputPath);
    }
    else
    {
      FileStream fp;
      fp.open(config.inputPath);

      auto class_ = parseClass(&fp);

      if(!fp.eof())
        throw runtime_error("parse error");

      if(!config.remapPath.empty())
      {
        loadRemappings(config.remapPath);
        renameClasses(class_);
      }

      dumpClass(class_);

      if(!config.outputPath.empty())
      {
        OutputFileStream out;
        out.open(config.outputPath);
        writeClass(&out, class_);
      }
    }

    return 0;
  }
  catch(runtime_error const& e)
  {
    cerr << "Fatal: " << e.what() << endl;
    return 1;
  }
}

<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);

	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());

	// Read fiber center positions and compute related things
	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1; // spectrometer has to be identified from 0 to F.Npetal-1
	F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);//get neighbors of each fiber;
                                                //for each spectrometer, get list of fibers

	// Read plates in order they are to be observed

	Plates P = read_plate_centers(F);
	F.Nplate = P.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct galaxy> T(G,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(G,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(G,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf("before assignment\n");
	Assignment A(G,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    simple_assign(G,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments
	for (int i=0; i<1; i++) redistribute_tf(G,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(G,P,pp,F,A);
		redistribute_tf(G,P,pp,F,A);
		redistribute_tf(G,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(G,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;
		//printf(" - Plate %d :",j);
		assign_sf_ss(j,G,P,pp,F,A); // Assign SS and SF just before an observation
		assign_unused(j,G,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		//printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
		// Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
		if (0<=j-F.Analysis) update_plan_from_one_obs(G,P,pp,F,A,F.Nplate-1); else printf("\n");
		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==2000 || j==4000) {
			redistribute_tf(G,P,pp,F,A);
			redistribute_tf(G,P,pp,F,A);
			improve(G,P,pp,F,A);
			redistribute_tf(G,P,pp,F,A);
		}
	}
	print_time(time,"# ... took :");

	init_time_at(time,"# Begin FITS writing",t);
	// Results -------------------------------------------------------
	if (F.Output) for (int j=0; j<F.Nplate; j++) fa_write(j,F.outDir,G,P,pp,F,A); // Write output
	display_results("doc/figs/",G,P,pp,F,A,true);
	if (F.Verif) A.verif(P,G,pp,F); // Verification that the assignment is sane
	print_time(time,"# ... took :");

	print_time(t,"# Finished !... in");

	return(0);
}
<commit_msg>extra printf in main<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);

	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());

	// Read fiber center positions and compute related things
	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1; // spectrometer has to be identified from 0 to F.Npetal-1
	F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);//get neighbors of each fiber;
                                                //for each spectrometer, get list of fibers

	// Read plates in order they are to be observed

	Plates P = read_plate_centers(F);
	F.Nplate = P.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct galaxy> T(G,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(G,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(G,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf("before assignment\n");
	Assignment A(G,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    simple_assign(G,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments
	for (int i=0; i<1; i++) redistribute_tf(G,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(G,P,pp,F,A);
		redistribute_tf(G,P,pp,F,A);
		redistribute_tf(G,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(G,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;
		//printf(" - Plate %d :",j);
		assign_sf_ss(j,G,P,pp,F,A); // Assign SS and SF just before an observation
		assign_unused(j,G,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		//printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
		// Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
		if (0<=j-F.Analysis) update_plan_from_one_obs(G,P,pp,F,A,F.Nplate-1); else printf("\n");
		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==2000 || j==4000) {
			redistribute_tf(G,P,pp,F,A);
			redistribute_tf(G,P,pp,F,A);
			improve(G,P,pp,F,A);
            redistribute_tf(G,P,pp,F,A);
		}
	}
	print_time(time,"# ... took :");

	init_time_at(time,"# Begin FITS writing",t);
	// Results -------------------------------------------------------
    if (F.Output) for (int j=0; j<F.Nplate; j++){
        printf(" printing output for j= %d\n", j);
        fa_write(j,F.outDir,G,P,pp,F,A); // Write output
    }
	display_results("doc/figs/",G,P,pp,F,A,true);
	if (F.Verif) A.verif(P,G,pp,F); // Verification that the assignment is sane
	print_time(time,"# ... took :");

	print_time(t,"# Finished !... in");

	return(0);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include "rectangle.h"
#include "circle.h"
#include "ellipse.h"
#include "square.h"
#include "picture.h"

using namespace std;
using namespace cv;

const int POPULATION = 3;		//size of test population
const int MUTATIONS = 100;		//number of mutations per generation
const int GENERATIONS = 10000;	//number of generations

//returns the total difference in color between the two images
//the less, the better
float getFitness(picture curr, Mat mainImage)
{
	float f = 0.0;
	for (int x = 0; x < curr.img.rows; x++)
	{
		for (int y = 0; y < curr.img.cols; y++)
		{
			Vec3b bgrMainPic = mainImage.at<Vec3b>(x, y);
			Vec3b bgrCurrPic = curr.img.at<Vec3b>(x, y);

			f += abs(bgrCurrPic.val[0] - bgrMainPic.val[0]);	//b
			f += abs(bgrCurrPic.val[1] - bgrMainPic.val[1]);	//g
			f += abs(bgrCurrPic.val[2] - bgrMainPic.val[2]);	//r
		}
	}
	return f;
}

//returns the main file name without the extension
string getFileName(string x)
{
	int i;
	for(i = 0; i < x.size(); i++)
	{
		if (x.at(i) == '.')
			break;
	}
	return x.erase(i, x.size() - i);
}

//determines shape to be used
string getShape(int argc, char** argv)
{
	if (argc != 3) //not provided in command line
	{
		int x = rand() % 4;
		if (x == 0)
			return "ellipse";
		else if (x == 1)
			return "circle";
		else if (x == 2)
			return "rectangle";
		else if (x == 4)
			return "square";
	}
	else
	{
		cout << argv[2] << endl;
		if (string(argv[2]) == "E")
			return "ellipse";
		else if (string(argv[2]) == "C")
			return "circle";
		else if (string(argv[2]) == "R")
			return "rectangle";
		else if (string(argv[2]) == "S")
			return "square";
		else
			return "bad";
	}
}

int main (int argc, char** argv)
{
	//get main image
	Mat mainImage = imread(argv[1], IMREAD_UNCHANGED);
	if (!mainImage.data)
	{
		cout << "Could not open image" << endl;
		return 0;
	}
	string FILENAME = getFileName(argv[1]);
	int ROWS = mainImage.rows;
	int COLS = mainImage.cols;

	//determine shape to use
	bool ELLIPSE = false, CIRCLE = false, RECTANGLE = false, SQUARE = false;
	string SHAPE = getShape(argc, argv);
	if (SHAPE == "bad")
	{
		cout << "Invalid shape input. Use E, C, R, or S." << endl;
		return 0;
	}
	else if (SHAPE == "ellipse")
		ELLIPSE = true;
	else if (SHAPE == "circle")
		CIRCLE = true;
	else if (SHAPE == "rectangle")
		RECTANGLE = true;
	else if (SHAPE == "square")
		SQUARE = true;

	//set up display windows
	namedWindow("Evolving Image", WINDOW_AUTOSIZE);
	//set rand seed
	srand(time(NULL));

	vector<picture> current(POPULATION);

	//generate random images
	for (int i = 0; i < POPULATION; i++)
	{
		Mat curModel(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
		current.at(i).img = curModel;
		current.at(i).fitness = 0;

		Mat buf(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
		if (ELLIPSE)
		{
			my_ellipse el(Point(rand()%COLS, rand()%ROWS));
			ellipse(current.at(i).img, el.pos, el.size, el.angle, 0, 360, el.color, -1);
			current.at(i).ellipses.push_back(el);
		}
		else if (CIRCLE)
		{
			my_circle C(Point(rand()%COLS, rand()%ROWS));
			circle(current.at(i).img, C.center, C.radius, C.color, -1);
			current.at(i).circles.push_back(C);
		}
		else if (RECTANGLE)
		{
			my_rectangle R(Point(rand()%COLS, rand()%ROWS));
			rectangle(current.at(i).img, Rect(R.pos, R.size), R.color, -1);
			current.at(i).rectangles.push_back(R);
		}
		else if (SQUARE)
		{
			my_square S(Point(rand()%COLS, rand()%ROWS));
			rectangle(current.at(i).img, Rect(S.pos, S.size), S.color, -1);
			current.at(i).squares.push_back(S);
		}
	}

	picture bestPicture;
	Mat curModel(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
	bestPicture.img = curModel;
	bestPicture.fitness = 9999;

	//start genetic hill climbing
	for (int k = 0; k < GENERATIONS; k++)
	{
		cout << "Generation #" << k << endl;
		for (int n = 0; n < MUTATIONS; n++)
		{
			//calculate image fitness level for all in population
			for (int i = 0; i < POPULATION; i++)
			{
				current.at(i).fitness = 0;
				current.at(i).fitness = getFitness(current.at(i), mainImage);
				current.at(i).fitness /= (current.at(i).img.rows * current.at(i).img.cols) * 3;
				imshow("Evolving Image", current.at(i).img);
				waitKey(1);
			}
			float bestFitness = 9999;
			int bestPic = -1;

			//select best image generated in population
			for (int i = 0; i < POPULATION; i++)
			{
				if (current.at(i).fitness < bestFitness)
				{
					bestFitness = current.at(i).fitness;
					bestPic = i;
				}
			}

			//generate new population by mutating the best image
			my_ellipse el;
			my_circle C;
			my_rectangle R;
			my_square S;
			if (ELLIPSE)
				el = current.at(bestPic).ellipses.at(current.at(bestPic).ellipses.size() - 1);
			else if (CIRCLE)
				C = current.at(bestPic).circles.at(current.at(bestPic).circles.size() - 1);
			else if (RECTANGLE)
				R = current.at(bestPic).rectangles.at(current.at(bestPic).rectangles.size() - 1);
			else if (SQUARE)
				S = current.at(bestPic).squares.at(current.at(bestPic).squares.size() - 1);

			for (int i = 0; i < POPULATION; i++) //mutate the population
			{
				current.at(i) = current.at(bestPic);
				if (i != bestPic)
				{
					if (ELLIPSE)
						el.mutate();
					else if (CIRCLE)
						C.mutate();
					else if (RECTANGLE)
						R.mutate();
					else if (SQUARE)
						S.mutate();

					Mat buf(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
					bestPicture.img.copyTo(buf);
					if (ELLIPSE)
					{
						ellipse(buf, el.pos, el.size, el.angle, 0, 360, el.color, -1);
						current.at(i).img = buf;
						current.at(i).ellipses.at(current.at(i).ellipses.size() - 1) = el;
					}
					else if (CIRCLE)
					{
						circle(buf, C.center, C.radius, C.color, -1);
						current.at(i).img = buf;
						current.at(i).circles.at(current.at(i).circles.size() - 1) = C;
					}
					else if (RECTANGLE)
					{
						rectangle(buf, Rect(R.pos, R.size), R.color, -1);
						current.at(i).img = buf;
						current.at(i).rectangles.at(current.at(i).rectangles.size() - 1) = R;
					}
					else if (SQUARE)
					{
						rectangle(buf, Rect(S.pos, S.size), S.color, -1);
						current.at(i).img = buf;
						current.at(i).squares.at(current.at(i).squares.size() - 1) = S;
					}
				}
			}

			if (n == MUTATIONS - 1) //after last mutation
			{
				//change bestPicture if new picture is an improvement
				cout << "Previous best = " << bestPicture.fitness << endl;
				cout << "Current best = " << current.at(bestPic).fitness << endl;
				if (bestPicture.fitness >= current.at(bestPic).fitness)
				{
					bestPicture = current.at(bestPic);
					stringstream path;
					if (k % 5 == 0)	//save image to computer
					{
						if (k < 10)
							path << FILENAME << "000" << k << ".jpg";
						else if (k < 100)
							path << FILENAME << "00" << k << ".jpg";
						else if (k < 1000)
							path << FILENAME << "0" << k << ".jpg";
						else
							path << FILENAME << k << ".jpg";
						string savePath = path.str();
						imwrite(savePath, bestPicture.img);
					}
				}
				cout << "Best fitness = " << bestFitness << endl;
			}
		}
		for (int q = 0; q < POPULATION; q++) //create new shapes
		{
			Mat buf(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
			bestPicture.img.copyTo(buf);
			current.at(q).fitness = bestPicture.fitness;
			if (ELLIPSE)
			{
				current.at(q).ellipses = bestPicture.ellipses;
				my_ellipse el(Point(rand()%COLS, rand()%ROWS));
				ellipse(buf, el.pos, el.size, el.angle, 0, 360, el.color, -1);
				current.at(q).img = buf;
				current.at(q).ellipses.push_back(el);
			}
			else if (CIRCLE)
			{
				current.at(q).circles = bestPicture.circles;
				my_circle C(Point(rand()%COLS, rand()%ROWS));
				circle(buf, C.center, C.radius, C.color, -1);
				current.at(q).img = buf;
				current.at(q).circles.push_back(C);
			}
			else if (RECTANGLE)
			{
				current.at(q).rectangles = bestPicture.rectangles;
				my_rectangle R(Point(rand()%COLS, rand()%ROWS));
				rectangle(buf, Rect(R.pos, R.size), R.color, -1);
				current.at(q).img = buf;
				current.at(q).rectangles.push_back(R);
			}
			else if (SQUARE)
			{
				current.at(q).squares = bestPicture.squares;
				my_square S(Point(rand()%COLS, rand()%ROWS));
				rectangle(buf, Rect(S.pos, S.size), S.color, -1);
				current.at(q).img = buf;
				current.at(q).squares.push_back(S);
			}
		}
	}

	cout << "Done!" << endl;
	return 0;
}
<commit_msg>made fitness output more meaningful<commit_after>#include <iostream>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include "rectangle.h"
#include "circle.h"
#include "ellipse.h"
#include "square.h"
#include "picture.h"

using namespace std;
using namespace cv;

const int POPULATION = 3;		//size of test population
const int MUTATIONS = 100;		//number of mutations per generation
const int GENERATIONS = 10000;	//number of generations

//returns the total difference in color between the two images
//the less, the better
float getFitness(picture curr, Mat mainImage)
{
	float f = 0.0;
	for (int x = 0; x < curr.img.rows; x++)
	{
		for (int y = 0; y < curr.img.cols; y++)
		{
			Vec3b bgrMainPic = mainImage.at<Vec3b>(x, y);
			Vec3b bgrCurrPic = curr.img.at<Vec3b>(x, y);

			f += abs(bgrCurrPic.val[0] - bgrMainPic.val[0]);	//b
			f += abs(bgrCurrPic.val[1] - bgrMainPic.val[1]);	//g
			f += abs(bgrCurrPic.val[2] - bgrMainPic.val[2]);	//r
		}
	}
	return f;
}

//returns the main file name without the extension
string getFileName(string x)
{
	int i;
	for(i = 0; i < x.size(); i++)
	{
		if (x.at(i) == '.')
			break;
	}
	return x.erase(i, x.size() - i);
}

//determines shape to be used
string getShape(int argc, char** argv)
{
	if (argc != 3) //not provided in command line
	{
		int x = rand() % 4;
		if (x == 0)
			return "ellipse";
		else if (x == 1)
			return "circle";
		else if (x == 2)
			return "rectangle";
		else if (x == 3)
			return "square";
	}
	else
	{
		cout << argv[2] << endl;
		if (string(argv[2]) == "E")
			return "ellipse";
		else if (string(argv[2]) == "C")
			return "circle";
		else if (string(argv[2]) == "R")
			return "rectangle";
		else if (string(argv[2]) == "S")
			return "square";
		else
			return "bad";
	}
}

int main (int argc, char** argv)
{
	//set rand seed
	srand(time(NULL));

	//get main image
	Mat mainImage = imread(argv[1], IMREAD_UNCHANGED);
	if (!mainImage.data)
	{
		cout << "Could not open image" << endl;
		return 0;
	}
	string FILENAME = getFileName(argv[1]);
	int ROWS = mainImage.rows;
	int COLS = mainImage.cols;

	//determine shape to use
	bool ELLIPSE = false, CIRCLE = false, RECTANGLE = false, SQUARE = false;
	string SHAPE = getShape(argc, argv);
	if (SHAPE == "bad")
	{
		cout << "Invalid shape input. Use E, C, R, or S." << endl;
		return 0;
	}
	else if (SHAPE == "ellipse")
		ELLIPSE = true;
	else if (SHAPE == "circle")
		CIRCLE = true;
	else if (SHAPE == "rectangle")
		RECTANGLE = true;
	else if (SHAPE == "square")
		SQUARE = true;

	//set up display windows
	namedWindow("Evolving Image", WINDOW_AUTOSIZE);

	vector<picture> current(POPULATION);

	//generate random images
	for (int i = 0; i < POPULATION; i++)
	{
		Mat curModel(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
		current.at(i).img = curModel;
		current.at(i).fitness = 0;

		Mat buf(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
		if (ELLIPSE)
		{
			my_ellipse el(Point(rand()%COLS, rand()%ROWS));
			ellipse(current.at(i).img, el.pos, el.size, el.angle, 0, 360, el.color, -1);
			current.at(i).ellipses.push_back(el);
		}
		else if (CIRCLE)
		{
			my_circle C(Point(rand()%COLS, rand()%ROWS));
			circle(current.at(i).img, C.center, C.radius, C.color, -1);
			current.at(i).circles.push_back(C);
		}
		else if (RECTANGLE)
		{
			my_rectangle R(Point(rand()%COLS, rand()%ROWS));
			rectangle(current.at(i).img, Rect(R.pos, R.size), R.color, -1);
			current.at(i).rectangles.push_back(R);
		}
		else if (SQUARE)
		{
			my_square S(Point(rand()%COLS, rand()%ROWS));
			rectangle(current.at(i).img, Rect(S.pos, S.size), S.color, -1);
			current.at(i).squares.push_back(S);
		}
	}

	picture bestPicture;
	Mat curModel(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
	bestPicture.img = curModel;
	bestPicture.fitness = 9999;
	float worstFitness = 9999;

	//start genetic hill climbing
	for (int k = 0; k < GENERATIONS; k++)
	{
		cout << "Generation #" << k << endl;
		for (int n = 0; n < MUTATIONS; n++)
		{
			//calculate image fitness level for all in population
			for (int i = 0; i < POPULATION; i++)
			{
				current.at(i).fitness = 0;
				current.at(i).fitness = getFitness(current.at(i), mainImage);
				current.at(i).fitness /= (current.at(i).img.rows * current.at(i).img.cols) * 3;
				imshow("Evolving Image", current.at(i).img);
				waitKey(1);
			}
			float bestFitness = 9999;
			int bestPic = -1;

			//select best image generated in population
			for (int i = 0; i < POPULATION; i++)
			{
				if (current.at(i).fitness < bestFitness)
				{
					bestFitness = current.at(i).fitness;
					bestPic = i;
				}
				if (k == 0)
					worstFitness = bestFitness;
			}

			//generate new population by mutating the best image
			my_ellipse el;
			my_circle C;
			my_rectangle R;
			my_square S;
			if (ELLIPSE)
				el = current.at(bestPic).ellipses.at(current.at(bestPic).ellipses.size() - 1);
			else if (CIRCLE)
				C = current.at(bestPic).circles.at(current.at(bestPic).circles.size() - 1);
			else if (RECTANGLE)
				R = current.at(bestPic).rectangles.at(current.at(bestPic).rectangles.size() - 1);
			else if (SQUARE)
				S = current.at(bestPic).squares.at(current.at(bestPic).squares.size() - 1);

			for (int i = 0; i < POPULATION; i++) //mutate the population
			{
				current.at(i) = current.at(bestPic);
				if (i != bestPic)
				{
					if (ELLIPSE)
						el.mutate();
					else if (CIRCLE)
						C.mutate();
					else if (RECTANGLE)
						R.mutate();
					else if (SQUARE)
						S.mutate();

					Mat buf(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
					bestPicture.img.copyTo(buf);
					if (ELLIPSE)
					{
						ellipse(buf, el.pos, el.size, el.angle, 0, 360, el.color, -1);
						current.at(i).img = buf;
						current.at(i).ellipses.at(current.at(i).ellipses.size() - 1) = el;
					}
					else if (CIRCLE)
					{
						circle(buf, C.center, C.radius, C.color, -1);
						current.at(i).img = buf;
						current.at(i).circles.at(current.at(i).circles.size() - 1) = C;
					}
					else if (RECTANGLE)
					{
						rectangle(buf, Rect(R.pos, R.size), R.color, -1);
						current.at(i).img = buf;
						current.at(i).rectangles.at(current.at(i).rectangles.size() - 1) = R;
					}
					else if (SQUARE)
					{
						rectangle(buf, Rect(S.pos, S.size), S.color, -1);
						current.at(i).img = buf;
						current.at(i).squares.at(current.at(i).squares.size() - 1) = S;
					}
				}
			}

			if (n == MUTATIONS - 1) //after last mutation
			{
				//change bestPicture if new picture is an improvement
				cout << "Previous best = " << 100*(1-(bestPicture.fitness/worstFitness)) << "%" << endl;
				cout << "Current best = " << 100*(1-(current.at(bestPic).fitness/worstFitness)) << "%" << endl;
				if (bestPicture.fitness >= current.at(bestPic).fitness)
				{
					bestPicture = current.at(bestPic);
					stringstream path;
					if (k % 5 == 0)	//save image to computer
					{
						if (k < 10)
							path << FILENAME << "000" << k << ".jpg";
						else if (k < 100)
							path << FILENAME << "00" << k << ".jpg";
						else if (k < 1000)
							path << FILENAME << "0" << k << ".jpg";
						else
							path << FILENAME << k << ".jpg";
						string savePath = path.str();
						imwrite(savePath, bestPicture.img);
					}
				}
				cout << "Best fitness = " << 100*(1-(bestFitness/worstFitness)) << "%" << endl;
			}
		}
		for (int q = 0; q < POPULATION; q++) //create new shapes
		{
			Mat buf(ROWS, COLS, CV_8UC3, Scalar(0,0,0));
			bestPicture.img.copyTo(buf);
			current.at(q).fitness = bestPicture.fitness;
			if (ELLIPSE)
			{
				current.at(q).ellipses = bestPicture.ellipses;
				my_ellipse el(Point(rand()%COLS, rand()%ROWS));
				ellipse(buf, el.pos, el.size, el.angle, 0, 360, el.color, -1);
				current.at(q).img = buf;
				current.at(q).ellipses.push_back(el);
			}
			else if (CIRCLE)
			{
				current.at(q).circles = bestPicture.circles;
				my_circle C(Point(rand()%COLS, rand()%ROWS));
				circle(buf, C.center, C.radius, C.color, -1);
				current.at(q).img = buf;
				current.at(q).circles.push_back(C);
			}
			else if (RECTANGLE)
			{
				current.at(q).rectangles = bestPicture.rectangles;
				my_rectangle R(Point(rand()%COLS, rand()%ROWS));
				rectangle(buf, Rect(R.pos, R.size), R.color, -1);
				current.at(q).img = buf;
				current.at(q).rectangles.push_back(R);
			}
			else if (SQUARE)
			{
				current.at(q).squares = bestPicture.squares;
				my_square S(Point(rand()%COLS, rand()%ROWS));
				rectangle(buf, Rect(S.pos, S.size), S.color, -1);
				current.at(q).img = buf;
				current.at(q).squares.push_back(S);
			}
		}
	}

	cout << "Done!" << endl;
	return 0;
}
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "LinuxKernelMTEventSource.h"

#include "LinuxMTHelper.h"
#include "TouchEvent.h"
#include "Player.h"
#include "AVGNode.h"
#include "TouchStatus.h"

#include "../base/Logger.h"
#include "../base/Point.h"
#include "../base/ObjectCounter.h"
#include "../base/Exception.h"

#include <linux/input.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <set>

using namespace std;

namespace avg {

LinuxKernelMTEventSource::LinuxKernelMTEventSource()
    : m_LastID(0)
{
}

LinuxKernelMTEventSource::~LinuxKernelMTEventSource()
{
}

void LinuxKernelMTEventSource::start()
{
    string sDevice = "/dev/input/event3";
    m_DeviceFD = ::open(sDevice.c_str(), O_RDONLY | O_NONBLOCK);
    if (m_DeviceFD == -1) {
        throw Exception(AVG_ERR_MT_INIT,
                string("Linux multitouch event source: Could not open device file '")+
                sDevice+"'. "+strerror(errno)+".");
    }

    MultitouchEventSource::start();
    AVG_TRACE(Logger::CONFIG, "Linux MTDev Multitouch event source created.");
}

std::vector<EventPtr> LinuxKernelMTEventSource::pollEvents()
{
    static int numContacts = 0;
    static int tmpID;
    static IntPoint tmpPos;

    struct input_event event[64];
    char * pReadPos = (char*)(void*)&event;
    ssize_t numBytes = 0;
    ssize_t newBytes = -1;
    while (newBytes != 0) {
        newBytes = read(m_DeviceFD, pReadPos+numBytes, sizeof(input_event));
        if (newBytes == -1) {
            newBytes = 0;
        }
        numBytes += newBytes;
    }
    AVG_ASSERT(numBytes%sizeof(input_event) == 0);

    if (numBytes > 0) {
        cerr << "---- read ----" << endl;
    }
    for (unsigned i = 0; i < numBytes/sizeof(input_event); ++i) {
        switch (event[i].type) {
            case EV_ABS:
                cerr << "EV_ABS " << mtCodeToString(event[i].code) << endl;
                switch (event[i].code) {
                    case ABS_MT_TRACKING_ID:
                        numContacts++;
                        tmpID = event[i].value;
                        break;
                    case ABS_MT_POSITION_X:
                        tmpPos.x = event[i].value;
                        break;
                    case ABS_MT_POSITION_Y:
                        tmpPos.y = event[i].value;
                        break;
                    default:
                        break;
                }
                break;
            case EV_SYN:
                cerr << "EV_SYN " << synCodeToString(event[i].code) << endl;
                switch (event[i].code) {
                    case SYN_MT_REPORT:
                        {
                            cerr << "id: " << tmpID << ", pos: " << tmpPos << endl;
                            TouchStatusPtr pTouchStatus = getTouchStatus(tmpID);
                            if (!pTouchStatus) {
                                // Down
                                m_LastID++;
                                TouchEventPtr pEvent = createEvent(m_LastID,
                                        Event::CURSORDOWN, tmpPos);
                                addTouchStatus((long)tmpID, pEvent);
                            } else {
                                // Move
                                TouchEventPtr pEvent = createEvent(0, Event::CURSORMOTION,
                                        tmpPos);
                                pTouchStatus->updateEvent(pEvent);
                            }
                        }
                        break;
                    case SYN_REPORT:
                        cerr << "SYN_REPORT" << endl;
                        break;
                    default:
                        break;
                }
                break;
            default:
                cerr << "Unexpected type " << eventTypeToString(event[i].type) << endl;
                break;
        }
    }
    return MultitouchEventSource::pollEvents();
}

TouchEventPtr LinuxKernelMTEventSource::createEvent(int id, Event::Type type,
        IntPoint pos)
{
    DPoint size = getWindowSize();
    DPoint normPos = DPoint(double(pos.x-m_Dimensions.tl.x)/m_Dimensions.width(),
            double(pos.y-m_Dimensions.tl.y)/m_Dimensions.height());
    IntPoint screenPos(int(normPos.x*size.x+0.5), int(normPos.y*size.y+0.5));
    return TouchEventPtr(new TouchEvent(id, type, screenPos, Event::TOUCH, DPoint(0,0),
            0, 20, 1, DPoint(5,0), DPoint(0,5)));
}

}
<commit_msg>Fixed typo.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "LinuxKernelMTEventSource.h"

#include "LinuxMTHelper.h"
#include "TouchEvent.h"
#include "Player.h"
#include "AVGNode.h"
#include "TouchStatus.h"

#include "../base/Logger.h"
#include "../base/Point.h"
#include "../base/ObjectCounter.h"
#include "../base/Exception.h"

#include <linux/input.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <set>

using namespace std;

namespace avg {

LinuxKernelMTEventSource::LinuxKernelMTEventSource()
    : m_LastID(0)
{
}

LinuxKernelMTEventSource::~LinuxKernelMTEventSource()
{
}

void LinuxKernelMTEventSource::start()
{
    string sDevice = "/dev/input/event3";
    m_DeviceFD = ::open(sDevice.c_str(), O_RDONLY | O_NONBLOCK);
    if (m_DeviceFD == -1) {
        throw Exception(AVG_ERR_MT_INIT,
                string("Linux multitouch event source: Could not open device file '")+
                sDevice+"'. "+strerror(errno)+".");
    }

    MultitouchEventSource::start();
    AVG_TRACE(Logger::CONFIG, "Linux Kernel Multitouch event source created.");
}

std::vector<EventPtr> LinuxKernelMTEventSource::pollEvents()
{
    static int numContacts = 0;
    static int tmpID;
    static IntPoint tmpPos;

    struct input_event event[64];
    char * pReadPos = (char*)(void*)&event;
    ssize_t numBytes = 0;
    ssize_t newBytes = -1;
    while (newBytes != 0) {
        newBytes = read(m_DeviceFD, pReadPos+numBytes, sizeof(input_event));
        if (newBytes == -1) {
            newBytes = 0;
        }
        numBytes += newBytes;
    }
    AVG_ASSERT(numBytes%sizeof(input_event) == 0);

    if (numBytes > 0) {
        cerr << "---- read ----" << endl;
    }
    for (unsigned i = 0; i < numBytes/sizeof(input_event); ++i) {
        switch (event[i].type) {
            case EV_ABS:
                cerr << "EV_ABS " << mtCodeToString(event[i].code) << endl;
                switch (event[i].code) {
                    case ABS_MT_TRACKING_ID:
                        numContacts++;
                        tmpID = event[i].value;
                        break;
                    case ABS_MT_POSITION_X:
                        tmpPos.x = event[i].value;
                        break;
                    case ABS_MT_POSITION_Y:
                        tmpPos.y = event[i].value;
                        break;
                    default:
                        break;
                }
                break;
            case EV_SYN:
                cerr << "EV_SYN " << synCodeToString(event[i].code) << endl;
                switch (event[i].code) {
                    case SYN_MT_REPORT:
                        {
                            cerr << "id: " << tmpID << ", pos: " << tmpPos << endl;
                            TouchStatusPtr pTouchStatus = getTouchStatus(tmpID);
                            if (!pTouchStatus) {
                                // Down
                                m_LastID++;
                                TouchEventPtr pEvent = createEvent(m_LastID,
                                        Event::CURSORDOWN, tmpPos);
                                addTouchStatus((long)tmpID, pEvent);
                            } else {
                                // Move
                                TouchEventPtr pEvent = createEvent(0, Event::CURSORMOTION,
                                        tmpPos);
                                pTouchStatus->updateEvent(pEvent);
                            }
                        }
                        break;
                    case SYN_REPORT:
                        cerr << "SYN_REPORT" << endl;
                        break;
                    default:
                        break;
                }
                break;
            default:
                cerr << "Unexpected type " << eventTypeToString(event[i].type) << endl;
                break;
        }
    }
    return MultitouchEventSource::pollEvents();
}

TouchEventPtr LinuxKernelMTEventSource::createEvent(int id, Event::Type type,
        IntPoint pos)
{
    DPoint size = getWindowSize();
    DPoint normPos = DPoint(double(pos.x-m_Dimensions.tl.x)/m_Dimensions.width(),
            double(pos.y-m_Dimensions.tl.y)/m_Dimensions.height());
    IntPoint screenPos(int(normPos.x*size.x+0.5), int(normPos.y*size.y+0.5));
    return TouchEventPtr(new TouchEvent(id, type, screenPos, Event::TOUCH, DPoint(0,0),
            0, 20, 1, DPoint(5,0), DPoint(0,5)));
}

}
<|endoftext|>