<commit_before>#pragma once

#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <numeric>

#include "gf/gf.h"
#include "gf/polynomial.h"
#include "codes/cyclic.h"
#include "gf/linear_equation_system.h"

namespace cyclic {
template <unsigned q, typename Capability,
          typename Sigma = peterson_gorenstein_zierler_tag,
          unsigned N = (1 << q) - 1, typename Coding = division_tag>
class primitive_bch : public cyclic<q, Capability, Sigma, N, Coding> {

  using Base = cyclic<q, Capability, Sigma, N, Coding>;

public:
  using Element = typename Base::Element;
  using Polynomial = typename Base::Polynomial;

private:
  static Polynomial g() {
    Polynomial g({ Element(1) });

    std::vector<unsigned> powers;
    for (unsigned p = 1; p < 2 * static_cast<unsigned>(Base::t); p += 2) {
      powers.push_back(p);
    }

    for (const auto &power : powers) {
      auto roots = minimal_polynomial_roots(power);
      Polynomial m{ Element(1) };
      for (const auto &root : roots) {
        /* build minimal polynomial */
        m *= Polynomial{ Element::from_power(root), Element(1) };
      }
      g = g.lcm(m);
    }
    return g;
  }

  static std::vector<Element> syndromes() {
    std::vector<Element> syndromes;
    Polynomial g_ = g();

    for (unsigned power = 1; power < 2 * Base::t + 1; power++)
      syndromes.push_back(Element::from_power(power));
    return syndromes;
  }

  /*      r - 1
   *       __
   * m_i = || (x - a^{2^j*i})
   *      j = 0
   */
  static std::vector<unsigned> minimal_polynomial_roots(const unsigned &i) {
    std::vector<unsigned> roots{ i };

    for (unsigned r = 1; r < q; r++) {
      auto power = ((1 << r) * i) % Base::n;
      if (power == i)
        break;
      roots.push_back(power);
    }

    auto power = ((1 << q) * i) % Base::n;
    if (power != i) {
      throw std::runtime_error("Cycle seems not be finished after q elements.");
    }

    return roots;
  }

  std::vector<Element>
  error_values(const std::vector<Element> &,
               const std::vector<Element> &zeroes, naive_tag) const
      override {
    return std::vector<Element>(zeroes.size(), Element(1));
  }

  std::vector<Element> error_values(const std::vector<Element> &s,
                                         const std::vector<Element> &z,
                                         forney_tag) const override {
    return error_values(s, z, naive_tag());
  }

public:
  primitive_bch() : Base(g(), syndromes()) {}

  template <typename Return_type = typename Base::Galois_Field::storage_t,
            typename InputSequence>
  std::vector<Return_type> correct(const InputSequence &b,
                                   const std::vector<unsigned> &erasures =
                                       std::vector<unsigned>()) const {
    if (!std::is_same<Sigma, peterson_gorenstein_zierler_tag>::value ||<commit_msg>Add virtual dtor and explicitly defaulted copy/move ctors/assignment operator<commit_after>#pragma once

#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <numeric>

#include "gf/gf.h"
#include "gf/polynomial.h"
#include "codes/cyclic.h"
#include "gf/linear_equation_system.h"

namespace cyclic {
template <unsigned q, typename Capability,
          typename Sigma = peterson_gorenstein_zierler_tag,
          unsigned N = (1 << q) - 1, typename Coding = division_tag>
class primitive_bch : public cyclic<q, Capability, Sigma, N, Coding> {

  using Base = cyclic<q, Capability, Sigma, N, Coding>;

public:
  using Element = typename Base::Element;
  using Polynomial = typename Base::Polynomial;

private:
  static Polynomial g() {
    Polynomial g({ Element(1) });

    std::vector<unsigned> powers;
    for (unsigned p = 1; p < 2 * static_cast<unsigned>(Base::t); p += 2) {
      powers.push_back(p);
    }

    for (const auto &power : powers) {
      auto roots = minimal_polynomial_roots(power);
      Polynomial m{ Element(1) };
      for (const auto &root : roots) {
        /* build minimal polynomial */
        m *= Polynomial{ Element::from_power(root), Element(1) };
      }
      g = g.lcm(m);
    }
    return g;
  }

  static std::vector<Element> syndromes() {
    std::vector<Element> syndromes;
    Polynomial g_ = g();

    for (unsigned power = 1; power < 2 * Base::t + 1; power++)
      syndromes.push_back(Element::from_power(power));
    return syndromes;
  }

  /*      r - 1
   *       __
   * m_i = || (x - a^{2^j*i})
   *      j = 0
   */
  static std::vector<unsigned> minimal_polynomial_roots(const unsigned &i) {
    std::vector<unsigned> roots{ i };

    for (unsigned r = 1; r < q; r++) {
      auto power = ((1 << r) * i) % Base::n;
      if (power == i)
        break;
      roots.push_back(power);
    }

    auto power = ((1 << q) * i) % Base::n;
    if (power != i) {
      throw std::runtime_error("Cycle seems not be finished after q elements.");
    }

    return roots;
  }

  std::vector<Element>
  error_values(const std::vector<Element> &,
               const std::vector<Element> &zeroes, naive_tag) const
      override {
    return std::vector<Element>(zeroes.size(), Element(1));
  }

  std::vector<Element> error_values(const std::vector<Element> &s,
                                         const std::vector<Element> &z,
                                         forney_tag) const override {
    return error_values(s, z, naive_tag());
  }

public:
  primitive_bch() : Base(g(), syndromes()) {}
  virtual ~primitive_bch() = default;

  primitive_bch(const primitive_bch &) = default;
  primitive_bch(primitive_bch &&) = default;
  primitive_bch &operator=(const primitive_bch &) = default;
  primitive_bch &operator=(primitive_bch &&) = default;

  template <typename Return_type = typename Base::Galois_Field::storage_t,
            typename InputSequence>
  std::vector<Return_type> correct(const InputSequence &b,
                                   const std::vector<unsigned> &erasures =
                                       std::vector<unsigned>()) const {
    if (!std::is_same<Sigma, peterson_gorenstein_zierler_tag>::value ||
{'fraction_non_alphanumeric': 0.13754282917278512, 'fraction_numerical': 0.005873715124816446, 'mean_word_length': 2.7423687423687424, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 13, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3342737', 'n_tokens_mistral': 2030, 'n_tokens_neox': 1923, 'n_words': 483}