From 564e09bd8d03f42133ce6bcaaed76eb9313be5f6 Mon Sep 17 00:00:00 2001 From: Neil Date: Mon, 30 Sep 2024 11:43:25 +0800 Subject: [PATCH] feat(MLEPolynomial): Add mul_quotients method Remove eval_from_coeffs method and implement mul_quotients for efficient polynomial multiplication using MLE representation --- src/mle2.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/mle2.py b/src/mle2.py index a8c7e83..9837e04 100644 --- a/src/mle2.py +++ b/src/mle2.py @@ -123,15 +123,6 @@ def evaluate_from_coeffs(coeffs, zs): half >>= 1 return f[0] - @staticmethod - def eval_from_coeffs(coeffs, z): - t = 1 - v = 0 - for i in range(0, len(coeffs)): - v += coeffs[i] * t - t *= z - return v - def decompose_by_div(self, point): """ Divide an MLE at the point: [X_0, X_1, ..., X_{n-1}] in O(N) (Linear!) @@ -192,3 +183,25 @@ def decompose_by_div_from_coeffs(coeffs: list, point: list) -> list: half >>= 1 return quotients, coeffs[0] + + def mul_quotients(quotient, remainder, p): + """ + r: current remainder + q: current quotient + p: current point + + last_remainder + = r + (xi - p) * q + = r - p * q + xi * q + = (r - p * q) * (1 - xi) + (r - (p - 1) * q) * xi + """ + + assert isinstance(quotient, MLEPolynomial), "quotient must be an MLEPolynomial" + assert isinstance(remainder, MLEPolynomial), "remainder must be an MLEPolynomial" + + half = len(quotient.evals) + result = [0] * 2 * half + for i, (q, r) in enumerate(zip(quotient.evals, remainder.evals)): + result[i] = r - p * q + result[i + half] = r - (p - 1) * q + return MLEPolynomial(result, quotient.num_var + 1)