<commit_before>#ifndef VPP_PYRAMID_HH__
# define VPP_PYRAMID_HH__

# include <vpp/core/image2d.hh>
# include <vpp/core/box_nbh2d.hh>

namespace vpp
{

  template <typename V>
  void subsample2(const image2d<V>& in, image2d<V>& out)
  {
    auto nbh = const_box_nbh2d<V, 2, 2>(in);

    int nr = out.nrows();
    int nc = out.ncols();

#pragma omp parallel for
    for (int r = 0; r < nr; r++)
    {
      V* out_row = &out(r, 0);
      const V* row1 = &in(r * 2, 0);
      const V* row2 = &in(r * 2 + 1, 0);
      #pragma omp simd
      for (int c = 0; c < nc; c++)
      {
        out_row[c][0] = (row1[c * 2][0] + row1[c * 2 + 1][0] + row2[c * 2][0] + row2[c * 2 + 1][0]) / 4;
      }
    }
  }

  template <typename V, unsigned N>
  struct pyramid
  {
  public:

    typedef imageNd<V, N> image_type;

    pyramid(boxNd<N> d, int nlevels, int factor)
      : levels_(nlevels),
        factor_(factor)
    {
      for (int i = 0; i < nlevels; i++)
      {
        levels_[i] = imageNd<V, N>(d);
        d = make_box2d(d.nrows() / factor, d.ncols() / factor);
      }
    }

    void update(const imageNd<V, N>& in)
    {
      copy(in, levels_[0]);
      for (int i = 1; i < levels_.size(); i++)
      {
        if (factor_ == 2)
          subsample2(levels_[i - 1], levels_[i]);
        else
          assert(0); // Not implemented.
      }
    }

    int factor() const
    {
      return factor_;
    }

    std::vector<image_type>& levels() { return levels_; };
    const std::vector<image_type>& levels() const { return levels_; };<commit_msg>Complete pyramid with    operator[]    swap    propagate_level0<commit_after>#ifndef VPP_PYRAMID_HH__
# define VPP_PYRAMID_HH__

# include <vpp/core/image2d.hh>
# include <vpp/core/box_nbh2d.hh>
# include <vpp/core/vector.hh>

namespace vpp
{

  template <typename V>
  void subsample2(const image2d<V>& in, image2d<V>& out)
  {
    int nr = out.nrows();
    int nc = out.ncols();

#pragma omp parallel for
    for (int r = 0; r < nr; r++)
    {
      V* out_row = &out(r, 0);
      const V* row1 = &in(r * 2, 0);
      const V* row2 = &in(r * 2 + 1, 0);
#pragma omp simd
      for (int c = 0; c < nc; c++)
      {
        out_row[c][0] = (row1[c * 2][0] + row1[c * 2 + 1][0] + row2[c * 2][0] + row2[c * 2 + 1][0]) / 4;
      }
    }
  }

  template <typename V, unsigned N>
  struct pyramid
  {
  public:

    typedef imageNd<V, N> image_type;

    pyramid(boxNd<N> d, int nlevels, int factor)
      : levels_(nlevels),
        factor_(factor)
    {
      for (int i = 0; i < nlevels; i++)
      {
        levels_[i] = imageNd<V, N>(d);
        d = make_box2d(d.nrows() / factor, d.ncols() / factor);
      }
    }

    image_type& operator[] (unsigned i)
    {
      return levels_[i];
    }

    const image_type& operator[] (unsigned i) const
    {
      return levels_[i];
    }

    void propagate_level0()
    {
      for (int i = 1; i < levels_.size(); i++)
      {
        if (factor_ == 2)
          subsample2(levels_[i - 1], levels_[i]);
        else
          assert(0); // Not implemented.
      }
    }

    void update(const imageNd<V, N>& in)
    {
      copy(in, levels_[0]);
      propagate_level0();
    }

    int factor() const { return factor_; }
    int size() const { return levels_.size(); }

    void swap(pyramid<V, N>& o)
    {
      levels_.swap(o.levels_);
      std::swap(factor_, o.factor_);
    }

    std::vector<image_type>& levels() { return levels_; };
    const std::vector<image_type>& levels() const { return levels_; };
{'fraction_non_alphanumeric': 0.16206209057248647, 'fraction_numerical': 0.023924807747080605, 'mean_word_length': 2.1668169522091976, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7516085', 'n_tokens_mistral': 1416, 'n_tokens_neox': 1340, 'n_words': 339}