46 using Convolver =
typename ConvolutionFactory::Convolver;
51 ReedSolomon(
size_t n,
size_t m,
const Field& F,
52 const ConvolutionFactory& factory)
56 leading_constant_(m - n + 1),
59 std::vector<Elt> inverses(m_);
60 AlgebraUtil<Field>::batch_inverse_arithmetic(m, &inverses[0], F);
61 c_ = factory.make(n, m, &inverses[0]);
62 leading_constant_[0] = F.one();
63 binom_i_[0] = F.one();
66 for (
size_t i = 1; i + degree_bound_ < m; ++i) {
67 leading_constant_[i] =
68 F.mulf(leading_constant_[i - 1],
69 F.mulf(F.of_scalar(degree_bound_ + i), inverses[i]));
73 for (
size_t k = degree_bound_; k < m; ++k) {
74 F.mul(leading_constant_[k - degree_bound_],
75 F.of_scalar(k - degree_bound_));
76 if (degree_bound_ % 2 == 1) {
77 F.neg(leading_constant_[k - degree_bound_]);
81 for (
size_t i = 1; i < n; ++i) {
83 F.mulf(binom_i_[i - 1], F.mulf(F.of_scalar(n - i), inverses[i]));
85 for (
size_t i = 1; i < n; i += 2) {
93 void interpolate(Elt y[])
const {
96 size_t n = degree_bound_ + 1;
99 std::vector<Elt> x(n);
100 for (
size_t i = 0; i < n; i++) {
101 x[i] = F.mulf(binom_i_[i], y[i]);
104 std::vector<Elt> T(m_);
105 c_->convolution(&x[0], &T[0]);
107 for (
size_t i = n; i < m_; ++i) {
108 y[i] = F.mulf(leading_constant_[i - degree_bound_], T[i]);
117 const size_t degree_bound_;
121 std::unique_ptr<const Convolver> c_;
127 std::vector<Elt> leading_constant_;
129 std::vector<Elt> binom_i_;
133class ReedSolomonFactory {
135 ReedSolomonFactory(
const ConvolutionFactory& factory,
const Field& f)
136 : factory_(factory), f_(f) {}
138 std::unique_ptr<ReedSolomon<Field, ConvolutionFactory>> make(
size_t n,
140 return std::make_unique<ReedSolomon<Field, ConvolutionFactory>>(n, m, f_,
145 const ConvolutionFactory& factory_;