f"prod_eval_ops[{i}] is incorrect: expected polynomial: "
f"{prod_eval_polys[i]} found polynomial: {eval_op.poly}")
+ def reversed(self):
+ # type: () -> ToomCookInstance
+ """return a ToomCookInstance where lhs/rhs are reversed"""
+ return ToomCookInstance(
+ lhs_part_count=self.rhs_part_count,
+ rhs_part_count=self.lhs_part_count,
+ eval_points=self.eval_points,
+ lhs_eval_ops=self.rhs_eval_ops,
+ rhs_eval_ops=self.lhs_eval_ops,
+ prod_eval_ops=self.prod_eval_ops)
+
@staticmethod
def make_toom_2():
# type: () -> ToomCookInstance
+ """make an instance of Toom-2 aka Karatsuba multiplication"""
return ToomCookInstance(
lhs_part_count=2,
rhs_part_count=2,
],
)
+ @staticmethod
+ def make_toom_2_5():
+ # type: () -> ToomCookInstance
+ """makes an instance of Toom-2.5"""
+ inp_0_plus_inp_2 = EvalOpAdd(EvalOpInput(0), EvalOpInput(2))
+ inp_1_minus_inp_2 = EvalOpSub(EvalOpInput(1), EvalOpInput(2))
+ inp_1_plus_inp_2 = EvalOpAdd(EvalOpInput(1), EvalOpInput(2))
+ inp_1_minus_inp_2_all_div_2 = EvalOpExactDiv(inp_1_minus_inp_2, 2)
+ inp_1_plus_inp_2_all_div_2 = EvalOpExactDiv(inp_1_plus_inp_2, 2)
+ return ToomCookInstance(
+ lhs_part_count=3,
+ rhs_part_count=2,
+ eval_points=[0, 1, -1, POINT_AT_INFINITY],
+ lhs_eval_ops=[
+ EvalOpInput(0),
+ EvalOpAdd(inp_0_plus_inp_2, EvalOpInput(1)),
+ EvalOpSub(inp_0_plus_inp_2, EvalOpInput(1)),
+ EvalOpInput(2),
+ ],
+ rhs_eval_ops=[
+ EvalOpInput(0),
+ EvalOpAdd(EvalOpInput(0), EvalOpInput(1)),
+ EvalOpSub(EvalOpInput(0), EvalOpInput(1)),
+ EvalOpInput(1),
+ ],
+ prod_eval_ops=[
+ EvalOpInput(0),
+ EvalOpSub(inp_1_minus_inp_2_all_div_2, EvalOpInput(3)),
+ EvalOpSub(inp_1_plus_inp_2_all_div_2, EvalOpInput(0)),
+ EvalOpInput(3),
+ ],
+ )
+
+ # TODO: add make_toom_3
+
def toom_cook_mul(fn, word_count, instances):
# type: (Fn, int, Sequence[ToomCookInstance]) -> OSet[Op]