26 static const size_t kN = N;
33 Elt& operator[](
size_t i) {
return t_[i]; }
34 const Elt& operator[](
size_t i)
const {
return t_[i]; }
36 T& add(
const T& y,
const Field& F) {
37 for (
size_t i = 0; i < N; ++i) {
42 T& sub(
const T& y,
const Field& F) {
43 for (
size_t i = 0; i < N; ++i) {
48 T& mul(
const T& y,
const Field& F) {
49 for (
size_t i = 0; i < N; ++i) {
54 T& mul_scalar(
const Elt& y,
const Field& F) {
55 for (
size_t i = 0; i < N; ++i) {
65 Elt df = F.subf(f[1], f[0]);
67 if (Field::kCharacteristicTwo) {
70 for (
size_t i = 2; i < N; ++i) {
71 g[i] = F.addf(g[0], F.mulf(F.poly_evaluation_point(i), df));
76 for (
size_t i = 2; i < N; ++i) {
77 g[i] = F.addf(g[i - 1], df);
87 void newton_of_lagrange(
const Field& F) {
88 for (
size_t i = 1; i < N; i++) {
89 for (
size_t k = N; k-- > i;) {
90 F.sub(t_[k], t_[k - 1]);
91 F.mul(t_[k], F.newton_denominator(k, i));
98 Elt eval_newton(
const Elt& x,
const Field& F)
const {
101 for (
size_t i = N - 1; i-- > 0;) {
102 F.mul(e, F.subf(x, F.poly_evaluation_point(i)));
109 Elt eval_lagrange(
const Elt& x,
const Field& F)
const {
111 tmp.newton_of_lagrange(F);
112 return tmp.eval_newton(x, F);
117 Elt eval_monomial(
const Elt& x,
const Field& F)
const {
120 for (
size_t i = N - 1; i-- > 0;) {
127 static T powers_of(
const Elt& e,
const Field& F) {
130 for (
size_t i = 1; i < N; ++i) {
131 r[i] = F.mulf(r[i - 1], e);
150 class dot_interpolation {
156 explicit dot_interpolation(
const Field& F) {
157 for (
size_t k = 0; k < N; ++k) {
158 for (
size_t i = 0; i < N; ++i) {
159 identity_[k][i] = (i == k) ? F.one() : F.zero();
161 identity_[k].newton_of_lagrange(F);
166 T coef(
const Elt& x,
const Field& F)
const {
168 for (
size_t k = 0; k < N; ++k) {
169 c[k] = identity_[k].eval_newton(x, F);