32 static const size_t kN = N;
39 Elt& operator[](
size_t i) {
return t_[i]; }
40 const Elt& operator[](
size_t i)
const {
return t_[i]; }
42 T& add(
const T& y,
const Field& F) {
43 for (
size_t i = 0; i < N; ++i) {
48 T& sub(
const T& y,
const Field& F) {
49 for (
size_t i = 0; i < N; ++i) {
54 T& mul(
const T& y,
const Field& F) {
55 for (
size_t i = 0; i < N; ++i) {
60 T& mul_scalar(
const Elt& y,
const Field& F) {
61 for (
size_t i = 0; i < N; ++i) {
71 Elt df = F.subf(f[1], f[0]);
73 if (Field::kCharacteristicTwo) {
76 for (
size_t i = 2; i < N; ++i) {
77 g[i] = F.addf(g[0], F.mulf(F.poly_evaluation_point(i), df));
82 for (
size_t i = 2; i < N; ++i) {
83 g[i] = F.addf(g[i - 1], df);
93 void newton_of_lagrange(
const Field& F) {
94 for (
size_t i = 1; i < N; i++) {
95 for (
size_t k = N; k-- > i;) {
96 F.sub(t_[k], t_[k - 1]);
97 F.mul(t_[k], F.newton_denominator(k, i));
104 Elt eval_newton(
const Elt& x,
const Field& F)
const {
107 for (
size_t i = N - 1; i-- > 0;) {
108 F.mul(e, F.subf(x, F.poly_evaluation_point(i)));
115 Elt eval_lagrange(
const Elt& x,
const Field& F)
const {
117 tmp.newton_of_lagrange(F);
118 return tmp.eval_newton(x, F);
123 Elt eval_monomial(
const Elt& x,
const Field& F)
const {
126 for (
size_t i = N - 1; i-- > 0;) {
147 class dot_interpolation {
153 explicit dot_interpolation(
const Field& F) {
154 for (
size_t k = 0; k < N; ++k) {
155 for (
size_t i = 0; i < N; ++i) {
156 identity_[k][i] = (i == k) ? F.one() : F.zero();
158 identity_[k].newton_of_lagrange(F);
163 T coef(
const Elt& x,
const Field& F)
const {
165 for (
size_t k = 0; k < N; ++k) {
166 c[k] = identity_[k].eval_newton(x, F);